Miscellaneous improvements

This commit is contained in:
Violeta Hernández 2021-07-17 21:43:50 -05:00
parent 10b5dc9bb6
commit b74be8499f
17 changed files with 86 additions and 69 deletions

View File

@ -57,9 +57,8 @@ where
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
let mut info = 0; let mut info = 0;
let mut tau = unsafe { let mut tau =
Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() };
};
if nrows.value() == 0 || ncols.value() == 0 { if nrows.value() == 0 || ncols.value() == 0 {
return Self { qr: m, tau: tau }; return Self { qr: m, tau: tau };

View File

@ -1,4 +1,5 @@
use std::mem;use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
use std::mem;
// use std::hash::{Hash, Hasher}; // use std::hash::{Hash, Hasher};
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
use std::io::{Result as IOResult, Write}; use std::io::{Result as IOResult, Write};
@ -12,8 +13,6 @@ use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use std::marker::PhantomData; use std::marker::PhantomData;
#[cfg(feature = "serde-serialize-no-std")]
use std::mem;
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation; use abomonation::Abomonation;

View File

@ -146,7 +146,7 @@ macro_rules! component_binop_impl(
); );
/// # Componentwise operations /// # Componentwise operations
impl<T:Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> { impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
component_binop_impl!( component_binop_impl!(
component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign, component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
r" r"

View File

@ -4,7 +4,7 @@
//! heap-allocated buffers for matrices with at least one dimension unknown at compile-time. //! heap-allocated buffers for matrices with at least one dimension unknown at compile-time.
use std::cmp; use std::cmp;
use std::mem::{self, ManuallyDrop, MaybeUninit}; use std::mem::{ManuallyDrop, MaybeUninit};
use std::ptr; use std::ptr;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
@ -92,9 +92,8 @@ impl<T, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>> for Def
// SAFETY: // SAFETY:
// * `ManuallyDrop<T>` and T are guaranteed to have the same layout // * `ManuallyDrop<T>` and T are guaranteed to have the same layout
// * `ManuallyDrop` does not drop, so there are no double-frees // * `ManuallyDrop` does not drop, so there are no double-frees
// * `ArrayStorage` is transparent.
// And thus the conversion is safe // And thus the conversion is safe
ArrayStorage(unsafe { mem::transmute_copy(&ManuallyDrop::new(buf.0)) }) unsafe { ArrayStorage((&ManuallyDrop::new(buf) as *const _ as *const [_; C]).read()) }
} }
} }
@ -132,32 +131,35 @@ impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
#[inline] #[inline]
unsafe fn assume_init(uninit: Owned<MaybeUninit<T>, Dynamic, C>) -> Owned<T, Dynamic, C> { unsafe fn assume_init(uninit: Owned<MaybeUninit<T>, Dynamic, C>) -> Owned<T, Dynamic, C> {
let mut data = ManuallyDrop::new(uninit.data); // Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
let mut md = ManuallyDrop::new(vec);
// Safety: MaybeUninit<T> has the same alignment and layout as T. // Safety:
let new_data = // - MaybeUninit<T> has the same alignment and layout as T.
Vec::from_raw_parts(data.as_mut_ptr() as *mut T, data.len(), data.capacity()); // - The length and capacity come from a valid vector.
let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
VecStorage::new(uninit.nrows, uninit.ncols, new_data) VecStorage::new(nrows, ncols, new_data)
} }
#[inline] #[inline]
fn manually_drop( fn manually_drop(
buf: <Self as InnerAllocator<T, Dynamic, C>>::Buffer, buf: <Self as InnerAllocator<T, Dynamic, C>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, Dynamic, C>>::Buffer { ) -> <Self as InnerAllocator<ManuallyDrop<T>, Dynamic, C>>::Buffer {
// Avoids dropping the buffer that will be used for the result. // Avoids a double-drop.
let mut data = ManuallyDrop::new(buf.data); let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
let mut md = ManuallyDrop::new(vec);
// Safety: ManuallyDrop<T> has the same alignment and layout as T. // Safety:
let new_data = unsafe { // - ManuallyDrop<T> has the same alignment and layout as T.
Vec::from_raw_parts( // - The length and capacity come from a valid vector.
data.as_mut_ptr() as *mut ManuallyDrop<T>, let new_data =
data.len(), unsafe { Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity()) };
data.capacity(),
)
};
VecStorage::new(buf.nrows, buf.ncols, new_data) VecStorage::new(nrows, ncols, new_data)
} }
} }
@ -194,32 +196,35 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[inline] #[inline]
unsafe fn assume_init(uninit: Owned<MaybeUninit<T>, R, Dynamic>) -> Owned<T, R, Dynamic> { unsafe fn assume_init(uninit: Owned<MaybeUninit<T>, R, Dynamic>) -> Owned<T, R, Dynamic> {
let mut data = ManuallyDrop::new(uninit.data); // Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
let mut md = ManuallyDrop::new(vec);
// Safety: MaybeUninit<T> has the same alignment and layout as T. // Safety:
let new_data = // - MaybeUninit<T> has the same alignment and layout as T.
Vec::from_raw_parts(data.as_mut_ptr() as *mut T, data.len(), data.capacity()); // - The length and capacity come from a valid vector.
let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
VecStorage::new(uninit.nrows, uninit.ncols, new_data) VecStorage::new(nrows, ncols, new_data)
} }
#[inline] #[inline]
fn manually_drop( fn manually_drop(
buf: <Self as InnerAllocator<T, R, Dynamic>>::Buffer, buf: <Self as InnerAllocator<T, R, Dynamic>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, R, Dynamic>>::Buffer { ) -> <Self as InnerAllocator<ManuallyDrop<T>, R, Dynamic>>::Buffer {
// Avoids dropping the buffer that will be used for the result. // Avoids a double-drop.
let mut data = ManuallyDrop::new(buf.data); let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
let mut md = ManuallyDrop::new(vec);
// Safety: ManuallyDrop<T> has the same alignment and layout as T. // Safety:
let new_data = unsafe { // - ManuallyDrop<T> has the same alignment and layout as T.
Vec::from_raw_parts( // - The length and capacity come from a valid vector.
data.as_mut_ptr() as *mut ManuallyDrop<T>, let new_data =
data.len(), unsafe { Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity()) };
data.capacity(),
)
};
VecStorage::new(buf.nrows, buf.ncols, new_data) VecStorage::new(nrows, ncols, new_data)
} }
} }

