src/euclidean.rs

branch
dev
changeset 131
8264d72aa347
parent 124
6aa955ad8122
--- a/src/euclidean.rs	Mon May 12 16:28:50 2025 -0500
+++ b/src/euclidean.rs	Mon May 12 17:10:39 2025 -0500
@@ -3,7 +3,8 @@
 */
 
 use crate::instance::Instance;
-use crate::norms::{HasDual, Reflexive};
+use crate::linops::AXPY;
+use crate::norms::{HasDual, NormExponent, Normed, Reflexive, L2};
 use crate::types::*;
 use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
 
@@ -12,66 +13,68 @@
 /// The type should implement vector space operations (addition, subtraction, scalar
 /// multiplication and scalar division) along with their assignment versions, as well
 /// as an inner product.
-pub trait Euclidean<F: Float = f64>:
-    HasDual<F, DualSpace = Self>
-    + Reflexive<F>
-    + Mul<F, Output = <Self as Euclidean<F>>::Output>
-    + MulAssign<F>
-    + Div<F, Output = <Self as Euclidean<F>>::Output>
-    + DivAssign<F>
-    + Add<Self, Output = <Self as Euclidean<F>>::Output>
-    + Sub<Self, Output = <Self as Euclidean<F>>::Output>
-    + for<'b> Add<&'b Self, Output = <Self as Euclidean<F>>::Output>
-    + for<'b> Sub<&'b Self, Output = <Self as Euclidean<F>>::Output>
+pub trait Euclidean:
+    AXPY<Owned = Self::Owned_>
+    + HasDual<Self::Field, DualSpace = Self>
+    //+ Normed<Self::Field, NormExp = L2>
+    + Reflexive<Self::Field>
+    + Mul<Self::Field, Output = <Self as AXPY>::Owned>
+    + MulAssign<Self::Field>
+    + Div<Self::Field, Output = <Self as AXPY>::Owned>
+    + DivAssign<Self::Field>
+    + Add<Self, Output = <Self as AXPY>::Owned>
+    + Sub<Self, Output = <Self as AXPY>::Owned>
+    + for<'b> Add<&'b Self, Output = <Self as AXPY>::Owned>
+    + for<'b> Sub<&'b Self, Output = <Self as AXPY>::Owned>
     + AddAssign<Self>
     + for<'b> AddAssign<&'b Self>
     + SubAssign<Self>
     + for<'b> SubAssign<&'b Self>
-    + Neg<Output = <Self as Euclidean<F>>::Output>
+    + Neg<Output = <Self as AXPY>::Owned>
 {
-    type Output: Euclidean<F>;
+    type Owned_: Euclidean<Field = Self::Field>;
 
     // Inner product
-    fn dot<I: Instance<Self>>(&self, other: I) -> F;
+    fn dot<I: Instance<Self>>(&self, other: I) -> Self::Field;
 
     /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$.
     ///
     /// This is not automatically implemented to avoid imposing
     /// `for <'a> &'a Self : Instance<Self>` trait bound bloat.
-    fn norm2_squared(&self) -> F;
+    fn norm2_squared(&self) -> Self::Field;
 
     /// Calculate the square of the 2-norm divided by 2, $\frac{1}{2}\\|x\\|_2^2$,
     /// where `self` is $x$.
     #[inline]
-    fn norm2_squared_div2(&self) -> F {
-        self.norm2_squared() / F::TWO
+    fn norm2_squared_div2(&self) -> Self::Field {
+        self.norm2_squared() / Self::Field::TWO
     }
 
     /// Calculate the 2-norm $‖x‖_2$, where `self` is $x$.
     #[inline]
-    fn norm2(&self) -> F {
+    fn norm2(&self) -> Self::Field {
         self.norm2_squared().sqrt()
     }
 
     /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$.
-    fn dist2_squared<I: Instance<Self>>(&self, y: I) -> F;
+    fn dist2_squared<I: Instance<Self>>(&self, y: I) -> Self::Field;
 
     /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$.
     #[inline]
-    fn dist2<I: Instance<Self>>(&self, y: I) -> F {
+    fn dist2<I: Instance<Self>>(&self, y: I) -> Self::Field {
         self.dist2_squared(y).sqrt()
     }
 
     /// Projection to the 2-ball.
     #[inline]
-    fn proj_ball2(mut self, ρ: F) -> Self {
+    fn proj_ball2(mut self, ρ: Self::Field) -> Self {
         self.proj_ball2_mut(ρ);
         self
     }
 
     /// In-place projection to the 2-ball.
     #[inline]
-    fn proj_ball2_mut(&mut self, ρ: F) {
+    fn proj_ball2_mut(&mut self, ρ: Self::Field) {
         let r = self.norm2();
         if r > ρ {
             *self *= ρ / r
@@ -80,7 +83,7 @@
 }
 
 /// Trait for [`Euclidean`] spaces with dimensions known at compile time.
-pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> {
+pub trait StaticEuclidean: Euclidean {
     /// Returns the origin
-    fn origin() -> <Self as Euclidean<F>>::Output;
+    fn origin() -> <Self as AXPY>::Owned;
 }

mercurial