CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

testAnonymousEngineRestore.cc

Go to the documentation of this file.
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 

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7