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]
typenum = "1.12"
generic-array = "0.14"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.3", default-features = false }

View File

@ -2,7 +2,7 @@
extern crate nalgebra as na;
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, U2, U3};
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const};
fn main() {
// Matrices can be reshaped in-place without moving or copying values.
@ -16,7 +16,7 @@ fn main() {
1.2, 2.3
);
let m3 = m1.reshape_generic(U3, U2);
let m3 = m1.reshape_generic(Const::<3>, Const::<2>);
assert_eq!(m3, m2);
// 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::hash::{Hash, Hasher};
// use std::hash::{Hash, Hasher};
#[cfg(feature = "abomonation-serialize")]
use std::io::{Result as IOResult, Write};
use std::ops::{Deref, DerefMut, Mul};
use std::ops::Mul;
#[cfg(feature = "serde-serialize")]
use serde::de::{Error, SeqAccess, Visitor};
@ -18,12 +18,9 @@ use std::mem;
#[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation;
use generic_array::{ArrayLength, GenericArray};
use typenum::Prod;
use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{DimName, U1};
use crate::base::dimension::{Const, ToTypenum};
use crate::base::storage::{
ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut,
};
@ -36,166 +33,53 @@ use crate::base::Scalar;
*/
/// A array-based statically sized matrix data storage.
#[repr(C)]
pub struct ArrayStorage<N, R, C>
where
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
data: GenericArray<N, Prod<R::Value, C::Value>>,
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct ArrayStorage<N, const R: usize, const C: usize> {
data: [[N; R]; C],
}
#[deprecated(note = "renamed to `ArrayStorage`")]
/// Renamed to [ArrayStorage].
pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>;
impl<N, R, C> Default for ArrayStorage<N, R, C>
// TODO: remove this once the stdlib implements Default for arrays.
impl<N: Default, const R: usize, const C: usize> Default for ArrayStorage<N, R, C>
where
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
N: Default,
[[N; R]; C]: Default,
{
#[inline]
fn default() -> Self {
ArrayStorage {
Self {
data: Default::default(),
}
}
}
impl<N, R, C> Hash 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>,
{
impl<N: Debug, const R: usize, const C: usize> Debug for ArrayStorage<N, R, C> {
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.data.fmt(fmt)
}
}
impl<N, R, C> Copy for ArrayStorage<N, R, C>
where
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>
unsafe impl<N, const R: usize, const C: usize> Storage<N, Const<R>, Const<C>>
for ArrayStorage<N, R, C>
where
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>,
{
type RStride = U1;
type CStride = R;
type RStride = Const<1>;
type CStride = Const<R>;
#[inline]
fn ptr(&self) -> *const N {
self[..].as_ptr()
self.data.as_ptr() as *const N
}
#[inline]
fn shape(&self) -> (R, C) {
(R::name(), C::name())
fn shape(&self) -> (Const<R>, Const<C>) {
(Const, Const)
}
#[inline]
fn strides(&self) -> (Self::RStride, Self::CStride) {
(Self::RStride::name(), Self::CStride::name())
(Const, Const)
}
#[inline]
@ -204,112 +88,107 @@ where
}
#[inline]
fn into_owned(self) -> Owned<N, R, C>
fn into_owned(self) -> Owned<N, Const<R>, Const<C>>
where
DefaultAllocator: Allocator<N, R, C>,
DefaultAllocator: Allocator<N, Const<R>, Const<C>>,
{
self
}
#[inline]
fn clone_owned(&self) -> Owned<N, R, C>
fn clone_owned(&self) -> Owned<N, Const<R>, Const<C>>
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)
}
#[inline]
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
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>,
{
#[inline]
fn ptr_mut(&mut self) -> *mut N {
self[..].as_mut_ptr()
self.data.as_mut_ptr() as *mut N
}
#[inline]
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
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
DefaultAllocator: Allocator<N, Const<R>, Const<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
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
DefaultAllocator: Allocator<N, Const<R>, Const<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
N: Scalar,
R1: DimName,
C1: DimName,
R1::Value: Mul<C1::Value>,
Prod<R1::Value, C1::Value>: ArrayLength<N>,
R2: DimName,
C2: DimName,
R2::Value: Mul<C2::Value, Output = Prod<R1::Value, C1::Value>>,
Prod<R2::Value, C2::Value>: ArrayLength<N>,
Const<R1>: ToTypenum,
Const<C1>: ToTypenum,
Const<R2>: ToTypenum,
Const<C2>: ToTypenum,
<Const<R1> as ToTypenum>::Typenum: Mul<<Const<C1> as ToTypenum>::Typenum>,
<Const<R2> as ToTypenum>::Typenum: Mul<
<Const<C2> as ToTypenum>::Typenum,
Output = typenum::Prod<
<Const<R1> as ToTypenum>::Typenum,
<Const<C1> as ToTypenum>::Typenum,
>,
>,
{
type Output = ArrayStorage<N, R2, C2>;
fn reshape_generic(self, _: R2, _: C2) -> Self::Output {
ArrayStorage { data: self.data }
fn reshape_generic(self, _: Const<R2>, _: Const<C2>) -> Self::Output {
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")]
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
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>
where
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)?;
}
@ -318,13 +197,9 @@ where
}
#[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
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>
where
@ -336,18 +211,14 @@ where
#[cfg(feature = "serde-serialize")]
/// A visitor that produces a matrix array.
struct ArrayStorageVisitor<N, R, C> {
marker: PhantomData<(N, R, C)>,
struct ArrayStorageVisitor<N, const R: usize, const C: usize> {
marker: PhantomData<N>,
}
#[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
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
/// Construct a new sequence visitor.
pub fn new() -> Self {
@ -358,13 +229,9 @@ where
}
#[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
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>;
@ -381,12 +248,13 @@ where
let mut curr = 0;
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;
curr += 1;
}
if curr == R::dim() * C::dim() {
if curr == R * C {
Ok(out)
} else {
Err(V::Error::invalid_length(curr, &self))
@ -415,16 +283,12 @@ where
}
#[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
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
N: Abomonation,
N: Scalar + Abomonation,
{
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)?;
}
@ -432,7 +296,7 @@ where
}
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;
bytes = if let Some(remainder) = element.exhume(temp) {
remainder
@ -444,9 +308,6 @@ where
}
fn extent(&self) -> usize {
self.data
.as_slice()
.iter()
.fold(0, |acc, e| acc + e.extent())
self.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::{
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::{
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSliceN,
@ -1120,7 +1120,7 @@ where
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) };
let subdim = Dynamic::new(dim1 - j);
// 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,
&x.rows_range(j..),
beta.inlined_clone(),
@ -1329,7 +1329,7 @@ where
DefaultAllocator: Allocator<N, D1>,
{
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)
}
@ -1423,7 +1423,7 @@ where
DefaultAllocator: Allocator<N, D2>,
{
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)
}
}

