Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
randomNumbers_Mseries.cpp
Go to the documentation of this file.
1 
14 #include "randomNumbers_Mseries.h"
15 
16 
17 #ifdef USE_FACTORY_AUTOREGISTER
18 namespace {
19  bool init = RandomNumbers_Mseries::register_factory();
20 }
21 #endif
22 
23 
24 const std::string RandomNumbers_Mseries::class_name = "RandomNumbers_Mseries";
25 const double RandomNumbers_Mseries::Fnorm = 4.656612870908988e-10;
26 
27 //====================================================================
28 void RandomNumbers_Mseries::reset(unsigned long seed)
29 {
30  initset((int)seed);
31 }
32 
33 
34 //====================================================================
35 void RandomNumbers_Mseries::initset(const int ndelay)
36 {
37  vout.general(m_vl, " Random number init: ndelay =%10d\n", ndelay);
38 
39  int IP = Np;
40  int IQ = Nq;
41 
42  int MACRM = 40;
43  int MACRI = 1;
44  unsigned IB[IP];
45 
46  unsigned IX = MACRI;
47  for (int i = 0; i < IP; ++i) {
48  IX = IX * 69069;
49  IB[i] = IX >> 31;
50  }
51 
52  int JR = 0;
53  int KR = IP - IQ;
54  for (int j = 0; j < IP; ++j) {
55  unsigned iwork = 0;
56 
57  for (int i = 0; i < 32; ++i) {
58  iwork = iwork * 2 + IB[JR];
59  IB[JR] = IB[JR] ^ IB[KR];
60  ++JR;
61  if (JR == IP) JR = 0;
62  ++KR;
63  if (KR == IP) KR = 0;
64  }
65 
66  w[j] = iwork >> 1;
67  }
68 
69  jr = JR;
70  kr = KR;
71 
72  delay3(ndelay);
73 }
74 
75 
76 //====================================================================
77 void RandomNumbers_Mseries::delay3(const int ndelay)
78 {
79  int IP = Np;
80  int IQ = Nq;
81 
82  int LAMBDA = ndelay;
83 
84  int MACRM = 40;
85  int MACRI = 1;
86 
87  unsigned IWK[2 * IP - 1];
88  unsigned C[2 * IP];
89  unsigned IB[IP + 32];
90 
91  int MU = MACRM;
92 
93  for (int i = 0; i < IP; ++i) {
94  IWK[i] = w[i];
95  }
96 
97  for (int i = IP; i < 2 * IP - 1; ++i) {
98  IWK[i] = IWK[i - IP] ^ IWK[i - IQ];
99  }
100 
101  for (int i = 0; i < MU; ++i) {
102  IB[i] = 0;
103  }
104  int M = LAMBDA;
105  int NB = MU - 1;
106 
107 continued220:
108  if (M <= IP - 1) goto continued300;
109  ++NB;
110  IB[NB] = M % 2;
111  M = M / 2;
112  goto continued220;
113 
114 continued300:
115  for (int i = 0; i < IP; ++i) {
116  C[i] = 0;
117  }
118 
119  C[M] = 1;
120  for (int j = NB; j >= 0; --j) {
121  for (int i = IP - 1; i >= 0; --i) {
122  C[2 * i + IB[j]] = C[i];
123  C[2 * i + 1 - IB[j]] = 0;
124  }
125  for (int i = 2 * IP - 1; i >= IP; --i) {
126  C[i - IP] = C[i - IP] ^ C[i];
127  C[i - IQ] = C[i - IQ] ^ C[i];
128  }
129  }
130 
131  for (int j = 0; j < IP; ++j) {
132  unsigned iwork = 0;
133  for (int i = 0; i < IP; ++i) {
134  iwork = iwork ^ (C[i] * IWK[j + i]);
135  }
136  w[j] = iwork;
137  }
138 }
139 
140 
141 //====================================================================
142 void RandomNumbers_Mseries::write_file(const std::string& filename)
143 {
144  vout.general(m_vl, "%s: write down to file = %s\n", class_name.c_str(), filename.c_str());
145 
146  if (Communicator::is_primary()) {
147  std::ofstream outfile;
148  outfile.open(filename.c_str());
149 
150  if (!outfile) {
151  vout.crucial(m_vl, "Error at %s: unable to open output file.\n", class_name.c_str());
152  exit(EXIT_FAILURE);
153  }
154 
155  outfile << " " << jr << " " << kr << std::endl;
156 
157  for (int i = 0; i < Np; i++) {
158  outfile << " " << w[i] << std::endl;
159  }
160 
161  outfile.close();
162  }
163 }
164 
165 
166 //====================================================================
167 void RandomNumbers_Mseries::read_file(const std::string& filename)
168 {
169  vout.general(m_vl, "%s: read from file = %s\n", class_name.c_str(), filename.c_str());
170 
171  if (Communicator::is_primary()) {
172  std::ifstream infile;
173  infile.open(filename.c_str());
174 
175  if (!infile) {
176  vout.crucial(m_vl, "Error at %s: unable to open input file.\n", class_name.c_str());
177  exit(EXIT_FAILURE);
178  }
179 
180  infile >> jr >> kr;
181 
182  for (int i = 0; i < Np; i++) {
183  infile >> w[i];
184  }
185 
186  infile.close();
187  }
188 
190  Communicator::broadcast(1, &jr, 0);
191  Communicator::broadcast(1, &kr, 0);
192 }
193 
194 
195 //====================================================================
196 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:503
void read_file(const std::string &)
save and load random number status.
void general(const char *format,...)
Definition: bridgeIO.cpp:197
void delay3(const int ndelay)
Bridge::VerboseLevel m_vl
Definition: randomNumbers.h:49
void initset(const int ndelay)
void reset(unsigned long seed)
reset state with new seed.
void write_file(const std::string &)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
static const double Fnorm
initialized in .cpp file.
static int broadcast(int count, double *data, int sender)
broadcast array of double from sender.
static bool is_primary()
check if the present node is primary in small communicator.
static const std::string class_name