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

DRand48Engine.cc

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

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