Mantid
Loading...
Searching...
No Matches
Spline.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2025 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
10#include <algorithm>
11#include <span>
12#include <vector>
13
14namespace Mantid::Kernel {
15
21template <typename X, typename Y> class Spline {
22 static_assert(std::is_floating_point<X>(), "Splines must have floating point X values");
23 static_assert(std::is_floating_point<Y>(), "Splines must have floating point Y values");
24
27 Spline(Spline const &) = delete;
28 Spline(Spline &&) = delete;
29 Spline &operator=(Spline const &) = delete;
30 Spline &operator=(Spline &&) = delete;
31
32public:
33 Spline(std::span<X const> x, std::span<Y const> y, gsl_interp_type const *type)
34 : m_spline(spline::make_spline<X, Y>(x, y, type)), m_acc(spline::make_interp_accel()) {}
35 virtual ~Spline() = default;
36 Y operator()(X const newX) const {
37 Y y;
38 int err = gsl_spline_eval_e(m_spline.get(), newX, m_acc.get(), &y);
39 if (err != GSL_SUCCESS) {
40 throw std::runtime_error("Failure in GSL spline interpolation at " + std::to_string(newX));
41 }
42 return y;
43 }
44 std::vector<Y> operator()(std::span<X const> newX) const {
45 std::vector<Y> newY;
46 newY.reserve(newX.size());
47 std::transform(newX.begin(), newX.end(), std::back_inserter(newY), [this](X const x) { return (*this)(x); });
48 return newY;
49 }
50 Y deriv(X const newX, unsigned int order = 1) const {
51 Y deriv;
52 int err = GSL_SUCCESS;
53 // evaluate up to the second derivative
54 if (order == 1) {
55 err = gsl_spline_eval_deriv_e(m_spline.get(), newX, m_acc.get(), &deriv);
56 } else if (order == 2) {
57 err = gsl_spline_eval_deriv2_e(m_spline.get(), newX, m_acc.get(), &deriv);
58 } else {
59 // for derivatives higher than 2, just return 0
60 deriv = 0;
61 }
62 if (err != GSL_SUCCESS) {
63 throw std::runtime_error("Failure in GSL spline derivative at " + std::to_string(newX));
64 }
65 return deriv;
66 }
67 std::vector<Y> deriv(std::span<X const> newX, unsigned int order = 1) const {
68 std::vector<Y> derivY;
69 derivY.reserve(newX.size());
70 std::transform(newX.begin(), newX.end(), std::back_inserter(derivY),
71 [this, order](X const x) { return this->deriv(x, order); });
72 return derivY;
73 }
74};
75
81template <typename X, typename Y> class CubicSpline : public Spline<X, Y> {
82public:
83 CubicSpline(std::span<X const> x, std::span<Y const> y) : Spline<X, Y>(x, y, gsl_interp_cspline) {}
84 static std::vector<Y> getSplinedYValues(std::span<X const> newX, std::span<X const> x, std::span<Y const> y) {
85 CubicSpline<X, Y> spline(x, y);
86 return spline(newX);
87 }
88};
89
95template <typename X, typename Y> class LinearSpline : public Spline<X, Y> {
96public:
97 LinearSpline(std::span<X const> x, std::span<Y const> y) : Spline<X, Y>(x, y, gsl_interp_linear) {}
98 static std::vector<Y> getSplinedYValues(std::span<X const> newX, std::span<X const> x, std::span<Y const> y) {
99 LinearSpline<X, Y> spline(x, y);
100 return spline(newX);
101 }
102};
103
104} // namespace Mantid::Kernel
Cubic spline interpolation using GSL.
Definition Spline.h:81
CubicSpline(std::span< X const > x, std::span< Y const > y)
Definition Spline.h:83
static std::vector< Y > getSplinedYValues(std::span< X const > newX, std::span< X const > x, std::span< Y const > y)
Definition Spline.h:84
Linear interpolation using GSL.
Definition Spline.h:95
LinearSpline(std::span< X const > x, std::span< Y const > y)
Definition Spline.h:97
static std::vector< Y > getSplinedYValues(std::span< X const > newX, std::span< X const > x, std::span< Y const > y)
Definition Spline.h:98
Generic spline interpolation base class.
Definition Spline.h:21
Spline & operator=(Spline &&)=delete
std::vector< Y > deriv(std::span< X const > newX, unsigned int order=1) const
Definition Spline.h:67
Y operator()(X const newX) const
Definition Spline.h:36
Spline(std::span< X const > x, std::span< Y const > y, gsl_interp_type const *type)
Definition Spline.h:33
spline::spline_uptr m_spline
Definition Spline.h:25
spline::accel_uptr m_acc
Definition Spline.h:26
Y deriv(X const newX, unsigned int order=1) const
Definition Spline.h:50
Spline(Spline const &)=delete
std::vector< Y > operator()(std::span< X const > newX) const
Definition Spline.h:44
Spline & operator=(Spline const &)=delete
virtual ~Spline()=default
Spline(Spline &&)=delete
std::unique_ptr< gsl_interp_accel, GSLFree > accel_uptr
Definition GSL_Helpers.h:49
std::unique_ptr< gsl_spline, GSLFree > spline_uptr
Definition GSL_Helpers.h:50
std::string to_string(const wide_integer< Bits, Signed > &n)