1 // ----------------------------------------------------------------------
2 #include "CLHEP/Random/Randomize.h"
3 #include "CLHEP/Random/NonRandomEngine.h"
4 #include "CLHEP/Random/defs.h"
5 #include <iostream>
6 #include <iomanip>
7 #include <vector>
8 
9 #define CLEAN_OUTPUT
10 #ifdef CLEAN_OUTPUT
11   std::ofstream output("testStaticStreamSave.cout");
12 #else
13   std::ostream & output = std::cout;
14 #endif
15 
16 // Normally on  for routine validation:
17 
18 #ifdef TURNOFF
19 #endif
20 
21 #define TEST_STATIC_SAVE
22 #define TEST_SAVE_STATIC_STATES
23 
24 
25 #define VERBOSER
26 #define VERBOSER2
27 
28 using namespace CLHEP;
29 
30 // Absolutely Safe Equals Without Registers Screwing Us Up
equals01(const std::vector<double> & ab)31 bool equals01(const std::vector<double> &ab) {
32   return ab[1]==ab[0];
33 }
equals(double a,double b)34 bool equals(double a, double b) {
35   std::vector<double> ab(2);
36   ab[0]=a;  ab[1]=b;
37   return (equals01(ab));
38 }
39 
40 // ----------- Tests for static methods -----------
41 
42 template <class D>
staticSave(int n)43 int staticSave(int n) {
44   int stat = 0;
45   int i;
46   output << "staticSave for distribution " << D::distributionName() << "\n";
47   double r = 0;
48   double v1, v2, k1, k2;
49   for (i=0; i < n; i++) r += D::shoot();
50   {
51     std::ofstream file ("ss1_distribution.save");
52     D::saveFullState(file);
53     v1 = D::shoot();
54     D::saveFullState(file);
55     v2 = D::shoot();
56 #ifdef VERBOSER2
57     int pr = output.precision(20);
58     output << "v1 = " << v1 << "  v2 = " << v2 << "\n";
59     output.precision(pr);
60 #endif
61   }
62   for (i=0; i < n; i++) r += D::shoot();
63   {
64     std::ifstream file ("ss1_distribution.save");
65     D::restoreFullState(file);
66     k1 = D::shoot();
67     for (i=0; i < n; i++) r += D::shoot();
68     D::restoreFullState(file);
69     k2 = D::shoot();
70 #ifdef VERBOSER2
71     int pr = output.precision(20);
72     output << "k1 = " << k1 << "  k2 = " << k2 << "\n";
73     output.precision(pr);
74 #endif
75    }
76   if ( (k1 != v1) || (k2 != v2) ) {
77     std::cout << "???? restoreFullState failed for " << D::distributionName() << "\n";
78     #ifdef CLEAN_OUTPUT
79     output << "???? restoreFullState failed for " << D::distributionName() << "\n";
80     #endif
81     stat |= 8192;
82   }
83 
84   for (i=0; i < n; i++) r += D::shoot();
85   {
86     std::ofstream file ("ss2_distribution.save");
87     D::saveDistState(file) << *D::getTheEngine();
88     v1 = D::shoot();
89     D::saveDistState(file) << *D::getTheEngine();
90     v2 = D::shoot();
91 #ifdef VERBOSER2
92     int pr = output.precision(20);
93     output << "v1 = " << v1 << "  v2 = " << v2 << "\n";
94     output.precision(pr);
95 #endif
96   }
97   for (i=0; i < n; i++) r += D::shoot();
98   {
99     std::ifstream file ("ss2_distribution.save");
100     D::restoreDistState(file) >> *D::getTheEngine();
101     k1 = D::shoot();
102     for (i=0; i < n; i++) r += D::shoot();
103     D::restoreDistState(file) >> *D::getTheEngine();
104     k2 = D::shoot();
105 #ifdef VERBOSER2
106     int pr = output.precision(20);
107     output << "k1 = " << k1 << "  k2 = " << k2 << "\n";
108     output.precision(pr);
109 #endif
110   }
111   if ( (k1 != v1) || (k2 != v2) ) {
112     std::cout << "???? restoreDistState failed for " << D::distributionName() << "\n";
113     #ifdef CLEAN_OUTPUT
114     output << "???? restoreDistState failed for " << D::distributionName() << "\n";
115     #endif
116     stat |= 16384;
117   }
118 
119   return stat;
120 }
121 
122 template <class D>
staticSaveShootBit(int n)123 int staticSaveShootBit(int n) {
124   int stat = 0;
125   int i;
126   output << "staticSaveShootBit for " << D::distributionName() << "\n";
127   double r = 0;
128   int bit = 0;
129   int v1, v2, k1, k2;
130   for (i=0; i < n; i++) r += D::shoot();
131   for (i=0; i < n; i++) bit |= D::shootBit();
132   {
133     std::ofstream file ("ss1_distribution.save");
134     D::saveFullState(file);
135     v1=0;
136     for (i=0; i<25; i++) {
137       v1 <<=1;
138       v1 += D::shootBit();
139     }
140     for (i=0; i < n; i++) bit |= D::shootBit();
141     D::saveFullState(file);
142     v2=0;
143     for (i=0; i<25; i++) {
144       v2 <<=1;
145       v2 += D::shootBit();
146     }
147 #ifdef VERBOSER2
148     int pr = output.precision(20);
149     output << std::hex << "v1 = " << v1 << "  v2 = " << v2 << std::dec << "\n";
150     output.precision(pr);
151 #endif
152   }
153   for (i=0; i < n; i++) r += D::shoot();
154   {
155     std::ifstream file ("ss1_distribution.save");
156     D::restoreFullState(file);
157     k1=0;
158     for (i=0; i<25; i++) {
159       k1 <<=1;
160       k1 += D::shootBit();
161     }
162     for (i=0; i < n; i++) r += D::shoot();
163     D::restoreFullState(file);
164     k2=0;
165     for (i=0; i<25; i++) {
166       k2 <<=1;
167       k2 += D::shootBit();
168     }
169 #ifdef VERBOSER2
170     int pr = output.precision(20);
171     output << std::hex << "k1 = " << k1 << "  k2 = " << k2 << std::dec << "\n";
172     output.precision(pr);
173 #endif
174    }
175   if ( (k1 != v1) || (k2 != v2) ) {
176     std::cout << "???? restoreFullState failed for D shootBit()\n";
177     #ifdef CLEAN_OUTPUT
178     output << "???? restoreFullState failed for D shootBit()\n";
179     #endif
180     stat |= 32768;
181   }
182 
183   for (i=0; i < n; i++) r += D::shoot();
184   for (i=0; i < n; i++) bit |= D::shootBit();
185   {
186     std::ofstream file ("ss2_distribution.save");
187     D::saveDistState(file) << *D::getTheEngine();
188     v1=0;
189     for (i=0; i<25; i++) {
190       v1 <<=1;
191       v1 += D::shootBit();
192     }
193     for (i=0; i < n; i++) bit |= D::shootBit();
194     D::saveDistState(file) << *D::getTheEngine();
195     v2=0;
196     for (i=0; i<25; i++) {
197       v2 <<=1;
198       v2 += D::shootBit();
199     }
200 #ifdef VERBOSER2
201     int pr = output.precision(20);
202     output << std::hex << "v1 = " << v1 << "  v2 = " << v2 << std::dec << "\n";
203     output.precision(pr);
204 #endif
205   }
206   for (i=0; i < n; i++) r += D::shoot();
207   {
208     std::ifstream file ("ss2_distribution.save");
209     D::restoreDistState(file) >> *D::getTheEngine();
210     k1=0;
211     for (i=0; i<25; i++) {
212       k1 <<=1;
213       k1 += D::shootBit();
214     }
215     for (i=0; i < n; i++) r += D::shoot();
216     for (i=0; i < n; i++) r += D::shootBit();
217     D::restoreDistState(file) >> *D::getTheEngine();
218     k2=0;
219     for (i=0; i<25; i++) {
220       k2 <<=1;
221       k2 += D::shootBit();
222     }
223 #ifdef VERBOSER2
224     int pr = output.precision(20);
225     output << std::hex << "k1 = " << k1 << "  k2 = " << k2 << std::dec << "\n";
226     output.precision(pr);
227 #endif
228   }
229   if ( (k1 != v1) || (k2 != v2) ) {
230     std::cout << "???? restoreDistState failed for RnadFlat::shootBit()\n";
231     #ifdef CLEAN_OUTPUT
232     output << "???? restoreDistState failed for RnadFlat::shootBit()\n";
233     #endif
234     stat |= 65536;
235   }
236 
237   return stat;
238 }
239 
240 // ----------- Tests saving all statics together -----------
241 
randomizeStatics(int n)242 void randomizeStatics(int n) {
243   for (int i=0; i<n; i++) {
244     RandGauss::shoot();
245     RandGaussQ::shoot();
246     RandGaussT::shoot();
247     RandFlat::shoot();
248     RandBit::shoot();
249     RandFlat::shootBit();
250     RandBit::shootBit();
251     RandPoisson::shoot();
252     RandPoissonQ::shoot();
253     RandPoissonT::shoot();
254     RandBinomial::shoot();
255     RandBreitWigner::shoot();
256     RandChiSquare::shoot();
257     RandExponential::shoot();
258     RandGamma::shoot();
259     RandLandau::shoot();
260     RandSkewNormal::shoot();
261     RandStudentT::shoot();
262   }
263 }
264 
captureStatics()265 std::vector<double> captureStatics() {
266   std::vector<double> c;
267   c.push_back( RandGauss::shoot() );
268   c.push_back( RandGaussQ::shoot() );
269   c.push_back( RandGaussT::shoot() );
270   c.push_back( RandFlat::shoot() );
271   c.push_back( RandBit::shoot() );
272   for (int i=0; i<20; i++)  {
273     c.push_back( RandFlat::shootBit() );
274     c.push_back( RandBit::shootBit() );
275   }
276   c.push_back( RandPoisson::shoot() );
277   c.push_back( RandPoissonQ::shoot() );
278   c.push_back( RandPoissonT::shoot() );
279   c.push_back( RandBinomial::shoot() );
280   c.push_back( RandBreitWigner::shoot() );
281   c.push_back( RandChiSquare::shoot() );
282   c.push_back( RandExponential::shoot() );
283   c.push_back( RandGamma::shoot() );
284   c.push_back( RandLandau::shoot() );
285   c.push_back( RandSkewNormal::shoot() );
286   c.push_back( RandStudentT::shoot() );
287   return c;
288 }
289 
saveStatics(std::string filename)290 void saveStatics(std::string filename) {
291   std::ofstream os(filename.c_str());
292   RandGeneral::saveStaticRandomStates(os);
293   // It should be possible to call this from HepRandom, or any distribution.
294   // RandGeneral, which is meaningless as a static distribution, should be the
295   // toughest test, so we use that here.
296 }
297 
restoreStatics(std::string filename)298 void restoreStatics(std::string filename) {
299   std::ifstream is(filename.c_str());
300   RandLandau::restoreStaticRandomStates(is);
301 }
302 
303 // ---------------------------------------------
304 // ---------------------------------------------
305 // ---------------------------------------------
306 
307 
main()308 int main() {
309   int stat = 0;
310 
311 #ifdef TEST_STATIC_SAVE
312   output << "\n=========================================\n";
313   output << "              Part V \n";
314   output << "Static Save/restore to/from streams \n";
315   output << "=========================================\n\n";
316 
317   stat |= staticSave <RandGauss>(7);
318   stat |= staticSave <RandFlat>(7);
319   stat |= staticSaveShootBit<RandFlat> (19);
320   stat |= staticSaveShootBit<RandBit> (23);
321   for (int ibinom=0; ibinom<15; ibinom++) {
322     stat |= staticSave <RandBinomial>(7+3*ibinom);
323   }
324   stat |= staticSave <RandBreitWigner>(7);
325   stat |= staticSave <RandChiSquare>(7);
326   stat |= staticSave <RandExponential>(7);
327   stat |= staticSave <RandGamma>(7);
328   stat |= staticSave <RandGaussQ>(7);
329   stat |= staticSave <RandGaussT>(7);
330   stat |= staticSave <RandLandau>(7);
331   stat |= staticSave <RandPoisson>(7);
332   stat |= staticSave <RandPoissonQ>(7);
333   stat |= staticSave <RandPoissonT>(7);
334   stat |= staticSave <RandSkewNormal>(7);
335   stat |= staticSave <RandStudentT>(7);
336 #endif
337 
338 #ifdef TEST_SAVE_STATIC_STATES
339   output << "\n==============================================\n";
340   output << "                 Part VI  \n";
341   output << "Save/restore all static states to/from streams \n";
342   output << "==============================================\n\n";
343 
344   randomizeStatics(15);
345   saveStatics("ss_distribution.save");
346   output << "Saved all static distributions\n";
347   std::vector<double> c = captureStatics();
348   output << "Captured output of all static distributions\n";
349   randomizeStatics(11);
350   output << "Randomized all static distributions\n";
351   restoreStatics("ss_distribution.save");
352   output << "Restored all static distributions to saved state\n";
353   std::vector<double> d = captureStatics();
354   output << "Captured output of all static distributions\n";
355   for (unsigned int iv=0; iv<c.size(); iv++) {
356     if (c[iv] != d[iv]) {
357       std::cout << "???? restoreStaticRandomStates failed at random "
358                 << iv <<"\n";
359       #ifdef CLEAN_OUTPUT
360       output << "???? restoreStaticRandomStates failed at random "
361                 << iv <<"\n";
362       #endif
363       stat |= 131072;
364     }
365   }
366   if ((stat & 131072) == 0) {
367     output << "All captured output agrees with earlier values\n";
368   }
369 #endif
370 
371   output << "\n=============================================\n\n";
372 
373   if (stat != 0) {
374      std::cout << "One or more problems detected: stat = " << stat << "\n";
375      output << "One or more problems detected: stat = " << stat << "\n";
376   }  else {
377      output << "testStaticStreamSave passed with no problems detected.\n";
378   }
379 
380   if (stat == 0) return 0;
381   if (stat > 0) return -(stat|1);
382   return stat|1;
383 }
384 
385