Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
randomNumbers_MT19937.cpp
Go to the documentation of this file.
1 
14 #include "randomNumbers_MT19937.h"
15 
16 #include <assert.h>
17 #include <iostream>
18 #include <fstream>
19 #include <vector>
20 using std::vector;
21 #include <string>
22 using std::string;
23 
24 #include "commonParameters.h"
25 #include "communicator.h"
26 #include "bridgeIO.h"
27 using Bridge::vout;
28 
29 //====================================================================
31  : m_left(1)
32 {
33  if (s < 0) {
34  std::cerr << "error: seed must be positive." << std::endl;
35  }
36  std::cout << " MT19937 seed = " << s << std::endl;
37  init(s);
38 }
39 
40 
42  : m_left(1)
43 {
44  std::cout << " MT19937 seed = " << s << std::endl;
45 
46  init(s);
47 }
48 
49 
50 RandomNumbers_MT19937::RandomNumbers_MT19937(vector<unsigned long>& key)
51  : m_left(1)
52 {
53  std::cout << " MT19937 seeds = (";
54 
55  for (int i = 0; i < key.size(); ++i) {
56  std::cout << key[i] << ", ";
57  }
58  std::cout << ")" << std::endl;
59  init(19650218UL, key);
60 }
61 
62 
64 {
65  std::cout << " Random number: read from file "
66  << filename << std::endl;
67 
68  std::ifstream in_file(filename.c_str());
69 
70  if (!in_file) {
71  std::cerr << "error: unable to open input file." << std::endl;
72  abort();
73  //return;
74  }
75 
76  unsigned long int n;
77  for (int i = 0; i < N; ++i) {
78  if (in_file >> n) {
79  m_state[i] = n;
80  } else {
81  std::cerr << "error: # of seed in input file is lacked." << std::endl;
82  }
83  }
84 
85  if (in_file >> n) {
86  m_left = n;
87  } else {
88  std::cerr << "error: # of seed in input file is lacked." << std::endl;
89  }
90 
91  m_next = m_state + N - m_left + 1;
92 }
93 
94 
95 //====================================================================
96 void
97 RandomNumbers_MT19937::writefile(const string filename)
98 {
99  std::cout << " Random number: write down to file "
100  << filename << std::endl;
101 
102  std::ofstream out_file(filename.c_str());
103 
104  if (!out_file) {
105  std::cerr << "error: unable to open output file." << std::endl;
106  return;
107  }
108 
109  for (int i = 0; i < N; ++i) {
110  out_file << m_state[i] << std::endl;
111  }
112 
113  out_file << m_left << std::endl;
114 }
115 
116 
117 //====================================================================
118 void
120 {
121  m_state[0] = s & 0xffffffffUL;
122  for (int j = 1; j < N; ++j) {
123  m_state[j] = (1812433253UL * (m_state[j - 1] ^ (m_state[j - 1] >> 30)) + j);
124  m_state[j] &= 0xffffffffUL;
125  }
126 }
127 
128 
129 void
130 RandomNumbers_MT19937::init(unsigned long s, vector<unsigned long>& key)
131 {
132  init(s);
133  int i = 1;
134  int j = 0;
135  int key_length = key.size();
136 
137  for (int k = N > key_length ? N : key_length; k; --k) {
138  // non linear
139  m_state[i]
140  = (m_state[i] ^ ((m_state[i - 1] ^ (m_state[i - 1] >> 30)) * 1664525UL)) + key[j] + j;
141  // for WORDSIZE > 32 machines
142  m_state[i] &= 0xffffffffUL;
143 
144  ++i;
145  ++j;
146  if (i >= N) {
147  m_state[0] = m_state[N - 1];
148  i = 1;
149  }
150  if (j >= key_length) j = 0;
151  }
152 
153  for (int k = N - 1; k; --k) {
154  // non linear
155  m_state[i] = (m_state[i] ^ ((m_state[i - 1] ^ (m_state[i - 1] >> 30)) * 1566083941UL)) - i;
156  m_state[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines
157  i++;
158  if (i >= N) {
159  m_state[0] = m_state[N - 1];
160  i = 1;
161  }
162  }
163  // MSB is 1; assuring non-zero initial array
164  m_state[0] = 0x80000000UL;
165 }
166 
167 
168 //====================================================================
169 void
171 {
172  unsigned long *p = m_state;
173 
174  m_left = N;
175  m_next = m_state;
176  for (int j = N - M + 1; --j; ++p) {
177  *p = p[M] ^ twist(p[0], p[1]);
178  }
179  for (int j = M; --j; ++p) {
180  *p = p[M - N] ^ twist(p[0], p[1]);
181  }
182 
183  *p = p[M - N] ^ twist(p[0], m_state[0]);
184 }
185 
186 
187 unsigned long
188 RandomNumbers_MT19937::twist(unsigned long u, unsigned long v) const
189 {
190  // Period parameters
191  const unsigned long mtrx_a = 0x9908b0dfUL; // constant vector a
192  const unsigned long umask = 0x80000000UL; // most significant w-r bits
193  const unsigned long lmask = 0x7fffffffUL; // least significant r bits
194 
195  unsigned long maxbits = (u & umask) | (v & lmask);
196 
197  return (maxbits >> 1) ^ (v & 1UL ? mtrx_a : 0UL);
198 }
199 
200 
201 //====================================================================
202 // generates a random number on [0,0xffffffff]
203 unsigned long
205 {
206  if (--m_left == 0) nextState();
207  unsigned long y = *m_next++;
208 
209  // Tempering
210  y ^= (y >> 11);
211  y ^= (y << 7) & 0x9d2c5680UL;
212  y ^= (y << 15) & 0xefc60000UL;
213  y ^= (y >> 18);
214  return y;
215 }
216 
217 
218 //generates a random number on [0,0x7fffffff]
219 long
221 {
222  return (long)(randInt32() >> 1);
223 }
224 
225 
226 //====================================================================
227 //generates a random number on [0,1] double number
228 double
230 {
231  static const double factor = 1.0 / 4294967295.0;
232 
233  return static_cast<double>(randInt32() * factor);
234 }
235 
236 
237 //generates a random number on [0,1) double number
238 double
240 {
241  static const double factor = 1.0 / 4294967296.0;
242 
243  return static_cast<double>(randInt32() * factor);
244 }
245 
246 
247 // generates a random number on (0,1) double number
248 double
250 {
251  static const double factor = 1.0 / 4294967296.0;
252 
253  return static_cast<double>((randInt32() + 0.5) * factor);
254 }
255 
256 
257 // generates a random number on [0,1) with 53-bit resolution
258 double
260 {
261  unsigned long a = randInt32() >> 5;
262  unsigned long b = randInt32() >> 6;
263  static const double factor = 1.0 / 9007199254740992.0;
264 
265  //std::cout<<"randRes53()="<< (a*67108864.0+b)*factor<<std::std::endl;
266  return (a * 67108864.0 + b) * factor;
267 }
268 
269 
270 //====================================================================
271 //============================================================END=====