Added scalar arithmetic operators for Matrix types

This commit is contained in:
Cameron Hart 2016-01-02 16:11:16 +11:00
parent 15b14c1e87
commit 24a21d5fc6
2 changed files with 115 additions and 12 deletions

View file

@ -859,9 +859,36 @@ macro_rules! impl_operators {
impl_operator!(<S: BaseFloat> Mul<$VectorN<S> > for $MatrixN<S> {
fn mul(matrix, vector) -> $VectorN<S> { $VectorN::new($(matrix.row($row_index).dot(vector.clone())),+) }
});
impl_scalar_ops!($MatrixN<usize> { $($field),+ });
impl_scalar_ops!($MatrixN<u8> { $($field),+ });
impl_scalar_ops!($MatrixN<u16> { $($field),+ });
impl_scalar_ops!($MatrixN<u32> { $($field),+ });
impl_scalar_ops!($MatrixN<u64> { $($field),+ });
impl_scalar_ops!($MatrixN<isize> { $($field),+ });
impl_scalar_ops!($MatrixN<i8> { $($field),+ });
impl_scalar_ops!($MatrixN<i16> { $($field),+ });
impl_scalar_ops!($MatrixN<i32> { $($field),+ });
impl_scalar_ops!($MatrixN<i64> { $($field),+ });
impl_scalar_ops!($MatrixN<f32> { $($field),+ });
impl_scalar_ops!($MatrixN<f64> { $($field),+ });
}
}
macro_rules! impl_scalar_ops {
($MatrixN:ident<$S:ident> { $($field:ident),+ }) => {
impl_operator!(Mul<$MatrixN<$S>> for $S {
fn mul(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar * matrix.$field),+ } }
});
impl_operator!(Div<$MatrixN<$S>> for $S {
fn div(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar / matrix.$field),+ } }
});
impl_operator!(Rem<$MatrixN<$S>> for $S {
fn rem(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar % matrix.$field),+ } }
});
};
}
impl_operators!(Matrix2, Vector2 { x: 0, y: 1 });
impl_operators!(Matrix3, Vector3 { x: 0, y: 1, z: 2 });
impl_operators!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 });

View file

@ -40,9 +40,30 @@ pub mod matrix2 {
#[test]
fn test_mul_scalar() {
assert_eq!(A * F,
Matrix2::new(0.5f64, 1.5f64,
1.0f64, 2.0f64));
let result = Matrix2::new(0.5f64, 1.5f64,
1.0f64, 2.0f64) ;
assert_eq!(A * F, result);
assert_eq!(F * A, result);
}
#[test]
fn test_div_scalar() {
assert_eq!(A / F,
Matrix2::new(2.0f64, 6.0f64,
4.0f64, 8.0f64));
assert_eq!(4.0f64 / C,
Matrix2::new(2.0f64, 4.0f64,
4.0f64, 2.0f64));
}
#[test]
fn test_rem_scalar() {
assert_eq!(A % 3.0f64,
Matrix2::new(1.0f64, 0.0f64,
2.0f64, 1.0f64));
assert_eq!(3.0f64 % A,
Matrix2::new(0.0f64, 0.0f64,
1.0f64, 3.0f64));
}
#[test]
@ -169,6 +190,7 @@ pub mod matrix3 {
const V: Vector3<f64> = Vector3 { x: 1.0f64, y: 2.0f64, z: 3.0f64 };
const F: f64 = 0.5;
const G: f64 = 6.0;
#[test]
fn test_neg() {
@ -180,10 +202,35 @@ pub mod matrix3 {
#[test]
fn test_mul_scalar() {
assert_eq!(A * F,
Matrix3::new(0.5f64, 2.0f64, 3.5f64,
1.0f64, 2.5f64, 4.0f64,
1.5f64, 3.0f64, 4.5f64));
let result = Matrix3::new(0.5f64, 2.0f64, 3.5f64,
1.0f64, 2.5f64, 4.0f64,
1.5f64, 3.0f64, 4.5f64);
assert_eq!(A * F, result);
assert_eq!(F * A, result);
}
#[test]
fn test_div_scalar() {
assert_eq!(A / F,
Matrix3::new(2.0f64, 8.0f64, 14.0f64,
4.0f64, 10.0f64, 16.0f64,
6.0f64, 12.0f64, 18.0f64));
assert_eq!(G / D,
Matrix3::new(2.0f64, 3.0f64, 6.0f64,
3.0f64, 2.0f64, 3.0f64,
6.0f64, 3.0f64, 2.0f64));
}
#[test]
fn test_rem_scalar() {
assert_eq!(A % 3.0f64,
Matrix3::new(1.0f64, 1.0f64, 1.0f64,
2.0f64, 2.0f64, 2.0f64,
0.0f64, 0.0f64, 0.0f64));
assert_eq!(9.0f64 % A,
Matrix3::new(0.0f64, 1.0f64, 2.0f64,
1.0f64, 4.0f64, 1.0f64,
0.0f64, 3.0f64, 0.0f64));
}
#[test]
@ -402,11 +449,40 @@ pub mod matrix4 {
#[test]
fn test_mul_scalar() {
assert_eq!(A * F,
Matrix4::new(0.5f64, 2.5f64, 4.5f64, 6.5f64,
1.0f64, 3.0f64, 5.0f64, 7.0f64,
1.5f64, 3.5f64, 5.5f64, 7.5f64,
2.0f64, 4.0f64, 6.0f64, 8.0f64));
let result = Matrix4::new(0.5f64, 2.5f64, 4.5f64, 6.5f64,
1.0f64, 3.0f64, 5.0f64, 7.0f64,
1.5f64, 3.5f64, 5.5f64, 7.5f64,
2.0f64, 4.0f64, 6.0f64, 8.0f64);
assert_eq!(A * F, result);
assert_eq!(F * A, result);
}
#[test]
fn test_div_scalar() {
assert_eq!(A / F,
Matrix4::new(2.0f64, 10.0f64, 18.0f64, 26.0f64,
4.0f64, 12.0f64, 20.0f64, 28.0f64,
6.0f64, 14.0f64, 22.0f64, 30.0f64,
8.0f64, 16.0f64, 24.0f64, 32.0f64));
assert_eq!(12.0f64 / D,
Matrix4::new( 3.0f64, 4.0f64, 6.0f64, 12.0f64,
4.0f64, 3.0f64, 4.0f64, 6.0f64,
6.0f64, 4.0f64, 3.0f64, 4.0f64,
12.0f64, 6.0f64, 4.0f64, 3.0f64));
}
#[test]
fn test_rem_scalar() {
assert_eq!(A % 4.0f64,
Matrix4::new(1.0f64, 1.0f64, 1.0f64, 1.0f64,
2.0f64, 2.0f64, 2.0f64, 2.0f64,
3.0f64, 3.0f64, 3.0f64, 3.0f64,
0.0f64, 0.0f64, 0.0f64, 0.0f64));
assert_eq!(16.0f64 % A,
Matrix4::new(0.0f64, 1.0f64, 7.0f64, 3.0f64,
0.0f64, 4.0f64, 6.0f64, 2.0f64,
1.0f64, 2.0f64, 5.0f64, 1.0f64,
0.0f64, 0.0f64, 4.0f64, 0.0f64));
}
#[test]