40 #include "CLHEP/Random/Random.h" 
   41 #include "CLHEP/Random/RanluxEngine.h" 
   42 #include "CLHEP/Random/engineIDulong.h" 
   43 #include "CLHEP/Utility/atomic_int.h" 
   52   CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
 
   55   const int maxIndex = 215;
 
   62 RanluxEngine::RanluxEngine(
long seed, 
int lux)
 
   65    long seedlist[2]={0,0};
 
   68    setSeed(seed, luxury);
 
   76 RanluxEngine::RanluxEngine()
 
   80    long seedlist[2]={0,0};
 
   83    int numEngines = numberOfEngines++;
 
   84    int cycle = std::abs(
int(numEngines/maxIndex));
 
   85    int curIndex = std::abs(
int(numEngines%maxIndex));
 
   87    long mask = ((cycle & 0x007fffff) << 8);
 
   88    HepRandom::getTheTableSeeds( seedlist, curIndex );
 
   89    seed = seedlist[0]^
mask;
 
   90    setSeed(seed, luxury);
 
   98 RanluxEngine::RanluxEngine(
int rowIndex, 
int colIndex, 
int lux)
 
  102    long seedlist[2]={0,0};
 
  105    int cycle = std::abs(
int(rowIndex/maxIndex));
 
  106    int row = std::abs(
int(rowIndex%maxIndex));
 
  107    int col = std::abs(
int(colIndex%2));
 
  108    long mask = (( cycle & 0x000007ff ) << 20 );
 
  109    HepRandom::getTheTableSeeds( seedlist, row );
 
  110    seed = ( seedlist[col] )^mask;
 
  111    setSeed(seed, luxury);
 
  119 RanluxEngine::RanluxEngine( std::istream& is )
 
  125 RanluxEngine::~RanluxEngine() {}
 
  127 void RanluxEngine::setSeed(
long seed, 
int lux) {
 
  135   const int ecuyer_a = 53668;
 
  136   const int ecuyer_b = 40014;
 
  137   const int ecuyer_c = 12211;
 
  138   const int ecuyer_d = 2147483563;
 
  140   const int lux_levels[5] = {0,24,73,199,365};  
 
  142   long int_seed_table[24];
 
  143   long next_seed = seed;
 
  151   if( (lux > 4)||(lux < 0) ){
 
  155         nskip = lux_levels[3]; 
 
  159      nskip = lux_levels[luxury];
 
  163   for(i = 0;i != 24;i++){
 
  164      k_multiple = next_seed / ecuyer_a;
 
  165      next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 
 
  166      - k_multiple * ecuyer_c ;
 
  167      if(next_seed < 0)next_seed += ecuyer_d;
 
  168      int_seed_table[i] = next_seed % int_modulus;
 
  171   for(i = 0;i != 24;i++)
 
  172     float_seed_table[i] = int_seed_table[i] * mantissa_bit_24();
 
  178   if( float_seed_table[23] == 0. ) carry = mantissa_bit_24();
 
  185    const int ecuyer_a = 53668;
 
  186    const int ecuyer_b = 40014;
 
  187    const int ecuyer_c = 12211;
 
  188    const int ecuyer_d = 2147483563;
 
  190    const int lux_levels[5] = {0,24,73,199,365};
 
  192    long int_seed_table[24];
 
  193    long k_multiple,next_seed;
 
  200       setSeed(theSeed,lux);
 
  210   if( (lux > 4)||(lux < 0) ){
 
  214         nskip = lux_levels[3]; 
 
  218      nskip = lux_levels[luxury];
 
  221   for( i = 0;(i != 24)&&(*seedptr != 0);i++){
 
  222       int_seed_table[i] = *seedptr % int_modulus;
 
  227      next_seed = int_seed_table[i-1];
 
  229         k_multiple = next_seed / ecuyer_a;
 
  230         next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a) 
 
  231         - k_multiple * ecuyer_c ;
 
  232         if(next_seed < 0)next_seed += ecuyer_d;
 
  233         int_seed_table[i] = next_seed % int_modulus;
 
  237   for(i = 0;i != 24;i++)
 
  238     float_seed_table[i] = int_seed_table[i] * mantissa_bit_24();
 
  244   if( float_seed_table[23] == 0. ) carry = mantissa_bit_24();
 
  249 void RanluxEngine::saveStatus( 
const char filename[] )
 const 
  251    std::ofstream outFile( filename, std::ios::out ) ;
 
  252   if (!outFile.bad()) {
 
  254     std::vector<unsigned long> v = put();
 
  255     for (
unsigned int i=0; i<v.size(); ++i) {
 
  256       outFile << v[i] << 
"\n";
 
  261 void RanluxEngine::restoreStatus( 
const char filename[] )
 
  263    std::ifstream inFile( filename, std::ios::in);
 
  264    if (!checkFile ( inFile, filename, engineName(), 
"restoreStatus" )) {
 
  265      std::cerr << 
"  -- Engine state remains unchanged\n";
 
  268   if ( possibleKeywordInput ( inFile, 
"Uvec", theSeed ) ) {
 
  269     std::vector<unsigned long> v;
 
  271     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  274         inFile.clear(std::ios::badbit | inFile.rdstate());
 
  275         std::cerr << 
"\nRanluxEngine state (vector) description improper." 
  276                << 
"\nrestoreStatus has failed." 
  277                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  286    if (!inFile.bad() && !inFile.eof()) {
 
  288      for (
int i=0; i<24; ++i)
 
  289        inFile >> float_seed_table[i];
 
  290      inFile >> i_lag; inFile >> j_lag;
 
  291      inFile >> carry; inFile >> count24;
 
  292      inFile >> luxury; inFile >> nskip;
 
  296 void RanluxEngine::showStatus()
 const 
  298    std::cout << std::endl;
 
  299    std::cout << 
"--------- Ranlux engine status ---------" << std::endl;
 
  300    std::cout << 
" Initial seed = " << theSeed << std::endl;
 
  301    std::cout << 
" float_seed_table[] = ";
 
  302    for (
int i=0; i<24; ++i)
 
  303      std::cout << float_seed_table[i] << 
" ";
 
  304    std::cout << std::endl;
 
  305    std::cout << 
" i_lag = " << i_lag << 
", j_lag = " << j_lag << std::endl;
 
  306    std::cout << 
" carry = " << carry << 
", count24 = " << count24 << std::endl;
 
  307    std::cout << 
" luxury = " << luxury << 
" nskip = " << nskip << std::endl;
 
  308    std::cout << 
"----------------------------------------" << std::endl;
 
  317   uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  320      carry = mantissa_bit_24();
 
  325   float_seed_table[i_lag] = uni;
 
  328   if(i_lag < 0) i_lag = 23;
 
  329   if(j_lag < 0) j_lag = 23;
 
  331   if( uni < mantissa_bit_12() ){
 
  332      uni += mantissa_bit_24() * float_seed_table[j_lag];
 
  333      if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24();
 
  343      for( i = 0; i != nskip ; i++){
 
  344          uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  347             carry = mantissa_bit_24();
 
  351          float_seed_table[i_lag] = uni;
 
  354          if(i_lag < 0)i_lag = 23;
 
  355          if(j_lag < 0) j_lag = 23;
 
  358   return (
double) next_random;
 
  361 void RanluxEngine::flatArray(
const int size, 
double* vect)
 
  368   for (index=0; index<size; ++index) {
 
  369     uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  372        carry = mantissa_bit_24();
 
  377     float_seed_table[i_lag] = uni;
 
  380     if(i_lag < 0) i_lag = 23;
 
  381     if(j_lag < 0) j_lag = 23;
 
  383     if( uni < mantissa_bit_12() ){
 
  384        uni += mantissa_bit_24() * float_seed_table[j_lag];
 
  385        if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24();
 
  388     vect[index] = (double)next_random;
 
  396        for( i = 0; i != nskip ; i++){
 
  397            uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
 
  400               carry = mantissa_bit_24();
 
  404            float_seed_table[i_lag] = uni;
 
  407            if(i_lag < 0)i_lag = 23;
 
  408            if(j_lag < 0) j_lag = 23;
 
  414 RanluxEngine::operator 
unsigned int() {
 
  415    return ((
unsigned int)(
flat() * exponent_bit_32()) & 0xffffffff) |
 
  416          (((
unsigned int)(float_seed_table[i_lag]*exponent_bit_32())>>16) & 0xff);
 
  421 std::ostream & RanluxEngine::put ( std::ostream& os )
 const 
  423    char beginMarker[] = 
"RanluxEngine-begin";
 
  424   os << beginMarker << 
"\nUvec\n";
 
  425   std::vector<unsigned long> v = put();
 
  426   for (
unsigned int i=0; i<v.size(); ++i) {
 
  432 std::vector<unsigned long> RanluxEngine::put ()
 const {
 
  433   std::vector<unsigned long> v;
 
  434   v.push_back (engineIDulong<RanluxEngine>());
 
  435   for (
int i=0; i<24; ++i) {
 
  437         (static_cast<unsigned long>(float_seed_table[i]/mantissa_bit_24()));
 
  439   v.push_back(static_cast<unsigned long>(i_lag));
 
  440   v.push_back(static_cast<unsigned long>(j_lag));
 
  441   v.push_back(static_cast<unsigned long>(carry/mantissa_bit_24()));
 
  442   v.push_back(static_cast<unsigned long>(count24));
 
  443   v.push_back(static_cast<unsigned long>(luxury));
 
  444   v.push_back(static_cast<unsigned long>(nskip));
 
  448 std::istream & RanluxEngine::get ( std::istream& is )
 
  456   if (strcmp(beginMarker,
"RanluxEngine-begin")) {
 
  457      is.clear(std::ios::badbit | is.rdstate());
 
  458      std::cerr << 
"\nInput stream mispositioned or" 
  459                << 
"\nRanluxEngine state description missing or" 
  460                << 
"\nwrong engine type found." << std::endl;
 
  466 std::string RanluxEngine::beginTag ( )  { 
 
  467   return "RanluxEngine-begin"; 
 
  470 std::istream & RanluxEngine::getState ( std::istream& is )
 
  472   if ( possibleKeywordInput ( is, 
"Uvec", theSeed ) ) {
 
  473     std::vector<unsigned long> v;
 
  475     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  478         is.clear(std::ios::badbit | is.rdstate());
 
  479         std::cerr << 
"\nRanluxEngine state (vector) description improper." 
  480                 << 
"\ngetState() has failed." 
  481                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  493   for (
int i=0; i<24; ++i) {
 
  494      is >> float_seed_table[i];
 
  496   is >> i_lag; is >>  j_lag;
 
  497   is >> carry; is >> count24;
 
  498   is >> luxury; is >> nskip;
 
  502   if (strcmp(endMarker,
"RanluxEngine-end")) {
 
  503      is.clear(std::ios::badbit | is.rdstate());
 
  504      std::cerr << 
"\nRanluxEngine state description incomplete." 
  505                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  511 bool RanluxEngine::get (
const std::vector<unsigned long> & v) {
 
  512   if ((v[0] & 0xffffffffUL) != engineIDulong<RanluxEngine>()) {
 
  514         "\nRanluxEngine get:state vector has wrong ID word - state unchanged\n";
 
  520 bool RanluxEngine::getState (
const std::vector<unsigned long> & v) {
 
  521   if (v.size() != VECTOR_STATE_SIZE ) {
 
  523         "\nRanluxEngine get:state vector has wrong length - state unchanged\n";
 
  526   for (
int i=0; i<24; ++i) {
 
  527     float_seed_table[i] = v[i+1]*mantissa_bit_24();
 
  531   carry    = v[27]*mantissa_bit_24();
 
static const int MarkerLen
 
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.