Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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"
60#include <string.h> // for strcmp
61#include <cstdlib> // for std::abs(int)
62#include <limits> // for numeric_limits
63
64namespace CLHEP {
65
66static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
67
68
69// Number of instances with automatic seed selection
70int Ranlux64Engine::numEngines = 0;
71
72// Maximum index into the seed table
73int Ranlux64Engine::maxIndex = 215;
74
75#ifndef WIN32
76namespace detail {
77
78template< std::size_t n,
79 bool = n < std::size_t(std::numeric_limits<unsigned long>::digits) >
80 struct do_right_shift;
81template< std::size_t n >
82 struct do_right_shift<n,true>
83{
84 unsigned long operator()(unsigned long value) { return value >> n; }
85};
86template< std::size_t n >
87 struct do_right_shift<n,false>
88{
89 unsigned long operator()(unsigned long) { return 0ul; }
90};
91
92template< 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
99std::string Ranlux64Engine::name() const {return "Ranlux64Engine";}
100
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
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
130Ranlux64Engine::Ranlux64Engine(int rowIndex, int, int lux)
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
146{
147 is >> *this;
148}
149
151
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
162void 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 register 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
252void Ranlux64Engine::advance(int dozens) {
253
254 register double y1, y2, y3;
255 register double cValue = twoToMinus_48();
256 register double zero = 0.0;
257 register 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
369void Ranlux64Engine::flatArray(const int size, double* vect) {
370 for( int i=0; i < size; ++i ) {
371 vect[i] = flat();
372 }
373}
374
375void 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
450void 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
523void 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
535void 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
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
588std::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
599std::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
615std::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
633std::string Ranlux64Engine::beginTag ( ) {
634 return "Ranlux64Engine-begin";
635}
636
637std::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
679bool 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
688bool 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
static double longs2double(const std::vector< unsigned long > &v)
Definition: DoubConv.cc:114
static std::vector< unsigned long > dto2longs(double d)
Definition: DoubConv.cc:98
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:45
static void getTheTableSeeds(long *seeds, int index)
Definition: Random.cc:151
std::string name() const
void setSeeds(const long *seeds, int lux=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 saveStatus(const char filename[]="Ranlux64.conf") const
static std::string beginTag()
void flatArray(const int size, double *vect)
void setSeed(long seed, int lux=1)
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:167
unsigned long operator()(unsigned long)
#define ns
Definition: xmlparse.cc:597