Files
Flux-openbuild/include/numerics/interpolation1d/interpolation1d_polynomial.h
2025-10-06 20:14:13 +00:00

76 lines
1.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "./numerics/interpolation1d/interpolation1d_base.h"
#include "./numerics/abs.h"
#include "./utils/vector.h"
namespace numerics{
template <typename T>
struct interp_polynomial : Base_interp<T> {
using Base = Base_interp<T>;
// bring base data members into scope (or use this->xx / this->yy below)
using Base::xx;
using Base::yy;
using Base::mm;
T dy;
interp_polynomial(const utils::Vector<T> &xv, const utils::Vector<T> &yv, uint64_t m)
: Base_interp<T>(xv, &yv[0], m), dy(T{0}){}
T rawinterp(int64_t jl, T x) override{
int64_t ns=0;
T y, den, dif, dift, ho, hp, w;
const T *xa = &xx[jl], *ya = &yy[jl];
utils::Vector<T> c(mm,0), d(mm,0);
dif = numerics::abs(x-xa[0]);
for (int64_t i = 0; i < mm; ++i){ // Here we find the index ns of the closest table entry,
dift = numerics::abs(x-xa[i]);
if (dift < dif){
ns = i;
dif=dift;
}
c[i]=ya[i]; // and initialize the tableau of cs and ds.
d[i]=ya[i];
}
y = ya[ns]; // This is the initial approximation to y.
ns -= 1;
for (int64_t m = 1; m < mm; ++m){ // For each column of the tableau,
for (int64_t i = 0; i < mm-m; ++i){ // we loop over the current cs and ds and update them.
ho = xa[i]-x;
hp = xa[i+m]-x;
w = c[i+1]-d[i];
den = ho-hp;
if (den == T{0.0}){
throw std::invalid_argument("interp_polynomial error"); // This error can occur only if two input xas are (to within roundoff identical.
}
den = w/den; // Here the cs and ds are updated.
d[i] = hp*den;
c[i] = ho*den;
}
bool take_left = 2 * (ns + 1) < (mm - m);
if (take_left) {
dy = c[ns + 1];
y += dy;
} else {
dy = d[ns];
y += dy;
ns -= 1;
}
}
return y;
}
};
} // namespace numerics