00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef MERSENNETWISTER_H
00058 #define MERSENNETWISTER_H
00059
00060
00061
00062 #include "stdafx.h"
00063 #include <iostream>
00064 #include <limits.h>
00065 #include <stdio.h>
00066 #include <time.h>
00067 #include <math.h>
00068
00071 class MTRand {
00072
00073 public:
00074 typedef unsigned long uint32;
00075
00076 enum { N = 624 };
00077 enum { SAVE = N + 1 };
00078
00079 protected:
00080 enum { M = 397 };
00081
00082 uint32 state[N];
00083 uint32 *pNext;
00084 int left;
00085
00086
00087
00088 public:
00089 MTRand( const uint32& oneSeed );
00090 MTRand( uint32 *const bigSeed, uint32 const seedLength = N );
00091 MTRand();
00092
00093
00094
00095
00096
00097
00098 double rand();
00099 double rand( const double& n );
00100 double randExc();
00101 double randExc( const double& n );
00102 double randDblExc();
00103 double randDblExc( const double& n );
00104 uint32 randInt();
00105 uint32 randInt( const uint32& n );
00106 double operator()() { return rand(); }
00107
00108
00109 double rand53();
00110
00111
00112 double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
00113
00114
00115 void seed( const uint32 oneSeed );
00116 void seed( uint32 *const bigSeed, const uint32 seedLength = N );
00117 void seed();
00118
00119
00120 void save( uint32* saveArray ) const;
00121 void load( uint32 *const loadArray );
00122
00123
00124
00125 protected:
00126 void initialize( const uint32 oneSeed );
00127 void reload();
00128 uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
00129 uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
00130 uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
00131 uint32 mixBits( const uint32& u, const uint32& v ) const
00132 { return hiBit(u) | loBits(v); }
00133 uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
00134 { return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
00135 static uint32 hash( time_t t, clock_t c );
00136 };
00137
00138
00139 inline MTRand::MTRand( const uint32& oneSeed )
00140 { seed(oneSeed); }
00141
00142 inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
00143 { seed(bigSeed,seedLength); }
00144
00145 inline MTRand::MTRand()
00146 { seed(); }
00147
00148 inline double MTRand::rand()
00149 { return double(randInt()) * (1.0/4294967295.0); }
00150
00151 inline double MTRand::rand( const double& n )
00152 { return rand() * n; }
00153
00154 inline double MTRand::randExc()
00155 { return double(randInt()) * (1.0/4294967296.0); }
00156
00157 inline double MTRand::randExc( const double& n )
00158 { return randExc() * n; }
00159
00160 inline double MTRand::randDblExc()
00161 { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
00162
00163 inline double MTRand::randDblExc( const double& n )
00164 { return randDblExc() * n; }
00165
00166 inline double MTRand::rand53()
00167 {
00168 uint32 a = randInt() >> 5, b = randInt() >> 6;
00169 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
00170 }
00171
00172 inline double MTRand::randNorm( const double& mean, const double& variance )
00173 {
00174
00175
00176 double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
00177 double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
00178 return mean + r * cos(phi);
00179 }
00180
00181 inline MTRand::uint32 MTRand::randInt()
00182 {
00183
00184
00185
00186 if( left == 0 ) reload();
00187 --left;
00188
00189 register uint32 s1;
00190 s1 = *pNext++;
00191 s1 ^= (s1 >> 11);
00192 s1 ^= (s1 << 7) & 0x9d2c5680UL;
00193 s1 ^= (s1 << 15) & 0xefc60000UL;
00194 return ( s1 ^ (s1 >> 18) );
00195 }
00196
00197 inline MTRand::uint32 MTRand::randInt( const uint32& n )
00198 {
00199
00200
00201 uint32 used = n;
00202 used |= used >> 1;
00203 used |= used >> 2;
00204 used |= used >> 4;
00205 used |= used >> 8;
00206 used |= used >> 16;
00207
00208
00209 uint32 i;
00210 do
00211 i = randInt() & used;
00212 while( i > n );
00213 return i;
00214 }
00215
00216
00217 inline void MTRand::seed( const uint32 oneSeed )
00218 {
00219
00220 initialize(oneSeed);
00221 reload();
00222 }
00223
00224
00225 inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
00226 {
00227
00228
00229
00230
00231
00232
00233 initialize(19650218UL);
00234 register int i = 1;
00235 register uint32 j = 0;
00236 register int k = ( N > seedLength ? N : seedLength );
00237 for( ; k; --k )
00238 {
00239 state[i] =
00240 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
00241 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
00242 state[i] &= 0xffffffffUL;
00243 ++i; ++j;
00244 if( i >= N ) { state[0] = state[N-1]; i = 1; }
00245 if( j >= seedLength ) j = 0;
00246 }
00247 for( k = N - 1; k; --k )
00248 {
00249 state[i] =
00250 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
00251 state[i] -= i;
00252 state[i] &= 0xffffffffUL;
00253 ++i;
00254 if( i >= N ) { state[0] = state[N-1]; i = 1; }
00255 }
00256 state[0] = 0x80000000UL;
00257 reload();
00258 }
00259
00260
00261 inline void MTRand::seed()
00262 {
00263
00264
00265
00266
00267 FILE* urandom = fopen( "/dev/urandom", "rb" );
00268 if( urandom )
00269 {
00270 uint32 bigSeed[N];
00271 register uint32 *s = bigSeed;
00272 register int i = N;
00273 register bool success = true;
00274 while( success && i-- )
00275 success = fread( s++, sizeof(uint32), 1, urandom ) == 0 ? false: true;
00276 fclose(urandom);
00277 if( success ) { seed( bigSeed, N ); return; }
00278 }
00279
00280
00281 seed( hash( time(NULL), clock() ) );
00282 }
00283
00284
00285 inline void MTRand::initialize( const uint32 seed )
00286 {
00287
00288
00289
00290
00291 register uint32 *s = state;
00292 register uint32 *r = state;
00293 register int i = 1;
00294 *s++ = seed & 0xffffffffUL;
00295 for( ; i < N; ++i )
00296 {
00297 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
00298 r++;
00299 }
00300 }
00301
00302
00303 inline void MTRand::reload()
00304 {
00305
00306
00307 register uint32 *p = state;
00308 register int i;
00309 for( i = N - M; i--; ++p )
00310 *p = twist( p[M], p[0], p[1] );
00311 for( i = M; --i; ++p )
00312 *p = twist( p[M-N], p[0], p[1] );
00313 *p = twist( p[M-N], p[0], state[0] );
00314
00315 left = N, pNext = state;
00316 }
00317
00318
00319 inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
00320 {
00321
00322
00323
00324
00325 static uint32 differ = 0;
00326
00327 uint32 h1 = 0;
00328 unsigned char *p = (unsigned char *) &t;
00329 for( size_t i = 0; i < sizeof(t); ++i )
00330 {
00331 h1 *= UCHAR_MAX + 2U;
00332 h1 += p[i];
00333 }
00334 uint32 h2 = 0;
00335 p = (unsigned char *) &c;
00336 for( size_t j = 0; j < sizeof(c); ++j )
00337 {
00338 h2 *= UCHAR_MAX + 2U;
00339 h2 += p[j];
00340 }
00341 return ( h1 + differ++ ) ^ h2;
00342 }
00343
00344
00345 inline void MTRand::save( uint32* saveArray ) const
00346 {
00347 register uint32 *sa = saveArray;
00348 register const uint32 *s = state;
00349 register int i = N;
00350 for( ; i--; *sa++ = *s++ ) {}
00351 *sa = left;
00352 }
00353
00354
00355 inline void MTRand::load( uint32 *const loadArray )
00356 {
00357 register uint32 *s = state;
00358 register uint32 *la = loadArray;
00359 register int i = N;
00360 for( ; i--; *s++ = *la++ ) {}
00361 left = *la;
00362 pNext = &state[N-left];
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 #endif // MERSENNETWISTER_H
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426