src/euclidean.rs

branch
dev
changeset 150
c4e394a9c84c
parent 146
3f9a03f95457
child 151
402d717bb5c0
--- a/src/euclidean.rs	Mon Sep 01 00:04:22 2025 -0500
+++ b/src/euclidean.rs	Mon Sep 01 13:51:03 2025 -0500
@@ -3,13 +3,15 @@
 */
 
 use crate::instance::Instance;
-use crate::linops::AXPY;
+use crate::linops::{VectorSpace, AXPY};
 use crate::norms::{HasDual, Reflexive};
 use crate::types::*;
 use std::ops::{Add, AddAssign, Sub, SubAssign};
 
 pub mod wrap;
 
+// TODO: Euclidean & EuclideanMut
+//
 /// Space (type) with Euclidean and vector space structure
 ///
 /// The type should implement vector space operations (addition, subtraction, scalar
@@ -18,11 +20,11 @@
 // TODO: remove F parameter, use AXPY::Field
 pub trait Euclidean<F: Float = f64>:
     HasDual<F, DualSpace = Self>
-    + AXPY<Field = F>
+    + VectorSpace<Field = F>
     + Reflexive<F>
     // TODO: move the following to AXPY
-    + for<'b> Add<&'b Self, Output = <Self as AXPY>::Owned>
-    + for<'b> Sub<&'b Self, Output = <Self as AXPY>::Owned>
+    + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned>
+    + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned>
     + for<'b> AddAssign<&'b Self>
     + for<'b> SubAssign<&'b Self>
 {
@@ -59,11 +61,20 @@
 
     /// Projection to the 2-ball.
     #[inline]
-    fn proj_ball2(mut self, ρ: F) -> Self {
-        self.proj_ball2_mut(ρ);
-        self
+    fn proj_ball2(self, ρ: F) -> Self::Owned {
+        let r = self.norm2();
+        if r > ρ {
+            self * (ρ / r)
+        } else {
+            self.into_owned()
+        }
     }
+}
 
+// TODO: remove F parameter, use AXPY::Field
+pub trait EuclideanMut<F: Float = f64>:
+    Euclidean<F> + AXPY<Field = F> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self>
+{
     /// In-place projection to the 2-ball.
     #[inline]
     fn proj_ball2_mut(&mut self, ρ: F) {
@@ -74,8 +85,13 @@
     }
 }
 
+impl<X, F: Float> EuclideanMut<F> for X where
+    X: Euclidean<F> + AXPY<Field = F> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self>
+{
+}
+
 /// Trait for [`Euclidean`] spaces with dimensions known at compile time.
 pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> {
     /// Returns the origin
-    fn origin() -> <Self as AXPY>::Owned;
+    fn origin() -> <Self as VectorSpace>::Owned;
 }

mercurial