2015-01-08 04:11:09 +08:00
|
|
|
#![macro_use]
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
macro_rules! dvec_impl(
|
2014-11-26 21:17:34 +08:00
|
|
|
($dvec: ident) => (
|
2014-12-18 06:28:32 +08:00
|
|
|
impl<N: Zero + Copy + Clone> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
/// Builds a vector filled with zeros.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
/// * `dim` - The dimension of the vector.
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn new_zeros(dim: usize) -> $dvec<N> {
|
2014-11-16 21:04:15 +08:00
|
|
|
$dvec::from_elem(dim, ::zero())
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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<N> $dvec<N> {
|
|
|
|
/// Slices this vector.
|
|
|
|
#[inline]
|
|
|
|
pub fn as_slice<'a>(&'a self) -> &'a [N] {
|
|
|
|
self.at.slice_to(self.len())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Mutably slices this vector.
|
|
|
|
#[inline]
|
|
|
|
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [N] {
|
|
|
|
let len = self.len();
|
2014-10-22 19:35:17 +08:00
|
|
|
self.at.slice_to_mut(len)
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-10 05:26:05 +08:00
|
|
|
impl<N> Shape<usize> for $dvec<N> {
|
2014-10-26 17:46:51 +08:00
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
fn shape(&self) -> usize {
|
2014-10-26 17:46:51 +08:00
|
|
|
self.len()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-10 05:26:05 +08:00
|
|
|
impl<N: Copy> Indexable<usize, N> for $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
fn at(&self, i: usize) -> N {
|
2014-08-16 18:16:26 +08:00
|
|
|
assert!(i < self.len());
|
|
|
|
unsafe {
|
|
|
|
self.unsafe_at(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
fn set(&mut self, i: usize, val: N) {
|
2014-08-16 18:16:26 +08:00
|
|
|
assert!(i < self.len());
|
|
|
|
unsafe {
|
|
|
|
self.unsafe_set(i, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
fn swap(&mut self, i: usize, j: usize) {
|
2014-08-16 18:16:26 +08:00
|
|
|
assert!(i < self.len());
|
|
|
|
assert!(j < self.len());
|
|
|
|
self.as_mut_slice().swap(i, j);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
unsafe fn unsafe_at(&self, i: usize) -> N {
|
2015-01-05 22:12:06 +08:00
|
|
|
*self.at.as_slice().get_unchecked(i)
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
unsafe fn unsafe_set(&mut self, i: usize, val: N) {
|
2015-01-02 06:23:35 +08:00
|
|
|
*self.at.as_mut_slice().get_unchecked_mut(i) = val
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-01-10 05:26:05 +08:00
|
|
|
impl<N> Index<usize> for $dvec<N> {
|
2015-01-05 02:03:28 +08:00
|
|
|
type Output = N;
|
|
|
|
|
2015-01-10 05:26:05 +08:00
|
|
|
fn index(&self, i: &usize) -> &N {
|
2014-09-18 10:20:36 +08:00
|
|
|
&self.as_slice()[*i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-10 05:26:05 +08:00
|
|
|
impl<N> IndexMut<usize> for $dvec<N> {
|
|
|
|
fn index_mut(&mut self, i: &usize) -> &mut N {
|
2014-09-18 10:20:36 +08:00
|
|
|
&mut self.as_mut_slice()[*i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
impl<N: One + Zero + Copy + Clone> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
/// Builds a vector filled with ones.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
/// * `dim` - The dimension of the vector.
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn new_ones(dim: usize) -> $dvec<N> {
|
2014-11-16 21:04:15 +08:00
|
|
|
$dvec::from_elem(dim, ::one())
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: Rand + Zero> $dvec<N> {
|
|
|
|
/// Builds a vector filled with random values.
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn new_random(dim: usize) -> $dvec<N> {
|
2015-01-07 07:46:50 +08:00
|
|
|
$dvec::from_fn(dim, |&: _| rand::random())
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N> Iterable<N> for $dvec<N> {
|
|
|
|
#[inline]
|
2014-12-24 02:01:49 +08:00
|
|
|
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
self.as_slice().iter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N> IterableMut<N> for $dvec<N> {
|
|
|
|
#[inline]
|
2014-12-24 02:01:49 +08:00
|
|
|
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
2014-10-22 19:35:17 +08:00
|
|
|
self.as_mut_slice().iter_mut()
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N>> Axpy<N> for $dvec<N> {
|
2014-12-18 06:28:32 +08:00
|
|
|
fn axpy(&mut self, a: &N, x: &$dvec<N>) {
|
|
|
|
assert!(self.len() == x.len());
|
|
|
|
|
2015-02-21 22:07:50 +08:00
|
|
|
for i in 0..x.len() {
|
2014-12-18 06:28:32 +08:00
|
|
|
unsafe {
|
|
|
|
let self_i = self.unsafe_at(i);
|
|
|
|
self.unsafe_set(i, self_i + *a * x.unsafe_at(i))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: BaseFloat + ApproxEq<N>> $dvec<N> {
|
2014-08-16 18:16:26 +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 except one which is equal
|
|
|
|
/// to 1.0.
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn canonical_basis_with_dim(dim: usize) -> Vec<$dvec<N>> {
|
2014-08-16 18:16:26 +08:00
|
|
|
let mut res : Vec<$dvec<N>> = Vec::new();
|
|
|
|
|
2015-02-21 22:07:50 +08:00
|
|
|
for i in 0..dim {
|
2014-08-16 18:16:26 +08:00
|
|
|
let mut basis_element : $dvec<N> = $dvec::new_zeros(dim);
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
basis_element.set(i, ::one());
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
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<N>> {
|
|
|
|
// compute the basis of the orthogonal subspace using Gram-Schmidt
|
|
|
|
// orthogonalization algorithm
|
|
|
|
let dim = self.len();
|
|
|
|
let mut res : Vec<$dvec<N>> = Vec::new();
|
|
|
|
|
2015-02-21 22:07:50 +08:00
|
|
|
for i in 0..dim {
|
2014-08-16 18:16:26 +08:00
|
|
|
let mut basis_element : $dvec<N> = $dvec::new_zeros(self.len());
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
basis_element.set(i, ::one());
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
if res.len() == dim - 1 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut elt = basis_element.clone();
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
elt.axpy(&-::dot(&basis_element, self), self);
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
for v in res.iter() {
|
2014-12-18 06:28:32 +08:00
|
|
|
let proj = ::dot(&elt, v);
|
|
|
|
elt.axpy(&-proj, v)
|
2014-08-16 18:16:26 +08:00
|
|
|
};
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) {
|
2015-02-02 06:23:57 +08:00
|
|
|
res.push(Norm::normalize(&elt));
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(res.len() == dim - 1);
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Mul<N, Output = N> + Zero> Mul<$dvec<N>> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-11-07 06:17:35 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn mul(self, right: $dvec<N>) -> $dvec<N> {
|
2014-11-26 21:17:34 +08:00
|
|
|
assert!(self.len() == right.len());
|
2014-12-18 06:28:32 +08:00
|
|
|
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) {
|
|
|
|
*left = *left * *right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-11-07 06:17:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Div<N, Output = N> + Zero> Div<$dvec<N>> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-11-07 06:17:35 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn div(self, right: $dvec<N>) -> $dvec<N> {
|
2014-11-26 21:17:34 +08:00
|
|
|
assert!(self.len() == right.len());
|
2014-12-18 06:28:32 +08:00
|
|
|
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) {
|
|
|
|
*left = *left / *right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-11-07 06:17:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Add<N, Output = N> + Zero> Add<$dvec<N>> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn add(self, right: $dvec<N>) -> $dvec<N> {
|
2014-11-26 21:17:34 +08:00
|
|
|
assert!(self.len() == right.len());
|
2014-12-18 06:28:32 +08:00
|
|
|
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) {
|
|
|
|
*left = *left + *right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Sub<N, Output = N> + Zero> Sub<$dvec<N>> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn sub(self, right: $dvec<N>) -> $dvec<N> {
|
2014-11-26 21:17:34 +08:00
|
|
|
assert!(self.len() == right.len());
|
2014-12-18 06:28:32 +08:00
|
|
|
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for (left, right) in res.as_mut_slice().iter_mut().zip(right.as_slice().iter()) {
|
|
|
|
*left = *left - *right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Neg<Output = N> + Zero + Copy> Neg for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-24 02:09:06 +08:00
|
|
|
fn neg(self) -> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
FromIterator::from_iter(self.as_slice().iter().map(|a| -*a))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
impl<N: BaseNum> Dot<N> for $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-02 01:50:11 +08:00
|
|
|
fn dot(&self, other: &$dvec<N>) -> N {
|
|
|
|
assert!(self.len() == other.len());
|
2014-11-16 21:04:15 +08:00
|
|
|
let mut res: N = ::zero();
|
2015-02-21 22:07:50 +08:00
|
|
|
for i in 0..self.len() {
|
2014-12-02 01:50:11 +08:00
|
|
|
res = res + unsafe { self.unsafe_at(i) * other.unsafe_at(i) };
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
impl<N: BaseFloat> Norm<N> for $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-02 01:50:11 +08:00
|
|
|
fn sqnorm(&self) -> N {
|
|
|
|
Dot::dot(self, self)
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
fn normalize(&self) -> $dvec<N> {
|
2014-12-02 01:50:11 +08:00
|
|
|
let mut res : $dvec<N> = self.clone();
|
2015-02-02 06:23:57 +08:00
|
|
|
let _ = res.normalize_mut();
|
2014-08-16 18:16:26 +08:00
|
|
|
res
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
fn normalize_mut(&mut self) -> N {
|
2014-08-16 18:16:26 +08:00
|
|
|
let l = Norm::norm(self);
|
|
|
|
|
2014-10-22 19:35:17 +08:00
|
|
|
for n in self.as_mut_slice().iter_mut() {
|
2014-08-16 18:16:26 +08:00
|
|
|
*n = *n / l;
|
|
|
|
}
|
|
|
|
|
|
|
|
l
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: ApproxEq<N>> ApproxEq<N> for $dvec<N> {
|
|
|
|
#[inline]
|
|
|
|
fn approx_epsilon(_: Option<$dvec<N>>) -> N {
|
|
|
|
ApproxEq::approx_epsilon(None::<N>)
|
|
|
|
}
|
|
|
|
|
2015-01-01 05:08:42 +08:00
|
|
|
#[inline]
|
|
|
|
fn approx_ulps(_: Option<$dvec<N>>) -> u32 {
|
|
|
|
ApproxEq::approx_ulps(None::<N>)
|
|
|
|
}
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-02 01:50:11 +08:00
|
|
|
fn approx_eq_eps(&self, other: &$dvec<N>, epsilon: &N) -> bool {
|
2015-03-01 08:48:58 +08:00
|
|
|
let mut zip = self.as_slice().iter().zip(other.as_slice().iter());
|
2014-08-16 18:16:26 +08:00
|
|
|
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
|
|
|
|
}
|
2015-01-01 05:08:42 +08:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn approx_eq_ulps(&self, other: &$dvec<N>, ulps: u32) -> bool {
|
2015-03-01 08:48:58 +08:00
|
|
|
let mut zip = self.as_slice().iter().zip(other.as_slice().iter());
|
2015-01-01 05:08:42 +08:00
|
|
|
zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps))
|
|
|
|
}
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Mul<N, Output = N> + Zero> Mul<N> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn mul(self, right: N) -> $dvec<N> {
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for e in res.as_mut_slice().iter_mut() {
|
|
|
|
*e = *e * right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Div<N, Output = N> + Zero> Div<N> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn div(self, right: N) -> $dvec<N> {
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for e in res.as_mut_slice().iter_mut() {
|
|
|
|
*e = *e / right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Add<N, Output = N> + Zero> Add<N> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn add(self, right: N) -> $dvec<N> {
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for e in res.as_mut_slice().iter_mut() {
|
|
|
|
*e = *e + right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
impl<N: Copy + Sub<N, Output = N> + Zero> Sub<N> for $dvec<N> {
|
|
|
|
type Output = $dvec<N>;
|
|
|
|
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
fn sub(self, right: N) -> $dvec<N> {
|
|
|
|
let mut res = self;
|
|
|
|
|
|
|
|
for e in res.as_mut_slice().iter_mut() {
|
|
|
|
*e = *e - right
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2014-12-19 22:33:01 +08:00
|
|
|
);
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
macro_rules! small_dvec_impl (
|
2015-01-10 04:55:15 +08:00
|
|
|
($dvec: ident, $dim: expr, $($idx: expr),*) => (
|
2014-11-03 05:47:11 +08:00
|
|
|
impl<N> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn len(&self) -> usize {
|
2014-08-16 18:16:26 +08:00
|
|
|
self.dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: PartialEq> PartialEq for $dvec<N> {
|
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &$dvec<N>) -> 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<N: Clone> Clone for $dvec<N> {
|
|
|
|
fn clone(&self) -> $dvec<N> {
|
2015-01-03 22:19:52 +08:00
|
|
|
let at: [N; $dim] = [ $( self.at[$idx].clone(), )* ];
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
$dvec {
|
|
|
|
at: at,
|
|
|
|
dim: self.dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-19 22:33:01 +08:00
|
|
|
dvec_impl!($dvec);
|
2014-08-16 18:16:26 +08:00
|
|
|
)
|
2014-12-19 22:33:01 +08:00
|
|
|
);
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
macro_rules! small_dvec_from_impl (
|
2015-01-10 04:55:15 +08:00
|
|
|
($dvec: ident, $dim: expr, $($zeros: expr),*) => (
|
2014-12-18 06:28:32 +08:00
|
|
|
impl<N: Copy + Zero> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
/// Builds a vector filled with a constant.
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn from_elem(dim: usize, elem: N) -> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
assert!(dim <= $dim);
|
|
|
|
|
2015-01-03 22:19:52 +08:00
|
|
|
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
2014-08-16 18:16:26 +08:00
|
|
|
|
2014-10-22 19:35:17 +08:00
|
|
|
for n in at.slice_to_mut(dim).iter_mut() {
|
2014-12-18 06:28:32 +08:00
|
|
|
*n = elem;
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
$dvec {
|
|
|
|
at: at,
|
|
|
|
dim: dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
impl<N: Copy + Zero> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
/// Builds a vector filled with the components provided by a vector.
|
|
|
|
///
|
|
|
|
/// The vector must have at least `dim` elements.
|
|
|
|
#[inline]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn from_slice(dim: usize, vec: &[N]) -> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
assert!(dim <= vec.len() && dim <= $dim);
|
|
|
|
|
|
|
|
// FIXME: not safe.
|
2015-01-03 22:19:52 +08:00
|
|
|
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
2014-08-16 18:16:26 +08:00
|
|
|
|
2014-10-22 19:35:17 +08:00
|
|
|
for (curr, other) in vec.iter().zip(at.iter_mut()) {
|
2014-12-18 06:28:32 +08:00
|
|
|
*other = *curr;
|
2014-08-16 18:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
$dvec {
|
|
|
|
at: at,
|
|
|
|
dim: dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: Zero> $dvec<N> {
|
|
|
|
/// Builds a vector filled with the result of a function.
|
|
|
|
#[inline(always)]
|
2015-01-10 05:26:05 +08:00
|
|
|
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> $dvec<N> {
|
2014-08-16 18:16:26 +08:00
|
|
|
assert!(dim <= $dim);
|
|
|
|
|
2015-01-03 22:19:52 +08:00
|
|
|
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
2014-08-16 18:16:26 +08:00
|
|
|
|
2015-02-21 22:07:50 +08:00
|
|
|
for i in 0..dim {
|
2014-08-16 18:16:26 +08:00
|
|
|
at[i] = f(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
$dvec {
|
|
|
|
at: at,
|
|
|
|
dim: dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: Zero> FromIterator<N> for $dvec<N> {
|
|
|
|
#[inline]
|
2015-02-21 07:02:27 +08:00
|
|
|
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> $dvec<N> {
|
2015-01-03 22:19:52 +08:00
|
|
|
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
2014-08-16 18:16:26 +08:00
|
|
|
|
|
|
|
let mut dim = 0;
|
|
|
|
|
2015-02-21 07:02:27 +08:00
|
|
|
for n in param.into_iter() {
|
2014-08-16 18:16:26 +08:00
|
|
|
if dim == $dim {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
at[dim] = n;
|
|
|
|
|
|
|
|
dim = dim + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
$dvec {
|
|
|
|
at: at,
|
|
|
|
dim: dim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-10 08:36:13 +08:00
|
|
|
|
|
|
|
#[cfg(feature="arbitrary")]
|
|
|
|
impl<N: Arbitrary + Zero> Arbitrary for $dvec<N> {
|
|
|
|
#[inline]
|
|
|
|
fn arbitrary<G: Gen>(g: &mut G) -> $dvec<N> {
|
|
|
|
$dvec::from_fn(g.gen_range(0, $dim), |_| Arbitrary::arbitrary(g))
|
|
|
|
}
|
|
|
|
}
|
2014-08-16 18:16:26 +08:00
|
|
|
)
|
2014-12-19 22:33:01 +08:00
|
|
|
);
|