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