32#include "boost/format.hpp"
34#include "gsl/gsl_errno.h"
35#include "gsl/gsl_interp.h"
47 if (
x.size() !=
y.size()) {
49 pex::exceptions::InvalidParameterError,
50 str(boost::format(
"Dimensions of x and y must match; %ul != %ul") %
x.size() %
y.size()));
54 throw LSST_EXCEPT(pex::exceptions::OutOfRangeError,
"You must provide at least 1 point");
55 }
else if (len == 1) {
62 recentered_x[0] = 0.5 * (3 *
x[0] -
x[1]);
63 recentered_y[0] =
y[0];
65 for (
std::size_t i = 0, j = 1; i < len - 1; ++i, ++j) {
66 recentered_x[j] = 0.5 * (
x[i] +
x[i + 1]);
67 recentered_y[j] = 0.5 * (
y[i] +
y[i + 1]);
69 recentered_x[len] = 0.5 * (3 *
x[len - 1] -
x[len - 2]);
70 recentered_y[len] =
y[len - 1];
104 if (xInterp < *_old) {
110 if (_old <
_x.
end() - 1 and xInterp < *(_old + 1)) {
118 if (low == _old && _old !=
_x.
begin()) {
125 if (low ==
_x.
end()) {
127 }
else if (low ==
_x.
begin()) {
144 "CONSTANT interpolation not supported.");
146 return ::gsl_interp_linear;
148 return ::gsl_interp_cspline;
150 return ::gsl_interp_cspline;
152 return ::gsl_interp_cspline_periodic;
154 return ::gsl_interp_akima;
156 return ::gsl_interp_akima_periodic;
159 "I am unable to make an interpolator of type UNKNOWN");
162 str(boost::format(
"You can't get here: style == %") % style));
166 str(boost::format(
"You can't get here: style == %") % style));
183 ::gsl_interp_type
const *_interpType;
184 ::gsl_interp_accel *_acc;
185 ::gsl_interp *_interp;
192 :
Interpolate(
x,
y), _interpType(styleToGslInterpType(style)) {
194 ::gsl_set_error_handler_off();
196 _acc = ::gsl_interp_accel_alloc();
201 _interp = ::gsl_interp_alloc(_interpType,
_y.
size());
204 str(boost::format(
"Failed to initialise spline for type %s, length %d") %
205 _interpType->name %
_y.
size()));
211 int const status = ::gsl_interp_init(_interp, &
x[0], &
y[0],
_y.
size());
215 str(boost::format(
"gsl_interp_init failed: %s [%d]") % ::gsl_strerror(status) % status));
220 ::gsl_interp_free(_interp);
221 ::gsl_interp_accel_free(_acc);
251 double d = ::gsl_interp_eval_deriv(_interp, &
_x[0], &
_y[0], x0, _acc);
253 double d2 = ::gsl_interp_eval_deriv2(_interp, &
_x[0], &
_y[0], x0, _acc);
254 return y0 + (xInterp - x0) * d + 0.5 * (xInterp - x0) * (xInterp - x0) * d2;
257 assert(xInterp <=
_x.
back());
258 return ::gsl_interp_eval(_interp, &
_x[0], &
_y[0], xInterp, _acc);
263 if (gslInterpTypeStrings.
empty()) {
273 if (gslInterpTypeStrings.
find(style) == gslInterpTypeStrings.
end()) {
276 return gslInterpTypeStrings[style];
286 if (styles.
empty()) {
300 size_t const num =
x.size();
302 for (
size_t i = 0; i < num; ++i) {
309 int const num =
x.getShape()[0];
310 ndarray::Array<double, 1> out = ndarray::allocate(ndarray::makeVector(num));
311 for (
int i = 0; i < num; ++i) {
320 if (minPoints.
empty()) {
332 return minPoints[style];
343 : _x(xy.first), _y(xy.second), _style(style) {
358 ndarray::Array<double const, 1>
const &
y,
#define LSST_EXCEPT(type,...)
Create an exception with a given 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
Reports invalid arguments.
Reports errors in the logical structure of the program.
Reports attempts to access elements outside a valid range of indices.
Reports errors that are due to events beyond the control of the program.
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.