Skip to content

Commit 7f80162

Browse files
committed
Update after feedback
1 parent 52e0daa commit 7f80162

File tree

1 file changed

+37
-27
lines changed

1 file changed

+37
-27
lines changed

lib/stdlib/src/rand.erl

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,17 @@ PRNGs in general, and so the algorithms in this module, are mostly used
4040
for test and simulation. They are designed for good statistical
4141
quality and high generation speed.
4242

43-
An generator algorithm, for each iteration, takes a state as input
43+
A generator algorithm, for each iteration, takes a state as input
4444
and produces a raw pseudo random number and a new state to be used
4545
for the next iteration.
4646

4747
A particular state always produces the same number and new state.
4848
The initial state is produced from a [seed](`seed/1`).
4949
This makes it possible to repeat for example a simulation with the same
5050
random number sequence, by re-using the same seed.
51+
There are also the functions `export_seed/0` and `export_seed_s/1`
52+
that captures the PRNG state in an `t:export_state/0` that
53+
can be used to start from a known state.
5154

5255
This property, and others, make the algorithms in this module
5356
unsuitable for cryptographical applications, but in the `m:crypto` module
@@ -56,19 +59,19 @@ there are suitable generators, for this module's
5659
See `crypto:rand_seed_s/0` and `crypto:rand_seed_alg_s/1`.
5760

