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 #include <cassert> 00010 00011 #define CLEAN_OUTPUT 00012 #ifdef CLEAN_OUTPUT 00013 std::ofstream output("testInstanceRestore.cout"); 00014 #else 00015 std::ostream & output = std::cout; 00016 #endif 00017 00018 // Normally on for routine validation: 00019 00020 00021 #ifdef TURNOFF 00022 #endif 00023 00024 #define TEST_ENGINE_NAMES 00025 #define TEST_INSTANCE_METHODS 00026 00027 #define VERBOSER 00028 #define VERBOSER2 00029 00030 using namespace CLHEP; 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 for instance methods ----------- 00053 00054 template <class E> 00055 int checkEngineName(const std::string & name) { 00056 int stat = 0; 00057 output << E::engineName() << "\n"; 00058 if (E::engineName() != name) { 00059 std::cout << "???? engineName mismatch for " << name << " <--> " 00060 << E::engineName() << "\n"; 00061 #ifdef CLEAN_OUTPUT 00062 output << "???? engineName mismatch for " << name << " <--> " 00063 << E::engineName() << "\n"; 00064 #endif 00065 stat |= 256; 00066 } 00067 E e(123); 00068 if (e.name() != name) { 00069 std::cout << "???? name mismatch for " << name << " <--> " 00070 << e.name() << "\n"; 00071 #ifdef CLEAN_OUTPUT 00072 output << "???? name mismatch for " << name << " <--> " 00073 << e.name() << "\n"; 00074 #endif 00075 stat |= 256; 00076 } 00077 return stat; 00078 } 00079 00080 template <class E, class D> 00081 int checkEngine() { 00082 int stat = 0; 00083 E e(1234); 00084 D d(e); 00085 if (d.engine().name() != e.name()) { 00086 std::cout << "???? Improper d.engine() \n"; 00087 #ifdef CLEAN_OUTPUT 00088 output << "???? Improper d.engine() \n"; 00089 #endif 00090 stat |= 512; 00091 } 00092 return stat; 00093 } 00094 00095 template <class E> 00096 int checkEngineInstanceSave(E & e) { 00097 int stat = 0; 00098 output << "checkEngineInstanceSave for " << e.name() << "\n"; 00099 int pr=output.precision(20); 00100 double r=0; 00101 for (int i=0; i<100; i++) r += e.flat(); 00102 {std::ofstream os ("engine.save"); os << e;} 00103 for (int i=0; i<100; i++) r += e.flat(); 00104 double keyValue1 = e.flat(); 00105 double keyValue2 = e.flat(); 00106 #ifdef VERBOSER 00107 output << keyValue1 << " " << keyValue2 << "\n"; 00108 #endif 00109 E e2; 00110 {std::ifstream is ("engine.save"); is >> e2;} 00111 for (int i=0; i<100; i++) r += e2.flat(); 00112 double k1 = e2.flat(); 00113 double k2 = e2.flat(); 00114 #ifdef VERBOSER 00115 output << k1 << " " << k2 << "\n"; 00116 #endif 00117 if ( !(equals(k1,keyValue1)) || !(equals(k2,keyValue2)) ) { 00118 std::cout << "???? checkInstanceSave failed for " << e.name() << "\n"; 00119 #ifdef CLEAN_OUTPUT 00120 output << "???? checkInstanceSave failed for " << e.name() << "\n"; 00121 #endif 00122 stat |= 1024; 00123 } 00124 output.precision(pr); 00125 return stat; 00126 } 00127 00128 template <class E, class D> 00129 int checkSaveDistribution(D & d, int nth) { 00130 // verify that engine is the expected type 00131 assert( &dynamic_cast<E &>(d.engine()) ); 00132 int stat = 0; 00133 output << "checkSaveDistribution with " << d.engine().name() 00134 << ", " << d.name() << "\n"; 00135 double r=0; 00136 r = d(); 00137 double keyValue1, keyValue2, keyValue3, keyValue4; 00138 for (int i=0; i<nth; i++) r += d(); 00139 {std::ofstream os ("distribution.save1"); os << d.engine() << d;} 00140 keyValue1 = d(); 00141 keyValue2 = d(); 00142 r += d(); 00143 // A second capture will test non-cached if first tested cached case: 00144 {std::ofstream os ("distribution.save2"); os << d.engine() << d;} 00145 keyValue3 = d(); 00146 keyValue4 = d(); 00147 int pr = output.precision(20); 00148 #ifdef VERBOSER 00149 output << "keyValue1 = " << keyValue1 << 00150 " keyValue2 = " << keyValue2 << "\n"; 00151 output << "keyValue3 = " << keyValue3 << 00152 " keyValue3 = " << keyValue4 << "\n"; 00153 #endif 00154 output.precision(pr); 00155 E e; 00156 D d2(e); 00157 { std::ifstream is ("distribution.save1"); is >> e >> d2;} 00158 double k1 = d2(); 00159 double k2 = d2(); 00160 { std::ifstream is ("distribution.save2"); is >> e >> d2;} 00161 double k3 = d2(); 00162 double k4 = d2(); 00163 #ifdef VERBOSER 00164 pr = output.precision(20); 00165 output << "k1 = " << k1 << 00166 " k2 = " << k2 << "\n"; 00167 output << "k3 = " << k3 << 00168 " k4 = " << k4 << "\n"; 00169 output.precision(pr); 00170 #endif 00171 if ( !equals(k1,keyValue1) || !equals(k2,keyValue2) || 00172 !equals(k3,keyValue3) || !equals(k4,keyValue4) ) { 00173 std::cout << "???? Incorrect restored value for distribution " 00174 << d.name() << "\n"; 00175 #ifdef CLEAN_OUTPUT 00176 output << "???? Incorrect restored value for distribution " 00177 << d.name() << "\n"; 00178 #endif 00179 stat |= 2048; 00180 } 00181 // if (stat) exit(-1); 00182 return stat; 00183 } 00184 00185 template <class E> 00186 int checkRandGeneralDistribution(RandGeneral & d, int nth) { 00187 assert( &dynamic_cast<E &>(d.engine()) ); 00188 int stat = 0; 00189 output << "checkSaveDistribution with " << d.engine().name() 00190 << ", " << d.name() << "\n"; 00191 double r=0; 00192 r = d(); 00193 double keyValue1, keyValue2, keyValue3, keyValue4; 00194 for (int i=0; i<nth; i++) r += d(); 00195 {std::ofstream os ("distribution.save1"); os << d.engine() << d;} 00196 keyValue1 = d(); 00197 keyValue2 = d(); 00198 r += d(); 00199 // A second capture will test non-cached if first tested cached case: 00200 {std::ofstream os ("distribution.save2"); os << d.engine() << d;} 00201 keyValue3 = d(); 00202 keyValue4 = d(); 00203 int pr = output.precision(20); 00204 #ifdef VERBOSER 00205 output << "keyValue1 = " << keyValue1 << 00206 " keyValue2 = " << keyValue2 << "\n"; 00207 output << "keyValue3 = " << keyValue3 << 00208 " keyValue3 = " << keyValue4 << "\n"; 00209 #endif 00210 output.precision(pr); 00211 E e; 00212 double temp = 1; 00213 RandGeneral d2(e, &temp, 1); 00214 { std::ifstream is ("distribution.save1"); is >> e >> d2;} 00215 double k1 = d2(); 00216 double k2 = d2(); 00217 { std::ifstream is ("distribution.save2"); is >> e >> d2;} 00218 double k3 = d2(); 00219 double k4 = d2(); 00220 #ifdef VERBOSER 00221 pr = output.precision(20); 00222 output << "k1 = " << k1 << 00223 " k2 = " << k2 << "\n"; 00224 output << "k3 = " << k3 << 00225 " k4 = " << k4 << "\n"; 00226 output.precision(pr); 00227 #endif 00228 if ( !equals(k1,keyValue1) || !equals(k2,keyValue2) || 00229 !equals(k3,keyValue3) || !equals(k4,keyValue4) ) { 00230 std::cout << "???? Incorrect restored value for distribution " 00231 << d.name() << "\n"; 00232 #ifdef CLEAN_OUTPUT 00233 output << "???? Incorrect restored value for distribution " 00234 << d.name() << "\n"; 00235 #endif 00236 stat |= 2048; 00237 } 00238 // if (stat) exit(-1); 00239 return stat; 00240 } 00241 00242 template <class E> 00243 int checkDistributions() { 00244 int stat = 0; 00245 {RandGauss d(new E(12561),100.0,3.0); 00246 stat |= checkSaveDistribution<E,RandGauss> (d,33); } 00247 {RandGauss d(new E(12572),100.0,3.0); 00248 stat |= checkSaveDistribution<E,RandGauss> (d,34); } 00249 {RandGaussQ d(new E(12563),10.0,4.0); 00250 stat |= checkSaveDistribution<E,RandGaussQ> (d,33); } 00251 {RandGaussT d(new E(12564),5.0,2.0); 00252 stat |= checkSaveDistribution<E,RandGaussT> (d,33); } 00253 {RandBinomial d(new E(12565),4,0.6); 00254 stat |= checkSaveDistribution<E,RandBinomial> (d,33); } 00255 {RandFlat d(new E(12576),12.5,35.0); 00256 stat |= checkSaveDistribution<E,RandFlat> (d,33); } 00257 {RandBit d(new E(12567)); 00258 stat |= checkSaveDistribution<E,RandBit> (d,31); } 00259 {RandBit d(new E(12578)); 00260 stat |= checkSaveDistribution<E,RandBit> (d,32); } 00261 {RandBit d(new E(12589)); 00262 stat |= checkSaveDistribution<E,RandBit> (d,33); } 00263 {RandBreitWigner d(new E(125611),50.0,15.0); 00264 stat |= checkSaveDistribution<E,RandBreitWigner> (d,33); } 00265 {RandChiSquare d(new E(125612),5.0); 00266 stat |= checkSaveDistribution<E,RandChiSquare> (d,33); } 00267 {RandExponential d(new E(125713),8.00); 00268 stat |= checkSaveDistribution<E,RandExponential> (d,33); } 00269 {RandGamma d(new E(125713),6.0,2.0); 00270 stat |= checkSaveDistribution<E,RandGamma> (d,33); } 00271 {RandLandau d(new E(125714)); 00272 stat |= checkSaveDistribution<E,RandLandau> (d,33); } 00273 {RandStudentT d(new E(125715),5); 00274 stat |= checkSaveDistribution<E,RandStudentT> (d,33); } 00275 00276 // Multiple tests of Poisson distributions for small desired, since 00277 // the answer in each test is a small int, and coincidental agreement 00278 // is very possible. 00279 00280 {RandPoisson d(new E(125616),2.5); 00281 stat |= checkSaveDistribution<E,RandPoisson> (d,33); } 00282 {RandPoisson d(new E(125617),105.0); 00283 stat |= checkSaveDistribution<E,RandPoisson> (d,34); } 00284 {RandPoisson d(new E(125618),2.5); 00285 stat |= checkSaveDistribution<E,RandPoisson> (d,35); } 00286 {RandPoisson d(new E(325618),2.5); 00287 stat |= checkSaveDistribution<E,RandPoisson> (d,36); } 00288 {RandPoisson d(new E(425618),2.5); 00289 stat |= checkSaveDistribution<E,RandPoisson> (d,37); } 00290 {RandPoisson d(new E(525618),2.5); 00291 stat |= checkSaveDistribution<E,RandPoisson> (d,38); } 00292 {RandPoisson d(new E(125619),110.0); 00293 stat |= checkSaveDistribution<E,RandPoisson> (d,39); } 00294 {RandPoissonQ d(new E(124616),2.5); 00295 stat |= checkSaveDistribution<E,RandPoissonQ> (d,33); } 00296 {RandPoissonQ d(new E(126616),2.5); 00297 stat |= checkSaveDistribution<E,RandPoissonQ> (d,32); } 00298 {RandPoissonQ d(new E(127616),2.5); 00299 stat |= checkSaveDistribution<E,RandPoissonQ> (d,31); } 00300 {RandPoissonQ d(new E(129616),2.5); 00301 stat |= checkSaveDistribution<E,RandPoissonQ> (d,30); } 00302 {RandPoissonQ d(new E(125616),110.0); 00303 stat |= checkSaveDistribution<E,RandPoissonQ> (d,33); } 00304 {RandPoissonQ d(new E(125616),2.5); 00305 stat |= checkSaveDistribution<E,RandPoissonQ> (d,34); } 00306 {RandPoissonQ d(new E(125616),110.0); 00307 stat |= checkSaveDistribution<E,RandPoissonQ> (d,34); } 00308 {RandPoissonT d(new E(125616),2.5); 00309 stat |= checkSaveDistribution<E,RandPoissonT> (d,33); } 00310 {RandPoissonT d(new E(125616),110.0); 00311 stat |= checkSaveDistribution<E,RandPoissonT> (d,33); } 00312 {RandPoissonT d(new E(125616),2.5); 00313 stat |= checkSaveDistribution<E,RandPoissonT> (d,34); } 00314 {RandPoissonT d(new E(125616),110.0); 00315 stat |= checkSaveDistribution<E,RandPoissonT> (d,34); } 00316 {RandPoissonT d(new E(125916),2.5); 00317 stat |= checkSaveDistribution<E,RandPoissonT> (d,10); } 00318 {RandPoissonT d(new E(125816),2.5); 00319 stat |= checkSaveDistribution<E,RandPoissonT> (d,11); } 00320 {RandPoissonT d(new E(125716),2.5); 00321 stat |= checkSaveDistribution<E,RandPoissonT> (d,12); } 00322 00323 {std::vector<double> pdf; 00324 int nbins = 20; 00325 for (int i = 0; i < nbins; ++i) 00326 pdf.push_back( 5*i + (10.5-i) * (10.5-i) ); 00327 RandGeneral d(new E(125917), &pdf[0], 20); 00328 stat |= checkRandGeneralDistribution<E> (d,33); } 00329 00330 return stat; 00331 } 00332 00333 // --------------------------------------------- 00334 // --------------------------------------------- 00335 // --------------------------------------------- 00336 00337 00338 int main() { 00339 int stat = 0; 00340 00341 #ifdef TEST_ENGINE_NAMES 00342 output << "\n=============================================\n"; 00343 output << " Part II \n"; 00344 output << "Check all engine names were entered correctly \n"; 00345 output << "=============================================\n\n"; 00346 00347 stat |= checkEngineName<DRand48Engine >("DRand48Engine"); 00348 stat |= checkEngineName<DualRand >("DualRand"); 00349 stat |= checkEngineName<Hurd160Engine >("Hurd160Engine"); 00350 stat |= checkEngineName<Hurd288Engine >("Hurd288Engine"); 00351 stat |= checkEngineName<HepJamesRandom>("HepJamesRandom"); 00352 stat |= checkEngineName<MTwistEngine >("MTwistEngine"); 00353 stat |= checkEngineName<RandEngine >("RandEngine"); 00354 stat |= checkEngineName<RanecuEngine >("RanecuEngine"); 00355 stat |= checkEngineName<Ranlux64Engine>("Ranlux64Engine"); 00356 stat |= checkEngineName<RanluxEngine >("RanluxEngine"); 00357 stat |= checkEngineName<RanshiEngine >("RanshiEngine"); 00358 stat |= checkEngineName<TripleRand >("TripleRand"); 00359 #endif 00360 00361 #ifdef TEST_INSTANCE_METHODS 00362 output << "===========================================\n\n"; 00363 output << " Part III\n"; 00364 output << "Check instance methods for specific engines \n"; 00365 output << " specific engines and distributions\n"; 00366 output << "===========================================\n\n"; 00367 00368 {DualRand e(234); stat |= checkEngineInstanceSave(e);} 00369 {Hurd160Engine e(234); stat |= checkEngineInstanceSave(e);} 00370 {Hurd288Engine e(234); stat |= checkEngineInstanceSave(e);} 00371 {HepJamesRandom e(234); stat |= checkEngineInstanceSave(e);} 00372 {MTwistEngine e(234); stat |= checkEngineInstanceSave(e);} 00373 {RandEngine e(234); stat |= checkEngineInstanceSave(e);} 00374 {RanecuEngine e(234); stat |= checkEngineInstanceSave(e);} 00375 {Ranlux64Engine e(234); stat |= checkEngineInstanceSave(e);} 00376 {RanluxEngine e(234); stat |= checkEngineInstanceSave(e);} 00377 {RanshiEngine e(234); stat |= checkEngineInstanceSave(e);} 00378 {TripleRand e(234); stat |= checkEngineInstanceSave(e);} 00379 00380 {std::vector<double> nonRand = aSequence(500); 00381 NonRandomEngine e; 00382 e.setRandomSequence(&nonRand[0], nonRand.size()); 00383 stat |= checkEngineInstanceSave(e);} 00384 00385 stat |= checkDistributions<DualRand>(); 00386 stat |= checkDistributions<Hurd160Engine>(); 00387 stat |= checkDistributions<Hurd288Engine>(); 00388 stat |= checkDistributions<HepJamesRandom>(); 00389 stat |= checkDistributions<MTwistEngine>(); 00390 stat |= checkDistributions<Ranlux64Engine>(); 00391 stat |= checkDistributions<RanluxEngine>(); 00392 stat |= checkDistributions<RanshiEngine>(); 00393 stat |= checkDistributions<TripleRand>(); 00394 00395 RandGaussQ::shoot(); // Just to verify that the static engine is OK 00396 #endif 00397 00398 output << "\n=============================================\n\n"; 00399 00400 if (stat != 0) { 00401 std::cout << "One or more problems detected: stat = " << stat << "\n"; 00402 output << "One or more problems detected: stat = " << stat << "\n"; 00403 } else { 00404 output << "testInstanceRestore passed with no problems detected.\n"; 00405 } 00406 00407 if (stat == 0) return 0; 00408 if (stat > 0) return -(stat|1); 00409 return stat|1; 00410 00411 } 00412