11 std::enable_if_t<!traits::has_size<Number>::value, Number>
12 val(
const Container<Number>& coeffs,
const Number& x) {
14 for (
const Number& c : coeffs) {
15 result = result * x + c;
21 std::enable_if_t<traits::has_size<Container<Number>>::value, Container<Number>>
22 val(
const Container<Number>& coeffs,
const Container<Number>& xx) {
23 Container<Number> result(xx.size(), 0);
24#if defined(_OPENMP) && !defined(ALFI_DISABLE_OPENMP)
25#pragma omp parallel for
27 for (
SizeT i = 0; i < xx.size(); ++i) {
28 for (
const Number& c : coeffs) {
29 result[i] = result[i] * xx[i] + c;
36 Container<Number>
lagrange(
const Container<Number>& X,
const Container<Number>& Y) {
37 if (X.size() != Y.size()) {
38 std::cerr <<
"Error in function " << __FUNCTION__
39 <<
": Vectors X (of size " << X.size()
40 <<
") and Y (of size " << Y.size()
41 <<
") are not the same size. Returning {NAN}..." << std::endl;
46 std::cerr <<
"Error in function " << __FUNCTION__
47 <<
": Vectors X and Y are empty. Cannot interpolate. Returning {NAN}..." << std::endl;
51 const auto N = X.size();
53 Container<Number> P(N);
54 std::fill(P.begin(), P.end(), 0);
56 Container<Number> l(N);
58 for (
SizeT k = 0; k < N; ++k) {
61 for (
SizeT j = 0; j < N; ++j) {
64 l.resize(l.size() + 1);
66 for (
SizeT i = l.size() - 1; i > 0; --i) {
67 l[i] = (l[i] - X[j] * l[i-1]) / (X[k] - X[j]);
72 for (
SizeT i = 0; i < l.size(); ++i) {
81 Container<Number>
lagrange_vals(
const Container<Number>& X,
const Container<Number>& Y,
const Container<Number>& xx) {
82 const auto nn = xx.size();
84 if (X.size() != Y.size()) {
85 std::cerr <<
"Error in function " << __FUNCTION__
86 <<
": Vectors X (of size " << X.size()
87 <<
") and Y (of size " << Y.size()
88 <<
") are not the same size. Returning an array of NaNs..." << std::endl;
89 Container<Number> yy(nn);
90 std::fill(yy.begin(), yy.end(), NAN);
95 std::cerr <<
"Error in function " << __FUNCTION__
96 <<
": Vectors X and Y are empty. Cannot interpolate. Returning an array of NaNs..." << std::endl;
97 Container<Number> yy(nn);
98 std::fill(yy.begin(), yy.end(), NAN);
102 const auto N = X.size();
104 Container<Number> yy(nn);
106#if defined(_OPENMP) && !defined(ALFI_DISABLE_OPENMP)
107#pragma omp parallel for
109 for (
SizeT k = 0; k < nn; ++k) {
111 for (
SizeT i = 0; i < N; ++i) {
113 for (
SizeT j = 0; j < N; ++j) {
115 l *= (xx[k] - X[j]) / (X[i] - X[j]);
126 Container<Number>
imp_lagrange(
const Container<Number>& X,
const Container<Number>& Y) {
127 if (X.size() != Y.size()) {
128 std::cerr <<
"Error in function " << __FUNCTION__
129 <<
": Vectors X (of size " << X.size()
130 <<
") and Y (of size " << Y.size()
131 <<
") are not the same size. Returning {NAN}..." << std::endl;
136 std::cerr <<
"Error in function " << __FUNCTION__
137 <<
": Vectors X and Y are empty. Cannot interpolate. Returning {NAN}..." << std::endl;
141 const auto N = X.size();
143 Container<Number> w_rev(N);
144 std::fill(w_rev.begin(), w_rev.end(), 1);
145 for (
SizeT i = 0; i < N; ++i) {
146 for (
SizeT j = 0; j < N; ++j) {
148 w_rev[i] *= (X[i] - X[j]);
153 Container<Number> P(N);
154 std::fill(P.begin(), P.end(), 0);
156 Container<Number> l(N + 1);
158 for (
SizeT k = 0; k < N; ++k) {
161 for (
SizeT j = 0; j < N; ++j) {
163 l.resize(l.size() + 1);
165 for (
SizeT i = l.size() - 1; i > 0; --i) {
166 l[i] -= X[j] * l[i-1];
171 for (
SizeT k = 0; k < N; ++k) {
172 Container<Number> l_cur(N);
174 for (
SizeT i = 1; i < N; ++i) {
175 l_cur[i] = l[i] + l_cur[i-1] * X[k];
177 for (
SizeT i = 0; i < N; ++i) {
178 P[i] += Y[k] * l_cur[i] / w_rev[k];
187 const Container<Number>& X,
188 const Container<Number>& Y,
189 const Container<Number>& xx,
190 const Number& epsilon = std::numeric_limits<Number>::epsilon()
192 const auto nn = xx.size();
194 if (X.size() != Y.size()) {
195 std::cerr <<
"Error in function " << __FUNCTION__
196 <<
": Vectors X (of size " << X.size()
197 <<
") and Y (of size " << Y.size()
198 <<
") are not the same size. Returning an array of NaNs..." << std::endl;
199 Container<Number> yy(nn);
200 std::fill(yy.begin(), yy.end(), NAN);
205 std::cerr <<
"Error in function " << __FUNCTION__
206 <<
": Vectors X and Y are empty. Cannot interpolate. Returning an array of NaNs..." << std::endl;
207 Container<Number> yy(nn);
208 std::fill(yy.begin(), yy.end(), NAN);
212 const auto N = X.size();
214 Container<Number> w_rev(N);
215 std::fill(w_rev.begin(), w_rev.end(), 1);
216 for (
SizeT i = 0; i < N; ++i) {
217 for (
SizeT j = 0; j < N; ++j) {
219 w_rev[i] *= (X[i] - X[j]);
224 Container<Number> yy(nn);
226#if defined(_OPENMP) && !defined(ALFI_DISABLE_OPENMP)
227#pragma omp parallel for
229 for (
SizeT k = 0; k < nn; ++k) {
231 for (
SizeT i = 0; i < N; ++i) {
235 for (
SizeT i = 0; i < N; ++i) {
240 yy[k] += Y[i] * l / (w_rev[i] * (xx[k] - X[i]));
249 Container<Number>
newton(
const Container<Number>& X,
const Container<Number>& Y) {
250 if (X.size() != Y.size()) {
251 std::cerr <<
"Error in function " << __FUNCTION__
252 <<
": Vectors X (of size " << X.size()
253 <<
") and Y (of size " << Y.size()
254 <<
") are not the same size. Returning {NAN}..." << std::endl;
259 std::cerr <<
"Error in function " << __FUNCTION__
260 <<
": Vectors X and Y are empty. Cannot interpolate. Returning {NAN}..." << std::endl;
264 const auto N = X.size();
266 Container<Number> F = Y;
268 for (
SizeT i = 1; i < N; ++i) {
269 for (
SizeT j = N - 1; j >= i; --j) {
270 F[j] = (F[j] - F[j-1]) / (X[j] - X[j-i]);
274 Container<Number> P(N);
275 std::fill(P.begin(), P.end() - 1, 0);
276 P[P.size()-1] = F[0];
278 Container<Number> f(N);
280 for (
SizeT i = 0; i < N - 1; ++i) {
283 for (
SizeT j = 0; j <= i; ++j) {
285 f.resize(f.size() + 1);
287 for (
SizeT k = f.size() - 1; k > 0; --k) {
288 f[k] -= X[j] * f[k-1];
293 for (
SizeT j = 0; j < f.size(); ++j) {
294 P[N-1-i-1+j] += f[j];
302 Container<Number>
newton_vals(
const Container<Number>& X,
const Container<Number>& Y,
const Container<Number>& xx) {
303 const auto nn = xx.size();
305 if (X.size() != Y.size()) {
306 std::cerr <<
"Error in function " << __FUNCTION__
307 <<
": Vectors X (of size " << X.size()
308 <<
") and Y (of size " << Y.size()
309 <<
") are not the same size. Returning an array of NaNs..." << std::endl;
310 Container<Number> yy(nn);
311 std::fill(yy.begin(), yy.end(), NAN);
316 std::cerr <<
"Error in function " << __FUNCTION__
317 <<
": Vectors X and Y are empty. Cannot interpolate. Returning an array of NaNs..." << std::endl;
318 Container<Number> yy(nn);
319 std::fill(yy.begin(), yy.end(), NAN);
323 const auto N = X.size();
325 Container<Number> F = Y;
327 for (
SizeT i = 1; i < N; ++i) {
328 for (
SizeT j = N - 1; j >= i; --j) {
329 F[j] = (F[j] - F[j-1]) / (X[j] - X[j-i]);
333 Container<Number> yy(nn);
335#if defined(_OPENMP) && !defined(ALFI_DISABLE_OPENMP)
336#pragma omp parallel for
338 for (
SizeT k = 0; k < nn; ++k) {
340 for (
SizeT iter = 0; iter < N - 1; ++iter) {
341 const auto i = N - 2 - iter;
342 yy[k] = yy[k] * (xx[k] - X[i]) + F[i];
std::enable_if_t<!traits::has_size< Number >::value, Number > val(const Container< Number > &coeffs, const Number &x)
Definition poly.h:12
Container< Number > newton(const Container< Number > &X, const Container< Number > &Y)
Definition poly.h:249
Container< Number > lagrange_vals(const Container< Number > &X, const Container< Number > &Y, const Container< Number > &xx)
Definition poly.h:81
Container< Number > newton_vals(const Container< Number > &X, const Container< Number > &Y, const Container< Number > &xx)
Definition poly.h:302
Container< Number > lagrange(const Container< Number > &X, const Container< Number > &Y)
Definition poly.h:36
Container< Number > imp_lagrange(const Container< Number > &X, const Container< Number > &Y)
Definition poly.h:126
Container< Number > imp_lagrange_vals(const Container< Number > &X, const Container< Number > &Y, const Container< Number > &xx, const Number &epsilon=std::numeric_limits< Number >::epsilon())
Definition poly.h:186
bool are_equal(const Number &a, const Number &b, const Number &epsilon=std::numeric_limits< Number >::epsilon())
Definition numeric.h:9
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