Bridge++  Ver. 2.0.2
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=====
CommonParameters::Ny
static int Ny()
Definition: commonParameters.h:106
CommonParameters::Nz
static int Nz()
Definition: commonParameters.h:107
RandomNumbers::rand_gauss_odd::operator()
void operator()(const bool do_fill)
Definition: randomNumbers.cpp:211
randomNumbers_Mseries.h
randomNumbers.h
RandomNumbers::rand_gauss_even::m_block
size_t m_block
Definition: randomNumbers.h:110
Field::set
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
Field::clone
Field clone() const
Definition: field.h:90
RandomNumbers::class_name
static const std::string class_name
Definition: randomNumbers.h:46
RandomNumbers::rand_gauss_even::operator()
void operator()(const bool do_fill)
Definition: randomNumbers.cpp:181
RandomNumbers::gauss_eo_global
virtual void gauss_eo_global(Field &)
gaussian noise for even-odd perconditioned field (S.UEDA)
Definition: randomNumbers.cpp:169
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:219
Field::nex
int nex() const
Definition: field.h:128
RandomNumbers::lex_global
virtual void lex_global(const std::string &, Field &)
Definition: randomNumbers.cpp:77
RandomNumbers::rand_gauss_even::m_rand_gauss
RandomNumbers * m_rand_gauss
Definition: randomNumbers.h:108
RandomNumbers::Z2_lex_global
virtual void Z2_lex_global(Field &)
Z(2) random number defined on global lattice.
Definition: randomNumbers.cpp:142
Communicator::size
static int size()
size of small world.
Definition: communicator.cpp:81
CommonParameters::Ly
static int Ly()
Definition: commonParameters.h:92
CommonParameters::Nvol
static int Nvol()
Definition: commonParameters.h:109
Index_eo
Even-odd site index.
Definition: index_eo.h:44
RandomNumbers::U1_lex_global
virtual void U1_lex_global(Field &)
U(1) random number defined on global lattice.
Definition: randomNumbers.cpp:113
Field::nin
int nin() const
Definition: field.h:126
CommonParameters::Nx
static int Nx()
Definition: commonParameters.h:105
CommonParameters::Lt
static int Lt()
Definition: commonParameters.h:94
CommonParameters::Lx
static int Lx()
Definition: commonParameters.h:91
CommonParameters::Lz
static int Lz()
Definition: commonParameters.h:93
RandomNumbers::rand_uniform::operator()
void operator()(const bool do_fill)
Definition: randomNumbers.cpp:253
CommonParameters::Nt
static int Nt()
Definition: commonParameters.h:108
RandomNumbers::get
virtual double get()=0
AIndex_eo_qxs::idx
int idx(const int in, const int Nin, const int ist, const int Nx2, const int Ny, const int leo, const int Nvol2, const int ex)
Definition: aindex_eo.h:27
Field::nvol
int nvol() const
Definition: field.h:127
RandomNumbers::rand_uniform::block_size
size_t block_size() const
Definition: randomNumbers.cpp:267
randomNumbers_MT19937.h
RandomNumbers::rand_gauss_odd::block_size
size_t block_size() const
Definition: randomNumbers.cpp:246
Field::cmp
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:143
RandomNumbers::rand_gauss_even::block_size
size_t block_size() const
Definition: randomNumbers.cpp:204
RandomNumbers::uniform_lex_global
virtual void uniform_lex_global(Field &)
uniform random number defined on global lattice.
Definition: randomNumbers.cpp:106
RandomNumbers::m_vl
Bridge::VerboseLevel m_vl
Definition: randomNumbers.h:49
Communicator::ipe
static int ipe(const int dir)
logical coordinate of current proc.
Definition: communicator.cpp:105
RandomNumbers::generate_global
void generate_global(Field &f)
Definition: randomNumbers.cpp:275
index_eo.h
RandomNumbers::gauss
void gauss(double &rand1, double &rand2)
Definition: randomNumbers.cpp:62
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:180
randomNumbers_SFMT.h
Field
Container of Field-type object.
Definition: field.h:46
RandomNumbers::gauss_lex_global
virtual void gauss_lex_global(Field &)
gaussian random number defined on global lattice.
Definition: randomNumbers.cpp:95
RandomNumbers::rand_gauss_even::m_ptr
double * m_ptr
Definition: randomNumbers.h:109
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512