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("testAnonymousEngineRestore.cout"); 00012 #else 00013 std::ostream & output = std::cout; 00014 #endif 00015 00016 // Normally on for routine validation: 00017 00018 #ifdef TURNOFF 00019 #endif 00020 00021 #define TEST_ANONYMOUS_ENGINE_RESTORE 00022 #define TEST_ANONYMOUS_RESTORE_STATICS 00023 00024 #define VERBOSER 00025 #define VERBOSER2 00026 00027 using namespace CLHEP; 00028 00029 template <class E1, class E2> int anonymousRestoreStatics(); 00030 00031 00032 // Absolutely Safe Equals Without Registers Screwing Us Up 00033 bool equals01(const std::vector<double> &ab) { 00034 return ab[1]==ab[0]; 00035 } 00036 bool equals(double a, double b) { 00037 std::vector<double> ab(2); 00038 ab[0]=a; ab[1]=b; 00039 return (equals01(ab)); 00040 } 00041 00042 std::vector<double> aSequence(int n) { 00043 std::vector<double> v; 00044 DualRand e(13542); 00045 RandFlat f(e); 00046 for (int i=0; i<n; i++) { 00047 v.push_back(f()); 00048 } 00049 return v; 00050 } 00051 00052 // ----------- Tests saving all statics together ----------- 00053 00054 void randomizeStatics(int n) { 00055 for (int i=0; i<n; i++) { 00056 RandGauss::shoot(); 00057 RandGaussQ::shoot(); 00058 RandGaussT::shoot(); 00059 RandFlat::shoot(); 00060 RandBit::shoot(); 00061 RandFlat::shootBit(); 00062 RandBit::shootBit(); 00063 RandPoisson::shoot(); 00064 RandPoissonQ::shoot(); 00065 RandPoissonT::shoot(); 00066 RandBinomial::shoot(); 00067 RandBreitWigner::shoot(); 00068 RandChiSquare::shoot(); 00069 RandExponential::shoot(); 00070 RandGamma::shoot(); 00071 RandLandau::shoot(); 00072 RandStudentT::shoot(); 00073 } 00074 } 00075 00076 std::vector<double> captureStatics() { 00077 std::vector<double> c; 00078 c.push_back( RandGauss::shoot() ); 00079 c.push_back( RandGaussQ::shoot() ); 00080 c.push_back( RandGaussT::shoot() ); 00081 c.push_back( RandFlat::shoot() ); 00082 c.push_back( RandBit::shoot() ); 00083 for (int i=0; i<20; i++) { 00084 c.push_back( RandFlat::shootBit() ); 00085 c.push_back( RandBit::shootBit() ); 00086 } 00087 c.push_back( RandPoisson::shoot() ); 00088 c.push_back( RandPoissonQ::shoot() ); 00089 c.push_back( RandPoissonT::shoot() ); 00090 c.push_back( RandBinomial::shoot() ); 00091 c.push_back( RandBreitWigner::shoot() ); 00092 c.push_back( RandChiSquare::shoot() ); 00093 c.push_back( RandExponential::shoot() ); 00094 c.push_back( RandGamma::shoot() ); 00095 c.push_back( RandLandau::shoot() ); 00096 c.push_back( RandStudentT::shoot() ); 00097 return c; 00098 } 00099 00100 void saveStatics(std::string filename) { 00101 std::ofstream os(filename.c_str()); 00102 RandGeneral::saveStaticRandomStates(os); 00103 // It should be possible to call this from HepRandom, or any distribution. 00104 // RandGeneral, which is meaningless as a static distribution, should be the 00105 // toughest test, so we use that here. 00106 } 00107 00108 void restoreStatics(std::string filename) { 00109 std::ifstream is(filename.c_str()); 00110 RandLandau::restoreStaticRandomStates(is); 00111 } 00112 00113 00114 00115 // ----------- Anonymous restore of engines ----------- 00116 00117 template <class E> 00118 void anonymousRestore1(int n, std::vector<double> & v) { 00119 output << "Anonymous restore for " << E::engineName() << "\n"; 00120 E e(12349876); 00121 double r=0; 00122 for (int i=0; i<n; i++) r += e.flat(); 00123 std::ofstream os("anonymous.save"); 00124 os << e; 00125 for (int j=0; j<25; j++) v.push_back(e.flat()); 00126 #ifdef VERBOSER2 00127 output << "First four of v are: " 00128 << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "\n"; 00129 #endif 00130 return; 00131 } 00132 00133 template <> 00134 void anonymousRestore1<NonRandomEngine> (int n, std::vector<double> & v) { 00135 #ifdef VERBOSER 00136 output << "Anonymous restore for " << NonRandomEngine::engineName() << "\n"; 00137 #endif 00138 std::vector<double> nonRand = aSequence(500); 00139 NonRandomEngine e; 00140 e.setRandomSequence(&nonRand[0], nonRand.size()); 00141 double r=0; 00142 for (int i=0; i<n; i++) r += e.flat(); 00143 std::ofstream os("anonymous.save"); 00144 os << e; 00145 for (int j=0; j<25; j++) v.push_back(e.flat()); 00146 #ifdef VERBOSER2 00147 output << "First four of v are: " 00148 << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "\n"; 00149 #endif 00150 return; 00151 } 00152 00153 template <class E> 00154 int anonymousRestore2(const std::vector<double> & v) { 00155 int stat = 0; 00156 std::vector<double> k; 00157 std::ifstream is("anonymous.save"); 00158 HepRandomEngine * a; 00159 a = HepRandomEngine::newEngine(is); 00160 for (int j=0; j<25; j++) k.push_back(a->flat()); 00161 delete a; 00162 #ifdef VERBOSER2 00163 output << "First four of k are: " 00164 << k[0] << ", " << k[1] << ", " << k[2] << ", " << k[3] << "\n"; 00165 #endif 00166 for (int m=0; m<25; m++) { 00167 if ( v[m] != k[m] ) { 00168 std::cout << "???? Incorrect restored value for anonymous engine" 00169 << E::engineName() << "\n"; 00170 #ifdef CLEAN_OUTPUT 00171 output << "???? Incorrect restored value for anonymous engine" 00172 << E::engineName() << "\n"; 00173 #endif 00174 stat |= 262144; 00175 return stat; 00176 } 00177 } 00178 return stat; 00179 } 00180 00181 00182 template <class E> 00183 int anonymousRestore(int n) { 00184 std::vector<double> v; 00185 anonymousRestore1<E>(n,v); 00186 return anonymousRestore2<E>(v); 00187 } 00188 00189 // ----------- Anonymous restore of all static distributions ----------- 00190 00191 template <class E> 00192 int anonymousRestoreStatics1() { 00193 int stat = 0; 00194 HepRandomEngine *e = new E(12456); 00195 HepRandom::setTheEngine(e); 00196 randomizeStatics(15); 00197 output << "\nRandomized, with theEngine = " << e->name() << "\n"; 00198 saveStatics("distribution.save"); 00199 output << "Saved all static distributions\n"; 00200 std::vector<double> c = captureStatics(); 00201 output << "Captured output of all static distributions\n"; 00202 randomizeStatics(11); 00203 output << "Randomized all static distributions\n"; 00204 restoreStatics("distribution.save"); 00205 output << "Restored all static distributions to saved state\n"; 00206 std::vector<double> d = captureStatics(); 00207 output << "Captured output of all static distributions\n"; 00208 for (unsigned int iv=0; iv<c.size(); iv++) { 00209 if (c[iv] != d[iv]) { 00210 std::cout << "???? restoreStaticRandomStates failed at random " 00211 << iv <<"\n"; 00212 #ifdef CLEAN_OUTPUT 00213 output << "???? restoreStaticRandomStates failed at random " 00214 << iv <<"\n"; 00215 #endif 00216 stat |= 131072; 00217 } 00218 } 00219 if ( (stat & 131072) == 0) { 00220 output << "All captured output agrees with earlier values\n"; 00221 } 00222 return stat; 00223 } 00224 00225 00226 00227 template <class E1, class E2> 00228 int anonymousRestoreStatics() { 00229 int stat = 0; 00230 if ( E1::engineName() == E2::engineName() ) { 00231 return anonymousRestoreStatics1<E1>(); 00232 } 00233 HepRandomEngine *e1 = new E1(12456); 00234 HepRandom::setTheEngine(e1); 00235 randomizeStatics(15); 00236 output << "\nRandomized, with theEngine = " << e1->name() << "\n"; 00237 saveStatics("distribution.save"); 00238 #ifdef VERBOSER2 00239 output << "Saved all static distributions\n"; 00240 #endif 00241 std::vector<double> c = captureStatics(); 00242 #ifdef VERBOSER2 00243 output << "Captured output of all static distributions\n"; 00244 #endif 00245 delete e1; 00246 HepRandomEngine *e2 = new E2(24653); 00247 HepRandom::setTheEngine(e2); 00248 output << "Switched to theEngine = " << e2->name() << "\n"; 00249 randomizeStatics(19); 00250 { std::ofstream os("engine.save"); os << *e2; } 00251 double v1 = e2->flat(); 00252 double v2 = e2->flat(); 00253 { std::ifstream is("engine.save"); is >> *e2; } 00254 #ifdef VERBOSER2 00255 output << "Saved the " << e2->name() << " engine: \n" 00256 << "Next randoms to be " << v1 << " " << v2 << "\n" 00257 << "Restored the " << e2->name() << " engine to that state\n"; 00258 #endif 00259 restoreStatics("distribution.save"); 00260 #ifdef VERBOSER2 00261 output << "Restored all static distributions to saved state\n" 00262 << "This changes the engine type back to " << E1::engineName() << "\n"; 00263 #endif 00264 std::vector<double> d = captureStatics(); 00265 #ifdef VERBOSER2 00266 output << "Captured output of all static distributions\n"; 00267 #endif 00268 for (unsigned int iv=0; iv<c.size(); iv++) { 00269 if (c[iv] != d[iv]) { 00270 std::cout << "???? restoreStaticRandomStates failed at random " 00271 << iv <<"\n"; 00272 #ifdef CLEAN_OUTPUT 00273 output << "???? restoreStaticRandomStates failed at random " 00274 << iv <<"\n"; 00275 #endif 00276 stat |= 524288; 00277 } 00278 } 00279 if ((stat & 524288) == 0) { 00280 output << "All captured output agrees with earlier values\n"; 00281 } 00282 double k1 = e2->flat(); 00283 double k2 = e2->flat(); 00284 #ifdef VERBOSER2 00285 output << "The " << e2->name() << " engine should not have been affected: \n" 00286 << "Next randoms are " << k1 << " " << k2 << "\n"; 00287 #endif 00288 if ( !equals(v1,k1) || !equals(v2,k2) ) { 00289 std::cout << "???? Engine used as theEngine was affected by restoring \n" 00290 << " static distributions to use engine of a different type.\n"; 00291 #ifdef CLEAN_OUTPUT 00292 output << "???? Engine used as theEngine was affected by restoring \n" 00293 << " static distributions to use engine of a different type.\n"; 00294 #endif 00295 stat |= 1048576; 00296 } 00297 return stat; 00298 } 00299 00300 // --------------------------------------------- 00301 // --------------------------------------------- 00302 // --------------------------------------------- 00303 00304 00305 int main() { 00306 int stat = 0; 00307 00308 #ifdef TEST_ANONYMOUS_ENGINE_RESTORE 00309 output << "\n=================================\n"; 00310 output << " Part VII \n"; 00311 output << "Anonymous restore of engines \n"; 00312 output << "=================================\n\n"; 00313 00314 stat |= anonymousRestore<DualRand>(13); 00315 stat |= anonymousRestore<DRand48Engine>(14); 00316 stat |= anonymousRestore<Hurd160Engine>(15); 00317 stat |= anonymousRestore<Hurd288Engine>(16); 00318 stat |= anonymousRestore<HepJamesRandom>(17); 00319 stat |= anonymousRestore<MTwistEngine>(18); 00320 stat |= anonymousRestore<RandEngine>(29); 00321 stat |= anonymousRestore<RanecuEngine>(39); 00322 stat |= anonymousRestore<Ranlux64Engine>(19); 00323 stat |= anonymousRestore<RanluxEngine>(20); 00324 stat |= anonymousRestore<RanshiEngine>(21); 00325 stat |= anonymousRestore<TripleRand>(22); 00326 stat |= anonymousRestore<NonRandomEngine>(22); 00327 #endif 00328 00329 #ifdef TEST_ANONYMOUS_RESTORE_STATICS 00330 output << "\n======================================\n"; 00331 output << " Part VIII \n"; 00332 output << "Anonymous restore static Distributions \n"; 00333 output << "======================================\n\n"; 00334 00335 stat |= anonymousRestoreStatics<DualRand, Ranlux64Engine> ( ); 00336 stat |= anonymousRestoreStatics<DRand48Engine, TripleRand> ( ); 00337 stat |= anonymousRestoreStatics<RandEngine, Ranlux64Engine> ( ); 00338 stat |= anonymousRestoreStatics<MTwistEngine, Hurd288Engine> ( ); 00339 stat |= anonymousRestoreStatics<RanecuEngine, MTwistEngine> ( ); 00340 stat |= anonymousRestoreStatics<HepJamesRandom, RanshiEngine> ( ); 00341 stat |= anonymousRestoreStatics<RanecuEngine, RandEngine> ( ); 00342 stat |= anonymousRestoreStatics<RanshiEngine, Hurd160Engine> ( ); 00343 stat |= anonymousRestoreStatics<TripleRand, DualRand> ( ); 00344 stat |= anonymousRestoreStatics<Hurd160Engine, HepJamesRandom> ( ); 00345 stat |= anonymousRestoreStatics<Hurd288Engine, RanecuEngine> ( ); 00346 stat |= anonymousRestoreStatics<HepJamesRandom, Ranlux64Engine> ( ); 00347 stat |= anonymousRestoreStatics<TripleRand, TripleRand> ( ); 00348 stat |= anonymousRestoreStatics<HepJamesRandom, HepJamesRandom> ( ); 00349 #endif 00350 00351 00352 output << "\n=============================================\n\n"; 00353 00354 if (stat != 0) { 00355 std::cout << "One or more problems detected: stat = " << stat << "\n"; 00356 output << "One or more problems detected: stat = " << stat << "\n"; 00357 } else { 00358 output << "testAnonymousEngineRestore passed with no problems detected.\n"; 00359 } 00360 00361 if (stat == 0) return 0; 00362 if (stat > 0) return -(stat|1); 00363 return stat|1; 00364 } 00365