Fri, 05 Sep 2025 00:48:59 -0500
AXPY implementation reductions
| src/euclidean/wrap.rs | file | annotate | diff | comparison | revisions | |
| src/linops.rs | file | annotate | diff | comparison | revisions | |
| src/nalgebra_support.rs | file | annotate | diff | comparison | revisions |
--- a/src/euclidean/wrap.rs Fri Sep 05 00:16:08 2025 -0500 +++ b/src/euclidean/wrap.rs Fri Sep 05 00:48:59 2025 -0500 @@ -148,7 +148,7 @@ impl<$($qual)*> $crate::norms::Dist<$crate::norms::L2, $F> for $type { fn dist<I: $crate::instance::Instance<Self>>(&self, other : I, p : $crate::norms::L2) -> $F { - other.eval_ref(|x| self.get_view().dist(x, p)) + other.eval_ref(|x| self.get_view().dist(x.get_view(), p)) } } @@ -226,19 +226,19 @@ { fn axpy<I: $crate::instance::Instance<Self>>(&mut self, α: $F, x: I, β: $F) { x.eval_decompose(|v| { - self.get_view_mut().axpy(α, v.get_view(), β) + self.get_view_mut().axpy(α, (*v).get_view(), β) }) } fn copy_from<I: $crate::instance::Instance<Self>>(&mut self, x: I) { x.eval_decompose(|v| { - self.get_view_mut().copy_from(&v.get_view()) + self.get_view_mut().copy_from((*v).get_view()) }) } fn scale_from<I: $crate::instance::Instance<Self>>(&mut self, α: $F, x: I) { x.eval_decompose(|v| { - self.get_view_mut().scale_from(α, v.get_view()) + self.get_view_mut().scale_from(α, (*v).get_view()) }) }
--- a/src/linops.rs Fri Sep 05 00:16:08 2025 -0500 +++ b/src/linops.rs Fri Sep 05 00:48:59 2025 -0500 @@ -44,9 +44,13 @@ /// Principal form of the space; always equal to [`Space::Principal`], but with /// more traits guaranteed. + /// + /// `PrincipalV` is only assumed to be `AXPY` for itself, as [`AXPY`] + /// uses [`Instance`] to apply all other variants and avoid problems + /// of choosing multiple implementations of the trait. type PrincipalV: ClosedSpace + AXPY< - Self, + Self::PrincipalV, Field = Self::Field, PrincipalV = Self::PrincipalV, OwnedVariant = Self::PrincipalV,
--- a/src/nalgebra_support.rs Fri Sep 05 00:16:08 2025 -0500 +++ b/src/nalgebra_support.rs Fri Sep 05 00:48:59 2025 -0500 @@ -359,10 +359,11 @@ } } -impl<SM, SV1, M, N, E> AXPY<Matrix<E, M, N, SV1>> for Matrix<E, M, N, SM> +// This can only be implemented for the “principal” OMatrix as parameter, as otherwise +// we run into problems of multiple implementations when calling the methods. +impl<M, N, E, S> AXPY<OMatrix<E, M, N>> for Matrix<E, M, N, S> where - SM: StorageMut<E, M, N>, - SV1: Storage<E, M, N>, + S: StorageMut<E, M, N>, M: Dim, N: Dim, E: Scalar + Zero + One + Float, @@ -370,7 +371,7 @@ ShapeConstraint: StridesOk<E, M, N>, { #[inline] - fn axpy<I: Instance<Matrix<E, M, N, SV1>>>(&mut self, α: E, x: I, β: E) { + fn axpy<I: Instance<OMatrix<E, M, N>>>(&mut self, α: E, x: I, β: E) { x.eval(|x̃| { assert_eq!(self.ncols(), x̃.ncols()); // nalgebra does not implement axpy for matrices, and flattenining @@ -382,7 +383,7 @@ } #[inline] - fn copy_from<I: Instance<Matrix<E, M, N, SV1>>>(&mut self, y: I) { + fn copy_from<I: Instance<OMatrix<E, M, N>>>(&mut self, y: I) { y.eval_ref(|ỹ| Matrix::copy_from(self, &ỹ)) }