libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


mtwister.h
1 //---------------------------------------------------------------------
2 // Algorithmic Conjurings @ http://www.coyotegulch.com
3 //
4 // mtwister.h (libcoyotl)
5 //
6 // Mersenne Twister -- A pseudorandom Number Generator
7 //
8 // ORIGINAL ALGORITHM COPYRIGHT
9 // ============================
10 // Copyright (C) 1997, 2002 Makoto Matsumoto and Takuji Nishimura.
11 // Any feedback is very welcome. For any question, comments, see
12 // http://www.math.keio.ac.jp/matumoto/emt.html or email
13 // matumoto@math.keio.ac.jp
14 //---------------------------------------------------------------------
15 //
16 // Copyright 1990-2005 Scott Robert Ladd
17 //
18 // This program is free software; you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation; either version 2 of the License, or
21 // (at your option) any later version.
22 //
23 // This program is distributed in the hope that it will be useful,
24 // but WITHOUT ANY WARRANTY; without even the implied warranty of
25 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 // GNU General Public License for more details.
27 //
28 // You should have received a copy of the GNU General Public License
29 // along with this program; if not, write to the
30 // Free Software Foundation, Inc.
31 // 59 Temple Place - Suite 330
32 // Boston, MA 02111-1307, USA.
33 //
34 //-----------------------------------------------------------------------
35 //
36 // For more information on this software package, please visit
37 // Scott's web site, Coyote Gulch Productions, at:
38 //
39 // http://www.coyotegulch.com
40 //
41 //-----------------------------------------------------------------------
42 
43 #if !defined(LIBCOYOTL_MTWISTER_H)
44 #define LIBCOYOTL_MTWISTER_H
45 
46 // #define USE_METATEMP
47 
48 #include "prng.h"
49 
50 namespace libcoyotl
51 {
53 
63  template <int i> class LOOP1;
64 
65  class mtwister : public prng
66  {
67  friend class LOOP1<0>;
68 
69  public:
70  // Period parameters
71  static const size_t N = 624;
72  static const size_t M = 397;
73 
74  static const uint32_t MATRIX_A = 0x9908b0dfUL;
75  static const uint32_t UPPER_MASK = 0x80000000UL;
76  static const uint32_t LOWER_MASK = 0x7fffffffUL;
77 
78  private:
79  // Working storage
80  uint32_t m_mt[N];
81  size_t m_mti;
82  uint32_t m_multiplier;
83 
84  public:
86 
90  mtwister();
91 
93 
97  mtwister(uint32_t seed);
98 
100 
104  virtual void init(uint32_t seed);
105 
106  private:
108 
112  void init_helper();
113 
114  public:
116 
120  uint32_t get_rand();
121  };
122 
123 #if defined(USE_METATEMP)
124  template <int i>
125  class LOOP1
126  {
127  public:
128  inline static void EXEC(uint32_t * a)
129  {
130  uint32_t y = (a[i] & mtwister::UPPER_MASK) | (a[i+1] & mtwister::LOWER_MASK);
131  a[i] = a[i + 397] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0);
132  LOOP1<i+1>::EXEC(a);
133  }
134  };
135 
136  template<>
137  class LOOP1<226>
138  {
139  public:
140  inline static void EXEC(uint32_t * a)
141  {
142  uint32_t y = (a[226] & mtwister::UPPER_MASK) | (a[227] & mtwister::LOWER_MASK);
143  a[226] = a[623] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0);
144  }
145  };
146 
147  template <int i>
148  class LOOP2
149  {
150  public:
151  inline static void EXEC(uint32_t * a)
152  {
153  uint32_t y = (a[i] & mtwister::UPPER_MASK) | (a[i+1] & mtwister::LOWER_MASK);
154  a[i] = a[i - 227] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0);
155  LOOP2<i+1>::EXEC(a);
156  }
157  };
158 
159  template<>
160  class LOOP2<623>
161  {
162  public:
163  inline static void EXEC(uint32_t * a)
164  {
165  uint32_t y = (a[623] & mtwister::UPPER_MASK) | (a[0] & mtwister::LOWER_MASK);
166  a[623] = a[396] ^ (y >> 1) ^ ((y & 1) ? mtwister::MATRIX_A : 0);
167  }
168  };
169 
170 #endif
171 
172 } // end namespace libcoyotl
173 
174 #endif

© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.