From 3cd4221bf7069e51730cd12366c50e0796be2257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 10 Jan 2016 14:49:55 +0100 Subject: [PATCH] Implement `Row` and `Col` for `DMat`. Fix #153. --- src/structs/dmat.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++- tests/mat.rs | 50 ++++++++++++++++++++++++++++++++++ tests/quat.rs | 10 +++---- tests/vec.rs | 20 +++++++------- 4 files changed, 130 insertions(+), 16 deletions(-) diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index a8826850..9dec5a3b 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -10,7 +10,7 @@ use rand::{self, Rand}; use num::{Zero, One}; use structs::dvec::DVec; use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov}; -use traits::structure::{Cast, ColSlice, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum}; +use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum}; #[cfg(feature="arbitrary")] use quickcheck::{Arbitrary, Gen}; @@ -541,6 +541,38 @@ impl + Clone> Cov> for DMat { } } +impl Col> for DMat { + #[inline] + fn ncols(&self) -> usize { + self.ncols + } + + #[inline] + fn set_col(&mut self, col_id: usize, v: DVec) { + assert!(col_id < self.ncols); + assert!(self.nrows == v.len()); + + for (i, e) in v[..].iter().enumerate() { + unsafe { + self.unsafe_set((i, col_id), *e); + } + } + } + + #[inline] + fn col(&self, col_id: usize) -> DVec { + let mut res: DVec = unsafe { + DVec::new_uninitialized(self.nrows) + }; + + for (row_id, e) in res[..].iter_mut().enumerate() { + *e = unsafe { self.unsafe_at((row_id, col_id)) }; + } + + res + } +} + impl ColSlice> for DMat { fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> DVec { assert!(col_id < self.ncols); @@ -556,6 +588,38 @@ impl ColSlice> for DMat { } } +impl Row> for DMat { + #[inline] + fn nrows(&self) -> usize { + self.nrows + } + + #[inline] + fn set_row(&mut self, row_id: usize, v: DVec) { + assert!(row_id < self.nrows); + assert!(self.ncols == v.len()); + + for (i, e) in v[..].iter().enumerate() { + unsafe { + self.unsafe_set((row_id, i), *e); + } + } + } + + #[inline] + fn row(&self, row_id: usize) -> DVec { + let mut res: DVec = unsafe { + DVec::new_uninitialized(self.ncols) + }; + + for (col_id, e) in res[..].iter_mut().enumerate() { + *e = unsafe { self.unsafe_at((row_id, col_id)) }; + } + + res + } +} + impl RowSlice> for DMat { fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> DVec { assert!(row_id < self.nrows); diff --git a/tests/mat.rs b/tests/mat.rs index b79c548d..05725f69 100644 --- a/tests/mat.rs +++ b/tests/mat.rs @@ -315,6 +315,33 @@ fn test_transpose_dmat() { assert!(na::transpose(&na::transpose(&mat)) == mat); } +#[test] +fn test_row_dmat() { + let mat = DMat::from_row_vec( + 8, + 4, + &[ + 1u32,2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + 17, 18, 19, 20, + 21, 22, 23, 24, + 25, 26, 27, 28, + 29, 30, 31, 32 + ] + ); + + assert_eq!(&DVec::from_slice(4, &[1u32, 2, 3, 4]), &mat.row(0)); + assert_eq!(&DVec::from_slice(4, &[5u32, 6, 7, 8]), &mat.row(1)); + assert_eq!(&DVec::from_slice(4, &[9u32, 10, 11, 12]), &mat.row(2)); + assert_eq!(&DVec::from_slice(4, &[13u32, 14, 15, 16]), &mat.row(3)); + assert_eq!(&DVec::from_slice(4, &[17u32, 18, 19, 20]), &mat.row(4)); + assert_eq!(&DVec::from_slice(4, &[21u32, 22, 23, 24]), &mat.row(5)); + assert_eq!(&DVec::from_slice(4, &[25u32, 26, 27, 28]), &mat.row(6)); + assert_eq!(&DVec::from_slice(4, &[29u32, 30, 31, 32]), &mat.row(7)); +} + #[test] fn test_row_slice_dmat() { let mat = DMat::from_row_vec( @@ -335,6 +362,29 @@ fn test_row_slice_dmat() { assert_eq!(&DVec::from_slice(2, &[19u32, 20]), &mat.row_slice(4, 2, 4)); } +#[test] +fn test_col_dmat() { + let mat = DMat::from_row_vec( + 8, + 4, + &[ + 1u32,2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + 17, 18, 19, 20, + 21, 22, 23, 24, + 25, 26, 27, 28, + 29, 30, 31, 32 + ] + ); + + assert_eq!(&DVec::from_slice(8, &[1u32, 5, 9, 13, 17, 21, 25, 29]), &mat.col(0)); + assert_eq!(&DVec::from_slice(8, &[2u32, 6, 10, 14, 18, 22, 26, 30]), &mat.col(1)); + assert_eq!(&DVec::from_slice(8, &[3u32, 7, 11, 15, 19, 23, 27, 31]), &mat.col(2)); + assert_eq!(&DVec::from_slice(8, &[4u32, 8, 12, 16, 20, 24, 28, 32]), &mat.col(3)); +} + #[test] fn test_col_slice_dmat() { let mat = DMat::from_row_vec( diff --git a/tests/quat.rs b/tests/quat.rs index 279ea623..84864721 100644 --- a/tests/quat.rs +++ b/tests/quat.rs @@ -6,7 +6,7 @@ use rand::random; #[test] fn test_quat_as_mat() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let axis_angle: Vec3 = random(); assert!(na::approx_eq(&UnitQuat::new(axis_angle).to_rot(), &Rot3::new(axis_angle))) @@ -15,7 +15,7 @@ fn test_quat_as_mat() { #[test] fn test_quat_mul_vec_or_pnt_as_mat() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let axis_angle: Vec3 = random(); let vec: Vec3 = random(); let pnt: Pnt3 = random(); @@ -32,7 +32,7 @@ fn test_quat_mul_vec_or_pnt_as_mat() { #[test] fn test_quat_div_quat() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let axis_angle1: Vec3 = random(); let axis_angle2: Vec3 = random(); @@ -48,7 +48,7 @@ fn test_quat_div_quat() { #[test] fn test_quat_to_axis_angle() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let axis_angle: Vec3 = random(); let q = UnitQuat::new(axis_angle); @@ -60,7 +60,7 @@ fn test_quat_to_axis_angle() { #[test] fn test_quat_euler_angles() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let angles: Vec3 = random(); let q = UnitQuat::new_with_euler_angles(angles.x, angles.y, angles.z); diff --git a/tests/vec.rs b/tests/vec.rs index daceba03..40bf02c9 100644 --- a/tests/vec.rs +++ b/tests/vec.rs @@ -6,7 +6,7 @@ use na::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, I macro_rules! test_iterator_impl( ($t: ty, $n: ty) => ( - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v: $t = random(); let mut mv: $t = v.clone(); let n: $n = random(); @@ -24,7 +24,7 @@ macro_rules! test_iterator_impl( macro_rules! test_commut_dot_impl( ($t: ty) => ( - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v1 : $t = random(); let v2 : $t = random(); @@ -35,7 +35,7 @@ macro_rules! test_commut_dot_impl( macro_rules! test_scalar_op_impl( ($t: ty, $n: ty) => ( - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v1 : $t = random(); let n : $n = random(); @@ -58,7 +58,7 @@ macro_rules! test_scalar_op_impl( macro_rules! test_basis_impl( ($t: ty) => ( - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { na::canonical_basis(|e1: $t| { na::canonical_basis(|e2: $t| { assert!(e1 == e2 || na::approx_eq(&na::dot(&e1, &e2), &na::zero())); @@ -76,7 +76,7 @@ macro_rules! test_basis_impl( macro_rules! test_subspace_basis_impl( ($t: ty) => ( - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v : $t = random(); let v1 = na::normalize(&v); @@ -100,7 +100,7 @@ macro_rules! test_subspace_basis_impl( #[test] fn test_cross_vec3() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v1 : Vec3 = random(); let v2 : Vec3 = random(); let v3 : Vec3 = na::cross(&v1, &v2); @@ -321,7 +321,7 @@ fn test_outer_vec3() { #[test] fn test_vec3_rotation_between() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v1: Vec3 = random(); let mut v2: Vec3 = random(); @@ -335,7 +335,7 @@ fn test_vec3_rotation_between() { #[test] fn test_vec3_angle_between() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let vec: Vec3 = random(); let other: Vec3 = random(); @@ -353,7 +353,7 @@ fn test_vec3_angle_between() { #[test] fn test_vec2_rotation_between() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let v1: Vec2 = random(); let mut v2: Vec2 = random(); @@ -367,7 +367,7 @@ fn test_vec2_rotation_between() { #[test] fn test_vec2_angle_between() { - for _ in (0usize .. 10000) { + for _ in 0usize .. 10000 { let axis_ang: Vec1 = random(); let ang = na::norm(&axis_ang);