use crate::math::mla;
use num_traits::{AsPrimitive, MulAdd, Signed};
use std::ops::{Add, Div, Mul, Neg, Sub};
pub(crate) fn cubic_spline<
V: Copy
+ Mul<Output = V>
+ Add<Output = V>
+ Neg<Output = V>
+ Sub<Output = V>
+ PartialOrd
+ PartialEq
+ Div<Output = V>
+ MulAdd<V, Output = V>
+ 'static,
>(
d: V,
) -> V
where
f32: AsPrimitive<V>,
{
let mut x = d;
if x < 0f32.as_() {
x = -x;
}
if x < 1f32.as_() {
return mla(x * x, mla(3f32.as_(), x, -6f32.as_()), 4f32.as_()) * (1f32.as_() / 6f32.as_());
} else if x < 2f32.as_() {
return mla(x, mla(x, 6f32.as_() - x, (-12f32).as_()), 8f32.as_())
* (1f32.as_() / 6f32.as_());
}
0f32.as_()
}
pub(crate) fn bicubic_spline<
V: Copy
+ Mul<Output = V>
+ Sub<Output = V>
+ Add<Output = V>
+ 'static
+ Neg<Output = V>
+ Signed
+ PartialOrd
+ MulAdd<V, Output = V>,
>(
d: V,
) -> V
where
f32: AsPrimitive<V>,
{
let x = d;
let a: V = (-0.5f32).as_();
let modulo = x.abs();
if modulo >= 2f32.as_() {
return 0f32.as_();
}
let floatd = modulo * modulo; let triplet = floatd * modulo; if modulo <= 1f32.as_() {
return mla(
a + 2f32.as_(),
triplet,
mla(-(a + 3f32.as_()), floatd, 1f32.as_()),
);
}
mla(
a,
triplet,
mla(
-(5f32.as_() * a),
floatd,
mla(8f32.as_() * a, modulo, -(4f32.as_() * a)),
),
)
}