28 #include "CLHEP/Random/Random.h"
29 #include "CLHEP/Random/MixMaxRng.h"
30 #include "CLHEP/Random/engineIDulong.h"
31 #include "CLHEP/Utility/atomic_int.h"
38 #include "CLHEP/Random/mixmax.h"
40 const unsigned long MASK32=0xffffffff;
46 CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
53 MixMaxRng::MixMaxRng()
56 int numEngines = ++numberOfEngines;
58 setSeed(static_cast<long>(numEngines));
61 MixMaxRng::MixMaxRng(
long seed)
68 MixMaxRng::MixMaxRng(std::istream& is)
74 MixMaxRng::~MixMaxRng()
79 MixMaxRng::MixMaxRng(
const MixMaxRng& rng)
80 : HepRandomEngine(rng)
82 fRngState=
rng_copy( rng.fRngState->V );
83 fRngState->sumtot= rng.fRngState->sumtot;
84 fRngState->counter= rng.fRngState->counter;
87 MixMaxRng& MixMaxRng::operator=(
const MixMaxRng& rng)
91 if (
this == &rng) {
return *
this; }
95 HepRandomEngine::operator=(rng);
100 fRngState=
rng_copy( rng.fRngState->V );
101 fRngState->sumtot= rng.fRngState->sumtot;
102 fRngState->counter= rng.fRngState->counter;
107 void MixMaxRng::saveStatus(
const char filename[] )
const
110 FILE *fh= fopen(filename,
"w");
120 void MixMaxRng::restoreStatus(
const char filename[] )
125 void MixMaxRng::showStatus()
const
127 std::cout << std::endl;
128 std::cout <<
"------- MixMaxRng engine status -------" << std::endl;
130 std::cout <<
" Current state vector is:" << std::endl;
131 fRngState->fh=stdout;
133 std::cout <<
"---------------------------------------" << std::endl;
136 void MixMaxRng::setSeed(
long longSeed,
int )
141 if(
sizeof(
long) > 4)
142 seed0=
static_cast<unsigned long>(longSeed) &
MASK32 ;
155 unsigned long seed0, seed1= 0, seed2= 0, seed3= 0;
158 seed0=
static_cast<unsigned long>(Seeds[0]) &
MASK32;
159 seed1=
static_cast<unsigned long>(Seeds[1]) &
MASK32;
164 seed0=
static_cast<unsigned long>(Seeds[0]) &
MASK32;
165 if( seedNum > 1){ seed1=
static_cast<unsigned long>(Seeds[1]) &
MASK32; }
166 if( seedNum > 2){ seed2=
static_cast<unsigned long>(Seeds[2]) &
MASK32; }
169 seed0=
static_cast<unsigned long>(Seeds[0]) &
MASK32;
170 seed1=
static_cast<unsigned long>(Seeds[1]) &
MASK32;
171 seed2=
static_cast<unsigned long>(Seeds[2]) &
MASK32;
172 seed3=
static_cast<unsigned long>(Seeds[3]) &
MASK32;
185 void MixMaxRng::flatArray(
const int size,
double* vect )
188 for (
int i=0; i<size; ++i) { vect[i] =
flat(); }
191 MixMaxRng::operator
unsigned int()
193 return static_cast<unsigned int>(
get_next(fRngState));
198 std::ostream & MixMaxRng::put ( std::ostream& os )
const
200 char beginMarker[] =
"MixMaxRng-begin";
201 char endMarker[] =
"MixMaxRng-end";
203 int pr = os.precision(24);
204 os << beginMarker <<
" ";
205 os << theSeed <<
" ";
207 os << fRngState->V[i] <<
"\n";
209 os << fRngState->counter <<
"\n";
210 os << fRngState->sumtot <<
"\n";
211 os << endMarker <<
"\n";
216 std::vector<unsigned long> MixMaxRng::put ()
const
218 std::vector<unsigned long> v;
219 v.push_back (engineIDulong<MixMaxRng>());
221 v.push_back(static_cast<unsigned long>(fRngState->V[i] &
MASK32));
223 v.push_back(static_cast<unsigned long>(fRngState->V[i] >> 32 ));
226 v.push_back(static_cast<unsigned long>(fRngState->counter));
227 v.push_back(static_cast<unsigned long>(fRngState->sumtot & MASK32));
228 v.push_back(static_cast<unsigned long>(fRngState->sumtot >> 32));
232 std::istream & MixMaxRng::get ( std::istream& is)
240 if (strcmp(beginMarker,
"MixMaxRng-begin")) {
241 is.clear(std::ios::badbit | is.rdstate());
242 std::cerr <<
"\nInput stream mispositioned or"
243 <<
"\nMixMaxRng state description missing or"
244 <<
"\nwrong engine type found." << std::endl;
250 std::string MixMaxRng::beginTag ()
252 return "MixMaxRng-begin";
255 std::istream & MixMaxRng::getState ( std::istream& is )
259 for (
int i=0; i<rng_get_N(); ++i) is >> fRngState->V[i];
260 is >> fRngState->counter;
266 if (strcmp(endMarker,
"MixMaxRng-end")) {
267 is.clear(std::ios::badbit | is.rdstate());
268 std::cerr <<
"\nMixMaxRng state description incomplete."
269 <<
"\nInput stream is probably mispositioned now.\n";
272 if ( fRngState->counter < 0 || fRngState->counter >
rng_get_N() ) {
273 std::cerr <<
"\nMixMaxRng::getState(): "
274 <<
"vector read wrong value of counter from file!"
275 <<
"\nInput stream is probably mispositioned now.\n";
279 if ( checksum != fRngState->sumtot) {
280 std::cerr <<
"\nMixMaxRng::getState(): "
281 <<
"checksum disagrees with value stored in file!"
282 <<
"\nInput stream is probably mispositioned now.\n";
288 bool MixMaxRng::get (
const std::vector<unsigned long> & v)
290 if ((v[0] & 0xffffffffUL) != engineIDulong<MixMaxRng>()) {
292 "\nMixMaxRng::get(): vector has wrong ID word - state unchanged\n";
298 bool MixMaxRng::getState (
const std::vector<unsigned long> & v)
300 if (v.size() != VECTOR_STATE_SIZE ) {
302 "\nMixMaxRng::getState(): vector has wrong length - state unchanged\n";
306 fRngState->V[i/2]= ( (v[i] &
MASK32) | ( (myuint)(v[i+1]) << 32 ) );
312 | ( (myuint)(v[2*
rng_get_N()+3]) << 32 ) ) != fRngState->sumtot) {
313 std::cerr <<
"\nMixMaxRng::getState(): vector has wrong checksum!"
314 <<
"\nInput vector is probably mispositioned now.\n";
void print_state(rng_state_t *X)
static const int MarkerLen
rng_state_t * rng_copy(myuint *Y)
myuint get_next(rng_state_t *X)
const unsigned long MASK32
int rng_free(rng_state_t *X)
const char * name(G4int ptype)
void seed_spbox(rng_state_t *X, myuint seed)
double get_next_float(rng_state_t *X)
void seed_uniquestream(rng_state_t *Xin, myID_t clusterID, myID_t machineID, myID_t runID, myID_t streamID)
rng_state_t * rng_alloc()
myuint precalc(rng_state_t *X)
void read_state(rng_state_t *X, const char filename[])
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.