CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

RanshiEngine.cc
Go to the documentation of this file.
1 // $Id: RanshiEngine.cc,v 1.6 2010/06/16 17:24:53 garren Exp $
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 //
33 // =======================================================================
34 
35 #include "CLHEP/Random/defs.h"
36 #include "CLHEP/Random/RanshiEngine.h"
37 #include "CLHEP/Random/engineIDulong.h"
38 #include <string.h> // for strcmp
39 
40 namespace CLHEP {
41 
42 static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
43 
44 std::string RanshiEngine::name() const {return "RanshiEngine";}
45 
46 // Number of instances with automatic seed selection
47 int RanshiEngine::numEngines = 0;
48 
50 : HepRandomEngine(),
51  halfBuff(0), numFlats(0)
52 {
53  int i = 0;
54  while (i < numBuff) {
55  buffer[i] = (unsigned int)(numEngines+19780503L*(i+1));
56  ++i;
57  }
58  theSeed = numEngines+19780503L*++i;
59  redSpin = (unsigned int)(theSeed & 0xffffffff);
60  ++numEngines;
61  for( i = 0; i < 10000; ++i) flat(); // Warm-up by running thorugh 10000 nums
62 }
63 
65 : HepRandomEngine(),
66  halfBuff(0), numFlats(0)
67 {
68  is >> *this;
69 }
70 
72 : HepRandomEngine(),
73  halfBuff(0), numFlats(0)
74 {
75  for (int i = 0; i < numBuff; ++i) {
76  buffer[i] = (unsigned int)seed&0xffffffff;
77  }
78  theSeed = seed;
79  redSpin = (unsigned int)(theSeed & 0xffffffff);
80  int j;
81  for (j = 0; j < numBuff*20; ++j) { // "warm-up" for engine to hit
82  flat(); // every ball on average 20X.
83  }
84 }
85 
86 RanshiEngine::RanshiEngine(int rowIndex, int colIndex)
87 : HepRandomEngine(),
88  halfBuff(0), numFlats(0)
89 {
90  int i = 0;
91  while( i < numBuff ) {
92  buffer[i] = (unsigned int)((rowIndex + (i+1)*(colIndex+8))&0xffffffff);
93  ++i;
94  }
95  theSeed = rowIndex;
96  redSpin = colIndex & 0xffffffff;
97  for( i = 0; i < 100; ++i) flat(); // Warm-up by running thorugh 100 nums
98 }
99 
101 
103  unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
104  unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
105  unsigned int boostResult = blkSpin ^ redSpin;
106 
107  buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
108 
109  redSpin = (blkSpin + numFlats++) & 0xffffffff;
110  halfBuff = numBuff/2 - halfBuff;
111 
112  return ( blkSpin * twoToMinus_32() + // most significant part
113  (boostResult>>11) * twoToMinus_53() + // fill in remaining bits
114  nearlyTwoToMinus_54()); // non-zero
115 }
116 
117 void RanshiEngine::flatArray(const int size, double* vect) {
118  for (int i = 0; i < size; ++i) {
119  vect[i] = flat();
120  }
121 }
122 
123 void RanshiEngine::setSeed(long seed, int) {
124  *this = RanshiEngine(seed);
125 }
126 
127 void RanshiEngine::setSeeds(const long* seeds, int) {
128  if (*seeds) {
129  int i = 0;
130  while (seeds[i] && i < numBuff) {
131  buffer[i] = (unsigned int)seeds[i];
132  ++i;
133  }
134  while (i < numBuff) {
135  buffer[i] = buffer[i-1];
136  ++i;
137  }
138  theSeed = seeds[0];
139  redSpin = (unsigned int)theSeed;
140  }
141  theSeeds = seeds;
142 }
143 
144 void RanshiEngine::saveStatus(const char filename[]) const {
145  std::ofstream outFile(filename, std::ios::out);
146  if (!outFile.bad()) {
147  outFile << "Uvec\n";
148  std::vector<unsigned long> v = put();
149  #ifdef TRACE_IO
150  std::cout << "Result of v = put() is:\n";
151  #endif
152  for (unsigned int i=0; i<v.size(); ++i) {
153  outFile << v[i] << "\n";
154  #ifdef TRACE_IO
155  std::cout << v[i] << " ";
156  if (i%6==0) std::cout << "\n";
157  #endif
158  }
159  #ifdef TRACE_IO
160  std::cout << "\n";
161  #endif
162  }
163 #ifdef REMOVED
164  if (!outFile.bad()) {
165  outFile << std::setprecision(20) << theSeed << std::endl;
166  for (int i = 0; i < numBuff; ++i) {
167  outFile << buffer[i] << " ";
168  }
169  outFile << redSpin << " " << numFlats << " " << halfBuff << std::endl;
170  }
171 #endif
172 }
173 
174 void RanshiEngine::restoreStatus(const char filename[]) {
175  std::ifstream inFile(filename, std::ios::in);
176  if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
177  std::cerr << " -- Engine state remains unchanged\n";
178  return;
179  }
180  if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) {
181  std::vector<unsigned long> v;
182  unsigned long xin;
183  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
184  inFile >> xin;
185  #ifdef TRACE_IO
186  std::cout << "ivec = " << ivec << " xin = " << xin << " ";
187  if (ivec%3 == 0) std::cout << "\n";
188  #endif
189  if (!inFile) {
190  inFile.clear(std::ios::badbit | inFile.rdstate());
191  std::cerr << "\nRanshiEngine state (vector) description improper."
192  << "\nrestoreStatus has failed."
193  << "\nInput stream is probably mispositioned now." << std::endl;
194  return;
195  }
196  v.push_back(xin);
197  }
198  getState(v);
199  return;
200  }
201 
202  if (!inFile.bad()) {
203 // inFile >> theSeed; removed -- encompased by possibleKeywordInput
204  for (int i = 0; i < numBuff; ++i) {
205  inFile >> buffer[i];
206  }
207  inFile >> redSpin >> numFlats >> halfBuff;
208  }
209 }
210 
212  std::cout << std::setprecision(20) << std::endl;
213  std::cout << "----------- Ranshi engine status ----------" << std::endl;
214  std::cout << "Initial seed = " << theSeed << std::endl;
215  std::cout << "Current red spin = " << redSpin << std::endl;
216  std::cout << "Values produced = " << numFlats << std::endl;
217  std::cout << "Side of buffer = " << (halfBuff ? "upper" : "lower")
218  << std::endl;
219  std::cout << "Current buffer = " << std::endl;
220  for (int i = 0; i < numBuff; i+=4) {
221  std::cout << std::setw(10) << std::setiosflags(std::ios::right)
222  << buffer[i] << std::setw(11) << buffer[i+1] << std::setw(11)
223  << buffer[i+2] << std::setw(11) << buffer[i+3] << std::endl;
224  }
225  std::cout << "-------------------------------------------" << std::endl;
226 }
227 
228 RanshiEngine::operator float() {
229  unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
230  unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
231 
232  buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
233 
234  redSpin = (blkSpin + numFlats++) & 0xffffffff;
235  halfBuff = numBuff/2 - halfBuff;
236 
237  return float(blkSpin * twoToMinus_32());
238 }
239 
240 RanshiEngine::operator unsigned int() {
241  unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
242  unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
243 
244  buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
245 
246  redSpin = (blkSpin + numFlats++) & 0xffffffff;
247  halfBuff = numBuff/2 - halfBuff;
248 
249  return blkSpin;
250 }
251 
252 std::ostream& RanshiEngine::put (std::ostream& os ) const {
253  char beginMarker[] = "RanshiEngine-begin";
254  os << beginMarker << "\nUvec\n";
255  std::vector<unsigned long> v = put();
256  for (unsigned int i=0; i<v.size(); ++i) {
257  os << v[i] << "\n";
258  }
259  return os;
260 #ifdef REMOVED
261  char endMarker[] = "RanshiEngine-end";
262  int pr=os.precision(20);
263  os << " " << beginMarker << " ";
264 
265  os << theSeed << "\n";
266  for (int i = 0; i < numBuff; ++i) {
267  os << buffer[i] << "\n";
268  }
269  os << redSpin << " " << numFlats << "\n" << halfBuff;
270 
271  os << " " << endMarker << "\n";
272  os.precision(pr);
273  return os;
274 #endif
275 }
276 
277 std::vector<unsigned long> RanshiEngine::put () const {
278  std::vector<unsigned long> v;
279  v.push_back (engineIDulong<RanshiEngine>());
280  for (int i = 0; i < numBuff; ++i) {
281  v.push_back(static_cast<unsigned long>(buffer[i]));
282  }
283  v.push_back(static_cast<unsigned long>(redSpin));
284  v.push_back(static_cast<unsigned long>(numFlats));
285  v.push_back(static_cast<unsigned long>(halfBuff));
286  return v;
287 }
288 
289 std::istream& RanshiEngine::get (std::istream& is) {
290  char beginMarker [MarkerLen];
291  is >> std::ws;
292  is.width(MarkerLen); // causes the next read to the char* to be <=
293  // that many bytes, INCLUDING A TERMINATION \0
294  // (Stroustrup, section 21.3.2)
295  is >> beginMarker;
296  if (strcmp(beginMarker,"RanshiEngine-begin")) {
297  is.clear(std::ios::badbit | is.rdstate());
298  std::cerr << "\nInput mispositioned or"
299  << "\nRanshiEngine state description missing or"
300  << "\nwrong engine type found." << std::endl;
301  return is;
302  }
303  return getState(is);
304 }
305 
306 std::string RanshiEngine::beginTag ( ) {
307  return "RanshiEngine-begin";
308 }
309 
310 std::istream& RanshiEngine::getState (std::istream& is) {
311  if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) {
312  std::vector<unsigned long> v;
313  unsigned long uu;
314  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
315  is >> uu;
316  if (!is) {
317  is.clear(std::ios::badbit | is.rdstate());
318  std::cerr << "\nRanshiEngine state (vector) description improper."
319  << "\ngetState() has failed."
320  << "\nInput stream is probably mispositioned now." << std::endl;
321  return is;
322  }
323  v.push_back(uu);
324  }
325  getState(v);
326  return (is);
327  }
328 
329 // is >> theSeed; Removed, encompassed by possibleKeywordInput()
330 
331  char endMarker [MarkerLen];
332  for (int i = 0; i < numBuff; ++i) {
333  is >> buffer[i];
334  }
335  is >> redSpin >> numFlats >> halfBuff;
336  is >> std::ws;
337  is.width(MarkerLen);
338  is >> endMarker;
339  if (strcmp(endMarker,"RanshiEngine-end")) {
340  is.clear(std::ios::badbit | is.rdstate());
341  std::cerr << "\nRanshiEngine state description incomplete."
342  << "\nInput stream is probably mispositioned now." << std::endl;
343  return is;
344  }
345  return is;
346 }
347 
348 bool RanshiEngine::get (const std::vector<unsigned long> & v) {
349  if ((v[0] & 0xffffffffUL) != engineIDulong<RanshiEngine>()) {
350  std::cerr <<
351  "\nRanshiEngine get:state vector has wrong ID word - state unchanged\n";
352  return false;
353  }
354  return getState(v);
355 }
356 
357 bool RanshiEngine::getState (const std::vector<unsigned long> & v) {
358  if (v.size() != VECTOR_STATE_SIZE ) {
359  std::cerr <<
360  "\nRanshiEngine get:state vector has wrong length - state unchanged\n";
361  return false;
362  }
363  for (int i = 0; i < numBuff; ++i) {
364  buffer[i] = v[i+1];
365  }
366  redSpin = v[numBuff+1];
367  numFlats = v[numBuff+2];
368  halfBuff = v[numBuff+3];
369  return true;
370 }
371 
372 } // namespace CLHEP
CLHEP::RanshiEngine::RanshiEngine
RanshiEngine()
Definition: RanshiEngine.cc:49
CLHEP::RanshiEngine::restoreStatus
void restoreStatus(const char filename[]="RanshiEngine.conf")
Definition: RanshiEngine.cc:174
CLHEP::HepRandomEngine
Definition: Matrix/CLHEP/Random/RandomEngine.h:55
CLHEP::RanshiEngine::beginTag
static std::string beginTag()
Definition: RanshiEngine.cc:306
CLHEP::HepRandomEngine::theSeed
long theSeed
Definition: Matrix/CLHEP/Random/RandomEngine.h:144
CLHEP::RanshiEngine::setSeed
void setSeed(long seed, int)
Definition: RanshiEngine.cc:123
is
HepRotation and so forth isNear() norm2() rectify() static Rotation row1 row4(To avoid bloat in the code pulled in for programs which don 't use all these features, we split the implementation .cc files. Only isNear() goes into the original Rotation.cc) --------------------------------------- HepAxisAngle and HepEulerAngles classes --------------------------------------- These classes are very useful and simple structures for holding the result of a nice intuituve decomposition of a rotation there is no longer much content in the distinct ZOOM PhysicsVectors library The only content left in the library is the object files representing the various Exception objects When we build the CLHEP classes for the ZOOM we will set up so as to use ZOOM SpaceVector is(but we can disable namespace usage and most of our users do so at this point). What I do is leave Hep3Vector in the global namespace
CLHEP::HepRandomEngine::theSeeds
const long * theSeeds
Definition: Matrix/CLHEP/Random/RandomEngine.h:145
CLHEP::HepRandomEngine::nearlyTwoToMinus_54
static double nearlyTwoToMinus_54()
size
user code seldom needs to call this function directly ZMerrno whether or not they are still recorded ZMerrno size() Return the(integer) number of ZMthrow 'n exceptions currently recorded. 5) ZMerrno.clear() Set an internal counter to zero. This counter is available(see next function) to user code to track ZMthrow 'n exceptions that have occurred during any arbitrary time interval. 6) ZMerrno.countSinceCleared() Return the(integer) number of ZMthrow 'n exceptions that have been recorded via ZMerrno.write()
CLHEP::RanshiEngine::flatArray
void flatArray(const int size, double *vect)
Definition: RanshiEngine.cc:117
CLHEP::RanshiEngine::engineName
static std::string engineName()
Definition: Matrix/CLHEP/Random/RanshiEngine.h:96
CLHEP
Definition: ClhepVersion.h:13
CLHEP::RanshiEngine::showStatus
void showStatus() const
Definition: RanshiEngine.cc:211
CLHEP::HepRandomEngine::twoToMinus_53
static double twoToMinus_53()
v
they are gone ZOOM Features Discontinued The following features of the ZOOM package were felt to be extreme overkill These have been after checking that no existing user code was utilizing as in SpaceVector v
Definition: keyMergeIssues.doc:324
CLHEP::RanshiEngine::flat
double flat()
Definition: RanshiEngine.cc:102
CLHEP::RanshiEngine::setSeeds
void setSeeds(const long *seeds, int)
Definition: RanshiEngine.cc:127
CLHEP::possibleKeywordInput
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
Definition: Matrix/CLHEP/Random/RandomEngine.h:168
j
long j
Definition: JamesRandomSeeding.txt:28
CLHEP::RanshiEngine::~RanshiEngine
virtual ~RanshiEngine()
Definition: RanshiEngine.cc:100
seeds
Technical Maintenance Note for CLHEP Random Consequences of seeding JamesRandom with positive seed values greater than In the source code JamesRandom The usual way of seeding a generator is via the default which makes use of the table of seeds(with some trickery to ensure that the values won 't repeat after the table rows are exhausted). The trickery preserves the fact that sees are never negative(because the table values are never negative
CLHEP::RanshiEngine::saveStatus
void saveStatus(const char filename[]="RanshiEngine.conf") const
Definition: RanshiEngine.cc:144
CLHEP::HepRandomEngine::twoToMinus_32
static double twoToMinus_32()
i
long i
Definition: JamesRandomSeeding.txt:27
CLHEP::RanshiEngine::put
std::vector< unsigned long > put() const
Definition: RanshiEngine.cc:277
CLHEP::RanshiEngine::get
virtual std::istream & get(std::istream &is)
Definition: RanshiEngine.cc:289
CLHEP::HepRandomEngine::checkFile
static bool checkFile(std::istream &file, const std::string &filename, const std::string &classname, const std::string &methodname)
Definition: RandomEngine.cc:46
CLHEP::RanshiEngine::getState
virtual std::istream & getState(std::istream &is)
Definition: RanshiEngine.cc:310
in
it has advantages For I leave the ZMthrows in
Definition: keyMergeIssues.doc:62
CLHEP::RanshiEngine::name
std::string name() const
Definition: RanshiEngine.cc:44