Miscellaneous improvements
This commit is contained in:
parent
10b5dc9bb6
commit
b74be8499f
|
@ -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 };
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue