StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DRand48Engine.cc
1  /***************************************************************************
2  *
3  * $Id: DRand48Engine.cc,v 1.4 2016/01/22 17:10:49 smirnovd Exp $
4  *
5  * Author: Gabriele Cosmo - Created: 5th September 1995
6  * modified for SCL bl
7  ***************************************************************************
8  *
9  * Description:
10  * DRand48Engine.cc,v 1.6 1998/01/23 07:39:56
11  *
12  * HEP Random
13  * --- DRand48Engine ---
14  * class implementation file
15  * -----------------------------------------------------------------------
16  * This file is part of Geant4 (simulation toolkit for HEP).
17  *
18  ***************************************************************************
19  *
20  * $Log: DRand48Engine.cc,v $
21  * Revision 1.4 2016/01/22 17:10:49 smirnovd
22  * StarClassLibrary: Removed deprecated storage class specifier 'register'
23  *
24  * This keyword is deprecated since C++11 and serves no purpose
25  *
26  * "
27  * The register specifier is only allowed for objects declared at block scope and
28  * in function parameter lists. It indicates automatic storage duration, which is
29  * the default for these kinds of declarations. Additionally, the presence of this
30  * keyword may be used as a hint for the optimizer to store the value of this
31  * variable in a CPU register.
32  * "
33  *
34  * Revision 1.3 2012/06/11 15:29:26 fisyak
35  * std namespace
36  *
37  * Revision 1.2 1999/12/07 23:43:03 ullrich
38  * Modified to get rid of warnings on Linux.
39  *
40  * Revision 1.1 1999/01/30 03:58:59 fisyak
41  * Root Version of StarClassLibrary
42  *
43  * Revision 1.1 1999/01/23 00:29:01 ullrich
44  * Initial Revision
45  *
46  **************************************************************************/
47 #include "DRand48Engine.h"
48 
49 #ifdef WIN32
50  // ********************************************************************
51  // Code extracted from GNU C Library 2.0.1
52 
53 # include <limits.h>
54 # include <sys/types.h>
55 # include <wtypes.h>
56 # include <string.h>
57 
58  /* Global state for non-reentrant functions. */
59  struct drand48_data libc_drand48_data;
60 
61  int drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer)
62  {
63  ULONGLONG X, a, result;
64 
65  /* Initialize buffer, if not yet done. */
66  if (!buffer->init)
67  {
68  #if (USHRT_MAX == 0xffffU)
69  buffer->a[2] = 0x5;
70  buffer->a[1] = 0xdeec;
71  buffer->a[0] = 0xe66d;
72  #else
73  buffer->a[2] = 0x5deecUL;
74  buffer->a[1] = 0xe66d0000UL;
75  buffer->a[0] = 0;
76  #endif
77  buffer->c = 0xb;
78  buffer->init = 1;
79  }
80 
81  /* Do the real work. We choose a data type which contains at least
82  48 bits. Because we compute the modulus it does not care how
83  many bits really are computed. */
84 
85  if (sizeof (unsigned short int) == 2)
86  {
87  X = (ULONGLONG)xsubi[2] << 32 | (ULONGLONG)xsubi[1] << 16 | xsubi[0];
88  a = ((ULONGLONG)buffer->a[2] << 32 | (ULONGLONG)buffer->a[1] << 16
89  | buffer->a[0]);
90 
91  result = X * a + buffer->c;
92 
93  xsubi[0] = (unsigned short int) (result & 0xffff);
94  xsubi[1] = (unsigned short int) ((result >> 16) & 0xffff);
95  xsubi[2] = (unsigned short int) ((result >> 32) & 0xffff);
96  }
97  else
98  {
99  X = (ULONGLONG)xsubi[2] << 16 | xsubi[1] >> 16;
100  a = (ULONGLONG)buffer->a[2] << 16 | buffer->a[1] >> 16;
101 
102  result = X * a + buffer->c;
103 
104  xsubi[0] = (unsigned short int) (result >> 16 & 0xffffffffl);
105  xsubi[1] = (unsigned short int) (result << 16 & 0xffff0000l);
106  }
107 
108  return 0;
109  }
110 
111  int seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer)
112  {
113  /* Save old value at a private place to be used as return value. */
114  memcpy (buffer->old_X, buffer->X, sizeof (buffer->X));
115 
116  /* Install new state. */
117  memcpy (buffer->X, seed16v, sizeof (buffer->X));
118 
119  return 0;
120  }
121 
122  unsigned short int * seed48 (unsigned short int seed16v[3])
123  {
124  (void) seed48_r (seed16v, &libc_drand48_data);
125 
126  return libc_drand48_data.old_X;
127  }
128 
129  int srand48_r (long seedval, struct drand48_data *buffer)
130  {
131  /* The standards say we only have 32 bits. */
132  if (sizeof (long) > 4)
133  seedval &= 0xffffffffl;
134 
135  #if (USHRT_MAX == 0xffffU)
136  buffer->X[2] = (unsigned short int) (seedval >> 16);
137  buffer->X[1] = (unsigned short int) (seedval & 0xffffl);
138  buffer->X[0] = 0x330e;
139  #else
140  buffer->X[2] = seedval;
141  buffer->X[1] = 0x330e0000UL;
142  buffer->X[0] = 0;
143  #endif
144 
145  return 0;
146  }
147 
148  void srand48 (long seedval)
149  {
150  (void) srand48_r (seedval, &libc_drand48_data);
151  }
152 
153  int erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, double *result)
154  {
155  /* Compute next state. */
156  if (drand48_iterate (xsubi, buffer) < 0)
157  return -1;
158 
159  /* Construct a positive double with the 48 random bits distributed over
160  its fractional part so the resulting FP number is [0.0,1.0). */
161 
162  #if USHRT_MAX == 65535
163  *result = ((double) xsubi[2] / ((ULONGLONG)1 << 48) +
164  (double) xsubi[1] / ((ULONGLONG)1 << 32) +
165  (double) xsubi[0] / ((ULONGLONG)1 << 16));
166  #else
167  # error Unsupported size of short int
168  #endif
169 
170  return 0;
171  }
172 
173  double drand48 ()
174  {
175  double result;
176 
177  (void) erand48_r (libc_drand48_data.X, &libc_drand48_data, &result);
178 
179  return result;
180  }
181 
182  // End Code extracted from GNU C Library 2.0.1
183  // ********************************************************************
184 #endif /* WIN32 */
185 
186 DRand48Engine::DRand48Engine(long seed)
187 {
188  setSeed(seed,0);
189  setSeeds(&theSeed,0);
190 }
191 
192 DRand48Engine::~DRand48Engine() {}
193 
194 DRand48Engine::DRand48Engine(const DRand48Engine &p)
195 {
196  // This copy constructor uses saveStatus() and restoreStatus()
197  // to make the physical copy of the object preserving its
198  // original status.
199 
200  if ((this != &p) && (&p)) {
201  p.saveStatus();
202  restoreStatus();
203  setSeeds(&theSeed,0);
204  }
205 }
206 
207 DRand48Engine & DRand48Engine::operator = (const DRand48Engine &p)
208 {
209  // This operator uses saveStatus() and restoreStatus()
210  // to make the physical copy of the object preserving its
211  // original status.
212 
213  if ((this != &p) && (&p)) {
214  p.saveStatus();
215  restoreStatus();
216  setSeeds(&theSeed,0);
217  }
218  return *this;
219 }
220 
221 void DRand48Engine::setSeed(long seed, HepInt)
222 {
223  srand48( seed );
224  theSeed = seed;
225 }
226 
227 void DRand48Engine::setSeeds(const long* seeds, HepInt)
228 {
229  setSeed(seeds ? *seeds : 19780503, 0);
230  theSeeds = seeds;
231 }
232 
233 void DRand48Engine::saveStatus() const
234 {
235  ofstream outFile("DRand48.conf", std::ios::out ) ;
236 
237  unsigned short dummy[] = { 0, 0, 0 };
238  unsigned short* cseed = seed48(dummy);
239 
240  if (!outFile.bad()) {
241  outFile << theSeed << endl;
242  for (HepInt i=0; i<3; ++i) {
243  outFile << cseed[i] << endl;
244  dummy[i] = cseed[i];
245  }
246  seed48(dummy);
247  }
248 }
249 
250 void DRand48Engine::restoreStatus()
251 {
252  ifstream inFile("DRand48.conf", std::ios::in);
253  unsigned short cseed[3];
254 
255  if (!inFile.bad() && !inFile.eof()) {
256  inFile >> theSeed;
257  for (HepInt i=0; i<3; ++i)
258  inFile >> cseed[i];
259  seed48(cseed);
260  }
261 }
262 
263 void DRand48Engine::showStatus() const
264 {
265  unsigned short dummy[] = { 0, 0, 0 };
266  unsigned short* cseed = seed48(dummy);
267  cout << endl;
268  cout << "-------- DRand48 engine status ---------" << endl;
269  cout << " Initial seed = " << theSeed << endl;
270  cout << " Current seeds = " << cseed[0] << ", ";
271  cout << cseed[1] << ", ";
272  cout << cseed[2] << endl;
273  cout << "----------------------------------------" << endl;
274  for (HepInt i=0; i<3; ++i)
275  dummy[i] = cseed[i];
276  seed48(dummy);
277 }
278 
279 HepDouble DRand48Engine::flat()
280 {
281  HepDouble num = 0.;
282 
283  while (num == 0.)
284  num = drand48();
285  return num;
286 }
287 
288 void DRand48Engine::flatArray(const HepInt size, HepDouble* vect)
289 {
290  HepInt i;
291 
292  for (i=0; i<size; ++i)
293  vect[i]=flat();
294 }
295 
296 void
297 #ifndef ST_NO_TEMPLATE_DEF_ARGS
298 DRand48Engine::flatArray(vector<HepDouble>& vec)
299 #else
300 DRand48Engine::flatArray(vector<HepDouble,allocator<HepDouble> >& vec)
301 #endif
302 {
303  for (unsigned int i=0; i<vec.size(); ++i)
304  vec[i]=flat();
305 }