Use iterators in inner product impl

This commit is contained in:
Brendan Zabarauskas 2013-09-02 14:01:16 +10:00
parent ac0732409e
commit 00bd313b87
2 changed files with 16 additions and 5 deletions

View file

@ -15,6 +15,8 @@
#[macro_escape]; #[macro_escape];
use std::vec::VecIterator;
pub trait Array<T, Slice> { pub trait Array<T, Slice> {
fn len(&self) -> uint; fn len(&self) -> uint;
fn i<'a>(&'a self, i: uint) -> &'a T; fn i<'a>(&'a self, i: uint) -> &'a T;
@ -23,6 +25,7 @@ pub trait Array<T, Slice> {
fn as_mut_slice<'a>(&'a mut self) -> &'a mut Slice; fn as_mut_slice<'a>(&'a mut self) -> &'a mut Slice;
fn from_slice(slice: Slice) -> Self; fn from_slice(slice: Slice) -> Self;
fn build(builder: &fn(i: uint) -> T) -> Self; fn build(builder: &fn(i: uint) -> T) -> Self;
fn iter<'a>(&'a self) -> VecIterator<'a, T>;
#[inline] #[inline]
fn map<U, SliceU, UU: Array<U, SliceU>>(&self, f: &fn(&T) -> U) -> UU { fn map<U, SliceU, UU: Array<U, SliceU>>(&self, f: &fn(&T) -> U) -> UU {
@ -99,6 +102,11 @@ macro_rules! array(
} }
Array::from_slice(s) Array::from_slice(s)
} }
#[inline]
fn iter<'a>(&'a self) -> ::std::vec::VecIterator<'a, $T> {
self.as_slice().iter()
}
} }
) )
) )

View file

@ -13,7 +13,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::num;
use std::num::{Zero, zero}; use std::num::{Zero, zero};
use std::num::{sqrt, atan2}; use std::num::{sqrt, atan2};
@ -121,17 +120,21 @@ impl<S: Field> Vec3<S> {
macro_rules! impl_vec_inner_product( macro_rules! impl_vec_inner_product(
($Self:ident <$S:ident>) => ( ($Self:ident <$S:ident>) => (
impl<$S:Real + Field + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> { impl<$S:Real + Field + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> {
#[inline]
fn norm(&self) -> $S { fn norm(&self) -> $S {
num::sqrt(self.inner(self)) sqrt(self.inner(self))
} }
#[inline]
fn inner(&self, other: &$Self<$S>) -> $S { fn inner(&self, other: &$Self<$S>) -> $S {
let comp_sum: $Self<$S> = self.bimap(other, |a, b| a.mul(b)); self.iter().zip(other.iter())
comp_sum.fold(num::zero::<$S>(), |a, b| a.add(b)) .map(|(a, b)| a.mul(b))
.fold(zero::<$S>(), |a, b| a.add(&b))
} }
#[inline]
fn is_orthogonal(&self, other: &$Self<$S>) -> bool { fn is_orthogonal(&self, other: &$Self<$S>) -> bool {
self.inner(other).approx_eq(&num::zero()) self.inner(other).approx_eq(&zero())
} }
} }
) )