Zero  0.1.0
MersenneTwisterRandom.hpp
Go to the documentation of this file.
1 /*
2  * derived from code at http://www.math.keio.ac.jp/matumoto/emt.html,
3  * see copyright/license in MersenneTwisterRandom.C
4  */
5 
10 #ifndef LINTEL_MERSENNE_TWISTER_RANDOM_HPP
11 #define LINTEL_MERSENNE_TWISTER_RANDOM_HPP
12 
13 #include <cstdint>
14 #include <vector>
15 
16 #include "RandomBase.hpp"
17 
18 namespace lintel {
19 
20 // A possibly faster version may be adaptable from:
21 // http://www.math.keio.ac.jp/matumoto/MT2002/emt19937ar.html
22 // or from http://www-personal.engin.umich.edu/~wagnerr/MersenneTwister.html
23 
24 // TODO: deprecate this for the boost library implementation once we
25 // figure out how to build the equivalent of the open53/closed53
26 // functions and verify that the performance is comparable
27 
30  public:
31  // 0=Defaults to seeding with various system parameters
32  MersenneTwisterInternal(uint32_t seed = 0);
33 
34  MersenneTwisterInternal(std::vector<uint32_t> seed_array);
35 
36  void init(uint32_t seed);
37 
38  // seed_array should be N bytes long for full randomness; if not, we will
39  // seed with seed_array repeated enough times.
40  void initArray(std::vector<uint32_t> seed_array);
41 
42  inline uint32_t randInt() {
43  uint32_t y;
44 
45  if (mti >= N) {
46  reloadArray();
47  }
48  y = mt[mti++];
49  y ^= (y >> TEMPERING_SHIFT_U);
50  y ^= (y << TEMPERING_SHIFT_S) & TEMPERING_MASK_B;
51  y ^= (y << TEMPERING_SHIFT_T) & TEMPERING_MASK_C;
52  y ^= (y >> TEMPERING_SHIFT_L);
53  return y;
54  }
55 
56  uint32_t seed_used;
57 
58  inline uint32_t seedUsed() {
59  return seed_used;
60  }
61 
62  static void selfTest();
63 
64  private:
65  static const int N = 624; // state vector size
66  static const int M = 397;
67 
68  static const uint32_t MATRIX_A = 0x9908b0dfUL; /* constant vector a */
69  static const uint32_t UPPER_MASK = 0x80000000UL; /* most significant w-r bits */
70  static const uint32_t LOWER_MASK = 0x7fffffffUL; /* least significant r bits */
71  static const uint32_t TEMPERING_MASK_B = 0x9d2c5680UL;
72 
73  static const uint32_t TEMPERING_MASK_C = 0xefc60000UL;
74 
75  static const int TEMPERING_SHIFT_U = 11;
76 
77  static const int TEMPERING_SHIFT_S = 7;
78 
79  static const int TEMPERING_SHIFT_T = 15;
80 
81  static const int TEMPERING_SHIFT_L = 18;
82 
83  void reloadArray();
84 
85  uint32_t mt[N];
86 
87  int mti;
88  };
89 
91 };
92 
93 
94 
95 //Evil, but duplicates old behavior where MersenneTwisterRandom wasn't namespaced.
97 
99 
100 // TODO: replace this with Fisher-Yates shuffle from
101 // http://en.wikipedia.org/wiki/Fisher–Yates_shuffle This is the same algorithm
102 // as in the g++ stl random_shuffle, but all the published explanations work
103 // differently, and it's cleaner to have a reference to algorithms that come
104 // with an explanation of correctness.
105 
106 template<class RandomAccessIter>
107 inline void
108 MT_random_shuffle(RandomAccessIter first, RandomAccessIter last, MersenneTwisterRandom& rng = MTRandom) {
109  if (first == last) {
110  return;
111  }
112  for (RandomAccessIter i = first + 1; i != last; ++i) {
113  int rval = rng.randInt((i - first) + 1);
114  iter_swap(i, first + rval);
115  }
116 }
117 
118 #endif // LINTEL_MERSENNE_TWISTER_RANDOM_HPP
RandomTempl< MersenneTwisterInternal > MersenneTwisterRandom
Definition: MersenneTwisterRandom.hpp:90
MersenneTwisterInternal(uint32_t seed=0)
Definition: mersenne.cpp:79
void init(uint32_t seed)
Definition: mersenne.cpp:104
Mersenne Twister random number generation class.
Definition: MersenneTwisterRandom.hpp:29
uint32_t randInt()
Definition: MersenneTwisterRandom.hpp:42
static const uint32_t TEMPERING_MASK_C
Definition: MersenneTwisterRandom.hpp:73
Definition: MersenneTwisterRandom.hpp:18
static const int TEMPERING_SHIFT_T
Definition: MersenneTwisterRandom.hpp:79
static const int M
Definition: MersenneTwisterRandom.hpp:66
static const uint32_t MATRIX_A
Definition: MersenneTwisterRandom.hpp:68
int mti
Definition: MersenneTwisterRandom.hpp:87
void MT_random_shuffle(RandomAccessIter first, RandomAccessIter last, MersenneTwisterRandom &rng=MTRandom)
Definition: MersenneTwisterRandom.hpp:108
static const int TEMPERING_SHIFT_U
Definition: MersenneTwisterRandom.hpp:75
uint32_t mt[N]
Definition: MersenneTwisterRandom.hpp:85
static const int TEMPERING_SHIFT_S
Definition: MersenneTwisterRandom.hpp:77
static const int TEMPERING_SHIFT_L
Definition: MersenneTwisterRandom.hpp:81
uint32_t seedUsed()
Definition: MersenneTwisterRandom.hpp:58
void reloadArray()
Definition: mersenne.cpp:199
MersenneTwisterRandom MTRandom
Definition: mersenne.cpp:77
Definition: RandomBase.hpp:14
uint32_t seed_used
Definition: MersenneTwisterRandom.hpp:56
void initArray(std::vector< uint32_t > seed_array)
Definition: mersenne.cpp:141
static const uint32_t TEMPERING_MASK_B
Definition: MersenneTwisterRandom.hpp:71
static const uint32_t LOWER_MASK
Definition: MersenneTwisterRandom.hpp:70
static const uint32_t UPPER_MASK
Definition: MersenneTwisterRandom.hpp:69
static const int N
Definition: MersenneTwisterRandom.hpp:65