CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // -*- C++ -*- 00002 // $Id: DRand48Engine.cc,v 1.7 2010/07/29 16:50:34 garren Exp $ 00003 // ----------------------------------------------------------------------- 00004 // HEP Random 00005 // --- DRand48Engine --- 00006 // class implementation file 00007 // ----------------------------------------------------------------------- 00008 // This file is part of Geant4 (simulation toolkit for HEP). 00009 00010 // ======================================================================= 00011 // G.Cosmo - Created: 5th September 1995 00012 // - Minor corrections: 31st October 1996 00013 // - Added methods for engine status: 19th November 1996 00014 // - Added srand48(), seed48(), drand48() implementations 00015 // for Windows/NT: 6th March 1997 00016 // - Fixed bug in setSeeds(): 15th September 1997 00017 // - Private copy constructor and operator=: 26th Feb 1998 00018 // J.Marraffino - Added stream operators and related constructor. 00019 // Added automatic seed selection from seed table and 00020 // engine counter: 16th Feb 1998 00021 // J.Marraffino - Remove dependence on hepString class 13 May 1999 00022 // E.Tcherniaev - More accurate code for drand48() on NT base on 00023 // a code extracted from GNU C Library 2.1.3: 8th Nov 2000 00024 // M. Fischler - In restore, checkFile for file not found 03 Dec 2004 00025 // M. Fischler - Methods for distrib. instacne save/restore 12/8/04 00026 // M. Fischler - split get() into tag validation and 00027 // getState() for anonymous restores 12/27/04 00028 // M. Fischler - put/get for vectors of ulongs 3/8/05 00029 // M. Fischler - State-saving using only ints, for portability 4/12/05 00030 // 00031 // ======================================================================= 00032 00033 #include "CLHEP/Random/defs.h" 00034 #include "CLHEP/Random/Random.h" 00035 #include "CLHEP/Random/DRand48Engine.h" 00036 #include "CLHEP/Random/RandomFunc.h" 00037 #include "CLHEP/Random/engineIDulong.h" 00038 #include <string.h> // for strcmp 00039 #include <stdlib.h> // for std::abs(int) 00040 00041 //#define TRACE_IO 00042 00043 namespace CLHEP { 00044 00045 static const int MarkerLen = 64; // Enough room to hold a begin or end marker. 00046 // Number of instances with automatic seed selection 00047 int DRand48Engine::numEngines = 0; 00048 00049 std::string DRand48Engine::name() const {return "DRand48Engine";} 00050 00051 // Maximum index into the seed table 00052 int DRand48Engine::maxIndex = 215; 00053 00054 DRand48Engine::DRand48Engine(long seed) 00055 : HepRandomEngine() 00056 { 00057 setSeed(seed,0); 00058 setSeeds(&theSeed,0); 00059 } 00060 00061 DRand48Engine::DRand48Engine() 00062 : HepRandomEngine() 00063 { 00064 long seeds[2]; 00065 long seed; 00066 00067 int cycle = abs(int(numEngines/maxIndex)); 00068 int curIndex = abs(int(numEngines%maxIndex)); 00069 ++numEngines; 00070 long mask = ((cycle & 0x007fffff) << 8); 00071 HepRandom::getTheTableSeeds( seeds, curIndex ); 00072 seed = seeds[0]^mask; 00073 setSeed(seed,0); 00074 setSeeds(&theSeed,0); 00075 } 00076 00077 DRand48Engine::DRand48Engine(int rowIndex, int colIndex) 00078 : HepRandomEngine() 00079 { 00080 long seed; 00081 long seeds[2]; 00082 00083 int cycle = abs(int(rowIndex/maxIndex)); 00084 int row = abs(int(rowIndex%maxIndex)); 00085 int col = abs(int(colIndex%2)); 00086 long mask = ((cycle & 0x000007ff) << 20); 00087 HepRandom::getTheTableSeeds( seeds, row ); 00088 seed = (seeds[col])^mask; 00089 setSeed(seed,0); 00090 setSeeds(&theSeed,0); 00091 } 00092 00093 DRand48Engine::DRand48Engine(std::istream& is) 00094 : HepRandomEngine() 00095 { 00096 is >> *this; 00097 } 00098 00099 DRand48Engine::~DRand48Engine() {} 00100 00101 void DRand48Engine::setSeed(long seed, int) 00102 { 00103 srand48( seed ); 00104 theSeed = seed; 00105 } 00106 00107 void DRand48Engine::setSeeds(const long* seeds, int) 00108 { 00109 setSeed(seeds ? *seeds : 19780503L, 0); 00110 theSeeds = seeds; 00111 } 00112 00113 void DRand48Engine::saveStatus( const char filename[] ) const 00114 { 00115 std::ofstream outFile( filename, std::ios::out ) ; 00116 00117 if (!outFile.bad()) { 00118 outFile << "Uvec\n"; 00119 std::vector<unsigned long> v = put(); 00120 #ifdef TRACE_IO 00121 std::cout << "Result of v = put() is:\n"; 00122 #endif 00123 for (unsigned int i=0; i<v.size(); ++i) { 00124 outFile << v[i] << "\n"; 00125 #ifdef TRACE_IO 00126 std::cout << v[i] << " "; 00127 if (i%6==0) std::cout << "\n"; 00128 #endif 00129 } 00130 #ifdef TRACE_IO 00131 std::cout << "\n"; 00132 #endif 00133 } 00134 00135 #ifdef REMOVED 00136 unsigned short dummy[] = { 0, 0, 0 }; 00137 unsigned short* cseed = seed48(dummy); 00138 if (!outFile.bad()) { 00139 outFile << theSeed << std::endl; 00140 for (int i=0; i<3; ++i) { 00141 outFile << cseed[i] << std::endl; 00142 dummy[i] = cseed[i]; 00143 } 00144 seed48(dummy); 00145 } 00146 #endif 00147 } 00148 00149 void DRand48Engine::restoreStatus( const char filename[] ) 00150 { 00151 std::ifstream inFile( filename, std::ios::in); 00152 unsigned short cseed[3]; 00153 00154 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) { 00155 std::cerr << " -- Engine state remains unchanged\n"; 00156 return; 00157 } 00158 if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) { 00159 std::vector<unsigned long> v; 00160 unsigned long xin; 00161 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00162 inFile >> xin; 00163 #ifdef TRACE_IO 00164 std::cout << "ivec = " << ivec << " xin = " << xin << " "; 00165 if (ivec%3 == 0) std::cout << "\n"; 00166 #endif 00167 if (!inFile) { 00168 inFile.clear(std::ios::badbit | inFile.rdstate()); 00169 std::cerr << "\nDRand48Engine state (vector) description improper." 00170 << "\nrestoreStatus has failed." 00171 << "\nInput stream is probably mispositioned now." << std::endl; 00172 return; 00173 } 00174 v.push_back(xin); 00175 } 00176 getState(v); 00177 return; 00178 } 00179 00180 if (!inFile.bad() && !inFile.eof()) { 00181 inFile >> theSeed; 00182 for (int i=0; i<3; ++i) 00183 // inFile >> theSeed; removed -- encompased by possibleKeywordInput 00184 seed48(cseed); 00185 } 00186 } 00187 00188 void DRand48Engine::showStatus() const 00189 { 00190 unsigned short dummy[] = { 0, 0, 0 }; 00191 unsigned short* cseed = seed48(dummy); 00192 std::cout << std::endl; 00193 std::cout << "-------- DRand48 engine status ---------" << std::endl; 00194 std::cout << " Initial seed = " << theSeed << std::endl; 00195 std::cout << " Current seeds = " << cseed[0] << ", "; 00196 std::cout << cseed[1] << ", "; 00197 std::cout << cseed[2] << std::endl; 00198 std::cout << "----------------------------------------" << std::endl; 00199 for (int i=0; i<3; ++i) 00200 dummy[i] = cseed[i]; 00201 seed48(dummy); 00202 } 00203 00204 double DRand48Engine::flat() 00205 { 00206 double num = 0.; 00207 00208 while (num == 0.) 00209 num = drand48(); 00210 return num; 00211 } 00212 00213 void DRand48Engine::flatArray(const int size, double* vect) 00214 { 00215 int i; 00216 00217 for (i=0; i<size; ++i) 00218 vect[i]=flat(); 00219 } 00220 00221 std::ostream & DRand48Engine::put ( std::ostream& os ) const 00222 { 00223 char beginMarker[] = "DRand48Engine-begin"; 00224 os << beginMarker << "\nUvec\n"; 00225 std::vector<unsigned long> v = put(); 00226 for (unsigned int i=0; i<v.size(); ++i) { 00227 os << v[i] << "\n"; 00228 } 00229 return os; 00230 00231 #ifdef REMOVED 00232 unsigned short dummy[] = { 0, 0, 0 }; 00233 unsigned short* cseed = seed48(dummy); 00234 char endMarker[] = "DRand48Engine-end"; 00235 os << " " << beginMarker << " "; 00236 os << theSeed << " "; 00237 for (int i=0; i<3; ++i) { 00238 dummy[i] = cseed[i]; 00239 os << cseed[i] << " "; 00240 } 00241 os << endMarker << " "; 00242 seed48(dummy); 00243 return os; 00244 #endif 00245 } 00246 00247 std::vector<unsigned long> DRand48Engine::put () const { 00248 std::vector<unsigned long> v; 00249 v.push_back (engineIDulong<DRand48Engine>()); 00250 unsigned short dummy[] = { 0, 0, 0 }; 00251 unsigned short* cseed = seed48(dummy); 00252 for (int i=0; i<3; ++i) { 00253 dummy[i] = cseed[i]; 00254 v.push_back (static_cast<unsigned long>(cseed[i])); 00255 } 00256 seed48(dummy); 00257 return v; 00258 } 00259 00260 std::istream & DRand48Engine::get ( std::istream& is ) 00261 { 00262 char beginMarker [MarkerLen]; 00263 is >> std::ws; 00264 is.width(MarkerLen); // causes the next read to the char* to be <= 00265 // that many bytes, INCLUDING A TERMINATION \0 00266 // (Stroustrup, section 21.3.2) 00267 is >> beginMarker; 00268 if (strcmp(beginMarker,"DRand48Engine-begin")) { 00269 is.clear(std::ios::badbit | is.rdstate()); 00270 std::cerr << "\nInput stream mispositioned or" 00271 << "\nDRand48Engine state description missing or" 00272 << "\nwrong engine type found." << std::endl; 00273 return is; 00274 } 00275 return getState(is); 00276 } 00277 00278 std::string DRand48Engine::beginTag ( ) { 00279 return "DRand48Engine-begin"; 00280 } 00281 00282 std::istream & DRand48Engine::getState ( std::istream& is ) 00283 { 00284 unsigned short cseed[3]; 00285 if ( possibleKeywordInput ( is, "Uvec", cseed[0] ) ) { 00286 std::vector<unsigned long> v; 00287 unsigned long uu; 00288 #ifdef TRACE_IO 00289 std::cout << "DRand48Engine::getState detected Uvec keyword\n"; 00290 uu = 999999; 00291 #endif 00292 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00293 uu = 999999; 00294 is >> uu; 00295 #ifdef TRACE_IO 00296 std::cout << "ivec = " << ivec << " uu = " << uu << "\n"; 00297 #endif 00298 if (!is) { 00299 is.clear(std::ios::badbit | is.rdstate()); 00300 std::cerr << "\nDRand48Engine state (vector) description improper." 00301 << "\ngetState() has failed." 00302 << "\nInput stream is probably mispositioned now." << std::endl; 00303 return is; 00304 } 00305 v.push_back(uu); 00306 } 00307 getState(v); 00308 return (is); 00309 } 00310 00311 // is >> cseed[0] was removed from loop, encompassed by possibleKeywordInput() 00312 00313 char endMarker [MarkerLen]; 00314 is >> theSeed; 00315 for (int i=1; i<3; ++i) { 00316 is >> cseed[i]; 00317 } 00318 is >> std::ws; 00319 is.width(MarkerLen); 00320 is >> endMarker; 00321 if (strcmp(endMarker,"DRand48Engine-end")) { 00322 is.clear(std::ios::badbit | is.rdstate()); 00323 std::cerr << "\nDRand48Engine state description incomplete." 00324 << "\nInput stream is probably mispositioned now." << std::endl; 00325 return is; 00326 } 00327 seed48(cseed); 00328 return is; 00329 } 00330 00331 bool DRand48Engine::get (const std::vector<unsigned long> & v) { 00332 if ((v[0] & 0xffffffffUL) != engineIDulong<DRand48Engine>()) { 00333 std::cerr << 00334 "\nDRand48Engine get:state vector has wrong ID word - state unchanged\n"; 00335 return false; 00336 } 00337 return getState(v); 00338 } 00339 00340 bool DRand48Engine::getState (const std::vector<unsigned long> & v) { 00341 if (v.size() != VECTOR_STATE_SIZE ) { 00342 std::cerr << 00343 "\nDRand48Engine getState:state vector has wrong length - state unchanged\n"; 00344 return false; 00345 } 00346 unsigned short cseed[3]; 00347 for (int i=0; i<3; ++i) { 00348 cseed[i] = static_cast<unsigned short>(v[i+1]); 00349 } 00350 seed48(cseed); 00351 return true; 00352 } 00353 00354 } // namespace CLHEP