Geant4 Cross Reference |
1 // -*- C++ -*- 1 2 // 3 // ------------------------------------------- 4 // HEP Random 5 // --- RanshiEngine --- 6 // class implementation fil 7 // ------------------------------------------- 8 // 9 // This algorithm implements the random number 10 // "F. Gutbrod, Comp. Phys. Comm. 87 (1995) 29 11 // 12 // =========================================== 13 // Ken Smith - Created: 14 // - Removed std::pow() from fl 15 // - Added conversion operators 16 // J. Marraffino - Added some explicit casts 17 // machines where sizeof(int) 18 // M. Fischler - Modified constructors taki 19 // depend on numEngines (same 20 // produce same sequences). 21 // depends on numEngines. 22 // - Modified use of the variou 23 // to avoid per-instance spac 24 // correct the rounding proce 25 // J. Marraffino - Remove dependence on hepSt 26 // M. Fischler - In restore, checkFile for 27 // M. Fischler - Methods for instance save/ 28 // M. Fischler - split get() into tag valid 29 // getState() for anonymous r 30 // M. Fischler - State-saving using only in 31 // L. Garren - use explicit 32bit mask to 32 // L. Garren - adding pragma for 32bit gc 33 // 34 // =========================================== 35 36 #include "CLHEP/Random/RanshiEngine.h" 37 #include "CLHEP/Random/engineIDulong.h" 38 #include "CLHEP/Utility/atomic_int.h" 39 40 #include <atomic> 41 #include <string.h> // for strcmp 42 #include <iostream> 43 #include <string> 44 #include <vector> 45 46 // don't generate warnings about agressive loo 47 #if defined __GNUC__ 48 #if __GNUC__ > 3 && __GNUC_MINOR__ > 8 49 #pragma GCC diagnostic push 50 #pragma GCC diagnostic ignored "-Waggressi 51 #endif 52 #endif 53 54 namespace CLHEP { 55 56 namespace { 57 // Number of instances with automatic seed s 58 CLHEP_ATOMIC_INT_TYPE numberOfEngines(0); 59 } 60 61 static const int MarkerLen = 64; // Enough roo 62 63 std::string RanshiEngine::name() const {return 64 65 RanshiEngine::RanshiEngine() 66 : HepRandomEngine(), 67 halfBuff(0), numFlats(0) 68 { 69 int numEngines = numberOfEngines++; 70 int i = 0; 71 while (i < numBuff) { 72 buffer[i] = (unsigned int)((numEngines+197 73 ++i; 74 } 75 theSeed = numEngines+19780503L*++i; 76 redSpin = (unsigned int)(theSeed & 0xfffffff 77 78 for( i = 0; i < 10000; ++i) flat(); // Warm 79 } 80 81 RanshiEngine::RanshiEngine(std::istream& is) 82 : HepRandomEngine(), 83 halfBuff(0), numFlats(0) 84 { 85 is >> *this; 86 } 87 88 RanshiEngine::RanshiEngine(long seed) 89 : HepRandomEngine(), 90 halfBuff(0), numFlats(0) 91 { 92 for (int i = 0; i < numBuff; ++i) { 93 buffer[i] = (unsigned int)seed&0xffffffff; 94 } 95 theSeed = seed; 96 redSpin = (unsigned int)(theSeed & 0xfffffff 97 int j; 98 for (j = 0; j < numBuff*20; ++j) { // " 99 flat(); // 100 } 101 } 102 103 RanshiEngine::RanshiEngine(int rowIndex, int c 104 : HepRandomEngine(), 105 halfBuff(0), numFlats(0) 106 { 107 int i = 0; 108 while( i < numBuff ) { 109 buffer[i] = (unsigned int)((rowIndex + (i+ 110 ++i; 111 } 112 theSeed = rowIndex; 113 redSpin = colIndex & 0xffffffff; 114 for( i = 0; i < 100; ++i) flat(); // Warm 115 } 116 117 RanshiEngine::~RanshiEngine() { } 118 119 double RanshiEngine::flat() { 120 unsigned int redAngle = (((numBuff/2) - 1) & 121 unsigned int blkSpin = buffer[redAngle] 122 unsigned int boostResult = blkSpin ^ redSpin 123 124 buffer[redAngle] = ((blkSpin << 17) | (blkSp 125 126 redSpin = (blkSpin + numFlats++) & 0xffffff 127 halfBuff = numBuff/2 - halfBuff; 128 129 return ( blkSpin * twoToMinus_32() + 130 (boostResult>>11) * twoToMinus_53() + // 131 nearlyTwoToMinus_54()); // non-zero 132 } 133 134 void RanshiEngine::flatArray(const int size, d 135 for (int i = 0; i < size; ++i) { 136 vect[i] = flat(); 137 } 138 } 139 140 void RanshiEngine::setSeed(long seed, int) { 141 *this = RanshiEngine(seed); 142 } 143 144 void RanshiEngine::setSeeds(const long* seeds, 145 if (*seeds) { 146 int i = 0; 147 while (seeds[i] && i < numBuff) { 148 buffer[i] = (unsigned int)seeds[i]; 149 ++i; 150 } 151 while (i < numBuff) { 152 buffer[i] = buffer[i-1]; 153 ++i; 154 } 155 theSeed = seeds[0]; 156 redSpin = (unsigned int)theSeed; 157 } 158 theSeeds = seeds; 159 } 160 161 void RanshiEngine::saveStatus(const char filen 162 std::ofstream outFile(filename, std::ios::ou 163 if (!outFile.bad()) { 164 outFile << "Uvec\n"; 165 std::vector<unsigned long> v = put(); 166 for (unsigned int i=0; i<v.size(); ++i) { 167 outFile << v[i] << "\n"; 168 } 169 } 170 } 171 172 void RanshiEngine::restoreStatus(const char fi 173 std::ifstream inFile(filename, std::ios::in) 174 if (!checkFile ( inFile, filename, engineNam 175 std::cerr << " -- Engine state remains un 176 return; 177 } 178 if ( possibleKeywordInput ( inFile, "Uvec", 179 std::vector<unsigned long> v; 180 unsigned long xin; 181 for (unsigned int ivec=0; ivec < VECTOR_ST 182 inFile >> xin; 183 if (!inFile) { 184 inFile.clear(std::ios::badbit | inFile 185 std::cerr << "\nRanshiEngine state (ve 186 << "\nrestoreStatus has failed." 187 << "\nInput stream is probably mispos 188 return; 189 } 190 v.push_back(xin); 191 } 192 getState(v); 193 return; 194 } 195 196 if (!inFile.bad()) { 197 // inFile >> theSeed; removed -- encompas 198 for (int i = 0; i < numBuff; ++i) { 199 inFile >> buffer[i]; 200 } 201 inFile >> redSpin >> numFlats >> halfBuff; 202 } 203 } 204 205 void RanshiEngine::showStatus() const { 206 std::cout << std::setprecision(20) << std::e 207 std::cout << "----------- Ranshi engine stat 208 std::cout << "Initial seed = " << theSe 209 std::cout << "Current red spin = " << redSp 210 std::cout << "Values produced = " << numFl 211 std::cout << "Side of buffer = " << (half 212 << std::endl; 213 std::cout << "Current buffer = " << std:: 214 for (int i = 0; i < numBuff; i+=4) { 215 std::cout << std::setw(10) << std::setiosf 216 << buffer[i] << std::setw(11) << b 217 << buffer[i+2] << std::setw(11) << b 218 } 219 std::cout << "------------------------------ 220 } 221 222 RanshiEngine::operator double() { 223 return flat(); 224 } 225 226 RanshiEngine::operator float() { 227 unsigned int redAngle = (((numBuff/2) - 1) & 228 unsigned int blkSpin = buffer[redAngle] & 0 229 230 buffer[redAngle] = ((blkSpin << 17) | (blkSp 231 232 redSpin = (blkSpin + numFlats++) & 0xffffff 233 halfBuff = numBuff/2 - halfBuff; 234 235 return float(blkSpin * twoToMinus_32()); 236 } 237 238 RanshiEngine::operator unsigned int() { 239 unsigned int redAngle = (((numBuff/2) - 1) & 240 unsigned int blkSpin = buffer[redAngle] & 0 241 242 buffer[redAngle] = ((blkSpin << 17) | (blkSp 243 244 redSpin = (blkSpin + numFlats++) & 0xffffff 245 halfBuff = numBuff/2 - halfBuff; 246 247 return blkSpin; 248 } 249 250 std::ostream& RanshiEngine::put (std::ostream& 251 char beginMarker[] = "RanshiEngine-begin"; 252 os << beginMarker << "\nUvec\n"; 253 std::vector<unsigned long> v = put(); 254 for (unsigned int i=0; i<v.size(); ++i) { 255 os << v[i] << "\n"; 256 } 257 return os; 258 } 259 260 std::vector<unsigned long> RanshiEngine::put ( 261 std::vector<unsigned long> v; 262 v.push_back (engineIDulong<RanshiEngine>()); 263 for (int i = 0; i < numBuff; ++i) { 264 v.push_back(static_cast<unsigned long>(buf 265 } 266 v.push_back(static_cast<unsigned long>(redSp 267 v.push_back(static_cast<unsigned long>(numFl 268 v.push_back(static_cast<unsigned long>(halfB 269 return v; 270 } 271 272 std::istream& RanshiEngine::get (std::istream& 273 char beginMarker [MarkerLen]; 274 is >> std::ws; 275 is.width(MarkerLen); // causes the next rea 276 // that many bytes, INCLUDING A TERMINAT 277 // (Stroustrup, section 21.3.2) 278 is >> beginMarker; 279 if (strcmp(beginMarker,"RanshiEngine-begin") 280 is.clear(std::ios::badbit | is.rdstate()); 281 std::cerr << "\nInput mispositioned or" 282 << "\nRanshiEngine state description m 283 << "\nwrong engine type found." << std 284 return is; 285 } 286 return getState(is); 287 } 288 289 std::string RanshiEngine::beginTag ( ) { 290 return "RanshiEngine-begin"; 291 } 292 293 std::istream& RanshiEngine::getState (std::ist 294 if ( possibleKeywordInput ( is, "Uvec", theS 295 std::vector<unsigned long> v; 296 unsigned long uu; 297 for (unsigned int ivec=0; ivec < VECTOR_ST 298 is >> uu; 299 if (!is) { 300 is.clear(std::ios::badbit | is.rdstate 301 std::cerr << "\nRanshiEngine state (ve 302 << "\ngetState() has failed." 303 << "\nInput stream is probably mispos 304 return is; 305 } 306 v.push_back(uu); 307 } 308 getState(v); 309 return (is); 310 } 311 312 // is >> theSeed; Removed, encompassed by po 313 314 char endMarker [MarkerLen]; 315 for (int i = 0; i < numBuff; ++i) { 316 is >> buffer[i]; 317 } 318 is >> redSpin >> numFlats >> halfBuff; 319 is >> std::ws; 320 is.width(MarkerLen); 321 is >> endMarker; 322 if (strcmp(endMarker,"RanshiEngine-end")) { 323 is.clear(std::ios::badbit | is.rdstate()); 324 std::cerr << "\nRanshiEngine state descrip 325 << "\nInput stream is probably misposi 326 return is; 327 } 328 return is; 329 } 330 331 bool RanshiEngine::get (const std::vector<unsi 332 if ((v[0] & 0xffffffffUL) != engineIDulong<R 333 std::cerr << 334 "\nRanshiEngine get:state vector has wro 335 return false; 336 } 337 return getState(v); 338 } 339 340 bool RanshiEngine::getState (const std::vector 341 if (v.size() != VECTOR_STATE_SIZE ) { 342 std::cerr << 343 "\nRanshiEngine get:state vector has wro 344 return false; 345 } 346 for (int i = 0; i < numBuff; ++i) { 347 buffer[i] = (unsigned int)v[i+1]; 348 } 349 redSpin = (unsigned int)v[numBuff+1]; 350 numFlats = (unsigned int)v[numBuff+2]; 351 halfBuff = (unsigned int)v[numBuff+3]; 352 return true; 353 } 354 355 } // namespace CLHEP 356 357 #if defined __GNUC__ 358 #if __GNUC__ > 3 && __GNUC_MINOR__ > 8 359 #pragma GCC diagnostic pop 360 #endif 361 #endif 362