--- a/src/nalgebra_support.rs Mon Sep 01 00:04:22 2025 -0500 +++ b/src/nalgebra_support.rs Mon Sep 01 13:51:03 2025 -0500 @@ -9,7 +9,7 @@ */ use crate::euclidean::*; -use crate::instance::Instance; +use crate::instance::{Instance, Ownable}; use crate::linops::*; use crate::mapping::{BasicDecomposition, Space}; use crate::norms::*; @@ -24,14 +24,36 @@ use num_traits::identities::{One, Zero}; use std::ops::Mul; +impl<S, M, N, E> Ownable for Matrix<E, M, N, S> +where + S: Storage<E, M, N>, + M: Dim, + N: Dim, + E: Scalar + Zero + One, + DefaultAllocator: Allocator<M, N>, +{ + type OwnedVariant = OMatrix<E, M, N>; + + #[inline] + fn into_owned(self) -> Self::OwnedVariant { + Matrix::into_owned(self) + } + + /// Returns an owned instance of a reference. + fn clone_owned(&self) -> Self::OwnedVariant { + Matrix::clone_owned(self) + } +} + impl<SM, N, M, E> Space for Matrix<E, N, M, SM> where - SM: Storage<E, N, M> + Clone, + SM: Storage<E, N, M>, N: Dim, M: Dim, - E: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, + E: Scalar + Zero + One, DefaultAllocator: Allocator<N, M>, { + type OwnedSpace = OMatrix<E, N, M>; type Decomp = BasicDecomposition; } @@ -103,10 +125,9 @@ } } -impl<SM, SV1, M, N, E> AXPY<Matrix<E, M, N, SV1>> for Matrix<E, M, N, SM> +impl<S, M, N, E> VectorSpace for Matrix<E, M, N, S> where - SM: StorageMut<E, M, N> + Clone, - SV1: Storage<E, M, N> + Clone, + S: Storage<E, M, N>, M: Dim, N: Dim, E: Scalar + Zero + One + Float, @@ -116,6 +137,22 @@ type Owned = OMatrix<E, M, N>; #[inline] + fn similar_origin(&self) -> Self::Owned { + let (n, m) = self.shape_generic(); + OMatrix::zeros_generic(n, m) + } +} + +impl<SM, SV1, M, N, E> AXPY<Matrix<E, M, N, SV1>> for Matrix<E, M, N, SM> +where + SM: StorageMut<E, M, N>, + SV1: Storage<E, M, N>, + M: Dim, + N: Dim, + E: Scalar + Zero + One + Float, + DefaultAllocator: Allocator<M, N>, +{ + #[inline] fn axpy<I: Instance<Matrix<E, M, N, SV1>>>(&mut self, α: E, x: I, β: E) { x.eval(|x̃| { assert_eq!(self.ncols(), x̃.ncols()); @@ -136,12 +173,6 @@ fn set_zero(&mut self) { self.iter_mut().for_each(|e| *e = E::ZERO); } - - #[inline] - fn similar_origin(&self) -> Self::Owned { - let (n, m) = self.shape_generic(); - OMatrix::zeros_generic(n, m) - } } /* Implemented automatically as Euclidean. @@ -160,6 +191,21 @@ impl<SM, M, E> Projection<E, Linfinity> for Vector<E, M, SM> where + SM: Storage<E, M> + Clone, + M: Dim, + E: Scalar + Zero + One + Float + RealField, + DefaultAllocator: Allocator<M>, +{ + #[inline] + fn proj_ball(self, ρ: E, exp: Linfinity) -> <Self as Space>::OwnedSpace { + let mut owned = self.into_owned(); + owned.proj_ball_mut(ρ, exp); + owned + } +} + +impl<SM, M, E> ProjectionMut<E, Linfinity> for Vector<E, M, SM> +where SM: StorageMut<E, M> + Clone, M: Dim, E: Scalar + Zero + One + Float + RealField,