CLHEP VERSION 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.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

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7