31 #include "boost/format.hpp"
33 #include "gsl/gsl_errno.h"
34 #include "gsl/gsl_interp.h"
35 #include "gsl/gsl_spline.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);
247 double d = ::gsl_interp_eval_deriv(_interp, &
_x[0], &
_y[0], x0, _acc);
249 double d2 = ::gsl_interp_eval_deriv2(_interp, &
_x[0], &
_y[0], x0, _acc);
250 return y0 + (xInterp - x0) * d + 0.5 * (xInterp - x0) * (xInterp - x0) * d2;
253 assert(xInterp <=
_x.
back());
254 return ::gsl_interp_eval(_interp, &
_x[0], &
_y[0], xInterp, _acc);
259 if (gslInterpTypeStrings.
empty()) {
269 if (gslInterpTypeStrings.
find(style) == gslInterpTypeStrings.
end()) {
272 return gslInterpTypeStrings[style];
282 if (styles.
empty()) {
296 size_t const num =
x.size();
298 for (
size_t i = 0; i < num; ++i) {
305 int const num =
x.getShape()[0];
306 ndarray::Array<double, 1> out = ndarray::allocate(ndarray::makeVector(num));
307 for (
int i = 0; i < num; ++i) {
316 if (minPoints.
empty()) {
328 return minPoints[style];
354 ndarray::Array<double const, 1>
const &
y,