Theoretica
A C++ numerical and automatic mathematical library
prng.h
Go to the documentation of this file.
1 
5 
6 #ifndef THEORETICA_PRNG_H
7 #define THEORETICA_PRNG_H
8 
9 #include <vector>
10 #include "./pseudorandom.h"
11 #include "../core/error.h"
12 
13 
14 namespace theoretica {
15 
18  class PRNG {
19  private:
20 
24 
26  uint64_t x;
27 
29  std::vector<uint64_t> param;
30 
31  public:
32 
36  uint64_t seed,
37  const std::vector<uint64_t>& s) : f(p), x(seed), param(s) {}
38 
39 
45  const std::vector<uint64_t>& s) : f(p), x(1), param(s) {}
46 
47 
50  PRNG(pseudorandom_function p, uint64_t seed) : f(p), x(seed) {}
51 
52 
55  PRNG(uint64_t seed) {
56  *this = PRNG::xoshiro(seed);
57  }
58 
59 
61  inline void seed(uint64_t seed) {
62  x = seed;
63  }
64 
65 
67  inline uint64_t next() {
68  return x = f(x, param);
69  }
70 
71 
74  inline uint64_t operator()() {
75  return next();
76  }
77 
78 
81  inline void discard(uint64_t n) {
82  for (uint64_t i = 0; i < n; ++i)
83  next();
84  }
85 
86 
88  inline uint64_t last() const {
89  return x;
90  }
91 
92 
95  f = p;
96  }
97 
100  return f;
101  }
102 
103 
105  inline void set_param(const std::vector<uint64_t>& v) {
106  param = v;
107  }
108 
110  inline void set_param(unsigned int i, uint64_t value) {
111  param[i] = value;
112  }
113 
115  inline std::vector<uint64_t> get_param() const {
116  return param;
117  }
118 
119 
121  inline PRNG& operator>>(uint64_t& n) {
122  n = next();
123  return *this;
124  }
125 
126 
130  inline static PRNG linear_congruential(uint64_t seed = 1) {
131 
132  if(seed == 0)
133  seed = 1;
134 
135  return PRNG(
137  {48271, 0, ((uint64_t) 1 << 31) - 1}
138  );
139  }
140 
141 
145  inline static PRNG xoshiro(const std::vector<uint64_t>& p) {
146  return PRNG(randgen_xoshiro, 0, p);
147  }
148 
149 
156  inline static PRNG xoshiro(uint64_t seed = 1) {
157 
158  if(seed == 0)
159  seed = 1;
160 
161  const uint64_t n1 = randgen_splitmix64(seed);
162  const uint64_t n2 = randgen_splitmix64(n1);
163  const uint64_t n3 = randgen_splitmix64(n2);
164  const uint64_t n4 = randgen_splitmix64(n3);
165 
166  return PRNG(randgen_xoshiro, 0, {n1, n2, n3, n4});
167  }
168 
169 
173  inline static PRNG splitmix64(uint64_t seed = 1) {
174 
175  if(seed == 0)
176  seed = 1;
177 
178  return PRNG(randgen_splitmix64, seed);
179  }
180 
181 
183  inline static PRNG wyrand(uint64_t seed = 1,
184  uint64_t p1 = 2549536629329, uint64_t p2 = 136137137) {
185 
186  if(seed == 0)
187  seed = 1;
188 
189  if(p2 == 0)
190  p2 = randgen_splitmix64(seed);
191 
192  return PRNG(randgen_wyrand, 0, {seed, p1, p2});
193  }
194 
195 
197  inline static PRNG middlesquare(
198  uint64_t seed, uint64_t offset = 765872292751861) {
199 
200  if(seed == 0)
201  seed = randgen_splitmix64(765872292751861);
202 
203  if(offset == 0)
204  offset = 765872292751861;
205 
206  return PRNG(randgen_middlesquare, seed, {offset});
207  }
208 
209  };
210 
211 
217  template<typename Vector>
218  inline void shuffle(Vector& v, PRNG& g, unsigned int rounds = 0) {
219 
220  if(v.size() == 0)
221  TH_MATH_ERROR("shuffle", v.size(), INVALID_ARGUMENT);
222 
223  // The number of rounds defaults to (N - 1)^2
224  if(rounds == 0)
225  rounds = square(v.size() - 1);
226 
227  for (unsigned int i = 0; i < rounds; ++i) {
228 
229  // Generate two random indices
230  size_t index1 = g() % v.size();
231  size_t index2 = g() % v.size();
232 
233  // Exchange the two values at the random indices
234  const auto x1 = v[index1];
235  v[index1] = v[index2];
236  v[index2] = x1;
237  }
238  }
239 
240 }
241 
242 #endif
A pseudorandom number generator.
Definition: prng.h:18
static PRNG middlesquare(uint64_t seed, uint64_t offset=765872292751861)
Returns a Middle-square generator.
Definition: prng.h:197
uint64_t last() const
Return the last generated number.
Definition: prng.h:88
static PRNG linear_congruential(uint64_t seed=1)
Returns a standard linear congruential generator.
Definition: prng.h:130
PRNG & operator>>(uint64_t &n)
Stream the next generated number.
Definition: prng.h:121
void set_param(const std::vector< uint64_t > &v)
Set the generator's parameters.
Definition: prng.h:105
void seed(uint64_t seed)
Seed the PRNG.
Definition: prng.h:61
uint64_t operator()()
Generate a pseudorandom number.
Definition: prng.h:74
PRNG(pseudorandom_function p, uint64_t seed)
Construct a PRNG with the given generating algorithm and seed.
Definition: prng.h:50
static PRNG wyrand(uint64_t seed=1, uint64_t p1=2549536629329, uint64_t p2=136137137)
Returns a Wyrand generator.
Definition: prng.h:183
std::vector< uint64_t > get_param() const
Get the generator's parameters.
Definition: prng.h:115
void discard(uint64_t n)
Discard n numbers from the generator.
Definition: prng.h:81
pseudorandom_function get_function() const
Get the generating function.
Definition: prng.h:99
static PRNG xoshiro(uint64_t seed=1)
Returns a Xoshiro256++ generator.
Definition: prng.h:156
static PRNG xoshiro(const std::vector< uint64_t > &p)
Returns a Xoshiro256++ generator.
Definition: prng.h:145
static PRNG splitmix64(uint64_t seed=1)
Returns a Splitmix64 generator.
Definition: prng.h:173
void set_function(pseudorandom_function p)
Set the generating function.
Definition: prng.h:94
void set_param(unsigned int i, uint64_t value)
Set a specific parameter by index.
Definition: prng.h:110
PRNG(uint64_t seed)
Construct a PRNG with the default generator and the given seed.
Definition: prng.h:55
uint64_t next()
Generate a pseudorandom number.
Definition: prng.h:67
PRNG(pseudorandom_function p, const std::vector< uint64_t > &s)
Construct a PRNG with the given generating algorithm p and parameters s.
Definition: prng.h:44
PRNG(pseudorandom_function p, uint64_t seed, const std::vector< uint64_t > &s)
Construct a PRNG with the given generating algorithm p, seed x and parameters s.
Definition: prng.h:35
#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 randgen_xoshiro(uint64_t &a, uint64_t &b, uint64_t &c, uint64_t &d)
Generate a pseudorandom natural number using the xoshiro256++ pseudorandom number generation algorith...
Definition: pseudorandom.h:86
void shuffle(Vector &v, PRNG &g, unsigned int rounds=0)
Shuffle a set by exchanging random couples of elements.
Definition: prng.h:218
uint64_t randgen_splitmix64(uint64_t x)
Generate a pseudorandom natural number using the SplitMix64 pseudorandom number generation algorithm.
Definition: pseudorandom.h:130
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 randgen_middlesquare(uint64_t seed, uint64_t offset=765872292751861)
Generate a pseudorandom natural number using the middle-square pseudorandom number generation algorit...
Definition: pseudorandom.h:194
uint64_t randgen_congruential(uint64_t x, uint64_t a=48271, uint64_t c=0, uint64_t m=((uint64_t) 1<< 31) - 1)
Generate a pseudorandom natural number using the congruential pseudorandom number generation algorith...
Definition: pseudorandom.h:39
uint64_t randgen_wyrand(uint64_t &seed, uint64_t p1, uint64_t p2)
Generate a pseudorandom natural number using the Wyrand pseudorandom number generation,...
Definition: pseudorandom.h:160
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition: dual2_functions.h:23
Pseudorandom number generation algorithms.