View File

@ -20,7 +20,7 @@ use typenum::{self, Cmp, Greater};
use simba::scalar::{ClosedAdd, ClosedMul};
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::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN};
@ -306,12 +306,12 @@ where
///
/// # Example
/// ```
/// # use nalgebra::{Dynamic, DMatrix, Matrix, U1};
/// # use nalgebra::{Dynamic, DMatrix, Matrix, Const};
///
/// let vec = vec![0, 1, 2, 3, 4, 5];
/// 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();
///
/// // `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>> {
Unit::new_normalize(VectorN::from_distribution_generic(
D::name(),
U1,
Const::<1>,
&rand_distr::StandardNormal,
rng,
))
@ -1051,6 +1051,7 @@ componentwise_constructors_impl!(
*/
impl<N, R: DimName> VectorN<N, R>
where
R: ToTypenum,
N: Scalar + Zero + One,
DefaultAllocator: Allocator<N, R>,
{
@ -1072,7 +1073,7 @@ where
#[inline]
pub fn x() -> Self
where
R::Value: Cmp<typenum::U0, Output = Greater>,
R::Typenum: Cmp<typenum::U0, Output = Greater>,
{
let mut res = Self::zeros();
unsafe {
@ -1086,7 +1087,7 @@ where
#[inline]
pub fn y() -> Self
where
R::Value: Cmp<typenum::U1, Output = Greater>,
R::Typenum: Cmp<typenum::U1, Output = Greater>,
{
let mut res = Self::zeros();
unsafe {
@ -1100,7 +1101,7 @@ where
#[inline]
pub fn z() -> Self
where
R::Value: Cmp<typenum::U2, Output = Greater>,
R::Typenum: Cmp<typenum::U2, Output = Greater>,
{
let mut res = Self::zeros();
unsafe {
@ -1114,7 +1115,7 @@ where
#[inline]
pub fn w() -> Self
where
R::Value: Cmp<typenum::U3, Output = Greater>,
R::Typenum: Cmp<typenum::U3, Output = Greater>,
{
let mut res = Self::zeros();
unsafe {
@ -1128,7 +1129,7 @@ where
#[inline]
pub fn a() -> Self
where
R::Value: Cmp<typenum::U4, Output = Greater>,
R::Typenum: Cmp<typenum::U4, Output = Greater>,
{
let mut res = Self::zeros();
unsafe {
@ -1142,7 +1143,7 @@ where
#[inline]
pub fn b() -> Self
where
R::Value: Cmp<typenum::U5, Output = Greater>,
R::Typenum: Cmp<typenum::U5, Output = Greater>,
{
let mut res = Self::zeros();
unsafe {
@ -1156,7 +1157,7 @@ where
#[inline]
pub fn x_axis() -> Unit<Self>
where
R::Value: Cmp<typenum::U0, Output = Greater>,
R::Typenum: Cmp<typenum::U0, Output = Greater>,
{
Unit::new_unchecked(Self::x())
}
@ -1165,7 +1166,7 @@ where
#[inline]
pub fn y_axis() -> Unit<Self>
where
R::Value: Cmp<typenum::U1, Output = Greater>,
R::Typenum: Cmp<typenum::U1, Output = Greater>,
{
Unit::new_unchecked(Self::y())
}
@ -1174,7 +1175,7 @@ where
#[inline]
pub fn z_axis() -> Unit<Self>
where
R::Value: Cmp<typenum::U2, Output = Greater>,
R::Typenum: Cmp<typenum::U2, Output = Greater>,
{
Unit::new_unchecked(Self::z())
}
@ -1183,7 +1184,7 @@ where
#[inline]
pub fn w_axis() -> Unit<Self>
where
R::Value: Cmp<typenum::U3, Output = Greater>,
R::Typenum: Cmp<typenum::U3, Output = Greater>,
{
Unit::new_unchecked(Self::w())
}
@ -1192,7 +1193,7 @@ where
#[inline]
pub fn a_axis() -> Unit<Self>
where
R::Value: Cmp<typenum::U4, Output = Greater>,
R::Typenum: Cmp<typenum::U4, Output = Greater>,
{
Unit::new_unchecked(Self::a())
}
@ -1201,7 +1202,7 @@ where
#[inline]
pub fn b_axis() -> Unit<Self>
where
R::Value: Cmp<typenum::U5, Output = Greater>,
R::Typenum: Cmp<typenum::U5, Output = Greater>,
{
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::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
@ -68,7 +68,9 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
nrows: R,
ncols: C,
) -> 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.
@ -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()`.
#[inline]
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,
ncols: C,
) -> 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.
@ -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()`.
#[inline]
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::ptr;
use generic_array::ArrayLength;
use std::ops::Mul;
use typenum::Prod;
use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::{Allocator, SameShapeAllocator};
@ -16,7 +12,7 @@ use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstr
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::Dynamic;
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::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);
);
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
N: Scalar,
R: DimName,
C: DimName,
RStride: 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()
}
}
@ -277,18 +271,15 @@ where
}
}
impl<'a, N, R, C, RStride, CStride> From<MatrixSliceMut<'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<MatrixSliceMut<'a, N, Const<R>, Const<C>, RStride, CStride>>
for Matrix<N, Const<R>, Const<C>, ArrayStorage<N, R, C>>
where
N: Scalar,
R: DimName,
C: DimName,
RStride: 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()
}
}

View File

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

View File

@ -6,9 +6,7 @@ use std::any::{Any, TypeId};
use std::cmp;
use std::fmt::Debug;
use std::ops::{Add, Div, Mul, Sub};
use typenum::{
self, Bit, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, UInt, UTerm, Unsigned, B1,
};
use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};
#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
@ -130,13 +128,17 @@ macro_rules! dim_ops(
fn $op(self, other: D) -> Self::Output;
}
impl<D1: DimName, D2: DimName> $DimOp<D2> for D1
where D1::Value: $Op<D2::Value>,
$ResOp<D1::Value, D2::Value>: NamedDim {
type Output = <$ResOp<D1::Value, D2::Value> as NamedDim>::Name;
impl<const A: usize, const B: usize> $DimOp<Const<B>> for Const<A>
where
Const<A>: ToTypenum,
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, _: D2) -> Self::Output {
fn $op(self, _: Const<B>) -> Self::Output {
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 {
type Output = Dynamic;
@ -167,13 +170,17 @@ macro_rules! dim_ops(
fn $op(self, other: D) -> Self::Output;
}
impl<D1: DimName, D2: DimName> $DimNameOp<D2> for D1
where D1::Value: $Op<D2::Value>,
$ResOp<D1::Value, D2::Value>: NamedDim {
type Output = <$ResOp<D1::Value, D2::Value> as NamedDim>::Name;
impl<const A: usize, const B: usize> $DimNameOp<Const<B>> for Const<A>
where
Const<A>: ToTypenum,
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, _: D2) -> Self::Output {
fn $op(self, _: Const<B>) -> Self::Output {
Self::Output::name()
}
}
@ -189,105 +196,81 @@ dim_ops!(
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.
pub trait DimName: Dim {
type Value: NamedDim<Name = Self>;
/// The name of this dimension, i.e., the singleton `Self`.
fn name() -> Self;
// TODO: this is not a very idiomatic name.
/// The value of this dimension.
#[inline]
fn dim() -> usize {
Self::Value::to_usize()
}
fn dim() -> usize;
}
pub trait NamedDim: Sized + Any + Unsigned {
type Name: DimName<Value = Self>;
pub trait ToConst {
type Const: DimName;
}
/// A type level dimension with a value of `1`.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct U1;
pub trait ToTypenum {
type Typenum: Unsigned;
}
impl Dim for U1 {
#[inline]
impl<const T: usize> Dim for Const<T> {
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 {
1
T
}
fn from_usize(dim: usize) -> Self {
assert_eq!(dim, T);
Self
}
}
impl DimName for U1 {
type Value = typenum::U1;
impl<const T: usize> DimName for Const<T> {
#[inline]
fn name() -> Self {
U1
Self
}
#[inline]
fn dim() -> usize {
T
}
}
impl NamedDim for typenum::U1 {
type Name = U1;
pub type U1 = Const<1>;
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),* $(,)*) => {$(
/// A type level dimension.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct $D;
pub type $D = Const<{ typenum::$D::USIZE }>;
impl Dim for $D {
#[inline]
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 ToTypenum for Const<{ typenum::$D::USIZE }> {
type Typenum = typenum::$D;
}
impl DimName for $D {
type Value = typenum::$D;
#[inline]
fn name() -> Self {
$D
}
}
impl NamedDim for typenum::$D {
type Name = $D;
impl ToConst for typenum::$D {
type Const = Const<{ typenum::$D::USIZE }>;
}
impl IsNotStaticOne for $D { }
)*}
);
// We give explicit names to all Unsigned in [0, 128[
named_dimension!(
from_to_typenum!(
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,
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,
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
///
/// ```
/// # use nalgebra::{Matrix3x2, Matrix2x3, DMatrix, U2, U3, Dynamic};
/// # use nalgebra::{Matrix3x2, Matrix2x3, DMatrix, Const, Dynamic};
///
/// let m1 = Matrix2x3::new(
/// 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,
/// 1.2, 2.3
/// );
/// let reshaped = m1.reshape_generic(U3, U2);
/// let reshaped = m1.reshape_generic(Const::<3>, Const::<2>);
/// assert_eq!(reshaped, m2);
///
/// let dm1 = DMatrix::from_row_slice(

View File

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

View File

@ -28,7 +28,7 @@ use crate::base::iter::{
use crate::base::storage::{
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;
/// 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 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() {
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() {
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 {
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 hnrows = DimSum::<D, U1>::from_usize(len + 1);
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())
.copy_from(self);
res[(len, 0)] = element;

View File

@ -4,7 +4,7 @@ use std::slice;
use crate::base::allocator::Allocator;
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::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
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.
#[inline]
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.
@ -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.
#[inline]
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.
@ -730,7 +730,7 @@ impl<D: Dim> SliceRange<D> for usize {
#[inline(always)]
fn size(&self, _: D) -> Self::Size {
U1
Const::<1>
}
}

View File

@ -1,6 +1,6 @@
use crate::allocator::Allocator;
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 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 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() {
// 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 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() {
// 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>,
{
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;
})
}
@ -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 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())
})
}

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 typenum::{self, Cmp, Greater};
@ -9,7 +9,7 @@ macro_rules! impl_swizzle {
/// Builds a new vector from components of `self`.
#[inline]
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()),*)
}
)*
@ -18,7 +18,10 @@ macro_rules! impl_swizzle {
}
/// # 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!(
where U0: xx() -> Vector2[0, 0],
xxx() -> Vector3[0, 0, 0];

View File

@ -1,5 +1,5 @@
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 typenum::{self, Cmp, Greater};
@ -10,7 +10,7 @@ macro_rules! impl_swizzle {
/// Builds a new point from components of `self`.
#[inline]
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()),*)
}
)*
@ -19,8 +19,9 @@ macro_rules! impl_swizzle {
}
/// # Swizzling
impl<N: Scalar, D: DimName> Point<N, D>
impl<N: Scalar, D> Point<N, D>
where
D: DimName + ToTypenum,
DefaultAllocator: Allocator<N, D>,
{
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(unused_qualifications)]
#![deny(unused_results)]
#![deny(missing_docs)]
// #![deny(missing_docs)]
#![doc(
html_favicon_url = "https://nalgebra.org/img/favicon.ico",
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 crate::allocator::Allocator;
use crate::base::dimension::{Dim, U1};
use crate::base::dimension::Dim;
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
/// the corresponding diagonal transformation.
@ -20,7 +20,7 @@ where
let dim = m.data.shape().0;
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;

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::allocator::Allocator;
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 simba::scalar::ComplexField;
@ -82,11 +82,11 @@ where
);
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 =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols.sub(U1), U1) };
let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) };
let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, 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, Const::<1>) };
let mut work = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, Const::<1>) };
let upper_diagonal = nrows.value() >= ncols.value();
if upper_diagonal {
@ -241,8 +241,8 @@ where
let mut res = Matrix::identity_generic(min_nrows_ncols, ncols);
let mut work =
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, U1) };
let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, U1) };
unsafe { crate::unimplemented_or_uninitialized_generic!(min_nrows_ncols, Const::<1>) };
let mut axis_packed = unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
let shift = self.axis_shift().1;

