Replace generic-array with a regular array based on min-const-generics.

This commit is contained in:
Crozet Sébastien 2021-01-03 15:20:34 +01:00
parent b2dadffcf2
commit d17088398a
33 changed files with 357 additions and 630 deletions

View File

@ -54,7 +54,6 @@ slow-tests = []
[dependencies] [dependencies]
typenum = "1.12" typenum = "1.12"
generic-array = "0.14"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false } rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.3", default-features = false } num-complex = { version = "0.3", default-features = false }

View File

@ -2,7 +2,7 @@
extern crate nalgebra as na; extern crate nalgebra as na;
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, U2, U3}; use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const};
fn main() { fn main() {
// Matrices can be reshaped in-place without moving or copying values. // Matrices can be reshaped in-place without moving or copying values.
@ -16,7 +16,7 @@ fn main() {
1.2, 2.3 1.2, 2.3
); );
let m3 = m1.reshape_generic(U3, U2); let m3 = m1.reshape_generic(Const::<3>, Const::<2>);
assert_eq!(m3, m2); assert_eq!(m3, m2);
// Note that, for statically sized matrices, invalid reshapes will not compile: // Note that, for statically sized matrices, invalid reshapes will not compile:

View File

@ -1,8 +1,8 @@
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
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};
use std::ops::{Deref, DerefMut, Mul}; use std::ops::Mul;
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
use serde::de::{Error, SeqAccess, Visitor}; use serde::de::{Error, SeqAccess, Visitor};
@ -18,12 +18,9 @@ use std::mem;
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation; use abomonation::Abomonation;
use generic_array::{ArrayLength, GenericArray};
use typenum::Prod;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator; use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{DimName, U1}; use crate::base::dimension::{Const, ToTypenum};
use crate::base::storage::{ use crate::base::storage::{
ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut, ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut,
}; };
@ -36,166 +33,53 @@ use crate::base::Scalar;
*/ */
/// A array-based statically sized matrix data storage. /// A array-based statically sized matrix data storage.
#[repr(C)] #[repr(C)]
pub struct ArrayStorage<N, R, C> #[derive(Copy, Clone, PartialEq, Eq, Hash)]
where pub struct ArrayStorage<N, const R: usize, const C: usize> {
R: DimName, data: [[N; R]; C],
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
data: GenericArray<N, Prod<R::Value, C::Value>>,
} }
#[deprecated(note = "renamed to `ArrayStorage`")] // TODO: remove this once the stdlib implements Default for arrays.
/// Renamed to [ArrayStorage]. impl<N: Default, const R: usize, const C: usize> Default for ArrayStorage<N, R, C>
pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>;
impl<N, R, C> Default for ArrayStorage<N, R, C>
where where
R: DimName, [[N; R]; C]: Default,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
N: Default,
{ {
#[inline]
fn default() -> Self { fn default() -> Self {
ArrayStorage { Self {
data: Default::default(), data: Default::default(),
} }
} }
} }
impl<N, R, C> Hash for ArrayStorage<N, R, C> impl<N: Debug, const R: usize, const C: usize> Debug for ArrayStorage<N, R, C> {
where
N: Hash,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.data[..].hash(state)
}
}
impl<N, R, C> Deref for ArrayStorage<N, R, C>
where
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
type Target = GenericArray<N, Prod<R::Value, C::Value>>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<N, R, C> DerefMut for ArrayStorage<N, R, C>
where
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<N, R, C> Debug for ArrayStorage<N, R, C>
where
N: Debug,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
#[inline] #[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.data.fmt(fmt) self.data.fmt(fmt)
} }
} }
impl<N, R, C> Copy for ArrayStorage<N, R, C> unsafe impl<N, const R: usize, const C: usize> Storage<N, Const<R>, Const<C>>
where for ArrayStorage<N, R, C>
N: Copy,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
GenericArray<N, Prod<R::Value, C::Value>>: Copy,
{
}
impl<N, R, C> Clone for ArrayStorage<N, R, C>
where
N: Clone,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
#[inline]
fn clone(&self) -> Self {
ArrayStorage {
data: self.data.clone(),
}
}
}
impl<N, R, C> Eq for ArrayStorage<N, R, C>
where
N: Eq,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
}
impl<N, R, C> PartialEq for ArrayStorage<N, R, C>
where
N: PartialEq,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
#[inline]
fn eq(&self, right: &Self) -> bool {
self.data == right.data
}
}
unsafe impl<N, R, C> Storage<N, R, C> for ArrayStorage<N, R, C>
where where
N: Scalar, N: Scalar,
R: DimName, DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
{ {
type RStride = U1; type RStride = Const<1>;
type CStride = R; type CStride = Const<R>;
#[inline] #[inline]
fn ptr(&self) -> *const N { fn ptr(&self) -> *const N {
self[..].as_ptr() self.data.as_ptr() as *const N
} }
#[inline] #[inline]
fn shape(&self) -> (R, C) { fn shape(&self) -> (Const<R>, Const<C>) {
(R::name(), C::name()) (Const, Const)
} }
#[inline] #[inline]
fn strides(&self) -> (Self::RStride, Self::CStride) { fn strides(&self) -> (Self::RStride, Self::CStride) {
(Self::RStride::name(), Self::CStride::name()) (Const, Const)
} }
#[inline] #[inline]
@ -204,112 +88,107 @@ where
} }
#[inline] #[inline]
fn into_owned(self) -> Owned<N, R, C> fn into_owned(self) -> Owned<N, Const<R>, Const<C>>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<N, Const<R>, Const<C>>,
{ {
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, R, C> fn clone_owned(&self) -> Owned<N, Const<R>, Const<C>>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<N, Const<R>, Const<C>>,
{ {
let it = self.iter().cloned(); let it = self.as_slice().iter().cloned();
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it) DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
} }
#[inline] #[inline]
fn as_slice(&self) -> &[N] { fn as_slice(&self) -> &[N] {
&self[..] unsafe { std::slice::from_raw_parts(self.ptr(), R * C) }
} }
} }
unsafe impl<N, R, C> StorageMut<N, R, C> for ArrayStorage<N, R, C> unsafe impl<N, const R: usize, const C: usize> StorageMut<N, Const<R>, Const<C>>
for ArrayStorage<N, R, C>
where where
N: Scalar, N: Scalar,
R: DimName, DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut N {
self[..].as_mut_ptr() self.data.as_mut_ptr() as *mut N
} }
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [N] { fn as_mut_slice(&mut self) -> &mut [N] {
&mut self[..] unsafe { std::slice::from_raw_parts_mut(self.ptr_mut(), R * C) }
} }
} }
unsafe impl<N, R, C> ContiguousStorage<N, R, C> for ArrayStorage<N, R, C> unsafe impl<N, const R: usize, const C: usize> ContiguousStorage<N, Const<R>, Const<C>>
for ArrayStorage<N, R, C>
where where
N: Scalar, N: Scalar,
R: DimName, DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
{ {
} }
unsafe impl<N, R, C> ContiguousStorageMut<N, R, C> for ArrayStorage<N, R, C> unsafe impl<N, const R: usize, const C: usize> ContiguousStorageMut<N, Const<R>, Const<C>>
for ArrayStorage<N, R, C>
where where
N: Scalar, N: Scalar,
R: DimName, DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
{ {
} }
impl<N, R1, C1, R2, C2> ReshapableStorage<N, R1, C1, R2, C2> for ArrayStorage<N, R1, C1> impl<N, const R1: usize, const C1: usize, const R2: usize, const C2: usize>
ReshapableStorage<N, Const<R1>, Const<C1>, Const<R2>, Const<C2>> for ArrayStorage<N, R1, C1>
where where
N: Scalar, N: Scalar,
R1: DimName, Const<R1>: ToTypenum,
C1: DimName, Const<C1>: ToTypenum,
R1::Value: Mul<C1::Value>, Const<R2>: ToTypenum,
Prod<R1::Value, C1::Value>: ArrayLength<N>, Const<C2>: ToTypenum,
R2: DimName, <Const<R1> as ToTypenum>::Typenum: Mul<<Const<C1> as ToTypenum>::Typenum>,
C2: DimName, <Const<R2> as ToTypenum>::Typenum: Mul<
R2::Value: Mul<C2::Value, Output = Prod<R1::Value, C1::Value>>, <Const<C2> as ToTypenum>::Typenum,
Prod<R2::Value, C2::Value>: ArrayLength<N>, Output = typenum::Prod<
<Const<R1> as ToTypenum>::Typenum,
<Const<C1> as ToTypenum>::Typenum,
>,
>,
{ {
type Output = ArrayStorage<N, R2, C2>; type Output = ArrayStorage<N, R2, C2>;
fn reshape_generic(self, _: R2, _: C2) -> Self::Output { fn reshape_generic(self, _: Const<R2>, _: Const<C2>) -> Self::Output {
ArrayStorage { data: self.data } unsafe {
let data: [[N; R2]; C2] = std::mem::transmute_copy(&self.data);
std::mem::forget(self.data);
ArrayStorage { data }
}
} }
} }
/* /*
* *
* Allocation-less serde impls. * Serialization.
* *
*/ */
// XXX: open an issue for GenericArray so that it implements serde traits? // XXX: open an issue for serde so that it allows the serialization/deserialization of all arrays?
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N, R, C> Serialize for ArrayStorage<N, R, C> impl<N, const R: usize, const C: usize> Serialize for ArrayStorage<N, R, C>
where where
N: Scalar + Serialize, N: Scalar + Serialize,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
let mut serializer = serializer.serialize_seq(Some(R::dim() * C::dim()))?; let mut serializer = serializer.serialize_seq(Some(R * C))?;
for e in self.iter() { for e in self.as_slice().iter() {
serializer.serialize_element(e)?; serializer.serialize_element(e)?;
} }
@ -318,13 +197,9 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N, R, C> Deserialize<'a> for ArrayStorage<N, R, C> impl<'a, N, const R: usize, const C: usize> Deserialize<'a> for ArrayStorage<N, R, C>
where where
N: Scalar + Deserialize<'a>, N: Scalar + Deserialize<'a>,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -336,18 +211,14 @@ where
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
/// A visitor that produces a matrix array. /// A visitor that produces a matrix array.
struct ArrayStorageVisitor<N, R, C> { struct ArrayStorageVisitor<N, const R: usize, const C: usize> {
marker: PhantomData<(N, R, C)>, marker: PhantomData<N>,
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N, R, C> ArrayStorageVisitor<N, R, C> impl<N, const R: usize, const C: usize> ArrayStorageVisitor<N, R, C>
where where
N: Scalar, N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
/// Construct a new sequence visitor. /// Construct a new sequence visitor.
pub fn new() -> Self { pub fn new() -> Self {
@ -358,13 +229,9 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N, R, C> Visitor<'a> for ArrayStorageVisitor<N, R, C> impl<'a, N, const R: usize, const C: usize> Visitor<'a> for ArrayStorageVisitor<N, R, C>
where where
N: Scalar + Deserialize<'a>, N: Scalar + Deserialize<'a>,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
type Value = ArrayStorage<N, R, C>; type Value = ArrayStorage<N, R, C>;
@ -381,12 +248,13 @@ where
let mut curr = 0; let mut curr = 0;
while let Some(value) = visitor.next_element()? { while let Some(value) = visitor.next_element()? {
*out.get_mut(curr) *out.as_mut_slice()
.get_mut(curr)
.ok_or_else(|| V::Error::invalid_length(curr, &self))? = value; .ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
curr += 1; curr += 1;
} }
if curr == R::dim() * C::dim() { if curr == R * C {
Ok(out) Ok(out)
} else { } else {
Err(V::Error::invalid_length(curr, &self)) Err(V::Error::invalid_length(curr, &self))
@ -415,16 +283,12 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N, R, C> Abomonation for ArrayStorage<N, R, C> impl<N, const R: usize, const C: usize> Abomonation for ArrayStorage<N, R, C>
where where
R: DimName, N: Scalar + Abomonation,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
N: Abomonation,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
for element in self.data.as_slice() { for element in self.as_slice() {
element.entomb(writer)?; element.entomb(writer)?;
} }
@ -432,7 +296,7 @@ where
} }
unsafe fn exhume<'a, 'b>(&'a mut self, mut bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { unsafe fn exhume<'a, 'b>(&'a mut self, mut bytes: &'b mut [u8]) -> Option<&'b mut [u8]> {
for element in self.data.as_mut_slice() { for element in self.as_mut_slice() {
let temp = bytes; let temp = bytes;
bytes = if let Some(remainder) = element.exhume(temp) { bytes = if let Some(remainder) = element.exhume(temp) {
remainder remainder
@ -444,9 +308,6 @@ where
} }
fn extent(&self) -> usize { fn extent(&self) -> usize {
self.data self.as_slice().iter().fold(0, |acc, e| acc + e.extent())
.as_slice()
.iter()
.fold(0, |acc, e| acc + e.extent())
} }
} }

View File

@ -10,7 +10,7 @@ use crate::base::allocator::Allocator;
use crate::base::constraint::{ use crate::base::constraint::{
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
}; };
use crate::base::dimension::{Dim, Dynamic, U1, U2, U3, U4}; use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{ use crate::base::{
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSliceN, DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSliceN,
@ -1120,7 +1120,7 @@ where
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) }; let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) };
let subdim = Dynamic::new(dim1 - j); let subdim = Dynamic::new(dim1 - j);
// TODO: avoid bound checks. // TODO: avoid bound checks.
self.generic_slice_mut((j, j), (subdim, U1)).axpy( self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy(
alpha.inlined_clone() * val, alpha.inlined_clone() * val,
&x.rows_range(j..), &x.rows_range(j..),
beta.inlined_clone(), beta.inlined_clone(),
@ -1329,7 +1329,7 @@ where
DefaultAllocator: Allocator<N, D1>, DefaultAllocator: Allocator<N, D1>,
{ {
let mut work = let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Const::<1>) };
self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta) self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta)
} }
@ -1423,7 +1423,7 @@ where
DefaultAllocator: Allocator<N, D2>, DefaultAllocator: Allocator<N, D2>,
{ {
let mut work = let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, Const::<1>) };
self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta) self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta)
} }
} }

