Merge pull request #803 from aweinstock314/no_unsound_assume_init

Propagate `mem::MaybeUninit` through the return types of `Allocator::…
This commit is contained in:
Sébastien Crozet 2021-02-25 15:46:49 +01:00 committed by GitHub
commit 21cc428480
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 220 additions and 115 deletions

View File

@ -36,6 +36,7 @@ compare = [ "matrixcompare-core" ]
libm = [ "simba/libm" ] libm = [ "simba/libm" ]
libm-force = [ "simba/libm_force" ] libm-force = [ "simba/libm_force" ]
proptest-support = [ "proptest" ] proptest-support = [ "proptest" ]
no_unsound_assume_init = [ ]
# This feature is only used for tests, and enables tests that require more time to run # This feature is only used for tests, and enables tests that require more time to run
slow-tests = [] slow-tests = []

View File

@ -78,9 +78,9 @@ where
let lda = n as i32; let lda = n as i32;
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
// TODO: Tap into the workspace. // TODO: Tap into the workspace.
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut info = 0; let mut info = 0;
let mut placeholder1 = [N::zero()]; let mut placeholder1 = [N::zero()];
@ -107,8 +107,10 @@ where
match (left_eigenvectors, eigenvectors) { match (left_eigenvectors, eigenvectors) {
(true, true) => { (true, true) => {
let mut vl = unsafe { Matrix::new_uninitialized_generic(nrows, ncols) }; let mut vl =
let mut vr = unsafe { Matrix::new_uninitialized_generic(nrows, ncols) }; unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
let mut vr =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
N::xgeev( N::xgeev(
ljob, ljob,
@ -137,7 +139,8 @@ where
} }
} }
(true, false) => { (true, false) => {
let mut vl = unsafe { Matrix::new_uninitialized_generic(nrows, ncols) }; let mut vl =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
N::xgeev( N::xgeev(
ljob, ljob,
@ -166,7 +169,8 @@ where
} }
} }
(false, true) => { (false, true) => {
let mut vr = unsafe { Matrix::new_uninitialized_generic(nrows, ncols) }; let mut vr =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
N::xgeev( N::xgeev(
ljob, ljob,
@ -243,8 +247,8 @@ where
let lda = n as i32; let lda = n as i32;
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut info = 0; let mut info = 0;
let mut placeholder1 = [N::zero()]; let mut placeholder1 = [N::zero()];
@ -287,7 +291,7 @@ where
); );
lapack_panic!(info); lapack_panic!(info);
let mut res = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut res = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
for i in 0..res.len() { for i in 0..res.len() {
res[i] = Complex::new(wr[i], wi[i]); res[i] = Complex::new(wr[i], wi[i]);

View File

@ -60,7 +60,7 @@ where
"Unable to compute the hessenberg decomposition of an empty matrix." "Unable to compute the hessenberg decomposition of an empty matrix."
); );
let mut tau = unsafe { Matrix::new_uninitialized_generic(nrows.sub(U1), U1) }; let mut tau = unsafe { Matrix::new_uninitialized_generic(nrows.sub(U1), U1).assume_init() };
let mut info = 0; let mut info = 0;
let lwork = let lwork =

View File

@ -57,7 +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 { Matrix::new_uninitialized_generic(nrows.min(ncols), U1) }; let mut tau =
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

@ -78,9 +78,9 @@ where
let mut info = 0; let mut info = 0;
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut q = unsafe { Matrix::new_uninitialized_generic(nrows, ncols) }; let mut q = unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
// Placeholders: // Placeholders:
let mut bwork = [0i32]; let mut bwork = [0i32];
let mut unused = 0; let mut unused = 0;
@ -151,7 +151,8 @@ where
where where
DefaultAllocator: Allocator<Complex<N>, D>, DefaultAllocator: Allocator<Complex<N>, D>,
{ {
let mut out = unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1) }; let mut out =
unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1).assume_init() };
for i in 0..out.len() { for i in 0..out.len() {
out[i] = Complex::new(self.re[i], self.im[i]) out[i] = Complex::new(self.re[i], self.im[i])

View File

@ -99,9 +99,9 @@ macro_rules! svd_impl(
let lda = nrows.value() as i32; let lda = nrows.value() as i32;
let mut u = unsafe { Matrix::new_uninitialized_generic(nrows, nrows) }; let mut u = unsafe { Matrix::new_uninitialized_generic(nrows, nrows).assume_init() };
let mut s = unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1) }; let mut s = unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() };
let mut vt = unsafe { Matrix::new_uninitialized_generic(ncols, ncols) }; let mut vt = unsafe { Matrix::new_uninitialized_generic(ncols, ncols).assume_init() };
let ldu = nrows.value(); let ldu = nrows.value();
let ldvt = ncols.value(); let ldvt = ncols.value();

View File

@ -94,7 +94,7 @@ where
let lda = n as i32; let lda = n as i32;
let mut values = unsafe { Matrix::new_uninitialized_generic(nrows, U1) }; let mut values = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut info = 0; let mut info = 0;
let lwork = N::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info); let lwork = N::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info);

View File

@ -1,6 +1,7 @@
//! Abstract definition of a matrix data storage allocator. //! Abstract definition of a matrix data storage allocator.
use std::any::Any; use std::any::Any;
use std::mem;
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::base::dimension::{Dim, U1}; use crate::base::dimension::{Dim, U1};
@ -21,7 +22,7 @@ pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
type Buffer: ContiguousStorageMut<N, R, C> + Clone; type Buffer: ContiguousStorageMut<N, R, C> + Clone;
/// Allocates a buffer with the given number of rows and columns without initializing its content. /// Allocates a buffer with the given number of rows and columns without initializing its content.
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer; unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> mem::MaybeUninit<Self::Buffer>;
/// Allocates a buffer initialized with the content of the given iterator. /// Allocates a buffer initialized with the content of the given iterator.
fn allocate_from_iterator<I: IntoIterator<Item = N>>( fn allocate_from_iterator<I: IntoIterator<Item = N>>(

View File

@ -1328,7 +1328,8 @@ where
ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>, ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>,
DefaultAllocator: Allocator<N, D1>, DefaultAllocator: Allocator<N, D1>,
{ {
let mut work = unsafe { Vector::new_uninitialized_generic(self.data.shape().0, U1) }; let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, U1) };
self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta) self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta)
} }
@ -1421,7 +1422,8 @@ where
ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>, ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>,
DefaultAllocator: Allocator<N, D2>, DefaultAllocator: Allocator<N, D2>,
{ {
let mut work = unsafe { Vector::new_uninitialized_generic(mid.data.shape().0, U1) }; let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, U1) };
self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta) self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta)
} }
} }

View File

@ -14,6 +14,7 @@ use rand::Rng;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use rand_distr::StandardNormal; use rand_distr::StandardNormal;
use std::iter; use std::iter;
use std::mem;
use typenum::{self, Cmp, Greater}; use typenum::{self, Cmp, Greater};
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -25,6 +26,23 @@ use crate::base::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN}; use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN};
/// When "no_unsound_assume_init" is enabled, expands to `unimplemented!()` instead of `new_uninitialized_generic().assume_init()`.
/// Intended as a placeholder, each callsite should be refactored to use uninitialized memory soundly
#[macro_export]
macro_rules! unimplemented_or_uninitialized_generic {
($nrows:expr, $ncols:expr) => {{
#[cfg(feature="no_unsound_assume_init")] {
// Some of the call sites need the number of rows and columns from this to infer a type, so
// uninitialized memory is used to infer the type, as `N: Zero` isn't available at all callsites.
// This may technically still be UB even though the assume_init is dead code, but all callsites should be fixed before #556 is closed.
let typeinference_helper = crate::base::Matrix::new_uninitialized_generic($nrows, $ncols);
unimplemented!();
typeinference_helper.assume_init()
}
#[cfg(not(feature="no_unsound_assume_init"))] { crate::base::Matrix::new_uninitialized_generic($nrows, $ncols).assume_init() }
}}
}
/// # Generic constructors /// # Generic constructors
/// This set of matrix and vector construction functions are all generic /// This set of matrix and vector construction functions are all generic
/// with-regard to the matrix dimensions. They all expect to be given /// with-regard to the matrix dimensions. They all expect to be given
@ -38,8 +56,8 @@ where
/// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics /// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics
/// if `nrows != R::to_usize()` or `ncols != C::to_usize()`. /// if `nrows != R::to_usize()` or `ncols != C::to_usize()`.
#[inline] #[inline]
pub unsafe fn new_uninitialized_generic(nrows: R, ncols: C) -> Self { pub unsafe fn new_uninitialized_generic(nrows: R, ncols: C) -> mem::MaybeUninit<Self> {
Self::from_data(DefaultAllocator::allocate_uninitialized(nrows, ncols)) Self::from_uninitialized_data(DefaultAllocator::allocate_uninitialized(nrows, ncols))
} }
/// Creates a matrix with all its elements set to `elem`. /// Creates a matrix with all its elements set to `elem`.
@ -88,7 +106,7 @@ where
"Matrix init. error: the slice did not contain the right number of elements." "Matrix init. error: the slice did not contain the right number of elements."
); );
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) }; let mut res = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
let mut iter = slice.iter(); let mut iter = slice.iter();
for i in 0..nrows.value() { for i in 0..nrows.value() {
@ -114,7 +132,7 @@ where
where where
F: FnMut(usize, usize) -> N, F: FnMut(usize, usize) -> N,
{ {
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) }; let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
for j in 0..ncols.value() { for j in 0..ncols.value() {
for i in 0..nrows.value() { for i in 0..nrows.value() {
@ -356,7 +374,7 @@ macro_rules! impl_constructors(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
/// Creates a new uninitialized matrix or vector. /// Creates a new uninitialized matrix or vector.
#[inline] #[inline]
pub unsafe fn new_uninitialized($($args: usize),*) -> Self { pub unsafe fn new_uninitialized($($args: usize),*) -> mem::MaybeUninit<Self> {
Self::new_uninitialized_generic($($gargs),*) Self::new_uninitialized_generic($($gargs),*)
} }
@ -865,7 +883,10 @@ macro_rules! componentwise_constructors_impl(
#[inline] #[inline]
pub fn new($($args: N),*) -> Self { pub fn new($($args: N),*) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); #[cfg(feature="no_unsound_assume_init")]
let mut res: Self = unimplemented!();
#[cfg(not(feature="no_unsound_assume_init"))]
let mut res = Self::new_uninitialized().assume_init();
$( *res.get_unchecked_mut(($irow, $icol)) = $args; )* $( *res.get_unchecked_mut(($irow, $icol)) = $args; )*
res res

View File

@ -50,7 +50,8 @@ where
let nrows2 = R2::from_usize(nrows); let nrows2 = R2::from_usize(nrows);
let ncols2 = C2::from_usize(ncols); let ncols2 = C2::from_usize(ncols);
let mut res = unsafe { MatrixMN::<N2, R2, C2>::new_uninitialized_generic(nrows2, ncols2) }; let mut res: MatrixMN<N2, R2, C2> =
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows2, ncols2) };
for i in 0..nrows { for i in 0..nrows {
for j in 0..ncols { for j in 0..ncols {
unsafe { unsafe {
@ -73,7 +74,7 @@ where
let nrows = R1::from_usize(nrows2); let nrows = R1::from_usize(nrows2);
let ncols = C1::from_usize(ncols2); let ncols = C1::from_usize(ncols2);
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) }; let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
for i in 0..nrows2 { for i in 0..nrows2 {
for j in 0..ncols2 { for j in 0..ncols2 {
unsafe { unsafe {
@ -117,9 +118,9 @@ macro_rules! impl_from_into_asref_1D(
fn from(arr: [N; $SZ]) -> Self { fn from(arr: [N; $SZ]) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&arr[0], res.data.ptr_mut(), $SZ); ptr::copy_nonoverlapping(&arr[0], (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
res res.assume_init()
} }
} }
} }
@ -184,9 +185,9 @@ macro_rules! impl_from_into_asref_2D(
fn from(arr: [[N; $SZRows]; $SZCols]) -> Self { fn from(arr: [[N; $SZRows]; $SZCols]) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&arr[0][0], res.data.ptr_mut(), $SZRows * $SZCols); ptr::copy_nonoverlapping(&arr[0][0], (*res.as_mut_ptr()).data.ptr_mut(), $SZRows * $SZCols);
res res.assume_init()
} }
} }
} }
@ -244,9 +245,9 @@ macro_rules! impl_from_into_mint_1D(
fn from(v: mint::$VT<N>) -> Self { fn from(v: mint::$VT<N>) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&v.x, res.data.ptr_mut(), $SZ); ptr::copy_nonoverlapping(&v.x, (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
res res.assume_init()
} }
} }
} }
@ -306,13 +307,13 @@ macro_rules! impl_from_into_mint_2D(
fn from(m: mint::$MV<N>) -> Self { fn from(m: mint::$MV<N>) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); let mut res = Self::new_uninitialized();
let mut ptr = res.data.ptr_mut(); let mut ptr = (*res.as_mut_ptr()).data.ptr_mut();
$( $(
ptr::copy_nonoverlapping(&m.$component.x, ptr, $SZRows); ptr::copy_nonoverlapping(&m.$component.x, ptr, $SZRows);
ptr = ptr.offset($SZRows); ptr = ptr.offset($SZRows);
)* )*
let _ = ptr; let _ = ptr;
res res.assume_init()
} }
} }
} }

View File

@ -45,9 +45,8 @@ where
type Buffer = ArrayStorage<N, R, C>; type Buffer = ArrayStorage<N, R, C>;
#[inline] #[inline]
unsafe fn allocate_uninitialized(_: R, _: C) -> Self::Buffer { unsafe fn allocate_uninitialized(_: R, _: C) -> mem::MaybeUninit<Self::Buffer> {
// TODO: Undefined behavior, see #556 mem::MaybeUninit::<Self::Buffer>::uninit()
mem::MaybeUninit::<Self::Buffer>::uninit().assume_init()
} }
#[inline] #[inline]
@ -56,7 +55,10 @@ where
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer { ) -> Self::Buffer {
let mut res = unsafe { Self::allocate_uninitialized(nrows, ncols) }; #[cfg(feature = "no_unsound_assume_init")]
let mut res: Self::Buffer = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))]
let mut res = unsafe { Self::allocate_uninitialized(nrows, ncols).assume_init() };
let mut count = 0; let mut count = 0;
for (res, e) in res.iter_mut().zip(iter.into_iter()) { for (res, e) in res.iter_mut().zip(iter.into_iter()) {
@ -80,13 +82,13 @@ impl<N: Scalar, C: Dim> Allocator<N, Dynamic, C> for DefaultAllocator {
type Buffer = VecStorage<N, Dynamic, C>; type Buffer = VecStorage<N, Dynamic, C>;
#[inline] #[inline]
unsafe fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> Self::Buffer { unsafe fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> mem::MaybeUninit<Self::Buffer> {
let mut res = Vec::new(); let mut res = Vec::new();
let length = nrows.value() * ncols.value(); let length = nrows.value() * ncols.value();
res.reserve_exact(length); res.reserve_exact(length);
res.set_len(length); res.set_len(length);
VecStorage::new(nrows, ncols, res) mem::MaybeUninit::new(VecStorage::new(nrows, ncols, res))
} }
#[inline] #[inline]
@ -110,13 +112,13 @@ impl<N: Scalar, R: DimName> Allocator<N, R, Dynamic> for DefaultAllocator {
type Buffer = VecStorage<N, R, Dynamic>; type Buffer = VecStorage<N, R, Dynamic>;
#[inline] #[inline]
unsafe fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> Self::Buffer { unsafe fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> mem::MaybeUninit<Self::Buffer> {
let mut res = Vec::new(); let mut res = Vec::new();
let length = nrows.value() * ncols.value(); let length = nrows.value() * ncols.value();
res.reserve_exact(length); res.reserve_exact(length);
res.set_len(length); res.set_len(length);
VecStorage::new(nrows, ncols, res) mem::MaybeUninit::new(VecStorage::new(nrows, ncols, res))
} }
#[inline] #[inline]
@ -156,7 +158,11 @@ where
cto: CTo, cto: CTo,
buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer, buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer,
) -> ArrayStorage<N, RTo, CTo> { ) -> ArrayStorage<N, RTo, CTo> {
let mut res = <Self as Allocator<N, RTo, CTo>>::allocate_uninitialized(rto, cto); #[cfg(feature = "no_unsound_assume_init")]
let mut res: ArrayStorage<N, RTo, CTo> = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))]
let mut res =
<Self as Allocator<N, RTo, CTo>>::allocate_uninitialized(rto, cto).assume_init();
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -184,7 +190,11 @@ where
cto: CTo, cto: CTo,
buf: ArrayStorage<N, RFrom, CFrom>, buf: ArrayStorage<N, RFrom, CFrom>,
) -> VecStorage<N, Dynamic, CTo> { ) -> VecStorage<N, Dynamic, CTo> {
let mut res = <Self as Allocator<N, Dynamic, CTo>>::allocate_uninitialized(rto, cto); #[cfg(feature = "no_unsound_assume_init")]
let mut res: VecStorage<N, Dynamic, CTo> = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))]
let mut res =
<Self as Allocator<N, Dynamic, CTo>>::allocate_uninitialized(rto, cto).assume_init();
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -212,7 +222,11 @@ where
cto: Dynamic, cto: Dynamic,
buf: ArrayStorage<N, RFrom, CFrom>, buf: ArrayStorage<N, RFrom, CFrom>,
) -> VecStorage<N, RTo, Dynamic> { ) -> VecStorage<N, RTo, Dynamic> {
let mut res = <Self as Allocator<N, RTo, Dynamic>>::allocate_uninitialized(rto, cto); #[cfg(feature = "no_unsound_assume_init")]
let mut res: VecStorage<N, RTo, Dynamic> = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))]
let mut res =
<Self as Allocator<N, RTo, Dynamic>>::allocate_uninitialized(rto, cto).assume_init();
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();

View File

@ -54,8 +54,9 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let irows = irows.into_iter(); let irows = irows.into_iter();
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res = let mut res = unsafe {
unsafe { MatrixMN::new_uninitialized_generic(Dynamic::new(irows.len()), ncols) }; crate::unimplemented_or_uninitialized_generic!(Dynamic::new(irows.len()), ncols)
};
// First, check that all the indices from irows are valid. // First, check that all the indices from irows are valid.
// This will allow us to use unchecked access in the inner loop. // This will allow us to use unchecked access in the inner loop.
@ -89,8 +90,9 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let icols = icols.into_iter(); let icols = icols.into_iter();
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
let mut res = let mut res = unsafe {
unsafe { MatrixMN::new_uninitialized_generic(nrows, Dynamic::new(icols.len())) }; crate::unimplemented_or_uninitialized_generic!(nrows, Dynamic::new(icols.len()))
};
for (destination, source) in icols.enumerate() { for (destination, source) in icols.enumerate() {
res.column_mut(destination).copy_from(&self.column(*source)) res.column_mut(destination).copy_from(&self.column(*source))
@ -896,7 +898,9 @@ impl<N: Scalar> DMatrix<N> {
where where
DefaultAllocator: Reallocator<N, Dynamic, Dynamic, Dynamic, Dynamic>, DefaultAllocator: Reallocator<N, Dynamic, Dynamic, Dynamic, Dynamic>,
{ {
let placeholder = unsafe { Self::new_uninitialized(0, 0) }; let placeholder = unsafe {
crate::unimplemented_or_uninitialized_generic!(Dynamic::new(0), Dynamic::new(0))
};
let old = mem::replace(self, placeholder); let old = mem::replace(self, placeholder);
let new = old.resize(new_nrows, new_ncols, val); let new = old.resize(new_nrows, new_ncols, val);
let _ = mem::replace(self, new); let _ = mem::replace(self, new);
@ -919,8 +923,9 @@ where
where where
DefaultAllocator: Reallocator<N, Dynamic, C, Dynamic, C>, DefaultAllocator: Reallocator<N, Dynamic, C, Dynamic, C>,
{ {
let placeholder = let placeholder = unsafe {
unsafe { Self::new_uninitialized_generic(Dynamic::new(0), self.data.shape().1) }; crate::unimplemented_or_uninitialized_generic!(Dynamic::new(0), self.data.shape().1)
};
let old = mem::replace(self, placeholder); let old = mem::replace(self, placeholder);
let new = old.resize_vertically(new_nrows, val); let new = old.resize_vertically(new_nrows, val);
let _ = mem::replace(self, new); let _ = mem::replace(self, new);
@ -943,8 +948,9 @@ where
where where
DefaultAllocator: Reallocator<N, R, Dynamic, R, Dynamic>, DefaultAllocator: Reallocator<N, R, Dynamic, R, Dynamic>,
{ {
let placeholder = let placeholder = unsafe {
unsafe { Self::new_uninitialized_generic(self.data.shape().0, Dynamic::new(0)) }; crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Dynamic::new(0))
};
let old = mem::replace(self, placeholder); let old = mem::replace(self, placeholder);
let new = old.resize_horizontally(new_ncols, val); let new = old.resize_horizontally(new_ncols, val);
let _ = mem::replace(self, new); let _ = mem::replace(self, new);

View File

@ -314,6 +314,21 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
unsafe { Self::from_data_statically_unchecked(data) } unsafe { Self::from_data_statically_unchecked(data) }
} }
/// Creates a new uninitialized matrix with the given uninitialized data
pub unsafe fn from_uninitialized_data(data: mem::MaybeUninit<S>) -> mem::MaybeUninit<Self> {
let res: Matrix<N, R, C, mem::MaybeUninit<S>> = Matrix {
data,
_phantoms: PhantomData,
};
let res: mem::MaybeUninit<Matrix<N, R, C, mem::MaybeUninit<S>>> =
mem::MaybeUninit::new(res);
// safety: since we wrap the inner MaybeUninit in an outer MaybeUninit above, the fact that the `data` field is partially-uninitialized is still opaque.
// with s/transmute_copy/transmute/, rustc claims that `MaybeUninit<Matrix<N, R, C, MaybeUninit<S>>>` may be of a different size from `MaybeUninit<Matrix<N, R, C, S>>`
// but MaybeUninit's documentation says "MaybeUninit<T> is guaranteed to have the same size, alignment, and ABI as T", which implies those types should be the same size
let res: mem::MaybeUninit<Matrix<N, R, C, S>> = mem::transmute_copy(&res);
res
}
/// The shape of this matrix returned as the tuple (number of rows, number of columns). /// The shape of this matrix returned as the tuple (number of rows, number of columns).
/// ///
/// # Examples: /// # Examples:
@ -513,7 +528,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
let ncols: SameShapeC<C, C2> = Dim::from_usize(ncols); let ncols: SameShapeC<C, C2> = Dim::from_usize(ncols);
let mut res: MatrixSum<N, R, C, R2, C2> = let mut res: MatrixSum<N, R, C, R2, C2> =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols) }; unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
// TODO: use copy_from // TODO: use copy_from
for j in 0..res.ncols() { for j in 0..res.ncols() {
@ -562,7 +577,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
unsafe { unsafe {
let mut res = Matrix::new_uninitialized_generic(ncols, nrows); let mut res = crate::unimplemented_or_uninitialized_generic!(ncols, nrows);
self.transpose_to(&mut res); self.transpose_to(&mut res);
res res
@ -580,7 +595,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) }; let mut res: MatrixMN<N2, R, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
for j in 0..ncols.value() { for j in 0..ncols.value() {
for i in 0..nrows.value() { for i in 0..nrows.value() {
@ -624,7 +640,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) }; let mut res: MatrixMN<N2, R, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
for j in 0..ncols.value() { for j in 0..ncols.value() {
for i in 0..nrows.value() { for i in 0..nrows.value() {
@ -651,7 +668,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) }; let mut res: MatrixMN<N3, R, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
assert_eq!( assert_eq!(
(nrows.value(), ncols.value()), (nrows.value(), ncols.value()),
@ -692,7 +710,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) }; let mut res: MatrixMN<N4, R, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
assert_eq!( assert_eq!(
(nrows.value(), ncols.value()), (nrows.value(), ncols.value()),
@ -1186,7 +1205,8 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
unsafe { unsafe {
let mut res: MatrixMN<_, C, R> = Matrix::new_uninitialized_generic(ncols, nrows); let mut res: MatrixMN<_, C, R> =
crate::unimplemented_or_uninitialized_generic!(ncols, nrows);
self.adjoint_to(&mut res); self.adjoint_to(&mut res);
res res
@ -1327,7 +1347,8 @@ impl<N: Scalar, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
); );
let dim = self.data.shape().0; let dim = self.data.shape().0;
let mut res = unsafe { VectorN::new_uninitialized_generic(dim, U1) }; let mut res: VectorN<N2, D> =
unsafe { crate::unimplemented_or_uninitialized_generic!(dim, U1) };
for i in 0..dim.value() { for i in 0..dim.value() {
unsafe { unsafe {
@ -1454,7 +1475,8 @@ impl<N: Scalar + Zero, D: DimAdd<U1>, S: Storage<N, D>> Vector<N, D, S> {
{ {
let len = self.len(); let len = self.len();
let hnrows = DimSum::<D, U1>::from_usize(len + 1); let hnrows = DimSum::<D, U1>::from_usize(len + 1);
let mut res = unsafe { VectorN::<N, _>::new_uninitialized_generic(hnrows, U1) }; let mut res: VectorN<N, _> =
unsafe { crate::unimplemented_or_uninitialized_generic!(hnrows, U1) };
res.generic_slice_mut((0, 0), self.data.shape()) res.generic_slice_mut((0, 0), self.data.shape())
.copy_from(self); .copy_from(self);
res[(len, 0)] = element; res[(len, 0)] = element;
@ -1799,7 +1821,8 @@ impl<N: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: Storage<N
// TODO: soooo ugly! // TODO: soooo ugly!
let nrows = SameShapeR::<R, R2>::from_usize(3); let nrows = SameShapeR::<R, R2>::from_usize(3);
let ncols = SameShapeC::<C, C2>::from_usize(1); let ncols = SameShapeC::<C, C2>::from_usize(1);
let mut res = Matrix::new_uninitialized_generic(nrows, ncols); let mut res: MatrixCross<N, R, C, R2, C2> =
crate::unimplemented_or_uninitialized_generic!(nrows, ncols);
let ax = self.get_unchecked((0, 0)); let ax = self.get_unchecked((0, 0));
let ay = self.get_unchecked((1, 0)); let ay = self.get_unchecked((1, 0));
@ -1823,7 +1846,8 @@ impl<N: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: Storage<N
// TODO: ugly! // TODO: ugly!
let nrows = SameShapeR::<R, R2>::from_usize(1); let nrows = SameShapeR::<R, R2>::from_usize(1);
let ncols = SameShapeC::<C, C2>::from_usize(3); let ncols = SameShapeC::<C, C2>::from_usize(3);
let mut res = Matrix::new_uninitialized_generic(nrows, ncols); let mut res: MatrixCross<N, R, C, R2, C2> =
crate::unimplemented_or_uninitialized_generic!(nrows, ncols);
let ax = self.get_unchecked((0, 0)); let ax = self.get_unchecked((0, 0));
let ay = self.get_unchecked((0, 1)); let ay = self.get_unchecked((0, 1));

View File

@ -433,8 +433,8 @@ where
"Matrix meet/join error: mismatched dimensions." "Matrix meet/join error: mismatched dimensions."
); );
let mut mres = unsafe { Self::new_uninitialized_generic(shape.0, shape.1) }; let mut mres = unsafe { crate::unimplemented_or_uninitialized_generic!(shape.0, shape.1) };
let mut jres = unsafe { Self::new_uninitialized_generic(shape.0, shape.1) }; let mut jres = unsafe { crate::unimplemented_or_uninitialized_generic!(shape.0, shape.1) };
for i in 0..shape.0.value() * shape.1.value() { for i in 0..shape.0.value() * shape.1.value() {
unsafe { unsafe {

View File

@ -15,6 +15,7 @@ mod alias_slice;
mod array_storage; mod array_storage;
mod cg; mod cg;
mod componentwise; mod componentwise;
#[macro_use]
mod construction; mod construction;
mod construction_slice; mod construction_slice;
mod conversion; mod conversion;

View File

@ -331,7 +331,7 @@ macro_rules! componentwise_binop_impl(
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let nrows: SameShapeR<R1, R2> = Dim::from_usize(nrows); let nrows: SameShapeR<R1, R2> = Dim::from_usize(nrows);
let ncols: SameShapeC<C1, C2> = Dim::from_usize(ncols); let ncols: SameShapeC<C1, C2> = Dim::from_usize(ncols);
Matrix::new_uninitialized_generic(nrows, ncols) crate::unimplemented_or_uninitialized_generic!(nrows, ncols)
}; };
self.$method_to_statically_unchecked(rhs, &mut res); self.$method_to_statically_unchecked(rhs, &mut res);
@ -573,9 +573,9 @@ where
#[inline] #[inline]
fn mul(self, rhs: &'b Matrix<N, R2, C2, SB>) -> Self::Output { fn mul(self, rhs: &'b Matrix<N, R2, C2, SB>) -> Self::Output {
let mut res = let mut res = unsafe {
unsafe { Matrix::new_uninitialized_generic(self.data.shape().0, rhs.data.shape().1) }; crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, rhs.data.shape().1)
};
self.mul_to(rhs, &mut res); self.mul_to(rhs, &mut res);
res res
} }
@ -684,8 +684,9 @@ where
DefaultAllocator: Allocator<N, C1, C2>, DefaultAllocator: Allocator<N, C1, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
let mut res = let mut res = unsafe {
unsafe { Matrix::new_uninitialized_generic(self.data.shape().1, rhs.data.shape().1) }; crate::unimplemented_or_uninitialized_generic!(self.data.shape().1, rhs.data.shape().1)
};
self.tr_mul_to(rhs, &mut res); self.tr_mul_to(rhs, &mut res);
res res
@ -700,8 +701,9 @@ where
DefaultAllocator: Allocator<N, C1, C2>, DefaultAllocator: Allocator<N, C1, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
let mut res = let mut res = unsafe {
unsafe { Matrix::new_uninitialized_generic(self.data.shape().1, rhs.data.shape().1) }; crate::unimplemented_or_uninitialized_generic!(self.data.shape().1, rhs.data.shape().1)
};
self.ad_mul_to(rhs, &mut res); self.ad_mul_to(rhs, &mut res);
res res
@ -815,8 +817,9 @@ where
let (nrows1, ncols1) = self.data.shape(); let (nrows1, ncols1) = self.data.shape();
let (nrows2, ncols2) = rhs.data.shape(); let (nrows2, ncols2) = rhs.data.shape();
let mut res = let mut res = unsafe {
unsafe { Matrix::new_uninitialized_generic(nrows1.mul(nrows2), ncols1.mul(ncols2)) }; crate::unimplemented_or_uninitialized_generic!(nrows1.mul(nrows2), ncols1.mul(ncols2))
};
{ {
let mut data_res = res.data.ptr_mut(); let mut data_res = res.data.ptr_mut();

View File

@ -17,7 +17,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
DefaultAllocator: Allocator<N, U1, C>, DefaultAllocator: Allocator<N, U1, C>,
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res = unsafe { RowVectorN::new_uninitialized_generic(U1, ncols) }; let mut res: RowVectorN<N, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(U1, ncols) };
for i in 0..ncols.value() { for i in 0..ncols.value() {
// TODO: avoid bound checking of column. // TODO: avoid bound checking of column.
@ -42,7 +43,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
DefaultAllocator: Allocator<N, C>, DefaultAllocator: Allocator<N, C>,
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res = unsafe { VectorN::new_uninitialized_generic(ncols, U1) }; let mut res: VectorN<N, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) };
for i in 0..ncols.value() { for i in 0..ncols.value() {
// TODO: avoid bound checking of column. // TODO: avoid bound checking of column.

View File

@ -199,7 +199,12 @@ where
D: DimNameAdd<U1>, D: DimNameAdd<U1>,
DefaultAllocator: Allocator<N, DimNameSum<D, U1>>, DefaultAllocator: Allocator<N, DimNameSum<D, U1>>,
{ {
let mut res = unsafe { VectorN::<_, DimNameSum<D, U1>>::new_uninitialized() }; let mut res = unsafe {
crate::unimplemented_or_uninitialized_generic!(
<DimNameSum<D, U1> as DimName>::name(),
U1
)
};
res.fixed_slice_mut::<D, U1>(0, 0).copy_from(&self.coords); res.fixed_slice_mut::<D, U1>(0, 0).copy_from(&self.coords);
res[(D::dim(), 0)] = N::one(); res[(D::dim(), 0)] = N::one();

View File

@ -24,7 +24,10 @@ where
/// Creates a new point with uninitialized coordinates. /// Creates a new point with uninitialized coordinates.
#[inline] #[inline]
pub unsafe fn new_uninitialized() -> Self { pub unsafe fn new_uninitialized() -> Self {
Self::from(VectorN::new_uninitialized()) Self::from(crate::unimplemented_or_uninitialized_generic!(
D::name(),
U1
))
} }
/// Creates a new point with all coordinates equal to zero. /// Creates a new point with all coordinates equal to zero.

View File

@ -87,6 +87,7 @@ an optimized set of tools for computer graphics and physics. Those features incl
)] )]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))] #![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
#![cfg_attr(feature = "no_unsound_assume_init", allow(unreachable_code))]
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
extern crate quickcheck; extern crate quickcheck;

View File

@ -81,11 +81,12 @@ where
"Cannot compute the bidiagonalization of an empty matrix." "Cannot compute the bidiagonalization of an empty matrix."
); );
let mut diagonal = unsafe { MatrixMN::new_uninitialized_generic(min_nrows_ncols, U1) }; let mut diagonal =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) };
let mut off_diagonal = let mut off_diagonal =
unsafe { MatrixMN::new_uninitialized_generic(min_nrows_ncols.sub(U1), U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols.sub(U1), U1) };
let mut axis_packed = unsafe { MatrixMN::new_uninitialized_generic(ncols, U1) }; let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) };
let mut work = unsafe { MatrixMN::new_uninitialized_generic(nrows, U1) }; let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, U1) };
let upper_diagonal = nrows.value() >= ncols.value(); let upper_diagonal = nrows.value() >= ncols.value();
if upper_diagonal { if upper_diagonal {
@ -239,8 +240,9 @@ where
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
let mut res = Matrix::identity_generic(min_nrows_ncols, ncols); let mut res = Matrix::identity_generic(min_nrows_ncols, ncols);
let mut work = unsafe { MatrixMN::new_uninitialized_generic(min_nrows_ncols, U1) }; let mut work =
let mut axis_packed = unsafe { MatrixMN::new_uninitialized_generic(ncols, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) };
let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) };
let shift = self.axis_shift().1; let shift = self.axis_shift().1;

View File

@ -223,9 +223,9 @@ where
// loads the data into a new matrix with an additional jth row/column // loads the data into a new matrix with an additional jth row/column
let mut chol = unsafe { let mut chol = unsafe {
Matrix::new_uninitialized_generic( crate::unimplemented_or_uninitialized_generic!(
self.chol.data.shape().0.add(U1), self.chol.data.shape().0.add(U1),
self.chol.data.shape().1.add(U1), self.chol.data.shape().1.add(U1)
) )
}; };
chol.slice_range_mut(..j, ..j) chol.slice_range_mut(..j, ..j)
@ -288,9 +288,9 @@ where
// loads the data into a new matrix except for the jth row/column // loads the data into a new matrix except for the jth row/column
let mut chol = unsafe { let mut chol = unsafe {
Matrix::new_uninitialized_generic( crate::unimplemented_or_uninitialized_generic!(
self.chol.data.shape().0.sub(U1), self.chol.data.shape().0.sub(U1),
self.chol.data.shape().1.sub(U1), self.chol.data.shape().1.sub(U1)
) )
}; };
chol.slice_range_mut(..j, ..j) chol.slice_range_mut(..j, ..j)

View File

@ -2,7 +2,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, MatrixMN, MatrixN, VectorN}; use crate::base::{DefaultAllocator, MatrixN, VectorN};
use crate::dimension::{DimDiff, DimSub, U1}; use crate::dimension::{DimDiff, DimSub, U1};
use crate::storage::Storage; use crate::storage::Storage;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -48,7 +48,8 @@ where
{ {
/// Computes the Hessenberg decomposition using householder reflections. /// Computes the Hessenberg decomposition using householder reflections.
pub fn new(hess: MatrixN<N, D>) -> Self { pub fn new(hess: MatrixN<N, D>) -> Self {
let mut work = unsafe { MatrixMN::new_uninitialized_generic(hess.data.shape().0, U1) }; let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(hess.data.shape().0, U1) };
Self::new_with_workspace(hess, &mut work) Self::new_with_workspace(hess, &mut work)
} }
@ -74,7 +75,8 @@ where
"Hessenberg: invalid workspace size." "Hessenberg: invalid workspace size."
); );
let mut subdiag = unsafe { MatrixMN::new_uninitialized_generic(dim.sub(U1), U1) }; let mut subdiag =
unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) };
if dim.value() == 0 { if dim.value() == 0 {
return Hessenberg { hess, subdiag }; return Hessenberg { hess, subdiag };

View File

@ -72,7 +72,7 @@ where
unsafe { unsafe {
Self { Self {
len: 0, len: 0,
ipiv: VectorN::new_uninitialized_generic(dim, U1), ipiv: crate::unimplemented_or_uninitialized_generic!(dim, U1),
} }
} }
} }

View File

@ -54,7 +54,8 @@ where
let (nrows, ncols) = matrix.data.shape(); let (nrows, ncols) = matrix.data.shape();
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
let mut diag = unsafe { MatrixMN::new_uninitialized_generic(min_nrows_ncols, U1) }; let mut diag =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) };
if min_nrows_ncols.value() == 0 { if min_nrows_ncols.value() == 0 {
return QR { qr: matrix, diag }; return QR { qr: matrix, diag };

View File

@ -71,7 +71,8 @@ where
/// number of iteration is exceeded, `None` is returned. If `niter == 0`, then the algorithm /// number of iteration is exceeded, `None` is returned. If `niter == 0`, then the algorithm
/// continues indefinitely until convergence. /// continues indefinitely until convergence.
pub fn try_new(m: MatrixN<N, D>, eps: N::RealField, max_niter: usize) -> Option<Self> { pub fn try_new(m: MatrixN<N, D>, eps: N::RealField, max_niter: usize) -> Option<Self> {
let mut work = unsafe { VectorN::new_uninitialized_generic(m.data.shape().0, U1) }; let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, U1) };
Self::do_decompose(m, &mut work, eps, max_niter, true) Self::do_decompose(m, &mut work, eps, max_niter, true)
.map(|(q, t)| Schur { q: q.unwrap(), t }) .map(|(q, t)| Schur { q: q.unwrap(), t })
@ -378,7 +379,8 @@ where
/// ///
/// Return `None` if some eigenvalues are complex. /// Return `None` if some eigenvalues are complex.
pub fn eigenvalues(&self) -> Option<VectorN<N, D>> { pub fn eigenvalues(&self) -> Option<VectorN<N, D>> {
let mut out = unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1) }; let mut out =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, U1) };
if Self::do_eigenvalues(&self.t, &mut out) { if Self::do_eigenvalues(&self.t, &mut out) {
Some(out) Some(out)
} else { } else {
@ -392,7 +394,8 @@ where
N: RealField, N: RealField,
DefaultAllocator: Allocator<NumComplex<N>, D>, DefaultAllocator: Allocator<NumComplex<N>, D>,
{ {
let mut out = unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1) }; let mut out =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, U1) };
Self::do_complex_eigenvalues(&self.t, &mut out); Self::do_complex_eigenvalues(&self.t, &mut out);
out out
} }
@ -503,7 +506,8 @@ where
"Unable to compute eigenvalues of a non-square matrix." "Unable to compute eigenvalues of a non-square matrix."
); );
let mut work = unsafe { VectorN::new_uninitialized_generic(self.data.shape().0, U1) }; let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, U1) };
// Special case for 2x2 matrices. // Special case for 2x2 matrices.
if self.nrows() == 2 { if self.nrows() == 2 {
@ -544,7 +548,7 @@ where
DefaultAllocator: Allocator<NumComplex<N>, D>, DefaultAllocator: Allocator<NumComplex<N>, D>,
{ {
let dim = self.data.shape().0; let dim = self.data.shape().0;
let mut work = unsafe { VectorN::new_uninitialized_generic(dim, U1) }; let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(dim, U1) };
let schur = Schur::do_decompose( let schur = Schur::do_decompose(
self.clone_owned(), self.clone_owned(),
@ -554,7 +558,7 @@ where
false, false,
) )
.unwrap(); .unwrap();
let mut eig = unsafe { VectorN::new_uninitialized_generic(dim, U1) }; let mut eig = unsafe { crate::unimplemented_or_uninitialized_generic!(dim, U1) };
Schur::do_complex_eigenvalues(&schur.1, &mut eig); Schur::do_complex_eigenvalues(&schur.1, &mut eig);
eig eig
} }

View File

@ -2,7 +2,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, MatrixMN, MatrixN, VectorN}; use crate::base::{DefaultAllocator, MatrixN, VectorN};
use crate::dimension::{DimDiff, DimSub, U1}; use crate::dimension::{DimDiff, DimSub, U1};
use crate::storage::Storage; use crate::storage::Storage;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -61,8 +61,9 @@ where
"Unable to compute the symmetric tridiagonal decomposition of an empty matrix." "Unable to compute the symmetric tridiagonal decomposition of an empty matrix."
); );
let mut off_diagonal = unsafe { MatrixMN::new_uninitialized_generic(dim.sub(U1), U1) }; let mut off_diagonal =
let mut p = unsafe { MatrixMN::new_uninitialized_generic(dim.sub(U1), U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) };
let mut p = unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) };
for i in 0..dim.value() - 1 { for i in 0..dim.value() - 1 {
let mut m = m.rows_range_mut(i + 1..); let mut m = m.rows_range_mut(i + 1..);

View File

@ -460,7 +460,7 @@ where
{ {
// Size = R // Size = R
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows, U1) }; let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, U1) };
self.sort_with_workspace(workspace.as_mut_slice()); self.sort_with_workspace(workspace.as_mut_slice());
} }

View File

@ -48,8 +48,10 @@ where
let (l, u) = Self::nonzero_pattern(m); let (l, u) = Self::nonzero_pattern(m);
// Workspaces. // Workspaces.
let work_x = unsafe { VectorN::new_uninitialized_generic(m.data.shape().0, U1) }; let work_x =
let work_c = unsafe { VectorN::new_uninitialized_generic(m.data.shape().1, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, U1) };
let work_c =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().1, U1) };
let mut original_p = m.data.p.as_slice().to_vec(); let mut original_p = m.data.p.as_slice().to_vec();
original_p.push(m.data.i.len()); original_p.push(m.data.i.len());
@ -291,7 +293,8 @@ where
let etree = Self::elimination_tree(m); let etree = Self::elimination_tree(m);
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
let mut rows = Vec::with_capacity(m.len()); let mut rows = Vec::with_capacity(m.len());
let mut cols = unsafe { VectorN::new_uninitialized_generic(m.data.shape().0, U1) }; let mut cols =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, U1) };
let mut marks = Vec::new(); let mut marks = Vec::new();
// NOTE: the following will actually compute the non-zero pattern of // NOTE: the following will actually compute the non-zero pattern of

View File

@ -242,7 +242,7 @@ where
let mut res = CsMatrix::new_uninitialized_generic(nrows1, ncols2, self.len() + rhs.len()); let mut res = CsMatrix::new_uninitialized_generic(nrows1, ncols2, self.len() + rhs.len());
let mut timestamps = VectorN::zeros_generic(nrows1, U1); let mut timestamps = VectorN::zeros_generic(nrows1, U1);
let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, U1) }; let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows1, U1) };
let mut nz = 0; let mut nz = 0;
for j in 0..ncols2.value() { for j in 0..ncols2.value() {

View File

@ -149,7 +149,8 @@ impl<N: RealField, D: Dim, S: CsStorage<N, D, D>> CsMatrix<N, D, D, S> {
self.lower_triangular_reach(b, &mut reach); self.lower_triangular_reach(b, &mut reach);
// We sort the reach so the result matrix has sorted indices. // We sort the reach so the result matrix has sorted indices.
reach.sort(); reach.sort();
let mut workspace = unsafe { VectorN::new_uninitialized_generic(b.data.shape().0, U1) }; let mut workspace =
unsafe { crate::unimplemented_or_uninitialized_generic!(b.data.shape().0, U1) };
for i in reach.iter().cloned() { for i in reach.iter().cloned() {
workspace[i] = N::zero(); workspace[i] = N::zero();