27 #include <gsl/gsl_errno.h> 36 gsl_interp_accel* clone_gsl_interp_accel(
const gsl_interp_accel* original)
42 gsl_interp_accel* cloned = gsl_interp_accel_alloc();
45 cloned->cache = original->cache;
46 cloned->miss_count = original->miss_count;
47 cloned->hit_count = original->hit_count;
53 gsl_spline* clone_gsl_spline(
const gsl_spline* original)
59 const gsl_interp_type* t = original->interp->type;
60 const auto size = original->size;
62 gsl_spline* cloned = gsl_spline_alloc(t, size);
68 const auto old_handler = gsl_set_error_handler_off();
70 gsl_set_error_handler(old_handler);
73 const int error = gsl_spline_init(cloned, original->x, original->y, size);
76 gsl_spline_free(cloned);
94 const Eigen::VectorXd& y_old,
95 const Eigen::VectorXd& x_new)
97 const std::size_t nx = x_old.size();
98 const std::size_t ny = y_old.size();
101 throw Setup_error(
"initial x and y vectors have different lengths");
115 const Eigen::VectorXd& y_old,
int n_old,
116 const Eigen::VectorXd& x_new,
int n_new)
119 throw Setup_error(
"spline interpolation requires at least two points");
122 if (n_old > x_old.size() || n_old > y_old.size()) {
123 throw Setup_error(
"requested number of points exceeds given number");
126 if (n_new > x_new.size()) {
129 "requested number of evaluation points exceeds given number");
132 const auto handler = gsl_set_error_handler_off();
134 gsl_set_error_handler(handler);
137 gsl_interp_accel* acc = gsl_interp_accel_alloc();
141 "unable to allocate memory for spline interpolation");
145 gsl_interp_accel_free(acc);
148 gsl_spline* spline = gsl_spline_alloc(gsl_interp_cspline, n_old);
152 "unable to allocate memory for spline interpolation");
156 gsl_spline_free(spline);
159 int error = gsl_spline_init(spline, x_old.data(), y_old.data(), n_old);
164 Eigen::VectorXd y_new(Eigen::VectorXd::Zero(n_new));
165 for (
int i = 0; i < n_new; ++i) {
166 error = gsl_spline_eval_e(spline, x_new(i), acc, &y_new(i));
169 "unable to evaluate spline interpolant");
177 : accelerator(gsl_interp_accel_alloc())
180 throw Setup_error(
"GSL_interpolator::GSL_interpolator: " 181 "unable to allocate memory for interpolator");
191 throw Setup_error(
"GSL_interpolator::GSL_interpolator: " 192 "unable to allocate memory for interpolator");
197 throw Setup_error(
"GSL_interpolator::GSL_interpolator: " 198 "unable to allocate memory for interpolator");
204 if (&other ==
this) {
212 throw Setup_error(
"GSL_interpolator::GSL_interpolator: " 213 "unable to allocate memory for interpolator");
218 throw Setup_error(
"GSL_interpolator::GSL_interpolator: " 219 "unable to allocate memory for interpolator");
234 const Eigen::VectorXd& y)
236 const auto nx = x.size();
237 const auto ny = y.size();
240 throw Setup_error(
"GSL_interpolator::construct_interpolant: " 241 "number of x values does not match number of y values");
256 const Eigen::VectorXd& y,
260 const int min_n = gsl_interp_type_min_size(t);
263 const std::string name(t->name);
264 std::string msg(
"GSL_interpolator::construct_interpolant: " 265 "interpolation with interpolator '");
267 msg +=
"' requires at least " + std::to_string(min_n)
268 +
" points (" + std::to_string(n) +
" given";
272 if (n > x.size() || n > y.size()) {
273 throw Setup_error(
"GSL_interpolator::construct_interpolant: " 274 "requested number of points exceeds given number");
279 const int error = gsl_spline_init(
interpolant.get(), x.data(), y.data(), n);
281 throw Setup_error(
"GSL_interpolator::construct_interpolant: " 282 "unable to initialize interpolant");
295 const auto handler = gsl_set_error_handler_off();
297 gsl_set_error_handler(handler);
306 "unable to evaluate interpolant (" 307 + std::to_string(error) +
")");
322 const auto handler = gsl_set_error_handler_off();
324 gsl_set_error_handler(handler);
328 const int error = gsl_spline_eval_deriv_e(
interpolant.get(), x,
333 "unable to evaluate interpolant");
348 const auto handler = gsl_set_error_handler_off();
350 gsl_set_error_handler(handler);
354 const int error = gsl_spline_eval_deriv2_e(
interpolant.get(), x,
359 "unable to evaluate interpolant");
370 return gsl_interp_linear;
373 return gsl_interp_polynomial;
376 return gsl_interp_cspline;
379 return gsl_interp_cspline_periodic;
382 return gsl_interp_akima;
385 return gsl_interp_akima_periodic;
387 #ifdef GSL_MAJOR_VERSION 388 #if (GSL_MAJOR_VERSION >= 2) 389 case Interpolation_type::GSL_steffen: {
390 return gsl_interp_steffen;
395 throw Setup_error(
"GSL_interpolator::to_gsl_interp_type: " 396 "unrecognized interpolator type");
410 "unable to allocate memory for interpolator");
417 throw Setup_error(
"GSL_interpolator::evaluate_second_deriv_at: " 418 "interpolant not computed");
424 const double x_min =
interpolant.get()->interp->xmin;
425 const double x_max =
interpolant.get()->interp->xmax;
427 if (x < x_min || x > x_max) {
428 throw Domain_error(
"GSL_interpolator::check_within_bounds: " 429 "cannot interpolate outside of domain");
std::unique_ptr< gsl_interp_accel, GSL_accel_deleter > accelerator
std::unique_ptr< gsl_spline, GSL_spline_deleter > interpolant
Exception indicating function evaluation out of allowed domain.
void reset(Interpolation_type, int)
double evaluate_deriv_at(double) const
Evaluates derivative of computed interpolant at a point.
Exception indicating that memory allocation failed.
double evaluate_at(double) const
Evaluates computed interpolant at a point.
double evaluate_second_deriv_at(double) const
Evaluates second derivative of computed interpolant at a point.
void construct_interpolant(const Eigen::VectorXd &, const Eigen::VectorXd &)
Computes interpolant using given x and y values.
Eigen::VectorXd interpolate_f_at(const Eigen::VectorXd &x_old, const Eigen::VectorXd &y_old, const Eigen::VectorXd &x_new)
Computes interpolated function values at a new set of grid points.
constexpr RAII_guard< F > make_raii_guard(F f)
contains the definition of the GSL_interpolator class
void check_interpolant_computed() const
Interpolation_type interp_type
const gsl_interp_type * to_gsl_interp_type(Interpolation_type) const
Exception indicating general setup error.
void check_within_bounds(double) const
GSL_interpolator & operator=(const GSL_interpolator &)
Provides routines for carrying out 1D interpolation.
Exception indicating generic numerical error.