1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
use Debug;
use ;
/// # Random Number Generation
///
/// ## Description:
///
/// Implementors of this trait allow for the random generation of numbers. By default, seeds are set
/// by the current time to allow for random and independent numbers, but a seed can be set by the
/// user.
///
/// ## Usage:
///
/// ```rust
/// # use r2rs_nmath::{rng::MarsagliaMulticarry, traits::RNG};
/// let mut rng = MarsagliaMulticarry::new();
/// rng.set_seed(1);
/// let state = rng.get_state();
/// let rand = rng.unif_rand();
/// ```
///
/// ## Details:
///
/// The currently available RNG kinds are given below.
///
/// * *Wichmann-Hill* The seed, ‘.Random.seed\[-1\] == r\[1:3\]’ is an
/// integer vector of length 3, where each ‘r\[i\]’ is in ‘1:(p\[i\]
/// - 1)’, where ‘p’ is the length 3 vector of primes, ‘p =
/// (30269, 30307, 30323)’. The Wichmann-Hill generator has a
/// cycle length of 6.9536e12 (= ‘prod(p-1)/4’, see _Applied
/// Statistics_ (1984) *33*, 123 which corrects the original
/// article). It exhibits 12 clear failures in the TestU01 Crush
/// suite and 22 in the BigCrush suite (_L'Ecuyer_, 2007).
///
/// * *Marsaglia-Multicarry*: A _multiply-with-carry_ RNG is used, as
/// recommended by George Marsaglia in his post to the mailing
/// list ‘sci.stat.math’. It has a period of more than 2^60.
///
/// It exhibits 40 clear failures in L'Ecuyer's TestU01 Crush
/// suite. Combined with Ahrens-Dieter or Kinderman-Ramage it
/// exhibits deviations from normality even for univariate
/// distribution generation. See PR#18168 for a discussion.
///
/// The seed is two integers (all values allowed).
///
/// * *Super-Duper*: Marsaglia's famous Super-Duper from the 70's.
/// This is the original version which does _not_ pass the MTUPLE
/// test of the Diehard battery. It has a period of about
/// 4.6*10^18 for most initial seeds. The seed is two integers
/// (all values allowed for the first seed: the second must be
/// odd).
///
/// We use the implementation by Reeds _et al_ (1982-84).
///
/// The two seeds are the Tausworthe and congruence long
/// integers, respectively. A one-to-one mapping to S's
/// ‘.Random.seed\[1:12\]’ is possible but we will not publish one,
/// not least as this generator is *not* exactly the same as that
/// in recent versions of S-PLUS.
///
/// It exhibits 25 clear failures in the TestU01 Crush suite
/// (_L'Ecuyer_, 2007).
///
/// * *Mersenne-Twister*: From Matsumoto and Nishimura (1998); code
/// updated in 2002. A twisted GFSR with period 2^19937 - 1 and
/// equidistribution in 623 consecutive dimensions (over the
/// whole period). The ‘seed’ is a 624-dimensional set of 32-bit
/// integers plus a current position in that set.
///
/// R uses its own initialization method due to B. D. Ripley and
/// is not affected by the initialization issue in the 1998 code
/// of Matsumoto and Nishimura addressed in a 2002 update.
///
/// It exhibits 2 clear failures in each of the TestU01 Crush and
/// the BigCrush suite (_L'Ecuyer_, 2007).
///
/// * *L'Ecuyer-CMRG*: A ‘combined multiple-recursive generator’ from
/// L'Ecuyer (1999), each element of which is a feedback
/// multiplicative generator with three integer elements: thus
/// the seed is a (signed) integer vector of length 6. The period
/// is around 2^191.
///
/// The 6 elements of the seed are internally regarded as 32-bit
/// unsigned integers. Neither the first three nor the last
/// three should be all zero, and they are limited to less than
/// ‘4294967087’ and ‘4294944443’ respectively.
///
/// This is not particularly interesting of itself, but provides
/// the basis for the multiple streams used in package
/// ‘parallel’.
///
/// It exhibits 6 clear failures in each of the TestU01 Crush and
/// the BigCrush suite (_L'Ecuyer_, 2007).
///
/// ## Note:
///
/// Initially, there is no seed; a new one is created from the current
/// time. Hence, different sessions will give different simulation results, by default.
/// However, the seed might be restored from a previous session if a
/// previously saved workspace is restored.
///
/// Do not rely on randomness of low-order bits from RNGs. Most of
/// the supplied uniform generators return 32-bit integer values that
/// are converted to doubles, so they take at most 2^32 distinct
/// values and long runs will return duplicated values (Wichmann-Hill
/// is the exception, and all give at least 30 varying bits.)
///
/// ## Author(s):
///
/// of RNGkind: Martin Maechler. Current implementation, B. D. Ripley
/// with modifications by Duncan Murdoch.
///
/// ## References:
///
/// Ahrens, J. H. and Dieter, U. (1973). Extensions of Forsythe's
/// method for random sampling from the normal distribution.
/// _Mathematics of Computation_, *27*, 927-937.
///
/// Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988). _The New
/// S Language_. Wadsworth & Brooks/Cole. (‘set.seed’, storing in
/// ‘.Random.seed’.)
///
/// Box, G. E. P. and Muller, M. E. (1958). A note on the generation
/// of normal random deviates. _Annals of Mathematical Statistics_,
/// *29*, 610-611. doi:10.1214/aoms/1177706645
/// <https://doi.org/10.1214/aoms/1177706645>.
///
/// De Matteis, A. and Pagnutti, S. (1993). Long-range Correlation
/// Analysis of the Wichmann-Hill Random Number Generator.
/// _Statistics and Computing_, *3*, 67-70. doi:10.1007/BF00153065
/// <https://doi.org/10.1007/BF00153065>.
///
/// Kinderman, A. J. and Ramage, J. G. (1976). Computer generation of
/// normal random variables. _Journal of the American Statistical
/// Association_, *71*, 893-896. doi:10.2307/2286857
/// <https://doi.org/10.2307/2286857>.
///
/// Knuth, D. E. (1997). _The Art of Computer Programming_. Volume
/// 2, third edition.
/// Source code at
/// <https://www-cs-faculty.stanford.edu/~knuth/taocp.html>.
///
/// Knuth, D. E. (2002). _The Art of Computer Programming_. Volume
/// 2, third edition, ninth printing.
///
/// L'Ecuyer, P. (1999). Good parameters and implementations for
/// combined multiple recursive random number generators. _Operations
/// Research_, *47*, 159-164. doi:10.1287/opre.47.1.159
/// <https://doi.org/10.1287/opre.47.1.159>.
///
/// L'Ecuyer, P. and Simard, R. (2007). TestU01: A C Library for
/// Empirical Testing of Random Number Generators _ACM Transactions on
/// Mathematical Software_, *33*, Article 22.
/// doi:10.1145/1268776.1268777
/// <https://doi.org/10.1145/1268776.1268777>.
///
/// The TestU01 C library is available from
/// <http://simul.iro.umontreal.ca/testu01/tu01.html> or also
/// <https://github.com/umontreal-simul/TestU01-2009>.
///
/// Marsaglia, G. (1997). _A random number generator for C_.
/// Discussion paper, posting on Usenet newsgroup ‘sci.stat.math’ on
/// September 29, 1997.
///
/// Marsaglia, G. and Zaman, A. (1994). Some portable
/// very-long-period random number generators. _Computers in
/// Physics_, *8*, 117-121. doi:10.1063/1.168514
/// <https://doi.org/10.1063/1.168514>.
///
/// Matsumoto, M. and Nishimura, T. (1998). Mersenne Twister: A
/// 623-dimensionally equidistributed uniform pseudo-random number
/// generator, _ACM Transactions on Modeling and Computer Simulation_,
/// *8*, 3-30.
/// Source code formerly at
/// ‘http://www.math.keio.ac.jp/~matumoto/emt.html’.
/// Now see
/// <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/c-lang.html>.
///
/// Reeds, J., Hubert, S. and Abrahams, M. (1982-4). C implementation
/// of SuperDuper, University of California at Berkeley. (Personal
/// communication from Jim Reeds to Ross Ihaka.)
///
/// Wichmann, B. A. and Hill, I. D. (1982). Algorithm AS 183: An
/// Efficient and Portable Pseudo-random Number Generator. _Applied
/// Statistics_, *31*, 188-190; Remarks: *34*, 198 and *35*, 89.
/// doi:10.2307/2347988 <https://doi.org/10.2307/2347988>.
///
/// ## Examples:
///
/// ```rust
/// # use r2rs_nmath::{rng::MarsagliaMulticarry, traits::RNG};
/// // Seed the current RNG, i.e., set the RNG status
/// let mut rng = MarsagliaMulticarry::new();
/// rng.set_seed(42);
/// let u1 = (0..30).map(|_| rng.unif_rand()).collect::<Vec<_>>();
///
/// rng.set_seed(42);
/// let u2 = (0..30).map(|_| rng.unif_rand()).collect::<Vec<_>>();
///
/// // These are the same because of identical RNG status
/// assert_eq!(u1, u2);
/// ```
///
/// ```rust
/// # use r2rs_nmath::{
/// # rng::{MarsagliaMulticarry, SuperDuper},
/// # traits::RNG,
/// # };
/// // Seed the current RNG, i.e., set the RNG status
/// let mut rng1 = MarsagliaMulticarry::new();
/// rng1.set_seed(42);
/// let u1 = (0..30).map(|_| rng1.unif_rand()).collect::<Vec<_>>();
///
/// let mut rng2 = SuperDuper::new();
/// rng2.set_seed(42);
/// let u2 = (0..30).map(|_| rng2.unif_rand()).collect::<Vec<_>>();
///
/// // These are different because of different RNG generators
/// assert_ne!(u1, u2);
/// ```