37 #include "CLHEP/Random/defs.h"
38 #include "CLHEP/Random/Random.h"
39 #include "CLHEP/Random/Hurd288Engine.h"
40 #include "CLHEP/Random/engineIDulong.h"
48 static const int MarkerLen = 64;
50 std::string Hurd288Engine::name()
const {
return "Hurd288Engine";}
53 int Hurd288Engine::numEngines = 0;
56 int Hurd288Engine::maxIndex = 215;
58 static inline unsigned int f288(
unsigned int a,
unsigned int b,
unsigned int c)
60 return ( ((b<<2) & 0x7ffc) | ((a<<2) & ~0x7ffc) | (a>>30) ) ^
64 Hurd288Engine::Hurd288Engine()
67 int cycle = std::abs(
int(numEngines/maxIndex));
68 int curIndex = std::abs(
int(numEngines%maxIndex));
69 long mask = ((cycle & 0x007fffff) << 8);
75 words[0] ^= 0x1324abcd;
76 if (words[0]==0) words[0] = 1;
78 for(
int i=0; i < 100; ++i )
flat();
90 long seedlist[2]={seed,0};
92 words[0] ^= 0xa5482134;
93 if (words[0]==0) words[0] = 1;
94 for(
int i=0; i < 100; ++i )
flat();
100 int cycle = std::abs(
int(rowIndex/maxIndex));
101 int row = std::abs(
int(rowIndex%maxIndex));
102 int col = colIndex & 0x1;
103 long mask = (( cycle & 0x000007ff ) << 20 );
106 seedlist[0] = (seedlist[col])^mask;
109 for(
int i=0; i < 100; ++i )
flat();
114 void Hurd288Engine::advance() {
116 register unsigned int W0, W1, W2, W3, W4, W5, W6, W7, W8;
127 W1 ^= W0; W0 = f288(W2, W3, W0);
128 W2 ^= W1; W1 = f288(W3, W4, W1);
129 W3 ^= W2; W2 = f288(W4, W5, W2);
130 W4 ^= W3; W3 = f288(W5, W6, W3);
131 W5 ^= W4; W4 = f288(W6, W7, W4);
132 W6 ^= W5; W5 = f288(W7, W8, W5);
133 W7 ^= W6; W6 = f288(W8, W0, W6);
134 W8 ^= W7; W7 = f288(W0, W1, W7);
135 W0 ^= W8; W8 = f288(W1, W2, W8);
136 words[0] = W0 & 0xffffffff;
137 words[1] = W1 & 0xffffffff;
138 words[2] = W2 & 0xffffffff;
139 words[3] = W3 & 0xffffffff;
140 words[4] = W4 & 0xffffffff;
141 words[5] = W5 & 0xffffffff;
142 words[6] = W6 & 0xffffffff;
143 words[7] = W7 & 0xffffffff;
144 words[8] = W8 & 0xffffffff;
152 if( wordIndex <= 2 ) {
166 for (
int i = 0; i < size; ++i) {
172 words[0] = (
unsigned int)seed;
173 for (wordIndex = 1; wordIndex < 9; ++wordIndex) {
174 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
179 setSeed( *seeds ? *seeds : 32767, 0 );
184 std::ofstream outFile(filename, std::ios::out);
185 if( !outFile.bad() ) {
187 std::vector<unsigned long> v =
put();
189 std::cout <<
"Result of v = put() is:\n";
191 for (
unsigned int i=0; i<v.size(); ++i) {
192 outFile << v[i] <<
"\n";
194 std::cout << v[i] <<
" ";
195 if (i%6==0) std::cout <<
"\n";
203 outFile << std::setprecision(20) <<
theSeed <<
" ";
204 outFile << wordIndex <<
" ";
205 for(
int i = 0; i < 9; ++i ) {
206 outFile << words[i] <<
" ";
208 outFile << std::endl;
213 std::ifstream inFile(filename, std::ios::in);
215 std::cerr <<
" -- Engine state remains unchanged\n";
219 std::vector<unsigned long> v;
224 std::cout <<
"ivec = " << ivec <<
" xin = " << xin <<
" ";
225 if (ivec%3 == 0) std::cout <<
"\n";
228 inFile.clear(std::ios::badbit | inFile.rdstate());
229 std::cerr <<
"\nHurd288Engine state (vector) description improper."
230 <<
"\nrestoreStatus has failed."
231 <<
"\nInput stream is probably mispositioned now." << std::endl;
240 if( !inFile.bad() ) {
243 for(
int i = 0; i < 9; ++i ) {
250 std::cout << std::setprecision(20) << std::endl;
251 std::cout <<
"----------- Hurd2 engine status ----------" << std::endl;
252 std::cout <<
"Initial seed = " <<
theSeed << std::endl;
253 std::cout <<
"Current index = " << wordIndex << std::endl;
254 std::cout <<
"Current words = " << std::endl;
255 for(
int i = 0; i < 9 ; ++i ) {
256 std::cout <<
" " << words[i] << std::endl;
258 std::cout <<
"-------------------------------------------" << std::endl;
261 Hurd288Engine::operator float() {
262 if( wordIndex <= 1 ) {
265 return words[--wordIndex ] * twoToMinus_32();
268 Hurd288Engine::operator
unsigned int() {
269 if( wordIndex <= 1 ) {
272 return words[--wordIndex];
276 char beginMarker[] =
"Hurd288Engine-begin";
277 os << beginMarker <<
"\nUvec\n";
278 std::vector<unsigned long> v =
put();
279 for (
unsigned int i=0; i<v.size(); ++i) {
284 char endMarker[] =
"Hurd288Engine-end";
285 int pr = os.precision(20);
286 os <<
" " << beginMarker <<
" ";
288 os << wordIndex <<
" ";
289 for (
int i = 0; i < 9; ++i) {
290 os << words[i] <<
"\n";
292 os << endMarker <<
"\n ";
299 std::vector<unsigned long> v;
300 v.push_back (engineIDulong<Hurd288Engine>());
301 v.push_back(static_cast<unsigned long>(wordIndex));
302 for (
int i = 0; i < 9; ++i) {
303 v.push_back(static_cast<unsigned long>(words[i]));
310 char beginMarker [MarkerLen];
316 if (strcmp(beginMarker,
"Hurd288Engine-begin")) {
317 is.clear(std::ios::badbit | is.rdstate());
318 std::cerr <<
"\nInput mispositioned or"
319 <<
"\nHurd288Engine state description missing or"
320 <<
"\nwrong engine type found." << std::endl;
327 return "Hurd288Engine-begin";
332 std::vector<unsigned long> v;
337 is.clear(std::ios::badbit | is.rdstate());
338 std::cerr <<
"\nHurd288Engine state (vector) description improper."
339 <<
"\ngetState() has failed."
340 <<
"\nInput stream is probably mispositioned now." << std::endl;
351 char endMarker [MarkerLen];
353 for (
int i = 0; i < 9; ++i) {
359 if (strcmp(endMarker,
"Hurd288Engine-end")) {
360 is.clear(std::ios::badbit | is.rdstate());
361 std::cerr <<
"\nHurd288Engine state description incomplete."
362 <<
"\nInput stream is probably mispositioned now." << std::endl;
369 if ((v[0] & 0xffffffffUL) != engineIDulong<Hurd288Engine>()) {
371 "\nHurd288Engine get:state vector has wrong ID word - state unchanged\n";
372 std::cerr <<
"The correct ID would be " << engineIDulong<Hurd288Engine>()
373 <<
"; the actual ID is " << v[0] <<
"\n";
382 "\nHurd288Engine get:state vector has wrong length - state unchanged\n";
386 for (
int i = 0; i < 9; ++i) {
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
void flatArray(const int size, double *vect)
virtual std::istream & getState(std::istream &is)
void setSeeds(const long *seeds, int)
std::vector< unsigned long > put() const
void saveStatus(const char filename[]="Hurd288Engine.conf") const
static double nearlyTwoToMinus_54()
static double twoToMinus_32()
virtual std::istream & get(std::istream &is)
void restoreStatus(const char filename[]="Hurd288Engine.conf")
static std::string beginTag()
static double twoToMinus_53()
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)
void setSeed(long seed, int)
static std::string engineName()
static const unsigned int VECTOR_STATE_SIZE