54 #include "CLHEP/Random/DualRand.h" 
   55 #include "CLHEP/Random/engineIDulong.h" 
   56 #include "CLHEP/Utility/atomic_int.h" 
   64   CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
 
   79   numEngines(numberOfEngines++),
 
   80   tausworthe (1234567 + numEngines + 175321),
 
   81   integerCong(69607 * tausworthe + 54329, numEngines)
 
   86 DualRand::DualRand(
long seed)
 
   89   tausworthe ((unsigned int)seed + 175321),
 
   90   integerCong(69607 * tausworthe + 54329, 8043) 
 
   95 DualRand::DualRand(std::istream & is) 
 
  102 DualRand::DualRand(
int rowIndex, 
int colIndex)
 
  105   tausworthe (rowIndex + 1000 * colIndex + 85329),
 
  106   integerCong(69607 * tausworthe + 54329, 1123) 
 
  111 DualRand::~DualRand() { }
 
  114   unsigned int ic ( integerCong );
 
  115   unsigned int t  ( tausworthe  );
 
  116   return ( (t  ^ ic) * twoToMinus_32() +              
 
  117            (t >> 11) * twoToMinus_53() +              
 
  118            nearlyTwoToMinus_54()                            
 
  122 void DualRand::flatArray(
const int size, 
double* vect) {
 
  123   for (
int i = 0; i < size; ++i) {
 
  128 void DualRand::setSeed(
long seed, 
int) {
 
  130   tausworthe  = Tausworthe((
unsigned int)seed + 175321);
 
  131   integerCong = IntegerCong(69607 * tausworthe + 54329, 8043);
 
  135   setSeed(seeds ? *seeds : 1234567, 0);
 
  139 void DualRand::saveStatus(
const char filename[])
 const {
 
  140   std::ofstream outFile(filename, std::ios::out);
 
  141   if (!outFile.bad()) {
 
  143     std::vector<unsigned long> v = put();
 
  144     for (
unsigned int i=0; i<v.size(); ++i) {
 
  145       outFile << v[i] << 
"\n";
 
  150 void DualRand::restoreStatus(
const char filename[]) {
 
  151   std::ifstream inFile(filename, std::ios::in);
 
  152   if (!checkFile ( inFile, filename, engineName(), 
"restoreStatus" )) { 
 
  153     std::cerr << 
"  -- Engine state remains unchanged\n";
 
  156   if ( possibleKeywordInput ( inFile, 
"Uvec", theSeed ) ) {
 
  157     std::vector<unsigned long> v;
 
  159     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  162         inFile.clear(std::ios::badbit | inFile.rdstate());
 
  163         std::cerr << 
"\nDualRand state (vector) description improper." 
  164                << 
"\nrestoreStatus has failed." 
  165                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  176     tausworthe.get(inFile);
 
  177     integerCong.get(inFile);
 
  181 void DualRand::showStatus()
 const {
 
  182   int pr=std::cout.precision(20);
 
  183   std::cout << std::endl;
 
  184   std::cout <<         
"-------- DualRand engine status ---------" 
  186   std::cout << 
"Initial seed          = " << theSeed << std::endl;
 
  187   std::cout << 
"Tausworthe generator  = " << std::endl;
 
  188   tausworthe.put(std::cout);
 
  189   std::cout << 
"\nIntegerCong generator = " << std::endl;
 
  190   integerCong.put(std::cout);
 
  191   std::cout << std::endl << 
"-----------------------------------------" 
  193   std::cout.precision(pr);
 
  196 DualRand::operator float() {
 
  197   return (
float) ( (integerCong ^ tausworthe) * twoToMinus_32() 
 
  198                                         + nearlyTwoToMinus_54()    ); 
 
  202 DualRand::operator 
unsigned int() {
 
  203   return (integerCong ^ tausworthe) & 0xffffffff;
 
  206 std::ostream & DualRand::put(std::ostream & os)
 const {
 
  207   char beginMarker[] = 
"DualRand-begin";
 
  208   os << beginMarker << 
"\nUvec\n";
 
  209   std::vector<unsigned long> v = put();
 
  210   for (
unsigned int i=0; i<v.size(); ++i) {
 
  216 std::vector<unsigned long> DualRand::put ()
 const {
 
  217   std::vector<unsigned long> v;
 
  218   v.push_back (engineIDulong<DualRand>());
 
  224 std::istream & DualRand::get(std::istream & is) {
 
  231   if (strcmp(beginMarker,
"DualRand-begin")) {
 
  232     is.clear(std::ios::badbit | is.rdstate());
 
  233     std::cerr << 
"\nInput mispositioned or" 
  234               << 
"\nDualRand state description missing or" 
  235               << 
"\nwrong engine type found." << std::endl;
 
  241 std::string DualRand::beginTag ( )  { 
 
  242   return "DualRand-begin"; 
 
  245 std::istream & DualRand::getState ( std::istream & is ) {
 
  246   if ( possibleKeywordInput ( is, 
"Uvec", theSeed ) ) {
 
  247     std::vector<unsigned long> v;
 
  249     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  252         is.clear(std::ios::badbit | is.rdstate());
 
  253         std::cerr << 
"\nDualRand state (vector) description improper." 
  254                 << 
"\ngetState() has failed." 
  255                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  272   if (strcmp(endMarker,
"DualRand-end")) {
 
  273     is.clear(std::ios::badbit | is.rdstate());
 
  274     std::cerr << 
"DualRand state description incomplete." 
  275               << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  281 bool DualRand::get(
const std::vector<unsigned long> & v) {
 
  282   if ((v[0] & 0xffffffffUL) != engineIDulong<DualRand>()) {
 
  284         "\nDualRand get:state vector has wrong ID word - state unchanged\n";
 
  287   if (v.size() != VECTOR_STATE_SIZE) {
 
  288     std::cerr << 
"\nDualRand get:state vector has wrong size: "  
  289     << v.size() << 
" - state unchanged\n";
 
  295 bool DualRand::getState (
const std::vector<unsigned long> & v) {
 
  296   std::vector<unsigned long>::const_iterator iv = v.begin()+1;
 
  297   if (!tausworthe.get(iv)) 
return false;
 
  298   if (!integerCong.get(iv)) 
return false;
 
  301         "\nDualRand get:state vector has wrong size: " << v.size() 
 
  302         << 
"\n         Apparently " << iv-v.begin() << 
" words were consumed\n";
 
  308 DualRand::Tausworthe::Tausworthe() {
 
  310   for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
 
  311     words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
 
  315 DualRand::Tausworthe::Tausworthe(
unsigned int seed) {
 
  317   for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
 
  318     words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
 
  322 DualRand::Tausworthe::operator 
unsigned int() {
 
  368   if (wordIndex <= 0) {
 
  369     for (wordIndex = 0; wordIndex < 4; ++wordIndex) {
 
  370       words[wordIndex] = ( (words[(wordIndex+1) & 3] << 1 ) |
 
  371                                    (words[wordIndex] >> 31)   )
 
  372                        ^ ( (words[(wordIndex+1) & 3] << 31) |
 
  373                                    (words[wordIndex] >>  1)   );
 
  376   return words[--wordIndex] & 0xffffffff;
 
  379 void DualRand::Tausworthe::put(std::ostream & os)
 const {
 
  380   char beginMarker[] = 
"Tausworthe-begin";
 
  381   char endMarker[]   = 
"Tausworthe-end";
 
  383   int pr=os.precision(20);
 
  384   os << 
" " << beginMarker << 
" ";
 
  385   for (
int i = 0; i < 4; ++i) {
 
  386     os << words[i] << 
" ";
 
  389   os << 
" " <<  endMarker  << 
" ";
 
  394 void DualRand::Tausworthe::put(std::vector<unsigned long> & v)
 const {
 
  395   for (
int i = 0; i < 4; ++i) {
 
  396     v.push_back(static_cast<unsigned long>(words[i]));
 
  398   v.push_back(static_cast<unsigned long>(wordIndex)); 
 
  401 void DualRand::Tausworthe::get(std::istream & is) {
 
  410   if (strcmp(beginMarker,
"Tausworthe-begin")) {
 
  411     is.clear(std::ios::badbit | is.rdstate());
 
  412     std::cerr << 
"\nInput mispositioned or" 
  413               << 
"\nTausworthe state description missing or" 
  414               << 
"\nwrong engine type found." << std::endl;
 
  416   for (
int i = 0; i < 4; ++i) {
 
  423   if (strcmp(endMarker,
"Tausworthe-end")) {
 
  424     is.clear(std::ios::badbit | is.rdstate());
 
  425     std::cerr << 
"\nTausworthe state description incomplete." 
  426               << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  431 DualRand::Tausworthe::get(std::vector<unsigned long>::const_iterator & iv){
 
  432   for (
int i = 0; i < 4; ++i) {
 
  439 DualRand::IntegerCong::IntegerCong() 
 
  440 : state((unsigned int)3758656018U),
 
  446 DualRand::IntegerCong::IntegerCong(
unsigned int seed, 
int streamNumber)
 
  448   multiplier(65536 + 1024 + 5 + (8 * 1017 * streamNumber)),
 
  466 DualRand::IntegerCong::operator 
unsigned int() {
 
  467   return state = (state * multiplier + addend) & 0xffffffff;
 
  470 void DualRand::IntegerCong::put(std::ostream & os)
 const {
 
  471   char beginMarker[] = 
"IntegerCong-begin";
 
  472   char endMarker[]   = 
"IntegerCong-end";
 
  474   int pr=os.precision(20);
 
  475   os << 
" " << beginMarker << 
" ";
 
  476   os << state << 
" " << multiplier << 
" " << addend;
 
  477   os << 
" " <<  endMarker  << 
" ";
 
  482 void DualRand::IntegerCong::put(std::vector<unsigned long> & v)
 const {
 
  483   v.push_back(static_cast<unsigned long>(state));
 
  484   v.push_back(static_cast<unsigned long>(multiplier));
 
  485   v.push_back(static_cast<unsigned long>(addend));
 
  488 void DualRand::IntegerCong::get(std::istream & is) {
 
  497   if (strcmp(beginMarker,
"IntegerCong-begin")) {
 
  498     is.clear(std::ios::badbit | is.rdstate());
 
  499     std::cerr << 
"\nInput mispositioned or" 
  500               << 
"\nIntegerCong state description missing or" 
  501               << 
"\nwrong engine type found." << std::endl;
 
  503   is >> state >> multiplier >> addend;
 
  507   if (strcmp(endMarker,
"IntegerCong-end")) {
 
  508     is.clear(std::ios::badbit | is.rdstate());
 
  509     std::cerr << 
"\nIntegerCong state description incomplete." 
  510               << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  515 DualRand::IntegerCong::get(std::vector<unsigned long>::const_iterator & iv) {
 
static const int MarkerLen
 
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.