37 #include "CLHEP/Random/RanshiEngine.h" 
   38 #include "CLHEP/Random/engineIDulong.h" 
   39 #include "CLHEP/Utility/atomic_int.h" 
   46   #if __GNUC__ > 3 && __GNUC_MINOR__ > 8 
   47     #pragma GCC diagnostic push 
   48     #pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" 
   56   CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
 
   63 RanshiEngine::RanshiEngine()
 
   65   halfBuff(0), numFlats(0) 
 
   67   int numEngines = numberOfEngines++;
 
   70     buffer[i] = (
unsigned int)((numEngines+19780503
L*(i+1))& 0xffffffff);
 
   73   theSeed = numEngines+19780503
L*++i;
 
   74   redSpin = (
unsigned int)(theSeed & 0xffffffff);
 
   76   for( i = 0; i < 10000; ++i) 
flat();  
 
   79 RanshiEngine::RanshiEngine(std::istream& is)
 
   81   halfBuff(0), numFlats(0) 
 
   86 RanshiEngine::RanshiEngine(
long seed)
 
   88   halfBuff(0), numFlats(0) 
 
   90   for (
int i = 0; i < numBuff; ++i) {
 
   91     buffer[i] = (
unsigned int)seed&0xffffffff;
 
   94   redSpin = (
unsigned int)(theSeed & 0xffffffff);
 
   96   for (j = 0; j < numBuff*20; ++j) {      
 
  101 RanshiEngine::RanshiEngine(
int rowIndex, 
int colIndex)
 
  103   halfBuff(0), numFlats(0) 
 
  106   while( i < numBuff ) {
 
  107     buffer[i] = (
unsigned int)((rowIndex + (i+1)*(colIndex+8))&0xffffffff);
 
  111   redSpin = colIndex & 0xffffffff;
 
  112   for( i = 0; i < 100; ++i) 
flat();    
 
  115 RanshiEngine::~RanshiEngine() { }
 
  118   unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
 
  119   unsigned int blkSpin     = 
buffer[redAngle] & 0xffffffff;
 
  120   unsigned int boostResult = blkSpin ^ redSpin;
 
  122   buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
 
  124   redSpin  = (blkSpin + numFlats++) & 0xffffffff;
 
  125   halfBuff = numBuff/2 - halfBuff;
 
  127   return ( blkSpin * twoToMinus_32() +            
 
  128            (boostResult>>11) * twoToMinus_53() +  
 
  129            nearlyTwoToMinus_54());              
 
  132 void RanshiEngine::flatArray(
const int size, 
double* vect) {
 
  133   for (
int i = 0; i < size; ++i) {
 
  138 void RanshiEngine::setSeed(
long seed, 
int) {
 
  139   *
this = RanshiEngine(seed); 
 
  145     while (seeds[i] && i < numBuff) {
 
  146       buffer[i] = (
unsigned int)seeds[i];
 
  149     while (i < numBuff) {
 
  154     redSpin = (
unsigned int)theSeed;
 
  159 void RanshiEngine::saveStatus(
const char filename[])
 const {
 
  160   std::ofstream outFile(filename, std::ios::out);
 
  161   if (!outFile.bad()) {
 
  163     std::vector<unsigned long> v = put();
 
  164     for (
unsigned int i=0; i<v.size(); ++i) {
 
  165       outFile << v[i] << 
"\n";
 
  170 void RanshiEngine::restoreStatus(
const char filename[]) {
 
  171   std::ifstream inFile(filename, std::ios::in);
 
  172   if (!checkFile ( inFile, filename, engineName(), 
"restoreStatus" )) {
 
  173     std::cerr << 
"  -- Engine state remains unchanged\n";
 
  176   if ( possibleKeywordInput ( inFile, 
"Uvec", theSeed ) ) {
 
  177     std::vector<unsigned long> v;
 
  179     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  182         inFile.clear(std::ios::badbit | inFile.rdstate());
 
  183         std::cerr << 
"\nRanshiEngine state (vector) description improper." 
  184                << 
"\nrestoreStatus has failed." 
  185                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  196     for (
int i = 0; i < numBuff; ++i) {
 
  199     inFile >> redSpin >> numFlats >> halfBuff;
 
  203 void RanshiEngine::showStatus()
 const {
 
  204   std::cout << std::setprecision(20) << std::endl;
 
  205   std::cout << 
"----------- Ranshi engine status ----------" << std::endl;
 
  206   std::cout << 
"Initial seed      = " << theSeed << std::endl;
 
  207   std::cout << 
"Current red spin  = " << redSpin << std::endl;
 
  208   std::cout << 
"Values produced   = " << numFlats << std::endl;
 
  209   std::cout << 
"Side of buffer    = " << (halfBuff ? 
"upper" : 
"lower")
 
  211   std::cout << 
"Current buffer    = " << std::endl;
 
  212   for (
int i = 0; i < numBuff; i+=4) {
 
  214               << 
buffer[i]     << std::setw(11) << 
buffer[i+1] << std::setw(11)
 
  215               << 
buffer[i+2]   << std::setw(11) << 
buffer[i+3] << std::endl;
 
  217   std::cout << 
"-------------------------------------------" << std::endl;
 
  220 RanshiEngine::operator float() {
 
  221   unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
 
  222   unsigned int blkSpin  = 
buffer[redAngle] & 0xffffffff;
 
  224   buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
 
  226   redSpin  = (blkSpin + numFlats++) & 0xffffffff;
 
  227   halfBuff = numBuff/2 - halfBuff;
 
  229   return float(blkSpin * twoToMinus_32());
 
  232 RanshiEngine::operator 
unsigned int() {
 
  233   unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
 
  234   unsigned int blkSpin  = 
buffer[redAngle] & 0xffffffff;
 
  236   buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
 
  238   redSpin  = (blkSpin + numFlats++) & 0xffffffff;
 
  239   halfBuff = numBuff/2 - halfBuff;
 
  244 std::ostream& RanshiEngine::put (std::ostream& os )
 const {
 
  245   char beginMarker[] = 
"RanshiEngine-begin";
 
  246   os << beginMarker << 
"\nUvec\n";
 
  247   std::vector<unsigned long> v = put();
 
  248   for (
unsigned int i=0; i<v.size(); ++i) {
 
  254 std::vector<unsigned long> RanshiEngine::put ()
 const {
 
  255   std::vector<unsigned long> v;
 
  256   v.push_back (engineIDulong<RanshiEngine>());
 
  257   for (
int i = 0; i < numBuff; ++i) {
 
  258     v.push_back(static_cast<unsigned long>(
buffer[i]));
 
  260   v.push_back(static_cast<unsigned long>(redSpin));
 
  261   v.push_back(static_cast<unsigned long>(numFlats));
 
  262   v.push_back(static_cast<unsigned long>(halfBuff));  
 
  266 std::istream& RanshiEngine::get (std::istream& is) {
 
  273   if (strcmp(beginMarker,
"RanshiEngine-begin")) {
 
  274     is.clear(std::ios::badbit | is.rdstate());
 
  275     std::cerr << 
"\nInput mispositioned or" 
  276               << 
"\nRanshiEngine state description missing or" 
  277               << 
"\nwrong engine type found." << std::endl;
 
  283 std::string RanshiEngine::beginTag ( )  { 
 
  284   return "RanshiEngine-begin"; 
 
  287 std::istream& RanshiEngine::getState (std::istream& is) {
 
  288   if ( possibleKeywordInput ( is, 
"Uvec", theSeed ) ) {
 
  289     std::vector<unsigned long> v;
 
  291     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  294         is.clear(std::ios::badbit | is.rdstate());
 
  295         std::cerr << 
"\nRanshiEngine state (vector) description improper." 
  296                 << 
"\ngetState() has failed." 
  297                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  309   for (
int i = 0; i < numBuff; ++i) {
 
  312   is >> redSpin >> numFlats >> halfBuff;
 
  316   if (strcmp(endMarker,
"RanshiEngine-end")) {
 
  317     is.clear(std::ios::badbit | is.rdstate());
 
  318     std::cerr << 
"\nRanshiEngine state description incomplete." 
  319               << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  325 bool RanshiEngine::get (
const std::vector<unsigned long> & v) {
 
  326   if ((v[0] & 0xffffffffUL) != engineIDulong<RanshiEngine>()) {
 
  328         "\nRanshiEngine get:state vector has wrong ID word - state unchanged\n";
 
  334 bool RanshiEngine::getState (
const std::vector<unsigned long> & v) {
 
  335   if (v.size() != VECTOR_STATE_SIZE ) {
 
  337         "\nRanshiEngine get:state vector has wrong length - state unchanged\n";
 
  340   for (
int i = 0; i < numBuff; ++i) {
 
  343   redSpin  = v[numBuff+1];
 
  344   numFlats = v[numBuff+2]; 
 
  345   halfBuff = v[numBuff+3];
 
  352   #if __GNUC__ > 3 && __GNUC_MINOR__ > 8 
  353     #pragma GCC diagnostic pop 
static const int MarkerLen
 
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.