CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // -*- C++ -*- 00002 // $Id: testVectorSave.cc,v 1.1.4.1.2.1 2008/11/18 22:09:51 garren Exp $ 00003 // ---------------------------------------------------------------------- 00004 #include "CLHEP/Random/Randomize.h" 00005 #include "CLHEP/Random/NonRandomEngine.h" 00006 #include "CLHEP/Random/defs.h" 00007 #include <iostream> 00008 #include <iomanip> 00009 #include <vector> 00010 00011 #define CLEAN_OUTPUT 00012 #ifdef CLEAN_OUTPUT 00013 std::ofstream output("testVectorSave.cout"); 00014 #else 00015 std::ostream & output = std::cout; 00016 #endif 00017 00018 // Normally on for routine validation: 00019 00020 #ifdef TURNOFF 00021 #endif 00022 00023 #define TEST_VECTOR_ENGINE_RESTORE 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 00051 // ----------- Vector restore of engines ----------- 00052 00053 // test the problem reported in bug #44156 00054 // Note that this test always works on a 32bit machine 00055 template <class E> 00056 int vectorTest64(int n) { 00057 output << "Vector restore 64bit test for " << E::engineName() << "\n"; 00058 00059 E e; 00060 double x = 0; 00061 for (int i=0; i<n; i++) x += e.flat(); 00062 std::vector<unsigned long> v = e.put(); 00063 x = e.flat(); 00064 output << "x = " << x << std::endl; 00065 00066 E f; 00067 v[0] &= 0xffffffffUL; 00068 f.get(v); 00069 double y = f.flat(); 00070 output << "y = " << y << std::endl; 00071 if( x != y ) return n; 00072 00073 return 0; 00074 } 00075 // special case for NonRandomEngine 00076 template <> 00077 int vectorTest64<NonRandomEngine>(int n) { 00078 output << "Vector restore 64bit test for " << NonRandomEngine::engineName() << "\n"; 00079 00080 std::vector<double> nonRand = aSequence(500); 00081 NonRandomEngine e; 00082 e.setRandomSequence(&nonRand[0], nonRand.size()); 00083 00084 double x = 0; 00085 for (int i=0; i<n; i++) x += e.flat(); 00086 std::vector<unsigned long> v = e.put(); 00087 x = e.flat(); 00088 output << "x = " << x << std::endl; 00089 00090 NonRandomEngine f; 00091 f.setRandomSequence(&nonRand[0], nonRand.size()); 00092 00093 v[0] &= 0xffffffffUL; 00094 f.get(v); 00095 double y = f.flat(); 00096 output << "y = " << y << std::endl; 00097 if( x != y ) return n; 00098 00099 return 0; 00100 } 00101 00102 template <class E> 00103 std::vector<unsigned long> vectorRestore1(int n, std::vector<double> & v) { 00104 output << "Vector restore for " << E::engineName() << "\n"; 00105 E e(97538466); 00106 double r=0; 00107 for (int i=0; i<n; i++) r += e.flat(); 00108 std::vector<unsigned long> state = e.put(); 00109 for (int j=0; j<25; j++) v.push_back(e.flat()); 00110 #ifdef VERBOSER2 00111 output << "First four of v are: " 00112 << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "\n"; 00113 #endif 00114 return state; 00115 } 00116 00117 template <> 00118 std::vector<unsigned long> 00119 vectorRestore1<NonRandomEngine> (int n, std::vector<double> & v) { 00120 #ifdef VERBOSER2 00121 output << "Vector restore for " << NonRandomEngine::engineName() << "\n"; 00122 #endif 00123 std::vector<double> nonRand = aSequence(500); 00124 NonRandomEngine e; 00125 e.setRandomSequence(&nonRand[0], nonRand.size()); 00126 double r=0; 00127 for (int i=0; i<n; i++) r += e.flat(); 00128 std::vector<unsigned long> state = e.put(); 00129 for (int j=0; j<25; j++) v.push_back(e.flat()); 00130 #ifdef VERBOSER2 00131 output << "First four of v are: " 00132 << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << "\n"; 00133 #endif 00134 return state; 00135 } 00136 00137 template <class E> 00138 int vectorRestore2(const std::vector<unsigned long> state, 00139 const std::vector<double> & v) { 00140 int stat = 0; 00141 std::vector<double> k; 00142 HepRandomEngine * a; 00143 a = HepRandomEngine::newEngine(state); 00144 if (!a) { 00145 std::cout << "???? could not restore engine state from vector for " 00146 << E::engineName() << "\n"; 00147 #ifdef CLEAN_OUTPUT 00148 output << "???? could not restore engine state from vector for " 00149 << E::engineName() << "\n"; 00150 #endif 00151 stat |= 1048576; 00152 return stat; 00153 } 00154 if (a->name() != E::engineName()) { 00155 #ifdef CLEAN_OUTPUT 00156 std::cout << "???? restored engine state from vector for " 00157 << E::engineName() << "to different type of engine: " 00158 << a->name() << "\n" 00159 << "There is probably a clash in CRC hashes for these two names!\n"; 00160 output << "???? restored engine state from vector for " 00161 << E::engineName() << "to different type of engine: " 00162 << a->name() << "\n" 00163 << "There is probably a clash in CRC hashes for these two names!\n"; 00164 #endif 00165 stat |= 1048576; 00166 return stat; 00167 } 00168 for (int j=0; j<25; j++) k.push_back(a->flat()); 00169 delete a; 00170 #ifdef VERBOSER2 00171 output << "First four of k are: " 00172 << k[0] << ", " << k[1] << ", " << k[2] << ", " << k[3] << "\n"; 00173 #endif 00174 for (int m=0; m<25; m++) { 00175 if ( v[m] != k[m] ) { 00176 std::cout << "???? Incorrect vector restored value for anonymous engine: " 00177 << E::engineName() << "\n"; 00178 #ifdef CLEAN_OUTPUT 00179 output << "???? Incorrect vector restored value for anonymous engine: " 00180 << E::engineName() << "\n"; 00181 #endif 00182 stat |= 1048576; 00183 return stat; 00184 } 00185 } 00186 return stat; 00187 } 00188 00189 00190 template <class E> 00191 int vectorRestore(int n) { 00192 std::vector<double> v; 00193 int status1 = vectorTest64<E>(n); 00194 std::vector<unsigned long> state = vectorRestore1<E>(n,v); 00195 int status2 = vectorRestore2<E>(state, v); 00196 return (status1 | status2); 00197 } 00198 00199 00200 00201 // --------------------------------------------- 00202 // --------------------------------------------- 00203 // --------------------------------------------- 00204 00205 00206 int main() { 00207 int stat = 0; 00208 00209 #ifdef TEST_VECTOR_ENGINE_RESTORE 00210 output << "\n=================================\n"; 00211 output << " Part IX \n"; 00212 output << "Save/restore of engines to vectors\n"; 00213 output << "=================================\n\n"; 00214 00215 stat |= vectorRestore<DualRand>(113); 00216 stat |= vectorRestore<DRand48Engine>(114); 00217 stat |= vectorRestore<Hurd160Engine>(115); 00218 stat |= vectorRestore<Hurd288Engine>(116); 00219 stat |= vectorRestore<HepJamesRandom>(117); 00220 stat |= vectorRestore<MTwistEngine>(118); 00221 stat |= vectorRestore<RanecuEngine>(139); 00222 stat |= vectorRestore<Ranlux64Engine>(119); 00223 stat |= vectorRestore<RanluxEngine>(120); 00224 stat |= vectorRestore<RanshiEngine>(121); 00225 stat |= vectorRestore<TripleRand>(122); 00226 stat |= vectorRestore<NonRandomEngine>(123); 00227 stat |= vectorRestore<RandEngine>(129); 00228 #endif 00229 00230 output << "\n=============================================\n\n"; 00231 00232 if (stat != 0) { 00233 std::cout << "One or more problems detected: stat = " << stat << "\n"; 00234 output << "One or more problems detected: stat = " << stat << "\n"; 00235 } else { 00236 output << "ranRestoreTest passed with no problems detected.\n"; 00237 } 00238 00239 if (stat == 0) return 0; 00240 if (stat > 0) return -(stat|1); 00241 return stat|1; 00242 } 00243