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  use
11       the   xoroshiro116+  and  xorshift1024* 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  some  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         exrop:
23           Xoroshiro116+, 58 bits precision and period of 2^116-1
24
25           Jump function: equivalent to 2^64 calls
26
27         exs1024s:
28           Xorshift1024*, 64 bits precision and a period of 2^1024-1
29
30           Jump function: equivalent to 2^512 calls
31
32         exsp:
33           Xorshift116+, 58 bits precision and period of 2^116-1
34
35           Jump function: equivalent to 2^64 calls
36
37           This is a corrected version of the previous default algorithm, that
38           now has been superseded by Xoroshiro116+ (exrop). Since there is no
39           native 58 bit rotate instruction this algorithm executes  a  little
40           (say < 15%) faster than exrop. See the algorithms' homepage.
41
42       The default algorithm is exrop (Xoroshiro116+). If a specific algorithm
43       is required, ensure to always use seed/1 to initialize the state.
44
45       Undocumented (old) algorithms are deprecated but still  implemented  so
46       old  code relying on them will produce the same pseudo random sequences
47       as before.
48
49   Note:
50       There were a number of problems in the implementation of the now undoc‐
51       umented  algorithms,  which  is  why they are deprecated. The new algo‐
52       rithms are a bit slower but do not have these problems:
53
54       Uniform integer ranges had a skew in the probability distribution  that
55       was  not  noticable for small ranges but for large ranges less than the
56       generator's precision the probability to produce a low number could  be
57       twice the probability for a high.
58
59       Uniform  integer  ranges larger than or equal to the generator's preci‐
60       sion used a floating point fallback that only calculated with  52  bits
61       which  is  smaller  than the requested range and therefore were not all
62       numbers in the requested range even possible to produce.
63
64       Uniform floats had a non-uniform density so small values i.e less  than
65       0.5  had  got  smaller  intervals  decreasing  as  the  generated value
66       approached 0.0 although still uniformly  distributed  for  sufficiently
67       large  subranges.  The  new  algorithms  produces uniformly distributed
68       floats on the form N * 2.0^(-53) hence equally spaced.
69
70
71       Every time a random number is requested, a state is used  to  calculate
72       it  and a new state is produced. The state can either be implicit or be
73       an explicit argument and return value.
74
75       The functions with implicit state use the process  dictionary  variable
76       rand_seed to remember the current state.
77
78       If  a process calls uniform/0, uniform/1 or uniform_real/0 without set‐
79       ting a seed first, seed/1 is  called  automatically  with  the  default
80       algorithm and creates a non-constant seed.
81
82       The functions with explicit state never use the process dictionary.
83
84       Examples:
85
86       Simple use; creates and seeds the default algorithm with a non-constant
87       seed if not already done:
88
89       R0 = rand:uniform(),
90       R1 = rand:uniform(),
91
92       Use a specified algorithm:
93
94       _ = rand:seed(exs1024s),
95       R2 = rand:uniform(),
96
97       Use a specified algorithm with a constant seed:
98
99       _ = rand:seed(exs1024s, {123, 123534, 345345}),
100       R3 = rand:uniform(),
101
102       Use the functional API with a non-constant seed:
103
104       S0 = rand:seed_s(exrop),
105       {R4, S1} = rand:uniform_s(S0),
106
107       Textbook basic form Box-Muller standard normal deviate
108
109       R5 = rand:uniform_real(),
110       R6 = rand:uniform(),
111       SND0 = math:sqrt(-2 * math:log(R5)) * math:cos(math:pi() * R6)
112
113       Create a standard normal deviate:
114
115       {SND1, S2} = rand:normal_s(S1),
116
117       Create a normal deviate with mean -3 and variance 0.5:
118
119       {ND0, S3} = rand:normal_s(-3, 0.5, S2),
120
121   Note:
122       The builtin random number generator algorithms  are  not  cryptographi‐
123       cally  strong. If a cryptographically strong random number generator is
124       needed, use something like crypto:rand_seed/0.
125
126
127       For all these generators the lowest bit(s) has got a slightly less ran‐
128       dom  behaviour  than  all other bits. 1 bit for exrop (and exsp), and 3
129       bits  for  exs1024s.  See  for   example   the   explanation   in   the
130       Xoroshiro128+  generator source code:
131
132       Beside passing BigCrush, this generator passes the PractRand test suite
133       up to (and included) 16TB, with the exception of binary rank tests,
134       which fail due to the lowest bit being an LFSR; all other bits pass all
135       tests. We suggest to use a sign test to extract a random Boolean value.
136
137       If this is a problem; to generate a boolean use something like this:
138
139       (rand:uniform(16) > 8)
140
141       And for a general range, with N = 1 for exrop, and N = 3 for exs1024s:
142
143       (((rand:uniform(Range bsl N) - 1) bsr N) + 1)
144
145       The floating point generating functions in this module waste the lowest
146       bits when converting from an integer so they avoid this snag.
147

