src/nalgebra_support.rs

branch
dev
changeset 158
9c720f822c79
parent 157
2ac69af65636
child 159
279b1f5b8608
--- a/src/nalgebra_support.rs	Tue Sep 02 08:01:57 2025 -0500
+++ b/src/nalgebra_support.rs	Tue Sep 02 12:37:53 2025 -0500
@@ -14,11 +14,12 @@
 use crate::norms::*;
 use crate::types::Float;
 use nalgebra::base::allocator::Allocator;
-use nalgebra::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
+use nalgebra::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
 use nalgebra::base::dimension::*;
 use nalgebra::{
     ClosedAddAssign, ClosedMulAssign, DefaultAllocator, Dim, LpNorm, Matrix, MatrixView, OMatrix,
-    OVector, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm, Vector,
+    OVector, RawStorage, RealField, Scalar, SimdComplexField, Storage, StorageMut, UniformNorm,
+    Vector,
 };
 use num_traits::identities::{One, Zero};
 use std::ops::Mul;
@@ -59,13 +60,11 @@
 #[derive(Copy, Clone, Debug)]
 pub struct MatrixDecomposition;
 
-impl<E, M, K, S, RS, CS> Decomposition<Matrix<E, M, K, S>> for MatrixDecomposition
+impl<E, M, K, S> Decomposition<Matrix<E, M, K, S>> for MatrixDecomposition
 where
-    S: Storage<E, M, K, RStride = RS, CStride = CS>,
+    S: Storage<E, M, K>,
     M: Dim,
     K: Dim,
-    RS: Dim,
-    CS: Dim,
     E: Scalar + Zero + One,
     DefaultAllocator: Allocator<M, K>,
 {
@@ -76,7 +75,7 @@
     where
         Matrix<E, M, K, S>: 'b;
     type Reference<'b>
-        = &'b MatrixView<'b, E, M, K, RS, CS>
+        = MatrixView<'b, E, M, K, Dyn, Dyn>
     where
         Matrix<E, M, K, S>: 'b;
 
@@ -89,40 +88,84 @@
     }
 }
 
-impl<S, SV, M, K, E, RS, CS> Instance<Matrix<E, M, K, S>, MatrixDecomposition>
-    for Matrix<E, M, K, SV>
-where
-    S: Storage<E, M, K, RStride = RS, CStride = CS>,
-    SV: Storage<E, M, K>,
-    M: Dim,
-    K: Dim,
-    E: Scalar + Zero + One,
-    DefaultAllocator: Allocator<M, K>,
-{
-    fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R
-    where
-        Self: 'b,
-    {
-        f(self.into_owned())
-    }
+macro_rules! impl_instances {
+    ($rstride:ty, $cstride:ty where $($qual:tt)*) => {
+        impl<$($qual)* S1, S2, M, K, E> Instance<Matrix<E, M, K, S1>, MatrixDecomposition> for Matrix<E, M, K, S2>
+        where
+            S1: Storage<E, M, K>,
+            S2: RawStorage<E, M, K, RStride=$rstride, CStride=$cstride>,
+            //ShapeConstraint: DimEq<Dyn, <S2 as RawStorage<E, M, K>>::RStride>
+            //    + DimEq<Dyn, <S2 as RawStorage<E, M, K>>::CStride>,
+            M: Dim,
+            K: Dim,
+            E: Scalar + Zero + One,
+            DefaultAllocator: Allocator<M, K>,
+        {
+            fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R
+            where
+                Self: 'b,
+            {
+                f(self.into_owned())
+            }
+
+            fn eval_ref_decompose<'b, R>(
+                &'b self,
+                f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R,
+            ) -> R
+            where
+                Self: 'b,
+                Matrix<E, M, K, S1>: 'b,
+            {
+                f(self.as_view::<M, K, Dyn, Dyn>())
+            }
+
+            #[inline]
+            fn own(self) -> OMatrix<E, M, K> {
+                self.into_owned()
+            }
+        }
 
-    fn eval_ref_decompose<'b, R>(
-        &'b self,
-        f: impl FnOnce(<MatrixDecomposition as Decomposition<Self>>::Reference<'b>) -> R,
-    ) -> R
-    where
-        Self: 'b,
-        Matrix<E, M, K, SM>: 'b,
-    {
-        f(&self.as_view::<M, K, Dyn, Dyn>())
-    }
+        impl<'a, $($qual)* S1, S2, M, K, E> Instance<Matrix<E, M, K, S1>, MatrixDecomposition>
+            for &'a Matrix<E, M, K, S2>
+        where
+            S1: Storage<E, M, K>,
+            S2: RawStorage<E, M, K, RStride=$rstride, CStride=$cstride>,
+            M: Dim,
+            K: Dim,
+            E: Scalar + Zero + One,
+            DefaultAllocator: Allocator<M, K>,
+        {
+            fn eval_decompose<'b, R>(self, f: impl FnOnce(OMatrix<E, M, K>) -> R) -> R
+            where
+                Self: 'b,
+            {
+                f(self.into_owned())
+            }
 
-    #[inline]
-    fn own(self) -> OMatrix<E, M, K> {
-        self.into_owned()
-    }
+            fn eval_ref_decompose<'b, R>(
+                &'b self,
+                f: impl FnOnce(<MatrixDecomposition as Decomposition<Matrix<E, M, K, S1>>>::Reference<'b>) -> R,
+            ) -> R
+            where
+                Self: 'b,
+                Matrix<E, M, K, S1>: 'b,
+            {
+                f((*self).as_view::<M, K, Dyn, Dyn>())
+            }
+
+            #[inline]
+            fn own(self) -> OMatrix<E, M, K> {
+                self.into_owned()
+            }
+        }
+    };
 }
 
+impl_instances!(Dyn, Dyn where );
+impl_instances!(Const<RS>, Dyn where const RS : usize,);
+impl_instances!(Dyn, Const<CS> where const CS : usize,);
+impl_instances!(Const<RS>, Const<CS> where const RS : usize, const CS : usize,);
+
 impl<SM, SV, N, M, K, E> Mapping<Matrix<E, M, K, SV>> for Matrix<E, N, M, SM>
 where
     SM: Storage<E, N, M>,
@@ -347,7 +390,7 @@
 
     #[inline]
     fn dot<I: Instance<Self>>(&self, other: I) -> E {
-        other.eval_ref_decompose(|r| Vector::<E, M, S>::dot(self, r))
+        other.eval_ref_decompose(|ref r| Vector::<E, M, S>::dot(self, r))
     }
 
     #[inline]
@@ -357,7 +400,7 @@
 
     #[inline]
     fn dist2_squared<I: Instance<Self>>(&self, other: I) -> E {
-        other.eval_ref_decompose(|r| metric_distance_squared(self, r))
+        other.eval_ref_decompose(|ref r| metric_distance_squared(self, r))
     }
 }
 
@@ -431,7 +474,7 @@
 {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: L1) -> E {
-        other.eval_ref_decompose(|r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r))
+        other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&LpNorm(1), self, r))
     }
 }
 
@@ -457,7 +500,7 @@
 {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: L2) -> E {
-        other.eval_ref_decompose(|r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r))
+        other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&LpNorm(2), self, r))
     }
 }
 
@@ -483,7 +526,7 @@
 {
     #[inline]
     fn dist<I: Instance<Self>>(&self, other: I, _: Linfinity) -> E {
-        other.eval_ref_decompose(|r| nalgebra::Norm::metric_distance(&UniformNorm, self, r))
+        other.eval_ref_decompose(|ref r| nalgebra::Norm::metric_distance(&UniformNorm, self, r))
     }
 }
 

mercurial