54 #include "CLHEP/Random/DualRand.h"
55 #include "CLHEP/Random/engineIDulong.h"
56 #include "CLHEP/Utility/atomic_int.h"
64 CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
79 numEngines(numberOfEngines++),
80 tausworthe (1234567 + numEngines + 175321),
81 integerCong(69607 * tausworthe + 54329, numEngines)
86 DualRand::DualRand(
long seed)
89 tausworthe ((unsigned int)seed + 175321),
90 integerCong(69607 * tausworthe + 54329, 8043)
95 DualRand::DualRand(std::istream & is)
102 DualRand::DualRand(
int rowIndex,
int colIndex)
105 tausworthe (rowIndex + 1000 * colIndex + 85329),
106 integerCong(69607 * tausworthe + 54329, 1123)
111 DualRand::~DualRand() { }
114 unsigned int ic ( integerCong );
115 unsigned int t ( tausworthe );
116 return ( (t ^ ic) * twoToMinus_32() +
117 (t >> 11) * twoToMinus_53() +
118 nearlyTwoToMinus_54()
122 void DualRand::flatArray(
const int size,
double* vect) {
123 for (
int i = 0; i < size; ++i) {
128 void DualRand::setSeed(
long seed,
int) {
130 tausworthe = Tausworthe((
unsigned int)seed + 175321);
131 integerCong = IntegerCong(69607 * tausworthe + 54329, 8043);
135 setSeed(seeds ? *seeds : 1234567, 0);
139 void DualRand::saveStatus(
const char filename[])
const {
140 std::ofstream outFile(filename, std::ios::out);
141 if (!outFile.bad()) {
143 std::vector<unsigned long> v = put();
144 for (
unsigned int i=0; i<v.size(); ++i) {
145 outFile << v[i] <<
"\n";
150 void DualRand::restoreStatus(
const char filename[]) {
151 std::ifstream inFile(filename, std::ios::in);
152 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
153 std::cerr <<
" -- Engine state remains unchanged\n";
156 if ( possibleKeywordInput ( inFile,
"Uvec", theSeed ) ) {
157 std::vector<unsigned long> v;
159 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
162 inFile.clear(std::ios::badbit | inFile.rdstate());
163 std::cerr <<
"\nDualRand state (vector) description improper."
164 <<
"\nrestoreStatus has failed."
165 <<
"\nInput stream is probably mispositioned now." << std::endl;
176 tausworthe.get(inFile);
177 integerCong.get(inFile);
181 void DualRand::showStatus()
const {
182 int pr=std::cout.precision(20);
183 std::cout << std::endl;
184 std::cout <<
"-------- DualRand engine status ---------"
186 std::cout <<
"Initial seed = " << theSeed << std::endl;
187 std::cout <<
"Tausworthe generator = " << std::endl;
188 tausworthe.put(std::cout);
189 std::cout <<
"\nIntegerCong generator = " << std::endl;
190 integerCong.put(std::cout);
191 std::cout << std::endl <<
"-----------------------------------------"
193 std::cout.precision(pr);
196 DualRand::operator float() {
197 return (
float) ( (integerCong ^ tausworthe) * twoToMinus_32()
198 + nearlyTwoToMinus_54() );
202 DualRand::operator
unsigned int() {
203 return (integerCong ^ tausworthe) & 0xffffffff;
206 std::ostream & DualRand::put(std::ostream & os)
const {
207 char beginMarker[] =
"DualRand-begin";
208 os << beginMarker <<
"\nUvec\n";
209 std::vector<unsigned long> v = put();
210 for (
unsigned int i=0; i<v.size(); ++i) {
216 std::vector<unsigned long> DualRand::put ()
const {
217 std::vector<unsigned long> v;
218 v.push_back (engineIDulong<DualRand>());
224 std::istream & DualRand::get(std::istream & is) {
231 if (strcmp(beginMarker,
"DualRand-begin")) {
232 is.clear(std::ios::badbit | is.rdstate());
233 std::cerr <<
"\nInput mispositioned or"
234 <<
"\nDualRand state description missing or"
235 <<
"\nwrong engine type found." << std::endl;
241 std::string DualRand::beginTag ( ) {
242 return "DualRand-begin";
245 std::istream & DualRand::getState ( std::istream & is ) {
246 if ( possibleKeywordInput ( is,
"Uvec", theSeed ) ) {
247 std::vector<unsigned long> v;
249 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
252 is.clear(std::ios::badbit | is.rdstate());
253 std::cerr <<
"\nDualRand state (vector) description improper."
254 <<
"\ngetState() has failed."
255 <<
"\nInput stream is probably mispositioned now." << std::endl;
272 if (strcmp(endMarker,
"DualRand-end")) {
273 is.clear(std::ios::badbit | is.rdstate());
274 std::cerr <<
"DualRand state description incomplete."
275 <<
"\nInput stream is probably mispositioned now." << std::endl;
281 bool DualRand::get(
const std::vector<unsigned long> & v) {
282 if ((v[0] & 0xffffffffUL) != engineIDulong<DualRand>()) {
284 "\nDualRand get:state vector has wrong ID word - state unchanged\n";
287 if (v.size() != VECTOR_STATE_SIZE) {
288 std::cerr <<
"\nDualRand get:state vector has wrong size: "
289 << v.size() <<
" - state unchanged\n";
295 bool DualRand::getState (
const std::vector<unsigned long> & v) {
296 std::vector<unsigned long>::const_iterator iv = v.begin()+1;
297 if (!tausworthe.get(iv))
return false;
298 if (!integerCong.get(iv))
return false;
301 "\nDualRand get:state vector has wrong size: " << v.size()
302 <<
"\n Apparently " << iv-v.begin() <<
" words were consumed\n";
308 DualRand::Tausworthe::Tausworthe() {
310 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
311 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
315 DualRand::Tausworthe::Tausworthe(
unsigned int seed) {
317 for (wordIndex = 1; wordIndex < 4; ++wordIndex) {
318 words[wordIndex] = 69607 * words[wordIndex-1] + 54329;
322 DualRand::Tausworthe::operator
unsigned int() {
368 if (wordIndex <= 0) {
369 for (wordIndex = 0; wordIndex < 4; ++wordIndex) {
370 words[wordIndex] = ( (words[(wordIndex+1) & 3] << 1 ) |
371 (words[wordIndex] >> 31) )
372 ^ ( (words[(wordIndex+1) & 3] << 31) |
373 (words[wordIndex] >> 1) );
376 return words[--wordIndex] & 0xffffffff;
379 void DualRand::Tausworthe::put(std::ostream & os)
const {
380 char beginMarker[] =
"Tausworthe-begin";
381 char endMarker[] =
"Tausworthe-end";
383 int pr=os.precision(20);
384 os <<
" " << beginMarker <<
" ";
385 for (
int i = 0; i < 4; ++i) {
386 os << words[i] <<
" ";
389 os <<
" " << endMarker <<
" ";
394 void DualRand::Tausworthe::put(std::vector<unsigned long> & v)
const {
395 for (
int i = 0; i < 4; ++i) {
396 v.push_back(static_cast<unsigned long>(words[i]));
398 v.push_back(static_cast<unsigned long>(wordIndex));
401 void DualRand::Tausworthe::get(std::istream & is) {
410 if (strcmp(beginMarker,
"Tausworthe-begin")) {
411 is.clear(std::ios::badbit | is.rdstate());
412 std::cerr <<
"\nInput mispositioned or"
413 <<
"\nTausworthe state description missing or"
414 <<
"\nwrong engine type found." << std::endl;
416 for (
int i = 0; i < 4; ++i) {
423 if (strcmp(endMarker,
"Tausworthe-end")) {
424 is.clear(std::ios::badbit | is.rdstate());
425 std::cerr <<
"\nTausworthe state description incomplete."
426 <<
"\nInput stream is probably mispositioned now." << std::endl;
431 DualRand::Tausworthe::get(std::vector<unsigned long>::const_iterator & iv){
432 for (
int i = 0; i < 4; ++i) {
439 DualRand::IntegerCong::IntegerCong()
440 : state((unsigned int)3758656018U),
446 DualRand::IntegerCong::IntegerCong(
unsigned int seed,
int streamNumber)
448 multiplier(65536 + 1024 + 5 + (8 * 1017 * streamNumber)),
466 DualRand::IntegerCong::operator
unsigned int() {
467 return state = (state * multiplier + addend) & 0xffffffff;
470 void DualRand::IntegerCong::put(std::ostream & os)
const {
471 char beginMarker[] =
"IntegerCong-begin";
472 char endMarker[] =
"IntegerCong-end";
474 int pr=os.precision(20);
475 os <<
" " << beginMarker <<
" ";
476 os << state <<
" " << multiplier <<
" " << addend;
477 os <<
" " << endMarker <<
" ";
482 void DualRand::IntegerCong::put(std::vector<unsigned long> & v)
const {
483 v.push_back(static_cast<unsigned long>(state));
484 v.push_back(static_cast<unsigned long>(multiplier));
485 v.push_back(static_cast<unsigned long>(addend));
488 void DualRand::IntegerCong::get(std::istream & is) {
497 if (strcmp(beginMarker,
"IntegerCong-begin")) {
498 is.clear(std::ios::badbit | is.rdstate());
499 std::cerr <<
"\nInput mispositioned or"
500 <<
"\nIntegerCong state description missing or"
501 <<
"\nwrong engine type found." << std::endl;
503 is >> state >> multiplier >> addend;
507 if (strcmp(endMarker,
"IntegerCong-end")) {
508 is.clear(std::ios::badbit | is.rdstate());
509 std::cerr <<
"\nIntegerCong state description incomplete."
510 <<
"\nInput stream is probably mispositioned now." << std::endl;
515 DualRand::IntegerCong::get(std::vector<unsigned long>::const_iterator & iv) {
static const int MarkerLen
const char * name(G4int ptype)
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.