40 #include "CLHEP/Random/Random.h" 
   41 #include "CLHEP/Random/RanecuEngine.h" 
   42 #include "CLHEP/Random/engineIDulong.h" 
   51 static const double prec = 4.6566128E-10;
 
   55 void RanecuEngine::further_randomize (
int seq1, 
int col, 
int index, 
int modulus)
 
   57   table[seq1][col] -= (index&0x3FFFFFFF);
 
   58   while (table[seq1][col] <= 0) table[seq1][col] += (modulus-1);
 
   62 int RanecuEngine::numEngines = 0;
 
   64 RanecuEngine::RanecuEngine()
 
   67   int cycle = std::abs(
int(numEngines/maxSeq));
 
   68   seq = std::abs(
int(numEngines%maxSeq));
 
   71   long mask = ((cycle & 0x007fffff) << 8);
 
   72   for (
int i=0; i<2; ++i) {
 
   73     for (
int j=0; j<maxSeq; ++j) {
 
   74       HepRandom::getTheTableSeeds(table[j],j);
 
   78   theSeeds = &table[seq][0];
 
   81 RanecuEngine::RanecuEngine(
int index)
 
   84   int cycle = std::abs(
int(index/maxSeq));
 
   85   seq = std::abs(
int(index%maxSeq));
 
   87   long mask = ((cycle & 0x000007ff) << 20);
 
   88   for (
int j=0; j<maxSeq; ++j) {
 
   89     HepRandom::getTheTableSeeds(table[j],j);
 
   93   theSeeds = &table[seq][0];
 
   94   further_randomize (seq, 0, index, shift1);     
 
   97 RanecuEngine::RanecuEngine(std::istream& is)
 
  103 RanecuEngine::~RanecuEngine() {}
 
  105 void RanecuEngine::setSeed(
long index, 
int dum)
 
  107   seq = std::abs(
int(index%maxSeq));
 
  109   HepRandom::getTheTableSeeds(table[seq],seq);
 
  110   theSeeds = &table[seq][0];
 
  111   further_randomize (seq, 0, index, shift1);     
 
  112   further_randomize (seq, 1, dum,   shift2);     
 
  118     seq = std::abs(
int(pos%maxSeq));
 
  122   table[seq][0] = std::abs(seeds[0])%shift1;
 
  123   table[seq][1] = std::abs(seeds[1])%shift2;
 
  124   theSeeds = &table[seq][0];
 
  127 void RanecuEngine::setIndex(
long index)
 
  129   seq = std::abs(
int(index%maxSeq));
 
  131   theSeeds = &table[seq][0];
 
  134 void RanecuEngine::saveStatus( 
const char filename[] )
 const 
  136    std::ofstream 
outFile( filename, std::ios::out ) ;
 
  140     std::vector<unsigned long> v = put();
 
  141     for (
unsigned int i=0; i<v.size(); ++i) {
 
  147 void RanecuEngine::restoreStatus( 
const char filename[] )
 
  149   std::ifstream inFile( filename, std::ios::in);
 
  150   if (!checkFile ( inFile, filename, engineName(), 
"restoreStatus" )) {
 
  151     std::cerr << 
"  -- Engine state remains unchanged\n";
 
  154   if ( possibleKeywordInput ( inFile, 
"Uvec", theSeed ) ) {
 
  155     std::vector<unsigned long> v;
 
  157     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  160         inFile.clear(std::ios::badbit | inFile.rdstate());
 
  161         std::cerr << 
"\nJamesRandom state (vector) description improper." 
  162                << 
"\nrestoreStatus has failed." 
  163                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  172   if (!inFile.bad() && !inFile.eof()) {
 
  174      for (
int i=0; i<2; ++i)
 
  175        inFile >> table[theSeed][i];
 
  180 void RanecuEngine::showStatus()
 const 
  182    std::cout << std::endl;
 
  183    std::cout << 
"--------- Ranecu engine status ---------" << std::endl;
 
  184    std::cout << 
" Initial seed (index) = " << theSeed << std::endl;
 
  185    std::cout << 
" Current couple of seeds = " 
  186              << table[theSeed][0] << 
", " 
  187              << table[theSeed][1] << std::endl;
 
  188    std::cout << 
"----------------------------------------" << std::endl;
 
  193    const int index = seq;
 
  194    long seed1 = table[index][0];
 
  195    long seed2 = table[index][1];
 
  197    int k1 = (int)(seed1/ecuyer_b);
 
  198    int k2 = (int)(seed2/ecuyer_e);
 
  200    seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
 
  201    if (seed1 < 0) seed1 += shift1;
 
  202    seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
 
  203    if (seed2 < 0) seed2 += shift2;
 
  205    table[index][0] = seed1;
 
  206    table[index][1] = seed2;
 
  208    long diff = seed1-seed2;
 
  210    if (diff <= 0) diff += (shift1-1);
 
  211    return (
double)(diff*
prec);
 
  214 void RanecuEngine::flatArray(
const int size, 
double* vect)
 
  216    const int index = seq;
 
  217    long seed1 = table[index][0];
 
  218    long seed2 = table[index][1];
 
  222    for (i=0; i<size; ++i)
 
  224      k1 = (int)(seed1/ecuyer_b);
 
  225      k2 = (int)(seed2/ecuyer_e);
 
  227      seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
 
  228      if (seed1 < 0) seed1 += shift1;
 
  229      seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
 
  230      if (seed2 < 0) seed2 += shift2;
 
  232      long diff = seed1-seed2;
 
  233      if (diff <= 0) diff += (shift1-1);
 
  235      vect[i] = (double)(diff*prec);
 
  237    table[index][0] = seed1;
 
  238    table[index][1] = seed2;
 
  241 RanecuEngine::operator 
unsigned int() {
 
  242    const int index = seq;
 
  243    long seed1 = table[index][0];
 
  244    long seed2 = table[index][1];
 
  246    int k1 = (int)(seed1/ecuyer_b);
 
  247    int k2 = (int)(seed2/ecuyer_e);
 
  249    seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
 
  250    if (seed1 < 0) seed1 += shift1;
 
  251    seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
 
  252    if (seed2 < 0) seed2 += shift2;
 
  254    table[index][0] = seed1;
 
  255    table[index][1] = seed2;
 
  256    long diff = seed1-seed2;
 
  257    if( diff <= 0 ) diff += (shift1-1);
 
  259    return ((diff << 1) | (seed1&1))& 0xffffffff;
 
  262 std::ostream & RanecuEngine::put( std::ostream& os )
 const 
  264    char beginMarker[] = 
"RanecuEngine-begin";
 
  265   os << beginMarker << 
"\nUvec\n";
 
  266   std::vector<unsigned long> v = put();
 
  267   for (
unsigned int i=0; i<v.size(); ++i) {
 
  273 std::vector<unsigned long> RanecuEngine::put ()
 const {
 
  274   std::vector<unsigned long> v;
 
  275   v.push_back (engineIDulong<RanecuEngine>());
 
  276   v.push_back(static_cast<unsigned long>(theSeed));
 
  277   v.push_back(static_cast<unsigned long>(table[theSeed][0]));
 
  278   v.push_back(static_cast<unsigned long>(table[theSeed][1]));
 
  282 std::istream & RanecuEngine::get ( std::istream& is )
 
  291   if (strcmp(beginMarker,
"RanecuEngine-begin")) {
 
  292      is.clear(std::ios::badbit | is.rdstate());
 
  293      std::cerr << 
"\nInput stream mispositioned or" 
  294                << 
"\nRanecuEngine state description missing or" 
  295                << 
"\nwrong engine type found." << std::endl;
 
  301 std::string RanecuEngine::beginTag ( )  { 
 
  302   return "RanecuEngine-begin"; 
 
  305 std::istream & RanecuEngine::getState ( std::istream& is )
 
  307   if ( possibleKeywordInput ( is, 
"Uvec", theSeed ) ) {
 
  308     std::vector<unsigned long> v;
 
  310     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  313         is.clear(std::ios::badbit | is.rdstate());
 
  314         std::cerr << 
"\nRanecuEngine state (vector) description improper." 
  315                 << 
"\ngetState() has failed." 
  316                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  327    for (
int i=0; i<2; ++i) {
 
  328      is >> table[theSeed][i];
 
  333   if (strcmp(endMarker,
"RanecuEngine-end")) {
 
  334      is.clear(std::ios::badbit | is.rdstate());
 
  335      std::cerr << 
"\nRanecuEngine state description incomplete." 
  336                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  344 bool RanecuEngine::get (
const std::vector<unsigned long> & v) {
 
  345   if ((v[0] & 0xffffffffUL) != engineIDulong<RanecuEngine>()) {
 
  347         "\nRanecuEngine get:state vector has wrong ID word - state unchanged\n";
 
  353 bool RanecuEngine::getState (
const std::vector<unsigned long> & v) {
 
  354   if (v.size() != VECTOR_STATE_SIZE ) {
 
  356         "\nRanecuEngine get:state vector has wrong length - state unchanged\n";
 
  360   table[theSeed][0] = v[2];
 
  361   table[theSeed][1] = v[3];
 
static const int MarkerLen
static const G4double pos
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.