1 #ifndef CPPAPE_INTERPOLATION_H
2 #define CPPAPE_INTERPOLATION_H
24 template<
typename T,
typename Signal>
28 long long start = std::floor<long long>(x);
29 for (
auto i = start - wsize + 1; i < (start + wsize + 1); ++i)
32 auto response = lanczos<T>(x - i, wsize);
33 resonance += impulse * response;
52 template<
typename T,
typename Signal>
53 inline T
sincFilter(
const Signal& s,
double x,
long long wsize)
56 long long start = std::floor<long long>(x);
57 for (
auto i = start - wsize + 1; i < (start + wsize + 1); ++i)
60 auto response = sinc<T>(x - i);
61 resonance += impulse * response;
76 inline const T
hermite4(
const T offset,
const T ym1,
const T y0,
const T y1,
const T y2)
78 const T c = (y1 - ym1) * static_cast<T>(0.5);
81 const T a = w + v + (y2 - y0) * static_cast<T>(0.5);
82 const T b_neg = w + a;
84 return ((((a * offset) - b_neg) * offset + c) * offset + y0);
95 template<
typename T,
typename Signal>
96 inline const T
hermite4(
const Signal& s,
const T x)
98 long long x0 = std::floor<long long>(x);
99 return hermite4(x - x0, s(x0 - 1), s(x0), s(x0 + 1), s(x0 + 2));
109 inline const T
linear(
const T offset,
const T y0,
const T y1)
111 return y0 * (1 - offset) + y1 * offset;
122 template<
typename T,
typename Signal>
123 inline const T
linear(
const Signal& s,
const T x)
125 long long x0 = std::floor<long long>(x);
126 return linear(x - x0, s(x0), s(x0 + 1));
132 template <
typename T,
int k>
133 struct lagrange_basis
135 static void mul(T& a, T b) { a *= b * (static_cast<T>(1) / k); }
139 struct lagrange_basis <T, 0>
141 static void mul(T&, T) {}
144 template <
typename T,
int k,
int Order, std::size_t... I>
145 static float lagrange_polynomial(T input,
const T offset, std::index_sequence<I...>) noexcept
147 auto const ks = -Order / 2;
148 (lagrange_basis <T, static_cast<int>(I) - k>::mul(input, static_cast<int>(I) + ks - offset), ...);
152 template<
typename T, std::size_t Order,
typename Signal, std::size_t... I>
153 inline const T
lagrange_unpack(
const Signal& s,
long long start,
const T offset, std::index_sequence<I...> indices) noexcept
155 auto const ks = static_cast<long>(-static_cast<T>(Order) / static_cast<T>(2));
156 return (lagrange_polynomial<T, I, Order>(s(ks + start + I), offset, indices) + ...);
169 template<
typename T, std::
size_t Order,
typename Signal>
170 inline const T
lagrange(
const Signal& s,
const T position) noexcept
172 using namespace detail;
173 const long long start = static_cast<long long>(position);
174 return lagrange_unpack<T, Order>(s, start, position - start, std::make_index_sequence<Order>());
184 inline const T
lagrange5(
const T offset,
const T ym2,
const T ym1,
const T y0,
const T y1,
const T y2)
186 using namespace detail;
188 const auto indices = std::make_index_sequence<5>();
190 return lagrange_polynomial<T, 0, 5>(ym2, offset, indices)
191 + lagrange_polynomial<T, 1, 5>(ym1, offset, indices)
192 + lagrange_polynomial<T, 2, 5>(y0, offset, indices)
193 + lagrange_polynomial<T, 3, 5>(y1, offset, indices)
194 + lagrange_polynomial<T, 4, 5>(y2, offset, indices);