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>
586 fNextState = (fNextState + 1) % 4;
594 fNextState = (fNextState + 1) % 4;
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++) {
618 auto &state = fStates[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++) {
650 int idx = (fNextState + i) % 4;
651 uint64_t nForThisState = nPerState;
655 fStates[idx].
Skip(nForThisState);
658 fNextState = (fNextState + remainder) % 4;
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.
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.
RanluxppCompatEngineGslRanlxd(uint64_t seed=1)
double operator()()
Generate a floating point random number (non-virtual method)
virtual ~RanluxppCompatEngineGslRanlxd()
Compatibility engine for gsl_rng_ranlxs* from the GNU Scientific Library.
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.
virtual ~RanluxppCompatEngineGslRanlxs()
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.
double operator()()
Generate a floating point random number (non-virtual method)
void Skip(uint64_t n)
Skip n random numbers without generating them.
virtual ~RanluxppCompatEngineJames()
void SetSeed(uint64_t seed)
Initialize and seed the state of the generator.
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.
RanluxppCompatEngineJames(uint64_t seed=314159265)
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.
void Skip(uint64_t n)
Skip n random numbers without generating them.
Compatibility engine for Lüscher's ranlxd implementation written in C.
RanluxppCompatEngineLuescherRanlxd(uint64_t seed=314159265)
virtual ~RanluxppCompatEngineLuescherRanlxd()
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)
RanluxppCompatEngineLuescherRanlxs(uint64_t seed=314159265)
double Rndm() override
Generate a floating point random number with 24 bits of randomness.
virtual ~RanluxppCompatEngineLuescherRanlxs()
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.
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.
uint64_t IntRndm()
Generate a random integer value with 24 bits.
virtual ~RanluxppCompatEngineStdRanlux24()
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)
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
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.
virtual ~RanluxppCompatEngineStdRanlux48()
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
unsigned fCarry
Carry bit of the RANLUX state.
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.
uint64_t fState[9]
RANLUX state of the generator.
int fPosition
Current position in bits.
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.
double operator()()
Generate a double-precision random number (non-virtual method)
RanluxppEngine(uint64_t seed=314159265)
virtual ~RanluxppEngine()
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.
Namespace for new Math classes and functions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
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.