diff --git a/nalgebra-lapack/src/symmetric_eigen.rs b/nalgebra-lapack/src/symmetric_eigen.rs index e2d9867b..7a1f6f2e 100644 --- a/nalgebra-lapack/src/symmetric_eigen.rs +++ b/nalgebra-lapack/src/symmetric_eigen.rs @@ -93,8 +93,8 @@ where let n = nrows.value(); let lda = n as i32; - - // IMPORTANT TODO: this is still UB. + + // IMPORTANT TODO: this is still UB. let mut values = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() }; let mut info = 0; diff --git a/nalgebra-sparse/src/ops/serial/csc.rs b/nalgebra-sparse/src/ops/serial/csc.rs index 03acf810..bd43d8e6 100644 --- a/nalgebra-sparse/src/ops/serial/csc.rs +++ b/nalgebra-sparse/src/ops/serial/csc.rs @@ -55,7 +55,7 @@ pub fn spadd_csc_prealloc( a: Op<&CscMatrix>, ) -> Result<(), OperationError> where - T: Scalar + ClosedAdd + ClosedMul + Zero + One+PartialEq, + T: Scalar + ClosedAdd + ClosedMul + Zero + One + PartialEq, { assert_compatible_spadd_dims!(c, a); spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs)) diff --git a/src/base/alias.rs b/src/base/alias.rs index f12fb383..a866935d 100644 --- a/src/base/alias.rs +++ b/src/base/alias.rs @@ -1,7 +1,6 @@ #[cfg(any(feature = "alloc", feature = "std"))] use crate::base::dimension::Dynamic; use crate::base::dimension::{U1, U2, U3, U4, U5, U6}; -use crate::base::storage::InnerOwned; #[cfg(any(feature = "std", feature = "alloc"))] use crate::base::vec_storage::VecStorage; use crate::base::{ArrayStorage, Const, Matrix, Owned, Unit}; @@ -31,7 +30,7 @@ pub type MatrixMN = OMatrix; /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** #[deprecated(note = "use OMatrix or SMatrix instead.")] -pub type MatrixN = Matrix>; +pub type MatrixN = Matrix>; /// A statically sized column-major matrix with `R` rows and `C` columns. /// @@ -274,7 +273,7 @@ pub type Matrix6x5 = Matrix>; pub type DVector = Matrix>; /// An owned D-dimensional column vector. -pub type OVector = Matrix>; +pub type OVector = Matrix>; /// A statically sized D-dimensional column vector. pub type SVector = Matrix, U1, ArrayStorage>; // Owned, U1>>; @@ -284,7 +283,7 @@ pub type SVector = Matrix, U1, ArrayStorage = Matrix>; +pub type VectorN = Matrix>; /// A stack-allocated, 1-dimensional column vector. pub type Vector1 = Matrix>; @@ -311,7 +310,7 @@ pub type Vector6 = Matrix>; pub type RowDVector = Matrix>; /// An owned D-dimensional row vector. -pub type RowOVector = Matrix>; +pub type RowOVector = Matrix>; /// A statically sized D-dimensional row vector. pub type RowSVector = Matrix, ArrayStorage>; diff --git a/src/base/construction.rs b/src/base/construction.rs index 801c3b2d..97e07f43 100644 --- a/src/base/construction.rs +++ b/src/base/construction.rs @@ -1,8 +1,6 @@ #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::vec::Vec; -#[cfg(feature = "arbitrary")] -use crate::base::storage::InnerOwned; #[cfg(feature = "arbitrary")] use quickcheck::{Arbitrary, Gen}; @@ -898,7 +896,6 @@ impl Arbitrary for OMatrix where T: Arbitrary + Send, DefaultAllocator: Allocator, - InnerOwned: Clone + Send, { #[inline] fn arbitrary(g: &mut Gen) -> Self { diff --git a/src/base/default_allocator.rs b/src/base/default_allocator.rs index cce4d848..df8d9208 100644 --- a/src/base/default_allocator.rs +++ b/src/base/default_allocator.rs @@ -66,19 +66,14 @@ impl InnerAllocator, Const> fo impl Allocator, Const> for DefaultAllocator { #[inline] - fn allocate_uninitialized( - _: Const, - _: Const, - ) -> InnerOwned, Const, Const> { + fn allocate_uninitialized(_: Const, _: Const) -> ArrayStorage, R, C> { // SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid. let array = unsafe { MaybeUninit::uninit().assume_init() }; ArrayStorage(array) } #[inline] - unsafe fn assume_init( - uninit: , Const, Const>>::Buffer, - ) -> InnerOwned, Const> { + unsafe fn assume_init(uninit: ArrayStorage, R, C>) -> ArrayStorage { // Safety: // * The caller guarantees that all elements of the array are initialized // * `MaybeUninit` and T are guaranteed to have the same layout @@ -89,9 +84,7 @@ impl Allocator, Const> for Def /// Specifies that a given buffer's entries should be manually dropped. #[inline] - fn manually_drop( - buf: , Const>>::Buffer, - ) -> , Const, Const>>::Buffer { + fn manually_drop(buf: ArrayStorage) -> ArrayStorage, R, C> { // SAFETY: // * `ManuallyDrop` and T are guaranteed to have the same layout // * `ManuallyDrop` does not drop, so there are no double-frees @@ -123,7 +116,7 @@ impl InnerAllocator for DefaultAllocator { impl Allocator for DefaultAllocator { #[inline] - fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> InnerOwned, Dynamic, C> { + fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> VecStorage, Dynamic, C> { let mut data = Vec::new(); let length = nrows.value() * ncols.value(); data.reserve_exact(length); @@ -134,8 +127,8 @@ impl Allocator for DefaultAllocator { #[inline] unsafe fn assume_init( - uninit: InnerOwned, Dynamic, C>, - ) -> InnerOwned { + uninit: VecStorage, Dynamic, C>, + ) -> VecStorage { // Avoids a double-drop. let (nrows, ncols) = uninit.shape(); let vec: Vec<_> = uninit.into(); @@ -150,9 +143,7 @@ impl Allocator for DefaultAllocator { } #[inline] - fn manually_drop( - buf: >::Buffer, - ) -> , Dynamic, C>>::Buffer { + fn manually_drop(buf: VecStorage) -> VecStorage, Dynamic, C> { // Avoids a double-drop. let (nrows, ncols) = buf.shape(); let vec: Vec<_> = buf.into(); @@ -178,7 +169,7 @@ impl InnerAllocator for DefaultAllocator { nrows: R, ncols: Dynamic, iter: I, - ) -> InnerOwned { + ) -> Self::Buffer { let it = iter.into_iter(); let res: Vec = it.collect(); assert!(res.len() == nrows.value() * ncols.value(), @@ -190,7 +181,7 @@ impl InnerAllocator for DefaultAllocator { impl Allocator for DefaultAllocator { #[inline] - fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> InnerOwned, R, Dynamic> { + fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> VecStorage, R, Dynamic> { let mut data = Vec::new(); let length = nrows.value() * ncols.value(); data.reserve_exact(length); @@ -201,8 +192,8 @@ impl Allocator for DefaultAllocator { #[inline] unsafe fn assume_init( - uninit: InnerOwned, R, Dynamic>, - ) -> InnerOwned { + uninit: VecStorage, R, Dynamic>, + ) -> VecStorage { // Avoids a double-drop. let (nrows, ncols) = uninit.shape(); let vec: Vec<_> = uninit.into(); @@ -217,9 +208,7 @@ impl Allocator for DefaultAllocator { } #[inline] - fn manually_drop( - buf: >::Buffer, - ) -> , R, Dynamic>>::Buffer { + fn manually_drop(buf: VecStorage) -> VecStorage, R, Dynamic> { // Avoids a double-drop. let (nrows, ncols) = buf.shape(); let vec: Vec<_> = buf.into(); @@ -239,18 +228,18 @@ impl Allocator for DefaultAllocator { #[repr(transparent)] pub struct Owned(pub InnerOwned) where - DefaultAllocator: Allocator; + DefaultAllocator: InnerAllocator; -impl Copy for Owned +impl Copy for Owned where - DefaultAllocator: Allocator, + DefaultAllocator: InnerAllocator, InnerOwned: Copy, { } impl Clone for Owned where - DefaultAllocator: Allocator, + DefaultAllocator: InnerAllocator, { fn clone(&self) -> Self { if Self::is_array() { @@ -260,23 +249,21 @@ where // We then transmute it back into an array and then an Owned. unsafe { mem::transmute_copy(&*vec.as_ptr()) } - - // TODO: check that the auxiliary copy is elided. } else { // We first clone the data. let clone = ManuallyDrop::new(self.as_vec_storage().clone()); // We then transmute it back into an Owned. unsafe { mem::transmute_copy(&clone) } - - // TODO: check that the auxiliary copy is elided. } + + // TODO: check that the auxiliary copies are elided. } } impl fmt::Debug for Owned where - DefaultAllocator: Allocator, + DefaultAllocator: InnerAllocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if Self::is_array() { @@ -288,22 +275,28 @@ where } } +impl Owned, Const> { + fn new(array: [[T; R]; C]) -> Self { + Self(ArrayStorage(array)) + } +} + impl Owned where - DefaultAllocator: Allocator, + DefaultAllocator: InnerAllocator, { - /// Returns whether `Self` stores an [`ArrayStorage`]. - fn is_array() -> bool { + /// Returns whether `Self` stores an [`ArrayStorage`]. This is a zero-cost + /// operation. + const fn is_array() -> bool { R::is_static() && C::is_static() } /// Returns whether `Self` stores a [`VecStorage`]. - fn is_vec() -> bool { + const fn is_vec() -> bool { !Self::is_array() } - /// Returns the underlying [`VecStorage`]. Does not do any sort of static - /// type checking. + /// Returns a reference to the underlying [`VecStorage`]. /// /// # Panics /// This method will panic if `Self` does not contain a [`VecStorage`]. @@ -311,13 +304,24 @@ where assert!(Self::is_vec()); // Safety: `self` is transparent and must contain a `VecStorage`. - unsafe { &*(&self as *const _ as *const _) } + unsafe { &*(self as *const _ as *const _) } + } + + /// Returns a mutable reference to the underlying [`VecStorage`]. + /// + /// # Panics + /// This method will panic if `Self` does not contain a [`VecStorage`]. + fn as_vec_storage_mut(&mut self) -> &mut VecStorage { + assert!(Self::is_vec()); + + // Safety: `self` is transparent and must contain a `VecStorage`. + unsafe { &mut *(self as *mut _ as *mut _) } } } unsafe impl Storage for Owned where - DefaultAllocator: Allocator, + DefaultAllocator: InnerAllocator, { type RStride = U1; @@ -349,6 +353,7 @@ where } } + #[inline(always)] fn is_contiguous(&self) -> bool { true } @@ -364,11 +369,13 @@ where } } - fn into_owned(self) -> Owned { + #[inline(always)] + fn into_owned(self) -> Self { self } - fn clone_owned(&self) -> Owned + #[inline(always)] + fn clone_owned(&self) -> Self where T: Clone, { @@ -378,24 +385,35 @@ where unsafe impl StorageMut for Owned where - DefaultAllocator: Allocator, + DefaultAllocator: InnerAllocator, { fn ptr_mut(&mut self) -> *mut T { - todo!() + if Self::is_array() { + &mut self as *mut _ as *mut T + } else { + self.as_vec_storage_mut().as_vec().as_ptr() + } } unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { - todo!() + if Self::is_array() { + std::slice::from_raw_parts( + self.ptr_mut(), + R::try_to_usize().unwrap() * C::try_to_usize().unwrap(), + ) + } else { + self.as_vec_storage_mut().as_vec_mut().as_mut() + } } } unsafe impl ContiguousStorage for Owned where - DefaultAllocator: Allocator + DefaultAllocator: InnerAllocator { } unsafe impl ContiguousStorageMut for Owned where - DefaultAllocator: Allocator + DefaultAllocator: InnerAllocator { } diff --git a/src/base/matrix.rs b/src/base/matrix.rs index 9bbe7261..b5353ffb 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -153,7 +153,7 @@ pub type MatrixCross = /// dynamically-sized column vector should be represented as a `Matrix` (given /// some concrete types for `T` and a compatible data storage type `S`). #[repr(transparent)] -#[derive(Clone,Copy,Debug)] +#[derive(Clone, Copy, Debug)] pub struct Matrix { /// The data storage that contains all the matrix components. Disappointed? /// diff --git a/src/base/ops.rs b/src/base/ops.rs index dee83c98..f252aaf3 100644 --- a/src/base/ops.rs +++ b/src/base/ops.rs @@ -16,7 +16,6 @@ use crate::base::constraint::{ use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dynamic}; use crate::base::storage::{ContiguousStorageMut, Storage, StorageMut}; use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar, VectorSlice}; -use crate::storage::InnerOwned; use crate::{MatrixSliceMut, SimdComplexField}; /* @@ -432,11 +431,6 @@ impl<'a, T, C: Dim> iter::Sum<&'a OMatrix> for OMatrix, - - // TODO: we should take out this trait bound, as T: Clone should suffice. - // The brute way to do it would be how it was already done: by adding this - // trait bound on the associated type itself. - InnerOwned: Clone, { /// # Example /// ``` diff --git a/src/base/storage.rs b/src/base/storage.rs index 24fc14f5..1f06a11e 100644 --- a/src/base/storage.rs +++ b/src/base/storage.rs @@ -10,21 +10,19 @@ use crate::base::Owned; /* * Aliases for allocation results. */ -/// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`. -pub type SameShapeStorage = - , SameShapeC>>::Buffer; // TODO: better name than Owned ? /// The owned data storage that can be allocated from `S`. pub type InnerOwned = >::Buffer; +/// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`. +pub type SameShapeStorage = Owned, SameShapeC>; + /// The row-stride of the owned data storage for a buffer of dimension `(R, C)`. -pub type RStride = - <>::Buffer as Storage>::RStride; +pub type RStride = as Storage>::RStride; /// The column-stride of the owned data storage for a buffer of dimension `(R, C)`. -pub type CStride = - <>::Buffer as Storage>::CStride; +pub type CStride = as Storage>::CStride; /// The trait shared by all matrix data storage. /// diff --git a/src/linalg/schur.rs b/src/linalg/schur.rs index 583c0397..9e752b23 100644 --- a/src/linalg/schur.rs +++ b/src/linalg/schur.rs @@ -1,6 +1,5 @@ #![allow(clippy::suspicious_operation_groupings)] use std::cmp; -use std::fmt; use std::mem::MaybeUninit; #[cfg(feature = "serde-serialize-no-std")] @@ -11,10 +10,10 @@ use num_complex::Complex as NumComplex; use simba::scalar::{ComplexField, RealField}; use crate::allocator::Allocator; -use crate::base::dimension::{Const, Dim, DimDiff, DimName, DimSub, Dynamic, U1, U2}; +use crate::base::dimension::{Const, Dim, DimDiff, DimSub, Dynamic, U1, U2}; use crate::base::storage::{InnerOwned, Storage}; use crate::base::{ - DefaultAllocator, OMatrix, OVector, Owned, SquareMatrix, Unit, Vector2, Vector3, + DefaultAllocator, OMatrix, OVector, SquareMatrix, Unit, Vector2, Vector3, }; use crate::geometry::Reflection; @@ -36,6 +35,7 @@ use crate::linalg::Hessenberg; serde(bound(deserialize = "DefaultAllocator: Allocator, OMatrix: Deserialize<'de>")) )] +#[derive(Clone, Debug)] pub struct Schur where DefaultAllocator: Allocator, @@ -44,39 +44,13 @@ where t: OMatrix, } -impl Copy for Schur +impl Copy for Schur where DefaultAllocator: Allocator, - Owned: Copy, + InnerOwned: Copy, { } -impl Clone for Schur -where - DefaultAllocator: Allocator, - InnerOwned: Clone, -{ - fn clone(&self) -> Self { - Self { - q: self.q.clone(), - t: self.t.clone(), - } - } -} - -impl fmt::Debug for Schur -where - DefaultAllocator: Allocator, - InnerOwned: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Schur") - .field("q", &self.q) - .field("t", &self.t) - .finish() - } -} - impl Schur where D: DimSub, // For Hessenberg. diff --git a/src/linalg/svd.rs b/src/linalg/svd.rs index c2f58221..355d1569 100644 --- a/src/linalg/svd.rs +++ b/src/linalg/svd.rs @@ -1,5 +1,3 @@ -use std::fmt; - #[cfg(feature = "serde-serialize-no-std")] use serde::{Deserialize, Serialize}; @@ -41,6 +39,7 @@ use crate::linalg::Bidiagonal; OVector>: Deserialize<'de>" )) )] +#[derive(Clone, Debug)] pub struct SVD, C: Dim> where DefaultAllocator: Allocator, C> @@ -66,42 +65,6 @@ where { } -impl, C: Dim> Clone for SVD -where - DefaultAllocator: Allocator, C> - + Allocator> - + Allocator>, - InnerOwned>: Clone, - InnerOwned, C>: Clone, - InnerOwned>: Clone, -{ - fn clone(&self) -> Self { - Self { - u: self.u.clone(), - v_t: self.v_t.clone(), - singular_values: self.singular_values.clone(), - } - } -} - -impl, C: Dim> fmt::Debug for SVD -where - DefaultAllocator: Allocator, C> - + Allocator> - + Allocator>, - InnerOwned>: fmt::Debug, - InnerOwned, C>: fmt::Debug, - InnerOwned>: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SVD") - .field("u", &self.u) - .field("v_t", &self.v_t) - .field("singular_values", &self.singular_values) - .finish() - } -} - impl, C: Dim> SVD where DimMinimum: DimSub, // for Bidiagonal.