DATA TYPES

149       builtin_alg() =
150           exs64 | exsplus | exsp | exs1024 | exs1024s | exrop
151
152       alg() = builtin_alg() | atom()
153
154       alg_handler() =
155           #{type := alg(),
156             bits => integer() >= 0,
157             weak_low_bits => integer() >= 0,
158             max => integer() >= 0,
159             next :=
160                 fun((alg_state()) -> {integer() >= 0, alg_state()}),
161             uniform => fun((state()) -> {float(), state()}),
162             uniform_n =>
163                 fun((integer() >= 1, state()) -> {integer() >= 1, state()}),
164             jump => fun((state()) -> state())}
165
166       alg_state() =
167           exs64_state() |
168           exsplus_state() |
169           exs1024_state() |
170           exrop_state() |
171           term()
172
173       state() = {alg_handler(), alg_state()}
174
175              Algorithm-dependent state.
176
177       export_state() = {alg(), alg_state()}
178
179              Algorithm-dependent state that can be printed or saved to file.
180
181       exs64_state()
182
183              Algorithm specific internal state
184
185       exsplus_state()
186
187              Algorithm specific internal state
188
189       exs1024_state()
190
191              Algorithm specific internal state
192
193       exrop_state()
194
195              Algorithm specific internal state
196

EXPORTS

