Sat, 21 Dec 2024 23:32:20 -0500
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,