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