View File

@ -6,7 +6,7 @@ use simba::scalar::ComplexField;
use simba::simd::SimdComplexField;
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::dimension::{Dim, DimAdd, DimDiff, DimSub, DimSum, U1};
use crate::storage::{Storage, StorageMut};
@ -234,8 +234,8 @@ where
// loads the data into a new matrix with an additional jth row/column
let mut chol = unsafe {
crate::unimplemented_or_uninitialized_generic!(
self.chol.data.shape().0.add(U1),
self.chol.data.shape().1.add(U1)
self.chol.data.shape().0.add(Const::<1>),
self.chol.data.shape().1.add(Const::<1>)
)
};
chol.slice_range_mut(..j, ..j)
@ -299,8 +299,8 @@ where
// loads the data into a new matrix except for the jth row/column
let mut chol = unsafe {
crate::unimplemented_or_uninitialized_generic!(
self.chol.data.shape().0.sub(U1),
self.chol.data.shape().1.sub(U1)
self.chol.data.shape().0.sub(Const::<1>),
self.chol.data.shape().1.sub(Const::<1>)
)
};
chol.slice_range_mut(..j, ..j)

View File

@ -2,7 +2,7 @@ use std::cmp;
use crate::base::allocator::Allocator;
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::{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();
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 mut conv = VectorN::zeros_generic(result_len, U1);
let result_len = self
.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) {
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);
}
let result_len = self.data.shape().0.add(U1).sub(kernel.data.shape().0);
let mut conv = VectorN::zeros_generic(result_len, U1);
let result_len = self
.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 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);
}
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 j in 0..ker {

View File

@ -3,7 +3,7 @@
use crate::{
base::{
allocator::Allocator,
dimension::{Dim, DimMin, DimMinimum, U1},
dimension::{Const, Dim, DimMin, DimMinimum},
storage::Storage,
DefaultAllocator,
},
@ -349,7 +349,7 @@ where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{
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();
for _ in 0..p {

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, MatrixN, VectorN};
use crate::dimension::{DimDiff, DimSub, U1};
use crate::dimension::{Const, DimDiff, DimSub, U1};
use crate::storage::Storage;
use simba::scalar::ComplexField;
@ -49,7 +49,7 @@ where
/// Computes the Hessenberg decomposition using householder reflections.
pub fn new(hess: MatrixN<N, D>) -> Self {
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)
}
@ -76,7 +76,7 @@ where
);
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 {
return Hessenberg { hess, subdiag };

View File

@ -8,7 +8,7 @@ use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::dimension::Dynamic;
use crate::dimension::{Dim, DimName, U1};
use crate::dimension::{Const, Dim, DimName};
use crate::storage::StorageMut;
/// A sequence of row or column permutations.
@ -72,7 +72,7 @@ where
unsafe {
Self {
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::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Unit, VectorN};
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 simba::scalar::ComplexField;
@ -55,7 +55,7 @@ where
let min_nrows_ncols = nrows.min(ncols);
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 {
return QR { qr: matrix, diag };

View File

@ -7,7 +7,7 @@ use simba::scalar::{ComplexField, RealField};
use std::cmp;
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::{DefaultAllocator, MatrixN, SquareMatrix, Unit, Vector2, Vector3, VectorN};
@ -72,7 +72,7 @@ where
/// continues indefinitely until convergence.
pub fn try_new(m: MatrixN<N, D>, eps: N::RealField, max_niter: usize) -> Option<Self> {
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)
.map(|(q, t)| Schur { q: q.unwrap(), t })
@ -172,18 +172,21 @@ where
{
let krows = cmp::min(k + 4, end + 1);
let mut work = work.rows_mut(0, krows);
refl.reflect(
&mut t
.generic_slice_mut((k, k), (U3, Dynamic::new(dim.value() - k))),
);
refl.reflect(&mut t.generic_slice_mut(
(k, k),
(Const::<3>, Dynamic::new(dim.value() - k)),
));
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,
);
}
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);
refl.reflect(
&mut t.generic_slice_mut((m, m), (U2, Dynamic::new(dim.value() - m))),
);
refl.reflect(&mut t.generic_slice_mut(
(m, m),
(Const::<2>, Dynamic::new(dim.value() - m)),
));
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,
);
}
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 {
@ -225,15 +232,15 @@ where
let inv_rot = rot.inverse();
inv_rot.rotate(&mut t.generic_slice_mut(
(start, start),
(U2, Dynamic::new(dim.value() - start)),
(Const::<2>, Dynamic::new(dim.value() - start)),
));
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();
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.
pub fn eigenvalues(&self) -> Option<VectorN<N, D>> {
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) {
Some(out)
} else {
@ -395,7 +402,7 @@ where
DefaultAllocator: Allocator<NumComplex<N>, D>,
{
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);
out
}
@ -507,7 +514,7 @@ where
);
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.
if self.nrows() == 2 {
@ -548,7 +555,7 @@ where
DefaultAllocator: Allocator<NumComplex<N>, D>,
{
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(
self.clone_owned(),
@ -558,7 +565,7 @@ where
false,
)
.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);
eig
}

