Files
geant4/source/externals/clhep/src/NonRandomEngine.cc
T
2020-12-04 12:30:43 +01:00

238 lines
6.9 KiB
C++

// -*- C++ -*-
//
// -----------------------------------------------------------------------
// Hep Random
// --- NonRandomEngine ---
// class implementation file
// -----------------------------------------------------------------------
// M. Fischler - Created 9/30/99
//
// M. Fischler - Modifications to capture sequence as a vector, which
// are needed to retain sanity when put and get are involved.
// Mark Fischler - Methods for distrib. instance save/restore 12/8/04
// M. Fischler - Initialization of all state data (even those parts unused)
// - at ctor time, to thwart a VC++ i/o bug.
// M. Fischler - put/get for vectors of ulongs 3/15/05
// M. Fischler - State-saving using only ints, for portability 4/12/05
//
//=========================================================================
#include "CLHEP/Random/NonRandomEngine.h"
#include "CLHEP/Random/engineIDulong.h"
#include "CLHEP/Random/DoubConv.h"
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
namespace CLHEP {
std::string NonRandomEngine::name() const {return "NonRandomEngine";}
NonRandomEngine::NonRandomEngine() : nextHasBeenSet(false),
sequenceHasBeenSet(false),
intervalHasBeenSet(false) ,
nextRandom(0.05),
nInSeq(0),
randomInterval(0.1) { }
NonRandomEngine::~NonRandomEngine() { }
void NonRandomEngine::setNextRandom(double r) {
nextRandom = r;
nextHasBeenSet=true;
return;
}
void NonRandomEngine::setRandomSequence(double* s, int n) {
sequence.clear();
for (int i=0; i<n; i++) sequence.push_back(*s++);
assert (sequence.size() == (unsigned int)n);
nInSeq = 0;
sequenceHasBeenSet=true;
nextHasBeenSet=false;
return;
}
void NonRandomEngine::setRandomInterval(double x) {
randomInterval = x;
intervalHasBeenSet=true;
return;
}
double NonRandomEngine::flat() {
if (sequenceHasBeenSet) {
double v = sequence[nInSeq++];
if (nInSeq >= sequence.size() ) sequenceHasBeenSet = false;
return v;
}
if ( !nextHasBeenSet ) {
std::cout
<< "Attempt to use NonRandomEngine without setting next random!\n";
exit(1);
}
double a = nextRandom;
nextHasBeenSet = false;
if (intervalHasBeenSet) {
nextRandom += randomInterval;
if ( nextRandom >= 1 ) nextRandom -= 1.0;
nextHasBeenSet = true;
}
return a;
}
void NonRandomEngine::flatArray(const int size, double* vect) {
for (int i = 0; i < size; ++i) {
vect[i] = flat();
}
}
std::ostream & NonRandomEngine::put (std::ostream & os) const {
std::string beginMarker = "NonRandomEngine-begin";
os << beginMarker << "\nUvec\n";
std::vector<unsigned long> v = put();
for (unsigned int i=0; i<v.size(); ++i) {
os << v[i] << "\n";
}
return os;
}
std::vector<unsigned long> NonRandomEngine::put () const {
std::vector<unsigned long> v;
v.push_back (engineIDulong<NonRandomEngine>());
std::vector<unsigned long> t;
v.push_back(static_cast<unsigned long>(nextHasBeenSet));
v.push_back(static_cast<unsigned long>(sequenceHasBeenSet));
v.push_back(static_cast<unsigned long>(intervalHasBeenSet));
t = DoubConv::dto2longs(nextRandom);
v.push_back(t[0]); v.push_back(t[1]);
v.push_back(static_cast<unsigned long>(nInSeq));
t = DoubConv::dto2longs(randomInterval);
v.push_back(t[0]); v.push_back(t[1]);
v.push_back(static_cast<unsigned long>(sequence.size()));
for (unsigned int i=0; i<sequence.size(); ++i) {
t = DoubConv::dto2longs(sequence[i]);
v.push_back(t[0]); v.push_back(t[1]);
}
return v;
}
std::istream & NonRandomEngine::get (std::istream & is) {
std::string beginMarker = "NonRandomEngine-begin";
is >> beginMarker;
if (beginMarker != "NonRandomEngine-begin") {
is.clear(std::ios::badbit | is.rdstate());
std::cerr << "\nInput mispositioned or"
<< "\nNonRandomEngine state description missing or"
<< "\nwrong engine type found.\n";
return is;
}
return getState(is);
}
std::string NonRandomEngine::beginTag ( ) {
return "NonRandomEngine-begin";
}
std::istream & NonRandomEngine::getState (std::istream & is) {
if ( possibleKeywordInput ( is, "Uvec", nextHasBeenSet ) ) {
std::vector<unsigned long> v;
unsigned long uu = 99999;
unsigned long ssiz = 0;
for (unsigned int istart=0; istart < 10; ++istart) {
is >> uu;
if (!is) {
is.clear(std::ios::badbit | is.rdstate());
std::cout << "istart = " << istart << "\n";
std::cerr
<< "\nNonRandomEngine state (vector) description has no sequence size."
<< "\ngetState() has failed."
<< "\nInput stream is probably mispositioned now." << std::endl;
return is;
}
v.push_back(uu);
if (istart==9) ssiz = uu;
}
for (unsigned int ivec=0; ivec < 2*ssiz; ++ivec) {
is >> uu;
if (!is) {
is.clear(std::ios::badbit | is.rdstate());
std::cerr << "\nNonRandomEngine state (vector) description improper."
<< "\ngetState() has failed."
<< "\nInput stream is probably mispositioned now." << std::endl;
return is;
}
v.push_back(uu);
}
getState(v);
return (is);
}
// is >> nextHasBeenSet; Removed, encompassed by possibleKeywordInput()
std::string endMarker = "NonRandomEngine-end";
is >> sequenceHasBeenSet >> intervalHasBeenSet;
is >> nextRandom >> nInSeq >> randomInterval;
unsigned int seqSize;
is >> seqSize;
sequence.clear();
double x;
for (unsigned int i = 0; i < seqSize; ++i) {
is >> x;
sequence.push_back(x);
}
is >> endMarker;
if (endMarker != "NonRandomEngine-end") {
is.clear(std::ios::badbit | is.rdstate());
std::cerr << "\n NonRandomEngine state description incomplete."
<< "\nInput stream is probably mispositioned now." << std::endl;
return is;
}
return is;
}
bool NonRandomEngine::get (const std::vector<unsigned long> & v) {
if ((v[0] & 0xffffffffUL) != engineIDulong<NonRandomEngine>()) {
std::cerr <<
"\nNonRandomEngine get:state vector has wrong ID word - state unchanged\n";
return false;
}
return getState(v);
}
bool NonRandomEngine::getState (const std::vector<unsigned long> & v) {
unsigned int seqSize = v[9];
if (v.size() != 2*seqSize + 10 ) {
std::cerr <<
"\nNonRandomEngine get:state vector has wrong length - state unchanged\n";
std::cerr << " (length = " << v.size()
<< "; expected " << 2*seqSize + 10 << ")\n";
return false;
}
std::vector<unsigned long> t(2);
nextHasBeenSet = (v[1]!=0);
sequenceHasBeenSet = (v[2]!=0);
intervalHasBeenSet = (v[3]!=0);
t[0] = v[4]; t[1] = v[5]; nextRandom = DoubConv::longs2double(t);
nInSeq = v[6];
t[0] = v[7]; t[1] = v[8]; randomInterval = DoubConv::longs2double(t);
sequence.clear();
for (unsigned int i=0; i<seqSize; ++i) {
t[0] = v[2*i+10]; t[1] = v[2*i+11];
sequence.push_back(DoubConv::longs2double(t));
}
return true;
}
} // namespace CLHEP