forked from M-Labs/nalgebra
Miscellaneous improvements
This commit is contained in:
parent
10b5dc9bb6
commit
b74be8499f
@ -57,9 +57,8 @@ where
|
||||
let (nrows, ncols) = m.data.shape();
|
||||
|
||||
let mut info = 0;
|
||||
let mut tau = unsafe {
|
||||
Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init()
|
||||
};
|
||||
let mut tau =
|
||||
unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() };
|
||||
|
||||
if nrows.value() == 0 || ncols.value() == 0 {
|
||||
return Self { qr: m, tau: tau };
|
||||
|
@ -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};
|
||||
#[cfg(feature = "abomonation-serialize")]
|
||||
use std::io::{Result as IOResult, Write};
|
||||
@ -12,8 +13,6 @@ use serde::ser::SerializeSeq;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use std::marker::PhantomData;
|
||||
#[cfg(feature = "serde-serialize-no-std")]
|
||||
use std::mem;
|
||||
|
||||
#[cfg(feature = "abomonation-serialize")]
|
||||
use abomonation::Abomonation;
|
||||
|
@ -146,7 +146,7 @@ macro_rules! component_binop_impl(
|
||||
);
|
||||
|
||||
/// # 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_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
|
||||
r"
|
||||
|
@ -4,7 +4,7 @@
|
||||
//! heap-allocated buffers for matrices with at least one dimension unknown at compile-time.
|
||||
|
||||
use std::cmp;
|
||||
use std::mem::{self, ManuallyDrop, MaybeUninit};
|
||||
use std::mem::{ManuallyDrop, MaybeUninit};
|
||||
use std::ptr;
|
||||
|
||||
#[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:
|
||||
// * `ManuallyDrop<T>` and T are guaranteed to have the same layout
|
||||
// * `ManuallyDrop` does not drop, so there are no double-frees
|
||||
// * `ArrayStorage` is transparent.
|
||||
// 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]
|
||||
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.
|
||||
let new_data =
|
||||
Vec::from_raw_parts(data.as_mut_ptr() as *mut T, data.len(), data.capacity());
|
||||
// Safety:
|
||||
// - MaybeUninit<T> has the same alignment and layout as T.
|
||||
// - 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]
|
||||
fn manually_drop(
|
||||
buf: <Self as InnerAllocator<T, Dynamic, C>>::Buffer,
|
||||
) -> <Self as InnerAllocator<ManuallyDrop<T>, Dynamic, C>>::Buffer {
|
||||
// Avoids dropping the buffer that will be used for the result.
|
||||
let mut data = ManuallyDrop::new(buf.data);
|
||||
// Avoids a double-drop.
|
||||
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.
|
||||
let new_data = unsafe {
|
||||
Vec::from_raw_parts(
|
||||
data.as_mut_ptr() as *mut ManuallyDrop<T>,
|
||||
data.len(),
|
||||
data.capacity(),
|
||||
)
|
||||
};
|
||||
// Safety:
|
||||
// - ManuallyDrop<T> has the same alignment and layout as T.
|
||||
// - The length and capacity come from a valid vector.
|
||||
let new_data =
|
||||
unsafe { Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.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]
|
||||
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.
|
||||
let new_data =
|
||||
Vec::from_raw_parts(data.as_mut_ptr() as *mut T, data.len(), data.capacity());
|
||||
// Safety:
|
||||
// - MaybeUninit<T> has the same alignment and layout as T.
|
||||
// - 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]
|
||||
fn manually_drop(
|
||||
buf: <Self as InnerAllocator<T, R, Dynamic>>::Buffer,
|
||||
) -> <Self as InnerAllocator<ManuallyDrop<T>, R, Dynamic>>::Buffer {
|
||||
// Avoids dropping the buffer that will be used for the result.
|
||||
let mut data = ManuallyDrop::new(buf.data);
|
||||
// Avoids a double-drop.
|
||||
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.
|
||||
let new_data = unsafe {
|
||||
Vec::from_raw_parts(
|
||||
data.as_mut_ptr() as *mut ManuallyDrop<T>,
|
||||
data.len(),
|
||||
data.capacity(),
|
||||
)
|
||||
};
|
||||
// Safety:
|
||||
// - ManuallyDrop<T> has the same alignment and layout as T.
|
||||
// - The length and capacity come from a valid vector.
|
||||
let new_data =
|
||||
unsafe { Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity()) };
|
||||
|
||||
VecStorage::new(buf.nrows, buf.ncols, new_data)
|
||||
VecStorage::new(nrows, ncols, new_data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,7 +643,7 @@ macro_rules! impl_index_pair {
|
||||
$(where $CConstraintType: ty: $CConstraintBound: ident $(<$($CConstraintBoundParams: ty $( = $CEqBound: ty )*),*>)* )*]
|
||||
) =>
|
||||
{
|
||||
impl<'a, T: 'a, $R: Dim, $C: Dim, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*>
|
||||
impl<'a, T: 'a, $R: Dim, $C: Dim, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*>
|
||||
MatrixIndex<'a, T, $R, $C, S> for ($RIdx, $CIdx)
|
||||
where
|
||||
S: Storage<T, R, C>,
|
||||
|
@ -385,6 +385,10 @@ where
|
||||
/// 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`].
|
||||
///
|
||||
/// # 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> {
|
||||
OMatrix::from_data(<DefaultAllocator as Allocator<T, R, C>>::assume_init(
|
||||
self.data,
|
||||
@ -408,6 +412,10 @@ where
|
||||
|
||||
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.
|
||||
///
|
||||
/// # 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>
|
||||
where
|
||||
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.
|
||||
///
|
||||
/// # 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>
|
||||
where
|
||||
S: StorageMut<MaybeUninit<T>, R, C>,
|
||||
|
@ -237,6 +237,10 @@ impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||
SliceStorageMut<'a, MaybeUninit<T>, R, C, RStride, CStride>
|
||||
{
|
||||
/// 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> {
|
||||
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,
|
||||
};
|
||||
|
||||
Matrix::from_data(data)
|
||||
Matrix::from_data(data)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use simba::scalar::{ClosedAdd, ClosedMul, ComplexField, RealField};
|
||||
use crate::base::allocator::Allocator;
|
||||
use crate::base::dimension::{Dim, DimMin};
|
||||
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> {
|
||||
/// The total number of elements of this matrix.
|
||||
|
@ -30,9 +30,9 @@ use abomonation::Abomonation;
|
||||
/// A Vec-based matrix data storage. It may be dynamically-sized.
|
||||
#[derive(Eq, Debug, Clone, PartialEq)]
|
||||
pub struct VecStorage<T, R: Dim, C: Dim> {
|
||||
pub(crate) data: Vec<T>,
|
||||
pub(crate) nrows: R,
|
||||
pub(crate) ncols: C,
|
||||
data: Vec<T>,
|
||||
nrows: R,
|
||||
ncols: C,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize")]
|
||||
@ -193,7 +193,8 @@ where
|
||||
|
||||
#[inline]
|
||||
fn clone_owned(&self) -> Owned<T, Dynamic, C>
|
||||
where T:Clone,
|
||||
where
|
||||
T: Clone,
|
||||
DefaultAllocator: InnerAllocator<T, Dynamic, C>,
|
||||
{
|
||||
self.clone()
|
||||
@ -242,7 +243,8 @@ where
|
||||
|
||||
#[inline]
|
||||
fn clone_owned(&self) -> Owned<T, R, Dynamic>
|
||||
where T:Clone,
|
||||
where
|
||||
T: Clone,
|
||||
DefaultAllocator: InnerAllocator<T, R, Dynamic>,
|
||||
{
|
||||
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
|
||||
SV: Storage<T, RV>,
|
||||
ShapeConstraint: SameNumberOfRows<R, RV>,
|
||||
|
@ -1,7 +1,5 @@
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use crate::base::storage::Owned;
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use crate::base::storage::Owned;
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use quickcheck::{Arbitrary, Gen};
|
||||
|
||||
|
@ -48,7 +48,7 @@ where
|
||||
|
||||
impl<T1, T2> SubsetOf<UnitDualQuaternion<T2>> for UnitDualQuaternion<T1>
|
||||
where
|
||||
T2: SupersetOf<T1>,
|
||||
T2: SupersetOf<T1>,
|
||||
{
|
||||
#[inline]
|
||||
fn to_superset(&self) -> UnitDualQuaternion<T2> {
|
||||
|
@ -108,7 +108,7 @@ where
|
||||
impl<T: Serialize, D: DimName> Serialize for OPoint<T, D>
|
||||
where
|
||||
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>
|
||||
where
|
||||
@ -122,7 +122,7 @@ where
|
||||
impl<'a, T: Deserialize<'a>, D: DimName> Deserialize<'a> for OPoint<T, D>
|
||||
where
|
||||
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>
|
||||
where
|
||||
|
@ -59,7 +59,7 @@ use std::ops::{
|
||||
|
||||
use crate::base::dimension::U3;
|
||||
use crate::base::storage::Storage;
|
||||
use crate::base::{Const, Unit, Vector, Vector3};
|
||||
use crate::base::{Const, Unit, Vector, Vector3};
|
||||
use crate::SimdRealField;
|
||||
|
||||
use crate::geometry::{Point3, Quaternion, Rotation, UnitQuaternion};
|
||||
|
@ -1,11 +1,16 @@
|
||||
//! This module provides the matrix exponent (exp) function to square matrices.
|
||||
//!
|
||||
use crate::{ComplexField, OMatrix, RealField, base::{
|
||||
use crate::{
|
||||
base::{
|
||||
allocator::Allocator,
|
||||
dimension::{Const, Dim, DimMin, DimMinimum},
|
||||
storage::Storage,
|
||||
DefaultAllocator,
|
||||
}, convert, storage::Owned, try_convert};
|
||||
},
|
||||
convert,
|
||||
storage::Owned,
|
||||
try_convert, ComplexField, OMatrix, RealField,
|
||||
};
|
||||
|
||||
use crate::num::Zero;
|
||||
|
||||
|
@ -327,15 +327,10 @@ where
|
||||
D: Dim,
|
||||
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>
|
||||
where
|
||||
NParameters: Default,
|
||||
R: DimName,
|
||||
C: DimName,
|
||||
{
|
||||
impl<NParameters: Default, R: DimName, C: DimName> Default for MatrixParameters<NParameters, R, C> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
rows: DimRange::from(R::name()),
|
||||
|
@ -474,7 +474,7 @@ where
|
||||
{
|
||||
// Size = R
|
||||
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());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user