From 678a2581fc6e07569c61cc779e6808f89c8c7961 Mon Sep 17 00:00:00 2001 From: Geordon Worley Date: Wed, 28 Aug 2024 15:55:07 -0500 Subject: [PATCH 1/5] update deps and remove patch versions --- Cargo.toml | 6 ++-- src/tonalgebra/ndarray_impl.rs | 64 +++++++++++++++------------------- src/tondarray/image_impl.rs | 8 ++--- src/tondarray/nalgebra_impl.rs | 56 +++++++++++++++-------------- 4 files changed, 66 insertions(+), 68 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0708991..83164e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,9 +16,9 @@ default = ["nalgebra", "nalgebra_std", "ndarray", "image"] nalgebra_std = ["nalgebra/std"] [dependencies] -ndarray = { version = "0.15.4", default-features = false, optional = true } -nalgebra = { version = "0.30.1", default-features = false, optional = true } -image = { version = "0.24.0", default-features = false, optional = true } +ndarray = { version = "0.16", default-features = false, optional = true } +nalgebra = { version = "0.33", default-features = false, optional = true } +image = { version = "0.25", default-features = false, optional = true } [package.metadata.docs.rs] all-features = true diff --git a/src/tonalgebra/ndarray_impl.rs b/src/tonalgebra/ndarray_impl.rs index a467d4a..76910ec 100644 --- a/src/tonalgebra/ndarray_impl.rs +++ b/src/tonalgebra/ndarray_impl.rs @@ -3,7 +3,7 @@ use super::*; use core::convert::TryFrom; -use nalgebra::Dynamic as Dy; +use nalgebra::Dyn; /// ``` /// use nshare::ToNalgebra; @@ -17,16 +17,16 @@ impl<'a, T> ToNalgebra for ndarray::ArrayView1<'a, T> where T: nalgebra::Scalar, { - type Out = nalgebra::DVectorSlice<'a, T>; + type Out = nalgebra::DVectorView<'a, T>; fn into_nalgebra(self) -> Self::Out { - let len = Dy::new(self.len()); + let len = Dyn(self.len()); let ptr = self.as_ptr(); let stride: usize = TryFrom::try_from(self.strides()[0]).expect("Negative stride"); let storage = unsafe { - nalgebra::SliceStorage::from_raw_parts( + nalgebra::ViewStorage::from_raw_parts( ptr, (len, nalgebra::Const::<1>), - (nalgebra::Const::<1>, Dy::new(stride)), + (nalgebra::Const::<1>, Dyn(stride)), ) }; nalgebra::Matrix::from_data(storage) @@ -44,18 +44,16 @@ impl<'a, T> ToNalgebra for ndarray::ArrayViewMut1<'a, T> where T: nalgebra::Scalar, { - type Out = nalgebra::DVectorSliceMut<'a, T>; + type Out = nalgebra::DVectorViewMut<'a, T>; fn into_nalgebra(mut self) -> Self::Out { - let len = Dy::new(self.len()); + let len = Dyn(self.len()); let stride: usize = TryFrom::try_from(self.strides()[0]).expect("Negative stride"); let ptr = self.as_mut_ptr(); let storage = unsafe { - // Drop to not have simultaneously the ndarray and nalgebra valid. - drop(self); - nalgebra::SliceStorageMut::from_raw_parts( + nalgebra::ViewStorageMut::from_raw_parts( ptr, (len, nalgebra::Const::<1>), - (nalgebra::Const::<1>, Dy::new(stride)), + (nalgebra::Const::<1>, Dyn(stride)), ) }; nalgebra::Matrix::from_data(storage) @@ -76,8 +74,13 @@ where { type Out = nalgebra::DVector; fn into_nalgebra(self) -> Self::Out { - let len = Dy::new(self.len()); - Self::Out::from_vec_generic(len, nalgebra::Const::<1>, self.into_raw_vec()) + let len = Dyn(self.len()); + // There is no method to give nalgebra the vector directly where it isn't allocated. If you call + // from_vec_generic, it simply calls from_iterator_generic which uses Iterator::collect(). Due to this, + // the simplest solution is to just pass an iterator over the values. If you come across this because you + // have a performance issue, I would recommend creating the owned data using naglebra and borrowing it with + // ndarray to perform operations on it instead of the other way around. + Self::Out::from_iterator_generic(len, nalgebra::Const::<1>, self.iter().cloned()) } } @@ -99,19 +102,19 @@ impl<'a, T> ToNalgebra for ndarray::ArrayView2<'a, T> where T: nalgebra::Scalar, { - type Out = nalgebra::DMatrixSlice<'a, T, Dy, Dy>; + type Out = nalgebra::DMatrixView<'a, T, Dyn, Dyn>; fn into_nalgebra(self) -> Self::Out { - let nrows = Dy::new(self.nrows()); - let ncols = Dy::new(self.ncols()); + let nrows = Dyn(self.nrows()); + let ncols = Dyn(self.ncols()); let ptr = self.as_ptr(); let stride_row: usize = TryFrom::try_from(self.strides()[0]).expect("Negative row stride"); let stride_col: usize = TryFrom::try_from(self.strides()[1]).expect("Negative column stride"); let storage = unsafe { - nalgebra::SliceStorage::from_raw_parts( + nalgebra::ViewStorage::from_raw_parts( ptr, (nrows, ncols), - (Dy::new(stride_row), Dy::new(stride_col)), + (Dyn(stride_row), Dyn(stride_col)), ) }; nalgebra::Matrix::from_data(storage) @@ -136,21 +139,19 @@ impl<'a, T> ToNalgebra for ndarray::ArrayViewMut2<'a, T> where T: nalgebra::Scalar, { - type Out = nalgebra::DMatrixSliceMut<'a, T, Dy, Dy>; + type Out = nalgebra::DMatrixViewMut<'a, T, Dyn, Dyn>; fn into_nalgebra(mut self) -> Self::Out { - let nrows = Dy::new(self.nrows()); - let ncols = Dy::new(self.ncols()); + let nrows = Dyn(self.nrows()); + let ncols = Dyn(self.ncols()); let stride_row: usize = TryFrom::try_from(self.strides()[0]).expect("Negative row stride"); let stride_col: usize = TryFrom::try_from(self.strides()[1]).expect("Negative column stride"); let ptr = self.as_mut_ptr(); let storage = unsafe { - // Drop to not have simultaneously the ndarray and nalgebra valid. - drop(self); - nalgebra::SliceStorageMut::from_raw_parts( + nalgebra::ViewStorageMut::from_raw_parts( ptr, (nrows, ncols), - (Dy::new(stride_row), Dy::new(stride_col)), + (Dyn(stride_row), Dyn(stride_col)), ) }; nalgebra::Matrix::from_data(storage) @@ -177,15 +178,8 @@ where { type Out = nalgebra::DMatrix; fn into_nalgebra(self) -> Self::Out { - let std_layout = self.is_standard_layout(); - let nrows = Dy::new(self.nrows()); - let ncols = Dy::new(self.ncols()); - let mut res = Self::Out::from_vec_generic(nrows, ncols, self.into_raw_vec()); - if std_layout { - // This can be expensive, but we have no choice since nalgebra VecStorage is always - // column-based. - res.transpose_mut(); - } - res + let nrows = Dyn(self.nrows()); + let ncols = Dyn(self.ncols()); + Self::Out::from_iterator_generic(nrows, ncols, self.t().iter().cloned()) } } diff --git a/src/tondarray/image_impl.rs b/src/tondarray/image_impl.rs index d025113..651a41b 100644 --- a/src/tondarray/image_impl.rs +++ b/src/tondarray/image_impl.rs @@ -70,7 +70,7 @@ where } = self.sample_layout(); let shape = (height as usize, width as usize); let strides = (height_stride, width_stride); - ArrayView2::from_shape(shape.strides(strides), &**self).unwrap() + ArrayView2::from_shape(shape.strides(strides), self).unwrap() } } @@ -102,7 +102,7 @@ where } = self.sample_layout(); let shape = (height as usize, width as usize); let strides = (height_stride, width_stride); - ArrayViewMut2::from_shape(shape.strides(strides), &mut **self).unwrap() + ArrayViewMut2::from_shape(shape.strides(strides), self).unwrap() } } @@ -170,7 +170,7 @@ where } = self.sample_layout(); let shape = (channels as usize, height as usize, width as usize); let strides = (channel_stride, height_stride, width_stride); - ArrayView3::from_shape(shape.strides(strides), &**self).unwrap() + ArrayView3::from_shape(shape.strides(strides), self).unwrap() } } @@ -201,6 +201,6 @@ where } = self.sample_layout(); let shape = (channels as usize, height as usize, width as usize); let strides = (channel_stride, height_stride, width_stride); - ArrayViewMut3::from_shape(shape.strides(strides), &mut **self).unwrap() + ArrayViewMut3::from_shape(shape.strides(strides), self).unwrap() } } diff --git a/src/tondarray/nalgebra_impl.rs b/src/tondarray/nalgebra_impl.rs index 99aaebe..cdf26ff 100644 --- a/src/tondarray/nalgebra_impl.rs +++ b/src/tondarray/nalgebra_impl.rs @@ -4,9 +4,9 @@ use super::*; use nalgebra::{ dimension::U1, storage::{Storage, StorageMut}, - Dim, Matrix, Scalar, SliceStorage, SliceStorageMut, Vector, + Dim, Matrix, Scalar, Vector, ViewStorage, ViewStorageMut, }; -use ndarray::{ArrayView1, ArrayView2, ArrayViewMut1, ArrayViewMut2, ShapeBuilder}; +use ndarray::ShapeBuilder; /// ``` /// use nshare::RefNdarray1; @@ -24,11 +24,11 @@ impl<'a, N: Scalar, R: Dim, S> RefNdarray1 for &'a Vector where S: Storage, { - type Out = ArrayView1<'a, N>; + type Out = ndarray::ArrayView1<'a, N>; fn ref_ndarray1(self) -> Self::Out { unsafe { - ArrayView1::from_shape_ptr( + ndarray::ArrayView1::from_shape_ptr( (self.shape().0,).strides((self.strides().0,)), self.as_ptr(), ) @@ -52,11 +52,11 @@ impl<'a, N: Scalar, R: Dim, S> MutNdarray1 for &'a mut Vector where S: StorageMut, { - type Out = ArrayViewMut1<'a, N>; + type Out = ndarray::ArrayViewMut1<'a, N>; fn mut_ndarray1(self) -> Self::Out { unsafe { - ArrayViewMut1::from_shape_ptr( + ndarray::ArrayViewMut1::from_shape_ptr( (self.shape().0,).strides((self.strides().0,)), self.as_ptr() as *mut N, ) @@ -76,13 +76,13 @@ where /// assert_eq!(arr.dim(), 4); /// ``` impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 - for Vector> + for Vector> { - type Out = ArrayView1<'a, N>; + type Out = ndarray::ArrayView1<'a, N>; fn into_ndarray1(self) -> Self::Out { unsafe { - ArrayView1::from_shape_ptr( + ndarray::ArrayView1::from_shape_ptr( (self.shape().0,).strides((self.strides().0,)), self.as_ptr(), ) @@ -101,13 +101,13 @@ impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 /// assert!(m.iter().eq(&[0.0, 0.2, 0.0, 0.4])); /// ``` impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 - for Matrix> + for Matrix> { - type Out = ArrayViewMut1<'a, N>; + type Out = ndarray::ArrayViewMut1<'a, N>; fn into_ndarray1(self) -> Self::Out { unsafe { - ArrayViewMut1::from_shape_ptr( + ndarray::ArrayViewMut1::from_shape_ptr( (self.shape().0,).strides((self.strides().0,)), self.as_ptr() as *mut N, ) @@ -134,10 +134,12 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S> RefNdarray2 for &'a Matrix where S: Storage, { - type Out = ArrayView2<'a, N>; + type Out = ndarray::ArrayView2<'a, N>; fn ref_ndarray2(self) -> Self::Out { - unsafe { ArrayView2::from_shape_ptr(self.shape().strides(self.strides()), self.as_ptr()) } + unsafe { + ndarray::ArrayView2::from_shape_ptr(self.shape().strides(self.strides()), self.as_ptr()) + } } } @@ -159,11 +161,11 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S> MutNdarray2 for &'a mut Matrix, { - type Out = ArrayViewMut2<'a, N>; + type Out = ndarray::ArrayViewMut2<'a, N>; fn mut_ndarray2(self) -> Self::Out { unsafe { - ArrayViewMut2::from_shape_ptr( + ndarray::ArrayViewMut2::from_shape_ptr( self.shape().strides(self.strides()), self.as_ptr() as *mut N, ) @@ -186,12 +188,14 @@ where /// assert_eq!(arr.dim(), (1, 4)); /// ``` impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 - for Matrix> + for Matrix> { - type Out = ArrayView2<'a, N>; + type Out = ndarray::ArrayView2<'a, N>; fn into_ndarray2(self) -> Self::Out { - unsafe { ArrayView2::from_shape_ptr(self.shape().strides(self.strides()), self.as_ptr()) } + unsafe { + ndarray::ArrayView2::from_shape_ptr(self.shape().strides(self.strides()), self.as_ptr()) + } } } @@ -209,13 +213,13 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 /// assert!(m.row(1).iter().eq(&[0.0; 4])); /// ``` impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 - for Matrix> + for Matrix> { - type Out = ArrayViewMut2<'a, N>; + type Out = ndarray::ArrayViewMut2<'a, N>; fn into_ndarray2(self) -> Self::Out { unsafe { - ArrayViewMut2::from_shape_ptr( + ndarray::ArrayViewMut2::from_shape_ptr( self.shape().strides(self.strides()), self.as_ptr() as *mut N, ) @@ -226,7 +230,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 #[cfg(feature = "nalgebra_std")] mod std_impl { use super::*; - use nalgebra::{allocator::Allocator, DVector, DefaultAllocator, Dynamic, VecStorage}; + use nalgebra::{allocator::Allocator, DVector, DefaultAllocator, Dyn, VecStorage}; use ndarray::{Array1, Array2}; /// ``` /// use nshare::ToNdarray1; @@ -240,7 +244,7 @@ mod std_impl { /// assert_eq!(arr.dim(), 4); /// assert!(arr.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// ``` - impl<'a, N: Scalar> ToNdarray1 for DVector { + impl ToNdarray1 for DVector { type Out = Array1; fn into_ndarray1(self) -> Self::Out { @@ -264,9 +268,9 @@ mod std_impl { /// assert!(arr.slice(s![.., 0]).iter().eq(&[0.1, 0.2, 0.3])); /// assert!(arr.slice(s![0, ..]).iter().eq(&[0.1, 0.5, 1.1, 1.5])); /// ``` - impl<'a, N: Scalar> ToNdarray2 for Matrix> + impl ToNdarray2 for Matrix> where - DefaultAllocator: Allocator>, + DefaultAllocator: Allocator = VecStorage>, { type Out = Array2; From e91b4420f6208e7b5fe170dd1d168347496d25bc Mon Sep 17 00:00:00 2001 From: Geordon Worley Date: Wed, 28 Aug 2024 16:46:45 -0500 Subject: [PATCH 2/5] use generic lifetimes to simplify traits; refactor names and features to reflect changes --- Cargo.toml | 7 +- src/toimage.rs | 2 +- src/tonalgebra.rs | 4 +- src/tonalgebra/ndarray_impl.rs | 24 ++--- src/tondarray.rs | 54 ++++++---- src/tondarray/image_impl.rs | 52 +++++----- src/tondarray/nalgebra_impl.rs | 174 ++++++++++++++++----------------- 7 files changed, 168 insertions(+), 149 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 83164e8..7902fce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,11 @@ license = "MIT" readme = "README.md" [features] -default = ["nalgebra", "nalgebra_std", "ndarray", "image"] -nalgebra_std = ["nalgebra/std"] +default = ["alloc", "nalgebra", "ndarray", "image"] +alloc = ["nalgebra?/alloc"] +nalgebra = ["dep:nalgebra"] +ndarray = ["dep:ndarray", "alloc"] +image = ["dep:image", "alloc"] [dependencies] ndarray = { version = "0.16", default-features = false, optional = true } diff --git a/src/toimage.rs b/src/toimage.rs index ef0659f..38062c2 100644 --- a/src/toimage.rs +++ b/src/toimage.rs @@ -2,7 +2,7 @@ /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait ToImageLuma { +pub trait IntoImageLuma { type Out; fn into_image_luma(self) -> Self::Out; diff --git a/src/tonalgebra.rs b/src/tonalgebra.rs index 0ba1e6c..267fa0f 100644 --- a/src/tonalgebra.rs +++ b/src/tonalgebra.rs @@ -1,11 +1,11 @@ -#[cfg(all(feature = "ndarray", feature = "nalgebra_std"))] +#[cfg(feature = "ndarray")] mod ndarray_impl; /// Converts a 1 or 2 dimensional type to a nalgebra type. /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait ToNalgebra { +pub trait IntoNalgebra { type Out; fn into_nalgebra(self) -> Self::Out; diff --git a/src/tonalgebra/ndarray_impl.rs b/src/tonalgebra/ndarray_impl.rs index 76910ec..9c41404 100644 --- a/src/tonalgebra/ndarray_impl.rs +++ b/src/tonalgebra/ndarray_impl.rs @@ -6,14 +6,14 @@ use core::convert::TryFrom; use nalgebra::Dyn; /// ``` -/// use nshare::ToNalgebra; +/// use nshare::IntoNalgebra; /// /// let arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]); /// let m = arr.view().into_nalgebra(); /// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(m.shape(), (4, 1)); /// ``` -impl<'a, T> ToNalgebra for ndarray::ArrayView1<'a, T> +impl<'a, T> IntoNalgebra for ndarray::ArrayView1<'a, T> where T: nalgebra::Scalar, { @@ -33,14 +33,14 @@ where } } /// ``` -/// use nshare::ToNalgebra; +/// use nshare::IntoNalgebra; /// /// let mut arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]); /// let m = arr.view_mut().into_nalgebra(); /// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(m.shape(), (4, 1)); /// ``` -impl<'a, T> ToNalgebra for ndarray::ArrayViewMut1<'a, T> +impl<'a, T> IntoNalgebra for ndarray::ArrayViewMut1<'a, T> where T: nalgebra::Scalar, { @@ -61,14 +61,14 @@ where } /// ``` -/// use nshare::ToNalgebra; +/// use nshare::IntoNalgebra; /// /// let arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]); /// let m = arr.into_nalgebra(); /// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(m.shape(), (4, 1)); /// ``` -impl ToNalgebra for ndarray::Array1 +impl IntoNalgebra for ndarray::Array1 where T: nalgebra::Scalar, { @@ -85,7 +85,7 @@ where } /// ``` -/// use nshare::ToNalgebra; +/// use nshare::IntoNalgebra; /// /// let arr = ndarray::arr2(&[ /// [0.1, 0.2, 0.3, 0.4], @@ -98,7 +98,7 @@ where /// assert_eq!(m.shape(), (4, 4)); /// assert!(arr.t().into_nalgebra().column(1).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// ``` -impl<'a, T> ToNalgebra for ndarray::ArrayView2<'a, T> +impl<'a, T> IntoNalgebra for ndarray::ArrayView2<'a, T> where T: nalgebra::Scalar, { @@ -122,7 +122,7 @@ where } /// ``` -/// use nshare::ToNalgebra; +/// use nshare::IntoNalgebra; /// /// let mut arr = ndarray::arr2(&[ /// [0.1, 0.2, 0.3, 0.4], @@ -135,7 +135,7 @@ where /// assert_eq!(m.shape(), (4, 4)); /// assert!(arr.view_mut().reversed_axes().into_nalgebra().column(1).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// ``` -impl<'a, T> ToNalgebra for ndarray::ArrayViewMut2<'a, T> +impl<'a, T> IntoNalgebra for ndarray::ArrayViewMut2<'a, T> where T: nalgebra::Scalar, { @@ -159,7 +159,7 @@ where } /// ``` -/// use nshare::ToNalgebra; +/// use nshare::IntoNalgebra; /// /// let mut arr = ndarray::arr2(&[ /// [0.1, 0.2, 0.3, 0.4], @@ -172,7 +172,7 @@ where /// assert_eq!(m.shape(), (4, 4)); /// assert!(arr.reversed_axes().into_nalgebra().column(1).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// ``` -impl ToNalgebra for ndarray::Array2 +impl IntoNalgebra for ndarray::Array2 where T: nalgebra::Scalar, { diff --git a/src/tondarray.rs b/src/tondarray.rs index bf541cf..232a43a 100644 --- a/src/tondarray.rs +++ b/src/tondarray.rs @@ -7,7 +7,7 @@ mod nalgebra_impl; /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait ToNdarray1 { +pub trait IntoNdarray1 { type Out; fn into_ndarray1(self) -> Self::Out; @@ -19,7 +19,7 @@ pub trait ToNdarray1 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait ToNdarray2 { +pub trait IntoNdarray2 { type Out; fn into_ndarray2(self) -> Self::Out; @@ -32,7 +32,7 @@ pub trait ToNdarray2 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait ToNdarray3 { +pub trait IntoNdarray3 { type Out; fn into_ndarray3(self) -> Self::Out; @@ -42,10 +42,12 @@ pub trait ToNdarray3 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait RefNdarray1 { - type Out; +pub trait AsNdarray1 { + type Out<'a> + where + Self: 'a; - fn ref_ndarray1(self) -> Self::Out; + fn as_ndarray1(&self) -> Self::Out<'_>; } /// Borrows a 2d type to a ndarray 2d array type. @@ -54,10 +56,12 @@ pub trait RefNdarray1 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait RefNdarray2 { - type Out; +pub trait AsNdarray2 { + type Out<'a> + where + Self: 'a; - fn ref_ndarray2(self) -> Self::Out; + fn as_ndarray2(&self) -> Self::Out<'_>; } /// Borrows a 3d type to a ndarray 2d array type. @@ -67,20 +71,24 @@ pub trait RefNdarray2 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait RefNdarray3 { - type Out; +pub trait AsNdarray3 { + type Out<'a> + where + Self: 'a; - fn ref_ndarray3(self) -> Self::Out; + fn as_ndarray3(&self) -> Self::Out<'_>; } /// Mutably borrows a 1d type to a ndarray 1d array type. /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait MutNdarray1 { - type Out; +pub trait AsNdarray1Mut { + type Out<'a> + where + Self: 'a; - fn mut_ndarray1(self) -> Self::Out; + fn as_ndarray1_mut(&mut self) -> Self::Out<'_>; } /// Mutably borrows a 2d type to a ndarray 2d array type. @@ -89,10 +97,12 @@ pub trait MutNdarray1 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait MutNdarray2 { - type Out; +pub trait AsNdarray2Mut { + type Out<'a> + where + Self: 'a; - fn mut_ndarray2(self) -> Self::Out; + fn as_ndarray2_mut(&mut self) -> Self::Out<'_>; } /// Mutably borrows a 3d type to a ndarray 2d array type. @@ -102,8 +112,10 @@ pub trait MutNdarray2 { /// /// This uses an associated type to avoid ambiguity for the compiler. /// By calling this, the compiler always knows the returned type. -pub trait MutNdarray3 { - type Out; +pub trait AsNdarray3Mut { + type Out<'a> + where + Self: 'a; - fn mut_ndarray3(self) -> Self::Out; + fn as_ndarray3_mut(&mut self) -> Self::Out<'_>; } diff --git a/src/tondarray/image_impl.rs b/src/tondarray/image_impl.rs index 651a41b..7de236f 100644 --- a/src/tondarray/image_impl.rs +++ b/src/tondarray/image_impl.rs @@ -11,7 +11,7 @@ use alloc::vec::Vec; /// ``` /// use image::GrayImage; -/// use nshare::ToNdarray2; +/// use nshare::IntoNdarray2; /// use ndarray::s; /// /// let zeros = GrayImage::new(2, 4); @@ -20,7 +20,7 @@ use alloc::vec::Vec; /// // ndarray uses (row, col), so the dims get flipped. /// assert_eq!(nd.dim(), (4, 2)); /// ``` -impl ToNdarray2 for ImageBuffer, Vec> +impl IntoNdarray2 for ImageBuffer, Vec> where A: Primitive + 'static, { @@ -42,25 +42,27 @@ where /// ``` /// use image::{GrayImage, Luma}; -/// use nshare::RefNdarray2; +/// use nshare::AsNdarray2; /// use ndarray::s; /// /// let mut vals = GrayImage::new(2, 4); /// vals[(1, 0)] = Luma([255]); -/// let nd = vals.ref_ndarray2(); +/// let nd = vals.as_ndarray2(); /// // ndarray uses (row, col), so the dims get flipped. /// assert_eq!(nd.dim(), (4, 2)); /// // The first row should sum to 255. /// assert_eq!(nd.slice(s![0, ..]).sum(), 255); /// ``` -impl<'a, A, Container> RefNdarray2 for &'a ImageBuffer, Container> +impl AsNdarray2 for ImageBuffer, Container> where A: Primitive + 'static, Container: Deref, { - type Out = ArrayView2<'a, A>; + type Out<'a> = ArrayView2<'a, A> + where + Container: 'a; - fn ref_ndarray2(self) -> Self::Out { + fn as_ndarray2(&self) -> Self::Out<'_> { let SampleLayout { height, height_stride, @@ -76,23 +78,25 @@ where /// ``` /// use image::{GrayImage, Luma}; -/// use nshare::MutNdarray2; +/// use nshare::AsNdarray2Mut; /// use ndarray::s; /// /// let mut vals = GrayImage::new(2, 4); -/// let mut nd = vals.mut_ndarray2(); +/// let mut nd = vals.as_ndarray2_mut(); /// assert_eq!(nd.dim(), (4, 2)); /// nd.slice_mut(s![0, ..]).fill(255); /// assert_eq!(vals[(1, 0)], Luma([255])); /// ``` -impl<'a, A, Container> MutNdarray2 for &'a mut ImageBuffer, Container> +impl AsNdarray2Mut for ImageBuffer, Container> where A: Primitive + 'static, Container: DerefMut, { - type Out = ArrayViewMut2<'a, A>; + type Out<'a> = ArrayViewMut2<'a, A> + where + Container: 'a; - fn mut_ndarray2(self) -> Self::Out { + fn as_ndarray2_mut(&mut self) -> Self::Out<'_> { let SampleLayout { height, height_stride, @@ -108,7 +112,7 @@ where /// ``` /// use image::RgbImage; -/// use nshare::ToNdarray3; +/// use nshare::IntoNdarray3; /// use ndarray::s; /// /// let zeros = RgbImage::new(2, 4); @@ -117,7 +121,7 @@ where /// // ndarray uses (channel, row, col), so the dims get flipped. /// assert_eq!(nd.dim(), (3, 4, 2)); /// ``` -impl

