ARTS 2.5.11 (git: 725533f0)
rng.h
Go to the documentation of this file.
1#pragma once
2
3#include "artstime.h"
4#include "debug.h"
5#include "matpack_concepts.h"
6
7#include <algorithm>
8#include <limits>
9#include <mutex>
10#include <ostream>
11#include <random>
12#include <vector>
13
21template <std::uniform_random_bit_generator Generator = std::mt19937_64>
23 using int_t = typename Generator::result_type;
24
25 static constexpr int_t min_v = std::numeric_limits<int_t>::lowest();
26 static constexpr int_t max_v = std::numeric_limits<int_t>::max();
27
28 // A mutable generator that
29 mutable Generator v;
30
31 // The
32 mutable std::mutex g;
33
34 // Keep the seed so we can "copy" the RandomNumberGenerator
36
37public:
42 RandomNumberGenerator(const Time &t = {}) { seed(t); }
43
49
56 std::lock_guard lock{rng.g};
57 seed(rng.current_seed);
58 }
59
65 Generator new_generator() const {
66 const std::lock_guard my_lock(this->g);
67 return Generator{std::uniform_int_distribution<int_t>(min_v, max_v)(v)};
68 }
69
100 template <template <typename>
101 class random_distribution = std::uniform_real_distribution,
102 typename... Ts>
103 auto get(Ts &&...x) const {
104 return [v = new_generator(),
105 draw = random_distribution(std::forward<Ts>(x)...)]() mutable {
106 return draw(v);
107 };
108 }
109
124 bool seed(int_t n) {
125 static std::mutex seed_mtx;
126 static std::vector<int_t> seeds{};
127
128 std::lock_guard class_lock{g};
129 std::lock_guard method_lock{seed_mtx};
130 bool seed_as_is = true;
131
132 constexpr auto add_one = [](int_t i) {
133 return (i >= max_v - 1) ? min_v : i + 1;
134 };
135
136 if (std::find(seeds.begin(), seeds.end(), n) != seeds.end()) {
137 seed_as_is = false;
138
139 auto minmax = std::minmax_element(seeds.begin(), seeds.end());
140 int_t min = *minmax.first;
141 int_t max = *minmax.second;
142
143 if (min not_eq min_v) {
144 n = add_one(max);
145 } else if (static_cast<std::size_t>(max - min) <= seeds.size()) {
146 n = add_one(max);
147 if (n == min)
148 seeds.clear();
149 } else {
150 do {
151 n = add_one(n);
152 } while (std::find(seeds.begin(), seeds.end(), n) != seeds.end());
153 }
154 }
155 seeds.push_back(n);
156
157 force_seed(n);
158
159 return seed_as_is;
160 }
161
170 bool seed(const Time &t = {}) {
171 return seed(static_cast<int_t>(t.EpochTime().count() % max_v));
172 }
173
182 v.seed(n);
183 current_seed = n;
184 }
185
187 friend std::ostream &operator<<(std::ostream &os,
188 const RandomNumberGenerator &rng) {
189 return os << rng.current_seed;
190 }
191};
192
201template <std::size_t N,
202 template <typename>
203 class random_distribution = std::uniform_real_distribution,
204 std::uniform_random_bit_generator Generator = std::mt19937_64,
205 typename... param_types, class RNG = RandomNumberGenerator<Generator>,
206 class T = decltype(RNG{}.template get<random_distribution>(
207 param_types{}...)())>
208matpack::matpack_data<T, N> random_numbers(std::array<Index, N> sz,
209 param_types &&...x) {
210 matpack::matpack_data<T, N> out(sz);
211 std::generate(out.elem_begin(), out.elem_end(),
212 RNG{}.template get<random_distribution>(
213 std::forward<param_types>(x)...));
214 return out;
215}
216
221template <template <typename>
222 class random_distribution = std::uniform_real_distribution,
223 std::uniform_random_bit_generator Generator = std::mt19937_64,
224 typename... param_types>
225auto random_numbers(Index n, param_types &&...x) {
226 return random_numbers<1, random_distribution, Generator>(
227 std::array<Index, 1>{n}, std::forward<param_types>(x)...);
228}
base max(const Array< base > &x)
Max function.
Definition array.h:128
base min(const Array< base > &x)
Min function.
Definition array.h:144
Stuff related to time in ARTS.
A C++ standards dependent random number generator class.
Definition rng.h:22
int_t current_seed
Definition rng.h:35
Generator v
Definition rng.h:29
static constexpr int_t max_v
Definition rng.h:26
friend std::ostream & operator<<(std::ostream &os, const RandomNumberGenerator &rng)
output the current seed
Definition rng.h:187
bool seed(const Time &t={})
As the main seed, but the number is extracted from the time.
Definition rng.h:170
auto get(Ts &&...x) const
Returns a random number generator of some random distribution.
Definition rng.h:103
bool seed(int_t n)
Seeds the random number engine with a new and unique seed.
Definition rng.h:124
std::mutex g
Definition rng.h:32
Generator new_generator() const
Returns a new Generator.
Definition rng.h:65
typename Generator::result_type int_t
Definition rng.h:23
RandomNumberGenerator(const int_t &s)
Construct a new Random Number Generator object.
Definition rng.h:48
RandomNumberGenerator(const RandomNumberGenerator &rng)
Copy a Random Number Generator object.
Definition rng.h:55
RandomNumberGenerator(const Time &t={})
Construct a new Random Number Generator object.
Definition rng.h:42
static constexpr int_t min_v
Definition rng.h:25
void force_seed(int_t n)
Force the seed to some integer, determining the randomness of the distributions.
Definition rng.h:181
Helper macros for debugging.
matpack::matpack_data< T, N > random_numbers(std::array< Index, N > sz, param_types &&...x)
Wraps the generation of a random number generator for a matpack type.
Definition rng.h:208
Class to handle time in ARTS.
Definition artstime.h:25