CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
RandomNumbers.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2010 by Federico Marulli *
3  * federico.marulli3@unibo.it *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public *
16  * License along with this program; if not, write to the Free *
17  * Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ********************************************************************/
20 
34 #include "RandomNumbers.h"
35 
36 using namespace std;
37 
38 using namespace cbl;
39 using namespace random;
40 
41 
42 // =====================================================================================
43 
44 
45 cbl::random::RandomNumbers::RandomNumbers (const int seed, const double MinVal, const double MaxVal)
46 {
47  set_seed(seed);
48  set_range(MinVal, MaxVal);
49 }
50 
51 
52 // =====================================================================================
53 
54 
56 {
57  m_seed = seed;
58  m_generator.seed(m_seed);
59 }
60 
61 
62 // =====================================================================================
63 
64 
65 void cbl::random::RandomNumbers::set_range (const double MinVal, const double MaxVal)
66 {
67  m_MinVal = MinVal;
68  m_MaxVal = MaxVal;
69 }
70 
71 
72 // =====================================================================================
73 
74 
75 cbl::random::UniformRandomNumbers::UniformRandomNumbers (double MinVal, const double MaxVal, const int seed) : RandomNumbers(seed, MinVal, MaxVal)
76 {
77  m_distribution = make_shared<uniform_real_distribution<double>>(uniform_real_distribution<double>(0, 1));
78 }
79 
80 
81 // =====================================================================================
82 
83 
85 {
86  return (m_MaxVal-m_MinVal)*m_distribution->operator()(m_generator)+m_MinVal;
87 }
88 
89 
90 // =====================================================================================
91 
92 
93 cbl::random::UniformRandomNumbers_Int::UniformRandomNumbers_Int (double MinVal, const double MaxVal, const int seed) : RandomNumbers(seed, MinVal, MaxVal)
94 {
95  m_distribution = make_shared<uniform_int_distribution<int>>(uniform_int_distribution<int>(ceil(m_MinVal), floor(m_MaxVal)));
96 }
97 
98 
99 // =====================================================================================
100 
101 
103 {
104  return m_distribution->operator()(m_generator);
105 }
106 
107 
108 
109 // =====================================================================================
110 
111 
112 cbl::random::PoissonRandomNumbers::PoissonRandomNumbers (const double mean, const int seed, const double MinVal, const double MaxVal) : RandomNumbers(seed, MinVal, MaxVal)
113 {
114  set_mean(mean);
115 }
116 
117 
118 // =====================================================================================
119 
120 
122 {
123  m_mean = mean;
124  m_distribution = make_shared<poisson_distribution<int> >(poisson_distribution<int>(mean));
125 }
126 
127 
128 // =====================================================================================
129 
130 
132 {
133  double val = m_distribution->operator()(m_generator);
134 
135  while (val>=m_MaxVal || val<=m_MinVal)
136  val = m_distribution->operator()(m_generator);
137 
138  return val;
139 }
140 
141 
142 // =====================================================================================
143 
144 
145 cbl::random::NormalRandomNumbers::NormalRandomNumbers (const double mean, const double sigma, const int seed, const double MinVal, const double MaxVal) : RandomNumbers(seed, MinVal, MaxVal)
146 {
147  set_mean_sigma(mean, sigma);
148 }
149 
150 
151 // =====================================================================================
152 
153 
154 void cbl::random::NormalRandomNumbers::set_mean_sigma (const double mean, const double sigma)
155 {
156  m_mean = mean;
157  m_sigma = sigma;
158  m_distribution = make_shared<normal_distribution<double> >(normal_distribution<double>(mean, sigma));
159 }
160 
161 
162 // =====================================================================================
163 
164 
166 {
167  double val = m_distribution->operator()(m_generator);
168 
169  while (val>=m_MaxVal || val<=m_MinVal)
170  val = m_distribution->operator()(m_generator);
171 
172  return val;
173 }
174 
175 
176 // =====================================================================================
177 
178 
179 cbl::random::DiscreteRandomNumbers::DiscreteRandomNumbers (const vector<double> values, const vector<double> weights, const int seed, const double MinVal, const double MaxVal) : RandomNumbers(seed, MinVal, MaxVal)
180 {
181  set_discrete_values(values, weights);
182 }
183 
184 
185 // =====================================================================================
186 
187 
188 void cbl::random::DiscreteRandomNumbers::set_discrete_values (const vector<double> values, const vector<double> weights)
189 {
190  if (weights.size()==0) {
191  m_values = values;
192  m_weights.erase(m_weights.begin(), m_weights.end());
193  m_weights.resize(m_values.size(), 1.);
194  }
195  else if (weights.size()!=values.size())
196  ErrorCBL("value and weight vectors have different sizes!", "set_discrete_values", "RandomNumbers.cpp");
197  else {
198  m_values = values;
199  m_weights = weights;
200  }
201 
202  for (size_t i=0; i<m_values.size(); i++)
203  if (m_values[i]>=m_MaxVal || m_values[i]<=m_MinVal)
204  m_weights[i]=0;
205 
206  m_distribution = make_shared<discrete_distribution<int> >(discrete_distribution<int>(m_weights.begin(), m_weights.end()));
207 }
208 
209 
210 // =====================================================================================
211 
212 
214 {
215  return m_values[m_distribution->operator()(m_generator)];
216 }
217 
218 
219 // =====================================================================================
220 
221 
222 cbl::random::DistributionRandomNumbers::DistributionRandomNumbers (const vector<double> xx, const vector<double> distribution_function, const string interpolation_method, const int seed) : RandomNumbers()
223 {
224  set_interpolated_distribution(xx, distribution_function, interpolation_method);
225  m_uniform_generator = make_shared<UniformRandomNumbers>(0., 1., seed);
226 }
227 
228 
229 // =====================================================================================
230 
231 
233 {
234  m_uniform_generator->set_seed(seed);
235 }
236 
237 
238 // =====================================================================================
239 
240 
241 void cbl::random::DistributionRandomNumbers::set_interpolated_distribution (const vector<double> xx, const vector<double> distribution_function, const string interpolation_method)
242 {
243  glob::FuncGrid ff(xx, distribution_function, interpolation_method);
244  double norm = ff.integrate_qag(Min(xx), Max(xx), 1.e-4);
245 
246  vector<double> newx;
247  vector<double> FX;
248 
249  newx.push_back(Min(xx));
250  FX.push_back(0.);
251  int n = 0;
252 
253  for (size_t i=1; i<xx.size(); i++) {
254  double cum = ff.integrate_qag(Min(xx), xx[i], 1.e-4)/norm;
255 
256  if (cum>FX[n]) {
257  FX.push_back(cum);
258  newx.push_back(xx[i]);
259  n ++;
260  //coutCBL << setprecision(10) << FX[n] << " " << newx[n] << endl;
261  }
262  }
263 
264  m_distribution = make_shared<glob::FuncGrid>(FX, newx, interpolation_method);
265 }
266 
267 
268 // =====================================================================================
269 
270 
272 {
273  return m_distribution->operator()(m_uniform_generator->operator()());
274 }
275 
276 
277 // =====================================================================================
278 
279 
280 cbl::random::CustomDistributionRandomNumbers::CustomDistributionRandomNumbers (const distribution_func func, const shared_ptr<void> modelInput, const vector<double> parameter, const int seed, const double MinVal, const double MaxVal) : RandomNumbers(seed, MinVal, MaxVal)
281 {
282  set_custom_distribution(func, modelInput, parameter);
283  m_uniform_generator = make_shared<UniformRandomNumbers>(0., 1., seed);
284 }
285 
286 
287 // =====================================================================================
288 
289 
291 {
292  m_uniform_generator->set_seed(seed);
293 }
294 
295 
296 // =====================================================================================
297 
298 
299 void cbl::random::CustomDistributionRandomNumbers::set_custom_distribution (const distribution_func func, const shared_ptr<void> modelInput, const vector<double> pars)
300 {
301  m_func = func;
302  m_func_modelInput = modelInput;
303  m_func_parameter = pars;
304 
305  m_normalization = wrapper::gsl::GSL_integrate_qag(m_func, m_func_modelInput, m_func_parameter, m_MinVal, m_MaxVal);
306 }
307 
308 
309 // =====================================================================================
310 
311 
313 {
314  auto f = [this] (double xx) { return wrapper::gsl::GSL_integrate_qag(m_func, m_func_modelInput, m_func_parameter, m_MinVal, xx)/m_normalization; };
315  return wrapper::gsl::GSL_root_brent(f, m_uniform_generator->operator()(), m_MinVal, m_MaxVal);
316 }
317 
318 
Class functions used to generate random numbers.
The class FuncGrid.
Definition: FuncGrid.h:55
double integrate_qag(const double a, const double b, const double rel_err=1.e-2, const double abs_err=1.e-6, const int limit_size=1000, const int rule=6)
compute the definite integral with GSL qag method
Definition: FuncGrid.cpp:187
void set_seed(const int seed)
set the random number generator seed
CustomDistributionRandomNumbers(const distribution_func func, const std::shared_ptr< void > modelInput, const std::vector< double > parameter, const int seed, const double MinVal=par::defaultDouble, const double MaxVal=-par::defaultDouble)
constructor
double operator()()
extract number from the distribution
std::shared_ptr< UniformRandomNumbers > m_uniform_generator
Uniform random number generator.
void set_custom_distribution(const distribution_func func, const std::shared_ptr< void > modelInput, const std::vector< double > parameter)
set parameters for interpolated distribution
DiscreteRandomNumbers(const std::vector< double > values, const std::vector< double > weights, const int seed, const double MinVal=par::defaultDouble, const double MaxVal=-par::defaultDouble)
constructor
void set_discrete_values(const std::vector< double > values, const std::vector< double > weights)
set parameters for Discrete distribution
double operator()()
extract number from the distribution
DistributionRandomNumbers(const std::vector< double > xx, const std::vector< double > distribution_function, const std::string interpolation_method, const int seed)
constructor
std::shared_ptr< UniformRandomNumbers > m_uniform_generator
Uniform random number generator.
void set_seed(const int seed)
set the random number generator seed
double operator()()
extract number from the distribution
void set_interpolated_distribution(const std::vector< double > xx, const std::vector< double > distribution_function, const std::string interpolation_method)
set parameters for interpolated distribution
double operator()()
extract number from the distribution
void set_mean_sigma(const double mean, const double sigma)
set parameters for Normal distribution
NormalRandomNumbers(const double mean, const double sigma, const int seed, const double MinVal=par::defaultDouble, const double MaxVal=-par::defaultDouble)
constructor
void set_mean(const double mean)
set the mean for Poisson distribution
PoissonRandomNumbers(const double mean, const int seed, const double MinVal=par::defaultDouble, const double MaxVal=-par::defaultDouble)
constructor
double operator()()
extract number from the distribution
The class RandomNumbers.
Definition: RandomNumbers.h:78
void set_seed(const int seed)
set the random number generator seed
double m_MinVal
minimum value to generate
Definition: RandomNumbers.h:88
RandomNumbers()=default
default constructor
double m_MaxVal
maximum value to generate
Definition: RandomNumbers.h:91
void set_range(const double MinVal, const double MaxVal)
set the range for the random number extraction
UniformRandomNumbers_Int(double MinVal, const double MaxVal, const int seed)
constructor
double operator()()
extract number from the distribution
std::shared_ptr< std::uniform_int_distribution< int > > m_distribution
uniform distribution
std::shared_ptr< std::uniform_real_distribution< double > > m_distribution
uniform distribution
UniformRandomNumbers(double MinVal, const double MaxVal, const int seed)
constructor
double operator()()
extract number from the distribution
double GSL_root_brent(gsl_function Func, const double low_guess, const double up_guess, const double rel_err=1.e-3, const double abs_err=0)
function to find roots using GSL qag method
Definition: GSLwrapper.cpp:430
double GSL_integrate_qag(gsl_function Func, const double a, const double b, const double rel_err=1.e-3, const double abs_err=0, const int limit_size=1000, const int rule=6)
integral, computed using the GSL qag method
Definition: GSLwrapper.cpp:180
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
T Min(const std::vector< T > vect)
minimum element of a std::vector
Definition: Kernel.h:1324
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
Definition: Kernel.h:780
T Max(const std::vector< T > vect)
maximum element of a std::vector
Definition: Kernel.h:1336
std::function< double(double, std::shared_ptr< void >, std::vector< double >)> distribution_func
generic distribution function
Definition: RandomNumbers.h:50