Theoretica
A C++ numerical and automatic mathematical library
pseudorandom.h
Go to the documentation of this file.
1 
5 
6 #ifndef THEORETICA_PSEUDORANDOM_H
7 #define THEORETICA_PSEUDORANDOM_H
8 
9 #include <vector>
10 #include <cstdint>
11 
12 #include "../core/bit_op.h"
13 #include "../core/error.h"
14 
15 
16 namespace theoretica {
17 
18 
23  using pseudorandom_function = uint64_t (*)(uint64_t, std::vector<uint64_t>&);
24 
25 
39  inline uint64_t rand_congruential(
40  uint64_t x,
41  uint64_t a = 48271,
42  uint64_t c = 0,
43  uint64_t m = ((uint64_t) 1 << 31) - 1) {
44 
45  return (a * x + c) % m;
46  }
47 
48 
57  inline uint64_t rand_congruential(uint64_t x, std::vector<uint64_t>& state) {
58 
59  if(state.size() != 3) {
60  TH_MATH_ERROR("rand_congruential", state.size(), INVALID_ARGUMENT);
61  return 0;
62  }
63 
64  const uint64_t a = state[0];
65  const uint64_t c = state[1];
66  const uint64_t m = state[2];
67 
68  if(a > m || c > m) {
69  TH_MATH_ERROR("rand_congruential", max(a, c), INVALID_ARGUMENT);
70  return 0;
71  }
72 
73  return rand_congruential(x, a, c, m);
74  }
75 
76 
86  inline uint64_t rand_xoshiro(uint64_t& a, uint64_t& b, uint64_t& c, uint64_t& d) {
87 
88  // Add and rotate
89  const uint64_t result = bit_rotate(a + d, 23) + a;
90  const uint64_t temp = b << 17;
91 
92  // Shift operations
93  c ^= a;
94  d ^= b;
95  b ^= c;
96  a ^= d;
97 
98  c ^= temp;
99  d = bit_rotate(d, 45);
100 
101  return result;
102  }
103 
104 
112  inline uint64_t rand_xoshiro(uint64_t x, std::vector<uint64_t>& state) {
113 
114  if(state.size() != 4) {
115  TH_MATH_ERROR("rand_xoshiro", state.size(), INVALID_ARGUMENT);
116  return 0;
117  }
118 
119  return rand_xoshiro(state[0], state[1], state[2], state[3]);
120  }
121 
122 
130  inline uint64_t rand_splitmix64(uint64_t x) {
131 
132  x += 0x9e3779b97f4a7c15;
133 
134  uint64_t res = x;
135  res = (res ^ (res >> 30)) * 0xbf58476d1ce4e5b9;
136  res = (res ^ (res >> 27)) * 0x94d049bb133111eb;
137 
138  return res ^ (res >> 31);
139  }
140 
141 
148  inline uint64_t rand_splitmix64(uint64_t x, std::vector<uint64_t>& p) {
149  return rand_splitmix64(x);
150  }
151 
152 
160  inline uint64_t rand_wyrand(uint64_t& seed, uint64_t p1, uint64_t p2) {
161  seed += p1;
162  return mix_mum(seed ^ p2, seed);
163  }
164 
165 
175  inline uint64_t rand_wyrand(uint64_t x, std::vector<uint64_t>& p) {
176 
177  if(p.size() != 3) {
178  TH_MATH_ERROR("rand_wyrand", p.size(), INVALID_ARGUMENT);
179  return 0;
180  }
181 
182  return rand_wyrand(p[0], p[1], p[2]);
183  }
184 
185 
194  inline uint64_t rand_middlesquare(uint64_t seed, uint64_t offset = 765872292751861) {
195 
196  seed += offset;
197  uint64_t high, low;
198  mul_uint128(seed, seed, low, high);
199 
200  return (high << 32) | (low >> 32);
201  }
202 
203 
210  inline uint64_t rand_middlesquare(uint64_t x, std::vector<uint64_t>& p) {
211 
212  if(p.size() != 1) {
213  TH_MATH_ERROR("rand_middlesquare", p.size(), INVALID_ARGUMENT);
214  return 0;
215  }
216 
217  return rand_middlesquare(x, p[0]);
218  }
219 
220 }
221 
222 
223 #endif
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition: error.h:219
Main namespace of the library which contains all functions and objects.
Definition: algebra.h:27
uint64_t rand_splitmix64(uint64_t x)
Generate a pseudorandom number using the SplitMix64 pseudorandom number generation algorithm.
Definition: pseudorandom.h:130
TH_CONSTEXPR UnsignedIntType bit_rotate(UnsignedIntType x, unsigned int i)
Bit rotation of unsigned integer types using shifts.
Definition: bit_op.h:78
uint64_t rand_wyrand(uint64_t &seed, uint64_t p1, uint64_t p2)
Generate a pseudorandom number using the Wyrand pseudorandom number generation, as invented by Yi Wan...
Definition: pseudorandom.h:160
uint64_t mix_mum(uint64_t a, uint64_t b)
MUM bit mixing function, computes the 128-bit product of a and b and the XOR of their high and low 64...
Definition: bit_op.h:62
auto max(const Vector &X)
Finds the maximum value inside a dataset.
Definition: dataset.h:330
uint64_t(*)(uint64_t, std::vector< uint64_t > &) pseudorandom_function
A function pointer which wraps a pseudorandom generator, taking as input the previous generated value...
Definition: pseudorandom.h:23
uint64_t rand_congruential(uint64_t x, uint64_t a=48271, uint64_t c=0, uint64_t m=((uint64_t) 1<< 31) - 1)
Generate a pseudorandom number using the congruential pseudorandom number generation algorithm.
Definition: pseudorandom.h:39
uint64_t rand_middlesquare(uint64_t seed, uint64_t offset=765872292751861)
Generate a pseudorandom number using the middle-square pseudorandom number generation algorithm.
Definition: pseudorandom.h:194
void mul_uint128(uint64_t a, uint64_t b, uint64_t &c_low, uint64_t &c_high)
Multiply two 64-bit unsigned integers and store the result in two 64-bit variables,...
Definition: bit_op.h:24
uint64_t rand_xoshiro(uint64_t &a, uint64_t &b, uint64_t &c, uint64_t &d)
Generate a pseudorandom number using the xoshiro256++ pseudorandom number generation algorithm.
Definition: pseudorandom.h:86