5861
At the end of this module documentation there are some
59-
[niche algorithms](#niche-algorithms) that does not use
62+
[niche algorithms](#niche-algorithms) that do not use
6063
this module's normal [plug-in framework](#plug-in-framework).
61-
They may be useful for special purposes like fast generation
64+
They are useful for special purposes like fast generation
6265
when quality is not essential, for seeding other generators, and such.
6366

6467
[](){: #plug-in-framework } Plug-in framework
6568
---------------------------------------------
6669

6770
The raw pseudo random numbers produced by the base generators
68-
are only suitable in some cases such as power of two ranges
71+
are only appropriate in some cases such as power of two ranges
6972
less than the generator size, and some have quirks,
7073
for example weak low bits. Therefore, the Plug-in Framework
71-
implements a common [API](#plug-in-framework-api) to all base generator,
74+
implements a common [API](#plug-in-framework-api) for all base generators,
7275
that add essential or useful funcionality:
7376

7477
* Keeping the generator [state](`seed/1`) in the process dictionary.
@@ -93,7 +96,7 @@ A generator has to be initialized. This is done by one of the
9396
`seed/1` or `seed_s/1` functions, which also select which
9497
[algorithm](#algorithms) to use. The `seed/1` functions
9598
store the generator and state in the process dictionary,
96-
while the `seed_s/1` functions do not, which requires
99+
while the `seed_s/1` functions only return the state, which requires
97100
the calling code to handle the state and updates to it.
98101

99102
The seed functions that do not have a `Seed` value as an argument
@@ -113,7 +116,8 @@ Sibling functions without that suffix take an implicit state from
113116
and store the new state in the process dictionary, and only return
114117
their "interesting " output value. If the process dictionary
115118
does not contain a state, [`seed(default)`](`seed/1`)
116-
is implicitly called to create an automatic seed as initial state.
119+
is implicitly called to create an automatic seed for the
120+
[_default algorithm_](#default-algorithm) as initial state.
117121

118122
#### _Usage_
119123

@@ -123,7 +127,7 @@ functions, which also selects a PRNG algorithm.
123127
Then call a [Plug-in framework API](#plug-in-framework-api) function
124128
either with an explicit state from the seed function
125129
and use the returned new state in the next call,
126-
or call an API function without an explicit state
130+
or call an API function without an explicit state argument
127131
to operate on the state in the process dictionary.
128132

129133
#### _Examples_
@@ -159,7 +163,7 @@ true
159163
%% with an automatic default seed, then generate
160164
%% a floating point number:
161165
%%
162-
5> _ = rand:seed(exro928ss).
166+
5> rand:seed(exro928ss).
163167
6> R2 = rand:uniform(),
164168
is_float(R2) andalso 0.0 =< R2 andalso R2 < 1.0.
165169
true
@@ -168,10 +172,9 @@ true
168172
%% with a specified seed, then generate
169173
%% a floating point number:
170174
%%
171-
7> _ = rand:seed(exro928ss, 123456789).
172-
8> R3 = rand:uniform(),
173-
is_float(R3) andalso 0.0 =< R3 andalso R3 < 1.0.
174-
true
175+
7> rand:seed(exro928ss, 123456789).
176+
8> R3 = rand:uniform().
177+
0.48303622772415256
175178

176179
%% Select and initialize a specific algorithm,
177180
%% with an automatic default seed, using the functional API
@@ -236,9 +239,10 @@ per generator bit.
236239

237240
By using a jump function instead of starting several generators
238241
from different seeds it is assured that the generated sequences
239-
do not overlap. Two different seeds may accidentally start
240-
the generators in sequence positions that are close to each other,
241-
but a jump function jumps to a sequence position very far ahead.
242+
do not overlap. The alternative of using different seeds
243+
may accidentally start the generators in sequence positions
244+
that are close to each other, but a jump function jumps
245+
to a sequence position very far ahead.
242246

243247
To create numbers with normal distribution the
244248
[Ziggurat Method by Marsaglia and Tsang](http://www.jstatsoft.org/v05/i08)
@@ -248,9 +252,9 @@ The following algorithms are provided:
248252

249253
- **`exsss`**, the [_default algorithm_](#default-algorithm)
250254
*(Since OTP 22.0)*
251-
Xorshift116\*\*, 58 bits precision and period of 2^116-1
255+
Xorshift116\*\*, 58 bits precision and period of 2^116-1.
252256

253-
Jump function: equivalent to 2^64 calls
257+
Jump function: equivalent to 2^64 calls.
254258

255259
This is the Xorshift116 generator combined with the StarStar scrambler from
256260
the 2018 paper by David Blackman and Sebastiano Vigna:
@@ -265,9 +269,9 @@ The following algorithms are provided:
265269
its statistical qualities.
266270

267271
- **`exro928ss`** *(Since OTP 22.0)*
268-
Xoroshiro928\*\*, 58 bits precision and a period of 2^928-1
272+
Xoroshiro928\*\*, 58 bits precision and a period of 2^928-1.
269273

270-
Jump function: equivalent to 2^512 calls
274+
Jump function: equivalent to 2^512 calls.
271275

272276
This is a 58 bit version of Xoroshiro1024\*\*, from the 2018 paper by
273277
David Blackman and Sebastiano Vigna:
@@ -280,25 +284,29 @@ The following algorithms are provided:
280284
Many thanks to Sebastiano Vigna for his help with the 58 bit adaption.
281285

282286
- **`exrop`** *(Since OTP 20.0)*
283-
Xoroshiro116+, 58 bits precision and period of 2^116-1
287+
Xoroshiro116+, 58 bits precision and period of 2^116-1.
284288

285-
Jump function: equivalent to 2^64 calls
289+
Jump function: equivalent to 2^64 calls.
286290

287291
- **`exs1024s`** *(Since OTP 20.0)*
288292
Xorshift1024\*, 64 bits precision and a period of 2^1024-1
289293

290-
Jump function: equivalent to 2^512 calls
294+
Jump function: equivalent to 2^512 calls.
295+
296+
Since this generator operates on 64-bit integers that are bignums
297+
on a 64 bit platforms, it is much slower than `exro928ss` above.
291298

292299
- **`exsp`** *(Since OTP 20.0)*
293300
Xorshift116+, 58 bits precision and period of 2^116-1
294301

295-
Jump function: equivalent to 2^64 calls
302+
Jump function: equivalent to 2^64 calls.
296303

297304
This is a corrected version of a previous
298305
[_default algorithm_](#default-algorithm) (`exsplus`, _deprecated_),
299306
that was superseded by Xoroshiro116+ (`exrop`). Since this algorithm
300-
does not use rotate it executes a little (say < 15%) faster than `exrop`
301-
(that has to do a 58 bit rotate, for which there is no native instruction).
307+
does not use rotate operations it executes a little (say < 15%) faster
308+
than `exrop` (that has to do a 58 bit rotate,
309+
for which there is no native instruction).
302310
See the [algorithms' homepage](http://xorshift.di.unimi.it).
303311

304312
[](){: #default-algorithm }
@@ -310,7 +318,9 @@ required, ensure to always use `seed/1` to initialize the state.
310318

311319
Which algorithm that is the default may change between Erlang/OTP releases,
312320
and is selected to be one with high speed, small state and "good enough"
313-
statistical properties.
321+
statistical properties. So to ensure that the same sequence is reproduced
322+
on a later Erlang/OTP release, use a `seed/2` or `seed_s/2` to select
323+
both a specific algorithm and the seed value.
314324

315325
#### Old Algorithms
316326

0 commit comments

Comments
 (0)