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