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::{Labels, Set};
pub trait Labelled {
fn labels(&self) -> &Labels;
#[inline]
fn label_to_index(&self, x: &str) -> usize {
self.labels()
.get_index_of(x)
.unwrap_or_else(|| panic!("Variable `{x}` label does not exist."))
}
#[inline]
fn index_to_label(&self, x: usize) -> &str {
self.labels()
.get_index(x)
.unwrap_or_else(|| panic!("Variable `{x}` is out of bounds."))
}
#[inline]
fn index_to(&self, x: usize, other: &Labels) -> usize {
let label = self.index_to_label(x);
other.get_index_of(label).unwrap_or_else(|| {
panic!("Variable `{label}` label does not exist in the other model.")
})
}
#[inline]
fn indices_to(&self, x: &Set<usize>, other: &Labels) -> Set<usize> {
x.iter().map(|&x| self.index_to(x, other)).collect()
}
#[inline]
fn index_from(&self, x: usize, other: &Labels) -> usize {
let label = other
.get_index(x)
.unwrap_or_else(|| panic!("Variable `{x}` is out of bounds in the other model."));
self.labels()
.get_index_of(label)
.unwrap_or_else(|| panic!("Variable `{label}` label does not exist."))
}
#[inline]
fn indices_from(&self, x: &Set<usize>, other: &Labels) -> 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 sample_statistics(&self) -> Option<&Self::Statistics>;
fn sample_log_likelihood(&self) -> Option<f64>;
fn pf(&self, x: &Self::Support, z: &Self::Support) -> f64;
fn sample<R: Rng>(&self, rng: &mut R, z: &Self::Support) -> 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 sample_statistics(&self) -> Option<&Self::Statistics>;
fn sample_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) -> Self;
fn marginalize(&self, x: &Set<usize>) -> Self;
fn normalize(&self) -> Self;
fn from_cpd(cpd: Self::CPD) -> Self;
fn into_cpd(self, x: &Set<usize>, z: &Set<usize>) -> Self::CPD;
}