View File

@ -20,7 +20,7 @@ use typenum::{self, Cmp, Greater};
use simba::scalar::{ClosedAdd, ClosedMul}; use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6}; use crate::base::dimension::{Const, Dim, DimName, Dynamic, ToTypenum, 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};
@ -306,12 +306,12 @@ where
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Dynamic, DMatrix, Matrix, U1}; /// # use nalgebra::{Dynamic, DMatrix, Matrix, Const};
/// ///
/// let vec = vec![0, 1, 2, 3, 4, 5]; /// let vec = vec![0, 1, 2, 3, 4, 5];
/// let vec_ptr = vec.as_ptr(); /// let vec_ptr = vec.as_ptr();
/// ///
/// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), U1, vec); /// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), Const::<1>, vec);
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr(); /// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
/// ///
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from. /// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
@ -865,7 +865,7 @@ where
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<VectorN<N, D>> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<VectorN<N, D>> {
Unit::new_normalize(VectorN::from_distribution_generic( Unit::new_normalize(VectorN::from_distribution_generic(
D::name(), D::name(),
U1, Const::<1>,
&rand_distr::StandardNormal, &rand_distr::StandardNormal,
rng, rng,
)) ))
@ -1051,6 +1051,7 @@ componentwise_constructors_impl!(
*/ */
impl<N, R: DimName> VectorN<N, R> impl<N, R: DimName> VectorN<N, R>
where where
R: ToTypenum,
N: Scalar + Zero + One, N: Scalar + Zero + One,
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<N, R>,
{ {
@ -1072,7 +1073,7 @@ where
#[inline] #[inline]
pub fn x() -> Self pub fn x() -> Self
where where
R::Value: Cmp<typenum::U0, Output = Greater>, R::Typenum: Cmp<typenum::U0, Output = Greater>,
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
@ -1086,7 +1087,7 @@ where
#[inline] #[inline]
pub fn y() -> Self pub fn y() -> Self
where where
R::Value: Cmp<typenum::U1, Output = Greater>, R::Typenum: Cmp<typenum::U1, Output = Greater>,
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
@ -1100,7 +1101,7 @@ where
#[inline] #[inline]
pub fn z() -> Self pub fn z() -> Self
where where
R::Value: Cmp<typenum::U2, Output = Greater>, R::Typenum: Cmp<typenum::U2, Output = Greater>,
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
@ -1114,7 +1115,7 @@ where
#[inline] #[inline]
pub fn w() -> Self pub fn w() -> Self
where where
R::Value: Cmp<typenum::U3, Output = Greater>, R::Typenum: Cmp<typenum::U3, Output = Greater>,
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
@ -1128,7 +1129,7 @@ where
#[inline] #[inline]
pub fn a() -> Self pub fn a() -> Self
where where
R::Value: Cmp<typenum::U4, Output = Greater>, R::Typenum: Cmp<typenum::U4, Output = Greater>,
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
@ -1142,7 +1143,7 @@ where
#[inline] #[inline]
pub fn b() -> Self pub fn b() -> Self
where where
R::Value: Cmp<typenum::U5, Output = Greater>, R::Typenum: Cmp<typenum::U5, Output = Greater>,
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
@ -1156,7 +1157,7 @@ where
#[inline] #[inline]
pub fn x_axis() -> Unit<Self> pub fn x_axis() -> Unit<Self>
where where
R::Value: Cmp<typenum::U0, Output = Greater>, R::Typenum: Cmp<typenum::U0, Output = Greater>,
{ {
Unit::new_unchecked(Self::x()) Unit::new_unchecked(Self::x())
} }
@ -1165,7 +1166,7 @@ where
#[inline] #[inline]
pub fn y_axis() -> Unit<Self> pub fn y_axis() -> Unit<Self>
where where
R::Value: Cmp<typenum::U1, Output = Greater>, R::Typenum: Cmp<typenum::U1, Output = Greater>,
{ {
Unit::new_unchecked(Self::y()) Unit::new_unchecked(Self::y())
} }
@ -1174,7 +1175,7 @@ where
#[inline] #[inline]
pub fn z_axis() -> Unit<Self> pub fn z_axis() -> Unit<Self>
where where
R::Value: Cmp<typenum::U2, Output = Greater>, R::Typenum: Cmp<typenum::U2, Output = Greater>,
{ {
Unit::new_unchecked(Self::z()) Unit::new_unchecked(Self::z())
} }
@ -1183,7 +1184,7 @@ where
#[inline] #[inline]
pub fn w_axis() -> Unit<Self> pub fn w_axis() -> Unit<Self>
where where
R::Value: Cmp<typenum::U3, Output = Greater>, R::Typenum: Cmp<typenum::U3, Output = Greater>,
{ {
Unit::new_unchecked(Self::w()) Unit::new_unchecked(Self::w())
} }
@ -1192,7 +1193,7 @@ where
#[inline] #[inline]
pub fn a_axis() -> Unit<Self> pub fn a_axis() -> Unit<Self>
where where
R::Value: Cmp<typenum::U4, Output = Greater>, R::Typenum: Cmp<typenum::U4, Output = Greater>,
{ {
Unit::new_unchecked(Self::a()) Unit::new_unchecked(Self::a())
} }
@ -1201,7 +1202,7 @@ where
#[inline] #[inline]
pub fn b_axis() -> Unit<Self> pub fn b_axis() -> Unit<Self>
where where
R::Value: Cmp<typenum::U5, Output = Greater>, R::Typenum: Cmp<typenum::U5, Output = Greater>,
{ {
Unit::new_unchecked(Self::b()) Unit::new_unchecked(Self::b())
} }

View File

@ -1,4 +1,4 @@
use crate::base::dimension::{Dim, DimName, Dynamic, U1}; use crate::base::dimension::{Const, Dim, DimName, Dynamic};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar}; use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
@ -68,7 +68,9 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
nrows: R, nrows: R,
ncols: C, ncols: C,
) -> Self { ) -> Self {
Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows) Self::from_slice_with_strides_generic_unchecked(
data, start, nrows, ncols, Const::<1>, nrows,
)
} }
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
@ -77,7 +79,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub fn from_slice_generic(data: &'a [N], nrows: R, ncols: C) -> Self { pub fn from_slice_generic(data: &'a [N], nrows: R, ncols: C) -> Self {
Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows) Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
} }
} }
@ -224,7 +226,9 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
nrows: R, nrows: R,
ncols: C, ncols: C,
) -> Self { ) -> Self {
Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows) Self::from_slice_with_strides_generic_unchecked(
data, start, nrows, ncols, Const::<1>, nrows,
)
} }
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
@ -233,7 +237,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub fn from_slice_generic(data: &'a mut [N], nrows: R, ncols: C) -> Self { pub fn from_slice_generic(data: &'a mut [N], nrows: R, ncols: C) -> Self {
Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows) Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
} }
} }