ToNdarray3 for ImageBuffer> +impl

IntoNdarray3 for ImageBuffer> where P: Pixel + 'static, { @@ -140,12 +144,12 @@ where /// ``` /// use image::{RgbImage, Rgb}; -/// use nshare::RefNdarray3; +/// use nshare::AsNdarray3; /// use ndarray::s; /// /// let mut vals = RgbImage::new(2, 4); /// vals[(1, 0)] = Rgb([0, 255, 0]); -/// let nd = vals.ref_ndarray3(); +/// let nd = vals.as_ndarray3(); /// // ndarray uses (channel, row, col), so the dims get flipped. /// assert_eq!(nd.dim(), (3, 4, 2)); /// // The first row green should sum to 255. @@ -153,13 +157,13 @@ where /// // The first row red should sum to 0. /// assert_eq!(nd.slice(s![0, 0, ..]).sum(), 0); /// ``` -impl<'a, P> RefNdarray3 for &'a ImageBuffer> +impl

AsNdarray3 for ImageBuffer> where P: Pixel + 'static, { - type Out = ArrayView3<'a, P::Subpixel>; + type Out<'a> = ArrayView3<'a, P::Subpixel>; - fn ref_ndarray3(self) -> Self::Out { + fn as_ndarray3(&self) -> Self::Out<'_> { let SampleLayout { channels, channel_stride, @@ -176,21 +180,21 @@ where /// ``` /// use image::{RgbImage, Rgb}; -/// use nshare::MutNdarray3; +/// use nshare::AsNdarray3Mut; /// use ndarray::s; /// /// let mut vals = RgbImage::new(2, 4); /// // Set all the blue channel to 255. -/// vals.mut_ndarray3().slice_mut(s![2, .., ..]).fill(255); +/// vals.as_ndarray3_mut().slice_mut(s![2, .., ..]).fill(255); /// assert_eq!(vals[(0, 0)], Rgb([0, 0, 255])); /// ``` -impl<'a, P> MutNdarray3 for &'a mut ImageBuffer> +impl

AsNdarray3Mut for ImageBuffer> where P: Pixel + 'static, { - type Out = ArrayViewMut3<'a, P::Subpixel>; + type Out<'a> = ArrayViewMut3<'a, P::Subpixel>; - fn mut_ndarray3(self) -> Self::Out { + fn as_ndarray3_mut(&mut self) -> Self::Out<'_> { let SampleLayout { channels, channel_stride, diff --git a/src/tondarray/nalgebra_impl.rs b/src/tondarray/nalgebra_impl.rs index cdf26ff..32202a9 100644 --- a/src/tondarray/nalgebra_impl.rs +++ b/src/tondarray/nalgebra_impl.rs @@ -1,32 +1,30 @@ //! Implementations for nalgebra types being converted to ndarray types. use super::*; -use nalgebra::{ - dimension::U1, - storage::{Storage, StorageMut}, - Dim, Matrix, Scalar, Vector, ViewStorage, ViewStorageMut, -}; +use nalgebra::{dimension::U1, Dim, Dyn, Scalar}; use ndarray::ShapeBuilder; /// ``` -/// use nshare::RefNdarray1; +/// use nshare::AsNdarray1; /// use nalgebra::Vector4; /// use ndarray::s; /// /// let m = Vector4::new( /// 0.1, 0.2, 0.3, 0.4f32, /// ); -/// let arr = m.ref_ndarray1(); +/// let arr = m.as_ndarray1(); /// assert!(arr.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(arr.dim(), 4); /// ``` -impl<'a, N: Scalar, R: Dim, S> RefNdarray1 for &'a Vector +impl AsNdarray1 for nalgebra::Vector where - S: Storage, + S: nalgebra::Storage, { - type Out = ndarray::ArrayView1<'a, N>; + type Out<'a> = ndarray::ArrayView1<'a, N> + where + S: 'a; - fn ref_ndarray1(self) -> Self::Out { + fn as_ndarray1(&self) -> Self::Out<'_> { unsafe { ndarray::ArrayView1::from_shape_ptr( (self.shape().0,).strides((self.strides().0,)), @@ -37,7 +35,7 @@ where } /// ``` -/// use nshare::MutNdarray1; +/// use nshare::AsNdarray1Mut; /// use nalgebra::Vector4; /// use ndarray::s; /// @@ -45,16 +43,18 @@ where /// 0.1, 0.2, 0.3, 0.4f32, /// ); /// // Set everything to 0. -/// m.mut_ndarray1().fill(0.0); +/// m.as_ndarray1_mut().fill(0.0); /// assert!(m.iter().eq(&[0.0; 4])); /// ``` -impl<'a, N: Scalar, R: Dim, S> MutNdarray1 for &'a mut Vector +impl AsNdarray1Mut for nalgebra::Vector where - S: StorageMut, + S: nalgebra::StorageMut, { - type Out = ndarray::ArrayViewMut1<'a, N>; + type Out<'a> = ndarray::ArrayViewMut1<'a, N> + where + S: 'a; - fn mut_ndarray1(self) -> Self::Out { + fn as_ndarray1_mut(&mut self) -> Self::Out<'_> { unsafe { ndarray::ArrayViewMut1::from_shape_ptr( (self.shape().0,).strides((self.strides().0,)), @@ -65,7 +65,7 @@ where } /// ``` -/// use nshare::ToNdarray1; +/// use nshare::IntoNdarray1; /// use nalgebra::Vector4; /// /// let m = Vector4::new( @@ -75,8 +75,8 @@ where /// assert!(arr.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(arr.dim(), 4); /// ``` -impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 - for Vector> +impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> IntoNdarray1 + for nalgebra::Vector> { type Out = ndarray::ArrayView1<'a, N>; @@ -91,7 +91,7 @@ impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 } /// ``` -/// use nshare::ToNdarray1; +/// use nshare::IntoNdarray1; /// use nalgebra::{Vector4, dimension::U2, Const}; /// /// let mut m = Vector4::new( @@ -100,8 +100,8 @@ impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 /// let arr = m.rows_generic_with_step_mut::>(0, Const::<2>, 1).into_ndarray1().fill(0.0); /// assert!(m.iter().eq(&[0.0, 0.2, 0.0, 0.4])); /// ``` -impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 - for Matrix> +impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> IntoNdarray1 + for nalgebra::Matrix> { type Out = ndarray::ArrayViewMut1<'a, N>; @@ -116,7 +116,7 @@ impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 } /// ``` -/// use nshare::RefNdarray2; +/// use nshare::AsNdarray2; /// use nalgebra::Matrix4; /// use ndarray::s; /// @@ -126,17 +126,19 @@ impl<'a, N: Scalar, R: Dim, RStride: Dim, CStride: Dim> ToNdarray1 /// 1.1, 1.2, 1.3, 1.4, /// 1.5, 1.6, 1.7, 1.8, /// ); -/// let arr = m.ref_ndarray2(); +/// let arr = m.as_ndarray2(); /// assert!(arr.slice(s![1, ..]).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// assert_eq!(arr.dim(), (4, 4)); /// ``` -impl<'a, N: Scalar, R: Dim, C: Dim, S> RefNdarray2 for &'a Matrix +impl AsNdarray2 for nalgebra::Matrix where - S: Storage, + S: nalgebra::Storage, { - type Out = ndarray::ArrayView2<'a, N>; + type Out<'a> = ndarray::ArrayView2<'a, N> + where + S: 'a; - fn ref_ndarray2(self) -> Self::Out { + fn as_ndarray2(&self) -> Self::Out<'_> { unsafe { ndarray::ArrayView2::from_shape_ptr(self.shape().strides(self.strides()), self.as_ptr()) } @@ -144,7 +146,7 @@ where } /// ``` -/// use nshare::MutNdarray2; +/// use nshare::AsNdarray2Mut; /// use nalgebra::Matrix4; /// use ndarray::s; /// @@ -154,16 +156,18 @@ where /// 1.1, 1.2, 1.3, 1.4, /// 1.5, 1.6, 1.7, 1.8, /// ); -/// let arr = m.mut_ndarray2().slice_mut(s![1, ..]).fill(0.0); +/// let arr = m.as_ndarray2_mut().slice_mut(s![1, ..]).fill(0.0); /// assert!(m.row(1).iter().eq(&[0.0; 4])); /// ``` -impl<'a, N: Scalar, R: Dim, C: Dim, S> MutNdarray2 for &'a mut Matrix +impl AsNdarray2Mut for nalgebra::Matrix where - S: StorageMut, + S: nalgebra::StorageMut, { - type Out = ndarray::ArrayViewMut2<'a, N>; + type Out<'a> = ndarray::ArrayViewMut2<'a, N> + where + S: 'a; - fn mut_ndarray2(self) -> Self::Out { + fn as_ndarray2_mut(&mut self) -> Self::Out<'_> { unsafe { ndarray::ArrayViewMut2::from_shape_ptr( self.shape().strides(self.strides()), @@ -174,7 +178,7 @@ where } /// ``` -/// use nshare::ToNdarray2; +/// use nshare::IntoNdarray2; /// use nalgebra::Matrix4; /// /// let m = Matrix4::new( @@ -187,8 +191,8 @@ where /// assert!(arr.iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// assert_eq!(arr.dim(), (1, 4)); /// ``` -impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 - for Matrix> +impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoNdarray2 + for nalgebra::Matrix> { type Out = ndarray::ArrayView2<'a, N>; @@ -200,7 +204,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 } /// ``` -/// use nshare::ToNdarray2; +/// use nshare::IntoNdarray2; /// use nalgebra::Matrix4; /// /// let mut m = Matrix4::new( @@ -212,8 +216,8 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 /// let arr = m.row_mut(1).into_ndarray2().fill(0.0); /// assert!(m.row(1).iter().eq(&[0.0; 4])); /// ``` -impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 - for Matrix> +impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoNdarray2 + for nalgebra::Matrix> { type Out = ndarray::ArrayViewMut2<'a, N>; @@ -227,55 +231,51 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ToNdarray2 } } -#[cfg(feature = "nalgebra_std")] -mod std_impl { - use super::*; - use nalgebra::{allocator::Allocator, DVector, DefaultAllocator, Dyn, VecStorage}; - use ndarray::{Array1, Array2}; - /// ``` - /// use nshare::ToNdarray1; - /// use nalgebra::DVector; - /// use ndarray::s; - /// - /// let m = DVector::from_vec(vec![ - /// 0.1, 0.2, 0.3, 0.4, - /// ]); - /// let arr = m.into_ndarray1(); - /// assert_eq!(arr.dim(), 4); - /// assert!(arr.iter().eq(&[0.1, 0.2, 0.3, 0.4])); - /// ``` - impl ToNdarray1 for DVector { - type Out = Array1; +/// ``` +/// use nshare::IntoNdarray1; +/// use nalgebra::DVector; +/// use ndarray::s; +/// +/// let m = DVector::from_vec(vec![ +/// 0.1, 0.2, 0.3, 0.4, +/// ]); +/// let arr = m.into_ndarray1(); +/// assert_eq!(arr.dim(), 4); +/// assert!(arr.iter().eq(&[0.1, 0.2, 0.3, 0.4])); +/// ``` +impl IntoNdarray1 for nalgebra::DVector { + type Out = ndarray::Array1; - fn into_ndarray1(self) -> Self::Out { - Array1::from_shape_vec((self.shape().0,), self.data.into()).unwrap() - } + fn into_ndarray1(self) -> Self::Out { + ndarray::Array1::from_shape_vec((self.shape().0,), self.data.into()).unwrap() } +} - /// ``` - /// use nshare::ToNdarray2; - /// use nalgebra::{Matrix, dimension::{U4, Dynamic}}; - /// use ndarray::s; - /// - /// // Note: from_vec takes data column-by-column ! - /// let m = Matrix::::from_vec(3, 4, vec![ - /// 0.1, 0.2, 0.3, - /// 0.5, 0.6, 0.7, - /// 1.1, 1.2, 1.3, - /// 1.5, 1.6, 1.7, - /// ]); - /// let arr = m.into_ndarray2(); - /// assert!(arr.slice(s![.., 0]).iter().eq(&[0.1, 0.2, 0.3])); - /// assert!(arr.slice(s![0, ..]).iter().eq(&[0.1, 0.5, 1.1, 1.5])); - /// ``` - impl ToNdarray2 for Matrix> - where - DefaultAllocator: Allocator = VecStorage>, - { - type Out = Array2; +/// ``` +/// use nshare::IntoNdarray2; +/// use nalgebra::{Matrix, dimension::{U4, Dynamic}}; +/// use ndarray::s; +/// +/// // Note: from_vec takes data column-by-column ! +/// let m = Matrix::::from_vec(3, 4, vec![ +/// 0.1, 0.2, 0.3, +/// 0.5, 0.6, 0.7, +/// 1.1, 1.2, 1.3, +/// 1.5, 1.6, 1.7, +/// ]); +/// let arr = m.into_ndarray2(); +/// assert!(arr.slice(s![.., 0]).iter().eq(&[0.1, 0.2, 0.3])); +/// assert!(arr.slice(s![0, ..]).iter().eq(&[0.1, 0.5, 1.1, 1.5])); +/// ``` +impl IntoNdarray2 for nalgebra::Matrix> +where + nalgebra::DefaultAllocator: + nalgebra::allocator::Allocator = nalgebra::VecStorage>, +{ + type Out = ndarray::Array2; - fn into_ndarray2(self) -> Self::Out { - Array2::from_shape_vec(self.shape().strides(self.strides()), self.data.into()).unwrap() - } + fn into_ndarray2(self) -> Self::Out { + ndarray::Array2::from_shape_vec(self.shape().strides(self.strides()), self.data.into()) + .unwrap() } } From 30a004d77a692148e52eeca5ad435c9dbe9b6e19 Mon Sep 17 00:00:00 2001 From: Geordon Worley Date: Wed, 28 Aug 2024 16:52:24 -0500 Subject: [PATCH 3/5] update readme with some helpful tips --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6fc93a5..5fcc5b3 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,16 @@ Provides traits that allow conversion between n-dimensional types in different Rust crates -**NOTE**: By default, this crate includes no conversions. You must choose which crates you want to use using the features: +**NOTE**: By default, this crate includes conversions for all supported crates. If you want to limit compilation, use `no-default-features = true` enable the corresponding feature for each dependency: -* `ndarray` * `nalgebra` +* `ndarray` * `image` -When crates are included, any available conversions between the enabled crates are turned on. +When two crate features are enabled, any available conversions between the two crates are turned on. + +## Limitations Right now this crate really only provides conversions to owned and borrowed ndarray types. Some limitations exist with `nalgebra`, as it only utilizes positive strides, while `ndarray` supports negative strides as well. The `image` crate has no concept of strides. Due to this, the `ndarray` crate is the most flexible, and is ideal for interoperability between these various crates. -## Supported Crates -* `image` -* `ndarray` -* `nalgebra` +`nalgebra` currently does not offer a solution to directly pass it an owned vector from `ndarray`, so `into` conversions do perform a copy. It is recommended to create the owned copy in `nalgebra` and then borrow a mutable array view of it using ndarray. You can then populate it accordingly without any copies of the data. From 9665475123548232174789dcb093df7931b6c384 Mon Sep 17 00:00:00 2001 From: Geordon Worley Date: Wed, 28 Aug 2024 19:40:11 -0500 Subject: [PATCH 4/5] update tests --- src/lib.rs | 2 +- src/tonalgebra/ndarray_impl.rs | 32 +++++++++++++++++--------------- tests/nalgebra.rs | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 tests/nalgebra.rs diff --git a/src/lib.rs b/src/lib.rs index 3343c45..c1c23dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![no_std] +// #![no_std] #[cfg(feature = "nalgebra")] mod tonalgebra; diff --git a/src/tonalgebra/ndarray_impl.rs b/src/tonalgebra/ndarray_impl.rs index 9c41404..7ecd8c5 100644 --- a/src/tonalgebra/ndarray_impl.rs +++ b/src/tonalgebra/ndarray_impl.rs @@ -8,7 +8,7 @@ use nalgebra::Dyn; /// ``` /// use nshare::IntoNalgebra; /// -/// let arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]); +/// let arr = ndarray::array![0.1, 0.2, 0.3, 0.4]; /// let m = arr.view().into_nalgebra(); /// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(m.shape(), (4, 1)); @@ -35,7 +35,7 @@ where /// ``` /// use nshare::IntoNalgebra; /// -/// let mut arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]); +/// let mut arr = ndarray::array![0.1, 0.2, 0.3, 0.4]; /// let m = arr.view_mut().into_nalgebra(); /// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(m.shape(), (4, 1)); @@ -63,7 +63,7 @@ where /// ``` /// use nshare::IntoNalgebra; /// -/// let arr = ndarray::arr1(&[0.1, 0.2, 0.3, 0.4]); +/// let arr = ndarray::array![0.1, 0.2, 0.3, 0.4]; /// let m = arr.into_nalgebra(); /// assert!(m.iter().eq(&[0.1, 0.2, 0.3, 0.4])); /// assert_eq!(m.shape(), (4, 1)); @@ -87,12 +87,12 @@ where /// ``` /// use nshare::IntoNalgebra; /// -/// let arr = ndarray::arr2(&[ +/// let arr = ndarray::array![ /// [0.1, 0.2, 0.3, 0.4], /// [0.5, 0.6, 0.7, 0.8], /// [1.1, 1.2, 1.3, 1.4], /// [1.5, 1.6, 1.7, 1.8], -/// ]); +/// ]; /// let m = arr.view().into_nalgebra(); /// assert!(m.row(1).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// assert_eq!(m.shape(), (4, 4)); @@ -107,9 +107,10 @@ where let nrows = Dyn(self.nrows()); let ncols = Dyn(self.ncols()); let ptr = self.as_ptr(); - let stride_row: usize = TryFrom::try_from(self.strides()[0]).expect("Negative row stride"); - let stride_col: usize = - TryFrom::try_from(self.strides()[1]).expect("Negative column stride"); + let stride_row: usize = TryFrom::try_from(self.strides()[0]) + .expect("can only convert positive row stride to nalgebra"); + let stride_col: usize = TryFrom::try_from(self.strides()[1]) + .expect("can only convert positive col stride to nalgebra"); let storage = unsafe { nalgebra::ViewStorage::from_raw_parts( ptr, @@ -124,12 +125,12 @@ where /// ``` /// use nshare::IntoNalgebra; /// -/// let mut arr = ndarray::arr2(&[ +/// let mut arr = ndarray::array![ /// [0.1, 0.2, 0.3, 0.4], /// [0.5, 0.6, 0.7, 0.8], /// [1.1, 1.2, 1.3, 1.4], /// [1.5, 1.6, 1.7, 1.8], -/// ]); +/// ]; /// let m = arr.view_mut().into_nalgebra(); /// assert!(m.row(1).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// assert_eq!(m.shape(), (4, 4)); @@ -143,9 +144,10 @@ where fn into_nalgebra(mut self) -> Self::Out { let nrows = Dyn(self.nrows()); let ncols = Dyn(self.ncols()); - let stride_row: usize = TryFrom::try_from(self.strides()[0]).expect("Negative row stride"); - let stride_col: usize = - TryFrom::try_from(self.strides()[1]).expect("Negative column stride"); + let stride_row: usize = TryFrom::try_from(self.strides()[0]) + .expect("can only convert positive row stride to nalgebra"); + let stride_col: usize = TryFrom::try_from(self.strides()[1]) + .expect("can only convert positive col stride to nalgebra"); let ptr = self.as_mut_ptr(); let storage = unsafe { nalgebra::ViewStorageMut::from_raw_parts( @@ -161,12 +163,12 @@ where /// ``` /// use nshare::IntoNalgebra; /// -/// let mut arr = ndarray::arr2(&[ +/// let mut arr = ndarray::array![ /// [0.1, 0.2, 0.3, 0.4], /// [0.5, 0.6, 0.7, 0.8], /// [1.1, 1.2, 1.3, 1.4], /// [1.5, 1.6, 1.7, 1.8], -/// ]); +/// ]; /// let m = arr.clone().into_nalgebra(); /// assert!(m.row(1).iter().eq(&[0.5, 0.6, 0.7, 0.8])); /// assert_eq!(m.shape(), (4, 4)); diff --git a/tests/nalgebra.rs b/tests/nalgebra.rs new file mode 100644 index 0000000..a9ec38b --- /dev/null +++ b/tests/nalgebra.rs @@ -0,0 +1,16 @@ +use nshare::IntoNalgebra; + +#[test] +fn single_row_ndarray_to_nalgebra() { + let mut arr = ndarray::array![[0.1, 0.2, 0.3, 0.4]]; + let m = arr.view_mut().into_nalgebra(); + assert!(m.row(0).iter().eq(&[0.1, 0.2, 0.3, 0.4])); + assert_eq!(m.shape(), (1, 4)); + assert!(arr + .view_mut() + .reversed_axes() + .into_nalgebra() + .column(0) + .iter() + .eq(&[0.1, 0.2, 0.3, 0.4])); +} From 31b0ae504ae3e8038770a28ddd3dd7553475e582 Mon Sep 17 00:00:00 2001 From: Geordon Worley Date: Wed, 28 Aug 2024 19:45:52 -0500 Subject: [PATCH 5/5] re-add no_std --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c1c23dd..3343c45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -// #![no_std] +#![no_std] #[cfg(feature = "nalgebra")] mod tonalgebra;