mod partition;
mod stat;
pub use partition::Partition;
pub use stat::BernoulliSuffStat;
pub use stat::CategoricalSuffStat;
pub use stat::GaussianSuffStat;
pub use stat::MvGaussianSuffStat;
pub use stat::PoissonSuffStat;
use crate::dist::{Bernoulli, Categorical, Gaussian, Poisson};
use crate::traits::{HasSuffStat, SuffStat};
pub type BernoulliData<'a, X> = DataOrSuffStat<'a, X, Bernoulli>;
pub type CategoricalData<'a, X> = DataOrSuffStat<'a, X, Categorical>;
pub type GaussianData<'a, X> = DataOrSuffStat<'a, X, Gaussian>;
pub type PoissonData<'a, X> = DataOrSuffStat<'a, X, Poisson>;
pub trait CategoricalDatum: Sized + Sync + Copy {
fn into_usize(&self) -> usize;
fn from_usize(n: usize) -> Self;
}
impl CategoricalDatum for usize {
fn into_usize(&self) -> usize {
*self
}
fn from_usize(n: usize) -> Self {
n
}
}
impl CategoricalDatum for bool {
fn into_usize(&self) -> usize {
if *self {
1
} else {
0
}
}
fn from_usize(n: usize) -> Self {
match n {
0 => false,
1 => true,
_ => panic!("cannot convert {} into bool", n),
}
}
}
macro_rules! impl_categorical_datum {
($kind:ty) => {
impl CategoricalDatum for $kind {
fn into_usize(&self) -> usize {
*self as usize
}
fn from_usize(n: usize) -> Self {
n as $kind
}
}
};
}
impl_categorical_datum!(u8);
impl_categorical_datum!(u16);
impl_categorical_datum!(u32);
pub trait Booleable: Sized + Sync + Copy {
fn from_bool(b: bool) -> Self;
fn into_bool(self) -> bool {
self.try_into_bool().expect("could not convert into bool")
}
fn try_into_bool(self) -> Option<bool>;
}
macro_rules! impl_booleable {
($kind:ty) => {
impl Booleable for $kind {
fn try_into_bool(self) -> Option<bool> {
if self == 1 {
Some(true)
} else if self == 0 {
Some(false)
} else {
None
}
}
fn from_bool(b: bool) -> Self {
if b {
1
} else {
0
}
}
}
};
}
impl_booleable!(u8);
impl_booleable!(u16);
impl_booleable!(u32);
impl_booleable!(u64);
impl_booleable!(usize);
impl_booleable!(i8);
impl_booleable!(i16);
impl_booleable!(i32);
impl_booleable!(i64);
impl_booleable!(isize);
#[derive(Debug, Clone, PartialEq)]
pub enum DataOrSuffStat<'a, X, Fx>
where
X: 'a,
Fx: 'a + HasSuffStat<X>,
{
Data(&'a Vec<X>),
SuffStat(&'a Fx::Stat),
None,
}
impl<'a, X, Fx> DataOrSuffStat<'a, X, Fx>
where
X: 'a,
Fx: 'a + HasSuffStat<X>,
{
pub fn n(&self) -> usize {
match &self {
DataOrSuffStat::Data(data) => data.len(),
DataOrSuffStat::SuffStat(s) => s.n(),
DataOrSuffStat::None => 0,
}
}
pub fn is_data(&self) -> bool {
match &self {
DataOrSuffStat::Data(..) => true,
_ => false,
}
}
pub fn is_suffstat(&self) -> bool {
match &self {
DataOrSuffStat::SuffStat(..) => true,
_ => false,
}
}
pub fn is_none(&self) -> bool {
match &self {
DataOrSuffStat::None => true,
_ => false,
}
}
}