18 #ifndef _RANDOMSTREAM_H 19 #define _RANDOMSTREAM_H 31 typedef unsigned long uint32;
34 enum { SAVE = N + 1 };
46 MTRand(
const uint32& oneSeed );
47 MTRand( uint32 *
const bigSeed, uint32
const seedLength = N );
56 double rand(
const double& n );
58 double randExc(
const double& n );
60 double randDblExc(
const double& n );
62 uint32 randInt(
const uint32& n );
63 double operator()() {
return rand(); }
69 double randNorm(
const double& mean = 0.0,
const double& variance = 1.0 );
72 void seed(
const uint32 oneSeed );
73 void seed( uint32 *
const bigSeed,
const uint32 seedLength = N );
77 void save( uint32* saveArray )
const;
78 void load( uint32 *
const loadArray );
79 friend std::ostream& operator<<( std::ostream& os,
const MTRand& mtrand );
80 friend std::istream& operator>>( std::istream& is,
MTRand& mtrand );
83 void initialize(
const uint32 oneSeed );
85 uint32 hiBit(
const uint32& u )
const {
return u & 0x80000000UL; }
86 uint32 loBit(
const uint32& u )
const {
return u & 0x00000001UL; }
87 uint32 loBits(
const uint32& u )
const {
return u & 0x7fffffffUL; }
88 uint32 mixBits(
const uint32& u,
const uint32& v )
const {
89 return hiBit(u) | loBits(v);
91 uint32 twist(
const uint32& m,
const uint32& s0,
const uint32& s1 )
const {
92 return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL);
94 static uint32 hash( time_t t, clock_t c );
98 inline MTRand::MTRand(
const uint32& oneSeed )
101 inline MTRand::MTRand( uint32 *
const bigSeed,
const uint32 seedLength )
102 { seed(bigSeed,seedLength); }
104 inline MTRand::MTRand()
107 inline double MTRand::rand()
108 {
return double(randInt()) * (1.0/4294967295.0); }
110 inline double MTRand::rand(
const double& n )
111 {
return rand() * n; }
113 inline double MTRand::randExc()
114 {
return double(randInt()) * (1.0/4294967296.0); }
116 inline double MTRand::randExc(
const double& n )
117 {
return randExc() * n; }
119 inline double MTRand::randDblExc()
120 {
return (
double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
122 inline double MTRand::randDblExc(
const double& n )
123 {
return randDblExc() * n; }
125 inline double MTRand::rand53()
127 uint32 a = randInt() >> 5, b = randInt() >> 6;
128 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
131 inline double MTRand::randNorm(
const double& mean,
const double& variance )
135 double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
136 double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
137 return mean + r * cos(phi);
140 inline MTRand::uint32 MTRand::randInt()
145 if( left == 0 ) reload();
151 s1 ^= (s1 << 7) & 0x9d2c5680UL;
152 s1 ^= (s1 << 15) & 0xefc60000UL;
153 return ( s1 ^ (s1 >> 18) );
156 inline MTRand::uint32 MTRand::randInt(
const uint32& n )
170 i = randInt() & used;
176 inline void MTRand::seed(
const uint32 oneSeed )
184 inline void MTRand::seed( uint32 *
const bigSeed,
const uint32 seedLength )
192 initialize(19650218UL);
193 const unsigned int Nenum = N;
196 int k = ( Nenum > seedLength ? Nenum : seedLength );
200 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
201 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
202 state[i] &= 0xffffffffUL;
204 if( i >= N ) { state[0] = state[N-1]; i = 1; }
205 if( j >= seedLength ) j = 0;
207 for( k = N - 1; k; --k )
210 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
212 state[i] &= 0xffffffffUL;
214 if( i >= N ) { state[0] = state[N-1]; i = 1; }
216 state[0] = 0x80000000UL;
221 inline void MTRand::seed()
227 FILE* urandom = fopen(
"/dev/urandom",
"rb" );
234 while( success && i-- )
235 success = fread( s++,
sizeof(uint32), 1, urandom );
237 if( success ) { seed( bigSeed, N );
return; }
241 seed( hash( time(NULL), clock() ) );
245 inline void MTRand::initialize(
const uint32 intseed )
254 *s++ = intseed & 0xffffffffUL;
257 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
263 inline void MTRand::reload()
269 for( i = N - M; i--; ++p )
270 *p = twist( p[M], p[0], p[1] );
271 for( i = M; --i; ++p )
272 *p = twist( p[M-N], p[0], p[1] );
273 *p = twist( p[M-N], p[0], state[0] );
275 left = N, pNext = state;
279 inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
285 static uint32 differ = 0;
288 unsigned char *p = (
unsigned char *) &t;
289 for(
size_t i = 0; i <
sizeof(t); ++i )
291 h1 *= std::numeric_limits<unsigned char>::max() + 2U;
295 p = (
unsigned char *) &c;
296 for(
size_t j = 0; j <
sizeof(c); ++j )
298 h2 *= std::numeric_limits<unsigned char>::max() + 2U;
301 return ( h1 + differ++ ) ^ h2;
305 inline void MTRand::save( uint32* saveArray )
const 307 uint32 *sa = saveArray;
308 const uint32 *s = state;
310 for( ; i--; *sa++ = *s++ ) {}
315 inline void MTRand::load( uint32 *
const loadArray )
318 uint32 *la = loadArray;
320 for( ; i--; *s++ = *la++ ) {}
322 pNext = &state[N-left];
326 inline std::ostream& operator<<( std::ostream& os,
const MTRand& mtrand )
328 const MTRand::uint32 *s = mtrand.state;
330 for( ; i--; os << *s++ <<
"\t" ) {}
331 return os << mtrand.left;
335 inline std::istream& operator>>( std::istream& is,
MTRand& mtrand )
337 MTRand::uint32 *s = mtrand.state;
339 for( ; i--; is >> *s++ ) {}
341 mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
354 inline float getFloat (
void ) {
return (
float)mtr.rand(); };
356 inline float getFloat(
float min,
float max ) {
return mtr.rand(max-min) + min; };
357 inline float getRandNorm(
float mean,
float var) {
return mtr.randNorm(mean, var); };
359 #if FLOATINGPOINT_PRECISION==1 360 inline Real getReal() {
return getFloat(); }
363 inline Real getReal() {
return getDouble(); }
366 inline Vec3 getVec3 () { Real a=getReal(), b=getReal(), c=getReal();
return Vec3(a,b,c); }
Definition: commonkernels.h:22
double getDouble(void)
Definition: randomstream.h:353
Definition: randomstream.h:346
Definition: randomstream.h:28
S normalize(Vector3D< S > &v)
Compute the norm of the vector and normalize it.
Definition: randomstream.h:408