ALFI
Advanced Library for Function Interpolation
Loading...
Searching...
No Matches
spline.h
Go to the documentation of this file.
1#pragma once
2
3#include <iostream>
4
5#include "../config.h"
6#include "../util/linalg.h"
7
9 template <typename Number = DefaultNumber, template <typename, typename...> class Container = DefaultContainer>
10 Container<Number> simple_spline(const Container<Number>& X, const Container<Number>& Y, SizeT degree) {
11 if (X.size() != Y.size()) {
12 std::cerr << "Error in function " << __FUNCTION__
13 << ": Vectors X (of size " << X.size()
14 << ") and Y (of size " << Y.size()
15 << ") are not the same size. Returning an empty array..." << std::endl;
16 return {};
17 }
18
19 const auto n = X.size();
20 const auto m = degree + 1;
21
22 if (n > m) {
23 std::cerr << "Error in function " << __FUNCTION__
24 << ": Number of points (" << n
25 << ") is bigger than degree + 1 (" << m
26 << "). The spline is not simple. Returning an empty array..." << std::endl;
27 return {};
28 }
29
30 if (n == 0) {
31 return {};
32 }
33
34 if (n == 1) {
35 Container<Number> coeffs(m, 0);
36 coeffs[m-1] = Y[0];
37 return coeffs;
38 }
39
40 if (n == 2) {
41 Container<Number> coeffs(m, 0);
42 coeffs[m-2] = (Y[1] - Y[0]) / (X[1] - X[0]);
43 coeffs[m-1] = Y[0];
44 return coeffs;
45 }
46
47 if (n == 3) {
48 const auto h1 = X[1] - X[0], h2 = X[2] - X[1];
49 const auto d1 = (Y[1] - Y[0]) / h1, d2 = (Y[2] - Y[1]) / h2;
50
51 Container<Number> coeffs(2*m, 0);
52
53 coeffs[m-3] = (d2 - d1) / (h1 + h2);
54 coeffs[m-2] = d1 - h1 * coeffs[m-3];
55 coeffs[m-1] = Y[0];
56 coeffs[2*m-3] = coeffs[m-3];
57 coeffs[2*m-2] = d1 + h1 * coeffs[m-3];
58 coeffs[2*m-1] = Y[1];
59
60 return coeffs;
61 }
62
63 if (n == 4) {
64 const auto h1 = X[1]-X[0], h2 = X[2]-X[1];
65 const auto h12 = X[2]-X[0], h13 = X[3]-X[0];
66 const auto d1 = Y[1]-Y[0], d12 = Y[2]-Y[0], d13 = Y[3]-Y[0];
67
69 {{std::pow(h1, 3), std::pow(h1, 2), h1},
70 {std::pow(h12, 3), std::pow(h12, 2), h12},
71 {std::pow(h13, 3), std::pow(h13, 2), h13}},
72 {d1, d12, d13});
73 if (abc.empty()) {
74 std::cerr << "Error in function " << __FUNCTION__ << ": Could not compute. Returning an empty array..." << std::endl;
75 return {};
76 }
77
78 const auto a = abc[0], b = abc[1], c = abc[2];
79
80 Container<Number> coeffs(3*m, 0);
81
82 coeffs[m-4] = a;
83 coeffs[m-3] = b;
84 coeffs[m-2] = c;
85 coeffs[m-1] = Y[0];
86 coeffs[2*m-4] = a;
87 coeffs[2*m-3] = 3 * a * h1 + b;
88 coeffs[2*m-2] = 3 * a * std::pow(h1, 2) + 2 * b * h1 + c;
89 coeffs[2*m-1] = Y[1];
90 coeffs[3*m-4] = a;
91 coeffs[3*m-3] = 3 * a * h2 + coeffs[2*m-3];
92 coeffs[3*m-2] = 3 * a * std::pow(h2, 2) + 2 * coeffs[2*m-3] * h2 + coeffs[2*m-2];
93 coeffs[3*m-1] = Y[2];
94
95 return coeffs;
96 }
97
98 std::cerr << "Error in function " << __FUNCTION__
99 << ": Number of points (" << n
100 << ") is too big (bigger than 4). Returning an empty array..." << std::endl;
101 return {};
102 }
103}
Container< Number > lup_solve(Container< Container< Number > > &&A, Container< Number > &&B, Number epsilon=std::numeric_limits< Number >::epsilon())
Solves a system of linear equations using LUP decomposition.
Definition linalg.h:32
Definition spline.h:8
Container< Number > simple_spline(const Container< Number > &X, const Container< Number > &Y, SizeT degree)
Definition spline.h:10
ALFI_DEFAULT_NUMBER DefaultNumber
Definition config.h:17
ALFI_SIZE_TYPE SizeT
Definition config.h:22
ALFI_DEFAULT_CONTAINER< Number > DefaultContainer
Definition config.h:20