# HG changeset patch # User Tuomo Valkonen # Date 1734841940 18000 # Node ID d8305c9b6fdfe68335390b181e708b27d83fb873 # Parent 05089fbc03105a70ca382b5904b41c534041accc Move origin stuff to AXPY form Euclidean diff -r 05089fbc0310 -r d8305c9b6fdf src/direct_product.rs --- 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; - fn similar_origin(&self) -> PairOutput { - 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, B : AXPY, - F : Num + F : Num, + Self : MulAssign, + Pair : MulAssign, + Pair : AXPY>, { + type Owned = Pair; + fn axpy>>(&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. diff -r 05089fbc0310 -r d8305c9b6fdf src/euclidean.rs --- 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> { type Output : Euclidean; - /// Returns origin of same dimensions as `self`. - fn similar_origin(&self) -> >::Output; - /// Calculate the square of the 2-norm, $\frac{1}{2}\\|x\\|_2^2$, where `self` is $x$. #[inline] fn norm2_squared(&self) -> F { diff -r 05089fbc0310 -r d8305c9b6fdf src/linops.rs --- 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 : Space +pub trait AXPY : Space + std::ops::MulAssign where F : Num, X : Space, { + type Owned : AXPY; + /// Computes `y = βy + αx`, where `y` is `Self`. fn axpy>(&mut self, α : F, x : I, β : F); @@ -34,6 +36,12 @@ fn scale_from>(&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. diff -r 05089fbc0310 -r d8305c9b6fdf src/loc.rs --- 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 Euclidean for Loc { 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 Linear> for Loc { } impl AXPY> for Loc { + type Owned = Self; + #[inline] fn axpy>>(&mut self, α : F, x : I, β : F) { x.eval(|x̃| { @@ -727,4 +724,15 @@ fn copy_from>>(&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; + } } + diff -r 05089fbc0310 -r d8305c9b6fdf src/nalgebra_support.rs --- 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 + Clone, SV1: Storage + Clone, M : Dim, E : Scalar + Zero + One + Float, DefaultAllocator : Allocator { + type Owned = OVector; #[inline] fn axpy>>(&mut self, α : E, x : I, β : E) { @@ -99,6 +100,16 @@ fn copy_from>>(&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; #[inline] - fn similar_origin(&self) -> OVector { - OVector::zeros_generic(M::from_usize(self.len()), Const) - } - - #[inline] fn norm2_squared(&self) -> E { Vector::::norm_squared(self) } diff -r 05089fbc0310 -r d8305c9b6fdf src/types.rs --- 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,