53#include "CLHEP/Random/DualRand.h"
54#include "CLHEP/Random/defs.h"
55#include "CLHEP/Random/engineIDulong.h"
56#include "CLHEP/Utility/atomic_int.h"
71static const int MarkerLen = 64;
83 numEngines(numberOfEngines++),
84 tausworthe (1234567 + numEngines + 175321),
85 integerCong(69607 * tausworthe + 54329, numEngines)
93 tausworthe ((unsigned int)seed + 175321),
94 integerCong(69607 * tausworthe + 54329, 8043)
109 tausworthe (rowIndex + 1000 * colIndex + 85329),
110 integerCong(69607 * tausworthe + 54329, 1123)
118 unsigned int ic ( integerCong );
119 unsigned int t ( tausworthe );
127 for (
int i = 0; i < size; ++i) {
134 tausworthe = Tausworthe((
unsigned int)seed + 175321);
135 integerCong = IntegerCong(69607 * tausworthe + 54329, 8043);
139 setSeed(seeds ? *seeds : 1234567, 0);
144 std::ofstream outFile(filename, std::ios::out);
145 if (!outFile.bad()) {
147 std::vector<unsigned long> v =
put();
149 std::cout <<
"Result of v = put() is:\n";
151 for (
unsigned int i=0; i<v.size(); ++i) {
152 outFile << v[i] <<
"\n";
154 std::cout << v[i] <<
" ";
155 if (i%6==0) std::cout <<
"\n";
163 long pr=outFile.precision(20);
164 outFile <<
theSeed << std::endl;
165 tausworthe.put(outFile);
166 integerCong.put(outFile);
167 outFile << std::endl;
168 outFile.precision(pr);
173 std::ifstream inFile(filename, std::ios::in);
175 std::cerr <<
" -- Engine state remains unchanged\n";
179 std::vector<unsigned long> v;
184 std::cout <<
"ivec = " << ivec <<
" xin = " << xin <<
" ";
185 if (ivec%3 == 0) std::cout <<
"\n";
188 inFile.clear(std::ios::badbit | inFile.rdstate());
189 std::cerr <<
"\nDualRand state (vector) description improper."
190 <<
"\nrestoreStatus has failed."
191 <<
"\nInput stream is probably mispositioned now." << std::endl;
202 tausworthe.get(inFile);
203 integerCong.get(inFile);
208 long pr=std::cout.precision(20);
209 std::cout << std::endl;
210 std::cout <<
"-------- DualRand engine status ---------"
212 std::cout <<
"Initial seed = " <<
theSeed << std::endl;
213 std::cout <<
"Tausworthe generator = " << std::endl;
214 tausworthe.put(std::cout);
215 std::cout <<
"\nIntegerCong generator = " << std::endl;
216 integerCong.put(std::cout);
217 std::cout << std::endl <<
"-----------------------------------------"
219 std::cout.precision(pr);
226DualRand::operator float() {
227 return (
float) ( (integerCong ^ tausworthe) * twoToMinus_32()
228 + nearlyTwoToMinus_54() );
232DualRand::operator
unsigned int() {
233 return (integerCong ^ tausworthe) & 0xffffffff;
237 char beginMarker[] =
"DualRand-begin";
238 os << beginMarker <<
"\nUvec\n";
239 std::vector<unsigned long> v =
put();
240 for (
unsigned int i=0; i<v.size(); ++i) {
245 char endMarker[] =
"DualRand-end";
246 long pr=os.precision(20);
247 os <<
" " << beginMarker <<
" ";
251 os <<
" " << endMarker <<
"\n";
258 std::vector<unsigned long> v;
259 v.push_back (engineIDulong<DualRand>());
266 char beginMarker [MarkerLen];
272 if (strcmp(beginMarker,
"DualRand-begin")) {
273 is.clear(std::ios::badbit | is.rdstate());
274 std::cerr <<
"\nInput mispositioned or"
275 <<
"\nDualRand state description missing or"
276 <<
"\nwrong engine type found." << std::endl;
283 return "DualRand-begin";
288 std::vector<unsigned long> v;
293 is.clear(std::ios::badbit | is.rdstate());
294 std::cerr <<
"\nDualRand state (vector) description improper."
295 <<
"\ngetState() has failed."
296 <<
"\nInput stream is probably mispositioned now." << std::endl;
307 char endMarker [MarkerLen];
313 if (strcmp(endMarker,
"DualRand-end")) {
314 is.clear(std::ios::badbit | is.rdstate());
315 std::cerr <<
"DualRand state description incomplete."
316 <<
"\nInput stream is probably mispositioned now." << std::endl;
323 if ((v[0] & 0xffffffffUL) != engineIDulong<DualRand>()) {
325 "\nDualRand get:state vector has wrong ID word - state unchanged\n";
329 std::cerr <<
"\nDualRand get:state vector has wrong size: "
330 << v.size() <<
" - state unchanged\n";
337 std::vector<unsigned long>::const_iterator iv = v.begin()+1;
338 if (!tausworthe.get(iv))
return false;
339 if (!integerCong.get(iv))
return false;
342 "\nDualRand get:state vector has wrong size: " << v.size()
343 <<
"\n Apparently " << iv-v.begin() <<
" words were consumed\n";
349DualRand::Tausworthe::Tausworthe() {
351 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
352 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
356DualRand::Tausworthe::Tausworthe(
unsigned int seed) {
358 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
359 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
363DualRand::Tausworthe::operator
unsigned int() {
409 if (wordIndex <= 0) {
410 for (wordIndex = 0; wordIndex < 4; ++wordIndex) {
411 words[wordIndex] = ( (words[(wordIndex+1) & 3] << 1 ) |
412 (words[wordIndex] >> 31) )
413 ^ ( (words[(wordIndex+1) & 3] << 31) |
414 (words[wordIndex] >> 1) );
417 return words[--wordIndex] & 0xffffffff;
420void DualRand::Tausworthe::put(std::ostream & os)
const {
421 char beginMarker[] =
"Tausworthe-begin";
422 char endMarker[] =
"Tausworthe-end";
424 long pr=os.precision(20);
425 os <<
" " << beginMarker <<
" ";
426 for (
int i = 0; i < 4; ++i) {
427 os << words[i] <<
" ";
430 os <<
" " << endMarker <<
" ";
435void DualRand::Tausworthe::put(std::vector<unsigned long> & v)
const {
436 for (
int i = 0; i < 4; ++i) {
437 v.push_back(
static_cast<unsigned long>(words[i]));
439 v.push_back(
static_cast<unsigned long>(wordIndex));
442void DualRand::Tausworthe::get(std::istream & is) {
443 char beginMarker [MarkerLen];
444 char endMarker [MarkerLen];
451 if (strcmp(beginMarker,
"Tausworthe-begin")) {
452 is.clear(std::ios::badbit | is.rdstate());
453 std::cerr <<
"\nInput mispositioned or"
454 <<
"\nTausworthe state description missing or"
455 <<
"\nwrong engine type found." << std::endl;
457 for (
int i = 0; i < 4; ++i) {
464 if (strcmp(endMarker,
"Tausworthe-end")) {
465 is.clear(std::ios::badbit | is.rdstate());
466 std::cerr <<
"\nTausworthe state description incomplete."
467 <<
"\nInput stream is probably mispositioned now." << std::endl;
472DualRand::Tausworthe::get(std::vector<unsigned long>::const_iterator & iv){
473 for (
int i = 0; i < 4; ++i) {
474 words[i] = (
unsigned int)*iv++;
476 wordIndex = (int)*iv++;
480DualRand::IntegerCong::IntegerCong()
481: state((unsigned int)3758656018U),
487DualRand::IntegerCong::IntegerCong(
unsigned int seed,
int streamNumber)
489 multiplier(65536 + 1024 + 5 + (8 * 1017 * streamNumber)),
507DualRand::IntegerCong::operator
unsigned int() {
508 return state = (state * multiplier + addend) & 0xffffffff;
511void DualRand::IntegerCong::put(std::ostream & os)
const {
512 char beginMarker[] =
"IntegerCong-begin";
513 char endMarker[] =
"IntegerCong-end";
515 long pr=os.precision(20);
516 os <<
" " << beginMarker <<
" ";
517 os << state <<
" " << multiplier <<
" " << addend;
518 os <<
" " << endMarker <<
" ";
523void DualRand::IntegerCong::put(std::vector<unsigned long> & v)
const {
524 v.push_back(
static_cast<unsigned long>(state));
525 v.push_back(
static_cast<unsigned long>(multiplier));
526 v.push_back(
static_cast<unsigned long>(addend));
529void DualRand::IntegerCong::get(std::istream & is) {
530 char beginMarker [MarkerLen];
531 char endMarker [MarkerLen];
538 if (strcmp(beginMarker,
"IntegerCong-begin")) {
539 is.clear(std::ios::badbit | is.rdstate());
540 std::cerr <<
"\nInput mispositioned or"
541 <<
"\nIntegerCong state description missing or"
542 <<
"\nwrong engine type found." << std::endl;
544 is >> state >> multiplier >> addend;
548 if (strcmp(endMarker,
"IntegerCong-end")) {
549 is.clear(std::ios::badbit | is.rdstate());
550 std::cerr <<
"\nIntegerCong state description incomplete."
551 <<
"\nInput stream is probably mispositioned now." << std::endl;
556DualRand::IntegerCong::get(std::vector<unsigned long>::const_iterator & iv) {
557 state = (
unsigned int)*iv++;
558 multiplier = (
unsigned int)*iv++;
559 addend = (
unsigned int)*iv++;
#define CLHEP_ATOMIC_INT_TYPE
void setSeeds(const long *seeds, int)
std::vector< unsigned long > put() const
static const unsigned int VECTOR_STATE_SIZE
void restoreStatus(const char filename[]="DualRand.conf")
void setSeed(long seed, int)
void saveStatus(const char filename[]="DualRand.conf") const
void flatArray(const int size, double *vect)
virtual std::istream & get(std::istream &is)
static std::string engineName()
virtual std::istream & getState(std::istream &is)
static std::string beginTag()
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)
bool possibleKeywordInput(IS &is, const std::string &key, T &t)