28 void CubicSpline::computeCoeffs()
30 std::sort(data.begin(), data.end(), Point2DDouble::Comparer(
Direction::LEFT));
32 std::vector<double> h(data.size() - 1);
33 std::vector<double> b(h.size());
34 for (
size_t tmp = 0; tmp < h.size(); ++tmp)
36 h[tmp] = data[tmp + 1].X - data[tmp].X;
37 b[tmp] = (data[tmp + 1].Y - data[tmp].Y) / h[tmp];
40 std::vector<double> u(h.size());
41 std::vector<double> v(h.size());
42 u[1] = 2 * (h[0] + h[1]);
43 v[1] = 6 * (b[1] - b[0]);
44 for (
size_t tmp = 2; tmp < u.size(); ++tmp)
46 u[tmp] = 2 * (h[tmp - 1] + h[tmp]) -
crn::Sqr(h[tmp - 1]) / u[tmp - 1];
47 v[tmp] = 6 * (b[tmp] - b[tmp - 1]) - h[tmp - 1] * v[tmp - 1] / u[tmp - 1];
50 z.resize(data.size());
52 for (
int tmp =
int(z.size()) - 2; tmp > 0; --tmp)
54 z[tmp] = (v[tmp] - h[tmp] * z[tmp + 1]) / u[tmp];
63 if (x < data.front().X)
65 double dx = data[1].X - data[0].X;
69 double dy = (*this)[data.front().X + dx] - data.front().Y;
70 double slope = dy / dx;
71 return data.front().Y + slope * (x - data.front().X);
73 if (x > data.back().X)
75 double dx = data[data.size() - 1].X - data[data.size() - 2].X;
79 double dy = data.back().Y - (*this)[data.back().X - dx];
80 double slope = dy / dx;
81 return data.back().Y + slope * (x - data.back().X);
85 if (x >= data.back().X)
89 for (i = 0; i < z.size() - 1; ++i)
91 if (x <= data[i + 1].X)
95 double h = data[i + 1].X - data[i].X;
97 double b = h * z[i + 1] / -6.0 - h * z[i] / 3.0 + (data[i + 1].Y - data[i].Y) / h;
98 double c = z[i] / 2.0;
99 double d = (z[i + 1] - z[i]) / (6.0 * h);
100 double dx = x - data[i].X;
101 return a + dx * (b + dx * (c + dx * d));
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
virtual double operator[](double x) const override
Gets ordinate at x.
Cubic spline interpolation.
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.