CLHEP 2.0.4.7 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, RandStudentT>();
00301   return stat;
00302 }
00303 
00304 int missingFile() {
00305   int stat = 0;
00306   stat |= fileNotThereEngine<DRand48Engine>();
00307   stat |= fileNotThereEngine<DualRand>();
00308   stat |= fileNotThereEngine<Hurd160Engine>();
00309   stat |= fileNotThereEngine<Hurd288Engine>();
00310   stat |= fileNotThereEngine<HepJamesRandom>();
00311   stat |= fileNotThereEngine<MTwistEngine>();
00312   stat |= fileNotThereEngine<RandEngine>();
00313   stat |= fileNotThereEngine<RanecuEngine>();
00314   stat |= fileNotThereEngine<Ranlux64Engine>();
00315   stat |= fileNotThereEngine<RanluxEngine>();
00316   stat |= fileNotThereEngine<RanshiEngine>();
00317   stat |= fileNotThereEngine<TripleRand>();
00318   return stat;
00319 }
00320   
00321 // -- The following was used to capture old-form engine states (sans name) --
00322 
00323 template <class E, class D>
00324 int saveEngine(const char* filename) {
00325   int stat = 0;
00326   HepRandomEngine * old = D::getTheEngine();
00327   E e(123);
00328   D::setTheEngine(&e);
00329   double r=0; 
00330   for (int i=0; i<3; i++) r += D::shoot();
00331   D::saveEngineStatus(filename);
00332   if (r == -99999999.1) stat = 999; // This prevents clever compilers from
00333                                     // deducing that r is never needed
00334   D::setTheEngine(old);  // If we don't do this, then the static engine shared
00335                          // by every shoot() method reamins e -- which is about
00336                          // to go out of scope and be destructed!
00337   return stat;
00338 }
00339 
00340 // -- The following checks on static engine restores, from old and new forms --
00341 
00342 template <class E, class D>
00343 int checkSaveEngine(const char* filename) {
00344   int stat = 0;
00345   HepRandomEngine * old = D::getTheEngine();
00346 
00347   // Generate save with current format (default file name is fine)
00348   E e(123);
00349   D::setTheEngine(&e);
00350   double r=0; 
00351   for (int i=0; i<3; i++) r += D::shoot();
00352   D::saveEngineStatus();
00353 
00354   // Figure out what the key variate value should be
00355   double keyValue = D::shoot();
00356 
00357   // Restore state based on old file, and check for proper value
00358   D::restoreEngineStatus(filename);
00359   if (!equals(D::shoot(), keyValue)) {
00360     std::cout << "???? Value mismatch from file " << filename << "\n";
00361     #ifdef CLEAN_OUTPUT
00362     output << "???? Value mismatch from file " << filename << "\n";
00363     #endif
00364     stat |= 64;
00365   }
00366 
00367   // Restore state based on that save, and check for proper value
00368   D::restoreEngineStatus();
00369   if (!equals(D::shoot(),keyValue)) {
00370     std::cout << "???? Value mismatch from new-format file \n";
00371     #ifdef CLEAN_OUTPUT
00372     output << "???? Value mismatch from new-format file \n";
00373     #endif
00374     stat |= 128;
00375   }
00376 
00377   D::setTheEngine(old);  
00378   return stat;
00379 }
00380 
00381 // ---------------------------------------------
00382 // ---------------------------------------------
00383 // ---------------------------------------------
00384 
00385 
00386 int main() {
00387   int stat = 0;
00388 
00389 #ifdef TEST_ORIGINAL_SAVE
00390   output << "=====================================\n";
00391   output << "             Part I \n";
00392   output << "Original tests of static save/restore\n";
00393   output << "=====================================\n\n";
00394   
00395   output << "Using old method or HepRandom::saveEngineStatus:\n";
00396   output << "All these tests should have a chance of failure.\n";
00397 
00398   output << RandGauss:: getTheEngine()->name();  
00399   output << RandGaussQ::getTheEngine()->name();  
00400 
00401   stat |= saveStepX();
00402   stat |= restoreStepX();
00403   stat |= BsaveStepX();
00404   stat |= BrestoreStepX();
00405   
00406   output << "Using the class-specific RandGauss::saveEngineStatus:\n";
00407   output << "All these tests should work properly.\n";
00408 
00409   stat |= saveStep();
00410   stat |= restoreStep();
00411   stat |= BsaveStep();
00412   stat |= BrestoreStep();
00413 #endif
00414   
00415 #ifdef TEST_MISSING_FILES
00416   output << "\n=======================================\n";
00417   output << "             Part Ia \n";
00418   output << "Test of behavior when a file is missing \n";
00419   output << "=======================================\n\n";
00420 
00421   output << "Testing restoreEngineStatus with missing file:\n";
00422   output << "Expect a number of <Failure to find or open> messages!\n";
00423   stat |= missingFile();
00424 #endif
00425 
00426 #ifdef CREATE_OLD_SAVES
00427   stat |= saveEngine<DRand48Engine, RandPoisson>("DRand48Engine.oldsav");
00428   stat |= saveEngine<DualRand,      RandPoisson>("DualRand.oldsav");
00429   stat |= saveEngine<Hurd160Engine, RandPoisson>("Hurd160Engine.oldsav");
00430   stat |= saveEngine<Hurd288Engine, RandPoisson>("Hurd288Engine.oldsav");
00431   stat |= saveEngine<HepJamesRandom,RandPoisson>("HepJamesRandom.oldsav");
00432   stat |= saveEngine<MTwistEngine,  RandPoisson>("MTwistEngine.oldsav");
00433   stat |= saveEngine<RanecuEngine,  RandPoisson>("RanecuEngine.oldsav");
00434   stat |= saveEngine<Ranlux64Engine,RandPoisson>("Ranlux64Engine.oldsav");
00435   stat |= saveEngine<RanluxEngine,  RandPoisson>("RanluxEngine.oldsav");
00436   stat |= saveEngine<RanshiEngine,  RandPoisson>("RanshiEngine.oldsav");
00437   stat |= saveEngine<TripleRand,    RandPoisson>("TripleRand.oldsav");
00438 #endif
00439 
00440 #ifdef VERIFY_OLD_SAVES
00441   output << "\n==============================================\n";
00442   output << "               Part Ib \n";
00443   output << "  Verification that changes wont invalidate \n";
00444   output << "invalidate engine saves from previous versions \n";
00445   output << "==============================================\n\n";
00446 
00447   stat |= checkSaveEngine<DRand48Engine, RandPoisson>("DRand48Engine.oldsav");
00448   stat |= checkSaveEngine<DualRand,      RandPoisson>("DualRand.oldsav");
00449   stat |= checkSaveEngine<Hurd160Engine, RandPoisson>("Hurd160Engine.oldsav");
00450   stat |= checkSaveEngine<Hurd288Engine, RandPoisson>("Hurd288Engine.oldsav");
00451   stat |= checkSaveEngine<HepJamesRandom,RandPoisson>("HepJamesRandom.oldsav");
00452   stat |= checkSaveEngine<MTwistEngine,  RandPoisson>("MTwistEngine.oldsav");
00453   stat |= checkSaveEngine<Ranlux64Engine,RandPoisson>("Ranlux64Engine.oldsav");
00454   stat |= checkSaveEngine<RanluxEngine,  RandPoisson>("RanluxEngine.oldsav");
00455   stat |= checkSaveEngine<RanshiEngine,  RandPoisson>("RanshiEngine.oldsav");
00456   stat |= checkSaveEngine<TripleRand,    RandPoisson>("TripleRand.oldsav");
00457   stat |= checkSaveEngine<RanecuEngine,  RandPoisson>("RanecuEngine.oldsav");
00458 #endif
00459 
00460   output << "\n=============================================\n\n";
00461 
00462   if (stat != 0) {
00463      std::cout << "One or more problems detected: stat = " << stat << "\n";
00464      output << "One or more problems detected: stat = " << stat << "\n";
00465   }  else {
00466      output << "testSaveEngineStatus passed with no problems detected.\n";    
00467   }
00468 
00469   if (stat == 0) return 0;
00470   if (stat > 0) return -(stat|1);
00471   return stat|1;
00472 }       
00473 

Generated on Thu Jul 1 22:02:31 2010 for CLHEP by  doxygen 1.4.7