BioDynaMo  v1.05.120-25dc9790
random.cc
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #include "core/util/random.h"
16 #include <TF1.h>
17 #include <TF2.h>
18 #include <TF3.h>
19 #include <TRandom3.h>
20 #include "core/simulation.h"
21 
22 namespace bdm {
23 
24 // -----------------------------------------------------------------------------
25 Random::Random() : generator_(new TRandom3()) {}
26 
27 // -----------------------------------------------------------------------------
28 Random::Random(TRootIOCtor*) {}
29 
30 // -----------------------------------------------------------------------------
31 Random::Random(const Random& other)
32  : generator_(static_cast<TRandom*>(other.generator_->Clone())) {}
33 
34 // -----------------------------------------------------------------------------
36  if (generator_) {
37  delete generator_;
38  }
39  for (auto& el : udd_tf1_map_) {
40  delete el.second;
41  }
42  for (auto& el : udd_tf2_map_) {
43  delete el.second;
44  }
45  for (auto& el : udd_tf3_map_) {
46  delete el.second;
47  }
48 }
49 
50 // -----------------------------------------------------------------------------
52  if (&other != this) {
53  if (generator_) {
54  delete generator_;
55  }
56  generator_ = static_cast<TRandom*>(other.generator_->Clone());
57  }
58  return *this;
59 }
60 
61 // -----------------------------------------------------------------------------
62 real_t Random::Uniform(real_t max) { return generator_->Uniform(max); }
63 
64 // -----------------------------------------------------------------------------
66  return generator_->Uniform(min, max);
67 }
68 
69 // -----------------------------------------------------------------------------
71  return generator_->Gaus(mean, sigma);
72 }
73 
74 // -----------------------------------------------------------------------------
75 real_t Random::Exp(real_t tau) { return generator_->Exp(tau); }
76 
77 // -----------------------------------------------------------------------------
79  return generator_->Landau(mean, sigma);
80 }
81 
82 // -----------------------------------------------------------------------------
83 real_t Random::PoissonD(real_t mean) { return generator_->PoissonD(mean); }
84 
85 // -----------------------------------------------------------------------------
87  return generator_->BreitWigner(mean, gamma);
88 }
89 
90 // -----------------------------------------------------------------------------
91 unsigned Random::Integer(int max) { return generator_->Integer(max); }
92 
93 // -----------------------------------------------------------------------------
94 int Random::Binomial(int ntot, real_t prob) {
95  return generator_->Binomial(ntot, prob);
96 }
97 
98 // -----------------------------------------------------------------------------
99 int Random::Poisson(real_t mean) { return generator_->Poisson(mean); }
100 
101 // -----------------------------------------------------------------------------
103  MathArray<double, 2> ret_double;
104  generator_->Circle(ret_double[0], ret_double[1], static_cast<double>(r));
105  return {static_cast<real_t>(ret_double[0]),
106  static_cast<real_t>(ret_double[1])};
107 }
108 
109 // -----------------------------------------------------------------------------
112  generator_->Sphere(ret[0], ret[1], ret[2], r);
113  return {static_cast<real_t>(ret[0]), static_cast<real_t>(ret[1]),
114  static_cast<real_t>(ret[2])};
115 }
116 
117 // -----------------------------------------------------------------------------
118 void Random::SetSeed(uint64_t seed) { generator_->SetSeed(seed); }
119 
120 // -----------------------------------------------------------------------------
121 uint64_t Random::GetSeed() const { return generator_->GetSeed(); }
122 
123 // -----------------------------------------------------------------------------
124 void Random::SetGenerator(TRandom* new_generator) {
125  if (generator_) {
126  delete generator_;
127  }
128  generator_ = new_generator;
129 }
130 
131 // -----------------------------------------------------------------------------
132 template <typename TSample>
134  auto* rng = Simulation::GetActive()->GetRandom()->generator_;
135  return SampleImpl(rng);
136 }
138 template int DistributionRng<int>::Sample();
139 
140 // -----------------------------------------------------------------------------
141 template <typename TSample>
143  auto* rng = Simulation::GetActive()->GetRandom()->generator_;
144  return Sample2Impl(rng);
145 }
148 
149 // -----------------------------------------------------------------------------
150 template <typename TSample>
152  return MathArray<TSample, 2>({Sample(), Sample()});
153 }
156 
157 // -----------------------------------------------------------------------------
158 template <typename TSample>
160  auto* rng = Simulation::GetActive()->GetRandom()->generator_;
161  return Sample3Impl(rng);
162 }
165 
166 // -----------------------------------------------------------------------------
167 template <typename TSample>
169  return MathArray<TSample, 3>(
170  {SampleImpl(rng), SampleImpl(rng), SampleImpl(rng)});
171 }
174 
175 // -----------------------------------------------------------------------------
176 UniformRng::UniformRng(real_t min, real_t max) : min_(min), max_(max) {}
177 UniformRng::~UniformRng() = default;
178 real_t UniformRng::SampleImpl(TRandom* rng) { return rng->Uniform(min_, max_); }
179 
181  return UniformRng(min, max);
182 }
183 
184 // -----------------------------------------------------------------------------
185 GausRng::GausRng(real_t mean, real_t sigma) : mean_(mean), sigma_(sigma) {}
186 GausRng::~GausRng() = default;
187 real_t GausRng::SampleImpl(TRandom* rng) { return rng->Gaus(mean_, sigma_); }
188 
190  return GausRng(mean, sigma);
191 }
192 
193 // -----------------------------------------------------------------------------
194 ExpRng::ExpRng(real_t tau) : tau_(tau) {}
195 ExpRng::~ExpRng() = default;
196 real_t ExpRng::SampleImpl(TRandom* rng) { return rng->Exp(tau_); }
197 
198 ExpRng Random::GetExpRng(real_t tau) const { return ExpRng(tau); }
199 
200 // -----------------------------------------------------------------------------
201 LandauRng::LandauRng(real_t mean, real_t sigma) : mean_(mean), sigma_(sigma) {}
202 LandauRng::~LandauRng() = default;
204  return rng->Landau(mean_, sigma_);
205 }
206 
208  return LandauRng(mean, sigma);
209 }
210 
211 // -----------------------------------------------------------------------------
212 PoissonDRng::PoissonDRng(real_t mean) : mean_(mean) {}
213 PoissonDRng::~PoissonDRng() = default;
214 real_t PoissonDRng::SampleImpl(TRandom* rng) { return rng->PoissonD(mean_); }
215 
217  return PoissonDRng(mean);
218 }
219 
220 // -----------------------------------------------------------------------------
222  : mean_(mean), gamma_(gamma) {}
225  return rng->BreitWigner(mean_, gamma_);
226 }
227 
229  return BreitWignerRng(mean, gamma);
230 }
231 
232 // -----------------------------------------------------------------------------
233 UserDefinedDistRng1D::UserDefinedDistRng1D(TF1* function, const char* option)
234  : function_(function), option_(option) {}
236 
237 // TODO(Lukas) after the update to ROOT 6.24 pass
238 // rng to GetRandom to avoid performance issue.
239 // also pass option_ to GetRandom.
241  auto min = function_->GetXmin();
242  auto max = function_->GetXmax();
243  return function_->GetRandom(min, max);
244 }
245 void UserDefinedDistRng1D::Draw(const char* option) { function_->Draw(option); }
247 
248 // -----------------------------------------------------------------------------
250  double (*f)(const double*, const double*),
251  const FixedSizeVector<real_t, 10>& params, real_t min, real_t max,
252  const char* option) {
253  TF1* tf1 = nullptr;
254  UserDefinedDist udd{f, params, min, max};
255  auto it = udd_tf1_map_.find(udd);
256  if (it == udd_tf1_map_.end()) {
257  tf1 = new TF1("", f, min, max, params.size());
258  udd_tf1_map_[udd] = tf1;
259  tf1->SetParameters(params[0], params[1], params[2], params[3], params[4],
260  params[5], params[6], params[7], params[8], params[9]);
261  } else {
262  tf1 = it->second;
263  }
264  return UserDefinedDistRng1D(tf1, option);
265 }
266 
267 // -----------------------------------------------------------------------------
268 UserDefinedDistRng2D::UserDefinedDistRng2D(TF2* function, const char* option)
269  : function_(function), option_(option) {}
271 
272 // TODO(Lukas) after the update to ROOT 6.24 pass
273 // rng to GetRandom to avoid performance issue.
274 // also pass option_ to GetRandom.
276  auto min = function_->GetXmin();
277  auto max = function_->GetXmax();
278  return function_->GetRandom(min, max);
279 }
282  function_->GetRandom2(ret[0], ret[1]);
283  return {static_cast<real_t>(ret[0]), static_cast<real_t>(ret[1])};
284 }
285 void UserDefinedDistRng2D::Draw(const char* option) { function_->Draw(option); }
287 
289  double (*f)(const double*, const double*),
290  const FixedSizeVector<real_t, 10>& params, real_t xmin, real_t xmax,
291  real_t ymin, real_t ymax, const char* option) {
292  TF2* tf2 = nullptr;
293  UserDefinedDist udd{f, params, xmin, xmax, ymin, ymax};
294  auto it = udd_tf2_map_.find(udd);
295  if (it == udd_tf2_map_.end()) {
296  tf2 = new TF2("", f, xmin, xmax, ymin, ymax, params.size());
297  udd_tf2_map_[udd] = tf2;
298  tf2->SetParameters(params[0], params[1], params[2], params[3], params[4],
299  params[5], params[6], params[7], params[8], params[9]);
300  } else {
301  tf2 = it->second;
302  }
303  return UserDefinedDistRng2D(tf2, option);
304 }
305 
306 // -----------------------------------------------------------------------------
307 UserDefinedDistRng3D::UserDefinedDistRng3D(TF3* function, const char* option)
308  : function_(function), option_(option) {}
310 
311 // TODO(Lukas) after the update to ROOT 6.24 pass
312 // rng to GetRandom to avoid performance issue.
313 // also pass option_ to GetRandom.
315  auto min = function_->GetXmin();
316  auto max = function_->GetXmax();
317  return function_->GetRandom(min, max);
318 }
321  function_->GetRandom2(ret[0], ret[1]);
322  return {static_cast<real_t>(ret[0]), static_cast<real_t>(ret[1])};
323 }
326  function_->GetRandom3(ret[0], ret[1], ret[2]);
327  return {static_cast<real_t>(ret[0]), static_cast<real_t>(ret[1]),
328  static_cast<real_t>(ret[2])};
329 }
330 void UserDefinedDistRng3D::Draw(const char* option) { function_->Draw(option); }
332 
334  double (*f)(const double*, const double*),
335  const FixedSizeVector<real_t, 10>& params, real_t xmin, real_t xmax,
336  real_t ymin, real_t ymax, real_t zmin, real_t zmax, const char* option) {
337  TF3* tf3 = nullptr;
338  UserDefinedDist udd{f, params, xmin, xmax, ymin, ymax, zmin, zmax};
339  auto it = udd_tf3_map_.find(udd);
340  if (it == udd_tf3_map_.end()) {
341  tf3 = new TF3("", f, xmin, xmax, ymin, ymax, zmin, zmax, params.size());
342  udd_tf3_map_[udd] = tf3;
343  tf3->SetParameters(params[0], params[1], params[2], params[3], params[4],
344  params[5], params[6], params[7], params[8], params[9]);
345  } else {
346  tf3 = it->second;
347  }
348  return UserDefinedDistRng3D(tf3, option);
349 }
350 
351 // -----------------------------------------------------------------------------
352 BinomialRng::BinomialRng(int ntot, real_t prob) : ntot_(ntot), prob_(prob) {}
353 BinomialRng::~BinomialRng() = default;
354 int BinomialRng::SampleImpl(TRandom* rng) {
355  return rng->Binomial(ntot_, prob_);
356 }
357 
359  return BinomialRng(ntot, prob);
360 }
361 
362 // -----------------------------------------------------------------------------
363 PoissonRng::PoissonRng(real_t mean) : mean_(mean) {}
364 PoissonRng::~PoissonRng() = default;
365 int PoissonRng::SampleImpl(TRandom* rng) { return rng->Poisson(mean_); }
366 
367 PoissonRng Random::GetPoissonRng(real_t mean) const { return PoissonRng(mean); }
368 
369 } // namespace bdm
bdm::UserDefinedDistRng2D::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:275
bdm::Random::Gaus
real_t Gaus(real_t mean=0.0, real_t sigma=1.0)
Definition: random.cc:70
bdm::BreitWignerRng::gamma_
real_t gamma_
Definition: random.h:132
bdm::Random::Sphere
MathArray< real_t, 3 > Sphere(real_t radius)
Definition: random.cc:110
bdm::UserDefinedDistRng1D::function_
TF1 * function_
Definition: random.h:149
bdm::BinomialRng::SampleImpl
int SampleImpl(TRandom *rng) override
Definition: random.cc:354
bdm::FixedSizeVector< real_t, 10 >
bdm::UserDefinedDistRng3D::~UserDefinedDistRng3D
~UserDefinedDistRng3D() override
bdm::Random::GetGausRng
GausRng GetGausRng(real_t mean=0, real_t sigma=1) const
Definition: random.cc:189
bdm::Random::PoissonD
real_t PoissonD(real_t mean)
Definition: random.cc:83
bdm::UserDefinedDistRng2D::~UserDefinedDistRng2D
~UserDefinedDistRng2D() override
bdm::BreitWignerRng::mean_
real_t mean_
Definition: random.h:132
bdm::PoissonRng::~PoissonRng
~PoissonRng() override
bdm::UserDefinedDistRng1D::UserDefinedDistRng1D
UserDefinedDistRng1D(TRootIOCtor *ioctor)
Definition: random.h:140
bdm::BinomialRng::BinomialRng
BinomialRng(int ntot, real_t prob)
Definition: random.cc:352
bdm::LandauRng::~LandauRng
~LandauRng() override
bdm::PoissonDRng::~PoissonDRng
~PoissonDRng() override
bdm::PoissonDRng
Definition: random.h:114
bdm::PoissonDRng::PoissonDRng
PoissonDRng(real_t mean)
Definition: random.cc:212
bdm::Random::GetUserDefinedDistRng3D
UserDefinedDistRng3D GetUserDefinedDistRng3D(double(*f)(const double *, const double *), const FixedSizeVector< real_t, 10 > &params, real_t xmin, real_t xmax, real_t ymin, real_t ymax, real_t zmin, real_t zmax, const char *option=nullptr)
Definition: random.cc:333
bdm::DistributionRng::Sample3
MathArray< TSample, 3 > Sample3()
Definition: random.cc:159
bdm::Random::Circle
MathArray< real_t, 2 > Circle(real_t radius)
Definition: random.cc:102
bdm::PoissonRng::mean_
real_t mean_
Definition: random.h:253
bdm
Definition: agent.cc:39
bdm::GausRng::sigma_
real_t sigma_
Definition: random.h:84
bdm::GausRng
Definition: random.h:78
bdm::Random::GetBreitWignerRng
BreitWignerRng GetBreitWignerRng(real_t mean=0, real_t gamma=1) const
Definition: random.cc:228
bdm::Random::GetExpRng
ExpRng GetExpRng(real_t tau) const
Definition: random.cc:198
bdm::Random::BreitWigner
real_t BreitWigner(real_t mean=0, real_t gamma=1)
Definition: random.cc:86
bdm::UserDefinedDistRng3D::function_
TF3 * function_
Definition: random.h:186
bdm::UserDefinedDistRng2D::function_
TF2 * function_
Definition: random.h:167
bdm::Random::operator=
Random & operator=(const Random &other)
Definition: random.cc:51
bdm::BreitWignerRng
Definition: random.h:126
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::PoissonDRng::mean_
real_t mean_
Definition: random.h:120
bdm::Random::GetPoissonDRng
PoissonDRng GetPoissonDRng(real_t mean) const
Definition: random.cc:216
bdm::UserDefinedDistRng1D::~UserDefinedDistRng1D
~UserDefinedDistRng1D() override
bdm::Simulation::GetRandom
Random * GetRandom()
Returns a thread local random number generator.
Definition: simulation.cc:267
bdm::Random::Poisson
int Poisson(real_t mean)
Definition: random.cc:99
bdm::Random::udd_tf1_map_
std::unordered_map< UserDefinedDist, TF1 * > udd_tf1_map_
Definition: random.h:428
bdm::Random
Definition: random.h:262
bdm::GausRng::mean_
real_t mean_
Definition: random.h:84
bdm::FixedSizeVector::size
size_t size() const
Definition: fixed_size_vector.h:46
bdm::ExpRng
Definition: random.h:90
random.h
bdm::Random::Uniform
real_t Uniform(real_t max=1.0)
Definition: random.cc:62
bdm::Random::GetBinomialRng
BinomialRng GetBinomialRng(int ntot, real_t prob) const
Definition: random.cc:358
bdm::LandauRng::sigma_
real_t sigma_
Definition: random.h:108
bdm::UserDefinedDistRng3D::UserDefinedDistRng3D
UserDefinedDistRng3D(TRootIOCtor *ioctor)
Definition: random.h:175
bdm::UserDefinedDistRng2D
Definition: random.h:155
bdm::UniformRng
Definition: random.h:66
bdm::DistributionRng::Sample2Impl
virtual MathArray< TSample, 2 > Sample2Impl(TRandom *rng)
Definition: random.cc:151
bdm::BreitWignerRng::BreitWignerRng
BreitWignerRng(real_t mean, real_t gamma)
Definition: random.cc:221
bdm::UniformRng::max_
real_t max_
Definition: random.h:72
bdm::LandauRng::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:203
bdm::Random::Integer
unsigned Integer(int max)
Definition: random.cc:91
bdm::UserDefinedDistRng2D::Draw
void Draw(const char *option="")
Definition: random.cc:285
bdm::Random::Binomial
int Binomial(int ntot, real_t prob)
Definition: random.cc:94
bdm::ExpRng::~ExpRng
~ExpRng() override
bdm::Random::SetGenerator
void SetGenerator(TRandom *new_rng)
Definition: random.cc:124
bdm::BreitWignerRng::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:224
bdm::DistributionRng::Sample3Impl
virtual MathArray< TSample, 3 > Sample3Impl(TRandom *rng)
Definition: random.cc:168
bdm::LandauRng
Definition: random.h:102
bdm::UserDefinedDistRng3D::GetTF3
TF3 * GetTF3()
Definition: random.cc:331
bdm::UserDefinedDistRng3D::Draw
void Draw(const char *option="")
Definition: random.cc:330
bdm::UserDefinedDistRng3D::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:314
bdm::UserDefinedDistRng1D::GetTF1
TF1 * GetTF1()
Definition: random.cc:246
bdm::ExpRng::ExpRng
ExpRng(real_t tau)
Definition: random.cc:194
bdm::Random::Random
Random()
Definition: random.cc:25
bdm::Random::Landau
real_t Landau(real_t mean=0, real_t sigma=1)
Definition: random.cc:78
bdm::UserDefinedDistRng1D::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:240
bdm::UserDefinedDistRng1D::Draw
void Draw(const char *option="")
Definition: random.cc:245
bdm::BinomialRng::~BinomialRng
~BinomialRng() override
bdm::ExpRng::tau_
real_t tau_
Definition: random.h:96
bdm::BinomialRng
Definition: random.h:234
bdm::BinomialRng::prob_
real_t prob_
Definition: random.h:241
bdm::Random::GetUserDefinedDistRng2D
UserDefinedDistRng2D GetUserDefinedDistRng2D(double(*f)(const double *, const double *), const FixedSizeVector< real_t, 10 > &params, real_t xmin, real_t xmax, real_t ymin, real_t ymax, const char *option=nullptr)
Definition: random.cc:288
bdm::BreitWignerRng::~BreitWignerRng
~BreitWignerRng() override
bdm::Random::udd_tf2_map_
std::unordered_map< UserDefinedDist, TF2 * > udd_tf2_map_
Definition: random.h:431
bdm::Random::GetUserDefinedDistRng1D
UserDefinedDistRng1D GetUserDefinedDistRng1D(double(*f)(const double *, const double *), const FixedSizeVector< real_t, 10 > &params, real_t min, real_t max, const char *option=nullptr)
Definition: random.cc:249
bdm::Random::GetUniformRng
UniformRng GetUniformRng(real_t min=0, real_t max=1) const
Definition: random.cc:180
bdm::UniformRng::~UniformRng
~UniformRng() override
bdm::UniformRng::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:178
bdm::ExpRng::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:196
bdm::UserDefinedDistRng3D::Sample2Impl
MathArray< real_t, 2 > Sample2Impl(TRandom *rng) override
Definition: random.cc:319
bdm::DistributionRng::Sample
TSample Sample()
Draws a sample from the distribution.
Definition: random.cc:133
bdm::UserDefinedDistRng3D::Sample3Impl
MathArray< real_t, 3 > Sample3Impl(TRandom *rng) override
Definition: random.cc:324
bdm::Random::Exp
real_t Exp(real_t tau)
Definition: random.cc:75
bdm::Random::GetPoissonRng
PoissonRng GetPoissonRng(real_t mean) const
Definition: random.cc:367
bdm::Random::GetSeed
uint64_t GetSeed() const
Definition: random.cc:121
bdm::UserDefinedDistRng2D::UserDefinedDistRng2D
UserDefinedDistRng2D(TRootIOCtor *ioctor)
Definition: random.h:157
bdm::UniformRng::UniformRng
UniformRng(real_t min, real_t max)
Definition: random.cc:176
bdm::PoissonRng::PoissonRng
PoissonRng(real_t mean)
Definition: random.cc:363
bdm::UserDefinedDistRng1D
Definition: random.h:138
bdm::Random::~Random
~Random()
Definition: random.cc:35
bdm::Random::GetLandauRng
LandauRng GetLandauRng(real_t mean=0, real_t sigma=1) const
Definition: random.cc:207
simulation.h
bdm::GausRng::GausRng
GausRng(real_t mean, real_t sigma)
Definition: random.cc:185
bdm::UniformRng::min_
real_t min_
Definition: random.h:72
bdm::MathArray
Definition: math_array.h:36
bdm::Random::generator_
TRandom * generator_
Definition: random.h:425
bdm::LandauRng::LandauRng
LandauRng(real_t mean, real_t sigma)
Definition: random.cc:201
bdm::PoissonRng::SampleImpl
int SampleImpl(TRandom *rng) override
Definition: random.cc:365
bdm::LandauRng::mean_
real_t mean_
Definition: random.h:108
bdm::GausRng::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:187
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68
bdm::UserDefinedDistRng3D
Definition: random.h:173
bdm::BinomialRng::ntot_
int ntot_
Definition: random.h:240
bdm::GausRng::~GausRng
virtual ~GausRng() override
bdm::UserDefinedDist
Definition: random.h:192
bdm::UserDefinedDistRng2D::GetTF2
TF2 * GetTF2()
Definition: random.cc:286
bdm::PoissonDRng::SampleImpl
real_t SampleImpl(TRandom *rng) override
Definition: random.cc:214
bdm::Random::SetSeed
void SetSeed(uint64_t seed)
Definition: random.cc:118
bdm::PoissonRng
Definition: random.h:247
bdm::Random::udd_tf3_map_
std::unordered_map< UserDefinedDist, TF3 * > udd_tf3_map_
Definition: random.h:434
bdm::UserDefinedDistRng2D::Sample2Impl
MathArray< real_t, 2 > Sample2Impl(TRandom *rng) override
Definition: random.cc:280
bdm::DistributionRng::Sample2
MathArray< TSample, 2 > Sample2()
Definition: random.cc:142