| 16 /// The type should implement vector space operations (addition, subtraction, scalar |
16 /// The type should implement vector space operations (addition, subtraction, scalar |
| 17 /// multiplication and scalar division) along with their assignment versions, as well |
17 /// multiplication and scalar division) along with their assignment versions, as well |
| 18 /// as an inner product. |
18 /// as an inner product. |
| 19 // TODO: remove F parameter, use VectorSpace::Field |
19 // TODO: remove F parameter, use VectorSpace::Field |
| 20 pub trait Euclidean<F: Float = f64>: |
20 pub trait Euclidean<F: Float = f64>: |
| 21 VectorSpace<Field = F, Owned = Self::OwnedEuclidean> |
21 VectorSpace<Field = F, PrincipalV = Self::PrincipalE> + Reflexive<F, DualSpace = Self::PrincipalE> |
| 22 + Reflexive<F, DualSpace = Self::OwnedEuclidean> |
|
| 23 { |
22 { |
| 24 type OwnedEuclidean: ClosedEuclidean<F>; |
23 /// Principal form of the space; always equal to [`Space::Principal`] and |
| |
24 /// [`VectorSpace::PrincipalV`], but with more traits guaranteed. |
| |
25 type PrincipalE: ClosedEuclidean<F>; |
| 25 |
26 |
| 26 // Inner product |
27 // Inner product |
| 27 fn dot<I: Instance<Self>>(&self, other: I) -> F; |
28 fn dot<I: Instance<Self>>(&self, other: I) -> F; |
| 28 |
29 |
| 29 /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$. |
30 /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$. |
| 54 self.dist2_squared(y).sqrt() |
55 self.dist2_squared(y).sqrt() |
| 55 } |
56 } |
| 56 |
57 |
| 57 /// Projection to the 2-ball. |
58 /// Projection to the 2-ball. |
| 58 #[inline] |
59 #[inline] |
| 59 fn proj_ball2(self, ρ: F) -> Self::Owned { |
60 fn proj_ball2(self, ρ: F) -> Self::PrincipalV { |
| 60 let r = self.norm2(); |
61 let r = self.norm2(); |
| 61 if r > ρ { |
62 if r > ρ { |
| 62 self * (ρ / r) |
63 self * (ρ / r) |
| 63 } else { |
64 } else { |
| 64 self.into_owned() |
65 self.into_owned() |
| 65 } |
66 } |
| 66 } |
67 } |
| 67 } |
68 } |
| 68 |
69 |
| 69 pub trait ClosedEuclidean<F: Float = f64>: |
70 pub trait ClosedEuclidean<F: Float = f64>: |
| 70 Instance<Self> + Euclidean<F, OwnedEuclidean = Self> |
71 Instance<Self> + Euclidean<F, PrincipalE = Self> |
| 71 { |
72 { |
| 72 } |
73 } |
| 73 impl<F: Float, X: Instance<X> + Euclidean<F, OwnedEuclidean = Self>> ClosedEuclidean<F> for X {} |
74 impl<F: Float, X: Instance<X> + Euclidean<F, PrincipalE = Self>> ClosedEuclidean<F> for X {} |
| 74 |
75 |
| 75 // TODO: remove F parameter, use AXPY::Field |
76 // TODO: remove F parameter, use AXPY::Field |
| 76 pub trait EuclideanMut<F: Float = f64>: Euclidean<F> + AXPY<Field = F> { |
77 pub trait EuclideanMut<F: Float = f64>: Euclidean<F> + AXPY<Field = F> { |
| 77 /// In-place projection to the 2-ball. |
78 /// In-place projection to the 2-ball. |
| 78 #[inline] |
79 #[inline] |
| 87 impl<X, F: Float> EuclideanMut<F> for X where X: Euclidean<F> + AXPY<Field = F> {} |
88 impl<X, F: Float> EuclideanMut<F> for X where X: Euclidean<F> + AXPY<Field = F> {} |
| 88 |
89 |
| 89 /// Trait for [`Euclidean`] spaces with dimensions known at compile time. |
90 /// Trait for [`Euclidean`] spaces with dimensions known at compile time. |
| 90 pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> { |
91 pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> { |
| 91 /// Returns the origin |
92 /// Returns the origin |
| 92 fn origin() -> <Self as VectorSpace>::Owned; |
93 fn origin() -> <Self as VectorSpace>::PrincipalV; |
| 93 } |
94 } |