Add a `Det` trait to compute the determinant + implement it for `Mat{1,2,3}`.

This commit is contained in:
Sébastien Crozet 2014-08-11 19:54:13 +02:00
parent 725f53d1e7
commit 7d6884c3df
5 changed files with 58 additions and 21 deletions

View File

@ -15,6 +15,7 @@ pub use traits::{
Cov,
Cross,
CrossMatrix,
Det,
Dim,
Dot,
FromHomogeneous,
@ -580,6 +581,15 @@ pub fn normalize<V: Norm<N>, N: Float>(v: &V) -> V {
Norm::normalize_cpy(v)
}
/*
* Det<N>
*/
/// Computes the determinant of a square matrix.
#[inline(always)]
pub fn det<M: Det<N>, N>(m: &M) -> N {
Det::det(m)
}
/*
* Cross<V>
*/

View File

@ -327,7 +327,7 @@ impl<N: Float + Clone> Norm<N> for DVec<N> {
let l = Norm::norm(self);
for i in range(0u, self.at.len()) {
*self.at.get_mut(i) = *self.at.get(i) / l;
*self.at.get_mut(i) = self.at[i] / l;
}
l

View File

@ -1,12 +1,11 @@
use std::num::{Zero, One};
use structs::vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs};
use structs::mat::{Mat1, Mat2, Mat3, Mat3MulRhs, Mat2MulRhs};
use traits::operations::Inv;
use traits::operations::{Inv, Det};
use traits::structure::{Row, Col};
// some specializations:
impl<N: Num + Clone>
Inv for Mat1<N> {
impl<N: Num + Clone> Inv for Mat1<N> {
#[inline]
fn inv_cpy(m: &Mat1<N>) -> Option<Mat1<N>> {
let mut res = m.clone();
@ -26,14 +25,14 @@ Inv for Mat1<N> {
}
else {
let _1: N = One::one();
self.m11 = _1 / self.m11;
self.m11 = _1 / Det::det(self);
true
}
}
}
impl<N: Num + Clone>
Inv for Mat2<N> {
impl<N: Num + Clone> Inv for Mat2<N> {
#[inline]
fn inv_cpy(m: &Mat2<N>) -> Option<Mat2<N>> {
let mut res = m.clone();
@ -48,7 +47,7 @@ Inv for Mat2<N> {
#[inline]
fn inv(&mut self) -> bool {
let det = self.m11 * self.m22 - self.m21 * self.m12;
let det = Det::det(self);
if det.is_zero() {
false
@ -63,8 +62,7 @@ Inv for Mat2<N> {
}
}
impl<N: Num + Clone>
Inv for Mat3<N> {
impl<N: Num + Clone> Inv for Mat3<N> {
#[inline]
fn inv_cpy(m: &Mat3<N>) -> Option<Mat3<N>> {
let mut res = m.clone();
@ -83,9 +81,7 @@ Inv for Mat3<N> {
let minor_m11_m23 = self.m21 * self.m33 - self.m31 * self.m23;
let minor_m11_m22 = self.m21 * self.m32 - self.m31 * self.m22;
let det = self.m11 * minor_m12_m23
- self.m12 * minor_m11_m23
+ self.m13 * minor_m11_m22;
let det = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22;
if det.is_zero() {
false
@ -110,6 +106,31 @@ Inv for Mat3<N> {
}
}
impl<N: Num + Clone> Det<N> for Mat1<N> {
#[inline]
fn det(m: &Mat1<N>) -> N {
m.m11.clone()
}
}
impl<N: Num> Det<N> for Mat2<N> {
#[inline]
fn det(m: &Mat2<N>) -> N {
m.m11 * m.m22 - m.m21 * m.m12
}
}
impl<N: Num> Det<N> for Mat3<N> {
#[inline]
fn det(m: &Mat3<N>) -> N {
let minor_m12_m23 = m.m22 * m.m33 - m.m32 * m.m23;
let minor_m11_m23 = m.m21 * m.m33 - m.m31 * m.m23;
let minor_m11_m22 = m.m21 * m.m32 - m.m31 * m.m22;
m.m11 * minor_m12_m23 - m.m12 * minor_m11_m23 + m.m13 * minor_m11_m22
}
}
impl<N: Clone> Row<Vec3<N>> for Mat3<N> {
#[inline]
fn nrows(&self) -> uint {

View File

@ -8,7 +8,7 @@ pub use self::structure::{FloatVec, FloatVecExt, Basis, Cast, Col, Dim, Indexabl
Iterable, IterableMut, Mat, Row, AnyVec, VecExt,
ColSlice, RowSlice, Eye};
pub use self::operations::{Absolute, ApproxEq, Cov, Inv, LMul, Mean, Outer, PartialOrd, RMul,
pub use self::operations::{Absolute, ApproxEq, Cov, Det, Inv, LMul, Mean, Outer, PartialOrd, RMul,
ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose};
pub use self::operations::{PartialOrdering, PartialLess, PartialEqual, PartialGreater, NotComparable};

View File

@ -196,13 +196,19 @@ pub trait Absolute<A> {
/// Trait of objects having an inverse. Typically used to implement matrix inverse.
pub trait Inv {
/// Returns the inverse of `self`.
/// Returns the inverse of `m`.
fn inv_cpy(m: &Self) -> Option<Self>;
/// In-place version of `inverse`.
fn inv(&mut self) -> bool;
}
/// Trait of objects having a determinant. Typically used by square matrices.
pub trait Det<N> {
/// Returns the determinant of `m`.
fn det(m: &Self) -> N;
}
/// Trait of objects which can be transposed.
pub trait Transpose {
/// Computes the transpose of a matrix.
@ -214,19 +220,19 @@ pub trait Transpose {
/// Traits of objects having an outer product.
pub trait Outer<M> {
/// Computes the outer product: `self * other`
/// Computes the outer product: `a * b`
fn outer(a: &Self, b: &Self) -> M;
}
/// Trait for computing the covariance of a set of data.
pub trait Cov<M> {
/// Computes the covariance of the obsevations stored by `self`:
/// Computes the covariance of the obsevations stored by `m`:
///
/// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn cov(&Self) -> M;
fn cov(m: &Self) -> M;
/// Computes the covariance of the obsevations stored by `self`:
/// Computes the covariance of the obsevations stored by `m`:
///
/// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional).
@ -237,11 +243,11 @@ pub trait Cov<M> {
/// Trait for computing the covariance of a set of data.
pub trait Mean<N> {
/// Computes the mean of the observations stored by `self`.
/// Computes the mean of the observations stored by `v`.
///
/// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn mean(&Self) -> N;
fn mean(v: &Self) -> N;
}