64 #ifndef MERSENNETWISTER_H
65 #define MERSENNETWISTER_H
79 typedef unsigned long uint32;
82 enum { SAVE = N + 1 };
93 MTRand(
const uint32 oneSeed );
94 MTRand(
uint32 *
const bigSeed,
uint32 const seedLength = N );
96 MTRand(
const MTRand& o );
106 double rand(
const double n );
108 double randExc(
const double n );
110 double randDblExc(
const double n );
117 double randNorm(
const double mean = 0.0,
const double stddev = 1.0 );
120 void seed(
const uint32 oneSeed );
121 void seed(
uint32 *
const bigSeed,
const uint32 seedLength = N );
125 void save(
uint32* saveArray )
const;
126 void load(
uint32 *
const loadArray );
127 friend std::ostream&
operator<<( std::ostream& os,
const MTRand& mtrand );
128 friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
129 MTRand& operator=(
const MTRand& o );
132 void initialize(
const uint32 oneSeed );
134 uint32 hiBit(
const uint32 u )
const {
return u & 0x80000000UL; }
135 uint32 loBit(
const uint32 u )
const {
return u & 0x00000001UL; }
136 uint32 loBits(
const uint32 u )
const {
return u & 0x7fffffffUL; }
138 {
return hiBit(u) | loBits(v); }
140 {
return loBit(u) ? 0x9908b0dfUL : 0x0UL; }
142 {
return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); }
143 static uint32 hash( time_t t, clock_t c );
157 unsigned char *p = (
unsigned char *) &t;
158 for(
size_t i = 0; i <
sizeof(t); ++i )
160 h1 *= UCHAR_MAX + 2U;
164 p = (
unsigned char *) &c;
165 for(
size_t j = 0; j <
sizeof(c); ++j )
167 h2 *= UCHAR_MAX + 2U;
170 return ( h1 + differ++ ) ^ h2;
173 inline void MTRand::initialize(
const uint32 _seed )
182 *s++ = _seed & 0xffffffffUL;
185 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
190 inline void MTRand::reload()
194 static const int MmN = int(M) - int(N);
197 for( i = N - M; i--; ++p )
198 *p = twist( p[M], p[0], p[1] );
199 for( i = M; --i; ++p )
200 *p = twist( p[MmN], p[0], p[1] );
201 *p = twist( p[MmN], p[0], state[0] );
203 left = N, pNext = state;
206 inline void MTRand::seed(
const uint32 oneSeed )
213 inline void MTRand::seed(
uint32 *
const bigSeed,
const uint32 seedLength )
221 initialize(19650218UL);
224 int k = ( N > seedLength ? N : seedLength );
228 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
229 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
230 state[i] &= 0xffffffffUL;
232 if( i >= N ) { state[0] = state[N-1]; i = 1; }
233 if( j >= seedLength ) j = 0;
235 for( k = N - 1; k; --k )
238 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
240 state[i] &= 0xffffffffUL;
242 if( i >= N ) { state[0] = state[N-1]; i = 1; }
244 state[0] = 0x80000000UL;
248 inline void MTRand::seed()
254 FILE* urandom = fopen(
"/dev/urandom",
"rb" );
261 while( success && i-- )
262 success = fread( s++,
sizeof(
uint32), 1, urandom );
264 if( success ) { seed( bigSeed, N );
return; }
268 seed( hash( time(NULL), clock() ) );
271 inline MTRand::MTRand(
const uint32 oneSeed )
274 inline MTRand::MTRand(
uint32 *
const bigSeed,
const uint32 seedLength )
275 { seed(bigSeed,seedLength); }
277 inline MTRand::MTRand()
280 inline MTRand::MTRand(
const MTRand& o )
282 const uint32 *t = o.state;
285 for( ; i--; *s++ = *t++ ) {}
287 pNext = &state[N-left];
295 if( left == 0 ) reload();
301 s1 ^= (s1 << 7) & 0x9d2c5680UL;
302 s1 ^= (s1 << 15) & 0xefc60000UL;
303 return ( s1 ^ (s1 >> 18) );
320 i = randInt() & used;
325 inline double MTRand::rand()
326 {
return double(randInt()) * (1.0/4294967295.0); }
328 inline double MTRand::rand(
const double n )
329 {
return rand() * n; }
331 inline double MTRand::randExc()
332 {
return double(randInt()) * (1.0/4294967296.0); }
334 inline double MTRand::randExc(
const double n )
335 {
return randExc() * n; }
337 inline double MTRand::randDblExc()
338 {
return (
double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
340 inline double MTRand::randDblExc(
const double n )
341 {
return randDblExc() * n; }
343 inline double MTRand::rand53()
345 uint32 a = randInt() >> 5, b = randInt() >> 6;
346 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
349 inline double MTRand::randNorm(
const double mean,
const double stddev )
356 x = 2.0 * rand() - 1.0;
357 y = 2.0 * rand() - 1.0;
360 while ( r >= 1.0 || r == 0.0 );
361 double s = sqrt( -2.0 * log(r) / r );
362 return mean + x * s * stddev;
365 inline double MTRand::operator()()
370 inline void MTRand::save(
uint32* saveArray )
const
375 for( ; i--; *sa++ = *s++ ) {}
379 inline void MTRand::load(
uint32 *
const loadArray )
384 for( ; i--; *s++ = *la++ ) {}
386 pNext = &state[N-left];
389 inline std::ostream&
operator<<( std::ostream& os,
const MTRand& mtrand )
393 for( ; i--; os << *s++ <<
"\t" ) {}
394 return os << mtrand.left;
397 inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
401 for( ; i--; is >> *s++ ) {}
403 mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
407 inline MTRand& MTRand::operator=(
const MTRand& o )
409 if(
this == &o )
return (*
this);
410 const uint32 *t = o.state;
413 for( ; i--; *s++ = *t++ ) {}
415 pNext = &state[N-left];
unsigned long uint32
Unsigned integer type, at least 32 bits.
ostream & operator<<(ostream &os, const vector< string > &vals)
Overload << to print a vector of strings to the terminal.