hypergraphx 0.0.5

A hypergraph library for Rust, based on the Python library of the same name.
Documentation
//! From petgraph.

use core::{fmt::Debug, ops::Add};

/// Associated data that can be used for measures (such as length).
pub trait Measure: Debug + PartialOrd + Add<Self, Output = Self> + Default + Clone {}

impl<M> Measure for M where M: Debug + PartialOrd + Add<M, Output = M> + Default + Clone {}

/// A floating-point measure.
pub trait FloatMeasure: Measure + Copy {
    fn zero() -> Self;
    fn infinite() -> Self;
}

impl FloatMeasure for f32 {
    fn zero() -> Self {
        0.
    }
    fn infinite() -> Self {
        1. / 0.
    }
}

impl FloatMeasure for f64 {
    fn zero() -> Self {
        0.
    }
    fn infinite() -> Self {
        1. / 0.
    }
}

pub trait BoundedMeasure: Measure + std::ops::Sub<Self, Output = Self> {
    fn min() -> Self;
    fn max() -> Self;
    fn overflowing_add(self, rhs: Self) -> (Self, bool);
}

macro_rules! impl_bounded_measure_integer(
    ( $( $t:ident ),* ) => {
        $(
            impl BoundedMeasure for $t {
                fn min() -> Self {
                    std::$t::MIN
                }

                fn max() -> Self {
                    std::$t::MAX
                }

                fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                    self.overflowing_add(rhs)
                }
            }
        )*
    };
);

impl_bounded_measure_integer!(
    u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
);

macro_rules! impl_bounded_measure_float(
    ( $( $t:ident ),* ) => {
        $(
            impl BoundedMeasure for $t {
                fn min() -> Self {
                    std::$t::MIN
                }

                fn max() -> Self {
                    std::$t::MAX
                }

                fn overflowing_add(self, rhs: Self) -> (Self, bool) {
                    // for an overflow: a + b > max: both values need to be positive and a > max - b must be satisfied
                    let overflow = self > Self::default() && rhs > Self::default() && self > std::$t::MAX - rhs;

                    // for an underflow: a + b < min: overflow can not happen and both values must be negative and a < min - b must be satisfied
                    let underflow = !overflow && self < Self::default() && rhs < Self::default() && self < std::$t::MIN - rhs;

                    (self + rhs, overflow || underflow)
                }
            }
        )*
    };
);

impl_bounded_measure_float!(f32, f64);

/// A floating-point measure that can be computed from `usize`
/// and with a default measure of proximity.  
pub trait UnitMeasure:
    Measure
    + std::ops::Sub<Self, Output = Self>
    + std::ops::Mul<Self, Output = Self>
    + std::ops::Div<Self, Output = Self>
    + std::iter::Sum
{
    fn zero() -> Self;
    fn one() -> Self;
    fn from_usize(nb: usize) -> Self;
    fn default_tol() -> Self;
}

macro_rules! impl_unit_measure(
    ( $( $t:ident ),* )=> {
        $(
            impl UnitMeasure for $t {
                fn zero() -> Self {
                    0 as $t
                }
                fn one() -> Self {
                    1 as $t
                }

                fn from_usize(nb: usize) -> Self {
                    nb as $t
                }

                fn default_tol() -> Self {
                    1e-6 as $t
                }

            }

        )*
    }
);
impl_unit_measure!(f32, f64);

/// Some measure of positive numbers, assuming positive
/// float-pointing numbers
pub trait PositiveMeasure: Measure + Copy {
    fn zero() -> Self;
    fn max() -> Self;
}

macro_rules! impl_positive_measure(
    ( $( $t:ident ),* )=> {
        $(
            impl PositiveMeasure for $t {
                fn zero() -> Self {
                    0 as $t
                }
                fn max() -> Self {
                    std::$t::MAX
                }
            }

        )*
    }
);

impl_positive_measure!(u8, u16, u32, u64, u128, usize, f32, f64);