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