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