diff -r 9c720f822c79 -r 279b1f5b8608 src/nalgebra_support.rs --- a/src/nalgebra_support.rs Tue Sep 02 12:37:53 2025 -0500 +++ b/src/nalgebra_support.rs Tue Sep 02 15:11:35 2025 -0500 @@ -19,7 +19,7 @@ use nalgebra::{ ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, MatrixView, OMatrix, OVector, RawStorage, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, - Vector, + Vector, U1, }; use num_traits::identities::{One, Zero}; use std::ops::Mul; @@ -45,6 +45,39 @@ } } +trait StridesOk>::Buffer>: + DimEq + + DimEq + + DimEq>::Buffer as RawStorage>::RStride> + + DimEq>::Buffer as RawStorage>::CStride> +where + S: RawStorage, + E: Scalar, + N: Dim, + M: Dim, + DefaultAllocator: Allocator, +{ +} + +impl StridesOk for ShapeConstraint +where + ShapeConstraint: DimEq + + DimEq + + DimEq< + Dyn, + <>::Buffer as RawStorage>::RStride, + > + DimEq< + Dyn, + <>::Buffer as RawStorage>::CStride, + >, + S: Storage, + E: Scalar, + N: Dim, + M: Dim, + DefaultAllocator: Allocator, +{ +} + impl Space for Matrix where SM: Storage, @@ -52,6 +85,7 @@ M: Dim, E: Scalar + Zero + One, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk + StridesOk, { type OwnedSpace = OMatrix; type Decomp = MatrixDecomposition; @@ -60,13 +94,60 @@ #[derive(Copy, Clone, Debug)] pub struct MatrixDecomposition; -impl Decomposition> for MatrixDecomposition +/// nalgebra [`Storage`] that's convertible to dynamic strides (practically all, but we need this +/// to work around the type system). +trait ViewableStorage: Storage +where + M: Dim, + K: Dim, + E: Scalar, + ShapeConstraint: StridesOk, + DefaultAllocator: Allocator, +{ +} + +impl ViewableStorage for S where S: Storage, M: Dim, K: Dim, + E: Scalar, + ShapeConstraint: StridesOk, + DefaultAllocator: Allocator, +{ +} + +/// nalgebra [`StorageMut`] that's convertible to dynamic strides (practically all, but we need this +/// to work around the type system). +trait ViewableStorageMut: StorageMut +where + M: Dim, + K: Dim, + E: Scalar, + ShapeConstraint: StridesOk, + DefaultAllocator: Allocator, +{ +} + +impl ViewableStorageMut for S +where + S: StorageMut, + M: Dim, + K: Dim, + E: Scalar, + ShapeConstraint: StridesOk, + DefaultAllocator: Allocator, +{ +} + +impl Decomposition> for MatrixDecomposition +where + S: ViewableStorage, + M: Dim, + K: Dim, E: Scalar + Zero + One, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk + StridesOk, { type OwnedInstance = OMatrix; @@ -88,96 +169,85 @@ } } -macro_rules! impl_instances { - ($rstride:ty, $cstride:ty where $($qual:tt)*) => { - impl<$($qual)* S1, S2, M, K, E> Instance, MatrixDecomposition> for Matrix - where - S1: Storage, - S2: RawStorage, - //ShapeConstraint: DimEq>::RStride> - // + DimEq>::CStride>, - M: Dim, - K: Dim, - E: Scalar + Zero + One, - DefaultAllocator: Allocator, - { - fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix) -> R) -> R - where - Self: 'b, - { - f(self.into_owned()) - } - - fn eval_ref_decompose<'b, R>( - &'b self, - f: impl FnOnce(>>::Reference<'b>) -> R, - ) -> R - where - Self: 'b, - Matrix: 'b, - { - f(self.as_view::()) - } +impl Instance, MatrixDecomposition> for Matrix +where + S1: ViewableStorage, + S2: ViewableStorage, + M: Dim, + K: Dim, + E: Scalar + Zero + One, + DefaultAllocator: Allocator, + ShapeConstraint: StridesOk + StridesOk, +{ + fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix) -> R) -> R + where + Self: 'b, + { + f(self.into_owned()) + } - #[inline] - fn own(self) -> OMatrix { - self.into_owned() - } - } + fn eval_ref_decompose<'b, R>( + &'b self, + f: impl FnOnce(>>::Reference<'b>) -> R, + ) -> R + where + Self: 'b, + Matrix: 'b, + { + f(self.as_view::()) + } - impl<'a, $($qual)* S1, S2, M, K, E> Instance, MatrixDecomposition> - for &'a Matrix - where - S1: Storage, - S2: RawStorage, - M: Dim, - K: Dim, - E: Scalar + Zero + One, - DefaultAllocator: Allocator, - { - fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix) -> R) -> R - where - Self: 'b, - { - f(self.into_owned()) - } - - fn eval_ref_decompose<'b, R>( - &'b self, - f: impl FnOnce(>>::Reference<'b>) -> R, - ) -> R - where - Self: 'b, - Matrix: 'b, - { - f((*self).as_view::()) - } - - #[inline] - fn own(self) -> OMatrix { - self.into_owned() - } - } - }; + #[inline] + fn own(self) -> OMatrix { + self.into_owned() + } } -impl_instances!(Dyn, Dyn where ); -impl_instances!(Const, Dyn where const RS : usize,); -impl_instances!(Dyn, Const where const CS : usize,); -impl_instances!(Const, Const where const RS : usize, const CS : usize,); +impl<'a, S1, S2, M, K, E> Instance, MatrixDecomposition> + for &'a Matrix +where + S1: ViewableStorage, + S2: ViewableStorage, + M: Dim, + K: Dim, + E: Scalar + Zero + One, + DefaultAllocator: Allocator, + ShapeConstraint: StridesOk + StridesOk, +{ + fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix) -> R) -> R + where + Self: 'b, + { + f(self.into_owned()) + } + + fn eval_ref_decompose<'b, R>( + &'b self, + f: impl FnOnce(>>::Reference<'b>) -> R, + ) -> R + where + Self: 'b, + Matrix: 'b, + { + f((*self).as_view::()) + } + + #[inline] + fn own(self) -> OMatrix { + self.into_owned() + } +} impl Mapping> for Matrix where - SM: Storage, - SV: Storage + Clone, + SM: ViewableStorage, + SV: ViewableStorage + Clone, N: Dim, M: Dim, K: Dim, E: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator + Allocator + Allocator + Allocator, + ShapeConstraint: StridesOk + StridesOk + StridesOk, { type Codomain = OMatrix; @@ -189,33 +259,29 @@ impl<'a, SM, SV, N, M, K, E> Linear> for Matrix where - SM: Storage, - SV: Storage + Clone, + SM: ViewableStorage, + SV: ViewableStorage + Clone, N: Dim, M: Dim, K: Dim, E: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator + Allocator + Allocator + Allocator, + ShapeConstraint: StridesOk + StridesOk + StridesOk, { } impl GEMV, Matrix> for Matrix where - SM: Storage, - SV1: Storage + Clone, - SV2: StorageMut, + SM: ViewableStorage, + SV1: ViewableStorage + Clone, + SV2: ViewableStorageMut, N: Dim, M: Dim, K: Dim, E: Scalar + Zero + One + Float, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator + Allocator + Allocator + Allocator, + ShapeConstraint: StridesOk + StridesOk + StridesOk, { #[inline] fn gemv>>( @@ -236,11 +302,12 @@ impl VectorSpace for Matrix where - S: Storage, + S: ViewableStorage, M: Dim, N: Dim, E: Scalar + Zero + One + Float, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { type Field = E; type Owned = OMatrix; @@ -254,12 +321,13 @@ impl AXPY> for Matrix where - SM: StorageMut, - SV1: Storage, + SM: ViewableStorageMut, + SV1: ViewableStorage, M: Dim, N: Dim, E: Scalar + Zero + One + Float, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk + StridesOk, { #[inline] fn axpy>>(&mut self, α: E, x: I, β: E) { @@ -300,10 +368,11 @@ impl Projection for Vector where - SM: Storage + Clone, + SM: ViewableStorageMut + Clone, M: Dim, E: Scalar + Zero + One + Float + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn proj_ball(self, ρ: E, exp: Linfinity) -> ::OwnedSpace { @@ -315,10 +384,11 @@ impl ProjectionMut for Vector where - SM: StorageMut + Clone, + SM: ViewableStorageMut + Clone, M: Dim, E: Scalar + Zero + One + Float + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn proj_ball_mut(&mut self, ρ: E, _: Linfinity) { @@ -330,17 +400,18 @@ impl<'own, SV1, SV2, SM, N, M, K, E> Adjointable, Matrix> for Matrix where - SM: Storage, - SV1: Storage + Clone, - SV2: Storage + Clone, + SM: ViewableStorage, + SV1: ViewableStorage + Clone, + SV2: ViewableStorage + Clone, N: Dim, M: Dim, K: Dim, E: Scalar + Zero + One + SimdComplexField, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator + Allocator + Allocator + Allocator, + ShapeConstraint: StridesOk + + StridesOk + + StridesOk + + StridesOk, { type AdjointCodomain = OMatrix; type Adjoint<'a> @@ -382,9 +453,10 @@ impl Euclidean for Vector where M: Dim, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { type OwnedEuclidean = OVector; @@ -407,9 +479,10 @@ impl StaticEuclidean for Vector where M: DimName, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn origin() -> OVector { @@ -421,9 +494,10 @@ impl Normed for Vector where M: Dim, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { type NormExp = L2; @@ -441,9 +515,10 @@ impl HasDual for Vector where M: Dim, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { type DualSpace = OVector; @@ -455,9 +530,10 @@ impl Norm for Vector where M: Dim, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn norm(&self, _: L1) -> E { @@ -468,9 +544,10 @@ impl Dist for Vector where M: Dim, - S: Storage + Clone, + S: ViewableStorage + Clone, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn dist>(&self, other: I, _: L1) -> E { @@ -481,9 +558,10 @@ impl Norm for Vector where M: Dim, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn norm(&self, _: L2) -> E { @@ -494,9 +572,10 @@ impl Dist for Vector where M: Dim, - S: Storage + Clone, + S: ViewableStorage + Clone, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn dist>(&self, other: I, _: L2) -> E { @@ -507,9 +586,10 @@ impl Norm for Vector where M: Dim, - S: Storage, + S: ViewableStorage, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn norm(&self, _: Linfinity) -> E { @@ -520,9 +600,10 @@ impl Dist for Vector where M: Dim, - S: Storage + Clone, + S: ViewableStorage + Clone, E: Float + Scalar + Zero + One + RealField, DefaultAllocator: Allocator, + ShapeConstraint: StridesOk, { #[inline] fn dist>(&self, other: I, _: Linfinity) -> E {