CLHEP VERSION 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, 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