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 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 or uniform/1 without setting a seed first,
79 seed/1 is called automatically with the default algorithm and creates a
80 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 Create a standard normal deviate:
108
109 {SND0, S2} = rand:normal_s(S1),
110
111 Create a normal deviate with mean -3 and variance 0.5:
112
113 {ND0, S3} = rand:normal_s(-3, 0.5, S2),
114
115 Note:
116 The builtin random number generator algorithms are not cryptographi‐
117 cally strong. If a cryptographically strong random number generator is
118 needed, use something like crypto:rand_seed/0.
119
120
121 For all these generators the lowest bit(s) has got a slightly less ran‐
122 dom behaviour than all other bits. 1 bit for exrop (and exsp), and 3
123 bits for exs1024s. See for example the explanation in the
124 Xoroshiro128+ generator source code:
125
126 Beside passing BigCrush, this generator passes the PractRand test suite
127 up to (and included) 16TB, with the exception of binary rank tests,
128 which fail due to the lowest bit being an LFSR; all other bits pass all
129 tests. We suggest to use a sign test to extract a random Boolean value.
130
131 If this is a problem; to generate a boolean use something like this:
132
133 (rand:uniform(16) > 8)
134
135 And for a general range, with N = 1 for exrop, and N = 3 for exs1024s:
136
137 (((rand:uniform(Range bsl N) - 1) bsr N) + 1)
138
139 The floating point generating functions in this module waste the lowest
140 bits when converting from an integer so they avoid this snag.
141
143 builtin_alg() =
144 exs64 | exsplus | exsp | exs1024 | exs1024s | exrop
145
146 alg() = builtin_alg() | atom()
147
148 alg_handler() =
149 #{type := alg(),
150 bits => integer() >= 0,
151 weak_low_bits => integer() >= 0,
152 max => integer() >= 0,
153 next :=
154 fun((alg_state()) -> {integer() >= 0, alg_state()}),
155 uniform => fun((state()) -> {float(), state()}),
156 uniform_n =>
157 fun((integer() >= 1, state()) -> {integer() >= 1, state()}),
158 jump => fun((state()) -> state())}
159
160 alg_state() =
161 exs64_state() |
162 exsplus_state() |
163 exs1024_state() |
164 exrop_state() |
165 term()
166
167 state() = {alg_handler(), alg_state()}
168
169 Algorithm-dependent state.
170
171 export_state() = {alg(), alg_state()}
172
173 Algorithm-dependent state that can be printed or saved to file.
174
175 exs64_state()
176
177 Algorithm specific internal state
178
179 exsplus_state()
180
181 Algorithm specific internal state
182
183 exs1024_state()
184
185 Algorithm specific internal state
186
187 exrop_state()
188
189 Algorithm specific internal state
190
192 export_seed() -> undefined | export_state()
193
194 Returns the random number state in an external format. To be
195 used with seed/1.
196
197 export_seed_s(State :: state()) -> export_state()
198
199 Returns the random number generator state in an external format.
200 To be used with seed/1.
201
202 jump() -> NewState :: state()
203
204 Returns the state after performing jump calculation to the state
205 in the process dictionary.
206
207 This function generates a not_implemented error exception when
208 the jump function is not implemented for the algorithm specified
209 in the state in the process dictionary.
210
211 jump(State :: state()) -> NewState :: state()
212
213 Returns the state after performing jump calculation to the given
214 state.
215
216 This function generates a not_implemented error exception when
217 the jump function is not implemented for the algorithm specified
218 in the state.
219
220 normal() -> float()
221
222 Returns a standard normal deviate float (that is, the mean is 0
223 and the standard deviation is 1) and updates the state in the
224 process dictionary.
225
226 normal(Mean :: number(), Variance :: number()) -> float()
227
228 Returns a normal N(Mean, Variance) deviate float and updates the
229 state in the process dictionary.
230
231 normal_s(State :: state()) -> {float(), NewState :: state()}
232
233 Returns, for a specified state, a standard normal deviate float
234 (that is, the mean is 0 and the standard deviation is 1) and a
235 new state.
236
237 normal_s(Mean :: number(),
238 Variance :: number(),
239 State0 :: state()) ->
240 {float(), NewS :: state()}
241
242 Returns, for a specified state, a normal N(Mean, Variance) devi‐
243 ate float and a new state.
244
245 seed(AlgOrStateOrExpState ::
246 builtin_alg() | state() | export_state()) ->
247 state()
248
249 Seeds random number generation with the specifed algorithm and
250 time-dependent data if AlgOrStateOrExpState is an algorithm.
251
252 Otherwise recreates the exported seed in the process dictionary,
253 and returns the state. See also export_seed/0.
254
255 seed(Alg :: builtin_alg(),
256 Seed :: {integer(), integer(), integer()}) ->
257 state()
258
259 Seeds random number generation with the specified algorithm and
260 integers in the process dictionary and returns the state.
261
262 seed_s(AlgOrStateOrExpState ::
263 builtin_alg() | state() | export_state()) ->
264 state()
265
266 Seeds random number generation with the specifed algorithm and
267 time-dependent data if AlgOrStateOrExpState is an algorithm.
268
269 Otherwise recreates the exported seed and returns the state. See
270 also export_seed/0.
271
272 seed_s(Alg :: builtin_alg(),
273 Seed :: {integer(), integer(), integer()}) ->
274 state()
275
276 Seeds random number generation with the specified algorithm and
277 integers and returns the state.
278
279 uniform() -> X :: float()
280
281 Returns a random float uniformly distributed in the value range
282 0.0 =< X < 1.0 and updates the state in the process dictionary.
283
284 The generated numbers are on the form N * 2.0^(-53), that is;
285 equally spaced in the interval.
286
287 Warning:
288 This function may return exactly 0.0 which can be fatal for cer‐
289 tain applications. If that is undesired you can use (1.0 -
290 rand:uniform()) to get the interval 0.0 < X =< 1.0.
291
292 If neither endpoint is desired you can test and re-try like
293 this:
294
295 my_uniform() ->
296 case rand:uniform() of
297 0.0 -> my_uniform();
298 X -> X
299 end
300 end.
301
302
303 uniform(N :: integer() >= 1) -> X :: integer() >= 1
304
305 Returns, for a specified integer N >= 1, a random integer uni‐
306 formly distributed in the value range 1 =< X =< N and updates
307 the state in the process dictionary.
308
309 uniform_s(State :: state()) -> {X :: float(), NewState :: state()}
310
311 Returns, for a specified state, random float uniformly distrib‐
312 uted in the value range 0.0 =< X < 1.0 and a new state.
313
314 The generated numbers are on the form N * 2.0^(-53), that is;
315 equally spaced in the interval.
316
317 Warning:
318 This function may return exactly 0.0 which can be fatal for cer‐
319 tain applications. If that is undesired you can use (1.0 -
320 rand:uniform(State)) to get the interval 0.0 < X =< 1.0.
321
322 If neither endpoint is desired you can test and re-try like
323 this:
324
325 my_uniform(State) ->
326 case rand:uniform(State) of
327 {0.0, NewState} -> my_uniform(NewState);
328 Result -> Result
329 end
330 end.
331
332
333 uniform_s(N :: integer() >= 1, State :: state()) ->
334 {X :: integer() >= 1, NewState :: state()}
335
336 Returns, for a specified integer N >= 1 and a state, a random
337 integer uniformly distributed in the value range 1 =< X =< N and
338 a new state.
339
340
341
342Ericsson AB stdlib 3.4.5.1 rand(3)