Go to the documentation of this file.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
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef VL_MERSENNETWISTER_H
00066 #define VL_MERSENNETWISTER_H
00067
00068
00069
00070
00071 #include <iostream>
00072 #include <climits>
00073 #include <cstdio>
00074 #include <ctime>
00075 #include <cmath>
00076 #include <vlCore/Object.hpp>
00077
00078 namespace vl
00079 {
00080
00081 class MersenneTwister;
00082
00083 VLCORE_EXPORT MersenneTwister* defMersenneTwister();
00084 VLCORE_EXPORT void setDefMersenneTwister(MersenneTwister*);
00085
00086 class MersenneTwister: public Object
00087 {
00088
00089 public:
00090 typedef unsigned long uint32;
00091
00092 enum { N = 624 };
00093 enum { SAVE = N + 1 };
00094
00095 protected:
00096 enum { M = 397 };
00097
00098 uint32 state[N];
00099 uint32 *pNext;
00100 int left;
00101
00102
00103 public:
00104 MersenneTwister( const uint32 oneSeed );
00105 MersenneTwister( uint32 *const bigSeed, uint32 const seedLength = N );
00106 MersenneTwister();
00107 MersenneTwister( const MersenneTwister& o );
00108
00109
00110
00111
00112
00113
00114 uint32 randInt();
00115 uint32 randInt( const uint32 n );
00116 double rand();
00117 double rand( const double n );
00118 double randExc();
00119 double randExc( const double n );
00120 double randDblExc();
00121 double randDblExc( const double n );
00122 double operator()();
00123
00124
00125 double rand53();
00126
00127
00128 double randNorm( const double mean = 0.0, const double stddev = 1.0 );
00129
00130
00131 void seed( const uint32 oneSeed );
00132 void seed( uint32 *const bigSeed, const uint32 seedLength = N );
00133 void seed();
00134
00135
00136 void save( uint32* saveArray ) const;
00137 void load( uint32 *const loadArray );
00138 friend std::ostream& operator<<( std::ostream& os, const MersenneTwister& mtrand );
00139 friend std::istream& operator>>( std::istream& is, MersenneTwister& mtrand );
00140 MersenneTwister& operator=( const MersenneTwister& o );
00141
00142 protected:
00143 void initialize( const uint32 oneSeed );
00144 void reload();
00145 uint32 hiBit( const uint32 u ) const { return u & 0x80000000UL; }
00146 uint32 loBit( const uint32 u ) const { return u & 0x00000001UL; }
00147 uint32 loBits( const uint32 u ) const { return u & 0x7fffffffUL; }
00148 uint32 mixBits( const uint32 u, const uint32 v ) const
00149 { return hiBit(u) | loBits(v); }
00150 uint32 magic( const uint32 u ) const
00151 { return loBit(u) ? 0x9908b0dfUL : 0x0UL; }
00152 uint32 twist( const uint32 m, const uint32 s0, const uint32 s1 ) const
00153 { return m ^ (mixBits(s0,s1)>>1) ^ magic(s1); }
00154 static uint32 hash( time_t t, clock_t c );
00155 };
00156
00157
00158
00159 inline MersenneTwister::uint32 MersenneTwister::hash( time_t t, clock_t c )
00160 {
00161
00162
00163
00164
00165 static uint32 differ = 0;
00166
00167 uint32 h1 = 0;
00168 unsigned char *p = (unsigned char *) &t;
00169 for( size_t i = 0; i < sizeof(t); ++i )
00170 {
00171 h1 *= UCHAR_MAX + 2U;
00172 h1 += p[i];
00173 }
00174 uint32 h2 = 0;
00175 p = (unsigned char *) &c;
00176 for( size_t j = 0; j < sizeof(c); ++j )
00177 {
00178 h2 *= UCHAR_MAX + 2U;
00179 h2 += p[j];
00180 }
00181 return ( h1 + differ++ ) ^ h2;
00182 }
00183
00184 inline void MersenneTwister::initialize( const uint32 seed )
00185 {
00186
00187
00188
00189
00190 register uint32 *s = state;
00191 register uint32 *r = state;
00192 register int i = 1;
00193 *s++ = seed & 0xffffffffUL;
00194 for( ; i < N; ++i )
00195 {
00196 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
00197 r++;
00198 }
00199 }
00200
00201 inline void MersenneTwister::reload()
00202 {
00203
00204
00205 static const int MmN = int(M) - int(N);
00206 register uint32 *p = state;
00207 register int i;
00208 for( i = N - M; i--; ++p )
00209 *p = twist( p[M], p[0], p[1] );
00210 for( i = M; --i; ++p )
00211 *p = twist( p[MmN], p[0], p[1] );
00212 *p = twist( p[MmN], p[0], state[0] );
00213
00214 left = N, pNext = state;
00215 }
00216
00217 inline void MersenneTwister::seed( const uint32 oneSeed )
00218 {
00219
00220 initialize(oneSeed);
00221 reload();
00222 }
00223
00224 inline void MersenneTwister::seed( uint32 *const bigSeed, const uint32 seedLength )
00225 {
00226
00227
00228
00229
00230
00231
00232 initialize(19650218UL);
00233 register int i = 1;
00234 register uint32 j = 0;
00235 register int k = ( N > seedLength ? (int)N : (int)seedLength );
00236 for( ; k; --k )
00237 {
00238 state[i] =
00239 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
00240 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
00241 state[i] &= 0xffffffffUL;
00242 ++i; ++j;
00243 if( i >= N ) { state[0] = state[N-1]; i = 1; }
00244 if( j >= seedLength ) j = 0;
00245 }
00246 for( k = N - 1; k; --k )
00247 {
00248 state[i] =
00249 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
00250 state[i] -= i;
00251 state[i] &= 0xffffffffUL;
00252 ++i;
00253 if( i >= N ) { state[0] = state[N-1]; i = 1; }
00254 }
00255 state[0] = 0x80000000UL;
00256 reload();
00257 }
00258
00259 inline void MersenneTwister::seed()
00260 {
00261
00262
00263
00264
00265 FILE* urandom = fopen( "/dev/urandom", "rb" );
00266 if( urandom )
00267 {
00268 uint32 bigSeed[N];
00269 register uint32 *s = bigSeed;
00270 register int i = N;
00271 register bool success = true;
00272 while( success && i-- )
00273 success = fread( s++, sizeof(uint32), 1, urandom ) != 0;
00274 fclose(urandom);
00275 if( success ) { seed( bigSeed, N ); return; }
00276 }
00277
00278
00279 seed( hash( time(NULL), clock() ) );
00280 }
00281
00282 inline MersenneTwister::MersenneTwister( const uint32 oneSeed )
00283 { seed(oneSeed); }
00284
00285 inline MersenneTwister::MersenneTwister( uint32 *const bigSeed, const uint32 seedLength )
00286 { seed(bigSeed,seedLength); }
00287
00288 inline MersenneTwister::MersenneTwister()
00289 { seed(); }
00290
00291 inline MersenneTwister::MersenneTwister( const MersenneTwister& o ): Object(o)
00292 {
00293 register const uint32 *t = o.state;
00294 register uint32 *s = state;
00295 register int i = N;
00296 for( ; i--; *s++ = *t++ ) {}
00297 left = o.left;
00298 pNext = &state[N-left];
00299 }
00300
00301 inline MersenneTwister::uint32 MersenneTwister::randInt()
00302 {
00303
00304
00305
00306 if( left == 0 ) reload();
00307 --left;
00308
00309 register uint32 s1;
00310 s1 = *pNext++;
00311 s1 ^= (s1 >> 11);
00312 s1 ^= (s1 << 7) & 0x9d2c5680UL;
00313 s1 ^= (s1 << 15) & 0xefc60000UL;
00314 return ( s1 ^ (s1 >> 18) );
00315 }
00316
00317 inline MersenneTwister::uint32 MersenneTwister::randInt( const uint32 n )
00318 {
00319
00320
00321 uint32 used = n;
00322 used |= used >> 1;
00323 used |= used >> 2;
00324 used |= used >> 4;
00325 used |= used >> 8;
00326 used |= used >> 16;
00327
00328
00329 uint32 i;
00330 do
00331 i = randInt() & used;
00332 while( i > n );
00333 return i;
00334 }
00335
00336 inline double MersenneTwister::rand()
00337 { return double(randInt()) * (1.0/4294967295.0); }
00338
00339 inline double MersenneTwister::rand( const double n )
00340 { return rand() * n; }
00341
00342 inline double MersenneTwister::randExc()
00343 { return double(randInt()) * (1.0/4294967296.0); }
00344
00345 inline double MersenneTwister::randExc( const double n )
00346 { return randExc() * n; }
00347
00348 inline double MersenneTwister::randDblExc()
00349 { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
00350
00351 inline double MersenneTwister::randDblExc( const double n )
00352 { return randDblExc() * n; }
00353
00354 inline double MersenneTwister::rand53()
00355 {
00356 uint32 a = randInt() >> 5, b = randInt() >> 6;
00357 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
00358 }
00359
00360 inline double MersenneTwister::randNorm( const double mean, const double stddev )
00361 {
00362
00363
00364 double x, y, r;
00365 do
00366 {
00367 x = 2.0 * rand() - 1.0;
00368 y = 2.0 * rand() - 1.0;
00369 r = x * x + y * y;
00370 }
00371 while ( r >= 1.0 || r == 0.0 );
00372 double s = sqrt( -2.0 * log(r) / r );
00373 return mean + x * s * stddev;
00374 }
00375
00376 inline double MersenneTwister::operator()()
00377 {
00378 return rand();
00379 }
00380
00381 inline void MersenneTwister::save( uint32* saveArray ) const
00382 {
00383 register const uint32 *s = state;
00384 register uint32 *sa = saveArray;
00385 register int i = N;
00386 for( ; i--; *sa++ = *s++ ) {}
00387 *sa = left;
00388 }
00389
00390 inline void MersenneTwister::load( uint32 *const loadArray )
00391 {
00392 register uint32 *s = state;
00393 register uint32 *la = loadArray;
00394 register int i = N;
00395 for( ; i--; *s++ = *la++ ) {}
00396 left = *la;
00397 pNext = &state[N-left];
00398 }
00399
00400 inline std::ostream& operator<<( std::ostream& os, const MersenneTwister& mtrand )
00401 {
00402 register const MersenneTwister::uint32 *s = mtrand.state;
00403 register int i = mtrand.N;
00404 for( ; i--; os << *s++ << "\t" ) {}
00405 return os << mtrand.left;
00406 }
00407
00408 inline std::istream& operator>>( std::istream& is, MersenneTwister& mtrand )
00409 {
00410 register MersenneTwister::uint32 *s = mtrand.state;
00411 register int i = mtrand.N;
00412 for( ; i--; is >> *s++ ) {}
00413 is >> mtrand.left;
00414 mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
00415 return is;
00416 }
00417
00418 inline MersenneTwister& MersenneTwister::operator=( const MersenneTwister& o )
00419 {
00420 if( this == &o ) return (*this);
00421 register const uint32 *t = o.state;
00422 register uint32 *s = state;
00423 register int i = N;
00424 for( ; i--; *s++ = *t++ ) {}
00425 left = o.left;
00426 pNext = &state[N-left];
00427 return (*this);
00428 }
00429
00430 }
00431
00432 #endif // MERSENNETWISTER_H
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480