nalgebra/src/dvec.rs

285 lines
6.7 KiB
Rust
Raw Normal View History

use std::num::{Zero, One, Algebraic};
use std::vec::{VecIterator, VecMutIterator};
2013-07-02 18:00:55 +08:00
use std::vec::from_elem;
use std::cmp::ApproxEq;
2013-08-11 22:07:34 +08:00
use std::iterator::FromIterator;
use traits::vector::{Vec, AlgebraicVec};
use traits::iterable::{Iterable, IterableMut};
use traits::translation::Translation;
use traits::scalar_op::{ScalarAdd, ScalarSub};
2013-05-31 17:01:07 +08:00
2013-07-24 22:50:40 +08:00
/// Vector with a dimension unknown at compile-time.
#[deriving(Eq, ToStr, Clone)]
2013-08-05 16:13:44 +08:00
pub struct DVec<N> {
2013-08-05 15:44:56 +08:00
/// Components of the vector. Contains as much elements as the vector dimension.
at: ~[N]
2013-05-31 17:01:07 +08:00
}
2013-07-24 22:50:40 +08:00
/// Builds a vector filled with zeros.
///
/// # Arguments
/// * `dim` - The dimension of the vector.
2013-06-28 01:40:37 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
pub fn zero_vec_with_dim<N: Zero + Clone>(dim: uint) -> DVec<N> {
DVec { at: from_elem(dim, Zero::zero::<N>()) }
}
2013-05-31 17:01:07 +08:00
2013-07-24 22:50:40 +08:00
/// Tests if all components of the vector are zeroes.
2013-06-28 01:40:37 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
pub fn is_zero_vec<N: Zero>(vec: &DVec<N>) -> bool {
vec.at.iter().all(|e| e.is_zero())
}
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
impl<N> Iterable<N> for DVec<N> {
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
self.at.iter()
}
}
2013-08-05 16:13:44 +08:00
impl<N> IterableMut<N> for DVec<N> {
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
self.at.mut_iter()
}
}
2013-08-16 16:14:01 +08:00
impl<N> FromIterator<N> for DVec<N> {
fn from_iterator<I: Iterator<N>>(mut param: &mut I) -> DVec<N> {
2013-08-05 15:44:56 +08:00
let mut res = DVec { at: ~[] };
2013-08-05 16:13:44 +08:00
for e in param {
res.at.push(e)
}
2013-08-05 15:44:56 +08:00
res
}
}
impl<N: Clone + Num + Algebraic + ApproxEq<N>> DVec<N> {
2013-08-05 15:44:56 +08:00
/// 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.
2013-08-05 16:13:44 +08:00
pub fn canonical_basis_with_dim(dim: uint) -> ~[DVec<N>] {
2013-08-05 15:44:56 +08:00
let mut res : ~[DVec<N>] = ~[];
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
for i in range(0u, dim) {
2013-08-05 15:44:56 +08:00
let mut basis_element : DVec<N> = zero_vec_with_dim(dim);
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
basis_element.at[i] = One::one();
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res.push(basis_element);
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
/// Computes a basis of the space orthogonal to the vector. If the input vector is of dimension
/// `n`, this will return `n - 1` vectors.
2013-08-05 16:13:44 +08:00
pub fn orthogonal_subspace_basis(&self) -> ~[DVec<N>] {
2013-08-05 15:44:56 +08:00
// compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm
let dim = self.at.len();
let mut res : ~[DVec<N>] = ~[];
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
for i in range(0u, dim) {
2013-08-05 15:44:56 +08:00
let mut basis_element : DVec<N> = zero_vec_with_dim(self.at.len());
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
basis_element.at[i] = One::one();
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
if res.len() == dim - 1 {
break;
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
let mut elt = basis_element.clone();
2013-05-31 17:01:07 +08:00
elt = elt - self * basis_element.dot(self);
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
for v in res.iter() {
elt = elt - v * elt.dot(v)
2013-08-05 16:13:44 +08:00
};
2013-08-05 15:44:56 +08:00
2013-08-05 16:13:44 +08:00
if !elt.sqnorm().approx_eq(&Zero::zero()) {
res.push(elt.normalized());
}
2013-08-05 15:44:56 +08:00
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
assert!(res.len() == dim - 1);
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn add(&self, other: &DVec<N>) -> DVec<N> {
2013-08-05 15:44:56 +08:00
assert!(self.at.len() == other.at.len());
DVec {
2013-08-11 22:07:34 +08:00
at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a + *b).collect()
2013-08-05 15:44:56 +08:00
}
2013-07-02 18:00:55 +08:00
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn sub(&self, other: &DVec<N>) -> DVec<N> {
2013-08-05 15:44:56 +08:00
assert!(self.at.len() == other.at.len());
DVec {
2013-08-11 22:07:34 +08:00
at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a - *b).collect()
2013-08-05 15:44:56 +08:00
}
2013-07-02 18:00:55 +08:00
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn neg(&self) -> DVec<N> {
2013-08-11 22:07:34 +08:00
DVec { at: self.at.iter().map(|a| -a).collect() }
2013-08-05 16:13:44 +08:00
}
2013-05-31 17:01:07 +08:00
}
impl<N: Num> DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn dot(&self, other: &DVec<N>) -> N {
2013-08-05 15:44:56 +08:00
assert!(self.at.len() == other.at.len());
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
let mut res = Zero::zero::<N>();
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
for i in range(0u, self.at.len()) {
res = res + self.at[i] * other.at[i];
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
2013-08-05 15:44:56 +08:00
let mut res = Zero::zero::<N>();
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
for i in range(0u, self.at.len()) {
res = res + (self.at[i] - a.at[i]) * b.at[i];
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res
}
2013-05-31 17:01:07 +08:00
}
impl<N: Mul<N, N>> Mul<N, DVec<N>> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
fn mul(&self, s: &N) -> DVec<N> {
2013-08-11 22:07:34 +08:00
DVec { at: self.at.iter().map(|a| a * *s).collect() }
2013-08-05 16:13:44 +08:00
}
2013-05-31 17:01:07 +08:00
}
impl<N: Div<N, N>> Div<N, DVec<N>> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
fn div(&self, s: &N) -> DVec<N> {
2013-08-11 22:07:34 +08:00
DVec { at: self.at.iter().map(|a| a / *s).collect() }
2013-08-05 16:13:44 +08:00
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: Add<N, N>> ScalarAdd<N> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_add(&self, s: &N) -> DVec<N> {
2013-08-11 22:07:34 +08:00
DVec { at: self.at.iter().map(|a| a + *s).collect() }
2013-08-05 16:13:44 +08:00
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_add_inplace(&mut self, s: &N) {
for i in range(0u, self.at.len()) {
self.at[i] = self.at[i] + *s;
}
2013-08-05 15:44:56 +08:00
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: Sub<N, N>> ScalarSub<N> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_sub(&self, s: &N) -> DVec<N> {
2013-08-11 22:07:34 +08:00
DVec { at: self.at.iter().map(|a| a - *s).collect() }
2013-08-05 16:13:44 +08:00
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn scalar_sub_inplace(&mut self, s: &N) {
for i in range(0u, self.at.len()) {
self.at[i] = self.at[i] - *s;
}
2013-08-05 15:44:56 +08:00
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn translation(&self) -> DVec<N> {
self.clone()
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn inv_translation(&self) -> DVec<N> {
-self
}
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn translate_by(&mut self, t: &DVec<N>) {
*self = *self + *t;
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn translated(&self, t: &DVec<N>) -> DVec<N> {
self + *t
}
}
impl<N: Num + Algebraic + Clone> DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn sqnorm(&self) -> N {
self.dot(self)
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn norm(&self) -> N {
self.sqnorm().sqrt()
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn normalized(&self) -> DVec<N> {
2013-08-05 15:44:56 +08:00
let mut res : DVec<N> = self.clone();
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res.normalize();
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
res
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn normalize(&mut self) -> N {
2013-08-05 15:44:56 +08:00
let l = self.norm();
2013-05-31 17:01:07 +08:00
2013-08-05 16:13:44 +08:00
for i in range(0u, self.at.len()) {
self.at[i] = self.at[i] / l;
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
l
}
2013-05-31 17:01:07 +08:00
}
2013-08-05 16:13:44 +08:00
impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn approx_epsilon() -> N {
ApproxEq::approx_epsilon::<N, N>()
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn approx_eq(&self, other: &DVec<N>) -> bool {
2013-08-05 15:44:56 +08:00
let mut zip = self.at.iter().zip(other.at.iter());
2013-06-09 20:09:22 +08:00
2013-08-05 16:13:44 +08:00
do zip.all |(a, b)| {
a.approx_eq(b)
}
2013-08-05 15:44:56 +08:00
}
2013-05-31 17:01:07 +08:00
2013-08-05 15:44:56 +08:00
#[inline]
2013-08-05 16:13:44 +08:00
fn approx_eq_eps(&self, other: &DVec<N>, epsilon: &N) -> bool {
2013-08-05 15:44:56 +08:00
let mut zip = self.at.iter().zip(other.at.iter());
2013-06-09 20:09:22 +08:00
2013-08-05 16:13:44 +08:00
do zip.all |(a, b)| {
a.approx_eq_eps(b, epsilon)
}
2013-08-05 15:44:56 +08:00
}
2013-05-31 17:01:07 +08:00
}