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.