Geant4  10.00.p02
Ranlux64Engine.cc
Go to the documentation of this file.
1 // $Id:$
2 // -*- C++ -*-
3 //
4 // -----------------------------------------------------------------------
5 // HEP Random
6 // --- Ranlux64Engine ---
7 // class implementation file
8 // -----------------------------------------------------------------------
9 // A double-precision implementation of the RanluxEngine generator as
10 // decsribed by the notes of the original ranlux author (Martin Luscher)
11 //
12 // See the note by Martin Luscher, December 1997, entitiled
13 // Double-precision implementation of the random number generator ranlux
14 //
15 // =======================================================================
16 // Ken Smith - Initial draft: 14th Jul 1998
17 // - Removed pow() from flat method 14th Jul 1998
18 // - Added conversion operators: 6th Aug 1998
19 //
20 // Mark Fischler The following were modified mostly to make the routine
21 // exactly match the Luscher algorithm in generating 48-bit
22 // randoms:
23 // 9/9/98 - Substantial changes in what used to be flat() to match
24 // algorithm in Luscher's ranlxd.c
25 // - Added update() method for 12 numbers, making flat() trivial
26 // - Added advance() method to hold the unrolled loop for update
27 // - Distinction between three forms of seeding such that it
28 // is impossible to get same sequence from different forms -
29 // done by discarding some fraction of one macro cycle which
30 // is different for the three cases
31 // - Change the misnomer "seed_table" to the more accurate
32 // "randoms"
33 // - Removed the no longer needed count12, i_lag, j_lag, etc.
34 // - Corrected seed procedure which had been filling bits past
35 // 2^-48. This actually was very bad, invalidating the
36 // number theory behind the proof that ranlxd is good.
37 // - Addition of 2**(-49) to generated number to prevent zero
38 // from being returned; this does not affect the sequence
39 // itself.
40 // - Corrected ecu seeding, which had been supplying only
41 // numbers less than 1/2. This is probably moot.
42 // 9/15/98 - Modified use of the various exponents of 2
43 // to avoid per-instance space overhead. Note that these
44 // are initialized in setSeed, which EVERY constructor
45 // must invoke.
46 // J. Marraffino - Remove dependence on hepString class 13 May 1999
47 // M. Fischler - In restore, checkFile for file not found 03 Dec 2004
48 // M. Fischler - put get Methods for distrib instance save/restore 12/8/04
49 // M. Fischler - split get() into tag validation and
50 // getState() for anonymous restores 12/27/04
51 // M. Fischler - put/get for vectors of ulongs 3/14/05
52 // M. Fischler - State-saving using only ints, for portability 4/12/05
53 //
54 // =======================================================================
55 
56 #include "CLHEP/Random/Random.h"
57 #include "CLHEP/Random/Ranlux64Engine.h"
58 #include "CLHEP/Random/engineIDulong.h"
59 #include "CLHEP/Random/DoubConv.h"
60 #include <string.h> // for strcmp
61 #include <cstdlib> // for std::abs(int)
62 #include <limits> // for numeric_limits
63 
64 namespace CLHEP {
65 
66 static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
67 
68 
69 // Number of instances with automatic seed selection
70 int Ranlux64Engine::numEngines = 0;
71 
72 // Maximum index into the seed table
73 int Ranlux64Engine::maxIndex = 215;
74 
75 #ifndef WIN32
76 namespace detail {
77 
78 template< std::size_t n,
79  bool = n < std::size_t(std::numeric_limits<unsigned long>::digits) >
80  struct do_right_shift;
81 template< std::size_t n >
82  struct do_right_shift<n,true>
83 {
84  unsigned long operator()(unsigned long value) { return value >> n; }
85 };
86 template< std::size_t n >
87  struct do_right_shift<n,false>
88 {
89  unsigned long operator()(unsigned long) { return 0ul; }
90 };
91 
92 template< std::size_t nbits >
93  unsigned long rshift( unsigned long value )
94 { return do_right_shift<nbits>()(value); }
95 
96 } // namespace detail
97 #endif
98 
99 std::string Ranlux64Engine::name() const {return "Ranlux64Engine";}
100 
101 Ranlux64Engine::Ranlux64Engine()
102 : HepRandomEngine()
103 {
104  luxury = 1;
105  int cycle = std::abs(int(numEngines/maxIndex));
106  int curIndex = std::abs(int(numEngines%maxIndex));
107  numEngines +=1;
108  long mask = ((cycle & 0x007fffff) << 8);
109  long seedlist[2];
110  HepRandom::getTheTableSeeds( seedlist, curIndex );
111  seedlist[0] ^= mask;
112  seedlist[1] = 0;
113 
114  setSeeds(seedlist, luxury);
115  advance ( 8 ); // Discard some iterations and ensure that
116  // this sequence won't match one where seeds
117  // were provided.
118 }
119 
120 Ranlux64Engine::Ranlux64Engine(long seed, int lux)
121 : HepRandomEngine()
122 {
123  luxury = lux;
124  long seedlist[2]={seed,0};
125  setSeeds(seedlist, lux);
126  advance ( 2*lux + 1 ); // Discard some iterations to use a different
127  // point in the sequence.
128 }
129 
130 Ranlux64Engine::Ranlux64Engine(int rowIndex, int, int lux)
131 : HepRandomEngine()
132 {
133  luxury = lux;
134  int cycle = std::abs(int(rowIndex/maxIndex));
135  int row = std::abs(int(rowIndex%maxIndex));
136  long mask = (( cycle & 0x000007ff ) << 20 );
137  long seedlist[2];
138  HepRandom::getTheTableSeeds( seedlist, row );
139  seedlist[0] ^= mask;
140  seedlist[1]= 0;
141  setSeeds(seedlist, lux);
142 }
143 
144 Ranlux64Engine::Ranlux64Engine( std::istream& is )
145 : HepRandomEngine()
146 {
147  is >> *this;
148 }
149 
150 Ranlux64Engine::~Ranlux64Engine() {}
151 
152 double Ranlux64Engine::flat() {
153  // Luscher improves the speed by computing several numbers in a shot,
154  // in a manner similar to that of the Tausworth in DualRand or the Hurd
155  // engines. Thus, the real work is done in update(). Here we merely ensure
156  // that zero, which the algorithm can produce, is never returned by flat().
157 
158  if (index <= 0) update();
159  return randoms[--index] + twoToMinus_49();
160 }
161 
162 void Ranlux64Engine::update() {
163  // Update the stash of twelve random numbers.
164  // When this routione is entered, index is always 0. The randoms
165  // contains the last 12 numbers in the sequents: s[0] is x[a+11],
166  // s[1] is x[a+10] ... and s[11] is x[a] for some a. Carry contains
167  // the last carry value (c[a+11]).
168  //
169  // The recursion relation (3) in Luscher's note says
170  // delta[n] = x[n-s] = x[n-r] -c[n-1] or for n=a+12,
171  // delta[a+12] = x[a+7] - x[a] -c[a+11] where we use r=12, s=5 per eqn. (7)
172  // This reduces to
173  // s[11] = s[4] - s[11] - carry.
174  // The next number similarly will be given by s[10] = s[3] - s[10] - carry,
175  // and so forth until s[0] is filled.
176  //
177  // However, we need to skip 397, 202 or 109 numbers - these are not divisible
178  // by 12 - to "fare well in the spectral test".
179 
180  advance(pDozens);
181 
182  // Since we wish at the end to have the 12 last numbers in the order of
183  // s[11] first, till s[0] last, we will have to do 1, 10, or 1 iterations
184  // and then re-arrange to place to get the oldest one in s[11].
185  // Generically, this will imply re-arranging the s array at the end,
186  // but we can treat the special case of endIters = 1 separately for superior
187  // efficiency in the cases of levels 0 and 2.
188 
189  double y1;
190 
191  if ( endIters == 1 ) { // Luxury levels 0 and 2 will go here
192  y1 = randoms[ 4] - randoms[11] - carry;
193  if ( y1 < 0.0 ) {
194  y1 += 1.0;
195  carry = twoToMinus_48();
196  } else {
197  carry = 0.0;
198  }
199  randoms[11] = randoms[10];
200  randoms[10] = randoms[ 9];
201  randoms[ 9] = randoms[ 8];
202  randoms[ 8] = randoms[ 7];
203  randoms[ 7] = randoms[ 6];
204  randoms[ 6] = randoms[ 5];
205  randoms[ 5] = randoms[ 4];
206  randoms[ 4] = randoms[ 3];
207  randoms[ 3] = randoms[ 2];
208  randoms[ 2] = randoms[ 1];
209  randoms[ 1] = randoms[ 0];
210  randoms[ 0] = y1;
211 
212  } else {
213 
214  int m, nr, ns;
215  for ( m = 0, nr = 11, ns = 4; m < endIters; ++m, --nr ) {
216  y1 = randoms [ns] - randoms[nr] - carry;
217  if ( y1 < 0.0 ) {
218  y1 += 1.0;
219  carry = twoToMinus_48();
220  } else {
221  carry = 0.0;
222  }
223  randoms[nr] = y1;
224  --ns;
225  if ( ns < 0 ) {
226  ns = 11;
227  }
228  } // loop on m
229 
230  double temp[12];
231  for (m=0; m<12; m++) {
232  temp[m]=randoms[m];
233  }
234 
235  ns = 11 - endIters;
236  for (m=11; m>=0; --m) {
237  randoms[m] = temp[ns];
238  --ns;
239  if ( ns < 0 ) {
240  ns = 11;
241  }
242  }
243 
244  }
245 
246  // Now when we return, there are 12 fresh usable numbers in s[11] ... s[0]
247 
248  index = 11;
249 
250 } // update()
251 
252 void Ranlux64Engine::advance(int dozens) {
253 
254  double y1, y2, y3;
255  double cValue = twoToMinus_48();
256  double zero = 0.0;
257  double one = 1.0;
258 
259  // Technical note: We use Luscher's trick to only do the
260  // carry subtraction when we really have to. Like him, we use
261  // three registers instead of two so that we avoid sequences
262  // like storing y1 then immediately replacing its value:
263  // some architectures lose time when this is done.
264 
265  // Luscher's ranlxd.c fills the stash going
266  // upward. We fill it downward to save a bit of time in the
267  // flat() routine at no cost later. This means that while
268  // Luscher's ir is jr+5, our n-r is (n-s)-5. (Note that
269  // though ranlxd.c initializes ir and jr to 11 and 7, ir as
270  // used is 5 more than jr because update is entered after
271  // incrementing ir.)
272  //
273 
274  // I have CAREFULLY checked that the algorithms do match
275  // in all details.
276 
277  int k;
278  for ( k = dozens; k > 0; --k ) {
279 
280  y1 = randoms[ 4] - randoms[11] - carry;
281 
282  y2 = randoms[ 3] - randoms[10];
283  if ( y1 < zero ) {
284  y1 += one;
285  y2 -= cValue;
286  }
287  randoms[11] = y1;
288 
289  y3 = randoms[ 2] - randoms[ 9];
290  if ( y2 < zero ) {
291  y2 += one;
292  y3 -= cValue;
293  }
294  randoms[10] = y2;
295 
296  y1 = randoms[ 1] - randoms[ 8];
297  if ( y3 < zero ) {
298  y3 += one;
299  y1 -= cValue;
300  }
301  randoms[ 9] = y3;
302 
303  y2 = randoms[ 0] - randoms[ 7];
304  if ( y1 < zero ) {
305  y1 += one;
306  y2 -= cValue;
307  }
308  randoms[ 8] = y1;
309 
310  y3 = randoms[11] - randoms[ 6];
311  if ( y2 < zero ) {
312  y2 += one;
313  y3 -= cValue;
314  }
315  randoms[ 7] = y2;
316 
317  y1 = randoms[10] - randoms[ 5];
318  if ( y3 < zero ) {
319  y3 += one;
320  y1 -= cValue;
321  }
322  randoms[ 6] = y3;
323 
324  y2 = randoms[ 9] - randoms[ 4];
325  if ( y1 < zero ) {
326  y1 += one;
327  y2 -= cValue;
328  }
329  randoms[ 5] = y1;
330 
331  y3 = randoms[ 8] - randoms[ 3];
332  if ( y2 < zero ) {
333  y2 += one;
334  y3 -= cValue;
335  }
336  randoms[ 4] = y2;
337 
338  y1 = randoms[ 7] - randoms[ 2];
339  if ( y3 < zero ) {
340  y3 += one;
341  y1 -= cValue;
342  }
343  randoms[ 3] = y3;
344 
345  y2 = randoms[ 6] - randoms[ 1];
346  if ( y1 < zero ) {
347  y1 += one;
348  y2 -= cValue;
349  }
350  randoms[ 2] = y1;
351 
352  y3 = randoms[ 5] - randoms[ 0];
353  if ( y2 < zero ) {
354  y2 += one;
355  y3 -= cValue;
356  }
357  randoms[ 1] = y2;
358 
359  if ( y3 < zero ) {
360  y3 += one;
361  carry = cValue;
362  }
363  randoms[ 0] = y3;
364 
365  } // End of major k loop doing 12 numbers at each cycle
366 
367 } // advance(dozens)
368 
369 void Ranlux64Engine::flatArray(const int size, double* vect) {
370  for( int i=0; i < size; ++i ) {
371  vect[i] = flat();
372  }
373 }
374 
375 void Ranlux64Engine::setSeed(long seed, int lux) {
376 
377 // The initialization is carried out using a Multiplicative
378 // Congruential generator using formula constants of L'Ecuyer
379 // as described in "A review of pseudorandom number generators"
380 // (Fred James) published in Computer Physics Communications 60 (1990)
381 // pages 329-344
382 
383  const int ecuyer_a(53668);
384  const int ecuyer_b(40014);
385  const int ecuyer_c(12211);
386  const int ecuyer_d(2147483563);
387 
388  const int lux_levels[3] = {109, 202, 397};
389  theSeed = seed;
390 
391  if( (lux > 2)||(lux < 0) ){
392  pDiscard = (lux >= 12) ? (lux-12) : lux_levels[1];
393  }else{
394  pDiscard = lux_levels[luxury];
395  }
396  pDozens = pDiscard / 12;
397  endIters = pDiscard % 12;
398 
399  long init_table[24];
400  long next_seed = seed;
401  long k_multiple;
402  int i;
403  next_seed &= 0xffffffff;
404  while( next_seed >= ecuyer_d ) {
405  next_seed -= ecuyer_d;
406  }
407 
408  for(i = 0;i != 24;i++){
409  k_multiple = next_seed / ecuyer_a;
410  next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
411  - k_multiple * ecuyer_c;
412  if(next_seed < 0) {
413  next_seed += ecuyer_d;
414  }
415  next_seed &= 0xffffffff;
416  init_table[i] = next_seed;
417  }
418  // are we on a 64bit machine?
419  if( sizeof(long) >= 8 ) {
420  long topbits1, topbits2;
421 #ifdef WIN32
422  topbits1 = ( seed >> 32) & 0xffff ;
423  topbits2 = ( seed >> 48) & 0xffff ;
424 #else
425  topbits1 = detail::rshift<32>(seed) & 0xffff ;
426  topbits2 = detail::rshift<48>(seed) & 0xffff ;
427 #endif
428  init_table[0] ^= topbits1;
429  init_table[2] ^= topbits2;
430  //std::cout << " init_table[0] " << init_table[0] << " from " << topbits1 << std::endl;
431  //std::cout << " init_table[2] " << init_table[2] << " from " << topbits2 << std::endl;
432  }
433 
434  for(i = 0;i < 12; i++){
435  randoms[i] = (init_table[2*i ] ) * 2.0 * twoToMinus_32() +
436  (init_table[2*i+1] >> 15) * twoToMinus_48();
437  //if( randoms[i] < 0. || randoms[i] > 1. ) {
438  //std::cout << "setSeed: init_table " << init_table[2*i ] << std::endl;
439  //std::cout << "setSeed: init_table " << init_table[2*i+1] << std::endl;
440  //std::cout << "setSeed: random " << i << " is " << randoms[i] << std::endl;
441  //}
442  }
443 
444  carry = 0.0;
445  if ( randoms[11] == 0. ) carry = twoToMinus_48();
446  index = 11;
447 
448 } // setSeed()
449 
450 void Ranlux64Engine::setSeeds(const long * seeds, int lux) {
451 // old code only uses the first long in seeds
452 // setSeed( *seeds ? *seeds : 32767, lux );
453 // theSeeds = seeds;
454 
455 // using code from Ranlux - even those are 32bit seeds,
456 // that is good enough to completely differentiate the sequences
457 
458  const int ecuyer_a = 53668;
459  const int ecuyer_b = 40014;
460  const int ecuyer_c = 12211;
461  const int ecuyer_d = 2147483563;
462 
463  const int lux_levels[3] = {109, 202, 397};
464  const long *seedptr;
465 
466  theSeeds = seeds;
467  seedptr = seeds;
468 
469  if(seeds == 0){
470  setSeed(theSeed,lux);
471  theSeeds = &theSeed;
472  return;
473  }
474 
475  theSeed = *seeds;
476 
477 // number of additional random numbers that need to be 'thrown away'
478 // every 24 numbers is set using luxury level variable.
479 
480  if( (lux > 2)||(lux < 0) ){
481  pDiscard = (lux >= 12) ? (lux-12) : lux_levels[1];
482  }else{
483  pDiscard = lux_levels[luxury];
484  }
485  pDozens = pDiscard / 12;
486  endIters = pDiscard % 12;
487 
488  long init_table[24];
489  long next_seed = *seeds;
490  long k_multiple;
491  int i;
492 
493  for( i = 0;(i != 24)&&(*seedptr != 0);i++){
494  init_table[i] = *seedptr & 0xffffffff;
495  seedptr++;
496  }
497 
498  if(i != 24){
499  next_seed = init_table[i-1];
500  for(;i != 24;i++){
501  k_multiple = next_seed / ecuyer_a;
502  next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
503  - k_multiple * ecuyer_c;
504  if(next_seed < 0) {
505  next_seed += ecuyer_d;
506  }
507  next_seed &= 0xffffffff;
508  init_table[i] = next_seed;
509  }
510  }
511 
512  for(i = 0;i < 12; i++){
513  randoms[i] = (init_table[2*i ] ) * 2.0 * twoToMinus_32() +
514  (init_table[2*i+1] >> 15) * twoToMinus_48();
515  }
516 
517  carry = 0.0;
518  if ( randoms[11] == 0. ) carry = twoToMinus_48();
519  index = 11;
520 
521 }
522 
523 void Ranlux64Engine::saveStatus( const char filename[] ) const
524 {
525  std::ofstream outFile( filename, std::ios::out ) ;
526  if (!outFile.bad()) {
527  outFile << "Uvec\n";
528  std::vector<unsigned long> v = put();
529  for (unsigned int i=0; i<v.size(); ++i) {
530  outFile << v[i] << "\n";
531  }
532  }
533 }
534 
535 void Ranlux64Engine::restoreStatus( const char filename[] )
536 {
537  std::ifstream inFile( filename, std::ios::in);
538  if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
539  std::cerr << " -- Engine state remains unchanged\n";
540  return;
541  }
542  if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) {
543  std::vector<unsigned long> v;
544  unsigned long xin;
545  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
546  inFile >> xin;
547  if (!inFile) {
548  inFile.clear(std::ios::badbit | inFile.rdstate());
549  std::cerr << "\nJamesRandom state (vector) description improper."
550  << "\nrestoreStatus has failed."
551  << "\nInput stream is probably mispositioned now." << std::endl;
552  return;
553  }
554  v.push_back(xin);
555  }
556  getState(v);
557  return;
558  }
559 
560  if (!inFile.bad() && !inFile.eof()) {
561 // inFile >> theSeed; removed -- encompased by possibleKeywordInput
562  for (int i=0; i<12; ++i) {
563  inFile >> randoms[i];
564  }
565  inFile >> carry; inFile >> index;
566  inFile >> luxury; inFile >> pDiscard;
567  pDozens = pDiscard / 12;
568  endIters = pDiscard % 12;
569  }
570 }
571 
572 void Ranlux64Engine::showStatus() const
573 {
574  std::cout << std::endl;
575  std::cout << "--------- Ranlux engine status ---------" << std::endl;
576  std::cout << " Initial seed = " << theSeed << std::endl;
577  std::cout << " randoms[] = ";
578  for (int i=0; i<12; ++i) {
579  std::cout << randoms[i] << std::endl;
580  }
581  std::cout << std::endl;
582  std::cout << " carry = " << carry << ", index = " << index << std::endl;
583  std::cout << " luxury = " << luxury << " pDiscard = "
584  << pDiscard << std::endl;
585  std::cout << "----------------------------------------" << std::endl;
586 }
587 
588 std::ostream & Ranlux64Engine::put( std::ostream& os ) const
589 {
590  char beginMarker[] = "Ranlux64Engine-begin";
591  os << beginMarker << "\nUvec\n";
592  std::vector<unsigned long> v = put();
593  for (unsigned int i=0; i<v.size(); ++i) {
594  os << v[i] << "\n";
595  }
596  return os;
597 }
598 
599 std::vector<unsigned long> Ranlux64Engine::put () const {
600  std::vector<unsigned long> v;
601  v.push_back (engineIDulong<Ranlux64Engine>());
602  std::vector<unsigned long> t;
603  for (int i=0; i<12; ++i) {
604  t = DoubConv::dto2longs(randoms[i]);
605  v.push_back(t[0]); v.push_back(t[1]);
606  }
607  t = DoubConv::dto2longs(carry);
608  v.push_back(t[0]); v.push_back(t[1]);
609  v.push_back(static_cast<unsigned long>(index));
610  v.push_back(static_cast<unsigned long>(luxury));
611  v.push_back(static_cast<unsigned long>(pDiscard));
612  return v;
613 }
614 
615 std::istream & Ranlux64Engine::get ( std::istream& is )
616 {
617  char beginMarker [MarkerLen];
618  is >> std::ws;
619  is.width(MarkerLen); // causes the next read to the char* to be <=
620  // that many bytes, INCLUDING A TERMINATION \0
621  // (Stroustrup, section 21.3.2)
622  is >> beginMarker;
623  if (strcmp(beginMarker,"Ranlux64Engine-begin")) {
624  is.clear(std::ios::badbit | is.rdstate());
625  std::cerr << "\nInput stream mispositioned or"
626  << "\nRanlux64Engine state description missing or"
627  << "\nwrong engine type found." << std::endl;
628  return is;
629  }
630  return getState(is);
631 }
632 
633 std::string Ranlux64Engine::beginTag ( ) {
634  return "Ranlux64Engine-begin";
635 }
636 
637 std::istream & Ranlux64Engine::getState ( std::istream& is )
638 {
639  if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) {
640  std::vector<unsigned long> v;
641  unsigned long uu;
642  for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
643  is >> uu;
644  if (!is) {
645  is.clear(std::ios::badbit | is.rdstate());
646  std::cerr << "\nRanlux64Engine state (vector) description improper."
647  << "\ngetState() has failed."
648  << "\nInput stream is probably mispositioned now." << std::endl;
649  return is;
650  }
651  v.push_back(uu);
652  }
653  getState(v);
654  return (is);
655  }
656 
657 // is >> theSeed; Removed, encompassed by possibleKeywordInput()
658 
659  char endMarker [MarkerLen];
660  for (int i=0; i<12; ++i) {
661  is >> randoms[i];
662  }
663  is >> carry; is >> index;
664  is >> luxury; is >> pDiscard;
665  pDozens = pDiscard / 12;
666  endIters = pDiscard % 12;
667  is >> std::ws;
668  is.width(MarkerLen);
669  is >> endMarker;
670  if (strcmp(endMarker,"Ranlux64Engine-end")) {
671  is.clear(std::ios::badbit | is.rdstate());
672  std::cerr << "\nRanlux64Engine state description incomplete."
673  << "\nInput stream is probably mispositioned now." << std::endl;
674  return is;
675  }
676  return is;
677 }
678 
679 bool Ranlux64Engine::get (const std::vector<unsigned long> & v) {
680  if ((v[0] & 0xffffffffUL) != engineIDulong<Ranlux64Engine>()) {
681  std::cerr <<
682  "\nRanlux64Engine get:state vector has wrong ID word - state unchanged\n";
683  return false;
684  }
685  return getState(v);
686 }
687 
688 bool Ranlux64Engine::getState (const std::vector<unsigned long> & v) {
689  if (v.size() != VECTOR_STATE_SIZE ) {
690  std::cerr <<
691  "\nRanlux64Engine get:state vector has wrong length - state unchanged\n";
692  return false;
693  }
694  std::vector<unsigned long> t(2);
695  for (int i=0; i<12; ++i) {
696  t[0] = v[2*i+1]; t[1] = v[2*i+2];
697  randoms[i] = DoubConv::longs2double(t);
698  }
699  t[0] = v[25]; t[1] = v[26];
700  carry = DoubConv::longs2double(t);
701  index = v[27];
702  luxury = v[28];
703  pDiscard = v[29];
704  return true;
705 }
706 
707 } // namespace CLHEP
unsigned long rshift(unsigned long value)
static const double lux
Definition: G4SIunits.hh:291
static const int MarkerLen
Definition: DualRand.cc:60
std::ofstream outFile
Definition: GammaRayTel.cc:68
G4String name
Definition: TRTMaterials.hh:40
double flat()
Definition: G4AblaRandom.cc:47
unsigned long operator()(unsigned long)
static const double m
Definition: G4SIunits.hh:110
#define ns
Definition: xmlparse.cc:597
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.
Definition: G4INCLRandom.cc:66