Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/random/mersenne_twister.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
6 * accompanying file LICENSE_1_0.txt or copy at | 6 * accompanying file LICENSE_1_0.txt or copy at |
7 * http://www.boost.org/LICENSE_1_0.txt) | 7 * http://www.boost.org/LICENSE_1_0.txt) |
8 * | 8 * |
9 * See http://www.boost.org for most recent version including documentation. | 9 * See http://www.boost.org for most recent version including documentation. |
10 * | 10 * |
11 * $Id: mersenne_twister.hpp 74867 2011-10-09 23:13:31Z steven_watanabe $ | 11 * $Id$ |
12 * | 12 * |
13 * Revision history | 13 * Revision history |
14 * 2013-10-14 fixed some warnings with Wshadow (mgaunard) | |
14 * 2001-02-18 moved to individual header files | 15 * 2001-02-18 moved to individual header files |
15 */ | 16 */ |
16 | 17 |
17 #ifndef BOOST_RANDOM_MERSENNE_TWISTER_HPP | 18 #ifndef BOOST_RANDOM_MERSENNE_TWISTER_HPP |
18 #define BOOST_RANDOM_MERSENNE_TWISTER_HPP | 19 #define BOOST_RANDOM_MERSENNE_TWISTER_HPP |
26 #include <boost/random/detail/config.hpp> | 27 #include <boost/random/detail/config.hpp> |
27 #include <boost/random/detail/ptr_helper.hpp> | 28 #include <boost/random/detail/ptr_helper.hpp> |
28 #include <boost/random/detail/seed.hpp> | 29 #include <boost/random/detail/seed.hpp> |
29 #include <boost/random/detail/seed_impl.hpp> | 30 #include <boost/random/detail/seed_impl.hpp> |
30 #include <boost/random/detail/generator_seed_seq.hpp> | 31 #include <boost/random/detail/generator_seed_seq.hpp> |
32 #include <boost/random/detail/polynomial.hpp> | |
33 | |
34 #include <boost/random/detail/disable_warnings.hpp> | |
31 | 35 |
32 namespace boost { | 36 namespace boost { |
33 namespace random { | 37 namespace random { |
34 | 38 |
35 /** | 39 /** |
38 * | 42 * |
39 * @blockquote | 43 * @blockquote |
40 * "Mersenne Twister: A 623-dimensionally equidistributed uniform | 44 * "Mersenne Twister: A 623-dimensionally equidistributed uniform |
41 * pseudo-random number generator", Makoto Matsumoto and Takuji Nishimura, | 45 * pseudo-random number generator", Makoto Matsumoto and Takuji Nishimura, |
42 * ACM Transactions on Modeling and Computer Simulation: Special Issue on | 46 * ACM Transactions on Modeling and Computer Simulation: Special Issue on |
43 * Uniform Random Number Generation, Vol. 8, No. 1, January 1998, pp. 3-30. | 47 * Uniform Random Number Generation, Vol. 8, No. 1, January 1998, pp. 3-30. |
44 * @endblockquote | 48 * @endblockquote |
45 * | 49 * |
46 * @xmlnote | 50 * @xmlnote |
47 * The boost variant has been implemented from scratch and does not | 51 * The boost variant has been implemented from scratch and does not |
48 * derive from or use mt19937.c provided on the above WWW site. However, it | 52 * derive from or use mt19937.c provided on the above WWW site. However, it |
49 * was verified that both produce identical output. | 53 * was verified that both produce identical output. |
50 * @endxmlnote | 54 * @endxmlnote |
51 * | 55 * |
52 * The seeding from an integer was changed in April 2005 to address a | 56 * The seeding from an integer was changed in April 2005 to address a |
53 * <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html">weakness</a>. | 57 * <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html">weakness</a>. |
54 * | 58 * |
55 * The quality of the generator crucially depends on the choice of the | 59 * The quality of the generator crucially depends on the choice of the |
56 * parameters. User code should employ one of the sensibly parameterized | 60 * parameters. User code should employ one of the sensibly parameterized |
57 * generators such as \mt19937 instead. | 61 * generators such as \mt19937 instead. |
58 * | 62 * |
59 * The generator requires considerable amounts of memory for the storage of | 63 * The generator requires considerable amounts of memory for the storage of |
81 BOOST_STATIC_CONSTANT(std::size_t, tempering_t = t); | 85 BOOST_STATIC_CONSTANT(std::size_t, tempering_t = t); |
82 BOOST_STATIC_CONSTANT(UIntType, tempering_c = c); | 86 BOOST_STATIC_CONSTANT(UIntType, tempering_c = c); |
83 BOOST_STATIC_CONSTANT(std::size_t, tempering_l = l); | 87 BOOST_STATIC_CONSTANT(std::size_t, tempering_l = l); |
84 BOOST_STATIC_CONSTANT(UIntType, initialization_multiplier = f); | 88 BOOST_STATIC_CONSTANT(UIntType, initialization_multiplier = f); |
85 BOOST_STATIC_CONSTANT(UIntType, default_seed = 5489u); | 89 BOOST_STATIC_CONSTANT(UIntType, default_seed = 5489u); |
86 | 90 |
87 // backwards compatibility | 91 // backwards compatibility |
88 BOOST_STATIC_CONSTANT(UIntType, parameter_a = a); | 92 BOOST_STATIC_CONSTANT(UIntType, parameter_a = a); |
89 BOOST_STATIC_CONSTANT(std::size_t, output_u = u); | 93 BOOST_STATIC_CONSTANT(std::size_t, output_u = u); |
90 BOOST_STATIC_CONSTANT(std::size_t, output_s = s); | 94 BOOST_STATIC_CONSTANT(std::size_t, output_s = s); |
91 BOOST_STATIC_CONSTANT(UIntType, output_b = b); | 95 BOOST_STATIC_CONSTANT(UIntType, output_b = b); |
92 BOOST_STATIC_CONSTANT(std::size_t, output_t = t); | 96 BOOST_STATIC_CONSTANT(std::size_t, output_t = t); |
93 BOOST_STATIC_CONSTANT(UIntType, output_c = c); | 97 BOOST_STATIC_CONSTANT(UIntType, output_c = c); |
94 BOOST_STATIC_CONSTANT(std::size_t, output_l = l); | 98 BOOST_STATIC_CONSTANT(std::size_t, output_l = l); |
95 | 99 |
96 // old Boost.Random concept requirements | 100 // old Boost.Random concept requirements |
97 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); | 101 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); |
98 | 102 |
99 | 103 |
100 /** | 104 /** |
134 * (i + f * (x(i-1) xor (x(i-1) rshift w-2))) mod 2<sup>w</sup> | 138 * (i + f * (x(i-1) xor (x(i-1) rshift w-2))) mod 2<sup>w</sup> |
135 * for i = 1 .. n-1. x(n) is the first value to be returned by operator(). | 139 * for i = 1 .. n-1. x(n) is the first value to be returned by operator(). |
136 */ | 140 */ |
137 BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister_engine, UIntType, value) | 141 BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister_engine, UIntType, value) |
138 { | 142 { |
139 // New seeding algorithm from | 143 // New seeding algorithm from |
140 // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html | 144 // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html |
141 // In the previous versions, MSBs of the seed affected only MSBs of the | 145 // In the previous versions, MSBs of the seed affected only MSBs of the |
142 // state x[]. | 146 // state x[]. |
143 const UIntType mask = (max)(); | 147 const UIntType mask = (max)(); |
144 x[0] = value & mask; | 148 x[0] = value & mask; |
145 for (i = 1; i < n; i++) { | 149 for (i = 1; i < n; i++) { |
146 // See Knuth "The Art of Computer Programming" | 150 // See Knuth "The Art of Computer Programming" |
147 // Vol. 2, 3rd ed., page 106 | 151 // Vol. 2, 3rd ed., page 106 |
148 x[i] = (f * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask; | 152 x[i] = (f * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask; |
149 } | 153 } |
150 } | 154 |
151 | 155 normalize_state(); |
156 } | |
157 | |
152 /** | 158 /** |
153 * Seeds a mersenne_twister_engine using values produced by seq.generate(). | 159 * Seeds a mersenne_twister_engine using values produced by seq.generate(). |
154 */ | 160 */ |
155 BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(mersenne_twister_engine, SeeqSeq, seq) | 161 BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(mersenne_twister_engine, SeeqSeq, seq) |
156 { | 162 { |
157 detail::seed_array_int<w>(seq, x); | 163 detail::seed_array_int<w>(seq, x); |
158 i = n; | 164 i = n; |
159 | 165 |
160 // fix up the state if it's all zeroes. | 166 normalize_state(); |
161 if((x[0] & (~static_cast<UIntType>(0) << r)) == 0) { | |
162 for(std::size_t j = 1; j < n; ++j) { | |
163 if(x[j] != 0) return; | |
164 } | |
165 x[0] = static_cast<UIntType>(1) << (w-1); | |
166 } | |
167 } | 167 } |
168 | 168 |
169 /** Sets the state of the generator using values from an iterator range. */ | 169 /** Sets the state of the generator using values from an iterator range. */ |
170 template<class It> | 170 template<class It> |
171 void seed(It& first, It last) | 171 void seed(It& first, It last) |
172 { | 172 { |
173 detail::fill_array_int<w>(first, last, x); | 173 detail::fill_array_int<w>(first, last, x); |
174 i = n; | 174 i = n; |
175 | 175 |
176 // fix up the state if it's all zeroes. | 176 normalize_state(); |
177 if((x[0] & (~static_cast<UIntType>(0) << r)) == 0) { | 177 } |
178 for(std::size_t j = 1; j < n; ++j) { | 178 |
179 if(x[j] != 0) return; | |
180 } | |
181 x[0] = static_cast<UIntType>(1) << (w-1); | |
182 } | |
183 } | |
184 | |
185 /** Returns the smallest value that the generator can produce. */ | 179 /** Returns the smallest value that the generator can produce. */ |
186 static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () | 180 static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () |
187 { return 0; } | 181 { return 0; } |
188 /** Returns the largest value that the generator can produce. */ | 182 /** Returns the largest value that the generator can produce. */ |
189 static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () | 183 static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () |
190 { return boost::low_bits_mask_t<w>::sig_bits; } | 184 { return boost::low_bits_mask_t<w>::sig_bits; } |
191 | 185 |
192 /** Produces the next value of the generator. */ | 186 /** Produces the next value of the generator. */ |
193 result_type operator()(); | 187 result_type operator()(); |
194 | 188 |
195 /** Fills a range with random values */ | 189 /** Fills a range with random values */ |
196 template<class Iter> | 190 template<class Iter> |
206 * } | 200 * } |
207 * @endcode | 201 * @endcode |
208 */ | 202 */ |
209 void discard(boost::uintmax_t z) | 203 void discard(boost::uintmax_t z) |
210 { | 204 { |
211 for(boost::uintmax_t j = 0; j < z; ++j) { | 205 #ifndef BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD |
212 (*this)(); | 206 #define BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD 10000000 |
207 #endif | |
208 if(z > BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD) { | |
209 discard_many(z); | |
210 } else { | |
211 for(boost::uintmax_t j = 0; j < z; ++j) { | |
212 (*this)(); | |
213 } | |
213 } | 214 } |
214 } | 215 } |
215 | 216 |
216 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS | 217 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS |
217 /** Writes a mersenne_twister_engine to a @c std::ostream */ | 218 /** Writes a mersenne_twister_engine to a @c std::ostream */ |
221 const mersenne_twister_engine& mt) | 222 const mersenne_twister_engine& mt) |
222 { | 223 { |
223 mt.print(os); | 224 mt.print(os); |
224 return os; | 225 return os; |
225 } | 226 } |
226 | 227 |
227 /** Reads a mersenne_twister_engine from a @c std::istream */ | 228 /** Reads a mersenne_twister_engine from a @c std::istream */ |
228 template<class CharT, class Traits> | 229 template<class CharT, class Traits> |
229 friend std::basic_istream<CharT,Traits>& | 230 friend std::basic_istream<CharT,Traits>& |
230 operator>>(std::basic_istream<CharT,Traits>& is, | 231 operator>>(std::basic_istream<CharT,Traits>& is, |
231 mersenne_twister_engine& mt) | 232 mersenne_twister_engine& mt) |
242 | 243 |
243 /** | 244 /** |
244 * Returns true if the two generators are in the same state, | 245 * Returns true if the two generators are in the same state, |
245 * and will thus produce identical sequences. | 246 * and will thus produce identical sequences. |
246 */ | 247 */ |
247 friend bool operator==(const mersenne_twister_engine& x, | 248 friend bool operator==(const mersenne_twister_engine& x_, |
248 const mersenne_twister_engine& y) | 249 const mersenne_twister_engine& y_) |
249 { | 250 { |
250 if(x.i < y.i) return x.equal_imp(y); | 251 if(x_.i < y_.i) return x_.equal_imp(y_); |
251 else return y.equal_imp(x); | 252 else return y_.equal_imp(x_); |
252 } | 253 } |
253 | 254 |
254 /** | 255 /** |
255 * Returns true if the two generators are in different states. | 256 * Returns true if the two generators are in different states. |
256 */ | 257 */ |
257 friend bool operator!=(const mersenne_twister_engine& x, | 258 friend bool operator!=(const mersenne_twister_engine& x_, |
258 const mersenne_twister_engine& y) | 259 const mersenne_twister_engine& y_) |
259 { return !(x == y); } | 260 { return !(x_ == y_); } |
260 | 261 |
261 private: | 262 private: |
262 /// \cond show_private | 263 /// \cond show_private |
263 | 264 |
264 void twist(); | 265 void twist(); |
331 y0 = y1; | 332 y0 = y1; |
332 } | 333 } |
333 } | 334 } |
334 | 335 |
335 /** | 336 /** |
337 * Converts an arbitrary array into a valid generator state. | |
338 * First we normalize x[0], so that it contains the same | |
339 * value we would get by running the generator forwards | |
340 * and then in reverse. (The low order r bits are redundant). | |
341 * Then, if the state consists of all zeros, we set the | |
342 * high order bit of x[0] to 1. This function only needs to | |
343 * be called by seed, since the state transform preserves | |
344 * this relationship. | |
345 */ | |
346 void normalize_state() | |
347 { | |
348 const UIntType upper_mask = (~static_cast<UIntType>(0)) << r; | |
349 const UIntType lower_mask = ~upper_mask; | |
350 UIntType y0 = x[m-1] ^ x[n-1]; | |
351 if(y0 & (static_cast<UIntType>(1) << (w-1))) { | |
352 y0 = ((y0 ^ a) << 1) | 1; | |
353 } else { | |
354 y0 = y0 << 1; | |
355 } | |
356 x[0] = (x[0] & upper_mask) | (y0 & lower_mask); | |
357 | |
358 // fix up the state if it's all zeroes. | |
359 for(std::size_t j = 0; j < n; ++j) { | |
360 if(x[j] != 0) return; | |
361 } | |
362 x[0] = static_cast<UIntType>(1) << (w-1); | |
363 } | |
364 | |
365 /** | |
336 * Given a pointer to the last element of the rewind array, | 366 * Given a pointer to the last element of the rewind array, |
337 * and the current size of the rewind array, finds an element | 367 * and the current size of the rewind array, finds an element |
338 * relative to the next available slot in the rewind array. | 368 * relative to the next available slot in the rewind array. |
339 */ | 369 */ |
340 UIntType | 370 UIntType |
346 } else { | 376 } else { |
347 return *(last - (n - 1 - index)); | 377 return *(last - (n - 1 - index)); |
348 } | 378 } |
349 } | 379 } |
350 | 380 |
381 /** | |
382 * Optimized algorithm for large jumps. | |
383 * | |
384 * Hiroshi Haramoto, Makoto Matsumoto, and Pierre L'Ecuyer. 2008. | |
385 * A Fast Jump Ahead Algorithm for Linear Recurrences in a Polynomial | |
386 * Space. In Proceedings of the 5th international conference on | |
387 * Sequences and Their Applications (SETA '08). | |
388 * DOI=10.1007/978-3-540-85912-3_26 | |
389 */ | |
390 void discard_many(boost::uintmax_t z) | |
391 { | |
392 // Compute the minimal polynomial, phi(t) | |
393 // This depends only on the transition function, | |
394 // which is constant. The characteristic | |
395 // polynomial is the same as the minimal | |
396 // polynomial for a maximum period generator | |
397 // (which should be all specializations of | |
398 // mersenne_twister.) Even if it weren't, | |
399 // the characteristic polynomial is guaranteed | |
400 // to be a multiple of the minimal polynomial, | |
401 // which is good enough. | |
402 detail::polynomial phi = get_characteristic_polynomial(); | |
403 | |
404 // calculate g(t) = t^z % phi(t) | |
405 detail::polynomial g = mod_pow_x(z, phi); | |
406 | |
407 // h(s_0, t) = \sum_{i=0}^{2k-1}o(s_i)t^{2k-i-1} | |
408 detail::polynomial h; | |
409 const std::size_t num_bits = w*n - r; | |
410 for(std::size_t j = 0; j < num_bits * 2; ++j) { | |
411 // Yes, we're advancing the generator state | |
412 // here, but it doesn't matter because | |
413 // we're going to overwrite it completely | |
414 // in reconstruct_state. | |
415 if(i >= n) twist(); | |
416 h[2*num_bits - j - 1] = x[i++] & UIntType(1); | |
417 } | |
418 // g(t)h(s_0, t) | |
419 detail::polynomial gh = g * h; | |
420 detail::polynomial result; | |
421 for(std::size_t j = 0; j <= num_bits; ++j) { | |
422 result[j] = gh[2*num_bits - j - 1]; | |
423 } | |
424 reconstruct_state(result); | |
425 } | |
426 static detail::polynomial get_characteristic_polynomial() | |
427 { | |
428 const std::size_t num_bits = w*n - r; | |
429 detail::polynomial helper; | |
430 helper[num_bits - 1] = 1; | |
431 mersenne_twister_engine tmp; | |
432 tmp.reconstruct_state(helper); | |
433 // Skip the first num_bits elements, since we | |
434 // already know what they are. | |
435 for(std::size_t j = 0; j < num_bits; ++j) { | |
436 if(tmp.i >= n) tmp.twist(); | |
437 if(j == num_bits - 1) | |
438 assert((tmp.x[tmp.i] & 1) == 1); | |
439 else | |
440 assert((tmp.x[tmp.i] & 1) == 0); | |
441 ++tmp.i; | |
442 } | |
443 detail::polynomial phi; | |
444 phi[num_bits] = 1; | |
445 detail::polynomial next_bits = tmp.as_polynomial(num_bits); | |
446 for(std::size_t j = 0; j < num_bits; ++j) { | |
447 int val = next_bits[j] ^ phi[num_bits-j-1]; | |
448 phi[num_bits-j-1] = val; | |
449 if(val) { | |
450 for(std::size_t k = j + 1; k < num_bits; ++k) { | |
451 phi[num_bits-k-1] ^= next_bits[k-j-1]; | |
452 } | |
453 } | |
454 } | |
455 return phi; | |
456 } | |
457 detail::polynomial as_polynomial(std::size_t size) { | |
458 detail::polynomial result; | |
459 for(std::size_t j = 0; j < size; ++j) { | |
460 if(i >= n) twist(); | |
461 result[j] = x[i++] & UIntType(1); | |
462 } | |
463 return result; | |
464 } | |
465 void reconstruct_state(const detail::polynomial& p) | |
466 { | |
467 const UIntType upper_mask = (~static_cast<UIntType>(0)) << r; | |
468 const UIntType lower_mask = ~upper_mask; | |
469 const std::size_t num_bits = w*n - r; | |
470 for(std::size_t j = num_bits - n + 1; j <= num_bits; ++j) | |
471 x[j % n] = p[j]; | |
472 | |
473 UIntType y0 = 0; | |
474 for(std::size_t j = num_bits + 1; j >= n - 1; --j) { | |
475 UIntType y1 = x[j % n] ^ x[(j + m) % n]; | |
476 if(p[j - n + 1]) | |
477 y1 = (y1 ^ a) << UIntType(1) | UIntType(1); | |
478 else | |
479 y1 = y1 << UIntType(1); | |
480 x[(j + 1) % n] = (y0 & upper_mask) | (y1 & lower_mask); | |
481 y0 = y1; | |
482 } | |
483 i = 0; | |
484 } | |
485 | |
351 /// \endcond | 486 /// \endcond |
352 | 487 |
353 // state representation: next output is o(x(i)) | 488 // state representation: next output is o(x(i)) |
354 // x[0] ... x[k] x[k+1] ... x[n-1] represents | 489 // x[0] ... x[k] x[k+1] ... x[n-1] represents |
355 // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) | 490 // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) |
356 | 491 |
357 UIntType x[n]; | 492 UIntType x[n]; |
358 std::size_t i; | 493 std::size_t i; |
359 }; | 494 }; |
360 | 495 |
361 /// \cond show_private | 496 /// \cond show_private |
362 | 497 |
466 * @blockquote | 601 * @blockquote |
467 * "Mersenne Twister: A 623-dimensionally equidistributed | 602 * "Mersenne Twister: A 623-dimensionally equidistributed |
468 * uniform pseudo-random number generator", Makoto Matsumoto | 603 * uniform pseudo-random number generator", Makoto Matsumoto |
469 * and Takuji Nishimura, ACM Transactions on Modeling and | 604 * and Takuji Nishimura, ACM Transactions on Modeling and |
470 * Computer Simulation: Special Issue on Uniform Random Number | 605 * Computer Simulation: Special Issue on Uniform Random Number |
471 * Generation, Vol. 8, No. 1, January 1998, pp. 3-30. | 606 * Generation, Vol. 8, No. 1, January 1998, pp. 3-30. |
472 * @endblockquote | 607 * @endblockquote |
473 */ | 608 */ |
474 typedef mersenne_twister_engine<uint32_t,32,351,175,19,0xccab8ee7, | 609 typedef mersenne_twister_engine<uint32_t,32,351,175,19,0xccab8ee7, |
475 11,0xffffffff,7,0x31b6ab00,15,0xffe50000,17,1812433253> mt11213b; | 610 11,0xffffffff,7,0x31b6ab00,15,0xffe50000,17,1812433253> mt11213b; |
476 | 611 |
480 * @blockquote | 615 * @blockquote |
481 * "Mersenne Twister: A 623-dimensionally equidistributed | 616 * "Mersenne Twister: A 623-dimensionally equidistributed |
482 * uniform pseudo-random number generator", Makoto Matsumoto | 617 * uniform pseudo-random number generator", Makoto Matsumoto |
483 * and Takuji Nishimura, ACM Transactions on Modeling and | 618 * and Takuji Nishimura, ACM Transactions on Modeling and |
484 * Computer Simulation: Special Issue on Uniform Random Number | 619 * Computer Simulation: Special Issue on Uniform Random Number |
485 * Generation, Vol. 8, No. 1, January 1998, pp. 3-30. | 620 * Generation, Vol. 8, No. 1, January 1998, pp. 3-30. |
486 * @endblockquote | 621 * @endblockquote |
487 */ | 622 */ |
488 typedef mersenne_twister_engine<uint32_t,32,624,397,31,0x9908b0df, | 623 typedef mersenne_twister_engine<uint32_t,32,624,397,31,0x9908b0df, |
489 11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253> mt19937; | 624 11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253> mt19937; |
490 | 625 |
540 | 675 |
541 BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt11213b) | 676 BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt11213b) |
542 BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937) | 677 BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937) |
543 BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937_64) | 678 BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937_64) |
544 | 679 |
680 #include <boost/random/detail/enable_warnings.hpp> | |
681 | |
545 #endif // BOOST_RANDOM_MERSENNE_TWISTER_HPP | 682 #endif // BOOST_RANDOM_MERSENNE_TWISTER_HPP |