CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
DRand48Engine.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// $Id: DRand48Engine.cc,v 1.7 2010/07/29 16:50:34 garren Exp $
3// -----------------------------------------------------------------------
4// HEP Random
5// --- DRand48Engine ---
6// class implementation file
7// -----------------------------------------------------------------------
8// This file is part of Geant4 (simulation toolkit for HEP).
9
10// =======================================================================
11// G.Cosmo - Created: 5th September 1995
12// - Minor corrections: 31st October 1996
13// - Added methods for engine status: 19th November 1996
14// - Added srand48(), seed48(), drand48() implementations
15// for Windows/NT: 6th March 1997
16// - Fixed bug in setSeeds(): 15th September 1997
17// - Private copy constructor and operator=: 26th Feb 1998
18// J.Marraffino - Added stream operators and related constructor.
19// Added automatic seed selection from seed table and
20// engine counter: 16th Feb 1998
21// J.Marraffino - Remove dependence on hepString class 13 May 1999
22// E.Tcherniaev - More accurate code for drand48() on NT base on
23// a code extracted from GNU C Library 2.1.3: 8th Nov 2000
24// M. Fischler - In restore, checkFile for file not found 03 Dec 2004
25// M. Fischler - Methods for distrib. instacne save/restore 12/8/04
26// M. Fischler - split get() into tag validation and
27// getState() for anonymous restores 12/27/04
28// M. Fischler - put/get for vectors of ulongs 3/8/05
29// M. Fischler - State-saving using only ints, for portability 4/12/05
30//
31// =======================================================================
32
33#include "CLHEP/Random/defs.h"
34#include "CLHEP/Random/Random.h"
35#include "CLHEP/Random/DRand48Engine.h"
36#include "CLHEP/Random/RandomFunc.h"
37#include "CLHEP/Random/engineIDulong.h"
38#include <string.h> // for strcmp
39#include <stdlib.h> // for std::abs(int)
40
41//#define TRACE_IO
42
43#include <ostream>
44#include <string>
45#include <vector>
46#include <iostream>
47
48namespace CLHEP {
49
50static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
51// Number of instances with automatic seed selection
52int DRand48Engine::numEngines = 0;
53
54std::string DRand48Engine::name() const {return "DRand48Engine";}
55
56// Maximum index into the seed table
57const int DRand48Engine::maxIndex = 215;
58
61{
62 setSeed(seed,0);
63 setSeeds(&theSeed,0);
64}
65
68{
69 long seeds[2];
70 long seed;
71
72 int cycle = abs(int(numEngines/maxIndex));
73 int curIndex = abs(int(numEngines%maxIndex));
74 ++numEngines;
75 long mask = ((cycle & 0x007fffff) << 8);
76 HepRandom::getTheTableSeeds( seeds, curIndex );
77 seed = seeds[0]^mask;
78 setSeed(seed,0);
79 setSeeds(&theSeed,0);
80}
81
82DRand48Engine::DRand48Engine(int rowIndex, int colIndex)
84{
85 long seed;
86 long seeds[2];
87
88 int cycle = abs(int(rowIndex/maxIndex));
89 int row = abs(int(rowIndex%maxIndex));
90 int col = abs(int(colIndex%2));
91 long mask = ((cycle & 0x000007ff) << 20);
92 HepRandom::getTheTableSeeds( seeds, row );
93 seed = (seeds[col])^mask;
94 setSeed(seed,0);
95 setSeeds(&theSeed,0);
96}
97
100{
101 is >> *this;
102}
103
105
106void DRand48Engine::setSeed(long seed, int)
107{
108 srand48( seed );
109 theSeed = seed;
110}
111
112void DRand48Engine::setSeeds(const long* seeds, int)
113{
114 setSeed(seeds ? *seeds : 19780503L, 0);
115 theSeeds = seeds;
116}
117
118void DRand48Engine::saveStatus( const char filename[] ) const
119{
120 std::ofstream outFile( filename, std::ios::out ) ;
121
122 if (!outFile.bad()) {
123 outFile << "Uvec\n";
124 std::vector<unsigned long> v = put();
125 #ifdef TRACE_IO
126 std::cout << "Result of v = put() is:\n";
127 #endif
128 for (unsigned int i=0; i<v.size(); ++i) {
129 outFile << v[i] << "\n";
130 #ifdef TRACE_IO
131 std::cout << v[i] << " ";
132 if (i%6==0) std::cout << "\n";
133 #endif
134 }
135 #ifdef TRACE_IO
136 std::cout << "\n";
137 #endif
138 }
139
140#ifdef REMOVED
141 unsigned short dummy[] = { 0, 0, 0 };
142 unsigned short* cseed = seed48(dummy);
143 if (!outFile.bad()) {
144 outFile << theSeed << std::endl;
145 for (int i=0; i<3; ++i) {
146 outFile << cseed[i] << std::endl;
147 dummy[i] = cseed[i];
148 }
149 seed48(dummy);
150 }
151#endif
152}
153
154void DRand48Engine::restoreStatus( const char filename[] )
155{
156 std::ifstream inFile( filename, std::ios::in);
157 unsigned short cseed[3];
158
159 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
160 std::cerr << " -- Engine state remains unchanged\n";
161 return;
162 }
163 if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) {
164 std::vector<unsigned long> v;
165 unsigned long xin;
166 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
167 inFile >> xin;
168 #ifdef TRACE_IO
169 std::cout << "ivec = " << ivec << " xin = " << xin << " ";
170 if (ivec%3 == 0) std::cout << "\n";
171 #endif
172 if (!inFile) {
173 inFile.clear(std::ios::badbit | inFile.rdstate());
174 std::cerr << "\nDRand48Engine state (vector) description improper."
175 << "\nrestoreStatus has failed."
176 << "\nInput stream is probably mispositioned now." << std::endl;
177 return;
178 }
179 v.push_back(xin);
180 }
181 getState(v);
182 return;
183 }
184
185 if (!inFile.bad() && !inFile.eof()) {
186 inFile >> theSeed;
187 for (int i=0; i<3; ++i)
188// inFile >> theSeed; removed -- encompased by possibleKeywordInput
189 seed48(cseed);
190 }
191}
192
194{
195 unsigned short dummy[] = { 0, 0, 0 };
196 unsigned short* cseed = seed48(dummy);
197 std::cout << std::endl;
198 std::cout << "-------- DRand48 engine status ---------" << std::endl;
199 std::cout << " Initial seed = " << theSeed << std::endl;
200 std::cout << " Current seeds = " << cseed[0] << ", ";
201 std::cout << cseed[1] << ", ";
202 std::cout << cseed[2] << std::endl;
203 std::cout << "----------------------------------------" << std::endl;
204 for (int i=0; i<3; ++i)
205 dummy[i] = cseed[i];
206 seed48(dummy);
207}
208
210{
211 double num = 0.;
212
213 while (num == 0.)
214 num = drand48();
215 return num;
216}
217
218void DRand48Engine::flatArray(const int size, double* vect)
219{
220 int i;
221
222 for (i=0; i<size; ++i)
223 vect[i]=flat();
224}
225
226std::ostream & DRand48Engine::put ( std::ostream& os ) const
227{
228 char beginMarker[] = "DRand48Engine-begin";
229 os << beginMarker << "\nUvec\n";
230 std::vector<unsigned long> v = put();
231 for (unsigned int i=0; i<v.size(); ++i) {
232 os << v[i] << "\n";
233 }
234 return os;
235
236#ifdef REMOVED
237 unsigned short dummy[] = { 0, 0, 0 };
238 unsigned short* cseed = seed48(dummy);
239 char endMarker[] = "DRand48Engine-end";
240 os << " " << beginMarker << " ";
241 os << theSeed << " ";
242 for (int i=0; i<3; ++i) {
243 dummy[i] = cseed[i];
244 os << cseed[i] << " ";
245 }
246 os << endMarker << " ";
247 seed48(dummy);
248 return os;
249#endif
250}
251
252std::vector<unsigned long> DRand48Engine::put () const {
253 std::vector<unsigned long> v;
254 v.push_back (engineIDulong<DRand48Engine>());
255 unsigned short dummy[] = { 0, 0, 0 };
256 unsigned short* cseed = seed48(dummy);
257 for (int i=0; i<3; ++i) {
258 dummy[i] = cseed[i];
259 v.push_back (static_cast<unsigned long>(cseed[i]));
260 }
261 seed48(dummy);
262 return v;
263}
264
265std::istream & DRand48Engine::get ( std::istream& is )
266{
267 char beginMarker [MarkerLen];
268 is >> std::ws;
269 is.width(MarkerLen); // causes the next read to the char* to be <=
270 // that many bytes, INCLUDING A TERMINATION \0
271 // (Stroustrup, section 21.3.2)
272 is >> beginMarker;
273 if (strcmp(beginMarker,"DRand48Engine-begin")) {
274 is.clear(std::ios::badbit | is.rdstate());
275 std::cerr << "\nInput stream mispositioned or"
276 << "\nDRand48Engine state description missing or"
277 << "\nwrong engine type found." << std::endl;
278 return is;
279 }
280 return getState(is);
281}
282
283std::string DRand48Engine::beginTag ( ) {
284 return "DRand48Engine-begin";
285}
286
287std::istream & DRand48Engine::getState ( std::istream& is )
288{
289 unsigned short cseed[3];
290 if ( possibleKeywordInput ( is, "Uvec", cseed[0] ) ) {
291 std::vector<unsigned long> v;
292 unsigned long uu;
293 #ifdef TRACE_IO
294 std::cout << "DRand48Engine::getState detected Uvec keyword\n";
295 uu = 999999;
296 #endif
297 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
298 uu = 999999;
299 is >> uu;
300 #ifdef TRACE_IO
301 std::cout << "ivec = " << ivec << " uu = " << uu << "\n";
302 #endif
303 if (!is) {
304 is.clear(std::ios::badbit | is.rdstate());
305 std::cerr << "\nDRand48Engine state (vector) description improper."
306 << "\ngetState() has failed."
307 << "\nInput stream is probably mispositioned now." << std::endl;
308 return is;
309 }
310 v.push_back(uu);
311 }
312 getState(v);
313 return (is);
314 }
315
316// is >> cseed[0] was removed from loop, encompassed by possibleKeywordInput()
317
318 char endMarker [MarkerLen];
319 is >> theSeed;
320 for (int i=1; i<3; ++i) {
321 is >> cseed[i];
322 }
323 is >> std::ws;
324 is.width(MarkerLen);
325 is >> endMarker;
326 if (strcmp(endMarker,"DRand48Engine-end")) {
327 is.clear(std::ios::badbit | is.rdstate());
328 std::cerr << "\nDRand48Engine state description incomplete."
329 << "\nInput stream is probably mispositioned now." << std::endl;
330 return is;
331 }
332 seed48(cseed);
333 return is;
334}
335
336bool DRand48Engine::get (const std::vector<unsigned long> & v) {
337 if ((v[0] & 0xffffffffUL) != engineIDulong<DRand48Engine>()) {
338 std::cerr <<
339 "\nDRand48Engine get:state vector has wrong ID word - state unchanged\n";
340 return false;
341 }
342 return getState(v);
343}
344
345bool DRand48Engine::getState (const std::vector<unsigned long> & v) {
346 if (v.size() != VECTOR_STATE_SIZE ) {
347 std::cerr <<
348 "\nDRand48Engine getState:state vector has wrong length - state unchanged\n";
349 return false;
350 }
351 unsigned short cseed[3];
352 for (int i=0; i<3; ++i) {
353 cseed[i] = static_cast<unsigned short>(v[i+1]);
354 }
355 seed48(cseed);
356 return true;
357}
358
359} // namespace CLHEP
void srand48(long)
unsigned short * seed48(unsigned short int[3])
double drand48(void)
virtual std::istream & getState(std::istream &is)
static std::string engineName()
void showStatus() const
static std::string beginTag()
void setSeed(long seed, int dum=0)
static const unsigned int VECTOR_STATE_SIZE
void setSeeds(const long *seeds, int dum=0)
virtual std::istream & get(std::istream &is)
void saveStatus(const char filename[]="DRand48.conf") const
std::vector< unsigned long > put() const
std::string name() const
void restoreStatus(const char filename[]="DRand48.conf")
void flatArray(const int size, double *vect)
static bool checkFile(std::istream &file, const std::string &filename, const std::string &classname, const std::string &methodname)
Definition: RandomEngine.cc:49
static void getTheTableSeeds(long *seeds, int index)
Definition: Random.cc:256
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
Definition: RandomEngine.h:168