Documentation for OpenFLUID 2.2.2
Loading...
Searching...
No Matches
RandomNumberGenerator.hpp
Go to the documentation of this file.
1/*
2
3 This file is part of OpenFLUID software
4 Copyright(c) 2021-2026, INRAE
5
6
7 == GNU General Public License Usage ==
8
9 OpenFLUID is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 OpenFLUID is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21
22
23 == Other Usage ==
24
25 Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26 license, and requires a written agreement between You and INRA.
27 Licensees for Other Usage of OpenFLUID may use this file in accordance
28 with the terms contained in the written agreement between You and INRA.
29
30*/
31
32
33/**
34 @file RandomNumberGenerator.hpp
35
36 @author Dorian GERARDIN <dorian.gerardin@inrae.fr>
37 @author Alain DUPUY <contact@openfluid-project.org>
38 @author David CREVOISIER <david.crevoisier@inrae.fr>
39 */
40
41
42#ifndef __OPENFLUID_TOOLS_RANDOMNUMBERGENERATOR_HPP__
43#define __OPENFLUID_TOOLS_RANDOMNUMBERGENERATOR_HPP__
44
45
46#include <string>
47#include <iostream>
48#include <random>
49#include <vector>
50
51#include <openfluid/ware/TypeDefs.hpp>
52
53
54namespace openfluid { namespace tools {
55
56
57/**
58 @brief Class for management of random. It includes distribution utility functions.
59
60 Sources:
61 @li https://en.wikipedia.org/wiki/Random_number_generation
62 @li https://en.wikipedia.org/wiki/Mersenne_Twister
63
64
65 <I>Example : declaring an instance</I>
66 @snippet wares/RNG.cpp rng_decl
67
68 <I>Example : initializing with a custom seed</I>
69 @snippet wares/RNG.cpp rng_initialize_seed
70
71 <I>Example : initializing with a random seed</I>
72 @snippet wares/RNG.cpp rng_initialize_random_seed
73
74 <I>Example : getting a random generated number using normal distribution</I>
75 @snippet wares/RNG.cpp rng_log
76
77 <I>Example : getting randomized value using Bernoulli distribution</I>
78 @snippet wares/RNG.cpp rng_bernoulli
79*/
81{
82 public:
83
85
87
88 /**
89 Set a seed for the generator
90 @param[in] CustomSeed The seed to set. If negative, random seed will be used
91 */
92 void init(long int CustomSeed = -1);
93
94 /**
95 Returns the seed
96 @return an uint64_t
97 */
98 uint64_t getSelectedSeed() const;
99
100 /**
101 * @brief Log normal distribution
102 *
103 * @tparam T type of value for distribution
104 * @param N number of values to generate with distribution
105 * @param Mean mean for log normal distribution
106 * @param Sd standard deviation for log normal distribution
107 * @return std::vector<T> vector with N randomized values using log normal distribution
108 */
109 template <typename T>
110 std::vector<T> rlnorm(size_t N, double Mean, double Sd)
111 {
112 T Maxlnorm = std::exp(Mean - Sd * Sd);
113 std::vector<T> vec(N, Maxlnorm);
114 std::lognormal_distribution<T> Distribution(Mean, Sd);
115
116 for (auto& v : vec)
117 {
118 v = Distribution(getGenerator());
119 }
120
121 return vec;
122 }
123
124
125 // =====================================================================
126 // =====================================================================
127
128
129 /**
130 * @brief Normal distribution
131 *
132 * @tparam T type of value for distribution
133 * @param N number of values to generate with distribution
134 * @param Mean mean for normal distribution
135 * @param Sd standard deviation for normal distribution
136 * @return std::vector<T> vector with N randomized values using normal distribution
137 */
138 template <typename T>
139 std::vector<T> rnorm(size_t N, double Mean, double Sd)
140 {
141 std::vector<T> vec(N, Mean + Sd);
142 std::normal_distribution<T> Distribution(Mean, Sd);
143 for (auto& v : vec)
144 {
145 v = Distribution(getGenerator());
146 }
147
148 return vec;
149 }
150
151
152 // =====================================================================
153 // =====================================================================
154
155
156 /**
157 * @brief Uniform distribution
158 *
159 * @tparam T type of value for distribution
160 * @param N number of values to generate with distribution
161 * @param V1 min value for distribution
162 * @param V2 max value for distribution
163 * @return std::vector<T> vector with N randomized values using real uniform distribution
164 */
165 template <typename T>
166 std::vector<T> runif(size_t N, T V1, T V2)
167 {
168 std::vector<T> vec(N, 0.5 * V1 + 0.5 * V2);
169 if (V2 > V1)
170 {
171 std::uniform_real_distribution<T> Distribution(V1, V2);
172 for (auto& v : vec)
173 {
174 v = Distribution(getGenerator());
175 }
176 }
177 else
178 {
179 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Max value < Min Value");
180 }
181
182 return vec;
183 }
184
185
186 // =====================================================================
187 // =====================================================================
188
189
190 /**
191 * @brief Uniform distribution
192 *
193 * @tparam T type of value for distribution
194 * @param N number of values to generate with distribution
195 * @param V1 min value for distribution
196 * @param V2 max value for distribution
197 * @return std::vector<T> vector with N randomized values using integer uniform distribution
198 */
199 template <typename T>
200 std::vector<T> irunif(size_t N, T V1, T V2)
201 {
202 std::vector<T> vec(N, 0.5 * V1 + 0.5 * V2);
203 if (V2 > V1)
204 {
205 std::uniform_int_distribution<T> Distribution(V1, V2);
206 for (auto& v : vec)
207 {
208 v = Distribution(getGenerator());
209 }
210 }
211 else
212 {
213 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Max value < Min Value");
214 }
215
216 return vec;
217 }
218
219
220 // =====================================================================
221 // =====================================================================
222
223
224 /**
225 * @brief Log normal distribution
226 *
227 * @tparam T type of value for distribution
228 * @param Mean mean for log normal distribution
229 * @param Sd standard deviation for log normal distribution
230 * @return Randomized value using log normal distribution
231 */
232 template <typename T>
233 T rlnorm(double Mean, double Sd)
234 {
235 std::lognormal_distribution<T> Distribution(Mean, Sd);
236 return Distribution(getGenerator());
237 }
238
239
240 // =====================================================================
241 // =====================================================================
242
243
244 /**
245 * @brief Normal distribution
246 *
247 * @tparam T type of value for distribution
248 * @param Mean mean for normal distribution
249 * @param Sd standard deviation for normal distribution
250 * @return Randomized value using normal distribution
251 */
252 template <typename T>
253 T rnorm(double Mean, double Sd)
254 {
255 std::normal_distribution<T> Distribution(Mean, Sd);
256 return Distribution(getGenerator());
257 }
258
259
260 // =====================================================================
261 // =====================================================================
262
263
264 /**
265 * @brief Real uniform distribution
266 *
267 * @tparam T type of value for distribution
268 * @param V1 min value for distribution
269 * @param V2 max value for distribution
270 * @return Randomized value using real uniform distribution
271 */
272 template <typename T>
273 T runif(T V1, T V2)
274 {
275 if (V2 > V1)
276 {
277 std::uniform_real_distribution<T> Distribution(V1, V2);
278 return Distribution(getGenerator());
279 }
280 else
281 {
282 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Max value < Min Value");
283 }
284 }
285
286
287 // =====================================================================
288 // =====================================================================
289
290
291 /**
292 * @brief Integer uniform distribution
293 *
294 * @tparam T type of value for distribution
295 * @param V1 min value for distribution
296 * @param V2 max value for distribution
297 * @return Randomized value using integer uniform distribution
298 */
299 template <typename T>
300 T irunif(T V1, T V2)
301 {
302 if (V2 > V1)
303 {
304 std::uniform_int_distribution<T> Distribution(V1, V2);
305 return Distribution(getGenerator());
306 }
307 else
308 {
309 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION, "Max value < Min Value");
310 }
311 }
312
313
314 // =====================================================================
315 // =====================================================================
316
317
318 /**
319 * @brief Bernoulli distribution
320 *
321 * @param Probability probability of success
322 * @return Randomized value using bernoulli distribution
323 */
324 bool bernoulli(double Probability)
325 {
326 std::bernoulli_distribution Distribution(Probability);
327 return Distribution(getGenerator());
328 }
329
330
331 protected:
332
333 /**
334 The Mersenne Twister generator
335 */
336 std::mt19937_64 m_Generator;
337
339
340 /**
341 A boolean to check if we need to display the seed in logs
342 */
344
345 /**
346 A string to display the seed in logs as "Seed: ${m_SelectedSeed}"
347 */
348 const std::string m_DisplayNameInfo;
349
350 std::mt19937_64& getGenerator();
351
352 virtual void displaySeedInfo();
353
354};
355
356
357} } // namespaces
358
359#endif /* __OPENFLUID_TOOLS_RANDOMNUMBERGENERATOR_HPP__ */
Definition FrameworkException.hpp:51
Class for management of random. It includes distribution utility functions.
Definition RandomNumberGenerator.hpp:81
T rnorm(double Mean, double Sd)
Normal distribution.
Definition RandomNumberGenerator.hpp:253
bool m_DisplaySeed
Definition RandomNumberGenerator.hpp:343
void init(long int CustomSeed=-1)
T runif(T V1, T V2)
Real uniform distribution.
Definition RandomNumberGenerator.hpp:273
const std::string m_DisplayNameInfo
Definition RandomNumberGenerator.hpp:348
uint64_t m_SelectedSeed
Definition RandomNumberGenerator.hpp:338
std::mt19937_64 m_Generator
Definition RandomNumberGenerator.hpp:336
T rlnorm(double Mean, double Sd)
Log normal distribution.
Definition RandomNumberGenerator.hpp:233
std::vector< T > irunif(size_t N, T V1, T V2)
Uniform distribution.
Definition RandomNumberGenerator.hpp:200
bool bernoulli(double Probability)
Bernoulli distribution.
Definition RandomNumberGenerator.hpp:324
T irunif(T V1, T V2)
Integer uniform distribution.
Definition RandomNumberGenerator.hpp:300
std::vector< T > rlnorm(size_t N, double Mean, double Sd)
Log normal distribution.
Definition RandomNumberGenerator.hpp:110
~RandomNumberGenerator()
Definition RandomNumberGenerator.hpp:86
std::vector< T > rnorm(size_t N, double Mean, double Sd)
Normal distribution.
Definition RandomNumberGenerator.hpp:139
std::vector< T > runif(size_t N, T V1, T V2)
Uniform distribution.
Definition RandomNumberGenerator.hpp:166
#define OPENFLUID_API
Definition dllexport.hpp:86
Definition ApplicationException.hpp:47