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

ranRestoreTest.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // $Id: ranRestoreTest.cc,v 1.6 2011/05/31 20:57:01 garren Exp $
00003 // ----------------------------------------------------------------------
00004 #include "CLHEP/Random/Randomize.h"
00005 #include "CLHEP/Random/NonRandomEngine.h"
00006 #include "CLHEP/Random/defs.h"
00007 #include <iostream>
00008 #include <iomanip>
00009 #include <vector>
00010 
00011 #define CLEAN_OUTPUT
00012 #ifdef CLEAN_OUTPUT
00013   std::ofstream output("ranRestoreTest.cout");  
00014 #else
00015   std::ostream & output = std::cout;
00016 #endif
00017 
00018 // Normally on  for routine validation:
00019 
00020 #define TEST_ORIGINAL_SAVE
00021 
00022 #ifdef TURNOFF
00023 #endif
00024 
00025 #define TEST_ENGINE_NAMES
00026 #define TEST_INSTANCE_METHODS
00027 #define TEST_SHARED_ENGINES
00028 #define TEST_STATIC_SAVE
00029 #define TEST_SAVE_STATIC_STATES
00030 #define TEST_ANONYMOUS_ENGINE_RESTORE
00031 #define TEST_ANONYMOUS_RESTORE_STATICS
00032 #define TEST_VECTOR_ENGINE_RESTORE
00033 
00034 // Normally off for routine validation:
00035 
00036 #ifdef TURNOFF
00037 #define TEST_MISSING_FILES
00038 #define CREATE_OLD_SAVES
00039 #define VERIFY_OLD_SAVES
00040 #endif
00041 
00042 //#define VERBOSER
00043 //#define VERBOSER2
00044 
00045 using namespace CLHEP;
00046 
00047 double remembered_r2;
00048 double remembered_r1005;
00049 double remembered_r1006;
00050 double remembered_r1007;
00051 
00052 // Absolutely Safe Equals Without Registers Screwing Us Up
00053 bool equals01(const std::vector<double> &ab) {
00054   return ab[1]==ab[0];
00055 }  
00056 bool equals(double a, double b) {
00057   std::vector<double> ab(2);
00058   ab[0]=a;  ab[1]=b;
00059   return (equals01(ab));
00060 }
00061 
00062 // ------------------- The following should all FAIL ------------
00063 
00064 int saveStepX() {
00065   double r = RandGauss::shoot();
00066   output << "r(1) = " << r << std::endl;
00067   HepRandom::saveEngineStatus();
00068   r = RandGauss::shoot();
00069   output << "r(2) = " << r << std::endl;
00070   remembered_r2 = r;
00071   r = RandGauss::shoot();
00072   output << "r(3) = " << r << std::endl;
00073   for (int i=0; i < 1001; i++) {
00074     r = RandGauss::shoot();
00075   }    
00076   r = RandGauss::shoot();
00077   remembered_r1005 = r;
00078   output << "r1005= " << r << std::endl;
00079   r = RandGauss::shoot();
00080   return 0;
00081 }
00082 
00083 int restoreStepX() {
00084   HepRandom::restoreEngineStatus();
00085   double r = RandGauss::shoot();
00086   output << "restored r(2) = " << r << std::endl;
00087   if ( ! equals(r,remembered_r2) ) {
00088     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00089   }
00090   r = RandGauss::shoot();
00091   output << "restored r(3) = " << r << std::endl;
00092   for (int i=0; i < 1001; i++) {
00093     r = RandGauss::shoot();
00094   }    
00095   r = RandGauss::shoot();
00096   output << "restored r1005= " << r << std::endl;
00097   if ( !equals(r,remembered_r1005) ) {
00098     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00099   }
00100   return 0;
00101 }
00102 
00103 int BsaveStepX() {
00104   int r = RandFlat::shootBit();
00105   output << "r(1) = " << r << std::endl;
00106   HepRandom::saveEngineStatus();
00107   r = RandFlat::shootBit();
00108   output << "r(2) = " << r << std::endl;
00109   remembered_r2 = r;
00110   r = RandFlat::shootBit();
00111   output << "r(3) = " << r << std::endl;
00112   double d;
00113   for (int i=0; i < 1001; i++) {
00114     d = RandFlat::shoot();
00115     if (d > 1) output << 
00116     "This line inserted so clever compilers don't warn about not using d\n";
00117   }    
00118   r = RandFlat::shootBit();
00119   remembered_r1005 = r;
00120   output << "r1005= " << r << std::endl;
00121   r = RandFlat::shootBit();
00122   return 0;
00123 }
00124 
00125 int BrestoreStepX() {
00126   HepRandom::restoreEngineStatus();
00127   int r = RandFlat::shootBit();
00128   output << "restored r(2) = " << r << std::endl;
00129   if ( r != remembered_r2 ) {
00130     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00131   }
00132   r = RandFlat::shootBit();
00133   output << "restored r(3) = " << r << std::endl;
00134   for (int i=0; i < 1001; i++) {
00135     r = RandFlat::shootBit();
00136   }    
00137   r = RandFlat::shootBit();
00138   output << "restored r1005= " << r << std::endl;
00139   if ( r != remembered_r1005 ) {
00140     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00141   }
00142   return 0;
00143 }
00144 
00145 // ------------------- The following should all WORK ------------
00146 
00147 int saveStep() {
00148   int stat=0;
00149   double r = RandGauss::shoot();
00150   output << "r(1) = " << r << std::endl;
00151   RandGauss::saveEngineStatus();
00152   r = RandGauss::shoot();
00153   output << "r(2) = " << r << std::endl;
00154   remembered_r2 = r;
00155   r = RandGauss::shoot();
00156   output << "r(3) = " << r << std::endl;
00157   for (int i=0; i < 1001; i++) {
00158     r = RandGauss::shoot();
00159   }    
00160   r = RandGauss::shoot();
00161   remembered_r1005 = r;
00162   output << "r1005= " << r << std::endl;
00163   r = RandGauss::shoot();
00164   return stat;
00165 }
00166 
00167 int restoreStep() {
00168   int stat=0;
00169   RandGauss::restoreEngineStatus();
00170   double r = RandGauss::shoot();
00171   output << "restored r(2) = " << r << std::endl;
00172   if ( !equals(r,remembered_r2) ) {
00173     std::cout << "restored r(2) = " << r << std::endl;
00174     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00175     stat += 1;
00176   }
00177   r = RandGauss::shoot();
00178   output << "restored r(3) = " << r << std::endl;
00179   for (int i=0; i < 1001; i++) {
00180     r = RandGauss::shoot();
00181   }    
00182   r = RandGauss::shoot();
00183   output << "restored r1005= " << r << std::endl;
00184   if ( !equals(r,remembered_r1005) ) {
00185     std::cout << "restored r1005= " << r << std::endl;
00186     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00187     stat += 2;
00188   }
00189   return stat;
00190 }
00191 
00192 int BsaveStep() {
00193   int stat=0;
00194   int r = RandFlat::shootBit();
00195   output << "r(1) = " << r << std::endl;
00196   RandFlat::saveEngineStatus();
00197   r = RandFlat::shootBit();
00198   output << "r(2) = " << r << std::endl;
00199   remembered_r2 = r;
00200   r = RandFlat::shootBit();
00201   output << "r(3) = " << r << std::endl;
00202   for (int i=0; i < 1001; i++) {
00203     r = RandFlat::shootBit();
00204   }    
00205   r = RandFlat::shootBit();
00206   remembered_r1005 = r;
00207   output << "r1005 = " << r << std::endl;
00208   r = RandFlat::shootBit();
00209   remembered_r1006 = r;
00210   output << "r1006 = " << r << std::endl;
00211   r = RandFlat::shootBit();
00212   remembered_r1007 = r;
00213   output << "r1007 = " << r << std::endl;
00214   r = RandFlat::shootBit();
00215   return stat;
00216 }
00217 
00218 int BrestoreStep() {
00219   int stat=0;
00220   RandFlat::restoreEngineStatus();
00221   int r = RandFlat::shootBit();
00222   output << "restored r(2) = " << r << std::endl;
00223   if ( r != remembered_r2 ) {
00224     stat += 4;
00225     std::cout << "restored r(2) = " << r << std::endl;
00226     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00227   }
00228   r = RandFlat::shootBit();
00229   output << "restored r(3) = " << r << std::endl;
00230   for (int i=0; i < 1001; i++) {
00231     r = RandFlat::shootBit();
00232   }    
00233   r = RandFlat::shootBit();
00234   output << "restored r1005= " << r << std::endl;
00235   if ( r != remembered_r1005 ) {
00236     stat += 8;
00237     std::cout << "restored r1005= " << r << std::endl;
00238     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00239   }
00240   r = RandFlat::shootBit();
00241   output << "restored r1006= " << r << std::endl;
00242   if ( r != remembered_r1006 ) {
00243     stat += 16;
00244     std::cout << "restored r1006= " << r << std::endl;
00245     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00246   }
00247   r = RandFlat::shootBit();
00248   output << "restored r1007= " << r << std::endl;
00249   if ( r != remembered_r1007 ) {
00250     stat += 32;
00251     std::cout << "restored r1007= " << r << std::endl;
00252     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00253   }
00254   return stat;
00255 }
00256 
00257 // --- The following should work, by failing in an expected way -------
00258 
00259 template <class E, class D>
00260 int fileNotThere() {
00261   int stat = 0;
00262   HepRandomEngine * old = D::getTheEngine();
00263   E e(123);
00264   output << "File-not-found test restoring "<<D::distributionName()<<":\n";
00265   D::setTheEngine(&e);
00266   D::restoreEngineStatus("noSuchFile");
00267   D::setTheEngine(old);  // If we don't do this, then the static engine shared
00268                          // by every shoot() method reamins e -- which is about
00269                          // to go out of scope and be destructed!
00270   return stat;
00271 }
00272 
00273 template <class E>
00274 int fileNotThereEngine() {
00275   int stat = 0;
00276   stat |= fileNotThere <E, RandBinomial>();
00277   stat |= fileNotThere <E, RandBit>();
00278   stat |= fileNotThere <E, RandBreitWigner>();
00279   stat |= fileNotThere <E, RandChiSquare>();
00280   stat |= fileNotThere <E, RandExponential>();
00281   stat |= fileNotThere <E, RandFlat>();
00282   stat |= fileNotThere <E, RandGamma>();
00283   stat |= fileNotThere <E, RandGauss>();
00284   stat |= fileNotThere <E, RandGaussQ>();
00285   stat |= fileNotThere <E, RandGaussT>();
00286   stat |= fileNotThere <E, RandLandau>();
00287   stat |= fileNotThere <E, RandPoisson>();
00288   stat |= fileNotThere <E, RandPoissonQ>();
00289   stat |= fileNotThere <E, RandPoissonT>();
00290   stat |= fileNotThere <E, RandSkewNormal>();
00291   stat |= fileNotThere <E, RandStudentT>();
00292   return stat;
00293 }
00294 
00295 int missingFile() {
00296   int stat = 0;
00297   stat |= fileNotThereEngine<DRand48Engine>();
00298   stat |= fileNotThereEngine<DualRand>();
00299   stat |= fileNotThereEngine<Hurd160Engine>();
00300   stat |= fileNotThereEngine<Hurd288Engine>();
00301   stat |= fileNotThereEngine<HepJamesRandom>();
00302   stat |= fileNotThereEngine<MTwistEngine>();
00303   stat |= fileNotThereEngine<RandEngine>();
00304   stat |= fileNotThereEngine<RanecuEngine>();
00305   stat |= fileNotThereEngine<Ranlux64Engine>();
00306   stat |= fileNotThereEngine<RanluxEngine>();
00307   stat |= fileNotThereEngine<RanshiEngine>();
00308   stat |= fileNotThereEngine<TripleRand>();
00309   return stat;
00310 }
00311   
00312 // -- The following was used to capture old-form engine states (sans name) --
00313 
00314 template <class E, class D>
00315 int saveEngine(const char* filename) {
00316   int stat = 0;
00317   HepRandomEngine * old = D::getTheEngine();
00318   E e(123);
00319   D::setTheEngine(&e);
00320   double r=0; 
00321   for (int i=0; i<3; i++) r += D::shoot();
00322   D::saveEngineStatus(filename);
00323   if (r == -99999999.1) stat = 999; // This prevents clever compilers from
00324                                     // deducing that r is never needed
00325   D::setTheEngine(old);  // If we don't do this, then the static engine shared
00326                          // by every shoot() method reamins e -- which is about
00327                          // to go out of scope and be destructed!
00328   return stat;
00329 }
00330 
00331 // -- The following checks on static engine restores, from old and new forms --
00332 
00333 template <class E, class D>
00334 int checkSaveEngine(const char* filename) {
00335   int stat = 0;
00336   HepRandomEngine * old = D::getTheEngine();
00337 
00338   // Generate save with current format (default file name is fine)
00339   E e(123);
00340   D::setTheEngine(&e);
00341   double r=0; 
00342   for (int i=0; i<3; i++) r += D::shoot();
00343   D::saveEngineStatus();
00344 
00345   // Figure out what the key variate value should be
00346   double keyValue = D::shoot();
00347 
00348   // Restore state based on old file, and check for proper value
00349   D::restoreEngineStatus(filename);
00350   if (!equals(D::shoot(), keyValue)) {
00351     std::cout << "???? Value mismatch from file " << filename << "\n";
00352     stat |= 64;
00353   }
00354 
00355   // Restore state based on that save, and check for proper value
00356   D::restoreEngineStatus();
00357   if (!equals(D::shoot(),keyValue)) {
00358     std::cout << "???? Value mismatch from new-format file \n";
00359     stat |= 128;
00360   }
00361 
00362   D::setTheEngine(old);  
00363   return stat;
00364 }
00365 
00366 
00367 // ----------- Tests for instance methods -----------
00368 
00369 template <class E>
00370 int checkEngineName(const std::string & name) {
00371   int stat = 0;
00372   output << E::engineName() << "\n";
00373   if (E::engineName() != name) {
00374     std::cout << "???? engineName mismatch for " << name << " <--> " 
00375                                         << E::engineName() << "\n";
00376     stat |= 256;
00377   }
00378   E e(123);
00379   if (e.name() != name) {
00380     std::cout << "???? name mismatch for " << name << " <--> " 
00381                                         << e.name() << "\n";
00382     stat |= 256;
00383   }
00384   return stat;
00385 }
00386 
00387 template <class E, class D>
00388 int checkEngine() {
00389   int stat = 0;
00390   E e(1234);
00391   D d(e);
00392   if (d.engine().name() != e.name()) {
00393     std::cout << "???? Improper d.engine() \n";
00394     stat |= 512;
00395   }
00396   return stat;
00397 }
00398 
00399 template <class E>
00400 int checkEngineInstanceSave(E & e) {
00401   int stat = 0;
00402   output << "checkEngineInstanceSave for " << e.name() << "\n";
00403   int pr=output.precision(20);
00404   double r=0; 
00405   for (int i=0; i<100; i++) r += e.flat();
00406   {std::ofstream os ("engine.save"); os << e;}
00407   for (int i=0; i<100; i++) r += e.flat();
00408   double keyValue1 = e.flat();
00409   double keyValue2 = e.flat();
00410 #ifdef VERBOSER
00411   output << keyValue1 << " " << keyValue2 << "\n";
00412 #endif
00413   E e2;
00414   {std::ifstream is ("engine.save"); is >> e2;}
00415   for (int i=0; i<100; i++) r += e2.flat();
00416   double k1 = e2.flat();
00417   double k2 = e2.flat();
00418 #ifdef VERBOSER
00419   output << k1 << " " << k2 << "\n";
00420 #endif
00421   if ( !(equals(k1,keyValue1)) || !(equals(k2,keyValue2)) ) {
00422     std::cout << "???? checkInstanceSave failed for " << e.name() << "\n";
00423     stat |= 1024;
00424   }
00425   output.precision(pr);
00426   return stat;
00427 }
00428 
00429 template <class E, class D>
00430 int checkSaveDistribution(D & d, int nth) {
00431   dynamic_cast<E &>(d.engine());
00432   int stat = 0;
00433   output << "checkSaveDistribution with " << d.engine().name() 
00434             << ", " << d.name() << "\n";
00435   double r=0; 
00436   r = d();
00437   double keyValue1, keyValue2, keyValue3, keyValue4;
00438   for (int i=0; i<nth; i++) r += d();
00439   {std::ofstream os ("distribution.save1"); os << d.engine() << d;}
00440   keyValue1 = d();
00441   keyValue2 = d();
00442   r += d();
00443   // A second capture will test non-cached if first tested cached case:
00444   {std::ofstream os ("distribution.save2"); os << d.engine() << d;}
00445   keyValue3 = d();
00446   keyValue4 = d();
00447   int pr = output.precision(20);
00448 #ifdef VERBOSER
00449   output << "keyValue1 = " << keyValue1 <<
00450              "  keyValue2 = " << keyValue2 << "\n";
00451   output << "keyValue3 = " << keyValue3 <<
00452              "  keyValue3 = " << keyValue4 << "\n";
00453 #endif
00454   output.precision(pr);
00455   E e;
00456   D d2(e);   
00457   { std::ifstream is ("distribution.save1"); is >> e >> d2;}
00458   double k1 = d2();
00459   double k2 = d2();
00460   { std::ifstream is ("distribution.save2"); is >> e >> d2;}
00461   double k3 = d2();
00462   double k4 = d2();
00463 #ifdef VERBOSER
00464   pr = output.precision(20);
00465   output << "k1 =        " << k1 <<
00466              "  k2 =        " << k2 << "\n";
00467   output << "k3 =        " << k3 <<
00468              "  k4 =        " << k4 << "\n";
00469   output.precision(pr);
00470 #endif
00471   if ( !equals(k1,keyValue1) || !equals(k2,keyValue2) ||
00472        !equals(k3,keyValue3) || !equals(k4,keyValue4) ) {
00473     std::cout << "???? Incorrect restored value for distribution " 
00474                         << d.name() << "\n"; 
00475     stat |= 2048;
00476   }
00477 //  if (stat) exit(-1);
00478   return stat;
00479 }
00480 
00481 template <class E>
00482 int checkRandGeneralDistribution(RandGeneral & d, int nth) {
00483   dynamic_cast<E &>(d.engine());
00484   int stat = 0;
00485   output << "checkSaveDistribution with " << d.engine().name() 
00486             << ", " << d.name() << "\n";
00487   double r=0; 
00488   r = d();
00489   double keyValue1, keyValue2, keyValue3, keyValue4;
00490   for (int i=0; i<nth; i++) r += d();
00491   {std::ofstream os ("distribution.save1"); os << d.engine() << d;}
00492   keyValue1 = d();
00493   keyValue2 = d();
00494   r += d();
00495   // A second capture will test non-cached if first tested cached case:
00496   {std::ofstream os ("distribution.save2"); os << d.engine() << d;}
00497   keyValue3 = d();
00498   keyValue4 = d();
00499   int pr = output.precision(20);
00500 #ifdef VERBOSER
00501   output << "keyValue1 = " << keyValue1 <<
00502              "  keyValue2 = " << keyValue2 << "\n";
00503   output << "keyValue3 = " << keyValue3 <<
00504              "  keyValue3 = " << keyValue4 << "\n";
00505 #endif
00506   output.precision(pr);
00507   E e;
00508   double temp = 1; 
00509   RandGeneral d2(e, &temp, 1);   
00510   { std::ifstream is ("distribution.save1"); is >> e >> d2;}
00511   double k1 = d2();
00512   double k2 = d2();
00513   { std::ifstream is ("distribution.save2"); is >> e >> d2;}
00514   double k3 = d2();
00515   double k4 = d2();
00516 #ifdef VERBOSER
00517   pr = output.precision(20);
00518   output << "k1 =        " << k1 <<
00519              "  k2 =        " << k2 << "\n";
00520   output << "k3 =        " << k3 <<
00521              "  k4 =        " << k4 << "\n";
00522   output.precision(pr);
00523 #endif
00524   if ( !equals(k1,keyValue1) || !equals(k2,keyValue2) ||
00525        !equals(k3,keyValue3) || !equals(k4,keyValue4) ) {
00526     std::cout << "???? Incorrect restored value for distribution " 
00527                         << d.name() << "\n"; 
00528     stat |= 2048;
00529   }
00530 //  if (stat) exit(-1);
00531   return stat;
00532 }
00533 
00534 template <class E>
00535 int checkDistributions() {
00536   int stat = 0;
00537   {RandGauss d(new E(12561),100.0,3.0);
00538    stat |= checkSaveDistribution<E,RandGauss> (d,33);                   }
00539   {RandGauss d(new E(12572),100.0,3.0);
00540    stat |= checkSaveDistribution<E,RandGauss> (d,34);                   }
00541   {RandGaussQ d(new E(12563),10.0,4.0);
00542    stat |= checkSaveDistribution<E,RandGaussQ> (d,33);                  }
00543   {RandGaussT d(new E(12564),5.0,2.0);
00544    stat |= checkSaveDistribution<E,RandGaussT> (d,33);                  }
00545   {RandBinomial d(new E(12565),4,0.6);
00546    stat |= checkSaveDistribution<E,RandBinomial> (d,33);                }
00547   {RandFlat d(new E(12576),12.5,35.0);
00548    stat |= checkSaveDistribution<E,RandFlat> (d,33);                    }
00549   {RandBit d(new E(12567));
00550    stat |= checkSaveDistribution<E,RandBit> (d,31);                     }
00551   {RandBit d(new E(12578));
00552    stat |= checkSaveDistribution<E,RandBit> (d,32);                     }
00553   {RandBit d(new E(12589));
00554    stat |= checkSaveDistribution<E,RandBit> (d,33);                     }
00555   {RandBreitWigner d(new E(125611),50.0,15.0);
00556    stat |= checkSaveDistribution<E,RandBreitWigner> (d,33);             }
00557   {RandChiSquare d(new E(125612),5.0);
00558    stat |= checkSaveDistribution<E,RandChiSquare> (d,33);               }
00559   {RandExponential d(new E(125713),8.00);
00560    stat |= checkSaveDistribution<E,RandExponential> (d,33);             }
00561   {RandGamma d(new E(125713),6.0,2.0);
00562    stat |= checkSaveDistribution<E,RandGamma> (d,33);                   }
00563   {RandLandau d(new E(125714));
00564    stat |= checkSaveDistribution<E,RandLandau> (d,33);                  }
00565   {RandSkewNormal d(new E(125713),8.00);
00566    stat |= checkSaveDistribution<E,RandSkewNormal> (d,33);              }
00567   {RandStudentT d(new E(125715),5);
00568    stat |= checkSaveDistribution<E,RandStudentT> (d,33);                }
00569 
00570   // Multiple tests of Poisson distributions for small desired, since 
00571   // the answer in each test is a small int, and coincidental agreement
00572   // is very possible.
00573   
00574   {RandPoisson d(new E(125616),2.5);
00575    stat |= checkSaveDistribution<E,RandPoisson> (d,33);                 }
00576   {RandPoisson d(new E(125617),105.0);
00577    stat |= checkSaveDistribution<E,RandPoisson> (d,34);                 }
00578   {RandPoisson d(new E(125618),2.5);
00579    stat |= checkSaveDistribution<E,RandPoisson> (d,35);                 }
00580   {RandPoisson d(new E(325618),2.5);
00581    stat |= checkSaveDistribution<E,RandPoisson> (d,36);                 }
00582   {RandPoisson d(new E(425618),2.5);
00583    stat |= checkSaveDistribution<E,RandPoisson> (d,37);                 }
00584   {RandPoisson d(new E(525618),2.5);
00585    stat |= checkSaveDistribution<E,RandPoisson> (d,38);                 }
00586   {RandPoisson d(new E(125619),110.0);
00587    stat |= checkSaveDistribution<E,RandPoisson> (d,39);                 }
00588   {RandPoissonQ d(new E(124616),2.5);
00589    stat |= checkSaveDistribution<E,RandPoissonQ> (d,33);                }
00590   {RandPoissonQ d(new E(126616),2.5);
00591    stat |= checkSaveDistribution<E,RandPoissonQ> (d,32);                }
00592   {RandPoissonQ d(new E(127616),2.5);
00593    stat |= checkSaveDistribution<E,RandPoissonQ> (d,31);                }
00594   {RandPoissonQ d(new E(129616),2.5);
00595    stat |= checkSaveDistribution<E,RandPoissonQ> (d,30);                }
00596   {RandPoissonQ d(new E(125616),110.0);
00597    stat |= checkSaveDistribution<E,RandPoissonQ> (d,33);                }
00598   {RandPoissonQ d(new E(125616),2.5);
00599    stat |= checkSaveDistribution<E,RandPoissonQ> (d,34);                }
00600   {RandPoissonQ d(new E(125616),110.0);
00601    stat |= checkSaveDistribution<E,RandPoissonQ> (d,34);                }
00602   {RandPoissonT d(new E(125616),2.5);
00603    stat |= checkSaveDistribution<E,RandPoissonT> (d,33);                }
00604   {RandPoissonT d(new E(125616),110.0);
00605    stat |= checkSaveDistribution<E,RandPoissonT> (d,33);                }
00606   {RandPoissonT d(new E(125616),2.5);
00607    stat |= checkSaveDistribution<E,RandPoissonT> (d,34);                }
00608   {RandPoissonT d(new E(125616),110.0);
00609    stat |= checkSaveDistribution<E,RandPoissonT> (d,34);                }
00610   {RandPoissonT d(new E(125916),2.5);
00611    stat |= checkSaveDistribution<E,RandPoissonT> (d,10);                }
00612   {RandPoissonT d(new E(125816),2.5);
00613    stat |= checkSaveDistribution<E,RandPoissonT> (d,11);                }
00614   {RandPoissonT d(new E(125716),2.5);
00615    stat |= checkSaveDistribution<E,RandPoissonT> (d,12);                }
00616 
00617   {std::vector<double> pdf;
00618    int nbins = 20;
00619    for (int i = 0; i < nbins; ++i) 
00620                 pdf.push_back( 5*i + (10.5-i) * (10.5-i) );
00621    RandGeneral d(new E(125917), &pdf[0], 20);  
00622    stat |= checkRandGeneralDistribution<E> (d,33);              }
00623    
00624   return stat;
00625 }
00626 
00627 template <class E, class D1, class D2>
00628 int checkSharingDistributions(D1 & d1, D2 & d2, int n1, int n2) {
00629   int stat = 0;
00630   output << "checkSharingDistribution with: \n" 
00631             << d1.name() << " using " << d1.engine().name() << " and\n"
00632             << d2.name() << " using " << d2.engine().name() << "\n";
00633   double r=0; 
00634   r = d1();
00635   r += d2();
00636   double kv11,kv12,kv13,kv14;
00637   double kv21,kv22,kv23,kv24;
00638   for (int i=0; i<n1; i++) r += d1();
00639   for (int j=0; j<n2; j++) r += d2();
00640   {std::ofstream os ("shared.save1"); os << d1.engine() << d1 << d2;}
00641   kv11 = d1();
00642   kv21 = d2();
00643   kv12 = d1();
00644   kv22 = d2();
00645   r += d1() + d2();
00646   // A second capture will test non-cached if first tested cached case:
00647   {std::ofstream os ("shared.save2"); os << d1.engine() << d1 << d2;}
00648   kv13 = d1();
00649   kv23 = d2();
00650   kv14 = d1();
00651   kv24 = d2();
00652 #ifdef VERBOSER2
00653   int pr = output.precision(20);
00654   output << "kv11 = " << kv11 <<
00655              "  kv21 = " << kv21 << "\n";
00656   output << "kv12 = " << kv12 <<
00657              "  kv22 = " << kv22 << "\n";
00658   output << "kv13 = " << kv13 <<
00659              "  kv23 = " << kv23 << "\n";
00660   output << "kv14 = " << kv14 <<
00661              "  kv24 = " << kv24 << "\n";
00662   output.precision(pr);
00663 #endif
00664   E e;
00665   D1 d1r(e);   
00666   D2 d2r(e);   
00667   { std::ifstream is ("shared.save1"); is >> e >> d1r >> d2r;}
00668   double k11 = d1r();
00669   double k21 = d2r();
00670   double k12 = d1r();
00671   double k22 = d2r();
00672   { std::ifstream is ("shared.save2"); is >> e >> d1r >> d2r;}
00673   double k13 = d1r();
00674   double k23 = d2r();
00675   double k14 = d1r();
00676   double k24 = d2r();
00677 #ifdef VERBOSER2
00678   pr = output.precision(20);
00679   output << "k11 = " << k11 <<
00680              "  k21 = " << k21 << "\n";
00681   output << "k12 = " << k12 <<
00682              "  k22 = " << k22 << "\n";
00683   output << "k13 = " << k13 <<
00684              "  k23 = " << k23 << "\n";
00685   output << "k14 = " << k14 <<
00686              "  k24 = " << k24 << "\n";
00687   output.precision(pr);
00688 #endif
00689   if ( !equals(k11,kv11) || !equals(k21,kv21) ||
00690        !equals(k12,kv12) || !equals(k22,kv22) ||
00691        !equals(k13,kv13) || !equals(k23,kv23) ||
00692        !equals(k14,kv14) || !equals(k24,kv24) ) {
00693     std::cout << "???? Incorrect restored value for distributions " 
00694                         << d1.name() << " " << d2.name() << "\n"; 
00695     stat |= 4096;
00696   }
00697 //  if (stat) exit(-1);
00698   return stat;
00699 }
00700 
00701 
00702 
00703 template <class E>
00704 int checkSharing() {
00705   int stat = 0;
00706   E e1(98746);
00707   RandGauss g1(e1,50.0,4.0);
00708   RandPoissonQ p1(e1, 112.0);
00709   RandGauss g2(e1,5.0,44.0);
00710   RandPoissonQ p2(e1, 212.0);
00711   stat |= checkSharingDistributions<E, RandGauss, RandPoissonQ>(g1,p1,5,4);
00712   stat |= checkSharingDistributions<E, RandGauss, RandPoissonQ>(g1,p2,6,6);
00713   stat |= checkSharingDistributions<E, RandGauss, RandPoissonQ>(g2,p1,8,9);
00714   stat |= checkSharingDistributions<E, RandGauss, RandPoissonQ>(g1,p1,7,5);
00715   stat |= checkSharingDistributions<E, RandPoissonQ, RandGauss>(p1,g2,5,4);
00716   stat |= checkSharingDistributions<E, RandPoissonQ, RandGauss>(p2,g1,6,6);
00717   stat |= checkSharingDistributions<E, RandPoissonQ, RandGauss>(p1,g1,8,9);
00718   stat |= checkSharingDistributions<E, RandPoissonQ, RandGauss>(p2,g1,7,5);     
00719   return stat;
00720 }
00721 
00722 std::vector<double> aSequence(int n) {
00723   std::vector<double> v;
00724   DualRand e(13542);
00725   RandFlat f(e);
00726   for (int i=0; i<n; i++) {
00727     v.push_back(f()); 
00728   }
00729   return v;
00730 }
00731 
00732 // ----------- Tests for static methods -----------
00733 
00734 template <class D>
00735 int staticSave(int n) {
00736   int stat = 0;
00737   int i;
00738   output << "staticSave for distribution " << D::distributionName() << "\n";
00739   double r = 0;
00740   double v1, v2, k1, k2;
00741   for (i=0; i < n; i++) r += D::shoot();
00742   {
00743     std::ofstream file ("distribution.save1"); 
00744     D::saveFullState(file);
00745     v1 = D::shoot();
00746     D::saveFullState(file);
00747     v2 = D::shoot();
00748 #ifdef VERBOSER2
00749     int pr = output.precision(20);
00750     output << "v1 = " << v1 << "  v2 = " << v2 << "\n";
00751     output.precision(pr);
00752 #endif
00753   }
00754   for (i=0; i < n; i++) r += D::shoot();
00755   {
00756     std::ifstream file ("distribution.save1"); 
00757     D::restoreFullState(file);
00758     k1 = D::shoot();
00759     for (i=0; i < n; i++) r += D::shoot();
00760     D::restoreFullState(file);
00761     k2 = D::shoot();
00762 #ifdef VERBOSER2
00763     int pr = output.precision(20);
00764     output << "k1 = " << k1 << "  k2 = " << k2 << "\n";
00765     output.precision(pr);
00766 #endif
00767    }
00768   if ( (k1 != v1) || (k2 != v2) ) {
00769     std::cout << "???? restoreFullState failed for " << D::distributionName() << "\n";
00770     stat |= 8192;
00771   }
00772 
00773   for (i=0; i < n; i++) r += D::shoot();
00774   {
00775     std::ofstream file ("distribution.save2"); 
00776     D::saveDistState(file) << *D::getTheEngine();
00777     v1 = D::shoot();
00778     D::saveDistState(file) << *D::getTheEngine();
00779     v2 = D::shoot();
00780 #ifdef VERBOSER2
00781     int pr = output.precision(20);
00782     output << "v1 = " << v1 << "  v2 = " << v2 << "\n";
00783     output.precision(pr);
00784 #endif
00785   }
00786   for (i=0; i < n; i++) r += D::shoot();
00787   {
00788     std::ifstream file ("distribution.save2"); 
00789     D::restoreDistState(file) >> *D::getTheEngine();
00790     k1 = D::shoot();
00791     for (i=0; i < n; i++) r += D::shoot();
00792     D::restoreDistState(file) >> *D::getTheEngine();
00793     k2 = D::shoot();
00794 #ifdef VERBOSER2
00795     int pr = output.precision(20);
00796     output << "k1 = " << k1 << "  k2 = " << k2 << "\n";
00797     output.precision(pr);
00798 #endif
00799   }
00800   if ( (k1 != v1) || (k2 != v2) ) {
00801     std::cout << "???? restoreDistState failed for " << D::distributionName() << "\n";
00802     stat |= 16384;
00803   }
00804 
00805   return stat;
00806 }
00807 
00808 template <class D>
00809 int staticSaveShootBit(int n) {
00810   int stat = 0;
00811   int i;
00812   output << "staticSaveShootBit for " << D::distributionName() << "\n";
00813   double r = 0;
00814   int bit = 0;
00815   int v1, v2, k1, k2;
00816   for (i=0; i < n; i++) r += D::shoot();
00817   for (i=0; i < n; i++) bit |= D::shootBit();
00818   {
00819     std::ofstream file ("distribution.save1"); 
00820     D::saveFullState(file);
00821     v1=0;
00822     for (i=0; i<25; i++) {
00823       v1 <<=1;
00824       v1 += D::shootBit();
00825     }
00826     for (i=0; i < n; i++) bit |= D::shootBit();
00827     D::saveFullState(file);
00828     v2=0;
00829     for (i=0; i<25; i++) {
00830       v2 <<=1;
00831       v2 += D::shootBit();
00832     }
00833 #ifdef VERBOSER2
00834     int pr = output.precision(20);
00835     output << std::hex << "v1 = " << v1 << "  v2 = " << v2 << std::dec << "\n";
00836     output.precision(pr);
00837 #endif
00838   }
00839   for (i=0; i < n; i++) r += D::shoot();
00840   {
00841     std::ifstream file ("distribution.save1"); 
00842     D::restoreFullState(file);
00843     k1=0;
00844     for (i=0; i<25; i++) {
00845       k1 <<=1;
00846       k1 += D::shootBit();
00847     }
00848     for (i=0; i < n; i++) r += D::shoot();
00849     D::restoreFullState(file);
00850     k2=0;
00851     for (i=0; i<25; i++) {
00852       k2 <<=1;
00853       k2 += D::shootBit();
00854     }
00855 #ifdef VERBOSER2
00856     int pr = output.precision(20);
00857     output << std::hex << "k1 = " << k1 << "  k2 = " << k2 << std::dec << "\n";
00858     output.precision(pr);
00859 #endif
00860    }
00861   if ( (k1 != v1) || (k2 != v2) ) {
00862     std::cout << "???? restoreFullState failed for D shootBit()\n";
00863     stat |= 32768;
00864   }
00865 
00866   for (i=0; i < n; i++) r += D::shoot();
00867   for (i=0; i < n; i++) bit |= D::shootBit();
00868   {
00869     std::ofstream file ("distribution.save2"); 
00870     D::saveDistState(file) << *D::getTheEngine();
00871     v1=0;
00872     for (i=0; i<25; i++) {
00873       v1 <<=1;
00874       v1 += D::shootBit();
00875     }
00876     for (i=0; i < n; i++) bit |= D::shootBit();
00877     D::saveDistState(file) << *D::getTheEngine();
00878     v2=0;
00879     for (i=0; i<25; i++) {
00880       v2 <<=1;
00881       v2 += D::shootBit();
00882     }
00883 #ifdef VERBOSER2
00884     int pr = output.precision(20);
00885     output << std::hex << "v1 = " << v1 << "  v2 = " << v2 << std::dec << "\n";
00886     output.precision(pr);
00887 #endif
00888   }
00889   for (i=0; i < n; i++) r += D::shoot();
00890   {
00891     std::ifstream file ("distribution.save2"); 
00892     D::restoreDistState(file) >> *D::getTheEngine();
00893     k1=0;
00894     for (i=0; i<25; i++) {
00895       k1 <<=1;
00896       k1 += D::shootBit();
00897     }
00898     for (i=0; i < n; i++) r += D::shoot();
00899     for (i=0; i < n; i++) r += D::shootBit();
00900     D::restoreDistState(file) >> *D::getTheEngine();
00901     k2=0;
00902     for (i=0; i<25; i++) {
00903       k2 <<=1;
00904       k2 += D::shootBit();
00905     }
00906 #ifdef VERBOSER2
00907     int pr = output.precision(20);
00908     output << std::hex << "k1 = " << k1 << "  k2 = " << k2 << std::dec << "\n";
00909     output.precision(pr);
00910 #endif
00911   }
00912   if ( (k1 != v1) || (k2 != v2) ) {
00913     std::cout << "???? restoreDistState failed for RnadFlat::shootBit()\n";
00914     stat |= 65536;
00915   }
00916 
00917   return stat;
00918 }
00919 
00920 // ----------- Tests saving all statics together -----------
00921 
00922 void randomizeStatics(int n) {
00923   for (int i=0; i<n; i++) {
00924     RandGauss::shoot();
00925     RandGaussQ::shoot();
00926     RandGaussT::shoot();
00927     RandFlat::shoot();
00928     RandBit::shoot();
00929     RandFlat::shootBit();
00930     RandBit::shootBit();
00931     RandPoisson::shoot();
00932     RandPoissonQ::shoot();
00933     RandPoissonT::shoot();
00934     RandBinomial::shoot();
00935     RandBreitWigner::shoot();
00936     RandChiSquare::shoot();
00937     RandExponential::shoot();
00938     RandGamma::shoot();
00939     RandLandau::shoot();
00940     RandSkewNormal::shoot();
00941     RandStudentT::shoot();
00942   }
00943 }
00944 
00945 std::vector<double> captureStatics() {
00946   std::vector<double> c;
00947   c.push_back( RandGauss::shoot() );
00948   c.push_back( RandGaussQ::shoot() );
00949   c.push_back( RandGaussT::shoot() );
00950   c.push_back( RandFlat::shoot() );
00951   c.push_back( RandBit::shoot() );
00952   for (int i=0; i<20; i++)  {
00953     c.push_back( RandFlat::shootBit() );
00954     c.push_back( RandBit::shootBit() );
00955   }
00956   c.push_back( RandPoisson::shoot() );      
00957   c.push_back( RandPoissonQ::shoot() );     
00958   c.push_back( RandPoissonT::shoot() );     
00959   c.push_back( RandBinomial::shoot() );     
00960   c.push_back( RandBreitWigner::shoot() );  
00961   c.push_back( RandChiSquare::shoot() );    
00962   c.push_back( RandExponential::shoot() );  
00963   c.push_back( RandGamma::shoot() );         
00964   c.push_back( RandLandau::shoot() );       
00965   c.push_back( RandSkewNormal::shoot() );  
00966   c.push_back( RandStudentT::shoot() );
00967   return c;     
00968 }
00969 
00970 void saveStatics(std::string filename) {
00971   std::ofstream os(filename.c_str());
00972   RandGeneral::saveStaticRandomStates(os);
00973   // It should be possible to call this from HepRandom, or any distribution.
00974   // RandGeneral, which is meaningless as a static distribution, should be the
00975   // toughest test, so we use that here.
00976 }
00977 
00978 void restoreStatics(std::string filename) {
00979   std::ifstream is(filename.c_str());
00980   RandLandau::restoreStaticRandomStates(is);
00981 }
00982 
00983 // ----------- Anonymous restore of engines -----------
00984 
00985 template <class E>
00986 void anonymousRestore1(int n, std::vector<double> & v) {
00987   output << "Anonymous restore for " << E::engineName() << "\n";
00988   E e(12349876);                                    
00989   double r=0;                                       
00990   for (int i=0; i<n; i++) r += e.flat();            
00991   std::ofstream os("anonymous.save");               
00992   os << e;                                          
00993   for (int j=0; j<25; j++) v.push_back(e.flat());   
00994 #ifdef VERBOSER2
00995   output << "First four of v are: " 
00996         << v[0] << ",  " << v[1] << ",  " << v[2] << ",  " << v[3] << "\n";
00997 #endif
00998   return;
00999 }
01000 
01001 template <>
01002 void anonymousRestore1<NonRandomEngine> (int n, std::vector<double> & v) {
01003 #ifdef VERBOSER
01004   output << "Anonymous restore for " << NonRandomEngine::engineName() << "\n";
01005 #endif
01006   std::vector<double> nonRand = aSequence(500);
01007   NonRandomEngine e; 
01008   e.setRandomSequence(&nonRand[0], nonRand.size());
01009   double r=0;
01010   for (int i=0; i<n; i++) r += e.flat();
01011   std::ofstream os("anonymous.save");
01012   os << e;
01013   for (int j=0; j<25; j++) v.push_back(e.flat()); 
01014 #ifdef VERBOSER2
01015   output << "First four of v are: " 
01016         << v[0] << ",  " << v[1] << ",  " << v[2] << ",  " << v[3] << "\n";
01017 #endif
01018   return;
01019 }
01020 
01021 template <class E>
01022 int anonymousRestore2(const std::vector<double> & v) {
01023   int stat = 0;
01024   std::vector<double> k;
01025   std::ifstream is("anonymous.save");
01026   HepRandomEngine * a;
01027   a = HepRandomEngine::newEngine(is);
01028   for (int j=0; j<25; j++) k.push_back(a->flat()); 
01029   delete a;
01030 #ifdef VERBOSER2
01031   output << "First four of k are: " 
01032         << k[0] << ",  " << k[1] << ",  " << k[2] << ",  " << k[3] << "\n";
01033 #endif
01034   for (int m=0; m<25; m++) {
01035     if ( v[m] != k[m] ) {
01036       std::cout << "???? Incorrect restored value for anonymous engine" 
01037                 << E::engineName() << "\n"; 
01038       stat |= 262144;
01039       return stat;
01040     }
01041   }
01042   return stat;       
01043 }
01044 
01045 
01046 template <class E>
01047 int anonymousRestore(int n) {
01048   std::vector<double> v;
01049   anonymousRestore1<E>(n,v);
01050   return anonymousRestore2<E>(v);  
01051 }
01052 
01053 // ----------- Anonymous restore of all static distributions -----------
01054 
01055 template <class E>
01056 int anonymousRestoreStatics1() {
01057   int stat = 0;
01058   HepRandomEngine *e = new E(12456);
01059   HepRandom::setTheEngine(e);
01060   randomizeStatics(15);
01061   output << "\nRandomized, with theEngine = " << e->name() << "\n";
01062   saveStatics("distribution.save");
01063   output << "Saved all static distributions\n";
01064   std::vector<double> c = captureStatics();
01065   output << "Captured output of all static distributions\n";
01066   randomizeStatics(11);
01067   output << "Randomized all static distributions\n";
01068   restoreStatics("distribution.save");
01069   output << "Restored all static distributions to saved state\n";
01070   std::vector<double> d = captureStatics();
01071   output << "Captured output of all static distributions\n";
01072   for (unsigned int iv=0; iv<c.size(); iv++) {
01073     if (c[iv] != d[iv]) {
01074       std::cout << "???? restoreStaticRandomStates failed at random " 
01075                 << iv <<"\n";
01076       stat |= 131072;
01077     }
01078   }
01079   if (stat & 131072 == 0) {
01080     output << "All captured output agrees with earlier values\n";
01081   }
01082   return stat;
01083 }
01084 
01085 
01086 
01087 template <class E1, class E2>
01088 int anonymousRestoreStatics() {
01089   int stat = 0;
01090   if ( E1::engineName() == E2::engineName() ) {
01091     return anonymousRestoreStatics1<E1>();
01092   }
01093   HepRandomEngine *e1 = new E1(12456);
01094   HepRandom::setTheEngine(e1);
01095   randomizeStatics(15);
01096   output << "\nRandomized, with theEngine = " << e1->name() << "\n";
01097   saveStatics("distribution.save");
01098 #ifdef VERBOSER2
01099   output << "Saved all static distributions\n";
01100 #endif
01101   std::vector<double> c = captureStatics();
01102 #ifdef VERBOSER2
01103   output << "Captured output of all static distributions\n";
01104 #endif
01105   delete e1;
01106   HepRandomEngine *e2 = new E2(24653);
01107   HepRandom::setTheEngine(e2);
01108   output << "Switched to theEngine = " << e2->name() << "\n";
01109   randomizeStatics(19);
01110   { std::ofstream os("engine.save"); os << *e2; }
01111   double v1 = e2->flat();
01112   double v2 = e2->flat();
01113   { std::ifstream is("engine.save"); is >> *e2; }
01114 #ifdef VERBOSER2
01115   output << "Saved the "  << e2->name() << " engine: \n"
01116          << "Next randoms to be " << v1 << " " << v2 << "\n"
01117          << "Restored the " << e2->name() << " engine to that state\n";
01118 #endif
01119   restoreStatics("distribution.save");
01120 #ifdef VERBOSER2
01121   output << "Restored all static distributions to saved state\n"
01122          << "This changes the engine type back to " << E1::engineName() << "\n";
01123 #endif
01124   std::vector<double> d = captureStatics();
01125 #ifdef VERBOSER2
01126   output << "Captured output of all static distributions\n";
01127 #endif
01128   for (unsigned int iv=0; iv<c.size(); iv++) {
01129     if (c[iv] != d[iv]) {
01130       std::cout << "???? restoreStaticRandomStates failed at random " 
01131                 << iv <<"\n";
01132       stat |= 524288;
01133     }
01134   }
01135   if (stat & 524288 == 0) {
01136     output << "All captured output agrees with earlier values\n";
01137   }
01138   double k1 = e2->flat();
01139   double k2 = e2->flat();
01140 #ifdef VERBOSER2
01141   output << "The "  << e2->name() << " engine should not have been affected: \n"
01142          << "Next randoms  are  " << k1 << " " << k2 << "\n";
01143 #endif
01144   if ( !equals(v1,k1) || !equals(v2,k2) ) {
01145     std::cout << "???? Engine used as theEngine was affected by restoring \n"
01146               << "     static distributions to use engine of a different type.\n";    
01147     stat |= 1048576; 
01148   }
01149   return stat;  
01150 }
01151 
01152 // ----------- Vector restore of engines -----------
01153 
01154 template <class E>
01155 std::vector<unsigned long> vectorRestore1(int n, std::vector<double> & v) {
01156   output << "Vector restore for " << E::engineName() << "\n";
01157   E e(97538466);                                    
01158   double r=0;                                       
01159   for (int i=0; i<n; i++) r += e.flat();            
01160   std::vector<unsigned long> state = e.put();       
01161   for (int j=0; j<25; j++) v.push_back(e.flat());   
01162 #ifdef VERBOSER2
01163   output << "First four of v are: " 
01164         << v[0] << ",  " << v[1] << ",  " << v[2] << ",  " << v[3] << "\n";
01165 #endif
01166   return state;
01167 }
01168 
01169 template <>
01170 std::vector<unsigned long>
01171 vectorRestore1<NonRandomEngine> (int n, std::vector<double> & v) {
01172 #ifdef VERBOSER2
01173   output << "Vector restore for " << NonRandomEngine::engineName() << "\n";
01174 #endif
01175   std::vector<double> nonRand = aSequence(500);
01176   NonRandomEngine e; 
01177   e.setRandomSequence(&nonRand[0], nonRand.size());
01178   double r=0;
01179   for (int i=0; i<n; i++) r += e.flat();
01180   std::vector<unsigned long> state = e.put();       
01181   for (int j=0; j<25; j++) v.push_back(e.flat()); 
01182 #ifdef VERBOSER2
01183   output << "First four of v are: " 
01184         << v[0] << ",  " << v[1] << ",  " << v[2] << ",  " << v[3] << "\n";
01185 #endif
01186   return state;
01187 }
01188 
01189 template <class E>
01190 int vectorRestore2(const std::vector<unsigned long> state,
01191                    const std::vector<double> & v) {
01192   int stat = 0;
01193   std::vector<double> k;
01194   HepRandomEngine * a;
01195   a = HepRandomEngine::newEngine(state);
01196   if (!a) {
01197       std::cout << "???? could not restore engine state from vector for " 
01198                 << E::engineName() << "\n"; 
01199       stat |= 1048576;
01200       return stat;
01201   }
01202   if (a->name() != E::engineName()) {
01203       std::cout << "???? restored engine state from vector for " 
01204                 << E::engineName() << "to different type of engine: "
01205                 << a->name() << "\n"
01206         << "There is probably a clash in CRC hashes for these two names!\n"; 
01207       stat |= 1048576;
01208       return stat;
01209   }
01210   for (int j=0; j<25; j++) k.push_back(a->flat());
01211   delete a;
01212 #ifdef VERBOSER2
01213   output << "First four of k are: " 
01214         << k[0] << ",  " << k[1] << ",  " << k[2] << ",  " << k[3] << "\n";
01215 #endif
01216   for (int m=0; m<25; m++) {
01217     if ( v[m] != k[m] ) {
01218       std::cout << "???? Incorrect vector restored value for anonymous engine: " 
01219                 << E::engineName() << "\n"; 
01220       stat |= 1048576;
01221       return stat;
01222     }
01223   }
01224   return stat;       
01225 }
01226 
01227 
01228 template <class E>
01229 int vectorRestore(int n) {
01230   std::vector<double> v;
01231   std::vector<unsigned long> state = vectorRestore1<E>(n,v);
01232   return vectorRestore2<E>(state, v);  
01233 }
01234 
01235 
01236 
01237 // ---------------------------------------------
01238 // ---------------------------------------------
01239 // ---------------------------------------------
01240 
01241 
01242 int main() {
01243   int stat = 0;
01244 
01245 #ifdef TEST_ORIGINAL_SAVE
01246   output << "=====================================\n";
01247   output << "             Part I \n";
01248   output << "Original tests of static save/restore\n";
01249   output << "=====================================\n\n";
01250   
01251   output << "Using old method or HepRandom::saveEngineStatus:\n";
01252   output << "All these tests should have a chance of failure.\n";
01253 
01254   output << RandGauss:: getTheEngine()->name();  
01255   output << RandGaussQ::getTheEngine()->name();  
01256 
01257   stat |= saveStepX();
01258   stat |= restoreStepX();
01259   stat |= BsaveStepX();
01260   stat |= BrestoreStepX();
01261   
01262   output << "Using the class-specific RandGauss::saveEngineStatus:\n";
01263   output << "All these tests should work properly.\n";
01264 
01265   stat |= saveStep();
01266   stat |= restoreStep();
01267   stat |= BsaveStep();
01268   stat |= BrestoreStep();
01269 #endif
01270   
01271 #ifdef TEST_MISSING_FILES
01272   output << "\n=======================================\n";
01273   output << "             Part Ia \n";
01274   output << "Test of behavior when a file is missing \n";
01275   output << "=======================================\n\n";
01276 
01277   output << "Testing restoreEngineStatus with missing file:\n";
01278   output << "Expect a number of <Failure to find or open> messages!\n";
01279   stat |= missingFile();
01280 #endif
01281 
01282 #ifdef CREATE_OLD_SAVES
01283   stat |= saveEngine<DRand48Engine, RandPoisson>("DRand48Engine.oldsav");
01284   stat |= saveEngine<DualRand,      RandPoisson>("DualRand.oldsav");
01285   stat |= saveEngine<Hurd160Engine, RandPoisson>("Hurd160Engine.oldsav");
01286   stat |= saveEngine<Hurd288Engine, RandPoisson>("Hurd288Engine.oldsav");
01287   stat |= saveEngine<HepJamesRandom,RandPoisson>("HepJamesRandom.oldsav");
01288   stat |= saveEngine<MTwistEngine,  RandPoisson>("MTwistEngine.oldsav");
01289   stat |= saveEngine<RanecuEngine,  RandPoisson>("RanecuEngine.oldsav");
01290   stat |= saveEngine<Ranlux64Engine,RandPoisson>("Ranlux64Engine.oldsav");
01291   stat |= saveEngine<RanluxEngine,  RandPoisson>("RanluxEngine.oldsav");
01292   stat |= saveEngine<RanshiEngine,  RandPoisson>("RanshiEngine.oldsav");
01293   stat |= saveEngine<TripleRand,    RandPoisson>("TripleRand.oldsav");
01294 #endif
01295 
01296 #ifdef VERIFY_OLD_SAVES
01297   output << "\n==============================================\n";
01298   output << "               Part Ib \n";
01299   output << "  Verification that changes wont invalidate \n";
01300   output << "invalidate engine saves from previous versions \n";
01301   output << "==============================================\n\n";
01302 
01303   stat |= checkSaveEngine<DRand48Engine, RandPoisson>("DRand48Engine.oldsav");
01304   stat |= checkSaveEngine<DualRand,      RandPoisson>("DualRand.oldsav");
01305   stat |= checkSaveEngine<Hurd160Engine, RandPoisson>("Hurd160Engine.oldsav");
01306   stat |= checkSaveEngine<Hurd288Engine, RandPoisson>("Hurd288Engine.oldsav");
01307   stat |= checkSaveEngine<HepJamesRandom,RandPoisson>("HepJamesRandom.oldsav");
01308   stat |= checkSaveEngine<MTwistEngine,  RandPoisson>("MTwistEngine.oldsav");
01309   stat |= checkSaveEngine<Ranlux64Engine,RandPoisson>("Ranlux64Engine.oldsav");
01310   stat |= checkSaveEngine<RanluxEngine,  RandPoisson>("RanluxEngine.oldsav");
01311   stat |= checkSaveEngine<RanshiEngine,  RandPoisson>("RanshiEngine.oldsav");
01312   stat |= checkSaveEngine<TripleRand,    RandPoisson>("TripleRand.oldsav");
01313   stat |= checkSaveEngine<RanecuEngine,  RandPoisson>("RanecuEngine.oldsav");
01314 #endif
01315 
01316 #ifdef TEST_ENGINE_NAMES
01317   output << "\n=============================================\n";
01318   output << "              Part II \n";
01319   output << "Check all engine names were entered correctly \n";
01320   output << "=============================================\n\n";
01321 
01322   stat |= checkEngineName<DRand48Engine >("DRand48Engine");
01323   stat |= checkEngineName<DualRand      >("DualRand");
01324   stat |= checkEngineName<Hurd160Engine >("Hurd160Engine");
01325   stat |= checkEngineName<Hurd288Engine >("Hurd288Engine");
01326   stat |= checkEngineName<HepJamesRandom>("HepJamesRandom");
01327   stat |= checkEngineName<MTwistEngine  >("MTwistEngine");
01328   stat |= checkEngineName<RandEngine    >("RandEngine");
01329   stat |= checkEngineName<RanecuEngine  >("RanecuEngine");
01330   stat |= checkEngineName<Ranlux64Engine>("Ranlux64Engine");
01331   stat |= checkEngineName<RanluxEngine  >("RanluxEngine");
01332   stat |= checkEngineName<RanshiEngine  >("RanshiEngine");
01333   stat |= checkEngineName<TripleRand    >("TripleRand");
01334 #endif
01335 
01336 #ifdef TEST_INSTANCE_METHODS
01337   output << "===========================================\n\n";
01338   output << "              Part III\n";
01339   output << "Check instance methods for specific engines \n";
01340   output << "     specific engines and distributions\n";
01341   output << "===========================================\n\n";
01342 
01343   {DualRand e(234);             stat |= checkEngineInstanceSave(e);}
01344   {Hurd160Engine e(234);        stat |= checkEngineInstanceSave(e);}
01345   {Hurd288Engine e(234);        stat |= checkEngineInstanceSave(e);}
01346   {HepJamesRandom e(234);       stat |= checkEngineInstanceSave(e);}
01347   {MTwistEngine e(234);         stat |= checkEngineInstanceSave(e);}
01348   {RandEngine e(234);           stat |= checkEngineInstanceSave(e);}
01349   {RanecuEngine e(234);         stat |= checkEngineInstanceSave(e);}
01350   {Ranlux64Engine e(234);       stat |= checkEngineInstanceSave(e);}
01351   {RanluxEngine e(234);         stat |= checkEngineInstanceSave(e);}
01352   {RanshiEngine e(234);         stat |= checkEngineInstanceSave(e);}
01353   {TripleRand e(234);           stat |= checkEngineInstanceSave(e);}
01354   
01355   {std::vector<double> nonRand = aSequence(500);
01356    NonRandomEngine e; 
01357    e.setRandomSequence(&nonRand[0], nonRand.size());
01358    stat |= checkEngineInstanceSave(e);}
01359 
01360   stat |= checkDistributions<DualRand>();
01361   stat |= checkDistributions<Hurd160Engine>();
01362   stat |= checkDistributions<Hurd288Engine>();
01363   stat |= checkDistributions<HepJamesRandom>();
01364   stat |= checkDistributions<MTwistEngine>();
01365   stat |= checkDistributions<Ranlux64Engine>();
01366   stat |= checkDistributions<RanluxEngine>();
01367   stat |= checkDistributions<RanshiEngine>();
01368   stat |= checkDistributions<TripleRand>();
01369 
01370   RandGaussQ::shoot();  // Just to verify that the static engine is OK
01371 #endif
01372 
01373 #ifdef TEST_SHARED_ENGINES
01374   output << "\n=============================================\n";
01375   output << "              Part IV \n";
01376   output << "Check behavior when engines are shared \n";
01377   output << "=============================================\n\n";
01378   
01379   stat |= checkSharing<DualRand>();
01380   stat |= checkSharing<Hurd160Engine>();
01381   stat |= checkSharing<Hurd288Engine>();
01382   stat |= checkSharing<HepJamesRandom>();
01383   stat |= checkSharing<MTwistEngine>();
01384   stat |= checkSharing<Ranlux64Engine>();
01385   stat |= checkSharing<RanluxEngine>();
01386   stat |= checkSharing<RanshiEngine>();
01387   stat |= checkSharing<TripleRand>();
01388 #endif
01389 
01390 #ifdef TEST_STATIC_SAVE
01391   output << "\n=========================================\n";
01392   output << "              Part V \n";
01393   output << "Static Save/restore to/from streams \n";
01394   output << "=========================================\n\n";
01395  
01396   stat |= staticSave <RandGauss>(7);
01397   stat |= staticSave <RandFlat>(7);
01398   stat |= staticSaveShootBit<RandFlat> (19);
01399   stat |= staticSaveShootBit<RandBit> (23);
01400   for (int ibinom=0; ibinom<15; ibinom++) {
01401     stat |= staticSave <RandBinomial>(7+3*ibinom);
01402   }
01403   stat |= staticSave <RandBreitWigner>(7);
01404   stat |= staticSave <RandChiSquare>(7);
01405   stat |= staticSave <RandExponential>(7);
01406   stat |= staticSave <RandGamma>(7);
01407   stat |= staticSave <RandGaussQ>(7);
01408   stat |= staticSave <RandGaussT>(7);
01409   stat |= staticSave <RandLandau>(7);
01410   stat |= staticSave <RandPoisson>(7);
01411   stat |= staticSave <RandPoissonQ>(7);
01412   stat |= staticSave <RandPoissonT>(7);
01413   stat |= staticSave <RandSkewNormal>(7);
01414   stat |= staticSave <RandStudentT>(7);
01415 #endif
01416 
01417 #ifdef TEST_SAVE_STATIC_STATES
01418   output << "\n==============================================\n";
01419   output << "                 Part VI  \n";
01420   output << "Save/restore all static states to/from streams \n";
01421   output << "==============================================\n\n";
01422  
01423   randomizeStatics(15);
01424   saveStatics("distribution.save");
01425   output << "Saved all static distributions\n";
01426   std::vector<double> c = captureStatics();
01427   output << "Captured output of all static distributions\n";
01428   randomizeStatics(11);
01429   output << "Randomized all static distributions\n";
01430   restoreStatics("distribution.save");
01431   output << "Restored all static distributions to saved state\n";
01432   std::vector<double> d = captureStatics();
01433   output << "Captured output of all static distributions\n";
01434   for (unsigned int iv=0; iv<c.size(); iv++) {
01435     if (c[iv] != d[iv]) {
01436       std::cout << "???? restoreStaticRandomStates failed at random " 
01437                 << iv <<"\n";
01438       stat |= 131072;
01439     }
01440   }
01441   if (stat & 131072 == 0) {
01442     output << "All captured output agrees with earlier values\n";
01443   }
01444 #endif
01445   
01446 #ifdef TEST_ANONYMOUS_ENGINE_RESTORE
01447   output << "\n=================================\n";
01448   output << "         Part VII \n";
01449   output << "Anonymous restore of engines \n";
01450   output << "=================================\n\n";
01451 
01452   stat |= anonymousRestore<DualRand>(13);
01453   stat |= anonymousRestore<DRand48Engine>(14);
01454   stat |= anonymousRestore<Hurd160Engine>(15);
01455   stat |= anonymousRestore<Hurd288Engine>(16);
01456   stat |= anonymousRestore<HepJamesRandom>(17);
01457   stat |= anonymousRestore<MTwistEngine>(18);
01458   stat |= anonymousRestore<RandEngine>(29);
01459   stat |= anonymousRestore<RanecuEngine>(39);
01460   stat |= anonymousRestore<Ranlux64Engine>(19);
01461   stat |= anonymousRestore<RanluxEngine>(20);
01462   stat |= anonymousRestore<RanshiEngine>(21);
01463   stat |= anonymousRestore<TripleRand>(22);
01464   stat |= anonymousRestore<NonRandomEngine>(22);
01465 #endif
01466 
01467 #ifdef TEST_ANONYMOUS_RESTORE_STATICS
01468   output << "\n======================================\n";
01469   output << "             Part VIII \n";
01470   output << "Anonymous restore static Distributions \n";
01471   output << "======================================\n\n";
01472 
01473   stat |= anonymousRestoreStatics<DualRand,       Ranlux64Engine> ( );
01474   stat |= anonymousRestoreStatics<DRand48Engine,  TripleRand>     ( );
01475   stat |= anonymousRestoreStatics<RandEngine,     Ranlux64Engine> ( );
01476   stat |= anonymousRestoreStatics<MTwistEngine,   Hurd288Engine>  ( );
01477   stat |= anonymousRestoreStatics<RanecuEngine,   MTwistEngine>   ( );
01478   stat |= anonymousRestoreStatics<HepJamesRandom, RanshiEngine>   ( );
01479   stat |= anonymousRestoreStatics<RanecuEngine,   RandEngine>     ( );
01480   stat |= anonymousRestoreStatics<RanshiEngine,   Hurd160Engine>  ( );
01481   stat |= anonymousRestoreStatics<TripleRand,     DualRand>       ( );
01482   stat |= anonymousRestoreStatics<Hurd160Engine,  HepJamesRandom> ( );
01483   stat |= anonymousRestoreStatics<Hurd288Engine,  RanecuEngine>   ( );
01484   stat |= anonymousRestoreStatics<HepJamesRandom, Ranlux64Engine> ( ); 
01485   stat |= anonymousRestoreStatics<TripleRand,     TripleRand>     ( );
01486   stat |= anonymousRestoreStatics<HepJamesRandom, HepJamesRandom> ( );
01487 #endif
01488 
01489 #ifdef TEST_VECTOR_ENGINE_RESTORE
01490   output << "\n=================================\n";
01491   output << "         Part IX \n";
01492   output << "Save/restore of engines to vectors\n";
01493   output << "=================================\n\n";
01494 
01495   stat |= vectorRestore<DualRand>(113);
01496   stat |= vectorRestore<DRand48Engine>(114);
01497   stat |= vectorRestore<Hurd160Engine>(115);
01498   stat |= vectorRestore<Hurd288Engine>(116);
01499   stat |= vectorRestore<HepJamesRandom>(117);
01500   stat |= vectorRestore<MTwistEngine>(118);
01501   stat |= vectorRestore<RanecuEngine>(139);
01502   stat |= vectorRestore<Ranlux64Engine>(119);
01503   stat |= vectorRestore<RanluxEngine>(120);
01504   stat |= vectorRestore<RanshiEngine>(121);
01505   stat |= vectorRestore<TripleRand>(122);
01506   stat |= vectorRestore<NonRandomEngine>(123);
01507   stat |= vectorRestore<RandEngine>(129);
01508 #endif
01509 
01510 
01511 
01512  
01513   output << "\n=============================================\n\n";
01514 
01515   if (stat != 0) {
01516      std::cout << "One or more problems detected: stat = " << stat << "\n";
01517   }  else {
01518      output << "ranRestoreTest passed with no problems detected.\n";    
01519   }
01520 
01521   return stat;
01522 }       
01523 

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7