1rand(3) Erlang Module Definition rand(3)
2
3
4
6 rand - Pseudo random number generation.
7
9 This module provides a pseudo random number generator. The module con‐
10 tains a number of algorithms. The uniform distribution algorithms are
11 based on the Xoroshiro and Xorshift algorithms by Sebastiano Vigna.
12 The normal distribution algorithm uses the Ziggurat Method by
13 Marsaglia and Tsang on top of the uniform distribution algorithm.
14
15 For most algorithms, jump functions are provided for generating non-
16 overlapping sequences for parallel computations. The jump functions
17 perform calculations equivalent to perform a large number of repeated
18 calls for calculating new states.
19
20 The following algorithms are provided:
21
22 exsss:
23 Xorshift116**, 58 bits precision and period of 2^116-1
24
25 Jump function: equivalent to 2^64 calls
26
27 This is the Xorshift116 generator combined with the StarStar scram‐
28 bler from the 2018 paper by David Blackman and Sebastiano Vigna:
29 Scrambled Linear Pseudorandom Number Generators
30
31 The generator does not need 58-bit rotates so it is faster than the
32 Xoroshiro116 generator, and when combined with the StarStar scram‐
33 bler it does not have any weak low bits like exrop (Xoroshiro116+).
34
35 Alas, this combination is about 10% slower than exrop, but is
36 despite that the default algorithm thanks to its statistical quali‐
37 ties.
38
39 exro928ss:
40 Xoroshiro928**, 58 bits precision and a period of 2^928-1
41
42 Jump function: equivalent to 2^512 calls
43
44 This is a 58 bit version of Xoroshiro1024**, from the 2018 paper by
45 David Blackman and Sebastiano Vigna: Scrambled Linear Pseudorandom
46 Number Generators that on a 64 bit Erlang system executes only
47 about 40% slower than the default exsss algorithm but with much
48 longer period and better statistical properties, and on the flip
49 side a larger state.
50
51 Many thanks to Sebastiano Vigna for his help with the 58 bit adap‐
52 tion.
53
54 exrop:
55 Xoroshiro116+, 58 bits precision and period of 2^116-1
56
57 Jump function: equivalent to 2^64 calls
58
59 exs1024s:
60 Xorshift1024*, 64 bits precision and a period of 2^1024-1
61
62 Jump function: equivalent to 2^512 calls
63
64 exsp:
65 Xorshift116+, 58 bits precision and period of 2^116-1
66
67 Jump function: equivalent to 2^64 calls
68
69 This is a corrected version of the previous default algorithm, that
70 now has been superseded by Xoroshiro116+ (exrop). Since there is no
71 native 58 bit rotate instruction this algorithm executes a little
72 (say < 15%) faster than exrop. See the algorithms' homepage.
73
74 The default algorithm is exsss (Xorshift116**). If a specific algorithm
75 is required, ensure to always use seed/1 to initialize the state.
76
77 Undocumented (old) algorithms are deprecated but still implemented so
78 old code relying on them will produce the same pseudo random sequences
79 as before.
80
81 Note:
82 There were a number of problems in the implementation of the now undoc‐
83 umented algorithms, which is why they are deprecated. The new algo‐
84 rithms are a bit slower but do not have these problems:
85
86 Uniform integer ranges had a skew in the probability distribution that
87 was not noticable for small ranges but for large ranges less than the
88 generator's precision the probability to produce a low number could be
89 twice the probability for a high.
90
91 Uniform integer ranges larger than or equal to the generator's preci‐
92 sion used a floating point fallback that only calculated with 52 bits
93 which is smaller than the requested range and therefore were not all
94 numbers in the requested range even possible to produce.
95
96 Uniform floats had a non-uniform density so small values i.e less than
97 0.5 had got smaller intervals decreasing as the generated value
98 approached 0.0 although still uniformly distributed for sufficiently
99 large subranges. The new algorithms produces uniformly distributed
100 floats on the form N * 2.0^(-53) hence equally spaced.
101
102
103 Every time a random number is requested, a state is used to calculate
104 it and a new state is produced. The state can either be implicit or be
105 an explicit argument and return value.
106
107 The functions with implicit state use the process dictionary variable
108 rand_seed to remember the current state.
109
110 If a process calls uniform/0, uniform/1 or uniform_real/0 without set‐
111 ting a seed first, seed/1 is called automatically with the default
112 algorithm and creates a non-constant seed.
113
114 The functions with explicit state never use the process dictionary.
115
116 Examples:
117
118 Simple use; creates and seeds the default algorithm with a non-constant
119 seed if not already done:
120
121 R0 = rand:uniform(),
122 R1 = rand:uniform(),
123
124 Use a specified algorithm:
125
126 _ = rand:seed(exs928ss),
127 R2 = rand:uniform(),
128
129 Use a specified algorithm with a constant seed:
130
131 _ = rand:seed(exs928ss, {123, 123534, 345345}),
132 R3 = rand:uniform(),
133
134 Use the functional API with a non-constant seed:
135
136 S0 = rand:seed_s(exsss),
137 {R4, S1} = rand:uniform_s(S0),
138
139 Textbook basic form Box-Muller standard normal deviate
140
141 R5 = rand:uniform_real(),
142 R6 = rand:uniform(),
143 SND0 = math:sqrt(-2 * math:log(R5)) * math:cos(math:pi() * R6)
144
145 Create a standard normal deviate:
146
147 {SND1, S2} = rand:normal_s(S1),
148
149 Create a normal deviate with mean -3 and variance 0.5:
150
151 {ND0, S3} = rand:normal_s(-3, 0.5, S2),
152
153 Note:
154 The builtin random number generator algorithms are not cryptographi‐
155 cally strong. If a cryptographically strong random number generator is
156 needed, use something like crypto:rand_seed/0.
157
158
159 For all these generators except exro928ss and exsss the lowest bit(s)
160 has got a slightly less random behaviour than all other bits. 1 bit for
161 exrop (and exsp), and 3 bits for exs1024s. See for example the explana‐
162 tion in the Xoroshiro128+ generator source code:
163
164 Beside passing BigCrush, this generator passes the PractRand test suite
165 up to (and included) 16TB, with the exception of binary rank tests,
166 which fail due to the lowest bit being an LFSR; all other bits pass all
167 tests. We suggest to use a sign test to extract a random Boolean value.
168
169 If this is a problem; to generate a boolean with these algorithms use
170 something like this:
171
172 (rand:uniform(16) > 8)
173
174 And for a general range, with N = 1 for exrop, and N = 3 for exs1024s:
175
176 (((rand:uniform(Range bsl N) - 1) bsr N) + 1)
177
178 The floating point generating functions in this module waste the lowest
179 bits when converting from an integer so they avoid this snag.
180
182 builtin_alg() =
183 exsss | exro928ss | exrop | exs1024s | exsp | exs64 |
184 exsplus | exs1024
185
186 alg() = builtin_alg() | atom()
187
188 alg_handler() =
189 #{type := alg(),
190 bits => integer() >= 0,
191 weak_low_bits => integer() >= 0,
192 max => integer() >= 0,
193 next :=
194 fun((alg_state()) -> {integer() >= 0, alg_state()}),
195 uniform => fun((state()) -> {float(), state()}),
196 uniform_n =>
197 fun((integer() >= 1, state()) -> {integer() >= 1, state()}),
198 jump => fun((state()) -> state())}
199
200 alg_state() =
201 exsplus_state() |
202 exro928_state() |
203 exrop_state() |
204 exs1024_state() |
205 exs64_state() |
206 term()
207
208 state() = {alg_handler(), alg_state()}
209
210 Algorithm-dependent state.
211
212 export_state() = {alg(), alg_state()}
213
214 Algorithm-dependent state that can be printed or saved to file.
215
216 seed() =
217 [integer()] | integer() | {integer(), integer(), integer()}
218
219 A seed value for the generator.
220
221 A list of integers sets the generator's internal state directly,
222 after algorithm-dependent checks of the value and masking to the
223 proper word size.
224
225 An integer is used as the initial state for a SplitMix64 genera‐
226 tor. The output values of that is then used for setting the gen‐
227 erator's internal state after masking to the proper word size
228 and if needed avoiding zero values.
229
230 A traditional 3-tuple of integers seed is passed through algo‐
231 rithm-dependent hashing functions to create the generator's ini‐
232 tial state.
233
234 exsplus_state()
235
236 Algorithm specific internal state
237
238 exro928_state()
239
240 Algorithm specific internal state
241
242 exrop_state()
243
244 Algorithm specific internal state
245
246 exs1024_state()
247
248 Algorithm specific internal state
249
250 exs64_state()
251
252 Algorithm specific internal state
253
255 export_seed() -> undefined | export_state()
256
257 Returns the random number state in an external format. To be
258 used with seed/1.
259
260 export_seed_s(State :: state()) -> export_state()
261
262 Returns the random number generator state in an external format.
263 To be used with seed/1.
264
265 jump() -> NewState :: state()
266
267 Returns the state after performing jump calculation to the state
268 in the process dictionary.
269
270 This function generates a not_implemented error exception when
271 the jump function is not implemented for the algorithm specified
272 in the state in the process dictionary.
273
274 jump(State :: state()) -> NewState :: state()
275
276 Returns the state after performing jump calculation to the given
277 state.
278
279 This function generates a not_implemented error exception when
280 the jump function is not implemented for the algorithm specified
281 in the state.
282
283 normal() -> float()
284
285 Returns a standard normal deviate float (that is, the mean is 0
286 and the standard deviation is 1) and updates the state in the
287 process dictionary.
288
289 normal(Mean :: number(), Variance :: number()) -> float()
290
291 Returns a normal N(Mean, Variance) deviate float and updates the
292 state in the process dictionary.
293
294 normal_s(State :: state()) -> {float(), NewState :: state()}
295
296 Returns, for a specified state, a standard normal deviate float
297 (that is, the mean is 0 and the standard deviation is 1) and a
298 new state.
299
300 normal_s(Mean :: number(),
301 Variance :: number(),
302 State0 :: state()) ->
303 {float(), NewS :: state()}
304
305 Returns, for a specified state, a normal N(Mean, Variance) devi‐
306 ate float and a new state.
307
308 seed(AlgOrStateOrExpState ::
309 builtin_alg() | state() | export_state()) ->
310 state()
311
312 Seeds random number generation with the specifed algorithm and
313 time-dependent data if AlgOrStateOrExpState is an algorithm.
314
315 Otherwise recreates the exported seed in the process dictionary,
316 and returns the state. See also export_seed/0.
317
318 seed(Alg :: builtin_alg(), Seed :: seed()) -> state()
319
320 Seeds random number generation with the specified algorithm and
321 integers in the process dictionary and returns the state.
322
323 seed_s(AlgOrStateOrExpState ::
324 builtin_alg() | state() | export_state()) ->
325 state()
326
327 Seeds random number generation with the specifed algorithm and
328 time-dependent data if AlgOrStateOrExpState is an algorithm.
329
330 Otherwise recreates the exported seed and returns the state. See
331 also export_seed/0.
332
333 seed_s(Alg :: builtin_alg(), Seed :: seed()) -> state()
334
335 Seeds random number generation with the specified algorithm and
336 integers and returns the state.
337
338 uniform() -> X :: float()
339
340 Returns a random float uniformly distributed in the value range
341 0.0 =< X < 1.0 and updates the state in the process dictionary.
342
343 The generated numbers are on the form N * 2.0^(-53), that is;
344 equally spaced in the interval.
345
346 Warning:
347 This function may return exactly 0.0 which can be fatal for cer‐
348 tain applications. If that is undesired you can use (1.0 -
349 rand:uniform()) to get the interval 0.0 < X =< 1.0, or instead
350 use uniform_real/0.
351
352 If neither endpoint is desired you can test and re-try like
353 this:
354
355 my_uniform() ->
356 case rand:uniform() of
357 0.0 -> my_uniform();
358 X -> X
359 end
360 end.
361
362
363 uniform_real() -> X :: float()
364
365 Returns a random float uniformly distributed in the value range
366 DBL_MIN =< X < 1.0 and updates the state in the process dictio‐
367 nary.
368
369 Conceptually, a random real number R is generated from the
370 interval 0 =< R < 1 and then the closest rounded down normalized
371 number in the IEEE 754 Double precision format is returned.
372
373 Note:
374 The generated numbers from this function has got better granu‐
375 larity for small numbers than the regular uniform/0 because all
376 bits in the mantissa are random. This property, in combination
377 with the fact that exactly zero is never returned is useful for
378 algoritms doing for example 1.0 / X or math:log(X).
379
380
381 See uniform_real_s/1 for more explanation.
382
383 uniform(N :: integer() >= 1) -> X :: integer() >= 1
384
385 Returns, for a specified integer N >= 1, a random integer uni‐
386 formly distributed in the value range 1 =< X =< N and updates
387 the state in the process dictionary.
388
389 uniform_s(State :: state()) -> {X :: float(), NewState :: state()}
390
391 Returns, for a specified state, random float uniformly distrib‐
392 uted in the value range 0.0 =< X < 1.0 and a new state.
393
394 The generated numbers are on the form N * 2.0^(-53), that is;
395 equally spaced in the interval.
396
397 Warning:
398 This function may return exactly 0.0 which can be fatal for cer‐
399 tain applications. If that is undesired you can use (1.0 -
400 rand:uniform(State)) to get the interval 0.0 < X =< 1.0, or
401 instead use uniform_real_s/1.
402
403 If neither endpoint is desired you can test and re-try like
404 this:
405
406 my_uniform(State) ->
407 case rand:uniform(State) of
408 {0.0, NewState} -> my_uniform(NewState);
409 Result -> Result
410 end
411 end.
412
413
414 uniform_real_s(State :: state()) ->
415 {X :: float(), NewState :: state()}
416
417 Returns, for a specified state, a random float uniformly dis‐
418 tributed in the value range DBL_MIN =< X < 1.0 and updates the
419 state in the process dictionary.
420
421 Conceptually, a random real number R is generated from the
422 interval 0 =< R < 1 and then the closest rounded down normalized
423 number in the IEEE 754 Double precision format is returned.
424
425 Note:
426 The generated numbers from this function has got better granu‐
427 larity for small numbers than the regular uniform_s/1 because
428 all bits in the mantissa are random. This property, in combina‐
429 tion with the fact that exactly zero is never returned is useful
430 for algoritms doing for example 1.0 / X or math:log(X).
431
432
433 The concept implicates that the probability to get exactly zero
434 is extremely low; so low that this function is in fact guaran‐
435 teed to never return zero. The smallest number that it might
436 return is DBL_MIN, which is 2.0^(-1022).
437
438 The value range stated at the top of this function description
439 is technically correct, but 0.0 =< X < 1.0 is a better descrip‐
440 tion of the generated numbers' statistical distribution. Except
441 that exactly 0.0 is never returned, which is not possible to
442 observe statistically.
443
444 For example; for all sub ranges N*2.0^(-53) =< X <
445 (N+1)*2.0^(-53) where 0 =< integer(N) < 2.0^53 the probability
446 is the same. Compare that with the form of the numbers generated
447 by uniform_s/1.
448
449 Having to generate extra random bits for small numbers costs a
450 little performance. This function is about 20% slower than the
451 regular uniform_s/1
452
453 uniform_s(N :: integer() >= 1, State :: state()) ->
454 {X :: integer() >= 1, NewState :: state()}
455
456 Returns, for a specified integer N >= 1 and a state, a random
457 integer uniformly distributed in the value range 1 =< X =< N and
458 a new state.
459
460
461
462Ericsson AB stdlib 3.10 rand(3)