src/loc.rs

branch
dev
changeset 150
c4e394a9c84c
parent 145
0b9aecd7bb76
child 151
402d717bb5c0
--- a/src/loc.rs	Mon Sep 01 00:04:22 2025 -0500
+++ b/src/loc.rs	Mon Sep 01 13:51:03 2025 -0500
@@ -4,8 +4,8 @@
 */
 
 use crate::euclidean::*;
-use crate::instance::{BasicDecomposition, Instance};
-use crate::linops::{Linear, Mapping, AXPY};
+use crate::instance::{BasicDecomposition, Instance, Ownable};
+use crate::linops::{Linear, Mapping, VectorSpace, AXPY};
 use crate::mapping::Space;
 use crate::maputil::{map1, map1_mut, map2, map2_mut, FixedLength, FixedLengthMut};
 use crate::norms::*;
@@ -27,6 +27,21 @@
     pub [F; N],
 );
 
+/// Trait for ownable-by-consumption objects
+impl<const N: usize, F: Copy> Ownable for Loc<N, F> {
+    type OwnedVariant = Self;
+
+    #[inline]
+    fn into_owned(self) -> Self::OwnedVariant {
+        self
+    }
+
+    /// Returns an owned instance of a reference.
+    fn clone_owned(&self) -> Self::OwnedVariant {
+        self.clone()
+    }
+}
+
 impl<F: Display, const N: usize> Display for Loc<N, F> {
     // Required method
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
@@ -648,6 +663,14 @@
 
 impl<F: Float, const N: usize> Projection<F, Linfinity> for Loc<N, F> {
     #[inline]
+    fn proj_ball(mut self, ρ: F, exp: Linfinity) -> Self {
+        self.proj_ball_mut(ρ, exp);
+        self
+    }
+}
+
+impl<F: Float, const N: usize> ProjectionMut<F, Linfinity> for Loc<N, F> {
+    #[inline]
     fn proj_ball_mut(&mut self, ρ: F, _: Linfinity) {
         self.iter_mut()
             .for_each(|v| *v = num_traits::clamp(*v, -ρ, ρ))
@@ -706,6 +729,7 @@
 }
 
 impl<F: Num, const N: usize> Space for Loc<N, F> {
+    type OwnedSpace = Self;
     type Decomp = BasicDecomposition;
 }
 
@@ -719,10 +743,32 @@
 
 impl<F: Float, const N: usize> Linear<Loc<N, F>> for Loc<N, F> {}
 
-impl<F: Float, const N: usize> AXPY<Loc<N, F>> for Loc<N, F> {
+impl<F: Float, const N: usize> VectorSpace for Loc<N, F> {
     type Field = F;
     type Owned = Self;
 
+    // #[inline]
+    // fn make_origin_generator(&self) -> StaticEuclideanOriginGenerator {
+    //     StaticEuclideanOriginGenerator
+    // }
+
+    #[inline]
+    fn similar_origin(&self) -> Self::Owned {
+        Self::ORIGIN
+    }
+
+    #[inline]
+    fn similar_origin_inst<I: Instance<Self>>(_: I) -> Self::Owned {
+        Self::ORIGIN
+    }
+
+    // #[inline]
+    // fn into_owned(self) -> Self::Owned {
+    //     self
+    // }
+}
+
+impl<F: Float, const N: usize> AXPY<Loc<N, F>> for Loc<N, F> {
     #[inline]
     fn axpy<I: Instance<Loc<N, F>>>(&mut self, α: F, x: I, β: F) {
         x.eval(|x̃| {
@@ -739,21 +785,6 @@
         x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi))
     }
 
-    // #[inline]
-    // fn make_origin_generator(&self) -> StaticEuclideanOriginGenerator {
-    //     StaticEuclideanOriginGenerator
-    // }
-
-    #[inline]
-    fn similar_origin(&self) -> Self::Owned {
-        Self::ORIGIN
-    }
-
-    #[inline]
-    fn similar_origin_inst<I: Instance<Self>>(_: I) -> Self::Owned {
-        Self::ORIGIN
-    }
-
     #[inline]
     fn set_zero(&mut self) {
         *self = Self::ORIGIN;

mercurial