View File

@ -5,10 +5,6 @@ use std::convert::{AsMut, AsRef, From, Into};
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use generic_array::ArrayLength;
use std::ops::Mul;
use typenum::Prod;
use simba::simd::{PrimitiveSimdValue, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::allocator::{Allocator, SameShapeAllocator};
@ -16,7 +12,7 @@ use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstr
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::Dynamic; use crate::base::dimension::Dynamic;
use crate::base::dimension::{ use crate::base::dimension::{
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9, Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
}; };
use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
@ -233,18 +229,16 @@ impl_from_into_asref_2D!(
(U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6); (U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6);
); );
impl<'a, N, R, C, RStride, CStride> From<MatrixSlice<'a, N, R, C, RStride, CStride>>
for Matrix<N, R, C, ArrayStorage<N, R, C>> impl<'a, N, RStride, CStride, const R: usize, const C: usize>
From<MatrixSlice<'a, N, Const<R>, Const<C>, RStride, CStride>>
for Matrix<N, Const<R>, Const<C>, ArrayStorage<N, R, C>>
where where
N: Scalar, N: Scalar,
R: DimName,
C: DimName,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
fn from(matrix_slice: MatrixSlice<'a, N, R, C, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSlice<'a, N, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
@ -277,18 +271,15 @@ where
} }
} }
impl<'a, N, R, C, RStride, CStride> From<MatrixSliceMut<'a, N, R, C, RStride, CStride>> impl<'a, N, RStride, CStride, const R: usize, const C: usize>
for Matrix<N, R, C, ArrayStorage<N, R, C>> From<MatrixSliceMut<'a, N, Const<R>, Const<C>, RStride, CStride>>
for Matrix<N, Const<R>, Const<C>, ArrayStorage<N, R, C>>
where where
N: Scalar, N: Scalar,
R: DimName,
C: DimName,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, N, R, C, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSliceMut<'a, N, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }

View File

@ -5,15 +5,12 @@
use std::cmp; use std::cmp;
use std::mem; use std::mem;
use std::ops::Mul;
use std::ptr; use std::ptr;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec; use alloc::vec::Vec;
use generic_array::ArrayLength; use super::Const;
use typenum::Prod;
use crate::base::allocator::{Allocator, Reallocator}; use crate::base::allocator::{Allocator, Reallocator};
use crate::base::array_storage::ArrayStorage; use crate::base::array_storage::ArrayStorage;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
@ -34,13 +31,8 @@ use crate::base::Scalar;
pub struct DefaultAllocator; pub struct DefaultAllocator;
// Static - Static // Static - Static
impl<N, R, C> Allocator<N, R, C> for DefaultAllocator impl<N: Scalar, const R: usize, const C: usize> Allocator<N, Const<R>, Const<C>>
where for DefaultAllocator
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
type Buffer = ArrayStorage<N, R, C>; type Buffer = ArrayStorage<N, R, C>;
@ -51,8 +43,8 @@ where
#[inline] #[inline]
fn allocate_from_iterator<I: IntoIterator<Item = N>>( fn allocate_from_iterator<I: IntoIterator<Item = N>>(
nrows: R, nrows: Const<R>,
ncols: C, ncols: Const<C>,
iter: I, iter: I,
) -> Self::Buffer { ) -> Self::Buffer {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
@ -61,7 +53,7 @@ where
let mut res = unsafe { Self::allocate_uninitialized(nrows, ncols).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.as_mut_slice().iter_mut().zip(iter.into_iter()) {
*res = e; *res = e;
count += 1; count += 1;
} }
@ -142,20 +134,17 @@ impl<N: Scalar, R: DimName> Allocator<N, R, Dynamic> for DefaultAllocator {
* *
*/ */
// Anything -> Static × Static // Anything -> Static × Static
impl<N: Scalar, RFrom, CFrom, RTo, CTo> Reallocator<N, RFrom, CFrom, RTo, CTo> for DefaultAllocator impl<N: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
Reallocator<N, RFrom, CFrom, Const<RTO>, Const<CTO>> for DefaultAllocator
where where
RFrom: Dim, RFrom: Dim,
CFrom: Dim, CFrom: Dim,
RTo: DimName,
CTo: DimName,
Self: Allocator<N, RFrom, CFrom>, Self: Allocator<N, RFrom, CFrom>,
RTo::Value: Mul<CTo::Value>,
Prod<RTo::Value, CTo::Value>: ArrayLength<N>,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: Const<RTO>,
cto: CTo, cto: Const<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> {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
@ -176,19 +165,16 @@ where
// Static × Static -> Dynamic × Any // Static × Static -> Dynamic × Any
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, RFrom, CFrom, CTo> Reallocator<N, RFrom, CFrom, Dynamic, CTo> for DefaultAllocator impl<N: Scalar, CTo, const RFROM: usize, const CFROM: usize>
Reallocator<N, Const<RFROM>, Const<CFROM>, Dynamic, CTo> for DefaultAllocator
where where
RFrom: DimName,
CFrom: DimName,
CTo: Dim, CTo: Dim,
RFrom::Value: Mul<CFrom::Value>,
Prod<RFrom::Value, CFrom::Value>: ArrayLength<N>,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: ArrayStorage<N, RFrom, CFrom>, buf: ArrayStorage<N, RFROM, CFROM>,
) -> VecStorage<N, Dynamic, CTo> { ) -> VecStorage<N, Dynamic, CTo> {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
let mut res: VecStorage<N, Dynamic, CTo> = unimplemented!(); let mut res: VecStorage<N, Dynamic, CTo> = unimplemented!();
@ -208,19 +194,16 @@ where
// Static × Static -> Static × Dynamic // Static × Static -> Static × Dynamic
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, RFrom, CFrom, RTo> Reallocator<N, RFrom, CFrom, RTo, Dynamic> for DefaultAllocator impl<N: Scalar, RTo, const RFROM: usize, const CFROM: usize>
Reallocator<N, Const<RFROM>, Const<CFROM>, RTo, Dynamic> for DefaultAllocator
where where
RFrom: DimName,
CFrom: DimName,
RTo: DimName, RTo: DimName,
RFrom::Value: Mul<CFrom::Value>,
Prod<RFrom::Value, CFrom::Value>: ArrayLength<N>,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: ArrayStorage<N, RFrom, CFrom>, buf: ArrayStorage<N, RFROM, CFROM>,
) -> VecStorage<N, RTo, Dynamic> { ) -> VecStorage<N, RTo, Dynamic> {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
let mut res: VecStorage<N, RTo, Dynamic> = unimplemented!(); let mut res: VecStorage<N, RTo, Dynamic> = unimplemented!();

View File

@ -6,9 +6,7 @@ use std::any::{Any, TypeId};
use std::cmp; use std::cmp;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
use typenum::{ use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};
self, Bit, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, UInt, UTerm, Unsigned, B1,
};
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
@ -130,13 +128,17 @@ macro_rules! dim_ops(
fn $op(self, other: D) -> Self::Output; fn $op(self, other: D) -> Self::Output;
} }
impl<D1: DimName, D2: DimName> $DimOp<D2> for D1 impl<const A: usize, const B: usize> $DimOp<Const<B>> for Const<A>
where D1::Value: $Op<D2::Value>, where
$ResOp<D1::Value, D2::Value>: NamedDim { Const<A>: ToTypenum,
type Output = <$ResOp<D1::Value, D2::Value> as NamedDim>::Name; Const<B>: ToTypenum,
<Const<A> as ToTypenum>::Typenum: $Op<<Const<B> as ToTypenum>::Typenum>,
$ResOp<<Const<A> as ToTypenum>::Typenum, <Const<B> as ToTypenum>::Typenum>: ToConst,
{
type Output =
<$ResOp<<Const<A> as ToTypenum>::Typenum, <Const<B> as ToTypenum>::Typenum> as ToConst>::Const;
#[inline] fn $op(self, _: Const<B>) -> Self::Output {
fn $op(self, _: D2) -> Self::Output {
Self::Output::name() Self::Output::name()
} }
} }
@ -150,6 +152,7 @@ macro_rules! dim_ops(
} }
} }
// TODO: use Const<T> instead of D: DimName?
impl<D: DimName> $DimOp<Dynamic> for D { impl<D: DimName> $DimOp<Dynamic> for D {
type Output = Dynamic; type Output = Dynamic;
@ -167,13 +170,17 @@ macro_rules! dim_ops(
fn $op(self, other: D) -> Self::Output; fn $op(self, other: D) -> Self::Output;
} }
impl<D1: DimName, D2: DimName> $DimNameOp<D2> for D1 impl<const A: usize, const B: usize> $DimNameOp<Const<B>> for Const<A>
where D1::Value: $Op<D2::Value>, where
$ResOp<D1::Value, D2::Value>: NamedDim { Const<A>: ToTypenum,
type Output = <$ResOp<D1::Value, D2::Value> as NamedDim>::Name; Const<B>: ToTypenum,
<Const<A> as ToTypenum>::Typenum: $Op<<Const<B> as ToTypenum>::Typenum>,
$ResOp<<Const<A> as ToTypenum>::Typenum, <Const<B> as ToTypenum>::Typenum>: ToConst,
{
type Output =
<$ResOp<<Const<A> as ToTypenum>::Typenum, <Const<B> as ToTypenum>::Typenum> as ToConst>::Const;
#[inline] fn $op(self, _: Const<B>) -> Self::Output {
fn $op(self, _: D2) -> Self::Output {
Self::Output::name() Self::Output::name()
} }
} }
@ -189,105 +196,81 @@ dim_ops!(
DimMax, DimNameMax, Max, max, cmp::max, DimMaximum, DimNameMaximum, Maximum; DimMax, DimNameMax, Max, max, cmp::max, DimMaximum, DimNameMaximum, Maximum;
); );
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Const<const R: usize>;
/// Trait implemented exclusively by type-level integers. /// Trait implemented exclusively by type-level integers.
pub trait DimName: Dim { pub trait DimName: Dim {
type Value: NamedDim<Name = Self>;
/// The name of this dimension, i.e., the singleton `Self`. /// The name of this dimension, i.e., the singleton `Self`.
fn name() -> Self; fn name() -> Self;
// TODO: this is not a very idiomatic name. // TODO: this is not a very idiomatic name.
/// The value of this dimension. /// The value of this dimension.
#[inline] fn dim() -> usize;
fn dim() -> usize {
Self::Value::to_usize()
}
} }
pub trait NamedDim: Sized + Any + Unsigned { pub trait ToConst {
type Name: DimName<Value = Self>; type Const: DimName;
} }
/// A type level dimension with a value of `1`. pub trait ToTypenum {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] type Typenum: Unsigned;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] }
pub struct U1;
impl Dim for U1 { impl<const T: usize> Dim for Const<T> {
#[inline]
fn try_to_usize() -> Option<usize> { fn try_to_usize() -> Option<usize> {
Some(1) Some(T)
} }
#[inline]
fn from_usize(dim: usize) -> Self {
assert!(dim == 1, "Mismatched dimension.");
U1
}
#[inline]
fn value(&self) -> usize { fn value(&self) -> usize {
1 T
}
fn from_usize(dim: usize) -> Self {
assert_eq!(dim, T);
Self
} }
} }
impl DimName for U1 { impl<const T: usize> DimName for Const<T> {
type Value = typenum::U1;
#[inline] #[inline]
fn name() -> Self { fn name() -> Self {
U1 Self
}
#[inline]
fn dim() -> usize {
T
} }
} }
impl NamedDim for typenum::U1 { pub type U1 = Const<1>;
type Name = U1;
impl ToTypenum for Const<{ typenum::U1::USIZE }> {
type Typenum = typenum::U1;
} }
macro_rules! named_dimension ( impl ToConst for typenum::U1 {
type Const = Const<{ typenum::U1::USIZE }>;
}
macro_rules! from_to_typenum (
($($D: ident),* $(,)*) => {$( ($($D: ident),* $(,)*) => {$(
/// A type level dimension. pub type $D = Const<{ typenum::$D::USIZE }>;
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct $D;
impl Dim for $D { impl ToTypenum for Const<{ typenum::$D::USIZE }> {
#[inline] type Typenum = typenum::$D;
fn try_to_usize() -> Option<usize> {
Some(typenum::$D::to_usize())
}
#[inline]
fn from_usize(dim: usize) -> Self {
assert!(dim == typenum::$D::to_usize(), "Mismatched dimension.");
$D
}
#[inline]
fn value(&self) -> usize {
typenum::$D::to_usize()
}
} }
impl DimName for $D { impl ToConst for typenum::$D {
type Value = typenum::$D; type Const = Const<{ typenum::$D::USIZE }>;
#[inline]
fn name() -> Self {
$D
}
}
impl NamedDim for typenum::$D {
type Name = $D;
} }
impl IsNotStaticOne for $D { } impl IsNotStaticOne for $D { }
)*} )*}
); );
// We give explicit names to all Unsigned in [0, 128[ from_to_typenum!(
named_dimension!(
U0, /*U1,*/ U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U0, /*U1,*/ U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18,
U19, U20, U21, U22, U23, U24, U25, U26, U27, U28, U29, U30, U31, U32, U33, U34, U35, U36, U37, U19, U20, U21, U22, U23, U24, U25, U26, U27, U28, U29, U30, U31, U32, U33, U34, U35, U36, U37,
U38, U39, U40, U41, U42, U43, U44, U45, U46, U47, U48, U49, U50, U51, U52, U53, U54, U55, U56, U38, U39, U40, U41, U42, U43, U44, U45, U46, U47, U48, U49, U50, U51, U52, U53, U54, U55, U56,
@ -297,117 +280,3 @@ named_dimension!(
U111, U112, U113, U114, U115, U116, U117, U118, U119, U120, U121, U122, U123, U124, U125, U126, U111, U112, U113, U114, U115, U116, U117, U118, U119, U120, U121, U122, U123, U124, U125, U126,
U127 U127
); );
// For values greater than U1023, just use the typenum binary representation directly.
impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
> NamedDim for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
type Name = Self;
}
impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
> Dim for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
#[inline]
fn try_to_usize() -> Option<usize> {
Some(Self::to_usize())
}
#[inline]
fn from_usize(dim: usize) -> Self {
assert!(dim == Self::to_usize(), "Mismatched dimension.");
Self::new()
}
#[inline]
fn value(&self) -> usize {
Self::to_usize()
}
}
impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
> DimName for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
type Value = Self;
#[inline]
fn name() -> Self {
Self::new()
}
}
impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
> IsNotStaticOne
for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
}
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> NamedDim
for UInt<U, B>
{
type Name = UInt<U, B>;
}
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> Dim
for UInt<U, B>
{
#[inline]
fn try_to_usize() -> Option<usize> {
Some(Self::to_usize())
}
#[inline]
fn from_usize(dim: usize) -> Self {
assert!(dim == Self::to_usize(), "Mismatched dimension.");
Self::new()
}
#[inline]
fn value(&self) -> usize {
Self::to_usize()
}
}
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> DimName
for UInt<U, B>
{
type Value = UInt<U, B>;
#[inline]
fn name() -> Self {
Self::new()
}
}
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> IsNotStaticOne
for UInt<U, B>
{
}

