Pyrogenesis  trunk
Random.h
Go to the documentation of this file.
1 /* Copyright (C) 2011 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_MATHS_RANDOM
19 #define INCLUDED_MATHS_RANDOM
20 
21 /**
22  * Random number generator with period 2^{512}-1;
23  * effectively a better version of MT19937 (smaller state, similarly fast,
24  * simpler code, better distribution).
25  * Implements Boost.Random's PseudoRandomNumberGenerator concept.
26  */
27 class WELL512
28 {
29 private:
32 
33 public:
35  {
36  seed((uint32_t)0);
37  }
38 
40  {
41  // WELL512 implementation by Chris Lomont (Game Programming Gems 7;
42  // http://lomont.org/Math/Papers/2008/Lomont_PRNG_2008.pdf)
43 
44  uint32_t a, b, c, d;
45  a = state[index];
46  c = state[(index + 13) & 15];
47  b = a ^ c ^ (a << 16) ^ (c << 15);
48  c = state[(index + 9) & 15];
49  c ^= (c >> 11);
50  a = state[index] = b ^ c;
51  d = a ^ ((a << 5) & 0xDA442D24UL);
52  index = (index + 15) & 15;
53  a = state[index];
54  state[index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28);
55  return state[index];
56  }
57 
58  void seed(uint32_t value)
59  {
60  index = 0;
61 
62  // Expand the seed with the same algorithm as boost::random::mersenne_twister
63  const uint32_t mask = ~0u;
64  state[0] = value & mask;
65  for (uint32_t i = 1; i < ARRAY_SIZE(state); ++i)
66  state[i] = (1812433253UL * (state[i - 1] ^ (state[i - 1] >> 30)) + i) & mask;
67  }
68 
69  void seed(uint32_t values[16])
70  {
71  index = 0;
72 
73  for (uint32_t i = 0; i < ARRAY_SIZE(state); ++i)
74  state[i] = values[i];
75  }
76 
77  // Implement UniformRandomNumberGenerator concept:
78 
80 
81  uint32_t min() const
82  {
83  return std::numeric_limits<uint32_t>::min();
84  }
85 
86  uint32_t max() const
87  {
88  return std::numeric_limits<uint32_t>::max();
89  }
90 
91  // Implement EqualityComparable concept:
92 
93  friend bool operator==(const WELL512& x, const WELL512& y)
94  {
95  if (x.index != y.index)
96  return false;
97  for (uint32_t i = 0; i < ARRAY_SIZE(x.state); ++i)
98  if (x.state[i] != y.state[i])
99  return false;
100  return true;
101  }
102 
103  friend bool operator!=(const WELL512& x, const WELL512& y)
104  {
105  return !(x == y);
106  }
107 
108  // Implement Streamable concept (based on boost::random::mersenne_twister):
109 
110  template<class CharT, class Traits>
111  friend std::basic_ostream<CharT, Traits>&
112  operator<<(std::basic_ostream<CharT, Traits>& os, const WELL512& rng)
113  {
114  os << rng.index << " ";
115  for (uint32_t i = 0; i < ARRAY_SIZE(rng.state); ++i)
116  os << rng.state[i] << " ";
117  return os;
118  }
119 
120  template<class CharT, class Traits>
121  friend std::basic_istream<CharT, Traits>&
122  operator>>(std::basic_istream<CharT, Traits>& is, WELL512& rng)
123  {
124  is >> rng.index >> std::ws;
125  for (uint32_t i = 0; i < ARRAY_SIZE(rng.state); ++i)
126  is >> rng.state[i] >> std::ws;
127  return is;
128  }
129 };
130 
131 #endif // INCLUDED_MATHS_RANDOM
uint32_t state[16]
Definition: Random.h:30
#define ARRAY_SIZE(name)
Definition: code_annotation.h:336
friend bool operator==(const WELL512 &x, const WELL512 &y)
Definition: Random.h:93
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, WELL512 &rng)
Definition: Random.h:122
void seed(uint32_t value)
Definition: Random.h:58
Random number generator with period 2^{512}-1; effectively a better version of MT19937 (smaller state...
Definition: Random.h:27
boost::mt19937 rng
Random number generator (Boost Mersenne Twister)
Definition: Noise.cpp:34
uint32_t min() const
Definition: Random.h:81
void seed(uint32_t values[16])
Definition: Random.h:69
uint32_t operator()()
Definition: Random.h:39
uint32_t max() const
Definition: Random.h:86
unsigned int uint32_t
Definition: wposix_types.h:53
WELL512()
Definition: Random.h:34
uint32_t result_type
Definition: Random.h:79
uint32_t index
Definition: Random.h:31
friend bool operator!=(const WELL512 &x, const WELL512 &y)
Definition: Random.h:103