fructose/algebra/linear/
vector.rs

1use crate::algebra::field::{ComplexField, Field, RealField};
2use crate::algebra::module::Module;
3use crate::operators::{ClosedAdd, ClosedMul, ClosedOps};
4use std::ops::{Neg, Sub};
5
6pub trait Norm {
7    type Norm: Field;
8}
9
10pub trait VectorSpace: Module<Ring = <Self as VectorSpace>::Field> {
11    type Field: Field;
12}
13
14pub trait NormedSpace: VectorSpace<Field = <Self as NormedSpace>::ComplexField> + Norm {
15    type ComplexField: ComplexField<RealField = Self::Norm>;
16
17    /// essentially magnitude squared
18    fn norm_squared(&self) -> Self::Norm;
19
20    /// essentially magnitude
21    fn norm(&self) -> Self::Norm;
22
23    fn normalize(&mut self);
24
25    fn normalized(&self) -> Self;
26}
27
28pub trait InnerSpace: NormedSpace {
29    fn inner_product(&self, other: &Self) -> Self::ComplexField;
30
31    fn angle(&self, other: &Self) -> Self::Norm;
32}
33
34pub trait AffineSpace:
35    Sized
36    + PartialEq
37    + Sub<Self, Output = <Self as AffineSpace>::Translation>
38    + ClosedAdd<<Self as AffineSpace>::Translation>
39{
40    type Translation: VectorSpace;
41
42    fn translate_by(&self, translation: &Self::Translation) -> Self;
43
44    fn subtract(&self, rhs: &Self) -> Self::Translation;
45}
46
47pub trait EuclideanSpace:
48    AffineSpace<Translation = <Self as EuclideanSpace>::Coordinates>
49    + ClosedMul<<Self as EuclideanSpace>::RealField>
50    + Neg<Output = Self>
51{
52    type Coordinates: InnerSpace<ComplexField = Self::RealField, Norm = Self::RealField>
53        + ClosedOps<Self::Coordinates>
54        + ClosedOps<Self::RealField>;
55
56    type RealField: RealField;
57
58    const ORIGIN: Self;
59
60    fn scale_by(&self, scalar: Self::RealField) -> Self {
61        Self::from_coordinates(self.coordinates() * scalar)
62    }
63
64    #[inline]
65    fn coordinates(&self) -> Self::Coordinates {
66        self.subtract(&Self::ORIGIN)
67    }
68
69    #[inline]
70    fn from_coordinates(coordinates: Self::Coordinates) -> Self {
71        Self::ORIGIN.translate_by(&coordinates)
72    }
73
74    #[inline]
75    fn distance_squared(&self, b: &Self) -> Self::RealField {
76        self.subtract(b).norm_squared()
77    }
78
79    #[inline]
80    fn distance(&self, b: &Self) -> Self::RealField {
81        self.subtract(b).norm()
82    }
83}
84
85macro_rules! impl_vector_space {
86    ($($set:ident)*) => {
87        $(
88            impl Norm for $set {
89                type Norm = $set;
90            }
91
92            impl VectorSpace for $set {
93                type Field = $set;
94            }
95
96            impl NormedSpace for $set {
97                type ComplexField = $set;
98
99                #[inline]
100                fn norm_squared(&self) -> Self::Norm {
101                    self.modulus_squared()
102                }
103
104                #[inline]
105                fn norm(&self) -> Self::Norm {
106                    self.modulus()
107                }
108
109                #[inline]
110                fn normalize(&mut self) {
111                    *self /= self.norm();
112                }
113
114                #[inline]
115                fn normalized(&self) -> Self {
116                    *self / self.norm()
117                }
118            }
119        )*
120    }
121}
122
123impl_vector_space!(f32 f64);