use std::num::{Zero, One, Algebraic}; use std::vec; use std::vec::{VecIterator, VecMutIterator}; use std::cmp::ApproxEq; use std::iterator::FromIterator; use traits::dot::Dot; use traits::norm::Norm; use traits::iterable::{Iterable, IterableMut}; use traits::translation::Translation; use traits::scalar_op::{ScalarAdd, ScalarSub}; /// Vector with a dimension unknown at compile-time. #[deriving(Eq, ToStr, Clone)] pub struct DVec { /// Components of the vector. Contains as much elements as the vector dimension. at: ~[N] } impl DVec { /// Builds a vector filled with zeros. /// /// # Arguments /// * `dim` - The dimension of the vector. #[inline] pub fn new_zeros(dim: uint) -> DVec { DVec::from_elem(dim, Zero::zero()) } /// Tests if all components of the vector are zeroes. #[inline] pub fn is_zero(&self) -> bool { self.at.iter().all(|e| e.is_zero()) } } impl DVec { /// Builds a vector filled with ones. /// /// # Arguments /// * `dim` - The dimension of the vector. #[inline] pub fn new_ones(dim: uint) -> DVec { DVec::from_elem(dim, One::one()) } } impl DVec { /// Builds a vector filled with a constant. #[inline] pub fn from_elem(dim: uint, elem: N) -> DVec { DVec { at: vec::from_elem(dim, elem) } } } impl DVec { /// Builds a vector filled with the result of a function. #[inline(always)] pub fn from_fn(dim: uint, f: &fn(uint) -> N) -> DVec { DVec { at: vec::from_fn(dim, |i| f(i)) } } } impl Container for DVec { #[inline] fn len(&self) -> uint { self.at.len() } } impl Iterable for DVec { #[inline] fn iter<'l>(&'l self) -> VecIterator<'l, N> { self.at.iter() } } impl IterableMut for DVec { #[inline] fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> { self.at.mut_iter() } } impl FromIterator for DVec { #[inline] fn from_iterator>(mut param: &mut I) -> DVec { let mut res = DVec { at: ~[] }; for e in param { res.at.push(e) } res } } impl> DVec { /// Computes the canonical basis for the given dimension. A canonical basis is a set of /// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal /// to 1.0. pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec] { let mut res : ~[DVec] = ~[]; for i in range(0u, dim) { let mut basis_element : DVec = DVec::new_zeros(dim); basis_element.at[i] = One::one(); res.push(basis_element); } res } /// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension /// `n`, this will return `n - 1` vectors. pub fn orthogonal_subspace_basis(&self) -> ~[DVec] { // compute the basis of the orthogonal subspace using Gram-Schmidt // orthogonalization algorithm let dim = self.at.len(); let mut res : ~[DVec] = ~[]; for i in range(0u, dim) { let mut basis_element : DVec = DVec::new_zeros(self.at.len()); basis_element.at[i] = One::one(); if res.len() == dim - 1 { break; } let mut elt = basis_element.clone(); elt = elt - self * basis_element.dot(self); for v in res.iter() { elt = elt - v * elt.dot(v) }; if !elt.sqnorm().approx_eq(&Zero::zero()) { res.push(elt.normalized()); } } assert!(res.len() == dim - 1); res } } impl> Add, DVec> for DVec { #[inline] fn add(&self, other: &DVec) -> DVec { assert!(self.at.len() == other.at.len()); DVec { at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a + *b).collect() } } } impl> Sub, DVec> for DVec { #[inline] fn sub(&self, other: &DVec) -> DVec { assert!(self.at.len() == other.at.len()); DVec { at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a - *b).collect() } } } impl> Neg> for DVec { #[inline] fn neg(&self) -> DVec { DVec { at: self.at.iter().map(|a| -a).collect() } } } impl Dot for DVec { #[inline] fn dot(&self, other: &DVec) -> N { assert!(self.at.len() == other.at.len()); let mut res: N = Zero::zero(); for i in range(0u, self.at.len()) { res = res + self.at[i] * other.at[i]; } res } #[inline] fn sub_dot(&self, a: &DVec, b: &DVec) -> N { let mut res: N = Zero::zero(); for i in range(0u, self.at.len()) { res = res + (self.at[i] - a.at[i]) * b.at[i]; } res } } impl> Mul> for DVec { #[inline] fn mul(&self, s: &N) -> DVec { DVec { at: self.at.iter().map(|a| a * *s).collect() } } } impl> Div> for DVec { #[inline] fn div(&self, s: &N) -> DVec { DVec { at: self.at.iter().map(|a| a / *s).collect() } } } impl> ScalarAdd for DVec { #[inline] fn scalar_add(&self, s: &N) -> DVec { DVec { at: self.at.iter().map(|a| a + *s).collect() } } #[inline] fn scalar_add_inplace(&mut self, s: &N) { for i in range(0u, self.at.len()) { self.at[i] = self.at[i] + *s; } } } impl> ScalarSub for DVec { #[inline] fn scalar_sub(&self, s: &N) -> DVec { DVec { at: self.at.iter().map(|a| a - *s).collect() } } #[inline] fn scalar_sub_inplace(&mut self, s: &N) { for i in range(0u, self.at.len()) { self.at[i] = self.at[i] - *s; } } } impl + Neg + Clone> Translation> for DVec { #[inline] fn translation(&self) -> DVec { self.clone() } #[inline] fn inv_translation(&self) -> DVec { -self } #[inline] fn translate_by(&mut self, t: &DVec) { *self = *self + *t; } #[inline] fn translated(&self, t: &DVec) -> DVec { self + *t } #[inline] fn set_translation(&mut self, t: DVec) { *self = t } } impl Norm for DVec { #[inline] fn sqnorm(&self) -> N { self.dot(self) } #[inline] fn norm(&self) -> N { self.sqnorm().sqrt() } #[inline] fn normalized(&self) -> DVec { let mut res : DVec = self.clone(); res.normalize(); res } #[inline] fn normalize(&mut self) -> N { let l = self.norm(); for i in range(0u, self.at.len()) { self.at[i] = self.at[i] / l; } l } } impl> ApproxEq for DVec { #[inline] fn approx_epsilon() -> N { fail!("Fix me.") // let res: N = ApproxEq::::approx_epsilon(); // res } #[inline] fn approx_eq(&self, other: &DVec) -> bool { let mut zip = self.at.iter().zip(other.at.iter()); do zip.all |(a, b)| { a.approx_eq(b) } } #[inline] fn approx_eq_eps(&self, other: &DVec, epsilon: &N) -> bool { let mut zip = self.at.iter().zip(other.at.iter()); do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) } } }