OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
TestCubicSpline.cpp
Go to the documentation of this file.
1
42#include <gtest/gtest.h>
43#include <cmath>
44#include <vector>
46#include "Utilities/GSLSpline.h"
47
48class CubicSplineTest : public testing::Test {
49protected:
50 void SetUp() override {
51 // Test data: y = x^2
52 x_data = {0.0, 1.0, 2.0, 3.0, 4.0};
53 y_data = {0.0, 1.0, 4.0, 9.0, 16.0};
54 }
55
56 std::vector<double> x_data;
57 std::vector<double> y_data;
58};
59
60TEST_F(CubicSplineTest, BasicInterpolation) {
61 const CubicSpline spline(x_data, y_data);
63
64 // Test interpolation at data points
65 EXPECT_NEAR(spline.eval(0.0, accel), 0.0, 1e-10);
66 EXPECT_NEAR(spline.eval(1.0, accel), 1.0, 1e-10);
67 EXPECT_NEAR(spline.eval(2.0, accel), 4.0, 1e-10);
68 EXPECT_NEAR(spline.eval(3.0, accel), 9.0, 1e-10);
69 EXPECT_NEAR(spline.eval(4.0, accel), 16.0, 1e-10);
70
71 // Test interpolation between points
72 const double val = spline.eval(1.5, accel);
73 EXPECT_GT(val, 1.0);
74 EXPECT_LT(val, 4.0);
75}
76
77TEST_F(CubicSplineTest, Uninitialised) {
78 // Uninitialised
80 CubicSpline spline_uninit;
81 EXPECT_THROW(spline_uninit.eval(0.0, accel), std::runtime_error);
82}
83
84TEST_F(CubicSplineTest, Extrapolation) {
85 const CubicSpline spline(x_data, y_data);
87
88 // Test left extrapolation
89 const double val_left = spline.eval(-1.0, accel);
90 EXPECT_LT(val_left, 0.0);
91
92 // Test right extrapolation
93 const double val_right = spline.eval(5.0, accel);
94 EXPECT_GT(val_right, 16.0);
95}
96
97TEST_F(CubicSplineTest, Accelerator) {
98 const CubicSpline spline(x_data, y_data);
100
101 // First evaluation
102 const double val1 = spline.eval(1.5, accel);
103 EXPECT_GT(val1, 1.0);
104 EXPECT_LT(val1, 4.0);
105
106 // Second evaluation in same interval (should use cached index)
107 const double val2 = spline.eval(1.6, accel);
108 EXPECT_GT(val2, val1);
109
110 // Evaluation in different interval
111 const double val3 = spline.eval(2.5, accel);
112 EXPECT_GT(val3, 4.0);
113 EXPECT_LT(val3, 9.0);
114}
115
116TEST_F(CubicSplineTest, SinFunction) {
117 std::vector<double> x(10);
118 std::vector<double> y(10);
119 for (size_t i = 0; i < 10; ++i) {
120 x[i] = static_cast<double>(i) * 0.5;
121 y[i] = std::sin(x[i]);
122 }
123
124 const CubicSpline spline(x, y);
126
127 // Test interpolation
128 const double val = spline.eval(1.25, accel);
129 const double expected = std::sin(1.25);
130 EXPECT_NEAR(val, expected, 0.01);
131}
132
133TEST_F(CubicSplineTest, InvalidInput) {
134 // Too few points
135 std::vector x = {0.0};
136 std::vector y = {0.0};
137 EXPECT_THROW(CubicSpline spline(x, y), std::invalid_argument);
138
139 // Non-increasing x
140 x = {0.0, 1.0, 0.5, 2.0};
141 y = {0.0, 1.0, 2.0, 3.0};
142 EXPECT_THROW(CubicSpline spline(x, y), std::invalid_argument);
143}
144
145TEST_F(CubicSplineTest, Integration) {
146 CubicSpline spline(x_data, y_data);
148
149 // Whole pre-computed intervals
150 EXPECT_NEAR(spline.evalIntegral(0, 1, accel), 0.39285714285714285, 1e-10);
151 EXPECT_NEAR(spline.evalIntegral(1, 2, accel), 2.3214285714285712, 1e-10);
152 EXPECT_NEAR(spline.evalIntegral(2, 3, accel), 6.3214285714285712, 1e-10);
153 EXPECT_NEAR(spline.evalIntegral(3, 4, accel), 12.392857142857142, 1e-10);
154 EXPECT_NEAR(spline.evalIntegral(0, 4, accel), 21.428571428571427, 1e-10);
155
156 // Partial first and last intervals
157 EXPECT_NEAR(spline.evalIntegral(0.6, 3.2, accel), 10.845085714285716, 1e-10);
158
159 // Asking again should use the cache
160 EXPECT_NEAR(spline.evalIntegral(0.6, 3.2, accel), 10.845085714285716, 1e-10);
161
162 // Extrapolation below the first interval
163 EXPECT_NEAR(spline.evalIntegral(-1, 1.5, accel), 0.890625, 1e-10);
164
165 // Extrapolation above the last interval
166 EXPECT_NEAR(spline.evalIntegral(3, 4.5, accel), 21.160714285714285, 1e-10);
167
168 // Swapping integral bounds
169 EXPECT_NEAR(spline.evalIntegral(2, 1, accel), 2.3214285714285712, 1e-10);
170
171 // Uninitialised spline
172 CubicSpline spline_uninit;
173 EXPECT_THROW(spline_uninit.evalIntegral(2, 1, accel), std::runtime_error);
174
175 // Re-initialise the spline to something different
176 std::vector x_data = {0.0, 1.0, 2.0, 3.0, 4.0};
177 std::vector y_data = {0.0, 2.0, 4.0, 6.0, 8.0};
178 spline.init(x_data, y_data);
179 EXPECT_NEAR(spline.evalIntegral(0, 4, accel), 16.0, 1e-10);
180}
181
182TEST_F(CubicSplineTest, GSLCompatibleInterface) {
183 gsl_spline* spline = gsl_spline_alloc(gsl_interp_cspline, x_data.size());
185 gsl_spline_init(spline, x_data.data(), y_data.data(), x_data.size());
186
187 // Test evaluation
188 double val = gsl_spline_eval(spline, 1.5, accel);
189 EXPECT_GT(val, 1.0);
190 EXPECT_LT(val, 4.0);
191
192 // Test at boundary
193 val = gsl_spline_eval(spline, 0.0, accel);
194 EXPECT_NEAR(val, 0.0, 1e-10);
195
196 // Reset accelerator
198 val = gsl_spline_eval(spline, 2.0, accel);
199 EXPECT_NEAR(val, 4.0, 1e-10);
200
201 // Integration
202 EXPECT_NEAR(gsl_spline_eval_integ(spline, 0.6, 3.2, accel), 10.845085714285716, 1e-10);
203
204 // Clean up
205 gsl_spline_free(spline);
207}
double gsl_spline_eval_integ(const gsl_spline *spline, const double xa, const double xb, gsl_interp_accel *accel)
Evaluate the integral of a spline at x using an accelerator.
Definition GSLSpline.h:76
void gsl_interp_accel_reset(gsl_interp_accel *accel)
Reset an accelerator to the initial state.
Definition GSLSpline.h:91
constexpr int gsl_interp_cspline
Definition GSLSpline.h:26
double gsl_spline_eval(const gsl_spline *spline, const double x, gsl_interp_accel *accel)
Evaluate a spline at x using an accelerator.
Definition GSLSpline.h:66
gsl_interp_accel * gsl_interp_accel_alloc()
Allocate an interpolation accelerator.
Definition GSLSpline.h:50
void gsl_spline_init(gsl_spline *spline, const double *x, const double *y, const size_t n)
Initialize a spline with tabulated data.
Definition GSLSpline.h:57
void gsl_spline_free(const gsl_spline *spline)
Free a spline instance.
Definition GSLSpline.h:83
void gsl_interp_accel_free(const gsl_interp_accel *accel)
Free an accelerator instance.
Definition GSLSpline.h:87
gsl_spline * gsl_spline_alloc(const int type, size_t)
Allocate a spline instance (size ignored).
Definition GSLSpline.h:38
TEST_F(CubicSplineTest, BasicInterpolation)
Accelerator caching last interval indices.
Base class for the linear and cubic interpolation spline classes.
void SetUp() override
std::vector< double > x_data
std::vector< double > y_data
Natural cubic spline interpolator.
Definition CubicSpline.h:28
double evalIntegral(double xa, double xb, Accelerator &accel) const override
Evaluate the integral of the spline at x.
void init(const std::vector< double > &x, const std::vector< double > &y) override
Initialize from tabulated data (natural spline).
double eval(double x, Accelerator &accel) const override
Evaluate the spline at x using an accelerator.