57 #ifndef __OMNETPP_MERSENNETWISTER_H
58 #define __OMNETPP_MERSENNETWISTER_H
74 typedef unsigned long uint32;
76 static const int N = 624;
77 static const int SAVE = N + 1;
80 static const int M = 397;
89 MTRand(
const uint32& oneSeed );
90 MTRand( uint32 *
const bigSeed, uint32
const seedLength = N );
99 double rand(
const double& n );
101 double randExc(
const double& n );
103 double randDblExc(
const double& n );
105 uint32 randInt(
const uint32& n );
106 double operator()() {
return rand(); }
112 double randNorm(
const double& mean = 0.0,
const double& variance = 0.0 );
115 void seed(
const uint32 oneSeed );
116 void seed( uint32 *
const bigSeed,
const uint32 seedLength = N );
120 void save( uint32* saveArray )
const;
121 void load( uint32 *
const loadArray );
122 friend std::ostream& operator<<( std::ostream& os,
const MTRand& mtrand );
123 friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
126 void initialize(
const uint32 oneSeed );
128 uint32 hiBit(
const uint32& u )
const {
return u & 0x80000000UL; }
129 uint32 loBit(
const uint32& u )
const {
return u & 0x00000001UL; }
130 uint32 loBits(
const uint32& u )
const {
return u & 0x7fffffffUL; }
131 uint32 mixBits(
const uint32& u,
const uint32& v )
const
132 {
return hiBit(u) | loBits(v); }
133 uint32 twist(
const uint32& m,
const uint32& s0,
const uint32& s1 )
const
134 {
return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
135 static uint32 hash( time_t t, clock_t c );
139 inline MTRand::MTRand(
const uint32& oneSeed )
142 inline MTRand::MTRand( uint32 *
const bigSeed,
const uint32 seedLength )
143 { seed(bigSeed,seedLength); }
145 inline MTRand::MTRand()
148 inline double MTRand::rand()
149 {
return double(randInt()) * (1.0/4294967295.0); }
151 inline double MTRand::rand(
const double& n )
152 {
return rand() * n; }
154 inline double MTRand::randExc()
155 {
return double(randInt()) * (1.0/4294967296.0); }
157 inline double MTRand::randExc(
const double& n )
158 {
return randExc() * n; }
160 inline double MTRand::randDblExc()
161 {
return (
double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
163 inline double MTRand::randDblExc(
const double& n )
164 {
return randDblExc() * n; }
166 inline double MTRand::rand53()
168 uint32 a = randInt() >> 5, b = randInt() >> 6;
169 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
172 inline double MTRand::randNorm(
const double& mean,
const double& variance )
176 double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
177 double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
178 return mean + r * cos(phi);
181 inline MTRand::uint32 MTRand::randInt()
186 if( left == 0 ) reload();
192 s1 ^= (s1 << 7) & 0x9d2c5680UL;
193 s1 ^= (s1 << 15) & 0xefc60000UL;
194 return ( s1 ^ (s1 >> 18) );
197 inline MTRand::uint32 MTRand::randInt(
const uint32& n )
211 i = randInt() & used;
217 inline void MTRand::seed(
const uint32 oneSeed )
225 inline void MTRand::seed( uint32 *
const bigSeed,
const uint32 seedLength )
233 initialize(19650218UL);
236 int k = ( N > seedLength ? N : seedLength );
240 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
241 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
242 state[i] &= 0xffffffffUL;
244 if( i >= N ) { state[0] = state[N-1]; i = 1; }
245 if( j >= seedLength ) j = 0;
247 for( k = N - 1; k; --k )
250 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
252 state[i] &= 0xffffffffUL;
254 if( i >= N ) { state[0] = state[N-1]; i = 1; }
256 state[0] = 0x80000000UL;
261 inline void MTRand::seed()
267 FILE* urandom = fopen(
"/dev/urandom",
"rb" );
274 while( success && i-- )
275 success = fread( s++,
sizeof(uint32), 1, urandom );
277 if( success ) { seed( bigSeed, N );
return; }
281 seed( hash( time(
nullptr), clock() ) );
285 inline void MTRand::initialize(
const uint32 seed )
294 *s++ = seed & 0xffffffffUL;
297 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
303 inline void MTRand::reload()
309 for( i = N - M; i--; ++p )
310 *p = twist( p[M], p[0], p[1] );
311 for( i = M; --i; ++p )
312 *p = twist( p[M-N], p[0], p[1] );
313 *p = twist( p[M-N], p[0], state[0] );
315 left = N, pNext = state;
319 inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
325 static uint32 differ = 0;
328 unsigned char *p = (
unsigned char *) &t;
329 for(
size_t i = 0; i <
sizeof(t); ++i )
331 h1 *= UCHAR_MAX + 2U;
335 p = (
unsigned char *) &c;
336 for(
size_t j = 0; j <
sizeof(c); ++j )
338 h2 *= UCHAR_MAX + 2U;
341 return ( h1 + differ++ ) ^ h2;
345 inline void MTRand::save( uint32* saveArray )
const
347 uint32 *sa = saveArray;
348 const uint32 *s = state;
350 for( ; i--; *sa++ = *s++ ) {}
355 inline void MTRand::load( uint32 *
const loadArray )
358 uint32 *la = loadArray;
360 for( ; i--; *s++ = *la++ ) {}
362 pNext = &state[N-left];
366 inline std::ostream& operator<<( std::ostream& os,
const MTRand& mtrand )
368 const MTRand::uint32 *s = mtrand.state;
370 for( ; i--; os << *s++ <<
"\t" ) {}
371 return os << mtrand.left;
375 inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
377 MTRand::uint32 *s = mtrand.state;
379 for( ; i--; is >> *s++ ) {}
381 mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
388 #endif // MERSENNETWISTER_H