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