mod bayesian_network;
use std::ops::{DivAssign, MulAssign};
use approx::{AbsDiffEq, RelativeEq};
pub use bayesian_network::*;
mod continuous_time_bayesian_network;
pub use continuous_time_bayesian_network::*;
use itertools::Either;
use rand::Rng;
mod graphs;
use std::fmt::Debug;
pub use graphs::*;
use crate::types::{Error, Labels, Result, Set};
pub trait Labelled {
fn labels(&self) -> &Labels;
#[inline]
fn label_to_index(&self, x: &str) -> Result<usize> {
self.labels()
.get_index_of(x)
.ok_or_else(|| Error::MissingLabel(x))
}
#[inline]
fn index_to_label(&self, x: usize) -> Result<&str> {
self.labels()
.get_index(x)
.map(|x| x.as_str())
.ok_or_else(|| Error::IndexOutOfBounds(x))
}
#[inline]
fn index_to(&self, x: usize, other: &Labels) -> Result<usize> {
let label = self.index_to_label(x)?;
other
.get_index_of(label)
.ok_or_else(|| Error::MissingLabel(label))
}
#[inline]
fn indices_to(&self, x: &Set<usize>, other: &Labels) -> Result<Set<usize>> {
x.iter().map(|&x| self.index_to(x, other)).collect()
}
#[inline]
fn index_from(&self, x: usize, other: &Labels) -> Result<usize> {
let label = other
.get_index(x)
.ok_or_else(|| Error::IndexOutOfBounds(x))?;
self.labels()
.get_index_of(label)
.ok_or_else(|| Error::MissingLabel(label))
}
#[inline]
fn indices_from(&self, x: &Set<usize>, other: &Labels) -> Result<Set<usize>> {
x.iter().map(|&x| self.index_from(x, other)).collect()
}
}
impl<L, R> Labelled for Either<L, R>
where
L: Labelled,
R: Labelled,
{
fn labels(&self) -> &Labels {
match self {
Either::Left(l) => l.labels(),
Either::Right(r) => r.labels(),
}
}
}
pub trait CPD: Clone + Debug + Labelled + PartialEq + AbsDiffEq + RelativeEq {
type Support;
type Parameters;
type Statistics;
fn conditioning_labels(&self) -> &Labels;
fn parameters(&self) -> &Self::Parameters;
fn parameters_size(&self) -> usize;
fn fitted_statistics(&self) -> Option<&Self::Statistics>;
fn fitted_log_likelihood(&self) -> Option<f64>;
fn pf(&self, x: &Self::Support, z: &Self::Support) -> Result<f64>;
fn sample<R: Rng>(&self, rng: &mut R, z: &Self::Support) -> Result<Self::Support>;
}
pub trait CIM: Clone + Debug + Labelled + PartialEq + AbsDiffEq + RelativeEq {
type Support;
type Parameters;
type Statistics;
fn conditioning_labels(&self) -> &Labels;
fn parameters(&self) -> &Self::Parameters;
fn parameters_size(&self) -> usize;
fn fitted_statistics(&self) -> Option<&Self::Statistics>;
fn fitted_log_likelihood(&self) -> Option<f64>;
}
pub trait Phi:
Clone
+ Debug
+ Labelled
+ PartialEq
+ AbsDiffEq
+ RelativeEq
+ for<'a> MulAssign<&'a Self>
+ for<'a> DivAssign<&'a Self>
{
type CPD;
type Parameters;
type Evidence;
fn parameters(&self) -> &Self::Parameters;
fn parameters_size(&self) -> usize;
fn condition(&self, e: &Self::Evidence) -> Result<Self>;
fn marginalize(&self, x: &Set<usize>) -> Result<Self>;
fn normalize(&self) -> Result<Self>;
fn from_cpd(cpd: Self::CPD) -> Result<Self>;
fn into_cpd(self, x: &Set<usize>, z: &Set<usize>) -> Result<Self::CPD>;
}