35 #include "CLHEP/Random/RanshiEngine.h" 
   36 #include "CLHEP/Random/engineIDulong.h" 
   46 int RanshiEngine::numEngines = 0;
 
   48 RanshiEngine::RanshiEngine()
 
   50   halfBuff(0), numFlats(0) 
 
   54     buffer[i] = (
unsigned int)(numEngines+19780503
L*(i+1));
 
   57   theSeed = numEngines+19780503
L*++i;
 
   58   redSpin = (
unsigned int)(theSeed & 0xffffffff);
 
   60   for( i = 0; i < 10000; ++i) 
flat();  
 
   63 RanshiEngine::RanshiEngine(std::istream& is)
 
   65   halfBuff(0), numFlats(0) 
 
   70 RanshiEngine::RanshiEngine(
long seed)
 
   72   halfBuff(0), numFlats(0) 
 
   74   for (
int i = 0; i < numBuff; ++i) {
 
   75     buffer[i] = (
unsigned int)seed&0xffffffff;
 
   78   redSpin = (
unsigned int)(theSeed & 0xffffffff);
 
   80   for (j = 0; j < numBuff*20; ++j) {      
 
   85 RanshiEngine::RanshiEngine(
int rowIndex, 
int colIndex)
 
   87   halfBuff(0), numFlats(0) 
 
   90   while( i < numBuff ) {
 
   91     buffer[i] = (
unsigned int)((rowIndex + (i+1)*(colIndex+8))&0xffffffff);
 
   95   redSpin = colIndex & 0xffffffff;
 
   96   for( i = 0; i < 100; ++i) 
flat();    
 
   99 RanshiEngine::~RanshiEngine() { }
 
  102   unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
 
  103   unsigned int blkSpin     = 
buffer[redAngle] & 0xffffffff;
 
  104   unsigned int boostResult = blkSpin ^ redSpin;
 
  106   buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
 
  108   redSpin  = (blkSpin + numFlats++) & 0xffffffff;
 
  109   halfBuff = numBuff/2 - halfBuff;
 
  111   return ( blkSpin * twoToMinus_32() +            
 
  112            (boostResult>>11) * twoToMinus_53() +  
 
  113            nearlyTwoToMinus_54());              
 
  116 void RanshiEngine::flatArray(
const int size, 
double* vect) {
 
  117   for (
int i = 0; i < size; ++i) {
 
  122 void RanshiEngine::setSeed(
long seed, 
int) {
 
  123   *
this = RanshiEngine(seed); 
 
  129     while (seeds[i] && i < numBuff) {
 
  130       buffer[i] = (
unsigned int)seeds[i];
 
  133     while (i < numBuff) {
 
  138     redSpin = (
unsigned int)theSeed;
 
  143 void RanshiEngine::saveStatus(
const char filename[])
 const {
 
  144   std::ofstream 
outFile(filename, std::ios::out);
 
  147     std::vector<unsigned long> v = put();
 
  148     for (
unsigned int i=0; i<v.size(); ++i) {
 
  154 void RanshiEngine::restoreStatus(
const char filename[]) {
 
  155   std::ifstream inFile(filename, std::ios::in);
 
  156   if (!checkFile ( inFile, filename, engineName(), 
"restoreStatus" )) {
 
  157     std::cerr << 
"  -- Engine state remains unchanged\n";
 
  160   if ( possibleKeywordInput ( inFile, 
"Uvec", theSeed ) ) {
 
  161     std::vector<unsigned long> v;
 
  163     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  166         inFile.clear(std::ios::badbit | inFile.rdstate());
 
  167         std::cerr << 
"\nRanshiEngine state (vector) description improper." 
  168                << 
"\nrestoreStatus has failed." 
  169                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  180     for (
int i = 0; i < numBuff; ++i) {
 
  183     inFile >> redSpin >> numFlats >> halfBuff;
 
  187 void RanshiEngine::showStatus()
 const {
 
  188   std::cout << std::setprecision(20) << std::endl;
 
  189   std::cout << 
"----------- Ranshi engine status ----------" << std::endl;
 
  190   std::cout << 
"Initial seed      = " << theSeed << std::endl;
 
  191   std::cout << 
"Current red spin  = " << redSpin << std::endl;
 
  192   std::cout << 
"Values produced   = " << numFlats << std::endl;
 
  193   std::cout << 
"Side of buffer    = " << (halfBuff ? 
"upper" : 
"lower")
 
  195   std::cout << 
"Current buffer    = " << std::endl;
 
  196   for (
int i = 0; i < numBuff; i+=4) {
 
  198               << 
buffer[i]     << std::setw(11) << 
buffer[i+1] << std::setw(11)
 
  199               << 
buffer[i+2]   << std::setw(11) << 
buffer[i+3] << std::endl;
 
  201   std::cout << 
"-------------------------------------------" << std::endl;
 
  204 RanshiEngine::operator float() {
 
  205   unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
 
  206   unsigned int blkSpin  = 
buffer[redAngle] & 0xffffffff;
 
  208   buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
 
  210   redSpin  = (blkSpin + numFlats++) & 0xffffffff;
 
  211   halfBuff = numBuff/2 - halfBuff;
 
  213   return float(blkSpin * twoToMinus_32());
 
  216 RanshiEngine::operator 
unsigned int() {
 
  217   unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
 
  218   unsigned int blkSpin  = 
buffer[redAngle] & 0xffffffff;
 
  220   buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
 
  222   redSpin  = (blkSpin + numFlats++) & 0xffffffff;
 
  223   halfBuff = numBuff/2 - halfBuff;
 
  228 std::ostream& RanshiEngine::put (std::ostream& os )
 const {
 
  229   char beginMarker[] = 
"RanshiEngine-begin";
 
  230   os << beginMarker << 
"\nUvec\n";
 
  231   std::vector<unsigned long> v = put();
 
  232   for (
unsigned int i=0; i<v.size(); ++i) {
 
  238 std::vector<unsigned long> RanshiEngine::put ()
 const {
 
  239   std::vector<unsigned long> v;
 
  240   v.push_back (engineIDulong<RanshiEngine>());
 
  241   for (
int i = 0; i < numBuff; ++i) {
 
  242     v.push_back(static_cast<unsigned long>(
buffer[i]));
 
  244   v.push_back(static_cast<unsigned long>(redSpin));
 
  245   v.push_back(static_cast<unsigned long>(numFlats));
 
  246   v.push_back(static_cast<unsigned long>(halfBuff));  
 
  250 std::istream& RanshiEngine::get (std::istream& is) {
 
  257   if (strcmp(beginMarker,
"RanshiEngine-begin")) {
 
  258     is.clear(std::ios::badbit | is.rdstate());
 
  259     std::cerr << 
"\nInput mispositioned or" 
  260               << 
"\nRanshiEngine state description missing or" 
  261               << 
"\nwrong engine type found." << std::endl;
 
  267 std::string RanshiEngine::beginTag ( )  { 
 
  268   return "RanshiEngine-begin"; 
 
  271 std::istream& RanshiEngine::getState (std::istream& is) {
 
  272   if ( possibleKeywordInput ( is, 
"Uvec", theSeed ) ) {
 
  273     std::vector<unsigned long> v;
 
  275     for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
 
  278         is.clear(std::ios::badbit | is.rdstate());
 
  279         std::cerr << 
"\nRanshiEngine state (vector) description improper." 
  280                 << 
"\ngetState() has failed." 
  281                << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  293   for (
int i = 0; i < numBuff; ++i) {
 
  296   is >> redSpin >> numFlats >> halfBuff;
 
  300   if (strcmp(endMarker,
"RanshiEngine-end")) {
 
  301     is.clear(std::ios::badbit | is.rdstate());
 
  302     std::cerr << 
"\nRanshiEngine state description incomplete." 
  303               << 
"\nInput stream is probably mispositioned now." << std::endl;
 
  309 bool RanshiEngine::get (
const std::vector<unsigned long> & v) {
 
  310   if ((v[0] & 0xffffffffUL) != engineIDulong<RanshiEngine>()) {
 
  312         "\nRanshiEngine get:state vector has wrong ID word - state unchanged\n";
 
  318 bool RanshiEngine::getState (
const std::vector<unsigned long> & v) {
 
  319   if (v.size() != VECTOR_STATE_SIZE ) {
 
  321         "\nRanshiEngine get:state vector has wrong length - state unchanged\n";
 
  324   for (
int i = 0; i < numBuff; ++i) {
 
  327   redSpin  = v[numBuff+1];
 
  328   numFlats = v[numBuff+2]; 
 
  329   halfBuff = v[numBuff+3];
 
static const int MarkerLen
 
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.