use {
crate::*,
std::{convert::*, f64::consts::LOG10_E},
};
#[derive(Debug)]
pub enum GlueErrors {
BorderCreation(HistErrors),
EmptyList,
BinarySearch,
OutOfBounds,
NoOverlap,
}
impl From<HistErrors> for GlueErrors {
fn from(e: HistErrors) -> Self {
GlueErrors::BorderCreation(e)
}
}
pub fn norm_log10_sum_to_1(log10_density: &mut [f64]) {
subtract_max(log10_density);
let sum = log10_density.iter().fold(0.0, |acc, &val| {
if val.is_finite() {
acc + 10_f64.powf(val)
} else {
acc
}
});
let sum = sum.log10();
log10_density.iter_mut().for_each(|val| *val -= sum);
}
pub(crate) fn height_correction(log10_vec: &mut [Vec<f64>], z_vec: &[f64]) {
log10_vec
.iter_mut()
.skip(1)
.zip(z_vec.iter())
.for_each(|(vec, &z)| {
vec.iter_mut().for_each(|val| {
*val += z;
})
});
}
pub(crate) fn subtract_max(list: &mut [f64]) -> f64 {
let max = list.iter().copied().fold(f64::NAN, f64::max);
if max.is_finite() {
list.iter_mut().for_each(|val| *val -= max);
}
max
}
pub(crate) fn ln_to_log10(slice: &mut [f64]) {
slice.iter_mut().for_each(|val| *val *= LOG10_E);
}
pub(crate) fn log10_to_ln(slice: &mut [f64]) {
slice.iter_mut().for_each(|val| *val /= LOG10_E);
}