View File

@ -831,7 +831,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # use nalgebra::{Matrix3x2, Matrix2x3, DMatrix, U2, U3, Dynamic}; /// # use nalgebra::{Matrix3x2, Matrix2x3, DMatrix, Const, Dynamic};
/// ///
/// let m1 = Matrix2x3::new( /// let m1 = Matrix2x3::new(
/// 1.1, 1.2, 1.3, /// 1.1, 1.2, 1.3,
@ -842,7 +842,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// 2.1, 1.3, /// 2.1, 1.3,
/// 1.2, 2.3 /// 1.2, 2.3
/// ); /// );
/// let reshaped = m1.reshape_generic(U3, U2); /// let reshaped = m1.reshape_generic(Const::<3>, Const::<2>);
/// assert_eq!(reshaped, m2); /// assert_eq!(reshaped, m2);
/// ///
/// let dm1 = DMatrix::from_row_slice( /// let dm1 = DMatrix::from_row_slice(

View File

@ -2,7 +2,7 @@
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{ use crate::base::{
Dim, DimDiff, DimName, DimSub, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1, Const, Dim, DimDiff, DimName, DimSub, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1,
}; };
use std::ops; use std::ops;
@ -32,7 +32,7 @@ impl<D: Dim> DimRange<D> for usize {
#[inline(always)] #[inline(always)]
fn length(&self, _: D) -> Self::Length { fn length(&self, _: D) -> Self::Length {
U1 Const::<1>
} }
#[inline(always)] #[inline(always)]
@ -43,9 +43,8 @@ impl<D: Dim> DimRange<D> for usize {
#[test] #[test]
fn dimrange_usize() { fn dimrange_usize() {
use crate::base::dimension::U0; assert_eq!(DimRange::contained_by(&0, Const::<0>), false);
assert_eq!(DimRange::contained_by(&0, U0), false); assert_eq!(DimRange::contained_by(&0, Const::<1>), true);
assert_eq!(DimRange::contained_by(&0, U1), true);
} }
impl<D: Dim> DimRange<D> for ops::Range<usize> { impl<D: Dim> DimRange<D> for ops::Range<usize> {
@ -69,11 +68,10 @@ impl<D: Dim> DimRange<D> for ops::Range<usize> {
#[test] #[test]
fn dimrange_range_usize() { fn dimrange_range_usize() {
use crate::base::dimension::U0;
use std::usize::MAX; use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(0..0), U0), false); assert_eq!(DimRange::contained_by(&(0..0), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(0..1), U0), false); assert_eq!(DimRange::contained_by(&(0..1), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(0..1), U1), true); assert_eq!(DimRange::contained_by(&(0..1), Const::<1>), true);
assert_eq!( assert_eq!(
DimRange::contained_by(&((MAX - 1)..MAX), Dynamic::new(MAX)), DimRange::contained_by(&((MAX - 1)..MAX), Dynamic::new(MAX)),
true true
@ -113,11 +111,10 @@ impl<D: Dim> DimRange<D> for ops::RangeFrom<usize> {
#[test] #[test]
fn dimrange_rangefrom_usize() { fn dimrange_rangefrom_usize() {
use crate::base::dimension::U0;
use std::usize::MAX; use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(0..), U0), false); assert_eq!(DimRange::contained_by(&(0..), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(0..), U0), false); assert_eq!(DimRange::contained_by(&(0..), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(0..), U1), true); assert_eq!(DimRange::contained_by(&(0..), Const::<1>), true);
assert_eq!( assert_eq!(
DimRange::contained_by(&((MAX - 1)..), Dynamic::new(MAX)), DimRange::contained_by(&((MAX - 1)..), Dynamic::new(MAX)),
true true
@ -156,8 +153,7 @@ where
#[test] #[test]
fn dimrange_rangefrom_dimname() { fn dimrange_rangefrom_dimname() {
use crate::base::dimension::{U4, U5}; assert_eq!(DimRange::length(&(Const::<1>..), Const::<5>), Const::<4>);
assert_eq!(DimRange::length(&(U1..), U5), U4);
} }
impl<D: Dim> DimRange<D> for ops::RangeFull { impl<D: Dim> DimRange<D> for ops::RangeFull {
@ -181,9 +177,8 @@ impl<D: Dim> DimRange<D> for ops::RangeFull {
#[test] #[test]
fn dimrange_rangefull() { fn dimrange_rangefull() {
use crate::base::dimension::U0; assert_eq!(DimRange::contained_by(&(..), Const::<0>), true);
assert_eq!(DimRange::contained_by(&(..), U0), true); assert_eq!(DimRange::length(&(..), Const::<1>), Const::<1>);
assert_eq!(DimRange::length(&(..), U1), U1);
} }
impl<D: Dim> DimRange<D> for ops::RangeInclusive<usize> { impl<D: Dim> DimRange<D> for ops::RangeInclusive<usize> {
@ -211,10 +206,9 @@ impl<D: Dim> DimRange<D> for ops::RangeInclusive<usize> {
#[test] #[test]
fn dimrange_rangeinclusive_usize() { fn dimrange_rangeinclusive_usize() {
use crate::base::dimension::U0;
use std::usize::MAX; use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(0..=0), U0), false); assert_eq!(DimRange::contained_by(&(0..=0), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(0..=0), U1), true); assert_eq!(DimRange::contained_by(&(0..=0), Const::<1>), true);
assert_eq!( assert_eq!(
DimRange::contained_by(&(MAX..=MAX), Dynamic::new(MAX)), DimRange::contained_by(&(MAX..=MAX), Dynamic::new(MAX)),
false false
@ -227,7 +221,7 @@ fn dimrange_rangeinclusive_usize() {
DimRange::contained_by(&((MAX - 1)..=(MAX - 1)), Dynamic::new(MAX)), DimRange::contained_by(&((MAX - 1)..=(MAX - 1)), Dynamic::new(MAX)),
true true
); );
assert_eq!(DimRange::length(&(0..=0), U1), Dynamic::new(1)); assert_eq!(DimRange::length(&(0..=0), Const::<1>), Dynamic::new(1));
assert_eq!( assert_eq!(
DimRange::length(&((MAX - 1)..=MAX), Dynamic::new(MAX)), DimRange::length(&((MAX - 1)..=MAX), Dynamic::new(MAX)),
Dynamic::new(2) Dynamic::new(2)
@ -263,11 +257,10 @@ impl<D: Dim> DimRange<D> for ops::RangeTo<usize> {
#[test] #[test]
fn dimrange_rangeto_usize() { fn dimrange_rangeto_usize() {
use crate::base::dimension::U0;
use std::usize::MAX; use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(..0), U0), true); assert_eq!(DimRange::contained_by(&(..0), Const::<0>), true);
assert_eq!(DimRange::contained_by(&(..1), U0), false); assert_eq!(DimRange::contained_by(&(..1), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(..0), U1), true); assert_eq!(DimRange::contained_by(&(..0), Const::<1>), true);
assert_eq!( assert_eq!(
DimRange::contained_by(&(..(MAX - 1)), Dynamic::new(MAX)), DimRange::contained_by(&(..(MAX - 1)), Dynamic::new(MAX)),
true true
@ -303,11 +296,10 @@ impl<D: Dim> DimRange<D> for ops::RangeToInclusive<usize> {
#[test] #[test]
fn dimrange_rangetoinclusive_usize() { fn dimrange_rangetoinclusive_usize() {
use crate::base::dimension::U0;
use std::usize::MAX; use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(..=0), U0), false); assert_eq!(DimRange::contained_by(&(..=0), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(..=1), U0), false); assert_eq!(DimRange::contained_by(&(..=1), Const::<0>), false);
assert_eq!(DimRange::contained_by(&(..=0), U1), true); assert_eq!(DimRange::contained_by(&(..=0), Const::<1>), true);
assert_eq!( assert_eq!(
DimRange::contained_by(&(..=(MAX)), Dynamic::new(MAX)), DimRange::contained_by(&(..=(MAX)), Dynamic::new(MAX)),
false false
@ -461,7 +453,7 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
/// .eq(&Matrix2x1::new(0, /// .eq(&Matrix2x1::new(0,
/// 1))); /// 1)));
/// ///
/// assert!(matrix.index((U1.., 0)) /// assert!(matrix.index((Const::<1>.., 0))
/// .eq(&Matrix2x1::new(1, /// .eq(&Matrix2x1::new(1,
/// 2))); /// 2)));
/// ``` /// ```

View File

@ -28,7 +28,7 @@ use crate::base::iter::{
use crate::base::storage::{ use crate::base::storage::{
ContiguousStorage, ContiguousStorageMut, Owned, SameShapeStorage, Storage, StorageMut, ContiguousStorage, ContiguousStorageMut, Owned, SameShapeStorage, Storage, StorageMut,
}; };
use crate::base::{DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN}; use crate::base::{Const, DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN};
use crate::SimdComplexField; use crate::SimdComplexField;
/// A square matrix. /// A square matrix.
@ -1365,7 +1365,7 @@ 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: VectorN<N2, D> = let mut res: VectorN<N2, D> =
unsafe { crate::unimplemented_or_uninitialized_generic!(dim, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(dim, Const::<1>) };
for i in 0..dim.value() { for i in 0..dim.value() {
unsafe { unsafe {
@ -1476,7 +1476,7 @@ impl<N: Scalar + Zero, D: DimAdd<U1>, S: Storage<N, D>> Vector<N, D, S> {
{ {
if v[v.len() - 1].is_zero() { if v[v.len() - 1].is_zero() {
let nrows = D::from_usize(v.len() - 1); let nrows = D::from_usize(v.len() - 1);
Some(v.generic_slice((0, 0), (nrows, U1)).into_owned()) Some(v.generic_slice((0, 0), (nrows, Const::<1>)).into_owned())
} else { } else {
None None
} }
@ -1493,7 +1493,7 @@ 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: VectorN<N, _> = let mut res: VectorN<N, _> =
unsafe { crate::unimplemented_or_uninitialized_generic!(hnrows, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(hnrows, Const::<1>) };
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;

View File

@ -4,7 +4,7 @@ use std::slice;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator; use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Dim, DimName, Dynamic, IsNotStaticOne, U1}; use crate::base::dimension::{Const, Dim, DimName, Dynamic, IsNotStaticOne, U1};
use crate::base::iter::MatrixIter; use crate::base::iter::MatrixIter;
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
use crate::base::{Matrix, Scalar}; use crate::base::{Matrix, Scalar};
@ -288,7 +288,7 @@ macro_rules! matrix_slice_impl(
/// Returns a slice containing the `n` first elements of the i-th row of this matrix. /// Returns a slice containing the `n` first elements of the i-th row of this matrix.
#[inline] #[inline]
pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<N, U1, Dynamic, S::RStride, S::CStride> { pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<N, U1, Dynamic, S::RStride, S::CStride> {
$me.$generic_slice((i, 0), (U1, Dynamic::new(n))) $me.$generic_slice((i, 0), (Const::<1>, Dynamic::new(n)))
} }
/// Extracts from this matrix a set of consecutive rows. /// Extracts from this matrix a set of consecutive rows.
@ -375,7 +375,7 @@ macro_rules! matrix_slice_impl(
/// Returns a slice containing the `n` first elements of the i-th column of this matrix. /// Returns a slice containing the `n` first elements of the i-th column of this matrix.
#[inline] #[inline]
pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<N, Dynamic, U1, S::RStride, S::CStride> { pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<N, Dynamic, U1, S::RStride, S::CStride> {
$me.$generic_slice((0, i), (Dynamic::new(n), U1)) $me.$generic_slice((0, i), (Dynamic::new(n), Const::<1>))
} }
/// Extracts from this matrix a set of consecutive columns. /// Extracts from this matrix a set of consecutive columns.
@ -730,7 +730,7 @@ impl<D: Dim> SliceRange<D> for usize {
#[inline(always)] #[inline(always)]
fn size(&self, _: D) -> Self::Size { fn size(&self, _: D) -> Self::Size {
U1 Const::<1>
} }
} }

View File

@ -1,6 +1,6 @@
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::storage::Storage; use crate::storage::Storage;
use crate::{DefaultAllocator, Dim, Matrix, RowVectorN, Scalar, VectorN, VectorSliceN, U1}; use crate::{Const, DefaultAllocator, Dim, Matrix, RowVectorN, Scalar, VectorN, VectorSliceN, U1};
use num::Zero; use num::Zero;
use simba::scalar::{ClosedAdd, Field, SupersetOf}; use simba::scalar::{ClosedAdd, Field, SupersetOf};
@ -18,7 +18,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res: RowVectorN<N, C> = let mut res: RowVectorN<N, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(U1, ncols) }; unsafe { crate::unimplemented_or_uninitialized_generic!(Const::<1>, 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.
@ -44,7 +44,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res: VectorN<N, C> = let mut res: VectorN<N, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
for i in 0..ncols.value() { for i in 0..ncols.value() {
// TODO: avoid bound checking of column. // TODO: avoid bound checking of column.
@ -174,7 +174,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<N, R>,
{ {
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
self.compress_columns(VectorN::zeros_generic(nrows, U1), |out, col| { self.compress_columns(VectorN::zeros_generic(nrows, Const::<1>), |out, col| {
*out += col; *out += col;
}) })
} }
@ -378,7 +378,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();
let denom = N::one() / crate::convert::<_, N>(ncols.value() as f64); let denom = N::one() / crate::convert::<_, N>(ncols.value() as f64);
self.compress_columns(VectorN::zeros_generic(nrows, U1), |out, col| { self.compress_columns(VectorN::zeros_generic(nrows, Const::<1>), |out, col| {
out.axpy(denom.inlined_clone(), &col, N::one()) out.axpy(denom.inlined_clone(), &col, N::one())
}) })
} }

View File

@ -1,4 +1,4 @@
use crate::base::{DimName, Scalar, Vector, Vector2, Vector3}; use crate::base::{DimName, Scalar, ToTypenum, Vector, Vector2, Vector3};
use crate::storage::Storage; use crate::storage::Storage;
use typenum::{self, Cmp, Greater}; use typenum::{self, Cmp, Greater};
@ -9,7 +9,7 @@ macro_rules! impl_swizzle {
/// Builds a new vector from components of `self`. /// Builds a new vector from components of `self`.
#[inline] #[inline]
pub fn $name(&self) -> $Result<N> pub fn $name(&self) -> $Result<N>
where D::Value: Cmp<typenum::$BaseDim, Output=Greater> { where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
$Result::new($(self[$i].inlined_clone()),*) $Result::new($(self[$i].inlined_clone()),*)
} }
)* )*
@ -18,7 +18,10 @@ macro_rules! impl_swizzle {
} }
/// # Swizzling /// # Swizzling
impl<N: Scalar, D: DimName, S: Storage<N, D>> Vector<N, D, S> { impl<N: Scalar, D, S: Storage<N, D>> Vector<N, D, S>
where
D: DimName + ToTypenum,
{
impl_swizzle!( impl_swizzle!(
where U0: xx() -> Vector2[0, 0], where U0: xx() -> Vector2[0, 0],
xxx() -> Vector3[0, 0, 0]; xxx() -> Vector3[0, 0, 0];

View File

@ -1,5 +1,5 @@
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::{DefaultAllocator, DimName, Scalar}; use crate::base::{DefaultAllocator, DimName, Scalar, ToTypenum};
use crate::geometry::{Point, Point2, Point3}; use crate::geometry::{Point, Point2, Point3};
use typenum::{self, Cmp, Greater}; use typenum::{self, Cmp, Greater};
@ -10,7 +10,7 @@ macro_rules! impl_swizzle {
/// Builds a new point from components of `self`. /// Builds a new point from components of `self`.
#[inline] #[inline]
pub fn $name(&self) -> $Result<N> pub fn $name(&self) -> $Result<N>
where D::Value: Cmp<typenum::$BaseDim, Output=Greater> { where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
$Result::new($(self[$i].inlined_clone()),*) $Result::new($(self[$i].inlined_clone()),*)
} }
)* )*
@ -19,8 +19,9 @@ macro_rules! impl_swizzle {
} }
/// # Swizzling /// # Swizzling
impl<N: Scalar, D: DimName> Point<N, D> impl<N: Scalar, D> Point<N, D>
where where
D: DimName + ToTypenum,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
{ {
impl_swizzle!( impl_swizzle!(

View File

@ -80,7 +80,7 @@ an optimized set of tools for computer graphics and physics. Those features incl
#![deny(non_upper_case_globals)] #![deny(non_upper_case_globals)]
#![deny(unused_qualifications)] #![deny(unused_qualifications)]
#![deny(unused_results)] #![deny(unused_results)]
#![deny(missing_docs)] // #![deny(missing_docs)]
#![doc( #![doc(
html_favicon_url = "https://nalgebra.org/img/favicon.ico", html_favicon_url = "https://nalgebra.org/img/favicon.ico",
html_root_url = "https://docs.rs/nalgebra/0.25.0" html_root_url = "https://docs.rs/nalgebra/0.25.0"

View File

@ -4,9 +4,9 @@ use simba::scalar::RealField;
use std::ops::{DivAssign, MulAssign}; use std::ops::{DivAssign, MulAssign};
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::dimension::{Dim, U1}; use crate::base::dimension::Dim;
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, MatrixN, VectorN}; use crate::base::{Const, DefaultAllocator, MatrixN, VectorN};
/// Applies in-place a modified Parlett and Reinsch matrix balancing with 2-norm to the matrix `m` and returns /// Applies in-place a modified Parlett and Reinsch matrix balancing with 2-norm to the matrix `m` and returns
/// the corresponding diagonal transformation. /// the corresponding diagonal transformation.
@ -20,7 +20,7 @@ where
let dim = m.data.shape().0; let dim = m.data.shape().0;
let radix: N = crate::convert(2.0f64); let radix: N = crate::convert(2.0f64);
let mut d = VectorN::from_element_generic(dim, U1, N::one()); let mut d = VectorN::from_element_generic(dim, Const::<1>, N::one());
let mut converged = false; let mut converged = false;

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Unit, VectorN}; use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Unit, VectorN};
use crate::dimension::{Dim, DimDiff, DimMin, DimMinimum, DimSub, U1}; use crate::dimension::{Const, Dim, DimDiff, DimMin, DimMinimum, DimSub, U1};
use crate::storage::Storage; use crate::storage::Storage;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -82,11 +82,11 @@ where
); );
let mut diagonal = let mut diagonal =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, Const::<1>) };
let mut off_diagonal = let mut off_diagonal =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols.sub(U1), U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols.sub(Const::<1>), Const::<1>) };
let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) }; let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, U1) }; let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, Const::<1>) };
let upper_diagonal = nrows.value() >= ncols.value(); let upper_diagonal = nrows.value() >= ncols.value();
if upper_diagonal { if upper_diagonal {
@ -241,8 +241,8 @@ where
let mut res = Matrix::identity_generic(min_nrows_ncols, ncols); let mut res = Matrix::identity_generic(min_nrows_ncols, ncols);
let mut work = let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, Const::<1>) };
let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) }; let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
let shift = self.axis_shift().1; let shift = self.axis_shift().1;

View File

@ -6,7 +6,7 @@ use simba::scalar::ComplexField;
use simba::simd::SimdComplexField; use simba::simd::SimdComplexField;
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Vector}; use crate::base::{Const, DefaultAllocator, Matrix, MatrixMN, MatrixN, Vector};
use crate::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::dimension::{Dim, DimAdd, DimDiff, DimSub, DimSum, U1}; use crate::dimension::{Dim, DimAdd, DimDiff, DimSub, DimSum, U1};
use crate::storage::{Storage, StorageMut}; use crate::storage::{Storage, StorageMut};
@ -234,8 +234,8 @@ 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 {
crate::unimplemented_or_uninitialized_generic!( crate::unimplemented_or_uninitialized_generic!(
self.chol.data.shape().0.add(U1), self.chol.data.shape().0.add(Const::<1>),
self.chol.data.shape().1.add(U1) self.chol.data.shape().1.add(Const::<1>)
) )
}; };
chol.slice_range_mut(..j, ..j) chol.slice_range_mut(..j, ..j)
@ -299,8 +299,8 @@ 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 {
crate::unimplemented_or_uninitialized_generic!( crate::unimplemented_or_uninitialized_generic!(
self.chol.data.shape().0.sub(U1), self.chol.data.shape().0.sub(Const::<1>),
self.chol.data.shape().1.sub(U1) self.chol.data.shape().1.sub(Const::<1>)
) )
}; };
chol.slice_range_mut(..j, ..j) chol.slice_range_mut(..j, ..j)

View File

@ -2,7 +2,7 @@ use std::cmp;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator; use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Dim, DimAdd, DimDiff, DimSub, DimSum}; use crate::base::dimension::{Const, Dim, DimAdd, DimDiff, DimSub, DimSum};
use crate::storage::Storage; use crate::storage::Storage;
use crate::{zero, RealField, Vector, VectorN, U1}; use crate::{zero, RealField, Vector, VectorN, U1};
@ -31,11 +31,16 @@ impl<N: RealField, D1: Dim, S1: Storage<N, D1>> Vector<N, D1, S1> {
let ker = kernel.len(); let ker = kernel.len();
if ker == 0 || ker > vec { if ker == 0 || ker > vec {
panic!("convolve_full expects `self.len() >= kernel.len() > 0`, received {} and {} respectively.",vec,ker); panic!("convolve_full expects `self.len() >= kernel.len() > 0`, received {} and {} respectively.", vec, ker);
} }
let result_len = self.data.shape().0.add(kernel.data.shape().0).sub(U1); let result_len = self
let mut conv = VectorN::zeros_generic(result_len, U1); .data
.shape()
.0
.add(kernel.data.shape().0)
.sub(Const::<1>);
let mut conv = VectorN::zeros_generic(result_len, Const::<1>);
for i in 0..(vec + ker - 1) { for i in 0..(vec + ker - 1) {
let u_i = if i > vec { i - ker } else { 0 }; let u_i = if i > vec { i - ker } else { 0 };
@ -82,8 +87,13 @@ impl<N: RealField, D1: Dim, S1: Storage<N, D1>> Vector<N, D1, S1> {
panic!("convolve_valid expects `self.len() >= kernel.len() > 0`, received {} and {} respectively.",vec,ker); panic!("convolve_valid expects `self.len() >= kernel.len() > 0`, received {} and {} respectively.",vec,ker);
} }
let result_len = self.data.shape().0.add(U1).sub(kernel.data.shape().0); let result_len = self
let mut conv = VectorN::zeros_generic(result_len, U1); .data
.shape()
.0
.add(Const::<1>)
.sub(kernel.data.shape().0);
let mut conv = VectorN::zeros_generic(result_len, Const::<1>);
for i in 0..(vec - ker + 1) { for i in 0..(vec - ker + 1) {
for j in 0..ker { for j in 0..ker {
@ -115,7 +125,7 @@ impl<N: RealField, D1: Dim, S1: Storage<N, D1>> Vector<N, D1, S1> {
panic!("convolve_same expects `self.len() >= kernel.len() > 0`, received {} and {} respectively.",vec,ker); panic!("convolve_same expects `self.len() >= kernel.len() > 0`, received {} and {} respectively.",vec,ker);
} }
let mut conv = VectorN::zeros_generic(self.data.shape().0, U1); let mut conv = VectorN::zeros_generic(self.data.shape().0, Const::<1>);
for i in 0..vec { for i in 0..vec {
for j in 0..ker { for j in 0..ker {

View File

@ -3,7 +3,7 @@
use crate::{ use crate::{
base::{ base::{
allocator::Allocator, allocator::Allocator,
dimension::{Dim, DimMin, DimMinimum, U1}, dimension::{Const, Dim, DimMin, DimMinimum},
storage::Storage, storage::Storage,
DefaultAllocator, DefaultAllocator,
}, },
@ -349,7 +349,7 @@ where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
let nrows = a.data.shape().0; let nrows = a.data.shape().0;
let mut v = crate::VectorN::<N, D>::repeat_generic(nrows, U1, convert(1.0)); let mut v = crate::VectorN::<N, D>::repeat_generic(nrows, Const::<1>, convert(1.0));
let m = a.transpose(); let m = a.transpose();
for _ in 0..p { for _ in 0..p {

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, MatrixN, VectorN}; use crate::base::{DefaultAllocator, MatrixN, VectorN};
use crate::dimension::{DimDiff, DimSub, U1}; use crate::dimension::{Const, DimDiff, DimSub, U1};
use crate::storage::Storage; use crate::storage::Storage;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -49,7 +49,7 @@ 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 = let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(hess.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(hess.data.shape().0, Const::<1>) };
Self::new_with_workspace(hess, &mut work) Self::new_with_workspace(hess, &mut work)
} }
@ -76,7 +76,7 @@ where
); );
let mut subdiag = let mut subdiag =
unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(Const::<1>), Const::<1>) };
if dim.value() == 0 { if dim.value() == 0 {
return Hessenberg { hess, subdiag }; return Hessenberg { hess, subdiag };

View File

@ -8,7 +8,7 @@ use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN}; use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::dimension::Dynamic; use crate::dimension::Dynamic;
use crate::dimension::{Dim, DimName, U1}; use crate::dimension::{Const, Dim, DimName};
use crate::storage::StorageMut; use crate::storage::StorageMut;
/// A sequence of row or column permutations. /// A sequence of row or column permutations.
@ -72,7 +72,7 @@ where
unsafe { unsafe {
Self { Self {
len: 0, len: 0,
ipiv: crate::unimplemented_or_uninitialized_generic!(dim, U1), ipiv: crate::unimplemented_or_uninitialized_generic!(dim, Const::<1>),
} }
} }
} }

View File

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::allocator::{Allocator, Reallocator}; use crate::allocator::{Allocator, Reallocator};
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Unit, VectorN}; use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Unit, VectorN};
use crate::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::dimension::{Dim, DimMin, DimMinimum, U1}; use crate::dimension::{Const, Dim, DimMin, DimMinimum};
use crate::storage::{Storage, StorageMut}; use crate::storage::{Storage, StorageMut};
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -55,7 +55,7 @@ where
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
let mut diag = let mut diag =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, Const::<1>) };
if min_nrows_ncols.value() == 0 { if min_nrows_ncols.value() == 0 {
return QR { qr: matrix, diag }; return QR { qr: matrix, diag };

View File

@ -7,7 +7,7 @@ use simba::scalar::{ComplexField, RealField};
use std::cmp; use std::cmp;
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::dimension::{Dim, DimDiff, DimSub, Dynamic, U1, U2, U3}; use crate::base::dimension::{Const, Dim, DimDiff, DimSub, Dynamic, U1, U2};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, MatrixN, SquareMatrix, Unit, Vector2, Vector3, VectorN}; use crate::base::{DefaultAllocator, MatrixN, SquareMatrix, Unit, Vector2, Vector3, VectorN};
@ -72,7 +72,7 @@ where
/// 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 = let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, Const::<1>) };
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 })
@ -172,18 +172,21 @@ where
{ {
let krows = cmp::min(k + 4, end + 1); let krows = cmp::min(k + 4, end + 1);
let mut work = work.rows_mut(0, krows); let mut work = work.rows_mut(0, krows);
refl.reflect( refl.reflect(&mut t.generic_slice_mut(
&mut t (k, k),
.generic_slice_mut((k, k), (U3, Dynamic::new(dim.value() - k))), (Const::<3>, Dynamic::new(dim.value() - k)),
); ));
refl.reflect_rows( refl.reflect_rows(
&mut t.generic_slice_mut((0, k), (Dynamic::new(krows), U3)), &mut t.generic_slice_mut((0, k), (Dynamic::new(krows), Const::<3>)),
&mut work, &mut work,
); );
} }
if let Some(ref mut q) = q { if let Some(ref mut q) = q {
refl.reflect_rows(&mut q.generic_slice_mut((0, k), (dim, U3)), work); refl.reflect_rows(
&mut q.generic_slice_mut((0, k), (dim, Const::<3>)),
work,
);
} }
} }
@ -206,17 +209,21 @@ where
{ {
let mut work = work.rows_mut(0, end + 1); let mut work = work.rows_mut(0, end + 1);
refl.reflect( refl.reflect(&mut t.generic_slice_mut(
&mut t.generic_slice_mut((m, m), (U2, Dynamic::new(dim.value() - m))), (m, m),
); (Const::<2>, Dynamic::new(dim.value() - m)),
));
refl.reflect_rows( refl.reflect_rows(
&mut t.generic_slice_mut((0, m), (Dynamic::new(end + 1), U2)), &mut t.generic_slice_mut((0, m), (Dynamic::new(end + 1), Const::<2>)),
&mut work, &mut work,
); );
} }
if let Some(ref mut q) = q { if let Some(ref mut q) = q {
refl.reflect_rows(&mut q.generic_slice_mut((0, m), (dim, U2)), work); refl.reflect_rows(
&mut q.generic_slice_mut((0, m), (dim, Const::<2>)),
work,
);
} }
} }
} else { } else {
@ -225,15 +232,15 @@ where
let inv_rot = rot.inverse(); let inv_rot = rot.inverse();
inv_rot.rotate(&mut t.generic_slice_mut( inv_rot.rotate(&mut t.generic_slice_mut(
(start, start), (start, start),
(U2, Dynamic::new(dim.value() - start)), (Const::<2>, Dynamic::new(dim.value() - start)),
)); ));
rot.rotate_rows( rot.rotate_rows(
&mut t.generic_slice_mut((0, start), (Dynamic::new(end + 1), U2)), &mut t.generic_slice_mut((0, start), (Dynamic::new(end + 1), Const::<2>)),
); );
t[(end, start)] = N::zero(); t[(end, start)] = N::zero();
if let Some(ref mut q) = q { if let Some(ref mut q) = q {
rot.rotate_rows(&mut q.generic_slice_mut((0, start), (dim, U2))); rot.rotate_rows(&mut q.generic_slice_mut((0, start), (dim, Const::<2>)));
} }
} }
@ -380,7 +387,7 @@ 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 = let mut out =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, Const::<1>) };
if Self::do_eigenvalues(&self.t, &mut out) { if Self::do_eigenvalues(&self.t, &mut out) {
Some(out) Some(out)
} else { } else {
@ -395,7 +402,7 @@ where
DefaultAllocator: Allocator<NumComplex<N>, D>, DefaultAllocator: Allocator<NumComplex<N>, D>,
{ {
let mut out = let mut out =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(self.t.data.shape().0, Const::<1>) };
Self::do_complex_eigenvalues(&self.t, &mut out); Self::do_complex_eigenvalues(&self.t, &mut out);
out out
} }
@ -507,7 +514,7 @@ where
); );
let mut work = let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Const::<1>) };
// Special case for 2x2 matrices. // Special case for 2x2 matrices.
if self.nrows() == 2 { if self.nrows() == 2 {
@ -548,7 +555,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 { crate::unimplemented_or_uninitialized_generic!(dim, U1) }; let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(dim, Const::<1>) };
let schur = Schur::do_decompose( let schur = Schur::do_decompose(
self.clone_owned(), self.clone_owned(),
@ -558,7 +565,7 @@ where
false, false,
) )
.unwrap(); .unwrap();
let mut eig = unsafe { crate::unimplemented_or_uninitialized_generic!(dim, U1) }; let mut eig = unsafe { crate::unimplemented_or_uninitialized_generic!(dim, Const::<1>) };
Schur::do_complex_eigenvalues(&schur.1, &mut eig); Schur::do_complex_eigenvalues(&schur.1, &mut eig);
eig eig
} }

View File

@ -2,8 +2,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, MatrixN, VectorN}; use crate::base::{DefaultAllocator, MatrixMN, MatrixN, VectorN};
use crate::dimension::{DimDiff, DimSub, U1}; use crate::dimension::{Const, DimDiff, DimSub, U1};
use crate::storage::Storage; use crate::storage::Storage;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -62,8 +62,8 @@ where
); );
let mut off_diagonal = let mut off_diagonal =
unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(Const::<1>), Const::<1>) };
let mut p = unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) }; let mut p = unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(Const::<1>), Const::<1>) };
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

