CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // -*- C++ -*- 00002 // $Id: DRand48Engine.cc,v 1.4.4.3.2.1 2008/11/13 21:35:23 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> 00039 00040 //#define TRACE_IO 00041 00042 namespace CLHEP { 00043 00044 static const int MarkerLen = 64; // Enough room to hold a begin or end marker. 00045 // Number of instances with automatic seed selection 00046 int DRand48Engine::numEngines = 0; 00047 00048 std::string DRand48Engine::name() const {return "DRand48Engine";} 00049 00050 // Maximum index into the seed table 00051 int DRand48Engine::maxIndex = 215; 00052 00053 DRand48Engine::DRand48Engine(long seed) 00054 { 00055 setSeed(seed,0); 00056 setSeeds(&theSeed,0); 00057 } 00058 00059 DRand48Engine::DRand48Engine() 00060 { 00061 long seeds[2]; 00062 long seed; 00063 int cycle,curIndex; 00064 00065 cycle = abs(int(numEngines/maxIndex)); 00066 curIndex = abs(int(numEngines%maxIndex)); 00067 numEngines += 1; 00068 long mask = ((cycle & 0x007fffff) << 8); 00069 HepRandom::getTheTableSeeds( seeds, curIndex ); 00070 seed = seeds[0]^mask; 00071 setSeed(seed,0); 00072 setSeeds(&theSeed,0); 00073 } 00074 00075 DRand48Engine::DRand48Engine(int rowIndex, int colIndex) 00076 { 00077 long seed; 00078 long seeds[2]; 00079 00080 int cycle = abs(int(rowIndex/maxIndex)); 00081 int row = abs(int(rowIndex%maxIndex)); 00082 int col = abs(int(colIndex%2)); 00083 long mask = ((cycle & 0x000007ff) << 20); 00084 HepRandom::getTheTableSeeds( seeds, row ); 00085 seed = (seeds[col])^mask; 00086 setSeed(seed,0); 00087 setSeeds(&theSeed,0); 00088 } 00089 00090 DRand48Engine::DRand48Engine(std::istream& is) 00091 { 00092 is >> *this; 00093 } 00094 00095 DRand48Engine::~DRand48Engine() {} 00096 00097 void DRand48Engine::setSeed(long seed, int) 00098 { 00099 srand48( seed ); 00100 theSeed = seed; 00101 } 00102 00103 void DRand48Engine::setSeeds(const long* seeds, int) 00104 { 00105 setSeed(seeds ? *seeds : 19780503L, 0); 00106 theSeeds = seeds; 00107 } 00108 00109 void DRand48Engine::saveStatus( const char filename[] ) const 00110 { 00111 std::ofstream outFile( filename, std::ios::out ) ; 00112 00113 if (!outFile.bad()) { 00114 outFile << "Uvec\n"; 00115 std::vector<unsigned long> v = put(); 00116 #ifdef TRACE_IO 00117 std::cout << "Result of v = put() is:\n"; 00118 #endif 00119 for (unsigned int i=0; i<v.size(); ++i) { 00120 outFile << v[i] << "\n"; 00121 #ifdef TRACE_IO 00122 std::cout << v[i] << " "; 00123 if (i%6==0) std::cout << "\n"; 00124 #endif 00125 } 00126 #ifdef TRACE_IO 00127 std::cout << "\n"; 00128 #endif 00129 } 00130 00131 #ifdef REMOVED 00132 unsigned short dummy[] = { 0, 0, 0 }; 00133 unsigned short* cseed = seed48(dummy); 00134 if (!outFile.bad()) { 00135 outFile << theSeed << std::endl; 00136 for (int i=0; i<3; ++i) { 00137 outFile << cseed[i] << std::endl; 00138 dummy[i] = cseed[i]; 00139 } 00140 seed48(dummy); 00141 } 00142 #endif 00143 } 00144 00145 void DRand48Engine::restoreStatus( const char filename[] ) 00146 { 00147 std::ifstream inFile( filename, std::ios::in); 00148 unsigned short cseed[3]; 00149 00150 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) { 00151 std::cerr << " -- Engine state remains unchanged\n"; 00152 return; 00153 } 00154 if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) { 00155 std::vector<unsigned long> v; 00156 unsigned long xin; 00157 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00158 inFile >> xin; 00159 #ifdef TRACE_IO 00160 std::cout << "ivec = " << ivec << " xin = " << xin << " "; 00161 if (ivec%3 == 0) std::cout << "\n"; 00162 #endif 00163 if (!inFile) { 00164 inFile.clear(std::ios::badbit | inFile.rdstate()); 00165 std::cerr << "\nDRand48Engine state (vector) description improper." 00166 << "\nrestoreStatus has failed." 00167 << "\nInput stream is probably mispositioned now." << std::endl; 00168 return; 00169 } 00170 v.push_back(xin); 00171 } 00172 getState(v); 00173 return; 00174 } 00175 00176 if (!inFile.bad() && !inFile.eof()) { 00177 inFile >> theSeed; 00178 for (int i=0; i<3; ++i) 00179 // inFile >> theSeed; removed -- encompased by possibleKeywordInput 00180 seed48(cseed); 00181 } 00182 } 00183 00184 void DRand48Engine::showStatus() const 00185 { 00186 unsigned short dummy[] = { 0, 0, 0 }; 00187 unsigned short* cseed = seed48(dummy); 00188 std::cout << std::endl; 00189 std::cout << "-------- DRand48 engine status ---------" << std::endl; 00190 std::cout << " Initial seed = " << theSeed << std::endl; 00191 std::cout << " Current seeds = " << cseed[0] << ", "; 00192 std::cout << cseed[1] << ", "; 00193 std::cout << cseed[2] << std::endl; 00194 std::cout << "----------------------------------------" << std::endl; 00195 for (int i=0; i<3; ++i) 00196 dummy[i] = cseed[i]; 00197 seed48(dummy); 00198 } 00199 00200 double DRand48Engine::flat() 00201 { 00202 double num = 0.; 00203 00204 while (num == 0.) 00205 num = drand48(); 00206 return num; 00207 } 00208 00209 void DRand48Engine::flatArray(const int size, double* vect) 00210 { 00211 int i; 00212 00213 for (i=0; i<size; ++i) 00214 vect[i]=flat(); 00215 } 00216 00217 std::ostream & DRand48Engine::put ( std::ostream& os ) const 00218 { 00219 char beginMarker[] = "DRand48Engine-begin"; 00220 os << beginMarker << "\nUvec\n"; 00221 std::vector<unsigned long> v = put(); 00222 for (unsigned int i=0; i<v.size(); ++i) { 00223 os << v[i] << "\n"; 00224 } 00225 return os; 00226 00227 #ifdef REMOVED 00228 unsigned short dummy[] = { 0, 0, 0 }; 00229 unsigned short* cseed = seed48(dummy); 00230 char endMarker[] = "DRand48Engine-end"; 00231 os << " " << beginMarker << " "; 00232 os << theSeed << " "; 00233 for (int i=0; i<3; ++i) { 00234 dummy[i] = cseed[i]; 00235 os << cseed[i] << " "; 00236 } 00237 os << endMarker << " "; 00238 seed48(dummy); 00239 return os; 00240 #endif 00241 } 00242 00243 std::vector<unsigned long> DRand48Engine::put () const { 00244 std::vector<unsigned long> v; 00245 v.push_back (engineIDulong<DRand48Engine>()); 00246 unsigned short dummy[] = { 0, 0, 0 }; 00247 unsigned short* cseed = seed48(dummy); 00248 for (int i=0; i<3; ++i) { 00249 dummy[i] = cseed[i]; 00250 v.push_back (static_cast<unsigned long>(cseed[i])); 00251 } 00252 seed48(dummy); 00253 return v; 00254 } 00255 00256 std::istream & DRand48Engine::get ( std::istream& is ) 00257 { 00258 char beginMarker [MarkerLen]; 00259 is >> std::ws; 00260 is.width(MarkerLen); // causes the next read to the char* to be <= 00261 // that many bytes, INCLUDING A TERMINATION \0 00262 // (Stroustrup, section 21.3.2) 00263 is >> beginMarker; 00264 if (strcmp(beginMarker,"DRand48Engine-begin")) { 00265 is.clear(std::ios::badbit | is.rdstate()); 00266 std::cerr << "\nInput stream mispositioned or" 00267 << "\nDRand48Engine state description missing or" 00268 << "\nwrong engine type found." << std::endl; 00269 return is; 00270 } 00271 return getState(is); 00272 } 00273 00274 std::string DRand48Engine::beginTag ( ) { 00275 return "DRand48Engine-begin"; 00276 } 00277 00278 std::istream & DRand48Engine::getState ( std::istream& is ) 00279 { 00280 unsigned short cseed[3]; 00281 if ( possibleKeywordInput ( is, "Uvec", cseed[0] ) ) { 00282 std::vector<unsigned long> v; 00283 unsigned long uu; 00284 #ifdef TRACE_IO 00285 std::cout << "DRand48Engine::getState detected Uvec keyword\n"; 00286 uu = 999999; 00287 #endif 00288 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00289 uu = 999999; 00290 is >> uu; 00291 #ifdef TRACE_IO 00292 std::cout << "ivec = " << ivec << " uu = " << uu << "\n"; 00293 #endif 00294 if (!is) { 00295 is.clear(std::ios::badbit | is.rdstate()); 00296 std::cerr << "\nDRand48Engine state (vector) description improper." 00297 << "\ngetState() has failed." 00298 << "\nInput stream is probably mispositioned now." << std::endl; 00299 return is; 00300 } 00301 v.push_back(uu); 00302 } 00303 getState(v); 00304 return (is); 00305 } 00306 00307 // is >> cseed[0] was removed from loop, encompassed by possibleKeywordInput() 00308 00309 char endMarker [MarkerLen]; 00310 is >> theSeed; 00311 for (int i=1; i<3; ++i) { 00312 is >> cseed[i]; 00313 } 00314 is >> std::ws; 00315 is.width(MarkerLen); 00316 is >> endMarker; 00317 if (strcmp(endMarker,"DRand48Engine-end")) { 00318 is.clear(std::ios::badbit | is.rdstate()); 00319 std::cerr << "\nDRand48Engine state description incomplete." 00320 << "\nInput stream is probably mispositioned now." << std::endl; 00321 return is; 00322 } 00323 seed48(cseed); 00324 return is; 00325 } 00326 00327 bool DRand48Engine::get (const std::vector<unsigned long> & v) { 00328 if ((v[0] & 0xffffffffUL) != engineIDulong<DRand48Engine>()) { 00329 std::cerr << 00330 "\nDRand48Engine get:state vector has wrong ID word - state unchanged\n"; 00331 return false; 00332 } 00333 return getState(v); 00334 } 00335 00336 bool DRand48Engine::getState (const std::vector<unsigned long> & v) { 00337 if (v.size() != VECTOR_STATE_SIZE ) { 00338 std::cerr << 00339 "\nDRand48Engine getState:state vector has wrong length - state unchanged\n"; 00340 return false; 00341 } 00342 unsigned short cseed[3]; 00343 for (int i=0; i<3; ++i) { 00344 cseed[i] = static_cast<unsigned short>(v[i+1]); 00345 } 00346 seed48(cseed); 00347 return true; 00348 } 00349 00350 } // namespace CLHEP