#![macro_use] macro_rules! vecn_dvec_common_impl( ($vecn: ident $(, $param: ident)*) => ( /* * * Zero. * */ impl)*> $vecn { /// Tests if all components of the vector are zeroes. #[inline] pub fn is_zero(&self) -> bool { self.as_ref().iter().all(|e| e.is_zero()) } } /* * * AsRef/AsMut * */ impl)*> AsRef<[N]> for $vecn { #[inline] fn as_ref(&self) -> &[N] { &self.at[.. self.len()] } } impl)*> AsMut<[N]> for $vecn { #[inline] fn as_mut(&mut self) -> &mut [N] { let len = self.len(); &mut self.at[.. len] } } /* * * Shape. * */ impl)*> Shape for $vecn { #[inline] fn shape(&self) -> usize { self.len() } } /* * * Index et. al. * */ impl)*> Indexable for $vecn { #[inline] fn swap(&mut self, i: usize, j: usize) { assert!(i < self.len()); assert!(j < self.len()); self.as_mut().swap(i, j); } #[inline] unsafe fn unsafe_at(&self, i: usize) -> N { *self[..].get_unchecked(i) } #[inline] unsafe fn unsafe_set(&mut self, i: usize, val: N) { *self[..].get_unchecked_mut(i) = val } } impl)*> Index for $vecn where [N]: Index { type Output = <[N] as Index>::Output; fn index(&self, i: T) -> &<[N] as Index>::Output { &self.as_ref()[i] } } impl)*> IndexMut for $vecn where [N]: IndexMut { fn index_mut(&mut self, i: T) -> &mut <[N] as Index>::Output { &mut self.as_mut()[i] } } /* * * Iterable et al. * */ impl)*> Iterable for $vecn { #[inline] fn iter(&self) -> Iter { self.as_ref().iter() } } impl)*> IterableMut for $vecn { #[inline] fn iter_mut(&mut self) -> IterMut { self.as_mut().iter_mut() } } /* * * Axpy * */ impl + Mul $(, $param : ArrayLength)*> Axpy for $vecn { fn axpy(&mut self, a: &N, x: &$vecn) { 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)) } } } } /* * * Mul * */ impl + Zero $(, $param : ArrayLength)*> Mul<$vecn> for $vecn { type Output = $vecn; #[inline] fn mul(self, right: $vecn) -> $vecn { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) { *left = *left * *right } res } } impl + Zero $(, $param : ArrayLength)*> Mul for $vecn { type Output = $vecn; #[inline] fn mul(self, right: N) -> $vecn { let mut res = self; for e in res.as_mut().iter_mut() { *e = *e * right } res } } impl)*> MulAssign<$vecn> for $vecn where N: Copy + MulAssign + Zero $(, $param : ArrayLength)* { #[inline] fn mul_assign(&mut self, right: $vecn) { assert!(self.len() == right.len()); for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) { *left *= *right } } } impl)*> MulAssign for $vecn where N: Copy + MulAssign + Zero $(, $param : ArrayLength)* { #[inline] fn mul_assign(&mut self, right: N) { for e in self.as_mut().iter_mut() { *e *= right } } } impl<$($param : ArrayLength),*> Mul<$vecn> for f32 { type Output = $vecn; #[inline] fn mul(self, right: $vecn) -> $vecn { let mut res = right; for e in res.as_mut().iter_mut() { *e = self * *e; } res } } impl<$($param : ArrayLength),*> Mul<$vecn> for f64 { type Output = $vecn; #[inline] fn mul(self, right: $vecn) -> $vecn { let mut res = right; for e in res.as_mut().iter_mut() { *e = self * *e; } res } } /* * * Div. * */ impl + Zero $(, $param : ArrayLength)*> Div<$vecn> for $vecn { type Output = $vecn; #[inline] fn div(self, right: $vecn) -> $vecn { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) { *left = *left / *right } res } } impl + Zero $(, $param : ArrayLength)*> Div for $vecn { type Output = $vecn; #[inline] fn div(self, right: N) -> $vecn { let mut res = self; for e in res.as_mut().iter_mut() { *e = *e / right } res } } impl<'a, N: Copy + Div + Zero $(, $param : ArrayLength)*> Div<$vecn> for &'a $vecn { type Output = $vecn; #[inline] fn div(self, right: $vecn) -> $vecn { self.clone() / right } } impl<'a, N: Copy + Div + Zero $(, $param : ArrayLength)*> Div for &'a $vecn { type Output = $vecn; #[inline] fn div(self, right: N) -> $vecn { self.clone() / right } } impl)*> DivAssign<$vecn> for $vecn where N: Copy + DivAssign + Zero $(, $param : ArrayLength)* { #[inline] fn div_assign(&mut self, right: $vecn) { assert!(self.len() == right.len()); for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) { *left /= *right } } } impl)*> DivAssign for $vecn where N: Copy + DivAssign + Zero $(, $param : ArrayLength)* { #[inline] fn div_assign(&mut self, right: N) { for e in self.as_mut().iter_mut() { *e /= right } } } /* * * Add. * */ impl + Zero $(, $param : ArrayLength)*> Add<$vecn> for $vecn { type Output = $vecn; #[inline] fn add(self, right: $vecn) -> $vecn { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) { *left = *left + *right } res } } impl + Zero $(, $param : ArrayLength)*> Add for $vecn { type Output = $vecn; #[inline] fn add(self, right: N) -> $vecn { let mut res = self; for e in res.as_mut().iter_mut() { *e = *e + right } res } } impl)*> AddAssign<$vecn> for $vecn where N: Copy + AddAssign + Zero $(, $param : ArrayLength)* { #[inline] fn add_assign(&mut self, right: $vecn) { assert!(self.len() == right.len()); for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) { *left += *right } } } impl)*> AddAssign for $vecn where N: Copy + AddAssign + Zero $(, $param : ArrayLength)* { #[inline] fn add_assign(&mut self, right: N) { for e in self.as_mut().iter_mut() { *e += right } } } impl<$($param : ArrayLength),*> Add<$vecn> for f32 { type Output = $vecn; #[inline] fn add(self, right: $vecn) -> $vecn { let mut res = right; for e in res.as_mut().iter_mut() { *e = self + *e; } res } } impl<$($param : ArrayLength),*> Add<$vecn> for f64 { type Output = $vecn; #[inline] fn add(self, right: $vecn) -> $vecn { let mut res = right; for e in res.as_mut().iter_mut() { *e = self + *e; } res } } /* * * Sub. * */ impl + Zero $(, $param : ArrayLength)*> Sub<$vecn> for $vecn { type Output = $vecn; #[inline] fn sub(self, right: $vecn) -> $vecn { assert!(self.len() == right.len()); let mut res = self; for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) { *left = *left - *right } res } } impl + Zero $(, $param : ArrayLength)*> Sub for $vecn { type Output = $vecn; #[inline] fn sub(self, right: N) -> $vecn { let mut res = self; for e in res.as_mut().iter_mut() { *e = *e - right } res } } impl)*> SubAssign<$vecn> for $vecn where N: Copy + SubAssign + Zero $(, $param : ArrayLength)* { #[inline] fn sub_assign(&mut self, right: $vecn) { assert!(self.len() == right.len()); for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) { *left -= *right } } } impl)*> SubAssign for $vecn where N: Copy + SubAssign + Zero $(, $param : ArrayLength)* { #[inline] fn sub_assign(&mut self, right: N) { for e in self.as_mut().iter_mut() { *e -= right } } } impl<$($param : ArrayLength),*> Sub<$vecn> for f32 { type Output = $vecn; #[inline] fn sub(self, right: $vecn) -> $vecn { let mut res = right; for e in res.as_mut().iter_mut() { *e = self - *e; } res } } impl<$($param : ArrayLength),*> Sub<$vecn> for f64 { type Output = $vecn; #[inline] fn sub(self, right: $vecn) -> $vecn { let mut res = right; for e in res.as_mut().iter_mut() { *e = self - *e; } res } } /* * * Neg. * */ impl + Zero + Copy $(, $param : ArrayLength)*> Neg for $vecn { type Output = $vecn; #[inline] fn neg(mut self) -> $vecn { for e in self.as_mut().iter_mut() { *e = -*e; } self } } /* * * Dot. * */ impl)*> Dot for $vecn { #[inline] fn dot(&self, other: &$vecn) -> 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 } } /* * * Norm. * */ impl)*> Norm for $vecn { type NormType = N; #[inline] fn norm_squared(&self) -> N { ::dot(self, self) } #[inline] fn normalize(&self) -> $vecn { let mut res : $vecn = self.clone(); let _ = res.normalize_mut(); res } #[inline] fn normalize_mut(&mut self) -> N { let n = ::norm(self); *self /= n; n } #[inline] fn try_normalize(&self, min_norm: N) -> Option<$vecn> { let n = ::norm(self); if n <= min_norm { None } else { Some(self / n) } } #[inline] fn try_normalize_mut(&mut self, min_norm: N) -> Option { let n = ::norm(self); if n <= min_norm { None } else { *self /= n; Some(n) } } } /* * * Mean. * */ impl $(, $param : ArrayLength)*> Mean for $vecn { #[inline] fn mean(&self) -> N { let normalizer = ::cast(1.0f64 / self.len() as f64); self.iter().fold(::zero(), |acc, x| acc + *x * normalizer) } } /* * * ApproxEq * */ impl $(, $param : ArrayLength)*> ApproxEq for $vecn { #[inline] fn approx_epsilon() -> N { >::approx_epsilon() } #[inline] fn approx_ulps() -> u32 { >::approx_ulps() } #[inline] fn approx_eq_eps(&self, other: &$vecn, epsilon: &N) -> bool { let mut zip = self.as_ref().iter().zip(other.as_ref().iter()); zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon)) } #[inline] fn approx_eq_ulps(&self, other: &$vecn, ulps: u32) -> bool { let mut zip = self.as_ref().iter().zip(other.as_ref().iter()); zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps)) } } ) );