00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "CLHEP/Random/RanshiEngine.h"
00036 #include "CLHEP/Random/engineIDulong.h"
00037 #include <string.h>
00038
00039 namespace CLHEP {
00040
00041 static const int MarkerLen = 64;
00042
00043 std::string RanshiEngine::name() const {return "RanshiEngine";}
00044
00045
00046 int RanshiEngine::numEngines = 0;
00047
00048 RanshiEngine::RanshiEngine()
00049 : HepRandomEngine(),
00050 halfBuff(0), numFlats(0)
00051 {
00052 int i = 0;
00053 while (i < numBuff) {
00054 buffer[i] = (unsigned int)(numEngines+19780503L*(i+1));
00055 ++i;
00056 }
00057 theSeed = numEngines+19780503L*++i;
00058 redSpin = (unsigned int)(theSeed & 0xffffffff);
00059 ++numEngines;
00060 for( i = 0; i < 10000; ++i) flat();
00061 }
00062
00063 RanshiEngine::RanshiEngine(std::istream& is)
00064 : HepRandomEngine(),
00065 halfBuff(0), numFlats(0)
00066 {
00067 is >> *this;
00068 }
00069
00070 RanshiEngine::RanshiEngine(long seed)
00071 : HepRandomEngine(),
00072 halfBuff(0), numFlats(0)
00073 {
00074 for (int i = 0; i < numBuff; ++i) {
00075 buffer[i] = (unsigned int)seed&0xffffffff;
00076 }
00077 theSeed = seed;
00078 redSpin = (unsigned int)(theSeed & 0xffffffff);
00079 int j;
00080 for (j = 0; j < numBuff*20; ++j) {
00081 flat();
00082 }
00083 }
00084
00085 RanshiEngine::RanshiEngine(int rowIndex, int colIndex)
00086 : HepRandomEngine(),
00087 halfBuff(0), numFlats(0)
00088 {
00089 int i = 0;
00090 while( i < numBuff ) {
00091 buffer[i] = (unsigned int)((rowIndex + (i+1)*(colIndex+8))&0xffffffff);
00092 ++i;
00093 }
00094 theSeed = rowIndex;
00095 redSpin = colIndex & 0xffffffff;
00096 for( i = 0; i < 100; ++i) flat();
00097 }
00098
00099 RanshiEngine::~RanshiEngine() { }
00100
00101 double RanshiEngine::flat() {
00102 unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
00103 unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
00104 unsigned int boostResult = blkSpin ^ redSpin;
00105
00106 buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
00107
00108 redSpin = (blkSpin + numFlats++) & 0xffffffff;
00109 halfBuff = numBuff/2 - halfBuff;
00110
00111 return ( blkSpin * twoToMinus_32() +
00112 (boostResult>>11) * twoToMinus_53() +
00113 nearlyTwoToMinus_54());
00114 }
00115
00116 void RanshiEngine::flatArray(const int size, double* vect) {
00117 for (int i = 0; i < size; ++i) {
00118 vect[i] = flat();
00119 }
00120 }
00121
00122 void RanshiEngine::setSeed(long seed, int) {
00123 *this = RanshiEngine(seed);
00124 }
00125
00126 void RanshiEngine::setSeeds(const long* seeds, int) {
00127 if (*seeds) {
00128 int i = 0;
00129 while (seeds[i] && i < numBuff) {
00130 buffer[i] = (unsigned int)seeds[i];
00131 ++i;
00132 }
00133 while (i < numBuff) {
00134 buffer[i] = buffer[i-1];
00135 ++i;
00136 }
00137 theSeed = seeds[0];
00138 redSpin = (unsigned int)theSeed;
00139 }
00140 theSeeds = seeds;
00141 }
00142
00143 void RanshiEngine::saveStatus(const char filename[]) const {
00144 std::ofstream outFile(filename, std::ios::out);
00145 if (!outFile.bad()) {
00146 outFile << "Uvec\n";
00147 std::vector<unsigned long> v = put();
00148 for (unsigned int i=0; i<v.size(); ++i) {
00149 outFile << v[i] << "\n";
00150 }
00151 }
00152 }
00153
00154 void RanshiEngine::restoreStatus(const char filename[]) {
00155 std::ifstream inFile(filename, std::ios::in);
00156 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
00157 std::cerr << " -- Engine state remains unchanged\n";
00158 return;
00159 }
00160 if ( possibleKeywordInput ( inFile, "Uvec", theSeed ) ) {
00161 std::vector<unsigned long> v;
00162 unsigned long xin;
00163 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
00164 inFile >> xin;
00165 if (!inFile) {
00166 inFile.clear(std::ios::badbit | inFile.rdstate());
00167 std::cerr << "\nRanshiEngine state (vector) description improper."
00168 << "\nrestoreStatus has failed."
00169 << "\nInput stream is probably mispositioned now." << std::endl;
00170 return;
00171 }
00172 v.push_back(xin);
00173 }
00174 getState(v);
00175 return;
00176 }
00177
00178 if (!inFile.bad()) {
00179
00180 for (int i = 0; i < numBuff; ++i) {
00181 inFile >> buffer[i];
00182 }
00183 inFile >> redSpin >> numFlats >> halfBuff;
00184 }
00185 }
00186
00187 void RanshiEngine::showStatus() const {
00188 std::cout << std::setprecision(20) << std::endl;
00189 std::cout << "----------- Ranshi engine status ----------" << std::endl;
00190 std::cout << "Initial seed = " << theSeed << std::endl;
00191 std::cout << "Current red spin = " << redSpin << std::endl;
00192 std::cout << "Values produced = " << numFlats << std::endl;
00193 std::cout << "Side of buffer = " << (halfBuff ? "upper" : "lower")
00194 << std::endl;
00195 std::cout << "Current buffer = " << std::endl;
00196 for (int i = 0; i < numBuff; i+=4) {
00197 std::cout << std::setw(10) << std::setiosflags(std::ios::right)
00198 << buffer[i] << std::setw(11) << buffer[i+1] << std::setw(11)
00199 << buffer[i+2] << std::setw(11) << buffer[i+3] << std::endl;
00200 }
00201 std::cout << "-------------------------------------------" << std::endl;
00202 }
00203
00204 RanshiEngine::operator float() {
00205 unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
00206 unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
00207
00208 buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
00209
00210 redSpin = (blkSpin + numFlats++) & 0xffffffff;
00211 halfBuff = numBuff/2 - halfBuff;
00212
00213 return float(blkSpin * twoToMinus_32());
00214 }
00215
00216 RanshiEngine::operator unsigned int() {
00217 unsigned int redAngle = (((numBuff/2) - 1) & redSpin) + halfBuff;
00218 unsigned int blkSpin = buffer[redAngle] & 0xffffffff;
00219
00220 buffer[redAngle] = ((blkSpin << 17) | (blkSpin >> (32-17))) ^ redSpin;
00221
00222 redSpin = (blkSpin + numFlats++) & 0xffffffff;
00223 halfBuff = numBuff/2 - halfBuff;
00224
00225 return blkSpin;
00226 }
00227
00228 std::ostream& RanshiEngine::put (std::ostream& os ) const {
00229 char beginMarker[] = "RanshiEngine-begin";
00230 os << beginMarker << "\nUvec\n";
00231 std::vector<unsigned long> v = put();
00232 for (unsigned int i=0; i<v.size(); ++i) {
00233 os << v[i] << "\n";
00234 }
00235 return os;
00236 }
00237
00238 std::vector<unsigned long> RanshiEngine::put () const {
00239 std::vector<unsigned long> v;
00240 v.push_back (engineIDulong<RanshiEngine>());
00241 for (int i = 0; i < numBuff; ++i) {
00242 v.push_back(static_cast<unsigned long>(buffer[i]));
00243 }
00244 v.push_back(static_cast<unsigned long>(redSpin));
00245 v.push_back(static_cast<unsigned long>(numFlats));
00246 v.push_back(static_cast<unsigned long>(halfBuff));
00247 return v;
00248 }
00249
00250 std::istream& RanshiEngine::get (std::istream& is) {
00251 char beginMarker [MarkerLen];
00252 is >> std::ws;
00253 is.width(MarkerLen);
00254
00255
00256 is >> beginMarker;
00257 if (strcmp(beginMarker,"RanshiEngine-begin")) {
00258 is.clear(std::ios::badbit | is.rdstate());
00259 std::cerr << "\nInput mispositioned or"
00260 << "\nRanshiEngine state description missing or"
00261 << "\nwrong engine type found." << std::endl;
00262 return is;
00263 }
00264 return getState(is);
00265 }
00266
00267 std::string RanshiEngine::beginTag ( ) {
00268 return "RanshiEngine-begin";
00269 }
00270
00271 std::istream& RanshiEngine::getState (std::istream& is) {
00272 if ( possibleKeywordInput ( is, "Uvec", theSeed ) ) {
00273 std::vector<unsigned long> v;
00274 unsigned long uu;
00275 for (unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
00276 is >> uu;
00277 if (!is) {
00278 is.clear(std::ios::badbit | is.rdstate());
00279 std::cerr << "\nRanshiEngine state (vector) description improper."
00280 << "\ngetState() has failed."
00281 << "\nInput stream is probably mispositioned now." << std::endl;
00282 return is;
00283 }
00284 v.push_back(uu);
00285 }
00286 getState(v);
00287 return (is);
00288 }
00289
00290
00291
00292 char endMarker [MarkerLen];
00293 for (int i = 0; i < numBuff; ++i) {
00294 is >> buffer[i];
00295 }
00296 is >> redSpin >> numFlats >> halfBuff;
00297 is >> std::ws;
00298 is.width(MarkerLen);
00299 is >> endMarker;
00300 if (strcmp(endMarker,"RanshiEngine-end")) {
00301 is.clear(std::ios::badbit | is.rdstate());
00302 std::cerr << "\nRanshiEngine state description incomplete."
00303 << "\nInput stream is probably mispositioned now." << std::endl;
00304 return is;
00305 }
00306 return is;
00307 }
00308
00309 bool RanshiEngine::get (const std::vector<unsigned long> & v) {
00310 if ((v[0] & 0xffffffffUL) != engineIDulong<RanshiEngine>()) {
00311 std::cerr <<
00312 "\nRanshiEngine get:state vector has wrong ID word - state unchanged\n";
00313 return false;
00314 }
00315 return getState(v);
00316 }
00317
00318 bool RanshiEngine::getState (const std::vector<unsigned long> & v) {
00319 if (v.size() != VECTOR_STATE_SIZE ) {
00320 std::cerr <<
00321 "\nRanshiEngine get:state vector has wrong length - state unchanged\n";
00322 return false;
00323 }
00324 for (int i = 0; i < numBuff; ++i) {
00325 buffer[i] = v[i+1];
00326 }
00327 redSpin = v[numBuff+1];
00328 numFlats = v[numBuff+2];
00329 halfBuff = v[numBuff+3];
00330 return true;
00331 }
00332
00333 }