Move origin stuff to AXPY form Euclidean dev

Sat, 21 Dec 2024 23:32:20 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sat, 21 Dec 2024 23:32:20 -0500
branch
dev
changeset 62
d8305c9b6fdf
parent 61
05089fbc0310
child 63
f7b87d84864d

Move origin stuff to AXPY form Euclidean

src/direct_product.rs file | annotate | diff | comparison | revisions
src/euclidean.rs file | annotate | diff | comparison | revisions
src/linops.rs file | annotate | diff | comparison | revisions
src/loc.rs file | annotate | diff | comparison | revisions
src/nalgebra_support.rs file | annotate | diff | comparison | revisions
src/types.rs file | annotate | diff | comparison | revisions
--- a/src/direct_product.rs	Tue Dec 31 08:30:43 2024 -0500
+++ b/src/direct_product.rs	Sat Dec 21 23:32:20 2024 -0500
@@ -270,10 +270,6 @@
 {
     type Output = PairOutput<F, A, B>;
 
-    fn similar_origin(&self) -> PairOutput<F, A, B> {
-        Pair(self.0.similar_origin(), self.1.similar_origin())
-    }
-
     fn dist2_squared(&self, Pair(ref u, ref v) : &Self) -> F {
         self.0.dist2_squared(u) + self.1.dist2_squared(v)
     }
@@ -285,9 +281,14 @@
     V : Space,
     A : AXPY<F, U>,
     B : AXPY<F, V>,
-    F : Num
+    F : Num,
+    Self : MulAssign<F>,
+    Pair<A, B> :  MulAssign<F>,
+    Pair<A::Owned, B::Owned> : AXPY<F, Pair<U, V>>,
 {
 
+    type Owned = Pair<A::Owned, B::Owned>;
+
     fn axpy<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I, β : F) {
         let Pair(u, v) = x.decompose();
         self.0.axpy(α, u, β);
@@ -305,6 +306,17 @@
         self.0.scale_from(α, u);
         self.1.scale_from(α, v);
     }
+
+    /// Return a similar zero as `self`.
+    fn similar_origin(&self) -> Self::Owned {
+        Pair(self.0.similar_origin(), self.1.similar_origin())
+    }
+
+    /// Set self to zero.
+    fn set_zero(&mut self) {
+        self.0.set_zero();
+        self.1.set_zero();
+    }
 }
 
 /// [`Decomposition`] for working with [`Pair`]s.
--- a/src/euclidean.rs	Tue Dec 31 08:30:43 2024 -0500
+++ b/src/euclidean.rs	Sat Dec 21 23:32:20 2024 -0500
@@ -31,9 +31,6 @@
         + 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;
-
     /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$.
     #[inline]
     fn norm2_squared(&self) -> F {
--- a/src/linops.rs	Tue Dec 31 08:30:43 2024 -0500
+++ b/src/linops.rs	Sat Dec 21 23:32:20 2024 -0500
@@ -17,11 +17,13 @@
 
 /// Efficient in-place summation.
 #[replace_float_literals(F::cast_from(literal))]
-pub trait AXPY<F, X = Self> : Space
+pub trait AXPY<F, X = Self> : Space + std::ops::MulAssign<F>
 where
     F : Num,
     X : Space,
 {
+    type Owned : AXPY<F, X>;
+
     /// Computes  `y = βy + αx`, where `y` is `Self`.
     fn axpy<I : Instance<X>>(&mut self, α : F, x : I, β : F);
 
@@ -34,6 +36,12 @@
     fn scale_from<I : Instance<X>>(&mut self, α : F, x : I) {
         self.axpy(α, x, 0.0)
     }
+
+    /// Return a similar zero as `self`.
+    fn similar_origin(&self) -> Self::Owned;
+
+    /// Set self to zero.
+    fn set_zero(&mut self);
 }
 
 /// Efficient in-place application for [`Linear`] operators.
--- a/src/loc.rs	Tue Dec 31 08:30:43 2024 -0500
+++ b/src/loc.rs	Sat Dec 21 23:32:20 2024 -0500
@@ -443,11 +443,6 @@
 impl<F : Float,const N : usize> Euclidean<F> for Loc<F, N> {
     type Output = Self;
 
-    #[inline]
-    fn similar_origin(&self) -> Self {
-        Self::ORIGIN
-    }
-
     /// This implementation is not stabilised as it's meant to be used for very small vectors.
     /// Use [`nalgebra`] for larger vectors.
     #[inline]
@@ -712,6 +707,8 @@
 impl<F : Num, const N : usize> Linear<Loc<F, N>> for Loc<F, N> { }
 
 impl<F : Num, const N : usize> AXPY<F, Loc<F, N>> for Loc<F, N> {
+    type Owned = Self;
+
     #[inline]
     fn axpy<I : Instance<Loc<F, N>>>(&mut self, α : F, x : I, β : F) {
         x.eval(|x̃| {
@@ -727,4 +724,15 @@
     fn copy_from<I : Instance<Loc<F, N>>>(&mut self, x : I) {
         x.eval(|x̃| map2_mut(self, x̃, |yi, xi| *yi = *xi ))
     }
+
+    #[inline]
+    fn similar_origin(&self) -> Self::Owned {
+        Self::ORIGIN
+    }
+
+    #[inline]
+    fn set_zero(&mut self) {
+        *self = Self::ORIGIN;
+    }
 }
+
--- a/src/nalgebra_support.rs	Tue Dec 31 08:30:43 2024 -0500
+++ b/src/nalgebra_support.rs	Sat Dec 21 23:32:20 2024 -0500
@@ -89,6 +89,7 @@
 where SM: StorageMut<E,M> + Clone, SV1: Storage<E,M> + Clone,
       M : Dim, E : Scalar + Zero + One + Float,
       DefaultAllocator : Allocator<M> {
+    type Owned = OVector<E, M>;
 
     #[inline]
     fn axpy<I : Instance<Vector<E,M,SV1>>>(&mut self, α : E, x : I, β : E) {
@@ -99,6 +100,16 @@
     fn copy_from<I : Instance<Vector<E,M,SV1>>>(&mut self, y : I) {
         y.eval(|ỹ| Matrix::copy_from(self, ỹ))
     }
+
+    #[inline]
+    fn set_zero(&mut self) {
+        self.iter_mut().for_each(|e| *e = E::ZERO);
+    }
+
+    #[inline]
+    fn similar_origin(&self) -> Self::Owned {
+        OVector::zeros_generic(M::from_usize(self.len()), Const)
+    }
 }
 
 /* Implemented automatically as Euclidean.
@@ -191,11 +202,6 @@
     type Output = OVector<E, M>;
     
     #[inline]
-    fn similar_origin(&self) -> OVector<E, M> {
-        OVector::zeros_generic(M::from_usize(self.len()), Const)
-    }
-
-    #[inline]
     fn norm2_squared(&self) -> E {
         Vector::<E,M,S>::norm_squared(self)
     }
--- a/src/types.rs	Tue Dec 31 08:30:43 2024 -0500
+++ b/src/types.rs	Sat Dec 21 23:32:20 2024 -0500
@@ -12,6 +12,7 @@
 //use trait_set::trait_set;
 pub use num_traits::Float as NumTraitsFloat; // needed to re-export functions.
 pub use num_traits::cast::AsPrimitive;
+
 pub use simba::scalar::{
     ClosedAdd, ClosedAddAssign,
     ClosedSub, ClosedSubAssign,

mercurial