Implement `Row` and `Col` for `DMat`.

Fix #153.
This commit is contained in:
Sébastien Crozet 2016-01-10 14:49:55 +01:00
parent 11b49f50c9
commit 3cd4221bf7
4 changed files with 130 additions and 16 deletions

View File

@ -10,7 +10,7 @@ use rand::{self, Rand};
use num::{Zero, One}; use num::{Zero, One};
use structs::dvec::DVec; use structs::dvec::DVec;
use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov}; 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")] #[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
@ -541,6 +541,38 @@ impl<N: BaseNum + Cast<f64> + Clone> Cov<DMat<N>> for DMat<N> {
} }
} }
impl<N: Copy + Zero> Col<DVec<N>> for DMat<N> {
#[inline]
fn ncols(&self) -> usize {
self.ncols
}
#[inline]
fn set_col(&mut self, col_id: usize, v: DVec<N>) {
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<N> {
let mut res: DVec<N> = 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<N: Copy + Clone> ColSlice<DVec<N>> for DMat<N> { impl<N: Copy + Clone> ColSlice<DVec<N>> for DMat<N> {
fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> DVec<N> { fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> DVec<N> {
assert!(col_id < self.ncols); assert!(col_id < self.ncols);
@ -556,6 +588,38 @@ impl<N: Copy + Clone> ColSlice<DVec<N>> for DMat<N> {
} }
} }
impl<N: Copy + Zero> Row<DVec<N>> for DMat<N> {
#[inline]
fn nrows(&self) -> usize {
self.nrows
}
#[inline]
fn set_row(&mut self, row_id: usize, v: DVec<N>) {
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<N> {
let mut res: DVec<N> = 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<N: Copy> RowSlice<DVec<N>> for DMat<N> { impl<N: Copy> RowSlice<DVec<N>> for DMat<N> {
fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> DVec<N> { fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> DVec<N> {
assert!(row_id < self.nrows); assert!(row_id < self.nrows);

View File

@ -315,6 +315,33 @@ fn test_transpose_dmat() {
assert!(na::transpose(&na::transpose(&mat)) == mat); 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] #[test]
fn test_row_slice_dmat() { fn test_row_slice_dmat() {
let mat = DMat::from_row_vec( 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)); 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] #[test]
fn test_col_slice_dmat() { fn test_col_slice_dmat() {
let mat = DMat::from_row_vec( let mat = DMat::from_row_vec(

View File

@ -6,7 +6,7 @@ use rand::random;
#[test] #[test]
fn test_quat_as_mat() { fn test_quat_as_mat() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random(); let axis_angle: Vec3<f64> = random();
assert!(na::approx_eq(&UnitQuat::new(axis_angle).to_rot(), &Rot3::new(axis_angle))) assert!(na::approx_eq(&UnitQuat::new(axis_angle).to_rot(), &Rot3::new(axis_angle)))
@ -15,7 +15,7 @@ fn test_quat_as_mat() {
#[test] #[test]
fn test_quat_mul_vec_or_pnt_as_mat() { fn test_quat_mul_vec_or_pnt_as_mat() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random(); let axis_angle: Vec3<f64> = random();
let vec: Vec3<f64> = random(); let vec: Vec3<f64> = random();
let pnt: Pnt3<f64> = random(); let pnt: Pnt3<f64> = random();
@ -32,7 +32,7 @@ fn test_quat_mul_vec_or_pnt_as_mat() {
#[test] #[test]
fn test_quat_div_quat() { fn test_quat_div_quat() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let axis_angle1: Vec3<f64> = random(); let axis_angle1: Vec3<f64> = random();
let axis_angle2: Vec3<f64> = random(); let axis_angle2: Vec3<f64> = random();
@ -48,7 +48,7 @@ fn test_quat_div_quat() {
#[test] #[test]
fn test_quat_to_axis_angle() { fn test_quat_to_axis_angle() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let axis_angle: Vec3<f64> = random(); let axis_angle: Vec3<f64> = random();
let q = UnitQuat::new(axis_angle); let q = UnitQuat::new(axis_angle);
@ -60,7 +60,7 @@ fn test_quat_to_axis_angle() {
#[test] #[test]
fn test_quat_euler_angles() { fn test_quat_euler_angles() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let angles: Vec3<f64> = random(); let angles: Vec3<f64> = random();
let q = UnitQuat::new_with_euler_angles(angles.x, angles.y, angles.z); let q = UnitQuat::new_with_euler_angles(angles.x, angles.y, angles.z);

View File

@ -6,7 +6,7 @@ use na::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Mat3, Rot2, Rot3, Iterable, I
macro_rules! test_iterator_impl( macro_rules! test_iterator_impl(
($t: ty, $n: ty) => ( ($t: ty, $n: ty) => (
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v: $t = random(); let v: $t = random();
let mut mv: $t = v.clone(); let mut mv: $t = v.clone();
let n: $n = random(); let n: $n = random();
@ -24,7 +24,7 @@ macro_rules! test_iterator_impl(
macro_rules! test_commut_dot_impl( macro_rules! test_commut_dot_impl(
($t: ty) => ( ($t: ty) => (
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v1 : $t = random(); let v1 : $t = random();
let v2 : $t = random(); let v2 : $t = random();
@ -35,7 +35,7 @@ macro_rules! test_commut_dot_impl(
macro_rules! test_scalar_op_impl( macro_rules! test_scalar_op_impl(
($t: ty, $n: ty) => ( ($t: ty, $n: ty) => (
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v1 : $t = random(); let v1 : $t = random();
let n : $n = random(); let n : $n = random();
@ -58,7 +58,7 @@ macro_rules! test_scalar_op_impl(
macro_rules! test_basis_impl( macro_rules! test_basis_impl(
($t: ty) => ( ($t: ty) => (
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
na::canonical_basis(|e1: $t| { na::canonical_basis(|e1: $t| {
na::canonical_basis(|e2: $t| { na::canonical_basis(|e2: $t| {
assert!(e1 == e2 || na::approx_eq(&na::dot(&e1, &e2), &na::zero())); 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( macro_rules! test_subspace_basis_impl(
($t: ty) => ( ($t: ty) => (
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v : $t = random(); let v : $t = random();
let v1 = na::normalize(&v); let v1 = na::normalize(&v);
@ -100,7 +100,7 @@ macro_rules! test_subspace_basis_impl(
#[test] #[test]
fn test_cross_vec3() { fn test_cross_vec3() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v1 : Vec3<f64> = random(); let v1 : Vec3<f64> = random();
let v2 : Vec3<f64> = random(); let v2 : Vec3<f64> = random();
let v3 : Vec3<f64> = na::cross(&v1, &v2); let v3 : Vec3<f64> = na::cross(&v1, &v2);
@ -321,7 +321,7 @@ fn test_outer_vec3() {
#[test] #[test]
fn test_vec3_rotation_between() { fn test_vec3_rotation_between() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v1: Vec3<f64> = random(); let v1: Vec3<f64> = random();
let mut v2: Vec3<f64> = random(); let mut v2: Vec3<f64> = random();
@ -335,7 +335,7 @@ fn test_vec3_rotation_between() {
#[test] #[test]
fn test_vec3_angle_between() { fn test_vec3_angle_between() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let vec: Vec3<f64> = random(); let vec: Vec3<f64> = random();
let other: Vec3<f64> = random(); let other: Vec3<f64> = random();
@ -353,7 +353,7 @@ fn test_vec3_angle_between() {
#[test] #[test]
fn test_vec2_rotation_between() { fn test_vec2_rotation_between() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let v1: Vec2<f64> = random(); let v1: Vec2<f64> = random();
let mut v2: Vec2<f64> = random(); let mut v2: Vec2<f64> = random();
@ -367,7 +367,7 @@ fn test_vec2_rotation_between() {
#[test] #[test]
fn test_vec2_angle_between() { fn test_vec2_angle_between() {
for _ in (0usize .. 10000) { for _ in 0usize .. 10000 {
let axis_ang: Vec1<f64> = random(); let axis_ang: Vec1<f64> = random();
let ang = na::norm(&axis_ang); let ang = na::norm(&axis_ang);