From ae74a05fdde1cbd07e65ead52c7520953a91f67a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sat, 20 Jul 2013 16:32:39 +0200 Subject: [PATCH] Add implementation of Vec0. --- src/nalgebra.rc | 1 + src/vec.rs | 40 +------ src/vec0_spec.rs | 285 +++++++++++++++++++++++++++++++++++++++++++++++ src/vec_impl.rs | 1 - src/vec_spec.rs | 6 - 5 files changed, 288 insertions(+), 45 deletions(-) create mode 100644 src/vec0_spec.rs diff --git a/src/nalgebra.rc b/src/nalgebra.rc index f60ac384..361428b9 100644 --- a/src/nalgebra.rc +++ b/src/nalgebra.rc @@ -21,6 +21,7 @@ pub mod dvec; // specialization for some 1d, 2d and 3d operations pub mod mat_spec; pub mod vec_spec; +pub mod vec0_spec; /// Wrappers around raw matrices to restrict their behaviour. pub mod adaptors diff --git a/src/vec.rs b/src/vec.rs index 4651f5e7..0a385f49 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -20,44 +20,8 @@ use traits::indexable::Indexable; mod vec_impl; -// #[deriving(Ord, ToStr)] -// pub struct Vec0 -// { at: [N, ..0] } - -// impl Vec0 -// { -// #[inline] -// pub fn new_repeat(_: N) -> Vec0 -// { Vec0 { at: [ ] } } -// } - -// clone_impl!(Vec0) -// deep_clone_impl!(Vec0) -// new_impl!(Vec0, 0) -// indexable_impl!(Vec0) -// dim_impl!(Vec0, 0) -// eq_impl!(Vec0) -// // (specialized) basis_impl!(Vec0, 0) -// add_impl!(Vec0) -// sub_impl!(Vec0) -// neg_impl!(Vec0) -// dot_impl!(Vec0, 0) -// sub_dot_impl!(Vec0, 0) -// scalar_mul_impl!(Vec0, 0) -// scalar_div_impl!(Vec0, 0) -// scalar_add_impl!(Vec0, 0) -// scalar_sub_impl!(Vec0, 0) -// translation_impl!(Vec0) -// translatable_impl!(Vec0) -// norm_impl!(Vec0, 0) -// approx_eq_impl!(Vec0) -// zero_impl!(Vec0) -// one_impl!(Vec0) -// bounded_impl!(Vec0) -// iterable_impl!(Vec0) -// iterable_mut_impl!(Vec0) -// to_homogeneous_impl!(Vec0, Vec1) -// from_homogeneous_impl!(Vec1, Vec0, 1) +#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, Rand, Zero, ToStr)] +pub struct Vec0; #[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec1 diff --git a/src/vec0_spec.rs b/src/vec0_spec.rs new file mode 100644 index 00000000..37e28644 --- /dev/null +++ b/src/vec0_spec.rs @@ -0,0 +1,285 @@ +use std::cast; +use std::num::{Zero, One, Algebraic, Bounded}; +use std::vec::{VecIterator, VecMutIterator}; +use std::iterator::{Iterator, IteratorUtil, FromIterator}; +use std::cmp::ApproxEq; +use std::uint::iterate; +use traits::iterable::{Iterable, IterableMut}; +use traits::basis::Basis; +use traits::dim::Dim; +use traits::dot::Dot; +use traits::sub_dot::SubDot; +use traits::norm::Norm; +use traits::translation::{Translation, Translatable}; +use traits::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; +use traits::ring::Ring; +use traits::division_ring::DivisionRing; +use traits::indexable::Indexable; +use vec; + +impl vec::Vec0 +{ + #[inline] + pub fn new() -> vec::Vec0 + { vec::Vec0 } +} + +impl Indexable for vec::Vec0 +{ + #[inline] + pub fn at(&self, i: uint) -> N + { unsafe { cast::transmute::<&vec::Vec0, &[N, ..0]>(self)[i].clone() } } + + #[inline] + pub fn set(&mut self, i: uint, val: N) + { unsafe { cast::transmute::<&mut vec::Vec0, &mut [N, ..0]>(self)[i] = val } } + + #[inline] + pub fn swap(&mut self, i1: uint, i2: uint) + { unsafe { cast::transmute::<&mut vec::Vec0, &mut [N, ..0]>(self).swap(i1, i2) } } +} + +impl vec::Vec0 +{ + #[inline] + pub fn new_repeat(_: N) -> vec::Vec0 + { vec::Vec0 } +} + +impl Iterable for vec::Vec0 +{ + fn iter<'l>(&'l self) -> VecIterator<'l, N> + { unsafe { cast::transmute::<&'l vec::Vec0, &'l [N, ..0]>(self).iter() } } +} + +impl IterableMut for vec::Vec0 +{ + fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> + { unsafe { cast::transmute::<&'l mut vec::Vec0, &'l mut [N, ..0]>(self).mut_iter() } } +} + +impl Dim for vec::Vec0 +{ + #[inline] + fn dim() -> uint + { 0 } +} + +impl> Basis for vec::Vec0 +{ + pub fn canonical_basis(f: &fn(vec::Vec0)) + { + for iterate(0u, 0) |i| + { + let mut basis_element : vec::Vec0 = Zero::zero(); + + basis_element.set(i, One::one()); + + f(basis_element); + } + } + + pub fn orthonormal_subspace_basis(&self, f: &fn(vec::Vec0)) + { + // compute the basis of the orthogonal subspace using Gram-Schmidt + // orthogonalization algorithm + let mut basis: ~[vec::Vec0] = ~[]; + + for iterate(0u, 0) |i| + { + let mut basis_element : vec::Vec0 = Zero::zero(); + + basis_element.set(i, One::one()); + + if basis.len() == 0 - 1 + { break; } + + let mut elt = basis_element.clone(); + + elt = elt - self.scalar_mul(&basis_element.dot(self)); + + for basis.iter().advance |v| + { elt = elt - v.scalar_mul(&elt.dot(v)) }; + + if !elt.sqnorm().approx_eq(&Zero::zero()) + { + let new_element = elt.normalized(); + + f(new_element.clone()); + + basis.push(new_element); + } + } + } +} + +impl> Add, vec::Vec0> for vec::Vec0 +{ + #[inline] + fn add(&self, _: &vec::Vec0) -> vec::Vec0 + { vec::Vec0 } +} + +impl> Sub, vec::Vec0> for vec::Vec0 +{ + #[inline] + fn sub(&self, _: &vec::Vec0) -> vec::Vec0 + { vec::Vec0 } +} + +impl> Neg> for vec::Vec0 +{ + #[inline] + fn neg(&self) -> vec::Vec0 + { vec::Vec0 } +} + +impl Dot for vec::Vec0 +{ + #[inline] + fn dot(&self, _: &vec::Vec0) -> N + { Zero::zero() } +} + +impl SubDot for vec::Vec0 +{ + #[inline] + fn sub_dot(&self, _: &vec::Vec0, _: &vec::Vec0) -> N + { Zero::zero() } +} + +impl> ScalarMul for vec::Vec0 +{ + #[inline] + fn scalar_mul(&self, _: &N) -> vec::Vec0 + { vec::Vec0 } + + #[inline] + fn scalar_mul_inplace(&mut self, _: &N) + { } +} + +impl> ScalarDiv for vec::Vec0 +{ + #[inline] + fn scalar_div(&self, _: &N) -> vec::Vec0 + { vec::Vec0 } + + #[inline] + fn scalar_div_inplace(&mut self, _: &N) + { } +} + +impl> ScalarAdd for vec::Vec0 +{ + #[inline] + fn scalar_add(&self, _: &N) -> vec::Vec0 + { vec::Vec0 } + + #[inline] + fn scalar_add_inplace(&mut self, _: &N) + { } +} + +impl> ScalarSub for vec::Vec0 +{ + #[inline] + fn scalar_sub(&self, _: &N) -> vec::Vec0 + { vec::Vec0 } + + #[inline] + fn scalar_sub_inplace(&mut self, _: &N) + { } +} + +impl + Neg> Translation> for vec::Vec0 +{ + #[inline] + fn translation(&self) -> vec::Vec0 + { self.clone() } + + #[inline] + fn inv_translation(&self) -> vec::Vec0 + { -self } + + #[inline] + fn translate_by(&mut self, t: &vec::Vec0) + { *self = *self + *t; } +} + +impl + Neg + Clone> Translatable, vec::Vec0> for vec::Vec0 +{ + #[inline] + fn translated(&self, t: &vec::Vec0) -> vec::Vec0 + { self + *t } +} + +impl Norm for vec::Vec0 +{ + #[inline] + fn sqnorm(&self) -> N + { self.dot(self) } + + #[inline] + fn norm(&self) -> N + { self.sqnorm().sqrt() } + + #[inline] + fn normalized(&self) -> vec::Vec0 + { + let mut res : vec::Vec0 = self.clone(); + + res.normalize(); + + res + } + + #[inline] + fn normalize(&mut self) -> N + { + let l = self.norm(); + + self.scalar_div_inplace(&l); + + l + } +} + +impl> ApproxEq for vec::Vec0 +{ + #[inline] + fn approx_epsilon() -> N + { ApproxEq::approx_epsilon::() } + + #[inline] + fn approx_eq(&self, _: &vec::Vec0) -> bool + { true } + + #[inline] + fn approx_eq_eps(&self, _: &vec::Vec0, _: &N) -> bool + { true } +} + +impl One for vec::Vec0 +{ + #[inline] + fn one() -> vec::Vec0 + { vec::Vec0 } +} + +impl> FromIterator for vec::Vec0 +{ + fn from_iterator(_: &mut Iter) -> vec::Vec0 + { vec::Vec0 } +} + +impl Bounded for vec::Vec0 +{ + #[inline] + fn max_value() -> vec::Vec0 + { vec::Vec0 } + + #[inline] + fn min_value() -> vec::Vec0 + { vec::Vec0 } +} diff --git a/src/vec_impl.rs b/src/vec_impl.rs index 9f3ed288..85c3e20b 100644 --- a/src/vec_impl.rs +++ b/src/vec_impl.rs @@ -82,7 +82,6 @@ macro_rules! dim_impl( ) ) -// FIXME: add the possibility to specialize that macro_rules! basis_impl( ($t: ident, $dim: expr) => ( impl> Basis for $t diff --git a/src/vec_spec.rs b/src/vec_spec.rs index 8d73b795..b760e5f7 100644 --- a/src/vec_spec.rs +++ b/src/vec_spec.rs @@ -6,12 +6,6 @@ use traits::norm::Norm; use traits::sample::UniformSphereSample; use vec::{Vec1, Vec2, Vec3}; -// FIXME: impl> FromIterator for Vec0 -// FIXME: { -// FIXME: fn from_iterator(_: &mut Iter) -> Vec0 -// FIXME: { Vec0 { at: [ ] } } -// FIXME: } - impl + Sub> Cross> for Vec2 { #[inline]