use std::{borrow::*, cmp::Ordering, num::NonZeroUsize, sync::atomic::AtomicUsize};
#[cfg(feature = "serde_support")]
use serde::{Deserialize, Serialize};
use crate::Bin;
pub trait Histogram {
#[inline(always)]
fn increment_index(&mut self, index: usize) -> Result<(), HistErrors> {
self.increment_index_by(index, 1)
}
fn increment_index_by(&mut self, index: usize, count: usize) -> Result<(), HistErrors>;
fn hist(&self) -> &Vec<usize>;
#[inline(always)]
fn bin_count(&self) -> usize {
self.hist().len()
}
fn reset(&mut self);
fn any_bin_zero(&self) -> bool {
self.hist().contains(&0)
}
}
pub trait HistogramVal<T> {
fn get_bin_index<V: Borrow<T>>(&self, val: V) -> Result<usize, HistErrors>;
fn count_val<V: Borrow<T>>(&mut self, val: V) -> Result<usize, HistErrors>;
fn bin_enum_iter(&'_ self) -> Box<dyn Iterator<Item = Bin<T>> + '_>;
fn is_inside<V: Borrow<T>>(&self, val: V) -> bool;
fn not_inside<V: Borrow<T>>(&self, val: V) -> bool;
fn first_border(&self) -> T;
fn last_border(&self) -> T;
fn last_border_is_inclusive(&self) -> bool;
fn distance<V: Borrow<T>>(&self, val: V) -> f64;
}
pub trait HistogramIntervalDistance<T> {
fn interval_distance_overlap<V: Borrow<T>>(&self, val: V, overlap: NonZeroUsize) -> usize;
}
pub trait HistogramPartition: Sized {
fn overlapping_partition(
&self,
n: NonZeroUsize,
overlap: usize,
) -> Result<Vec<Self>, HistErrors>;
}
pub trait HistogramCombine: Sized {
fn encapsulating_hist<S>(hists: &[S]) -> Result<Self, HistErrors>
where
S: Borrow<Self>;
fn align<S>(&self, right: S) -> Result<usize, HistErrors>
where
S: Borrow<Self>;
}
pub trait IntervalOrder {
fn left_compare(&self, other: &Self) -> Ordering;
}
#[derive(Debug, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub enum HistErrors {
NoBins,
IntervalWidthZero,
OutsideHist,
Underflow,
Overflow,
UsizeCastError,
CastError,
InvalidVal,
ModuloError,
InvalidOverlap,
EmptySlice,
Alignment,
}
pub trait AtomicHistogram {
#[inline(always)]
fn count_index(&self, index: usize) -> Result<(), HistErrors> {
self.count_multiple_index(index, 1)
}
fn count_multiple_index(&self, index: usize, count: usize) -> Result<(), HistErrors>;
fn hist(&self) -> &[AtomicUsize];
#[inline(always)]
fn bin_count(&self) -> usize {
self.hist().len()
}
fn reset(&mut self);
fn any_bin_zero(&self) -> bool {
self.hist()
.iter()
.any(|val| val.load(std::sync::atomic::Ordering::SeqCst) == 0)
}
}
pub trait AtomicHistogramVal<T> {
fn get_bin_index<V: Borrow<T>>(&self, val: V) -> Result<usize, HistErrors>;
fn count_val<V: Borrow<T>>(&self, val: V) -> Result<usize, HistErrors>;
fn is_inside<V: Borrow<T>>(&self, val: V) -> bool;
fn not_inside<V: Borrow<T>>(&self, val: V) -> bool;
fn first_border(&self) -> T;
fn last_border(&self) -> T;
fn distance<V: Borrow<T>>(&self, val: V) -> f64;
}