CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

testAnonymousEngineRestore.cc
Go to the documentation of this file.
1 // ----------------------------------------------------------------------
2 #include "CLHEP/Units/GlobalPhysicalConstants.h" // used to provoke shadowing warnings
3 #include "CLHEP/Random/Randomize.h"
4 #include "CLHEP/Random/NonRandomEngine.h"
5 #include "CLHEP/Random/defs.h"
6 #include <iostream>
7 #include <iomanip>
8 #include <vector>
9 
10 #define CLEAN_OUTPUT
11 #ifdef CLEAN_OUTPUT
12  std::ofstream output("testAnonymousEngineRestore.cout");
13 #else
14  std::ostream & output = std::cout;
15 #endif
16 
17 // Normally on for routine validation:
18 
19 #ifdef TURNOFF
20 #endif
21 
22 #define TEST_ANONYMOUS_ENGINE_RESTORE
23 #define TEST_ANONYMOUS_RESTORE_STATICS
24 
25 #define VERBOSER
26 #define VERBOSER2
27 
28 using namespace CLHEP;
29 
30 template <class E1, class E2> int anonymousRestoreStatics();
31 
32 
33 // Absolutely Safe Equals Without Registers Screwing Us Up
34 bool equals01(const std::vector<double> &ab) {
35  return ab[1]==ab[0];
36 }
37 bool equals(double a, double b) {
38  std::vector<double> ab(2);
39  ab[0]=a; ab[1]=b;
40  return (equals01(ab));
41 }
42 
43 std::vector<double> aSequence(int n) {
44  std::vector<double> v;
45  DualRand e(13542);
46  RandFlat f(e);
47  for (int i=0; i<n; i++) {
48  v.push_back(f());
49  }
50  return v;
51 }
52 
53 // ----------- Tests saving all statics together -----------
54 
55 void randomizeStatics(int n) {
56  for (int i=0; i<n; i++) {
75  }
76 }
77 
78 std::vector<double> captureStatics() {
79  std::vector<double> c;
80  c.push_back( RandGauss::shoot() );
81  c.push_back( RandGaussQ::shoot() );
82  c.push_back( RandGaussT::shoot() );
83  c.push_back( RandFlat::shoot() );
84  c.push_back( RandBit::shoot() );
85  for (int i=0; i<20; i++) {
86  c.push_back( RandFlat::shootBit() );
87  c.push_back( RandBit::shootBit() );
88  }
89  c.push_back( RandPoisson::shoot() );
90  c.push_back( RandPoissonQ::shoot() );
91  c.push_back( RandPoissonT::shoot() );
92  c.push_back( RandBinomial::shoot() );
93  c.push_back( RandBreitWigner::shoot() );
94  c.push_back( RandChiSquare::shoot() );
95  c.push_back( RandExponential::shoot() );
96  c.push_back( RandGamma::shoot() );
97  c.push_back( RandLandau::shoot() );
98  c.push_back( RandSkewNormal::shoot() );
99  c.push_back( RandStudentT::shoot() );
100  return c;
101 }
102 
103 void saveStatics(std::string filename) {
104  std::ofstream os(filename.c_str());
106  // It should be possible to call this from HepRandom, or any distribution.
107  // RandGeneral, which is meaningless as a static distribution, should be the
108  // toughest test, so we use that here.
109 }
110 
111 void restoreStatics(std::string filename) {
112  std::ifstream is(filename.c_str());
114 }
115 
116 
117 
118 // ----------- Anonymous restore of engines -----------
119 
120 template <class E>
121 void anonymousRestore1(int n, std::vector<double> & v) {
122  output << "Anonymous restore for " << E::engineName() << "\n";
123  E e(12349876);
124  double r=0;
125  for (int i=0; i<n; i++) r += e.flat();
126  std::ofstream os("anonymous.save");
127  os << e;
128  for (int j=0; j<25; j++) v.push_back(e.flat());
129 #ifdef VERBOSER2
130  output << "First four of v are: "
131  << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "\n";
132 #endif
133  return;
134 }
135 
136 template <>
137 void anonymousRestore1<NonRandomEngine> (int n, std::vector<double> & v) {
138 #ifdef VERBOSER
139  output << "Anonymous restore for " << NonRandomEngine::engineName() << "\n";
140 #endif
141  std::vector<double> nonRand = aSequence(500);
142  NonRandomEngine e;
143  e.setRandomSequence(&nonRand[0], nonRand.size());
144  double r=0;
145  for (int i=0; i<n; i++) r += e.flat();
146  std::ofstream os("anonymous.save");
147  os << e;
148  for (int j=0; j<25; j++) v.push_back(e.flat());
149 #ifdef VERBOSER2
150  output << "First four of v are: "
151  << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "\n";
152 #endif
153  return;
154 }
155 
156 template <class E>
157 int anonymousRestore2(const std::vector<double> & v) {
158  int stat = 0;
159  std::vector<double> k;
160  std::ifstream is("anonymous.save");
161  HepRandomEngine * a;
163  for (int j=0; j<25; j++) k.push_back(a->flat());
164  delete a;
165 #ifdef VERBOSER2
166  output << "First four of k are: "
167  << k[0] << ", " << k[1] << ", " << k[2] << ", " << k[3] << "\n";
168 #endif
169  for (int m=0; m<25; m++) {
170  if ( v[m] != k[m] ) {
171  std::cout << "???? Incorrect restored value for anonymous engine"
172  << E::engineName() << "\n";
173  #ifdef CLEAN_OUTPUT
174  output << "???? Incorrect restored value for anonymous engine"
175  << E::engineName() << "\n";
176  #endif
177  stat |= 262144;
178  return stat;
179  }
180  }
181  return stat;
182 }
183 
184 
185 template <class E>
186 int anonymousRestore(int n) {
187  std::vector<double> v;
188  anonymousRestore1<E>(n,v);
189  return anonymousRestore2<E>(v);
190 }
191 
192 // ----------- Anonymous restore of all static distributions -----------
193 
194 template <class E>
196  int stat = 0;
197  HepRandomEngine *e = new E(12456);
199  randomizeStatics(15);
200  output << "\nRandomized, with theEngine = " << e->name() << "\n";
201  saveStatics("distribution.save");
202  output << "Saved all static distributions\n";
203  std::vector<double> c = captureStatics();
204  output << "Captured output of all static distributions\n";
205  randomizeStatics(11);
206  output << "Randomized all static distributions\n";
207  restoreStatics("distribution.save");
208  output << "Restored all static distributions to saved state\n";
209  std::vector<double> d = captureStatics();
210  output << "Captured output of all static distributions\n";
211  for (unsigned int iv=0; iv<c.size(); iv++) {
212  if (c[iv] != d[iv]) {
213  std::cout << "???? restoreStaticRandomStates failed at random "
214  << iv <<"\n";
215  #ifdef CLEAN_OUTPUT
216  output << "???? restoreStaticRandomStates failed at random "
217  << iv <<"\n";
218  #endif
219  stat |= 131072;
220  }
221  }
222  if ( (stat & 131072) == 0) {
223  output << "All captured output agrees with earlier values\n";
224  }
225  return stat;
226 }
227 
228 
229 
230 template <class E1, class E2>
232  int stat = 0;
233  if ( E1::engineName() == E2::engineName() ) {
234  return anonymousRestoreStatics1<E1>();
235  }
236  HepRandomEngine *e1 = new E1(12456);
238  randomizeStatics(15);
239  output << "\nRandomized, with theEngine = " << e1->name() << "\n";
240  saveStatics("distribution.save");
241 #ifdef VERBOSER2
242  output << "Saved all static distributions\n";
243 #endif
244  std::vector<double> c = captureStatics();
245 #ifdef VERBOSER2
246  output << "Captured output of all static distributions\n";
247 #endif
248  delete e1;
249  HepRandomEngine *e2 = new E2(24653);
251  output << "Switched to theEngine = " << e2->name() << "\n";
252  randomizeStatics(19);
253  { std::ofstream os("engine.save"); os << *e2; }
254  double v1 = e2->flat();
255  double v2 = e2->flat();
256  { std::ifstream is("engine.save"); is >> *e2; }
257 #ifdef VERBOSER2
258  output << "Saved the " << e2->name() << " engine: \n"
259  << "Next randoms to be " << v1 << " " << v2 << "\n"
260  << "Restored the " << e2->name() << " engine to that state\n";
261 #endif
262  restoreStatics("distribution.save");
263 #ifdef VERBOSER2
264  output << "Restored all static distributions to saved state\n"
265  << "This changes the engine type back to " << E1::engineName() << "\n";
266 #endif
267  std::vector<double> d = captureStatics();
268 #ifdef VERBOSER2
269  output << "Captured output of all static distributions\n";
270 #endif
271  for (unsigned int iv=0; iv<c.size(); iv++) {
272  if (c[iv] != d[iv]) {
273  std::cout << "???? restoreStaticRandomStates failed at random "
274  << iv <<"\n";
275  #ifdef CLEAN_OUTPUT
276  output << "???? restoreStaticRandomStates failed at random "
277  << iv <<"\n";
278  #endif
279  stat |= 524288;
280  }
281  }
282  if ((stat & 524288) == 0) {
283  output << "All captured output agrees with earlier values\n";
284  }
285  double k1 = e2->flat();
286  double k2 = e2->flat();
287 #ifdef VERBOSER2
288  output << "The " << e2->name() << " engine should not have been affected: \n"
289  << "Next randoms are " << k1 << " " << k2 << "\n";
290 #endif
291  if ( !equals(v1,k1) || !equals(v2,k2) ) {
292  std::cout << "???? Engine used as theEngine was affected by restoring \n"
293  << " static distributions to use engine of a different type.\n";
294  #ifdef CLEAN_OUTPUT
295  output << "???? Engine used as theEngine was affected by restoring \n"
296  << " static distributions to use engine of a different type.\n";
297  #endif
298  stat |= 1048576;
299  }
300  return stat;
301 }
302 
303 // ---------------------------------------------
304 // ---------------------------------------------
305 // ---------------------------------------------
306 
307 
308 int main() {
309  int stat = 0;
310 
311 #ifdef TEST_ANONYMOUS_ENGINE_RESTORE
312  output << "\n=================================\n";
313  output << " Part VII \n";
314  output << "Anonymous restore of engines \n";
315  output << "=================================\n\n";
316 
317  stat |= anonymousRestore<DualRand>(13);
318  stat |= anonymousRestore<DRand48Engine>(14);
319  stat |= anonymousRestore<Hurd160Engine>(15);
320  stat |= anonymousRestore<Hurd288Engine>(16);
321  stat |= anonymousRestore<HepJamesRandom>(17);
322  stat |= anonymousRestore<MTwistEngine>(18);
323  stat |= anonymousRestore<RandEngine>(29);
324  stat |= anonymousRestore<RanecuEngine>(39);
325  stat |= anonymousRestore<Ranlux64Engine>(19);
326  stat |= anonymousRestore<RanluxEngine>(20);
327  stat |= anonymousRestore<RanshiEngine>(21);
328  stat |= anonymousRestore<TripleRand>(22);
329  stat |= anonymousRestore<NonRandomEngine>(22);
330 #endif
331 
332 #ifdef TEST_ANONYMOUS_RESTORE_STATICS
333  output << "\n======================================\n";
334  output << " Part VIII \n";
335  output << "Anonymous restore static Distributions \n";
336  output << "======================================\n\n";
337 
338  stat |= anonymousRestoreStatics<DualRand, Ranlux64Engine> ( );
339  stat |= anonymousRestoreStatics<DRand48Engine, TripleRand> ( );
340  stat |= anonymousRestoreStatics<RandEngine, Ranlux64Engine> ( );
341  stat |= anonymousRestoreStatics<MTwistEngine, Hurd288Engine> ( );
342  stat |= anonymousRestoreStatics<RanecuEngine, MTwistEngine> ( );
343  stat |= anonymousRestoreStatics<HepJamesRandom, RanshiEngine> ( );
344  stat |= anonymousRestoreStatics<RanecuEngine, RandEngine> ( );
345  stat |= anonymousRestoreStatics<RanshiEngine, Hurd160Engine> ( );
346  stat |= anonymousRestoreStatics<TripleRand, DualRand> ( );
347  stat |= anonymousRestoreStatics<Hurd160Engine, HepJamesRandom> ( );
348  stat |= anonymousRestoreStatics<Hurd288Engine, RanecuEngine> ( );
349  stat |= anonymousRestoreStatics<HepJamesRandom, Ranlux64Engine> ( );
350  stat |= anonymousRestoreStatics<TripleRand, TripleRand> ( );
351  stat |= anonymousRestoreStatics<HepJamesRandom, HepJamesRandom> ( );
352 #endif
353 
354 
355  output << "\n=============================================\n\n";
356 
357  if (stat != 0) {
358  std::cout << "One or more problems detected: stat = " << stat << "\n";
359  output << "One or more problems detected: stat = " << stat << "\n";
360  } else {
361  output << "testAnonymousEngineRestore passed with no problems detected.\n";
362  }
363 
364  if (stat == 0) return 0;
365  if (stat > 0) return -(stat|1);
366  return stat|1;
367 }
368