diff --git a/src/base/alias_slice.rs b/src/base/alias_slice.rs index 14519344..1b368c8e 100644 --- a/src/base/alias_slice.rs +++ b/src/base/alias_slice.rs @@ -1,6 +1,6 @@ -use base::Matrix; use base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6}; use base::matrix_slice::{SliceStorage, SliceStorageMut}; +use base::Matrix; /* * diff --git a/src/base/allocator.rs b/src/base/allocator.rs index 61dd71eb..5b17c183 100644 --- a/src/base/allocator.rs +++ b/src/base/allocator.rs @@ -2,10 +2,10 @@ use std::any::Any; -use base::{DefaultAllocator, Scalar}; use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use base::dimension::{Dim, U1}; use base::storage::ContiguousStorageMut; +use base::{DefaultAllocator, Scalar}; /// A matrix allocator of a memory buffer that may contain `R::to_usize() * C::to_usize()` /// elements of type `N`. @@ -33,8 +33,9 @@ pub trait Allocator: Any + Sized { /// A matrix reallocator. Changes the size of the memory buffer that initially contains (RFrom × /// CFrom) elements to a smaller or larger size (RTo, CTo). -pub trait Reallocator - : Allocator + Allocator { +pub trait Reallocator: + Allocator + Allocator +{ /// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer /// `buf`. Data stored by `buf` are linearly copied to the output: /// @@ -57,8 +58,8 @@ pub type SameShapeC = >:: // FIXME: Bad name. /// Restricts the given number of rows and columns to be respectively the same. -pub trait SameShapeAllocator - : Allocator + Allocator, SameShapeC> +pub trait SameShapeAllocator: + Allocator + Allocator, SameShapeC> where R1: Dim, R2: Dim, @@ -78,13 +79,12 @@ where N: Scalar, DefaultAllocator: Allocator + Allocator, SameShapeC>, ShapeConstraint: SameNumberOfRows + SameNumberOfColumns, -{ -} +{} // XXX: Bad name. /// Restricts the given number of rows to be equal. -pub trait SameShapeVectorAllocator - : Allocator + Allocator> + SameShapeAllocator +pub trait SameShapeVectorAllocator: + Allocator + Allocator> + SameShapeAllocator where R1: Dim, R2: Dim, @@ -100,5 +100,4 @@ where N: Scalar, DefaultAllocator: Allocator + Allocator>, ShapeConstraint: SameNumberOfRows, -{ -} +{} diff --git a/src/base/blas.rs b/src/base/blas.rs index 49797519..b4a5cfbe 100644 --- a/src/base/blas.rs +++ b/src/base/blas.rs @@ -14,7 +14,6 @@ use base::storage::{Storage, StorageMut}; use base::{DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector}; impl> Vector { - /// Computes the index of the vector component with the largest value. /// /// # Examples: @@ -685,13 +684,19 @@ where // We could use matrixmultiply for large statically-sized matrices but the performance // threshold to activate it would be different from SMALL_DIM because our code optimizes // better for statically-sized matrices. - let is_dynamic = R1::is::() || C1::is::() || R2::is::() - || C2::is::() || R3::is::() + let is_dynamic = R1::is::() + || C1::is::() + || R2::is::() + || C2::is::() + || R3::is::() || C3::is::(); // Threshold determined empirically. const SMALL_DIM: usize = 5; - if is_dynamic && nrows1 > SMALL_DIM && ncols1 > SMALL_DIM && nrows2 > SMALL_DIM + if is_dynamic + && nrows1 > SMALL_DIM + && ncols1 > SMALL_DIM + && nrows2 > SMALL_DIM && ncols2 > SMALL_DIM { if N::is::() { diff --git a/src/base/cg.rs b/src/base/cg.rs index 84fff1a5..39509f2f 100644 --- a/src/base/cg.rs +++ b/src/base/cg.rs @@ -7,15 +7,18 @@ use num::One; -use base::{DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, - Vector3, VectorN}; +use base::allocator::Allocator; use base::dimension::{DimName, DimNameDiff, DimNameSub, U1}; use base::storage::{Storage, StorageMut}; -use base::allocator::Allocator; -use geometry::{Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point3, Rotation2, - Rotation3}; +use base::{ + DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, Vector3, + VectorN, +}; +use geometry::{ + Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point3, Rotation2, Rotation3, +}; -use alga::general::{Ring, Real}; +use alga::general::{Real, Ring}; use alga::linear::Transformation; impl MatrixN @@ -302,7 +305,8 @@ impl> SquareMatrix SB: Storage>, DefaultAllocator: Allocator>, { - let scale = self.fixed_slice::>(D::dim() - 1, 0) + let scale = self + .fixed_slice::>(D::dim() - 1, 0) .tr_dot(&shift); let post_translation = self.fixed_slice::, DimNameDiff>(0, 0) * shift; @@ -341,9 +345,8 @@ where let transform = self.fixed_slice::, DimNameDiff>(0, 0); let translation = self.fixed_slice::, U1>(0, D::dim() - 1); let normalizer = self.fixed_slice::>(D::dim() - 1, 0); - let n = normalizer.tr_dot(&pt.coords) + unsafe { - *self.get_unchecked(D::dim() - 1, D::dim() - 1) - }; + let n = normalizer.tr_dot(&pt.coords) + + unsafe { *self.get_unchecked(D::dim() - 1, D::dim() - 1) }; if !n.is_zero() { return transform * (pt / n) + translation; diff --git a/src/base/componentwise.rs b/src/base/componentwise.rs index 94934715..5db2ebb8 100644 --- a/src/base/componentwise.rs +++ b/src/base/componentwise.rs @@ -1,4 +1,4 @@ -// Non-conventional componentwise operators. +// Non-conventional component-wise operators. use num::{Signed, Zero}; use std::ops::{Add, Mul}; diff --git a/src/base/constraint.rs b/src/base/constraint.rs index 369841b5..d9d7aafe 100644 --- a/src/base/constraint.rs +++ b/src/base/constraint.rs @@ -8,11 +8,9 @@ pub struct ShapeConstraint; /// Constraints `C1` and `R2` to be equivalent. pub trait AreMultipliable: DimEq {} -impl AreMultipliable for ShapeConstraint -where - ShapeConstraint: DimEq, -{ -} +impl AreMultipliable for ShapeConstraint where + ShapeConstraint: DimEq +{} /// Constraints `D1` and `D2` to be equivalent. pub trait DimEq { @@ -70,8 +68,9 @@ equality_trait_decl!( /// Constraints D1 and D2 to be equivalent, where they both designate dimensions of algebraic /// entities (e.g. square matrices). -pub trait SameDimension - : SameNumberOfRows + SameNumberOfColumns { +pub trait SameDimension: + SameNumberOfRows + SameNumberOfColumns +{ /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level /// constant. type Representative: Dim; diff --git a/src/base/coordinates.rs b/src/base/coordinates.rs index e092763e..986b8e9d 100644 --- a/src/base/coordinates.rs +++ b/src/base/coordinates.rs @@ -7,9 +7,9 @@ use std::mem; use std::ops::{Deref, DerefMut}; -use base::{Matrix, Scalar}; use base::dimension::{U1, U2, U3, U4, U5, U6}; use base::storage::{ContiguousStorage, ContiguousStorageMut}; +use base::{Matrix, Scalar}; /* * diff --git a/src/base/dimension.rs b/src/base/dimension.rs index c660c5a4..d694ec39 100644 --- a/src/base/dimension.rs +++ b/src/base/dimension.rs @@ -7,7 +7,7 @@ use std::cmp; use std::fmt::Debug; use std::ops::{Add, Div, Mul, Sub}; use typenum::{ - self, B1, Bit, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, UInt, UTerm, Unsigned, + self, Bit, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, UInt, UTerm, Unsigned, B1, }; #[cfg(feature = "serde-serialize")] diff --git a/src/base/edition.rs b/src/base/edition.rs index 58517614..649d4cda 100644 --- a/src/base/edition.rs +++ b/src/base/edition.rs @@ -285,7 +285,8 @@ impl> Matrix { let copied_value_start = i + nremove.value(); unsafe { - let ptr_in = m.data + let ptr_in = m + .data .ptr() .offset((copied_value_start * nrows.value()) as isize); let ptr_out = m.data.ptr_mut().offset((i * nrows.value()) as isize); @@ -448,7 +449,8 @@ impl> Matrix { if ninsert.value() != 0 && i != ncols.value() { let ptr_in = res.data.ptr().offset((i * nrows.value()) as isize); - let ptr_out = res.data + let ptr_out = res + .data .ptr_mut() .offset(((i + ninsert.value()) * nrows.value()) as isize); diff --git a/src/base/iter.rs b/src/base/iter.rs index 52d492da..fe8fd4f6 100644 --- a/src/base/iter.rs +++ b/src/base/iter.rs @@ -3,21 +3,20 @@ use std::marker::PhantomData; use std::mem; -use base::Scalar; use base::dimension::Dim; use base::storage::{Storage, StorageMut}; +use base::Scalar; macro_rules! iterator { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => { - /// An iterator through a dense matrix with arbitrary strides matrix. pub struct $Name<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage> { - ptr: $Ptr, + ptr: $Ptr, inner_ptr: $Ptr, inner_end: $Ptr, - size: usize, // We can't use an end pointer here because a stride might be zero. - strides: (S::RStride, S::CStride), - _phantoms: PhantomData<($Ref, R, C, S)> + size: usize, // We can't use an end pointer here because a stride might be zero. + strides: (S::RStride, S::CStride), + _phantoms: PhantomData<($Ref, R, C, S)>, } // FIXME: we need to specialize for the case where the matrix storage is owned (in which @@ -25,23 +24,25 @@ macro_rules! iterator { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage> $Name<'a, N, R, C, S> { /// Creates a new iterator for the given matrix storage. pub fn new(storage: $SRef) -> $Name<'a, N, R, C, S> { - let shape = storage.shape(); + let shape = storage.shape(); let strides = storage.strides(); let inner_offset = shape.0.value() * strides.0.value(); let ptr = storage.$ptr(); $Name { - ptr: ptr, + ptr: ptr, inner_ptr: ptr, inner_end: unsafe { ptr.offset(inner_offset as isize) }, - size: shape.0.value() * shape.1.value(), - strides: strides, - _phantoms: PhantomData + size: shape.0.value() * shape.1.value(), + strides: strides, + _phantoms: PhantomData, } } } - impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage> Iterator for $Name<'a, N, R, C, S> { + impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage> Iterator + for $Name<'a, N, R, C, S> + { type Item = $Ref; #[inline] @@ -82,13 +83,15 @@ macro_rules! iterator { } } - impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage> ExactSizeIterator for $Name<'a, N, R, C, S> { + impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage> ExactSizeIterator + for $Name<'a, N, R, C, S> + { #[inline] fn len(&self) -> usize { self.size } } - } + }; } iterator!(struct MatrixIter for Storage.ptr -> *const N, &'a N, &'a S); diff --git a/src/base/matrix_array.rs b/src/base/matrix_array.rs index 023c7c7b..fc81176c 100644 --- a/src/base/matrix_array.rs +++ b/src/base/matrix_array.rs @@ -107,8 +107,7 @@ where R::Value: Mul, Prod: ArrayLength, GenericArray>: Copy, -{ -} +{} impl Clone for MatrixArray where @@ -133,8 +132,7 @@ where C: DimName, R::Value: Mul, Prod: ArrayLength, -{ -} +{} impl PartialEq for MatrixArray where @@ -234,8 +232,7 @@ where R::Value: Mul, Prod: ArrayLength, DefaultAllocator: Allocator, -{ -} +{} unsafe impl ContiguousStorageMut for MatrixArray where @@ -245,8 +242,7 @@ where R::Value: Mul, Prod: ArrayLength, DefaultAllocator: Allocator, -{ -} +{} /* * diff --git a/src/base/matrix_vec.rs b/src/base/matrix_vec.rs index 8a28b26c..90bdfe28 100644 --- a/src/base/matrix_vec.rs +++ b/src/base/matrix_vec.rs @@ -211,17 +211,13 @@ where } } -unsafe impl ContiguousStorage for MatrixVec -where - DefaultAllocator: Allocator, -{ -} +unsafe impl ContiguousStorage for MatrixVec where + DefaultAllocator: Allocator +{} -unsafe impl ContiguousStorageMut for MatrixVec -where - DefaultAllocator: Allocator, -{ -} +unsafe impl ContiguousStorageMut for MatrixVec where + DefaultAllocator: Allocator +{} unsafe impl StorageMut for MatrixVec where @@ -253,14 +249,10 @@ impl Abomonation for MatrixVec { } } -unsafe impl ContiguousStorage for MatrixVec -where - DefaultAllocator: Allocator, -{ -} +unsafe impl ContiguousStorage for MatrixVec where + DefaultAllocator: Allocator +{} -unsafe impl ContiguousStorageMut for MatrixVec -where - DefaultAllocator: Allocator, -{ -} +unsafe impl ContiguousStorageMut for MatrixVec where + DefaultAllocator: Allocator +{} diff --git a/src/base/mod.rs b/src/base/mod.rs index 7197b004..2f573025 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -12,7 +12,6 @@ pub mod storage; mod alias; mod alias_slice; -mod swizzle; mod cg; mod componentwise; mod construction; @@ -27,6 +26,7 @@ mod matrix_slice; mod matrix_vec; mod properties; mod scalar; +mod swizzle; mod unit; #[doc(hidden)] diff --git a/src/base/ops.rs b/src/base/ops.rs index 217ed194..a83d5112 100644 --- a/src/base/ops.rs +++ b/src/base/ops.rs @@ -1,17 +1,19 @@ -use std::iter; -use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, - SubAssign}; -use std::cmp::PartialOrd; use num::{One, Signed, Zero}; +use std::cmp::PartialOrd; +use std::iter; +use std::ops::{ + Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign, +}; use alga::general::{ClosedAdd, ClosedDiv, ClosedMul, ClosedNeg, ClosedSub}; -use base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, MatrixSum, Scalar}; -use base::dimension::{Dim, DimMul, DimName, DimProd}; -use base::constraint::{AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, - ShapeConstraint}; -use base::storage::{ContiguousStorageMut, Storage, StorageMut}; use base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR}; +use base::constraint::{ + AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, +}; +use base::dimension::{Dim, DimMul, DimName, DimProd}; +use base::storage::{ContiguousStorageMut, Storage, StorageMut}; +use base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, MatrixSum, Scalar}; /* * @@ -783,7 +785,8 @@ impl> Matri #[inline] pub fn amin(&self) -> N { let mut it = self.iter(); - let mut min = it.next() + let mut min = it + .next() .expect("amin: empty matrices not supported.") .abs(); diff --git a/src/base/scalar.rs b/src/base/scalar.rs index ca6da510..47e3019c 100644 --- a/src/base/scalar.rs +++ b/src/base/scalar.rs @@ -1,6 +1,6 @@ +use std::any::Any; use std::any::TypeId; use std::fmt::Debug; -use std::any::Any; /// The basic scalar type for all structures of `nalgebra`. /// diff --git a/src/base/storage.rs b/src/base/storage.rs index 63d10bcb..bf57242e 100644 --- a/src/base/storage.rs +++ b/src/base/storage.rs @@ -3,10 +3,10 @@ use std::fmt::Debug; use std::mem; -use base::Scalar; +use base::allocator::{Allocator, SameShapeC, SameShapeR}; use base::default_allocator::DefaultAllocator; use base::dimension::{Dim, U1}; -use base::allocator::{Allocator, SameShapeC, SameShapeR}; +use base::Scalar; /* * Aliases for allocation results. @@ -177,8 +177,9 @@ pub unsafe trait StorageMut: Storage { /// The storage requirement means that for any value of `i` in `[0, nrows * ncols[`, the value /// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because /// failing to comply to this may cause Undefined Behaviors. -pub unsafe trait ContiguousStorage - : Storage { +pub unsafe trait ContiguousStorage: + Storage +{ } /// A mutable matrix storage that is stored contiguously in memory. @@ -186,6 +187,7 @@ pub unsafe trait ContiguousStorage /// The storage requirement means that for any value of `i` in `[0, nrows * ncols[`, the value /// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because /// failing to comply to this may cause Undefined Behaviors. -pub unsafe trait ContiguousStorageMut - : ContiguousStorage + StorageMut { +pub unsafe trait ContiguousStorageMut: + ContiguousStorage + StorageMut +{ } diff --git a/src/base/swizzle.rs b/src/base/swizzle.rs index e4ae9c9c..e1908e35 100644 --- a/src/base/swizzle.rs +++ b/src/base/swizzle.rs @@ -1,8 +1,7 @@ -use base::{Scalar, Vector, DimName, Vector2, Vector3}; +use base::{DimName, Scalar, Vector, Vector2, Vector3}; use storage::Storage; use typenum::{self, Cmp, Greater}; - macro_rules! impl_swizzle { ($(where $BaseDim: ident: $name: ident() -> $Result: ident[$($i: expr),*]);*) => { $( @@ -64,4 +63,4 @@ impl_swizzle!( where U2: zzx() -> Vector3[2, 2, 0]; where U2: zzy() -> Vector3[2, 2, 1]; where U2: zzz() -> Vector3[2, 2, 2] -); \ No newline at end of file +); diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs index 435585f7..94bf9abe 100644 --- a/src/geometry/isometry.rs +++ b/src/geometry/isometry.rs @@ -6,7 +6,7 @@ use std::io::{Result as IOResult, Write}; use std::marker::PhantomData; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; @@ -26,23 +26,19 @@ use geometry::{Point, Translation}; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "R: Serialize, + serde(bound( + serialize = "R: Serialize, DefaultAllocator: Allocator, Owned: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "R: Deserialize<'de>, + serde(bound( + deserialize = "R: Deserialize<'de>, DefaultAllocator: Allocator, Owned: Deserialize<'de>" - ) - ) + )) )] pub struct Isometry where @@ -54,7 +50,10 @@ where pub translation: Translation, // One dummy private field just to prevent explicit construction. - #[cfg_attr(feature = "serde-serialize", serde(skip_serializing, skip_deserializing))] + #[cfg_attr( + feature = "serde-serialize", + serde(skip_serializing, skip_deserializing) + )] _noconstruct: PhantomData, } @@ -98,8 +97,7 @@ impl> + Copy> Copy for Isome where DefaultAllocator: Allocator, Owned: Copy, -{ -} +{} impl> + Clone> Clone for Isometry where @@ -200,8 +198,7 @@ impl Eq for Isometry where R: Rotation> + Eq, DefaultAllocator: Allocator, -{ -} +{} impl PartialEq for Isometry where diff --git a/src/geometry/isometry_alga.rs b/src/geometry/isometry_alga.rs index 58ddc692..6a144550 100644 --- a/src/geometry/isometry_alga.rs +++ b/src/geometry/isometry_alga.rs @@ -1,9 +1,12 @@ -use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, - AbstractQuasigroup, AbstractSemigroup, Id, Identity, Inverse, Multiplicative, - Real}; +use alga::general::{ + AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, + AbstractSemigroup, Id, Identity, Inverse, Multiplicative, Real, +}; use alga::linear::Isometry as AlgaIsometry; -use alga::linear::{AffineTransformation, DirectIsometry, ProjectiveTransformation, Rotation, - Similarity, Transformation}; +use alga::linear::{ + AffineTransformation, DirectIsometry, ProjectiveTransformation, Rotation, Similarity, + Transformation, +}; use base::allocator::Allocator; use base::dimension::DimName; diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs index f125f9ed..af712461 100644 --- a/src/geometry/mod.rs +++ b/src/geometry/mod.rs @@ -4,61 +4,61 @@ mod op_macros; mod point; -mod point_construction; -mod point_alias; -mod point_ops; mod point_alga; +mod point_alias; +mod point_construction; mod point_conversion; mod point_coordinates; +mod point_ops; mod rotation; -mod rotation_construction; -mod rotation_ops; mod rotation_alga; // FIXME: implement Rotation methods. -mod rotation_conversion; mod rotation_alias; +mod rotation_construction; +mod rotation_conversion; +mod rotation_ops; mod rotation_specialization; mod quaternion; -mod quaternion_construction; -mod quaternion_ops; mod quaternion_alga; +mod quaternion_construction; mod quaternion_conversion; mod quaternion_coordinates; +mod quaternion_ops; mod unit_complex; -mod unit_complex_construction; -mod unit_complex_ops; mod unit_complex_alga; +mod unit_complex_construction; mod unit_complex_conversion; +mod unit_complex_ops; mod translation; -mod translation_construction; -mod translation_ops; mod translation_alga; -mod translation_conversion; mod translation_alias; +mod translation_construction; +mod translation_conversion; +mod translation_ops; mod isometry; -mod isometry_construction; -mod isometry_ops; mod isometry_alga; -mod isometry_conversion; mod isometry_alias; +mod isometry_construction; +mod isometry_conversion; +mod isometry_ops; mod similarity; -mod similarity_construction; -mod similarity_ops; mod similarity_alga; -mod similarity_conversion; mod similarity_alias; +mod similarity_construction; +mod similarity_conversion; +mod similarity_ops; mod transform; -mod transform_construction; -mod transform_ops; mod transform_alga; -mod transform_conversion; mod transform_alias; +mod transform_construction; +mod transform_conversion; +mod transform_ops; mod reflection; diff --git a/src/geometry/point.rs b/src/geometry/point.rs index 6b3e4d2d..4f26d632 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -7,7 +7,7 @@ use std::hash; use std::io::{Result as IOResult, Write}; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; @@ -42,8 +42,7 @@ impl Copy for Point where DefaultAllocator: Allocator, >::Buffer: Copy, -{ -} +{} impl Clone for Point where @@ -241,11 +240,7 @@ where } } -impl Eq for Point -where - DefaultAllocator: Allocator, -{ -} +impl Eq for Point where DefaultAllocator: Allocator {} impl PartialEq for Point where diff --git a/src/geometry/point_alga.rs b/src/geometry/point_alga.rs index e3bb32e0..5673d0df 100644 --- a/src/geometry/point_alga.rs +++ b/src/geometry/point_alga.rs @@ -1,9 +1,9 @@ use alga::general::{Field, JoinSemilattice, Lattice, MeetSemilattice, Real}; use alga::linear::{AffineSpace, EuclideanSpace}; -use base::{DefaultAllocator, Scalar, VectorN}; -use base::dimension::DimName; use base::allocator::Allocator; +use base::dimension::DimName; +use base::{DefaultAllocator, Scalar, VectorN}; use geometry::Point; diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index ccfd6af0..60c21f8d 100644 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -8,7 +8,7 @@ use std::io::{Result as IOResult, Write}; #[cfg(feature = "serde-serialize")] use base::storage::Owned; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; @@ -457,9 +457,11 @@ impl UnitQuaternion { /// is not well-defined). #[inline] pub fn slerp(&self, other: &UnitQuaternion, t: N) -> UnitQuaternion { - Unit::new_unchecked( - Quaternion::from_vector(Unit::new_unchecked(self.coords).slerp(&Unit::new_unchecked(other.coords), t).unwrap()) - ) + Unit::new_unchecked(Quaternion::from_vector( + Unit::new_unchecked(self.coords) + .slerp(&Unit::new_unchecked(other.coords), t) + .unwrap(), + )) } /// Computes the spherical linear interpolation between two unit quaternions or returns `None` @@ -479,7 +481,8 @@ impl UnitQuaternion { t: N, epsilon: N, ) -> Option> { - Unit::new_unchecked(self.coords).try_slerp(&Unit::new_unchecked(other.coords), t, epsilon) + Unit::new_unchecked(self.coords) + .try_slerp(&Unit::new_unchecked(other.coords), t, epsilon) .map(|q| Unit::new_unchecked(Quaternion::from_vector(q.unwrap()))) } diff --git a/src/geometry/quaternion_alga.rs b/src/geometry/quaternion_alga.rs index 44fa5143..4b926560 100644 --- a/src/geometry/quaternion_alga.rs +++ b/src/geometry/quaternion_alga.rs @@ -1,11 +1,15 @@ use num::Zero; -use alga::general::{AbstractGroup, AbstractGroupAbelian, AbstractLoop, AbstractMagma, - AbstractModule, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, - Additive, Id, Identity, Inverse, Module, Multiplicative, Real}; -use alga::linear::{AffineTransformation, DirectIsometry, FiniteDimVectorSpace, Isometry, - NormedSpace, OrthogonalTransformation, ProjectiveTransformation, Rotation, - Similarity, Transformation, VectorSpace}; +use alga::general::{ + AbstractGroup, AbstractGroupAbelian, AbstractLoop, AbstractMagma, AbstractModule, + AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Additive, Id, Identity, Inverse, Module, + Multiplicative, Real, +}; +use alga::linear::{ + AffineTransformation, DirectIsometry, FiniteDimVectorSpace, Isometry, NormedSpace, + OrthogonalTransformation, ProjectiveTransformation, Rotation, Similarity, Transformation, + VectorSpace, +}; use base::{Vector3, Vector4}; use geometry::{Point3, Quaternion, UnitQuaternion}; diff --git a/src/geometry/quaternion_ops.rs b/src/geometry/quaternion_ops.rs index b6144226..498a0def 100644 --- a/src/geometry/quaternion_ops.rs +++ b/src/geometry/quaternion_ops.rs @@ -50,15 +50,16 @@ * */ -use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, - SubAssign}; +use std::ops::{ + Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign, +}; use alga::general::Real; -use base::{DefaultAllocator, Unit, Vector, Vector3}; -use base::storage::Storage; use base::allocator::Allocator; use base::dimension::{U1, U3, U4}; +use base::storage::Storage; +use base::{DefaultAllocator, Unit, Vector, Vector3}; use geometry::{Point3, Quaternion, Rotation, UnitQuaternion}; diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs index 0ceaa73b..476c045f 100644 --- a/src/geometry/rotation.rs +++ b/src/geometry/rotation.rs @@ -6,7 +6,7 @@ use std::hash; use std::io::{Result as IOResult, Write}; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "serde-serialize")] use base::storage::Owned; @@ -44,8 +44,7 @@ impl Copy for Rotation where DefaultAllocator: Allocator, >::Buffer: Copy, -{ -} +{} impl Clone for Rotation where @@ -187,11 +186,7 @@ where } } -impl Eq for Rotation -where - DefaultAllocator: Allocator, -{ -} +impl Eq for Rotation where DefaultAllocator: Allocator {} impl PartialEq for Rotation where diff --git a/src/geometry/rotation_alga.rs b/src/geometry/rotation_alga.rs index 17e92bbf..b95a028b 100644 --- a/src/geometry/rotation_alga.rs +++ b/src/geometry/rotation_alga.rs @@ -1,12 +1,15 @@ -use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, - AbstractQuasigroup, AbstractSemigroup, Id, Identity, Inverse, Multiplicative, - Real}; -use alga::linear::{self, AffineTransformation, DirectIsometry, Isometry, OrthogonalTransformation, - ProjectiveTransformation, Similarity, Transformation}; +use alga::general::{ + AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, + AbstractSemigroup, Id, Identity, Inverse, Multiplicative, Real, +}; +use alga::linear::{ + self, AffineTransformation, DirectIsometry, Isometry, OrthogonalTransformation, + ProjectiveTransformation, Similarity, Transformation, +}; -use base::{DefaultAllocator, VectorN}; -use base::dimension::DimName; use base::allocator::Allocator; +use base::dimension::DimName; +use base::{DefaultAllocator, VectorN}; use geometry::{Point, Rotation}; diff --git a/src/geometry/rotation_construction.rs b/src/geometry/rotation_construction.rs index 14fa28b3..54cfc3c7 100644 --- a/src/geometry/rotation_construction.rs +++ b/src/geometry/rotation_construction.rs @@ -2,9 +2,9 @@ use num::{One, Zero}; use alga::general::{ClosedAdd, ClosedMul}; -use base::{DefaultAllocator, MatrixN, Scalar}; -use base::dimension::DimName; use base::allocator::Allocator; +use base::dimension::DimName; +use base::{DefaultAllocator, MatrixN, Scalar}; use geometry::Rotation; diff --git a/src/geometry/rotation_ops.rs b/src/geometry/rotation_ops.rs index 419830f2..0e5b20b7 100644 --- a/src/geometry/rotation_ops.rs +++ b/src/geometry/rotation_ops.rs @@ -17,16 +17,16 @@ * Matrix ×= Rotation */ -use std::ops::{Div, DivAssign, Index, Mul, MulAssign}; use num::{One, Zero}; +use std::ops::{Div, DivAssign, Index, Mul, MulAssign}; use alga::general::{ClosedAdd, ClosedMul}; -use base::{DefaultAllocator, Matrix, MatrixMN, Scalar, Unit, Vector, VectorN}; -use base::dimension::{Dim, DimName, U1}; -use base::constraint::{AreMultipliable, ShapeConstraint}; -use base::storage::Storage; use base::allocator::Allocator; +use base::constraint::{AreMultipliable, ShapeConstraint}; +use base::dimension::{Dim, DimName, U1}; +use base::storage::Storage; +use base::{DefaultAllocator, Matrix, MatrixMN, Scalar, Unit, Vector, VectorN}; use geometry::{Point, Rotation}; diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs index 46a9627a..d01a529d 100644 --- a/src/geometry/rotation_specialization.rs +++ b/src/geometry/rotation_specialization.rs @@ -5,7 +5,7 @@ use quickcheck::{Arbitrary, Gen}; use alga::general::Real; use num::Zero; -use rand::distributions::{Distribution, Standard, OpenClosed01}; +use rand::distributions::{Distribution, OpenClosed01, Standard}; use rand::Rng; use std::ops::Neg; @@ -329,7 +329,7 @@ impl Rotation3 { pub fn angle(&self) -> N { ((self.matrix()[(0, 0)] + self.matrix()[(1, 1)] + self.matrix()[(2, 2)] - N::one()) / ::convert(2.0)) - .acos() + .acos() } /// The rotation axis. Returns `None` if the rotation angle is zero or PI. @@ -398,9 +398,15 @@ where let theta = N::two_pi() * rng.sample(OpenClosed01); let (ts, tc) = theta.sin_cos(); let a = MatrixN::::new( - tc, ts, N::zero(), - -ts, tc, N::zero(), - N::zero(), N::zero(), N::one() + tc, + ts, + N::zero(), + -ts, + tc, + N::zero(), + N::zero(), + N::zero(), + N::one(), ); // Compute a random rotation *of* Z diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index c29a0209..cbf26a69 100644 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -5,7 +5,7 @@ use std::hash; use std::io::{Result as IOResult, Write}; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; @@ -25,25 +25,21 @@ use geometry::{Isometry, Point, Translation}; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "N: Serialize, + serde(bound( + serialize = "N: Serialize, R: Serialize, DefaultAllocator: Allocator, Owned: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "N: Deserialize<'de>, + serde(bound( + deserialize = "N: Deserialize<'de>, R: Deserialize<'de>, DefaultAllocator: Allocator, Owned: Deserialize<'de>" - ) - ) + )) )] pub struct Similarity where @@ -89,8 +85,7 @@ impl> + Copy> Copy for Simil where DefaultAllocator: Allocator, Owned: Copy, -{ -} +{} impl> + Clone> Clone for Similarity where @@ -276,8 +271,7 @@ impl Eq for Similarity where R: Rotation> + Eq, DefaultAllocator: Allocator, -{ -} +{} impl PartialEq for Similarity where diff --git a/src/geometry/similarity_alga.rs b/src/geometry/similarity_alga.rs index 8ad0e674..c416cad8 100644 --- a/src/geometry/similarity_alga.rs +++ b/src/geometry/similarity_alga.rs @@ -1,11 +1,13 @@ -use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, - AbstractQuasigroup, AbstractSemigroup, Identity, Inverse, Multiplicative, Real}; -use alga::linear::{AffineTransformation, ProjectiveTransformation, Rotation, Transformation}; +use alga::general::{ + AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, + AbstractSemigroup, Identity, Inverse, Multiplicative, Real, +}; use alga::linear::Similarity as AlgaSimilarity; +use alga::linear::{AffineTransformation, ProjectiveTransformation, Rotation, Transformation}; -use base::{DefaultAllocator, VectorN}; -use base::dimension::DimName; use base::allocator::Allocator; +use base::dimension::DimName; +use base::{DefaultAllocator, VectorN}; use geometry::{Point, Similarity, Translation}; diff --git a/src/geometry/similarity_ops.rs b/src/geometry/similarity_ops.rs index 92e77d08..7469c4cd 100644 --- a/src/geometry/similarity_ops.rs +++ b/src/geometry/similarity_ops.rs @@ -3,9 +3,9 @@ use std::ops::{Div, DivAssign, Mul, MulAssign}; use alga::general::Real; use alga::linear::Rotation as AlgaRotation; -use base::{DefaultAllocator, VectorN}; -use base::dimension::{DimName, U1, U3, U4}; use base::allocator::Allocator; +use base::dimension::{DimName, U1, U3, U4}; +use base::{DefaultAllocator, VectorN}; use geometry::{Isometry, Point, Rotation, Similarity, Translation, UnitQuaternion}; diff --git a/src/geometry/transform.rs b/src/geometry/transform.rs index 78a53829..4d7f8ba1 100644 --- a/src/geometry/transform.rs +++ b/src/geometry/transform.rs @@ -3,14 +3,14 @@ use std::fmt::Debug; use std::marker::PhantomData; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use alga::general::Real; -use base::{DefaultAllocator, MatrixN}; +use base::allocator::Allocator; use base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use base::storage::Owned; -use base::allocator::Allocator; +use base::{DefaultAllocator, MatrixN}; /// Trait implemented by phantom types identifying the projective transformation type. /// @@ -56,18 +56,15 @@ where /// Tag representing the most general (not necessarily inversible) `Transform` type. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum TGeneral { -} +pub enum TGeneral {} /// Tag representing the most general inversible `Transform` type. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum TProjective { -} +pub enum TProjective {} /// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum TAffine { -} +pub enum TAffine {} impl TCategory for TGeneral { #[inline] @@ -104,7 +101,8 @@ impl TCategory for TAffine { DefaultAllocator: Allocator, { let last = D::dim() - 1; - mat.is_invertible() && mat[(last, last)] == N::one() + mat.is_invertible() + && mat[(last, last)] == N::one() && (0..last).all(|i| mat[(last, i)].is_zero()) } } @@ -177,8 +175,7 @@ impl + Copy, C: TCategory> Copy for Transform, DimNameSum>, Owned, DimNameSum>: Copy, -{ -} +{} impl, C: TCategory> Clone for Transform where @@ -220,11 +217,9 @@ where } } -impl, C: TCategory> Eq for Transform -where - DefaultAllocator: Allocator, DimNameSum>, -{ -} +impl, C: TCategory> Eq for Transform where + DefaultAllocator: Allocator, DimNameSum> +{} impl, C: TCategory> PartialEq for Transform where diff --git a/src/geometry/transform_alga.rs b/src/geometry/transform_alga.rs index d01e61bf..652da373 100644 --- a/src/geometry/transform_alga.rs +++ b/src/geometry/transform_alga.rs @@ -1,10 +1,12 @@ -use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, - AbstractQuasigroup, AbstractSemigroup, Identity, Inverse, Multiplicative, Real}; +use alga::general::{ + AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, + AbstractSemigroup, Identity, Inverse, Multiplicative, Real, +}; use alga::linear::{ProjectiveTransformation, Transformation}; -use base::{DefaultAllocator, VectorN}; -use base::dimension::{DimNameAdd, DimNameSum, U1}; use base::allocator::Allocator; +use base::dimension::{DimNameAdd, DimNameSum, U1}; +use base::{DefaultAllocator, VectorN}; use geometry::{Point, SubTCategoryOf, TCategory, TProjective, Transform}; diff --git a/src/geometry/transform_construction.rs b/src/geometry/transform_construction.rs index 6d5bb135..1a7beba4 100644 --- a/src/geometry/transform_construction.rs +++ b/src/geometry/transform_construction.rs @@ -2,9 +2,9 @@ use num::One; use alga::general::Real; -use base::{DefaultAllocator, MatrixN}; -use base::dimension::{DimNameAdd, DimNameSum, U1}; use base::allocator::Allocator; +use base::dimension::{DimNameAdd, DimNameSum, U1}; +use base::{DefaultAllocator, MatrixN}; use geometry::{TCategory, Transform}; diff --git a/src/geometry/transform_ops.rs b/src/geometry/transform_ops.rs index 0e2b4826..6fc4ec32 100644 --- a/src/geometry/transform_ops.rs +++ b/src/geometry/transform_ops.rs @@ -3,13 +3,14 @@ use std::ops::{Div, DivAssign, Index, IndexMut, Mul, MulAssign}; use alga::general::{ClosedAdd, ClosedMul, Real, SubsetOf}; -use base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use base::allocator::Allocator; use base::dimension::{DimName, DimNameAdd, DimNameSum, U1, U3, U4}; +use base::{DefaultAllocator, MatrixN, Scalar, VectorN}; -use geometry::{Isometry, Point, Rotation, Similarity, SubTCategoryOf, SuperTCategoryOf, TAffine, - TCategory, TCategoryMul, TGeneral, TProjective, Transform, Translation, - UnitQuaternion}; +use geometry::{ + Isometry, Point, Rotation, Similarity, SubTCategoryOf, SuperTCategoryOf, TAffine, TCategory, + TCategoryMul, TGeneral, TProjective, Transform, Translation, UnitQuaternion, +}; /* * diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs index ddf7651c..33a0f349 100644 --- a/src/geometry/translation.rs +++ b/src/geometry/translation.rs @@ -6,7 +6,7 @@ use std::hash; use std::io::{Result as IOResult, Write}; #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; @@ -44,8 +44,7 @@ impl Copy for Translation where DefaultAllocator: Allocator, Owned: Copy, -{ -} +{} impl Clone for Translation where @@ -153,11 +152,7 @@ where } } -impl Eq for Translation -where - DefaultAllocator: Allocator, -{ -} +impl Eq for Translation where DefaultAllocator: Allocator {} impl PartialEq for Translation where diff --git a/src/geometry/translation_alga.rs b/src/geometry/translation_alga.rs index 296d6e17..ce095cc5 100644 --- a/src/geometry/translation_alga.rs +++ b/src/geometry/translation_alga.rs @@ -1,13 +1,16 @@ -use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, - AbstractQuasigroup, AbstractSemigroup, Id, Identity, Inverse, Multiplicative, - Real}; -use alga::linear::{AffineTransformation, DirectIsometry, Isometry, ProjectiveTransformation, - Similarity, Transformation}; +use alga::general::{ + AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, + AbstractSemigroup, Id, Identity, Inverse, Multiplicative, Real, +}; use alga::linear::Translation as AlgaTranslation; +use alga::linear::{ + AffineTransformation, DirectIsometry, Isometry, ProjectiveTransformation, Similarity, + Transformation, +}; -use base::{DefaultAllocator, VectorN}; -use base::dimension::DimName; use base::allocator::Allocator; +use base::dimension::DimName; +use base::{DefaultAllocator, VectorN}; use geometry::{Point, Translation}; diff --git a/src/geometry/translation_ops.rs b/src/geometry/translation_ops.rs index 639affdd..d124c763 100644 --- a/src/geometry/translation_ops.rs +++ b/src/geometry/translation_ops.rs @@ -2,10 +2,10 @@ use std::ops::{Div, DivAssign, Mul, MulAssign}; use alga::general::{ClosedAdd, ClosedSub}; -use base::{DefaultAllocator, Scalar}; -use base::dimension::{DimName, U1}; -use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use base::allocator::{Allocator, SameShapeAllocator}; +use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; +use base::dimension::{DimName, U1}; +use base::{DefaultAllocator, Scalar}; use geometry::{Point, Translation}; diff --git a/src/geometry/unit_complex_alga.rs b/src/geometry/unit_complex_alga.rs index bfc99202..d464ea56 100644 --- a/src/geometry/unit_complex_alga.rs +++ b/src/geometry/unit_complex_alga.rs @@ -1,12 +1,15 @@ -use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, - AbstractQuasigroup, AbstractSemigroup, Id, Identity, Inverse, Multiplicative, - Real}; -use alga::linear::{AffineTransformation, DirectIsometry, Isometry, OrthogonalTransformation, - ProjectiveTransformation, Rotation, Similarity, Transformation}; +use alga::general::{ + AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, + AbstractSemigroup, Id, Identity, Inverse, Multiplicative, Real, +}; +use alga::linear::{ + AffineTransformation, DirectIsometry, Isometry, OrthogonalTransformation, + ProjectiveTransformation, Rotation, Similarity, Transformation, +}; -use base::{DefaultAllocator, Vector2}; use base::allocator::Allocator; use base::dimension::U2; +use base::{DefaultAllocator, Vector2}; use geometry::{Point2, UnitComplex}; /* diff --git a/src/geometry/unit_complex_construction.rs b/src/geometry/unit_complex_construction.rs index 4b020789..82dd2e7d 100644 --- a/src/geometry/unit_complex_construction.rs +++ b/src/geometry/unit_complex_construction.rs @@ -3,7 +3,7 @@ use quickcheck::{Arbitrary, Gen}; use num::One; use num_complex::Complex; -use rand::distributions::{Distribution, Standard, OpenClosed01}; +use rand::distributions::{Distribution, OpenClosed01, Standard}; use rand::Rng; use alga::general::Real; diff --git a/src/linalg/bidiagonal.rs b/src/linalg/bidiagonal.rs index db340a9c..a5fd178d 100644 --- a/src/linalg/bidiagonal.rs +++ b/src/linalg/bidiagonal.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; use allocator::Allocator; @@ -15,31 +15,27 @@ use linalg::householder; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DimMinimum: DimSub, + serde(bound( + serialize = "DimMinimum: DimSub, DefaultAllocator: Allocator + Allocator> + Allocator, U1>>, MatrixMN: Serialize, VectorN>: Serialize, VectorN, U1>>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DimMinimum: DimSub, + serde(bound( + deserialize = "DimMinimum: DimSub, DefaultAllocator: Allocator + Allocator> + Allocator, U1>>, MatrixMN: Deserialize<'de>, VectorN>: Deserialize<'de>, VectorN, U1>>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct Bidiagonal, C: Dim> @@ -68,8 +64,7 @@ where MatrixMN: Copy, VectorN>: Copy, VectorN, U1>>: Copy, -{ -} +{} impl, C: Dim> Bidiagonal where diff --git a/src/linalg/cholesky.rs b/src/linalg/cholesky.rs index e6592227..9bf3cb18 100644 --- a/src/linalg/cholesky.rs +++ b/src/linalg/cholesky.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; @@ -13,21 +13,17 @@ use storage::{Storage, StorageMut}; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator, + serde(bound( + serialize = "DefaultAllocator: Allocator, MatrixN: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator, + serde(bound( + deserialize = "DefaultAllocator: Allocator, MatrixN: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct Cholesky @@ -41,8 +37,7 @@ impl Copy for Cholesky where DefaultAllocator: Allocator, MatrixN: Copy, -{ -} +{} impl> Cholesky where diff --git a/src/linalg/full_piv_lu.rs b/src/linalg/full_piv_lu.rs index 85079b17..a65ab5d0 100644 --- a/src/linalg/full_piv_lu.rs +++ b/src/linalg/full_piv_lu.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; use allocator::Allocator; @@ -15,25 +15,21 @@ use linalg::PermutationSequence; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator + + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator<(usize, usize), DimMinimum>, MatrixMN: Serialize, PermutationSequence>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator + + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator<(usize, usize), DimMinimum>, MatrixMN: Deserialize<'de>, PermutationSequence>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct FullPivLU, C: Dim> @@ -50,8 +46,7 @@ where DefaultAllocator: Allocator + Allocator<(usize, usize), DimMinimum>, MatrixMN: Copy, PermutationSequence>: Copy, -{ -} +{} impl, C: Dim> FullPivLU where diff --git a/src/linalg/hessenberg.rs b/src/linalg/hessenberg.rs index a831cc2e..d575a476 100644 --- a/src/linalg/hessenberg.rs +++ b/src/linalg/hessenberg.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; use allocator::Allocator; @@ -14,25 +14,21 @@ use linalg::householder; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator + + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator>, MatrixN: Serialize, VectorN>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator + + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator>, MatrixN: Deserialize<'de>, VectorN>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct Hessenberg> @@ -48,8 +44,7 @@ where DefaultAllocator: Allocator + Allocator>, MatrixN: Copy, VectorN>: Copy, -{ -} +{} impl> Hessenberg where diff --git a/src/linalg/inverse.rs b/src/linalg/inverse.rs index e00f4b8b..921234d7 100644 --- a/src/linalg/inverse.rs +++ b/src/linalg/inverse.rs @@ -1,9 +1,9 @@ use alga::general::Real; -use base::{DefaultAllocator, MatrixN, SquareMatrix}; +use base::allocator::Allocator; use base::dimension::Dim; use base::storage::{Storage, StorageMut}; -use base::allocator::Allocator; +use base::{DefaultAllocator, MatrixN, SquareMatrix}; use linalg::lu; @@ -129,52 +129,84 @@ where let m = m.data.as_slice(); out[(0, 0)] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] - + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10]; + + m[9] * m[7] * m[14] + + m[13] * m[6] * m[11] + - m[13] * m[7] * m[10]; out[(1, 0)] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10]; + - m[9] * m[3] * m[14] + - m[13] * m[2] * m[11] + + m[13] * m[3] * m[10]; out[(2, 0)] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] - + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6]; + + m[5] * m[3] * m[14] + + m[13] * m[2] * m[7] + - m[13] * m[3] * m[6]; out[(3, 0)] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6]; + - m[5] * m[3] * m[10] + - m[9] * m[2] * m[7] + + m[9] * m[3] * m[6]; out[(0, 1)] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10]; + - m[8] * m[7] * m[14] + - m[12] * m[6] * m[11] + + m[12] * m[7] * m[10]; out[(1, 1)] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] - + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10]; + + m[8] * m[3] * m[14] + + m[12] * m[2] * m[11] + - m[12] * m[3] * m[10]; out[(2, 1)] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6]; + - m[4] * m[3] * m[14] + - m[12] * m[2] * m[7] + + m[12] * m[3] * m[6]; out[(3, 1)] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] - + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6]; + + m[4] * m[3] * m[10] + + m[8] * m[2] * m[7] + - m[8] * m[3] * m[6]; out[(0, 2)] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] - + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9]; + + m[8] * m[7] * m[13] + + m[12] * m[5] * m[11] + - m[12] * m[7] * m[9]; out[(1, 2)] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9]; + - m[8] * m[3] * m[13] + - m[12] * m[1] * m[11] + + m[12] * m[3] * m[9]; out[(2, 2)] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] - + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5]; + + m[4] * m[3] * m[13] + + m[12] * m[1] * m[7] + - m[12] * m[3] * m[5]; out[(0, 3)] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9]; + - m[8] * m[6] * m[13] + - m[12] * m[5] * m[10] + + m[12] * m[6] * m[9]; out[(3, 2)] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5]; + - m[4] * m[3] * m[9] + - m[8] * m[1] * m[7] + + m[8] * m[3] * m[5]; out[(1, 3)] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] - + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9]; + + m[8] * m[2] * m[13] + + m[12] * m[1] * m[10] + - m[12] * m[2] * m[9]; out[(2, 3)] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5]; + - m[4] * m[2] * m[13] + - m[12] * m[1] * m[6] + + m[12] * m[2] * m[5]; out[(3, 3)] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] - + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5]; + + m[4] * m[2] * m[9] + + m[8] * m[1] * m[6] + - m[8] * m[2] * m[5]; let det = m[0] * out[(0, 0)] + m[1] * out[(0, 1)] + m[2] * out[(0, 2)] + m[3] * out[(0, 3)]; diff --git a/src/linalg/lu.rs b/src/linalg/lu.rs index 7707242b..2dccbc0b 100644 --- a/src/linalg/lu.rs +++ b/src/linalg/lu.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::{Field, Real}; use allocator::{Allocator, Reallocator}; @@ -15,25 +15,21 @@ use linalg::PermutationSequence; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator + + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator<(usize, usize), DimMinimum>, MatrixMN: Serialize, PermutationSequence>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator + + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator<(usize, usize), DimMinimum>, MatrixMN: Deserialize<'de>, PermutationSequence>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct LU, C: Dim> @@ -49,8 +45,7 @@ where DefaultAllocator: Allocator + Allocator<(usize, usize), DimMinimum>, MatrixMN: Copy, PermutationSequence>: Copy, -{ -} +{} /// Performs a LU decomposition to overwrite `out` with the inverse of `matrix`. /// diff --git a/src/linalg/mod.rs b/src/linalg/mod.rs index 04f7e3f8..4418b283 100644 --- a/src/linalg/mod.rs +++ b/src/linalg/mod.rs @@ -1,35 +1,35 @@ //! [Reexported at the root of this crate.] Factorization of real matrices. -mod solve; -mod determinant; -mod inverse; -pub mod householder; -pub mod givens; pub mod balancing; +mod bidiagonal; +mod cholesky; +mod determinant; +mod full_piv_lu; +pub mod givens; +mod hessenberg; +pub mod householder; +mod inverse; +mod lu; mod permutation_sequence; mod qr; -mod hessenberg; -mod bidiagonal; -mod symmetric_tridiagonal; -mod cholesky; -mod lu; -mod full_piv_lu; mod schur; +mod solve; mod svd; mod symmetric_eigen; +mod symmetric_tridiagonal; //// FIXME: Not complete enough for publishing. //// This handles only cases where each eigenvalue has multiplicity one. // mod eigen; -pub use self::permutation_sequence::*; -pub use self::qr::*; -pub use self::hessenberg::*; pub use self::bidiagonal::*; pub use self::cholesky::*; -pub use self::lu::*; pub use self::full_piv_lu::*; +pub use self::hessenberg::*; +pub use self::lu::*; +pub use self::permutation_sequence::*; +pub use self::qr::*; pub use self::schur::*; pub use self::svd::*; -pub use self::symmetric_tridiagonal::*; pub use self::symmetric_eigen::*; +pub use self::symmetric_tridiagonal::*; diff --git a/src/linalg/permutation_sequence.rs b/src/linalg/permutation_sequence.rs index b6818751..a6f555f9 100644 --- a/src/linalg/permutation_sequence.rs +++ b/src/linalg/permutation_sequence.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::ClosedNeg; use num::One; @@ -15,21 +15,17 @@ use storage::StorageMut; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator<(usize, usize), D>, + serde(bound( + serialize = "DefaultAllocator: Allocator<(usize, usize), D>, VectorN<(usize, usize), D>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator<(usize, usize), D>, + serde(bound( + deserialize = "DefaultAllocator: Allocator<(usize, usize), D>, VectorN<(usize, usize), D>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct PermutationSequence @@ -44,8 +40,7 @@ impl Copy for PermutationSequence where DefaultAllocator: Allocator<(usize, usize), D>, VectorN<(usize, usize), D>: Copy, -{ -} +{} impl PermutationSequence where diff --git a/src/linalg/qr.rs b/src/linalg/qr.rs index 0dea31a7..487a06a4 100644 --- a/src/linalg/qr.rs +++ b/src/linalg/qr.rs @@ -1,28 +1,36 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; +use allocator::{Allocator, Reallocator}; use base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Unit, VectorN}; +use constraint::{SameNumberOfRows, ShapeConstraint}; use dimension::{Dim, DimMin, DimMinimum, U1}; use storage::{Storage, StorageMut}; -use allocator::{Allocator, Reallocator}; -use constraint::{SameNumberOfRows, ShapeConstraint}; -use linalg::householder; use geometry::Reflection; +use linalg::householder; /// The QR decomposition of a general matrix. #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde-serialize", - serde(bound(serialize = "DefaultAllocator: Allocator + +#[cfg_attr( + feature = "serde-serialize", + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator>, MatrixMN: Serialize, - VectorN>: Serialize")))] -#[cfg_attr(feature = "serde-serialize", - serde(bound(deserialize = "DefaultAllocator: Allocator + + VectorN>: Serialize" + )) +)] +#[cfg_attr( + feature = "serde-serialize", + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator>, MatrixMN: Deserialize<'de>, - VectorN>: Deserialize<'de>")))] + VectorN>: Deserialize<'de>" + )) +)] #[derive(Clone, Debug)] pub struct QR, C: Dim> where @@ -37,8 +45,7 @@ where DefaultAllocator: Allocator + Allocator>, MatrixMN: Copy, VectorN>: Copy, -{ -} +{} impl, C: Dim> QR where @@ -132,8 +139,8 @@ where ) where DimMinimum: DimMin>, - DefaultAllocator: Allocator> - + Reallocator, C>, + DefaultAllocator: + Allocator> + Reallocator, C>, { (self.q(), self.unpack_r()) } diff --git a/src/linalg/schur.rs b/src/linalg/schur.rs index fd385512..0918bee9 100644 --- a/src/linalg/schur.rs +++ b/src/linalg/schur.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; use num_complex::Complex; @@ -19,21 +19,17 @@ use linalg::Hessenberg; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator, + serde(bound( + serialize = "DefaultAllocator: Allocator, MatrixN: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator, + serde(bound( + deserialize = "DefaultAllocator: Allocator, MatrixN: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct RealSchur @@ -48,8 +44,7 @@ impl Copy for RealSchur where DefaultAllocator: Allocator, MatrixN: Copy, -{ -} +{} impl RealSchur where @@ -180,10 +175,10 @@ 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), (U3, Dynamic::new(dim.value() - k))), + ); refl.reflect_rows( &mut t.generic_slice_mut((0, k), (Dynamic::new(krows), U3)), &mut work, @@ -214,10 +209,9 @@ 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), (U2, Dynamic::new(dim.value() - m))), + ); refl.reflect_rows( &mut t.generic_slice_mut((0, m), (Dynamic::new(end + 1), U2)), &mut work, @@ -236,10 +230,9 @@ where (start, start), (U2, Dynamic::new(dim.value() - start)), )); - rot.rotate_rows(&mut t.generic_slice_mut( - (0, start), - (Dynamic::new(end + 1), U2), - )); + rot.rotate_rows( + &mut t.generic_slice_mut((0, start), (Dynamic::new(end + 1), U2)), + ); t[(end, start)] = N::zero(); if let Some(ref mut q) = q { @@ -433,9 +426,11 @@ where )); } } - None => if compute_q { - q = Some(MatrixN::identity_generic(dim, dim)); - }, + None => { + if compute_q { + q = Some(MatrixN::identity_generic(dim, dim)); + } + } }; Some((q, m)) @@ -558,7 +553,8 @@ where N::default_epsilon(), 0, false, - ).unwrap(); + ) + .unwrap(); if RealSchur::do_eigenvalues(&schur.1, &mut work) { Some(work) } else { @@ -581,7 +577,8 @@ where N::default_epsilon(), 0, false, - ).unwrap(); + ) + .unwrap(); let mut eig = unsafe { VectorN::new_uninitialized_generic(dim, U1) }; RealSchur::do_complex_eigenvalues(&schur.1, &mut eig); eig diff --git a/src/linalg/svd.rs b/src/linalg/svd.rs index 43e2946e..3945af9c 100644 --- a/src/linalg/svd.rs +++ b/src/linalg/svd.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use num_complex::Complex; use std::ops::MulAssign; @@ -20,31 +20,27 @@ use linalg::Bidiagonal; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator + + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator> + Allocator, C> + Allocator>, MatrixMN>: Serialize, MatrixMN, C>: Serialize, VectorN>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator + + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator> + Allocator, C> + Allocator>, MatrixMN>: Deserialize<'de>, MatrixMN, C>: Deserialize<'de>, VectorN>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct SVD, C: Dim> @@ -69,8 +65,7 @@ where MatrixMN>: Copy, MatrixMN, C>: Copy, VectorN>: Copy, -{ -} +{} impl, C: Dim> SVD where @@ -489,7 +484,8 @@ where /// right- and left- singular vectors have not been computed at construction-time. pub fn recompose(self) -> MatrixMN { let mut u = self.u.expect("SVD recomposition: U has not been computed."); - let v_t = self.v_t + let v_t = self + .v_t .expect("SVD recomposition: V^t has not been computed."); for i in 0..self.singular_values.len() { @@ -545,10 +541,12 @@ where eps >= N::zero(), "SVD solve: the epsilon must be non-negative." ); - let u = self.u + let u = self + .u .as_ref() .expect("SVD solve: U has not been computed."); - let v_t = self.v_t + let v_t = self + .v_t .as_ref() .expect("SVD solve: V^t has not been computed."); diff --git a/src/linalg/symmetric_eigen.rs b/src/linalg/symmetric_eigen.rs index 1628f4ba..f1e7b026 100644 --- a/src/linalg/symmetric_eigen.rs +++ b/src/linalg/symmetric_eigen.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use num_complex::Complex; use std::ops::MulAssign; @@ -18,25 +18,21 @@ use linalg::SymmetricTridiagonal; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator + + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator, VectorN: Serialize, MatrixN: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator + + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator, VectorN: Deserialize<'de>, MatrixN: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct SymmetricEigen @@ -55,8 +51,7 @@ where DefaultAllocator: Allocator + Allocator, MatrixN: Copy, VectorN: Copy, -{ -} +{} impl SymmetricEigen where diff --git a/src/linalg/symmetric_tridiagonal.rs b/src/linalg/symmetric_tridiagonal.rs index a1af96d0..37d6b194 100644 --- a/src/linalg/symmetric_tridiagonal.rs +++ b/src/linalg/symmetric_tridiagonal.rs @@ -1,5 +1,5 @@ #[cfg(feature = "serde-serialize")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use alga::general::Real; use allocator::Allocator; @@ -13,25 +13,21 @@ use linalg::householder; #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - serialize = "DefaultAllocator: Allocator + + serde(bound( + serialize = "DefaultAllocator: Allocator + Allocator>, MatrixN: Serialize, VectorN>: Serialize" - ) - ) + )) )] #[cfg_attr( feature = "serde-serialize", - serde( - bound( - deserialize = "DefaultAllocator: Allocator + + serde(bound( + deserialize = "DefaultAllocator: Allocator + Allocator>, MatrixN: Deserialize<'de>, VectorN>: Deserialize<'de>" - ) - ) + )) )] #[derive(Clone, Debug)] pub struct SymmetricTridiagonal> @@ -47,8 +43,7 @@ where DefaultAllocator: Allocator + Allocator>, MatrixN: Copy, VectorN>: Copy, -{ -} +{} impl> SymmetricTridiagonal where diff --git a/src/sparse/cs_matrix.rs b/src/sparse/cs_matrix.rs new file mode 100644 index 00000000..f172bbee --- /dev/null +++ b/src/sparse/cs_matrix.rs @@ -0,0 +1,485 @@ +use alga::general::{ClosedAdd, ClosedMul}; +use num::{One, Zero}; +use std::marker::PhantomData; +use std::ops::{Add, Mul, Range}; + +use allocator::Allocator; +use constraint::{AreMultipliable, DimEq, ShapeConstraint}; +use storage::{Storage, StorageMut}; +use {DefaultAllocator, Dim, Matrix, MatrixMN, Scalar, Vector, VectorN, U1}; + +pub trait CsStorage { + fn shape(&self) -> (R, C); + fn nvalues(&self) -> usize; + unsafe fn row_index_unchecked(&self, i: usize) -> usize; + unsafe fn get_value_unchecked(&self, i: usize) -> &N; + fn get_value(&self, i: usize) -> &N; + fn row_index(&self, i: usize) -> usize; + fn column_range(&self, j: usize) -> Range; +} + +pub trait CsStorageMut: CsStorage { + /* + /// Sets the length of this column without initializing its values and row indices. + /// + /// If the given length is larger than the current one, uninitialized entries are + /// added at the end of the column `i`. This will effectively shift all the matrix entries + /// of the columns at indices `j` with `j > i`. Therefore this is a `O(n)` operation. + /// This is unsafe as the row indices on newly created components may end up being out + /// of bounds. + unsafe fn set_column_len(&mut self, i: usize, len: usize); + */ +} + +#[derive(Clone, Debug)] +pub struct CsVecStorage +where + DefaultAllocator: Allocator, +{ + shape: (R, C), + p: VectorN, + i: Vec, + vals: Vec, +} + +impl CsStorage for CsVecStorage +where + DefaultAllocator: Allocator, +{ + #[inline] + fn shape(&self) -> (R, C) { + self.shape + } + + #[inline] + fn nvalues(&self) -> usize { + self.vals.len() + } + + #[inline] + fn column_range(&self, j: usize) -> Range { + let end = if j + 1 == self.p.len() { + self.nvalues() + } else { + self.p[j + 1] + }; + + self.p[j]..end + } + + #[inline] + fn row_index(&self, i: usize) -> usize { + self.i[i] + } + + #[inline] + unsafe fn row_index_unchecked(&self, i: usize) -> usize { + *self.i.get_unchecked(i) + } + + #[inline] + unsafe fn get_value_unchecked(&self, i: usize) -> &N { + self.vals.get_unchecked(i) + } + + #[inline] + fn get_value(&self, i: usize) -> &N { + &self.vals[i] + } +} + +/* +pub struct CsSliceStorage<'a, N: Scalar, R: Dim, C: DimAdd> { + shape: (R, C), + p: VectorSlice>, + i: VectorSlice, + vals: VectorSlice, +}*/ + +/// A compressed sparse column matrix. +#[derive(Clone, Debug)] +pub struct CsMatrix = CsVecStorage> { + pub data: S, + _phantoms: PhantomData<(N, R, C)>, +} + +pub type CsVector = CsMatrix; + +impl CsMatrix +where + DefaultAllocator: Allocator, +{ + pub fn new_uninitialized_generic(nrows: R, ncols: C, nvals: usize) -> Self { + let mut i = Vec::with_capacity(nvals); + unsafe { + i.set_len(nvals); + } + i.shrink_to_fit(); + + let mut vals = Vec::with_capacity(nvals); + unsafe { + vals.set_len(nvals); + } + vals.shrink_to_fit(); + + CsMatrix { + data: CsVecStorage { + shape: (nrows, ncols), + p: unsafe { VectorN::new_uninitialized_generic(ncols, U1) }, + i, + vals, + }, + _phantoms: PhantomData, + } + } +} + +fn cumsum(a: &mut VectorN, b: &mut VectorN) -> usize +where + DefaultAllocator: Allocator, +{ + assert!(a.len() == b.len()); + let mut sum = 0; + + for i in 0..a.len() { + b[i] = sum; + sum += a[i]; + a[i] = b[i]; + } + + sum +} + +impl> CsMatrix { + pub fn nvalues(&self) -> usize { + self.data.nvalues() + } + + pub fn transpose(&self) -> CsMatrix + where + DefaultAllocator: Allocator, + { + let (nrows, ncols) = self.data.shape(); + + let nvals = self.nvalues(); + let mut res = CsMatrix::new_uninitialized_generic(ncols, nrows, nvals); + let mut workspace = Vector::zeros_generic(nrows, U1); + + // Compute p. + for i in 0..nvals { + let row_id = self.data.row_index(i); + workspace[row_id] += 1; + } + + let _ = cumsum(&mut workspace, &mut res.data.p); + + // Fill the result. + for j in 0..ncols.value() { + let column_idx = self.data.column_range(j); + + for vi in column_idx { + let row_id = self.data.row_index(vi); + let shift = workspace[row_id]; + + res.data.vals[shift] = *self.data.get_value(vi); + res.data.i[shift] = j; + workspace[row_id] += 1; + } + } + + res + } + + fn scatter( + &self, + j: usize, + beta: N, + timestamps: &mut [usize], + timestamp: usize, + workspace: &mut [N], + mut nz: usize, + res: &mut CsMatrix, + ) -> usize + where + N: ClosedAdd + ClosedMul, + DefaultAllocator: Allocator, + { + let column_idx = self.data.column_range(j); + + for vi in column_idx { + let i = self.data.row_index(vi); + let val = beta * *self.data.get_value(vi); + + if timestamps[i] < timestamp { + timestamps[i] = timestamp; + res.data.i[nz] = i; + nz += 1; + workspace[i] = val; + } else { + workspace[i] += val; + } + } + + nz + } +} + +/* +impl CsVector { + pub fn axpy(&mut self, alpha: N, x: CsVector, beta: N) { + // First, compute the number of non-zero entries. + let mut nnzero = 0; + + // Allocate a size large enough. + self.data.set_column_len(0, nnzero); + + // Fill with the axpy. + let mut i = self.nvalues(); + let mut j = x.nvalues(); + let mut k = nnzero - 1; + let mut rid1 = self.data.row_index(0, i - 1); + let mut rid2 = x.data.row_index(0, j - 1); + + while k > 0 { + if rid1 == rid2 { + self.data.set_row_index(0, k, rid1); + self[k] = alpha * x[j] + beta * self[k]; + i -= 1; + j -= 1; + } else if rid1 < rid2 { + self.data.set_row_index(0, k, rid1); + self[k] = beta * self[i]; + i -= 1; + } else { + self.data.set_row_index(0, k, rid2); + self[k] = alpha * x[j]; + j -= 1; + } + + k -= 1; + } + } +} +*/ + +impl> Vector { + pub fn axpy_cs(&mut self, alpha: N, x: &CsVector, beta: N) + where + S2: CsStorage, + ShapeConstraint: DimEq, + { + if beta.is_zero() { + for i in 0..x.nvalues() { + unsafe { + let k = x.data.row_index_unchecked(i); + let y = self.vget_unchecked_mut(k); + *y = alpha * *x.data.get_value_unchecked(i); + } + } + } else { + for i in 0..x.nvalues() { + unsafe { + let k = x.data.row_index_unchecked(i); + let y = self.vget_unchecked_mut(k); + *y = alpha * *x.data.get_value_unchecked(i) + beta * *y; + } + } + } + } + + /* + pub fn gemv_sparse(&mut self, alpha: N, a: &CsMatrix, x: &DVector, beta: N) + where + S2: CsStorage { + let col2 = a.column(0); + let val = unsafe { *x.vget_unchecked(0) }; + self.axpy_sparse(alpha * val, &col2, beta); + + for j in 1..ncols2 { + let col2 = a.column(j); + let val = unsafe { *x.vget_unchecked(j) }; + + self.axpy_sparse(alpha * val, &col2, N::one()); + } + } + */ +} + +impl<'a, 'b, N, R1, R2, C1, C2, S1, S2> Mul<&'b CsMatrix> + for &'a CsMatrix +where + N: Scalar + ClosedAdd + ClosedMul + Zero, + R1: Dim, + C1: Dim, + R2: Dim, + C2: Dim, + S1: CsStorage, + S2: CsStorage, + ShapeConstraint: AreMultipliable, + DefaultAllocator: Allocator + Allocator + Allocator, +{ + type Output = CsMatrix; + + fn mul(self, rhs: &'b CsMatrix) -> CsMatrix { + let (nrows1, ncols1) = self.data.shape(); + let (nrows2, ncols2) = rhs.data.shape(); + assert_eq!( + ncols1.value(), + nrows2.value(), + "Mismatched dimensions for matrix multiplication." + ); + + let mut res = + CsMatrix::new_uninitialized_generic(nrows1, ncols2, self.nvalues() + rhs.nvalues()); + let mut timestamps = VectorN::zeros_generic(nrows1, U1); + let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, U1) }; + let mut nz = 0; + + for j in 0..ncols2.value() { + res.data.p[j] = nz; + let column_idx = rhs.data.column_range(j); + let new_size_bound = nz + nrows1.value(); + res.data.i.resize(new_size_bound, 0); + res.data.vals.resize(new_size_bound, N::zero()); + + for vi in column_idx { + let i = rhs.data.row_index(vi); + nz = self.scatter( + i, + *rhs.data.get_value(vi), + timestamps.as_mut_slice(), + j + 1, + workspace.as_mut_slice(), + nz, + &mut res, + ); + } + + for p in res.data.p[j]..nz { + res.data.vals[p] = workspace[res.data.i[p]] + } + } + + res.data.i.truncate(nz); + res.data.i.shrink_to_fit(); + res.data.vals.truncate(nz); + res.data.vals.shrink_to_fit(); + res + } +} + +impl<'a, 'b, N, R1, R2, C1, C2, S1, S2> Add<&'b CsMatrix> + for &'a CsMatrix +where + N: Scalar + ClosedAdd + ClosedMul + One, + R1: Dim, + C1: Dim, + R2: Dim, + C2: Dim, + S1: CsStorage, + S2: CsStorage, + ShapeConstraint: DimEq + DimEq, + DefaultAllocator: Allocator + Allocator + Allocator, +{ + type Output = CsMatrix; + + fn add(self, rhs: &'b CsMatrix) -> CsMatrix { + let (nrows1, ncols1) = self.data.shape(); + let (nrows2, ncols2) = rhs.data.shape(); + assert_eq!( + (nrows1.value(), ncols1.value()), + (nrows2.value(), ncols2.value()), + "Mismatched dimensions for matrix sum." + ); + + let mut res = + CsMatrix::new_uninitialized_generic(nrows1, ncols2, self.nvalues() + rhs.nvalues()); + let mut timestamps = VectorN::zeros_generic(nrows1, U1); + let mut workspace = unsafe { VectorN::new_uninitialized_generic(nrows1, U1) }; + let mut nz = 0; + + for j in 0..ncols2.value() { + res.data.p[j] = nz; + + nz = self.scatter( + j, + N::one(), + timestamps.as_mut_slice(), + j + 1, + workspace.as_mut_slice(), + nz, + &mut res, + ); + + nz = rhs.scatter( + j, + N::one(), + timestamps.as_mut_slice(), + j + 1, + workspace.as_mut_slice(), + nz, + &mut res, + ); + + for p in res.data.p[j]..nz { + res.data.vals[p] = workspace[res.data.i[p]] + } + } + + res.data.i.truncate(nz); + res.data.i.shrink_to_fit(); + res.data.vals.truncate(nz); + res.data.vals.shrink_to_fit(); + res + } +} + +impl<'a, N: Scalar + Zero, R: Dim, C: Dim, S> From> for MatrixMN +where + S: CsStorage, + DefaultAllocator: Allocator, +{ + fn from(m: CsMatrix) -> Self { + let (nrows, ncols) = m.data.shape(); + let mut res = MatrixMN::zeros_generic(nrows, ncols); + + for j in 0..ncols.value() { + let column_idx = m.data.column_range(j); + + for iv in column_idx { + let i = m.data.row_index(iv); + res[(i, j)] = *m.data.get_value(iv); + } + } + + res + } +} + +impl<'a, N: Scalar + Zero, R: Dim, C: Dim, S> From> for CsMatrix +where + S: Storage, + DefaultAllocator: Allocator + Allocator, +{ + fn from(m: Matrix) -> Self { + let (nrows, ncols) = m.data.shape(); + let nvalues = m.iter().filter(|e| !e.is_zero()).count(); + let mut res = CsMatrix::new_uninitialized_generic(nrows, ncols, nvalues); + let mut nz = 0; + + for j in 0..ncols.value() { + let column = m.column(j); + res.data.p[j] = nz; + + for i in 0..nrows.value() { + if !column[i].is_zero() { + res.data.i[nz] = i; + res.data.vals[nz] = column[i]; + nz += 1; + } + } + } + + res + } +} diff --git a/src/sparse/mod.rs b/src/sparse/mod.rs new file mode 100644 index 00000000..f859e97f --- /dev/null +++ b/src/sparse/mod.rs @@ -0,0 +1,3 @@ +pub use self::cs_matrix::CsMatrix; + +mod cs_matrix; diff --git a/tests/core/abomonation.rs b/tests/core/abomonation.rs index ac53716b..be3952cd 100644 --- a/tests/core/abomonation.rs +++ b/tests/core/abomonation.rs @@ -1,9 +1,9 @@ -use rand::random; -use abomonation::{Abomonation, encode, decode}; +use abomonation::{decode, encode, Abomonation}; use na::{ - DMatrix, Matrix3x4, Point3, Translation3, Rotation3, Isometry3, Quaternion, - IsometryMatrix3, Similarity3, SimilarityMatrix3 + DMatrix, Isometry3, IsometryMatrix3, Matrix3x4, Point3, Quaternion, Rotation3, Similarity3, + SimilarityMatrix3, Translation3, }; +use rand::random; #[test] fn abomonate_dmatrix() { @@ -39,7 +39,9 @@ fn assert_encode_and_decode(original_data: T // Encode let mut bytes = Vec::new(); - unsafe { encode(&original_data, &mut bytes); } + unsafe { + encode(&original_data, &mut bytes); + } // Drop the original, so that dangling pointers are revealed by the test drop(original_data); diff --git a/tests/core/blas.rs b/tests/core/blas.rs index e37cb049..00eac3a3 100644 --- a/tests/core/blas.rs +++ b/tests/core/blas.rs @@ -1,7 +1,7 @@ #![cfg(feature = "arbitrary")] +use na::{DMatrix, DVector}; use std::cmp; -use na::{DVector, DMatrix}; quickcheck! { /* diff --git a/tests/core/conversion.rs b/tests/core/conversion.rs index 175c6f2b..f8be8588 100644 --- a/tests/core/conversion.rs +++ b/tests/core/conversion.rs @@ -1,18 +1,13 @@ #![cfg(feature = "arbitrary")] use alga::linear::Transformation; use na::{ - self, + self, Affine3, Isometry3, Matrix2, Matrix2x3, Matrix2x4, Matrix2x5, Matrix2x6, Matrix3, + Matrix3x2, Matrix3x4, Matrix3x5, Matrix3x6, Matrix4, Matrix4x2, Matrix4x3, Matrix4x5, + Matrix4x6, Matrix5, Matrix5x2, Matrix5x3, Matrix5x4, Matrix5x6, Matrix6, Matrix6x2, Matrix6x3, + Matrix6x4, Matrix6x5, Point3, Projective3, Rotation3, RowVector1, RowVector2, RowVector3, + RowVector4, RowVector5, RowVector6, Similarity3, Transform3, Translation3, UnitQuaternion, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, - RowVector1, RowVector2, RowVector3, RowVector4, RowVector5, RowVector6, - Matrix2, Matrix3, Matrix4, Matrix5, Matrix6, - Matrix2x3, Matrix2x4, Matrix2x5, Matrix2x6, - Matrix3x2, Matrix3x4, Matrix3x5, Matrix3x6, - Matrix4x2, Matrix4x3, Matrix4x5, Matrix4x6, - Matrix5x2, Matrix5x3, Matrix5x4, Matrix5x6, - Matrix6x2, Matrix6x3, Matrix6x4, Matrix6x5, - Point3, Translation3, Isometry3, Similarity3, Affine3, - Projective3, Transform3, Rotation3, UnitQuaternion}; - +}; quickcheck!{ fn translation_conversion(t: Translation3, v: Vector3, p: Point3) -> bool { diff --git a/tests/core/mod.rs b/tests/core/mod.rs index e8bac456..7e1f8591 100644 --- a/tests/core/mod.rs +++ b/tests/core/mod.rs @@ -1,10 +1,10 @@ +#[cfg(feature = "abomonation-serialize")] +mod abomonation; +mod blas; mod conversion; mod edition; mod matrix; mod matrix_slice; -mod blas; -mod serde; -#[cfg(feature = "abomonation-serialize")] -mod abomonation; #[cfg(feature = "mint")] mod mint; +mod serde; diff --git a/tests/core/serde.rs b/tests/core/serde.rs index 14456eac..a65ca8b3 100644 --- a/tests/core/serde.rs +++ b/tests/core/serde.rs @@ -1,20 +1,11 @@ #![cfg(feature = "serde-serialize")] -use serde_json; -use rand; use na::{ - DMatrix, - Matrix3x4, - Point3, - Translation3, - Rotation3, - Isometry3, - IsometryMatrix3, - Similarity3, - SimilarityMatrix3, - Quaternion, - Unit, + DMatrix, Isometry3, IsometryMatrix3, Matrix3x4, Point3, Quaternion, Rotation3, Similarity3, + SimilarityMatrix3, Translation3, Unit, }; +use rand; +use serde_json; macro_rules! test_serde( ($($test: ident, $ty: ident);* $(;)*) => {$( diff --git a/tests/geometry/isometry.rs b/tests/geometry/isometry.rs index f7226bbf..c72a2475 100644 --- a/tests/geometry/isometry.rs +++ b/tests/geometry/isometry.rs @@ -1,10 +1,10 @@ #![cfg(feature = "arbitrary")] #![allow(non_snake_case)] -use alga::linear::{Transformation, ProjectiveTransformation}; +use alga::linear::{ProjectiveTransformation, Transformation}; use na::{ - Vector3, Point3, Rotation3, Isometry3, Translation3, UnitQuaternion, - Vector2, Point2, Rotation2, Isometry2, Translation2, UnitComplex + Isometry2, Isometry3, Point2, Point3, Rotation2, Rotation3, Translation2, Translation3, + UnitComplex, UnitQuaternion, Vector2, Vector3, }; quickcheck!( diff --git a/tests/geometry/point.rs b/tests/geometry/point.rs index 1b673f92..90c51587 100644 --- a/tests/geometry/point.rs +++ b/tests/geometry/point.rs @@ -1,6 +1,6 @@ #![cfg(feature = "arbitrary")] -use num::Zero; use na::{Point3, Vector3, Vector4}; +use num::Zero; #[test] fn point_ops() { @@ -8,20 +8,20 @@ fn point_ops() { let b = Point3::new(1.0, 2.0, 3.0); let c = Vector3::new(1.0, 2.0, 3.0); - assert_eq!( a - b, Vector3::zero()); + assert_eq!(a - b, Vector3::zero()); assert_eq!(&a - &b, Vector3::zero()); - assert_eq!( a - &b, Vector3::zero()); - assert_eq!(&a - b, Vector3::zero()); + assert_eq!(a - &b, Vector3::zero()); + assert_eq!(&a - b, Vector3::zero()); - assert_eq!( b - c, Point3::origin()); + assert_eq!(b - c, Point3::origin()); assert_eq!(&b - &c, Point3::origin()); - assert_eq!( b - &c, Point3::origin()); - assert_eq!(&b - c, Point3::origin()); + assert_eq!(b - &c, Point3::origin()); + assert_eq!(&b - c, Point3::origin()); - assert_eq!( b + c, 2.0 * a); + assert_eq!(b + c, 2.0 * a); assert_eq!(&b + &c, 2.0 * a); - assert_eq!( b + &c, 2.0 * a); - assert_eq!(&b + c, 2.0 * a); + assert_eq!(b + &c, 2.0 * a); + assert_eq!(&b + c, 2.0 * a); let mut a1 = a; let mut a2 = a; @@ -58,20 +58,19 @@ fn point_coordinates() { #[test] fn point_scale() { - let pt = Point3::new(1, 2, 3); + let pt = Point3::new(1, 2, 3); let expected = Point3::new(10, 20, 30); assert_eq!(pt * 10, expected); assert_eq!(&pt * 10, expected); assert_eq!(10 * pt, expected); assert_eq!(10 * &pt, expected); - } #[test] fn point_vector_sum() { - let pt = Point3::new(1, 2, 3); - let vec = Vector3::new(10, 20, 30); + let pt = Point3::new(1, 2, 3); + let vec = Vector3::new(10, 20, 30); let expected = Point3::new(11, 22, 33); assert_eq!(&pt + &vec, expected); @@ -82,15 +81,13 @@ fn point_vector_sum() { #[test] fn to_homogeneous() { - let a = Point3::new(1.0, 2.0, 3.0); + let a = Point3::new(1.0, 2.0, 3.0); let expected = Vector4::new(1.0, 2.0, 3.0, 1.0); assert_eq!(a.to_homogeneous(), expected); } -quickcheck!( - fn point_sub(pt1: Point3, pt2: Point3) -> bool { - let dpt = &pt2 - &pt1; - relative_eq!(pt2, pt1 + dpt, epsilon = 1.0e-7) - } -); +quickcheck!(fn point_sub(pt1: Point3, pt2: Point3) -> bool { + let dpt = &pt2 - &pt1; + relative_eq!(pt2, pt1 + dpt, epsilon = 1.0e-7) +}); diff --git a/tests/geometry/projection.rs b/tests/geometry/projection.rs index 7be0d49d..17d04a13 100644 --- a/tests/geometry/projection.rs +++ b/tests/geometry/projection.rs @@ -1,9 +1,9 @@ -use na::{Perspective3, Orthographic3}; +use na::{Orthographic3, Perspective3}; #[test] fn perspective_inverse() { let proj = Perspective3::new(800.0 / 600.0, 3.14 / 2.0, 1.0, 1000.0); - let inv = proj.inverse(); + let inv = proj.inverse(); let id = inv * proj.unwrap(); @@ -13,17 +13,16 @@ fn perspective_inverse() { #[test] fn orthographic_inverse() { let proj = Orthographic3::new(1.0, 2.0, -3.0, -2.5, 10.0, 900.0); - let inv = proj.inverse(); + let inv = proj.inverse(); let id = inv * proj.unwrap(); assert!(id.is_identity(1.0e-7)); } - #[cfg(feature = "arbitrary")] mod quickcheck_tests { - use na::{Point3, Perspective3, Orthographic3}; + use na::{Orthographic3, Perspective3, Point3}; quickcheck!{ fn perspective_project_unproject(pt: Point3) -> bool { diff --git a/tests/geometry/quaternion.rs b/tests/geometry/quaternion.rs index 927835e2..c5b91554 100644 --- a/tests/geometry/quaternion.rs +++ b/tests/geometry/quaternion.rs @@ -1,8 +1,7 @@ #![cfg(feature = "arbitrary")] #![allow(non_snake_case)] -use na::{Unit, UnitQuaternion, Quaternion, Vector3, Point3, Rotation3}; - +use na::{Point3, Quaternion, Rotation3, Unit, UnitQuaternion, Vector3}; quickcheck!( /* diff --git a/tests/geometry/rotation.rs b/tests/geometry/rotation.rs index a2e91dec..9bd3e590 100644 --- a/tests/geometry/rotation.rs +++ b/tests/geometry/rotation.rs @@ -18,9 +18,9 @@ fn angle_3() { #[cfg(feature = "arbitrary")] mod quickcheck_tests { - use std::f64; use alga::general::Real; - use na::{self, Vector2, Vector3, Rotation2, Rotation3, Unit}; + use na::{self, Rotation2, Rotation3, Unit, Vector2, Vector3}; + use std::f64; quickcheck! { /* diff --git a/tests/geometry/similarity.rs b/tests/geometry/similarity.rs index feb8ba1b..e9fde466 100644 --- a/tests/geometry/similarity.rs +++ b/tests/geometry/similarity.rs @@ -1,8 +1,8 @@ #![cfg(feature = "arbitrary")] #![allow(non_snake_case)] -use alga::linear::{Transformation, ProjectiveTransformation}; -use na::{Vector3, Point3, Similarity3, Translation3, Isometry3, UnitQuaternion}; +use alga::linear::{ProjectiveTransformation, Transformation}; +use na::{Isometry3, Point3, Similarity3, Translation3, UnitQuaternion, Vector3}; quickcheck!( fn inverse_is_identity(i: Similarity3, p: Point3, v: Vector3) -> bool { diff --git a/tests/geometry/unit_complex.rs b/tests/geometry/unit_complex.rs index 65837d8b..7da0d20c 100644 --- a/tests/geometry/unit_complex.rs +++ b/tests/geometry/unit_complex.rs @@ -1,7 +1,7 @@ #![cfg(feature = "arbitrary")] #![allow(non_snake_case)] -use na::{Unit, UnitComplex, Vector2, Point2, Rotation2}; +use na::{Point2, Rotation2, Unit, UnitComplex, Vector2}; quickcheck!( diff --git a/tests/lib.rs b/tests/lib.rs index a2238f1e..c32f4066 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -14,5 +14,7 @@ extern crate rand; extern crate serde_json; mod core; -mod linalg; mod geometry; +mod linalg; +#[cfg(feature = "sparse")] +mod sparse; diff --git a/tests/linalg/balancing.rs b/tests/linalg/balancing.rs index 73fd8230..401f672a 100644 --- a/tests/linalg/balancing.rs +++ b/tests/linalg/balancing.rs @@ -2,8 +2,8 @@ use std::cmp; -use na::{DMatrix, Matrix4}; use na::balancing; +use na::{DMatrix, Matrix4}; quickcheck! { fn balancing_parlett_reinsch(n: usize) -> bool { diff --git a/tests/linalg/bidiagonal.rs b/tests/linalg/bidiagonal.rs index a96ce47c..a7d5952f 100644 --- a/tests/linalg/bidiagonal.rs +++ b/tests/linalg/bidiagonal.rs @@ -1,6 +1,6 @@ #![cfg(feature = "arbitrary")] -use na::{DMatrix, Matrix2, Matrix4, Matrix5x3, Matrix3x5}; +use na::{DMatrix, Matrix2, Matrix3x5, Matrix4, Matrix5x3}; quickcheck! { fn bidiagonal(m: DMatrix) -> bool { diff --git a/tests/linalg/cholesky.rs b/tests/linalg/cholesky.rs index df213ad4..9fe086ff 100644 --- a/tests/linalg/cholesky.rs +++ b/tests/linalg/cholesky.rs @@ -1,9 +1,9 @@ #![cfg(all(feature = "arbitrary", feature = "debug"))] -use std::cmp; -use na::{DMatrix, Matrix4x3, DVector, Vector4}; -use na::dimension::U4; use na::debug::RandomSDP; +use na::dimension::U4; +use na::{DMatrix, DVector, Matrix4x3, Vector4}; +use std::cmp; quickcheck! { fn cholesky(m: RandomSDP) -> bool { diff --git a/tests/linalg/eigen.rs b/tests/linalg/eigen.rs index ceb44bdf..f609292a 100644 --- a/tests/linalg/eigen.rs +++ b/tests/linalg/eigen.rs @@ -2,8 +2,8 @@ use na::DMatrix; #[cfg(feature = "arbitrary")] mod quickcheck_tests { - use std::cmp; use na::{DMatrix, Matrix2, Matrix3, Matrix4}; + use std::cmp; quickcheck! { fn symmetric_eigen(n: usize) -> bool { @@ -62,39 +62,58 @@ mod quickcheck_tests { // Test proposed on the issue #176 of rulinalg. #[test] fn symmetric_eigen_singular_24x24() { - let m = DMatrix::from_row_slice(24, 24, &[ - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, - 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]); + let m = DMatrix::from_row_slice( + 24, + 24, + &[ + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, + 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, + -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, + 0.0, 1.0, 1.0, 1.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, + ], + ); let eig = m.clone().symmetric_eigen(); let recomp = eig.recompose(); - assert!(relative_eq!(m.lower_triangle(), recomp.lower_triangle(), epsilon = 1.0e-5)); + assert!(relative_eq!( + m.lower_triangle(), + recomp.lower_triangle(), + epsilon = 1.0e-5 + )); } - // #[cfg(feature = "arbitrary")] // quickcheck! { // FIXME: full eigendecomposition is not implemented yet because of its complexity when some @@ -167,16 +186,16 @@ fn symmetric_eigen_singular_24x24() { // MatrixN: Display, // VectorN: Display { // let mv = &m * &eig.eigenvectors; -// +// // println!("eigenvalues: {}eigenvectors: {}", eig.eigenvalues, eig.eigenvectors); -// +// // let dim = m.nrows(); // for i in 0 .. dim { // let mut col = eig.eigenvectors.column_mut(i); // col *= eig.eigenvalues[i]; // } -// +// // println!("{}{:.5}{:.5}", m, mv, eig.eigenvectors); -// +// // relative_eq!(eig.eigenvectors, mv, epsilon = 1.0e-5) // } diff --git a/tests/linalg/hessenberg.rs b/tests/linalg/hessenberg.rs index 67206487..22d62fbf 100644 --- a/tests/linalg/hessenberg.rs +++ b/tests/linalg/hessenberg.rs @@ -1,12 +1,11 @@ #![cfg(feature = "arbitrary")] -use std::cmp; use na::{DMatrix, Matrix2, Matrix4}; +use std::cmp; #[test] fn hessenberg_simple() { - let m = Matrix2::new(1.0, 0.0, - 1.0, 3.0); + let m = Matrix2::new(1.0, 0.0, 1.0, 3.0); let hess = m.hessenberg(); let (p, h) = hess.unpack(); assert!(relative_eq!(m, p * h * p.transpose(), epsilon = 1.0e-7)) diff --git a/tests/linalg/mod.rs b/tests/linalg/mod.rs index 6ce28085..74a5e03c 100644 --- a/tests/linalg/mod.rs +++ b/tests/linalg/mod.rs @@ -1,13 +1,13 @@ -mod inverse; -mod solve; -mod qr; -mod cholesky; -mod hessenberg; -mod lu; -mod full_piv_lu; -mod bidiagonal; -mod real_schur; -mod svd; mod balancing; -mod tridiagonal; +mod bidiagonal; +mod cholesky; mod eigen; +mod full_piv_lu; +mod hessenberg; +mod inverse; +mod lu; +mod qr; +mod real_schur; +mod solve; +mod svd; +mod tridiagonal; diff --git a/tests/linalg/qr.rs b/tests/linalg/qr.rs index 394a8b42..d7211623 100644 --- a/tests/linalg/qr.rs +++ b/tests/linalg/qr.rs @@ -1,8 +1,7 @@ #![cfg(feature = "arbitrary")] +use na::{DMatrix, DVector, Matrix3x5, Matrix4, Matrix4x3, Matrix5x3, Vector4}; use std::cmp; -use na::{DMatrix, Matrix4, Matrix4x3, Matrix5x3, Matrix3x5, - DVector, Vector4}; quickcheck! { fn qr(m: DMatrix) -> bool { diff --git a/tests/linalg/solve.rs b/tests/linalg/solve.rs index f960fb0a..76dc05b5 100644 --- a/tests/linalg/solve.rs +++ b/tests/linalg/solve.rs @@ -3,7 +3,7 @@ use na::{Matrix4, Matrix4x5}; fn unzero_diagonal(a: &mut Matrix4) { - for i in 0 .. 4 { + for i in 0..4 { if a[(i, i)] < 1.0e-7 { a[(i, i)] = 1.0; } diff --git a/tests/linalg/svd.rs b/tests/linalg/svd.rs index 5b09c7c8..629b404d 100644 --- a/tests/linalg/svd.rs +++ b/tests/linalg/svd.rs @@ -2,8 +2,10 @@ use na::{DMatrix, Matrix6}; #[cfg(feature = "arbitrary")] mod quickcheck_tests { + use na::{ + DMatrix, DVector, Matrix2, Matrix2x5, Matrix3, Matrix3x5, Matrix4, Matrix5x2, Matrix5x3, + }; use std::cmp; - use na::{DMatrix, Matrix2, Matrix3, Matrix4, Matrix5x2, Matrix5x3, Matrix2x5, Matrix3x5, DVector}; quickcheck! { fn svd(m: DMatrix) -> bool { @@ -143,31 +145,47 @@ mod quickcheck_tests { // Test proposed on the issue #176 of rulinalg. #[test] fn svd_singular() { - let m = DMatrix::from_row_slice(24, 24, &[ - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, - 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]); + let m = DMatrix::from_row_slice( + 24, + 24, + &[ + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, + 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, + -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, + 0.0, 1.0, 1.0, 1.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, + ], + ); let svd = m.clone().svd(true, true); let (u, s, v_t) = (svd.u.unwrap(), svd.singular_values, svd.v_t.unwrap()); @@ -184,33 +202,48 @@ fn svd_singular() { // Same as the previous test but with one additional row. #[test] fn svd_singular_vertical() { - let m = DMatrix::from_row_slice(25, 24, &[ - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, - 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]); - + let m = DMatrix::from_row_slice( + 25, + 24, + &[ + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, + 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, + -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, + 0.0, 1.0, 1.0, 1.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, + 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + ], + ); let svd = m.clone().svd(true, true); let (u, s, v_t) = (svd.u.unwrap(), svd.singular_values, svd.v_t.unwrap()); @@ -223,31 +256,48 @@ fn svd_singular_vertical() { // Same as the previous test but with one additional column. #[test] fn svd_singular_horizontal() { - let m = DMatrix::from_row_slice(24, 25, &[ - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, - 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]); + let m = DMatrix::from_row_slice( + 24, + 25, + &[ + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, + 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, + -1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, -4.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, + 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, + 0.0, 0.0, -4.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, + 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + -4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.0, 0.0, + 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, -4.0, 0.0, 0.0, + 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + ], + ); let svd = m.clone().svd(true, true); let (u, s, v_t) = (svd.u.unwrap(), svd.singular_values, svd.v_t.unwrap()); @@ -257,7 +307,6 @@ fn svd_singular_horizontal() { assert!(relative_eq!(m, &u * ds * &v_t, epsilon = 1.0e-5)); } - #[test] fn svd_zeros() { let m = DMatrix::from_element(10, 10, 0.0); @@ -283,47 +332,100 @@ fn svd_identity() { #[test] fn svd_with_delimited_subproblem() { let mut m = DMatrix::::from_element(10, 10, 0.0); - m[(0,0)] = 1.0; m[(0,1)] = 2.0; - m[(1,1)] = 0.0; m[(1,2)] = 3.0; - m[(2,2)] = 4.0; m[(2,3)] = 5.0; - m[(3,3)] = 6.0; m[(3,4)] = 0.0; - m[(4,4)] = 8.0; m[(3,5)] = 9.0; - m[(5,5)] = 10.0; m[(3,6)] = 11.0; - m[(6,6)] = 12.0; m[(3,7)] = 12.0; - m[(7,7)] = 14.0; m[(3,8)] = 13.0; - m[(8,8)] = 16.0; m[(3,9)] = 17.0; - m[(9,9)] = 18.0; + m[(0, 0)] = 1.0; + m[(0, 1)] = 2.0; + m[(1, 1)] = 0.0; + m[(1, 2)] = 3.0; + m[(2, 2)] = 4.0; + m[(2, 3)] = 5.0; + m[(3, 3)] = 6.0; + m[(3, 4)] = 0.0; + m[(4, 4)] = 8.0; + m[(3, 5)] = 9.0; + m[(5, 5)] = 10.0; + m[(3, 6)] = 11.0; + m[(6, 6)] = 12.0; + m[(3, 7)] = 12.0; + m[(7, 7)] = 14.0; + m[(3, 8)] = 13.0; + m[(8, 8)] = 16.0; + m[(3, 9)] = 17.0; + m[(9, 9)] = 18.0; let svd = m.clone().svd(true, true); assert!(relative_eq!(m, svd.recompose(), epsilon = 1.0e-7)); // Rectangular versions. let mut m = DMatrix::::from_element(15, 10, 0.0); - m[(0,0)] = 1.0; m[(0,1)] = 2.0; - m[(1,1)] = 0.0; m[(1,2)] = 3.0; - m[(2,2)] = 4.0; m[(2,3)] = 5.0; - m[(3,3)] = 6.0; m[(3,4)] = 0.0; - m[(4,4)] = 8.0; m[(3,5)] = 9.0; - m[(5,5)] = 10.0; m[(3,6)] = 11.0; - m[(6,6)] = 12.0; m[(3,7)] = 12.0; - m[(7,7)] = 14.0; m[(3,8)] = 13.0; - m[(8,8)] = 16.0; m[(3,9)] = 17.0; - m[(9,9)] = 18.0; + m[(0, 0)] = 1.0; + m[(0, 1)] = 2.0; + m[(1, 1)] = 0.0; + m[(1, 2)] = 3.0; + m[(2, 2)] = 4.0; + m[(2, 3)] = 5.0; + m[(3, 3)] = 6.0; + m[(3, 4)] = 0.0; + m[(4, 4)] = 8.0; + m[(3, 5)] = 9.0; + m[(5, 5)] = 10.0; + m[(3, 6)] = 11.0; + m[(6, 6)] = 12.0; + m[(3, 7)] = 12.0; + m[(7, 7)] = 14.0; + m[(3, 8)] = 13.0; + m[(8, 8)] = 16.0; + m[(3, 9)] = 17.0; + m[(9, 9)] = 18.0; let svd = m.clone().svd(true, true); assert!(relative_eq!(m, svd.recompose(), epsilon = 1.0e-7)); let svd = m.transpose().svd(true, true); - assert!(relative_eq!(m.transpose(), svd.recompose(), epsilon = 1.0e-7)); + assert!(relative_eq!( + m.transpose(), + svd.recompose(), + epsilon = 1.0e-7 + )); } #[test] fn svd_fail() { let m = Matrix6::new( - 0.9299319121545955, 0.9955870335651049, 0.8824725266413644, 0.28966880207132295, 0.06102723649846409, 0.9311880746048009, - 0.5938395242304351, 0.8398522876024204, 0.06672831951963198, 0.9941213119963099, 0.9431846038057834, 0.8159885168706427, - 0.9121962883152357, 0.6471119669367571, 0.4823309702814407, 0.6420516076705516, 0.7731203925207113, 0.7424069470756647, - 0.07311092531259344, 0.5579247949052946, 0.14518764691585773, 0.03502980663114896, 0.7991329455957719, 0.4929930019965745, - 0.12293810556077789, 0.6617084679545999, 0.9002240700227326, 0.027153062135304884, 0.3630189466989524, 0.18207502727558866, - 0.843196731466686, 0.08951878746549924, 0.7533450877576973, 0.009558876499740077, 0.9429679490873482, 0.9355764454129878); + 0.9299319121545955, + 0.9955870335651049, + 0.8824725266413644, + 0.28966880207132295, + 0.06102723649846409, + 0.9311880746048009, + 0.5938395242304351, + 0.8398522876024204, + 0.06672831951963198, + 0.9941213119963099, + 0.9431846038057834, + 0.8159885168706427, + 0.9121962883152357, + 0.6471119669367571, + 0.4823309702814407, + 0.6420516076705516, + 0.7731203925207113, + 0.7424069470756647, + 0.07311092531259344, + 0.5579247949052946, + 0.14518764691585773, + 0.03502980663114896, + 0.7991329455957719, + 0.4929930019965745, + 0.12293810556077789, + 0.6617084679545999, + 0.9002240700227326, + 0.027153062135304884, + 0.3630189466989524, + 0.18207502727558866, + 0.843196731466686, + 0.08951878746549924, + 0.7533450877576973, + 0.009558876499740077, + 0.9429679490873482, + 0.9355764454129878, + ); let svd = m.clone().svd(true, true); println!("Singular values: {}", svd.singular_values); println!("u: {:.5}", svd.u.unwrap());