38#include "CLHEP/Random/RanluxppEngine.h"
40#include "CLHEP/Random/engineIDulong.h"
41#include "CLHEP/Utility/atomic_int.h"
57const uint64_t kA_2048[] = {
58 0xed7faa90747aaad9, 0x4cec2c78af55c101, 0xe64dcb31c48228ec,
59 0x6d8a15a13bee7cb0, 0x20b2ca60cb78c509, 0x256c3d3c662ea36c,
60 0xff74e54107684ed2, 0x492edfcc0cc8e753, 0xb48c187cf5b22097,
65 int numEngines = ++numberOfEngines;
80static constexpr int kMaxPos = 9 * 64;
81static constexpr int kBits = 48;
83void RanluxppEngine::advance() {
85 to_lcg(fState, fCarry, lcg);
87 to_ranlux(lcg, fState, fCarry);
91uint64_t RanluxppEngine::nextRandomBits() {
92 if (fPosition + kBits > kMaxPos) {
96 int idx = fPosition / 64;
97 int offset = fPosition % 64;
98 int numBits = 64 - offset;
100 uint64_t bits = fState[idx] >> offset;
101 if (numBits < kBits) {
102 bits |= fState[idx + 1] << numBits;
104 bits &= ((uint64_t(1) << kBits) - 1);
107 assert(fPosition <= kMaxPos &&
"position out of range!");
117 random = nextRandomBits();
118 }
while (random == 0);
120 static constexpr double div = 1.0 / (uint64_t(1) << kBits);
125 for (
int i = 0; i < size; i++) {
135 for (
int i = 1; i < 9; i++) {
141 powermod(kA_2048, a_seed, uint64_t(1) << 48);
142 powermod(a_seed, a_seed, uint64_t(1) << 48);
144 powermod(a_seed, a_seed, seed);
147 to_ranlux(lcg, fState, fCarry);
157 int left = (kMaxPos - fPosition) / kBits;
158 assert(left >= 0 &&
"position was out of range!");
159 if (n < (uint64_t)left) {
161 fPosition += n * kBits;
167 int nPerState = kMaxPos / kBits;
168 int skip = int(n / nPerState);
171 powermod(kA_2048, a_skip,
skip + 1);
174 to_lcg(fState, fCarry, lcg);
176 to_ranlux(lcg, fState, fCarry);
179 int remaining = int(n -
skip * nPerState);
180 assert(remaining >= 0 &&
"should not end up at a negative position!");
181 fPosition = remaining * kBits;
182 assert(fPosition <= kMaxPos &&
"position out of range!");
186 std::ofstream os(filename);
192 std::ifstream is(filename);
199 <<
"--------------------- RanluxppEngine status --------------------"
201 std::cout <<
" fState[] = {";
202 std::cout << std::hex << std::setfill(
'0');
203 for (
int i = 0; i < 9; i++) {
205 std::cout << std::endl <<
" ";
209 std::cout <<
"0x" << std::setw(16) << fState[i] <<
",";
211 std::cout << std::endl <<
" }" << std::endl;
212 std::cout << std::dec;
213 std::cout <<
" fCarry = " << fCarry <<
", fPosition = " << fPosition
216 <<
"----------------------------------------------------------------"
228 const std::vector<unsigned long> state =
put();
229 for (
unsigned long v : state) {
239 is.clear(std::ios::badbit | is.rdstate());
240 std::cerr <<
"No RanluxppEngine found at current position\n";
247 std::vector<unsigned long> state;
260 std::vector<unsigned long> v;
262 v.push_back(engineIDulong<RanluxppEngine>());
266 for (
int i = 0; i < 9; i++) {
267 unsigned long lower =
static_cast<uint32_t
>(fState[i]);
269 unsigned long upper =
static_cast<uint32_t
>(fState[i] >> 32);
274 v.push_back(fPosition);
279 if (v[0] != engineIDulong<RanluxppEngine>()) {
280 std::cerr <<
"RanluxppEngine::get(): "
281 <<
"vector has wrong ID word - state unchanged" << std::endl;
289 std::cerr <<
"RanluxppEngine::getState(): "
290 <<
"vector has wrong length - state unchanged" << std::endl;
295 for (
int i = 0; i < 9; i++) {
296 uint64_t lower = v[2 * i + 1];
297 uint64_t upper = v[2 * i + 2];
298 fState[i] = (upper << 32) + lower;
300 fCarry = (
unsigned int)v[19];
301 fPosition = (int)v[20];
#define CLHEP_ATOMIC_INT_TYPE
void showStatus() const override
virtual ~RanluxppEngine()
void saveStatus(const char filename[]="Ranluxpp.conf") const override
std::string name() const override
std::istream & get(std::istream &is) override
static std::string engineName()
std::vector< unsigned long > put() const override
void setSeeds(const long *seeds, int dummy=0) override
void restoreStatus(const char filename[]="Ranluxpp.conf") override
static const unsigned int VECTOR_STATE_SIZE
void flatArray(const int size, double *vect) override
void setSeed(long seed, int dummy=0) override
std::istream & getState(std::istream &is) override
static std::string beginTag()