Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

MersenneTwister.cpp

Go to the documentation of this file.
00001 #include "./MersenneTwister.h"
00002 #include "time.h"
00003 
00004 // Period parameters
00005 const LongNatural N = 624;
00006 const LongNatural M = 397;
00007 // constant vector a
00008 const LongNatural MATRIX_A = 0x9908b0dfUL;
00009 // most significant w-r bits
00010 const LongNatural UPPER_MASK=0x80000000UL;
00011 // least significant r bits
00012 const LongNatural LOWER_MASK=0x7fffffffUL;
00013 
00014 MersenneTwister::MersenneTwister(LongNatural seed)
00015 : mt(N)
00016 {
00017         SetSeed(seed);
00018 }
00019 
00020 MersenneTwister::~MersenneTwister(void)
00021 {
00022 }
00023 
00024 VeryLongNatural MersenneTwister::Max() {
00025         return 4294967296; //return 2^32;
00026 }
00027 
00028 LongNatural MersenneTwister::Min()
00029 {
00030     return 1;
00031 }
00032 
00033 void MersenneTwister::SetSeed(LongNatural seed) {
00034         LongNatural s = (seed != 0 ? seed : clock());
00035         mt[0]= s & 0xffffffffUL;
00036         for (mti=1; mti<N; mti++) {
00037                 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
00038                 mt[mti] &= 0xffffffffUL;
00039         }
00040 }
00041 
00042 MersenneTwister::MersenneTwister(const valarray<LongNatural>& seeds)
00043 : mt(N) {
00044         SetSeed(19650218UL);
00045         LongNatural i=1, j=0, k = (N>seeds.size() ? N : seeds.size());
00046         for (; k; k--) {
00047                 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
00048                         + seeds[j] + j; /* non linear */
00049                 mt[i] &= 0xffffffffUL;
00050                 i++; j++;
00051                 if (i>=N) { mt[0] = mt[N-1]; i=1; }
00052                 if (j>=seeds.size()) j=0;
00053         }
00054         for (k=N-1; k; k--) {
00055                 mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
00056                         - i;
00057                 mt[i] &= 0xffffffffUL;
00058                 i++;
00059                 if (i>=N) { mt[0] = mt[N-1]; i=1; }
00060         }
00061 
00062         mt[0] = 0x80000000UL;
00063 }
00064 
00065 LongNatural MersenneTwister::GetOneRandomInteger() {
00066 
00067         LongNatural y;
00068         static LongNatural mag01[2]={0x0UL, MATRIX_A};
00069 
00070         if (mti >= N) { /* generate N words at one time */
00071                 LongNatural kk;
00072 
00073                 for (kk=0;kk<N-M;kk++) {
00074                         y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00075                         mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
00076                 }
00077                 for (;kk<N-1;kk++) {
00078                         y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00079                         mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
00080                 }
00081                 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00082                 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
00083 
00084                 mti = 0;
00085         }
00086 
00087         y = mt[mti++];
00088 
00089         /* Tempering */
00090         y ^= (y >> 11);
00091         y ^= (y << 7) & 0x9d2c5680UL;
00092         y ^= (y << 15) & 0xefc60000UL;
00093         y ^= (y >> 18);
00094 
00095         return y;
00096 }

Note: Generated nightly - reload for latest version
Generated on Thu Dec 22 23:12:36 2005 for terreneuve by doxygen 1.3.6