CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // $Id: RandFlat.cc,v 1.6 2010/06/16 17:24:53 garren Exp $ 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/defs.h" 00031 #include "CLHEP/Random/RandFlat.h" 00032 #include "CLHEP/Random/DoubConv.hh" 00033 #include <string.h> // for strcmp 00034 00035 namespace CLHEP { 00036 00037 const int RandFlat::MSBBits= 15; 00038 const unsigned long RandFlat::MSB= 1ul<<RandFlat::MSBBits; 00039 unsigned long RandFlat::staticRandomInt= 0; 00040 unsigned long RandFlat::staticFirstUnusedBit= 0; 00041 00042 std::string RandFlat::name() const {return "RandFlat";} 00043 HepRandomEngine & RandFlat::engine() {return *localEngine;} 00044 00045 RandFlat::~RandFlat() { 00046 } 00047 00048 double RandFlat::operator()() { 00049 return fire( defaultA, defaultB ); 00050 } 00051 00052 double RandFlat::operator()( double w ) { 00053 return fire( w ); 00054 } 00055 00056 double RandFlat::operator()( double a, double b ) { 00057 return fire( a, b ); 00058 } 00059 00060 double RandFlat::shoot() { 00061 return HepRandom::getTheEngine()->flat(); 00062 } 00063 00064 void RandFlat::shootArray(const int size, double* vect) { 00065 HepRandom::getTheEngine()->flatArray(size,vect); 00066 } 00067 00068 void RandFlat::shootArray( const int size, double* vect, 00069 double lx, double dx ) 00070 { 00071 int i; 00072 00073 for (i=0; i<size; ++i) 00074 vect[i] = shoot(lx,dx); 00075 } 00076 00077 void RandFlat::shootArray( HepRandomEngine* anEngine, 00078 const int size, double* vect, 00079 double lx, double dx ) 00080 { 00081 int i; 00082 00083 for (i=0; i<size; ++i) 00084 vect[i] = shoot(anEngine,lx,dx); 00085 } 00086 00087 void RandFlat::fireArray( const int size, double* vect) 00088 { 00089 int i; 00090 00091 for (i=0; i<size; ++i) 00092 vect[i] = fire( defaultA, defaultB ); 00093 } 00094 00095 void RandFlat::fireArray( const int size, double* vect, 00096 double lx, double dx ) 00097 { 00098 int i; 00099 00100 for (i=0; i<size; ++i) 00101 vect[i] = fire( lx, dx ); 00102 } 00103 00104 void RandFlat::saveEngineStatus ( const char filename[] ) { 00105 00106 // First save the engine status just like the base class would do: 00107 getTheEngine()->saveStatus( filename ); 00108 00109 // Now append the cached random Int, and first unused bit: 00110 00111 std::ofstream outfile ( filename, std::ios::app ); 00112 00113 outfile << "RANDFLAT staticRandomInt: " << staticRandomInt 00114 << " staticFirstUnusedBit: " << staticFirstUnusedBit << "\n"; 00115 00116 } // saveEngineStatus 00117 00118 00119 void RandFlat::restoreEngineStatus( const char filename[] ) { 00120 00121 // First restore the engine status just like the base class would do: 00122 getTheEngine()->restoreStatus( filename ); 00123 00124 // Now find the line describing the cached data: 00125 00126 std::ifstream infile ( filename, std::ios::in ); 00127 if (!infile) return; 00128 char inputword[] = "NO_KEYWORD "; // leaves room for 14 characters plus \0 00129 while (true) { 00130 infile.width(13); 00131 infile >> inputword; 00132 if (strcmp(inputword,"RANDFLAT")==0) break; 00133 if (infile.eof()) break; 00134 // If the file ends without the RANDFLAT line, that means this 00135 // was a file produced by an earlier version of RandFlat. We will 00136 // replicate the old behavior in that case: staticFirstUnusedBit 00137 // and staticRandomInt retain their existing values. 00138 } 00139 00140 // Then read and use the caching info: 00141 00142 if (strcmp(inputword,"RANDFLAT")==0) { 00143 char setword[40]; // the longest, staticFirstUnusedBit: has length 21 00144 infile.width(39); 00145 infile >> setword; 00146 // setword should be staticRandomInt: 00147 infile >> staticRandomInt; 00148 infile.width(39); 00149 infile >> setword; 00150 // setword should be staticFirstUnusedBit: 00151 infile >> staticFirstUnusedBit; 00152 } 00153 00154 } // restoreEngineStatus 00155 00156 std::ostream & RandFlat::put ( std::ostream & os ) const { 00157 int pr=os.precision(20); 00158 std::vector<unsigned long> t(2); 00159 os << " " << name() << "\n"; 00160 os << "Uvec" << "\n"; 00161 os << randomInt << " " << firstUnusedBit << "\n"; 00162 t = DoubConv::dto2longs(defaultWidth); 00163 os << defaultWidth << " " << t[0] << " " << t[1] << "\n"; 00164 t = DoubConv::dto2longs(defaultA); 00165 os << defaultA << " " << t[0] << " " << t[1] << "\n"; 00166 t = DoubConv::dto2longs(defaultB); 00167 os << defaultB << " " << t[0] << " " << t[1] << "\n"; 00168 #ifdef TRACE_IO 00169 std::cout << "RandFlat::put(): randomInt = " << randomInt 00170 << " firstUnusedBit = " << firstUnusedBit 00171 << "\ndefaultWidth = " << defaultWidth 00172 << " defaultA = " << defaultA 00173 << " defaultB = " << defaultB << "\n"; 00174 #endif 00175 os.precision(pr); 00176 return os; 00177 #ifdef REMOVED 00178 int pr=os.precision(20); 00179 os << " " << name() << "\n"; 00180 os << randomInt << " " << firstUnusedBit << "\n"; 00181 os << defaultWidth << " " << defaultA << " " << defaultB << "\n"; 00182 os.precision(pr); 00183 return os; 00184 #endif 00185 } 00186 00187 std::istream & RandFlat::get ( std::istream & is ) { 00188 std::string inName; 00189 is >> inName; 00190 if (inName != name()) { 00191 is.clear(std::ios::badbit | is.rdstate()); 00192 std::cerr << "Mismatch when expecting to read state of a " 00193 << name() << " distribution\n" 00194 << "Name found was " << inName 00195 << "\nistream is left in the badbit state\n"; 00196 return is; 00197 } 00198 if (possibleKeywordInput(is, "Uvec", randomInt)) { 00199 std::vector<unsigned long> t(2); 00200 is >> randomInt >> firstUnusedBit; 00201 is >> defaultWidth >>t[0]>>t[1]; defaultWidth = DoubConv::longs2double(t); 00202 is >> defaultA >> t[0] >> t[1]; defaultA = DoubConv::longs2double(t); 00203 is >> defaultB >> t[0] >> t[1]; defaultB = DoubConv::longs2double(t); 00204 #ifdef TRACE_IO 00205 std::cout << "RandFlat::get(): randomInt = " << randomInt 00206 << " firstUnusedBit = " << firstUnusedBit 00207 << "\ndefaultWidth = " << defaultWidth 00208 << " defaultA = " << defaultA 00209 << " defaultB = " << defaultB << "\n"; 00210 #endif 00211 if (!is) { 00212 is.clear(std::ios::badbit | is.rdstate()); 00213 std::cerr << "\nRandFlat input failed" 00214 << "\nInput stream is probably mispositioned now." << std::endl; 00215 return is; 00216 } 00217 return is; 00218 } 00219 // is >> randomInt encompassed by possibleKeywordInput 00220 is >> firstUnusedBit; 00221 is >> defaultWidth >> defaultA >> defaultB; 00222 return is; 00223 } 00224 00225 std::ostream & RandFlat::saveDistState ( std::ostream & os ) { 00226 os << distributionName() << "\n"; 00227 int prec = os.precision(20); 00228 os << "RANDFLAT staticRandomInt: " << staticRandomInt 00229 << " staticFirstUnusedBit: " << staticFirstUnusedBit << "\n"; 00230 os.precision(prec); 00231 return os; 00232 } 00233 00234 std::istream & RandFlat::restoreDistState ( std::istream & is ) { 00235 std::string inName; 00236 is >> inName; 00237 if (inName != distributionName()) { 00238 is.clear(std::ios::badbit | is.rdstate()); 00239 std::cerr << "Mismatch when expecting to read static state of a " 00240 << distributionName() << " distribution\n" 00241 << "Name found was " << inName 00242 << "\nistream is left in the badbit state\n"; 00243 return is; 00244 } 00245 std::string keyword; 00246 std::string c1; 00247 std::string c2; 00248 is >> keyword; 00249 if (keyword!="RANDFLAT") { 00250 is.clear(std::ios::badbit | is.rdstate()); 00251 std::cerr << "Mismatch when expecting to read RANDFLAT bit cache info: " 00252 << keyword << "\n"; 00253 return is; 00254 } 00255 is >> c1 >> staticRandomInt >> c2 >> staticFirstUnusedBit; 00256 return is; 00257 } 00258 00259 std::ostream & RandFlat::saveFullState ( std::ostream & os ) { 00260 HepRandom::saveFullState(os); 00261 saveDistState(os); 00262 return os; 00263 } 00264 00265 std::istream & RandFlat::restoreFullState ( std::istream & is ) { 00266 HepRandom::restoreFullState(is); 00267 restoreDistState(is); 00268 return is; 00269 } 00270 00271 00272 } // namespace CLHEP 00273