diff --git a/src/lib.rs b/src/lib.rs index dac3a565..02412d07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -152,6 +152,7 @@ pub use traits::{ ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Shape, + SquareMat, ToHomogeneous, Transform, Transformation, Translate, Translation, @@ -644,7 +645,7 @@ pub fn append_rotation_wrt_center, /// Builds a rotation matrix from `r`. #[inline(always)] -pub fn to_rot_mat + Rotation, R: RotationMatrix>(r: &R) -> M { +pub fn to_rot_mat + Rotation, R: RotationMatrix>(r: &R) -> M { r.to_rot_mat() } diff --git a/src/linalg/decompositions.rs b/src/linalg/decompositions.rs index ccd5d168..2d785a77 100644 --- a/src/linalg/decompositions.rs +++ b/src/linalg/decompositions.rs @@ -1,6 +1,6 @@ use std::num::{Zero, Float}; use traits::operations::{Transpose, ApproxEq}; -use traits::structure::{ColSlice, Eye, Indexable, Diag}; +use traits::structure::{ColSlice, Eye, Indexable, Diag, SquareMat}; use traits::geometry::Norm; use std::cmp::min; @@ -73,19 +73,17 @@ pub fn qr(m: &M) -> (M, M) } /// Eigendecomposition of a square matrix using the qr algorithm. -pub fn eigen_qr(m: &M, eps: &N, niter: uint) -> (M, V2) +pub fn eigen_qr(m: &M, eps: &N, niter: uint) -> (M, V) where N: Float, - V: Indexable + Norm, - V2: Zero, - M: Clone + Eye + ColSlice + Transpose + Indexable<(uint, uint), N> + Mul - + Diag + ApproxEq + Add + Sub { + VS: Indexable + Norm, + M: Indexable<(uint, uint), N> + SquareMat + ColSlice + ApproxEq + Clone { let (rows, cols) = m.shape(); assert!(rows == cols, "The matrix being decomposed must be square."); let mut eigenvectors: M = Eye::new_identity(rows); let mut eigenvalues = m.clone(); - let mut shifter: M = Eye::new_identity(rows); + // let mut shifter: M = Eye::new_identity(rows); let mut iter = 0u; for _ in range(0, niter) { @@ -112,16 +110,9 @@ pub fn eigen_qr(m: &M, eps: &N, niter: uint) -> (M, V2) } iter = iter + 1; - // FIXME: This is a very naive implementation. - let shift = unsafe { eigenvalues.unsafe_at((rows - 1, rows - 1)) }; + let (q, r) = qr(&eigenvalues);; - for i in range(0, rows) { - unsafe { shifter.unsafe_set((i, i), shift.clone()) } - } - - let (q, r) = qr(&eigenvalues);// - shifter)); - - eigenvalues = r * q /*+ shifter*/; + eigenvalues = r * q; eigenvectors = eigenvectors * q; } diff --git a/src/structs/iso_macros.rs b/src/structs/iso_macros.rs index 6eeb6fad..af573282 100644 --- a/src/structs/iso_macros.rs +++ b/src/structs/iso_macros.rs @@ -27,7 +27,7 @@ macro_rules! iso_impl( macro_rules! rotation_matrix_impl( ($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( impl + FloatMath + Num + Clone> - RotationMatrix<$tlv, $tav, $trot> for $t { + RotationMatrix, $tav, $trot> for $t { #[inline] fn to_rot_mat(&self) -> $trot { self.rotation.clone() diff --git a/src/structs/rot_macros.rs b/src/structs/rot_macros.rs index 3a4197f7..07b660bc 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rot_macros.rs @@ -122,8 +122,7 @@ macro_rules! dim_impl( macro_rules! rotation_matrix_impl( ($t: ident, $tlv: ident, $tav: ident) => ( - impl + FloatMath + Clone> - RotationMatrix<$tlv, $tav, $t> for $t { + impl + FloatMath> RotationMatrix, $tav, $t> for $t { #[inline] fn to_rot_mat(&self) -> $t { self.clone() diff --git a/src/traits/geometry.rs b/src/traits/geometry.rs index 4a05a7f0..84205500 100644 --- a/src/traits/geometry.rs +++ b/src/traits/geometry.rs @@ -141,7 +141,7 @@ impl, AV, M: Rotation + Translation> RotationWithTranslation /// Trait of transformation having a rotation extractable as a rotation matrix. This can typically /// be implemented by quaternions to convert them to a rotation matrix. -pub trait RotationMatrix + Rotation> : Rotation { +pub trait RotationMatrix + Rotation> : Rotation { /// Gets the rotation matrix represented by `self`. fn to_rot_mat(&self) -> M; } diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 5f71ac9d..511523ea 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -1,16 +1,16 @@ //! Mathematical traits. -pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneous, Norm, Orig, - Rotate, Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous, - Transform, Transformation, Translate, Translation, UniformSphereSample}; +pub use traits::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneous, Norm, Orig, + Rotate, Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous, + Transform, Transformation, Translate, Translation, UniformSphereSample}; -pub use self::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable, - IterableMut, Mat, Row, NumVec, NumPnt, PntAsVec, VecAsPnt, ColSlice, - RowSlice, Diag, Eye, Shape}; +pub use traits::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable, + IterableMut, Mat, SquareMat, Row, NumVec, NumPnt, PntAsVec, VecAsPnt, + ColSlice, RowSlice, Diag, Eye, Shape}; -pub use self::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd, - RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose}; -pub use self::operations::{POrdering, PartialLess, PartialEqual, PartialGreater, NotComparable}; +pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd, + RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose}; +pub use traits::operations::{POrdering, PartialLess, PartialEqual, PartialGreater, NotComparable}; pub mod geometry; pub mod structure; diff --git a/src/traits/structure.rs b/src/traits/structure.rs index 7c8a16da..b4f2d811 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -2,7 +2,7 @@ use std::num::Zero; use std::slice::{Items, MutItems}; -use traits::operations::{RMul, LMul, Axpy}; +use traits::operations::{RMul, LMul, Axpy, Transpose}; use traits::geometry::{Dot, Norm, Orig}; /// Traits of objects which can be created from an object of type `T`. @@ -14,9 +14,19 @@ pub trait Cast { /// Trait of matrices. /// /// A matrix has rows and columns and are able to multiply them. -pub trait Mat : Row + Col + RMul + LMul { } +pub trait Mat: Row + Col + RMul + LMul + Index<(uint, uint), N> { } -impl + Col + RMul + LMul, R, C> Mat for M { +impl Mat for M + where M: Row + Col + RMul + LMul + Index<(uint, uint), N> { +} + +/// Trait implemented by square matrices. +pub trait SquareMat: Mat + Mul + Eye + Transpose + Add + + Sub + Diag { +} + +impl SquareMat for M + where M: Mat + Mul + Eye + Transpose + Add + Sub + Diag { } /// Trait for constructing the identity matrix diff --git a/tests/mat.rs b/tests/mat.rs index c4a2100d..c2eefbd4 100644 --- a/tests/mat.rs +++ b/tests/mat.rs @@ -6,7 +6,7 @@ use std::num::{Float, abs}; use std::rand::random; use std::cmp::{min, max}; use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, - DMat, DVec, Indexable, Row, Col}; + DMat, DVec, Row, Col}; macro_rules! test_inv_mat_impl( ($t: ty) => ( @@ -141,7 +141,7 @@ fn test_rotation2() { fn test_index_mat2() { let mat: Mat2 = random(); - assert!(mat.at((0, 1)) == na::transpose(&mat).at((1, 0))); + assert!(mat[(0, 1)] == na::transpose(&mat)[(1, 0)]); } #[test]