Lumiera  0.pre.03
»edit your freedom«
random.hpp
Go to the documentation of this file.
1 /*
2  RANDOM.hpp - support for random number generation with controlled seed
3 
4  Copyright (C)
5  2024, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
27 #ifndef LIB_RANDOM_H
28 #define LIB_RANDOM_H
29 
30 
31 #include "lib/integral.hpp"
32 #include "lib/hash-value.h"
33 #include "lib/nocopy.hpp"
34 
35 #include <random>
36 
37 
38 namespace lib {
39  namespace {
40  inline uint constexpr
41  _iBOUND()
42  {
43  return 1u+uint(std::numeric_limits<int>::max());
44  }
45  }
46 
49  {
50  public:
51  virtual ~SeedNucleus();
52  virtual uint64_t getSeed() =0;
53  };
54 
63  template<class GEN>
65  {
66  GEN generator_;
67 
68  public:
71 
73  template<class G>
75 
76  // default copy operations (can copy and assign a state)
77 
78 
79  int i(uint bound =_iBOUND());
80  int i32();
81  uint64_t u64();
82  double uni();
83  double range (double start, double bound);
84  double normal(double mean=0.0, double stdev=1.0);
85  HashVal hash();
86 
88  template<class DIST>
89  auto distribute(DIST);
90 
92  void reseed (SeedNucleus&);
93 
95  class Seed;
96  };
97 
98  template<class GEN>
99  class RandomSequencer<GEN>::Seed
100  : public SeedNucleus
101  {
102  RandomSequencer& srcGen_;
103  public:
104  Seed(RandomSequencer& parent)
105  : srcGen_{parent}
106  { }
107 
108  uint64_t
109  getSeed() override
110  {
111  return srcGen_.u64();
112  }
113  };
114 
115 
116 
121 
122 
124  extern Random defaultGen;
125 
127  extern Random entropyGen;
128 
129 
130 
131  /* ===== convenience accessors ===== */
132 
134  inline int
135  rani (uint bound =_iBOUND())
136  {
137  return defaultGen.i(bound);
138  }
139 
141  inline double
142  ranRange (double start, double bound)
143  {
144  return defaultGen.range (start, bound);
145  }
146 
147  inline double
148  ranNormal(double mean =0.0, double stdev =1.0)
149  {
150  return defaultGen.normal (mean, stdev);
151  }
152 
154  inline lib::HashVal
156  {
157  return defaultGen.hash();
158  }
159 
160 
162  void randomiseRandomness();
163 
166 
167 
168 
169 
170  /* ===== Implementation details ===== */
171 
172  template<class GEN>
173  inline
175  : generator_{nucleus.getSeed()}
176  { }
177 
178  template<class GEN>
179  template<class G>
180  inline
182  : generator_{RandomSequencer<GEN>::Seed{parent}.getSeed()}
183  { }
184 
185 
186  template<class GEN>
187  inline void
189  {
190  generator_.seed (nucleus.getSeed());
191  }
192 
193 
194  template<class GEN>
195  template<class DIST>
196  inline auto
198  {
199  return distribution (generator_);
200  }
201 
203  template<class GEN>
204  inline int
206  {
207  if (!bound) bound=1;
208  --bound;
209  uint upper{std::numeric_limits<int>::max()};
210  upper = bound < upper? bound : upper;
211  return distribute (std::uniform_int_distribution<int> (0, upper));
212  }
213 
214  template<class GEN>
215  inline int
217  {
218  return distribute (std::uniform_int_distribution<int> {std::numeric_limits<int>::min()
219  ,std::numeric_limits<int>::max()});
220  }
221 
222  template<class GEN>
223  inline uint64_t
225  {
226  return distribute (std::uniform_int_distribution<uint64_t> {std::numeric_limits<uint64_t>::min()
227  ,std::numeric_limits<uint64_t>::max()});
228  }
229 
230  template<class GEN>
231  inline double
233  {
234  return range (0.0, 1.0);
235  }
236 
237  template<class GEN>
238  inline double
239  RandomSequencer<GEN>::range (double start, double bound)
240  {
241  return distribute (std::uniform_real_distribution<double>{start,bound});
242  }
243 
244  template<class GEN>
245  inline double
246  RandomSequencer<GEN>::normal (double mean, double stdev)
247  {
248  return distribute (std::normal_distribution<double>{mean,stdev});
249  }
250 
251  template<class GEN>
252  inline HashVal
254  {
255  return distribute (std::uniform_int_distribution<lib::HashVal>{lib::HashVal(1)});
256  }
257 
258 
259 
276  template<class GEN>
277  class CappedGen
278  : public GEN
279  {
280  public:
281  using GEN::GEN;
282 
283  typename GEN::result_type
284  operator()()
285  {
286  if constexpr (GEN::max() < std::numeric_limits<typename GEN::result_type>::max())
287  return GEN::operator()() % (GEN::max()+1);
288  else
289  return GEN::operator()();
290  }
291  };
292 
293  template<class GEN>
294  auto
295  buildCappedSubSequence (RandomSequencer<GEN>& src)
296  {
297  typename RandomSequencer<GEN>::Seed seedChain(src);
298  RandomSequencer<CappedGen<GEN>> subSeq{seedChain};
299  return subSeq;
300  }
301 
302 
303 
304 } // namespace lib
305 #endif /*LIB_RANDOM_H*/
virtual ~SeedNucleus()
this is an interface
Definition: random.cpp:80
Access point to a selection of random number sources.
Definition: random.hpp:64
int i(uint bound=_iBOUND())
drop-in replacement for rand() % bound
Definition: random.hpp:205
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
RandomSequencer(SeedNucleus &)
Build new generator, drawing seed from a virtual seed source.
Definition: random.hpp:174
double ranRange(double start, double bound)
Definition: random.hpp:142
lib::HashVal ranHash()
Definition: random.hpp:155
Random entropyGen
a global RandomSequencer seeded with real entropy
Definition: random.cpp:71
Implementation namespace for support and library code.
double range(double start, double bound)
random double from designated interval (upper bound excluded)
Definition: random.hpp:239
SeedNucleus & seedFromDefaultGen()
draw seed another Generator from the default RandomSequencer
Definition: random.cpp:74
Mix-Ins to allow or prohibit various degrees of copying and cloning.
uint64_t u64()
random 64bit number from full range.
Definition: random.hpp:224
Establishes a seed point for any instance or performance.
Definition: random.hpp:48
HashVal hash()
non-zero hash value from full 64bit range
Definition: random.hpp:253
Hash value types and utilities.
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:52
Adapter to protect against data corruption caused by concurrent access.
Definition: random.hpp:277
double normal(double mean=0.0, double stdev=1.0)
normal distribution (gaussian)
Definition: random.hpp:246
Random defaultGen
a global default RandomSequencer for mundane purposes
Definition: random.cpp:70
void randomiseRandomness()
inject true randomness into the defaultGen
Definition: random.cpp:83