37#include "CLHEP/Random/defs.h"
38#include "CLHEP/Random/Random.h"
39#include "CLHEP/Random/Hurd288Engine.h"
40#include "CLHEP/Random/engineIDulong.h"
41#include "CLHEP/Utility/atomic_int.h"
59 const int maxIndex = 215;
62static const int MarkerLen = 64;
66static inline unsigned int f288(
unsigned int a,
unsigned int b,
unsigned int c)
68 return ( ((b<<2) & 0x7ffc) | ((a<<2) & ~0x7ffc) | (a>>30) ) ^
75 int numEngines = numberOfEngines++;
76 int cycle = std::abs(
int(numEngines/maxIndex));
77 int curIndex = std::abs(
int(numEngines%maxIndex));
78 long mask = ((cycle & 0x007fffff) << 8);
82 words[0] ^= 0x1324abcd;
83 if (words[0]==0) words[0] = 1;
85 for(
int i=0; i < 100; ++i )
flat();
99 words[0] ^= 0xa5482134;
100 if (words[0]==0) words[0] = 1;
101 for(
int i=0; i < 100; ++i )
flat();
107 int cycle = std::abs(
int(rowIndex/maxIndex));
108 int row = std::abs(
int(rowIndex%maxIndex));
109 int col = colIndex & 0x1;
110 long mask = (( cycle & 0x000007ff ) << 20 );
112 seeds_[0] = seeds_[col]^mask;
114 for(
int i=0; i < 100; ++i )
flat();
119void Hurd288Engine::advance() {
121 unsigned int W0, W1, W2, W3, W4, W5, W6, W7, W8;
132 W1 ^= W0; W0 = f288(W2, W3, W0);
133 W2 ^= W1; W1 = f288(W3, W4, W1);
134 W3 ^= W2; W2 = f288(W4, W5, W2);
135 W4 ^= W3; W3 = f288(W5, W6, W3);
136 W5 ^= W4; W4 = f288(W6, W7, W4);
137 W6 ^= W5; W5 = f288(W7, W8, W5);
138 W7 ^= W6; W6 = f288(W8, W0, W6);
139 W8 ^= W7; W7 = f288(W0, W1, W7);
140 W0 ^= W8; W8 = f288(W1, W2, W8);
141 words[0] = W0 & 0xffffffff;
142 words[1] = W1 & 0xffffffff;
143 words[2] = W2 & 0xffffffff;
144 words[3] = W3 & 0xffffffff;
145 words[4] = W4 & 0xffffffff;
146 words[5] = W5 & 0xffffffff;
147 words[6] = W6 & 0xffffffff;
148 words[7] = W7 & 0xffffffff;
149 words[8] = W8 & 0xffffffff;
157 if( wordIndex <= 2 ) {
171 for (
int i = 0; i < size; ++i) {
180 words[0] = (
unsigned int)seed;
181 for (wordIndex = 1; wordIndex < 9; ++wordIndex) {
182 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
188 setSeed( *seeds ? *seeds : 32767, 0 );
192 std::ofstream outFile(filename, std::ios::out);
193 if( !outFile.bad() ) {
195 std::vector<unsigned long> v =
put();
197 std::cout <<
"Result of v = put() is:\n";
199 for (
unsigned int i=0; i<v.size(); ++i) {
200 outFile << v[i] <<
"\n";
202 std::cout << v[i] <<
" ";
203 if (i%6==0) std::cout <<
"\n";
211 outFile << std::setprecision(20) <<
theSeed <<
" ";
212 outFile << wordIndex <<
" ";
213 for(
int i = 0; i < 9; ++i ) {
214 outFile << words[i] <<
" ";
216 outFile << std::endl;
221 std::ifstream inFile(filename, std::ios::in);
223 std::cerr <<
" -- Engine state remains unchanged\n";
227 std::vector<unsigned long> v;
232 std::cout <<
"ivec = " << ivec <<
" xin = " << xin <<
" ";
233 if (ivec%3 == 0) std::cout <<
"\n";
236 inFile.clear(std::ios::badbit | inFile.rdstate());
237 std::cerr <<
"\nHurd288Engine state (vector) description improper."
238 <<
"\nrestoreStatus has failed."
239 <<
"\nInput stream is probably mispositioned now." << std::endl;
248 if( !inFile.bad() ) {
251 for(
int i = 0; i < 9; ++i ) {
258 std::cout << std::setprecision(20) << std::endl;
259 std::cout <<
"----------- Hurd2 engine status ----------" << std::endl;
260 std::cout <<
"Initial seed = " <<
theSeed << std::endl;
261 std::cout <<
"Current index = " << wordIndex << std::endl;
262 std::cout <<
"Current words = " << std::endl;
263 for(
int i = 0; i < 9 ; ++i ) {
264 std::cout <<
" " << words[i] << std::endl;
266 std::cout <<
"-------------------------------------------" << std::endl;
273Hurd288Engine::operator float() {
274 if( wordIndex <= 1 ) {
277 return words[--wordIndex ] * twoToMinus_32();
280Hurd288Engine::operator
unsigned int() {
281 if( wordIndex <= 1 ) {
284 return words[--wordIndex];
288 char beginMarker[] =
"Hurd288Engine-begin";
289 os << beginMarker <<
"\nUvec\n";
290 std::vector<unsigned long> v =
put();
291 for (
unsigned int i=0; i<v.size(); ++i) {
296 char endMarker[] =
"Hurd288Engine-end";
297 int pr = os.precision(20);
298 os <<
" " << beginMarker <<
" ";
300 os << wordIndex <<
" ";
301 for (
int i = 0; i < 9; ++i) {
302 os << words[i] <<
"\n";
304 os << endMarker <<
"\n ";
311 std::vector<unsigned long> v;
312 v.push_back (engineIDulong<Hurd288Engine>());
313 v.push_back(
static_cast<unsigned long>(wordIndex));
314 for (
int i = 0; i < 9; ++i) {
315 v.push_back(
static_cast<unsigned long>(words[i]));
322 char beginMarker [MarkerLen];
328 if (strcmp(beginMarker,
"Hurd288Engine-begin")) {
329 is.clear(std::ios::badbit | is.rdstate());
330 std::cerr <<
"\nInput mispositioned or"
331 <<
"\nHurd288Engine state description missing or"
332 <<
"\nwrong engine type found." << std::endl;
339 return "Hurd288Engine-begin";
344 std::vector<unsigned long> v;
349 is.clear(std::ios::badbit | is.rdstate());
350 std::cerr <<
"\nHurd288Engine state (vector) description improper."
351 <<
"\ngetState() has failed."
352 <<
"\nInput stream is probably mispositioned now." << std::endl;
363 char endMarker [MarkerLen];
365 for (
int i = 0; i < 9; ++i) {
371 if (strcmp(endMarker,
"Hurd288Engine-end")) {
372 is.clear(std::ios::badbit | is.rdstate());
373 std::cerr <<
"\nHurd288Engine state description incomplete."
374 <<
"\nInput stream is probably mispositioned now." << std::endl;
381 if ((v[0] & 0xffffffffUL) != engineIDulong<Hurd288Engine>()) {
383 "\nHurd288Engine get:state vector has wrong ID word - state unchanged\n";
384 std::cerr <<
"The correct ID would be " << engineIDulong<Hurd288Engine>()
385 <<
"; the actual ID is " << v[0] <<
"\n";
394 "\nHurd288Engine get:state vector has wrong length - state unchanged\n";
397 wordIndex = (int)v[1];
398 for (
int i = 0; i < 9; ++i) {
399 words[i] = (
unsigned int)v[i+2];
#define CLHEP_ATOMIC_INT_TYPE
static double twoToMinus_32()
static double twoToMinus_53()
static double nearlyTwoToMinus_54()
static bool checkFile(std::istream &file, const std::string &filename, const std::string &classname, const std::string &methodname)
static void getTheTableSeeds(long *seeds, int index)
virtual std::istream & getState(std::istream &is)
void setSeeds(const long *seeds, int)
void flatArray(const int size, double *vect)
static std::string beginTag()
virtual std::istream & get(std::istream &is)
static std::string engineName()
void setSeed(long seed, int)
void saveStatus(const char filename[]="Hurd288Engine.conf") const
void restoreStatus(const char filename[]="Hurd288Engine.conf")
static const unsigned int VECTOR_STATE_SIZE
std::vector< unsigned long > put() const
bool possibleKeywordInput(IS &is, const std::string &key, T &t)