Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
RanecuEngine.cc
이 파일의 문서화 페이지로 가기
1 // $Id:$
2 // -*- C++ -*-
3 //
4 // -----------------------------------------------------------------------
5 // HEP Random
6 // --- RanecuEngine ---
7 // class implementation file
8 // -----------------------------------------------------------------------
9 // This file is part of Geant4 (simulation toolkit for HEP).
10 //
11 // RANECU Random Engine - algorithm originally written in FORTRAN77
12 // as part of the MATHLIB HEP library.
13 
14 // =======================================================================
15 // Gabriele Cosmo - Created - 2nd February 1996
16 // - Minor corrections: 31st October 1996
17 // - Added methods for engine status: 19th November 1996
18 // - Added abs for setting seed index: 11th July 1997
19 // - Modified setSeeds() to handle default index: 16th Oct 1997
20 // - setSeed() now resets the engine status to the original
21 // values in the static table of HepRandom: 19th Mar 1998
22 // J.Marraffino - Added stream operators and related constructor.
23 // Added automatic seed selection from seed table and
24 // engine counter: 16th Feb 1998
25 // Ken Smith - Added conversion operators: 6th Aug 1998
26 // J. Marraffino - Remove dependence on hepString class 13 May 1999
27 // M. Fischler - Add endl to the end of saveStatus 10 Apr 2001
28 // M. Fischler - In restore, checkFile for file not found 03 Dec 2004
29 // M. Fischler - Methods for distrib. instance save/restore 12/8/04
30 // M. Fischler - split get() into tag validation and
31 // getState() for anonymous restores 12/27/04
32 // M. Fischler - put/get for vectors of ulongs 3/14/05
33 // M. Fischler - State-saving using only ints, for portability 4/12/05
34 // M. Fischler - Modify ctor and setSeed to utilize all info provided
35 // and avoid coincidence of same state from different
36 // seeds 6/22/10
37 //
38 // =======================================================================
39 
40 #include "CLHEP/Random/Random.h"
44 
45 #include <string.h> // for strcmp
46 #include <cmath>
47 #include <cstdlib>
48 
49 namespace CLHEP {
50 
51 namespace {
52  // Number of instances with automatic seed selection
53  CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
54 }
55 
56 static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
57 
58 static const double prec = 4.6566128E-10;
59 
60 std::string RanecuEngine::name() const {return "RanecuEngine";}
61 
62 void RanecuEngine::further_randomize (int seq1, int col, int index, int modulus)
63 {
64  table[seq1][col] -= (index&0x3FFFFFFF);
65  while (table[seq1][col] <= 0) table[seq1][col] += (modulus-1);
66 } // mf 6/22/10
67 
70 {
71  int numEngines = numberOfEngines++;
72  int cycle = std::abs(int(numEngines/maxSeq));
73  seq = std::abs(int(numEngines%maxSeq));
74 
75  theSeed = seq;
76  long mask = ((cycle & 0x007fffff) << 8);
77  for (int i=0; i<2; ++i) {
78  for (int j=0; j<maxSeq; ++j) {
80  table[j][i] ^= mask;
81  }
82  }
83  theSeeds = &table[seq][0];
84 }
85 
88 {
89  int cycle = std::abs(int(index/maxSeq));
90  seq = std::abs(int(index%maxSeq));
91  theSeed = seq;
92  long mask = ((cycle & 0x000007ff) << 20);
93  for (int j=0; j<maxSeq; ++j) {
95  table[j][0] ^= mask;
96  table[j][1] ^= mask;
97  }
98  theSeeds = &table[seq][0];
99  further_randomize (seq, 0, index, shift1); // mf 6/22/10
100 }
101 
102 RanecuEngine::RanecuEngine(std::istream& is)
103 : HepRandomEngine()
104 {
105  is >> *this;
106 }
107 
109 
110 void RanecuEngine::setSeed(long index, int dum)
111 {
112  seq = std::abs(int(index%maxSeq));
113  theSeed = seq;
115  theSeeds = &table[seq][0];
116  further_randomize (seq, 0, index, shift1); // mf 6/22/10
117  further_randomize (seq, 1, dum, shift2); // mf 6/22/10
118 }
119 
120 void RanecuEngine::setSeeds(const long* seeds, int pos)
121 {
122  if (pos != -1) {
123  seq = std::abs(int(pos%maxSeq));
124  theSeed = seq;
125  }
126  // only positive seeds are allowed
127  table[seq][0] = std::abs(seeds[0])%shift1;
128  table[seq][1] = std::abs(seeds[1])%shift2;
129  theSeeds = &table[seq][0];
130 }
131 
132 void RanecuEngine::setIndex(long index)
133 {
134  seq = std::abs(int(index%maxSeq));
135  theSeed = seq;
136  theSeeds = &table[seq][0];
137 }
138 
139 void RanecuEngine::saveStatus( const char filename[] ) const
140 {
141  std::ofstream outFile( filename, std::ios::out ) ;
142 
143  if (!outFile.bad()) {
144  outFile << "Uvec\n";
145  std::vector<unsigned long> v = put();
146  for (unsigned int i=0; i<v.size(); ++i) {
147  outFile << v[i] << "\n";
148  }
149  }
150 }
151 
152 void RanecuEngine::restoreStatus( const char filename[] )
153 {
154  std::ifstream inFile( filename, std::ios::in);
155  if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
156  std::cerr << " -- Engine state remains unchanged\n";
157  return;
158  }
159  if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) {
160  std::vector<unsigned long> v;
161  unsigned long xin;
162  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
163  inFile >> xin;
164  if (!inFile) {
165  inFile.clear(std::ios::badbit | inFile.rdstate());
166  std::cerr << "\nJamesRandom state (vector) description improper."
167  << "\nrestoreStatus has failed."
168  << "\nInput stream is probably mispositioned now." << std::endl;
169  return;
170  }
171  v.push_back(xin);
172  }
173  getState(v);
174  return;
175  }
176 
177  if (!inFile.bad() && !inFile.eof()) {
178 // inFile >> theSeed; removed -- encompased by possibleKeywordInput
179  for (int i=0; i<2; ++i)
180  inFile >> table[theSeed][i];
181  seq = int(theSeed);
182  }
183 }
184 
186 {
187  std::cout << std::endl;
188  std::cout << "--------- Ranecu engine status ---------" << std::endl;
189  std::cout << " Initial seed (index) = " << theSeed << std::endl;
190  std::cout << " Current couple of seeds = "
191  << table[theSeed][0] << ", "
192  << table[theSeed][1] << std::endl;
193  std::cout << "----------------------------------------" << std::endl;
194 }
195 
197 {
198  const int index = seq;
199  long seed1 = table[index][0];
200  long seed2 = table[index][1];
201 
202  int k1 = (int)(seed1/ecuyer_b);
203  int k2 = (int)(seed2/ecuyer_e);
204 
205  seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
206  if (seed1 < 0) seed1 += shift1;
207  seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
208  if (seed2 < 0) seed2 += shift2;
209 
210  table[index][0] = seed1;
211  table[index][1] = seed2;
212 
213  long diff = seed1-seed2;
214 
215  if (diff <= 0) diff += (shift1-1);
216  return (double)(diff*prec);
217 }
218 
219 void RanecuEngine::flatArray(const int size, double* vect)
220 {
221  const int index = seq;
222  long seed1 = table[index][0];
223  long seed2 = table[index][1];
224  int k1, k2;
225  int i;
226 
227  for (i=0; i<size; ++i)
228  {
229  k1 = (int)(seed1/ecuyer_b);
230  k2 = (int)(seed2/ecuyer_e);
231 
232  seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
233  if (seed1 < 0) seed1 += shift1;
234  seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
235  if (seed2 < 0) seed2 += shift2;
236 
237  long diff = seed1-seed2;
238  if (diff <= 0) diff += (shift1-1);
239 
240  vect[i] = (double)(diff*prec);
241  }
242  table[index][0] = seed1;
243  table[index][1] = seed2;
244 }
245 
246 RanecuEngine::operator double() {
247  return flat();
248 }
249 
250 RanecuEngine::operator float() {
251  return float( flat() );
252 }
253 
254 RanecuEngine::operator unsigned int() {
255  const int index = seq;
256  long seed1 = table[index][0];
257  long seed2 = table[index][1];
258 
259  int k1 = (int)(seed1/ecuyer_b);
260  int k2 = (int)(seed2/ecuyer_e);
261 
262  seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
263  if (seed1 < 0) seed1 += shift1;
264  seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
265  if (seed2 < 0) seed2 += shift2;
266 
267  table[index][0] = seed1;
268  table[index][1] = seed2;
269  long diff = seed1-seed2;
270  if( diff <= 0 ) diff += (shift1-1);
271 
272  return ((diff << 1) | (seed1&1))& 0xffffffff;
273 }
274 
275 std::ostream & RanecuEngine::put( std::ostream& os ) const
276 {
277  char beginMarker[] = "RanecuEngine-begin";
278  os << beginMarker << "\nUvec\n";
279  std::vector<unsigned long> v = put();
280  for (unsigned int i=0; i<v.size(); ++i) {
281  os << v[i] << "\n";
282  }
283  return os;
284 }
285 
286 std::vector<unsigned long> RanecuEngine::put () const {
287  std::vector<unsigned long> v;
288  v.push_back (engineIDulong<RanecuEngine>());
289  v.push_back(static_cast<unsigned long>(theSeed));
290  v.push_back(static_cast<unsigned long>(table[theSeed][0]));
291  v.push_back(static_cast<unsigned long>(table[theSeed][1]));
292  return v;
293 }
294 
295 std::istream & RanecuEngine::get ( std::istream& is )
296 {
297  char beginMarker [MarkerLen];
298 
299  is >> std::ws;
300  is.width(MarkerLen); // causes the next read to the char* to be <=
301  // that many bytes, INCLUDING A TERMINATION \0
302  // (Stroustrup, section 21.3.2)
303  is >> beginMarker;
304  if (strcmp(beginMarker,"RanecuEngine-begin")) {
305  is.clear(std::ios::badbit | is.rdstate());
306  std::cerr << "\nInput stream mispositioned or"
307  << "\nRanecuEngine state description missing or"
308  << "\nwrong engine type found." << std::endl;
309  return is;
310  }
311  return getState(is);
312 }
313 
314 std::string RanecuEngine::beginTag ( ) {
315  return "RanecuEngine-begin";
316 }
317 
318 std::istream & RanecuEngine::getState ( std::istream& is )
319 {
320  if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) {
321  std::vector<unsigned long> v;
322  unsigned long uu;
323  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
324  is >> uu;
325  if (!is) {
326  is.clear(std::ios::badbit | is.rdstate());
327  std::cerr << "\nRanecuEngine state (vector) description improper."
328  << "\ngetState() has failed."
329  << "\nInput stream is probably mispositioned now." << std::endl;
330  return is;
331  }
332  v.push_back(uu);
333  }
334  getState(v);
335  return (is);
336  }
337 
338 // is >> theSeed; Removed, encompassed by possibleKeywordInput()
339  char endMarker [MarkerLen];
340  for (int i=0; i<2; ++i) {
341  is >> table[theSeed][i];
342  }
343  is >> std::ws;
344  is.width(MarkerLen);
345  is >> endMarker;
346  if (strcmp(endMarker,"RanecuEngine-end")) {
347  is.clear(std::ios::badbit | is.rdstate());
348  std::cerr << "\nRanecuEngine state description incomplete."
349  << "\nInput stream is probably mispositioned now." << std::endl;
350  return is;
351  }
352 
353  seq = int(theSeed);
354  return is;
355 }
356 
357 bool RanecuEngine::get (const std::vector<unsigned long> & v) {
358  if ((v[0] & 0xffffffffUL) != engineIDulong<RanecuEngine>()) {
359  std::cerr <<
360  "\nRanecuEngine get:state vector has wrong ID word - state unchanged\n";
361  return false;
362  }
363  return getState(v);
364 }
365 
366 bool RanecuEngine::getState (const std::vector<unsigned long> & v) {
367  if (v.size() != VECTOR_STATE_SIZE ) {
368  std::cerr <<
369  "\nRanecuEngine get:state vector has wrong length - state unchanged\n";
370  return false;
371  }
372  theSeed = v[1];
373  table[theSeed][0] = v[2];
374  table[theSeed][1] = v[3];
375  seq = int(theSeed);
376  return true;
377 }
378 
379 
380 } // namespace CLHEP
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
Definition: RandomEngine.h:167
static const int ecuyer_c
Definition: RanecuEngine.h:112
static const double prec
Definition: RanecuEngine.cc:58
void restoreStatus(const char filename[]="Ranecu.conf")
static std::string engineName()
Definition: RanecuEngine.h:100
static const G4double pos
void showStatus() const
void setSeeds(const long *seeds, int index=-1)
static ush mask[]
Definition: csz_inflate.cc:317
void setSeed(long index, int dum=0)
static const int ecuyer_a
Definition: RanecuEngine.h:110
static const int maxSeq
Definition: RanecuEngine.h:128
virtual std::istream & getState(std::istream &is)
void setIndex(long index)
static const int MarkerLen
Definition: DualRand.cc:67
Int_t col[ntarg]
Definition: Style.C:29
#define CLHEP_ATOMIC_INT_TYPE
Definition: atomic_int.h:20
static const int shift2
Definition: RanecuEngine.h:117
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
virtual std::istream & get(std::istream &is)
std::string name() const
Definition: RanecuEngine.cc:60
void flatArray(const int size, double *vect)
static const unsigned int VECTOR_STATE_SIZE
Definition: RanecuEngine.h:119
long table[215][2]
Definition: RanecuEngine.h:129
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
static void getTheTableSeeds(long *seeds, int index)
Definition: Random.cc:251
void further_randomize(int seq, int col, int index, int modulus)
Definition: RanecuEngine.cc:62
static const int ecuyer_b
Definition: RanecuEngine.h:111
std::vector< unsigned long > put() const
void saveStatus(const char filename[]="Ranecu.conf") const
static const int ecuyer_d
Definition: RanecuEngine.h:113
static const int shift1
Definition: RanecuEngine.h:116
double flat()
Definition: G4AblaRandom.cc:48
static const int ecuyer_f
Definition: RanecuEngine.h:115
static std::string beginTag()
static const int ecuyer_e
Definition: RanecuEngine.h:114