#![allow(
clippy::cast_precision_loss,
clippy::cast_sign_loss,
clippy::cast_possible_truncation
)]
use crate::{grid::Grid1D, grid_nd::GridFnND};
#[inline]
pub(crate) fn lerp_idx_1d_f64(x: f64, grid: &Grid1D) -> (usize, usize, f64) {
let n = grid.n;
let lo = grid.x_at(0);
let hi = grid.x_at(n - 1);
if x <= lo {
return (0, 0, 0.0);
}
if x >= hi {
return (n - 1, n - 1, 0.0);
}
let dx = (hi - lo) / (n - 1) as f64;
let idx_f = (x - lo) / dx;
let k0 = (idx_f as usize).min(n - 2);
let k1 = k0 + 1;
let alpha = (idx_f - k0 as f64).clamp(0.0, 1.0);
(k0, k1, alpha)
}
#[inline]
#[allow(clippy::too_many_arguments)]
pub(crate) fn sample_5d(
src: &GridFnND<f64, 5>,
x0: f64,
x1: f64,
x2: f64,
x3: f64,
x4: f64,
) -> f64 {
let (k0, k0h, a0) = lerp_idx_1d_f64(x0, &src.grid.axes[0]);
let (k1, k1h, a1) = lerp_idx_1d_f64(x1, &src.grid.axes[1]);
let (k2, k2h, a2) = lerp_idx_1d_f64(x2, &src.grid.axes[2]);
let (k3, k3h, a3) = lerp_idx_1d_f64(x3, &src.grid.axes[3]);
let (k4, k4h, a4) = lerp_idx_1d_f64(x4, &src.grid.axes[4]);
let b0 = 1.0 - a0;
let b1 = 1.0 - a1;
let b2 = 1.0 - a2;
let b3 = 1.0 - a3;
let b4 = 1.0 - a4;
let v = |i0, i1, i2, i3, i4| src.values[src.grid.flat_idx(&[i0, i1, i2, i3, i4])];
let s3 = |i0: usize, i1: usize, i2: usize, i3: usize| {
b3 * (b2
* (b1 * (b0 * v(i0, i1, i2, i3, k4) + a0 * v(k0h, i1, i2, i3, k4))
+ a1 * (b0 * v(i0, k1h, i2, i3, k4) + a0 * v(k0h, k1h, i2, i3, k4)))
+ a2 * (b1 * (b0 * v(i0, i1, k2h, i3, k4) + a0 * v(k0h, i1, k2h, i3, k4))
+ a1 * (b0 * v(i0, k1h, k2h, i3, k4) + a0 * v(k0h, k1h, k2h, i3, k4))))
+ a3 * (b2
* (b1 * (b0 * v(i0, i1, i2, k3h, k4) + a0 * v(k0h, i1, i2, k3h, k4))
+ a1 * (b0 * v(i0, k1h, i2, k3h, k4) + a0 * v(k0h, k1h, i2, k3h, k4)))
+ a2 * (b1 * (b0 * v(i0, i1, k2h, k3h, k4) + a0 * v(k0h, i1, k2h, k3h, k4))
+ a1 * (b0 * v(i0, k1h, k2h, k3h, k4) + a0 * v(k0h, k1h, k2h, k3h, k4))))
};
let s3h = |i0: usize, i1: usize, i2: usize, i3: usize| {
b3 * (b2
* (b1 * (b0 * v(i0, i1, i2, i3, k4h) + a0 * v(k0h, i1, i2, i3, k4h))
+ a1 * (b0 * v(i0, k1h, i2, i3, k4h) + a0 * v(k0h, k1h, i2, i3, k4h)))
+ a2 * (b1 * (b0 * v(i0, i1, k2h, i3, k4h) + a0 * v(k0h, i1, k2h, i3, k4h))
+ a1 * (b0 * v(i0, k1h, k2h, i3, k4h) + a0 * v(k0h, k1h, k2h, i3, k4h))))
+ a3 * (b2
* (b1 * (b0 * v(i0, i1, i2, k3h, k4h) + a0 * v(k0h, i1, i2, k3h, k4h))
+ a1 * (b0 * v(i0, k1h, i2, k3h, k4h) + a0 * v(k0h, k1h, i2, k3h, k4h)))
+ a2 * (b1 * (b0 * v(i0, i1, k2h, k3h, k4h) + a0 * v(k0h, i1, k2h, k3h, k4h))
+ a1 * (b0 * v(i0, k1h, k2h, k3h, k4h) + a0 * v(k0h, k1h, k2h, k3h, k4h))))
};
b4 * s3(k0, k1, k2, k3) + a4 * s3h(k0, k1, k2, k3)
}