代数 - 超数
全順序付き群(整数など)に \(\pm \infty\) を付加した数.
/// Algebra - Hyper Numbers (numbers with infinity)
use crate::algebra::group::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Hyper<X> {
NegInf,
Real(X),
Inf,
}
use Hyper::{Inf, NegInf, Real};
impl<X> Hyper<X> {
pub fn unwrap(self) -> X {
if let Hyper::Real(x) = self {
x
} else {
panic!()
}
}
}
impl<X: Group> std::ops::Add for Hyper<X> {
type Output = Self;
fn add(self, rhs: Hyper<X>) -> Hyper<X> {
match (self, rhs) {
(Real(x), Real(y)) => Real(x + y),
(Inf, _) => Inf,
(_, Inf) => Inf,
_ => NegInf,
}
}
}
impl<X: Group> std::ops::Sub for Hyper<X> {
type Output = Self;
fn sub(self, rhs: Hyper<X>) -> Hyper<X> {
self + (-rhs)
}
}
impl<X: Group> std::ops::Neg for Hyper<X> {
type Output = Self;
fn neg(self) -> Hyper<X> {
match self {
Inf => NegInf,
NegInf => Inf,
Real(x) => Real(-x),
}
}
}
impl<X: Group> std::iter::Sum for Hyper<X> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Hyper::zero(), std::ops::Add::add)
}
}
impl<X: Group> Group for Hyper<X> {
fn zero() -> Self {
Hyper::Real(X::zero())
}
}
impl<X: Group> std::ops::Add<X> for Hyper<X> {
type Output = Self;
fn add(self, other: X) -> Self {
match self {
Inf => Inf,
NegInf => NegInf,
Real(x) => Real(x + other),
}
}
}
#[cfg(test)]
mod test_hyper {
use crate::algebra::hyper::*;
#[test]
fn it_works() {
assert_eq!(Hyper::<i32>::zero(), Hyper::Real(0));
assert_eq!(Hyper::Real(42).unwrap(), 42);
assert!(Hyper::Real(0_i32) < Hyper::Real(1));
assert!(Hyper::NegInf < Hyper::Real(1));
assert!(Hyper::Real(0) < Hyper::Inf);
assert!(Hyper::<i32>::NegInf < Hyper::Inf);
assert_eq!(Hyper::Real(1) + 3, Hyper::Real(4));
}
}