47const unsigned long MASK32=0xffffffff;
56static const int MarkerLen = 64;
61 int numEngines = ++numberOfEngines;
62 setSeed(
static_cast<long>(numEngines));
85 std::copy(rng.V, rng.V+N, V);
94 if (
this == &rng) {
return *
this; }
98 HepRandomEngine::operator=(rng);
100 std::copy(rng.V, rng.V+N, V);
102 counter= rng.counter;
110 FILE *fh= fopen(filename,
"w");
114 fprintf(fh,
"mixmax state, file version 1.0\n" );
115 fprintf(fh,
"N=%u; V[N]={", rng_get_N() );
116 for (j=0; (j< (rng_get_N()-1) ); ++j) {
117 fprintf(fh,
"%llu, ", (
unsigned long long)V[j] );
119 fprintf(fh,
"%llu", (
unsigned long long)V[rng_get_N()-1] );
121 fprintf(fh,
"counter=%u; ", counter );
122 fprintf(fh,
"sumtot=%llu;\n", (
unsigned long long)sumtot );
131 if( ( fin = fopen(filename,
"r") ) )
141 fprintf(stderr,
"mixmax -> read_state: error reading file %s\n", filename);
142 throw std::runtime_error(
"Error in reading state file");
147 if (!fscanf(fin,
"%llu", (
unsigned long long*) &V[0]) )
149 fprintf(stderr,
"mixmax -> read_state: error reading file %s\n", filename);
150 throw std::runtime_error(
"Error in reading state file");
153 for (
int i = 1; i < rng_get_N(); ++i)
155 if (!fscanf(fin,
", %llu", (
unsigned long long*) &vecVal) )
157 fprintf(stderr,
"mixmax -> read_state: error reading vector component i=%d from file %s\n", i, filename);
158 throw std::runtime_error(
"Error in reading state file");
160 if( vecVal <= MixMaxRng::M61 )
166 fprintf(stderr,
"mixmax -> read_state: Invalid state vector value= %llu"
167 " ( must be less than %llu ) "
168 " obtained from reading file %s\n"
169 , (
unsigned long long)vecVal, (
unsigned long long)MixMaxRng::M61, filename);
174 if (!fscanf( fin,
"}; counter=%i; ", &incounter))
176 fprintf(stderr,
"mixmax -> read_state: error reading counter from file %s\n", filename);
177 throw std::runtime_error(
"Error in reading state file");
179 if( incounter <= rng_get_N() )
185 fprintf(stderr,
"mixmax -> read_state: Invalid counter = %d"
186 " Must be 0 <= counter < %u\n" , counter, rng_get_N());
188 throw std::runtime_error(
"Error in reading state counter");
192 if (!fscanf( fin,
"sumtot=%llu\n", (
unsigned long long*) &insumtot))
194 fprintf(stderr,
"mixmax -> read_state: error reading checksum from file %s\n", filename);
195 throw std::runtime_error(
"Error in reading state file");
198 if (sumtot != insumtot)
200 fprintf(stderr,
"mixmax -> checksum error while reading state from file %s - corrupted?\n", filename);
201 throw std::runtime_error(
"Error in reading state checksum");
208 std::cout << std::endl;
209 std::cout <<
"------- MixMaxRng engine status -------" << std::endl;
211 std::cout <<
" Current state vector is:" << std::endl;
213 std::cout <<
"---------------------------------------" << std::endl;
222 myID_t seed0, seed1= 0, seed2= 0, seed3= 0;
232 if( seedNum > 1){ seed1=
static_cast<myID_t>(Seeds[1]) &
MASK32; }
233 if( seedNum > 2){ seed2=
static_cast<myID_t>(Seeds[2]) &
MASK32; }
244 seed_uniquestream(seed3, seed2, seed1, seed0);
252constexpr int MixMaxRng::rng_get_N()
259 for (
int i=0; i<size; ++i) { vect[i] =
flat(); }
264 char beginMarker[] =
"MixMaxRng-begin";
265 char endMarker[] =
"MixMaxRng-end";
267 long pr = os.precision(24);
268 os << beginMarker <<
" ";
270 for (
int i=0; i<rng_get_N(); ++i) {
273 os << counter <<
"\n";
274 os << sumtot <<
"\n";
275 os << endMarker <<
"\n";
282 std::vector<unsigned long> vec;
284 for (
int i=0; i<rng_get_N(); ++i)
286 vec.push_back(
static_cast<unsigned long>(V[i] &
MASK32));
288 vec.push_back(
static_cast<unsigned long>(V[i] >> 32 ));
291 vec.push_back(
static_cast<unsigned long>(counter));
292 vec.push_back(
static_cast<unsigned long>(sumtot &
MASK32));
293 vec.push_back(
static_cast<unsigned long>(sumtot >> 32));
299 char beginMarker [MarkerLen];
305 if (strcmp(beginMarker,
"MixMaxRng-begin")) {
306 is.clear(std::ios::badbit | is.rdstate());
307 std::cerr <<
"\nInput stream mispositioned or"
308 <<
"\nMixMaxRng state description missing or"
309 <<
"\nwrong engine type found." << std::endl;
317 return "MixMaxRng-begin";
322 char endMarker[MarkerLen];
324 for (
int i=0; i<rng_get_N(); ++i) is >> V[i];
331 if (strcmp(endMarker,
"MixMaxRng-end")) {
332 is.clear(std::ios::badbit | is.rdstate());
333 std::cerr <<
"\nMixMaxRng state description incomplete."
334 <<
"\nInput stream is probably mispositioned now.\n";
337 if ( counter < 0 || counter > rng_get_N() ) {
338 std::cerr <<
"\nMixMaxRng::getState(): "
339 <<
"vector read wrong value of counter from file!"
340 <<
"\nInput stream is probably mispositioned now.\n";
344 if ( checksum != sumtot) {
345 std::cerr <<
"\nMixMaxRng::getState(): "
346 <<
"checksum disagrees with value stored in file!"
347 <<
"\nInput stream is probably mispositioned now.\n";
358 "\nMixMaxRng::get(): vector has wrong ID word - state unchanged\n";
366 if (vec.size() != VECTOR_STATE_SIZE ) {
368 "\nMixMaxRng::getState(): vector has wrong length - state unchanged\n";
371 for (
int i=1; i<2*rng_get_N() ; i=i+2) {
375 counter = (int)vec[2*rng_get_N()+1];
377 if ( ( (vec[2*rng_get_N()+2] &
MASK32)
378 | ( (
myuint_t)(vec[2*rng_get_N()+3]) << 32 ) ) != sumtot) {
379 std::cerr <<
"\nMixMaxRng::getState(): vector has wrong checksum!"
380 <<
"\nInput vector is probably mispositioned now.\n";
391 Y[0] = ( tempV = sumtotOld);
394 for (
int i=1; (i<N); ++i)
397 tempP = modadd(tempP,
Y[i]);
398 tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO);
400 insumtot += tempV;
if (insumtot < tempV) {++ovflow;}
402 return MIXMAX_MOD_MERSENNE(MIXMAX_MOD_MERSENNE(insumtot) + (ovflow <<3 ));
416 sumtot = iterate_raw_vec(V, sumtot);
425 for (
int i=0; i < N; ++i) { temp = MIXMAX_MOD_MERSENNE(temp + V[i]); }
430void MixMaxRng::state_init()
432 for (
int i=1; i < N; ++i) { V[i] = 0; }
438void MixMaxRng::seed_spbox(
myuint_t seed)
443 throw std::runtime_error(
"try seeding with nonzero seed next time");
445 const myuint_t MULT64=6364136223846793005ULL;
450 for (
int i=0; i < N; ++i)
452 l*=MULT64; l = (l << 32) ^ (l>>32);
454 sumtot = MIXMAX_MOD_MERSENNE(sumtot + V[(i)]);
462 sumtot = apply_bigskip(V, V, clusterID, machineID, runID, streamID );
489 #include "CLHEP/Random/mixmax_skip_N17.icc"
493 for (
int i=0; i<128; ++i) { skipMat[i] = skipMat17[i]; }
495 myID_t IDvec[4] = {streamID, runID, machineID, clusterID};
503 for (i=0; i<
N; ++i) {
Y[i] = Vin[i]; insumtot = modadd( insumtot, Vin[i]); }
504 for (IDindex=0; IDindex<4; ++IDindex)
514 for (i=0; i<
N; ++i){ cum[i] = 0; }
519 for (i =0; i<
N; ++i){
520 cum[i] = fmodmulM61( cum[i], coeff ,
Y[i] ) ;
522 insumtot = iterate_raw_vec(
Y, insumtot);
525 for (i=0; i<
N; ++i){
Y[i] = cum[i]; insumtot = modadd( insumtot, cum[i]); } ;
531 for (i=0; i<
N; ++i){ Vout[i] =
Y[i]; insumtot = modadd( insumtot,
Y[i]); }
536#if defined(__x86_64__)
537 myuint_t MixMaxRng::mod128(__uint128_t s)
541 return MIXMAX_MOD_MERSENNE(s1);
546 temp = (__uint128_t)a*(__uint128_t)b + cum;
559 o = (o & M61) + ((ph*ah)<<3) + ((ah*pl+al*ph + ((al*pl)>>32))>>29) ;
561 o = (o & M61) + ((o>>61));
566void MixMaxRng::print_state()
const
568 std::cout <<
"mixmax state, file version 1.0\n";
569 std::cout <<
"N=" << rng_get_N() <<
"; V[N]={";
570 for (
int j=0; (j< (rng_get_N()-1) ); ++j) { std::cout << V[j] <<
", "; }
571 std::cout << V[rng_get_N()-1];
573 std::cout <<
"counter= " << counter;
574 std::cout <<
"sumtot= " << sumtot <<
"\n";
577MixMaxRng MixMaxRng::Branch()
579 sumtot = iterate_raw_vec(V, sumtot); counter = 1;
581 tmp.BranchInplace(0);
585void MixMaxRng::BranchInplace(
int id)
589 constexpr myuint_t MULT64=6364136223846793005ULL;
591 V[1] *= MULT64; V[id] &= M61;
592 sumtot = MIXMAX_MOD_MERSENNE( sumtot + V[
id] - tmp + M61);
593 sumtot = iterate_raw_vec(V, sumtot);
G4double Y(G4double density)
const unsigned long MASK32
#define CLHEP_ATOMIC_INT_TYPE
void restoreStatus(const char filename[]="MixMaxRngState.conf")
void flatArray(const int size, double *vect)
static std::string beginTag()
void saveStatus(const char filename[]="MixMaxRngState.conf") const
virtual std::istream & get(std::istream &is)
MixMaxRng & operator=(const MixMaxRng &rng)
virtual std::istream & getState(std::istream &is)
std::vector< unsigned long > put() const
void setSeeds(const long *seeds, int seedNum=0)
void setSeed(long longSeed, int=0)
static std::string engineName()
unsigned long engineIDulong()