#![warn(missing_docs)]
use adapters::*;
use num_traits::{identities, Float};
use rand_pcg::Pcg32;
use reference::RefUncertain;
mod adapters;
mod boxed;
mod dist;
mod expectation;
mod point;
mod reference;
mod sprt;
pub use boxed::BoxedUncertain;
pub use dist::Distribution;
pub use point::PointMass;
pub use expectation::ConvergenceError;
pub(crate) type Rng = Pcg32;
#[must_use = "uncertain values are lazy and do nothing unless queried"]
pub trait Uncertain {
type Value;
fn sample(&self, rng: &mut Rng, epoch: usize) -> Self::Value;
fn pr(&self, probability: f32) -> bool
where
Self::Value: Into<bool>,
{
if probability <= 0.0 || probability >= 1.0 {
panic!("Probability {:?} must be in (0, 1)", probability);
}
sprt::compute(self, probability)
}
fn expect(&self, precision: Self::Value) -> Result<Self::Value, ConvergenceError<Self::Value>>
where
Self::Value: Float,
{
if precision <= identities::zero() {
panic!("Precision must be larger than 0");
}
expectation::compute(self, precision)
}
fn into_boxed(self) -> BoxedUncertain<Self::Value>
where
Self: 'static + Sized + Send,
{
BoxedUncertain::new(self)
}
fn into_ref(self) -> RefUncertain<Self>
where
Self: Sized,
Self::Value: Clone,
{
RefUncertain::new(self)
}
fn map<O, F>(self, func: F) -> Map<Self, F>
where
Self: Sized,
F: Fn(Self::Value) -> O,
{
Map::new(self, func)
}
fn flat_map<O, F>(self, func: F) -> FlatMap<Self, F>
where
Self: Sized,
O: Uncertain,
F: Fn(Self::Value) -> O,
{
FlatMap::new(self, func)
}
fn join<O, U, F>(self, other: U, func: F) -> Join<Self, U, F>
where
Self: Sized,
U: Uncertain,
F: Fn(Self::Value, U::Value) -> O,
{
Join::new(self, other, func)
}
fn not(self) -> Not<Self>
where
Self: Sized,
Self::Value: Into<bool>,
{
Not::new(self)
}
fn and<U>(self, other: U) -> And<Self, U>
where
Self: Sized,
Self::Value: Into<bool>,
U: Uncertain,
U::Value: Into<bool>,
{
And::new(self, other)
}
fn or<U>(self, other: U) -> Or<Self, U>
where
Self: Sized,
Self::Value: Into<bool>,
U: Uncertain,
U::Value: Into<bool>,
{
Or::new(self, other)
}
fn add<U>(self, other: U) -> Sum<Self, U>
where
Self: Sized,
U: Uncertain,
Self::Value: std::ops::Add<U::Value>,
{
Sum::new(self, other)
}
fn sub<U>(self, other: U) -> Difference<Self, U>
where
Self: Sized,
U: Uncertain,
Self::Value: std::ops::Sub<U::Value>,
{
Difference::new(self, other)
}
fn mul<U>(self, other: U) -> Product<Self, U>
where
Self: Sized,
U: Uncertain,
Self::Value: std::ops::Mul<U::Value>,
{
Product::new(self, other)
}
fn div<U>(self, other: U) -> Ratio<Self, U>
where
Self: Sized,
U: Uncertain,
Self::Value: std::ops::Div<U::Value>,
{
Ratio::new(self, other)
}
}