@ -7,7 +7,7 @@ use std::slice;
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::sparse::cs_utils; use crate::sparse::cs_utils;
use crate::{DefaultAllocator, Dim, Dynamic, Scalar, Vector, VectorN, U1}; use crate::{Const, DefaultAllocator, Dim, Dynamic, Scalar, Vector, VectorN, U1};
pub struct ColumnEntries<'a, N> { pub struct ColumnEntries<'a, N> {
curr: usize, curr: usize,
@ -274,7 +274,7 @@ where
CsMatrix { CsMatrix {
data: CsVecStorage { data: CsVecStorage {
shape: (nrows, ncols), shape: (nrows, ncols),
p: VectorN::zeros_generic(ncols, U1), p: VectorN::zeros_generic(ncols, Const::<1>),
i, i,
vals, vals,
}, },
@ -417,7 +417,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: CsStorage<N, R, C>> CsMatrix<N, R, C, S> {
let nvals = self.len(); let nvals = self.len();
let mut res = CsMatrix::new_uninitialized_generic(ncols, nrows, nvals); let mut res = CsMatrix::new_uninitialized_generic(ncols, nrows, nvals);
let mut workspace = Vector::zeros_generic(nrows, U1); let mut workspace = Vector::zeros_generic(nrows, Const::<1>);
// Compute p. // Compute p.
for i in 0..nvals { for i in 0..nvals {
@ -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 { crate::unimplemented_or_uninitialized_generic!(nrows, U1) }; let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, Const::<1>) };
self.sort_with_workspace(workspace.as_mut_slice()); self.sort_with_workspace(workspace.as_mut_slice());
} }

View File

@ -3,7 +3,7 @@ use std::mem;
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::sparse::{CsMatrix, CsStorage, CsStorageIter, CsStorageIterMut, CsVecStorage}; use crate::sparse::{CsMatrix, CsStorage, CsStorageIter, CsStorageIterMut, CsVecStorage};
use crate::{DefaultAllocator, Dim, RealField, VectorN, U1}; use crate::{Const, DefaultAllocator, Dim, RealField, VectorN};
/// The cholesky decomposition of a column compressed sparse matrix. /// The cholesky decomposition of a column compressed sparse matrix.
pub struct CsCholesky<N: RealField, D: Dim> pub struct CsCholesky<N: RealField, D: Dim>
@ -49,9 +49,9 @@ where
// Workspaces. // Workspaces.
let work_x = let work_x =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, Const::<1>) };
let work_c = let work_c =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().1, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().1, Const::<1>) };
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());
@ -294,7 +294,7 @@ where
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 = let mut cols =
unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(m.data.shape().0, Const::<1>) };
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

