alice-math 0.1.0

A topology and algebra library from first principles
Documentation
use crate::core::scalar::Scalar;
use crate::core::ops::AbelianGroup;

pub trait MetricSpace {
    type Point: Clone + Eq;
    type Distance: Scalar;

    fn distance(&self, a: &Self::Point, b: &Self::Point) -> Self::Distance;

    fn is_positive(&self, a: &Self::Point, b: &Self::Point) -> bool {
        if a == b {
            self.distance(a, b) == Self::Distance::zero()
        } else {
            self.distance(a, b) > Self::Distance::zero()
        }
    }

    fn is_symmetric(&self, a: &Self::Point, b: &Self::Point) -> bool {
        self.distance(a, b) == self.distance(b, a)
    }

    fn satisfies_triangle_inequality(
        &self,
        a: &Self::Point,
        b: &Self::Point,
        c: &Self::Point,
    ) -> bool {
        let ab = self.distance(a, b);
        let bc = self.distance(b, c);
        let ac = self.distance(a, c);
        ac <= ab.add(&bc)
    }
}

pub trait NormedSpace: Sized {
    type Scalar: Scalar;

    fn norm(&self) -> Self::Scalar;

    fn norm_positive(&self) -> bool
    where
        Self: Eq + AbelianGroup,
    {
        if *self == Self::zero() {
            self.norm() == Self::Scalar::zero()
        } else {
            self.norm() > Self::Scalar::zero()
        }
    }

    fn norm_homogeneous(&self, scalar: &Self::Scalar) -> Self::Scalar
    where
        Self: crate::core::module::VectorSpace<Self::Scalar>,
    {
        let scaled = self.scale(scalar);
        scaled.norm()
    }
}

pub trait InnerProductSpace: NormedSpace {
    fn inner_product(&self, other: &Self) -> Self::Scalar;

    fn norm_from_inner(&self) -> Option<Self::Scalar> {
        self.inner_product(self).sqrt()
    }

    fn is_orthogonal(&self, other: &Self) -> bool {
        self.inner_product(other) == Self::Scalar::zero()
    }

    fn is_symmetric_inner(&self, other: &Self) -> bool {
        self.inner_product(other) == other.inner_product(self)
    }
}