use alloc::boxed::Box;
use alloc::vec::Vec;
pub mod bins;
pub mod categorical;
#[cfg(feature = "kmeans-binning")]
#[cfg_attr(docsrs, doc(cfg(feature = "kmeans-binning")))]
pub mod kmeans;
pub mod quantile;
#[cfg(feature = "simd")]
#[cfg_attr(docsrs, doc(cfg(feature = "simd")))]
pub mod simd;
pub mod uniform;
#[derive(Debug, Clone)]
pub struct BinEdges {
pub edges: Vec<f64>,
}
impl BinEdges {
#[inline]
pub fn find_bin(&self, value: f64) -> usize {
match self
.edges
.binary_search_by(|e| e.partial_cmp(&value).unwrap())
{
Ok(i) => i + 1,
Err(i) => i,
}
}
#[inline]
pub fn n_bins(&self) -> usize {
self.edges.len() + 1
}
}
pub trait BinningStrategy: Send + Sync + 'static {
fn observe(&mut self, value: f64);
fn compute_edges(&self, n_bins: usize) -> BinEdges;
fn reset(&mut self);
fn clone_fresh(&self) -> Box<dyn BinningStrategy>;
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum BinnerKind {
Uniform(uniform::UniformBinning),
Categorical(categorical::CategoricalBinning),
#[cfg(feature = "kmeans-binning")]
#[cfg_attr(docsrs, doc(cfg(feature = "kmeans-binning")))]
KMeans(kmeans::KMeansBinning),
}
impl BinnerKind {
#[inline]
pub fn uniform() -> Self {
BinnerKind::Uniform(uniform::UniformBinning::new())
}
#[inline]
pub fn categorical() -> Self {
BinnerKind::Categorical(categorical::CategoricalBinning::new())
}
#[cfg(feature = "kmeans-binning")]
#[cfg_attr(docsrs, doc(cfg(feature = "kmeans-binning")))]
#[inline]
pub fn kmeans() -> Self {
BinnerKind::KMeans(kmeans::KMeansBinning::new())
}
#[inline]
pub fn observe(&mut self, value: f64) {
match self {
BinnerKind::Uniform(b) => b.observe(value),
BinnerKind::Categorical(b) => b.observe(value),
#[cfg(feature = "kmeans-binning")]
BinnerKind::KMeans(b) => b.observe(value),
}
}
#[inline]
pub fn compute_edges(&self, n_bins: usize) -> BinEdges {
match self {
BinnerKind::Uniform(b) => b.compute_edges(n_bins),
BinnerKind::Categorical(b) => b.compute_edges(n_bins),
#[cfg(feature = "kmeans-binning")]
BinnerKind::KMeans(b) => b.compute_edges(n_bins),
}
}
#[inline]
pub fn reset(&mut self) {
match self {
BinnerKind::Uniform(b) => b.reset(),
BinnerKind::Categorical(b) => b.reset(),
#[cfg(feature = "kmeans-binning")]
BinnerKind::KMeans(b) => b.reset(),
}
}
#[inline]
pub fn is_categorical(&self) -> bool {
matches!(self, BinnerKind::Categorical(_))
}
pub fn clone_fresh(&self) -> Self {
match self {
BinnerKind::Uniform(_) => BinnerKind::Uniform(uniform::UniformBinning::new()),
BinnerKind::Categorical(_) => {
BinnerKind::Categorical(categorical::CategoricalBinning::new())
}
#[cfg(feature = "kmeans-binning")]
BinnerKind::KMeans(_) => BinnerKind::KMeans(kmeans::KMeansBinning::new()),
}
}
}