@ -6,7 +6,7 @@ use crate::allocator::Allocator;
use crate::constraint::{AreMultipliable, DimEq, ShapeConstraint}; use crate::constraint::{AreMultipliable, DimEq, ShapeConstraint};
use crate::sparse::{CsMatrix, CsStorage, CsStorageMut, CsVector}; use crate::sparse::{CsMatrix, CsStorage, CsStorageMut, CsVector};
use crate::storage::StorageMut; use crate::storage::StorageMut;
use crate::{DefaultAllocator, Dim, Scalar, Vector, VectorN, U1}; use crate::{Const, DefaultAllocator, Dim, Scalar, Vector, VectorN};
impl<N: Scalar, R: Dim, C: Dim, S: CsStorage<N, R, C>> CsMatrix<N, R, C, S> { impl<N: Scalar, R: Dim, C: Dim, S: CsStorage<N, R, C>> CsMatrix<N, R, C, S> {
fn scatter<R2: Dim, C2: Dim>( fn scatter<R2: Dim, C2: Dim>(
@ -148,7 +148,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 workspace = VectorN::<N, R1>::zeros_generic(nrows1, U1); let mut workspace = VectorN::<N, R1>::zeros_generic(nrows1, Const::<1>);
let mut nz = 0; let mut nz = 0;
for j in 0..ncols2.value() { for j in 0..ncols2.value() {
@ -177,8 +177,8 @@ where
// of branching inside of the inner loop. // of branching inside of the inner loop.
// //
// 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, Const::<)>;
// let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, U1) }; // let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, Const::<)> };
// let mut nz = 0; // let mut nz = 0;
// //
// for j in 0..ncols2.value() { // for j in 0..ncols2.value() {
@ -241,8 +241,8 @@ 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, Const::<1>);
let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows1, U1) }; let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows1, Const::<1>) };
let mut nz = 0; let mut nz = 0;
for j in 0..ncols2.value() { for j in 0..ncols2.value() {

View File

@ -2,7 +2,7 @@ use crate::allocator::Allocator;
use crate::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::sparse::{CsMatrix, CsStorage, CsVector}; use crate::sparse::{CsMatrix, CsStorage, CsVector};
use crate::storage::{Storage, StorageMut}; use crate::storage::{Storage, StorageMut};
use crate::{DefaultAllocator, Dim, Matrix, MatrixMN, RealField, VectorN, U1}; use crate::{Const, DefaultAllocator, Dim, Matrix, MatrixMN, RealField, VectorN};
impl<N: RealField, D: Dim, S: CsStorage<N, D, D>> CsMatrix<N, D, D, S> { impl<N: RealField, D: Dim, S: CsStorage<N, D, D>> CsMatrix<N, D, D, S> {
/// Solve a lower-triangular system with a dense right-hand-side. /// Solve a lower-triangular system with a dense right-hand-side.
@ -150,7 +150,7 @@ impl<N: RealField, D: Dim, S: CsStorage<N, D, D>> CsMatrix<N, D, D, S> {
// 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 = let mut workspace =
unsafe { crate::unimplemented_or_uninitialized_generic!(b.data.shape().0, U1) }; unsafe { crate::unimplemented_or_uninitialized_generic!(b.data.shape().0, Const::<1>) };
for i in reach.iter().cloned() { for i in reach.iter().cloned() {
workspace[i] = N::zero(); workspace[i] = N::zero();
@ -187,7 +187,8 @@ impl<N: RealField, D: Dim, S: CsStorage<N, D, D>> CsMatrix<N, D, D, S> {
} }
// Copy the result into a sparse vector. // Copy the result into a sparse vector.
let mut result = CsVector::new_uninitialized_generic(b.data.shape().0, U1, reach.len()); let mut result =
CsVector::new_uninitialized_generic(b.data.shape().0, Const::<1>, reach.len());
for (i, val) in reach.iter().zip(result.data.vals.iter_mut()) { for (i, val) in reach.iter().zip(result.data.vals.iter_mut()) {
*val = workspace[*i]; *val = workspace[*i];
@ -251,7 +252,7 @@ impl<N: RealField, D: Dim, S: CsStorage<N, D, D>> CsMatrix<N, D, D, S> {
S2: CsStorage<N, D2>, S2: CsStorage<N, D2>,
DefaultAllocator: Allocator<bool, D>, DefaultAllocator: Allocator<bool, D>,
{ {
let mut visited = VectorN::repeat_generic(self.data.shape().1, U1, false); let mut visited = VectorN::repeat_generic(self.data.shape().1, Const::<1>, false);
let mut stack = Vec::new(); let mut stack = Vec::new();
for irow in b.data.column_row_indices(0) { for irow in b.data.column_row_indices(0) {

View File

@ -1,11 +1,11 @@
use num::{One, Zero}; use num::{One, Zero};
use std::cmp::Ordering; use std::cmp::Ordering;
use na::dimension::{U15, U2, U4, U8}; use na::dimension::{U15, U8};
use na::{ use na::{
self, DMatrix, DVector, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, self, Const, DMatrix, DVector, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4,
Matrix4x3, Matrix4x5, Matrix5, Matrix6, MatrixMN, RowVector3, RowVector4, RowVector5, Vector1, Matrix4, Matrix4x3, Matrix4x5, Matrix5, Matrix6, MatrixMN, RowVector3, RowVector4, RowVector5,
Vector2, Vector3, Vector4, Vector5, Vector6, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
}; };
#[test] #[test]
@ -79,10 +79,15 @@ fn iter() {
#[test] #[test]
fn debug_output_corresponds_to_data_container() { fn debug_output_corresponds_to_data_container() {
assert!( let m = Matrix2::new(1.0, 2.0, 3.0, 4.0);
format!("{:?}", Matrix2::new(1.0, 2.0, 3.0, 4.0)) == "Matrix { data: [1, 3, 2, 4] }" || // Current output on the stable chanel. let output_stable = "Matrix { data: [[1, 3], [2, 4]] }"; // Current output on the stable channel.
format!("{:?}", Matrix2::new(1.0, 2.0, 3.0, 4.0)) == "Matrix { data: [1.0, 3.0, 2.0, 4.0] }" // Current output on the nightyl chanel. let output_nightly = "Matrix { data: [[1.0, 3.0], [2.0, 4.0]] }"; // Current output on the nightly channel.
); let current_output = format!("{:?}", m);
dbg!(output_stable);
dbg!(output_nightly);
dbg!(&current_output);
assert!(current_output == output_stable || current_output == output_nightly);
} }
#[test] #[test]
@ -1061,13 +1066,13 @@ fn partial_eq_different_types() {
let dynamic_mat = DMatrix::from_row_slice(2, 4, &[1, 2, 3, 4, 5, 6, 7, 8]); let dynamic_mat = DMatrix::from_row_slice(2, 4, &[1, 2, 3, 4, 5, 6, 7, 8]);
let static_mat = Matrix2x4::new(1, 2, 3, 4, 5, 6, 7, 8); let static_mat = Matrix2x4::new(1, 2, 3, 4, 5, 6, 7, 8);
let mut typenum_static_mat = MatrixMN::<u8, typenum::U1024, U4>::zeros(); let mut typenum_static_mat = MatrixMN::<u8, Const<1024>, Const<4>>::zeros();
let mut slice = typenum_static_mat.slice_mut((0, 0), (2, 4)); let mut slice = typenum_static_mat.slice_mut((0, 0), (2, 4));
slice += static_mat; slice += static_mat;
let fslice_of_dmat = dynamic_mat.fixed_slice::<U2, U2>(0, 0); let fslice_of_dmat = dynamic_mat.fixed_slice::<Const<2>, Const<2>>(0, 0);
let dslice_of_dmat = dynamic_mat.slice((0, 0), (2, 2)); let dslice_of_dmat = dynamic_mat.slice((0, 0), (2, 2));
let fslice_of_smat = static_mat.fixed_slice::<U2, U2>(0, 0); let fslice_of_smat = static_mat.fixed_slice::<Const<2>, Const<2>>(0, 0);
let dslice_of_smat = static_mat.slice((0, 0), (2, 2)); let dslice_of_smat = static_mat.slice((0, 0), (2, 2));
assert_eq!(dynamic_mat, static_mat); assert_eq!(dynamic_mat, static_mat);

View File

@ -4,7 +4,7 @@ macro_rules! gen_tests(
($module: ident, $scalar: ty) => { ($module: ident, $scalar: ty) => {
mod $module { mod $module {
use na::debug::RandomSDP; use na::debug::RandomSDP;
use na::dimension::{U4, Dynamic}; use na::dimension::{U4, Const, Dynamic};
use na::{DMatrix, DVector, Matrix4x3, Vector4}; use na::{DMatrix, DVector, Matrix4x3, Vector4};
use rand::random; use rand::random;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
@ -24,7 +24,7 @@ macro_rules! gen_tests(
#[test] #[test]
fn cholesky_static(_n in PROPTEST_MATRIX_DIM) { fn cholesky_static(_n in PROPTEST_MATRIX_DIM) {
let m = RandomSDP::new(U4, || random::<$scalar>().0).unwrap(); let m = RandomSDP::new(Const::<4>, || random::<$scalar>().0).unwrap();
let chol = m.cholesky().unwrap(); let chol = m.cholesky().unwrap();
let l = chol.unpack(); let l = chol.unpack();
@ -48,7 +48,7 @@ macro_rules! gen_tests(
#[test] #[test]
fn cholesky_solve_static(_n in PROPTEST_MATRIX_DIM) { fn cholesky_solve_static(_n in PROPTEST_MATRIX_DIM) {
let m = RandomSDP::new(U4, || random::<$scalar>().0).unwrap(); let m = RandomSDP::new(Const::<4>, || random::<$scalar>().0).unwrap();
let chol = m.clone().cholesky().unwrap(); let chol = m.clone().cholesky().unwrap();
let b1 = Vector4::<$scalar>::new_random().map(|e| e.0); let b1 = Vector4::<$scalar>::new_random().map(|e| e.0);
let b2 = Matrix4x3::<$scalar>::new_random().map(|e| e.0); let b2 = Matrix4x3::<$scalar>::new_random().map(|e| e.0);
@ -72,7 +72,7 @@ macro_rules! gen_tests(
#[test] #[test]
fn cholesky_inverse_static(_n in PROPTEST_MATRIX_DIM) { fn cholesky_inverse_static(_n in PROPTEST_MATRIX_DIM) {
let m = RandomSDP::new(U4, || random::<$scalar>().0).unwrap(); let m = RandomSDP::new(Const::<4>, || random::<$scalar>().0).unwrap();
let m1 = m.clone().cholesky().unwrap().inverse(); let m1 = m.clone().cholesky().unwrap().inverse();
let id1 = &m * &m1; let id1 = &m * &m1;
let id2 = &m1 * &m; let id2 = &m1 * &m;
@ -102,7 +102,7 @@ macro_rules! gen_tests(
#[test] #[test]
fn cholesky_rank_one_update(_n in PROPTEST_MATRIX_DIM) { fn cholesky_rank_one_update(_n in PROPTEST_MATRIX_DIM) {
let mut m = RandomSDP::new(U4, || random::<$scalar>().0).unwrap(); let mut m = RandomSDP::new(Const::<4>, || random::<$scalar>().0).unwrap();
let x = Vector4::<$scalar>::new_random().map(|e| e.0); let x = Vector4::<$scalar>::new_random().map(|e| e.0);
// this is dirty but $scalar is not a scalar type (its a Rand) in this file // this is dirty but $scalar is not a scalar type (its a Rand) in this file