54 #include "CLHEP/Random/DualRand.h"
55 #include "CLHEP/Random/defs.h"
56 #include "CLHEP/Random/engineIDulong.h"
61 static const int MarkerLen = 64;
66 int DualRand::numEngines = 0;
76 tausworthe (1234567 + numEngines + 175321),
77 integerCong(69607 * tausworthe + 54329, numEngines)
85 tausworthe ((unsigned int)seed + 175321),
86 integerCong(69607 * tausworthe + 54329, 8043)
99 tausworthe (rowIndex + 1000 * colIndex + 85329),
100 integerCong(69607 * tausworthe + 54329, 1123)
108 unsigned int ic ( integerCong );
109 unsigned int t ( tausworthe );
117 for (
int i = 0; i < size; ++i) {
124 tausworthe = Tausworthe((
unsigned int)seed + numEngines + 175321);
125 integerCong = IntegerCong(69607 * tausworthe + 54329, numEngines);
129 setSeed(seeds ? *seeds : 1234567, 0);
134 std::ofstream outFile(filename, std::ios::out);
135 if (!outFile.bad()) {
137 std::vector<unsigned long> v =
put();
139 std::cout <<
"Result of v = put() is:\n";
141 for (
unsigned int i=0; i<v.size(); ++i) {
142 outFile << v[i] <<
"\n";
144 std::cout << v[i] <<
" ";
145 if (i%6==0) std::cout <<
"\n";
153 int pr=outFile.precision(20);
154 outFile <<
theSeed << std::endl;
155 tausworthe.put(outFile);
156 integerCong.put(outFile);
157 outFile << std::endl;
158 outFile.precision(pr);
163 std::ifstream inFile(filename, std::ios::in);
165 std::cerr <<
" -- Engine state remains unchanged\n";
169 std::vector<unsigned long> v;
174 std::cout <<
"ivec = " << ivec <<
" xin = " << xin <<
" ";
175 if (ivec%3 == 0) std::cout <<
"\n";
178 inFile.clear(std::ios::badbit | inFile.rdstate());
179 std::cerr <<
"\nDualRand state (vector) description improper."
180 <<
"\nrestoreStatus has failed."
181 <<
"\nInput stream is probably mispositioned now." << std::endl;
192 tausworthe.get(inFile);
193 integerCong.get(inFile);
198 int pr=std::cout.precision(20);
199 std::cout << std::endl;
200 std::cout <<
"-------- DualRand engine status ---------"
202 std::cout <<
"Initial seed = " <<
theSeed << std::endl;
203 std::cout <<
"Tausworthe generator = " << std::endl;
204 tausworthe.put(std::cout);
205 std::cout <<
"\nIntegerCong generator = " << std::endl;
206 integerCong.put(std::cout);
207 std::cout << std::endl <<
"-----------------------------------------"
209 std::cout.precision(pr);
212 DualRand::operator float() {
213 return (
float) ( (integerCong ^ tausworthe) * twoToMinus_32()
214 + nearlyTwoToMinus_54() );
218 DualRand::operator
unsigned int() {
219 return (integerCong ^ tausworthe) & 0xffffffff;
223 char beginMarker[] =
"DualRand-begin";
224 os << beginMarker <<
"\nUvec\n";
225 std::vector<unsigned long> v =
put();
226 for (
unsigned int i=0; i<v.size(); ++i) {
231 char endMarker[] =
"DualRand-end";
232 int pr=os.precision(20);
233 os <<
" " << beginMarker <<
" ";
237 os <<
" " << endMarker <<
"\n";
244 std::vector<unsigned long> v;
245 v.push_back (engineIDulong<DualRand>());
252 char beginMarker [MarkerLen];
258 if (strcmp(beginMarker,
"DualRand-begin")) {
259 is.clear(std::ios::badbit | is.rdstate());
260 std::cerr <<
"\nInput mispositioned or"
261 <<
"\nDualRand state description missing or"
262 <<
"\nwrong engine type found." << std::endl;
269 return "DualRand-begin";
274 std::vector<unsigned long> v;
279 is.clear(std::ios::badbit | is.rdstate());
280 std::cerr <<
"\nDualRand state (vector) description improper."
281 <<
"\ngetState() has failed."
282 <<
"\nInput stream is probably mispositioned now." << std::endl;
293 char endMarker [MarkerLen];
299 if (strcmp(endMarker,
"DualRand-end")) {
300 is.clear(std::ios::badbit | is.rdstate());
301 std::cerr <<
"DualRand state description incomplete."
302 <<
"\nInput stream is probably mispositioned now." << std::endl;
309 if ((v[0] & 0xffffffffUL) != engineIDulong<DualRand>()) {
311 "\nDualRand get:state vector has wrong ID word - state unchanged\n";
315 std::cerr <<
"\nDualRand get:state vector has wrong size: "
316 << v.size() <<
" - state unchanged\n";
323 std::vector<unsigned long>::const_iterator iv = v.begin()+1;
324 if (!tausworthe.get(iv))
return false;
325 if (!integerCong.get(iv))
return false;
328 "\nDualRand get:state vector has wrong size: " << v.size()
329 <<
"\n Apparently " << iv-v.begin() <<
" words were consumed\n";
335 DualRand::Tausworthe::Tausworthe() {
337 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
338 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
342 DualRand::Tausworthe::Tausworthe(
unsigned int seed) {
344 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
345 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
349 DualRand::Tausworthe::operator
unsigned int() {
395 if (wordIndex <= 0) {
396 for (wordIndex = 0; wordIndex < 4; ++wordIndex) {
397 words[wordIndex] = ( (words[(wordIndex+1) & 3] << 1 ) |
398 (words[wordIndex] >> 31) )
399 ^ ( (words[(wordIndex+1) & 3] << 31) |
400 (words[wordIndex] >> 1) );
403 return words[--wordIndex] & 0xffffffff;
406 void DualRand::Tausworthe::put(std::ostream & os)
const {
407 char beginMarker[] =
"Tausworthe-begin";
408 char endMarker[] =
"Tausworthe-end";
410 int pr=os.precision(20);
411 os <<
" " << beginMarker <<
" ";
412 for (
int i = 0; i < 4; ++i) {
413 os << words[i] <<
" ";
416 os <<
" " << endMarker <<
" ";
421 void DualRand::Tausworthe::put(std::vector<unsigned long> & v)
const {
422 for (
int i = 0; i < 4; ++i) {
423 v.push_back(static_cast<unsigned long>(words[i]));
425 v.push_back(static_cast<unsigned long>(wordIndex));
428 void DualRand::Tausworthe::get(std::istream & is) {
429 char beginMarker [MarkerLen];
430 char endMarker [MarkerLen];
437 if (strcmp(beginMarker,
"Tausworthe-begin")) {
438 is.clear(std::ios::badbit | is.rdstate());
439 std::cerr <<
"\nInput mispositioned or"
440 <<
"\nTausworthe state description missing or"
441 <<
"\nwrong engine type found." << std::endl;
443 for (
int i = 0; i < 4; ++i) {
450 if (strcmp(endMarker,
"Tausworthe-end")) {
451 is.clear(std::ios::badbit | is.rdstate());
452 std::cerr <<
"\nTausworthe state description incomplete."
453 <<
"\nInput stream is probably mispositioned now." << std::endl;
458 DualRand::Tausworthe::get(std::vector<unsigned long>::const_iterator & iv){
459 for (
int i = 0; i < 4; ++i) {
466 DualRand::IntegerCong::IntegerCong()
467 : state((unsigned int)3758656018U),
473 DualRand::IntegerCong::IntegerCong(
unsigned int seed,
int streamNumber)
475 multiplier(65536 + 1024 + 5 + (8 * 1017 * streamNumber)),
493 DualRand::IntegerCong::operator
unsigned int() {
494 return state = (state * multiplier + addend) & 0xffffffff;
497 void DualRand::IntegerCong::put(std::ostream & os)
const {
498 char beginMarker[] =
"IntegerCong-begin";
499 char endMarker[] =
"IntegerCong-end";
501 int pr=os.precision(20);
502 os <<
" " << beginMarker <<
" ";
503 os << state <<
" " << multiplier <<
" " << addend;
504 os <<
" " << endMarker <<
" ";
509 void DualRand::IntegerCong::put(std::vector<unsigned long> & v)
const {
510 v.push_back(static_cast<unsigned long>(state));
511 v.push_back(static_cast<unsigned long>(multiplier));
512 v.push_back(static_cast<unsigned long>(addend));
515 void DualRand::IntegerCong::get(std::istream & is) {
516 char beginMarker [MarkerLen];
517 char endMarker [MarkerLen];
524 if (strcmp(beginMarker,
"IntegerCong-begin")) {
525 is.clear(std::ios::badbit | is.rdstate());
526 std::cerr <<
"\nInput mispositioned or"
527 <<
"\nIntegerCong state description missing or"
528 <<
"\nwrong engine type found." << std::endl;
530 is >> state >> multiplier >> addend;
534 if (strcmp(endMarker,
"IntegerCong-end")) {
535 is.clear(std::ios::badbit | is.rdstate());
536 std::cerr <<
"\nIntegerCong state description incomplete."
537 <<
"\nInput stream is probably mispositioned now." << std::endl;
542 DualRand::IntegerCong::get(std::vector<unsigned long>::const_iterator & iv) {
bool possibleKeywordInput(IS &is, const std::string &key, T &t)
static const unsigned int VECTOR_STATE_SIZE
void flatArray(const int size, double *vect)
static std::string engineName()
void restoreStatus(const char filename[]="DualRand.conf")
static double nearlyTwoToMinus_54()
void saveStatus(const char filename[]="DualRand.conf") const
static double twoToMinus_32()
virtual std::istream & get(std::istream &is)
static std::string beginTag()
virtual std::istream & getState(std::istream &is)
std::vector< unsigned long > put() const
void setSeeds(const long *seeds, int)
static double twoToMinus_53()
static bool checkFile(std::istream &file, const std::string &filename, const std::string &classname, const std::string &methodname)
void setSeed(long seed, int)