10 #ifndef SRC_INCLUDE_SMASH_INTERPOLATION_H_
11 #define SRC_INCLUDE_SMASH_INTERPOLATION_H_
23 #include "gsl/gsl_errno.h"
24 #include "gsl/gsl_spline.h"
90 const std::vector<T>& x,
const std::vector<T>& y,
109 std::vector<InterpolateLinear<T>>
f_{};
114 template <
typename T>
117 slope_ = (y1 - y0) / (x1 - x0);
118 yintercept_ = y0 - slope_ * x0;
121 template <
typename T>
123 return slope_ * x + yintercept_;
137 template <
typename T,
typename Cmp>
140 std::iota(
p.begin(),
p.end(), 0);
141 std::sort(
p.begin(),
p.end(),
142 [&](
size_t i,
size_t j) { return compare(v[i], v[j]); });
154 template <
typename T>
157 std::vector<T> copied_v = v;
158 std::transform(
p.begin(),
p.end(), copied_v.begin(),
159 [&](
size_t i) { return v[i]; });
173 template <
typename T>
175 const std::string& error_position) {
176 auto it = std::adjacent_find(x.begin(), x.end());
178 std::stringstream error_msg{};
179 error_msg << error_position <<
": Each x value must be unique. \"" << *it
180 <<
"\" was found twice.";
181 throw std::runtime_error(error_msg.str());
185 template <
typename T>
187 const std::vector<T>& x,
const std::vector<T>& y,
189 : extrapolation_type_{extrapolation_type} {
197 throw std::invalid_argument(
198 "The provided extrapolation type is not supported. Valid types are "
199 "'None', 'Zero', 'Constant', and 'Linear'.");
201 if (x.size() != y.size()) {
202 throw std::invalid_argument(
203 "The interpolation requires two vectors of equal length.");
205 const size_t n = x.size();
207 x, [&](T
const& a, T
const& b) {
return a < b; });
212 for (
size_t i = 0; i <
n - 1; i++) {
236 template <
typename T>
238 const auto it = std::lower_bound(v.begin(), v.end(), x);
239 if (it == v.begin()) {
242 return it - 1 - v.begin();
246 template <
typename T>
248 const double first_x = x_.front();
249 const double last_x = x_.back();
250 if (x0 < first_x || x0 > last_x) {
252 std::ostringstream error_msg{
253 "InterpolateDataLinear only accepts x values within the range of the "
254 "underlying data\nwhen an extrapolation type is not specified. ",
256 error_msg <<
"x value " << x0 <<
" is out of bounds.";
257 throw std::out_of_range(error_msg.str());
261 return (x0 < first_x) ? f_.front()(first_x) : f_.back()(last_x);
263 return (x0 < first_x) ? f_.front()(x0) : f_.back()(x0);
296 const std::vector<double>& x,
const std::vector<double>& y,
326 gsl_interp_accel*
acc_ =
nullptr;
Represent a piecewise linear interpolation.
ExtrapolationType extrapolation_type_
Extrapolation type.
std::vector< InterpolateLinear< T > > f_
Piecewise linear interpolation using f(x_i)
T operator()(T x) const
Calculate linear interpolation at x.
InterpolateDataLinear(const std::vector< T > &x, const std::vector< T > &y, ExtrapolationType extrapolation_type=ExtrapolationType::None)
Interpolate function f given discrete samples f(x_i) = y_i.
Represent a cubic spline interpolation.
double first_x_
First x value of underlying data.
gsl_spline * spline_
GSL spline.
~InterpolateDataSpline()
Destructor.
double last_y_
Last y value of underlying data.
double operator()(double x) const
Calculate spline interpolation at x.
double first_y_
First y value of underlying data.
ExtrapolationType extrapolation_type_
Extrapolation type.
InterpolateDataSpline(const std::vector< double > &x, const std::vector< double > &y, ExtrapolationType extrapolation_type=ExtrapolationType::None)
Interpolate function f given discrete samples f(x_i) = y_i.
gsl_interp_accel * acc_
GSL iterator for interpolation lookups.
double last_x_
Last x value of underlying data.
Represent a linear interpolation.
T yintercept_
y-axis intercept of the linear interpolation.
T operator()(T x) const
Calculate linear interpolation at x.
T slope_
Slope of the linear interpolation.
InterpolateLinear(T x0, T y0, T x1, T y1)
Linear interpolation given two points (x0, y0) and (x1, y1).
Collection of useful constants that are known at compile time.
ExtrapolationType
Allows to specify the desired extrapolation type.
@ Linear
Extrapolate using a linear approach.
@ None
No extrapolation is done.
@ Constant
Extrapolate using a constant value.
@ Zero
Extrapolate with zero.
size_t find_index(const std::vector< T > &v, T x)
Find the index in v that corresponds to the last value strictly smaller than x.
std::vector< T > apply_permutation(const std::vector< T > &v, const Permutation &p)
Apply a permutation to a vector.
void check_duplicates(const std::vector< T > &x, const std::string &error_position)
Check whether two components have the same value in a sorted vector x.
Permutation generate_sort_permutation(std::vector< T > const &v, Cmp compare)
Calculate the permutations necessary for sorting a vector.
std::vector< size_t > Permutation
Represent a permutation.