prodef 0.1.0

A simple Rust crate for handling probability distributions.
Documentation
//! Types and traits for representing function domains.

mod domm;
mod doms;

pub use domm::*;
pub use doms::*;

use nalgebra::{
    DefaultAllocator, Dim, OVector, RealField, Scalar, U1, VectorView, allocator::Allocator,
};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;

/// A trait that is shared by all types that represent a function domain.
pub trait Domain<T, D>: Clone + Debug + PartialEq + Send + Sync
where
    T: Scalar,
    D: Dim,
    DefaultAllocator: Allocator<D>,
{
    /// Clip `sample`` to be contained within the domain.
    ///
    /// This function returns the input value if the given
    /// sample is already contained within the domain.
    fn clip<RStride: Dim, CStride: Dim>(
        &self,
        sample: &VectorView<T, D, RStride, CStride>,
    ) -> OVector<T, D>;

    /// Returns `true` if the sample is contained within the domain.
    fn contains<RStride: Dim, CStride: Dim>(
        &self,
        sample: &VectorView<T, D, RStride, CStride>,
    ) -> bool;

    /// Returns the maximum value of the domain along each dimension.
    fn maximum_values(&self) -> Option<OVector<T, D>>;

    /// Returns the minimum value of the domain along each dimension.
    fn minimum_values(&self) -> Option<OVector<T, D>>;

    /// Returns the maximum size of the domain along each dimension.
    fn size(&self) -> OVector<Option<T>, D>
    where
        T: RealField;
}

/// An unbounded domain.
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct UDomain<D>(D);

impl<D> UDomain<D> {
    /// Create a new unbounded domain.
    pub fn new(dim: D) -> Self {
        UDomain(dim)
    }
}

impl<T, D> Domain<T, D> for UDomain<D>
where
    T: PartialOrd + Scalar,
    D: Dim,
    DefaultAllocator: Allocator<D>,
{
    fn clip<RStride: Dim, CStride: Dim>(
        &self,
        sample: &VectorView<T, D, RStride, CStride>,
    ) -> OVector<T, D> {
        sample.clone_owned()
    }

    fn contains<RStride: Dim, CStride: Dim>(
        &self,
        _sample: &VectorView<T, D, RStride, CStride>,
    ) -> bool {
        true
    }

    fn maximum_values(&self) -> Option<OVector<T, D>> {
        None
    }

    fn minimum_values(&self) -> Option<OVector<T, D>> {
        None
    }

    fn size(&self) -> OVector<Option<T>, D> {
        OVector::<Option<T>, D>::from_element_generic(self.0, U1, None)
    }
}