rand_python/
mersenne_twister.rs

1/*
2   Rust port of the original mt19937ar Mersenne Twister.
3
4   Porting, additional comments and documentation by Ronald Volgers.
5
6   The original copyright notice and BSD 3-clause license is reproduced below.
7
8   ---
9
10   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
11   All rights reserved.
12
13   Redistribution and use in source and binary forms, with or without
14   modification, are permitted provided that the following conditions
15   are met:
16
17     1. Redistributions of source code must retain the above copyright
18        notice, this list of conditions and the following disclaimer.
19
20     2. Redistributions in binary form must reproduce the above copyright
21        notice, this list of conditions and the following disclaimer in the
22        documentation and/or other materials provided with the distribution.
23
24     3. The names of its contributors may not be used to endorse or promote
25        products derived from this software without specific prior written
26        permission.
27
28   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
35   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41use std::cmp::max;
42use std::fmt;
43
44const N: usize = 624;
45const M: usize = 397;
46const MATRIX_A: u32 = 0x9908b0df;
47const UPPER_MASK: u32 = 0x80000000;
48const LOWER_MASK: u32 = 0x7fffffff;
49
50/// `self.index` is set to this value after seeding. It is also encountered during normal
51/// operation, when a block of random numbers has been consumed and `genrand_int32` needs
52/// to generate a new one before returning the next random number.
53const INITIAL_INDEX: usize = N;
54
55/// `self.index` is set to this value at creation time. It indicates the random number
56/// generator has not been seeded. If this value is encountered when trying to generate
57/// a random number, the implementation will panic.
58const UNSEEDED_INDEX: usize = N + 1;
59
60/// Implementation of [Mersenne Twister] (`mt19937ar`).
61///
62/// This is a direct Rust port of the C implementation known as [`mt19937ar.c`].
63///
64/// It tries to stay as close as possible to the original in terms of function naming
65/// and overall interface. This makes it easier to port libraries that use the Mersenne
66/// Twister internally.
67///
68/// The code remains functionally the same but has been cleaned up and re-commented
69/// to reflect my own understanding of the original code and algorithm. Some comments from
70/// the original have been omitted. Errors are mine.
71///
72/// [Mersenne Twister]: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
73/// [`mt19937ar.c`]: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
74#[derive(Clone)]
75pub struct MersenneTwister {
76    index: usize,
77    state: [u32; N],
78}
79
80impl fmt::Debug for MersenneTwister {
81    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
82        fmt.debug_struct("MersenneTwister")
83            .field("index", &self.index)
84            .field("state", &&self.state[..])
85            .finish()
86    }
87}
88
89impl MersenneTwister {
90    /// Creates a new, unseeded random number generator.
91    ///
92    /// Seed it using [`init_by_array`], [`init_genrand`], or the deprecated and buggy
93    /// [`sgenrand`].
94    ///
95    /// Trying to generate random numbers without seeding will cause a panic.
96    /// The upstream implementation automatically seeds the generator using a hardcoded
97    /// seed instead. To use that seed, you can manually call `init_genrand(5489)`.
98    ///
99    /// [`init_by_array`]: #method.init_by_array
100    /// [`init_genrand`]: #method.init_genrand
101    /// [`sgenrand`]: #method.sgenrand
102    pub fn new() -> MersenneTwister {
103        MersenneTwister {
104            index: UNSEEDED_INDEX,
105            state: [0; N],
106        }
107    }
108
109    /// This is the core random number generation function that all the others are
110    /// based on.
111    ///
112    /// It generates a random `u32` value.
113    pub fn genrand_int32(&mut self) -> u32 {
114
115        let mt = &mut self.state;
116
117        if self.index >= N {
118
119            // This deviates from the original implementation, which will simply call
120            // init_genrand(5489) in this situation instead.
121            assert!(self.index != UNSEEDED_INDEX,
122                "random number generator must be seeded before use");
123
124            #[cfg(feature = "prefetch")]
125            #[cfg(target_feature = "sse")]
126            unsafe {
127                // 64 is min possible cache line size
128                for i in (0..N).step_by(64) {
129                    core::arch::x86_64::_mm_prefetch((mt as *const _ as *const i8).add(i), core::arch::x86_64::_MM_HINT_T2);
130                }
131            }
132
133            // Produce an entire block of outputs at once.
134            // The calculation for each entry is the same, but the loop is split into
135            // three separate parts according to which indexing calculations will wrap,
136            // to avoid needing modulo operations or conditionals in the loop itself.
137
138            // Process initial items, where kk+M and kk+1 both don't wrap
139            for kk in 0..(N - M) {
140                let y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
141                mt[kk] = mt[kk + M] ^ (y >> 1) ^ ((y & 1) * MATRIX_A);
142            }
143
144            // Process next items, where kk+M wraps but kk+1 doesn't
145            for kk in (N - M)..(N - 1) {
146                let y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
147                mt[kk] = mt[kk + M - N] ^ (y >> 1) ^ ((y & 1) * MATRIX_A);
148            }
149
150            // Process final item, where both kk+M and kk+1 wrap
151            let kk = N - 1;
152            let y = (mt[kk] & UPPER_MASK) | (mt[kk + 1 - N] & LOWER_MASK);
153            mt[kk] = mt[kk + M - N] ^ (y >> 1) ^ ((y & 1) * MATRIX_A);
154
155            self.index = 0;
156        }
157
158        let y = mt[self.index];
159        self.index += 1;
160
161        // This is the "tempering" operation to improve the distribution of bits in
162        // the output. This transformation is *not* intended to prevent recovery of
163        // the state from the output; in fact this transformation is fully invertible
164        // so it does nothing to prevent that.
165        let mut y = y;
166        y ^= y >> 11;
167        y ^= (y << 7) & 0x9d2c5680;
168        y ^= (y << 15) & 0xefc60000;
169        y ^= y >> 18;
170        y
171    }
172
173    /// Reset the random number generator with a seed of arbitary length.
174    ///
175    /// The seed is specified as a slice of `u32` values. It cannot be specified as an
176    /// iterator because if the seed is shorter than 624 values each value may
177    /// be accessed more than once.
178    pub fn init_by_array(&mut self, init_key: &[u32]) {
179
180        // Reset self.state to some decently varied constant data.
181        // This also sets self.index = N, which ensures that genrand_int32 will run
182        // its random number generation loop when it is called for the first time
183        // after seeding.
184        self.init_genrand(19650218);
185
186        let mt = &mut self.state;
187
188        // Cycles through 1..N, which has length N-1, not N.
189        // The zero index is "skipped over" and handled specially.
190        let mut i: usize = 1;
191
192        // Cycles through the valid indices of init_key.
193        let mut j: usize = 0;
194
195        for _ in 0..max(N, init_key.len()) {
196            let prev = mt[i - 1] ^ (mt[i - 1] >> 30);
197            mt[i] = (mt[i] ^ prev.wrapping_mul(1664525))
198                .wrapping_add(init_key[j])
199                .wrapping_add(j as u32);
200
201            i += 1;
202            if i >= N {
203                mt[0] = mt[N - 1];
204                i = 1;
205            }
206
207            j += 1;
208            if j >= init_key.len() {
209                j = 0;
210            }
211        }
212
213        for _ in 0..(N - 1) {
214            let prev = mt[i - 1] ^ (mt[i - 1] >> 30);
215            mt[i] = (mt[i] ^ prev.wrapping_mul(1566083941))
216                .wrapping_sub(i as u32);
217
218            i += 1;
219            if i >= N {
220                mt[0] = mt[N - 1];
221                i = 1;
222            }
223        }
224
225        mt[0] = 0x80000000;
226    }
227
228    /// Reset the random number generator using a single 32 bit seed.
229    ///
230    /// This is generally not recommended since it means all future output
231    /// of the random number generator can be reproduced by knowing, guessing,
232    /// or accidentally picking the same 32 bit seed value.
233    ///
234    /// If you want to seed the random number generator with more than 32 bits
235    /// of data, see [`init_by_array`].
236    ///
237    /// [`init_by_array`]: #method.init_by_array
238    pub fn init_genrand(&mut self, s: u32) {
239
240        let mt = &mut self.state;
241
242        mt[0] = s;
243
244        for i in 1..N {
245            let prev = mt[i - 1] ^ (mt[i - 1] >> 30);
246            mt[i] = prev.wrapping_mul(1812433253)
247                .wrapping_add(i as u32);
248        }
249
250        self.index = INITIAL_INDEX;  // == N
251    }
252
253    /// Generates a random `value: f64` such that `0. <= value && value < 1.`,
254    /// using 53 bits of randomness (the maximum possible for a `f64` value).
255    pub fn genrand_res53(&mut self) -> f64 {
256
257        let a = self.genrand_int32() >> 5;  // 32 - 5 = 27 bits
258        let b = self.genrand_int32() >> 6;  // 32 - 6 = 26 bits
259
260        // This is essentially doing ((a << 26) + b) / 2**53, but combining
261        // a and b is done in floating point because on 32 bits systems the
262        // CPU often has native support for f64 but not u64.
263
264        // Combining a and b in a u64 instead of a f64 is about 25% faster in
265        // my testing, but changing anything about the generation of floating
266        // point numbers is extremely risky since even the smallest change
267        // can cause a number to be rounded up instead of down or vice versa
268        // in downstream calculations. So, let's just do it the way the original
269        // implementation does.
270
271        // Likewise, the multiplication-by-reciprocal instead of division is
272        // how it's done in the original code.
273
274        // 2**26 == 67108864
275        // 2**53 == 9007199254740992
276        (a as f64 * 67108864.0 + b as f64) * (1.0 / 9007199254740992.0)
277    }
278
279    /// Generates a random `value: i32` such that `0 <= value && value <= 0x7fffffff`.
280    ///
281    /// If you want a `u32`, see [`genrand_int32`].
282    ///
283    /// [`genrand_int32`]: #method.genrand_int32
284    pub fn genrand_int31(&mut self) -> i32 {
285        (self.genrand_int32() >> 1) as i32
286    }
287
288    /// Generates a random `value: f64` such that `0. <= value && value <= 1.`,
289    /// using 32 bits worth of randomness.
290    ///
291    /// If you want `value < 1` instead of `value <= 1`, see [`genrand_real2`]
292    /// (or [`genrand_res53`] if you also want the maximum amount of randomness).
293    ///
294    /// [`genrand_real2`]: #method.genrand_real2
295    /// [`genrand_res53`]: #method.genrand_res53
296    pub fn genrand_real1(&mut self) -> f64 {
297        // 4294967295 == 2**32 - 1
298        self.genrand_int32() as f64 / 4294967295.0
299    }
300
301    /// Generates a random `value: f64` such that `0. <= value && value < 1.`,
302    /// using 32 bits of randomness.
303    ///
304    /// If you want the maximum amount of randomness, see [`genrand_res53`].
305    ///
306    /// [`genrand_res53`]: #method.genrand_res53
307    pub fn genrand_real2(&mut self) -> f64 {
308        // 4294967296 == 2**32
309        self.genrand_int32() as f64 / 4294967296.0
310    }
311
312    /// Generates a random `value: f64` such that `0. < value && value < 1.`,
313    /// using 32 bits of randomness.
314    ///
315    /// If you want `0 <= value` instead of `0 < value`, see [`genrand_real2`]
316    /// (or [`genrand_res53`] if you also want the maximum amount of randomness).
317    ///
318    /// [`genrand_real2`]: #method.genrand_real2
319    /// [`genrand_res53`]: #method.genrand_res53
320    pub fn genrand_real3(&mut self) -> f64 {
321        // 4294967296 == 2**32
322        (self.genrand_int32() as f64 + 0.5) / 4294967296.0
323    }
324
325    /// Reset the random number generator using a single 32 bit seed.
326    ///
327    /// This old seed function can cause very poor quality random numbers and
328    /// is mainly included for historical purposes. It is only present in older
329    /// versions of the Mersenne Twister code base, not the `mt19937ar` version
330    /// this module is based on.
331    ///
332    /// Most software uses [`init_by_array`] or [`init_genrand`] instead, which were
333    /// introduced in the `mt19937ar` version.
334    ///
335    /// [`init_by_array`]: #method.init_by_array
336    /// [`init_genrand`]: #method.init_getrand
337    #[deprecated = "Can lead to very poor quality random numbers. \
338                    Use `init_by_array` or `init_genrand` instead."]
339    pub fn sgenrand(&mut self, seed: u32) {
340
341        let mt = &mut self.state;
342
343        mt[0] = seed;
344
345        for i in 1..N {
346            mt[i] = mt[i - 1].wrapping_mul(69069);
347        }
348
349    }
350
351}