View File

@ -385,6 +385,10 @@ where
/// Assumes a matrix's entries to be initialized. This operation should be near zero-cost. /// Assumes a matrix's entries to be initialized. This operation should be near zero-cost.
/// ///
/// For the similar method that operates on matrix slices, see [`slice_assume_init`]. /// For the similar method that operates on matrix slices, see [`slice_assume_init`].
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init(self) -> OMatrix<T, R, C> { pub unsafe fn assume_init(self) -> OMatrix<T, R, C> {
OMatrix::from_data(<DefaultAllocator as Allocator<T, R, C>>::assume_init( OMatrix::from_data(<DefaultAllocator as Allocator<T, R, C>>::assume_init(
self.data, self.data,
@ -408,6 +412,10 @@ where
impl<T, R: Dim, C: Dim, S> Matrix<MaybeUninit<T>, R, C, S> { impl<T, R: Dim, C: Dim, S> Matrix<MaybeUninit<T>, R, C, S> {
/// Creates a full slice from `self` and assumes it to be initialized. /// Creates a full slice from `self` and assumes it to be initialized.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init_ref(&self) -> MatrixSlice<T, R, C, S::RStride, S::CStride> pub unsafe fn assume_init_ref(&self) -> MatrixSlice<T, R, C, S::RStride, S::CStride>
where where
S: Storage<MaybeUninit<T>, R, C>, S: Storage<MaybeUninit<T>, R, C>,
@ -416,6 +424,10 @@ impl<T, R: Dim, C: Dim, S> Matrix<MaybeUninit<T>, R, C, S> {
} }
/// Creates a full mutable slice from `self` and assumes it to be initialized. /// Creates a full mutable slice from `self` and assumes it to be initialized.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init_mut(&mut self) -> MatrixSliceMut<T, R, C, S::RStride, S::CStride> pub unsafe fn assume_init_mut(&mut self) -> MatrixSliceMut<T, R, C, S::RStride, S::CStride>
where where
S: StorageMut<MaybeUninit<T>, R, C>, S: StorageMut<MaybeUninit<T>, R, C>,

View File

@ -237,6 +237,10 @@ impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
SliceStorageMut<'a, MaybeUninit<T>, R, C, RStride, CStride> SliceStorageMut<'a, MaybeUninit<T>, R, C, RStride, CStride>
{ {
/// Assumes a slice storage's entries to be initialized. This operation should be near zero-cost. /// Assumes a slice storage's entries to be initialized. This operation should be near zero-cost.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init(self) -> SliceStorageMut<'a, T, R, C, RStride, CStride> { pub unsafe fn assume_init(self) -> SliceStorageMut<'a, T, R, C, RStride, CStride> {
SliceStorageMut::from_raw_parts(self.ptr as *mut T, self.shape, self.strides) SliceStorageMut::from_raw_parts(self.ptr as *mut T, self.shape, self.strides)
} }
@ -1012,6 +1016,6 @@ impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
_phantoms: PhantomData, _phantoms: PhantomData,
}; };
Matrix::from_data(data) Matrix::from_data(data)
} }
} }

View File

@ -7,7 +7,7 @@ use simba::scalar::{ClosedAdd, ClosedMul, ComplexField, RealField};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, DimMin}; use crate::base::dimension::{Dim, DimMin};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Matrix, SquareMatrix}; use crate::base::{DefaultAllocator, Matrix, SquareMatrix};
impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> { impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// The total number of elements of this matrix. /// The total number of elements of this matrix.

View File

@ -30,9 +30,9 @@ use abomonation::Abomonation;
/// A Vec-based matrix data storage. It may be dynamically-sized. /// A Vec-based matrix data storage. It may be dynamically-sized.
#[derive(Eq, Debug, Clone, PartialEq)] #[derive(Eq, Debug, Clone, PartialEq)]
pub struct VecStorage<T, R: Dim, C: Dim> { pub struct VecStorage<T, R: Dim, C: Dim> {
pub(crate) data: Vec<T>, data: Vec<T>,
pub(crate) nrows: R, nrows: R,
pub(crate) ncols: C, ncols: C,
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
@ -193,7 +193,8 @@ where
#[inline] #[inline]
fn clone_owned(&self) -> Owned<T, Dynamic, C> fn clone_owned(&self) -> Owned<T, Dynamic, C>
where T:Clone, where
T: Clone,
DefaultAllocator: InnerAllocator<T, Dynamic, C>, DefaultAllocator: InnerAllocator<T, Dynamic, C>,
{ {
self.clone() self.clone()
@ -242,7 +243,8 @@ where
#[inline] #[inline]
fn clone_owned(&self) -> Owned<T, R, Dynamic> fn clone_owned(&self) -> Owned<T, R, Dynamic>
where T:Clone, where
T: Clone,
DefaultAllocator: InnerAllocator<T, R, Dynamic>, DefaultAllocator: InnerAllocator<T, R, Dynamic>,
{ {
self.clone() self.clone()
@ -413,7 +415,7 @@ impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage<T, R, Dynamic> {
} }
} }
impl<T:Clone, R: Dim, RV: Dim, SV> Extend<Vector<T, RV, SV>> for VecStorage<T, R, Dynamic> impl<T: Clone, R: Dim, RV: Dim, SV> Extend<Vector<T, RV, SV>> for VecStorage<T, R, Dynamic>
where where
SV: Storage<T, RV>, SV: Storage<T, RV>,
ShapeConstraint: SameNumberOfRows<R, RV>, ShapeConstraint: SameNumberOfRows<R, RV>,

View File

@ -1,7 +1,5 @@
use std::fmt; use std::fmt;
#[cfg(feature = "arbitrary")]
use crate::base::storage::Owned;
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};

View File

@ -1,7 +1,5 @@
use std::fmt; use std::fmt;
#[cfg(feature = "arbitrary")]
use crate::base::storage::Owned;
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};

View File

@ -48,7 +48,7 @@ where
impl<T1, T2> SubsetOf<UnitDualQuaternion<T2>> for UnitDualQuaternion<T1> impl<T1, T2> SubsetOf<UnitDualQuaternion<T2>> for UnitDualQuaternion<T1>
where where
T2: SupersetOf<T1>, T2: SupersetOf<T1>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> UnitDualQuaternion<T2> { fn to_superset(&self) -> UnitDualQuaternion<T2> {

View File

@ -108,7 +108,7 @@ where
impl<T: Serialize, D: DimName> Serialize for OPoint<T, D> impl<T: Serialize, D: DimName> Serialize for OPoint<T, D>
where where
DefaultAllocator: Allocator<T, D>, DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Serialize, <DefaultAllocator as InnerAllocator<T, D>>::Buffer: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -122,7 +122,7 @@ where
impl<'a, T: Deserialize<'a>, D: DimName> Deserialize<'a> for OPoint<T, D> impl<'a, T: Deserialize<'a>, D: DimName> Deserialize<'a> for OPoint<T, D>
where where
DefaultAllocator: Allocator<T, D>, DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Deserialize<'a>, <DefaultAllocator as InnerAllocator<T, D>>::Buffer: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where where

View File

@ -59,7 +59,7 @@ use std::ops::{
use crate::base::dimension::U3; use crate::base::dimension::U3;
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{Const, Unit, Vector, Vector3}; use crate::base::{Const, Unit, Vector, Vector3};
use crate::SimdRealField; use crate::SimdRealField;
use crate::geometry::{Point3, Quaternion, Rotation, UnitQuaternion}; use crate::geometry::{Point3, Quaternion, Rotation, UnitQuaternion};

View File

@ -1,11 +1,16 @@
//! This module provides the matrix exponent (exp) function to square matrices. //! This module provides the matrix exponent (exp) function to square matrices.
//! //!
use crate::{ComplexField, OMatrix, RealField, base::{ use crate::{
base::{
allocator::Allocator, allocator::Allocator,
dimension::{Const, Dim, DimMin, DimMinimum}, dimension::{Const, Dim, DimMin, DimMinimum},
storage::Storage, storage::Storage,
DefaultAllocator, DefaultAllocator,
}, convert, storage::Owned, try_convert}; },
convert,
storage::Owned,
try_convert, ComplexField, OMatrix, RealField,
};
use crate::num::Zero; use crate::num::Zero;

View File

@ -327,15 +327,10 @@ where
D: Dim, D: Dim,
DefaultAllocator: Allocator<ScalarStrategy::Value, D>, DefaultAllocator: Allocator<ScalarStrategy::Value, D>,
{ {
matrix_(value_strategy, length.into(), U1.into()) matrix_(value_strategy, length.into(), Const::<1>.into())
} }
impl<NParameters, R, C> Default for MatrixParameters<NParameters, R, C> impl<NParameters: Default, R: DimName, C: DimName> Default for MatrixParameters<NParameters, R, C> {
where
NParameters: Default,
R: DimName,
C: DimName,
{
fn default() -> Self { fn default() -> Self {
Self { Self {
rows: DimRange::from(R::name()), rows: DimRange::from(R::name()),

View File

@ -474,7 +474,7 @@ where
{ {
// Size = R // Size = R
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
let mut workspace = Matrix::new_uninitialized_generic(nrows, Const::<1>); let mut workspace = CsMatrix::new_uninitialized_generic(nrows, Const::<1>);
self.sort_with_workspace(workspace.as_mut_slice()); self.sort_with_workspace(workspace.as_mut_slice());
} }