CLHEP 2.0.4.7 Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

RanluxEngine.cc

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

Generated on Thu Jul 1 22:02:30 2010 for CLHEP by  doxygen 1.4.7