Replace generic-array with a regular array based on min-const-generics.
This commit is contained in:
parent
b2dadffcf2
commit
d17088398a
|
@ -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 }
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!();
|
||||
|
|
|
@ -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>
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)));
|
||||
/// ```
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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>),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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..);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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!(¤t_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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue