mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
gslInterpolator.hpp
Go to the documentation of this file.
1 /** \file gslInterpolator.hpp
2  * \brief Class for managing 1-D interpolation using the GNU Scientific Library
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup gen_math_files
7  *
8  */
9 
10 //***********************************************************************//
11 // Copyright 2015-2022 Jared R. Males (jaredmales@gmail.com)
12 //
13 // This file is part of mxlib.
14 //
15 // mxlib is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // mxlib is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
27 //***********************************************************************//
28 
29 #ifndef gslInterpolator_hpp
30 #define gslInterpolator_hpp
31 
32 #include <vector>
33 #include <gsl/gsl_interp.h>
34 #include <gsl/gsl_errno.h>
35 
36 #include "../mxException.hpp"
37 
38 namespace mx
39 {
40 namespace math
41 {
42 
43 /// GSL Linear Interpolation
44 /** \ingroup interpolation
45  */
46 template<typename _realT>
48 {
49  typedef _realT realT;
50 
51  static const gsl_interp_type * interpolator()
52  {
53  return ::gsl_interp_linear;
54  }
55 };
56 
57 #ifndef MX_OLD_GSL
58 /// GSL Steffen Interpolation
59 /** \ingroup interpolation
60  */
61 template<typename _realT>
63 {
64  typedef _realT realT;
65 
66  static const gsl_interp_type * interpolator()
67  {
68  return ::gsl_interp_steffen;
69  }
70 };
71 #endif
72 
73 /// Class to manage interpolation using the GSL interpolation library.
74 /**
75  *
76  * \tparam interpT is the interpolation type, which also specifies the floating point precision.
77  *
78  * \ingroup interpolation
79  */
80 template<typename interpT>
82 {
83 public:
84  typedef typename interpT::realT realT;
85 
86  static_assert( std::is_same<double, typename std::remove_cv<realT>::type>::value, "GSL Interpolation only works with double");
87 
88 protected:
89 
90  gsl_interp * m_interp {nullptr}; ///< the gsl interpolator structure
91  gsl_interp_accel * m_acc {nullptr}; ///< the gsl interpolation accelerator structure
92 
93  realT *m_xin; ///< the input x data
94  realT *m_yin; ///< the input y data
95 
96 public:
97 
98  /// Default constructor
100 
101  /// Raw pointer constructor
102  gslInterpolator( realT *xin, ///< [in] the input x data, this pointer is stored and must remain valid
103  realT *yin, ///< [in] the input y data, this pointer is stored and must remain valid
104  size_t Nin ///< [in] the size of data vectors
105  );
106 
107  /// Vector constructor
108  gslInterpolator( std::vector<realT> & xin, ///< [in] the input x data, the pointer to xin.data() is stored and xin must remain unchanged
109  std::vector<realT> & yin ///< [in] the input y data, the pointer to yin.data() is stored and yin must remain unchanged
110  );
111 
112  /// Destructor
113  /** Deallocates working memory.
114  */
116 
117  /// Setup the interpolator for the supplied data pointers
118  /**
119  * \throws mx::err::allocerr if allocation fails
120  * \throws mx::err::liberr if GSL initialization fails
121  */
122  void setup( realT *xin, ///< [in] the input x data, this pointer is stored and must remain valid
123  realT *yin, ///< [in] the input y data, this pointer is stored and must remain valid
124  size_t Nin ///< [in] the size of data vectors
125  );
126 
127  /// Setup the interpolator for the supplied data vectors
128  /**
129  * \throws mx::err::sizeerr if the vectors are not the same size
130  * \throws mx::err::allocerr if allocation fails
131  * \throws mx::err::liberr if GSL initialization fails
132  */
133  void setup( std::vector<realT> & xin, ///< [in] the input x data, the pointer to xin.data() is stored and xin must remain unchanged
134  std::vector<realT> & yin ///< [in] the input y data, the pointer to yin.data() is stored and yin must remain unchanged
135  );
136 
137  /// Calculate the interpolated function value at a point
138  /**
139  * \returns the interpolated value at \p x
140  */
141  realT operator()( const realT & x /**< [in] the point at which to interpolate */ );
142 
143 };
144 
145 template<typename interpT>
147 {
148 }
149 
150 template<typename interpT>
152  realT *yin,
153  size_t Nin
154  )
155 {
156  setup(xin,yin,Nin);
157 }
158 
159 template<typename interpT>
160 gslInterpolator<interpT>::gslInterpolator( std::vector<realT> & xin,
161  std::vector<realT> & yin
162  )
163 {
164  setup(xin.data(), yin.data(), xin.size());
165 }
166 
167 template<typename interpT>
169 {
170  if(m_interp != nullptr) gsl_interp_free(m_interp);
171  if(m_acc != nullptr) gsl_interp_accel_free (m_acc);
172 }
173 
174 template<typename interpT>
176  realT *yin,
177  size_t Nin
178  )
179 {
180  if(m_interp != nullptr) gsl_interp_free(m_interp);
181  if(m_acc != nullptr) gsl_interp_accel_free(m_acc);
182 
183  m_interp = gsl_interp_alloc(interpT::interpolator(), Nin);
184  if(!m_interp) mxThrowException(err::allocerr, "gslInterpolation::setup", "gsl_interp_alloc failed");
185 
186  m_acc = gsl_interp_accel_alloc ();
187  if(!m_acc) mxThrowException(err::allocerr, "gslInterpolation::setup", "gsl_interp_accel_alloc failed");
188 
189 
190  int errv = gsl_interp_init(m_interp, xin, yin, Nin);
191 
192  if(errv != 0)
193  {
194  mxThrowException(err::liberr, "gslInterpolation::setup", std::string("gsl_interp_init failed: ") + gsl_strerror(errv));
195  }
196  errv = gsl_interp_accel_reset(m_acc);
197 
198  if(errv != 0)
199  {
200  mxThrowException(err::liberr, "gslInterpolation::setup", std::string("gsl_interp_accel_reset failed: ") + gsl_strerror(errv));
201  }
202  m_xin = xin;
203  m_yin = yin;
204 }
205 
206 template<typename interpT>
207 void gslInterpolator<interpT>::setup( std::vector<realT> & xin,
208  std::vector<realT> & yin
209  )
210 {
211  if(xin.size() != yin.size())
212  {
213  mxThrowException(err::sizeerr, "gslInterpolator<interpT>::setup", "input vectors must be the same size");
214  }
215  setup(xin.data(), yin.data(), xin.size());
216 }
217 
218 template<typename interpT>
219 typename interpT::realT gslInterpolator<interpT>::operator()(const realT & x)
220 {
221  realT y;
222  int errv = gsl_interp_eval_e (m_interp, m_xin, m_yin, x, m_acc, &y);
223  if(errv != 0 && errv != GSL_EDOM)
224  {
225  mxThrowException(err::liberr, "gslInterpolation::setup", "gsl_interp_eval_e failed");
226  }
227  return y;
228 }
229 
230 
231 
232 } //namespace math
233 } //namespace mx
234 
235 #endif //gslInterpolator_hpp
mxException for an allocation error
mxException for errors returned by a library call
mxException for a size error
Class to manage interpolation using the GSL interpolation library.
gslInterpolator(std::vector< realT > &xin, std::vector< realT > &yin)
Vector constructor.
gsl_interp_accel * m_acc
the gsl interpolation accelerator structure
void setup(std::vector< realT > &xin, std::vector< realT > &yin)
Setup the interpolator for the supplied data vectors.
realT * m_xin
the input x data
realT operator()(const realT &x)
Calculate the interpolated function value at a point.
gslInterpolator()
Default constructor.
gslInterpolator(realT *xin, realT *yin, size_t Nin)
Raw pointer constructor
gsl_interp * m_interp
the gsl interpolator structure
void setup(realT *xin, realT *yin, size_t Nin)
Setup the interpolator for the supplied data pointers.
realT * m_yin
the input y data
The mxlib c++ namespace.
Definition: mxError.hpp:107
GSL Linear Interpolation.
GSL Steffen Interpolation.