198       export_seed() -> undefined | export_state()
199
200              Returns the random number state in an  external  format.  To  be
201              used with seed/1.
202
203       export_seed_s(State :: state()) -> export_state()
204
205              Returns the random number generator state in an external format.
206              To be used with seed/1.
207
208       jump() -> NewState :: state()
209
210              Returns the state after performing jump calculation to the state
211              in the process dictionary.
212
213              This  function  generates a not_implemented error exception when
214              the jump function is not implemented for the algorithm specified
215              in the state in the process dictionary.
216
217       jump(State :: state()) -> NewState :: state()
218
219              Returns the state after performing jump calculation to the given
220              state.
221
222              This function generates a not_implemented error  exception  when
223              the jump function is not implemented for the algorithm specified
224              in the state.
225
226       normal() -> float()
227
228              Returns a standard normal deviate float (that is, the mean is  0
229              and  the  standard  deviation is 1) and updates the state in the
230              process dictionary.
231
232       normal(Mean :: number(), Variance :: number()) -> float()
233
234              Returns a normal N(Mean, Variance) deviate float and updates the
235              state in the process dictionary.
236
237       normal_s(State :: state()) -> {float(), NewState :: state()}
238
239              Returns,  for a specified state, a standard normal deviate float
240              (that is, the mean is 0 and the standard deviation is 1)  and  a
241              new state.
242
243       normal_s(Mean :: number(),
244                Variance :: number(),
245                State0 :: state()) ->
246                   {float(), NewS :: state()}
247
248              Returns, for a specified state, a normal N(Mean, Variance) devi‐
249              ate float and a new state.
250
251       seed(AlgOrStateOrExpState ::
252                builtin_alg() | state() | export_state()) ->
253               state()
254
255              Seeds random number generation with the specifed  algorithm  and
256              time-dependent data if AlgOrStateOrExpState is an algorithm.
257
258              Otherwise recreates the exported seed in the process dictionary,
259              and returns the state. See also export_seed/0.
260
261       seed(Alg :: builtin_alg(),
262            Seed :: {integer(), integer(), integer()}) ->
263               state()
264
265              Seeds random number generation with the specified algorithm  and
266              integers in the process dictionary and returns the state.
267
268       seed_s(AlgOrStateOrExpState ::
269                  builtin_alg() | state() | export_state()) ->
270                 state()
271
272              Seeds  random  number generation with the specifed algorithm and
273              time-dependent data if AlgOrStateOrExpState is an algorithm.
274
275              Otherwise recreates the exported seed and returns the state. See
276              also export_seed/0.
277
278       seed_s(Alg :: builtin_alg(),
279              Seed :: {integer(), integer(), integer()}) ->
280                 state()
281
282              Seeds  random number generation with the specified algorithm and
283              integers and returns the state.
284
285       uniform() -> X :: float()
286
287              Returns a random float uniformly distributed in the value  range
288              0.0 =< X < 1.0 and updates the state in the process dictionary.
289
290              The  generated  numbers  are on the form N * 2.0^(-53), that is;
291              equally spaced in the interval.
292
293          Warning:
294              This function may return exactly 0.0 which can be fatal for cer‐
295              tain  applications.  If  that  is  undesired  you can use (1.0 -
296              rand:uniform()) to get the interval 0.0 < X =< 1.0,  or  instead
297              use uniform_real/0.
298
299              If  neither  endpoint  is  desired  you can test and re-try like
300              this:
301
302              my_uniform() ->
303                  case rand:uniform() of
304                      0.0 -> my_uniform();
305                   X -> X
306                  end
307              end.
308
309
310       uniform_real() -> X :: float()
311
312              Returns a random float uniformly distributed in the value  range
313              DBL_MIN  =< X < 1.0 and updates the state in the process dictio‐
314              nary.
315
316              Conceptually, a random real  number  R  is  generated  from  the
317              interval 0 =< R < 1 and then the closest rounded down normalized
318              number in the IEEE 754 Double precision format is returned.
319
320          Note:
321              The generated numbers from this function has got  better  granu‐
322              larity  for small numbers than the regular uniform/0 because all
323              bits in the mantissa are random. This property,  in  combination
324              with  the fact that exactly zero is never returned is useful for
325              algoritms doing for example 1.0 / X or math:log(X).
326
327
328              See uniform_real_s/1 for more explanation.
329
330       uniform(N :: integer() >= 1) -> X :: integer() >= 1
331
332              Returns, for a specified integer N >= 1, a random  integer  uni‐
333              formly  distributed  in  the value range 1 =< X =< N and updates
334              the state in the process dictionary.
335
336       uniform_s(State :: state()) -> {X :: float(), NewState :: state()}
337
338              Returns, for a specified state, random float uniformly  distrib‐
339              uted in the value range 0.0 =< X < 1.0 and a new state.
340
341              The  generated  numbers  are on the form N * 2.0^(-53), that is;
342              equally spaced in the interval.
343
344          Warning:
345              This function may return exactly 0.0 which can be fatal for cer‐
346              tain  applications.  If  that  is  undesired  you can use (1.0 -
347              rand:uniform(State)) to get the interval 0.0  <  X  =<  1.0,  or
348              instead use uniform_real_s/1.
349
350              If  neither  endpoint  is  desired  you can test and re-try like
351              this:
352
353              my_uniform(State) ->
354                  case rand:uniform(State) of
355                      {0.0, NewState} -> my_uniform(NewState);
356                   Result -> Result
357                  end
358              end.
359
360
361       uniform_real_s(State :: state()) ->
362                         {X :: float(), NewState :: state()}
363
364              Returns, for a specified state, a random  float  uniformly  dis‐
365              tributed  in  the value range DBL_MIN =< X < 1.0 and updates the
366              state in the process dictionary.
367
368              Conceptually, a random real  number  R  is  generated  from  the
369              interval 0 =< R < 1 and then the closest rounded down normalized
370              number in the IEEE 754 Double precision format is returned.
371
372          Note:
373              The generated numbers from this function has got  better  granu‐
374              larity  for  small  numbers than the regular uniform_s/1 because
375              all bits in the mantissa are random. This property, in  combina‐
376              tion with the fact that exactly zero is never returned is useful
377              for algoritms doing for example 1.0 / X or math:log(X).
378
379
380              The concept implicates that the probability to get exactly  zero
381              is  extremely  low; so low that this function is in fact guaran‐
382              teed to never return zero. The smallest  number  that  it  might
383              return is DBL_MIN, which is 2.0^(-1022).
384
385              The  value  range stated at the top of this function description
386              is technically correct, but 0.0 =< X < 1.0 is a better  descrip‐
387              tion  of the generated numbers' statistical distribution. Except
388              that exactly 0.0 is never returned, which  is  not  possible  to
389              observe statistically.
390
391              For   example;   for   all   sub   ranges  N*2.0^(-53)  =<  X  <
392              (N+1)*2.0^(-53) where 0 =< integer(N) < 2.0^53  the  probability
393              is the same. Compare that with the form of the numbers generated
394              by uniform_s/1.
395
396              Having to generate extra random bits for small numbers  costs  a
397              little  performance.  This function is about 20% slower than the
398              regular uniform_s/1
399
400       uniform_s(N :: integer() >= 1, State :: state()) ->
401                    {X :: integer() >= 1, NewState :: state()}
402
403              Returns, for a specified integer N >= 1 and a  state,  a  random
404              integer uniformly distributed in the value range 1 =< X =< N and
405              a new state.
406
407
408
409Ericsson AB                     stdlib 3.8.2.1                         rand(3)
Impressum