Move element-wise operations into Array1
trait
This commit is contained in:
parent
137c3a7b0a
commit
25ca567060
5 changed files with 69 additions and 37 deletions
14
src/array.rs
14
src/array.rs
|
@ -17,6 +17,8 @@ use std::mem;
|
|||
use std::ptr;
|
||||
use std::ops::*;
|
||||
|
||||
use num::PartialOrd;
|
||||
|
||||
/// An array containing elements of type `Element`
|
||||
pub trait Array1 where
|
||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||
|
@ -47,6 +49,18 @@ pub trait Array1 where
|
|||
fn replace_elem(&mut self, i: usize, src: Self::Element) -> Self::Element {
|
||||
mem::replace(&mut self[i], src)
|
||||
}
|
||||
|
||||
/// The sum of the elements of the array.
|
||||
fn sum(self) -> Self::Element where Self::Element: Add<Output = <Self as Array1>::Element>;
|
||||
|
||||
/// The product of the elements of the array.
|
||||
fn product(self) -> Self::Element where Self::Element: Mul<Output = <Self as Array1>::Element>;
|
||||
|
||||
/// The minimum element of the array.
|
||||
fn min(self) -> Self::Element where Self::Element: PartialOrd;
|
||||
|
||||
/// The maximum element of the array.
|
||||
fn max(self) -> Self::Element where Self::Element: PartialOrd;
|
||||
}
|
||||
|
||||
/// A column-major array
|
||||
|
|
32
src/point.rs
32
src/point.rs
|
@ -132,6 +132,22 @@ pub trait Point: Copy + Clone where
|
|||
|
||||
impl<S: BaseNum> Array1 for Point2<S> {
|
||||
type Element = S;
|
||||
|
||||
fn sum(self) -> S {
|
||||
self.x + self.y
|
||||
}
|
||||
|
||||
fn product(self) -> S {
|
||||
self.x * self.y
|
||||
}
|
||||
|
||||
fn min(self) -> S {
|
||||
self.x.partial_min(self.y)
|
||||
}
|
||||
|
||||
fn max(self) -> S {
|
||||
self.x.partial_max(self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Point for Point2<S> {
|
||||
|
@ -212,6 +228,22 @@ impl<S: BaseFloat> ApproxEq for Point2<S> {
|
|||
|
||||
impl<S: BaseNum> Array1 for Point3<S> {
|
||||
type Element = S;
|
||||
|
||||
fn sum(self) -> S {
|
||||
self.x + self.y + self.z
|
||||
}
|
||||
|
||||
fn product(self) -> S {
|
||||
self.x * self.y * self.z
|
||||
}
|
||||
|
||||
fn min(self) -> S {
|
||||
self.x.partial_min(self.y).partial_min(self.z)
|
||||
}
|
||||
|
||||
fn max(self) -> S {
|
||||
self.x.partial_max(self.y).partial_max(self.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Point for Point3<S> {
|
||||
|
|
|
@ -24,7 +24,6 @@ use rust_num::traits::cast;
|
|||
|
||||
use angle::{Angle, Rad, acos, sin, sin_cos, rad};
|
||||
use approx::ApproxEq;
|
||||
use array::Array1;
|
||||
use matrix::{Matrix3, Matrix4};
|
||||
use num::BaseFloat;
|
||||
use point::Point3;
|
||||
|
@ -40,10 +39,6 @@ pub struct Quaternion<S> {
|
|||
pub v: Vector3<S>,
|
||||
}
|
||||
|
||||
impl<S: Copy + BaseFloat> Array1 for Quaternion<S> {
|
||||
type Element = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Quaternion<S> {
|
||||
/// Construct a new quaternion from one scalar component and three
|
||||
/// imaginary components
|
||||
|
|
|
@ -106,7 +106,7 @@ use rust_num::{NumCast, Zero, One};
|
|||
use angle::{Rad, atan2, acos};
|
||||
use approx::ApproxEq;
|
||||
use array::Array1;
|
||||
use num::{BaseNum, BaseFloat};
|
||||
use num::{BaseNum, BaseFloat, PartialOrd};
|
||||
|
||||
/// A trait that specifies a range of numeric operations for vectors. Not all
|
||||
/// of these make sense from a linear algebra point of view, but are included
|
||||
|
@ -196,19 +196,8 @@ pub trait Vector: Copy + Clone where
|
|||
/// Take the remainder of this vector by another, in-place.
|
||||
fn rem_self_v(&mut self, v: Self);
|
||||
|
||||
/// The sum of the components of the vector.
|
||||
fn sum(self) -> Self::Scalar;
|
||||
/// The product of the components of the vector.
|
||||
fn product(self) -> Self::Scalar;
|
||||
|
||||
/// Vector dot product.
|
||||
#[inline]
|
||||
fn dot(self, v: Self) -> Self::Scalar { self.mul_v(v).sum() }
|
||||
|
||||
/// The minimum component of the vector.
|
||||
fn comp_min(self) -> Self::Scalar;
|
||||
/// The maximum component of the vector.
|
||||
fn comp_max(self) -> Self::Scalar;
|
||||
/// Vector dot product
|
||||
fn dot(self, other: Self) -> Self::Scalar;
|
||||
}
|
||||
|
||||
/// Dot product of two vectors.
|
||||
|
@ -252,6 +241,11 @@ macro_rules! vec {
|
|||
|
||||
impl<S: Copy> Array1 for $VectorN<S> {
|
||||
type Element = S;
|
||||
|
||||
#[inline] fn sum(self) -> S where S: Add<Output = S> { fold!(add, { $(self.$field),+ }) }
|
||||
#[inline] fn product(self) -> S where S: Mul<Output = S> { fold!(mul, { $(self.$field),+ }) }
|
||||
#[inline] fn min(self) -> S where S: PartialOrd { fold!(partial_min, { $(self.$field),+ }) }
|
||||
#[inline] fn max(self) -> S where S: PartialOrd { fold!(partial_max, { $(self.$field),+ }) }
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Vector for $VectorN<S> {
|
||||
|
@ -283,10 +277,7 @@ macro_rules! vec {
|
|||
#[inline] fn div_self_v(&mut self, v: $VectorN<S>) { *self = &*self / v; }
|
||||
#[inline] fn rem_self_v(&mut self, v: $VectorN<S>) { *self = &*self % v; }
|
||||
|
||||
#[inline] fn sum(self) -> S { fold!(add, { $(self.$field),+ }) }
|
||||
#[inline] fn product(self) -> S { fold!(mul, { $(self.$field),+ }) }
|
||||
#[inline] fn comp_min(self) -> S { fold!(partial_min, { $(self.$field),+ }) }
|
||||
#[inline] fn comp_max(self) -> S { fold!(partial_max, { $(self.$field),+ }) }
|
||||
#[inline] fn dot(self, other: $VectorN<S>) -> S { (self * other).sum() }
|
||||
}
|
||||
|
||||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||
|
|
|
@ -63,25 +63,25 @@ fn test_product() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_comp_min() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).comp_min(), 1isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).comp_min(), 1isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).comp_min(), 1isize);
|
||||
fn test_min() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).min(), 1isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).min(), 1isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).min(), 1isize);
|
||||
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).comp_min(), 3.0f64);
|
||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).comp_min(), 4.0f64);
|
||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).comp_min(), 5.0f64);
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).min(), 3.0f64);
|
||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).min(), 4.0f64);
|
||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).min(), 5.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comp_max() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).comp_max(), 2isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).comp_max(), 3isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).comp_max(), 4isize);
|
||||
fn test_max() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).max(), 2isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).max(), 3isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).max(), 4isize);
|
||||
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).comp_max(), 4.0f64);
|
||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).comp_max(), 6.0f64);
|
||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).comp_max(), 8.0f64);
|
||||
assert_eq!(Vector2::new(3.0f64, 4.0f64).max(), 4.0f64);
|
||||
assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).max(), 6.0f64);
|
||||
assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).max(), 8.0f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue