A standard normal that is identical on every platform, compiler and flag set, not merely for a given libm.
Same arguments and same distribution as pf_random_normal_at; a different algorithm, and so
a different value at the same coordinate. Marsaglia's polar method: draw a point in the
square, reject it unless it lands in the unit disc, and map the survivor through
sqrt(-2*log(s)/s). Every step is IEEE + - * / and sqrt -- both correctly rounded by the
standard -- over parquet_expkey's frozen logarithm, with rounding barriers on the two
squares and on the argument of the sqrt so that no compiler may fuse or regroup them.
It costs more than the Ziggurat, in two ways. It rejects 21.5 % of candidate pairs
rather than 1.5 % of single draws, it discards the second variate the method produces (a
stream that kept it would have hidden state, so %rewind would stop being exact), and its
logarithm is about 3x libm's. Reach for it when a stored result must reproduce across
machines; take pf_random_normal_at otherwise.
Not pure, because the frozen transform's rounding barrier is a volatile local and a
pure procedure may not have one. Elemental use still works, but a caller's own pure
procedure and a do concurrent body cannot reach it -- pf_random_normal_at can.
pf_random_normal_portable_at for an integer(int32) stream index.
impure because exp_key is: the frozen transform's rounding barrier is a volatile
local, and a pure procedure may not have one. Elemental use is unaffected.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(in) | :: | seed |
the stream family's seed |
||
| integer(kind=int32), | intent(in) | :: | i |
stream index; sign-extends, so any value is valid |
||
| integer(kind=int64), | intent(in), | optional | :: | draw |
1-based value index; absent means 1 |
a standard normal draw
pf_random_normal_portable_at for an integer(int64) stream index.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(in) | :: | seed |
the stream family's seed |
||
| integer(kind=int64), | intent(in) | :: | i |
stream index; every value is valid |
||
| integer(kind=int64), | intent(in), | optional | :: | draw |
1-based value index; absent means 1 |
a standard normal draw