115 lines
3.5 KiB
C++
115 lines
3.5 KiB
C++
#pragma once
|
|
|
|
/* Mersenne Twister rng. */
|
|
class MTRand_int32 {
|
|
public:
|
|
/* The default constructor uses default seed only if this is the first instance. */
|
|
MTRand_int32(void) { seed(5489UL); }
|
|
/* Constructor with 32 bit int as seed. */
|
|
MTRand_int32(unsigned long s) { seed(s); }
|
|
/* Consstructor with array of size 32 bit ints as seed. */
|
|
MTRand_int32(const unsigned long* array, int size) { seed(array, size); }
|
|
|
|
void seed(unsigned long); /* Seed with 32 bit integer. */
|
|
void seed(const unsigned long*, int size); /* Seed with array. */
|
|
|
|
virtual ~MTRand_int32(void) { }
|
|
protected: /* Used by derived classes, otherwise not accessible; use the ()-operator. */
|
|
unsigned long rand_int32(void);
|
|
private:
|
|
unsigned long operator()() { return rand_int32(); }
|
|
static const int n = 624, m = 397; /* Compile time constants. */
|
|
|
|
/* Static: */
|
|
unsigned long state[n]; /* State vector array. */
|
|
int p; /* Position in array state. */
|
|
|
|
/* Generate the pseudo random numbers. */
|
|
unsigned long twiddle(unsigned long, unsigned long);
|
|
void gen_state(void);
|
|
|
|
/* Doesn't make much sense having a copy or assignment operator laying around. */
|
|
MTRand_int32(const MTRand_int32&);
|
|
void operator=(const MTRand_int32&);
|
|
};
|
|
|
|
/* Inline for speed, must therefore reside in header. */
|
|
inline unsigned long MTRand_int32::twiddle(unsigned long u, unsigned long v) {
|
|
return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1)
|
|
^ ((v & 1UL) ? 0x9908B0DFUL : 0x0UL);
|
|
}
|
|
|
|
/* Generate 32 bit random int. */
|
|
inline unsigned long MTRand_int32::rand_int32(void) {
|
|
if(p == n) gen_state(); /* New state vector needed. */
|
|
/* gen_state() is split off to be non-inline, because it is only called once
|
|
* in every 624 calls, otherwise irand() would become too big to get inlined.
|
|
*/
|
|
unsigned long x = state[p++];
|
|
x ^= (x >> 11);
|
|
x ^= (x << 7) & 0x9D2C5680UL;
|
|
x ^= (x << 15) & 0xEFC60000UL;
|
|
return x ^ (x>>18);
|
|
}
|
|
|
|
class MTRand : public MTRand_int32 {
|
|
public:
|
|
MTRand(void) : MTRand_int32() {}
|
|
MTRand(unsigned int long seed) : MTRand_int32(seed) {}
|
|
MTRand(const unsigned long* seed, int size) : MTRand_int32(seed, size) {}
|
|
~MTRand(void) {}
|
|
|
|
double NDouble(int p) {
|
|
double o = Double(1.0);
|
|
while(--p) o *= Double(1.0);
|
|
return o;
|
|
}
|
|
|
|
double Double(double min, double max) {
|
|
return Double(max-min)+min;
|
|
}
|
|
|
|
/* Interval [0, 1]. */
|
|
double Double(double max) {
|
|
/* Divided by 2^32 */
|
|
return max*static_cast<double>(rand_int32()) * (1./4294967296.);
|
|
}
|
|
|
|
/* Interval [0, 1]. */
|
|
double Double(void) {
|
|
/* Divided by 2^32. */
|
|
return static_cast<double>(rand_int32()) * (1./4294967296.);
|
|
}
|
|
|
|
/* [0, 1] */
|
|
double Double_closed(void) {
|
|
/* Divided by 2^32 - 1. */
|
|
return static_cast<double>(rand_int32()) * (1./4294967295.);
|
|
}
|
|
|
|
/* [0, 1]. */
|
|
double Double_open(void) {
|
|
/* Divided by 2^32. */
|
|
return (static_cast<double>(rand_int32()) + .5) * (1./4294967296.);
|
|
}
|
|
|
|
/* Generates 53 bit resolution doubles in the half-open interval [0, 1]. */
|
|
double Double53(void) {
|
|
return (static_cast<double>(rand_int32() >> 5) * 67108864. +
|
|
static_cast<double>(rand_int32() >> 6)) * (1./9007199254740992.);
|
|
}
|
|
/* [min,max] */
|
|
unsigned int Int32(int min, int max) {
|
|
return (rand_int32()%(1+max-min))+min;
|
|
}
|
|
|
|
/* [0,max] */
|
|
unsigned int Int32(int max) { return rand_int32()%max; }
|
|
unsigned int Int32(void) { return rand_int32(); }
|
|
private:
|
|
/* Copy and assignment operators not defined. */
|
|
MTRand(const MTRand&);
|
|
void operator=(const MTRand&);
|
|
};
|
|
|