Scythe-1.0.3
|
00001 /* 00002 * Scythe Statistical Library 00003 * Copyright (C) 2000-2002 Andrew D. Martin and Kevin M. Quinn; 00004 * 2002-present Andrew D. Martin, Kevin M. Quinn, and Daniel 00005 * Pemstein. All Rights Reserved. 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * under the terms of the GNU General Public License as published by 00009 * Free Software Foundation; either version 2 of the License, or (at 00010 * your option) any later version. See the text files COPYING 00011 * and LICENSE, distributed with this source code, for further 00012 * information. 00013 * -------------------------------------------------------------------- 00014 * scythestat/rng/mersenne.h 00015 * 00016 * Provides the class definition for the mersenne random number 00017 * generator. This class extends the base rng class by providing an 00018 * implementation of runif() based on an implementation of the 00019 * mersenne twister, released under the following license: 00020 * 00021 * A C-program for MT19937, with initialization improved 2002/1/26. 00022 * Coded by Takuji Nishimura and Makoto Matsumoto. 00023 * 00024 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 00025 * All rights reserved. 00026 * 00027 * Redistribution and use in source and binary forms, with or without 00028 * modification, are permitted provided that the following conditions 00029 * are met: 00030 * 00031 * 1. Redistributions of source code must retain the above copyright 00032 * notice, this list of conditions and the following disclaimer. 00033 * 00034 * 2. Redistributions in binary form must reproduce the above 00035 * copyright 00036 * notice, this list of conditions and the following disclaimer 00037 * in the documentation and/or other materials provided with the 00038 * distribution. 00039 * 00040 * 3. The names of its contributors may not be used to endorse or 00041 * promote products derived from this software without specific 00042 * prior written permission. 00043 * 00044 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 00045 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 00046 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00047 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00048 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00049 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, 00050 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00051 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00052 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00053 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00054 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00055 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00056 * POSSIBILITY OF SUCH DAMAGE. 00057 * 00058 * For more information see: 00059 * http://www.math.keio.ac.jp/matumoto/emt.html 00060 * 00061 */ 00062 00072 #ifndef SCYTHE_MERSENNE_H 00073 #define SCYTHE_MERSENNE_H 00074 00075 #ifdef SCYTHE_COMPILE_DIRECT 00076 #include "rng.h" 00077 #else 00078 #include "scythestat/rng.h" 00079 #endif 00080 00081 namespace scythe { 00082 00083 #ifdef __MINGW32__ 00084 /* constant vector a */ 00085 static const unsigned long MATRIX_A = 0x9908b0dfUL; 00086 00087 /* most significant w-r bits */ 00088 static const unsigned long UPPER_MASK = 0x80000000UL; 00089 00090 /* least significant r bits */ 00091 static const unsigned long LOWER_MASK = 0x7fffffffUL; 00092 #else 00093 namespace { 00094 /* constant vector a */ 00095 const unsigned long MATRIX_A = 0x9908b0dfUL; 00096 00097 /* most significant w-r bits */ 00098 const unsigned long UPPER_MASK = 0x80000000UL; 00099 00100 /* least significant r bits */ 00101 const unsigned long LOWER_MASK = 0x7fffffffUL; 00102 } 00103 #endif 00104 00120 class mersenne: public rng<mersenne> 00121 { 00122 public: 00123 00135 mersenne () 00136 : rng<mersenne> (), 00137 mti (N + 1) 00138 {} 00139 00149 mersenne (const mersenne &m) 00150 : rng<mersenne> (), 00151 mti (m.mti) 00152 { 00153 } 00154 00167 void initialize (unsigned long s) 00168 { 00169 mt[0]= s & 0xffffffffUL; 00170 for (mti=1; mti<N; mti++) { 00171 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) 00172 + mti); 00173 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 00174 /* In the previous versions, MSBs of the seed affect */ 00175 /* only MSBs of the array mt[]. */ 00176 /* 2002/01/09 modified by Makoto Matsumoto */ 00177 mt[mti] &= 0xffffffffUL; 00178 /* for >32 bit machines */ 00179 } 00180 } 00181 00193 inline double runif() 00194 { 00195 return (((double) genrand_int32()) + 0.5) * 00196 (1.0 / 4294967296.0); 00197 } 00198 00199 /* We have to override the overloaded forms of runif because 00200 * overloading the no-arg runif() hides the base class 00201 * definition; C++ stops looking once it finds the above. 00202 */ 00224 template <matrix_order O, matrix_style S> 00225 inline Matrix<double,O,S> runif(unsigned int rows, 00226 unsigned int cols) 00227 { 00228 return rng<mersenne>::runif<O,S>(rows, cols); 00229 } 00230 00252 Matrix<double,Col,Concrete> runif(unsigned int rows, 00253 unsigned int cols) 00254 { 00255 return rng<mersenne>::runif<Col,Concrete>(rows, cols); 00256 } 00257 00258 /* generates a random number on [0,0xffffffff]-interval */ 00267 unsigned long genrand_int32() 00268 { 00269 unsigned long y; 00270 static unsigned long mag01[2]={0x0UL, MATRIX_A}; 00271 /* mag01[x] = x * MATRIX_A for x=0,1 */ 00272 00273 if (mti >= N) { /* generate N words at one time */ 00274 int kk; 00275 00276 if (mti == N+1) // if init_genrand() has not been called, 00277 this->initialize(5489UL); // a default initial seed is used 00278 00279 for (kk=0;kk<N-M;kk++) { 00280 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 00281 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00282 } 00283 for (;kk<N-1;kk++) { 00284 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 00285 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00286 } 00287 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); 00288 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; 00289 00290 mti = 0; 00291 } 00292 00293 y = mt[mti++]; 00294 00295 /* Tempering */ 00296 y ^= (y >> 11); 00297 y ^= (y << 7) & 0x9d2c5680UL; 00298 y ^= (y << 15) & 0xefc60000UL; 00299 y ^= (y >> 18); 00300 00301 return y; 00302 } 00303 00304 protected: 00305 /* Period parameters */ 00306 static const int N = 624; 00307 static const int M = 398; 00308 00309 /* the array for the state vector */ 00310 unsigned long mt[N]; 00311 00312 /* mti==N+1 means mt[N] is not initialized */ 00313 int mti; 00314 }; 00315 00316 } 00317 00318 #endif /* SCYTHE_MERSENNE_H */