Random.cpp
Go to the documentation of this file.00001 //*** Random.cpp *** 00002 00003 // This is the copyright notice for the original source code for the marsienne twister 00004 // Algorithmically, I'm using the same code, I've just reformatted it and turned it into 00005 // a c++ class. /Mattias 00006 /* 00007 A C-program for MT19937, with initialization improved 2002/1/26. 00008 Coded by Takuji Nishimura and Makoto Matsumoto. 00009 00010 Before using, initialize the state by using init_genrand(seed) 00011 or init_by_array(init_key, key_length). 00012 00013 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 00014 All rights reserved. 00015 00016 Redistribution and use in source and binary forms, with or without 00017 modification, are permitted provided that the following conditions 00018 are met: 00019 00020 1. Redistributions of source code must retain the above copyright 00021 notice, this list of conditions and the following disclaimer. 00022 00023 2. Redistributions in binary form must reproduce the above copyright 00024 notice, this list of conditions and the following disclaimer in the 00025 documentation and/or other materials provided with the distribution. 00026 00027 3. The names of its contributors may not be used to endorse or promote 00028 products derived from this software without specific prior written 00029 permission. 00030 00031 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00032 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00033 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00034 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00035 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00036 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00037 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00038 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00039 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00040 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00041 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00042 00043 00044 Any feedback is very welcome. 00045 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 00046 email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 00047 */ 00048 #include "Random.h" 00049 00050 //*** Constructor *** 00051 00052 Random::Random() 00053 { 00054 mti_=N+1; // mti==N+1 means mt[N] is not initialized 00055 } 00056 00057 00058 //*** Seed *** 00059 00060 void Random::Seed(unsigned int s) 00061 { 00062 mt_[0]= s & 0xffffffff; 00063 for (mti_=1; mti_<N; mti_++) 00064 { 00065 mt_[mti_] = (1812433253 * (mt_[mti_-1] ^ (mt_[mti_-1] >> 30)) + mti_); 00066 00067 // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. 00068 // In the previous versions, MSBs of the seed affect 00069 // only MSBs of the array mt[]. 00070 // 2002/01/09 modified by Makoto Matsumoto 00071 mt_[mti_] &= 0xffffffff; 00072 // for >32 bit machines 00073 } 00074 } 00075 00076 00077 //*** Seed *** 00078 00079 void Random::Seed(unsigned int seeds[], int count) 00080 { 00081 int i; 00082 int j; 00083 int k; 00084 Seed(19650218); 00085 i=1; j=0; 00086 k = (N>count ? N : count); 00087 for (; k; k--) 00088 { 00089 mt_[i] = (mt_[i] ^ ((mt_[i-1] ^ (mt_[i-1] >> 30)) * 1664525)) + seeds[j] + j; // non linear 00090 mt_[i] &= 0xffffffff; // for WORDSIZE > 32 machines 00091 i++; j++; 00092 if (i>=N) 00093 { 00094 mt_[0] = mt_[N-1]; i=1; 00095 } 00096 if (j>=count) 00097 { 00098 j=0; 00099 } 00100 } 00101 for (k=N-1; k; k--) 00102 { 00103 mt_[i] = (mt_[i] ^ ((mt_[i-1] ^ (mt_[i-1] >> 30)) * 1566083941)) - i; // non linear 00104 mt_[i] &= 0xffffffff; // for WORDSIZE > 32 machines 00105 i++; 00106 if (i>=N) 00107 { 00108 mt_[0] = mt_[N-1]; i=1; 00109 } 00110 } 00111 00112 mt_[0] = 0x80000000; // MSB is 1; assuring non-zero initial array 00113 } 00114 00115 00116 //*** RandomInteger *** 00117 00118 unsigned int Random::RandomInteger() 00119 { 00120 const unsigned int M = 397; 00121 const unsigned int MATRIX_A = 0x9908b0df; // constant vector a 00122 const unsigned int UPPER_MASK = 0x80000000; // most significant w-r bits 00123 const unsigned int LOWER_MASK = 0x7fffffff; // least significant r bits 00124 static unsigned int mag01[2]={0x0, MATRIX_A}; 00125 00126 unsigned long y; 00127 // mag01[x] = x * MATRIX_A for x=0,1 00128 00129 if (mti_ >= N) 00130 { 00131 // generate N words at one time 00132 int kk; 00133 00134 // if Seed() has not been called, 00135 if (mti_ == N+1) 00136 { 00137 Seed(5489); // a default initial seed is used 00138 } 00139 00140 for (kk=0;kk<N-M;kk++) 00141 { 00142 y = (mt_[kk]&UPPER_MASK)|(mt_[kk+1]&LOWER_MASK); 00143 mt_[kk] = mt_[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]; 00144 } 00145 for (;kk<N-1;kk++) 00146 { 00147 y = (mt_[kk]&UPPER_MASK)|(mt_[kk+1]&LOWER_MASK); 00148 mt_[kk] = mt_[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]; 00149 } 00150 y = (mt_[N-1]&UPPER_MASK)|(mt_[0]&LOWER_MASK); 00151 mt_[N-1] = mt_[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; 00152 00153 mti_ = 0; 00154 } 00155 00156 y = mt_[mti_++]; 00157 00158 // Tempering 00159 y ^= (y >> 11); 00160 y ^= (y << 7) & 0x9d2c5680; 00161 y ^= (y << 15) & 0xefc60000; 00162 y ^= (y >> 18); 00163 00164 return y; 00165 } 00166 00167 00168 //*** RandomRanged *** 00169 00170 int Random::RandomRanged(int min, int max) 00171 { 00172 int range=(max-min)+1; 00173 if (range<=0) 00174 { 00175 return min; 00176 } 00177 int value=RandomInteger()%range; 00178 return min+value; 00179 } 00180 00181 00182 //*** RandomFloat *** 00183 00184 float Random::RandomFloat() 00185 { 00186 return (RandomInteger()/4294967296.0f); 00187 // divided by 2^32 00188 } 00189
Reproduction/republishing of any material on this site without permission is strictly prohibited.
