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
const char * name(G4int ptype)
static constexpr double L
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.