use crate::float::AlpFloat;
#[inline(always)]
pub fn delta_range<F: AlpFloat>(first: F::Int, rest: &[F::Int]) -> (F::Int, u8) {
let mut min_delta = F::MAX_INT;
let mut max_delta = F::MIN_INT;
let mut prev = first;
for &curr in rest {
let delta = F::int_sub(curr, prev);
min_delta = min_delta.min(delta);
max_delta = max_delta.max(delta);
prev = curr;
}
let delta_bit_width = F::bits_needed(F::calc_range(min_delta, max_delta));
(min_delta, delta_bit_width)
}
#[inline(always)]
pub fn eval_delta_benefit<F: AlpFloat>(
first: F::Int,
rest: &[F::Int],
for_bit_width: u8,
) -> Option<(F::Int, u8)> {
if rest.is_empty() {
return None;
}
let (min_delta, delta_bit_width) = delta_range::<F>(first, rest);
if delta_bit_width < for_bit_width {
Some((min_delta, delta_bit_width))
} else {
None
}
}
#[inline(always)]
pub fn in_place_deltas<F: AlpFloat>(data: &mut [F::Int]) {
for i in (1..data.len()).rev() {
data[i] = F::int_sub(data[i], data[i - 1]);
}
}
#[inline(always)]
pub fn reconstruct_ramp_into_floats<F: AlpFloat>(
first: F::Int,
constant_delta: F::Int,
count: usize,
fac_int: i64,
frac_flt: F,
dst: &mut [F],
) {
let mut curr = first;
for slot in dst.iter_mut().take(count) {
*slot = F::decode_from_int(curr, fac_int, frac_flt);
curr = F::int_add(curr, constant_delta);
}
}