Vita
random.h
Go to the documentation of this file.
1
13#if !defined(VITA_RANDOM_H)
14#define VITA_RANDOM_H
15
16#include <cstdlib>
17#include <random>
18
19#include "kernel/common.h"
20#include "kernel/range.h"
21#include "utility/xoshiro256ss.h"
22
23namespace vita::random
24{
25
26enum class distribution {uniform, normal};
27
34using engine_t = vigna::xoshiro256ss;
35
36extern engine_t engine;
37
38template<class T> [[nodiscard]] T sup(T);
39
40[[nodiscard]] unsigned ring(unsigned, unsigned, unsigned);
41
42[[nodiscard]] bool boolean(double = 0.5);
43
44void seed(unsigned);
45void randomize();
46
57template<class T>
58T ephemeral(distribution d, T p1, T p2)
59{
60 switch (d)
61 {
62 case distribution::uniform:
63 return between(p1, p2);
64
65 case distribution::normal:
66 return std::normal_distribution<T>(p1, p2)(engine);
67 }
68}
69
83template<class T>
84std::enable_if_t<std::is_floating_point_v<T>, T>
85between(T min, T sup)
86{
87 Expects(min < sup);
88
89 std::uniform_real_distribution<T> d(min, sup);
90 return d(engine);
91}
92
106template<class T>
107std::enable_if_t<std::is_integral_v<T>, T>
108between(T min, T sup)
109{
110 Expects(min < sup);
111
112 std::uniform_int_distribution<T> d(min, sup - 1);
113 return d(engine);
114}
115
116template<class T>
117std::enable_if_t<std::is_enum_v<T>, T>
118between(T min, T sup)
119{
120 Expects(min < sup);
121
122 return static_cast<T>(between<std::underlying_type_t<T>>(min, sup));
123}
124
131template<class T>
133{
134 return between(r.first, r.second);
135}
136
143template<class T>
144T sup(T sup)
145{
146 return between(static_cast<T>(0), sup);
147}
148
153template<class C>
154const typename C::value_type &element(const C &c)
155{
156 Expects(c.size());
157
158 return *std::next(
159 c.begin(),
160 static_cast<typename C::difference_type>(sup(c.size())));
161}
162
167template<class C>
168typename C::value_type &element(C &c)
169{
170 Expects(c.size());
171
172 return *std::next(
173 c.begin(),
174 static_cast<typename C::difference_type>(sup(c.size())));
175}
176
183inline bool boolean(double p)
184{
185 Expects(0.0 <= p);
186 Expects(p <= 1.0);
187
188 std::bernoulli_distribution d(p);
189 return d(engine);
190
191 //return between<double>(0, 1) < p;
192}
193
194} // namespace vita::random
195
196#endif // include guard
std::pair< T, T > range_t
Right-open interval.
Definition: range.h:25
unsigned ring(unsigned base, unsigned width, unsigned n)
Returns a random number in a modular arithmetic system.
Definition: random.cc:65
void seed(unsigned s)
Initalizes the random number generator.
Definition: random.cc:42
engine_t engine
The shared random engine generator.
Definition: random.cc:27
void randomize()
Sets the shared engine to an unpredictable state.
Definition: random.cc:50
std::enable_if_t< std::is_floating_point_v< T >, T > between(T min, T sup)
A specialization for floating point values of the random::between(T, T) template function.
Definition: random.h:85
T in(range_t< T > r)
Uniformly extracts a random value in a range.
Definition: random.h:132
bool boolean(double=0.5)
Definition: random.h:183
vigna::xoshiro256ss engine_t
xoshiro256** (XOR/shift/rotate) is an all-purpose, rock-solid generator (not a cryptographically secu...
Definition: random.h:34
T sup(T)
Definition: random.h:144
const C::value_type & element(const C &c)
Definition: random.h:154
T ephemeral(distribution d, T p1, T p2)
Used for ephemeral random constant generation.
Definition: random.h:58