34namespace triqs::mc_tools::RandomGenerators {
91 typedef unsigned long uint32;
95 static const int N = 624;
96 static const int M = 397;
97 static const uint32 K = 0x9908B0DFU;
106 inline uint32 hiBit(uint32 u) {
107 return u & 0x80000000U;
110 inline uint32 loBit(uint32 u) {
111 return u & 0x00000001U;
114 inline uint32 loBits(uint32 u) {
115 return u & 0x7FFFFFFFU;
118 inline uint32 mixBits(uint32 u, uint32 v) {
119 return hiBit(u) | loBits(v);
122 uint32 reloadMT(
void) {
123 uint32 *p0 = state, *p2 = state + 2, *pM = state + M, s0, s1;
126 if (left < -1) seedMT(initseed);
128 left = N - 1, next = state + 1;
130 for (s0 = state[0], s1 = state[1], j = N - M + 1; --j; s0 = s1, s1 = *p2++) *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
132 for (pM = state, j = M; --j; s0 = s1, s1 = *p2++) *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
134 s1 = state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
136 s1 ^= (s1 << 7) & 0x9D2C5680U;
137 s1 ^= (s1 << 15) & 0xEFC60000U;
138 return (s1 ^ (s1 >> 18));
144 RandMT() { seedMT(1U); }
146 RandMT(uint32 seed) { seedMT(seed); }
148 RandMT(RandMT
const &R) { seedMT(R.seed_save); }
150 void seedMT(uint32 seed) {
201 uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
204 for (*s++ = x, j = N; --j; *s++ = (x *= 69069U) & 0xFFFFFFFFU);
207 inline uint32 randomMT(
void) {
210 if (--left < 0)
return (reloadMT());
214 y ^= (y << 7) & 0x9D2C5680U;
215 y ^= (y << 15) & 0xEFC60000U;
216 return (y ^ (y >> 18));
219 double operator()() {
return DBL_EPSILON + eval() * (1 - 2 * DBL_EPSILON); }
228 [[nodiscard]] RandMT &engine() {
return *
this; }
229 [[nodiscard]] RandMT
const &engine()
const {
return *
this; }
232 friend std::ostream &operator<<(std::ostream &os,
const RandMT &rng) {
233 for (uint32 i = 0; i < std::size(rng.state); ++i) os << rng.state[i] <<
' ';
234 long distance = rng.next - rng.state;
235 os << distance <<
' ' << rng.left <<
' ' << rng.initseed <<
' ' << rng.seed_save;
236 if (!os)
throw std::runtime_error(
"Error writing a triqs::mc_tools::RandomGenerators::RandMT to ostream.");
241 friend std::istream &operator>>(std::istream &is, RandMT &rng) {
242 for (uint32 i = 0; i < std::size(rng.state); ++i) { is >> rng.state[i] >> std::ws; }
244 is >> distance >> std::ws >> rng.left >> std::ws >> rng.initseed >> std::ws >> rng.seed_save;
245 rng.next = rng.state + distance;
246 if (!is)
throw std::runtime_error(
"Error reading a triqs::mc_tools::RandomGenerators::RandMT from istream.");
const_view_type operator()() const
Make a const view of *this.