40 #include "CLHEP/Random/Random.h" 
   41 #include "CLHEP/Random/RanluxEngine.h" 
   42 #include "CLHEP/Random/engineIDulong.h" 
   54 int RanluxEngine::numEngines = 0;
 
   57 int RanluxEngine::maxIndex = 215;
 
   59 RanluxEngine::RanluxEngine(
long seed, 
int lux)
 
   62    long seedlist[2]={0,0};
 
   65    setSeed(seed, luxury);
 
   73 RanluxEngine::RanluxEngine()
 
   77    long seedlist[2]={0,0};
 
   80    int cycle = std::abs(
int(numEngines/maxIndex));
 
   81    int curIndex = std::abs(
int(numEngines%maxIndex));
 
   83    long mask = ((cycle & 0x007fffff) << 8);
 
   84    HepRandom::getTheTableSeeds( seedlist, curIndex );
 
   85    seed = seedlist[0]^mask;
 
   86    setSeed(seed, luxury);
 
   94 RanluxEngine::RanluxEngine(
int rowIndex, 
int colIndex, 
int lux)
 
   98    long seedlist[2]={0,0};
 
  101    int cycle = std::abs(
int(rowIndex/maxIndex));
 
  102    int row = std::abs(
int(rowIndex%maxIndex));
 
  103    int col = std::abs(
int(colIndex%2));
 
  104    long mask = (( cycle & 0x000007ff ) << 20 );
 
  105    HepRandom::getTheTableSeeds( seedlist, row );
 
  106    seed = ( seedlist[col] )^mask;
 
  107    setSeed(seed, luxury);
 
  115 RanluxEngine::RanluxEngine( std::istream& is )
 
  121 RanluxEngine::~RanluxEngine() {}
 
  123 void RanluxEngine::setSeed(
long seed, 
int lux) {
 
  131   const int ecuyer_a = 53668;
 
  132   const int ecuyer_b = 40014;
 
  133   const int ecuyer_c = 12211;
 
  134   const int ecuyer_d = 2147483563;
 
  136   const int lux_levels[5] = {0,24,73,199,365};  
 
  138   long int_seed_table[24];
 
  139   long next_seed = seed;
 
  147   if( (lux > 4)||(lux < 0) ){
 
  151         nskip = lux_levels[3]; 
 
  155      nskip = lux_levels[luxury];
 
  159   for(i = 0;i != 24;i++){
 
  160      k_multiple = next_seed / ecuyer_a;
 
  161      next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 
 
  162      - k_multiple * ecuyer_c ;
 
  163      if(next_seed < 0)next_seed += ecuyer_d;
 
  164      int_seed_table[i] = next_seed % int_modulus;
 
  167   for(i = 0;i != 24;i++)
 
  168     float_seed_table[i] = int_seed_table[i] * mantissa_bit_24();
 
  174   if( float_seed_table[23] == 0. ) carry = mantissa_bit_24();
 
  181    const int ecuyer_a = 53668;
 
  182    const int ecuyer_b = 40014;
 
  183    const int ecuyer_c = 12211;
 
  184    const int ecuyer_d = 2147483563;
 
  186    const int lux_levels[5] = {0,24,73,199,365};
 
  188    long int_seed_table[24];
 
  189    long k_multiple,next_seed;
 
  196       setSeed(theSeed,lux);
 
  206   if( (lux > 4)||(lux < 0) ){
 
  210         nskip = lux_levels[3]; 
 
  214      nskip = lux_levels[luxury];
 
  217   for( i = 0;(i != 24)&&(*seedptr != 0);i++){
 
  218       int_seed_table[i] = *seedptr % int_modulus;
 
  223      next_seed = int_seed_table[i-1];
 
  225         k_multiple = next_seed / ecuyer_a;
 
  226         next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 
 
  227         - k_multiple * ecuyer_c ;
 
  228         if(next_seed < 0)next_seed += ecuyer_d;
 
  229         int_seed_table[i] = next_seed % int_modulus;
 
  233   for(i = 0;i != 24;i++)
 
  234     float_seed_table[i] = int_seed_table[i] * mantissa_bit_24();
 
  240   if( float_seed_table[23] == 0. ) carry = mantissa_bit_24();
 
  245 void RanluxEngine::saveStatus( 
const char filename[] )
 const 
  247    std::ofstream 
outFile( filename, std::ios::out ) ;
 
  250     std::vector<unsigned long> v = put();
 
  251     for (
unsigned int i=0; i<v.size(); ++i) {
 
  257 void RanluxEngine::restoreStatus( 
const char filename[] )
 
  259    std::ifstream inFile( filename, std::ios::in);
 
  260    if (!checkFile ( inFile, filename, engineName(), 
"restoreStatus" )) {
 
  261      std::cerr << 
"  -- Engine state remains unchanged\n";
 
  264   if ( possibleKeywordInput ( inFile, 
"Uvec", theSeed ) ) {
 
  265     std::vector<unsigned long> v;
 
  267     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  270         inFile.clear(std::ios::badbit | inFile.rdstate());
 
  271         std::cerr << 
"\nRanluxEngine state (vector) description improper." 
  272                << 
"\nrestoreStatus has failed." 
  273                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  282    if (!inFile.bad() && !inFile.eof()) {
 
  284      for (
int i=0; i<24; ++i)
 
  285        inFile >> float_seed_table[i];
 
  286      inFile >> i_lag; inFile >> j_lag;
 
  287      inFile >> carry; inFile >> count24;
 
  288      inFile >> luxury; inFile >> nskip;
 
  292 void RanluxEngine::showStatus()
 const 
  294    std::cout << std::endl;
 
  295    std::cout << 
"--------- Ranlux engine status ---------" << std::endl;
 
  296    std::cout << 
" Initial seed = " << theSeed << std::endl;
 
  297    std::cout << 
" float_seed_table[] = ";
 
  298    for (
int i=0; i<24; ++i)
 
  299      std::cout << float_seed_table[i] << 
" ";
 
  300    std::cout << std::endl;
 
  301    std::cout << 
" i_lag = " << i_lag << 
", j_lag = " << j_lag << std::endl;
 
  302    std::cout << 
" carry = " << carry << 
", count24 = " << count24 << std::endl;
 
  303    std::cout << 
" luxury = " << luxury << 
" nskip = " << nskip << std::endl;
 
  304    std::cout << 
"----------------------------------------" << std::endl;
 
  313   uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  316      carry = mantissa_bit_24();
 
  321   float_seed_table[i_lag] = uni;
 
  324   if(i_lag < 0) i_lag = 23;
 
  325   if(j_lag < 0) j_lag = 23;
 
  327   if( uni < mantissa_bit_12() ){
 
  328      uni += mantissa_bit_24() * float_seed_table[j_lag];
 
  329      if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24();
 
  339      for( i = 0; i != nskip ; i++){
 
  340          uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  343             carry = mantissa_bit_24();
 
  347          float_seed_table[i_lag] = uni;
 
  350          if(i_lag < 0)i_lag = 23;
 
  351          if(j_lag < 0) j_lag = 23;
 
  354   return (
double) next_random;
 
  357 void RanluxEngine::flatArray(
const int size, 
double* vect)
 
  364   for (index=0; index<size; ++index) {
 
  365     uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  368        carry = mantissa_bit_24();
 
  373     float_seed_table[i_lag] = uni;
 
  376     if(i_lag < 0) i_lag = 23;
 
  377     if(j_lag < 0) j_lag = 23;
 
  379     if( uni < mantissa_bit_12() ){
 
  380        uni += mantissa_bit_24() * float_seed_table[j_lag];
 
  381        if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24();
 
  384     vect[index] = (double)next_random;
 
  392        for( i = 0; i != nskip ; i++){
 
  393            uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  396               carry = mantissa_bit_24();
 
  400            float_seed_table[i_lag] = uni;
 
  403            if(i_lag < 0)i_lag = 23;
 
  404            if(j_lag < 0) j_lag = 23;
 
  410 RanluxEngine::operator 
unsigned int() {
 
  411    return ((
unsigned int)(
flat() * exponent_bit_32()) & 0xffffffff) |
 
  412          (((
unsigned int)(float_seed_table[i_lag]*exponent_bit_32())>>16) & 0xff);
 
  417 std::ostream & RanluxEngine::put ( std::ostream& os )
 const 
  419    char beginMarker[] = 
"RanluxEngine-begin";
 
  420   os << beginMarker << 
"\nUvec\n";
 
  421   std::vector<unsigned long> v = put();
 
  422   for (
unsigned int i=0; i<v.size(); ++i) {
 
  428 std::vector<unsigned long> RanluxEngine::put ()
 const {
 
  429   std::vector<unsigned long> v;
 
  430   v.push_back (engineIDulong<RanluxEngine>());
 
  431   for (
int i=0; i<24; ++i) {
 
  433         (static_cast<unsigned long>(float_seed_table[i]/mantissa_bit_24()));
 
  435   v.push_back(static_cast<unsigned long>(i_lag));
 
  436   v.push_back(static_cast<unsigned long>(j_lag));
 
  437   v.push_back(static_cast<unsigned long>(carry/mantissa_bit_24()));
 
  438   v.push_back(static_cast<unsigned long>(count24));
 
  439   v.push_back(static_cast<unsigned long>(luxury));
 
  440   v.push_back(static_cast<unsigned long>(nskip));
 
  444 std::istream & RanluxEngine::get ( std::istream& is )
 
  452   if (strcmp(beginMarker,
"RanluxEngine-begin")) {
 
  453      is.clear(std::ios::badbit | is.rdstate());
 
  454      std::cerr << 
"\nInput stream mispositioned or" 
  455                << 
"\nRanluxEngine state description missing or" 
  456                << 
"\nwrong engine type found." << std::endl;
 
  462 std::string RanluxEngine::beginTag ( )  { 
 
  463   return "RanluxEngine-begin"; 
 
  466 std::istream & RanluxEngine::getState ( std::istream& is )
 
  468   if ( possibleKeywordInput ( is, 
"Uvec", theSeed ) ) {
 
  469     std::vector<unsigned long> v;
 
  471     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  474         is.clear(std::ios::badbit | is.rdstate());
 
  475         std::cerr << 
"\nRanluxEngine state (vector) description improper." 
  476                 << 
"\ngetState() has failed." 
  477                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  489   for (
int i=0; i<24; ++i) {
 
  490      is >> float_seed_table[i];
 
  492   is >> i_lag; is >>  j_lag;
 
  493   is >> carry; is >> count24;
 
  494   is >> luxury; is >> nskip;
 
  498   if (strcmp(endMarker,
"RanluxEngine-end")) {
 
  499      is.clear(std::ios::badbit | is.rdstate());
 
  500      std::cerr << 
"\nRanluxEngine state description incomplete." 
  501                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  507 bool RanluxEngine::get (
const std::vector<unsigned long> & v) {
 
  508   if ((v[0] & 0xffffffffUL) != engineIDulong<RanluxEngine>()) {
 
  510         "\nRanluxEngine get:state vector has wrong ID word - state unchanged\n";
 
  516 bool RanluxEngine::getState (
const std::vector<unsigned long> & v) {
 
  517   if (v.size() != VECTOR_STATE_SIZE ) {
 
  519         "\nRanluxEngine get:state vector has wrong length - state unchanged\n";
 
  522   for (
int i=0; i<24; ++i) {
 
  523     float_seed_table[i] = v[i+1]*mantissa_bit_24();
 
  527   carry    = v[27]*mantissa_bit_24();
 
static const int MarkerLen
 
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.