Remove the redundant `Column` trait + Add unchecked access indexing to dynamic matrices/vectors.

This commit is contained in:
Sébastien Crozet 2013-09-18 14:22:29 +02:00
parent c89a6681c1
commit 9a9de20b8a
6 changed files with 50 additions and 71 deletions

View File

@ -11,7 +11,7 @@ use Ts = traits::transformation::Transform;
use traits::transformation::{Transformation}; use traits::transformation::{Transformation};
use traits::rlmul::RMul; use traits::rlmul::RMul;
use traits::homogeneous::{ToHomogeneous, FromHomogeneous}; use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
use traits::column::Column; use traits::col::Col;
use traits::comp::absolute_rotate::AbsoluteRotate; use traits::comp::absolute_rotate::AbsoluteRotate;
use adaptors::rotmat::Rotmat; use adaptors::rotmat::Rotmat;
use vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs}; use vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs};
@ -335,7 +335,7 @@ Inv for Transform<V, M> {
} }
} }
impl<M: ToHomogeneous<M2>, M2: Dim + Column<V2>, V: ToHomogeneous<V2> + Clone, V2> impl<M: ToHomogeneous<M2>, M2: Dim + Col<V2>, V: ToHomogeneous<V2> + Clone, V2>
ToHomogeneous<M2> for Transform<V, M> { ToHomogeneous<M2> for Transform<V, M> {
fn to_homogeneous(&self) -> M2 { fn to_homogeneous(&self) -> M2 {
let mut res = self.submat.to_homogeneous(); let mut res = self.submat.to_homogeneous();
@ -343,16 +343,16 @@ ToHomogeneous<M2> for Transform<V, M> {
// copy the translation // copy the translation
let dim = Dim::dim(None::<M2>); let dim = Dim::dim(None::<M2>);
res.set_column(dim - 1, self.subtrans.to_homogeneous()); res.set_col(dim - 1, self.subtrans.to_homogeneous());
res res
} }
} }
impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V> impl<M: Col<V> + Dim, M2: FromHomogeneous<M>, V>
FromHomogeneous<M> for Transform<V, M2> { FromHomogeneous<M> for Transform<V, M2> {
fn from(m: &M) -> Transform<V, M2> { fn from(m: &M) -> Transform<V, M2> {
Transform::new(m.column(Dim::dim(None::<M>) - 1), FromHomogeneous::from(m)) Transform::new(m.col(Dim::dim(None::<M>) - 1), FromHomogeneous::from(m))
} }
} }

View File

@ -102,14 +102,22 @@ impl<N> DMat<N> {
} }
/// The number of row on the matrix. /// The number of row on the matrix.
#[inline]
pub fn nrows(&self) -> uint { pub fn nrows(&self) -> uint {
self.nrows self.nrows
} }
/// The number of columns on the matrix. /// The number of columns on the matrix.
#[inline]
pub fn ncols(&self) -> uint { pub fn ncols(&self) -> uint {
self.ncols self.ncols
} }
/// Transforms this matrix into an array. This consumes the matrix and is O(1).
#[inline]
pub fn to_array(self) -> ~[N] {
self.mij
}
} }
// FIXME: add a function to modify the dimension (to avoid useless allocations)? // FIXME: add a function to modify the dimension (to avoid useless allocations)?
@ -152,6 +160,13 @@ impl<N: Clone> DMat<N> {
self.mij[self.offset(row, col)] = val self.mij[self.offset(row, col)] = val
} }
/// Just like `set` without bounds checking.
#[inline]
pub unsafe fn set_fast(&mut self, row: uint, col: uint, val: N) {
let off = self.offset(row, col);
*self.mij.unsafe_mut_ref(off) = val
}
/// Reads the value of a component of the matrix. /// Reads the value of a component of the matrix.
/// ///
/// # Arguments /// # Arguments
@ -161,10 +176,9 @@ impl<N: Clone> DMat<N> {
pub fn at(&self, row: uint, col: uint) -> N { pub fn at(&self, row: uint, col: uint) -> N {
assert!(row < self.nrows); assert!(row < self.nrows);
assert!(col < self.ncols); assert!(col < self.ncols);
unsafe { vec::raw::get(self.mij, self.offset(row, col)) } unsafe { self.at_fast(row, col) }
} }
// FIXME: put that on a `raw` module.
/// Just like `at` without bounds checking. /// Just like `at` without bounds checking.
#[inline] #[inline]
pub unsafe fn at_fast(&self, row: uint, col: uint) -> N { pub unsafe fn at_fast(&self, row: uint, col: uint) -> N {
@ -182,13 +196,13 @@ impl<N: Clone + Mul<N, N> + Add<N, N> + Zero> DMatMulRhs<N, DMat<N>> for DMat<N>
for j in range(0u, right.ncols) { for j in range(0u, right.ncols) {
let mut acc: N = Zero::zero(); let mut acc: N = Zero::zero();
for k in range(0u, left.ncols) { unsafe {
unsafe { for k in range(0u, left.ncols) {
acc = acc + left.at_fast(i, k) * right.at_fast(k, j); acc = acc + left.at_fast(i, k) * right.at_fast(k, j);
} }
}
res.set(i, j, acc); res.set_fast(i, j, acc);
}
} }
} }
@ -273,7 +287,7 @@ Inv for DMat<N> {
let mut n0 = k; // index of a non-zero entry let mut n0 = k; // index of a non-zero entry
while (n0 != dim) { while (n0 != dim) {
if self.at(n0, k) != _0T { if unsafe { self.at_fast(n0, k) } != _0T {
break; break;
} }
@ -295,30 +309,32 @@ Inv for DMat<N> {
} }
} }
let pivot = self.at(k, k); unsafe {
let pivot = self.at_fast(k, k);
for j in range(k, dim) { for j in range(k, dim) {
let selfval = self.at(k, j) / pivot; let selfval = self.at_fast(k, j) / pivot;
self.set(k, j, selfval); self.set_fast(k, j, selfval);
} }
for j in range(0u, dim) { for j in range(0u, dim) {
let resval = res.at(k, j) / pivot; let resval = res.at_fast(k, j) / pivot;
res.set(k, j, resval); res.set_fast(k, j, resval);
} }
for l in range(0u, dim) { for l in range(0u, dim) {
if l != k { if l != k {
let normalizer = self.at(l, k); let normalizer = self.at_fast(l, k);
for j in range(k, dim) { for j in range(k, dim) {
let selfval = self.at(l, j) - self.at(k, j) * normalizer; let selfval = self.at_fast(l, j) - self.at_fast(k, j) * normalizer;
self.set(l, j, selfval); self.set_fast(l, j, selfval);
} }
for j in range(0u, dim) { for j in range(0u, dim) {
let resval = res.at(l, j) - res.at(k, j) * normalizer; let resval = res.at_fast(l, j) - res.at_fast(k, j) * normalizer;
res.set(l, j, resval); res.set_fast(l, j, resval);
}
} }
} }
} }

View File

@ -26,6 +26,8 @@ mod mat_spec;
mod vec_spec; mod vec_spec;
mod vec0_spec; mod vec0_spec;
mod identity_spec; mod identity_spec;
// mod lower_triangular;
// mod chol;
/// Wrappers around raw matrices to restrict their behaviour. /// Wrappers around raw matrices to restrict their behaviour.
pub mod adaptors { pub mod adaptors {
@ -39,7 +41,6 @@ pub mod traits {
pub mod vector; pub mod vector;
pub mod sample; pub mod sample;
pub mod indexable; pub mod indexable;
pub mod column;
pub mod row; pub mod row;
pub mod iterable; pub mod iterable;
pub mod outer; pub mod outer;

View File

@ -14,7 +14,6 @@ pub use traits::indexable::Indexable;
pub use traits::iterable::{Iterable, IterableMut}; pub use traits::iterable::{Iterable, IterableMut};
pub use traits::scalar_op::{ScalarSub, ScalarAdd}; pub use traits::scalar_op::{ScalarSub, ScalarAdd};
pub use traits::mat_cast::MatCast; pub use traits::mat_cast::MatCast;
pub use traits::column::Column;
pub use traits::inv::Inv; pub use traits::inv::Inv;
pub use traits::rlmul::RMul; pub use traits::rlmul::RMul;
pub use traits::rotation::{Rotation, RotationMatrix, Rotate}; pub use traits::rotation::{Rotation, RotationMatrix, Rotate};
@ -138,7 +137,6 @@ transform_impl!(Mat1, Vec1)
// (specialized) inv_impl!(Mat1, 1) // (specialized) inv_impl!(Mat1, 1)
transpose_impl!(Mat1, 1) transpose_impl!(Mat1, 1)
approx_eq_impl!(Mat1) approx_eq_impl!(Mat1)
column_impl!(Mat1, Vec1, 1)
row_impl!(Mat1, Vec1, 1) row_impl!(Mat1, Vec1, 1)
col_impl!(Mat1, Vec1, 1) col_impl!(Mat1, Vec1, 1)
to_homogeneous_impl!(Mat1, Mat2, 1, 2) to_homogeneous_impl!(Mat1, Mat2, 1, 2)
@ -239,7 +237,6 @@ transform_impl!(Mat2, Vec2)
// (specialized) inv_impl!(Mat2, 2) // (specialized) inv_impl!(Mat2, 2)
transpose_impl!(Mat2, 2) transpose_impl!(Mat2, 2)
approx_eq_impl!(Mat2) approx_eq_impl!(Mat2)
column_impl!(Mat2, Vec2, 2)
row_impl!(Mat2, Vec2, 2) row_impl!(Mat2, Vec2, 2)
col_impl!(Mat2, Vec2, 2) col_impl!(Mat2, Vec2, 2)
to_homogeneous_impl!(Mat2, Mat3, 2, 3) to_homogeneous_impl!(Mat2, Mat3, 2, 3)
@ -354,7 +351,6 @@ transform_impl!(Mat3, Vec3)
// (specialized) inv_impl!(Mat3, 3) // (specialized) inv_impl!(Mat3, 3)
transpose_impl!(Mat3, 3) transpose_impl!(Mat3, 3)
approx_eq_impl!(Mat3) approx_eq_impl!(Mat3)
column_impl!(Mat3, Vec3, 3)
// (specialized) row_impl!(Mat3, Vec3, 3) // (specialized) row_impl!(Mat3, Vec3, 3)
// (specialized) col_impl!(Mat3, Vec3, 3) // (specialized) col_impl!(Mat3, Vec3, 3)
to_homogeneous_impl!(Mat3, Mat4, 3, 4) to_homogeneous_impl!(Mat3, Mat4, 3, 4)
@ -525,7 +521,6 @@ transform_impl!(Mat4, Vec4)
inv_impl!(Mat4, 4) inv_impl!(Mat4, 4)
transpose_impl!(Mat4, 4) transpose_impl!(Mat4, 4)
approx_eq_impl!(Mat4) approx_eq_impl!(Mat4)
column_impl!(Mat4, Vec4, 4)
row_impl!(Mat4, Vec4, 4) row_impl!(Mat4, Vec4, 4)
col_impl!(Mat4, Vec4, 4) col_impl!(Mat4, Vec4, 4)
to_homogeneous_impl!(Mat4, Mat5, 4, 5) to_homogeneous_impl!(Mat4, Mat5, 4, 5)
@ -712,7 +707,6 @@ transform_impl!(Mat5, Vec5)
inv_impl!(Mat5, 5) inv_impl!(Mat5, 5)
transpose_impl!(Mat5, 5) transpose_impl!(Mat5, 5)
approx_eq_impl!(Mat5) approx_eq_impl!(Mat5)
column_impl!(Mat5, Vec5, 5)
row_impl!(Mat5, Vec5, 5) row_impl!(Mat5, Vec5, 5)
col_impl!(Mat5, Vec5, 5) col_impl!(Mat5, Vec5, 5)
to_homogeneous_impl!(Mat5, Mat6, 5, 6) to_homogeneous_impl!(Mat5, Mat6, 5, 6)
@ -955,7 +949,6 @@ transform_impl!(Mat6, Vec6)
inv_impl!(Mat6, 6) inv_impl!(Mat6, 6)
transpose_impl!(Mat6, 6) transpose_impl!(Mat6, 6)
approx_eq_impl!(Mat6) approx_eq_impl!(Mat6)
column_impl!(Mat6, Vec6, 6)
row_impl!(Mat6, Vec6, 6) row_impl!(Mat6, Vec6, 6)
col_impl!(Mat6, Vec6, 6) col_impl!(Mat6, Vec6, 6)
outer_impl!(Vec6, Mat6) outer_impl!(Vec6, Mat6)

View File

@ -196,30 +196,6 @@ macro_rules! indexable_impl(
) )
) )
macro_rules! column_impl(
($t: ident, $tv: ident, $dim: expr) => (
impl<N: Clone + Zero> Column<$tv<N>> for $t<N> {
#[inline]
fn set_column(&mut self, col: uint, v: $tv<N>) {
for (i, e) in v.iter().enumerate() {
self.set((i, col), e.clone());
}
}
#[inline]
fn column(&self, col: uint) -> $tv<N> {
let mut res: $tv<N> = Zero::zero();
for (i, e) in res.mut_iter().enumerate() {
*e = self.at((i, col));
}
res
}
}
)
)
macro_rules! row_impl( macro_rules! row_impl(
($t: ident, $tv: ident, $dim: expr) => ( ($t: ident, $tv: ident, $dim: expr) => (
impl<N: Clone + Zero> Row<$tv<N>> for $t<N> { impl<N: Clone + Zero> Row<$tv<N>> for $t<N> {
@ -260,7 +236,7 @@ macro_rules! col_impl(
#[inline] #[inline]
fn set_col(&mut self, col: uint, v: $tv<N>) { fn set_col(&mut self, col: uint, v: $tv<N>) {
for (i, e) in v.iter().enumerate() { for (i, e) in v.iter().enumerate() {
self.set((col, i), e.clone()); self.set((i, col), e.clone());
} }
} }

View File

@ -1,7 +0,0 @@
/// Traits to access columns of a matrix.
pub trait Column<C> {
/// Reads the `i`-th column of `self`.
fn column(&self, i: uint) -> C;
/// Writes the `i`-th column of `self`.
fn set_column(&mut self, i: uint, C);
}