00001 #ifndef Random_H
00002 #define Random_H
00003
00024 #include <cmath>
00025 #include <unistd.h>
00026 #include <fcntl.h>
00027
00029
00041
00042
00052 class MTRand {
00053 public:
00057 MTRand(const unsigned long &oneSeed) {setSeed(oneSeed);}
00058
00060
00061 void setSeed(unsigned long seed);
00062
00064 void randomize();
00065
00067
00068
00069 virtual double mean() const = 0;
00071 virtual double variance() const = 0;
00073 virtual double stdDev() const = 0;
00075
00076 private:
00077 typedef unsigned long uint32;
00078
00079 protected:
00082 double rand() {return double(randInt()) * 2.3283064370807974e-10;}
00083
00086 uint32 randInt();
00090 uint32 randInt(const uint32 &n);
00091
00092 private:
00093 enum {N = 624, M = 397, MAGIC = 0x9908b0dfU};
00094
00095 uint32 state[N];
00096 uint32 *pNext;
00097 int left;
00098
00099 void reload();
00100
00101 uint32 hiBit(const uint32 &u) const {return u & 0x80000000U;}
00102 uint32 loBit(const uint32 &u) const {return u & 0x00000001U;}
00103 uint32 loBits(const uint32 &u) const {return u & 0x7fffffffU;}
00104 uint32 mixBits(const uint32 &u, const uint32 &v) const {
00105 return hiBit(u) | loBits(v);}
00106 uint32 twist(const uint32 &m, const uint32 &s0, const uint32 &s1) const {
00107 return m ^ (mixBits(s0,s1)>>1) ^ (loBit(s1) ? MAGIC : 0U);}
00108
00109
00110 MTRand(const MTRand &mtrand);
00111 MTRand &operator=(const MTRand &mtrand);
00112 };
00113
00114
00116
00123 class RealRandom : public MTRand {
00124 public:
00128 RealRandom(const unsigned long seed) :MTRand(seed) {}
00129
00131
00132
00133
00139 RealRandom &operator>>(double &random_number) {
00140 random_number = number(); return *this;}
00142
00145 double operator()() {return number();}
00147
00152 operator double() {return number();}
00153
00155
00159 virtual double number() = 0;
00161
00163
00164 virtual double mean() const = 0;
00165 virtual double variance() const = 0;
00166 virtual double stdDev() const = 0;
00168 };
00169
00170
00172
00179 class IntegerRandom : public MTRand {
00180 public:
00184 IntegerRandom(const unsigned long seed) :MTRand(seed) {}
00185
00187
00188
00189
00194 IntegerRandom &operator>>(int &random_number) {
00195 random_number = number(); return *this;}
00197
00200 int operator()() {return number();}
00202
00207 operator int() {return number();}
00208
00210
00214 virtual int number() = 0;
00216
00218
00219 virtual double mean() const = 0;
00220 virtual double variance() const = 0;
00221 virtual double stdDev() const = 0;
00223 };
00224
00225
00227
00235 class UniformRandomSimple : public RealRandom {
00236 public:
00240 UniformRandomSimple(const unsigned long seed = 1UL) :RealRandom(seed) {}
00241
00243
00244 double number() {return MTRand::rand();}
00246
00248
00249 double mean() const {return 0.5;}
00250 double variance() const {return (1.0 / 12.0);}
00251 double stdDev() const {return sqrt(1.0 / 12.0);}
00253 };
00254
00255
00257
00264 class UniformRandom : public RealRandom {
00265 public:
00281 UniformRandom(const double low = 1.0, const double high = 0.0,
00282 const unsigned long seed = 1UL)
00283 :RealRandom(seed), m_low((low < high)?low:high),
00284 m_range((low < high)?(high - low):(low - high)) {}
00285
00287
00288 double number() {return (MTRand::rand() * m_range) + m_low;}
00290
00292
00293 double mean() const {return ((m_range / 2.0) + m_low);}
00294 double variance() const {return ((m_range * m_range) / 12.0);}
00295 double stdDev() const {return sqrt(variance());}
00297
00299
00300
00301 double lowValue() const {return m_low;}
00303 double highValue() const {return (m_low + m_range);}
00305 double range() const {return m_range;}
00307
00309
00310
00312 void setLowValue(const double low) {m_low = low;}
00315 void setHighValue(const double high) {m_range = high - m_low;}
00319 void setValues(const double low, const double high) {
00320 setLowValue(low); setHighValue(high);}
00322
00323 private:
00324 double m_low;
00325 double m_range;
00326 };
00327
00328
00330
00338 class NormalRandom : public RealRandom {
00339 public:
00346 NormalRandom(const double mean = 0.0, const double variance = 1.0,
00347 const unsigned long seed = 1UL)
00348 :RealRandom(seed), m_mean(mean), m_std_dev(sqrt(fabs(variance))) {}
00349
00351
00352 double number();
00354
00356
00357 double mean() const {return m_mean;}
00358 double variance() const {return (m_std_dev * m_std_dev);}
00359 double stdDev() const {return m_std_dev;}
00361
00363
00364
00366 void setMean(const double mean) {m_mean = mean;}
00369 void setVariance(const double variance) {m_std_dev = sqrt(fabs(variance));}
00372 void setStdDev(const double std_dev) {m_std_dev = fabs(std_dev);}
00376 void setParameters(const double mean, const double variance) {
00377 setMean(mean); setVariance(variance);}
00379
00380 private:
00381 double m_mean;
00382 double m_std_dev;
00383 };
00384
00385
00387
00393 class ExponentialRandom : public RealRandom {
00394 public:
00400 ExponentialRandom(const double lambda = 1.0, const unsigned long seed = 1UL)
00401 :RealRandom(seed), m_lambda(lambda) {}
00402
00404
00405 double number();
00407
00409
00410 double mean() const {return (1.0 / m_lambda);}
00411 double variance() const {return (1.0 / (m_lambda * m_lambda));}
00412 double stdDev() const {return (1.0 / m_lambda);}
00414
00416
00417
00418 double lambda() const {return m_lambda;}
00420
00422
00423
00425 void setMean(const double mean) {m_lambda = (1.0 / mean);}
00428 void setVariance(const double variance) {m_lambda = sqrt(1.0 / variance);}
00431 void setStdDev(const double std_dev) {m_lambda = (1.0 / std_dev);}
00434 void setLambda(const double lambda) {m_lambda = lambda;}
00438 void setParameters(const double mean, const double variance) {
00439 setMean(mean); setVariance(variance);}
00441
00442 private:
00443 double m_lambda;
00444 };
00445
00446
00448
00454 class DiscreteUniformRandom : public IntegerRandom {
00455 public:
00464 DiscreteUniformRandom(const int low, const int high,
00465 const unsigned long seed = 1UL)
00466 :IntegerRandom(seed), m_low((low < high)?low:high),
00467 m_range((unsigned long)((low < high)?(high - low):(low - high))) {}
00475 DiscreteUniformRandom(const int range, const unsigned long seed = 1UL)
00476 :IntegerRandom(seed), m_low(0), m_range(range - 1) {}
00477
00479
00480 int number() {return MTRand::randInt(m_range) + m_low;}
00482
00484
00485 double mean() const {return (((double)m_range / 2.0));}
00486 double variance() const {return ((double)(m_range * m_range) / 12.0);}
00487 double stdDev() const {return sqrt(variance());}
00489
00491
00492
00493 int lowValue() const {return m_low;}
00495 int highValue() const {return (m_low + m_range);}
00497 int range() const {return m_range + 1;}
00499
00501
00502
00504 void setLowValue(const int low) {m_low = low;}
00507 void setHighValue(const int high) {m_range = (unsigned long)(high - m_low);}
00511 void setValues(const int low, const int high) {
00512 setLowValue(low); setHighValue(high);}
00514
00515 private:
00516 int m_low;
00517 unsigned long m_range;
00518 };
00519
00520
00522
00528 class BernoulliRandom : public IntegerRandom {
00529 public:
00535 BernoulliRandom(const double success = 0.5, const unsigned long seed = 1UL)
00536 :IntegerRandom(seed), m_success(success) {}
00537
00539
00540 int number() {return (rand() <= m_success)?1:0;}
00542
00544
00545 double mean() const {return m_success;}
00546 double variance() const {return (m_success * (1.0 - m_success));}
00547 double stdDev() const {return sqrt(variance());}
00549
00551
00552
00553 double success() const {return m_success;}
00555 double probSuccess() const {return success();}
00557 double failure() const {return (1.0 - m_success);}
00559 double probFailure() const {return failure();}
00561
00563
00564
00566 void setProbSuccess(const double success) {m_success = success;}
00569 void setProbFailure(const double failure) {m_success = 1.0 - failure;}
00571
00572 private:
00573 double m_success;
00574 };
00575
00576
00577
00578
00579
00580
00581 inline MTRand::uint32 MTRand::randInt() {
00582 if(left == 0)
00583 reload();
00584 --left;
00585
00586 register uint32 s1;
00587 s1 = *pNext++;
00588 s1 ^= (s1 >> 11);
00589 s1 ^= (s1 << 7) & 0x9d2c5680U;
00590 s1 ^= (s1 << 15) & 0xefc60000U;
00591 return (s1 ^ (s1 >> 18));
00592 }
00593
00594
00595 inline MTRand::uint32 MTRand::randInt(const uint32 &n) {
00596
00597
00598
00599 long int used = ~0;
00600 for(uint32 m = n; m; used <<= 1, m >>= 1 ) {}
00601 used = ~used;
00602
00603
00604 uint32 i;
00605 do
00606 i = randInt() & used;
00607 while(i > n);
00608 return i;
00609 }
00610
00611
00612 inline void MTRand::setSeed(unsigned long seed) {
00613
00614 register uint32 *s;
00615 register int i;
00616 for(i = N, s = state; i--;
00617 *s = seed & 0xffff0000,
00618 *s++ |= ((seed *= 69069U)++ & 0xffff0000) >> 16,
00619 (seed *= 69069U)++) {}
00620 reload();
00621 }
00622
00623
00624 inline void MTRand::randomize() {
00625 unsigned long seed_number;
00626
00627 int fp = open("/dev/urandom", O_RDONLY);
00628 read(fp, &seed_number, sizeof(seed_number));
00629 close(fp);
00630
00631 MTRand::setSeed(seed_number);
00632 }
00633
00634
00635
00636 inline void MTRand::reload() {
00637
00638
00639 register uint32 *p = state;
00640 register int i;
00641 for(i = N - M; i--;) {
00642
00643 *p = twist(p[M], p[0], p[1]);
00644 p++;
00645 }
00646 for(i = M; --i;) {
00647
00648 *p = twist(p[M-N], p[0], p[1]);
00649 p++;
00650 }
00651 *p = twist(p[M-N], p[0], state[0]);
00652 left = N, pNext = state;
00653 }
00654
00655
00656
00657
00658
00659 inline double NormalRandom::number() {
00660 double theta = 2.0 * M_PI * MTRand::rand();
00661 double r = sqrt(-2.0 * log(MTRand::rand()));
00662
00663 return ((m_std_dev * r * cos(theta)) + m_mean);
00664 }
00665
00666
00667 #endif