use crate::Accelerator;
use crate::z_idx;
#[derive(Debug, Clone)]
pub struct Accelerator2d {
xacc: Accelerator,
yacc: Accelerator,
xgrid_values: (f64, f64),
ygrid_values: (f64, f64),
zgrid_values: (f64, f64, f64, f64),
zx_values: (f64, f64, f64, f64),
zy_values: (f64, f64, f64, f64),
zxy_values: (f64, f64, f64, f64),
partials: (f64, f64),
uninit: bool,
}
impl Accelerator2d {
#[must_use]
pub fn new() -> Self {
Self {
xacc: Accelerator::new(),
yacc: Accelerator::new(),
xgrid_values: (f64::NAN, f64::NAN),
ygrid_values: (f64::NAN, f64::NAN),
zgrid_values: (f64::NAN, f64::NAN, f64::NAN, f64::NAN),
zx_values: (f64::NAN, f64::NAN, f64::NAN, f64::NAN),
zy_values: (f64::NAN, f64::NAN, f64::NAN, f64::NAN),
zxy_values: (f64::NAN, f64::NAN, f64::NAN, f64::NAN),
partials: (f64::NAN, f64::NAN),
uninit: true,
}
}
pub fn reset(&mut self) {
*self = Self::new()
}
pub fn xacc(&mut self) -> &mut Accelerator {
&mut self.xacc
}
pub fn yacc(&mut self) -> &mut Accelerator {
&mut self.yacc
}
pub(crate) fn is_uptodate(&mut self, xa: &[f64], ya: &[f64], x: f64, y: f64) -> bool {
let old_xi = self.xacc.cache;
let old_yi = self.yacc.cache;
self.xacc.find(xa, x);
self.yacc.find(ya, y);
if self.uninit {
self.uninit = false;
return false;
}
(old_xi == self.xacc.cache) && (old_yi == self.yacc.cache)
}
pub(crate) fn update_step1(&mut self, xa: &[f64], ya: &[f64], za: &[f64]) {
self.update_xy_grid_values(xa, ya);
self.update_z_grid_values(za, xa.len(), ya.len());
self.update_partials();
}
#[expect(clippy::too_many_arguments, reason = "unavoidable")]
pub(crate) fn update_step2(
&mut self,
xa: &[f64],
ya: &[f64],
zx: &[f64],
zy: &[f64],
zxy: &[f64],
dt: f64,
du: f64,
) {
self.update_zxminmaxing(zx, xa.len(), ya.len(), dt);
self.update_zyminmaxing(zy, xa.len(), ya.len(), du);
self.update_zxyminmaxing(zxy, xa.len(), ya.len(), dt * du);
}
}
impl Accelerator2d {
fn update_xy_grid_values(&mut self, xa: &[f64], ya: &[f64]) {
let xi = self.xacc.cache;
let yi = self.yacc.cache;
self.xgrid_values = (xa[xi], xa[xi + 1]);
self.ygrid_values = (ya[yi], ya[yi + 1]);
}
fn update_z_grid_values(&mut self, za: &[f64], xlen: usize, ylen: usize) {
let xi = self.xacc.cache;
let yi = self.yacc.cache;
self.zgrid_values.0 = za[z_idx(xi, yi, xlen, ylen)];
self.zgrid_values.1 = za[z_idx(xi, yi + 1, xlen, ylen)];
self.zgrid_values.2 = za[z_idx(xi + 1, yi, xlen, ylen)];
self.zgrid_values.3 = za[z_idx(xi + 1, yi + 1, xlen, ylen)];
}
fn update_partials(&mut self) {
self.partials.0 = self.xgrid_values.1 - self.xgrid_values.0;
self.partials.1 = self.ygrid_values.1 - self.ygrid_values.0;
}
fn update_zxminmaxing(&mut self, zx: &[f64], xsize: usize, ysize: usize, d: f64) {
let xi = self.xacc.cache;
let yi = self.yacc.cache;
self.zx_values.0 = zx[z_idx(xi, yi, xsize, ysize)] / d;
self.zx_values.1 = zx[z_idx(xi, yi + 1, xsize, ysize)] / d;
self.zx_values.2 = zx[z_idx(xi + 1, yi, xsize, ysize)] / d;
self.zx_values.3 = zx[z_idx(xi + 1, yi + 1, xsize, ysize)] / d;
}
fn update_zyminmaxing(&mut self, zy: &[f64], xsize: usize, ysize: usize, d: f64) {
let xi = self.xacc.cache;
let yi = self.yacc.cache;
self.zy_values.0 = zy[z_idx(xi, yi, xsize, ysize)] / d;
self.zy_values.1 = zy[z_idx(xi, yi + 1, xsize, ysize)] / d;
self.zy_values.2 = zy[z_idx(xi + 1, yi, xsize, ysize)] / d;
self.zy_values.3 = zy[z_idx(xi + 1, yi + 1, xsize, ysize)] / d;
}
fn update_zxyminmaxing(&mut self, zxy: &[f64], xsize: usize, ysize: usize, d: f64) {
let xi = self.xacc.cache;
let yi = self.yacc.cache;
self.zxy_values.0 = zxy[z_idx(xi, yi, xsize, ysize)] / d;
self.zxy_values.1 = zxy[z_idx(xi, yi + 1, xsize, ysize)] / d;
self.zxy_values.2 = zxy[z_idx(xi + 1, yi, xsize, ysize)] / d;
self.zxy_values.3 = zxy[z_idx(xi + 1, yi + 1, xsize, ysize)] / d;
}
}
impl Accelerator2d {
pub(crate) fn get_xy_grid_values(&self) -> (f64, f64, f64, f64) {
(
self.xgrid_values.0,
self.xgrid_values.1,
self.ygrid_values.0,
self.ygrid_values.1,
)
}
pub(crate) fn get_z_grid_values(&self) -> (f64, f64, f64, f64) {
self.zgrid_values
}
pub(crate) fn get_partials(&self) -> (f64, f64) {
self.partials
}
pub(crate) fn get_zxminmaxxing(&self) -> (f64, f64, f64, f64) {
self.zx_values
}
pub(crate) fn get_zyminmaxxing(&self) -> (f64, f64, f64, f64) {
self.zy_values
}
pub(crate) fn get_zxyminmaxxing(&self) -> (f64, f64, f64, f64) {
self.zxy_values
}
}
impl Default for Accelerator2d {
fn default() -> Self {
Self::new()
}
}