RandomGenerators.hpp
Go to the documentation of this file.
1 // ========================================================================================
2 // ApproxMVBB
3 // Copyright (C) 2014 by Gabriel Nützi <nuetzig (at) imes (d0t) mavt (d0t) ethz (døt) ch>
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 // ========================================================================================
9 #ifndef ApproxMVBB_RandomGenerator_hpp
10 #define ApproxMVBB_RandomGenerator_hpp
11 
14 #include ApproxMVBB_TypeDefs_INCLUDE_FILE
15 
16 #include <type_traits>
17 #include <cstdint>
18 #include <random>
19 #include <limits>
20 #include <ctime>
21 
22 namespace ApproxMVBB{
23 namespace RandomGenerators{
24 
35  private:
36  uint64_t x; //< The state can be seeded with any value.
37  public:
38 
39  SplitMix64(const SplitMix64 & gen) = default;
40  SplitMix64(SplitMix64 && gen) = default;
41 
42  SplitMix64(uint64_t seed);
43  void seed(uint64_t seed);
44  uint64_t operator()();
45 
46  // for standard random
47  using result_type = uint64_t;
48  static constexpr result_type min(){ return std::numeric_limits<result_type>::min(); }
49  static constexpr result_type max(){ return std::numeric_limits<result_type>::max(); }
50  };
51 
52 
63  private:
64  uint64_t s[2];
65 
66  public:
67  XorShift128Plus(const XorShift128Plus & gen) = default;
68  XorShift128Plus(XorShift128Plus && gen) = default;
69 
70  XorShift128Plus(uint64_t seed);
73 
74  void seed(uint64_t seed);
76  uint64_t operator()();
77 
81  void jump();
82 
83  // for standard random
84  using result_type = uint64_t;
85  static constexpr result_type min(){ return std::numeric_limits<result_type>::min(); }
86  static constexpr result_type max(){ return std::numeric_limits<result_type>::max(); }
87  };
88 
89 
90  /* This is a fast, top-quality generator. If 1024 bits of state are too
91  much, try a xorshift128+ generator.
92 
93  The state must be seeded so that it is not everywhere zero. If you have
94  a 64-bit seed, we suggest to seed a splitmix64 generator and use its
95  output to fill s. */
97 
98  private:
99  uint64_t s[16];
100  int p = 0;
101 
102  public:
103  XorShift1024Star(const XorShift1024Star & gen) = default;
104  XorShift1024Star(XorShift1024Star && gen) = default;
105 
106 
107  XorShift1024Star(uint64_t seed);
110 
111  void seed(uint64_t seed);
113  uint64_t operator()();
114 
118  void jump();
119 
120  // for standard random
121  using result_type = uint64_t;
122  static constexpr result_type min(){ return std::numeric_limits<result_type>::min(); }
123  static constexpr result_type max(){ return std::numeric_limits<result_type>::max(); }
124  };
125 
127  template<typename T>
129  public:
130  ApproxMVBB_STATIC_ASSERT( std::is_unsigned<T>::value )
131 
132  AlmostUniformUIntDistribution(T min,T max): m_min(min), m_max(max) {
133  m_nRange = m_max - m_min + 1;
134  }
135 
136  template<typename G>
137  T operator()(G & g){
138  return ((double)g() / ((double)(G::max()-G::min()) + 1.0)) * m_nRange + m_min;
139  }
140 
141  private:
142  T m_min,m_max,m_nRange;
143  };
144 
146  template<typename T>
148  public:
149  ApproxMVBB_STATIC_ASSERT( std::is_floating_point<T>::value )
150 
151  AlmostUniformRealDistribution(T min,T max): m_min(min), m_max(max) {
152  m_nRange = m_max - m_min + 1;
153  }
154 
155  template<typename G>
156  T operator()(G & g){
157  return ((T)g() / (T)(G::max()-G::min())) * m_nRange + m_min;
158  }
159 
160  private:
161  T m_min,m_max,m_nRange;
162  };
163 
165  static const uint64_t defaultSeed = 314159;
167 
169  #ifdef ApproxMVBB_BUILD_TESTS
170  #warning "ApproxMVBB: Using non-standart uniform distributions for testing!"
171  template<typename T>
173  template<typename T>
175  #else
176  template<typename T>
177  using DefaultUniformUIntDistribution = std::uniform_int_distribution<T>;
178  template<typename T>
179  using DefaultUniformRealDistribution = std::uniform_real_distribution<T>;
180  #endif
181 
182 
183 }
184 }
185 
186 
187 
188 namespace ApproxMVBB{
189 namespace RandomGenerators{
190 
191 
192 inline SplitMix64::SplitMix64(uint64_t sd) :x(sd) {}
193 
194 inline void SplitMix64::seed(uint64_t sd){ x = sd;}
195 
196 inline uint64_t SplitMix64::operator()() {
197  uint64_t z = (x += UINT64_C(0x9E3779B97F4A7C15));
198  z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9);
199  z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB);
200  return z ^ (z >> 31);
201 }
202 
203 
205  seed(sd);
206 }
207 
210  seed(time(NULL));
211 }
212 
213 inline void XorShift128Plus::seed(uint64_t sd){
214  s[0] = SplitMix64{sd}();
215  s[1] = s[0] ;
216 }
217 
219 inline uint64_t XorShift128Plus::operator()(){
220  uint64_t s1 = s[0];
221  const uint64_t s0 = s[1];
222  s[0] = s0;
223  s1 ^= s1 << 23; // a
224  s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
225  return s[1] + s0;
226 }
227 
228 
229 
230 inline void XorShift128Plus::jump() {
231  static const uint64_t JUMP[] = { 0x8a5cd789635d2dff, 0x121fd2155c472f96 };
232 
233  uint64_t s0 = 0;
234  uint64_t s1 = 0;
235  for(unsigned int i = 0; i < sizeof(JUMP) / sizeof (*JUMP); i++)
236  for(int b = 0; b < 64; b++) {
237  if (JUMP[i] & 1ULL << b) {
238  s0 ^= s[0];
239  s1 ^= s[1];
240  }
241  this->operator()();
242  }
243 
244  s[0] = s0;
245  s[1] = s1;
246 }
247 
248 
249 
251  seed(sd);
252 }
253 
256  seed(time(NULL));
257 }
258 
259 inline void XorShift1024Star::seed(uint64_t sd){
260  uint64_t ss = SplitMix64{sd}();
261  for(auto & v : s){
262  v = ss;
263  }
264 }
265 
267 inline uint64_t XorShift1024Star::operator()() {
268  const uint64_t s0 = s[p];
269  uint64_t s1 = s[p = (p + 1) & 15];
270  s1 ^= s1 << 31; // a
271  s[p] = s1 ^ s0 ^ (s1 >> 11) ^ (s0 >> 30); // b,c
272  return s[p] * UINT64_C(1181783497276652981);
273 }
274 
275 
276 
280 inline void XorShift1024Star::jump() {
281  static const uint64_t JUMP[] = { 0x84242f96eca9c41d,
282  0xa3c65b8776f96855, 0x5b34a39f070b5837, 0x4489affce4f31a1e,
283  0x2ffeeb0a48316f40, 0xdc2d9891fe68c022, 0x3659132bb12fea70,
284  0xaac17d8efa43cab8, 0xc4cb815590989b13, 0x5ee975283d71c93b,
285  0x691548c86c1bd540, 0x7910c41d10a1e6a5, 0x0b5fc64563b3e2a8,
286  0x047f7684e9fc949d, 0xb99181f2d8f685ca, 0x284600e3f30e38c3
287  };
288 
289  uint64_t t[16] = { 0 };
290  for(unsigned int i = 0; i < sizeof(JUMP) / sizeof (*JUMP); i++)
291  for(int b = 0; b < 64; b++) {
292  if (JUMP[i] & 1ULL << b)
293  for(int j = 0; j < 16; j++)
294  t[j] ^= s[(j + p) & 15];
295  this->operator()();
296  }
297 
298  for(int j = 0; j < 16; j++)
299  s[(j + p) & 15] = t[j];
300 }
301 
302 }
303 }
304 
305 #endif
SplitMix64(const SplitMix64 &gen)=default
These are some container definitions.
std::uniform_real_distribution< T > DefaultUniformRealDistribution
#define APPROXMVBB_EXPORT
Definition: Platform.hpp:60
static constexpr result_type min()
#define ApproxMVBB_STATIC_ASSERT(B)
static const uint64_t defaultSeed
static constexpr result_type max()
std::uniform_int_distribution< T > DefaultUniformUIntDistribution


asr_approx_mvbb
Author(s): Gassner Nikolai
autogenerated on Mon Jun 10 2019 12:38:08