Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Random.h

Go to the documentation of this file.
00001 /* SimData: Data Infrastructure for Simulations
00002  * Copyright (C) 2002, 2003 Mark Rose <tm2@stm.lbl.gov>
00003  * 
00004  * This file is part of SimData.
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  */
00020 
00021 
00047 #ifndef __SIMDATA_RANDOM_H__
00048 #define __SIMDATA_RANDOM_H__
00049 
00050 
00051 #include <cmath>
00052 #include <SimData/Ref.h>
00053 #include <SimData/Export.h>
00054 
00055 
00056 NAMESPACE_SIMDATA
00057 
00058 
00060 // Random Number Generators
00061 
00062 namespace rng { // random number generators
00063 
00110 class SIMDATA_EXPORT MT19937 {
00111         static const int N = 624;       /* Period parameters */
00112         static const int M = 397;
00113 
00114         // most significant w-r bits
00115         static const unsigned long UPPER_MASK = 0x80000000UL;   
00116 
00117         // least significant r bits 
00118         static const unsigned long LOWER_MASK = 0x7fffffffUL;   
00119 
00120         // state
00121         unsigned long _mt[N];
00122         int _mti;
00123 
00124         static inline unsigned long MAGIC(unsigned long y) {
00125                 return (((y)&0x1) ? 0x9908b0dfUL : 0);
00126         }
00127 
00130         void update();
00131         
00137         inline unsigned long generate() {
00138                 if (_mti >= N) update(); // generate N words at one time
00139                 unsigned long k = _mt[_mti];
00140                 k ^= (k >> 11);
00141                 k ^= (k << 7) & 0x9d2c5680UL;
00142                 k ^= (k << 15) & 0xefc60000UL;
00143                 k ^= (k >> 18);
00144                 _mti++;
00145                 return k;
00146         }
00147 
00148 public:
00151         struct State {
00152                 unsigned long _mt[N];
00153                 int _mti;
00154         };
00155 
00158         inline std::string getName() const { return "Mersenne Twister (MT19937)"; }
00159 
00162         MT19937() { setSeed(0); }
00163 
00170         template <typename T>
00171         inline T uniformInt(T lower, T upper) {
00172                 return lower + static_cast<T>(unit() * (upper-lower));
00173         }
00174 
00177         template <typename T>
00178         inline T uniformInt(T upper) {
00179                 return uniformInt(static_cast<T>(0), upper);
00180         }
00181 
00184         inline double unit() {
00185                 return generate() / 4294967296.0 ;
00186         };
00187 
00190         inline double uniform(double lower, double upper) {
00191                 return lower + unit() * (upper-lower);
00192         }
00193 
00198         void setSeed(unsigned long int s);
00199 
00204         void getState(State &state) const;
00205 
00211         void setState(State const &state);
00212 };
00213 
00214 
00215 
00216 
00285 class SIMDATA_EXPORT Taus2 {
00286         // state
00287         unsigned long int _s1, _s2, _s3;
00288 
00289         static const unsigned long int MASK = 0xffffffffUL;
00290 
00291         inline static unsigned long int LCG(unsigned long int n) {
00292                 return ((69069 * n) & 0xffffffffUL);
00293         }
00294 
00295         inline static unsigned long int TAUSWORTHE(unsigned long int s,
00296                                                    unsigned long int a,
00297                                                    unsigned long int b,
00298                                                    unsigned long int c,
00299                                                    unsigned long int d) {
00300                 return (((s &c) <<d) &MASK) ^ ((((s <<a) &MASK)^s) >>b);
00301         }
00302 
00306         inline unsigned long generate() {
00307                 _s1 = TAUSWORTHE(_s1, 13, 19, 4294967294UL, 12);
00308                 _s2 = TAUSWORTHE(_s2, 2, 25, 4294967288UL, 4);
00309                 _s3 = TAUSWORTHE(_s3, 3, 11, 4294967280UL, 17);
00310                 return (_s1 ^ _s2 ^ _s3);
00311         }
00312 public:
00315         struct State {
00316                 unsigned long int _s1, _s2, _s3;
00317         };
00318 
00321         inline std::string getName() const { return "Tausworthe (Taus2)"; }
00322 
00325         Taus2() { setSeed(0); }
00326 
00333         template <typename T>
00334         inline T uniformInt(T lower, T upper) {
00335                 return lower + static_cast<T>(unit() * (upper-lower));
00336         }
00337 
00340         template <typename T>
00341         inline T uniformInt(T upper) {
00342                 return uniformInt(static_cast<T>(0), upper);
00343         }
00344 
00347         inline double unit() {
00348                 return generate() / 4294967296.0 ;
00349         };
00350 
00353         inline double uniform(double lower, double upper) {
00354                 return lower + unit() * (upper-lower);
00355         }
00356 
00361         void setSeed(unsigned long int s);
00362 
00367         void getState(State &state) const;
00368 
00374         void setState(State const &state);
00375 };
00376 
00377 
00378 } // namespace rng
00379 
00380 
00381 
00383 // Random Number Generator Wrappers
00384 
00387 class SIMDATA_EXPORT RandomInterface {
00388 protected:
00391         struct _State: Referenced { };
00392 public:
00393         typedef Ref<_State> State;
00394         typedef unsigned long int SeedType;
00395 
00396         virtual ~RandomInterface();
00397 
00400         virtual void setSeed(SeedType seed)=0;
00401         
00404         virtual State getState() const=0;
00405 
00408         virtual void setState(State const &state)=0;
00409 
00412         virtual std::string getName() const=0;
00413 };
00414 
00415 
00418 class SIMDATA_EXPORT RandomNumberGeneratorInterface: public RandomInterface {
00419 public:
00422         virtual double unit()=0;
00423 
00426         virtual double uniform(double lower, double upper)=0;
00427         
00430         virtual long uniformInt(long lower, long upper)=0;
00431 
00434         virtual long uniformInt(long upper)=0;
00435 
00438         virtual unsigned long uniformUInt(unsigned long lower, unsigned long upper)=0;
00439 
00442         virtual unsigned long uniformUInt(unsigned long upper)=0;
00443 };
00444 
00453 template <class RNG>
00454 class RandomNumberGenerator: public RandomNumberGeneratorInterface {
00455 
00458         struct RNGState: _State {
00459                 typename RNG::State _state;
00460         };
00461         RNG _gen;
00462 public:
00467         virtual void setSeed(SeedType seed);
00468 
00473         virtual State getState() const;
00474 
00480         virtual void setState(State const &);
00481 
00484         virtual double unit();
00485 
00488         virtual double uniform(double, double);
00489 
00496         virtual long uniformInt(long lower, long upper);
00497 
00500         virtual long uniformInt(long upper);
00501 
00508         virtual unsigned long uniformUInt(unsigned long lower, unsigned long upper);
00509 
00512         virtual unsigned long uniformUInt(unsigned long upper);
00513 
00516         virtual std::string getName() const;
00517 
00523         inline RNG *operator->() { return &_gen; }
00524 };
00525 
00526 
00527 template <class RNG>
00528 RandomInterface::State RandomNumberGenerator<RNG>::getState() const {
00529         RNGState *rng_state = new RNGState;
00530         _gen.getState(rng_state->_state);
00531         return rng_state;
00532 }
00533 
00534 template <class RNG>
00535 void RandomNumberGenerator<RNG>::setState(RandomInterface::State const &state) {
00536         Ref<RNGState> rng_state = state;
00537         _gen.setState(rng_state->_state);
00538 }
00539 
00540 template <class RNG>
00541 void RandomNumberGenerator<RNG>::setSeed(RandomInterface::SeedType seed) {
00542         _gen.setSeed(seed);
00543 }
00544 
00545 template <class RNG>
00546 double RandomNumberGenerator<RNG>::unit() {
00547         return _gen.unit();
00548 }
00549 
00550 template <class RNG>
00551 double RandomNumberGenerator<RNG>::uniform(double low, double high) {
00552         return _gen.uniform(low, high);
00553 }
00554 
00555 template <class RNG>
00556 long RandomNumberGenerator<RNG>::uniformInt(long low, long high) {
00557         return _gen.uniformInt(low, high);
00558 }
00559 
00560 template <class RNG>
00561 long RandomNumberGenerator<RNG>::uniformInt(long high) {
00562         return _gen.uniformInt(high);
00563 }
00564 
00565 template <class RNG>
00566 unsigned long RandomNumberGenerator<RNG>::uniformUInt(unsigned long low, unsigned long high) {
00567         return _gen.uniformInt(low, high);
00568 }
00569 
00570 template <class RNG>
00571 unsigned long RandomNumberGenerator<RNG>::uniformUInt(unsigned long high) {
00572         return _gen.uniformInt(high);
00573 }
00574 
00575 template <class RNG>
00576 std::string RandomNumberGenerator<RNG>::getName() const { 
00577         return _gen.getName(); 
00578 }
00579 
00580 
00582 // Random Distributions
00583 
00584 namespace rd { // random distributions
00585 
00588 class SIMDATA_EXPORT Gauss {
00589         rng::Taus2 _gen;
00590         double _mean, _sigma;
00591         double _x;
00592         bool _odd;
00593 public:
00594 
00597         struct State {
00598                 rng::Taus2::State _state;
00599                 double _mean, _sigma, _x;
00600                 bool _odd;
00601         };
00602 
00605         std::string getName() const { return "Gaussian (Gauss)"; }
00606 
00612         Gauss(double mean=0.0, double sigma=0.0): _mean(mean), _sigma(sigma), _odd(true) {}
00613 
00619         inline void setDistribution(double mean, double sigma) {
00620                 _mean = mean;
00621                 _sigma = sigma;
00622         }
00623 
00626         inline double getMean() const { return _mean; }
00627 
00630         inline double getSigma() const { return _sigma; }
00631 
00634         double sample();
00635 
00640         inline void setSeed(unsigned long int seed) { _gen.setSeed(seed); _odd = true; }
00641 
00648         void getState(State &) const;
00649 
00656         void setState(State const &);
00657 };
00658 
00659 
00660 extern SIMDATA_EXPORT double BoxMueller(RandomNumberGeneratorInterface &_gen, double _mean, double _sigma);
00661 
00662 } // namespace rd
00663 
00664 
00665 
00667 // Random Distribution Wrappers
00668 
00669 
00672 class SIMDATA_EXPORT RandomDistributionInterface: public RandomInterface {
00673 public:
00676         virtual double sample()=0;
00677 };
00678 
00679 
00680 
00687 template <class RD>
00688 class RandomDistribution: public RandomDistributionInterface {
00691         struct RDState: _State {
00692                 typename RD::State _state;
00693         };
00694         RD _dist;
00695 public:
00698         double sample();
00699 
00704         virtual void setSeed(SeedType seed);
00705 
00710         virtual State getState() const;
00711 
00717         virtual void setState(State const &);
00718 
00721         virtual std::string getName() const;
00722 
00728         inline RD *operator->() { return &_dist; }
00729 };
00730 
00731 
00732 template <class RD>
00733 double RandomDistribution<RD>::sample() {
00734         return _dist.sample();
00735 }
00736 
00737 template <class RD>
00738 RandomInterface::State RandomDistribution<RD>::getState() const { 
00739         RDState *rd_state = new RDState;
00740         _dist.getState(rd_state->_state);
00741         return rd_state;
00742 }
00743 
00744 template <class RD>
00745 void RandomDistribution<RD>::setState(RandomInterface::State const &state) { 
00746         Ref<RDState> rd_state = state;
00747         _dist.setState(rd_state->_state);
00748 }
00749 
00750 template <class RD>
00751 void RandomDistribution<RD>::setSeed(RandomInterface::SeedType s) {
00752         _dist.setSeed(s);
00753 }
00754 
00755 template <class RD>
00756 std::string RandomDistribution<RD>::getName() const { 
00757         return _dist.getName(); 
00758 }
00759 
00760 
00761 
00762 
00763 namespace random { // generators and distributions
00764         typedef RandomDistribution<rd::Gauss> Gauss;
00765         typedef RandomNumberGenerator<rng::MT19937> MersenneTwister;
00766         typedef RandomNumberGenerator<rng::Taus2> Taus2;
00767         typedef Taus2 Standard;
00768 }
00769 
00770 
00773 extern SIMDATA_EXPORT random::Taus2 g_Random;
00774 
00775 
00776 NAMESPACE_SIMDATA_END // simdata
00777 
00778 #endif // __SIMDATA_RANDOM_H__
00779 

SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage.

Generated on Tue Oct 14 12:06:39 2003, using Doxygen 1.2.18.

[SF.net]