54 #include "CLHEP/Random/DualRand.h"
55 #include "CLHEP/Random/engineIDulong.h"
65 int DualRand::numEngines = 0;
75 tausworthe (1234567 + numEngines + 175321),
76 integerCong(69607 * tausworthe + 54329, numEngines)
82 DualRand::DualRand(
long seed)
84 tausworthe ((unsigned int)seed + 175321),
85 integerCong(69607 * tausworthe + 54329, 8043)
90 DualRand::DualRand(std::istream & is)
96 DualRand::DualRand(
int rowIndex,
int colIndex)
98 tausworthe (rowIndex + 1000 * colIndex + 85329),
99 integerCong(69607 * tausworthe + 54329, 1123)
104 DualRand::~DualRand() { }
107 unsigned int ic ( integerCong );
108 unsigned int t ( tausworthe );
109 return ( (t ^ ic) * twoToMinus_32() +
110 (t >> 11) * twoToMinus_53() +
111 nearlyTwoToMinus_54()
115 void DualRand::flatArray(
const int size,
double* vect) {
116 for (
int i = 0; i < size; ++i) {
121 void DualRand::setSeed(
long seed,
int) {
123 tausworthe = Tausworthe((
unsigned int)seed + numEngines + 175321);
124 integerCong = IntegerCong(69607 * tausworthe + 54329, numEngines);
128 setSeed(seeds ? *seeds : 1234567, 0);
132 void DualRand::saveStatus(
const char filename[])
const {
133 std::ofstream
outFile(filename, std::ios::out);
136 std::vector<unsigned long> v = put();
137 for (
unsigned int i=0; i<v.size(); ++i) {
143 void DualRand::restoreStatus(
const char filename[]) {
144 std::ifstream inFile(filename, std::ios::in);
145 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
146 std::cerr <<
" -- Engine state remains unchanged\n";
149 if ( possibleKeywordInput ( inFile,
"Uvec", theSeed ) ) {
150 std::vector<unsigned long> v;
152 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
155 inFile.clear(std::ios::badbit | inFile.rdstate());
156 std::cerr <<
"\nDualRand state (vector) description improper."
157 <<
"\nrestoreStatus has failed."
158 <<
"\nInput stream is probably mispositioned now." << std::endl;
169 tausworthe.get(inFile);
170 integerCong.get(inFile);
174 void DualRand::showStatus()
const {
175 int pr=std::cout.precision(20);
176 std::cout << std::endl;
177 std::cout <<
"-------- DualRand engine status ---------"
179 std::cout <<
"Initial seed = " << theSeed << std::endl;
180 std::cout <<
"Tausworthe generator = " << std::endl;
181 tausworthe.put(std::cout);
182 std::cout <<
"\nIntegerCong generator = " << std::endl;
183 integerCong.put(std::cout);
184 std::cout << std::endl <<
"-----------------------------------------"
186 std::cout.precision(pr);
189 DualRand::operator float() {
190 return (
float) ( (integerCong ^ tausworthe) * twoToMinus_32()
191 + nearlyTwoToMinus_54() );
195 DualRand::operator
unsigned int() {
196 return (integerCong ^ tausworthe) & 0xffffffff;
199 std::ostream & DualRand::put(std::ostream & os)
const {
200 char beginMarker[] =
"DualRand-begin";
201 os << beginMarker <<
"\nUvec\n";
202 std::vector<unsigned long> v = put();
203 for (
unsigned int i=0; i<v.size(); ++i) {
209 std::vector<unsigned long> DualRand::put ()
const {
210 std::vector<unsigned long> v;
211 v.push_back (engineIDulong<DualRand>());
217 std::istream & DualRand::get(std::istream & is) {
224 if (strcmp(beginMarker,
"DualRand-begin")) {
225 is.clear(std::ios::badbit | is.rdstate());
226 std::cerr <<
"\nInput mispositioned or"
227 <<
"\nDualRand state description missing or"
228 <<
"\nwrong engine type found." << std::endl;
234 std::string DualRand::beginTag ( ) {
235 return "DualRand-begin";
238 std::istream & DualRand::getState ( std::istream & is ) {
239 if ( possibleKeywordInput ( is,
"Uvec", theSeed ) ) {
240 std::vector<unsigned long> v;
242 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
245 is.clear(std::ios::badbit | is.rdstate());
246 std::cerr <<
"\nDualRand state (vector) description improper."
247 <<
"\ngetState() has failed."
248 <<
"\nInput stream is probably mispositioned now." << std::endl;
265 if (strcmp(endMarker,
"DualRand-end")) {
266 is.clear(std::ios::badbit | is.rdstate());
267 std::cerr <<
"DualRand state description incomplete."
268 <<
"\nInput stream is probably mispositioned now." << std::endl;
274 bool DualRand::get(
const std::vector<unsigned long> & v) {
275 if ((v[0] & 0xffffffffUL) != engineIDulong<DualRand>()) {
277 "\nDualRand get:state vector has wrong ID word - state unchanged\n";
280 if (v.size() != VECTOR_STATE_SIZE) {
281 std::cerr <<
"\nDualRand get:state vector has wrong size: "
282 << v.size() <<
" - state unchanged\n";
288 bool DualRand::getState (
const std::vector<unsigned long> & v) {
289 std::vector<unsigned long>::const_iterator iv = v.begin()+1;
290 if (!tausworthe.get(iv))
return false;
291 if (!integerCong.get(iv))
return false;
294 "\nDualRand get:state vector has wrong size: " << v.size()
295 <<
"\n Apparently " << iv-v.begin() <<
" words were consumed\n";
301 DualRand::Tausworthe::Tausworthe() {
303 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
304 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
308 DualRand::Tausworthe::Tausworthe(
unsigned int seed) {
310 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
311 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
315 DualRand::Tausworthe::operator
unsigned int() {
361 if (wordIndex <= 0) {
362 for (wordIndex = 0; wordIndex < 4; ++wordIndex) {
363 words[wordIndex] = ( (words[(wordIndex+1) & 3] << 1 ) |
364 (words[wordIndex] >> 31) )
365 ^ ( (words[(wordIndex+1) & 3] << 31) |
366 (words[wordIndex] >> 1) );
369 return words[--wordIndex] & 0xffffffff;
372 void DualRand::Tausworthe::put(std::ostream & os)
const {
373 char beginMarker[] =
"Tausworthe-begin";
374 char endMarker[] =
"Tausworthe-end";
376 int pr=os.precision(20);
377 os <<
" " << beginMarker <<
" ";
378 for (
int i = 0; i < 4; ++i) {
379 os << words[i] <<
" ";
382 os <<
" " << endMarker <<
" ";
387 void DualRand::Tausworthe::put(std::vector<unsigned long> & v)
const {
388 for (
int i = 0; i < 4; ++i) {
389 v.push_back(static_cast<unsigned long>(words[i]));
391 v.push_back(static_cast<unsigned long>(wordIndex));
394 void DualRand::Tausworthe::get(std::istream & is) {
403 if (strcmp(beginMarker,
"Tausworthe-begin")) {
404 is.clear(std::ios::badbit | is.rdstate());
405 std::cerr <<
"\nInput mispositioned or"
406 <<
"\nTausworthe state description missing or"
407 <<
"\nwrong engine type found." << std::endl;
409 for (
int i = 0; i < 4; ++i) {
416 if (strcmp(endMarker,
"Tausworthe-end")) {
417 is.clear(std::ios::badbit | is.rdstate());
418 std::cerr <<
"\nTausworthe state description incomplete."
419 <<
"\nInput stream is probably mispositioned now." << std::endl;
424 DualRand::Tausworthe::get(std::vector<unsigned long>::const_iterator & iv){
425 for (
int i = 0; i < 4; ++i) {
432 DualRand::IntegerCong::IntegerCong()
433 : state((unsigned int)3758656018U),
439 DualRand::IntegerCong::IntegerCong(
unsigned int seed,
int streamNumber)
441 multiplier(65536 + 1024 + 5 + (8 * 1017 * streamNumber)),
459 DualRand::IntegerCong::operator
unsigned int() {
460 return state = (state * multiplier + addend) & 0xffffffff;
463 void DualRand::IntegerCong::put(std::ostream & os)
const {
464 char beginMarker[] =
"IntegerCong-begin";
465 char endMarker[] =
"IntegerCong-end";
467 int pr=os.precision(20);
468 os <<
" " << beginMarker <<
" ";
469 os << state <<
" " << multiplier <<
" " << addend;
470 os <<
" " << endMarker <<
" ";
475 void DualRand::IntegerCong::put(std::vector<unsigned long> & v)
const {
476 v.push_back(static_cast<unsigned long>(state));
477 v.push_back(static_cast<unsigned long>(multiplier));
478 v.push_back(static_cast<unsigned long>(addend));
481 void DualRand::IntegerCong::get(std::istream & is) {
490 if (strcmp(beginMarker,
"IntegerCong-begin")) {
491 is.clear(std::ios::badbit | is.rdstate());
492 std::cerr <<
"\nInput mispositioned or"
493 <<
"\nIntegerCong state description missing or"
494 <<
"\nwrong engine type found." << std::endl;
496 is >> state >> multiplier >> addend;
500 if (strcmp(endMarker,
"IntegerCong-end")) {
501 is.clear(std::ios::badbit | is.rdstate());
502 std::cerr <<
"\nIntegerCong state description incomplete."
503 <<
"\nInput stream is probably mispositioned now." << std::endl;
508 DualRand::IntegerCong::get(std::vector<unsigned long>::const_iterator & iv) {
static const int MarkerLen
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.