From 3bc3df09a178d2787a3cb4c34faebd8eb5d164aa Mon Sep 17 00:00:00 2001 From: Lishen Date: Tue, 21 Nov 2023 12:39:01 +0300 Subject: [PATCH 1/3] add straightforward implementation of From trait for SMatrix<->DMatrix and SVector<->DVector conversation --- src/base/conversion.rs | 31 ++++++++++++++++++- tests/core/matrix.rs | 68 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/base/conversion.rs b/src/base/conversion.rs index 783e6d9ed..ace35fe45 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -23,7 +23,10 @@ use crate::base::{ use crate::base::{DVector, RowDVector, VecStorage}; use crate::base::{ViewStorage, ViewStorageMut}; use crate::constraint::DimEq; -use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut}; +use crate::{ + DMatrix, DMatrixView, IsNotStaticOne, RowSVector, SMatrix, SMatrixView, SVector, SVectorView, + VectorView, VectorViewMut, +}; use std::mem::MaybeUninit; // TODO: too bad this won't work for slice conversions. @@ -428,6 +431,32 @@ where } } +impl<'a, T: Scalar, const R: usize, const C: usize> From<&'a DMatrix> for SMatrix { + fn from(m: &'a DMatrix) -> Self { + let v: DMatrixView<'a, T> = m.as_view(); + SMatrixView::::from(&v).clone_owned() + } +} +impl<'a, T: Scalar, const R: usize, const C: usize> From<&'a SMatrix> for DMatrix { + fn from(m: &'a SMatrix) -> Self { + let v: SMatrixView<'a, T, R, C> = m.as_view(); + DMatrixView::::from(&v).clone_owned() + } +} +impl<'a, T: Scalar, const R: usize> From<&'a DVector> for SVector { + fn from(m: &'a DVector) -> Self { + let v: DVectorView<'a, T> = m.as_view(); + SVectorView::::from(&v).clone_owned() + } +} + +impl<'a, T: Scalar, const R: usize> From<&'a SVector> for DVector { + fn from(m: &'a SVector) -> Self { + let v: SVectorView<'a, T, R> = m.as_view(); + DVectorView::::from(&v).clone_owned() + } +} + impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix> for MatrixView<'a, T, RView, CView, RStride, CStride> where diff --git a/tests/core/matrix.rs b/tests/core/matrix.rs index 501a05665..18a167ad2 100644 --- a/tests/core/matrix.rs +++ b/tests/core/matrix.rs @@ -6,7 +6,8 @@ use na::dimension::{U15, U8}; use na::{ self, Const, DMatrix, DVector, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, Matrix4x3, Matrix4x5, Matrix5, Matrix6, MatrixView2x3, MatrixViewMut2x3, OMatrix, - RowVector3, RowVector4, RowVector5, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, + RowVector3, RowVector4, RowVector5, SMatrix, SVector, Vector1, Vector2, Vector3, Vector4, + Vector5, Vector6, }; #[test] @@ -1332,3 +1333,68 @@ fn parallel_column_iteration_mut() { assert_eq!(first, second); assert_eq!(second, DMatrix::identity(400, 300)); } + +#[test] +fn dmatrix_from_smatrix() { + type T = f64; + let s = SMatrix::::from_fn(|i, j| (i * 3) as T + j as T); + let d = DMatrix::::from(&s); + assert_eq!(d, s); +} + +#[test] +fn smatrix_from_dmatrix() { + type T = f64; + let d = DMatrix::::from_fn(3, 3, |i, j| (i * 3) as T + j as T); + let s = SMatrix::::from(&d); + assert_eq!(d, s); +} + +#[test] +fn svector_from_dvector() { + type T = f64; + let d = DVector::::from_fn(3, |i, j| (i * 3) as T + j as T); + let s = SVector::::from(&d); + assert_eq!(d, s); +} + +#[test] +fn dvector_from_svector() { + type T = f64; + let s = SVector::::from_fn(|i, j| (i * 3) as T + j as T); + let d = DVector::::from(&s); + assert_eq!(d, s); +} + +#[test] +fn svector3_from_dvector() { + type T = f64; + let d = DVector::::from_fn(3, |i, j| (i * 3) as T + j as T); + let s = Vector3::::from(&d); + assert_eq!(d, s); +} + +#[test] +fn dvector_from_svector3() { + type T = f64; + let s = Vector3::::from_fn(|i, j| (i * 3) as T + j as T); + let d = DVector::::from(&s); + assert_eq!(d, s); +} + +#[test] +fn svector3_from_dmatrix3x1() { + type T = f64; + let d = DMatrix::::from_fn(3, 1, |i, j| (i * 3) as T + j as T); + let s = Vector3::::from(&d); + assert_eq!(d, s); +} + +#[test] +#[should_panic] +fn svector3_from_dmatrix3x3() { + type T = f64; + let d = DMatrix::::from_fn(3, 3, |i, j| (i * 3) as T + j as T); + let s = Vector3::::from(&d); + assert_eq!(d, s); +} From d65b4574108af79beff94d5fc3c5739e19f811fe Mon Sep 17 00:00:00 2001 From: Lishen Date: Tue, 21 Nov 2023 18:06:22 +0300 Subject: [PATCH 2/3] fix build without default features --- src/base/conversion.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/base/conversion.rs b/src/base/conversion.rs index ace35fe45..acb404119 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -19,14 +19,15 @@ use crate::base::{ ArrayStorage, DVectorView, DVectorViewMut, DefaultAllocator, Matrix, MatrixView, MatrixViewMut, OMatrix, Scalar, }; +//TODO: move near From implementation? #[cfg(any(feature = "std", feature = "alloc"))] -use crate::base::{DVector, RowDVector, VecStorage}; +use crate::base::{DMatrixView, SMatrixView, SVectorView}; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::base::{DMatrix, DVector, RowDVector, VecStorage}; use crate::base::{ViewStorage, ViewStorageMut}; use crate::constraint::DimEq; -use crate::{ - DMatrix, DMatrixView, IsNotStaticOne, RowSVector, SMatrix, SMatrixView, SVector, SVectorView, - VectorView, VectorViewMut, -}; +use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut}; use std::mem::MaybeUninit; // TODO: too bad this won't work for slice conversions. @@ -431,18 +432,23 @@ where } } +#[cfg(any(feature = "std", feature = "alloc"))] impl<'a, T: Scalar, const R: usize, const C: usize> From<&'a DMatrix> for SMatrix { fn from(m: &'a DMatrix) -> Self { let v: DMatrixView<'a, T> = m.as_view(); SMatrixView::::from(&v).clone_owned() } } + +#[cfg(any(feature = "std", feature = "alloc"))] impl<'a, T: Scalar, const R: usize, const C: usize> From<&'a SMatrix> for DMatrix { fn from(m: &'a SMatrix) -> Self { let v: SMatrixView<'a, T, R, C> = m.as_view(); DMatrixView::::from(&v).clone_owned() } } + +#[cfg(any(feature = "std", feature = "alloc"))] impl<'a, T: Scalar, const R: usize> From<&'a DVector> for SVector { fn from(m: &'a DVector) -> Self { let v: DVectorView<'a, T> = m.as_view(); @@ -450,6 +456,7 @@ impl<'a, T: Scalar, const R: usize> From<&'a DVector> for SVector { } } +#[cfg(any(feature = "std", feature = "alloc"))] impl<'a, T: Scalar, const R: usize> From<&'a SVector> for DVector { fn from(m: &'a SVector) -> Self { let v: SVectorView<'a, T, R> = m.as_view(); From 62e7d8a43e813ac47e1cafc6accfb8779ab277bb Mon Sep 17 00:00:00 2001 From: Lishen <> Date: Sun, 5 May 2024 02:26:03 +0300 Subject: [PATCH 3/3] more generic static<->dynamic conversation --- src/base/conversion.rs | 71 +++++++++++++++++++++++++++++------------- tests/core/matrix.rs | 23 +++++--------- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/base/conversion.rs b/src/base/conversion.rs index acb404119..7dfc07014 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -1,5 +1,7 @@ #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::vec::Vec; +use core::convert::TryFrom; +use core::panic; use simba::scalar::{SubsetOf, SupersetOf}; use std::borrow::{Borrow, BorrowMut}; use std::convert::{AsMut, AsRef, From, Into}; @@ -19,12 +21,8 @@ use crate::base::{ ArrayStorage, DVectorView, DVectorViewMut, DefaultAllocator, Matrix, MatrixView, MatrixViewMut, OMatrix, Scalar, }; -//TODO: move near From implementation? #[cfg(any(feature = "std", feature = "alloc"))] -use crate::base::{DMatrixView, SMatrixView, SVectorView}; - -#[cfg(any(feature = "std", feature = "alloc"))] -use crate::base::{DMatrix, DVector, RowDVector, VecStorage}; +use crate::base::{DVector, RowDVector, VecStorage}; use crate::base::{ViewStorage, ViewStorageMut}; use crate::constraint::DimEq; use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut}; @@ -433,34 +431,65 @@ where } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T: Scalar, const R: usize, const C: usize> From<&'a DMatrix> for SMatrix { - fn from(m: &'a DMatrix) -> Self { - let v: DMatrixView<'a, T> = m.as_view(); - SMatrixView::::from(&v).clone_owned() +impl<'a, T: Scalar, const R0: usize, const C0: usize, R1: Dim, C1: Dim> + TryFrom<&VecStorage> for ArrayStorage +{ + // TODO: where to put Error enum ? + type Error = (); + + fn try_from(vstorage: &VecStorage) -> Result { + if R0 * C0 != vstorage.len() { + Err(()) + } else { + let mut data = MaybeUninit::<[[T; R0]; C0]>::uninit(); + unsafe { core::slice::from_raw_parts_mut(data.as_mut_ptr() as *mut T, R0 * C0) } + .clone_from_slice(vstorage.as_slice()); + Ok(Self(unsafe { data.assume_init() })) + } } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T: Scalar, const R: usize, const C: usize> From<&'a SMatrix> for DMatrix { - fn from(m: &'a SMatrix) -> Self { - let v: SMatrixView<'a, T, R, C> = m.as_view(); - DMatrixView::::from(&v).clone_owned() +impl<'a, T: Scalar, const R0: usize, const C0: usize, R1: Dim, C1: Dim> + From<&ArrayStorage> for VecStorage +{ + fn from(astorage: &ArrayStorage) -> Self { + VecStorage::new( + R1::from_usize(R0), + C1::from_usize(C0), + Vec::from(astorage.as_slice()), + ) } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T: Scalar, const R: usize> From<&'a DVector> for SVector { - fn from(m: &'a DVector) -> Self { - let v: DVectorView<'a, T> = m.as_view(); - SVectorView::::from(&v).clone_owned() +impl<'a, T: Scalar, const R0: usize, const C0: usize, R1: Dim, C1: Dim> + From<&'a Matrix>> + for Matrix, Const, ArrayStorage> +where + VecStorage: RawStorage, +{ + fn from(m: &'a Matrix>) -> Self { + match ArrayStorage::::try_from(&m.data) { + Ok(s) => { + assert_eq!(R0, m.nrows()); + assert_eq!(C0, m.ncols()); + Self::from_array_storage(s) + } + Err(_) => panic!("storage dimensions mismatch"), + } } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T: Scalar, const R: usize> From<&'a SVector> for DVector { - fn from(m: &'a SVector) -> Self { - let v: SVectorView<'a, T, R> = m.as_view(); - DVectorView::::from(&v).clone_owned() +impl<'a, T: Scalar, const R0: usize, const C0: usize, R1: Dim, C1: Dim> + From<&'a Matrix, Const, ArrayStorage>> + for Matrix> +where + VecStorage: RawStorage, +{ + fn from(m: &'a Matrix, Const, ArrayStorage>) -> Self { + Self::from_data(VecStorage::from(&m.data)) } } diff --git a/tests/core/matrix.rs b/tests/core/matrix.rs index 18a167ad2..05d69d80c 100644 --- a/tests/core/matrix.rs +++ b/tests/core/matrix.rs @@ -1366,22 +1366,6 @@ fn dvector_from_svector() { assert_eq!(d, s); } -#[test] -fn svector3_from_dvector() { - type T = f64; - let d = DVector::::from_fn(3, |i, j| (i * 3) as T + j as T); - let s = Vector3::::from(&d); - assert_eq!(d, s); -} - -#[test] -fn dvector_from_svector3() { - type T = f64; - let s = Vector3::::from_fn(|i, j| (i * 3) as T + j as T); - let d = DVector::::from(&s); - assert_eq!(d, s); -} - #[test] fn svector3_from_dmatrix3x1() { type T = f64; @@ -1398,3 +1382,10 @@ fn svector3_from_dmatrix3x3() { let s = Vector3::::from(&d); assert_eq!(d, s); } +#[test] +fn dmatrix_from_svector3() { + type T = f64; + let s = SVector::::from_fn(|i, j| (i * 3) as T + j as T); + let d = DMatrix::::from(&s); + assert_eq!(d, s); +}