ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Interpolator.hpp
1 #pragma once
2 #include <cassert>
3 #include <gsl/gsl_errno.h>
4 #include <gsl/gsl_spline.h>
5 #include <gsl/gsl_version.h>
6 #include <iostream>
7 #include <map>
8 #include <vector>
9 
10 // This should make code work with old versions of GSL
11 #ifdef GSL_MAJOR_VERSION
12 #if GSL_MAJOR_VERSION == 1
13 #define GSL_VERSION_1
14 #endif
15 #endif
16 
19 namespace Interpolator {
20 
22 
55 enum class Method {
57  linear,
59  polynomial,
61  cspline,
65  akima,
69  steffen
70 };
71 
73 static const std::map<Method, const gsl_interp_type *> interp_method{
74  {Method::linear, gsl_interp_linear},
75  {Method::polynomial, gsl_interp_polynomial},
76  {Method::cspline, gsl_interp_cspline},
77  {Method::cspline_periodic, gsl_interp_cspline_periodic},
78  {Method::akima, gsl_interp_akima},
79  {Method::akima_periodic, gsl_interp_akima_periodic}
80 #ifndef GSL_VERSION_1
81  ,
82  {Method::steffen, gsl_interp_steffen}
83 #endif
84 };
85 
86 //==============================================================================
87 
89 
100 class Interp {
101 
102 private:
103  gsl_interp_accel *acc;
104  gsl_spline *spline;
105  double x0, xmax;
106 
107 public:
109  Interp(const std::vector<double> &x, const std::vector<double> &y,
110  Method method = Method::cspline)
111  : acc(gsl_interp_accel_alloc()),
112  spline(gsl_spline_alloc(interp_method.at(method), x.size())),
113  x0(x.front()),
114  xmax(x.back()) {
115  assert(x.size() == y.size() &&
116  "In Interp, input vectors x and y must have same size");
117  assert(x.size() >= gsl_interp_type_min_size(interp_method.at(method)) &&
118  "In Interp, certain interpolation methods require a minimum number "
119  "of points");
120  gsl_spline_init(spline, x.data(), y.data(), x.size());
121  }
122  ~Interp() {
123  gsl_spline_free(spline);
124  gsl_interp_accel_free(acc);
125  }
126  Interp(const Interpolator::Interp &) = delete;
127  Interp &operator=(const Interpolator::Interp &) = delete;
128 
130  double interp(double x) const {
131  if (x < x0 || x > xmax)
132  return 0.0;
133  else
134  return gsl_spline_eval(spline, x, acc);
135  }
136 
138  std::vector<double> interp(const std::vector<double> &x) const {
139  std::vector<double> y;
140  y.reserve(x.size());
141  for (auto xi : x)
142  y.push_back(interp(xi));
143  return y;
144  }
145 
147  double operator()(double x) const { return interp(x); }
148 
150  std::vector<double> operator()(const std::vector<double> &x) const {
151  return interp(x);
152  }
153 };
154 
155 //==============================================================================
156 
158 
162 inline std::vector<double> interpolate(const std::vector<double> &x_in,
163  const std::vector<double> &y_in,
164  const std::vector<double> &x_out,
165  Method method = Method::cspline) {
166  Interp i_func(x_in, y_in, method);
167  return i_func(x_out);
168 }
169 
170 //==============================================================================
171 
173 static constexpr bool has_steffen_method() {
174 #ifndef GSL_VERSION_1
175  return true;
176 #else
177  return false;
178 #endif
179 }
180 
181 } // namespace Interpolator
Performs interpolation using GSL (GNU Scientific Library)
Definition: Interpolator.hpp:100
std::vector< double > interp(const std::vector< double > &x) const
Evaluates interpolation function at set of points {x}. Does not extrapolate.
Definition: Interpolator.hpp:138
double interp(double x) const
Evaluates interpolation function at point x. Does not extrapolate.
Definition: Interpolator.hpp:130
double operator()(double x) const
Evaluates interpolation function at point x. Does not extrapolate.
Definition: Interpolator.hpp:147
Interp(const std::vector< double > &x, const std::vector< double > &y, Method method=Method::cspline)
x_in and y_in
Definition: Interpolator.hpp:109
std::vector< double > operator()(const std::vector< double > &x) const
Evaluates interpolation function at set of points {x}. Does not extrapolate.
Definition: Interpolator.hpp:150
Interpolates functions using cubic splines. Uses GSL: https://www.gnu.org/software/gsl/doc/html/inter...
Definition: Interpolator.hpp:19
Method
Method (type) of 1D Interpolation used.
Definition: Interpolator.hpp:55
@ polynomial
polynomial interpolation
@ akima_periodic
akima interpolation with periodic boundary condition
@ cspline_periodic
cubic b-spline interpolation with periodic boundary condition
@ linear
linear interpolation
@ cspline
cubic b-spline interpolation
@ steffen
steffen interpolation (ensure monotonicity between points). Only GSLv2+
@ akima
akima interpolation
std::vector< double > interpolate(const std::vector< double > &x_in, const std::vector< double > &y_in, const std::vector< double > &x_out, Method method=Method::cspline)
Performs interpolation using GSL (GNU Scientific Library)
Definition: Interpolator.hpp:162