Fixed some more blatant issues
This commit is contained in:
parent
fa1ed9683b
commit
7e1b2f81b3
|
@ -942,7 +942,8 @@ impl<T: Clone> OMatrix<T, Dynamic, Dynamic> {
|
||||||
where
|
where
|
||||||
DefaultAllocator: Reallocator<T, Dynamic, Dynamic, Dynamic, Dynamic>,
|
DefaultAllocator: Reallocator<T, Dynamic, Dynamic, Dynamic, Dynamic>,
|
||||||
{
|
{
|
||||||
// BEEEP!!!! BEEEEEEEP!!!
|
// IMPORTANT TODO: this method is still UB, and we should decide how to
|
||||||
|
// update the API to take it into account.
|
||||||
|
|
||||||
let placeholder = unsafe {
|
let placeholder = unsafe {
|
||||||
Matrix::new_uninitialized_generic(Dynamic::new(0), Dynamic::new(0)).assume_init()
|
Matrix::new_uninitialized_generic(Dynamic::new(0), Dynamic::new(0)).assume_init()
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::io::{Result as IOResult, Write};
|
||||||
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
|
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;use std::ptr;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::{self, ManuallyDrop, MaybeUninit};
|
use std::mem::{self, ManuallyDrop, MaybeUninit};
|
||||||
|
@ -341,6 +341,7 @@ impl<T, R, C, S> Matrix<T, R, C, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Memory manipulation methods.
|
||||||
impl<T, R: Dim, C: Dim> OMatrix<T, R, C>
|
impl<T, R: Dim, C: Dim> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
|
@ -365,6 +366,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # More memory manipulation methods.
|
||||||
impl<T, R: Dim, C: Dim> OMatrix<MaybeUninit<T>, R, C>
|
impl<T, R: Dim, C: Dim> OMatrix<MaybeUninit<T>, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
|
@ -377,6 +379,18 @@ where
|
||||||
<DefaultAllocator as Allocator<T, R, C>>::assume_init(self.data),
|
<DefaultAllocator as Allocator<T, R, C>>::assume_init(self.data),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Assumes a matrix's entries to be initialized, and drops them. This allows the
|
||||||
|
/// buffer to be safely reused.
|
||||||
|
pub fn reinitialize(&mut self) {
|
||||||
|
for i in 0..self.nrows() {
|
||||||
|
for j in 0..self.ncols() {
|
||||||
|
unsafe {
|
||||||
|
ptr::drop_in_place(self.get_unchecked_mut((i, j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
|
@ -447,21 +461,6 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, 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: MaybeUninit<S>) -> MaybeUninit<Self> {
|
|
||||||
// BEEP BEEP this doesn't seem good
|
|
||||||
let res: Matrix<T, R, C, MaybeUninit<S>> = Matrix {
|
|
||||||
data,
|
|
||||||
_phantoms: PhantomData,
|
|
||||||
};
|
|
||||||
let res: MaybeUninit<Matrix<T, R, C, MaybeUninit<S>>> = 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<T, R, C, MaybeUninit<S>>>` may be of a different size from `MaybeUninit<Matrix<T, 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: MaybeUninit<Matrix<T, 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:
|
||||||
|
@ -941,24 +940,22 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
/// Folds a function `f` on each entry of `self`.
|
/// Folds a function `f` on each entry of `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn fold<Acc>(&self, init: Acc, mut f: impl FnMut(Acc, T) -> Acc) -> Acc
|
pub fn fold<Acc>(&self, mut init: Acc, mut f: impl FnMut(Acc, T) -> Acc) -> Acc
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
{
|
{
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
|
|
||||||
let mut res = init;
|
|
||||||
|
|
||||||
for j in 0..ncols.value() {
|
for j in 0..ncols.value() {
|
||||||
for i in 0..nrows.value() {
|
for i in 0..nrows.value() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
res = f(res, a)
|
init = f(init, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
init
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Folds a function `f` on each pairs of entries from `self` and `rhs`.
|
/// Folds a function `f` on each pairs of entries from `self` and `rhs`.
|
||||||
|
@ -967,7 +964,7 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
pub fn zip_fold<T2: Clone, R2: Dim, C2: Dim, S2, Acc>(
|
pub fn zip_fold<T2: Clone, R2: Dim, C2: Dim, S2, Acc>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Matrix<T2, R2, C2, S2>,
|
rhs: &Matrix<T2, R2, C2, S2>,
|
||||||
init: Acc,
|
mut init: Acc,
|
||||||
mut f: impl FnMut(Acc, T, T2) -> Acc,
|
mut f: impl FnMut(Acc, T, T2) -> Acc,
|
||||||
) -> Acc
|
) -> Acc
|
||||||
where
|
where
|
||||||
|
@ -976,7 +973,6 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
|
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
|
||||||
{
|
{
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
let mut res = init;
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
(nrows.value(), ncols.value()),
|
(nrows.value(), ncols.value()),
|
||||||
|
@ -989,12 +985,12 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = self.data.get_unchecked(i, j).clone();
|
let a = self.data.get_unchecked(i, j).clone();
|
||||||
let b = rhs.data.get_unchecked(i, j).clone();
|
let b = rhs.data.get_unchecked(i, j).clone();
|
||||||
res = f(res, a, b)
|
init = f(init, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
init
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces each component of `self` by the result of a closure `f` applied on it.
|
/// Replaces each component of `self` by the result of a closure `f` applied on it.
|
||||||
|
|
|
@ -59,7 +59,6 @@ impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a column vector resulting from the folding of `f` on each column of this matrix.
|
/// Returns a column vector resulting from the folding of `f` on each column of this matrix.
|
||||||
// BEEEEP!!!! Pretty sure there's something fishy here.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn compress_columns(
|
pub fn compress_columns(
|
||||||
|
|
|
@ -42,23 +42,24 @@ where
|
||||||
// extra allocations.
|
// extra allocations.
|
||||||
let (nrows, ncols) = self.data.shape();
|
let (nrows, ncols) = self.data.shape();
|
||||||
let mut multiplier = self.clone_owned();
|
let mut multiplier = self.clone_owned();
|
||||||
|
let mut buf = Matrix::new_uninitialized_generic(nrows, ncols);
|
||||||
// TODO: ACTUALLY MAKE BUF USEFUL! BEEEEEEEEP!!
|
|
||||||
|
|
||||||
// Exponentiation by squares.
|
// Exponentiation by squares.
|
||||||
loop {
|
loop {
|
||||||
if e % two == one {
|
if e % two == one {
|
||||||
let mut buf = Matrix::new_uninitialized_generic(nrows, ncols);
|
|
||||||
self.mul_to(&multiplier, &mut buf);
|
self.mul_to(&multiplier, &mut buf);
|
||||||
let buf = unsafe { buf.assume_init() };
|
unsafe {
|
||||||
self.copy_from(&buf);
|
self.copy_from(&buf.assume_init_ref());
|
||||||
|
}
|
||||||
|
buf.reinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
e /= two;
|
e /= two;
|
||||||
let mut buf = Matrix::new_uninitialized_generic(nrows, ncols);
|
|
||||||
multiplier.mul_to(&multiplier, &mut buf);
|
multiplier.mul_to(&multiplier, &mut buf);
|
||||||
let buf = unsafe { buf.assume_init() };
|
unsafe {
|
||||||
multiplier.copy_from(&buf);
|
multiplier.copy_from(&buf.assume_init_ref());
|
||||||
|
}
|
||||||
|
buf.reinitialize();
|
||||||
|
|
||||||
if e == zero {
|
if e == zero {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -264,7 +264,9 @@ where
|
||||||
pub fn new_uninitialized_generic(nrows: R, ncols: C, nvals: usize) -> Self {
|
pub fn new_uninitialized_generic(nrows: R, ncols: C, nvals: usize) -> Self {
|
||||||
let mut i = Vec::with_capacity(nvals);
|
let mut i = Vec::with_capacity(nvals);
|
||||||
|
|
||||||
//BEEP BEEP!!!! UNDEFINED BEHAVIOR ALERT!!! BEEP BEEEP!!!
|
// IMPORTANT TODO: this method is still UB, and we should decide how to
|
||||||
|
// update the API to take it into account.
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
i.set_len(nvals);
|
i.set_len(nvals);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue