31 #include "CLHEP/Random/defs.h"
32 #include "CLHEP/Random/Random.h"
33 #include "CLHEP/Random/Hurd160Engine.h"
34 #include "CLHEP/Random/engineIDulong.h"
40 static const int MarkerLen = 64;
45 int Hurd160Engine::numEngines = 0;
48 int Hurd160Engine::maxIndex = 215;
50 static inline unsigned int f160(
unsigned int a,
unsigned int b,
unsigned int c)
52 return ( ((
b<<2) & 0x7c) | ((
a<<2) & ~0x7c) | (
a>>30) ) ^ ( (c<<1)|(c>>31) );
58 int cycle = std::abs(
int(numEngines/maxIndex));
59 int curIndex = std::abs(
int(numEngines%maxIndex));
60 long mask = ((cycle & 0x007fffff) << 8);
66 words[0] ^= 0x1324abcd;
67 if (words[0]==0) words[0] = 1;
69 for(
int i=0; i < 100; ++i )
flat();
81 long seedlist[2]={seed,0};
83 words[0] ^= 0xa5482134;
84 if (words[0]==0) words[0] = 1;
85 for(
int i=0; i < 100; ++i )
flat();
91 int cycle = std::abs(
int(rowIndex/maxIndex));
92 int row = std::abs(
int(rowIndex%maxIndex));
93 int col = colIndex & 0x1;
94 long mask = (( cycle & 0x000007ff ) << 20 );
98 seedlist[0] = (seedlist[col])^mask;
101 for(
int i=0; i < 100; ++i )
flat();
106 void Hurd160Engine::advance() {
107 register unsigned int W0, W1, W2, W3, W4;
114 W1 ^= W0; W0 = f160(W4, W3, W0);
115 W2 ^= W1; W1 = f160(W0, W4, W1);
116 W3 ^= W2; W2 = f160(W1, W0, W2);
117 W4 ^= W3; W3 = f160(W2, W1, W3);
118 W0 ^= W4; W4 = f160(W3, W2, W4);
119 words[0] = W0 & 0xffffffff;
120 words[1] = W1 & 0xffffffff;
121 words[2] = W2 & 0xffffffff;
122 words[3] = W3 & 0xffffffff;
123 words[4] = W4 & 0xffffffff;
130 if( wordIndex <= 2 ) {
144 for (
int i = 0; i < size; ++i) {
150 words[0] = (
unsigned int)seed;
151 for (wordIndex = 1; wordIndex < 5; ++wordIndex) {
152 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
157 setSeed( *seeds ? *seeds : 32767, 0 );
162 std::ofstream outFile(filename, std::ios::out);
163 if( !outFile.bad() ) {
165 std::vector<unsigned long> v =
put();
167 std::cout <<
"Result of v = put() is:\n";
169 for (
unsigned int i=0; i<v.size(); ++i) {
170 outFile << v[i] <<
"\n";
172 std::cout << v[i] <<
" ";
173 if (i%6==0) std::cout <<
"\n";
181 outFile << std::setprecision(20) <<
theSeed <<
" ";
182 outFile << wordIndex <<
" ";
183 for(
int i = 0; i < 5; ++i ) {
184 outFile << words[i] <<
" ";
186 outFile << std::endl;
191 std::ifstream inFile(filename, std::ios::in);
193 std::cerr <<
" -- Engine state remains unchanged\n";
197 std::vector<unsigned long> v;
202 std::cout <<
"ivec = " << ivec <<
" xin = " << xin <<
" ";
203 if (ivec%3 == 0) std::cout <<
"\n";
206 inFile.clear(std::ios::badbit | inFile.rdstate());
207 std::cerr <<
"\nHurd160Engine state (vector) description improper."
208 <<
"\nrestoreStatus has failed."
209 <<
"\nInput stream is probably mispositioned now." << std::endl;
218 if( !inFile.bad() ) {
221 for(
int i = 0; i < 5; ++i ) {
228 int pr = std::cout.precision(20);
229 std::cout << std::endl;
230 std::cout <<
"----------- Hurd engine status ----------" << std::endl;
231 std::cout <<
"Initial seed = " <<
theSeed << std::endl;
232 std::cout <<
"Current index = " << wordIndex << std::endl;
233 std::cout <<
"Current words = " << std::endl;
234 for(
int i = 0; i < 5 ; ++i ) {
235 std::cout <<
" " << words[i] << std::endl;
237 std::cout <<
"------------------------------------------" << std::endl;
238 std::cout.precision(pr);
241 Hurd160Engine::operator float() {
242 if( wordIndex <= 1 ) {
245 return words[--wordIndex ] * twoToMinus_32();
248 Hurd160Engine::operator
unsigned int() {
249 if( wordIndex <= 1 ) {
252 return words[--wordIndex];
256 char beginMarker[] =
"Hurd160Engine-begin";
257 os << beginMarker <<
"\nUvec\n";
258 std::vector<unsigned long> v =
put();
259 for (
unsigned int i=0; i<v.size(); ++i) {
264 char endMarker[] =
"Hurd160Engine-end";
265 int pr = os.precision(20);
266 os <<
" " << beginMarker <<
" ";
268 os << wordIndex <<
" ";
269 for (
int i = 0; i < 5; ++i) {
270 os << words[i] <<
"\n";
272 os << endMarker <<
"\n ";
279 std::vector<unsigned long> v;
280 v.push_back (engineIDulong<Hurd160Engine>());
281 v.push_back(
static_cast<unsigned long>(wordIndex));
282 for (
int i = 0; i < 5; ++i) {
283 v.push_back(
static_cast<unsigned long>(words[i]));
290 char beginMarker [MarkerLen];
296 if (strcmp(beginMarker,
"Hurd160Engine-begin")) {
297 is.clear(std::ios::badbit | is.rdstate());
298 std::cerr <<
"\nInput mispositioned or"
299 <<
"\nHurd160Engine state description missing or"
300 <<
"\nwrong engine type found." << std::endl;
307 return "Hurd160Engine-begin";
312 std::vector<unsigned long> v;
317 is.clear(std::ios::badbit | is.rdstate());
318 std::cerr <<
"\nHurd160Engine state (vector) description improper."
319 <<
"\ngetState() has failed."
320 <<
"\nInput stream is probably mispositioned now." << std::endl;
331 char endMarker [MarkerLen];
333 for (
int i = 0; i < 5; ++i) {
339 if (strcmp(endMarker,
"Hurd160Engine-end")) {
340 is.clear(std::ios::badbit | is.rdstate());
341 std::cerr <<
"\nHurd160Engine state description incomplete."
342 <<
"\nInput stream is probably mispositioned now." << std::endl;
350 if ((v[0] & 0xffffffffUL) != engineIDulong<Hurd160Engine>()) {
352 "\nHurd160Engine get:state vector has wrong ID word - state unchanged\n";
361 "\nHurd160Engine get:state vector has wrong length - state unchanged\n";
365 for (
int i = 0; i < 5; ++i) {
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 & get(std::istream &is)
void setSeeds(const long *seeds, int)
void restoreStatus(const char filename[]="Hurd160Engine.conf")
virtual std::istream & getState(std::istream &is)
std::vector< unsigned long > put() const
static std::string engineName()
void flatArray(const int size, double *vect)
void setSeed(long seed, int)
static std::string beginTag()
static const unsigned int VECTOR_STATE_SIZE
void saveStatus(const char filename[]="Hurd160Engine.conf") const
bool possibleKeywordInput(IS &is, const std::string &key, T &t)