Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
randomNumbers.cpp
Go to the documentation of this file.
1 
14 #include "randomNumbers.h"
15 
16 #include <fstream>
17 #include <cassert>
18 
19 #include "Field/index_eo.h"
20 
21 #ifdef USE_FACTORY
22 
23 #ifdef USE_FACTORY_AUTOREGISTER
24 #else
25 // setup factories for all subclasses
26 
27 #include "randomNumbers_Mseries.h"
28 #include "randomNumbers_MT19937.h"
29 #ifdef USE_SFMTLIB
30 #include "randomNumbers_SFMT.h"
31 #endif
32 
33 bool RandomNumbers::init_factory()
34 {
35  bool result = true;
36 
37  result &= RandomNumbers_Mseries::register_factory();
38  result &= RandomNumbers_MT19937::register_factory();
39 #ifdef USE_SFMTLIB
40  result &= RandomNumbers_SFMT::register_factory();
41 #endif
42 
43  return result;
44 }
45 
46 
47 #endif /* USE_FACTORY_AUTOREGISTER */
48 
49 #endif /* USE_FACTORY */
50 
51 
52 namespace {
53  const double sq2r = 1.0 / sqrt(2.0);
54  // const double pi = 3.141592653589793;
55  const double pi = 4.0 * atan(1.0);
56  const double pi2 = 2.0 * pi;
57 }
58 
59 const std::string RandomNumbers::class_name = "RandomNumbers";
60 
61 //====================================================================
62 void RandomNumbers::gauss(double& rand1, double& rand2)
63 {
64  // Two Gaussian random number with deviation 1/\sqrt(2).
65  double r1 = get();
66  double r2 = get();
67 
68  double slg1 = sqrt(-log(1.0 - r1) * 2.0) * sq2r;
69  double ang1 = pi2 * r2;
70 
71  rand1 = slg1 * cos(ang1);
72  rand2 = slg1 * sin(ang1);
73 }
74 
75 
76 //====================================================================
77 void RandomNumbers::lex_global(const std::string& str_rand_type, Field& f)
78 {
79  if (str_rand_type == "Gaussian") {
81  } else if (str_rand_type == "Uniform") {
83  } else if (str_rand_type == "U1") {
84  U1_lex_global(f);
85  } else if (str_rand_type == "Z2") {
86  Z2_lex_global(f);
87  } else {
88  vout.crucial(m_vl, "Error at %s: unsupported rand_type \"%s\"\n", class_name.c_str(), str_rand_type.c_str());
89  exit(EXIT_FAILURE);
90  }
91 }
92 
93 
94 //====================================================================
96 {
97  if (f.nin() % 2 == 0) {
98  return generate_global<rand_gauss_even>(f);
99  } else {
100  return generate_global<rand_gauss_odd>(f);
101  }
102 }
103 
104 
105 //====================================================================
107 {
108  return generate_global<rand_uniform>(f);
109 }
110 
111 
112 //====================================================================
114 {
115  // This implementation assumes the given field f is complex field.
116  gauss_lex_global(f);
117 
118  const int Nex = f.nex();
119  const int Nvol = f.nvol();
120  const int Nin = f.nin();
121 
122  assert(Nin % 2 == 0);
123 
124  for (int ex = 0; ex < Nex; ++ex) {
125  for (int site = 0; site < Nvol; ++site) {
126  for (int in_half = 0; in_half < Nin / 2; ++in_half) {
127  int idx_r = 2 * in_half;
128  int idx_i = 2 * in_half + 1;
129 
130  //- NB. arg = atan2(y,x), not atan2(x,y)
131  double arg = atan2(f.cmp(idx_i, site, ex), f.cmp(idx_r, site, ex));
132 
133  f.set(idx_r, site, ex, cos(arg));
134  f.set(idx_i, site, ex, sin(arg));
135  }
136  }
137  }
138 }
139 
140 
141 //====================================================================
143 {
144  // This implementation assumes the given field f is complex field.
145  generate_global<rand_uniform>(f);
146 
147  const int Nex = f.nex();
148  const int Nvol = f.nvol();
149  const int Nin = f.nin();
150 
151  assert(Nin % 2 == 0);
152 
153  double RF2 = 1.0 / sqrt(2.0);
154 
155  for (int ex = 0; ex < Nex; ++ex) {
156  for (int site = 0; site < Nvol; ++site) {
157  for (int in = 0; in < Nin; ++in) {
158  double rn1 = f.cmp(in, site, ex);
159  double rn2 = floor(2.0 * rn1);
160  double rn3 = (2.0 * rn2 - 1.0) * RF2;
161  f.set(in, site, ex, rn3);
162  }
163  }
164  }
165 }
166 
167 
168 //====================================================================
170 {
171  Field g = f.clone();
172 
173  gauss_lex_global(g);
174 
175  Index_eo idx;
176  idx.convertField(f, g);
177 }
178 
179 
180 //====================================================================
182 {
183  if (do_fill) {
184  for (size_t i = 0; i < m_block; i += 2) {
185  double r1 = m_rand_gauss->get();
186  double r2 = m_rand_gauss->get();
187 
188  double slg1 = sqrt(-log(1 - r1) * 2.0) * sq2r;
189  double ang1 = pi2 * r2;
190 
191  *m_ptr++ = slg1 * cos(ang1);
192  *m_ptr++ = slg1 * sin(ang1);
193  }
194  } else {
195  // just let rand_gauss state proceed
196  for (size_t i = 0; i < m_block; i += 2) {
197  m_rand_gauss->get();
198  m_rand_gauss->get();
199  }
200  }
201 }
202 
203 
205 {
206  return m_block;
207 }
208 
209 
210 //====================================================================
212 {
213  if (do_fill) {
214  size_t ngauss = m_block / 2;
215 
216  for (size_t i = 0; i < ngauss; ++i) {
217  double r1 = m_rand_gauss->get();
218  double r2 = m_rand_gauss->get();
219 
220  double slg1 = sqrt(-log(1 - r1) * 2.0) * sq2r;
221  double ang1 = pi2 * r2;
222 
223  *m_ptr++ = slg1 * cos(ang1);
224  *m_ptr++ = slg1 * sin(ang1);
225  }
226 
227  // remaining one
228  {
229  double r1 = m_rand_gauss->get();
230  double r2 = m_rand_gauss->get();
231 
232  double slg1 = sqrt(-log(1 - r1) * 2.0) * sq2r;
233  double ang1 = pi2 * r2;
234 
235  *m_ptr++ = slg1 * cos(ang1);
236  // the other one is dropped.
237  }
238  } else {
239  for (size_t i = 0; i < m_block + 1; ++i) {
240  m_rand_gauss->get();
241  }
242  }
243 }
244 
245 
247 {
248  return m_block + 1;
249 }
250 
251 
252 //====================================================================
254 {
255  if (do_fill) {
256  for (size_t i = 0; i < m_block; ++i) {
257  *m_ptr++ = m_rand_gauss->get();
258  }
259  } else {
260  for (size_t i = 0; i < m_block; ++i) {
261  m_rand_gauss->get();
262  }
263  }
264 }
265 
266 
268 {
269  return m_block;
270 }
271 
272 
273 //====================================================================
274 template<typename InnerGenerator>
276 {
277  InnerGenerator fill(f, this);
278 
279  const int Nin = f.nin();
280  const int Nvol = f.nvol();
281  const int Nex = f.nex();
282 
283  if (Communicator::size() == 1) {
284  vout.detailed(m_vl, "%s: single node. No need to consider division.\n", class_name.c_str());
285 
286  for (int j = 0; j < Nex; ++j) {
287  for (int i = 0; i < Nvol; ++i) {
288  fill(true);
289  }
290  }
291  } else {
292  assert(Nvol == CommonParameters::Nvol());
293 
294  const int Lx = CommonParameters::Lx();
295  const int Ly = CommonParameters::Ly();
296  const int Lz = CommonParameters::Lz();
297  const int Lt = CommonParameters::Lt();
298 
299  const int Nx = CommonParameters::Nx();
300  const int Ny = CommonParameters::Ny();
301  const int Nz = CommonParameters::Nz();
302  const int Nt = CommonParameters::Nt();
303 
304  const int ipe_x = Communicator::ipe(0);
305  const int ipe_y = Communicator::ipe(1);
306  const int ipe_z = Communicator::ipe(2);
307  const int ipe_t = Communicator::ipe(3);
308 
309  for (int j = 0; j < Nex; ++j) {
310  bool in_j = true;
311 
312  for (int t = 0; t < Lt; ++t) {
313  bool in_t = in_j && (t >= ipe_t * Nt) && (t < (ipe_t + 1) * Nt);
314 
315  for (int z = 0; z < Lz; ++z) {
316  bool in_z = in_t && (z >= ipe_z * Nz) && (z < (ipe_z + 1) * Nz);
317 
318  for (int y = 0; y < Ly; ++y) {
319  bool in_y = in_z && (y >= ipe_y * Ny) && (y < (ipe_y + 1) * Ny);
320 
321  for (int x = 0; x < Lx; ++x) {
322  bool in_x = in_y && (x >= ipe_x * Nx) && (x < (ipe_x + 1) * Nx);
323 
324  fill(in_x);
325  }
326  }
327  }
328  }
329  }
330  } // end if communicator::size == 1
331 }
332 
333 
334 //====================================================================
335 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:503
void detailed(const char *format,...)
Definition: bridgeIO.cpp:216
virtual double get()=0
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
virtual void uniform_lex_global(Field &)
uniform random number defined on global lattice.
Container of Field-type object.
Definition: field.h:45
int nvol() const
Definition: field.h:127
virtual void U1_lex_global(Field &)
U(1) random number defined on global lattice.
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:143
static int ipe(const int dir)
logical coordinate of current proc.
Even-odd site index.
Definition: index_eo.h:40
static const std::string class_name
Definition: randomNumbers.h:46
void convertField(Field &eo, const Field &lex)
Definition: index_eo.cpp:20
virtual void gauss_lex_global(Field &)
gaussian random number defined on global lattice.
Bridge::VerboseLevel m_vl
Definition: randomNumbers.h:49
int nin() const
Definition: field.h:126
void operator()(const bool do_fill)
virtual void gauss_eo_global(Field &)
gaussian noise for even-odd perconditioned field (S.UEDA)
Field clone() const
Definition: field.h:90
int nex() const
Definition: field.h:128
void operator()(const bool do_fill)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
void operator()(const bool do_fill)
static int size()
size of small world.
virtual void lex_global(const std::string &, Field &)
virtual void Z2_lex_global(Field &)
Z(2) random number defined on global lattice.
void generate_global(Field &f)
void gauss(double &rand1, double &rand2)