Tatooine
random.h
Go to the documentation of this file.
1#ifndef TATOOINE_RANDOM_H
2#define TATOOINE_RANDOM_H
3//==============================================================================
4#include <tatooine/concepts.h>
5#include <tatooine/real.h>
7
8#include <boost/range/algorithm/generate.hpp>
9#include <random>
10#include <string>
11//==============================================================================
13//==============================================================================
14template <typename ValueType, typename Engine = std::mt19937_64>
15struct uniform {
16 static_assert(is_arithmetic<ValueType>);
17 //============================================================================
18 using engine_type = Engine;
19 using real_type = ValueType;
21 std::conditional_t<is_floating_point<ValueType>,
22 std::uniform_real_distribution<ValueType>,
23 std::uniform_int_distribution<ValueType>>;
24 //============================================================================
25 private:
28 //============================================================================
29 public:
31 : m_engine{std::random_device{}()},
32 m_distribution{ValueType(0), ValueType(1)} {}
33 uniform(const uniform&) = default;
34 uniform(uniform&&) noexcept = default;
35 //----------------------------------------------------------------------------
36 auto operator=(const uniform&) noexcept -> uniform& = default;
37 auto operator=(uniform&&) noexcept -> uniform& = default;
38 //----------------------------------------------------------------------------
39 ~uniform() = default;
40 //----------------------------------------------------------------------------
41 uniform(ValueType const min, ValueType const max)
42 : m_engine{std::random_device{}()}, m_distribution{min, max} {}
43 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
44 template <convertible_to<Engine> EngineArg>
45 uniform(ValueType const min, ValueType const max, EngineArg&& eng)
46 : m_engine{std::forward<EngineArg>(eng)}, m_distribution{min, max} {}
47 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48 template <convertible_to<Engine> EngineArg>
49 uniform(EngineArg&& eng)
50 : m_engine{std::forward<EngineArg>(eng)},
51 m_distribution{ValueType(0), ValueType(1)} {}
52 //============================================================================
54 //----------------------------------------------------------------------------
55 auto engine() const -> auto const& { return m_engine; }
56 auto engine() -> auto& { return m_engine; }
57 //----------------------------------------------------------------------------
58 auto distribution() const -> auto const& { return m_distribution; }
59 auto distribution() -> auto& { return m_distribution; }
60};
61//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62uniform()->uniform<real_number, std::mt19937_64>;
63
64template <typename ValueType>
65uniform(ValueType const min, ValueType const max)
67
68template <typename ValueType, typename Engine>
69uniform(ValueType const min, ValueType const max, Engine&&)
71//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72template <typename ValueType, typename Engine = std::mt19937_64>
73auto uniform_vector(std::size_t n, ValueType a = ValueType(0),
74 ValueType b = ValueType(1),
75 Engine&& engine = Engine{std::random_device{}()}) {
76 uniform rand(a, b, std::forward<Engine>(engine));
77
78 std::vector<ValueType> rand_data(n);
79 boost::generate(rand_data, [&] { return rand(); });
80 return rand_data;
81}
82//==============================================================================
83inline auto alpha_numeric_string(std::size_t const size) {
84 static constexpr auto char_set = std::string_view{
85 "0123456789"
86 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
87 "abcdefghijklmnopqrstuvwxyz"};
88 auto index = uniform<std::size_t>{0, char_set.size() - 1};
89 auto str = std::string(size, ' ');
90 for (auto& c : str) {
91 c = char_set[index()];
92 }
93 return str;
94}
95//==============================================================================
96template <typename ValueType, typename Engine = std::mt19937_64>
97struct normal {
98 using engine_type = Engine;
99 using real_type = ValueType;
100 using distribution_type = std::normal_distribution<ValueType>;
101
102 //============================================================================
103 normal() : engine{std::random_device{}()}, distribution{0, 1} {}
104 normal(const normal&) = default;
105 normal(normal&&) noexcept = default;
106 //============================================================================
107 auto operator=(const normal&) -> normal& = default;
108 auto operator=(normal&&) noexcept -> normal& = default;
109 //----------------------------------------------------------------------------
110 ~normal() = default;
111
112 //----------------------------------------------------------------------------
113 explicit normal(const Engine& _engine)
114 : engine{_engine}, distribution{0, 1} {}
115 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116 explicit normal(Engine&& _engine)
117 : engine{std::move(_engine)}, distribution{0, 1} {}
118 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
119 normal(ValueType mean, ValueType stddev)
120 : engine{std::random_device{}()}, distribution{mean, stddev} {}
121 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
122 normal(const Engine& _engine, ValueType mean, ValueType stddev)
123 : engine{_engine}, distribution{mean, stddev} {}
124 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
125 normal(Engine&& _engine, ValueType mean, ValueType stddev)
126 : engine{std::move(_engine)}, distribution{mean, stddev} {}
127 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
128 normal(ValueType mean, ValueType stddev, const Engine& _engine)
129 : engine{_engine}, distribution{mean, stddev} {}
130 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
131 normal(ValueType mean, ValueType stddev, Engine&& _engine)
132 : engine{std::move(_engine)}, distribution{mean, stddev} {}
133
134 //============================================================================
135 private:
136 Engine engine;
138
139 //============================================================================
140 public:
141 auto get() { return distribution(engine); }
142 auto operator()() { return get(); }
143};
144//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145normal()->normal<double, std::mt19937_64>;
146// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
147template <typename Engine>
149// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
150template <typename ValueType>
151normal(ValueType mean, ValueType stddev) -> normal<ValueType, std::mt19937_64>;
152//==============================================================================
153template <typename Iterator, typename RandomEngine>
154auto random_elem(Iterator begin, Iterator end, RandomEngine& eng) {
155 if (begin == end) {
156 return end;
157 }
158 const auto size = static_cast<std::size_t>(distance(begin, end));
159 std::uniform_int_distribution<std::size_t> rand{0, size - 1};
160 return next(begin, rand(eng));
161}
162//------------------------------------------------------------------------------
163template <typename Range, typename RandomEngine>
164auto random_elem(Range&& range, RandomEngine& eng) {
165 return random_elem(begin(range), end(range), eng);
166}
167//==============================================================================
168enum coin { HEADS, TAILS };
169template <typename RandomEngine>
170auto flip_coin(RandomEngine&& eng) {
171 std::uniform_int_distribution<std::size_t> coin{0, 1};
172 return coin(eng) == 0 ? HEADS : TAILS;
173}
174//==============================================================================
175} // namespace tatooine::random
176//==============================================================================
177namespace tatooine {
178//==============================================================================
179template <typename ValueType>
180struct is_random_number_generator_impl : std::false_type {};
181template <typename ValueType, typename Engine>
182struct is_random_number_generator_impl<random::uniform<ValueType, Engine>>
183 : std::true_type {};
184template <typename ValueType, typename Engine>
185struct is_random_number_generator_impl<random::normal<ValueType, Engine>>
186 : std::true_type {};
187template <typename ValueType>
188static auto constexpr is_random_number_generator =
190template <typename ValueType>
192 is_random_number_generator<std::decay_t<ValueType>>;
193//==============================================================================
194} // namespace tatooine
195//==============================================================================
196#endif
Definition: random.h:191
Definition: concepts.h:84
Definition: random.h:12
auto uniform_vector(std::size_t n, ValueType a=ValueType(0), ValueType b=ValueType(1), Engine &&engine=Engine{std::random_device{}()})
Definition: random.h:73
auto alpha_numeric_string(std::size_t const size)
Definition: random.h:83
auto flip_coin(RandomEngine &&eng)
Definition: random.h:170
auto random_elem(Iterator begin, Iterator end, RandomEngine &eng)
Definition: random.h:154
coin
Definition: random.h:168
@ TAILS
Definition: random.h:168
@ HEADS
Definition: random.h:168
Definition: algorithm.h:6
constexpr auto distance(Iter const &it0, Iter const &it1)
Definition: iterator_facade.h:372
void normal(base_tensor< Tensor, GiNaC::ex, Dims... > &m)
Definition: tensor_symbolic.h:75
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
auto constexpr index(handle< Child, Int > const h)
Definition: handle.h:119
static auto constexpr is_random_number_generator
Definition: random.h:188
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto next(Iter iter)
Definition: iterator_facade.h:325
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
static constexpr forward_tag forward
Definition: tags.h:9
Definition: random.h:97
normal(Engine &&_engine)
Definition: random.h:116
std::normal_distribution< ValueType > distribution_type
Definition: random.h:100
auto get()
Definition: random.h:141
normal(Engine &&_engine, ValueType mean, ValueType stddev)
Definition: random.h:125
normal()
Definition: random.h:103
distribution_type distribution
Definition: random.h:137
Engine engine_type
Definition: random.h:98
normal(ValueType mean, ValueType stddev)
Definition: random.h:119
Engine engine
Definition: random.h:136
normal(const normal &)=default
auto operator()()
Definition: random.h:142
normal(normal &&) noexcept=default
ValueType real_type
Definition: random.h:99
normal(const Engine &_engine, ValueType mean, ValueType stddev)
Definition: random.h:122
normal(ValueType mean, ValueType stddev, Engine &&_engine)
Definition: random.h:131
normal(ValueType mean, ValueType stddev, const Engine &_engine)
Definition: random.h:128
Definition: random.h:15
distribution_type m_distribution
Definition: random.h:27
auto distribution() -> auto &
Definition: random.h:59
std::conditional_t< is_floating_point< ValueType >, std::uniform_real_distribution< ValueType >, std::uniform_int_distribution< ValueType > > distribution_type
Definition: random.h:23
auto engine() -> auto &
Definition: random.h:56
auto operator()()
Definition: random.h:53
uniform(EngineArg &&eng)
Definition: random.h:49
Engine engine_type
Definition: random.h:18
uniform()
Definition: random.h:30
uniform(ValueType const min, ValueType const max, EngineArg &&eng)
Definition: random.h:45
auto distribution() const -> auto const &
Definition: random.h:58
auto engine() const -> auto const &
Definition: random.h:55
uniform(uniform &&) noexcept=default
engine_type m_engine
Definition: random.h:26
uniform(const uniform &)=default
ValueType real_type
Definition: random.h:19