Tue, 02 Sep 2025 08:01:57 -0500
matrix fubar
| 5 | 1 | /*! |
| 2 | Euclidean spaces. | |
| 3 | */ | |
| 4 | ||
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
5 | use crate::instance::Instance; |
| 150 | 6 | use crate::linops::{VectorSpace, AXPY}; |
| 151 | 7 | use crate::norms::Reflexive; |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
8 | use crate::types::*; |
| 5 | 9 | |
| 146 | 10 | pub mod wrap; |
| 11 | ||
| 150 | 12 | // TODO: Euclidean & EuclideanMut |
| 13 | // | |
| 5 | 14 | /// Space (type) with Euclidean and vector space structure |
| 15 | /// | |
| 16 | /// The type should implement vector space operations (addition, subtraction, scalar | |
| 17 | /// multiplication and scalar division) along with their assignment versions, as well | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
18 | /// as an inner product. |
| 151 | 19 | // TODO: remove F parameter, use VectorSpace::Field |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
20 | pub trait Euclidean<F: Float = f64>: |
| 151 | 21 | VectorSpace<Field = F, Owned = Self::OwnedEuclidean> |
| 22 | + Reflexive<F, DualSpace = Self::OwnedEuclidean> | |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
23 | { |
| 151 | 24 | type OwnedEuclidean: ClosedEuclidean<F>; |
| 25 | ||
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
26 | // Inner product |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
27 | fn dot<I: Instance<Self>>(&self, other: I) -> F; |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
28 | |
| 5 | 29 | /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$. |
|
63
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
30 | /// |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
31 | /// This is not automatically implemented to avoid imposing |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
32 | /// `for <'a> &'a Self : Instance<Self>` trait bound bloat. |
|
f7b87d84864d
Extra reflexivity and hilbert-like requirements for Euclidean. Fuse Dot into Euclidean.
Tuomo Valkonen <tuomov@iki.fi>
parents:
62
diff
changeset
|
33 | fn norm2_squared(&self) -> F; |
| 5 | 34 | |
| 35 | /// Calculate the square of the 2-norm divided by 2, $\frac{1}{2}\\|x\\|_2^2$, | |
| 36 | /// where `self` is $x$. | |
| 37 | #[inline] | |
| 38 | fn norm2_squared_div2(&self) -> F { | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
39 | self.norm2_squared() / F::TWO |
| 5 | 40 | } |
| 41 | ||
| 42 | /// Calculate the 2-norm $‖x‖_2$, where `self` is $x$. | |
| 43 | #[inline] | |
| 44 | fn norm2(&self) -> F { | |
| 45 | self.norm2_squared().sqrt() | |
| 46 | } | |
| 47 | ||
| 48 | /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$. | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
49 | fn dist2_squared<I: Instance<Self>>(&self, y: I) -> F; |
| 5 | 50 | |
| 51 | /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$. | |
| 52 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
53 | fn dist2<I: Instance<Self>>(&self, y: I) -> F { |
| 5 | 54 | self.dist2_squared(y).sqrt() |
| 55 | } | |
| 56 | ||
| 57 | /// Projection to the 2-ball. | |
| 58 | #[inline] | |
| 150 | 59 | fn proj_ball2(self, ρ: F) -> Self::Owned { |
| 60 | let r = self.norm2(); | |
| 61 | if r > ρ { | |
| 62 | self * (ρ / r) | |
| 63 | } else { | |
| 64 | self.into_owned() | |
| 65 | } | |
| 5 | 66 | } |
| 150 | 67 | } |
| 5 | 68 | |
| 151 | 69 | pub trait ClosedEuclidean<F: Float = f64>: |
| 70 | Instance<Self> + Euclidean<F, OwnedEuclidean = Self> | |
| 71 | { | |
| 72 | } | |
| 73 | impl<F: Float, X: Instance<X> + Euclidean<F, OwnedEuclidean = Self>> ClosedEuclidean<F> for X {} | |
| 74 | ||
| 150 | 75 | // TODO: remove F parameter, use AXPY::Field |
| 151 | 76 | pub trait EuclideanMut<F: Float = f64>: Euclidean<F> + AXPY<Field = F> { |
| 5 | 77 | /// In-place projection to the 2-ball. |
| 78 | #[inline] | |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
79 | fn proj_ball2_mut(&mut self, ρ: F) { |
| 5 | 80 | let r = self.norm2(); |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
81 | if r > ρ { |
|
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
82 | *self *= ρ / r |
| 5 | 83 | } |
| 84 | } | |
| 85 | } | |
| 86 | ||
| 151 | 87 | impl<X, F: Float> EuclideanMut<F> for X where X: Euclidean<F> + AXPY<Field = F> {} |
| 150 | 88 | |
| 5 | 89 | /// Trait for [`Euclidean`] spaces with dimensions known at compile time. |
|
124
6aa955ad8122
Transpose loc parameters to allow f64 defaults
Tuomo Valkonen <tuomov@iki.fi>
parents:
64
diff
changeset
|
90 | pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> { |
| 5 | 91 | /// Returns the origin |
| 150 | 92 | fn origin() -> <Self as VectorSpace>::Owned; |
| 5 | 93 | } |