From b6090042ac54391850aceef30691a07f07485ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 12 Oct 2014 09:17:17 +0200 Subject: [PATCH] Add a `Axpy` that implements y <- y + ax. This is very useful for accumulations to compute, e.g. centers. --- src/lib.rs | 1 + src/structs/pnt.rs | 9 ++++++++- src/structs/vec.rs | 8 +++++++- src/structs/vec_macros.rs | 12 ++++++++++++ src/traits/mod.rs | 4 ++-- src/traits/operations.rs | 6 ++++++ src/traits/structure.rs | 10 +++++----- 7 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1920f498..cc311dc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,6 +117,7 @@ pub use traits::{ AnyVec, AnyPnt, ApproxEq, + Axpy, Basis, Cast, Col, diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index 9974d625..a980d70f 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -7,7 +7,7 @@ use std::num::{Zero, One, Bounded}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, PartialOrd, PartialOrdering, PartialLess, PartialEqual, - PartialGreater, NotComparable}; + PartialGreater, NotComparable, Axpy}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; @@ -115,6 +115,7 @@ vec_sub_scalar_impl!(Pnt1, int, Pnt1SubRhs, x) approx_eq_impl!(Pnt1, x) from_iterator_impl!(Pnt1, iterator) bounded_impl!(Pnt1, x) +axpy_impl!(Pnt1, x) iterable_impl!(Pnt1, 1) iterable_mut_impl!(Pnt1, 1) pnt_to_homogeneous_impl!(Pnt1, Pnt2, y, x) @@ -206,6 +207,7 @@ vec_sub_scalar_impl!(Pnt2, int, Pnt2SubRhs, x, y) approx_eq_impl!(Pnt2, x, y) from_iterator_impl!(Pnt2, iterator, iterator) bounded_impl!(Pnt2, x, y) +axpy_impl!(Pnt2, x, y) iterable_impl!(Pnt2, 2) iterable_mut_impl!(Pnt2, 2) pnt_to_homogeneous_impl!(Pnt2, Pnt3, z, x, y) @@ -299,6 +301,7 @@ vec_sub_scalar_impl!(Pnt3, int, Pnt3SubRhs, x, y, z) approx_eq_impl!(Pnt3, x, y, z) from_iterator_impl!(Pnt3, iterator, iterator, iterator) bounded_impl!(Pnt3, x, y, z) +axpy_impl!(Pnt3, x, y, z) iterable_impl!(Pnt3, 3) iterable_mut_impl!(Pnt3, 3) pnt_to_homogeneous_impl!(Pnt3, Pnt4, w, x, y, z) @@ -394,6 +397,7 @@ vec_sub_scalar_impl!(Pnt4, int, Pnt4SubRhs, x, y, z, w) approx_eq_impl!(Pnt4, x, y, z, w) from_iterator_impl!(Pnt4, iterator, iterator, iterator, iterator) bounded_impl!(Pnt4, x, y, z, w) +axpy_impl!(Pnt4, x, y, z, w) iterable_impl!(Pnt4, 4) iterable_mut_impl!(Pnt4, 4) pnt_to_homogeneous_impl!(Pnt4, Pnt5, a, x, y, z, w) @@ -491,6 +495,7 @@ vec_sub_scalar_impl!(Pnt5, int, Pnt5SubRhs, x, y, z, w, a) approx_eq_impl!(Pnt5, x, y, z, w, a) from_iterator_impl!(Pnt5, iterator, iterator, iterator, iterator, iterator) bounded_impl!(Pnt5, x, y, z, w, a) +axpy_impl!(Pnt5, x, y, z, w, a) iterable_impl!(Pnt5, 5) iterable_mut_impl!(Pnt5, 5) pnt_to_homogeneous_impl!(Pnt5, Pnt6, b, x, y, z, w, a) @@ -589,5 +594,7 @@ vec_sub_scalar_impl!(Pnt6, uint, Pnt6SubRhs, x, y, z, w, a, b) vec_sub_scalar_impl!(Pnt6, int, Pnt6SubRhs, x, y, z, w, a, b) approx_eq_impl!(Pnt6, x, y, z, w, a, b) from_iterator_impl!(Pnt6, iterator, iterator, iterator, iterator, iterator, iterator) +bounded_impl!(Pnt6, x, y, z, w, a, b) +axpy_impl!(Pnt6, x, y, z, w, a, b) iterable_impl!(Pnt6, 6) iterable_mut_impl!(Pnt6, 6) diff --git a/src/structs/vec.rs b/src/structs/vec.rs index f86838d6..3fe592ef 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -7,7 +7,7 @@ use std::num::{Zero, One, Float, Bounded}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, PartialOrd, PartialOrdering, PartialLess, PartialEqual, - PartialGreater, NotComparable}; + PartialGreater, NotComparable, Axpy}; use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt}; @@ -121,6 +121,7 @@ approx_eq_impl!(Vec1, x) one_impl!(Vec1, x) from_iterator_impl!(Vec1, iterator) bounded_impl!(Vec1, x) +axpy_impl!(Vec1, x) iterable_impl!(Vec1, 1) iterable_mut_impl!(Vec1, 1) vec_to_homogeneous_impl!(Vec1, Vec2, y, x) @@ -222,6 +223,7 @@ approx_eq_impl!(Vec2, x, y) one_impl!(Vec2, x, y) from_iterator_impl!(Vec2, iterator, iterator) bounded_impl!(Vec2, x, y) +axpy_impl!(Vec2, x, y) iterable_impl!(Vec2, 2) iterable_mut_impl!(Vec2, 2) vec_to_homogeneous_impl!(Vec2, Vec3, z, x, y) @@ -328,6 +330,7 @@ approx_eq_impl!(Vec3, x, y, z) one_impl!(Vec3, x, y, z) from_iterator_impl!(Vec3, iterator, iterator, iterator) bounded_impl!(Vec3, x, y, z) +axpy_impl!(Vec3, x, y, z) iterable_impl!(Vec3, 3) iterable_mut_impl!(Vec3, 3) vec_to_homogeneous_impl!(Vec3, Vec4, w, x, y, z) @@ -434,6 +437,7 @@ approx_eq_impl!(Vec4, x, y, z, w) one_impl!(Vec4, x, y, z, w) from_iterator_impl!(Vec4, iterator, iterator, iterator, iterator) bounded_impl!(Vec4, x, y, z, w) +axpy_impl!(Vec4, x, y, z, w) iterable_impl!(Vec4, 4) iterable_mut_impl!(Vec4, 4) vec_to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w) @@ -541,6 +545,7 @@ approx_eq_impl!(Vec5, x, y, z, w, a) one_impl!(Vec5, x, y, z, w, a) from_iterator_impl!(Vec5, iterator, iterator, iterator, iterator, iterator) bounded_impl!(Vec5, x, y, z, w, a) +axpy_impl!(Vec5, x, y, z, w, a) iterable_impl!(Vec5, 5) iterable_mut_impl!(Vec5, 5) vec_to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a) @@ -650,6 +655,7 @@ approx_eq_impl!(Vec6, x, y, z, w, a, b) one_impl!(Vec6, x, y, z, w, a, b) from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iterator) bounded_impl!(Vec6, x, y, z, w, a, b) +axpy_impl!(Vec6, x, y, z, w, a, b) iterable_impl!(Vec6, 6) iterable_mut_impl!(Vec6, 6) translate_impl!(Vec6, Pnt6) diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index c3eea585..ac389042 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -343,6 +343,18 @@ macro_rules! basis_impl( ) ) +macro_rules! axpy_impl( + ($t: ident, $comp0: ident $(,$compN: ident)*) => ( + impl + Mul> Axpy for $t { + #[inline] + fn axpy(&mut self, a: &N, x: &$t) { + self.$comp0 = self.$comp0 + x.$comp0 * *a; + $( self.$compN = self.$compN + x.$compN * *a; )* + } + } + ) +) + macro_rules! add_impl( ($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => ( impl> $trhs> for $t { diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 2fefef1e..59b8e7ca 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -9,8 +9,8 @@ pub use self::structure::{FloatVec, FloatVecExt, FloatPnt, FloatPntExt, Basis, C Indexable, Iterable, IterableMut, Mat, Row, AnyVec, VecExt, AnyPnt, PntExt, PntAsVec, VecAsPnt, ColSlice, RowSlice, Diag, Eye}; -pub use self::operations::{Absolute, ApproxEq, Cov, Det, Inv, LMul, Mean, Outer, PartialOrd, RMul, - ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose}; +pub use self::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, PartialOrd, + RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose}; pub use self::operations::{PartialOrdering, PartialLess, PartialEqual, PartialGreater, NotComparable}; pub mod geometry; diff --git a/src/traits/operations.rs b/src/traits/operations.rs index 58600e9c..35b79f30 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -360,3 +360,9 @@ impl> ScalarDiv for T { *self / *n } } + +/// Trait of objects implementing the $$y = ax + y$$ operation. +pub trait Axpy { + /// Adds $$a * x$$ to `self`. + fn axpy(&mut self, a: &N, x: &Self); +} diff --git a/src/traits/structure.rs b/src/traits/structure.rs index 402768a2..268b68a8 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -2,7 +2,7 @@ use std::num::{Zero, Bounded}; use std::slice::{Items, MutItems}; -use traits::operations::{RMul, LMul, ScalarAdd, ScalarSub}; +use traits::operations::{RMul, LMul, ScalarAdd, ScalarSub, Axpy}; use traits::geometry::{Dot, Norm, UniformSphereSample, Orig}; /// Traits of objects which can be created from an object of type `T`. @@ -156,7 +156,7 @@ pub trait VecAsPnt

{ /// Trait grouping most common operations on vectors. pub trait AnyVec: Dim + Sub + Add + Neg + Zero + PartialEq + Mul - + Div + Dot { + + Div + Dot + Axpy { } /// Trait of vector with components implementing the `Float` trait. @@ -173,7 +173,7 @@ pub trait VecExt: AnyVec + Indexable + Iterable + /// operations on vectors. pub trait FloatVecExt: FloatVec + VecExt + Basis { } -impl + Add + Neg + Zero + PartialEq + Mul + Div + Dot> +impl + Add + Neg + Zero + PartialEq + Mul + Div + Dot + Axpy> AnyVec for V { } impl + Norm> FloatVec for V { } @@ -228,7 +228,7 @@ pub trait FloatPnt>: AnyPnt { /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on points. pub trait PntExt: AnyPnt + Indexable + Iterable + - ScalarAdd + ScalarSub + Bounded + ScalarAdd + ScalarSub + Bounded + Axpy { } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) @@ -239,6 +239,6 @@ pub trait FloatPntExt> : FloatPnt + PntExt { } impl + Dim + Sub + Add + Orig + Neg

+ PartialEq + Mul + Div> AnyPnt for P { } impl, P: AnyPnt> FloatPnt for P { } -impl + Indexable + Iterable + ScalarAdd + ScalarSub + Bounded> +impl + Indexable + Iterable + ScalarAdd + ScalarSub + Bounded + Axpy> PntExt for P { } impl, P: FloatPnt + PntExt> FloatPntExt for P { }