Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
RanshiEngine.cc
이 파일의 문서화 페이지로 가기
1 // $Id:$
2 // -*- C++ -*-
3 //
4 // -----------------------------------------------------------------------
5 // HEP Random
6 // --- RanshiEngine ---
7 // class implementation file
8 // -----------------------------------------------------------------------
9 //
10 // This algorithm implements the random number generator as proposed by
11 // "F. Gutbrod, Comp. Phys. Comm. 87 (1995) 291-306".
12 //
13 // =======================================================================
14 // Ken Smith - Created: 9th June 1998
15 // - Removed std::pow() from flat method: 21st Jul 1998
16 // - Added conversion operators: 6th Aug 1998
17 // J. Marraffino - Added some explicit casts to deal with
18 // machines where sizeof(int) != sizeof(long) 22 Aug 1998
19 // M. Fischler - Modified constructors taking seeds to not
20 // depend on numEngines (same seeds should
21 // produce same sequences). Default still
22 // depends on numEngines. 16 Sep 1998
23 // - Modified use of the various exponents of 2
24 // to avoid per-instance space overhead and
25 // correct the rounding procedure 16 Sep 1998
26 // J. Marraffino - Remove dependence on hepString class 13 May 1999
27 // M. Fischler - In restore, checkFile for file not found 03 Dec 2004
28 // M. Fischler - Methods for instance save/restore 12/8/04
29 // M. Fischler - split get() into tag validation and
30 // getState() for anonymous restores 12/27/04
31 // M. Fischler - State-saving using only ints, for portability 4/12/05
32 // L. Garren - use explicit 32bit mask to avoid compiler warnings 6/6/2014
33 // L. Garren - adding pragma for 32bit gcc 4.9 11/20/2014
34 //
35 // =======================================================================
36 
40 
41 #include <string.h> // for strcmp
42 #include <iostream>
43 
44 // don't generate warnings about agressive loop optimization
45 #if defined __GNUC__
46  #if __GNUC__ > 3 && __GNUC_MINOR__ > 8
47  #pragma GCC diagnostic push
48  #pragma GCC diagnostic ignored "-Waggressive-loop-optimizations"
49  #endif
50 #endif
51 
52 namespace CLHEP {
53 
54 namespace {
55  // Number of instances with automatic seed selection
56  CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
57 }
58 
59 static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
60 
61 std::string RanshiEngine::name() const {return "RanshiEngine";}
62 
64 : HepRandomEngine(),
65  halfBuff(0), numFlats(0)
66 {
67  int numEngines = numberOfEngines++;
68  int i = 0;
69  while (i < numBuff) {
70  buffer[i] = (unsigned int)((numEngines+19780503L*(i+1))& 0xffffffff);
71  ++i;
72  }
73  theSeed = numEngines+19780503L*++i;
74  redSpin = (unsigned int)(theSeed & 0xffffffff);
75 
76  for( i = 0; i < 10000; ++i) flat(); // Warm-up by running thorugh 10000 nums
77 }
78 
79 RanshiEngine::RanshiEngine(std::istream& is)
80 : HepRandomEngine(),
81  halfBuff(0), numFlats(0)
82 {
83  is >> *this;
84 }
85 
87 : HepRandomEngine(),
88  halfBuff(0), numFlats(0)
89 {
90  for (int i = 0; i < numBuff; ++i) {
91  buffer[i] = (unsigned int)seed&0xffffffff;
92  }
93  theSeed = seed;
94  redSpin = (unsigned int)(theSeed & 0xffffffff);
95  int j;
96  for (j = 0; j < numBuff*20; ++j) { // "warm-up" for engine to hit
97  flat(); // every ball on average 20X.
98  }
99 }
100 
101 RanshiEngine::RanshiEngine(int rowIndex, int colIndex)
102 : HepRandomEngine(),
103  halfBuff(0), numFlats(0)
104 {
105  int i = 0;
106  while( i < numBuff ) {
107  buffer[i] = (unsigned int)((rowIndex + (i+1)*(colIndex+8))&0xffffffff);
108  ++i;
109  }
110  theSeed = rowIndex;
111  redSpin = colIndex & 0xffffffff;
112  for( i = 0; i < 100; ++i) flat(); // Warm-up by running thorugh 100 nums
113 }
114 
116 
118  unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
119  unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
120  unsigned int boostResult = blkSpin ^ redSpin;
121 
122  buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
123 
124  redSpin = (blkSpin + numFlats++) & 0xffffffff;
125  halfBuff = numBuff/2 - halfBuff;
126 
127  return ( blkSpin * twoToMinus_32() + // most significant part
128  (boostResult>>11) * twoToMinus_53() + // fill in remaining bits
129  nearlyTwoToMinus_54()); // non-zero
130 }
131 
132 void RanshiEngine::flatArray(const int size, double* vect) {
133  for (int i = 0; i < size; ++i) {
134  vect[i] = flat();
135  }
136 }
137 
138 void RanshiEngine::setSeed(long seed, int) {
139  *this = RanshiEngine(seed);
140 }
141 
142 void RanshiEngine::setSeeds(const long* seeds, int) {
143  if (*seeds) {
144  int i = 0;
145  while (seeds[i] && i < numBuff) {
146  buffer[i] = (unsigned int)seeds[i];
147  ++i;
148  }
149  while (i < numBuff) {
150  buffer[i] = buffer[i-1];
151  ++i;
152  }
153  theSeed = seeds[0];
154  redSpin = (unsigned int)theSeed;
155  }
156  theSeeds = seeds;
157 }
158 
159 void RanshiEngine::saveStatus(const char filename[]) const {
160  std::ofstream outFile(filename, std::ios::out);
161  if (!outFile.bad()) {
162  outFile << "Uvec\n";
163  std::vector<unsigned long> v = put();
164  for (unsigned int i=0; i<v.size(); ++i) {
165  outFile << v[i] << "\n";
166  }
167  }
168 }
169 
170 void RanshiEngine::restoreStatus(const char filename[]) {
171  std::ifstream inFile(filename, std::ios::in);
172  if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
173  std::cerr << " -- Engine state remains unchanged\n";
174  return;
175  }
176  if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) {
177  std::vector<unsigned long> v;
178  unsigned long xin;
179  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
180  inFile >> xin;
181  if (!inFile) {
182  inFile.clear(std::ios::badbit | inFile.rdstate());
183  std::cerr << "\nRanshiEngine state (vector) description improper."
184  << "\nrestoreStatus has failed."
185  << "\nInput stream is probably mispositioned now." << std::endl;
186  return;
187  }
188  v.push_back(xin);
189  }
190  getState(v);
191  return;
192  }
193 
194  if (!inFile.bad()) {
195 // inFile >> theSeed; removed -- encompased by possibleKeywordInput
196  for (int i = 0; i < numBuff; ++i) {
197  inFile >> buffer[i];
198  }
199  inFile >> redSpin >> numFlats >> halfBuff;
200  }
201 }
202 
204  std::cout << std::setprecision(20) << std::endl;
205  std::cout << "----------- Ranshi engine status ----------" << std::endl;
206  std::cout << "Initial seed = " << theSeed << std::endl;
207  std::cout << "Current red spin = " << redSpin << std::endl;
208  std::cout << "Values produced = " << numFlats << std::endl;
209  std::cout << "Side of buffer = " << (halfBuff ? "upper" : "lower")
210  << std::endl;
211  std::cout << "Current buffer = " << std::endl;
212  for (int i = 0; i < numBuff; i+=4) {
213  std::cout << std::setw(10) << std::setiosflags(std::ios::right)
214  << buffer[i] << std::setw(11) << buffer[i+1] << std::setw(11)
215  << buffer[i+2] << std::setw(11) << buffer[i+3] << std::endl;
216  }
217  std::cout << "-------------------------------------------" << std::endl;
218 }
219 
220 RanshiEngine::operator double() {
221  return flat();
222 }
223 
224 RanshiEngine::operator float() {
225  unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
226  unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
227 
228  buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
229 
230  redSpin = (blkSpin + numFlats++) & 0xffffffff;
231  halfBuff = numBuff/2 - halfBuff;
232 
233  return float(blkSpin * twoToMinus_32());
234 }
235 
236 RanshiEngine::operator unsigned int() {
237  unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
238  unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
239 
240  buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
241 
242  redSpin = (blkSpin + numFlats++) & 0xffffffff;
243  halfBuff = numBuff/2 - halfBuff;
244 
245  return blkSpin;
246 }
247 
248 std::ostream& RanshiEngine::put (std::ostream& os ) const {
249  char beginMarker[] = "RanshiEngine-begin";
250  os << beginMarker << "\nUvec\n";
251  std::vector<unsigned long> v = put();
252  for (unsigned int i=0; i<v.size(); ++i) {
253  os << v[i] << "\n";
254  }
255  return os;
256 }
257 
258 std::vector<unsigned long> RanshiEngine::put () const {
259  std::vector<unsigned long> v;
260  v.push_back (engineIDulong<RanshiEngine>());
261  for (int i = 0; i < numBuff; ++i) {
262  v.push_back(static_cast<unsigned long>(buffer[i]));
263  }
264  v.push_back(static_cast<unsigned long>(redSpin));
265  v.push_back(static_cast<unsigned long>(numFlats));
266  v.push_back(static_cast<unsigned long>(halfBuff));
267  return v;
268 }
269 
270 std::istream& RanshiEngine::get (std::istream& is) {
271  char beginMarker [MarkerLen];
272  is >> std::ws;
273  is.width(MarkerLen); // causes the next read to the char* to be <=
274  // that many bytes, INCLUDING A TERMINATION \0
275  // (Stroustrup, section 21.3.2)
276  is >> beginMarker;
277  if (strcmp(beginMarker,"RanshiEngine-begin")) {
278  is.clear(std::ios::badbit | is.rdstate());
279  std::cerr << "\nInput mispositioned or"
280  << "\nRanshiEngine state description missing or"
281  << "\nwrong engine type found." << std::endl;
282  return is;
283  }
284  return getState(is);
285 }
286 
287 std::string RanshiEngine::beginTag ( ) {
288  return "RanshiEngine-begin";
289 }
290 
291 std::istream& RanshiEngine::getState (std::istream& is) {
292  if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) {
293  std::vector<unsigned long> v;
294  unsigned long uu;
295  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
296  is >> uu;
297  if (!is) {
298  is.clear(std::ios::badbit | is.rdstate());
299  std::cerr << "\nRanshiEngine state (vector) description improper."
300  << "\ngetState() has failed."
301  << "\nInput stream is probably mispositioned now." << std::endl;
302  return is;
303  }
304  v.push_back(uu);
305  }
306  getState(v);
307  return (is);
308  }
309 
310 // is >> theSeed; Removed, encompassed by possibleKeywordInput()
311 
312  char endMarker [MarkerLen];
313  for (int i = 0; i < numBuff; ++i) {
314  is >> buffer[i];
315  }
316  is >> redSpin >> numFlats >> halfBuff;
317  is >> std::ws;
318  is.width(MarkerLen);
319  is >> endMarker;
320  if (strcmp(endMarker,"RanshiEngine-end")) {
321  is.clear(std::ios::badbit | is.rdstate());
322  std::cerr << "\nRanshiEngine state description incomplete."
323  << "\nInput stream is probably mispositioned now." << std::endl;
324  return is;
325  }
326  return is;
327 }
328 
329 bool RanshiEngine::get (const std::vector<unsigned long> & v) {
330  if ((v[0] & 0xffffffffUL) != engineIDulong<RanshiEngine>()) {
331  std::cerr <<
332  "\nRanshiEngine get:state vector has wrong ID word - state unchanged\n";
333  return false;
334  }
335  return getState(v);
336 }
337 
338 bool RanshiEngine::getState (const std::vector<unsigned long> & v) {
339  if (v.size() != VECTOR_STATE_SIZE ) {
340  std::cerr <<
341  "\nRanshiEngine get:state vector has wrong length - state unchanged\n";
342  return false;
343  }
344  for (int i = 0; i < numBuff; ++i) {
345  buffer[i] = v[i+1];
346  }
347  redSpin = v[numBuff+1];
348  numFlats = v[numBuff+2];
349  halfBuff = v[numBuff+3];
350  return true;
351 }
352 
353 } // namespace CLHEP
354 
355 #if defined __GNUC__
356  #if __GNUC__ > 3 && __GNUC_MINOR__ > 8
357  #pragma GCC diagnostic pop
358  #endif
359 #endif
void setSeeds(const long *seeds, int)
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
Definition: RandomEngine.h:167
static const unsigned int VECTOR_STATE_SIZE
Definition: RanshiEngine.h:109
static std::string engineName()
Definition: RanshiEngine.h:96
virtual std::istream & get(std::istream &is)
static double nearlyTwoToMinus_54()
#define buffer
Definition: xmlparse.cc:628
void showStatus() const
static std::string beginTag()
void saveStatus(const char filename[]="RanshiEngine.conf") const
static double twoToMinus_32()
unsigned int halfBuff
Definition: RanshiEngine.h:105
static const int MarkerLen
Definition: DualRand.cc:67
unsigned int numFlats
Definition: RanshiEngine.h:105
static constexpr double L
long seed
Definition: chem4.cc:68
void setSeed(long seed, int)
#define CLHEP_ATOMIC_INT_TYPE
Definition: atomic_int.h:20
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
unsigned int redSpin
Definition: RanshiEngine.h:107
void flatArray(const int size, double *vect)
static double twoToMinus_53()
static bool checkFile(std::istream &file, const std::string &filename, const std::string &classname, const std::string &methodname)
Definition: RandomEngine.cc:45
ifstream in
Definition: comparison.C:7
virtual std::istream & getState(std::istream &is)
std::vector< unsigned long > put() const
std::string name() const
Definition: RanshiEngine.cc:61
void restoreStatus(const char filename[]="RanshiEngine.conf")
double flat()
Definition: G4AblaRandom.cc:48
unsigned int buffer[numBuff]
Definition: RanshiEngine.h:106