17 InitialSeed, LastSeed, NewSeed
38 static int64_t find_b(int64_t a, int64_t k, int64_t m) {
41 for (
int i = 1; i < 32; i++) {
42 sqrs[i] =(sqrs[i - 1] * sqrs[i - 1]) % m;
45 int64_t power_of_2 = 1;
47 for (
int i = 0; i < 32; i++) {
48 if (!(power_of_2 & k)) {
52 power_of_2 = power_of_2 * 2;
58 static constexpr int32_t H = 32768;
59 static int32_t mult_mod_M(int32_t s, int32_t t, int32_t M) {
60 int32_t R, S0, S1, q, qh, rh, k;
62 if (s < 0) { s += M; }
63 if (t < 0) { t += M; }
77 R = H *(t - k * qh) - k * rh;
78 while(R < 0) { R += M; }
87 if (R > 0) { R -= M; }
89 while(R < 0) { R += M; }
92 R = H *(R - k * qh) - k * rh;
93 while(R < 0) { R += M; }
100 if (R > 0) { R -= M; }
101 R += S0 *(t - k * q);
102 while(R < 0) { R += M; }
108 void init_generator(SeedType Where) {
109 for (
int j = 0; j < 4; j++) {
115 Lg[j] = mult_mod_M(rng.aw[j], Lg[j], rng.m[j]);
125 using result_type = double;
127 static void init(
int v,
int w) {
128 int32_t default_seed[4] = {11111111, 22222222, 33333333, 44444444};
129 init(v, w, default_seed);
132 static void init(
int v,
int w, int32_t init_seed[4]) {
134 rng.m[0] = 2147483647;
135 rng.m[1] = 2147483543;
136 rng.m[2] = 2147483423;
137 rng.m[3] = 2147483323;
145 for (
int j = 0; j < 4; j++) {
147 rng.aw[j] = rng.a[j];
148 for (
int i = 0; i < w; i++) {
149 rng.aw[j] = mult_mod_M(rng.aw[j], rng.aw[j], rng.m[j]);
153 rng.avw[j] = rng.aw[j];
154 for (
int i = 0; i < v; i++) {
155 rng.avw[j] = mult_mod_M(rng.avw[j], rng.avw[j], rng.m[j]);
159 rng.b[j] = find_b(rng.a[j], rng.m[j] - 2, rng.m[j]);
162 rng.seed[j] = init_seed[j];
167 clcg4(int32_t s[4]) { seed(s); }
168 clcg4(uint64_t
id) { seed(
id); }
174 void seed(int32_t s[4]) {
175 for (
int j = 0; j < 4; j++)
178 init_generator(InitialSeed);
181 void seed(uint64_t
id) {
182 uint64_t mask_bit = 1;
187 int positions = ((
sizeof(uint64_t)) * 8) - 1;
190 for (
int j = 0; j < 4; j++) {
191 Ig_t[j] = rng.seed[j];
194 mask_bit <<= positions;
198 for (
int j = 0; j < 4; j++) {
199 avw_t[j] = rng.avw[j];
202 for (
int i = 0; i < positions; i++) {
203 avw_t[j] = mult_mod_M(avw_t[j], avw_t[j], rng.m[j]);
206 Ig_t[j] = mult_mod_M(avw_t[j], Ig_t[j], rng.m[j]);
212 }
while(positions > 0);
215 for (
int j = 0; j < 4; j++) {
216 Ig_t[j] = mult_mod_M(rng.avw[j], Ig_t[j], rng.m[j]);
220 for (
int j = 0; j < 4; j++) {
224 init_generator(InitialSeed);
227 static constexpr result_type min() noexcept {
return 0.0; }
228 static constexpr result_type max() noexcept {
return 1.0; }
230 constexpr result_type operator() () noexcept {
232 int32_t k = s / 46693;
235 s = 45991 *(s - k * 46693) - k * 25884;
239 u = u + 4.65661287524579692e-10 * s;
243 s = 207707 *(s - k * 10339) - k * 870;
247 u = u - 4.65661310075985993e-10 * s;
253 s = 138556 *(s - k * 15499) - k * 3979;
257 u = u + 4.65661336096842131e-10 * s;
263 s = 49689 *(s - k * 43218) - k * 24121;
267 u = u - 4.65661357780891134e-10 * s;
275 void prev() noexcept {
279 s = (rng.b[0] * s) % rng.m[0];
281 u = u + 4.65661287524579692e-10 * s;
284 s = (rng.b[1] * s) % rng.m[1];
286 u = u - 4.65661310075985993e-10 * s;
287 if (u < 0) { u = u + 1.0; }
290 s = (rng.b[2] * s) % rng.m[2];
292 u = u + 4.65661336096842131e-10 * s;
293 if (u >= 1.0) { u = u - 1.0; }
296 s = (rng.b[3] * s) % rng.m[3];
298 u = u - 4.65661357780891134e-10 * s;
299 if (u < 0) { u = u + 1.0; }
304 constexpr uint64_t count() noexcept {
return _count; }
306 void pup(PUP::er& p) {
312 constexpr
void discard(uint64_t n) noexcept {
313 for (uint64_t i = 0; i < n; ++i) {
318 constexpr
bool operator == (
const clcg4& rhs) noexcept {
319 return Ig[0] == rhs.Ig[0] && Ig[1] == rhs.Ig[1] && Ig[2] == rhs.Ig[2] && Ig[3] == rhs.Ig[3] &&
320 Lg[0] == rhs.Lg[0] && Lg[1] == rhs.Lg[1] && Lg[2] == rhs.Lg[2] && Lg[3] == rhs.Lg[3] &&
321 Cg[0] == rhs.Cg[0] && Cg[1] == rhs.Cg[1] && Cg[2] == rhs.Cg[2] && Cg[3] == rhs.Cg[3];
324 constexpr
bool operator != (
const clcg4& rhs) noexcept {
325 return !(*
this == rhs);
328 friend std::ostream& operator << (std::ostream& os,
const clcg4& rhs) {
329 os << rhs.Ig[0] <<
' ' << rhs.Ig[1] <<
' ' << rhs.Ig[2] <<
' ' << rhs.Ig[3] <<
' ';
330 os << rhs.Lg[0] <<
' ' << rhs.Lg[1] <<
' ' << rhs.Lg[2] <<
' ' << rhs.Lg[3] <<
' ';
331 os << rhs.Cg[0] <<
' ' << rhs.Cg[1] <<
' ' << rhs.Cg[2] <<
' ' << rhs.Cg[3];
335 friend auto operator >> (std::istream& is,
clcg4& rhs) -> std::istream& {
Implementation of a CLCG4 random number generator, based on the reversible implementation from ROSS (...
Definition: clcg4.h:14