Adapted to new vec iterator api.

This commit is contained in:
Sébastien Crozet 2013-06-09 12:09:22 +00:00
parent ec87e81426
commit 965601d4e0
3 changed files with 61 additions and 31 deletions

View File

@ -1,7 +1,8 @@
use std::uint::iterate; use std::uint::iterate;
use std::num::{One, Zero}; use std::num::{One, Zero};
use std::vec::{from_elem, swap, all, all2, len}; use std::vec::{from_elem, swap};
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::iterator::IteratorUtil;
use traits::inv::Inv; use traits::inv::Inv;
use traits::division_ring::DivisionRing; use traits::division_ring::DivisionRing;
use traits::transpose::Transpose; use traits::transpose::Transpose;
@ -19,7 +20,7 @@ pub fn zero_mat_with_dim<T: Zero + Copy>(dim: uint) -> DMat<T>
{ DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) } } { DMat { dim: dim, mij: from_elem(dim * dim, Zero::zero()) } }
pub fn is_zero_mat<T: Zero>(mat: &DMat<T>) -> bool pub fn is_zero_mat<T: Zero>(mat: &DMat<T>) -> bool
{ all(mat.mij, |e| e.is_zero()) } { mat.mij.all(|e| e.is_zero()) }
pub fn one_mat_with_dim<T: Copy + One + Zero>(dim: uint) -> DMat<T> pub fn one_mat_with_dim<T: Copy + One + Zero>(dim: uint) -> DMat<T>
{ {
@ -90,7 +91,7 @@ RMul<DVec<T>> for DMat<T>
{ {
fn rmul(&self, other: &DVec<T>) -> DVec<T> fn rmul(&self, other: &DVec<T>) -> DVec<T>
{ {
assert!(self.dim == len(other.at)); assert!(self.dim == other.at.len());
let dim = self.dim; let dim = self.dim;
let mut res : DVec<T> = zero_vec_with_dim(dim); let mut res : DVec<T> = zero_vec_with_dim(dim);
@ -110,7 +111,7 @@ LMul<DVec<T>> for DMat<T>
{ {
fn lmul(&self, other: &DVec<T>) -> DVec<T> fn lmul(&self, other: &DVec<T>) -> DVec<T>
{ {
assert!(self.dim == len(other.at)); assert!(self.dim == other.at.len());
let dim = self.dim; let dim = self.dim;
let mut res : DVec<T> = zero_vec_with_dim(dim); let mut res : DVec<T> = zero_vec_with_dim(dim);
@ -248,8 +249,16 @@ impl<T: ApproxEq<T>> ApproxEq<T> for DMat<T>
{ ApproxEq::approx_epsilon::<T, T>() } { ApproxEq::approx_epsilon::<T, T>() }
fn approx_eq(&self, other: &DMat<T>) -> bool fn approx_eq(&self, other: &DMat<T>) -> bool
{ all2(self.mij, other.mij, |a, b| a.approx_eq(b)) } {
let mut zip = self.mij.iter().zip(other.mij.iter());
do zip.all |(a, b)| { a.approx_eq(b) }
}
fn approx_eq_eps(&self, other: &DMat<T>, epsilon: &T) -> bool fn approx_eq_eps(&self, other: &DMat<T>, epsilon: &T) -> bool
{ all2(self.mij, other.mij, |a, b| a.approx_eq_eps(b, epsilon)) } {
let mut zip = self.mij.iter().zip(other.mij.iter());
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
}
} }

View File

@ -1,7 +1,8 @@
use std::uint::iterate; use std::uint::iterate;
use std::num::{Zero, One, Algebraic}; use std::num::{Zero, One, Algebraic};
use std::vec::{map_zip, map, all2, len, from_elem, all}; use std::vec::{map_zip, map, from_elem};
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
use std::iterator::IteratorUtil;
use traits::ring::Ring; use traits::ring::Ring;
use traits::division_ring::DivisionRing; use traits::division_ring::DivisionRing;
use traits::dot::Dot; use traits::dot::Dot;
@ -20,7 +21,7 @@ pub fn zero_vec_with_dim<T: Zero + Copy>(dim: uint) -> DVec<T>
{ DVec { at: from_elem(dim, Zero::zero::<T>()) } } { DVec { at: from_elem(dim, Zero::zero::<T>()) } }
pub fn is_zero_vec<T: Zero>(vec: &DVec<T>) -> bool pub fn is_zero_vec<T: Zero>(vec: &DVec<T>) -> bool
{ all(vec.at, |e| e.is_zero()) } { vec.at.all(|e| e.is_zero()) }
// FIXME: is Clone needed? // FIXME: is Clone needed?
impl<T: Copy + DivisionRing + Algebraic + Clone + ApproxEq<T>> DVec<T> impl<T: Copy + DivisionRing + Algebraic + Clone + ApproxEq<T>> DVec<T>
@ -45,12 +46,12 @@ impl<T: Copy + DivisionRing + Algebraic + Clone + ApproxEq<T>> DVec<T>
{ {
// compute the basis of the orthogonal subspace using Gram-Schmidt // compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm // orthogonalization algorithm
let dim = len(self.at); let dim = self.at.len();
let mut res : ~[DVec<T>] = ~[]; let mut res : ~[DVec<T>] = ~[];
for iterate(0u, dim) |i| for iterate(0u, dim) |i|
{ {
let mut basis_element : DVec<T> = zero_vec_with_dim(len(self.at)); let mut basis_element : DVec<T> = zero_vec_with_dim(self.at.len());
basis_element.at[i] = One::one(); basis_element.at[i] = One::one();
@ -78,7 +79,7 @@ impl<T: Copy + Add<T,T>> Add<DVec<T>, DVec<T>> for DVec<T>
{ {
fn add(&self, other: &DVec<T>) -> DVec<T> fn add(&self, other: &DVec<T>) -> DVec<T>
{ {
assert!(len(self.at) == len(other.at)); assert!(self.at.len() == other.at.len());
DVec { at: map_zip(self.at, other.at, | a, b | { *a + *b }) } DVec { at: map_zip(self.at, other.at, | a, b | { *a + *b }) }
} }
} }
@ -87,7 +88,7 @@ impl<T: Copy + Sub<T,T>> Sub<DVec<T>, DVec<T>> for DVec<T>
{ {
fn sub(&self, other: &DVec<T>) -> DVec<T> fn sub(&self, other: &DVec<T>) -> DVec<T>
{ {
assert!(len(self.at) == len(other.at)); assert!(self.at.len() == other.at.len());
DVec { at: map_zip(self.at, other.at, | a, b | *a - *b) } DVec { at: map_zip(self.at, other.at, | a, b | *a - *b) }
} }
} }
@ -103,11 +104,11 @@ Dot<T> for DVec<T>
{ {
fn dot(&self, other: &DVec<T>) -> T fn dot(&self, other: &DVec<T>) -> T
{ {
assert!(len(self.at) == len(other.at)); assert!(self.at.len() == other.at.len());
let mut res = Zero::zero::<T>(); let mut res = Zero::zero::<T>();
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ res += self.at[i] * other.at[i]; } { res += self.at[i] * other.at[i]; }
res res
@ -120,7 +121,7 @@ impl<T: Copy + Ring> SubDot<T> for DVec<T>
{ {
let mut res = Zero::zero::<T>(); let mut res = Zero::zero::<T>();
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ res += (self.at[i] - a.at[i]) * b.at[i]; } { res += (self.at[i] - a.at[i]) * b.at[i]; }
res res
@ -135,7 +136,7 @@ ScalarMul<T> for DVec<T>
fn scalar_mul_inplace(&mut self, s: &T) fn scalar_mul_inplace(&mut self, s: &T)
{ {
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ self.at[i] *= *s; } { self.at[i] *= *s; }
} }
} }
@ -149,7 +150,7 @@ ScalarDiv<T> for DVec<T>
fn scalar_div_inplace(&mut self, s: &T) fn scalar_div_inplace(&mut self, s: &T)
{ {
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ self.at[i] /= *s; } { self.at[i] /= *s; }
} }
} }
@ -162,7 +163,7 @@ ScalarAdd<T> for DVec<T>
fn scalar_add_inplace(&mut self, s: &T) fn scalar_add_inplace(&mut self, s: &T)
{ {
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ self.at[i] += *s; } { self.at[i] += *s; }
} }
} }
@ -175,7 +176,7 @@ ScalarSub<T> for DVec<T>
fn scalar_sub_inplace(&mut self, s: &T) fn scalar_sub_inplace(&mut self, s: &T)
{ {
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ self.at[i] -= *s; } { self.at[i] -= *s; }
} }
} }
@ -214,7 +215,7 @@ Norm<T> for DVec<T>
{ {
let l = self.norm(); let l = self.norm();
for iterate(0u, len(self.at)) |i| for iterate(0u, self.at.len()) |i|
{ self.at[i] /= l; } { self.at[i] /= l; }
l l
@ -227,8 +228,16 @@ impl<T: ApproxEq<T>> ApproxEq<T> for DVec<T>
{ ApproxEq::approx_epsilon::<T, T>() } { ApproxEq::approx_epsilon::<T, T>() }
fn approx_eq(&self, other: &DVec<T>) -> bool fn approx_eq(&self, other: &DVec<T>) -> bool
{ all2(self.at, other.at, |a, b| a.approx_eq(b)) } {
let mut zip = self.at.iter().zip(other.at.iter());
do zip.all |(a, b)| { a.approx_eq(b) }
}
fn approx_eq_eps(&self, other: &DVec<T>, epsilon: &T) -> bool fn approx_eq_eps(&self, other: &DVec<T>, epsilon: &T) -> bool
{ all2(self.at, other.at, |a, b| a.approx_eq_eps(b, epsilon)) } {
let mut zip = self.at.iter().zip(other.at.iter());
do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) }
}
} }

View File

@ -1,10 +1,10 @@
#[test] #[test]
use std::iterator::IteratorUtil;
#[test]
use std::num::{Zero, One}; use std::num::{Zero, One};
#[test] #[test]
use std::rand::{random}; use std::rand::{random};
#[test] #[test]
use std::vec::{all, all2};
#[test]
use std::cmp::ApproxEq; use std::cmp::ApproxEq;
#[test] #[test]
use dim3::vec3::Vec3; use dim3::vec3::Vec3;
@ -44,9 +44,14 @@ macro_rules! test_basis_impl(
let basis = Basis::canonical_basis::<$t>(); let basis = Basis::canonical_basis::<$t>();
// check vectors form an ortogonal basis // check vectors form an ortogonal basis
assert!(all2(basis, basis, |e1, e2| e1 == e2 || e1.dot(e2).approx_eq(&Zero::zero()))); assert!(
do basis.iter().zip(basis.iter()).all
|(e1, e2)| { e1 == e2 || e1.dot(e2).approx_eq(&Zero::zero()) }
);
// check vectors form an orthonormal basis // check vectors form an orthonormal basis
assert!(all(basis, |e| e.norm().approx_eq(&One::one()))); assert!(
do basis.iter().all |e| { e.norm().approx_eq(&One::one()) }
);
} }
); );
) )
@ -56,15 +61,22 @@ macro_rules! test_subspace_basis_impl(
for 10000.times for 10000.times
{ {
let v : Vec3<f64> = random(); let v : Vec3<f64> = random();
let v1 = v.normalized(); let v1 = v.normalized();
let subbasis = v1.orthogonal_subspace_basis(); let subbasis = v1.orthogonal_subspace_basis();
// check vectors are orthogonal to v1 // check vectors are orthogonal to v1
assert!(all(subbasis, |e| v1.dot(e).approx_eq(&Zero::zero()))); assert!(
do subbasis.iter().all |e| { v1.dot(e).approx_eq(&Zero::zero()) }
);
// check vectors form an ortogonal basis // check vectors form an ortogonal basis
assert!(all2(subbasis, subbasis, |e1, e2| e1 == e2 || e1.dot(e2).approx_eq(&Zero::zero()))); assert!(
do subbasis.iter().zip(subbasis.iter()).all
|(e1, e2)| { e1 == e2 || e1.dot(e2).approx_eq(&Zero::zero()) }
);
// check vectors form an orthonormal basis // check vectors form an orthonormal basis
assert!(all(subbasis, |e| e.norm().approx_eq(&One::one()))); assert!(
do subbasis.iter().all |e| { e.norm().approx_eq(&One::one()) }
);
} }
); );
) )