Added some derives

This commit is contained in:
Violeta Hernández 2021-07-29 12:33:45 -05:00
parent 22b657f566
commit 2243a11e89
10 changed files with 84 additions and 141 deletions

View File

@ -93,8 +93,8 @@ where
let n = nrows.value();
let lda = n as i32;
// IMPORTANT TODO: this is still UB.
// IMPORTANT TODO: this is still UB.
let mut values =
unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
let mut info = 0;

View File

@ -55,7 +55,7 @@ pub fn spadd_csc_prealloc<T>(
a: Op<&CscMatrix<T>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One+PartialEq,
T: Scalar + ClosedAdd + ClosedMul + Zero + One + PartialEq,
{
assert_compatible_spadd_dims!(c, a);
spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs))

View File

@ -1,7 +1,6 @@
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::Dynamic;
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::base::storage::InnerOwned;
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage;
use crate::base::{ArrayStorage, Const, Matrix, Owned, Unit};
@ -31,7 +30,7 @@ pub type MatrixMN<T, R, C> = OMatrix<T, R, C>;
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated(note = "use OMatrix<T, D, D> or SMatrix<T, D, D> instead.")]
pub type MatrixN<T, D> = Matrix<T, D, D, InnerOwned<T, D, D>>;
pub type MatrixN<T, D> = Matrix<T, D, D, Owned<T, D, D>>;
/// A statically sized column-major matrix with `R` rows and `C` columns.
///
@ -274,7 +273,7 @@ pub type Matrix6x5<T> = Matrix<T, U6, U5, ArrayStorage<T, 6, 5>>;
pub type DVector<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;
/// An owned D-dimensional column vector.
pub type OVector<T, D> = Matrix<T, D, U1, InnerOwned<T, D, U1>>;
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
/// A statically sized D-dimensional column vector.
pub type SVector<T, const D: usize> = Matrix<T, Const<D>, U1, ArrayStorage<T, D, 1>>; // Owned<T, Const<D>, U1>>;
@ -284,7 +283,7 @@ pub type SVector<T, const D: usize> = Matrix<T, Const<D>, U1, ArrayStorage<T, D,
#[deprecated(
note = "use SVector for a statically-sized matrix using integer dimensions, or OVector for an owned matrix using types as dimensions."
)]
pub type VectorN<T, D> = Matrix<T, D, U1, InnerOwned<T, D, U1>>;
pub type VectorN<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
/// A stack-allocated, 1-dimensional column vector.
pub type Vector1<T> = Matrix<T, U1, U1, ArrayStorage<T, 1, 1>>;
@ -311,7 +310,7 @@ pub type Vector6<T> = Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>;
pub type RowDVector<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;
/// An owned D-dimensional row vector.
pub type RowOVector<T, D> = Matrix<T, U1, D, InnerOwned<T, U1, D>>;
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;
/// A statically sized D-dimensional row vector.
pub type RowSVector<T, const D: usize> = Matrix<T, U1, Const<D>, ArrayStorage<T, 1, D>>;

View File

@ -1,8 +1,6 @@
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;
#[cfg(feature = "arbitrary")]
use crate::base::storage::InnerOwned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
@ -898,7 +896,6 @@ impl<T, R: Dim, C: Dim> Arbitrary for OMatrix<T, R, C>
where
T: Arbitrary + Send,
DefaultAllocator: Allocator<T, R, C>,
InnerOwned<T, R, C>: Clone + Send,
{
#[inline]
fn arbitrary(g: &mut Gen) -> Self {

View File

@ -66,19 +66,14 @@ impl<T, const R: usize, const C: usize> InnerAllocator<T, Const<R>, Const<C>> fo
impl<T, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>> for DefaultAllocator {
#[inline]
fn allocate_uninitialized(
_: Const<R>,
_: Const<C>,
) -> InnerOwned<MaybeUninit<T>, Const<R>, Const<C>> {
fn allocate_uninitialized(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
let array = unsafe { MaybeUninit::uninit().assume_init() };
ArrayStorage(array)
}
#[inline]
unsafe fn assume_init(
uninit: <Self as InnerAllocator<MaybeUninit<T>, Const<R>, Const<C>>>::Buffer,
) -> InnerOwned<T, Const<R>, Const<C>> {
unsafe fn assume_init(uninit: ArrayStorage<MaybeUninit<T>, R, C>) -> ArrayStorage<T, R, C> {
// Safety:
// * The caller guarantees that all elements of the array are initialized
// * `MaybeUninit<T>` and T are guaranteed to have the same layout
@ -89,9 +84,7 @@ impl<T, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>> for Def
/// Specifies that a given buffer's entries should be manually dropped.
#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, Const<R>, Const<C>>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, Const<R>, Const<C>>>::Buffer {
fn manually_drop(buf: ArrayStorage<T, R, C>) -> ArrayStorage<ManuallyDrop<T>, R, C> {
// SAFETY:
// * `ManuallyDrop<T>` and T are guaranteed to have the same layout
// * `ManuallyDrop` does not drop, so there are no double-frees
@ -123,7 +116,7 @@ impl<T, C: Dim> InnerAllocator<T, Dynamic, C> for DefaultAllocator {
impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
#[inline]
fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> InnerOwned<MaybeUninit<T>, Dynamic, C> {
fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> VecStorage<MaybeUninit<T>, Dynamic, C> {
let mut data = Vec::new();
let length = nrows.value() * ncols.value();
data.reserve_exact(length);
@ -134,8 +127,8 @@ impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
#[inline]
unsafe fn assume_init(
uninit: InnerOwned<MaybeUninit<T>, Dynamic, C>,
) -> InnerOwned<T, Dynamic, C> {
uninit: VecStorage<MaybeUninit<T>, Dynamic, C>,
) -> VecStorage<T, Dynamic, C> {
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
@ -150,9 +143,7 @@ impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
}
#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, Dynamic, C>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, Dynamic, C>>::Buffer {
fn manually_drop(buf: VecStorage<T, Dynamic, C>) -> VecStorage<ManuallyDrop<T>, Dynamic, C> {
// Avoids a double-drop.
let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
@ -178,7 +169,7 @@ impl<T, R: DimName> InnerAllocator<T, R, Dynamic> for DefaultAllocator {
nrows: R,
ncols: Dynamic,
iter: I,
) -> InnerOwned<T, R, Dynamic> {
) -> Self::Buffer {
let it = iter.into_iter();
let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(),
@ -190,7 +181,7 @@ impl<T, R: DimName> InnerAllocator<T, R, Dynamic> for DefaultAllocator {
impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[inline]
fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> InnerOwned<MaybeUninit<T>, R, Dynamic> {
fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> VecStorage<MaybeUninit<T>, R, Dynamic> {
let mut data = Vec::new();
let length = nrows.value() * ncols.value();
data.reserve_exact(length);
@ -201,8 +192,8 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[inline]
unsafe fn assume_init(
uninit: InnerOwned<MaybeUninit<T>, R, Dynamic>,
) -> InnerOwned<T, R, Dynamic> {
uninit: VecStorage<MaybeUninit<T>, R, Dynamic>,
) -> VecStorage<T, R, Dynamic> {
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
@ -217,9 +208,7 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
}
#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, R, Dynamic>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, R, Dynamic>>::Buffer {
fn manually_drop(buf: VecStorage<T, R, Dynamic>) -> VecStorage<ManuallyDrop<T>, R, Dynamic> {
// Avoids a double-drop.
let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
@ -239,18 +228,18 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[repr(transparent)]
pub struct Owned<T, R: Dim, C: Dim>(pub InnerOwned<T, R, C>)
where
DefaultAllocator: Allocator<T, R, C>;
DefaultAllocator: InnerAllocator<T, R, C>;
impl<T: Copy, R: DimName, C: DimName> Copy for Owned<T, R, C>
impl<T: Copy, R: Dim, C: Dim> Copy for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
InnerOwned<T, R, C>: Copy,
{
}
impl<T: Clone, R: Dim, C: Dim> Clone for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
fn clone(&self) -> Self {
if Self::is_array() {
@ -260,23 +249,21 @@ where
// We then transmute it back into an array and then an Owned.
unsafe { mem::transmute_copy(&*vec.as_ptr()) }
// TODO: check that the auxiliary copy is elided.
} else {
// We first clone the data.
let clone = ManuallyDrop::new(self.as_vec_storage().clone());
// We then transmute it back into an Owned.
unsafe { mem::transmute_copy(&clone) }
// TODO: check that the auxiliary copy is elided.
}
// TODO: check that the auxiliary copies are elided.
}
}
impl<T: fmt::Debug, R: Dim, C: Dim> fmt::Debug for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if Self::is_array() {
@ -288,22 +275,28 @@ where
}
}
impl<T, const R: usize, const C: usize> Owned<T, Const<R>, Const<C>> {
fn new(array: [[T; R]; C]) -> Self {
Self(ArrayStorage(array))
}
}
impl<T, R: Dim, C: Dim> Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
/// Returns whether `Self` stores an [`ArrayStorage`].
fn is_array() -> bool {
/// Returns whether `Self` stores an [`ArrayStorage`]. This is a zero-cost
/// operation.
const fn is_array() -> bool {
R::is_static() && C::is_static()
}
/// Returns whether `Self` stores a [`VecStorage`].
fn is_vec() -> bool {
const fn is_vec() -> bool {
!Self::is_array()
}
/// Returns the underlying [`VecStorage`]. Does not do any sort of static
/// type checking.
/// Returns a reference to the underlying [`VecStorage`].
///
/// # Panics
/// This method will panic if `Self` does not contain a [`VecStorage`].
@ -311,13 +304,24 @@ where
assert!(Self::is_vec());
// Safety: `self` is transparent and must contain a `VecStorage`.
unsafe { &*(&self as *const _ as *const _) }
unsafe { &*(self as *const _ as *const _) }
}
/// Returns a mutable reference to the underlying [`VecStorage`].
///
/// # Panics
/// This method will panic if `Self` does not contain a [`VecStorage`].
fn as_vec_storage_mut(&mut self) -> &mut VecStorage<T, R, C> {
assert!(Self::is_vec());
// Safety: `self` is transparent and must contain a `VecStorage`.
unsafe { &mut *(self as *mut _ as *mut _) }
}
}
unsafe impl<T, R: Dim, C: Dim> Storage<T, R, C> for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
type RStride = U1;
@ -349,6 +353,7 @@ where
}
}
#[inline(always)]
fn is_contiguous(&self) -> bool {
true
}
@ -364,11 +369,13 @@ where
}
}
fn into_owned(self) -> Owned<T, R, C> {
#[inline(always)]
fn into_owned(self) -> Self {
self
}
fn clone_owned(&self) -> Owned<T, R, C>
#[inline(always)]
fn clone_owned(&self) -> Self
where
T: Clone,
{
@ -378,24 +385,35 @@ where
unsafe impl<T, R: Dim, C: Dim> StorageMut<T, R, C> for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
fn ptr_mut(&mut self) -> *mut T {
todo!()
if Self::is_array() {
&mut self as *mut _ as *mut T
} else {
self.as_vec_storage_mut().as_vec().as_ptr()
}
}
unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] {
todo!()
if Self::is_array() {
std::slice::from_raw_parts(
self.ptr_mut(),
R::try_to_usize().unwrap() * C::try_to_usize().unwrap(),
)
} else {
self.as_vec_storage_mut().as_vec_mut().as_mut()
}
}
}
unsafe impl<T, R: Dim, C: Dim> ContiguousStorage<T, R, C> for Owned<T, R, C> where
DefaultAllocator: Allocator<T, R, C>
DefaultAllocator: InnerAllocator<T, R, C>
{
}
unsafe impl<T, R: Dim, C: Dim> ContiguousStorageMut<T, R, C> for Owned<T, R, C> where
DefaultAllocator: Allocator<T, R, C>
DefaultAllocator: InnerAllocator<T, R, C>
{
}

View File

@ -153,7 +153,7 @@ pub type MatrixCross<T, R1, C1, R2, C2> =
/// dynamically-sized column vector should be represented as a `Matrix<T, Dynamic, U1, S>` (given
/// some concrete types for `T` and a compatible data storage type `S`).
#[repr(transparent)]
#[derive(Clone,Copy,Debug)]
#[derive(Clone, Copy, Debug)]
pub struct Matrix<T, R, C, S> {
/// The data storage that contains all the matrix components. Disappointed?
///

View File

@ -16,7 +16,6 @@ use crate::base::constraint::{
use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dynamic};
use crate::base::storage::{ContiguousStorageMut, Storage, StorageMut};
use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar, VectorSlice};
use crate::storage::InnerOwned;
use crate::{MatrixSliceMut, SimdComplexField};
/*
@ -432,11 +431,6 @@ impl<'a, T, C: Dim> iter::Sum<&'a OMatrix<T, Dynamic, C>> for OMatrix<T, Dynamic
where
T: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<T, Dynamic, C>,
// TODO: we should take out this trait bound, as T: Clone should suffice.
// The brute way to do it would be how it was already done: by adding this
// trait bound on the associated type itself.
InnerOwned<T, Dynamic, C>: Clone,
{
/// # Example
/// ```

View File

@ -10,21 +10,19 @@ use crate::base::Owned;
/*
* Aliases for allocation results.
*/
/// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`.
pub type SameShapeStorage<T, R1, C1, R2, C2> =
<DefaultAllocator as InnerAllocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>>::Buffer;
// TODO: better name than Owned ?
/// The owned data storage that can be allocated from `S`.
pub type InnerOwned<T, R, C = U1> = <DefaultAllocator as InnerAllocator<T, R, C>>::Buffer;
/// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`.
pub type SameShapeStorage<T, R1, C1, R2, C2> = Owned<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>;
/// The row-stride of the owned data storage for a buffer of dimension `(R, C)`.
pub type RStride<T, R, C = U1> =
<<DefaultAllocator as InnerAllocator<T, R, C>>::Buffer as Storage<T, R, C>>::RStride;
pub type RStride<T, R, C = U1> = <InnerOwned<T, R, C> as Storage<T, R, C>>::RStride;
/// The column-stride of the owned data storage for a buffer of dimension `(R, C)`.
pub type CStride<T, R, C = U1> =
<<DefaultAllocator as InnerAllocator<T, R, C>>::Buffer as Storage<T, R, C>>::CStride;
pub type CStride<T, R, C = U1> = <InnerOwned<T, R, C> as Storage<T, R, C>>::CStride;
/// The trait shared by all matrix data storage.
///

View File

@ -1,6 +1,5 @@
#![allow(clippy::suspicious_operation_groupings)]
use std::cmp;
use std::fmt;
use std::mem::MaybeUninit;
#[cfg(feature = "serde-serialize-no-std")]
@ -11,10 +10,10 @@ use num_complex::Complex as NumComplex;
use simba::scalar::{ComplexField, RealField};
use crate::allocator::Allocator;
use crate::base::dimension::{Const, Dim, DimDiff, DimName, DimSub, Dynamic, U1, U2};
use crate::base::dimension::{Const, Dim, DimDiff, DimSub, Dynamic, U1, U2};
use crate::base::storage::{InnerOwned, Storage};
use crate::base::{
DefaultAllocator, OMatrix, OVector, Owned, SquareMatrix, Unit, Vector2, Vector3,
DefaultAllocator, OMatrix, OVector, SquareMatrix, Unit, Vector2, Vector3,
};
use crate::geometry::Reflection;
@ -36,6 +35,7 @@ use crate::linalg::Hessenberg;
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D>,
OMatrix<T, D, D>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct Schur<T, D: Dim>
where
DefaultAllocator: Allocator<T, D, D>,
@ -44,39 +44,13 @@ where
t: OMatrix<T, D, D>,
}
impl<T: Copy, D: DimName> Copy for Schur<T, D>
impl<T: Copy, D: Dim> Copy for Schur<T, D>
where
DefaultAllocator: Allocator<T, D, D>,
Owned<T, D, D>: Copy,
InnerOwned<T, D, D>: Copy,
{
}
impl<T: Clone, D: Dim> Clone for Schur<T, D>
where
DefaultAllocator: Allocator<T, D, D>,
InnerOwned<T, D, D>: Clone,
{
fn clone(&self) -> Self {
Self {
q: self.q.clone(),
t: self.t.clone(),
}
}
}
impl<T: fmt::Debug, D: Dim> fmt::Debug for Schur<T, D>
where
DefaultAllocator: Allocator<T, D, D>,
InnerOwned<T, D, D>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Schur")
.field("q", &self.q)
.field("t", &self.t)
.finish()
}
}
impl<T: ComplexField, D: Dim> Schur<T, D>
where
D: DimSub<U1>, // For Hessenberg.

View File

@ -1,5 +1,3 @@
use std::fmt;
#[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Serialize};
@ -41,6 +39,7 @@ use crate::linalg::Bidiagonal;
OVector<T::RealField, DimMinimum<R, C>>: Deserialize<'de>"
))
)]
#[derive(Clone, Debug)]
pub struct SVD<T: ComplexField, R: DimMin<C>, C: Dim>
where
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>
@ -66,42 +65,6 @@ where
{
}
impl<T: ComplexField, R: DimMin<C>, C: Dim> Clone for SVD<T, R, C>
where
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>
+ Allocator<T, R, DimMinimum<R, C>>
+ Allocator<T::RealField, DimMinimum<R, C>>,
InnerOwned<T, R, DimMinimum<R, C>>: Clone,
InnerOwned<T, DimMinimum<R, C>, C>: Clone,
InnerOwned<T::RealField, DimMinimum<R, C>>: Clone,
{
fn clone(&self) -> Self {
Self {
u: self.u.clone(),
v_t: self.v_t.clone(),
singular_values: self.singular_values.clone(),
}
}
}
impl<T: ComplexField, R: DimMin<C>, C: Dim> fmt::Debug for SVD<T, R, C>
where
DefaultAllocator: Allocator<T, DimMinimum<R, C>, C>
+ Allocator<T, R, DimMinimum<R, C>>
+ Allocator<T::RealField, DimMinimum<R, C>>,
InnerOwned<T, R, DimMinimum<R, C>>: fmt::Debug,
InnerOwned<T, DimMinimum<R, C>, C>: fmt::Debug,
InnerOwned<T::RealField, DimMinimum<R, C>>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SVD")
.field("u", &self.u)
.field("v_t", &self.v_t)
.field("singular_values", &self.singular_values)
.finish()
}
}
impl<T: ComplexField, R: DimMin<C>, C: Dim> SVD<T, R, C>
where
DimMinimum<R, C>: DimSub<U1>, // for Bidiagonal.