2 * A C-program for MT19937, with initialization improved 2002/1/26.
3 * Coded by Takuji Nishimura and Makoto Matsumoto.
5 * Before using, initialize the state by using init_genrand(seed)
6 * or init_by_array(init_key, key_length).
8 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials provided
21 * with the distribution.
23 * 3. The names of its contributors may not be used to endorse or
24 * promote products derived from this software without specific
25 * prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38 * OF THE POSSIBILITY OF SUCH DAMAGE.
41 * Any feedback is very welcome.
42 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
43 * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
46 #include "base/random.hh"
48 /* initializes mt[N] with a seed */
50 Random::init(uint32_t s
)
53 mt
[0] = s
& (uint32_t)0xffffffff;
55 for (mti
= 1; mti
< N
; mti
++) {
56 mt
[mti
] = 1812433253UL * (mt
[mti
-1] ^ (mt
[mti
-1] >> 30)) + mti
;
57 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
58 /* In the previous versions, MSBs of the seed affect */
59 /* only MSBs of the array mt[]. */
60 /* 2002/01/09 modified by Makoto Matsumoto */
61 mt
[mti
] &= (uint32_t)0xffffffff;
62 /* for >32 bit machines */
66 /* initialize by an array with array-length */
67 /* init_key is the array for initializing keys */
68 /* key_length is its length */
69 /* slight change for C++, 2004/2/26 */
71 Random::init(uint32_t init_key
[], int key_length
)
75 int k
= (N
> key_length
) ? N
: key_length
;
80 mt
[i
] = (mt
[i
] ^ ((mt
[i
-1] ^ (mt
[i
-1] >> 30)) * (uint32_t)1664525))
81 + init_key
[j
] + j
; /* non linear */
83 mt
[i
] &= 0xffffffffUL
; /* for WORDSIZE > 32 machines */
97 for (k
= N
- 1; k
; k
--) {
99 mt
[i
] = (mt
[i
] ^ ((mt
[i
- 1] ^ (mt
[i
- 1] >> 30)) * 1566083941UL)) - i
;
101 /* for WORDSIZE > 32 machines */
102 mt
[i
] &= (uint32_t)0xffffffff;
111 /* MSB is 1; assuring non-zero initial array */
112 mt
[0] = (uint32_t)0x80000000;
115 /* generates a random number on [0,0xffffffff]-interval */
120 static uint32_t mag01
[2] = { 0, MATRIX_A
};
122 if (mti
>= N
) { /* generate N words at one time */
125 for (kk
= 0; kk
< N
- M
; kk
++) {
126 y
= mt
[kk
] & UPPER_MASK
| mt
[kk
+1] & LOWER_MASK
;
127 mt
[kk
] = mt
[kk
+ M
] ^ (y
>> 1) ^ mag01
[y
& 0x1UL
];
129 for (; kk
< N
- 1; kk
++) {
130 y
= mt
[kk
] & UPPER_MASK
| mt
[kk
+1] & LOWER_MASK
;
131 mt
[kk
] = mt
[kk
+ (M
- N
)] ^ (y
>> 1) ^ mag01
[y
& 0x1UL
];
134 y
= mt
[N
- 1] & UPPER_MASK
| mt
[0] & LOWER_MASK
;
135 mt
[N
- 1] = mt
[M
- 1] ^ (y
>> 1) ^ mag01
[y
& 0x1UL
];
144 y
^= (y
<< 7) & (uint32_t)0x9d2c5680;
145 y
^= (y
<< 15) & (uint32_t)0xefc60000;