#[derive(Copy, Clone)]
pub struct KeyMax {
pub lag_index: usize,
pub value_at_lag_index: f32,
pub value: f32,
pub lag: f32,
}
impl KeyMax {
pub(crate) fn new() -> Self {
KeyMax {
lag_index: 0,
value_at_lag_index: 0.0,
value: 0.0,
lag: 0.0,
}
}
pub(crate) fn set(&mut self, nsdf: &[f32], lag_index: usize) {
self.lag_index = lag_index;
let value_at_lag_index = nsdf[lag_index];
self.value_at_lag_index = value_at_lag_index;
let left_index = 0.max(lag_index - 1);
let right_index = (nsdf.len() - 1).min(lag_index + 1);
let left = nsdf[left_index];
let right = nsdf[right_index];
let a = 0.5 * (right - 2.0 * value_at_lag_index + left);
let b = 0.5 * (right - left);
let c = value_at_lag_index;
let x_max = if a != 0.0 { -b / (2.0 * a) } else { 0.0 };
let value = a * x_max * x_max + b * x_max + c;
let lag = (lag_index as f32) + x_max;
self.value = value;
self.lag = lag;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn key_maximum_interpolation() {
{
let nsdf: [f32; 4] = [0.0, 0.0, 3.0, 0.0];
let mut key_max = KeyMax::new();
key_max.set(&nsdf, 2);
assert!((key_max.lag - 2.0).abs() <= f32::EPSILON);
assert!((key_max.value - 3.0).abs() <= f32::EPSILON);
}
{
let nsdf: [f32; 3] = [-2.0, 0.0, -1.0];
let mut key_max = KeyMax::new();
key_max.set(&nsdf, 1);
assert!((key_max.lag - 1.1666666_f32).abs() <= f32::EPSILON);
}
}
}