31#include "boost/format.hpp"
33#include "gsl/gsl_errno.h"
34#include "gsl/gsl_interp.h"
46 if (
x.size() !=
y.size()) {
48 pex::exceptions::InvalidParameterError,
49 str(boost::format(
"Dimensions of x and y must match; %ul != %ul") %
x.size() %
y.size()));
53 throw LSST_EXCEPT(pex::exceptions::OutOfRangeError,
"You must provide at least 1 point");
54 }
else if (len == 1) {
61 recentered_x[0] = 0.5 * (3 *
x[0] -
x[1]);
62 recentered_y[0] =
y[0];
64 for (
std::size_t i = 0, j = 1; i < len - 1; ++i, ++j) {
65 recentered_x[j] = 0.5 * (
x[i] +
x[i + 1]);
66 recentered_y[j] = 0.5 * (
y[i] +
y[i + 1]);
68 recentered_x[len] = 0.5 * (3 *
x[len - 1] -
x[len - 2]);
69 recentered_y[len] =
y[len - 1];
103 if (xInterp < *_old) {
109 if (_old <
_x.
end() - 1 and xInterp < *(_old + 1)) {
117 if (low == _old && _old !=
_x.
begin()) {
124 if (low ==
_x.
end()) {
126 }
else if (low ==
_x.
begin()) {
143 "CONSTANT interpolation not supported.");
145 return ::gsl_interp_linear;
147 return ::gsl_interp_cspline;
149 return ::gsl_interp_cspline;
151 return ::gsl_interp_cspline_periodic;
153 return ::gsl_interp_akima;
155 return ::gsl_interp_akima_periodic;
158 "I am unable to make an interpolator of type UNKNOWN");
161 str(boost::format(
"You can't get here: style == %") % style));
165 str(boost::format(
"You can't get here: style == %") % style));
182 ::gsl_interp_type
const *_interpType;
183 ::gsl_interp_accel *_acc;
184 ::gsl_interp *_interp;
191 :
Interpolate(
x,
y), _interpType(styleToGslInterpType(style)) {
193 ::gsl_set_error_handler_off();
195 _acc = ::gsl_interp_accel_alloc();
200 _interp = ::gsl_interp_alloc(_interpType,
_y.
size());
203 str(boost::format(
"Failed to initialise spline for type %s, length %d") %
204 _interpType->name %
_y.
size()));
210 int const status = ::gsl_interp_init(_interp, &
x[0], &
y[0],
_y.
size());
214 str(boost::format(
"gsl_interp_init failed: %s [%d]") % ::gsl_strerror(status) % status));
219 ::gsl_interp_free(_interp);
220 ::gsl_interp_accel_free(_acc);
246 double d = ::gsl_interp_eval_deriv(_interp, &
_x[0], &
_y[0], x0, _acc);
248 double d2 = ::gsl_interp_eval_deriv2(_interp, &
_x[0], &
_y[0], x0, _acc);
249 return y0 + (xInterp - x0) * d + 0.5 * (xInterp - x0) * (xInterp - x0) * d2;
252 assert(xInterp <=
_x.
back());
253 return ::gsl_interp_eval(_interp, &
_x[0], &
_y[0], xInterp, _acc);
258 if (gslInterpTypeStrings.
empty()) {
268 if (gslInterpTypeStrings.
find(style) == gslInterpTypeStrings.
end()) {
271 return gslInterpTypeStrings[style];
281 if (styles.
empty()) {
295 size_t const num =
x.size();
297 for (
size_t i = 0; i < num; ++i) {
304 int const num =
x.getShape()[0];
305 ndarray::Array<double, 1> out = ndarray::allocate(ndarray::makeVector(num));
306 for (
int i = 0; i < num; ++i) {
315 if (minPoints.
empty()) {
327 return minPoints[style];
353 ndarray::Array<double const, 1>
const &
y,
#define LSST_EXCEPT(type,...)
~InterpolateConstant() override=default
friend std::shared_ptr< Interpolate > makeInterpolate(std::vector< double > const &x, std::vector< double > const &y, Interpolate::Style const style)
A factory function to make Interpolate objects.
double interpolate(double const x) const override
friend std::shared_ptr< Interpolate > makeInterpolate(std::vector< double > const &x, std::vector< double > const &y, Interpolate::Style const style)
A factory function to make Interpolate objects.
~InterpolateGsl() override
double interpolate(double const x) const override
virtual double interpolate(double const x) const =0
std::vector< double > const _x
std::vector< double > const _y
Interpolate(Interpolate const &)=delete
Interpolate::Style lookupMaxInterpStyle(int const n)
Get the highest order Interpolation::Style available for 'n' points.
int lookupMinInterpPoints(Interpolate::Style const style)
Get the minimum number of points needed to use the requested interpolation style.
Interpolate::Style stringToInterpStyle(std::string const &style)
Conversion function to switch a string to an Interpolate::Style.
std::shared_ptr< Interpolate > makeInterpolate(std::vector< double > const &x, std::vector< double > const &y, Interpolate::Style const style=Interpolate::AKIMA_SPLINE)
A factory function to make Interpolate objects.