src/euclidean.rs

changeset 90
b3c35d16affe
parent 64
4f6ca107ccb1
--- a/src/euclidean.rs	Tue Feb 20 12:33:16 2024 -0500
+++ b/src/euclidean.rs	Mon Feb 03 19:22:16 2025 -0500
@@ -2,42 +2,37 @@
 Euclidean spaces.
 */
 
+use std::ops::{Mul, MulAssign, Div, DivAssign, Add, Sub, AddAssign, SubAssign, Neg};
 use crate::types::*;
-use std::ops::{Mul, MulAssign, Div, DivAssign, Add, Sub, AddAssign, SubAssign, Neg};
-
-/// Space (type) with a defined dot product.
-///
-/// `U` is the space of the multiplier, and `F` the space of scalars.
-/// Since `U` ≠ `Self`, this trait can also implement dual products.
-pub trait Dot<U, F> {
-    fn dot(&self, other : &U) -> F;
-}
+use crate::instance::Instance;
+use crate::norms::{HasDual, Reflexive};
 
 /// Space (type) with Euclidean and vector space structure
 ///
 /// The type should implement vector space operations (addition, subtraction, scalar
 /// multiplication and scalar division) along with their assignment versions, as well
-/// as the [`Dot`] product with respect to `Self`.
-pub trait Euclidean<F : Float> : Sized + Dot<Self,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>
-        + AddAssign<Self> + for<'b> AddAssign<&'b Self>
-        + SubAssign<Self> + for<'b> SubAssign<&'b Self>
-        + Neg<Output=<Self as Euclidean<F>>::Output> {
+/// as an inner product.
+pub trait Euclidean<F : Float> : 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>
+    + AddAssign<Self> + for<'b> AddAssign<&'b Self>
+    + SubAssign<Self> + for<'b> SubAssign<&'b Self>
+    + Neg<Output=<Self as Euclidean<F>>::Output>
+{
     type Output : Euclidean<F>;
 
-    /// Returns origin of same dimensions as `self`.
-    fn similar_origin(&self) -> <Self as Euclidean<F>>::Output;
+    // Inner product
+    fn dot<I : Instance<Self>>(&self, other : I) -> F;
 
     /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$.
-    #[inline]
-    fn norm2_squared(&self) -> F {
-        self.dot(self)
-    }
+    ///
+    /// This is not automatically implemented to avoid imposing
+    /// `for <'a> &'a Self : Instance<Self>` trait bound bloat.
+    fn norm2_squared(&self) -> F;
 
     /// Calculate the square of the 2-norm divided by 2, $\frac{1}{2}\\|x\\|_2^2$,
     /// where `self` is $x$.
@@ -53,11 +48,11 @@
     }
 
     /// Calculate the 2-distance squared $\\|x-y\\|_2^2$, where `self` is $x$.
-    fn dist2_squared(&self, y : &Self) -> F;
+    fn dist2_squared<I : Instance<Self>>(&self, y : I) -> F;
 
     /// Calculate the 2-distance $\\|x-y\\|_2$, where `self` is $x$.
     #[inline]
-    fn dist2(&self, y : &Self) -> F {
+    fn dist2<I : Instance<Self>>(&self, y : I) -> F {
         self.dist2_squared(y).sqrt()
     }
 

mercurial