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>
90 unsigned long operator()(
unsigned long value) {
return value >>
n; }
92template< std::
size_t n >
93 struct do_right_shift<
n,false>
98template< std::
size_t nbits >
99 unsigned long rshift(
unsigned long value )
100{
return do_right_shift<nbits>()(value); }
113 int curIndex = std::abs(
int(numEngines%
maxIndex));
115 long mask = ((
cycle & 0x007fffff) << 8);
131 long seedlist[2]={seed,0};
142 int row = std::abs(
int(rowIndex%
maxIndex));
143 long mask = ((
cycle & 0x000007ff ) << 20 );
238 for (
m=0;
m<12;
m++) {
243 for (
m=11;
m>=0; --
m) {
285 for ( k = dozens; k > 0; --k ) {
377 for(
int i=0; i < size; ++i ) {
390 const int ecuyer_a(53668);
391 const int ecuyer_b(40014);
392 const int ecuyer_c(12211);
393 const int ecuyer_d(2147483563);
395 const int lux_levels[3] = {109, 202, 397};
398 if( (
lux > 2)||(
lux < 0) ){
407 long next_seed = seed;
410 next_seed &= 0xffffffff;
411 while( next_seed >= ecuyer_d ) {
412 next_seed -= ecuyer_d;
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;
420 next_seed += ecuyer_d;
422 next_seed &= 0xffffffff;
423 init_table[i] = next_seed;
426 if(
sizeof(
long) >= 8 ) {
427 int64_t topbits1, topbits2;
429 topbits1 = ( (int64_t) seed >> 32) & 0xffff ;
430 topbits2 = ( (int64_t) seed >> 48) & 0xffff ;
432 topbits1 = detail::rshift<32>(seed) & 0xffff ;
433 topbits2 = detail::rshift<48>(seed) & 0xffff ;
435 init_table[0] ^= topbits1;
436 init_table[2] ^= topbits2;
441 for(i = 0;i < 12; i++){
466 const int ecuyer_a = 53668;
467 const int ecuyer_b = 40014;
468 const int ecuyer_c = 12211;
469 const int ecuyer_d = 2147483563;
471 const int lux_levels[3] = {109, 202, 397};
488 if( (
lux > 2)||(
lux < 0) ){
497 long next_seed = *seeds;
501 for( i = 0;(i != 24)&&(*seedptr != 0);i++){
502 init_table[i] = *seedptr & 0xffffffff;
507 next_seed = init_table[i-1];
509 k_multiple = next_seed / ecuyer_a;
510 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
511 - k_multiple * ecuyer_c;
513 next_seed += ecuyer_d;
515 next_seed &= 0xffffffff;
516 init_table[i] = next_seed;
520 for(i = 0;i < 12; i++){
534 std::ofstream outFile( filename, std::ios::out ) ;
535 if (!outFile.bad()) {
537 std::vector<unsigned long> v =
put();
538 for (
unsigned int i=0; i<v.size(); ++i) {
539 outFile << v[i] <<
"\n";
546 std::ifstream inFile( filename, std::ios::in);
548 std::cerr <<
" -- Engine state remains unchanged\n";
552 std::vector<unsigned long> v;
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;
569 if (!inFile.bad() && !inFile.eof()) {
571 for (
int i=0; i<12; ++i) {
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;
590 std::cout << std::endl;
591 std::cout <<
" carry = " <<
carry <<
", index = " <<
index << std::endl;
592 std::cout <<
" luxury = " <<
luxury <<
" pDiscard = "
594 std::cout <<
"----------------------------------------" << std::endl;
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) {
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) {
614 v.push_back(t[0]); v.push_back(t[1]);
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));
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;
643 return "Ranlux64Engine-begin";
649 std::vector<unsigned long> v;
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;
669 for (
int i=0; i<12; ++i) {
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;
689 if ((v[0] & 0xffffffffUL) != engineIDulong<Ranlux64Engine>()) {
691 "\nRanlux64Engine get:state vector has wrong ID word - state unchanged\n";
700 "\nRanlux64Engine get:state vector has wrong length - state unchanged\n";
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];
708 t[0] = v[25]; t[1] = v[26];
#define CLHEP_ATOMIC_INT_TYPE
static double longs2double(const std::vector< unsigned long > &v)
static std::vector< unsigned long > dto2longs(double d)
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)
static void getTheTableSeeds(long *seeds, int index)
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)
virtual ~Ranlux64Engine()
CLHEP_ATOMIC_INT_TYPE numberOfEngines(0)
unsigned long rshift(unsigned long value)
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
static const int MarkerLen
static constexpr double ns
static constexpr double lux
static constexpr double m
static const G4LorentzVector zero(0., 0., 0., 0.)
unsigned long operator()(unsigned long)