Add traits `Distance` and `Norm` in order to provide abstract notions of distances between numbers.
The `Norm` trait provides a `norm` function for types that represent a normed vector space – e.g. the absolute value of a float or the norm of a complex number. The `Distance` trait provides a `distance` function to still calculate the distance between two values if no sensible norm can be defined.
This commit is contained in:
parent
58f02a8677
commit
bef01a8a86
|
@ -0,0 +1,73 @@
|
|||
use std::ops::{Sub, Div, DivAssign};
|
||||
|
||||
use {Num};
|
||||
|
||||
pub trait Distance {
|
||||
type Output: Num;
|
||||
fn distance(&self, other: &Self) -> Self::Output;
|
||||
}
|
||||
|
||||
pub trait Norm: Sized {
|
||||
type Output: Num;
|
||||
fn norm(&self) -> <Self as Norm>::Output;
|
||||
}
|
||||
|
||||
pub fn normalize<T: Norm<Output=R> + DivAssign<R>, R: Num>(v: &mut T) {
|
||||
*v /= v.norm();
|
||||
}
|
||||
|
||||
pub fn normalized<T: Norm<Output=R> + Div<R, Output=T>, R: Num>(v: T) -> T {
|
||||
let norm = v.norm();
|
||||
v / norm
|
||||
}
|
||||
|
||||
impl<T: Copy + Norm + Sub<Self, Output=Self>> Distance for T{
|
||||
type Output = <Self as Norm>::Output;
|
||||
fn distance(&self, other: &Self) -> <Self as Distance>::Output {
|
||||
(*self - *other).norm()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
macro_rules! norm_impl_self {
|
||||
($($t:ty)*) => ($(
|
||||
impl Norm for $t {
|
||||
type Output = Self;
|
||||
fn norm(&self) -> <Self as Norm>::Output {
|
||||
*self
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! norm_impl_abs {
|
||||
($($t:ty)*) => ($(
|
||||
impl Norm for $t {
|
||||
type Output = Self;
|
||||
fn norm(&self) -> <Self as Norm>::Output {
|
||||
self.abs()
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! norm_impl_unsigned_output {
|
||||
($($t:ty, $out:ty);*) => ($(
|
||||
impl Norm for $t {
|
||||
type Output = $out;
|
||||
fn norm(&self) -> <Self as Norm>::Output {
|
||||
self.abs() as $out
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
norm_impl_abs!(f32 f64);
|
||||
norm_impl_unsigned_output!(i8, u8; i16, u16; i32, u32; i64, u64; isize, usize);
|
||||
norm_impl_self!(u8 u16 u32 u64 usize);
|
||||
|
||||
#[cfg(has_i128)]
|
||||
norm_impl_unsigned_output!(i128, u128);
|
||||
|
||||
#[cfg(has_u128)]
|
||||
norm_impl_self!(u128);
|
|
@ -48,6 +48,7 @@ mod macros;
|
|||
|
||||
pub mod bounds;
|
||||
pub mod cast;
|
||||
pub mod dist;
|
||||
pub mod float;
|
||||
pub mod identities;
|
||||
pub mod int;
|
||||
|
|
Loading…
Reference in New Issue