use crate::algebra::field::{ComplexField, Field, RealField};
use crate::algebra::module::Module;
use crate::operators::{ClosedAdd, ClosedMul, ClosedOps};
use std::ops::{Neg, Sub};
pub trait Norm {
type Norm: Field;
}
pub trait VectorSpace: Module<Ring = <Self as VectorSpace>::Field> {
type Field: Field;
}
pub trait NormedSpace: VectorSpace<Field = <Self as NormedSpace>::ComplexField> + Norm {
type ComplexField: ComplexField<RealField = Self::Norm>;
fn norm_squared(&self) -> Self::Norm;
fn norm(&self) -> Self::Norm;
fn normalize(&mut self);
fn normalized(&self) -> Self;
}
pub trait InnerSpace: NormedSpace {
fn inner_product(&self, other: &Self) -> Self::ComplexField;
fn angle(&self, other: &Self) -> Self::Norm;
}
pub trait AffineSpace:
Sized
+ PartialEq
+ Sub<Self, Output = <Self as AffineSpace>::Translation>
+ ClosedAdd<<Self as AffineSpace>::Translation>
{
type Translation: VectorSpace;
fn translate_by(&self, translation: &Self::Translation) -> Self;
fn subtract(&self, rhs: &Self) -> Self::Translation;
}
pub trait EuclideanSpace:
AffineSpace<Translation = <Self as EuclideanSpace>::Coordinates>
+ ClosedMul<<Self as EuclideanSpace>::RealField>
+ Neg<Output = Self>
{
type Coordinates: InnerSpace<ComplexField = Self::RealField, Norm = Self::RealField>
+ ClosedOps<Self::Coordinates>
+ ClosedOps<Self::RealField>;
type RealField: RealField;
const ORIGIN: Self;
fn scale_by(&self, scalar: Self::RealField) -> Self {
Self::from_coordinates(self.coordinates() * scalar)
}
#[inline]
fn coordinates(&self) -> Self::Coordinates {
self.subtract(&Self::ORIGIN)
}
#[inline]
fn from_coordinates(coordinates: Self::Coordinates) -> Self {
Self::ORIGIN.translate_by(&coordinates)
}
#[inline]
fn distance_squared(&self, b: &Self) -> Self::RealField {
self.subtract(b).norm_squared()
}
#[inline]
fn distance(&self, b: &Self) -> Self::RealField {
self.subtract(b).norm()
}
}
macro_rules! impl_vector_space {
($($set:ident)*) => {
$(
impl Norm for $set {
type Norm = $set;
}
impl VectorSpace for $set {
type Field = $set;
}
impl NormedSpace for $set {
type ComplexField = $set;
#[inline]
fn norm_squared(&self) -> Self::Norm {
self.modulus_squared()
}
#[inline]
fn norm(&self) -> Self::Norm {
self.modulus()
}
#[inline]
fn normalize(&mut self) {
*self /= self.norm();
}
#[inline]
fn normalized(&self) -> Self {
*self / self.norm()
}
}
)*
}
}
impl_vector_space!(f32 f64);