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 #ifndef MERSENNETWISTER_H
00044 #define MERSENNETWISTER_H
00045
00046
00047
00048
00049 #include <iostream>
00050 #include <limits.h>
00051 #include <stdio.h>
00052
00053 class MTRand {
00054
00055 public:
00056 typedef unsigned long uint32;
00057
00058 enum { N = 624 };
00059 enum { SAVE = N + 1 };
00060
00061 protected:
00062 enum { M = 397 };
00063 enum { MAGIC = 0x9908b0dfU };
00064
00065 uint32 state[N];
00066 uint32 *pNext;
00067 int left;
00068
00069
00070
00071 public:
00072 MTRand( const uint32& oneSeed );
00073 MTRand( uint32 *const bigSeed );
00074 MTRand();
00075
00076
00077
00078
00079
00080 inline double rand();
00081 double rand( const double& n );
00082 double randExc();
00083 double randExc( const double& n );
00084 double randDblExc();
00085 double randDblExc( const double& n );
00086 inline uint32 randInt();
00087 uint32 randInt( const uint32& n );
00088 double operator()() { return rand(); }
00089
00090
00091 inline void seed( uint32 oneSeed );
00092 inline void seed( uint32 *const bigSeed );
00093 inline void seed();
00094
00095
00096 void save( uint32* saveArray ) const;
00097 void load( uint32 *const loadArray );
00098 friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
00099 friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
00100
00101 protected:
00102 inline void reload();
00103 uint32 hiBit( const uint32& u ) const { return u & 0x80000000U; }
00104 uint32 loBit( const uint32& u ) const { return u & 0x00000001U; }
00105 uint32 loBits( const uint32& u ) const { return u & 0x7fffffffU; }
00106 uint32 mixBits( const uint32& u, const uint32& v ) const
00107 { return hiBit(u) | loBits(v); }
00108 uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
00109 { return m ^ (mixBits(s0,s1)>>1) ^ (loBit(s1) ? MAGIC : 0U); }
00110 inline static uint32 hash( time_t t, clock_t c );
00111 };
00112
00113
00114 inline MTRand::MTRand( const uint32& oneSeed )
00115 { seed(oneSeed); }
00116
00117 inline MTRand::MTRand( uint32 *const bigSeed )
00118 { seed(bigSeed); }
00119
00120 inline MTRand::MTRand()
00121 { seed(); }
00122
00123 inline double MTRand::rand()
00124 { return double(randInt()) * 2.3283064370807974e-10; }
00125
00126 inline double MTRand::rand( const double& n )
00127 { return rand() * n; }
00128
00129 inline double MTRand::randExc()
00130 { return double(randInt()) * 2.3283064365386963e-10; }
00131
00132 inline double MTRand::randExc( const double& n )
00133 { return randExc() * n; }
00134
00135 inline double MTRand::randDblExc()
00136 { return double( 1.0 + randInt() ) * 2.3283064359965952e-10; }
00137
00138 inline double MTRand::randDblExc( const double& n )
00139 { return randDblExc() * n; }
00140
00141 inline MTRand::uint32 MTRand::randInt()
00142 {
00143 if( left == 0 ) reload();
00144 --left;
00145
00146 register uint32 s1;
00147 s1 = *pNext++;
00148 s1 ^= (s1 >> 11);
00149 s1 ^= (s1 << 7) & 0x9d2c5680U;
00150 s1 ^= (s1 << 15) & 0xefc60000U;
00151 return ( s1 ^ (s1 >> 18) );
00152 }
00153
00154
00155 inline MTRand::uint32 MTRand::randInt( const uint32& n )
00156 {
00157
00158 uint32 used = ~0;
00159 for( uint32 m = n; m; used <<= 1, m >>= 1 ) {}
00160 used = ~used;
00161
00162
00163 uint32 i;
00164 do
00165 i = randInt() & used;
00166 while( i > n );
00167 return i;
00168 }
00169
00170
00171 inline void MTRand::seed( uint32 oneSeed )
00172 {
00173
00174 register uint32 *s;
00175 register int i;
00176 for( i = N, s = state;
00177 i--;
00178 *s = oneSeed & 0xffff0000,
00179 *s++ |= ( (oneSeed *= 69069U)++ & 0xffff0000 ) >> 16,
00180 (oneSeed *= 69069U)++ ) {}
00181 reload();
00182 }
00183
00184
00185 inline void MTRand::seed( uint32 *const bigSeed )
00186 {
00187
00188
00189
00190
00191
00192
00193
00194 register uint32 *s = state, *b = bigSeed;
00195 register int i = N;
00196 for( ; i--; *s++ = *b++ & 0xffffffff ) {}
00197 reload();
00198 }
00199
00200
00201 inline void MTRand::seed()
00202 {
00203
00204
00205
00206
00207 FILE* urandom = fopen( "/dev/urandom", "rb" );
00208 if( urandom )
00209 {
00210 register uint32 *s = state;
00211 register int i = N;
00212 register bool success = true;
00213 while( success && i-- )
00214 {
00215 success = fread( s, sizeof(uint32), 1, urandom );
00216 *s++ &= 0xffffffff;
00217 }
00218 fclose(urandom);
00219 if( success )
00220 {
00221
00222
00223
00224 reload();
00225 return;
00226 }
00227 }
00228
00229
00230 seed( hash( time(NULL), clock() ) );
00231 }
00232
00233
00234 inline void MTRand::reload()
00235 {
00236
00237
00238 register uint32 *p = state;
00239 register int i;
00240 for( i = N - M; i--; ++p )
00241 *p = twist( p[M], p[0], p[1] );
00242 for( i = M; --i; ++p )
00243 *p = twist( p[M-N], p[0], p[1] );
00244 *p = twist( p[M-N], p[0], state[0] );
00245
00246 left = N, pNext = state;
00247 }
00248
00249
00250 inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
00251 {
00252
00253
00254
00255
00256 static uint32 differ = 0;
00257
00258 uint32 h1 = 0;
00259 unsigned char *p = (unsigned char *) &t;
00260 for( size_t i = 0; i < sizeof(t); ++i )
00261 {
00262 h1 *= UCHAR_MAX + 2U;
00263 h1 += p[i];
00264 }
00265 uint32 h2 = 0;
00266 p = (unsigned char *) &c;
00267 for( size_t j = 0; j < sizeof(c); ++j )
00268 {
00269 h2 *= UCHAR_MAX + 2U;
00270 h2 += p[j];
00271 }
00272 return ( h1 + differ++ ) ^ h2;
00273 }
00274
00275
00276 inline void MTRand::save( uint32* saveArray ) const
00277 {
00278 register uint32 *sa = saveArray;
00279 register const uint32 *s = state;
00280 register int i = N;
00281 for( ; i--; *sa++ = *s++ ) {}
00282 *sa = left;
00283 }
00284
00285
00286 inline void MTRand::load( uint32 *const loadArray )
00287 {
00288 register uint32 *s = state;
00289 register uint32 *la = loadArray;
00290 register int i = N;
00291 for( ; i--; *s++ = *la++ ) {}
00292 left = *la;
00293 pNext = &state[N-left];
00294 }
00295
00296
00297 inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
00298 {
00299 register const MTRand::uint32 *s = mtrand.state;
00300 register int i = mtrand.N;
00301 for( ; i--; os << *s++ << "\t" ) {}
00302 return os << mtrand.left;
00303 }
00304
00305
00306 inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
00307 {
00308 register MTRand::uint32 *s = mtrand.state;
00309 register int i = mtrand.N;
00310 for( ; i--; is >> *s++ ) {}
00311 is >> mtrand.left;
00312 mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
00313 return is;
00314 }
00315
00316 #endif //MERSENNETWISTER_H
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344