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

testSaveEngineStatus.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------
00002 #include "CLHEP/Random/Randomize.h"
00003 #include "CLHEP/Random/NonRandomEngine.h"
00004 #include "CLHEP/Random/defs.h"
00005 #include <iostream>
00006 #include <iomanip>
00007 #include <vector>
00008 
00009 #define CLEAN_OUTPUT
00010 #ifdef CLEAN_OUTPUT
00011   std::ofstream output("testSaveEngineStatus.cout");  
00012 #else
00013   std::ostream & output = std::cout;
00014 #endif
00015 
00016 // Normally on  for routine validation:
00017 
00018 #define TEST_ORIGINAL_SAVE
00019 
00020 // Normally off for routine validation:
00021 
00022 #ifdef TURNOFF
00023 #define TEST_MISSING_FILES
00024 #define CREATE_OLD_SAVES
00025 #define VERIFY_OLD_SAVES
00026 #endif
00027 
00028 #define VERBOSER
00029 #define VERBOSER2
00030 
00031 using namespace CLHEP;
00032 
00033 double remembered_r2;
00034 double remembered_r1005;
00035 double remembered_r1006;
00036 double remembered_r1007;
00037 
00038 // Absolutely Safe Equals Without Registers Screwing Us Up
00039 bool equals01(const std::vector<double> &ab) {
00040   return ab[1]==ab[0];
00041 }  
00042 bool equals(double a, double b) {
00043   std::vector<double> ab(2);
00044   ab[0]=a;  ab[1]=b;
00045   return (equals01(ab));
00046 }
00047 
00048 // ------------------- The following should all FAIL ------------
00049 
00050 int saveStepX() {
00051   double r = RandGauss::shoot();
00052   output << "r(1) = " << r << std::endl;
00053   HepRandom::saveEngineStatus();
00054   r = RandGauss::shoot();
00055   output << "r(2) = " << r << std::endl;
00056   remembered_r2 = r;
00057   r = RandGauss::shoot();
00058   output << "r(3) = " << r << std::endl;
00059   for (int i=0; i < 1001; i++) {
00060     r = RandGauss::shoot();
00061   }    
00062   r = RandGauss::shoot();
00063   remembered_r1005 = r;
00064   output << "r1005= " << r << std::endl;
00065   r = RandGauss::shoot();
00066   return 0;
00067 }
00068 
00069 int restoreStepX() {
00070   HepRandom::restoreEngineStatus();
00071   double r = RandGauss::shoot();
00072   output << "restored r(2) = " << r << std::endl;
00073   if ( ! equals(r,remembered_r2) ) {
00074     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00075   }
00076   r = RandGauss::shoot();
00077   output << "restored r(3) = " << r << std::endl;
00078   for (int i=0; i < 1001; i++) {
00079     r = RandGauss::shoot();
00080   }    
00081   r = RandGauss::shoot();
00082   output << "restored r1005= " << r << std::endl;
00083   if ( !equals(r,remembered_r1005) ) {
00084     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00085   }
00086   return 0;
00087 }
00088 
00089 int BsaveStepX() {
00090   int r = RandFlat::shootBit();
00091   output << "r(1) = " << r << std::endl;
00092   HepRandom::saveEngineStatus();
00093   r = RandFlat::shootBit();
00094   output << "r(2) = " << r << std::endl;
00095   remembered_r2 = r;
00096   r = RandFlat::shootBit();
00097   output << "r(3) = " << r << std::endl;
00098   double d;
00099   for (int i=0; i < 1001; i++) {
00100     d = RandFlat::shoot();
00101     if (d > 1) output << 
00102     "This line inserted so clever compilers don't warn about not using d\n";
00103   }    
00104   r = RandFlat::shootBit();
00105   remembered_r1005 = r;
00106   output << "r1005= " << r << std::endl;
00107   r = RandFlat::shootBit();
00108   return 0;
00109 }
00110 
00111 int BrestoreStepX() {
00112   HepRandom::restoreEngineStatus();
00113   int r = RandFlat::shootBit();
00114   output << "restored r(2) = " << r << std::endl;
00115   if ( r != remembered_r2 ) {
00116     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00117   }
00118   r = RandFlat::shootBit();
00119   output << "restored r(3) = " << r << std::endl;
00120   for (int i=0; i < 1001; i++) {
00121     r = RandFlat::shootBit();
00122   }    
00123   r = RandFlat::shootBit();
00124   output << "restored r1005= " << r << std::endl;
00125   if ( r != remembered_r1005 ) {
00126     output << "THIS DOES NOT MATCH REMEMBERED VALUE BUT THAT IS EXPECTED\n";
00127   }
00128   return 0;
00129 }
00130 
00131 // ------------------- The following should all WORK ------------
00132 
00133 int saveStep() {
00134   int stat=0;
00135   double r = RandGauss::shoot();
00136   output << "r(1) = " << r << std::endl;
00137   RandGauss::saveEngineStatus();
00138   r = RandGauss::shoot();
00139   output << "r(2) = " << r << std::endl;
00140   remembered_r2 = r;
00141   r = RandGauss::shoot();
00142   output << "r(3) = " << r << std::endl;
00143   for (int i=0; i < 1001; i++) {
00144     r = RandGauss::shoot();
00145   }    
00146   r = RandGauss::shoot();
00147   remembered_r1005 = r;
00148   output << "r1005= " << r << std::endl;
00149   r = RandGauss::shoot();
00150   return stat;
00151 }
00152 
00153 int restoreStep() {
00154   int stat=0;
00155   RandGauss::restoreEngineStatus();
00156   double r = RandGauss::shoot();
00157   output << "restored r(2) = " << r << std::endl;
00158   if ( !equals(r,remembered_r2) ) {
00159     std::cout << "restored r(2) = " << r << std::endl;
00160     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00161     #ifdef CLEAN_OUTPUT
00162     output << "restored r(2) = " << r << std::endl;
00163     output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00164     #endif
00165     stat += 1;
00166   }
00167   r = RandGauss::shoot();
00168   output << "restored r(3) = " << r << std::endl;
00169   for (int i=0; i < 1001; i++) {
00170     r = RandGauss::shoot();
00171   }    
00172   r = RandGauss::shoot();
00173   output << "restored r1005= " << r << std::endl;
00174   if ( !equals(r,remembered_r1005) ) {
00175     std::cout << "restored r1005= " << r << std::endl;
00176     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00177     #ifdef CLEAN_OUTPUT
00178     output << "restored r1005= " << r << std::endl;
00179     output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00180     #endif
00181     stat += 2;
00182   }
00183   return stat;
00184 }
00185 
00186 int BsaveStep() {
00187   int stat=0;
00188   int r = RandFlat::shootBit();
00189   output << "r(1) = " << r << std::endl;
00190   RandFlat::saveEngineStatus();
00191   r = RandFlat::shootBit();
00192   output << "r(2) = " << r << std::endl;
00193   remembered_r2 = r;
00194   r = RandFlat::shootBit();
00195   output << "r(3) = " << r << std::endl;
00196   for (int i=0; i < 1001; i++) {
00197     r = RandFlat::shootBit();
00198   }    
00199   r = RandFlat::shootBit();
00200   remembered_r1005 = r;
00201   output << "r1005 = " << r << std::endl;
00202   r = RandFlat::shootBit();
00203   remembered_r1006 = r;
00204   output << "r1006 = " << r << std::endl;
00205   r = RandFlat::shootBit();
00206   remembered_r1007 = r;
00207   output << "r1007 = " << r << std::endl;
00208   r = RandFlat::shootBit();
00209   return stat;
00210 }
00211 
00212 int BrestoreStep() {
00213   int stat=0;
00214   RandFlat::restoreEngineStatus();
00215   int r = RandFlat::shootBit();
00216   output << "restored r(2) = " << r << std::endl;
00217   if ( r != remembered_r2 ) {
00218     stat += 4;
00219     std::cout << "restored r(2) = " << r << std::endl;
00220     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00221     #ifdef CLEAN_OUTPUT
00222     output << "restored r(2) = " << r << std::endl;
00223     output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00224     #endif
00225   }
00226   r = RandFlat::shootBit();
00227   output << "restored r(3) = " << r << std::endl;
00228   for (int i=0; i < 1001; i++) {
00229     r = RandFlat::shootBit();
00230   }    
00231   r = RandFlat::shootBit();
00232   output << "restored r1005= " << r << std::endl;
00233   if ( r != remembered_r1005 ) {
00234     stat += 8;
00235     std::cout << "restored r1005= " << r << std::endl;
00236     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00237     #ifdef CLEAN_OUTPUT
00238     output << "restored r1005= " << r << std::endl;
00239     output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00240     #endif
00241   }
00242   r = RandFlat::shootBit();
00243   output << "restored r1006= " << r << std::endl;
00244   if ( r != remembered_r1006 ) {
00245     stat += 16;
00246     std::cout << "restored r1006= " << r << std::endl;
00247     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00248     #ifdef CLEAN_OUTPUT
00249     output << "restored r1006= " << r << std::endl;
00250     output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00251     #endif
00252   }
00253   r = RandFlat::shootBit();
00254   output << "restored r1007= " << r << std::endl;
00255   if ( r != remembered_r1007 ) {
00256     stat += 32;
00257     std::cout << "restored r1007= " << r << std::endl;
00258     std::cout << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00259     #ifdef CLEAN_OUTPUT
00260     output << "restored r1007= " << r << std::endl;
00261     output << "????? THIS DOES NOT MATCH REMEMBERED VALUE!\n";
00262     #endif
00263   }
00264   return stat;
00265 }
00266 
00267 // --- The following should work, by failing in an expected way -------
00268 
00269 template <class E, class D>
00270 int fileNotThere() {
00271   int stat = 0;
00272   HepRandomEngine * old = D::getTheEngine();
00273   E e(123);
00274   output << "File-not-found test restoring "<<D::distributionName()<<":\n";
00275   D::setTheEngine(&e);
00276   D::restoreEngineStatus("noSuchFile");
00277   D::setTheEngine(old);  // If we don't do this, then the static engine shared
00278                          // by every shoot() method reamins e -- which is about
00279                          // to go out of scope and be destructed!
00280   return stat;
00281 }
00282 
00283 template <class E>
00284 int fileNotThereEngine() {
00285   int stat = 0;
00286   stat |= fileNotThere <E, RandBinomial>();
00287   stat |= fileNotThere <E, RandBit>();
00288   stat |= fileNotThere <E, RandBreitWigner>();
00289   stat |= fileNotThere <E, RandChiSquare>();
00290   stat |= fileNotThere <E, RandExponential>();
00291   stat |= fileNotThere <E, RandFlat>();
00292   stat |= fileNotThere <E, RandGamma>();
00293   stat |= fileNotThere <E, RandGauss>();
00294   stat |= fileNotThere <E, RandGaussQ>();
00295   stat |= fileNotThere <E, RandGaussT>();
00296   stat |= fileNotThere <E, RandLandau>();
00297   stat |= fileNotThere <E, RandPoisson>();
00298   stat |= fileNotThere <E, RandPoissonQ>();
00299   stat |= fileNotThere <E, RandPoissonT>();
00300   stat |= fileNotThere <E, RandSkewNormal>();
00301   stat |= fileNotThere <E, RandStudentT>();
00302   return stat;
00303 }
00304 
00305 int missingFile() {
00306   int stat = 0;
00307   stat |= fileNotThereEngine<DRand48Engine>();
00308   stat |= fileNotThereEngine<DualRand>();
00309   stat |= fileNotThereEngine<Hurd160Engine>();
00310   stat |= fileNotThereEngine<Hurd288Engine>();
00311   stat |= fileNotThereEngine<HepJamesRandom>();
00312   stat |= fileNotThereEngine<MTwistEngine>();
00313   stat |= fileNotThereEngine<RandEngine>();
00314   stat |= fileNotThereEngine<RanecuEngine>();
00315   stat |= fileNotThereEngine<Ranlux64Engine>();
00316   stat |= fileNotThereEngine<RanluxEngine>();
00317   stat |= fileNotThereEngine<RanshiEngine>();
00318   stat |= fileNotThereEngine<TripleRand>();
00319   return stat;
00320 }
00321   
00322 // -- The following was used to capture old-form engine states (sans name) --
00323 
00324 template <class E, class D>
00325 int saveEngine(const char* filename) {
00326   int stat = 0;
00327   HepRandomEngine * old = D::getTheEngine();
00328   E e(123);
00329   D::setTheEngine(&e);
00330   double r=0; 
00331   for (int i=0; i<3; i++) r += D::shoot();
00332   D::saveEngineStatus(filename);
00333   if (r == -99999999.1) stat = 999; // This prevents clever compilers from
00334                                     // deducing that r is never needed
00335   D::setTheEngine(old);  // If we don't do this, then the static engine shared
00336                          // by every shoot() method reamins e -- which is about
00337                          // to go out of scope and be destructed!
00338   return stat;
00339 }
00340 
00341 // -- The following checks on static engine restores, from old and new forms --
00342 
00343 template <class E, class D>
00344 int checkSaveEngine(const char* filename) {
00345   int stat = 0;
00346   HepRandomEngine * old = D::getTheEngine();
00347 
00348   // Generate save with current format (default file name is fine)
00349   E e(123);
00350   D::setTheEngine(&e);
00351   double r=0; 
00352   for (int i=0; i<3; i++) r += D::shoot();
00353   D::saveEngineStatus();
00354 
00355   // Figure out what the key variate value should be
00356   double keyValue = D::shoot();
00357 
00358   // Restore state based on old file, and check for proper value
00359   D::restoreEngineStatus(filename);
00360   if (!equals(D::shoot(), keyValue)) {
00361     std::cout << "???? Value mismatch from file " << filename << "\n";
00362     #ifdef CLEAN_OUTPUT
00363     output << "???? Value mismatch from file " << filename << "\n";
00364     #endif
00365     stat |= 64;
00366   }
00367 
00368   // Restore state based on that save, and check for proper value
00369   D::restoreEngineStatus();
00370   if (!equals(D::shoot(),keyValue)) {
00371     std::cout << "???? Value mismatch from new-format file \n";
00372     #ifdef CLEAN_OUTPUT
00373     output << "???? Value mismatch from new-format file \n";
00374     #endif
00375     stat |= 128;
00376   }
00377 
00378   D::setTheEngine(old);  
00379   return stat;
00380 }
00381 
00382 // ---------------------------------------------
00383 // ---------------------------------------------
00384 // ---------------------------------------------
00385 
00386 
00387 int main() {
00388   int stat = 0;
00389 
00390 #ifdef TEST_ORIGINAL_SAVE
00391   output << "=====================================\n";
00392   output << "             Part I \n";
00393   output << "Original tests of static save/restore\n";
00394   output << "=====================================\n\n";
00395   
00396   output << "Using old method or HepRandom::saveEngineStatus:\n";
00397   output << "All these tests should have a chance of failure.\n";
00398 
00399   output << RandGauss:: getTheEngine()->name();  
00400   output << RandGaussQ::getTheEngine()->name();  
00401 
00402   stat |= saveStepX();
00403   stat |= restoreStepX();
00404   stat |= BsaveStepX();
00405   stat |= BrestoreStepX();
00406   
00407   output << "Using the class-specific RandGauss::saveEngineStatus:\n";
00408   output << "All these tests should work properly.\n";
00409 
00410   stat |= saveStep();
00411   stat |= restoreStep();
00412   stat |= BsaveStep();
00413   stat |= BrestoreStep();
00414 #endif
00415   
00416 #ifdef TEST_MISSING_FILES
00417   output << "\n=======================================\n";
00418   output << "             Part Ia \n";
00419   output << "Test of behavior when a file is missing \n";
00420   output << "=======================================\n\n";
00421 
00422   output << "Testing restoreEngineStatus with missing file:\n";
00423   output << "Expect a number of <Failure to find or open> messages!\n";
00424   stat |= missingFile();
00425 #endif
00426 
00427 #ifdef CREATE_OLD_SAVES
00428   stat |= saveEngine<DRand48Engine, RandPoisson>("DRand48Engine.oldsav");
00429   stat |= saveEngine<DualRand,      RandPoisson>("DualRand.oldsav");
00430   stat |= saveEngine<Hurd160Engine, RandPoisson>("Hurd160Engine.oldsav");
00431   stat |= saveEngine<Hurd288Engine, RandPoisson>("Hurd288Engine.oldsav");
00432   stat |= saveEngine<HepJamesRandom,RandPoisson>("HepJamesRandom.oldsav");
00433   stat |= saveEngine<MTwistEngine,  RandPoisson>("MTwistEngine.oldsav");
00434   stat |= saveEngine<RanecuEngine,  RandPoisson>("RanecuEngine.oldsav");
00435   stat |= saveEngine<Ranlux64Engine,RandPoisson>("Ranlux64Engine.oldsav");
00436   stat |= saveEngine<RanluxEngine,  RandPoisson>("RanluxEngine.oldsav");
00437   stat |= saveEngine<RanshiEngine,  RandPoisson>("RanshiEngine.oldsav");
00438   stat |= saveEngine<TripleRand,    RandPoisson>("TripleRand.oldsav");
00439 #endif
00440 
00441 #ifdef VERIFY_OLD_SAVES
00442   output << "\n==============================================\n";
00443   output << "               Part Ib \n";
00444   output << "  Verification that changes wont invalidate \n";
00445   output << "invalidate engine saves from previous versions \n";
00446   output << "==============================================\n\n";
00447 
00448   stat |= checkSaveEngine<DRand48Engine, RandPoisson>("DRand48Engine.oldsav");
00449   stat |= checkSaveEngine<DualRand,      RandPoisson>("DualRand.oldsav");
00450   stat |= checkSaveEngine<Hurd160Engine, RandPoisson>("Hurd160Engine.oldsav");
00451   stat |= checkSaveEngine<Hurd288Engine, RandPoisson>("Hurd288Engine.oldsav");
00452   stat |= checkSaveEngine<HepJamesRandom,RandPoisson>("HepJamesRandom.oldsav");
00453   stat |= checkSaveEngine<MTwistEngine,  RandPoisson>("MTwistEngine.oldsav");
00454   stat |= checkSaveEngine<Ranlux64Engine,RandPoisson>("Ranlux64Engine.oldsav");
00455   stat |= checkSaveEngine<RanluxEngine,  RandPoisson>("RanluxEngine.oldsav");
00456   stat |= checkSaveEngine<RanshiEngine,  RandPoisson>("RanshiEngine.oldsav");
00457   stat |= checkSaveEngine<TripleRand,    RandPoisson>("TripleRand.oldsav");
00458   stat |= checkSaveEngine<RanecuEngine,  RandPoisson>("RanecuEngine.oldsav");
00459 #endif
00460 
00461   output << "\n=============================================\n\n";
00462 
00463   if (stat != 0) {
00464      std::cout << "One or more problems detected: stat = " << stat << "\n";
00465      output << "One or more problems detected: stat = " << stat << "\n";
00466   }  else {
00467      output << "testSaveEngineStatus passed with no problems detected.\n";    
00468   }
00469 
00470   if (stat == 0) return 0;
00471   if (stat > 0) return -(stat|1);
00472   return stat|1;
00473 }       
00474 

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7