RandFlat.cc

Go to the documentation of this file.
00001 // $Id:$
00002 // -*- C++ -*-
00003 //
00004 // -----------------------------------------------------------------------
00005 //                             HEP Random
00006 //                          --- RandFlat ---
00007 //                      class implementation file
00008 // -----------------------------------------------------------------------
00009 // This file is part of Geant4 (simulation toolkit for HEP).
00010 
00011 // =======================================================================
00012 // Gabriele Cosmo - Created: 17th May 1995
00013 //                - Added methods to shoot arrays: 28th July 1997
00014 //                - Added operator(): 24th Jul 1997
00015 // J.Marraffino   - Added default arguments as attributes and
00016 //                  operator() with arguments: 16th Feb 1998
00017 // M Fischler     - Copy constructor should supply right engine to HepRandom:
00018 //                  1/26/00.
00019 // M Fischler     - Semi-fix to the saveEngineStatus misbehavior causing
00020 //                  non-reproducing shootBit() 3/1/00.
00021 // M Fischler     - Avoiding hang when file not found in restoreEngineStatus 
00022 //                  12/3/04
00023 // M Fischler     - put and get to/from streams 12/10/04
00024 // M Fischler     - save and restore dist to streams 12/20/04
00025 // M Fischler         - put/get to/from streams uses pairs of ulongs when
00026 //                      + storing doubles avoid problems with precision 
00027 //                      4/14/05
00028 // =======================================================================
00029 
00030 #include "CLHEP/Random/RandFlat.h"
00031 #include "CLHEP/Random/DoubConv.h"
00032 #include <string.h>     // for strcmp
00033 
00034 namespace CLHEP {
00035 
00036 const int RandFlat::MSBBits= 15;
00037 const unsigned long RandFlat::MSB= 1ul<<RandFlat::MSBBits;
00038 unsigned long RandFlat::staticRandomInt= 0;
00039 unsigned long RandFlat::staticFirstUnusedBit= 0;
00040 
00041 std::string RandFlat::name() const {return "RandFlat";}
00042 HepRandomEngine & RandFlat::engine() {return *localEngine;}
00043 
00044 RandFlat::~RandFlat() {
00045 }
00046 
00047 double RandFlat::operator()() {
00048   return fire( defaultA, defaultB );
00049 }
00050 
00051 double RandFlat::operator()( double w ) {
00052   return fire( w );
00053 }
00054 
00055 double RandFlat::operator()( double a, double b ) {
00056   return fire( a, b );
00057 }
00058 
00059 double RandFlat::shoot() {
00060   return HepRandom::getTheEngine()->flat();
00061 }
00062 
00063 void RandFlat::shootArray(const int size, double* vect) {
00064   HepRandom::getTheEngine()->flatArray(size,vect);
00065 }
00066 
00067 void RandFlat::shootArray( const int size, double* vect,
00068                            double lx, double dx  )
00069 {
00070    int i;
00071 
00072    for (i=0; i<size; ++i)
00073      vect[i] = shoot(lx,dx);
00074 }
00075 
00076 void RandFlat::shootArray( HepRandomEngine* anEngine,
00077                            const int size, double* vect,
00078                            double lx, double dx  )
00079 {
00080    int i;
00081 
00082    for (i=0; i<size; ++i)
00083      vect[i] = shoot(anEngine,lx,dx);
00084 }
00085 
00086 void RandFlat::fireArray( const int size, double* vect)
00087 {
00088    int i;
00089 
00090    for (i=0; i<size; ++i)
00091      vect[i] = fire( defaultA, defaultB );
00092 }
00093 
00094 void RandFlat::fireArray( const int size, double* vect,
00095                           double lx, double dx  )
00096 {
00097    int i;
00098 
00099    for (i=0; i<size; ++i)
00100      vect[i] = fire( lx, dx );
00101 }
00102 
00103 void RandFlat::saveEngineStatus ( const char filename[] ) {
00104 
00105   // First save the engine status just like the base class would do:
00106   getTheEngine()->saveStatus( filename );
00107 
00108   // Now append the cached random Int, and first unused bit:
00109 
00110   std::ofstream outfile ( filename, std::ios::app );
00111 
00112   outfile << "RANDFLAT staticRandomInt: " << staticRandomInt 
00113           << "    staticFirstUnusedBit: " << staticFirstUnusedBit << "\n";
00114 
00115 } // saveEngineStatus
00116 
00117 
00118 void RandFlat::restoreEngineStatus( const char filename[] ) {
00119 
00120   // First restore the engine status just like the base class would do:
00121   getTheEngine()->restoreStatus( filename );
00122 
00123   // Now find the line describing the cached data:
00124 
00125   std::ifstream infile ( filename, std::ios::in );
00126   if (!infile) return;
00127   char inputword[] = "NO_KEYWORD    "; // leaves room for 14 characters plus \0
00128   while (true) {
00129     infile.width(13);
00130     infile >> inputword;
00131     if (strcmp(inputword,"RANDFLAT")==0) break;
00132     if (infile.eof()) break;
00133         // If the file ends without the RANDFLAT line, that means this
00134         // was a file produced by an earlier version of RandFlat.  We will
00135         // replicate the old behavior in that case:  staticFirstUnusedBit 
00136         // and staticRandomInt retain their existing values.
00137   }
00138 
00139   // Then read and use the caching info:
00140 
00141   if (strcmp(inputword,"RANDFLAT")==0) {
00142     char setword[40];   // the longest, staticFirstUnusedBit: has length 21
00143     infile.width(39);
00144     infile >> setword;
00145     // setword should be staticRandomInt:  
00146     infile >> staticRandomInt;
00147     infile.width(39);
00148     infile >> setword;
00149     // setword should be staticFirstUnusedBit: 
00150     infile >> staticFirstUnusedBit;
00151   }
00152 
00153 } // restoreEngineStatus
00154 
00155 std::ostream & RandFlat::put ( std::ostream & os ) const {
00156   int pr=os.precision(20);
00157   std::vector<unsigned long> t(2);
00158   os << " " << name() << "\n";
00159   os << "Uvec" << "\n";
00160   os << randomInt << " " << firstUnusedBit << "\n";
00161   t = DoubConv::dto2longs(defaultWidth);
00162   os << defaultWidth << " " << t[0] << " " << t[1] << "\n";
00163   t = DoubConv::dto2longs(defaultA);
00164   os << defaultA << " " << t[0] << " " << t[1] << "\n";
00165   t = DoubConv::dto2longs(defaultB);
00166   os << defaultB << " " << t[0] << " " << t[1] << "\n";
00167   os.precision(pr);
00168   return os;
00169 }
00170 
00171 std::istream & RandFlat::get ( std::istream & is ) {
00172   std::string inName;
00173   is >> inName;
00174   if (inName != name()) {
00175     is.clear(std::ios::badbit | is.rdstate());
00176     std::cerr << "Mismatch when expecting to read state of a "
00177               << name() << " distribution\n"
00178               << "Name found was " << inName
00179               << "\nistream is left in the badbit state\n";
00180     return is;
00181   }
00182   if (possibleKeywordInput(is, "Uvec", randomInt)) {
00183     std::vector<unsigned long> t(2);
00184     is >> randomInt >> firstUnusedBit;
00185     is >> defaultWidth >>t[0]>>t[1]; defaultWidth = DoubConv::longs2double(t); 
00186     is >> defaultA >> t[0] >> t[1]; defaultA = DoubConv::longs2double(t); 
00187     is >> defaultB >> t[0] >> t[1]; defaultB = DoubConv::longs2double(t); 
00188     if (!is) {
00189       is.clear(std::ios::badbit | is.rdstate());
00190       std::cerr << "\nRandFlat input failed"
00191              << "\nInput stream is probably mispositioned now." << std::endl;
00192       return is;
00193     }
00194     return is;
00195   }
00196   // is >> randomInt encompassed by possibleKeywordInput
00197   is >> firstUnusedBit;
00198   is >> defaultWidth >> defaultA >> defaultB;
00199   return is;
00200 }
00201 
00202 std::ostream & RandFlat::saveDistState ( std::ostream & os ) {
00203   os << distributionName() << "\n";
00204   int prec = os.precision(20);
00205   os << "RANDFLAT staticRandomInt: " << staticRandomInt 
00206      << "    staticFirstUnusedBit: " << staticFirstUnusedBit << "\n";
00207   os.precision(prec);
00208   return os;
00209 }    
00210 
00211 std::istream & RandFlat::restoreDistState ( std::istream & is ) {
00212   std::string inName;
00213   is >> inName;
00214   if (inName != distributionName()) {
00215     is.clear(std::ios::badbit | is.rdstate());
00216     std::cerr << "Mismatch when expecting to read static state of a "
00217               << distributionName() << " distribution\n"
00218               << "Name found was " << inName
00219               << "\nistream is left in the badbit state\n";
00220     return is;
00221   }
00222   std::string keyword;
00223   std::string c1;
00224   std::string c2;
00225   is >> keyword;
00226   if (keyword!="RANDFLAT") {
00227     is.clear(std::ios::badbit | is.rdstate());
00228     std::cerr << "Mismatch when expecting to read RANDFLAT bit cache info: "
00229               << keyword << "\n";
00230     return is;
00231   }
00232   is >> c1 >> staticRandomInt >> c2 >> staticFirstUnusedBit;
00233   return is;
00234 } 
00235 
00236 std::ostream & RandFlat::saveFullState ( std::ostream & os ) {
00237   HepRandom::saveFullState(os);
00238   saveDistState(os);
00239   return os;
00240 }
00241   
00242 std::istream & RandFlat::restoreFullState ( std::istream & is ) {
00243   HepRandom::restoreFullState(is);
00244   restoreDistState(is);
00245   return is;
00246 }
00247 
00248 
00249 }  // namespace CLHEP
00250 

Generated on Mon May 27 17:50:33 2013 for Geant4 by  doxygen 1.4.7