Created by Scott Robert Ladd at Coyote Gulch Productions.
00001 //--------------------------------------------------------------------- 00002 // Algorithmic Conjurings @ http://www.coyotegulch.com 00003 // 00004 // mtwister.h (libcoyotl) 00005 // 00006 // Mersenne Twister -- A pseudorandom Number Generator 00007 // 00008 // ORIGINAL ALGORITHM COPYRIGHT 00009 // ============================ 00010 // Copyright (C) 1997, 2002 Makoto Matsumoto and Takuji Nishimura. 00011 // Any feedback is very welcome. For any question, comments, see 00012 // http://www.math.keio.ac.jp/matumoto/emt.html or email 00013 // matumoto@math.keio.ac.jp 00014 //--------------------------------------------------------------------- 00015 // 00016 // Copyright 1990-2005 Scott Robert Ladd 00017 // 00018 // This program is free software; you can redistribute it and/or modify 00019 // it under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation; either version 2 of the License, or 00021 // (at your option) any later version. 00022 // 00023 // This program is distributed in the hope that it will be useful, 00024 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00026 // GNU General Public License for more details. 00027 // 00028 // You should have received a copy of the GNU General Public License 00029 // along with this program; if not, write to the 00030 // Free Software Foundation, Inc. 00031 // 59 Temple Place - Suite 330 00032 // Boston, MA 02111-1307, USA. 00033 // 00034 //----------------------------------------------------------------------- 00035 // 00036 // For more information on this software package, please visit 00037 // Scott's web site, Coyote Gulch Productions, at: 00038 // 00039 // http://www.coyotegulch.com 00040 // 00041 //----------------------------------------------------------------------- 00042 00043 #if !defined(LIBCOYOTL_MTWISTER_H) 00044 #define LIBCOYOTL_MTWISTER_H 00045 00046 // #define USE_METATEMP 00047 00048 #include "prng.h" 00049 00050 namespace libcoyotl 00051 { 00053 00063 template <int i> class LOOP1; 00064 00065 class mtwister : public prng 00066 { 00067 friend class LOOP1<0>; 00068 00069 public: 00070 // Period parameters 00071 static const size_t N = 624; 00072 static const size_t M = 397; 00073 00074 static const uint32_t MATRIX_A = 0x9908b0dfUL; 00075 static const uint32_t UPPER_MASK = 0x80000000UL; 00076 static const uint32_t LOWER_MASK = 0x7fffffffUL; 00077 00078 private: 00079 // Working storage 00080 uint32_t m_mt[N]; 00081 size_t m_mti; 00082 uint32_t m_multiplier; 00083 00084 public: 00086 00090 mtwister(); 00091 00093 00097 mtwister(uint32_t seed); 00098 00100 00104 virtual void init(uint32_t seed); 00105 00106 private: 00108 00112 void init_helper(); 00113 00114 public: 00116 00120 uint32_t get_rand(); 00121 }; 00122 00123 #if defined(USE_METATEMP) 00124 template <int i> 00125 class LOOP1 00126 { 00127 public: 00128 inline static void EXEC(uint32_t * a) 00129 { 00130 uint32_t y = (a[i] & mtwister::UPPER_MASK) | (a[i+1] & mtwister::LOWER_MASK); 00131 a[i] = a[i + 397] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0); 00132 LOOP1<i+1>::EXEC(a); 00133 } 00134 }; 00135 00136 template<> 00137 class LOOP1<226> 00138 { 00139 public: 00140 inline static void EXEC(uint32_t * a) 00141 { 00142 uint32_t y = (a[226] & mtwister::UPPER_MASK) | (a[227] & mtwister::LOWER_MASK); 00143 a[226] = a[623] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0); 00144 } 00145 }; 00146 00147 template <int i> 00148 class LOOP2 00149 { 00150 public: 00151 inline static void EXEC(uint32_t * a) 00152 { 00153 uint32_t y = (a[i] & mtwister::UPPER_MASK) | (a[i+1] & mtwister::LOWER_MASK); 00154 a[i] = a[i - 227] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0); 00155 LOOP2<i+1>::EXEC(a); 00156 } 00157 }; 00158 00159 template<> 00160 class LOOP2<623> 00161 { 00162 public: 00163 inline static void EXEC(uint32_t * a) 00164 { 00165 uint32_t y = (a[623] & mtwister::UPPER_MASK) | (a[0] & mtwister::LOWER_MASK); 00166 a[623] = a[396] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0); 00167 } 00168 }; 00169 00170 #endif 00171 00172 } // end namespace libcoyotl 00173 00174 #endif
© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.