1rand(3)                    Erlang Module Definition                    rand(3)
2
3
4

NAME

6       rand - Pseudo random number generation.
7

DESCRIPTION

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

DATA TYPES

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

EXPORTS

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.12.1                         rand(3)
Impressum