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