View File

@ -2,8 +2,8 @@
use serde::{Deserialize, Serialize};
use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, MatrixN, VectorN};
use crate::dimension::{DimDiff, DimSub, U1};
use crate::base::{DefaultAllocator, MatrixMN, MatrixN, VectorN};
use crate::dimension::{Const, DimDiff, DimSub, U1};
use crate::storage::Storage;
use simba::scalar::ComplexField;
@ -62,8 +62,8 @@ where
);
let mut off_diagonal =
unsafe { crate::unimplemented_or_uninitialized_generic!(dim.sub(U1), U1) };
let mut p = 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(Const::<1>), Const::<1>) };
for i in 0..dim.value() - 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::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> {
curr: usize,
@ -274,7 +274,7 @@ where
CsMatrix {
data: CsVecStorage {
shape: (nrows, ncols),
p: VectorN::zeros_generic(ncols, U1),
p: VectorN::zeros_generic(ncols, Const::<1>),
i,
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 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.
for i in 0..nvals {
@ -460,7 +460,7 @@ where
{
// Size = R
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());
}

View File

@ -3,7 +3,7 @@ use std::mem;
use crate::allocator::Allocator;
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.
pub struct CsCholesky<N: RealField, D: Dim>
@ -49,9 +49,9 @@ where
// Workspaces.
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 =
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();
original_p.push(m.data.i.len());
@ -294,7 +294,7 @@ where
let (nrows, ncols) = m.data.shape();
let mut rows = Vec::with_capacity(m.len());
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();
// 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::sparse::{CsMatrix, CsStorage, CsStorageMut, CsVector};
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> {
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 workspace = VectorN::<N, R1>::zeros_generic(nrows1, U1);
let mut workspace = VectorN::<N, R1>::zeros_generic(nrows1, Const::<1>);
let mut nz = 0;
for j in 0..ncols2.value() {
@ -177,8 +177,8 @@ where
// of branching inside of the inner loop.
//
// let mut res = CsMatrix::new_uninitialized_generic(nrows1, ncols2, self.len() + rhs.len());
// let mut timestamps = VectorN::zeros_generic(nrows1, U1);
// let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, U1) };
// let mut timestamps = VectorN::zeros_generic(nrows1, Const::<)>;
// let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, Const::<)> };
// let mut nz = 0;
//
// 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 timestamps = VectorN::zeros_generic(nrows1, U1);
let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows1, U1) };
let mut timestamps = VectorN::zeros_generic(nrows1, Const::<1>);
let mut workspace = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows1, Const::<1>) };
let mut nz = 0;
for j in 0..ncols2.value() {

View File

@ -2,7 +2,7 @@ use crate::allocator::Allocator;
use crate::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::sparse::{CsMatrix, CsStorage, CsVector};
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> {
/// 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.
reach.sort();
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() {
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.
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()) {
*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>,
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();
for irow in b.data.column_row_indices(0) {

View File

@ -1,11 +1,11 @@
use num::{One, Zero};
use std::cmp::Ordering;
use na::dimension::{U15, U2, U4, U8};
use na::dimension::{U15, U8};
use na::{
self, DMatrix, DVector, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4,
Matrix4x3, Matrix4x5, Matrix5, Matrix6, MatrixMN, RowVector3, RowVector4, RowVector5, Vector1,
Vector2, Vector3, Vector4, Vector5, Vector6,
self, Const, DMatrix, DVector, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4,
Matrix4, Matrix4x3, Matrix4x5, Matrix5, Matrix6, MatrixMN, RowVector3, RowVector4, RowVector5,
Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
};
#[test]
@ -79,10 +79,15 @@ fn iter() {
#[test]
fn debug_output_corresponds_to_data_container() {
assert!(
format!("{:?}", Matrix2::new(1.0, 2.0, 3.0, 4.0)) == "Matrix { data: [1, 3, 2, 4] }" || // Current output on the stable chanel.
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 m = Matrix2::new(1.0, 2.0, 3.0, 4.0);
let output_stable = "Matrix { data: [[1, 3], [2, 4]] }"; // Current output on the stable channel.
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]
@ -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 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));
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 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));
assert_eq!(dynamic_mat, static_mat);

View File

@ -4,7 +4,7 @@ macro_rules! gen_tests(
($module: ident, $scalar: ty) => {
mod $module {
use na::debug::RandomSDP;
use na::dimension::{U4, Dynamic};
use na::dimension::{U4, Const, Dynamic};
use na::{DMatrix, DVector, Matrix4x3, Vector4};
use rand::random;
use simba::scalar::ComplexField;
@ -24,7 +24,7 @@ macro_rules! gen_tests(
#[test]
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 l = chol.unpack();
@ -48,7 +48,7 @@ macro_rules! gen_tests(
#[test]
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 b1 = Vector4::<$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]
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 id1 = &m * &m1;
let id2 = &m1 * &m;
@ -102,7 +102,7 @@ macro_rules! gen_tests(
#[test]
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);
// this is dirty but $scalar is not a scalar type (its a Rand) in this file