Remove the redundant `Column` trait + Add unchecked access indexing to dynamic matrices/vectors.
This commit is contained in:
parent
c89a6681c1
commit
9a9de20b8a
|
@ -11,7 +11,7 @@ use Ts = traits::transformation::Transform;
|
|||
use traits::transformation::{Transformation};
|
||||
use traits::rlmul::RMul;
|
||||
use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
||||
use traits::column::Column;
|
||||
use traits::col::Col;
|
||||
use traits::comp::absolute_rotate::AbsoluteRotate;
|
||||
use adaptors::rotmat::Rotmat;
|
||||
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> {
|
||||
fn to_homogeneous(&self) -> M2 {
|
||||
let mut res = self.submat.to_homogeneous();
|
||||
|
@ -343,16 +343,16 @@ ToHomogeneous<M2> for Transform<V, M> {
|
|||
// copy the translation
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Column<V> + Dim, M2: FromHomogeneous<M>, V>
|
||||
impl<M: Col<V> + Dim, M2: FromHomogeneous<M>, V>
|
||||
FromHomogeneous<M> for 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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
68
src/dmat.rs
68
src/dmat.rs
|
@ -102,14 +102,22 @@ impl<N> DMat<N> {
|
|||
}
|
||||
|
||||
/// The number of row on the matrix.
|
||||
#[inline]
|
||||
pub fn nrows(&self) -> uint {
|
||||
self.nrows
|
||||
}
|
||||
|
||||
/// The number of columns on the matrix.
|
||||
#[inline]
|
||||
pub fn ncols(&self) -> uint {
|
||||
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)?
|
||||
|
@ -152,6 +160,13 @@ impl<N: Clone> DMat<N> {
|
|||
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.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -161,10 +176,9 @@ impl<N: Clone> DMat<N> {
|
|||
pub fn at(&self, row: uint, col: uint) -> N {
|
||||
assert!(row < self.nrows);
|
||||
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.
|
||||
#[inline]
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
while (n0 != dim) {
|
||||
if self.at(n0, k) != _0T {
|
||||
if unsafe { self.at_fast(n0, k) } != _0T {
|
||||
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) {
|
||||
let selfval = self.at(k, j) / pivot;
|
||||
self.set(k, j, selfval);
|
||||
}
|
||||
for j in range(k, dim) {
|
||||
let selfval = self.at_fast(k, j) / pivot;
|
||||
self.set_fast(k, j, selfval);
|
||||
}
|
||||
|
||||
for j in range(0u, dim) {
|
||||
let resval = res.at(k, j) / pivot;
|
||||
res.set(k, j, resval);
|
||||
}
|
||||
for j in range(0u, dim) {
|
||||
let resval = res.at_fast(k, j) / pivot;
|
||||
res.set_fast(k, j, resval);
|
||||
}
|
||||
|
||||
for l in range(0u, dim) {
|
||||
if l != k {
|
||||
let normalizer = self.at(l, k);
|
||||
for l in range(0u, dim) {
|
||||
if l != k {
|
||||
let normalizer = self.at_fast(l, k);
|
||||
|
||||
for j in range(k, dim) {
|
||||
let selfval = self.at(l, j) - self.at(k, j) * normalizer;
|
||||
self.set(l, j, selfval);
|
||||
}
|
||||
for j in range(k, dim) {
|
||||
let selfval = self.at_fast(l, j) - self.at_fast(k, j) * normalizer;
|
||||
self.set_fast(l, j, selfval);
|
||||
}
|
||||
|
||||
for j in range(0u, dim) {
|
||||
let resval = res.at(l, j) - res.at(k, j) * normalizer;
|
||||
res.set(l, j, resval);
|
||||
for j in range(0u, dim) {
|
||||
let resval = res.at_fast(l, j) - res.at_fast(k, j) * normalizer;
|
||||
res.set_fast(l, j, resval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ mod mat_spec;
|
|||
mod vec_spec;
|
||||
mod vec0_spec;
|
||||
mod identity_spec;
|
||||
// mod lower_triangular;
|
||||
// mod chol;
|
||||
|
||||
/// Wrappers around raw matrices to restrict their behaviour.
|
||||
pub mod adaptors {
|
||||
|
@ -39,7 +41,6 @@ pub mod traits {
|
|||
pub mod vector;
|
||||
pub mod sample;
|
||||
pub mod indexable;
|
||||
pub mod column;
|
||||
pub mod row;
|
||||
pub mod iterable;
|
||||
pub mod outer;
|
||||
|
|
|
@ -14,7 +14,6 @@ pub use traits::indexable::Indexable;
|
|||
pub use traits::iterable::{Iterable, IterableMut};
|
||||
pub use traits::scalar_op::{ScalarSub, ScalarAdd};
|
||||
pub use traits::mat_cast::MatCast;
|
||||
pub use traits::column::Column;
|
||||
pub use traits::inv::Inv;
|
||||
pub use traits::rlmul::RMul;
|
||||
pub use traits::rotation::{Rotation, RotationMatrix, Rotate};
|
||||
|
@ -138,7 +137,6 @@ transform_impl!(Mat1, Vec1)
|
|||
// (specialized) inv_impl!(Mat1, 1)
|
||||
transpose_impl!(Mat1, 1)
|
||||
approx_eq_impl!(Mat1)
|
||||
column_impl!(Mat1, Vec1, 1)
|
||||
row_impl!(Mat1, Vec1, 1)
|
||||
col_impl!(Mat1, Vec1, 1)
|
||||
to_homogeneous_impl!(Mat1, Mat2, 1, 2)
|
||||
|
@ -239,7 +237,6 @@ transform_impl!(Mat2, Vec2)
|
|||
// (specialized) inv_impl!(Mat2, 2)
|
||||
transpose_impl!(Mat2, 2)
|
||||
approx_eq_impl!(Mat2)
|
||||
column_impl!(Mat2, Vec2, 2)
|
||||
row_impl!(Mat2, Vec2, 2)
|
||||
col_impl!(Mat2, Vec2, 2)
|
||||
to_homogeneous_impl!(Mat2, Mat3, 2, 3)
|
||||
|
@ -354,7 +351,6 @@ transform_impl!(Mat3, Vec3)
|
|||
// (specialized) inv_impl!(Mat3, 3)
|
||||
transpose_impl!(Mat3, 3)
|
||||
approx_eq_impl!(Mat3)
|
||||
column_impl!(Mat3, Vec3, 3)
|
||||
// (specialized) row_impl!(Mat3, Vec3, 3)
|
||||
// (specialized) col_impl!(Mat3, Vec3, 3)
|
||||
to_homogeneous_impl!(Mat3, Mat4, 3, 4)
|
||||
|
@ -525,7 +521,6 @@ transform_impl!(Mat4, Vec4)
|
|||
inv_impl!(Mat4, 4)
|
||||
transpose_impl!(Mat4, 4)
|
||||
approx_eq_impl!(Mat4)
|
||||
column_impl!(Mat4, Vec4, 4)
|
||||
row_impl!(Mat4, Vec4, 4)
|
||||
col_impl!(Mat4, Vec4, 4)
|
||||
to_homogeneous_impl!(Mat4, Mat5, 4, 5)
|
||||
|
@ -712,7 +707,6 @@ transform_impl!(Mat5, Vec5)
|
|||
inv_impl!(Mat5, 5)
|
||||
transpose_impl!(Mat5, 5)
|
||||
approx_eq_impl!(Mat5)
|
||||
column_impl!(Mat5, Vec5, 5)
|
||||
row_impl!(Mat5, Vec5, 5)
|
||||
col_impl!(Mat5, Vec5, 5)
|
||||
to_homogeneous_impl!(Mat5, Mat6, 5, 6)
|
||||
|
@ -955,7 +949,6 @@ transform_impl!(Mat6, Vec6)
|
|||
inv_impl!(Mat6, 6)
|
||||
transpose_impl!(Mat6, 6)
|
||||
approx_eq_impl!(Mat6)
|
||||
column_impl!(Mat6, Vec6, 6)
|
||||
row_impl!(Mat6, Vec6, 6)
|
||||
col_impl!(Mat6, Vec6, 6)
|
||||
outer_impl!(Vec6, Mat6)
|
||||
|
|
|
@ -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(
|
||||
($t: ident, $tv: ident, $dim: expr) => (
|
||||
impl<N: Clone + Zero> Row<$tv<N>> for $t<N> {
|
||||
|
@ -260,7 +236,7 @@ macro_rules! col_impl(
|
|||
#[inline]
|
||||
fn set_col(&mut self, col: uint, v: $tv<N>) {
|
||||
for (i, e) in v.iter().enumerate() {
|
||||
self.set((col, i), e.clone());
|
||||
self.set((i, col), e.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue