mod bayesian;
pub use bayesian::*;
mod expectation_maximization;
pub use expectation_maximization::*;
mod maximum_likelihood;
pub use maximum_likelihood::*;
mod sufficient_statistics;
pub use sufficient_statistics::*;
mod raw;
pub use raw::*;
use rayon::prelude::*;
use crate::{
models::{BN, CIM, CPD, CTBN, DiGraph, Graph},
set,
types::{Result, Set},
};
pub trait CSSEstimator<T> {
fn fit(&self, x: &Set<usize>, z: &Set<usize>) -> Result<T>;
}
pub trait ParCSSEstimator<T> {
fn par_fit(&self, x: &Set<usize>, z: &Set<usize>) -> Result<T>;
}
pub trait CPDEstimator<T> {
fn fit(&self, x: &Set<usize>, z: &Set<usize>) -> Result<T>;
}
pub trait ParCPDEstimator<T> {
fn par_fit(&self, x: &Set<usize>, z: &Set<usize>) -> Result<T>;
}
pub trait BNEstimator<T> {
fn fit(&self, graph: DiGraph) -> Result<T>;
}
impl<T, E> BNEstimator<T> for E
where
T: BN,
T::CPD: CPD,
E: CPDEstimator<T::CPD>,
{
fn fit(&self, graph: DiGraph) -> Result<T> {
let cpds: Vec<_> = graph
.vertices()
.into_iter()
.map(|i| {
let i = set![i];
self.fit(&i, &graph.parents(&i)?)
})
.collect::<Result<_>>()?;
T::new(graph, cpds)
}
}
pub trait ParBNEstimator<T> {
fn par_fit(&self, graph: DiGraph) -> Result<T>;
}
impl<T, E> ParBNEstimator<T> for E
where
T: BN,
T::CPD: CPD + Send,
E: ParCPDEstimator<T::CPD> + Sync,
{
fn par_fit(&self, graph: DiGraph) -> Result<T> {
let cpds: Vec<_> = graph
.vertices()
.into_par_iter()
.map(|i| {
let i = set![i];
self.par_fit(&i, &graph.parents(&i)?)
})
.collect::<Result<_>>()?;
T::new(graph, cpds)
}
}
pub trait CTBNEstimator<T> {
fn fit(&self, graph: DiGraph) -> Result<T>;
}
impl<T, E> CTBNEstimator<T> for E
where
T: CTBN,
T::CIM: CIM,
E: CPDEstimator<T::CIM>,
{
fn fit(&self, graph: DiGraph) -> Result<T> {
let cims: Vec<_> = graph
.vertices()
.into_iter()
.map(|i| {
let i = set![i];
self.fit(&i, &graph.parents(&i)?)
})
.collect::<Result<_>>()?;
T::new(graph, cims)
}
}
pub trait ParCTBNEstimator<T> {
fn par_fit(&self, graph: DiGraph) -> Result<T>;
}
impl<T, E> ParCTBNEstimator<T> for E
where
T: CTBN,
T::CIM: CIM + Send,
E: ParCPDEstimator<T::CIM> + Sync,
{
fn par_fit(&self, graph: DiGraph) -> Result<T> {
let cims: Vec<_> = graph
.vertices()
.into_par_iter()
.map(|i| {
let i = set![i];
self.par_fit(&i, &graph.parents(&i)?)
})
.collect::<Result<_>>()?;
T::new(graph, cims)
}
}