41 const unsigned long MASK32=0xffffffff;
55 int numEngines = ++numberOfEngines;
56 setSeed(static_cast<long>(numEngines));
88 if (
this == &rng) {
return *
this; }
92 HepRandomEngine::operator=(rng);
104 FILE *fh= fopen(filename,
"w");
108 fprintf(fh,
"mixmax state, file version 1.0\n" );
109 fprintf(fh,
"N=%u; V[N]={",
rng_get_N() );
111 fprintf(fh,
"%llu, ",
S.
V[j] );
115 fprintf(fh,
"counter=%u; ",
S.
counter );
116 fprintf(fh,
"sumtot=%llu;\n",
S.
sumtot );
121 #define MIXMAX_ARRAY_INDEX_OUT_OF_BOUNDS 0xFF01
122 #define MIXMAX_SEED_WAS_ZERO 0xFF02
123 #define MIXMAX_ERROR_READING_STATE_FILE 0xFF03
124 #define MIXMAX_ERROR_READING_STATE_COUNTER 0xFF04
125 #define MIXMAX_ERROR_READING_STATE_CHECKSUM 0xFF05
131 if( ( fin = fopen(filename,
"r") ) )
141 fprintf(stderr,
"mixmax -> read_state: error reading file %s\n", filename);
147 if (!fscanf(fin,
"%llu", &
S.
V[0]) )
149 fprintf(stderr,
"mixmax -> read_state: error reading file %s\n", filename);
156 if (!fscanf(fin,
", %llu", &vecVal) )
158 fprintf(stderr,
"mixmax -> read_state: error reading vector component i=%d from file %s\n", i, filename);
167 fprintf(stderr,
"mixmax -> read_state: Invalid state vector value= %llu"
168 " ( must be less than %llu ) "
169 " obtained from reading file %s\n"
175 if (!fscanf( fin,
"}; counter=%i; ", &counter))
177 fprintf(stderr,
"mixmax -> read_state: error reading counter from file %s\n", filename);
186 fprintf(stderr,
"mixmax -> read_state: Invalid counter = %d"
187 " Must be 0 <= counter < %u\n" , counter,
rng_get_N());
193 if (!fscanf( fin,
"sumtot=%llu\n", &sumtot))
195 fprintf(stderr,
"mixmax -> read_state: error reading checksum from file %s\n", filename);
201 fprintf(stderr,
"mixmax -> checksum error while reading state from file %s - corrupted?\n", filename);
207 #undef MIXMAX_ARRAY_INDEX_OUT_OF_BOUNDS
208 #undef MIXMAX_SEED_WAS_ZERO
209 #undef MIXMAX_ERROR_READING_STATE_FILE
210 #undef MIXMAX_ERROR_READING_STATE_COUNTER
211 #undef MIXMAX_ERROR_READING_STATE_CHECKSUM
215 std::cout << std::endl;
216 std::cout <<
"------- MixMaxRng engine status -------" << std::endl;
218 std::cout <<
" Current state vector is:" << std::endl;
220 std::cout <<
"---------------------------------------" << std::endl;
236 unsigned long seed0, seed1= 0, seed2= 0, seed3= 0;
239 seed0=
static_cast<unsigned long>(Seeds[0]) &
MASK32;
240 seed1=
static_cast<unsigned long>(Seeds[1]) &
MASK32;
245 seed0=
static_cast<unsigned long>(Seeds[0]) &
MASK32;
246 if( seedNum > 1){ seed1=
static_cast<unsigned long>(Seeds[1]) &
MASK32; }
247 if( seedNum > 2){ seed2=
static_cast<unsigned long>(Seeds[2]) &
MASK32; }
250 seed0=
static_cast<unsigned long>(Seeds[0]) &
MASK32;
251 seed1=
static_cast<unsigned long>(Seeds[1]) &
MASK32;
252 seed2=
static_cast<unsigned long>(Seeds[2]) &
MASK32;
253 seed3=
static_cast<unsigned long>(Seeds[3]) &
MASK32;
284 #if defined(__clang__) || defined(__llvm__)
285 return INV_M61*
static_cast<double>(
S.
V[i]);
286 #elif defined(__GNUC__) && (__GNUC__ < 7) && (!defined(__ICC)) && defined(__x86_64__) && defined(__SSE2_MATH__)
293 __asm__ __volatile__(
"pxor %0, %0;"
313 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[1] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[1] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
314 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[2] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[2] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
315 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[3] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[3] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
316 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[4] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[4] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
317 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[5] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[5] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
318 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[6] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[6] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
319 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[7] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[7] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
320 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[8] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[8] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
321 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[9] ); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[9] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
322 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[10]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[10] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
323 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[11]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[11] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
324 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[12]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[12] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
325 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[13]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[13] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
326 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[14]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[14] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
327 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[15]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[15] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
328 tempPO =
MULWU(tempP); tempP =
modadd(tempP, Y[16]); tempV =
MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); Y[16] = tempV; sumtot += tempV;
if (sumtot < tempV) {ovflow++;};
338 for (
int i=0; i<size; ++i) { vect[i] =
flat(); }
341 MixMaxRng::operator double()
346 MixMaxRng::operator float()
348 return float(
flat() );
351 MixMaxRng::operator
unsigned int()
353 return static_cast<unsigned int>(get_next());
360 char beginMarker[] =
"MixMaxRng-begin";
361 char endMarker[] =
"MixMaxRng-end";
363 int pr = os.precision(24);
364 os << beginMarker <<
" ";
367 os <<
S.
V[i] <<
"\n";
371 os << endMarker <<
"\n";
378 std::vector<unsigned long> v;
379 v.push_back (engineIDulong<MixMaxRng>());
382 v.push_back(static_cast<unsigned long>(
S.
V[i] &
MASK32));
384 v.push_back(static_cast<unsigned long>(
S.
V[i] >> 32 ));
387 v.push_back(static_cast<unsigned long>(
S.
counter));
389 v.push_back(static_cast<unsigned long>(
S.
sumtot >> 32));
401 if (strcmp(beginMarker,
"MixMaxRng-begin")) {
402 is.clear(std::ios::badbit | is.rdstate());
403 std::cerr <<
"\nInput stream mispositioned or"
404 <<
"\nMixMaxRng state description missing or"
405 <<
"\nwrong engine type found." << std::endl;
413 return "MixMaxRng-begin";
420 for (
int i=0; i<rng_get_N(); ++i) is >>
S.
V[i];
427 if (strcmp(endMarker,
"MixMaxRng-end")) {
428 is.clear(std::ios::badbit | is.rdstate());
429 std::cerr <<
"\nMixMaxRng state description incomplete."
430 <<
"\nInput stream is probably mispositioned now.\n";
434 std::cerr <<
"\nMixMaxRng::getState(): "
435 <<
"vector read wrong value of counter from file!"
436 <<
"\nInput stream is probably mispositioned now.\n";
441 std::cerr <<
"\nMixMaxRng::getState(): "
442 <<
"checksum disagrees with value stored in file!"
443 <<
"\nInput stream is probably mispositioned now.\n";
451 if ((v[0] & 0xffffffffUL) != engineIDulong<MixMaxRng>()) {
453 "\nMixMaxRng::get(): vector has wrong ID word - state unchanged\n";
463 "\nMixMaxRng::getState(): vector has wrong length - state unchanged\n";
474 std::cerr <<
"\nMixMaxRng::getState(): vector has wrong checksum!"
475 <<
"\nInput vector is probably mispositioned now.\n";
495 std::cerr <<
"MIXMAX ERROR: " <<
"Disallowed value of parameter N\n";
512 Y[0] = ( tempV = sumtotOld);
515 for (i=1; (i<
N); i++)
518 tempP =
modadd(tempP, Y[i]);
521 sumtot += tempV;
if (sumtot < tempV) {ovflow++;}
549 for (i=0; i <
N; i++){
567 for (i=0; i <
N; i++){
580 #define MIXMAX_SEED_WAS_ZERO 0xFF02
586 const myuint_t MULT64=6364136223846793005ULL;
592 fprintf(stderr,
" try seeding with nonzero seed next time!\n");
598 for (i=0; i <
N; i++){
599 l*=MULT64; l = (l << 32) ^ (l>>32);
601 sumtot +=
S.
V[(i)];
if (sumtot <
S.
V[(i)]) {ovflow++;}
607 #undef MIXMAX_SEED_WAS_ZERO
639 #include "CLHEP/Random/mixmax_skip_N17.icc"
643 for (
int i=0; i<128; i++) { skipMat[i] = skipMat17[i];}
645 myID_t IDvec[4] = {streamID, runID, machineID, clusterID};
653 for (i=0; i<
N; i++) { Y[i] = Vin[i]; sumtot =
modadd( sumtot, Vin[i]); } ;
654 for (IDindex=0; IDindex<4; IDindex++)
664 for (i=0; i<
N; i++){ cum[i] = 0; }
669 for (i =0; i<
N; i++){
675 for (i=0; i<
N; i++){ Y[i] = cum[i]; sumtot =
modadd( sumtot, cum[i]); } ;
681 for (i=0; i<
N; i++){ Vout[i] = Y[i]; sumtot =
modadd( sumtot, Y[i]); }
686 #if defined(__x86_64__)
687 myuint_t MixMaxRng::mod128(__uint128_t
s)
696 temp = (__uint128_t)a*(__uint128_t)b + cum;
699 #else // on all other platforms, including 32-bit linux, PPC and PPC64, ARM and all Windows
709 o = (o &
M61) + ((ph*ah)<<3) + ((ah*pl+al*ph + ((al*pl)>>32))>>29) ;
711 o = (o &
M61) + ((o>>61));
718 #if defined(__x86_64__) && defined(__GNUC__) && (!defined(__ICC))
722 __asm__ (
"addq %2, %0; "
737 std::cout <<
"mixmax state, file version 1.0\n";
738 std::cout <<
"N=" <<
rng_get_N() <<
"; V[N]={";
740 std::cout <<
S.
V[j] <<
", ";
744 std::cout <<
"counter= " <<
S.
counter;
745 std::cout <<
"sumtot= " <<
S.
sumtot <<
"\n";
760 constexpr
myuint_t MULT64=6364136223846793005ULL;
762 S.
V[1] *= MULT64;
S.
V[id] &=
M61;
double convert1double(myuint_t u)
void BranchInplace(int id)
static constexpr long long int SPECIAL
unsigned long long int myuint_t
std::vector< ExP01TrackerHit * > a
virtual std::istream & getState(std::istream &is)
static std::string beginTag()
#define MIXMAX_ERROR_READING_STATE_FILE
myuint_t apply_bigskip(myuint_t *Vout, myuint_t *Vin, myID_t clusterID, myID_t machineID, myID_t runID, myID_t streamID)
#define MIXMAX_MOD_MERSENNE(k)
void restoreStatus(const char filename[]="MixMaxRngState.conf")
static constexpr unsigned int VECTOR_STATE_SIZE
myuint_t MOD_MULSPEC(myuint_t k)
std::array< myuint_t, N > V
virtual std::istream & get(std::istream &is)
MixMaxRng & operator=(const MixMaxRng &rng)
std::vector< unsigned long > put() const
const unsigned long MASK32
#define MIXMAX_ERROR_READING_STATE_CHECKSUM
static const int MarkerLen
myuint_t iterate_raw_vec(myuint_t *Y, myuint_t sumtotOld)
void setSeeds(const long *seeds, int seedNum=0)
myuint_t fmodmulM61(myuint_t cum, myuint_t s, myuint_t a)
double get_next_float_packbits()
void seed_vielbein(unsigned int i)
static constexpr double INV_M61
#define CLHEP_ATOMIC_INT_TYPE
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
static constexpr double s
#define MIXMAX_SEED_WAS_ZERO
void saveStatus(const char filename[]="MixMaxRngState.conf") const
static constexpr myuint_t M61
static constexpr int rng_get_SPECIALMUL()
static constexpr long long int rng_get_SPECIAL()
myuint_t MULWU(myuint_t k)
void flatArray(const int size, double *vect)
static constexpr double bar
myuint_t modadd(myuint_t foo, myuint_t bar)
void seed_uniquestream(myID_t clusterID, myID_t machineID, myID_t runID, myID_t streamID)
static constexpr int BITS
static std::string engineName()
#define MIXMAX_ERROR_READING_STATE_COUNTER
void setSeed(long seed, int dum=0)
static constexpr int rng_get_N()
static constexpr long long int SPECIALMUL
void seed_spbox(myuint_t)