Add vector perametrizable by their sizes.
This commit is contained in:
parent
20070e9677
commit
f8f4924e47
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra"
|
name = "nalgebra"
|
||||||
version = "0.5.1"
|
version = "0.6.0"
|
||||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ] # FIXME: add the contributors.
|
authors = [ "Sébastien Crozet <developer@crozet.re>" ] # FIXME: add the contributors.
|
||||||
|
|
||||||
description = "Linear algebra library for computer physics, computer graphics and general low-dimensional linear algebra for Rust."
|
description = "Linear algebra library for computer physics, computer graphics and general low-dimensional linear algebra for Rust."
|
||||||
|
@ -17,12 +17,14 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Generate arbitrary instances of nalgebra types for testing with quickcheck
|
# Generate arbitrary instances of nalgebra types for testing with quickcheck
|
||||||
arbitrary = ["quickcheck"]
|
arbitrary = [ "quickcheck" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc-serialize = "0.3.*"
|
rustc-serialize = "0.3.*"
|
||||||
rand = "0.3.*"
|
rand = "0.3.*"
|
||||||
num = "0.1.*"
|
num = "0.1.*"
|
||||||
|
generic-array = "0.2.*"
|
||||||
|
typenum = "1.3.*"
|
||||||
|
|
||||||
[dependencies.quickcheck]
|
[dependencies.quickcheck]
|
||||||
optional = true
|
optional = true
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
extern crate typenum;
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
use na::{Vec2, Vec3, Vec4};
|
use typenum::{U2, U3, U4};
|
||||||
|
use na::{Vec2, Vec3, Vec4, VecN};
|
||||||
use std::ops::{Add, Sub, Mul, Div};
|
use std::ops::{Add, Sub, Mul, Div};
|
||||||
|
|
||||||
#[path="common/macros.rs"]
|
#[path="common/macros.rs"]
|
||||||
|
@ -15,45 +17,78 @@ mod macros;
|
||||||
bench_binop!(_bench_vec2_add_v, Vec2<f32>, Vec2<f32>, add);
|
bench_binop!(_bench_vec2_add_v, Vec2<f32>, Vec2<f32>, add);
|
||||||
bench_binop!(_bench_vec3_add_v, Vec3<f32>, Vec3<f32>, add);
|
bench_binop!(_bench_vec3_add_v, Vec3<f32>, Vec3<f32>, add);
|
||||||
bench_binop!(_bench_vec4_add_v, Vec4<f32>, Vec4<f32>, add);
|
bench_binop!(_bench_vec4_add_v, Vec4<f32>, Vec4<f32>, add);
|
||||||
|
bench_binop!(_bench_vecn2_add_v, VecN<f32, U2>, VecN<f32, U2>, add);
|
||||||
|
bench_binop!(_bench_vecn3_add_v, VecN<f32, U3>, VecN<f32, U3>, add);
|
||||||
|
bench_binop!(_bench_vecn4_add_v, VecN<f32, U4>, VecN<f32, U4>, add);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_sub_v, Vec2<f32>, Vec2<f32>, sub);
|
bench_binop!(_bench_vec2_sub_v, Vec2<f32>, Vec2<f32>, sub);
|
||||||
bench_binop!(_bench_vec3_sub_v, Vec3<f32>, Vec3<f32>, sub);
|
bench_binop!(_bench_vec3_sub_v, Vec3<f32>, Vec3<f32>, sub);
|
||||||
bench_binop!(_bench_vec4_sub_v, Vec4<f32>, Vec4<f32>, sub);
|
bench_binop!(_bench_vec4_sub_v, Vec4<f32>, Vec4<f32>, sub);
|
||||||
|
bench_binop!(_bench_vecn2_sub_v, VecN<f32, U2>, VecN<f32, U2>, sub);
|
||||||
|
bench_binop!(_bench_vecn3_sub_v, VecN<f32, U3>, VecN<f32, U3>, sub);
|
||||||
|
bench_binop!(_bench_vecn4_sub_v, VecN<f32, U4>, VecN<f32, U4>, sub);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_mul_v, Vec2<f32>, Vec2<f32>, mul);
|
bench_binop!(_bench_vec2_mul_v, Vec2<f32>, Vec2<f32>, mul);
|
||||||
bench_binop!(_bench_vec3_mul_v, Vec3<f32>, Vec3<f32>, mul);
|
bench_binop!(_bench_vec3_mul_v, Vec3<f32>, Vec3<f32>, mul);
|
||||||
bench_binop!(_bench_vec4_mul_v, Vec4<f32>, Vec4<f32>, mul);
|
bench_binop!(_bench_vec4_mul_v, Vec4<f32>, Vec4<f32>, mul);
|
||||||
|
bench_binop!(_bench_vecn2_mul_v, VecN<f32, U2>, VecN<f32, U2>, mul);
|
||||||
|
bench_binop!(_bench_vecn3_mul_v, VecN<f32, U3>, VecN<f32, U3>, mul);
|
||||||
|
bench_binop!(_bench_vecn4_mul_v, VecN<f32, U4>, VecN<f32, U4>, mul);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_div_v, Vec2<f32>, Vec2<f32>, div);
|
bench_binop!(_bench_vec2_div_v, Vec2<f32>, Vec2<f32>, div);
|
||||||
bench_binop!(_bench_vec3_div_v, Vec3<f32>, Vec3<f32>, div);
|
bench_binop!(_bench_vec3_div_v, Vec3<f32>, Vec3<f32>, div);
|
||||||
bench_binop!(_bench_vec4_div_v, Vec4<f32>, Vec4<f32>, div);
|
bench_binop!(_bench_vec4_div_v, Vec4<f32>, Vec4<f32>, div);
|
||||||
|
bench_binop!(_bench_vecn2_div_v, VecN<f32, U2>, VecN<f32, U2>, div);
|
||||||
|
bench_binop!(_bench_vecn3_div_v, VecN<f32, U3>, VecN<f32, U3>, div);
|
||||||
|
bench_binop!(_bench_vecn4_div_v, VecN<f32, U4>, VecN<f32, U4>, div);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_add_s, Vec2<f32>, f32, add);
|
bench_binop!(_bench_vec2_add_s, Vec2<f32>, f32, add);
|
||||||
bench_binop!(_bench_vec3_add_s, Vec3<f32>, f32, add);
|
bench_binop!(_bench_vec3_add_s, Vec3<f32>, f32, add);
|
||||||
bench_binop!(_bench_vec4_add_s, Vec4<f32>, f32, add);
|
bench_binop!(_bench_vec4_add_s, Vec4<f32>, f32, add);
|
||||||
|
bench_binop!(_bench_vecn2_add_s, VecN<f32, U2>, f32, add);
|
||||||
|
bench_binop!(_bench_vecn3_add_s, VecN<f32, U3>, f32, add);
|
||||||
|
bench_binop!(_bench_vecn4_add_s, VecN<f32, U4>, f32, add);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_sub_s, Vec2<f32>, f32, sub);
|
bench_binop!(_bench_vec2_sub_s, Vec2<f32>, f32, sub);
|
||||||
bench_binop!(_bench_vec3_sub_s, Vec3<f32>, f32, sub);
|
bench_binop!(_bench_vec3_sub_s, Vec3<f32>, f32, sub);
|
||||||
bench_binop!(_bench_vec4_sub_s, Vec4<f32>, f32, sub);
|
bench_binop!(_bench_vec4_sub_s, Vec4<f32>, f32, sub);
|
||||||
|
bench_binop!(_bench_vecn2_sub_s, VecN<f32, U2>, f32, sub);
|
||||||
|
bench_binop!(_bench_vecn3_sub_s, VecN<f32, U3>, f32, sub);
|
||||||
|
bench_binop!(_bench_vecn4_sub_s, VecN<f32, U4>, f32, sub);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_mul_s, Vec2<f32>, f32, mul);
|
bench_binop!(_bench_vec2_mul_s, Vec2<f32>, f32, mul);
|
||||||
bench_binop!(_bench_vec3_mul_s, Vec3<f32>, f32, mul);
|
bench_binop!(_bench_vec3_mul_s, Vec3<f32>, f32, mul);
|
||||||
bench_binop!(_bench_vec4_mul_s, Vec4<f32>, f32, mul);
|
bench_binop!(_bench_vec4_mul_s, Vec4<f32>, f32, mul);
|
||||||
|
bench_binop!(_bench_vecn2_mul_s, VecN<f32, U2>, f32, mul);
|
||||||
|
bench_binop!(_bench_vecn3_mul_s, VecN<f32, U3>, f32, mul);
|
||||||
|
bench_binop!(_bench_vecn4_mul_s, VecN<f32, U4>, f32, mul);
|
||||||
|
|
||||||
bench_binop!(_bench_vec2_div_s, Vec2<f32>, f32, div);
|
bench_binop!(_bench_vec2_div_s, Vec2<f32>, f32, div);
|
||||||
bench_binop!(_bench_vec3_div_s, Vec3<f32>, f32, div);
|
bench_binop!(_bench_vec3_div_s, Vec3<f32>, f32, div);
|
||||||
bench_binop!(_bench_vec4_div_s, Vec4<f32>, f32, div);
|
bench_binop!(_bench_vec4_div_s, Vec4<f32>, f32, div);
|
||||||
|
bench_binop!(_bench_vecn2_div_s, VecN<f32, U2>, f32, div);
|
||||||
|
bench_binop!(_bench_vecn3_div_s, VecN<f32, U3>, f32, div);
|
||||||
|
bench_binop!(_bench_vecn4_div_s, VecN<f32, U4>, f32, div);
|
||||||
|
|
||||||
bench_binop_na!(_bench_vec2_dot, Vec2<f32>, Vec2<f32>, dot);
|
bench_binop_na!(_bench_vec2_dot, Vec2<f32>, Vec2<f32>, dot);
|
||||||
bench_binop_na!(_bench_vec3_dot, Vec3<f32>, Vec3<f32>, dot);
|
bench_binop_na!(_bench_vec3_dot, Vec3<f32>, Vec3<f32>, dot);
|
||||||
bench_binop_na!(_bench_vec4_dot, Vec4<f32>, Vec4<f32>, dot);
|
bench_binop_na!(_bench_vec4_dot, Vec4<f32>, Vec4<f32>, dot);
|
||||||
|
bench_binop_na!(_bench_vecn2_dot, VecN<f32, U2>, VecN<f32, U2>, dot);
|
||||||
|
bench_binop_na!(_bench_vecn3_dot, VecN<f32, U3>, VecN<f32, U3>, dot);
|
||||||
|
bench_binop_na!(_bench_vecn4_dot, VecN<f32, U4>, VecN<f32, U4>, dot);
|
||||||
|
|
||||||
bench_binop_na!(_bench_vec3_cross, Vec3<f32>, Vec3<f32>, cross);
|
bench_binop_na!(_bench_vec3_cross, Vec3<f32>, Vec3<f32>, cross);
|
||||||
|
|
||||||
bench_unop!(_bench_vec2_norm, Vec2<f32>, norm);
|
bench_unop!(_bench_vec2_norm, Vec2<f32>, norm);
|
||||||
bench_unop!(_bench_vec3_norm, Vec3<f32>, norm);
|
bench_unop!(_bench_vec3_norm, Vec3<f32>, norm);
|
||||||
bench_unop!(_bench_vec4_norm, Vec4<f32>, norm);
|
bench_unop!(_bench_vec4_norm, Vec4<f32>, norm);
|
||||||
|
bench_unop!(_bench_vecn2_norm, VecN<f32, U2>, norm);
|
||||||
|
bench_unop!(_bench_vecn3_norm, VecN<f32, U3>, norm);
|
||||||
|
bench_unop!(_bench_vecn4_norm, VecN<f32, U4>, norm);
|
||||||
|
|
||||||
bench_unop!(_bench_vec2_normalize, Vec2<f32>, normalize);
|
bench_unop!(_bench_vec2_normalize, Vec2<f32>, normalize);
|
||||||
bench_unop!(_bench_vec3_normalize, Vec3<f32>, normalize);
|
bench_unop!(_bench_vec3_normalize, Vec3<f32>, normalize);
|
||||||
bench_unop!(_bench_vec4_normalize, Vec4<f32>, normalize);
|
bench_unop!(_bench_vec4_normalize, Vec4<f32>, normalize);
|
||||||
|
bench_unop!(_bench_vecn2_normalize, VecN<f32, U2>, normalize);
|
||||||
|
bench_unop!(_bench_vecn3_normalize, VecN<f32, U3>, normalize);
|
||||||
|
bench_unop!(_bench_vecn4_normalize, VecN<f32, U4>, normalize);
|
||||||
|
|
|
@ -76,6 +76,7 @@ Feel free to add your project to this list if you happen to use **nalgebra**!
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
|
extern crate generic_array;
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
extern crate quickcheck;
|
extern crate quickcheck;
|
||||||
|
@ -141,7 +142,7 @@ pub use structs::{
|
||||||
Mat1, Mat2, Mat3, Mat4,
|
Mat1, Mat2, Mat3, Mat4,
|
||||||
Mat5, Mat6,
|
Mat5, Mat6,
|
||||||
Rot2, Rot3, Rot4,
|
Rot2, Rot3, Rot4,
|
||||||
Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6,
|
VecN, Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6,
|
||||||
Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6,
|
Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6,
|
||||||
Persp3, PerspMat3,
|
Persp3, PerspMat3,
|
||||||
Ortho3, OrthoMat3,
|
Ortho3, OrthoMat3,
|
||||||
|
|
|
@ -62,6 +62,7 @@ impl<N> DVec<N> {
|
||||||
DVec { at: (0..dim).map(|i| f(i)).collect() }
|
DVec { at: (0..dim).map(|i| f(i)).collect() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The vector length.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.at.len()
|
self.at.len()
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
macro_rules! dvec_impl(
|
macro_rules! dvec_impl(
|
||||||
($dvec: ident) => (
|
($dvec: ident) => (
|
||||||
|
vecn_dvec_common_impl!($dvec);
|
||||||
|
|
||||||
impl<N: Zero + Copy + Clone> $dvec<N> {
|
impl<N: Zero + Copy + Clone> $dvec<N> {
|
||||||
/// Builds a vector filled with zeros.
|
/// Builds a vector filled with zeros.
|
||||||
///
|
///
|
||||||
|
@ -11,68 +13,6 @@ macro_rules! dvec_impl(
|
||||||
pub fn new_zeros(dim: usize) -> $dvec<N> {
|
pub fn new_zeros(dim: usize) -> $dvec<N> {
|
||||||
$dvec::from_elem(dim, ::zero())
|
$dvec::from_elem(dim, ::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N> $dvec<N> {
|
|
||||||
/// Slices this vector.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_ref<'a>(&'a self) -> &'a [N] {
|
|
||||||
&self.at[.. self.len()]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mutably slices this vector.
|
|
||||||
#[inline]
|
|
||||||
pub fn as_mut<'a>(&'a mut self) -> &'a mut [N] {
|
|
||||||
let len = self.len();
|
|
||||||
&mut self.at[.. len]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N> Shape<usize> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn shape(&self) -> usize {
|
|
||||||
self.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy> Indexable<usize, N> for $dvec<N> {
|
|
||||||
#[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.at[..].get_unchecked(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn unsafe_set(&mut self, i: usize, val: N) {
|
|
||||||
*self.at[..].get_unchecked_mut(i) = val
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, T> Index<T> for $dvec<N> where [N]: Index<T> {
|
|
||||||
type Output = <[N] as Index<T>>::Output;
|
|
||||||
|
|
||||||
fn index(&self, i: T) -> &<[N] as Index<T>>::Output {
|
|
||||||
&self.as_ref()[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, T> IndexMut<T> for $dvec<N> where [N]: IndexMut<T> {
|
|
||||||
fn index_mut(&mut self, i: T) -> &mut <[N] as Index<T>>::Output {
|
|
||||||
&mut self.as_mut()[i]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: One + Zero + Copy + Clone> $dvec<N> {
|
impl<N: One + Zero + Copy + Clone> $dvec<N> {
|
||||||
|
@ -94,33 +34,6 @@ macro_rules! dvec_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N> Iterable<N> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
|
||||||
self.as_ref().iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N> IterableMut<N> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
|
||||||
self.as_mut().iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N>> Axpy<N> for $dvec<N> {
|
|
||||||
fn axpy(&mut self, a: &N, x: &$dvec<N>) {
|
|
||||||
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<N: BaseFloat + ApproxEq<N>> $dvec<N> {
|
impl<N: BaseFloat + ApproxEq<N>> $dvec<N> {
|
||||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
/// 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
|
/// vectors, mutually orthogonal, with all its component equal to 0.0 except one which is equal
|
||||||
|
@ -128,7 +41,7 @@ macro_rules! dvec_impl(
|
||||||
pub fn canonical_basis_with_dim(dim: usize) -> Vec<$dvec<N>> {
|
pub fn canonical_basis_with_dim(dim: usize) -> Vec<$dvec<N>> {
|
||||||
let mut res : Vec<$dvec<N>> = Vec::new();
|
let mut res : Vec<$dvec<N>> = Vec::new();
|
||||||
|
|
||||||
for i in 0..dim {
|
for i in 0 .. dim {
|
||||||
let mut basis_element : $dvec<N> = $dvec::new_zeros(dim);
|
let mut basis_element : $dvec<N> = $dvec::new_zeros(dim);
|
||||||
|
|
||||||
basis_element[i] = ::one();
|
basis_element[i] = ::one();
|
||||||
|
@ -147,7 +60,7 @@ macro_rules! dvec_impl(
|
||||||
let dim = self.len();
|
let dim = self.len();
|
||||||
let mut res : Vec<$dvec<N>> = Vec::new();
|
let mut res : Vec<$dvec<N>> = Vec::new();
|
||||||
|
|
||||||
for i in 0..dim {
|
for i in 0 .. dim {
|
||||||
let mut basis_element : $dvec<N> = $dvec::new_zeros(self.len());
|
let mut basis_element : $dvec<N> = $dvec::new_zeros(self.len());
|
||||||
|
|
||||||
basis_element[i] = ::one();
|
basis_element[i] = ::one();
|
||||||
|
@ -175,217 +88,13 @@ macro_rules! dvec_impl(
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Copy + Mul<N, Output = N> + Zero> Mul<$dvec<N>> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mul(self, right: $dvec<N>) -> $dvec<N> {
|
|
||||||
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<N: Copy + Div<N, Output = N> + Zero> Div<$dvec<N>> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn div(self, right: $dvec<N>) -> $dvec<N> {
|
|
||||||
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<N: Copy + Add<N, Output = N> + Zero> Add<$dvec<N>> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add(self, right: $dvec<N>) -> $dvec<N> {
|
|
||||||
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<N: Copy + Sub<N, Output = N> + Zero> Sub<$dvec<N>> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $dvec<N>) -> $dvec<N> {
|
|
||||||
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<N: Neg<Output = N> + Zero + Copy> Neg for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn neg(self) -> $dvec<N> {
|
|
||||||
FromIterator::from_iter(self.as_ref().iter().map(|a| -*a))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: BaseNum> Dot<N> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn dot(&self, other: &$dvec<N>) -> 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<N: BaseFloat> Norm<N> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn sqnorm(&self) -> N {
|
|
||||||
Dot::dot(self, self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn normalize(&self) -> $dvec<N> {
|
|
||||||
let mut res : $dvec<N> = 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().iter_mut() {
|
|
||||||
*n = *n / l;
|
|
||||||
}
|
|
||||||
|
|
||||||
l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: BaseFloat + Cast<f64>> Mean<N> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn mean(&self) -> N {
|
|
||||||
let normalizer = ::cast(1.0f64 / self.len() as f64);
|
|
||||||
self.iter().fold(::zero(), |acc, x| acc + *x * normalizer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: ApproxEq<N>> ApproxEq<N> for $dvec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn approx_epsilon(_: Option<$dvec<N>>) -> N {
|
|
||||||
ApproxEq::approx_epsilon(None::<N>)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_ulps(_: Option<$dvec<N>>) -> u32 {
|
|
||||||
ApproxEq::approx_ulps(None::<N>)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &$dvec<N>, 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: &$dvec<N>, 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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Mul<N, Output = N> + Zero> Mul<N> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mul(self, right: N) -> $dvec<N> {
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for e in res.as_mut().iter_mut() {
|
|
||||||
*e = *e * right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Div<N, Output = N> + Zero> Div<N> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn div(self, right: N) -> $dvec<N> {
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for e in res.as_mut().iter_mut() {
|
|
||||||
*e = *e / right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Add<N, Output = N> + Zero> Add<N> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add(self, right: N) -> $dvec<N> {
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for e in res.as_mut().iter_mut() {
|
|
||||||
*e = *e + right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Sub<N, Output = N> + Zero> Sub<N> for $dvec<N> {
|
|
||||||
type Output = $dvec<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: N) -> $dvec<N> {
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for e in res.as_mut().iter_mut() {
|
|
||||||
*e = *e - right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! small_dvec_impl (
|
macro_rules! small_dvec_impl (
|
||||||
($dvec: ident, $dim: expr, $($idx: expr),*) => (
|
($dvec: ident, $dim: expr, $($idx: expr),*) => (
|
||||||
|
dvec_impl!($dvec);
|
||||||
|
|
||||||
impl<N> $dvec<N> {
|
impl<N> $dvec<N> {
|
||||||
/// The number of elements of this vector.
|
/// The number of elements of this vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -434,8 +143,6 @@ macro_rules! small_dvec_impl (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dvec_impl!($dvec);
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -490,7 +197,7 @@ macro_rules! small_dvec_from_impl (
|
||||||
|
|
||||||
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
let mut at: [N; $dim] = [ $( $zeros, )* ];
|
||||||
|
|
||||||
for i in 0..dim {
|
for i in 0 .. dim {
|
||||||
at[i] = f(i);
|
at[i] = f(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
pub use self::dmat::{DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6};
|
pub use self::dmat::{DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6};
|
||||||
pub use self::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
|
pub use self::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6};
|
||||||
pub use self::vec::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
pub use self::vec::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
|
||||||
|
pub use self::vecn::VecN;
|
||||||
pub use self::pnt::{Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
|
pub use self::pnt::{Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
|
||||||
pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
|
pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
|
||||||
pub use self::rot::{Rot2, Rot3, Rot4};
|
pub use self::rot::{Rot2, Rot3, Rot4};
|
||||||
|
@ -13,6 +14,8 @@ pub use self::quat::{Quat, UnitQuat};
|
||||||
|
|
||||||
mod dmat_macros;
|
mod dmat_macros;
|
||||||
mod dmat;
|
mod dmat;
|
||||||
|
mod vecn_macros;
|
||||||
|
mod vecn;
|
||||||
mod dvec_macros;
|
mod dvec_macros;
|
||||||
mod dvec;
|
mod dvec;
|
||||||
mod vec_macros;
|
mod vec_macros;
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub struct Pnt1<N> {
|
||||||
|
|
||||||
new_impl!(Pnt1, x);
|
new_impl!(Pnt1, x);
|
||||||
orig_impl!(Pnt1, x);
|
orig_impl!(Pnt1, x);
|
||||||
ord_impl!(Pnt1, x,);
|
pord_impl!(Pnt1, x,);
|
||||||
scalar_mul_impl!(Pnt1, x);
|
scalar_mul_impl!(Pnt1, x);
|
||||||
scalar_div_impl!(Pnt1, x);
|
scalar_div_impl!(Pnt1, x);
|
||||||
scalar_add_impl!(Pnt1, x);
|
scalar_add_impl!(Pnt1, x);
|
||||||
|
@ -90,7 +90,7 @@ pub struct Pnt2<N> {
|
||||||
|
|
||||||
new_impl!(Pnt2, x, y);
|
new_impl!(Pnt2, x, y);
|
||||||
orig_impl!(Pnt2, x, y);
|
orig_impl!(Pnt2, x, y);
|
||||||
ord_impl!(Pnt2, x, y);
|
pord_impl!(Pnt2, x, y);
|
||||||
scalar_mul_impl!(Pnt2, x, y);
|
scalar_mul_impl!(Pnt2, x, y);
|
||||||
scalar_div_impl!(Pnt2, x, y);
|
scalar_div_impl!(Pnt2, x, y);
|
||||||
scalar_add_impl!(Pnt2, x, y);
|
scalar_add_impl!(Pnt2, x, y);
|
||||||
|
@ -134,7 +134,7 @@ pub struct Pnt3<N> {
|
||||||
|
|
||||||
new_impl!(Pnt3, x, y, z);
|
new_impl!(Pnt3, x, y, z);
|
||||||
orig_impl!(Pnt3, x, y, z);
|
orig_impl!(Pnt3, x, y, z);
|
||||||
ord_impl!(Pnt3, x, y, z);
|
pord_impl!(Pnt3, x, y, z);
|
||||||
scalar_mul_impl!(Pnt3, x, y, z);
|
scalar_mul_impl!(Pnt3, x, y, z);
|
||||||
scalar_div_impl!(Pnt3, x, y, z);
|
scalar_div_impl!(Pnt3, x, y, z);
|
||||||
scalar_add_impl!(Pnt3, x, y, z);
|
scalar_add_impl!(Pnt3, x, y, z);
|
||||||
|
@ -180,7 +180,7 @@ pub struct Pnt4<N> {
|
||||||
|
|
||||||
new_impl!(Pnt4, x, y, z, w);
|
new_impl!(Pnt4, x, y, z, w);
|
||||||
orig_impl!(Pnt4, x, y, z, w);
|
orig_impl!(Pnt4, x, y, z, w);
|
||||||
ord_impl!(Pnt4, x, y, z, w);
|
pord_impl!(Pnt4, x, y, z, w);
|
||||||
scalar_mul_impl!(Pnt4, x, y, z, w);
|
scalar_mul_impl!(Pnt4, x, y, z, w);
|
||||||
scalar_div_impl!(Pnt4, x, y, z, w);
|
scalar_div_impl!(Pnt4, x, y, z, w);
|
||||||
scalar_add_impl!(Pnt4, x, y, z, w);
|
scalar_add_impl!(Pnt4, x, y, z, w);
|
||||||
|
@ -228,7 +228,7 @@ pub struct Pnt5<N> {
|
||||||
|
|
||||||
new_impl!(Pnt5, x, y, z, w, a);
|
new_impl!(Pnt5, x, y, z, w, a);
|
||||||
orig_impl!(Pnt5, x, y, z, w, a);
|
orig_impl!(Pnt5, x, y, z, w, a);
|
||||||
ord_impl!(Pnt5, x, y, z, w, a);
|
pord_impl!(Pnt5, x, y, z, w, a);
|
||||||
scalar_mul_impl!(Pnt5, x, y, z, w, a);
|
scalar_mul_impl!(Pnt5, x, y, z, w, a);
|
||||||
scalar_div_impl!(Pnt5, x, y, z, w, a);
|
scalar_div_impl!(Pnt5, x, y, z, w, a);
|
||||||
scalar_add_impl!(Pnt5, x, y, z, w, a);
|
scalar_add_impl!(Pnt5, x, y, z, w, a);
|
||||||
|
@ -278,7 +278,7 @@ pub struct Pnt6<N> {
|
||||||
|
|
||||||
new_impl!(Pnt6, x, y, z, w, a, b);
|
new_impl!(Pnt6, x, y, z, w, a, b);
|
||||||
orig_impl!(Pnt6, x, y, z, w, a, b);
|
orig_impl!(Pnt6, x, y, z, w, a, b);
|
||||||
ord_impl!(Pnt6, x, y, z, w, a, b);
|
pord_impl!(Pnt6, x, y, z, w, a, b);
|
||||||
scalar_mul_impl!(Pnt6, x, y, z, w, a, b);
|
scalar_mul_impl!(Pnt6, x, y, z, w, a, b);
|
||||||
scalar_div_impl!(Pnt6, x, y, z, w, a, b);
|
scalar_div_impl!(Pnt6, x, y, z, w, a, b);
|
||||||
scalar_add_impl!(Pnt6, x, y, z, w, a, b);
|
scalar_add_impl!(Pnt6, x, y, z, w, a, b);
|
||||||
|
|
|
@ -515,7 +515,7 @@ impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuat<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ord_impl!(Quat, w, i, j, k);
|
pord_impl!(Quat, w, i, j, k);
|
||||||
vec_axis_impl!(Quat, w, i, j, k);
|
vec_axis_impl!(Quat, w, i, j, k);
|
||||||
vec_cast_impl!(Quat, w, i, j, k);
|
vec_cast_impl!(Quat, w, i, j, k);
|
||||||
conversion_impl!(Quat, 4);
|
conversion_impl!(Quat, 4);
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub struct Vec1<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_impl!(Vec1, x);
|
new_impl!(Vec1, x);
|
||||||
ord_impl!(Vec1, x,);
|
pord_impl!(Vec1, x,);
|
||||||
vec_axis_impl!(Vec1, x);
|
vec_axis_impl!(Vec1, x);
|
||||||
vec_cast_impl!(Vec1, x);
|
vec_cast_impl!(Vec1, x);
|
||||||
conversion_impl!(Vec1, 1);
|
conversion_impl!(Vec1, 1);
|
||||||
|
@ -103,7 +103,7 @@ pub struct Vec2<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_impl!(Vec2, x, y);
|
new_impl!(Vec2, x, y);
|
||||||
ord_impl!(Vec2, x, y);
|
pord_impl!(Vec2, x, y);
|
||||||
vec_axis_impl!(Vec2, x, y);
|
vec_axis_impl!(Vec2, x, y);
|
||||||
vec_cast_impl!(Vec2, x, y);
|
vec_cast_impl!(Vec2, x, y);
|
||||||
conversion_impl!(Vec2, 2);
|
conversion_impl!(Vec2, 2);
|
||||||
|
@ -159,7 +159,7 @@ pub struct Vec3<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_impl!(Vec3, x, y, z);
|
new_impl!(Vec3, x, y, z);
|
||||||
ord_impl!(Vec3, x, y, z);
|
pord_impl!(Vec3, x, y, z);
|
||||||
vec_axis_impl!(Vec3, x, y, z);
|
vec_axis_impl!(Vec3, x, y, z);
|
||||||
vec_cast_impl!(Vec3, x, y, z);
|
vec_cast_impl!(Vec3, x, y, z);
|
||||||
conversion_impl!(Vec3, 3);
|
conversion_impl!(Vec3, 3);
|
||||||
|
@ -218,7 +218,7 @@ pub struct Vec4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_impl!(Vec4, x, y, z, w);
|
new_impl!(Vec4, x, y, z, w);
|
||||||
ord_impl!(Vec4, x, y, z, w);
|
pord_impl!(Vec4, x, y, z, w);
|
||||||
vec_axis_impl!(Vec4, x, y, z, w);
|
vec_axis_impl!(Vec4, x, y, z, w);
|
||||||
vec_cast_impl!(Vec4, x, y, z, w);
|
vec_cast_impl!(Vec4, x, y, z, w);
|
||||||
conversion_impl!(Vec4, 4);
|
conversion_impl!(Vec4, 4);
|
||||||
|
@ -278,7 +278,7 @@ pub struct Vec5<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_impl!(Vec5, x, y, z, w, a);
|
new_impl!(Vec5, x, y, z, w, a);
|
||||||
ord_impl!(Vec5, x, y, z, w, a);
|
pord_impl!(Vec5, x, y, z, w, a);
|
||||||
vec_axis_impl!(Vec5, x, y, z, w, a);
|
vec_axis_impl!(Vec5, x, y, z, w, a);
|
||||||
vec_cast_impl!(Vec5, x, y, z, w, a);
|
vec_cast_impl!(Vec5, x, y, z, w, a);
|
||||||
conversion_impl!(Vec5, 5);
|
conversion_impl!(Vec5, 5);
|
||||||
|
@ -340,7 +340,7 @@ pub struct Vec6<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_impl!(Vec6, x, y, z, w, a, b);
|
new_impl!(Vec6, x, y, z, w, a, b);
|
||||||
ord_impl!(Vec6, x, y, z, w, a, b);
|
pord_impl!(Vec6, x, y, z, w, a, b);
|
||||||
vec_axis_impl!(Vec6, x, y, z, w, a, b);
|
vec_axis_impl!(Vec6, x, y, z, w, a, b);
|
||||||
vec_cast_impl!(Vec6, x, y, z, w, a, b);
|
vec_cast_impl!(Vec6, x, y, z, w, a, b);
|
||||||
conversion_impl!(Vec6, 6);
|
conversion_impl!(Vec6, 6);
|
||||||
|
|
|
@ -74,7 +74,7 @@ macro_rules! at_fast_impl(
|
||||||
|
|
||||||
// FIXME: N should be bounded by Ord instead of BaseFloat…
|
// FIXME: N should be bounded by Ord instead of BaseFloat…
|
||||||
// However, f32/f64 does not implement Ord…
|
// However, f32/f64 does not implement Ord…
|
||||||
macro_rules! ord_impl(
|
macro_rules! pord_impl(
|
||||||
($t: ident, $comp0: ident, $($compN: ident),*) => (
|
($t: ident, $comp0: ident, $($compN: ident),*) => (
|
||||||
impl<N: BaseFloat> POrd for $t<N> {
|
impl<N: BaseFloat> POrd for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
use std::slice::{Iter, IterMut};
|
||||||
|
use std::iter::{FromIterator, IntoIterator};
|
||||||
|
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
||||||
|
use std::mem;
|
||||||
|
use rand::{Rand, Rng};
|
||||||
|
use num::{Zero, One};
|
||||||
|
use generic_array::{GenericArray, ArrayLength};
|
||||||
|
use traits::operations::{ApproxEq, Axpy, Mean};
|
||||||
|
use traits::geometry::{Dot, Norm};
|
||||||
|
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Cast, Dim};
|
||||||
|
#[cfg(feature="arbitrary")]
|
||||||
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
/// A static array of arbitrary dimension.
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Eq, PartialEq, Debug)] // FIXME: Hash, RustcEncodable, RustcDecodable
|
||||||
|
pub struct VecN<N, D: ArrayLength<N>> {
|
||||||
|
/// The underlying data of the vector.
|
||||||
|
pub at: GenericArray<N, D>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone, D: ArrayLength<N>> Clone for VecN<N, D> {
|
||||||
|
fn clone(&self) -> VecN<N, D> {
|
||||||
|
VecN::new(self.at.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy, D: ArrayLength<N>> Copy for VecN<N, D>
|
||||||
|
where D::ArrayType: Copy { }
|
||||||
|
|
||||||
|
impl<N, D: ArrayLength<N>> VecN<N, D> {
|
||||||
|
/// Creates a new vector from a given arbirtarily-sized array.
|
||||||
|
#[inline]
|
||||||
|
pub fn new(components: GenericArray<N, D>) -> VecN<N, D> {
|
||||||
|
VecN {
|
||||||
|
at: components
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The vector length.
|
||||||
|
#[inline]
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.at.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, D: ArrayLength<N>> Dim for VecN<N, D> {
|
||||||
|
fn dim(_unused: Option<Self>) -> usize {
|
||||||
|
D::to_usize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy, D: ArrayLength<N>> FromIterator<N> for VecN<N, D> {
|
||||||
|
#[inline]
|
||||||
|
fn from_iter<I: IntoIterator<Item = N>>(param: I) -> VecN<N, D> {
|
||||||
|
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||||
|
|
||||||
|
let mut it = param.into_iter();
|
||||||
|
|
||||||
|
for e in res.iter_mut() {
|
||||||
|
*e = it.next().expect("Not enough data into the provided iterator to initialize this `VecN`.");
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Rand + Zero, D: ArrayLength<N>> Rand for VecN<N, D> {
|
||||||
|
#[inline]
|
||||||
|
fn rand<R: Rng>(rng: &mut R) -> VecN<N, D> {
|
||||||
|
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||||
|
|
||||||
|
for e in res.iter_mut() {
|
||||||
|
*e = Rand::rand(rng)
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + One + Zero, D: ArrayLength<N>> One for VecN<N, D> {
|
||||||
|
#[inline]
|
||||||
|
fn one() -> VecN<N, D> {
|
||||||
|
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||||
|
|
||||||
|
for e in res.iter_mut() {
|
||||||
|
*e = ::one()
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + Zero, D: ArrayLength<N>> Zero for VecN<N, D> {
|
||||||
|
#[inline]
|
||||||
|
fn zero() -> VecN<N, D> {
|
||||||
|
let mut res: VecN<N, D> = unsafe { mem::uninitialized() };
|
||||||
|
|
||||||
|
for e in res.iter_mut() {
|
||||||
|
*e = ::zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
self.iter().all(|e| e.is_zero())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vecn_dvec_common_impl!(VecN, D);
|
|
@ -0,0 +1,312 @@
|
||||||
|
#![macro_use]
|
||||||
|
|
||||||
|
macro_rules! vecn_dvec_common_impl(
|
||||||
|
($vecn: ident $(, $param: ident)*) => (
|
||||||
|
impl<N: Zero + Copy + Clone $(, $param: ArrayLength<N>)*> $vecn<N $(, $param)*> {
|
||||||
|
/// 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N $(, $param: ArrayLength<N>)*> AsRef<[N]> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn as_ref(&self) -> &[N] {
|
||||||
|
&self[.. self.len()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N $(, $param: ArrayLength<N>)*> AsMut<[N]> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn as_mut(&mut self) -> &mut [N] {
|
||||||
|
let len = self.len();
|
||||||
|
&mut self[.. len]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N $(, $param: ArrayLength<N>)*> Shape<usize> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn shape(&self) -> usize {
|
||||||
|
self.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy $(, $param : ArrayLength<N>)*> Indexable<usize, N> for $vecn<N $(, $param)*> {
|
||||||
|
#[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<N, T $(, $param: ArrayLength<N>)*> Index<T> for $vecn<N $(, $param)*> where [N]: Index<T> {
|
||||||
|
type Output = <[N] as Index<T>>::Output;
|
||||||
|
|
||||||
|
fn index(&self, i: T) -> &<[N] as Index<T>>::Output {
|
||||||
|
&self.as_ref()[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, T $(, $param: ArrayLength<N>)*> IndexMut<T> for $vecn<N $(, $param)*> where [N]: IndexMut<T> {
|
||||||
|
fn index_mut(&mut self, i: T) -> &mut <[N] as Index<T>>::Output {
|
||||||
|
&mut self.as_mut()[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N $(, $param : ArrayLength<N>)*> Iterable<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
||||||
|
self.as_ref().iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N $(, $param : ArrayLength<N>)*> IterableMut<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
||||||
|
self.as_mut().iter_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> $(, $param : ArrayLength<N>)*>
|
||||||
|
Axpy<N> for $vecn<N $(, $param)*> {
|
||||||
|
fn axpy(&mut self, a: &N, x: &$vecn<N $(, $param)*>) {
|
||||||
|
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<N: Copy + Mul<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Mul<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
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<N: Copy + Div<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Div<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
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<N: Copy + Add<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Add<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
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<N: Copy + Sub<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Sub<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
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<N: Neg<Output = N> + Zero + Copy $(, $param : ArrayLength<N>)*> Neg for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn neg(mut self) -> $vecn<N $(, $param)*> {
|
||||||
|
for e in self.as_mut().iter_mut() {
|
||||||
|
*e = -*e;
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum $(, $param : ArrayLength<N>)*> Dot<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn dot(&self, other: &$vecn<N $(, $param)*>) -> 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<N: BaseFloat $(, $param : ArrayLength<N>)*> Norm<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn sqnorm(&self) -> N {
|
||||||
|
Dot::dot(self, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalize(&self) -> $vecn<N $(, $param)*> {
|
||||||
|
let mut res : $vecn<N $(, $param)*> = 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().iter_mut() {
|
||||||
|
*n = *n / l;
|
||||||
|
}
|
||||||
|
|
||||||
|
l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat + Cast<f64> $(, $param : ArrayLength<N>)*> Mean<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn mean(&self) -> N {
|
||||||
|
let normalizer = ::cast(1.0f64 / self.len() as f64);
|
||||||
|
self.iter().fold(::zero(), |acc, x| acc + *x * normalizer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: ApproxEq<N> $(, $param : ArrayLength<N>)*> ApproxEq<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn approx_epsilon(_: Option<$vecn<N $(, $param)*>>) -> N {
|
||||||
|
ApproxEq::approx_epsilon(None::<N>)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_ulps(_: Option<$vecn<N $(, $param)*>>) -> u32 {
|
||||||
|
ApproxEq::approx_ulps(None::<N>)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$vecn<N $(, $param)*>, 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<N $(, $param)*>, 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + Mul<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Mul<N> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, right: N) -> $vecn<N $(, $param)*> {
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for e in res.as_mut().iter_mut() {
|
||||||
|
*e = *e * right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + Div<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Div<N> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, right: N) -> $vecn<N $(, $param)*> {
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for e in res.as_mut().iter_mut() {
|
||||||
|
*e = *e / right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + Add<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Add<N> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, right: N) -> $vecn<N $(, $param)*> {
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for e in res.as_mut().iter_mut() {
|
||||||
|
*e = *e + right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + Sub<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Sub<N> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: N) -> $vecn<N $(, $param)*> {
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for e in res.as_mut().iter_mut() {
|
||||||
|
*e = *e - right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
|
@ -158,7 +158,7 @@ pub trait RowSlice<R> {
|
||||||
/// Trait of objects having a spacial dimension known at compile time.
|
/// Trait of objects having a spacial dimension known at compile time.
|
||||||
pub trait Dim: Sized {
|
pub trait Dim: Sized {
|
||||||
/// The dimension of the object.
|
/// The dimension of the object.
|
||||||
fn dim(unused_mut: Option<Self>) -> usize;
|
fn dim(_unused: Option<Self>) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to get the diagonal of square matrices.
|
/// Trait to get the diagonal of square matrices.
|
||||||
|
|
15
tests/vec.rs
15
tests/vec.rs
|
@ -1,8 +1,10 @@
|
||||||
extern crate nalgebra as na;
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
extern crate typenum;
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use na::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, IterableMut};
|
use typenum::U10;
|
||||||
|
use na::{VecN, Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, IterableMut};
|
||||||
|
|
||||||
macro_rules! test_iterator_impl(
|
macro_rules! test_iterator_impl(
|
||||||
($t: ty, $n: ty) => (
|
($t: ty, $n: ty) => (
|
||||||
|
@ -318,6 +320,15 @@ fn test_outer_vec3() {
|
||||||
12.0, 15.0, 18.0));
|
12.0, 15.0, 18.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_vecn10_add_mul() {
|
||||||
|
for _ in 0usize .. 10000 {
|
||||||
|
let v1: VecN<f64, U10> = random();
|
||||||
|
|
||||||
|
assert!(na::approx_eq(&(v1 + v1), &(v1 * 2.0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vec3_rotation_between() {
|
fn test_vec3_rotation_between() {
|
||||||
|
|
Loading…
Reference in New Issue