#![macro_use] macro_rules! dvec_impl( ($dvec: ident) => ( impl $dvec { /// Builds a vector filled with zeros. /// /// # Arguments /// * `dim` - The dimension of the vector. #[inline] pub fn new_zeros(dim: usize) -> $dvec { $dvec::from_elem(dim, ::zero()) } /// Tests if all components of the vector are zeroes. #[inline] pub fn is_zero(&self) -> bool { self.as_slice().iter().all(|e| e.is_zero()) } } impl $dvec { /// Slices this vector. #[inline] pub fn as_slice<'a>(&'a self) -> &'a [N] { &self.at[.. self.len()] } /// Mutably slices this vector. #[inline] pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [N] { let len = self.len(); &mut self.at[.. len] } } impl Shape for $dvec { #[inline] fn shape(&self) -> usize { self.len() } } impl Indexable for $dvec { #[inline] fn at(&self, i: usize) -> N { assert!(i < self.len()); unsafe { self.unsafe_at(i) } } #[inline] fn set(&mut self, i: usize, val: N) { assert!(i < self.len()); unsafe { self.unsafe_set(i, val); } } #[inline] fn swap(&mut self, i: usize, j: usize) { assert!(i < self.len()); assert!(j < self.len()); self.as_mut_slice().swap(i, j); } #[inline] unsafe fn unsafe_at(&self, i: usize) -> N { *self.at[..].get_unchecked(i) } #[inline] unsafe fn unsafe_set(&mut self, i: usize, val: N) { *self.at[..].get_unchecked_mut(i) = val } } impl Index for $dvec { type Output = N; fn index(&self, i: usize) -> &N { &self.as_slice()[i] } } impl IndexMut for $dvec { fn index_mut(&mut self, i: usize) -> &mut N { &mut self.as_mut_slice()[i] } } impl $dvec { /// Builds a vector filled with ones. /// /// # Arguments /// * `dim` - The dimension of the vector. #[inline] pub fn new_ones(dim: usize) -> $dvec { $dvec::from_elem(dim, ::one()) } } impl $dvec { /// Builds a vector filled with random values. #[inline] pub fn new_random(dim: usize) -> $dvec { $dvec::from_fn(dim, |_| rand::random()) } } impl Iterable for $dvec { #[inline] fn iter<'l>(&'l self) -> Iter<'l, N> { self.as_slice().iter() } } impl IterableMut for $dvec { #[inline] fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> { self.as_mut_slice().iter_mut() } } impl + Mul> Axpy for $dvec { fn axpy(&mut self, a: &N, x: &$dvec) { assert!(self.len() == x.len()); for i in 0..x.len() { unsafe { let self_i = self.unsafe_at(i); self.unsafe_set(i, self_i + *a * x.unsafe_at(i)) } } } } 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 except one which is equal /// to 1.0. pub fn canonical_basis_with_dim(dim: usize) -> Vec<$dvec> { let mut res : Vec<$dvec> = Vec::new(); for i in 0..dim { let mut basis_element : $dvec = $dvec::new_zeros(dim); basis_element.set(i, ::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) -> Vec<$dvec> { // compute the basis of the orthogonal subspace using Gram-Schmidt // orthogonalization algorithm let dim = self.len(); let mut res : Vec<$dvec> = Vec::new(); for i in 0..dim { let mut basis_element : $dvec = $dvec::new_zeros(self.len()); basis_element.set(i, ::one()); if res.len() == dim - 1 { break; } let mut elt = basis_element.clone(); elt.axpy(&-::dot(&basis_element, self), self); for v in res.iter() { let proj = ::dot(&elt, v); elt.axpy(&-proj, v) }; if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) { res.push(Norm::normalize(&elt)); } } assert!(res.len() == dim - 1); res } } impl + Zero> Mul<$dvec> for $dvec { type Output = $dvec; #[inline] fn mul(self, right: $dvec) -> $dvec { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) { *left = *left * *right } res } } impl + Zero> Div<$dvec> for $dvec { type Output = $dvec; #[inline] fn div(self, right: $dvec) -> $dvec { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) { *left = *left / *right } res } } impl + Zero> Add<$dvec> for $dvec { type Output = $dvec; #[inline] fn add(self, right: $dvec) -> $dvec { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) { *left = *left + *right } res } } impl + Zero> Sub<$dvec> for $dvec { type Output = $dvec; #[inline] fn sub(self, right: $dvec) -> $dvec { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) { *left = *left - *right } res } } impl + Zero + Copy> Neg for $dvec { type Output = $dvec; #[inline] fn neg(self) -> $dvec { FromIterator::from_iter(self.as_slice().iter().map(|a| -*a)) } } impl Dot for $dvec { #[inline] fn dot(&self, other: &$dvec) -> N { assert!(self.len() == other.len()); let mut res: N = ::zero(); for i in 0..self.len() { res = res + unsafe { self.unsafe_at(i) * other.unsafe_at(i) }; } res } } impl Norm for $dvec { #[inline] fn sqnorm(&self) -> N { Dot::dot(self, self) } #[inline] fn normalize(&self) -> $dvec { let mut res : $dvec = self.clone(); let _ = res.normalize_mut(); res } #[inline] fn normalize_mut(&mut self) -> N { let l = Norm::norm(self); for n in self.as_mut_slice().iter_mut() { *n = *n / l; } l } } impl> ApproxEq for $dvec { #[inline] fn approx_epsilon(_: Option<$dvec>) -> N { ApproxEq::approx_epsilon(None::) } #[inline] fn approx_ulps(_: Option<$dvec>) -> u32 { ApproxEq::approx_ulps(None::) } #[inline] fn approx_eq_eps(&self, other: &$dvec, epsilon: &N) -> bool { let mut zip = self.as_slice().iter().zip(other.as_slice().iter()); zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon)) } #[inline] fn approx_eq_ulps(&self, other: &$dvec, ulps: u32) -> bool { let mut zip = self.as_slice().iter().zip(other.as_slice().iter()); zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps)) } } impl + Zero> Mul for $dvec { type Output = $dvec; #[inline] fn mul(self, right: N) -> $dvec { let mut res = self; for e in res.as_mut_slice().iter_mut() { *e = *e * right } res } } impl + Zero> Div for $dvec { type Output = $dvec; #[inline] fn div(self, right: N) -> $dvec { let mut res = self; for e in res.as_mut_slice().iter_mut() { *e = *e / right } res } } impl + Zero> Add for $dvec { type Output = $dvec; #[inline] fn add(self, right: N) -> $dvec { let mut res = self; for e in res.as_mut_slice().iter_mut() { *e = *e + right } res } } impl + Zero> Sub for $dvec { type Output = $dvec; #[inline] fn sub(self, right: N) -> $dvec { let mut res = self; for e in res.as_mut_slice().iter_mut() { *e = *e - right } res } } ) ); macro_rules! small_dvec_impl ( ($dvec: ident, $dim: expr, $($idx: expr),*) => ( impl $dvec { #[inline] pub fn len(&self) -> usize { self.dim } } impl PartialEq for $dvec { #[inline] fn eq(&self, other: &$dvec) -> bool { if self.len() != other.len() { return false; // FIXME: fail instead? } for (a, b) in self.as_slice().iter().zip(other.as_slice().iter()) { if *a != *b { return false; } } true } } impl Clone for $dvec { fn clone(&self) -> $dvec { let at: [N; $dim] = [ $( self.at[$idx].clone(), )* ]; $dvec { at: at, dim: self.dim } } } dvec_impl!($dvec); ) ); macro_rules! small_dvec_from_impl ( ($dvec: ident, $dim: expr, $($zeros: expr),*) => ( impl $dvec { /// Builds a vector filled with a constant. #[inline] pub fn from_elem(dim: usize, elem: N) -> $dvec { assert!(dim <= $dim); let mut at: [N; $dim] = [ $( $zeros, )* ]; for n in &mut at[.. dim] { *n = elem; } $dvec { at: at, dim: dim } } } impl $dvec { /// Builds a vector filled with the components provided by a vector. /// /// The vector must have at least `dim` elements. #[inline] pub fn from_slice(dim: usize, vec: &[N]) -> $dvec { assert!(dim <= vec.len() && dim <= $dim); // FIXME: not safe. let mut at: [N; $dim] = [ $( $zeros, )* ]; for (curr, other) in vec.iter().zip(at.iter_mut()) { *other = *curr; } $dvec { at: at, dim: dim } } } impl $dvec { /// Builds a vector filled with the result of a function. #[inline(always)] pub fn from_fn N>(dim: usize, mut f: F) -> $dvec { assert!(dim <= $dim); let mut at: [N; $dim] = [ $( $zeros, )* ]; for i in 0..dim { at[i] = f(i); } $dvec { at: at, dim: dim } } } impl FromIterator for $dvec { #[inline] fn from_iter>(param: I) -> $dvec { let mut at: [N; $dim] = [ $( $zeros, )* ]; let mut dim = 0; for n in param.into_iter() { if dim == $dim { break; } at[dim] = n; dim = dim + 1; } $dvec { at: at, dim: dim } } } #[cfg(feature="arbitrary")] impl Arbitrary for $dvec { #[inline] fn arbitrary(g: &mut G) -> $dvec { $dvec::from_fn(g.gen_range(0, $dim), |_| Arbitrary::arbitrary(g)) } } ) );