CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
FuncGrid_Bspline.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_Bspline.h"
35 
36 using namespace std;
37 
38 using namespace cbl;
39 using namespace glob;
40 
41 
42 // ============================================================================
43 
44 
45 cbl::glob::FuncGrid_Bspline::FuncGrid_Bspline (const std::vector<double> x, const std::vector<double> fx, const int nbreakpoints, const int order, const double frac, const double xmin, const double xmax)
46 {
47  this->set(x, fx, nbreakpoints, order, frac, xmin, xmax);
48 }
49 
50 
51 // ============================================================================
52 
53 
54 cbl::glob::FuncGrid_Bspline::FuncGrid_Bspline (const std::vector<double> x, const std::vector<double> fx, const std::vector<double> breakpoints, const int order, const double frac)
55 {
56  this->set(x, fx, breakpoints, order, frac);
57 }
58 
59 
60 // ============================================================================
61 
62 
63 void cbl::glob::FuncGrid_Bspline::m_set_bspline(const vector<double> x, const vector<double> fx, const int nbreakpoints, const int order)
64 {
65  m_x = x;
66  m_fx = fx;
67  m_order = order;
68  m_nbreakpoints = nbreakpoints;
69  m_ncoefficients = m_nbreakpoints-2+m_order;
70 
71  // Define gsl bspline workspace and vectors
72  shared_ptr<gsl_bspline_workspace> bspline(gsl_bspline_alloc(m_order, m_nbreakpoints), gsl_bspline_free);
73  shared_ptr<gsl_vector> Bcoeff(gsl_vector_alloc(m_ncoefficients), gsl_vector_free);
74  shared_ptr<gsl_vector> weights(gsl_vector_alloc(m_ncoefficients), gsl_vector_free);
75  shared_ptr<gsl_matrix> covariance(gsl_matrix_alloc(m_ncoefficients, m_ncoefficients), gsl_matrix_free);
76 
77  m_bspline = bspline;
78  m_Bcoeff = Bcoeff;
79  m_weights = weights;
80  m_covariance = covariance;
81 }
82 
83 // ============================================================================
84 
85 
86 void cbl::glob::FuncGrid_Bspline::m_set_knots (const double xmin, const double xmax)
87 {
88  gsl_bspline_knots_uniform((xmin!=par::defaultDouble) ? xmin : Min(m_x),
89  (xmax!=par::defaultDouble) ? xmax : Max(m_x),
90  m_bspline.get());
91 }
92 
93 
94 // ============================================================================
95 
96 
97 void cbl::glob::FuncGrid_Bspline::m_set_knots (const std::vector<double> breakpoints)
98 {
99  shared_ptr<gsl_vector> bp(gsl_vector_alloc(m_nbreakpoints), gsl_vector_free);
100 
101  for (int i=0; i<m_nbreakpoints; i++)
102  gsl_vector_set(bp.get(), i, breakpoints[i]);
103 
104  gsl_bspline_knots(bp.get(), m_bspline.get());
105 }
106 
107 
108 // ============================================================================
109 
110 
111 void cbl::glob::FuncGrid_Bspline::m_compute_func_integral ()
112 {
113  auto func = [&] (const double &xx) {return this->operator()(xx, par::defaultDouble);};
114 
115  m_integral = wrapper::gsl::GSL_integrate_qag(func, Min(m_x), Max(m_x));
116 }
117 
118 // ============================================================================
119 
120 
121 void cbl::glob::FuncGrid_Bspline::m_linear_fit(const double frac)
122 {
123  cout << "Computing basis spline coefficients" << endl;
124 
125  size_t n = m_x.size();
126 
127  // Put input points in gsl vectors
128  shared_ptr<gsl_vector> y(gsl_vector_alloc(n), gsl_vector_free);
129  shared_ptr<gsl_vector> w(gsl_vector_alloc(n), gsl_vector_free);
130 
131  for (size_t i=0; i<m_x.size(); i++) {
132  gsl_vector_set(y.get(), i, m_fx[i]);
133  gsl_vector_set(w.get(), i, (frac>0) ? pow(frac*m_fx[i], -2) : 1.); //check!!!
134  }
135 
136  // Construct the fit matrix X
137  shared_ptr<gsl_matrix> XX(gsl_matrix_alloc(n, m_ncoefficients), gsl_matrix_free);
138  for (size_t i = 0; i < n; ++i)
139  {
140  /* compute B_j(xi) for all j */
141  gsl_bspline_eval(m_x[i], m_Bcoeff.get(), m_bspline.get());
142  /* fill in row i of X */
143  for (int j = 0; j < m_ncoefficients; ++j)
144  gsl_matrix_set(XX.get(), i, j, gsl_vector_get(m_Bcoeff.get(), j));
145  }
146 
147  // Compute coefficients
148  double chisq;
149 
150  shared_ptr<gsl_multifit_linear_workspace> mw(gsl_multifit_linear_alloc(n, m_ncoefficients), gsl_multifit_linear_free);
151 
152  gsl_multifit_wlinear(XX.get(), w.get(), y.get(), m_weights.get(), m_covariance.get(), &chisq, mw.get());
153 
154  cout << "Done! Chi2/d.o.f. = " << chisq/(n-m_ncoefficients) << endl;
155 }
156 
157 
158 // ============================================================================
159 
160 
161 void cbl::glob::FuncGrid_Bspline::set (const std::vector<double> x, const std::vector<double> fx, const int nbreakpoints, const int order, const double frac, const double xmin, const double xmax)
162 {
163  this->m_set_bspline(x, fx, nbreakpoints, order);
164  this->m_set_knots(xmin, xmax);
165  this->m_linear_fit(frac);
166  this->m_compute_func_integral();
167 }
168 
169 
170 // ============================================================================
171 
172 
173 void cbl::glob::FuncGrid_Bspline::set (const std::vector<double> x, const std::vector<double> fx, const std::vector<double> breakpoints, const int order, const double frac)
174 {
175  this->m_set_bspline(x, fx, static_cast<int>(breakpoints.size()), order);
176  this->m_set_knots(breakpoints);
177  this->m_linear_fit(frac);
178  this->m_compute_func_integral();
179 }
180 
181 
182 // ============================================================================
183 
184 
185 double cbl::glob::FuncGrid_Bspline::operator () (const double xx, const double integral) const
186 {
187  double fx, fx_err;
188 
189  gsl_bspline_eval(xx, m_Bcoeff.get(), m_bspline.get());
190  gsl_multifit_linear_est(m_Bcoeff.get(), m_weights.get(), m_covariance.get(), &fx, &fx_err);
191 
192  return (integral!=par::defaultDouble) ? integral*fx/m_integral : fx;
193 }
194 
195 
196 // ============================================================================
197 
198 
199 vector<double> cbl::glob::FuncGrid_Bspline::eval_func (const vector<double> xx, const double integral) const
200 {
201  vector<double> vv(xx.size(), 0), yerr;
202 
203  for (size_t i=0; i<xx.size(); i++)
204  vv[i] = this->operator()(xx[i], integral);
205 
206  return vv;
207 }
Class used to handle functions interpolated using a basis spline http://mathworld....
static const double defaultDouble
default double value
Definition: Constants.h:348
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
T Max(const std::vector< T > vect)
maximum element of a std::vector
Definition: Kernel.h:1336