File indexing completed on 2025-09-16 08:52:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef MixMaxRng_h
0036 #define MixMaxRng_h 1
0037
0038 #include <array>
0039 #include <cstdint>
0040 #include "CLHEP/Random/defs.h"
0041 #include "CLHEP/Random/RandomEngine.h"
0042
0043 namespace CLHEP {
0044
0045
0046
0047
0048
0049
0050 using myID_t = std::uint32_t;
0051 using myuint_t = std::uint64_t;
0052
0053 class
0054 #if (__cplusplus >= 201703L && __cpp_aligned_new >= 201606L)
0055 alignas(128)
0056 #endif
0057 MixMaxRng : public HepRandomEngine
0058 {
0059
0060 static const int N = 17;
0061
0062 public:
0063
0064 MixMaxRng(std::istream& is);
0065 MixMaxRng();
0066 MixMaxRng(long seed);
0067 ~MixMaxRng();
0068
0069
0070 MixMaxRng(const MixMaxRng& rng);
0071 MixMaxRng& operator=(const MixMaxRng& rng);
0072
0073
0074 inline double flat()
0075 {
0076 if (counter >= N) iterate();
0077 return INV_M61*static_cast<double>(V[counter++]);
0078 }
0079
0080
0081
0082
0083 void flatArray (const int size, double* vect);
0084
0085
0086 inline void setSeed(long longSeed, int = 0 )
0087 {
0088 seed_spbox(theSeed = longSeed);
0089 }
0090
0091
0092 void setSeeds(const long * seeds, int seedNum=0);
0093
0094
0095
0096
0097
0098 void saveStatus( const char filename[] = "MixMaxRngState.conf" ) const;
0099
0100
0101 void restoreStatus( const char filename[] = "MixMaxRngState.conf" );
0102
0103
0104
0105 void showStatus() const;
0106
0107
0108 inline operator double() { return flat(); }
0109
0110
0111 inline operator float() { return float( flat() ); }
0112
0113
0114 inline operator unsigned int() { return static_cast<unsigned int>(get_next()); }
0115
0116
0117
0118 virtual std::ostream & put (std::ostream & os) const;
0119 virtual std::istream & get (std::istream & is);
0120 static std::string beginTag ( );
0121 virtual std::istream & getState ( std::istream & is );
0122
0123 std::string name() const { return "MixMaxRng"; }
0124 static std::string engineName();
0125
0126 std::vector<unsigned long> put () const;
0127 bool get (const std::vector<unsigned long> & vec);
0128 bool getState (const std::vector<unsigned long> & vec);
0129
0130 private:
0131
0132 static constexpr long long int SPECIAL = 0;
0133 static constexpr long long int SPECIALMUL= 36;
0134 static constexpr int BITS=61;
0135 static constexpr myuint_t M61=2305843009213693951ULL;
0136 static constexpr double INV_M61=0.43368086899420177360298E-18;
0137 static constexpr unsigned int VECTOR_STATE_SIZE = 2*N+4;
0138
0139 inline myuint_t MIXMAX_MOD_MERSENNE(myuint_t k)
0140 {
0141 return ((((k)) & M61) + (((k)) >> BITS) );
0142 }
0143
0144 static constexpr int rng_get_N();
0145 void seed_uniquestream( myID_t clusterID, myID_t machineID, myID_t runID, myID_t streamID );
0146 void seed_spbox(myuint_t seed);
0147 void print_state() const;
0148 myuint_t precalc();
0149 myuint_t get_next();
0150
0151 MixMaxRng Branch();
0152 void BranchInplace(int id);
0153
0154 MixMaxRng(myID_t clusterID, myID_t machineID, myID_t runID, myID_t streamID );
0155 inline void seed64(myuint_t seedval)
0156 {
0157 seed_uniquestream( 0, 0, (myID_t)(seedval>>32), (myID_t)seedval );
0158 }
0159
0160 inline void iterate()
0161 {
0162 myuint_t tempP, tempV;
0163 V[0] = ( tempV = sumtot );
0164 myuint_t insumtot = V[0], ovflow = 0;
0165 tempP = 0;
0166 myuint_t tempPO;
0167 tempPO = MULWU(tempP); tempP = modadd(tempP, V[1] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[1] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0168 tempPO = MULWU(tempP); tempP = modadd(tempP, V[2] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[2] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0169 tempPO = MULWU(tempP); tempP = modadd(tempP, V[3] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[3] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0170 tempPO = MULWU(tempP); tempP = modadd(tempP, V[4] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[4] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0171 tempPO = MULWU(tempP); tempP = modadd(tempP, V[5] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[5] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0172 tempPO = MULWU(tempP); tempP = modadd(tempP, V[6] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[6] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0173 tempPO = MULWU(tempP); tempP = modadd(tempP, V[7] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[7] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0174 tempPO = MULWU(tempP); tempP = modadd(tempP, V[8] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[8] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0175 tempPO = MULWU(tempP); tempP = modadd(tempP, V[9] ); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[9] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0176 tempPO = MULWU(tempP); tempP = modadd(tempP, V[10]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[10] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0177 tempPO = MULWU(tempP); tempP = modadd(tempP, V[11]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[11] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0178 tempPO = MULWU(tempP); tempP = modadd(tempP, V[12]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[12] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0179 tempPO = MULWU(tempP); tempP = modadd(tempP, V[13]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[13] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0180 tempPO = MULWU(tempP); tempP = modadd(tempP, V[14]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[14] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0181 tempPO = MULWU(tempP); tempP = modadd(tempP, V[15]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[15] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0182 tempPO = MULWU(tempP); tempP = modadd(tempP, V[16]); tempV = MIXMAX_MOD_MERSENNE(tempV+tempP+tempPO); V[16] = tempV; insumtot += tempV; if (insumtot < tempV) {++ovflow;}
0183 sumtot = MIXMAX_MOD_MERSENNE(MIXMAX_MOD_MERSENNE(insumtot) + (ovflow <<3 ));
0184
0185 counter=1;
0186 }
0187
0188 void state_init();
0189 inline myuint_t MULWU (myuint_t k)
0190 {
0191 return (( (k)<<(SPECIALMUL) & M61) ^ ( (k) >> (BITS-SPECIALMUL)) );
0192 }
0193 myuint_t iterate_raw_vec(myuint_t* Y, myuint_t sumtotOld);
0194 myuint_t apply_bigskip(myuint_t* Vout, myuint_t* Vin, myID_t clusterID, myID_t machineID, myID_t runID, myID_t streamID );
0195 inline myuint_t modadd(myuint_t xfoo, myuint_t xbar)
0196 {
0197 return MIXMAX_MOD_MERSENNE(xfoo+xbar);
0198 }
0199
0200 #if defined(__x86_64__)
0201 myuint_t mod128(__uint128_t s);
0202 myuint_t fmodmulM61(myuint_t cum, myuint_t a, myuint_t b);
0203 #else
0204 myuint_t fmodmulM61(myuint_t cum, myuint_t s, myuint_t a);
0205 #endif
0206
0207
0208
0209 myuint_t V[N] = {0};
0210 myuint_t sumtot = 0;
0211 int counter = N;
0212 };
0213
0214 }
0215
0216 #endif