2013-09-22 16:58:21 +08:00
|
|
|
//! Vector with dimensions unknown at compile-time.
|
|
|
|
|
2013-09-15 16:48:18 +08:00
|
|
|
#[doc(hidden)]; // we hide doc to not have to document the $trhs double dispatch trait.
|
|
|
|
|
2013-06-02 02:50:00 +08:00
|
|
|
use std::num::{Zero, One, Algebraic};
|
2013-09-13 16:53:59 +08:00
|
|
|
use std::rand::Rand;
|
|
|
|
use std::rand;
|
2013-09-07 14:43:17 +08:00
|
|
|
use std::vec;
|
2013-06-29 05:03:40 +08:00
|
|
|
use std::vec::{VecIterator, VecMutIterator};
|
2013-06-02 02:50:00 +08:00
|
|
|
use std::cmp::ApproxEq;
|
2013-09-09 17:19:54 +08:00
|
|
|
use std::iter::FromIterator;
|
2013-09-22 16:58:21 +08:00
|
|
|
use traits::geometry::{Dot, Norm, Translation};
|
|
|
|
use traits::structure::{Iterable, IterableMut};
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-09-22 20:22:17 +08:00
|
|
|
#[doc(hidden)]
|
2013-09-15 16:48:18 +08:00
|
|
|
mod metal;
|
|
|
|
|
2013-07-24 22:50:40 +08:00
|
|
|
/// Vector with a dimension unknown at compile-time.
|
2013-08-13 16:57:19 +08:00
|
|
|
#[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-09-15 16:48:18 +08:00
|
|
|
double_dispatch_binop_decl_trait!(DVec, DVecMulRhs)
|
|
|
|
double_dispatch_binop_decl_trait!(DVec, DVecDivRhs)
|
|
|
|
double_dispatch_binop_decl_trait!(DVec, DVecAddRhs)
|
|
|
|
double_dispatch_binop_decl_trait!(DVec, DVecSubRhs)
|
|
|
|
|
|
|
|
mul_redispatch_impl!(DVec, DVecMulRhs)
|
|
|
|
div_redispatch_impl!(DVec, DVecDivRhs)
|
|
|
|
add_redispatch_impl!(DVec, DVecAddRhs)
|
|
|
|
sub_redispatch_impl!(DVec, DVecSubRhs)
|
|
|
|
|
2013-09-05 06:01:10 +08:00
|
|
|
impl<N: Zero + Clone> DVec<N> {
|
|
|
|
/// Builds a vector filled with zeros.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
/// * `dim` - The dimension of the vector.
|
|
|
|
#[inline]
|
|
|
|
pub fn new_zeros(dim: uint) -> DVec<N> {
|
2013-09-07 14:43:17 +08:00
|
|
|
DVec::from_elem(dim, Zero::zero())
|
2013-09-05 06:01:10 +08:00
|
|
|
}
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-09-05 06:01:10 +08:00
|
|
|
/// Tests if all components of the vector are zeroes.
|
|
|
|
#[inline]
|
|
|
|
pub fn is_zero(&self) -> bool {
|
|
|
|
self.at.iter().all(|e| e.is_zero())
|
|
|
|
}
|
2013-08-05 16:13:44 +08:00
|
|
|
}
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-09-13 17:32:30 +08:00
|
|
|
impl<N: Clone> DVec<N> {
|
|
|
|
/// Indexing without bounds checking.
|
|
|
|
pub unsafe fn at_fast(&self, i: uint) -> N {
|
|
|
|
vec::raw::get(self.at, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-07 14:43:17 +08:00
|
|
|
impl<N: One + Clone> DVec<N> {
|
|
|
|
/// Builds a vector filled with ones.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
/// * `dim` - The dimension of the vector.
|
|
|
|
#[inline]
|
|
|
|
pub fn new_ones(dim: uint) -> DVec<N> {
|
|
|
|
DVec::from_elem(dim, One::one())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-13 16:53:59 +08:00
|
|
|
impl<N: Rand> DVec<N> {
|
|
|
|
/// Builds a vector filled with random values.
|
|
|
|
#[inline]
|
|
|
|
pub fn new_random(dim: uint) -> DVec<N> {
|
|
|
|
DVec::from_fn(dim, |_| rand::random())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-13 17:11:04 +08:00
|
|
|
impl<N> DVec<N> {
|
|
|
|
/// Creates an uninitialized vec.
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn new_uninitialized(dim: uint) -> DVec<N> {
|
|
|
|
let mut vec = vec::with_capacity(dim);
|
|
|
|
vec::raw::set_len(&mut vec, dim);
|
|
|
|
|
|
|
|
DVec {
|
|
|
|
at: vec
|
|
|
|
}
|
|
|
|
}
|
2013-09-22 20:22:17 +08:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn set_fast(&mut self, i: uint, val: N) {
|
|
|
|
*self.at.unsafe_mut_ref(i) = val
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn to_vec(self) -> ~[N] {
|
|
|
|
self.at
|
|
|
|
}
|
2013-09-13 17:11:04 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 14:43:17 +08:00
|
|
|
impl<N: Clone> DVec<N> {
|
|
|
|
/// Builds a vector filled with a constant.
|
|
|
|
#[inline]
|
|
|
|
pub fn from_elem(dim: uint, elem: N) -> DVec<N> {
|
|
|
|
DVec { at: vec::from_elem(dim, elem) }
|
|
|
|
}
|
2013-09-22 20:22:17 +08:00
|
|
|
|
|
|
|
/// Builds a vector filled with the components provided by a vector.
|
|
|
|
///
|
|
|
|
/// The vector must have at least `dim` elements.
|
|
|
|
#[inline]
|
|
|
|
pub fn from_vec(dim: uint, vec: &[N]) -> DVec<N> {
|
|
|
|
assert!(dim <= vec.len());
|
|
|
|
|
|
|
|
DVec {
|
|
|
|
at: vec.slice_to(dim).to_owned()
|
|
|
|
}
|
|
|
|
}
|
2013-09-07 14:43:17 +08:00
|
|
|
}
|
|
|
|
|
2013-09-13 16:53:59 +08:00
|
|
|
impl<N> DVec<N> {
|
2013-09-07 14:43:17 +08:00
|
|
|
/// Builds a vector filled with the result of a function.
|
|
|
|
#[inline(always)]
|
|
|
|
pub fn from_fn(dim: uint, f: &fn(uint) -> N) -> DVec<N> {
|
|
|
|
DVec { at: vec::from_fn(dim, |i| f(i)) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-08 23:19:50 +08:00
|
|
|
impl<N> Container for DVec<N> {
|
|
|
|
#[inline]
|
|
|
|
fn len(&self) -> uint {
|
|
|
|
self.at.len()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
impl<N> Iterable<N> for DVec<N> {
|
2013-09-08 23:19:50 +08:00
|
|
|
#[inline]
|
2013-08-05 16:13:44 +08:00
|
|
|
fn iter<'l>(&'l self) -> VecIterator<'l, N> {
|
|
|
|
self.at.iter()
|
|
|
|
}
|
2013-06-29 05:03:40 +08:00
|
|
|
}
|
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
impl<N> IterableMut<N> for DVec<N> {
|
2013-09-08 23:19:50 +08:00
|
|
|
#[inline]
|
2013-08-05 16:13:44 +08:00
|
|
|
fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> {
|
|
|
|
self.at.mut_iter()
|
|
|
|
}
|
2013-06-29 05:03:40 +08:00
|
|
|
}
|
|
|
|
|
2013-08-16 16:14:01 +08:00
|
|
|
impl<N> FromIterator<N> for DVec<N> {
|
2013-09-08 23:19:50 +08:00
|
|
|
#[inline]
|
2013-08-16 16:14:01 +08:00
|
|
|
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-06-29 05:03:40 +08:00
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
for e in param {
|
|
|
|
res.at.push(e)
|
|
|
|
}
|
2013-06-29 05:03:40 +08:00
|
|
|
|
2013-08-05 15:44:56 +08:00
|
|
|
res
|
|
|
|
}
|
2013-06-29 05:03:40 +08:00
|
|
|
}
|
|
|
|
|
2013-09-15 16:48:18 +08:00
|
|
|
impl<N: Clone + Num + Algebraic + ApproxEq<N> + DVecMulRhs<N, DVec<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-09-05 06:01:10 +08:00
|
|
|
let mut basis_element : DVec<N> = DVec::new_zeros(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-09-05 06:01:10 +08:00
|
|
|
let mut basis_element : DVec<N> = DVec::new_zeros(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
|
|
|
|
Rework of the traits for Vectors.
The goal is to make traits less fine-grained for vectors, and reduce the amount of `use`.
- Scalar{Mul, Div} are removed, replaced by Mul<N, V> and Div<N, V>,
- Ring and DivisionRing are removed. Use Num instead.
- VectorSpace, Dot, and Norm are removed, replaced by the new, higher-level traits.
Add four traits:
- Vec: common operations on vectors. Replaces VectorSpace and Dot.
- AlgebraicVec: Vec + the old Norm trait.
- VecExt: Vec + every other traits vectors implement.
- AlgebraicVecExt: AlgebraicVec + VecExt.
2013-08-19 00:33:25 +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() {
|
Rework of the traits for Vectors.
The goal is to make traits less fine-grained for vectors, and reduce the amount of `use`.
- Scalar{Mul, Div} are removed, replaced by Mul<N, V> and Div<N, V>,
- Ring and DivisionRing are removed. Use Num instead.
- VectorSpace, Dot, and Norm are removed, replaced by the new, higher-level traits.
Add four traits:
- Vec: common operations on vectors. Replaces VectorSpace and Dot.
- AlgebraicVec: Vec + the old Norm trait.
- VecExt: Vec + every other traits vectors implement.
- AlgebraicVecExt: AlgebraicVec + VecExt.
2013-08-19 00:33:25 +08:00
|
|
|
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-09-15 16:48:18 +08:00
|
|
|
impl<N: Add<N, N>> DVecAddRhs<N, DVec<N>> for DVec<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
#[inline]
|
2013-09-15 16:48:18 +08:00
|
|
|
fn binop(left: &DVec<N>, right: &DVec<N>) -> DVec<N> {
|
|
|
|
assert!(left.at.len() == right.at.len());
|
2013-08-05 15:44:56 +08:00
|
|
|
DVec {
|
2013-09-15 16:48:18 +08:00
|
|
|
at: left.at.iter().zip(right.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-09-15 16:48:18 +08:00
|
|
|
impl<N: Sub<N, N>> DVecSubRhs<N, DVec<N>> for DVec<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
#[inline]
|
2013-09-15 16:48:18 +08:00
|
|
|
fn binop(left: &DVec<N>, right: &DVec<N>) -> DVec<N> {
|
|
|
|
assert!(left.at.len() == right.at.len());
|
2013-08-05 15:44:56 +08:00
|
|
|
DVec {
|
2013-09-15 16:48:18 +08:00
|
|
|
at: left.at.iter().zip(right.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
|
|
|
}
|
|
|
|
|
2013-09-26 23:05:11 +08:00
|
|
|
impl<N: Num + Clone> Dot<N> for DVec<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
#[inline]
|
2013-09-09 00:29:51 +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-28 20:22:12 +08:00
|
|
|
let mut res: N = Zero::zero();
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
for i in range(0u, self.at.len()) {
|
2013-09-26 23:05:11 +08:00
|
|
|
res = res + unsafe { self.at_fast(i) * other.at_fast(i) };
|
2013-08-05 16:13:44 +08:00
|
|
|
}
|
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-09-09 00:29:51 +08:00
|
|
|
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N {
|
2013-08-28 20:22:12 +08:00
|
|
|
let mut res: N = Zero::zero();
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-08-05 16:13:44 +08:00
|
|
|
for i in range(0u, self.at.len()) {
|
2013-09-26 23:05:11 +08:00
|
|
|
res = res + unsafe { (self.at_fast(i) - a.at_fast(i)) * b.at_fast(i) };
|
2013-08-05 16:13:44 +08:00
|
|
|
}
|
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> + 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-06-29 05:03:40 +08:00
|
|
|
|
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
|
|
|
|
}
|
2013-09-06 14:48:08 +08:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn set_translation(&mut self, t: DVec<N>) {
|
|
|
|
*self = t
|
|
|
|
}
|
2013-06-28 00:16:07 +08:00
|
|
|
}
|
|
|
|
|
2013-09-09 00:29:51 +08:00
|
|
|
impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> {
|
2013-08-05 15:44:56 +08:00
|
|
|
#[inline]
|
2013-09-09 00:29:51 +08:00
|
|
|
fn sqnorm(&self) -> N {
|
2013-08-05 16:13:44 +08:00
|
|
|
self.dot(self)
|
|
|
|
}
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-08-05 15:44:56 +08:00
|
|
|
#[inline]
|
2013-09-09 00:29:51 +08:00
|
|
|
fn norm(&self) -> N {
|
2013-08-05 16:13:44 +08:00
|
|
|
self.sqnorm().sqrt()
|
|
|
|
}
|
2013-05-31 17:01:07 +08:00
|
|
|
|
2013-08-05 15:44:56 +08:00
|
|
|
#[inline]
|
2013-09-09 00:29:51 +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-09-09 00:29:51 +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 {
|
2013-08-28 20:22:12 +08:00
|
|
|
fail!("Fix me.")
|
|
|
|
// let res: N = ApproxEq::<N>::approx_epsilon();
|
|
|
|
|
|
|
|
// res
|
2013-08-05 16:13:44 +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(&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
|
|
|
}
|
2013-09-15 16:48:18 +08:00
|
|
|
|
|
|
|
macro_rules! scalar_mul_impl (
|
|
|
|
($n: ident) => (
|
|
|
|
impl DVecMulRhs<$n, DVec<$n>> for $n {
|
|
|
|
#[inline]
|
|
|
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
|
|
|
DVec { at: left.at.iter().map(|a| a * *right).collect() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! scalar_div_impl (
|
|
|
|
($n: ident) => (
|
|
|
|
impl DVecDivRhs<$n, DVec<$n>> for $n {
|
|
|
|
#[inline]
|
|
|
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
|
|
|
DVec { at: left.at.iter().map(|a| a / *right).collect() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! scalar_add_impl (
|
|
|
|
($n: ident) => (
|
|
|
|
impl DVecAddRhs<$n, DVec<$n>> for $n {
|
|
|
|
#[inline]
|
|
|
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
|
|
|
DVec { at: left.at.iter().map(|a| a + *right).collect() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
macro_rules! scalar_sub_impl (
|
|
|
|
($n: ident) => (
|
|
|
|
impl DVecSubRhs<$n, DVec<$n>> for $n {
|
|
|
|
#[inline]
|
|
|
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
|
|
|
DVec { at: left.at.iter().map(|a| a - *right).collect() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
scalar_mul_impl!(f64)
|
|
|
|
scalar_mul_impl!(f32)
|
|
|
|
scalar_mul_impl!(u64)
|
|
|
|
scalar_mul_impl!(u32)
|
|
|
|
scalar_mul_impl!(u16)
|
|
|
|
scalar_mul_impl!(u8)
|
|
|
|
scalar_mul_impl!(i64)
|
|
|
|
scalar_mul_impl!(i32)
|
|
|
|
scalar_mul_impl!(i16)
|
|
|
|
scalar_mul_impl!(i8)
|
|
|
|
scalar_mul_impl!(uint)
|
|
|
|
scalar_mul_impl!(int)
|
|
|
|
|
|
|
|
scalar_div_impl!(f64)
|
|
|
|
scalar_div_impl!(f32)
|
|
|
|
scalar_div_impl!(u64)
|
|
|
|
scalar_div_impl!(u32)
|
|
|
|
scalar_div_impl!(u16)
|
|
|
|
scalar_div_impl!(u8)
|
|
|
|
scalar_div_impl!(i64)
|
|
|
|
scalar_div_impl!(i32)
|
|
|
|
scalar_div_impl!(i16)
|
|
|
|
scalar_div_impl!(i8)
|
|
|
|
scalar_div_impl!(uint)
|
|
|
|
scalar_div_impl!(int)
|
|
|
|
|
|
|
|
scalar_add_impl!(f64)
|
|
|
|
scalar_add_impl!(f32)
|
|
|
|
scalar_add_impl!(u64)
|
|
|
|
scalar_add_impl!(u32)
|
|
|
|
scalar_add_impl!(u16)
|
|
|
|
scalar_add_impl!(u8)
|
|
|
|
scalar_add_impl!(i64)
|
|
|
|
scalar_add_impl!(i32)
|
|
|
|
scalar_add_impl!(i16)
|
|
|
|
scalar_add_impl!(i8)
|
|
|
|
scalar_add_impl!(uint)
|
|
|
|
scalar_add_impl!(int)
|
|
|
|
|
|
|
|
scalar_sub_impl!(f64)
|
|
|
|
scalar_sub_impl!(f32)
|
|
|
|
scalar_sub_impl!(u64)
|
|
|
|
scalar_sub_impl!(u32)
|
|
|
|
scalar_sub_impl!(u16)
|
|
|
|
scalar_sub_impl!(u8)
|
|
|
|
scalar_sub_impl!(i64)
|
|
|
|
scalar_sub_impl!(i32)
|
|
|
|
scalar_sub_impl!(i16)
|
|
|
|
scalar_sub_impl!(i8)
|
|
|
|
scalar_sub_impl!(uint)
|
|
|
|
scalar_sub_impl!(int)
|