68struct RanluxppData<24> {
69 static const uint64_t kA[9];
72const uint64_t RanluxppData<24>::kA[] = {
73 0x0000000000000000, 0x0000000000000000, 0x0000000000010000, 0xfffe000000000000, 0xffffffffffffffff,
74 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffeffffffff, 0xffffffffffffffff,
78struct RanluxppData<218> {
79 static const uint64_t kA[9];
81const uint64_t RanluxppData<218>::kA[] = {
82 0xf445fffffffffd94, 0xfffffd74ffffffff, 0x000000000ba5ffff, 0xfc76000000000942, 0xfffffaaaffffffff,
83 0x0000000000b0ffff, 0x027b0000000007d1, 0xfffff96000000000, 0xfffffffff8e4ffff,
87struct RanluxppData<223> {
88 static const uint64_t kA[9];
91const uint64_t RanluxppData<223>::kA[] = {
92 0x0000000ba6000000, 0x0a00000000094200, 0xffeef0fffffffffa, 0xfffffffe25ffffff, 0x7b0000000007d0ff,
93 0xfff9600000000002, 0xfffffff8e4ffffff, 0xba00000000026cff, 0x00028b000000000b,
97struct RanluxppData<389> {
98 static const uint64_t kA[9];
101const uint64_t RanluxppData<389>::kA[] = {
102 0x00002ecac9000000, 0x740000002c389600, 0xb9c8a6ffffffe525, 0xfffff593cfffffff, 0xab0000001e93f2ff,
103 0xe4ab160000000d92, 0xffffdf6604ffffff, 0x020000000b9242ff, 0x0df0600000002ee0,
107struct RanluxppData<404> {
108 static const uint64_t kA[9];
110const uint64_t RanluxppData<404>::kA[] = {
111 0x2eabffffffc9d08b, 0x00012612ffffff99, 0x0000007c3ebe0000, 0x353600000047bba1, 0xffd3c769ffffffd1,
112 0x0000001ada8bffff, 0x6c30000000463759, 0xffb2a1440000000a, 0xffffffc634beffff,
116struct RanluxppData<778> {
117 static const uint64_t kA[9];
119const uint64_t RanluxppData<778>::kA[] = {
120 0x872de42d9dca512b, 0xdbf015ea1662f8a0, 0x01f48f0d28482e96, 0x392fca0b3be2ae04, 0xed00881af896ce54,
121 0x14f0a768664013f3, 0x9489f52deb1f7f80, 0x72139804e09c0f37, 0x2146b0bb92a2f9a4,
125struct RanluxppData<794> {
126 static const uint64_t kA[9];
128const uint64_t RanluxppData<794>::kA[] = {
129 0x428df7227a2ca7c9, 0xde32225faaa74b1a, 0x4b9d965ca1ebd668, 0x78d15f59e58e2aff, 0x240fea15e99d075f,
130 0xfe0b70f2d7b7d169, 0x75a535f4c41d51fb, 0x1a5ef0b7233b93e1, 0xbc787ca783d5d5a9,
134struct RanluxppData<2048> {
135 static const uint64_t kA[9];
138const uint64_t RanluxppData<2048>::kA[] = {
139 0xed7faa90747aaad9, 0x4cec2c78af55c101, 0xe64dcb31c48228ec, 0x6d8a15a13bee7cb0, 0x20b2ca60cb78c509,
140 0x256c3d3c662ea36c, 0xff74e54107684ed2, 0x492edfcc0cc8e753, 0xb48c187cf5b22097,
148template <
int w,
int p,
int u>
158 static constexpr const uint64_t *
kA = RanluxppData<p>::kA;
159 static constexpr int kMaxPos = (u == 0) ? 9 * 64 : u * w;
160 static_assert(
kMaxPos <= 576,
"maximum position larger than 576 bits");
194 int numBits = 64 - offset;
196 uint64_t bits =
fState[idx] >> offset;
198 bits |=
fState[idx + 1] << numBits;
200 bits &= ((uint64_t(1) << w) - 1);
211 static constexpr double div = 1.0 / (uint64_t(1) << w);
224 const int a = 0xd1a4,
b = 0x9c4e,
c = 0x2fb3,
d = 0x7fffffab;
225 int64_t k = seed /
a;
226 seed =
b * (seed - k *
a) - k *
c ;
227 if (seed < 0) seed +=
d;
228 return seed & 0xffffff;
233 for (
int i = 6; i >= 0; i -= 3) {
235 for (
int j = 0; j < 8; j++) {
239 fState[i+0] =
r[7] + (
r[6] << 24) + (
r[5] << 48);
240 fState[i+1] = (
r[5] >> 16) + (
r[4] << 8) + (
r[3] << 32) + (
r[2] << 56);
241 fState[i+2] = (
r[2] >> 8) + (
r[1] << 16) + (
r[0] << 40);
257 auto next_bit = [&]() {
258 int b13 = (bits >> 18) & 0x1;
259 int b31 = bits & 0x1;
260 uint32_t bn = b13 ^ b31;
261 bits = (bn << 30) + (bits >> 1);
266 for (
int i = 0; i < 48; i++) {
276 for (
int i = 0; i < 9; i += 3) {
278 for (
int j = 0; j < 4; j++) {
283 fState[i+1] = (
r[1] >> 16) + (
r[2] << 32);
284 fState[i+2] = (
r[2] >> 32) + (
r[3] << 16);
297 for (
int i = 1; i < 9; i++) {
304 powermod(a_seed, a_seed, uint64_t(1) << 48);
318 const uint64_t
a = 40014,
m = 2147483563;
320 seed = (
a * seed) %
m;
321 return seed & 0xffffff;
324 for (
int i = 0; i < 9; i += 3) {
326 for (
int j = 0; j < 8; j++) {
330 fState[i+0] =
r[0] + (
r[1] << 24) + (
r[2] << 48);
331 fState[i+1] = (
r[2] >> 16) + (
r[3] << 8) + (
r[4] << 32) + (
r[5] << 56);
332 fState[i+2] = (
r[5] >> 8) + (
r[6] << 16) + (
r[7] << 40);
344 const uint64_t
a = 40014,
m = 2147483563;
346 seed = (
a * seed) %
m;
347 uint64_t result = seed;
348 seed = (
a * seed) %
m;
349 result += seed << 32;
350 return result & 0xffffffffffff;
353 for (
int i = 0; i < 9; i += 3) {
355 for (
int j = 0; j < 4; j++) {
360 fState[i+1] = (
r[1] >> 16) + (
r[2] << 32);
361 fState[i+2] = (
r[2] >> 32) + (
r[3] << 16);
372 assert(left >= 0 &&
"position was out of range!");
373 if (
n < (uint64_t)left) {
383 int skip = (
n / nPerState);
394 int remaining =
n - skip * nPerState;
395 assert(remaining >= 0 &&
"should not end up at a negative position!");
419 return fImpl->NextRandomFloat();
425 return fImpl->NextRandomBits();
431 fImpl->SetSeedSibidanov(seed);
462 return fImpl->NextRandomFloat();
468 return fImpl->NextRandomBits();
474 fImpl->SetSeedJames(seed);
505 return fImpl->NextRandomFloat();
511 return fImpl->NextRandomBits();
517 fImpl->SetSeedGsl(seed,
false);
549 return fImpl->NextRandomFloat();
555 return fImpl->NextRandomBits();
561 fImpl->SetSeedGsl(seed,
true);
574template <
int w,
int p>
602 auto next_bit = [&]() {
603 int b13 = (bits >> 18) & 0x1;
604 int b31 = bits & 0x1;
605 uint32_t bn = b13 ^ b31;
606 bits = (bn << 30) + (bits >> 1);
611 for (
int l = 0;
l < 24;
l++) {
612 ix = 2 * ix + next_bit();
617 for (
int i = 0; i < 4; i++) {
619 for (
int j = 0; j < 9; j += 3) {
621 for (
int m = 0;
m < 8;
m++) {
622 uint64_t ix = next();
625 if ((!ranlxd && (
m % 4) == i) || (ranlxd && (
m % 4) != i)) {
631 state.fState[j+0] =
r[0] + (
r[1] << 24) + (
r[2] << 48);
632 state.fState[j+1] = (
r[2] >> 16) + (
r[3] << 8) + (
r[4] << 32) + (
r[5] << 56);
633 state.fState[j+2] = (
r[5] >> 8) + (
r[6] << 16) + (
r[7] << 40);
647 uint64_t nPerState =
n / 4;
648 int remainder =
n % 4;
649 for (
int i = 0; i < 4; i++) {
651 uint64_t nForThisState = nPerState;
655 fStates[idx].Skip(nForThisState);
680 return fImpl->NextRandomFloat();
686 return fImpl->NextRandomBits();
692 fImpl->SetSeed(seed,
false);
724 return fImpl->NextRandomFloat();
730 return fImpl->NextRandomBits();
736 fImpl->SetSeed(seed,
true);
763 return fImpl->NextRandomFloat();
768 return fImpl->NextRandomBits();
773 fImpl->SetSeedStd24(seed);
796 return fImpl->NextRandomFloat();
801 return fImpl->NextRandomBits();
806 fImpl->SetSeedStd48(seed);
Compatibility engine for gsl_rng_ranlxd* from the GNU Scientific Library.
~RanluxppCompatEngineGslRanlxd() override
uint64_t IntRndm()
Generate a random integer value with 48 bits.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
std::unique_ptr< ImplType > fImpl
void Skip(uint64_t n)
Skip n random numbers without generating them.
double Rndm() override
Generate a floating point random number with 48 bits of randomness.
RanluxppEngineImpl< 48, p > ImplType
RanluxppCompatEngineGslRanlxd(uint64_t seed=1)
double operator()()
Generate a floating point random number (non-virtual method).
Compatibility engine for gsl_rng_ranlxs* from the GNU Scientific Library.
RanluxppEngineImpl< 24, p > ImplType
~RanluxppCompatEngineGslRanlxs() override
double operator()()
Generate a floating point random number (non-virtual method).
double Rndm() override
Generate a floating point random number with 24 bits of randomness.
void Skip(uint64_t n)
Skip n random numbers without generating them.
RanluxppCompatEngineGslRanlxs(uint64_t seed=1)
uint64_t IntRndm()
Generate a random integer value with 24 bits.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
std::unique_ptr< ImplType > fImpl
double operator()()
Generate a floating point random number (non-virtual method).
void Skip(uint64_t n)
Skip n random numbers without generating them.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
RanluxppEngineImpl< 24, p > ImplType
double Rndm() override
Generate a floating point random number with 24 bits of randomness.
uint64_t IntRndm()
Generate a random integer value with 24 bits.
std::unique_ptr< ImplType > fImpl
RanluxppCompatEngineJames(uint64_t seed=314159265)
~RanluxppCompatEngineJames() override
double NextRandomFloat()
Return a floating point number, converted from the next random bits.
uint64_t NextRandomBits()
Return the next random bits, generate a new block if necessary.
void SetSeed(uint32_t s, bool ranlxd)
Initialize and seed the state of the generator as in Lüscher's ranlxs.
RanluxppEngineImpl< w, p > fStates[4]
void Skip(uint64_t n)
Skip n random numbers without generating them.
Compatibility engine for Lüscher's ranlxd implementation written in C.
RanluxppCompatEngineLuescherImpl< 48, p > ImplType
RanluxppCompatEngineLuescherRanlxd(uint64_t seed=314159265)
~RanluxppCompatEngineLuescherRanlxd() override
std::unique_ptr< ImplType > fImpl
uint64_t IntRndm()
Generate a random integer value with 48 bits.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
void Skip(uint64_t n)
Skip n random numbers without generating them.
double Rndm() override
Generate a floating point random number with 48 bits of randomness.
double operator()()
Generate a floating point random number (non-virtual method).
Compatibility engine for Lüscher's ranlxs implementation written in C.
double operator()()
Generate a floating point random number (non-virtual method).
std::unique_ptr< ImplType > fImpl
RanluxppCompatEngineLuescherRanlxs(uint64_t seed=314159265)
double Rndm() override
Generate a floating point random number with 24 bits of randomness.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
~RanluxppCompatEngineLuescherRanlxs() override
void Skip(uint64_t n)
Skip n random numbers without generating them.
RanluxppCompatEngineLuescherImpl< 24, p > ImplType
uint64_t IntRndm()
Generate a random integer value with 24 bits.
std::unique_ptr< ImplType > fImpl
RanluxppCompatEngineStdRanlux24(uint64_t seed=19780503)
void Skip(uint64_t n)
Skip n random numbers without generating them.
RanluxppEngineImpl< 24, 223, 23 > ImplType
uint64_t IntRndm()
Generate a random integer value with 24 bits.
double Rndm() override
Generate a floating point random number with 24 bits of randomness.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
double operator()()
Generate a floating point random number (non-virtual method).
~RanluxppCompatEngineStdRanlux24() override
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
double operator()()
Generate a floating point random number (non-virtual method).
RanluxppCompatEngineStdRanlux48(uint64_t seed=19780503)
void Skip(uint64_t n)
Skip n random numbers without generating them.
std::unique_ptr< ImplType > fImpl
~RanluxppCompatEngineStdRanlux48() override
uint64_t IntRndm()
Generate a random integer value with 48 bits.
double Rndm() override
Generate a floating point random number with 48 bits of randomness.
RanluxppEngineImpl< 48, 2 *389, 11 > ImplType
void SetSeedGsl(uint32_t s, bool ranlxd)
Initialize and seed the state of the generator as in gsl_rng_ranlx*.
static constexpr const uint64_t * kA
void SetSeedStd24(uint64_t s)
Initialize and seed the state of the generator as described by the C++ standard.
void SetSeedJames(uint64_t s)
Initialize and seed the state of the generator as in James' implementation.
void Skip(uint64_t n)
Skip n random numbers without generating them.
void SetSeedStd48(uint64_t s)
Initialize and seed the state of the generator as described by the C++ standard.
double NextRandomFloat()
Return a floating point number, converted from the next random bits.
void Advance(const uint64_t *a)
Advance with given multiplier.
void SetSeedSibidanov(uint64_t s)
Initialize and seed the state of the generator as proposed by Sibidanov.
uint64_t NextRandomBits()
Return the next random bits, generate a new block if necessary.
static constexpr int kMaxPos
void Skip24()
Skip 24 RANLUX numbers.
void Advance()
Produce next block of random bits.
Implementation of the RANLUX++ generator.
uint64_t IntRndm()
Generate a random integer value with 48 bits.
double Rndm() override
Generate a double-precision random number with 48 bits of randomness.
void Skip(uint64_t n)
Skip n random numbers without generating them.
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
~RanluxppEngine() override
double operator()()
Generate a double-precision random number (non-virtual method).
RanluxppEngine(uint64_t seed=314159265)
RanluxppEngineImpl< 48, p > ImplType
std::unique_ptr< ImplType > fImpl
static void mulmod(const uint64_t *in1, uint64_t *inout)
Combine multiply9x9 and mod_m with internal temporary storage.
static void powermod(const uint64_t *base, uint64_t *res, uint64_t n)
Compute base to the n modulo m.
static void to_lcg(const uint64_t *ranlux, unsigned c, uint64_t *lcg)
Convert RANLUX numbers to an LCG state.
static void to_ranlux(const uint64_t *lcg, uint64_t *ranlux, unsigned &c_out)
Convert an LCG state to RANLUX numbers.