CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
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