CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // $Id: RanluxEngine.cc,v 1.4.4.2.2.2 2008/11/13 21:35:23 garren Exp $ 00002 // -*- C++ -*- 00003 // 00004 // ----------------------------------------------------------------------- 00005 // HEP Random 00006 // --- RanluxEngine --- 00007 // class implementation file 00008 // ----------------------------------------------------------------------- 00009 // This file is part of Geant4 (simulation toolkit for HEP). 00010 // 00011 // Ranlux random number generator originally implemented in FORTRAN77 00012 // by Fred James as part of the MATHLIB HEP library. 00013 // 'RanluxEngine' is designed to fit into the CLHEP random number 00014 // class structure. 00015 00016 // =============================================================== 00017 // Adeyemi Adesanya - Created: 6th November 1995 00018 // Gabriele Cosmo - Adapted & Revised: 22nd November 1995 00019 // Adeyemi Adesanya - Added setSeeds() method: 2nd February 1996 00020 // Gabriele Cosmo - Added flatArray() method: 8th February 1996 00021 // - Minor corrections: 31st October 1996 00022 // - Added methods for engine status: 19th November 1996 00023 // - Fixed bug in setSeeds(): 15th September 1997 00024 // J.Marraffino - Added stream operators and related constructor. 00025 // Added automatic seed selection from seed table and 00026 // engine counter: 14th Feb 1998 00027 // - Fixed bug: setSeeds() requires a zero terminated 00028 // array of seeds: 19th Feb 1998 00029 // Ken Smith - Added conversion operators: 6th Aug 1998 00030 // J. Marraffino - Remove dependence on hepString class 13 May 1999 00031 // M. Fischler - In restore, checkFile for file not found 03 Dec 2004 00032 // M. Fischler - Methods put, getfor instance save/restore 12/8/04 00033 // M. Fischler - split get() into tag validation and 00034 // getState() for anonymous restores 12/27/04 00035 // M. Fischler - put/get for vectors of ulongs 3/14/05 00036 // M. Fischler - State-saving using only ints, for portability 4/12/05 00037 // 00038 // =============================================================== 00039 00040 #include "CLHEP/Random/defs.h" 00041 #include "CLHEP/Random/Random.h" 00042 #include "CLHEP/Random/RanluxEngine.h" 00043 #include "CLHEP/Random/engineIDulong.h" 00044 #include <string.h> 00045 #include <cmath> 00046 #include <stdlib.h> // for abs(int) 00047 00048 #ifdef TRACE_IO 00049 #include "CLHEP/Random/DoubConv.hh" 00050 bool flat_trace = false; 00051 #endif 00052 00053 using namespace std; 00054 00055 namespace CLHEP { 00056 00057 00058 static const int MarkerLen = 64; // Enough room to hold a begin or end marker. 00059 00060 std::string RanluxEngine::name() const {return "RanluxEngine";} 00061 00062 // Number of instances with automatic seed selection 00063 int RanluxEngine::numEngines = 0; 00064 00065 // Maximum index into the seed table 00066 int RanluxEngine::maxIndex = 215; 00067 00068 RanluxEngine::RanluxEngine(long seed, int lux) 00069 : int_modulus(0x1000000), 00070 mantissa_bit_24( pow(0.5,24.) ), 00071 mantissa_bit_12( pow(0.5,12.) ) 00072 { 00073 long seedlist[2]={0,0}; 00074 00075 luxury = lux; 00076 setSeed(seed, luxury); 00077 00078 // setSeeds() wants a zero terminated array! 00079 seedlist[0]=theSeed; 00080 seedlist[1]=0; 00081 setSeeds(seedlist, luxury); 00082 } 00083 00084 RanluxEngine::RanluxEngine() 00085 : int_modulus(0x1000000), 00086 mantissa_bit_24( pow(0.5,24.) ), 00087 mantissa_bit_12( pow(0.5,12.) ) 00088 { 00089 long seed; 00090 long seedlist[2]={0,0}; 00091 00092 luxury = 3; 00093 int cycle = abs(int(numEngines/maxIndex)); 00094 int curIndex = abs(int(numEngines%maxIndex)); 00095 numEngines +=1; 00096 long mask = ((cycle & 0x007fffff) << 8); 00097 HepRandom::getTheTableSeeds( seedlist, curIndex ); 00098 seed = seedlist[0]^mask; 00099 setSeed(seed, luxury); 00100 00101 // setSeeds() wants a zero terminated array! 00102 seedlist[0]=theSeed; 00103 seedlist[1]=0; 00104 setSeeds(seedlist, luxury); 00105 } 00106 00107 RanluxEngine::RanluxEngine(int rowIndex, int colIndex, int lux) 00108 : int_modulus(0x1000000), 00109 mantissa_bit_24( pow(0.5,24.) ), 00110 mantissa_bit_12( pow(0.5,12.) ) 00111 { 00112 long seed; 00113 long seedlist[2]={0,0}; 00114 00115 luxury = lux; 00116 int cycle = abs(int(rowIndex/maxIndex)); 00117 int row = abs(int(rowIndex%maxIndex)); 00118 int col = abs(int(colIndex%2)); 00119 long mask = (( cycle & 0x000007ff ) << 20 ); 00120 HepRandom::getTheTableSeeds( seedlist, row ); 00121 seed = ( seedlist[col] )^mask; 00122 setSeed(seed, luxury); 00123 00124 // setSeeds() wants a zero terminated array! 00125 seedlist[0]=theSeed; 00126 seedlist[1]=0; 00127 setSeeds(seedlist, luxury); 00128 } 00129 00130 RanluxEngine::RanluxEngine( std::istream& is ) 00131 : int_modulus(0x1000000), 00132 mantissa_bit_24( pow(0.5,24.) ), 00133 mantissa_bit_12( pow(0.5,12.) ) 00134 { 00135 is >> *this; 00136 } 00137 00138 RanluxEngine::~RanluxEngine() {} 00139 00140 RanluxEngine::RanluxEngine(const RanluxEngine &p) 00141 : int_modulus(0x1000000), 00142 mantissa_bit_24( pow(0.5,24.) ), 00143 mantissa_bit_12( pow(0.5,12.) ) 00144 { 00145 long seedlist[2]={0,0}; 00146 00147 if ((this != &p) && (&p)) { 00148 theSeed = p.getSeed(); 00149 00150 // setSeeds() wants a zero terminated array! 00151 seedlist[0]=theSeed; 00152 setSeeds(seedlist, p.luxury); 00153 00154 for (int i=0; i<24; ++i) 00155 float_seed_table[i] = p.float_seed_table[i]; 00156 nskip = p.nskip; 00157 luxury = p.luxury; 00158 i_lag = p.i_lag; j_lag = p.j_lag; 00159 carry = p.carry; 00160 count24 = p.count24; 00161 } 00162 } 00163 00164 RanluxEngine & RanluxEngine::operator = (const RanluxEngine &p) 00165 { 00166 long seedlist[2]={0,0}; 00167 00168 if ((this != &p) && (&p)) { 00169 theSeed = p.getSeed(); 00170 00171 // setSeeds() wants a zero terminated array! 00172 seedlist[0]=theSeed; 00173 setSeeds(seedlist, p.luxury); 00174 00175 for (int i=0; i<24; ++i) 00176 float_seed_table[i] = p.float_seed_table[i]; 00177 nskip = p.nskip; 00178 luxury = p.luxury; 00179 i_lag = p.i_lag; j_lag = p.j_lag; 00180 carry = p.carry; 00181 count24 = p.count24; 00182 } 00183 return *this; 00184 } 00185 00186 void RanluxEngine::setSeed(long seed, int lux) { 00187 00188 // The initialisation is carried out using a Multiplicative 00189 // Congruential generator using formula constants of L'Ecuyer 00190 // as described in "A review of pseudorandom number generators" 00191 // (Fred James) published in Computer Physics Communications 60 (1990) 00192 // pages 329-344 00193 00194 const int ecuyer_a = 53668; 00195 const int ecuyer_b = 40014; 00196 const int ecuyer_c = 12211; 00197 const int ecuyer_d = 2147483563; 00198 00199 const int lux_levels[5] = {0,24,73,199,365}; 00200 00201 long int_seed_table[24]; 00202 long next_seed = seed; 00203 long k_multiple; 00204 int i; 00205 00206 // number of additional random numbers that need to be 'thrown away' 00207 // every 24 numbers is set using luxury level variable. 00208 00209 theSeed = seed; 00210 if( (lux > 4)||(lux < 0) ){ 00211 if(lux >= 24){ 00212 nskip = lux - 24; 00213 }else{ 00214 nskip = lux_levels[3]; // corresponds to default luxury level 00215 } 00216 }else{ 00217 luxury = lux; 00218 nskip = lux_levels[luxury]; 00219 } 00220 00221 00222 for(i = 0;i != 24;i++){ 00223 k_multiple = next_seed / ecuyer_a; 00224 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 00225 - k_multiple * ecuyer_c ; 00226 if(next_seed < 0)next_seed += ecuyer_d; 00227 int_seed_table[i] = next_seed % int_modulus; 00228 } 00229 00230 for(i = 0;i != 24;i++) 00231 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24; 00232 00233 i_lag = 23; 00234 j_lag = 9; 00235 carry = 0. ; 00236 00237 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24; 00238 00239 count24 = 0; 00240 } 00241 00242 void RanluxEngine::setSeeds(const long *seeds, int lux) { 00243 00244 const int ecuyer_a = 53668; 00245 const int ecuyer_b = 40014; 00246 const int ecuyer_c = 12211; 00247 const int ecuyer_d = 2147483563; 00248 00249 const int lux_levels[5] = {0,24,73,199,365}; 00250 int i; 00251 long int_seed_table[24]; 00252 long k_multiple,next_seed; 00253 const long *seedptr; 00254 00255 theSeeds = seeds; 00256 seedptr = seeds; 00257 00258 if(seeds == 0){ 00259 setSeed(theSeed,lux); 00260 theSeeds = &theSeed; 00261 return; 00262 } 00263 00264 theSeed = *seeds; 00265 00266 // number of additional random numbers that need to be 'thrown away' 00267 // every 24 numbers is set using luxury level variable. 00268 00269 if( (lux > 4)||(lux < 0) ){ 00270 if(lux >= 24){ 00271 nskip = lux - 24; 00272 }else{ 00273 nskip = lux_levels[3]; // corresponds to default luxury level 00274 } 00275 }else{ 00276 luxury = lux; 00277 nskip = lux_levels[luxury]; 00278 } 00279 00280 for( i = 0;(i != 24)&&(*seedptr != 0);i++){ 00281 int_seed_table[i] = *seedptr % int_modulus; 00282 seedptr++; 00283 } 00284 00285 if(i != 24){ 00286 next_seed = int_seed_table[i-1]; 00287 for(;i != 24;i++){ 00288 k_multiple = next_seed / ecuyer_a; 00289 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 00290 - k_multiple * ecuyer_c ; 00291 if(next_seed < 0)next_seed += ecuyer_d; 00292 int_seed_table[i] = next_seed % int_modulus; 00293 } 00294 } 00295 00296 for(i = 0;i != 24;i++) 00297 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24; 00298 00299 i_lag = 23; 00300 j_lag = 9; 00301 carry = 0. ; 00302 00303 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24; 00304 00305 count24 = 0; 00306 } 00307 00308 void RanluxEngine::saveStatus( const char filename[] ) const 00309 { 00310 std::ofstream outFile( filename, std::ios::out ) ; 00311 if (!outFile.bad()) { 00312 outFile << "Uvec\n"; 00313 std::vector<unsigned long> v = put(); 00314 #ifdef TRACE_IO 00315 std::cout << "Result of v = put() is:\n"; 00316 #endif 00317 for (unsigned int i=0; i<v.size(); ++i) { 00318 outFile << v[i] << "\n"; 00319 #ifdef TRACE_IO 00320 std::cout << v[i] << " "; 00321 if (i%6==0) std::cout << "\n"; 00322 #endif 00323 } 00324 #ifdef TRACE_IO 00325 std::cout << "\n"; 00326 #endif 00327 } 00328 #ifdef REMOVED 00329 if (!outFile.bad()) { 00330 outFile << theSeed << std::endl; 00331 for (int i=0; i<24; ++i) 00332 outFile <<std::setprecision(20) << float_seed_table[i] << " "; 00333 outFile << std::endl; 00334 outFile << i_lag << " " << j_lag << std::endl; 00335 outFile << std::setprecision(20) << carry << " " << count24 << std::endl; 00336 outFile << luxury << " " << nskip << std::endl; 00337 } 00338 #endif 00339 } 00340 00341 void RanluxEngine::restoreStatus( const char filename[] ) 00342 { 00343 std::ifstream inFile( filename, std::ios::in); 00344 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) { 00345 std::cerr << " -- Engine state remains unchanged\n"; 00346 return; 00347 } 00348 if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) { 00349 std::vector<unsigned long> v; 00350 unsigned long xin; 00351 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00352 inFile >> xin; 00353 #ifdef TRACE_IO 00354 std::cout << "ivec = " << ivec << " xin = " << xin << " "; 00355 if (ivec%3 == 0) std::cout << "\n"; 00356 #endif 00357 if (!inFile) { 00358 inFile.clear(std::ios::badbit | inFile.rdstate()); 00359 std::cerr << "\nRanluxEngine state (vector) description improper." 00360 << "\nrestoreStatus has failed." 00361 << "\nInput stream is probably mispositioned now." << std::endl; 00362 return; 00363 } 00364 v.push_back(xin); 00365 } 00366 getState(v); 00367 return; 00368 } 00369 00370 if (!inFile.bad() && !inFile.eof()) { 00371 // inFile >> theSeed; removed -- encompased by possibleKeywordInput 00372 for (int i=0; i<24; ++i) 00373 inFile >> float_seed_table[i]; 00374 inFile >> i_lag; inFile >> j_lag; 00375 inFile >> carry; inFile >> count24; 00376 inFile >> luxury; inFile >> nskip; 00377 } 00378 } 00379 00380 void RanluxEngine::showStatus() const 00381 { 00382 std::cout << std::endl; 00383 std::cout << "--------- Ranlux engine status ---------" << std::endl; 00384 std::cout << " Initial seed = " << theSeed << std::endl; 00385 std::cout << " float_seed_table[] = "; 00386 for (int i=0; i<24; ++i) 00387 std::cout << float_seed_table[i] << " "; 00388 std::cout << std::endl; 00389 std::cout << " i_lag = " << i_lag << ", j_lag = " << j_lag << std::endl; 00390 std::cout << " carry = " << carry << ", count24 = " << count24 << std::endl; 00391 std::cout << " luxury = " << luxury << " nskip = " << nskip << std::endl; 00392 std::cout << "----------------------------------------" << std::endl; 00393 } 00394 00395 double RanluxEngine::flat() { 00396 00397 float next_random; 00398 float uni; 00399 int i; 00400 00401 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00402 #ifdef TRACE_IO 00403 if (flat_trace) { 00404 std::cout << "float_seed_table[" << j_lag << "] = " 00405 << float_seed_table[j_lag] 00406 << " float_seed_table[" << i_lag << "] = " << float_seed_table[i_lag] 00407 << " uni = " << uni << "\n"; 00408 std::cout << float_seed_table[j_lag] 00409 << " - " << float_seed_table[i_lag] 00410 << " - " << carry << " = " 00411 << (double)float_seed_table[j_lag] 00412 - (double) float_seed_table[i_lag] - (double)carry 00413 << "\n"; 00414 } 00415 #endif 00416 if(uni < 0. ){ 00417 uni += 1.0; 00418 carry = mantissa_bit_24; 00419 }else{ 00420 carry = 0.; 00421 } 00422 00423 float_seed_table[i_lag] = uni; 00424 i_lag --; 00425 j_lag --; 00426 if(i_lag < 0) i_lag = 23; 00427 if(j_lag < 0) j_lag = 23; 00428 00429 if( uni < mantissa_bit_12 ){ 00430 uni += mantissa_bit_24 * float_seed_table[j_lag]; 00431 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24; 00432 } 00433 next_random = uni; 00434 count24 ++; 00435 00436 // every 24th number generation, several random numbers are generated 00437 // and wasted depending upon the luxury level. 00438 00439 if(count24 == 24 ){ 00440 count24 = 0; 00441 #ifdef TRACE_IO 00442 if (flat_trace) { 00443 std::cout << "carry = " << carry << "\n"; 00444 } 00445 #endif 00446 for( i = 0; i != nskip ; i++){ 00447 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00448 if(uni < 0. ){ 00449 uni += 1.0; 00450 carry = mantissa_bit_24; 00451 }else{ 00452 carry = 0.; 00453 } 00454 float_seed_table[i_lag] = uni; 00455 #ifdef TRACE_IO 00456 if (flat_trace) { 00457 double xfst = float_seed_table[i_lag]; 00458 std::cout << "fst[" << i_lag << "] = " 00459 << DoubConv::d2x(xfst) << "\n"; 00460 } 00461 #endif 00462 i_lag --; 00463 j_lag --; 00464 if(i_lag < 0)i_lag = 23; 00465 if(j_lag < 0) j_lag = 23; 00466 } 00467 } 00468 #ifdef TRACE_IO 00469 if (flat_trace) { 00470 std::cout << "next_random = " << next_random << "\n"; 00471 // flat_trace = false; 00472 } 00473 #endif 00474 return (double) next_random; 00475 } 00476 00477 void RanluxEngine::flatArray(const int size, double* vect) 00478 { 00479 float next_random; 00480 float uni; 00481 int i; 00482 int index; 00483 00484 for (index=0; index<size; ++index) { 00485 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00486 if(uni < 0. ){ 00487 uni += 1.0; 00488 carry = mantissa_bit_24; 00489 }else{ 00490 carry = 0.; 00491 } 00492 00493 float_seed_table[i_lag] = uni; 00494 i_lag --; 00495 j_lag --; 00496 if(i_lag < 0) i_lag = 23; 00497 if(j_lag < 0) j_lag = 23; 00498 00499 if( uni < mantissa_bit_12 ){ 00500 uni += mantissa_bit_24 * float_seed_table[j_lag]; 00501 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24; 00502 } 00503 next_random = uni; 00504 vect[index] = (double)next_random; 00505 count24 ++; 00506 00507 // every 24th number generation, several random numbers are generated 00508 // and wasted depending upon the luxury level. 00509 00510 if(count24 == 24 ){ 00511 count24 = 0; 00512 for( i = 0; i != nskip ; i++){ 00513 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry; 00514 if(uni < 0. ){ 00515 uni += 1.0; 00516 carry = mantissa_bit_24; 00517 }else{ 00518 carry = 0.; 00519 } 00520 float_seed_table[i_lag] = uni; 00521 i_lag --; 00522 j_lag --; 00523 if(i_lag < 0)i_lag = 23; 00524 if(j_lag < 0) j_lag = 23; 00525 } 00526 } 00527 } 00528 } 00529 00530 RanluxEngine::operator unsigned int() { 00531 return ((unsigned int)(flat() * exponent_bit_32) & 0xffffffff) | 00532 (((unsigned int)(float_seed_table[i_lag]*exponent_bit_32)>>16) & 0xff); 00533 // needed because Ranlux doesn't fill all bits of the double 00534 // which therefore doesn't fill all bits of the integer. 00535 } 00536 00537 std::ostream & RanluxEngine::put ( std::ostream& os ) const 00538 { 00539 char beginMarker[] = "RanluxEngine-begin"; 00540 os << beginMarker << "\nUvec\n"; 00541 std::vector<unsigned long> v = put(); 00542 for (unsigned int i=0; i<v.size(); ++i) { 00543 os << v[i] << "\n"; 00544 } 00545 return os; 00546 #ifdef REMOVED 00547 char endMarker[] = "RanluxEngine-end"; 00548 int pr = os.precision(20); 00549 os << " " << beginMarker << " "; 00550 os << theSeed << "\n"; 00551 for (int i=0; i<24; ++i) { 00552 os << float_seed_table[i] << "\n"; 00553 } 00554 os << i_lag << " " << j_lag << "\n"; 00555 os << carry << " " << count24 << " "; 00556 os << luxury << " " << nskip << "\n"; 00557 os << endMarker << "\n"; 00558 os.precision(pr); 00559 return os; 00560 #endif 00561 } 00562 00563 std::vector<unsigned long> RanluxEngine::put () const { 00564 std::vector<unsigned long> v; 00565 v.push_back (engineIDulong<RanluxEngine>()); 00566 #ifdef TRACE_IO 00567 std::cout << "RanluxEngine put: ID is " << v[0] << "\n"; 00568 #endif 00569 for (int i=0; i<24; ++i) { 00570 v.push_back 00571 (static_cast<unsigned long>(float_seed_table[i]/mantissa_bit_24)); 00572 #ifdef TRACE_IO 00573 std::cout << "v[" << i+1 << "] = " << v[i+1] << 00574 " float_seed_table[" << i << "] = " << float_seed_table[i] << "\n"; 00575 #endif 00576 } 00577 v.push_back(static_cast<unsigned long>(i_lag)); 00578 v.push_back(static_cast<unsigned long>(j_lag)); 00579 v.push_back(static_cast<unsigned long>(carry/mantissa_bit_24)); 00580 v.push_back(static_cast<unsigned long>(count24)); 00581 v.push_back(static_cast<unsigned long>(luxury)); 00582 v.push_back(static_cast<unsigned long>(nskip)); 00583 #ifdef TRACE_IO 00584 std::cout << "i_lag: " << v[25] << " j_lag: " << v[26] 00585 << " carry: " << v[27] << "\n"; 00586 std::cout << "count24: " << v[28] << " luxury: " << v[29] 00587 << " nskip: " << v[30] << "\n"; 00588 #endif 00589 #ifdef TRACE_IO 00590 flat_trace = true; 00591 #endif 00592 return v; 00593 } 00594 00595 std::istream & RanluxEngine::get ( std::istream& is ) 00596 { 00597 char beginMarker [MarkerLen]; 00598 is >> std::ws; 00599 is.width(MarkerLen); // causes the next read to the char* to be <= 00600 // that many bytes, INCLUDING A TERMINATION \0 00601 // (Stroustrup, section 21.3.2) 00602 is >> beginMarker; 00603 if (strcmp(beginMarker,"RanluxEngine-begin")) { 00604 is.clear(std::ios::badbit | is.rdstate()); 00605 std::cerr << "\nInput stream mispositioned or" 00606 << "\nRanluxEngine state description missing or" 00607 << "\nwrong engine type found." << std::endl; 00608 return is; 00609 } 00610 return getState(is); 00611 } 00612 00613 std::string RanluxEngine::beginTag ( ) { 00614 return "RanluxEngine-begin"; 00615 } 00616 00617 std::istream & RanluxEngine::getState ( std::istream& is ) 00618 { 00619 if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) { 00620 std::vector<unsigned long> v; 00621 unsigned long uu; 00622 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) { 00623 is >> uu; 00624 if (!is) { 00625 is.clear(std::ios::badbit | is.rdstate()); 00626 std::cerr << "\nRanluxEngine state (vector) description improper." 00627 << "\ngetState() has failed." 00628 << "\nInput stream is probably mispositioned now." << std::endl; 00629 return is; 00630 } 00631 v.push_back(uu); 00632 #ifdef TRACE_IO 00633 std::cout << "RanluxEngine::getState -- v[" << v.size()-1 00634 << "] = " << v[v.size()-1] << "\n"; 00635 #endif 00636 } 00637 getState(v); 00638 return (is); 00639 } 00640 00641 // is >> theSeed; Removed, encompassed by possibleKeywordInput() 00642 00643 char endMarker [MarkerLen]; 00644 for (int i=0; i<24; ++i) { 00645 is >> float_seed_table[i]; 00646 } 00647 is >> i_lag; is >> j_lag; 00648 is >> carry; is >> count24; 00649 is >> luxury; is >> nskip; 00650 is >> std::ws; 00651 is.width(MarkerLen); 00652 is >> endMarker; 00653 if (strcmp(endMarker,"RanluxEngine-end")) { 00654 is.clear(std::ios::badbit | is.rdstate()); 00655 std::cerr << "\nRanluxEngine state description incomplete." 00656 << "\nInput stream is probably mispositioned now." << std::endl; 00657 return is; 00658 } 00659 return is; 00660 } 00661 00662 bool RanluxEngine::get (const std::vector<unsigned long> & v) { 00663 if ((v[0] & 0xffffffffUL) != engineIDulong<RanluxEngine>()) { 00664 std::cerr << 00665 "\nRanluxEngine get:state vector has wrong ID word - state unchanged\n"; 00666 return false; 00667 } 00668 return getState(v); 00669 } 00670 00671 bool RanluxEngine::getState (const std::vector<unsigned long> & v) { 00672 if (v.size() != VECTOR_STATE_SIZE ) { 00673 std::cerr << 00674 "\nRanluxEngine get:state vector has wrong length - state unchanged\n"; 00675 return false; 00676 } 00677 for (int i=0; i<24; ++i) { 00678 float_seed_table[i] = v[i+1]*mantissa_bit_24; 00679 #ifdef TRACE_IO 00680 std::cout << 00681 "float_seed_table[" << i << "] = " << float_seed_table[i] << "\n"; 00682 #endif 00683 } 00684 i_lag = v[25]; 00685 j_lag = v[26]; 00686 carry = v[27]*mantissa_bit_24; 00687 count24 = v[28]; 00688 luxury = v[29]; 00689 nskip = v[30]; 00690 #ifdef TRACE_IO 00691 std::cout << "i_lag: " << i_lag << " j_lag: " << j_lag 00692 << " carry: " << carry << "\n"; 00693 std::cout << "count24: " << count24 << " luxury: " << luxury 00694 << " nskip: " << nskip << "\n"; 00695 00696 #endif 00697 #ifdef TRACE_IO 00698 flat_trace = true; 00699 #endif 00700 return true; 00701 } 00702 00703 } // namespace CLHEP