CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
FuncGrid.cpp
Go to the documentation of this file.
1 /*******************************************************************
2  * Copyright (C) 2010 by Federico Marulli and Alfonso Veropalumbo *
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 "FuncGrid.h"
35 
36 using namespace std;
37 
38 using namespace cbl;
39 using namespace glob;
40 
41 
42 // ============================================================================
43 
44 
45 cbl::glob::FuncGrid::FuncGrid (const std::vector<double> x, const std::vector<double> y, const std::string interpType, const cbl::BinType bin_type)
46  : m_x(x), m_y(y), m_size(x.size()), m_interpType(interpType), m_binType(bin_type)
47 {
48  if (!is_sorted(x.begin(), x.end()))
49  ErrorCBL("the x array is not sorted!", "FuncGrid", "FuncGrid.cpp");
50 
51  shared_ptr<gsl_interp_accel> acc(gsl_interp_accel_alloc(), gsl_interp_accel_free);
52  m_acc = acc;
53 
54  if (m_size<5 && interpType!="Linear") {
55  WarningMsgCBL("the array size is less than 5 -> setting interpolation method to Linear!", "FuncGrid", "FuncGrid.cpp");
56  m_interpType = "Linear";
57  }
58 
59  if (m_interpType=="Linear")
60  m_type = gsl_interp_linear;
61 
62  else if (m_interpType=="Poly")
63  m_type = gsl_interp_polynomial;
64 
65  else if (m_interpType=="Spline")
66  m_type = gsl_interp_cspline;
67 
68  else if (m_interpType=="Spline_periodic")
69  m_type = gsl_interp_cspline_periodic;
70 
71  else if (m_interpType=="Akima")
72  m_type = gsl_interp_akima;
73 
74  else if (m_interpType=="Akima_periodic")
75  m_type = gsl_interp_akima_periodic;
76 
77  else if (m_interpType=="Steffen")
78  m_type = gsl_interp_steffen;
79 
80  else
81  ErrorCBL("the value of m_interpType is not permitted!", "FuncGrid", "FuncGrid.cpp");
82 
83  vector<double> xx, yy;
84 
86  xx = m_x;
87  yy = m_y;
88  }
90  for (size_t i=0; i<m_size; i++) {
91  xx.emplace_back(log10(m_x[i]));
92  yy.emplace_back(log10(m_y[i]));
93  }
94  }
95  else
96  ErrorCBL("the value of m_binType is not permitted!", "FuncGrid", "FuncGrid.cpp");
97 
98  m_xmin = Min(m_x);
99  m_xmax = Max(m_x);
100 
101  std::shared_ptr<gsl_spline> spline(gsl_spline_alloc(m_type, m_size), gsl_spline_free);
102  gsl_spline_init(spline.get(), xx.data(), yy.data(), m_size);
103  m_spline = spline;
104 }
105 
106 
107 // =====================================================================================
108 
109 
111 {
112  //gsl_spline_free(m_spline);
113  //gsl_interp_accel_free(m_acc);
114 }
115 
116 
117 // =====================================================================================
118 
119 
120 double cbl::glob::FuncGrid::operator () (const double xx) const
121 {
122  const double _xx = (m_binType==cbl::BinType::_logarithmic_) ? log10(xx) : xx;
123 
124  double val = -1.;
125 
126  if (xx<m_xmin) { // perform a linear extrapolation
127  val = m_spline.get()->y[0]+(_xx-m_spline.get()->x[0])/(m_spline.get()->x[1]-m_spline.get()->x[0])*(m_spline.get()->y[1]-m_spline.get()->y[0]);
128  val = (m_binType==cbl::BinType::_logarithmic_) ? pow(10, val) : val;
129  if (val!=val) return ErrorCBL("inside the xx<m_xmin condition, the return value is nan!", "operator ()", "FuncGrid.cpp");
130  else return val;
131  }
132 
133  else if (xx>m_xmax) { // perform a linear extrapolation
134  val = m_spline.get()->y[m_size-2]+(_xx-m_spline.get()->x[m_size-2])/(m_spline.get()->x[m_size-1]-m_spline.get()->x[m_size-2])*(m_spline.get()->y[m_size-1]-m_spline.get()->y[m_size-2]);
135  val = (m_binType==cbl::BinType::_logarithmic_) ? pow(10, val) : val;
136  if (val!=val) return ErrorCBL("inside the xx>m_xmax condition, the return value is nan!", "operator ()", "FuncGrid.cpp");
137  else return val;
138  }
139 
140  // performe an interpolation
141  else {
142  val = (m_binType==cbl::BinType::_logarithmic_) ? pow(10., gsl_spline_eval(m_spline.get(), _xx, m_acc.get())) : gsl_spline_eval(m_spline.get(), _xx, m_acc.get());
143  if (val!=val) coutCBL << "xx = " << conv(_xx, par::fDP3) << endl;
144  if (val!=val) return ErrorCBL("the return value is nan!", "operator ()", "FuncGrid.cpp");
145  else return val;
146  }
147 }
148 
149 
150 // =====================================================================================
151 
152 
153 std::vector<double> cbl::glob::FuncGrid::eval_func (const std::vector<double> xx) const
154 {
155  vector<double> yy;
156 
157  for (size_t i=0; i<xx.size(); i++)
158  yy.push_back(this->operator()(xx[i]));
159 
160  return yy;
161 }
162 
163 
164 // =====================================================================================
165 
166 
167 double cbl::glob::FuncGrid::D1v (const double xx) const
168 {
169  double D1 = gsl_spline_eval_deriv(m_spline.get(), xx, m_acc.get());
170 
171  return ((m_binType==cbl::BinType::_logarithmic_) ? xx*D1/this->operator()(xx): D1);
172 }
173 
174 
175 // =====================================================================================
176 
177 
178 double cbl::glob::FuncGrid::D2v (const double xx) const
179 {
180  return gsl_spline_eval_deriv2(m_spline.get(), xx, m_acc.get());
181 }
182 
183 
184 // =====================================================================================
185 
186 
187 double cbl::glob::FuncGrid::integrate_qag (const double a, const double b, const double rel_err, const double abs_err, const int limit_size, const int rule)
188 {
189  function<double(double)> f = bind(&FuncGrid::operator(), this, std::placeholders::_1);
190 
191  return wrapper::gsl::GSL_integrate_qag(f, a, b, rel_err, abs_err, limit_size, rule);
192 }
193 
194 
195 // =====================================================================================
196 
197 
198 double cbl::glob::FuncGrid::integrate_cquad (const double a, const double b, const double rel_err, const double abs_err, const int neval)
199 {
200  function<double(double)> f = bind(&FuncGrid::operator(), this, std::placeholders::_1);
201 
202  return wrapper::gsl::GSL_integrate_cquad(f, a, b, rel_err, abs_err, neval);
203 }
204 
205 
206 // =====================================================================================
207 
208 
209 double cbl::glob::FuncGrid::integrate_qaws (const double a, const double b, const double alpha, const double beta, const int mu, const int nu, const double rel_err, const double abs_err, const int limit_size)
210 {
211  function<double(double)> f = bind(&FuncGrid::operator(), this, std::placeholders::_1);
212 
213  return wrapper::gsl::GSL_integrate_qaws(f, a, b, alpha, beta, mu, nu, rel_err, abs_err, limit_size);
214 }
215 
216 
217 // =====================================================================================
218 
219 
220 double cbl::glob::FuncGrid::root (const double x_low, const double x_up, const double fx0, const double rel_err, const double abs_err)
221 {
222  function<double(double)> f = bind(&FuncGrid::operator(), this, std::placeholders::_1);
223 
224  return wrapper::gsl::GSL_root_brent(f, fx0, x_low, x_up, rel_err, abs_err);
225 }
226 
227 
228 // =====================================================================================
229 
230 
231 double cbl::glob::FuncGrid::root_D1v (const double x_low, const double x_up, const double fx0, const double rel_err, const double abs_err)
232 {
233  function<double(double)> f = bind(&FuncGrid::D1v, this, std::placeholders::_1);
234 
235  return wrapper::gsl::GSL_root_brent(f, fx0, x_low, x_up, rel_err, abs_err);
236 }
237 
238 
239 // =====================================================================================
240 
241 
242 double cbl::glob::FuncGrid::root_D2v (const double x_low, const double x_up, const double fx0, const double rel_err, const double abs_err)
243 {
244  function<double(double)> f = bind(&FuncGrid::D2v, this, std::placeholders::_1);
245 
246  return wrapper::gsl::GSL_root_brent(f, fx0, x_low, x_up, rel_err, abs_err);
247 }
248 
249 
250 // =====================================================================================
251 
252 
253 cbl::glob::FuncGrid2D::FuncGrid2D (const std::vector<double> x, const std::vector<double> y, const std::vector<std::vector<double>> fxy, const std::string interpType)
254 {
255  if(!is_sorted(x.begin(), x.end()))
256  ErrorCBL("the x array is not sorted!", "FuncGrid2D", "FuncGrid.cpp");
257  if(!is_sorted(y.begin(), y.end()))
258  ErrorCBL("the y array is not sorted!", "FuncGrid2D", "FuncGrid.cpp");
259 
260  // set internal variables
261  m_x = x;
262 
263  m_size_x = m_x.size();
264  m_xmin = Min(m_x);
265  m_xmax = Max(m_x);
266 
267  m_y = y;
268  m_size_y = m_y.size();
269  m_ymin = Min(m_y);
270  m_ymax = Max(m_y);
271 
272  std::shared_ptr<double> grid( new double[m_size_x*m_size_y], []( double *p ) { delete[] p; });
273 
274  for (size_t i=0; i<m_size_x; i++)
275  for (size_t j=0; j<m_size_y; j++)
276  grid.get()[i+j*m_size_x] = fxy[i][j];
277 
278  m_fxy = grid;
279 
280  m_interpType = interpType;
281 
282  if (m_interpType=="Linear")
283  m_type = gsl_interp2d_bilinear;
284 
285  else if (m_interpType=="Cubic")
286  m_type = gsl_interp2d_bicubic;
287 
288  else
289  ErrorCBL("the value of m_interpType is not permitted!", "FuncGrid2D", "FuncGrid.cpp");
290 
291  shared_ptr<gsl_interp_accel> acc_x(gsl_interp_accel_alloc(), gsl_interp_accel_free);
292  shared_ptr<gsl_interp_accel> acc_y(gsl_interp_accel_alloc(), gsl_interp_accel_free);
293  m_acc_x = acc_x;
294  m_acc_y = acc_y;
295 
296  shared_ptr<gsl_spline2d> spline(gsl_spline2d_alloc(m_type, m_size_x, m_size_y), gsl_spline2d_free);
297  gsl_spline2d_init(spline.get(), m_x.data(), m_y.data(), m_fxy.get(), m_size_x, m_size_y);
298  m_spline = spline;
299 }
300 
301 
302 // =====================================================================================
303 
304 
306 {
307  /*
308  gsl_interp2d_free(m_interp);
309  gsl_interp_accel_free(m_acc_x);
310  gsl_interp_accel_free(m_acc_y);
311  std::free(m_fxy);
312  */
313 }
314 
315 
316 // =====================================================================================
317 
318 
319 double cbl::glob::FuncGrid2D::operator () (const double xx, const double yy) const
320 {
321  bool extr = false;
322  if ((xx>m_xmax || xx<m_xmin) ||(yy>m_ymax || yy<m_ymin))
323  extr = true;
324 
325  double val;
326 
327  if (extr)
328  ErrorCBL("Point ("+conv(xx, par::fDP2)+", "+conv(yy, par::fDP2)+") is outside the interpolation range...", "operator ()", "FuncGrid.cpp", glob::ExitCode::_workInProgress_);
329 
330  else
331  val = gsl_spline2d_eval(m_spline.get(), xx, yy, m_acc_x.get(), m_acc_y.get());
332 
333  return val;
334 
335 }
336 
337 
338 // =====================================================================================
339 
340 
341 std::vector<double> cbl::glob::FuncGrid2D::eval_func (const std::vector<std::vector<double>> xx) const
342 {
343  vector<double> yy;
344 
345  for (size_t i=0; i<xx.size(); i++)
346  yy.push_back(this->operator()(xx[i][0], xx[i][1]));
347 
348  return yy;
349 }
350 
351 
352 // =====================================================================================
353 
354 
355 double cbl::glob::FuncGrid2D::IntegrateVegas (const double xmin, const double xmax, const double ymin, const double ymax) const
356 {
357  auto integrand = [&] (const vector<double> var)
358  {
359  return this->operator()(var[0], var[1]);
360  };
361 
362  wrapper::cuba::CUBAwrapper cuba_integral(integrand, 2);
363 
364  return cuba_integral.IntegrateVegas({{xmin, xmax}, {ymin, ymax}});
365 }
366 
367 
368 // =====================================================================================
369 
370 
371 double cbl::glob::FuncGrid2D::IntegrateSuave (const double xmin, const double xmax, const double ymin, const double ymax) const
372 {
373  auto integrand = [&] (const vector<double> var)
374  {
375  return this->operator()(var[0], var[1]);
376  };
377 
378  wrapper::cuba::CUBAwrapper cuba_integral(integrand, 2);
379 
380  return cuba_integral.IntegrateSuave({{xmin, xmax}, {ymin, ymax}});
381 }
382 
383 
384 // =====================================================================================
385 
386 
387 double cbl::glob::FuncGrid2D::IntegrateDivonne (const double xmin, const double xmax, const double ymin, const double ymax) const
388 {
389  auto integrand = [&] (const vector<double> var)
390  {
391  return this->operator()(var[0], var[1]);
392  };
393 
394  wrapper::cuba::CUBAwrapper cuba_integral(integrand, 2);
395 
396  return cuba_integral.IntegrateDivonne({{xmin, xmax}, {ymin, ymax}});
397 }
398 
399 
400 // =====================================================================================
401 
402 
403 double cbl::glob::FuncGrid2D::IntegrateCuhre (const double xmin, const double xmax, const double ymin, const double ymax) const
404 {
405  auto integrand = [&] (const vector<double> var)
406  {
407  return this->operator()(var[0], var[1]);
408  };
409 
410  wrapper::cuba::CUBAwrapper cuba_integral(integrand, 2);
411 
412  return cuba_integral.IntegrateCuhre ({{xmin, xmax}, {ymin, ymax}});
413 }
Class used to handle functions stored on a grid.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
double IntegrateSuave(const double xmin, const double xmax, const double ymin, const double ymax) const
evaluate the 2D integral of the interpolated function using the Suave routine from CUBA libraries
Definition: FuncGrid.cpp:371
FuncGrid2D()=default
default constructor
double operator()(const double xx, const double yy) const
overloading of the () operator
Definition: FuncGrid.cpp:319
double IntegrateCuhre(const double xmin, const double xmax, const double ymin, const double ymax) const
evaluate the 2D integral of the interpolated function using the Cuhre routine from CUBA libraries
Definition: FuncGrid.cpp:403
void free()
free the GSL objects
Definition: FuncGrid.cpp:305
double IntegrateVegas(const double xmin, const double xmax, const double ymin, const double ymax) const
evaluate the 2D integral of the interpolated function using the Vegas routine from CUBA libraries
Definition: FuncGrid.cpp:355
double IntegrateDivonne(const double xmin, const double xmax, const double ymin, const double ymax) const
evaluate the 2D integral of the interpolated function using the Divonne routine from CUBA libraries
Definition: FuncGrid.cpp:387
std::vector< double > eval_func(const std::vector< std::vector< double >> xx) const
evaluate the function at the xx points
Definition: FuncGrid.cpp:341
BinType m_binType
bin type
Definition: FuncGrid.h:87
std::vector< double > m_y
y values
Definition: FuncGrid.h:63
const gsl_interp_type * m_type
GSL object used to set the interpolation type.
Definition: FuncGrid.h:75
void free()
free the GSL objects
Definition: FuncGrid.cpp:110
std::shared_ptr< gsl_spline > m_spline
GSL object used to interpolate.
Definition: FuncGrid.h:72
std::vector< double > eval_func(const std::vector< double > xx) const
evaluate the function at the xx points
Definition: FuncGrid.cpp:153
double integrate_cquad(const double a, const double b, const double rel_err=1.e-2, const double abs_err=1.e-6, const int nevals=100)
compute the definite integral with GSL cquad method
Definition: FuncGrid.cpp:198
double integrate_qaws(const double a, const double b, const double alpha=0, const double beta=0, const int mu=0, const int nu=0, const double rel_err=1.e-2, const double abs_err=1.e-6, const int limit_size=1000)
compute the definite integral with GSL qaws method
Definition: FuncGrid.cpp:209
double root(const double x_low, const double x_up, const double fx0=0, const double rel_err=1.e-2, const double abs_err=1.e-6)
find roots with GSL brent method
Definition: FuncGrid.cpp:220
double m_xmax
maximum x value
Definition: FuncGrid.h:84
double D2v(const double xx) const
compute the second derivative at xx
Definition: FuncGrid.cpp:178
double operator()(const double xx) const
overloading of the () operator
Definition: FuncGrid.cpp:120
std::shared_ptr< gsl_interp_accel > m_acc
GSL accelerator object.
Definition: FuncGrid.h:78
double D1v(const double xx) const
compute the first derivative at xx
Definition: FuncGrid.cpp:167
size_t m_size
size of the x,y vectors, i.e. the grid size
Definition: FuncGrid.h:66
double root_D1v(const double x_low, const double x_up, const double fx0=0, const double rel_err=1.e-2, const double abs_err=1.e-6)
find roots with GSL brent method for the first derivative
Definition: FuncGrid.cpp:231
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
double root_D2v(const double x_low, const double x_up, const double fx0=0, const double rel_err=1.e-2, const double abs_err=1.e-6)
find roots with GSL brent method for the second derivative
Definition: FuncGrid.cpp:242
std::vector< double > x() const
get the private member FuncGrid::m_x
Definition: FuncGrid.h:131
FuncGrid()=default
default constructor
double m_xmin
minimum x value
Definition: FuncGrid.h:81
std::string m_interpType
method used to interpolate
Definition: FuncGrid.h:69
std::vector< double > m_x
x values
Definition: FuncGrid.h:60
The class CUBAwrapper.
Definition: CUBAwrapper.h:187
double IntegrateSuave(std::vector< std::vector< double >> integration_limits, const bool parallelize=true)
integrate using the Suave routine
double IntegrateDivonne(std::vector< std::vector< double >> integration_limits, const bool parallelize=true)
integrate using the Divonne routine
double IntegrateCuhre(std::vector< std::vector< double >> integration_limits, const bool parallelize=true)
integrate using the Cuhre routine
double IntegrateVegas(std::vector< std::vector< double >> integration_limits, const bool parallelize=true)
integrate using the Vegas routine
static const char fDP2[]
conversion symbol for: double -> std::string
Definition: Constants.h:133
static const char fDP3[]
conversion symbol for: double -> std::string
Definition: Constants.h:136
static const double alpha
: the fine-structure constant
Definition: Constants.h:233
@ _workInProgress_
error due to work in progress
double GSL_integrate_cquad(gsl_function func, const double a, const double b, const double rel_err=1.e-3, const double abs_err=0, const int nevals=100)
integral, using the gsl cquad method
Definition: GSLwrapper.cpp:159
double GSL_integrate_qaws(gsl_function Func, const double a, const double b, const double alpha=0, const double beta=0, const int mu=1, const int nu=0, const double rel_err=1.e-3, const double abs_err=0, const int limit_size=1000)
integral, computed using the GSL qaws method
Definition: GSLwrapper.cpp:240
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
std::string conv(const T val, const char *fact)
convert a number to a std::string
Definition: Kernel.h:903
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
BinType
the binning type
Definition: Kernel.h:505
@ _logarithmic_
logarithmic binning
@ _linear_
linear binning
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747