| 0 | 1 // MersenneTwister.h | 
|  | 2 // Mersenne Twister random number generator -- a C++ class MTRand | 
|  | 3 // Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus | 
|  | 4 // Richard J. Wagner  v1.0  15 May 2003  rjwagner@writeme.com | 
|  | 5 | 
|  | 6 // The Mersenne Twister is an algorithm for generating random numbers.  It | 
|  | 7 // was designed with consideration of the flaws in various other generators. | 
|  | 8 // The period, 2^19937-1, and the order of equidistribution, 623 dimensions, | 
|  | 9 // are far greater.  The generator is also fast; it avoids multiplication and | 
|  | 10 // division, and it benefits from caches and pipelines.  For more information | 
|  | 11 // see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html | 
|  | 12 | 
|  | 13 // Reference | 
|  | 14 // M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally | 
|  | 15 // Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on | 
|  | 16 // Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. | 
|  | 17 | 
|  | 18 // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, | 
|  | 19 // Copyright (C) 2000 - 2003, Richard J. Wagner | 
|  | 20 // All rights reserved. | 
|  | 21 // | 
|  | 22 // Redistribution and use in source and binary forms, with or without | 
|  | 23 // modification, are permitted provided that the following conditions | 
|  | 24 // are met: | 
|  | 25 // | 
|  | 26 //   1. Redistributions of source code must retain the above copyright | 
|  | 27 //      notice, this list of conditions and the following disclaimer. | 
|  | 28 // | 
|  | 29 //   2. Redistributions in binary form must reproduce the above copyright | 
|  | 30 //      notice, this list of conditions and the following disclaimer in the | 
|  | 31 //      documentation and/or other materials provided with the distribution. | 
|  | 32 // | 
|  | 33 //   3. The names of its contributors may not be used to endorse or promote | 
|  | 34 //      products derived from this software without specific prior written | 
|  | 35 //      permission. | 
|  | 36 // | 
|  | 37 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | 38 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | 39 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | 40 // A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR | 
|  | 41 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
|  | 42 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
|  | 43 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
|  | 44 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 
|  | 45 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
|  | 46 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
|  | 47 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 48 | 
|  | 49 // The original code included the following notice: | 
|  | 50 // | 
|  | 51 //     When you use this, send an email to: matumoto@math.keio.ac.jp | 
|  | 52 //     with an appropriate reference to your work. | 
|  | 53 // | 
|  | 54 // It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu | 
|  | 55 // when you write. | 
|  | 56 | 
|  | 57 #ifndef MERSENNETWISTER_H | 
|  | 58 #define MERSENNETWISTER_H | 
|  | 59 | 
|  | 60 // Not thread safe (unless auto-initialization is avoided and each thread has | 
|  | 61 // its own MTRand object) | 
|  | 62 | 
|  | 63 #include <iostream> | 
|  | 64 #include <limits.h> | 
|  | 65 #include <stdio.h> | 
|  | 66 #include <time.h> | 
|  | 67 #include <math.h> | 
|  | 68 | 
|  | 69 class MTRand { | 
|  | 70 // Data | 
|  | 71 public: | 
|  | 72 	typedef unsigned long uint32;  // unsigned integer type, at least 32 bits | 
|  | 73 | 
|  | 74 	enum { N = 624 };       // length of state vector | 
|  | 75 	enum { SAVE = N + 1 };  // length of array for save() | 
|  | 76 | 
|  | 77 protected: | 
|  | 78 	enum { M = 397 };  // period parameter | 
|  | 79 | 
|  | 80 	uint32 state[N];   // internal state | 
|  | 81 	uint32 *pNext;     // next value to get from state | 
|  | 82 	int left;          // number of values left before reload needed | 
|  | 83 | 
|  | 84 | 
|  | 85 //Methods | 
|  | 86 public: | 
|  | 87 	MTRand( const uint32& oneSeed );  // initialize with a simple uint32 | 
|  | 88 	MTRand( uint32 *const bigSeed, uint32 const seedLength = N );  // or an array | 
|  | 89 	MTRand();  // auto-initialize with /dev/urandom or time() and clock() | 
|  | 90 | 
|  | 91 	// Do NOT use for CRYPTOGRAPHY without securely hashing several returned | 
|  | 92 	// values together, otherwise the generator state can be learned after | 
|  | 93 	// reading 624 consecutive values. | 
|  | 94 | 
|  | 95 	// Access to 32-bit random numbers | 
|  | 96 	double rand();                          // real number in [0,1] | 
|  | 97 	double rand( const double& n );         // real number in [0,n] | 
|  | 98 	double randExc();                       // real number in [0,1) | 
|  | 99 	double randExc( const double& n );      // real number in [0,n) | 
|  | 100 	double randDblExc();                    // real number in (0,1) | 
|  | 101 	double randDblExc( const double& n );   // real number in (0,n) | 
|  | 102 	uint32 randInt();                       // integer in [0,2^32-1] | 
|  | 103 	uint32 randInt( const uint32& n );      // integer in [0,n] for n < 2^32 | 
|  | 104 	double operator()() { return rand(); }  // same as rand() | 
|  | 105 | 
|  | 106 	// Access to 53-bit random numbers (capacity of IEEE double precision) | 
|  | 107 	double rand53();  // real number in [0,1) | 
|  | 108 | 
|  | 109 	// Access to nonuniform random number distributions | 
|  | 110 	double randNorm( const double& mean = 0.0, const double& variance = 0.0 ); | 
|  | 111 | 
|  | 112 	// Re-seeding functions with same behavior as initializers | 
|  | 113 	void seed( const uint32 oneSeed ); | 
|  | 114 	void seed( uint32 *const bigSeed, const uint32 seedLength = N ); | 
|  | 115 	void seed(); | 
|  | 116 | 
|  | 117 	// Saving and loading generator state | 
|  | 118 	void save( uint32* saveArray ) const;  // to array of size SAVE | 
|  | 119 	void load( uint32 *const loadArray );  // from such array | 
|  | 120 	friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ); | 
|  | 121 	friend std::istream& operator>>( std::istream& is, MTRand& mtrand ); | 
|  | 122 | 
|  | 123 protected: | 
|  | 124 	void initialize( const uint32 oneSeed ); | 
|  | 125 	void reload(); | 
|  | 126 	uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; } | 
|  | 127 	uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; } | 
|  | 128 	uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; } | 
|  | 129 	uint32 mixBits( const uint32& u, const uint32& v ) const | 
|  | 130 		{ return hiBit(u) | loBits(v); } | 
|  | 131 	uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const | 
|  | 132 		{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); } | 
|  | 133 	static uint32 hash( time_t t, clock_t c ); | 
|  | 134 }; | 
|  | 135 | 
|  | 136 | 
|  | 137 inline MTRand::MTRand( const uint32& oneSeed ) | 
|  | 138 	{ seed(oneSeed); } | 
|  | 139 | 
|  | 140 inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength ) | 
|  | 141 	{ seed(bigSeed,seedLength); } | 
|  | 142 | 
|  | 143 inline MTRand::MTRand() | 
|  | 144 	{ seed(); } | 
|  | 145 | 
|  | 146 inline double MTRand::rand() | 
|  | 147 	{ return double(randInt()) * (1.0/4294967295.0); } | 
|  | 148 | 
|  | 149 inline double MTRand::rand( const double& n ) | 
|  | 150 	{ return rand() * n; } | 
|  | 151 | 
|  | 152 inline double MTRand::randExc() | 
|  | 153 	{ return double(randInt()) * (1.0/4294967296.0); } | 
|  | 154 | 
|  | 155 inline double MTRand::randExc( const double& n ) | 
|  | 156 	{ return randExc() * n; } | 
|  | 157 | 
|  | 158 inline double MTRand::randDblExc() | 
|  | 159 	{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); } | 
|  | 160 | 
|  | 161 inline double MTRand::randDblExc( const double& n ) | 
|  | 162 	{ return randDblExc() * n; } | 
|  | 163 | 
|  | 164 inline double MTRand::rand53() | 
|  | 165 { | 
|  | 166 	uint32 a = randInt() >> 5, b = randInt() >> 6; | 
|  | 167 	return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);  // by Isaku Wada | 
|  | 168 } | 
|  | 169 | 
|  | 170 inline double MTRand::randNorm( const double& mean, const double& variance ) | 
|  | 171 { | 
|  | 172 	// Return a real number from a normal (Gaussian) distribution with given | 
|  | 173 	// mean and variance by Box-Muller method | 
|  | 174 	double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance; | 
|  | 175 	double phi = 2.0 * 3.14159265358979323846264338328 * randExc(); | 
|  | 176 	return mean + r * cos(phi); | 
|  | 177 } | 
|  | 178 | 
|  | 179 inline MTRand::uint32 MTRand::randInt() | 
|  | 180 { | 
|  | 181 	// Pull a 32-bit integer from the generator state | 
|  | 182 	// Every other access function simply transforms the numbers extracted here | 
|  | 183 | 
|  | 184 	if( left == 0 ) reload(); | 
|  | 185 	--left; | 
|  | 186 | 
|  | 187 	register uint32 s1; | 
|  | 188 	s1 = *pNext++; | 
|  | 189 	s1 ^= (s1 >> 11); | 
|  | 190 	s1 ^= (s1 <<  7) & 0x9d2c5680UL; | 
|  | 191 	s1 ^= (s1 << 15) & 0xefc60000UL; | 
|  | 192 	return ( s1 ^ (s1 >> 18) ); | 
|  | 193 } | 
|  | 194 | 
|  | 195 inline MTRand::uint32 MTRand::randInt( const uint32& n ) | 
|  | 196 { | 
|  | 197 	// Find which bits are used in n | 
|  | 198 	// Optimized by Magnus Jonsson (magnus@smartelectronix.com) | 
|  | 199 	uint32 used = n; | 
|  | 200 	used |= used >> 1; | 
|  | 201 	used |= used >> 2; | 
|  | 202 	used |= used >> 4; | 
|  | 203 	used |= used >> 8; | 
|  | 204 	used |= used >> 16; | 
|  | 205 | 
|  | 206 	// Draw numbers until one is found in [0,n] | 
|  | 207 	uint32 i; | 
|  | 208 	do | 
|  | 209 		i = randInt() & used;  // toss unused bits to shorten search | 
|  | 210 	while( i > n ); | 
|  | 211 	return i; | 
|  | 212 } | 
|  | 213 | 
|  | 214 | 
|  | 215 inline void MTRand::seed( const uint32 oneSeed ) | 
|  | 216 { | 
|  | 217 	// Seed the generator with a simple uint32 | 
|  | 218 	initialize(oneSeed); | 
|  | 219 	reload(); | 
|  | 220 } | 
|  | 221 | 
|  | 222 | 
|  | 223 inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) | 
|  | 224 { | 
|  | 225 	// Seed the generator with an array of uint32's | 
|  | 226 	// There are 2^19937-1 possible initial states.  This function allows | 
|  | 227 	// all of those to be accessed by providing at least 19937 bits (with a | 
|  | 228 	// default seed length of N = 624 uint32's).  Any bits above the lower 32 | 
|  | 229 	// in each element are discarded. | 
|  | 230 	// Just call seed() if you want to get array from /dev/urandom | 
|  | 231 	initialize(19650218UL); | 
|  | 232 	register int i = 1; | 
|  | 233 	register uint32 j = 0; | 
|  | 234 	register int k = ( N > seedLength ? N : seedLength ); | 
|  | 235 	for( ; k; --k ) | 
|  | 236 	{ | 
|  | 237 		state[i] = | 
|  | 238 			state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL ); | 
|  | 239 		state[i] += ( bigSeed[j] & 0xffffffffUL ) + j; | 
|  | 240 		state[i] &= 0xffffffffUL; | 
|  | 241 		++i;  ++j; | 
|  | 242 		if( i >= N ) { state[0] = state[N-1];  i = 1; } | 
|  | 243 		if( j >= seedLength ) j = 0; | 
|  | 244 	} | 
|  | 245 	for( k = N - 1; k; --k ) | 
|  | 246 	{ | 
|  | 247 		state[i] = | 
|  | 248 			state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL ); | 
|  | 249 		state[i] -= i; | 
|  | 250 		state[i] &= 0xffffffffUL; | 
|  | 251 		++i; | 
|  | 252 		if( i >= N ) { state[0] = state[N-1];  i = 1; } | 
|  | 253 	} | 
|  | 254 	state[0] = 0x80000000UL;  // MSB is 1, assuring non-zero initial array | 
|  | 255 	reload(); | 
|  | 256 } | 
|  | 257 | 
|  | 258 | 
|  | 259 inline void MTRand::seed() | 
|  | 260 { | 
|  | 261 	// Seed the generator with an array from /dev/urandom if available | 
|  | 262 	// Otherwise use a hash of time() and clock() values | 
|  | 263 | 
|  | 264 	// First try getting an array from /dev/urandom | 
|  | 265 	FILE* urandom = fopen( "/dev/urandom", "rb" ); | 
|  | 266 	if( urandom ) | 
|  | 267 	{ | 
|  | 268 		uint32 bigSeed[N]; | 
|  | 269 		register uint32 *s = bigSeed; | 
|  | 270 		register int i = N; | 
|  | 271 		register bool success = true; | 
|  | 272 		while( success && i-- ) | 
|  | 273 			success = fread( s++, sizeof(uint32), 1, urandom ); | 
|  | 274 		fclose(urandom); | 
|  | 275 		if( success ) { seed( bigSeed, N );  return; } | 
|  | 276 	} | 
|  | 277 | 
|  | 278 	// Was not successful, so use time() and clock() instead | 
|  | 279 	seed( hash( time(NULL), clock() ) ); | 
|  | 280 } | 
|  | 281 | 
|  | 282 | 
|  | 283 inline void MTRand::initialize( const uint32 seed ) | 
|  | 284 { | 
|  | 285 	// Initialize generator state with seed | 
|  | 286 	// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. | 
|  | 287 	// In previous versions, most significant bits (MSBs) of the seed affect | 
|  | 288 	// only MSBs of the state array.  Modified 9 Jan 2002 by Makoto Matsumoto. | 
|  | 289 	register uint32 *s = state; | 
|  | 290 	register uint32 *r = state; | 
|  | 291 	register int i = 1; | 
|  | 292 	*s++ = seed & 0xffffffffUL; | 
|  | 293 	for( ; i < N; ++i ) | 
|  | 294 	{ | 
|  | 295 		*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; | 
|  | 296 		r++; | 
|  | 297 	} | 
|  | 298 } | 
|  | 299 | 
|  | 300 | 
|  | 301 inline void MTRand::reload() | 
|  | 302 { | 
|  | 303 	// Generate N new values in state | 
|  | 304 	// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) | 
|  | 305 	register uint32 *p = state; | 
|  | 306 	register int i; | 
|  | 307 	for( i = N - M; i--; ++p ) | 
|  | 308 		*p = twist( p[M], p[0], p[1] ); | 
|  | 309 	for( i = M; --i; ++p ) | 
|  | 310 		*p = twist( p[M-N], p[0], p[1] ); | 
|  | 311 	*p = twist( p[M-N], p[0], state[0] ); | 
|  | 312 | 
|  | 313 	left = N, pNext = state; | 
|  | 314 } | 
|  | 315 | 
|  | 316 | 
|  | 317 inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) | 
|  | 318 { | 
|  | 319 	// Get a uint32 from t and c | 
|  | 320 	// Better than uint32(x) in case x is floating point in [0,1] | 
|  | 321 	// Based on code by Lawrence Kirby (fred@genesis.demon.co.uk) | 
|  | 322 | 
|  | 323 	static uint32 differ = 0;  // guarantee time-based seeds will change | 
|  | 324 | 
|  | 325 	uint32 h1 = 0; | 
|  | 326 	unsigned char *p = (unsigned char *) &t; | 
|  | 327 	for( size_t i = 0; i < sizeof(t); ++i ) | 
|  | 328 	{ | 
|  | 329 		h1 *= UCHAR_MAX + 2U; | 
|  | 330 		h1 += p[i]; | 
|  | 331 	} | 
|  | 332 	uint32 h2 = 0; | 
|  | 333 	p = (unsigned char *) &c; | 
|  | 334 	for( size_t j = 0; j < sizeof(c); ++j ) | 
|  | 335 	{ | 
|  | 336 		h2 *= UCHAR_MAX + 2U; | 
|  | 337 		h2 += p[j]; | 
|  | 338 	} | 
|  | 339 	return ( h1 + differ++ ) ^ h2; | 
|  | 340 } | 
|  | 341 | 
|  | 342 | 
|  | 343 inline void MTRand::save( uint32* saveArray ) const | 
|  | 344 { | 
|  | 345 	register uint32 *sa = saveArray; | 
|  | 346 	register const uint32 *s = state; | 
|  | 347 	register int i = N; | 
|  | 348 	for( ; i--; *sa++ = *s++ ) {} | 
|  | 349 	*sa = left; | 
|  | 350 } | 
|  | 351 | 
|  | 352 | 
|  | 353 inline void MTRand::load( uint32 *const loadArray ) | 
|  | 354 { | 
|  | 355 	register uint32 *s = state; | 
|  | 356 	register uint32 *la = loadArray; | 
|  | 357 	register int i = N; | 
|  | 358 	for( ; i--; *s++ = *la++ ) {} | 
|  | 359 	left = *la; | 
|  | 360 	pNext = &state[N-left]; | 
|  | 361 } | 
|  | 362 | 
|  | 363 | 
|  | 364 inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) | 
|  | 365 { | 
|  | 366 	register const MTRand::uint32 *s = mtrand.state; | 
|  | 367 	register int i = mtrand.N; | 
|  | 368 	for( ; i--; os << *s++ << "\t" ) {} | 
|  | 369 	return os << mtrand.left; | 
|  | 370 } | 
|  | 371 | 
|  | 372 | 
|  | 373 inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) | 
|  | 374 { | 
|  | 375 	register MTRand::uint32 *s = mtrand.state; | 
|  | 376 	register int i = mtrand.N; | 
|  | 377 	for( ; i--; is >> *s++ ) {} | 
|  | 378 	is >> mtrand.left; | 
|  | 379 	mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; | 
|  | 380 	return is; | 
|  | 381 } | 
|  | 382 | 
|  | 383 #endif  // MERSENNETWISTER_H | 
|  | 384 | 
|  | 385 // Change log: | 
|  | 386 // | 
|  | 387 // v0.1 - First release on 15 May 2000 | 
|  | 388 //      - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus | 
|  | 389 //      - Translated from C to C++ | 
|  | 390 //      - Made completely ANSI compliant | 
|  | 391 //      - Designed convenient interface for initialization, seeding, and | 
|  | 392 //        obtaining numbers in default or user-defined ranges | 
|  | 393 //      - Added automatic seeding from /dev/urandom or time() and clock() | 
|  | 394 //      - Provided functions for saving and loading generator state | 
|  | 395 // | 
|  | 396 // v0.2 - Fixed bug which reloaded generator one step too late | 
|  | 397 // | 
|  | 398 // v0.3 - Switched to clearer, faster reload() code from Matthew Bellew | 
|  | 399 // | 
|  | 400 // v0.4 - Removed trailing newline in saved generator format to be consistent | 
|  | 401 //        with output format of built-in types | 
|  | 402 // | 
|  | 403 // v0.5 - Improved portability by replacing static const int's with enum's and | 
|  | 404 //        clarifying return values in seed(); suggested by Eric Heimburg | 
|  | 405 //      - Removed MAXINT constant; use 0xffffffffUL instead | 
|  | 406 // | 
|  | 407 // v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits | 
|  | 408 //      - Changed integer [0,n] generator to give better uniformity | 
|  | 409 // | 
|  | 410 // v0.7 - Fixed operator precedence ambiguity in reload() | 
|  | 411 //      - Added access for real numbers in (0,1) and (0,n) | 
|  | 412 // | 
|  | 413 // v0.8 - Included time.h header to properly support time_t and clock_t | 
|  | 414 // | 
|  | 415 // v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto | 
|  | 416 //      - Allowed for seeding with arrays of any length | 
|  | 417 //      - Added access for real numbers in [0,1) with 53-bit resolution | 
|  | 418 //      - Added access for real numbers from normal (Gaussian) distributions | 
|  | 419 //      - Increased overall speed by optimizing twist() | 
|  | 420 //      - Doubled speed of integer [0,n] generation | 
|  | 421 //      - Fixed out-of-range number generation on 64-bit machines | 
|  | 422 //      - Improved portability by substituting literal constants for long enum's | 
|  | 423 //      - Changed license from GNU LGPL to BSD |