72 #ifndef MERSENNETWISTER_H 73 #define MERSENNETWISTER_H 88 typedef unsigned long uint32;
91 enum { SAVE = N + 1 };
103 MTRand(
const uint32& oneSeed );
104 MTRand( uint32 *
const bigSeed, uint32
const seedLength = N );
113 double rand(
const double& n );
115 double randExc(
const double& n );
117 double randDblExc(
const double& n );
119 uint32 randInt(
const uint32& n );
120 double operator()() {
128 double randNorm(
const double& mean = 0.0,
const double& variance = 0.0 );
131 void seed(
const uint32 oneSeed );
132 void seed( uint32 *
const bigSeed,
const uint32 seedLength = N );
136 void save( uint32* saveArray )
const;
137 void load( uint32 *
const loadArray );
138 friend std::ostream&
operator<<( std::ostream& os,
const MTRand& mtrand );
139 friend std::istream&
operator>>( std::istream& is, MTRand& mtrand );
142 void initialize(
const uint32 oneSeed );
144 uint32 hiBit(
const uint32& u )
const {
145 return u & 0x80000000UL;
147 uint32 loBit(
const uint32& u )
const {
148 return u & 0x00000001UL;
150 uint32 loBits(
const uint32& u )
const {
151 return u & 0x7fffffffUL;
153 uint32 mixBits(
const uint32& u,
const uint32& v )
const 155 return hiBit(u) | loBits(v);
157 uint32 twist(
const uint32& m,
const uint32& s0,
const uint32& s1 )
const 159 return m ^ (mixBits(s0,s1)>>1) ^ (-static_cast<long>(loBit(s1)) & 0x9908b0dfUL);
161 static uint32 hash( time_t t, clock_t c );
165 inline MTRand::MTRand(
const uint32& oneSeed )
170 inline MTRand::MTRand( uint32 *
const bigSeed,
const uint32 seedLength )
172 seed(bigSeed,seedLength);
175 inline MTRand::MTRand()
180 inline double MTRand::rand()
182 return double(randInt()) * (1.0/4294967295.0);
185 inline double MTRand::rand(
const double& n )
190 inline double MTRand::randExc()
192 return double(randInt()) * (1.0/4294967296.0);
195 inline double MTRand::randExc(
const double& n )
197 return randExc() * n;
200 inline double MTRand::randDblExc()
202 return (
double(randInt()) + 0.5 ) * (1.0/4294967296.0);
205 inline double MTRand::randDblExc(
const double& n )
207 return randDblExc() * n;
210 inline double MTRand::rand53()
212 uint32 a = randInt() >> 5, b = randInt() >> 6;
213 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
216 inline double MTRand::randNorm(
const double& mean,
const double& variance )
220 double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
221 double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
222 return mean + r * cos(phi);
230 if( left == 0 ) reload();
236 s1 ^= (s1 << 7) & 0x9d2c5680UL;
237 s1 ^= (s1 << 15) & 0xefc60000UL;
238 return ( s1 ^ (s1 >> 18) );
255 i = randInt() & used;
261 inline void MTRand::seed(
const uint32 oneSeed )
269 inline void MTRand::seed( uint32 *
const bigSeed,
const uint32 seedLength )
277 initialize(19650218UL);
280 int k = ( N > seedLength ? N : seedLength );
284 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
285 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
286 state[i] &= 0xffffffffUL;
290 state[0] = state[N-1];
293 if( j >= seedLength ) j = 0;
295 for( k = N - 1; k; --k )
298 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
300 state[i] &= 0xffffffffUL;
303 state[0] = state[N-1];
307 state[0] = 0x80000000UL;
312 inline void MTRand::seed()
318 FILE* urandom = fopen(
"/dev/urandom",
"rb" );
325 while( success && i-- )
326 success = fread( s++,
sizeof(uint32), 1, urandom );
335 seed( hash( time(NULL), clock() ) );
339 inline void MTRand::initialize(
const uint32 seed )
348 *s++ = seed & 0xffffffffUL;
351 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
357 inline void MTRand::reload()
363 for( i = N - M; i--; ++p )
364 *p = twist( p[M], p[0], p[1] );
365 for( i = M; --i; ++p )
366 *p = twist( p[M-N], p[0], p[1] );
367 *p = twist( p[M-N], p[0], state[0] );
369 left = N, pNext = state;
379 static uint32 differ = 0;
382 unsigned char *p =
reinterpret_cast<unsigned char *
>( &t );
383 for(
size_t i = 0; i <
sizeof(t); ++i )
385 h1 *= UCHAR_MAX + 2U;
389 p =
reinterpret_cast<unsigned char *
>( &c );
390 for(
size_t j = 0; j <
sizeof(c); ++j )
392 h2 *= UCHAR_MAX + 2U;
395 return ( h1 + differ++ ) ^ h2;
399 inline void MTRand::save( uint32* saveArray )
const 401 uint32 *sa = saveArray;
402 const uint32 *s = state;
404 for( ; i--; *sa++ = *s++ ) {}
409 inline void MTRand::load( uint32 *
const loadArray )
412 uint32 *la = loadArray;
414 for( ; i--; *s++ = *la++ ) {}
416 pNext = &state[N-left];
420 inline std::ostream&
operator<<( std::ostream& os,
const MTRand& mtrand )
424 for( ; i--; os << *s++ <<
"\t" ) {}
425 return os << mtrand.left;
429 inline std::istream&
operator>>( std::istream& is, MTRand& mtrand )
433 for( ; i--; is >> *s++ ) {}
435 mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
441 #endif // MERSENNETWISTER_H std::istream & operator>>(std::istream &is, uint_impl_t< N > &v)
std::ostream & operator<<(std::ostream &o, const Point &a)