use num_traits::AsPrimitive;
use std::ops::{Add, Div, Mul, MulAssign, Sub};
#[inline]
pub(crate) fn lagrange<
V: Copy
+ PartialEq
+ PartialOrd
+ AsPrimitive<usize>
+ Mul<Output = V>
+ Add<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ MulAssign,
>(
x: V,
support: usize,
) -> V
where
f32: AsPrimitive<V>,
usize: AsPrimitive<V>,
{
if x > support.as_() {
return 0f32.as_();
}
let order = (2.0f32.as_() * support.as_()).as_();
let n = (support.as_() + x).as_();
let mut value = 1.0f32.as_();
for i in 0..order {
if i != n {
value *= (n.as_() - i.as_() - x) / (n.as_() - i.as_());
}
}
value
}
pub(crate) fn lagrange2<
V: Copy
+ PartialEq
+ PartialOrd
+ AsPrimitive<usize>
+ Mul<Output = V>
+ Add<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ MulAssign,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
usize: AsPrimitive<V>,
{
lagrange(x, 2)
}
pub(crate) fn lagrange3<
V: Copy
+ PartialEq
+ PartialOrd
+ AsPrimitive<usize>
+ Mul<Output = V>
+ Add<Output = V>
+ Sub<Output = V>
+ Div<Output = V>
+ MulAssign,
>(
x: V,
) -> V
where
f32: AsPrimitive<V>,
usize: AsPrimitive<V>,
{
lagrange(x, 3)
}