libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


mtwister.h

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.