- Main Page
- Classes
- Files

- File List

# OptFrame/Util/RandGenMersenneTwister.hpp

    00001 //Description and pseudocode in http://en.wikipedia.org/wiki/Mersenne_twister
    00002
    00003 #ifndef RANDGENMersenneTwister_HPP_
    00004 #define RANDGENMersenneTwister_HPP_
    00005
    00006 #include "../RandGen.hpp"
    00007 #include <limits.h>
    00008
    00009 class RandGenMersenneTwister: public RandGen
    00010 {
    00011 private:
    00012         static const unsigned int GEN_STATE_LENGTH = 624;
    00013         static const unsigned int MASK_1 = 0xffffffff; //4294967295
    00014         static const unsigned int MASK_2 = 0x80000000; //2147483648
    00015         static const unsigned int MASK_3 = 0x7fffffff; //2147483647
    00016
    00017         static const unsigned int CONSTANT_1 = 0x6c078965; //1812433253
    00018         static const unsigned int CONSTANT_2 = 0x9d2c5680; //2636928640
    00019         static const unsigned int CONSTANT_3 = 0xefc60000; //4022730752
    00020         static const unsigned int CONSTANT_4 = 0x9908b0df; //2567483615
    00021         unsigned int MT[GEN_STATE_LENGTH];
    00022         int index;
    00023
    00024         void GenNum()
    00025         {
    00026                 register int i;
    00027                 unsigned int y;
    00028                 for (i = 0; i < GEN_STATE_LENGTH; i++)
    00029                 {
    00030                         y = (MT[i] ^ MASK_2) + (MT[(i + 1) % GEN_STATE_LENGTH] ^ MASK_3);
    00031                         MT[i] = MT[(i + 397) % GEN_STATE_LENGTH] ^ (y >> 1);
    00032                         if ((y % 2) == 1)
    00033                         {
    00034                                 MT[i] = MT[i] ^ CONSTANT_4;
    00035                         }
    00036                 }
    00037         }
    00038
    00039         unsigned mt_rand()
    00040         {
    00041                 if (!RandGen::init)
    00042                 {
    00043                         initialize();
    00044                         RandGen::init = true;
    00045                 }
    00046
    00047                 unsigned int y;
    00048
    00049                 if (index == 0)
    00050                         GenNum();
    00051
    00052                 y = MT[index];
    00053                 y = y ^ (y >> 11);
    00054                 y = y ^ ((y << 7) & CONSTANT_2);
    00055                 y = y ^ ((y << 15) & CONSTANT_3);
    00056                 y = y ^ (y >> 18);
    00057
    00058                 index = (index + 1) % GEN_STATE_LENGTH;
    00059
    00060                 return y;
    00061         }
    00062
    00063 public:
    00064
    00065         RandGenMersenneTwister() :
    00066                 RandGen()
    00067         {
    00068         }
    00069
    00070         RandGenMersenneTwister(long seed) :
    00071                 RandGen(seed)
    00072         {
    00073         }
    00074
    00075         using RandGen::rand;
    00076
    00077         // initialize random number generation
    00078         void initialize()
    00079         {
    00080                 register int i;
    00081
    00082                 index = 0;
    00083                 MT[0] = seed;
    00084                 for (i = 1; i < GEN_STATE_LENGTH; i++)
    00085                 {
    00086                         MT[i] = ((CONSTANT_1 * (MT[i - 1] ^ (MT[i - 1] >> 30))) + i) & MASK_1;
    00087                 }
    00088         }
    00089
    00090         // generate random number
    00091         int rand()
    00092         {
    00093                 return mt_rand();
    00094         }
    00095
    00096         // generate random number between 0 and n-1
    00097         int rand(int n)
    00098         {
    00099                 if (n < 0)
    00100                         n *= (-1);
    00101
    00102                 return mt_rand() % n;
    00103         }
    00104
    00105         // random uniform between [0,1)
    00106         double rand01()
    00107         {
    00108                 return (double) mt_rand() / UINT_MAX;
    00109         }
    00110 };
    00111
    00112 #endif /* RANDGENMersenneTwister_HPP_ */

All Classes Functions