From 58de7f461ebe68c1af7d55c4916c788df23cf3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 10 Jan 2016 15:23:18 +0100 Subject: [PATCH] DMat{1..6}: make the `Col` and `Row` implementation return a DVec{1..6} instead of a plain DVec. Also adds the `DVec{1..6}::new_uninitialized(dim)` function. --- src/structs/dmat.rs | 46 ++++++++++---------- src/structs/dmat_macros.rs | 88 ++++++++++++++++++++------------------ src/structs/dvec.rs | 1 + src/structs/dvec_macros.rs | 14 ++++++ 4 files changed, 84 insertions(+), 65 deletions(-) diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index efc359df..345c0742 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -9,7 +9,7 @@ use std::ops::{Add, Sub, Mul, Div, Index, IndexMut}; use std::fmt::{Debug, Formatter, Result}; use rand::{self, Rand}; use num::{Zero, One}; -use structs::dvec::DVec; +use structs::dvec::{DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov}; use traits::structure::{Cast, Col, ColSlice, Row, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum}; #[cfg(feature="arbitrary")] @@ -128,7 +128,7 @@ impl DMat { } } -dmat_impl!(DMat); +dmat_impl!(DMat, DVec); pub struct DMat1 { @@ -137,7 +137,7 @@ pub struct DMat1 { mij: [N; 1 * 1], } -small_dmat_impl!(DMat1, 1, 0); +small_dmat_impl!(DMat1, DVec1, 1, 0); small_dmat_from_impl!(DMat1, 1, ::zero()); @@ -147,8 +147,8 @@ pub struct DMat2 { mij: [N; 2 * 2], } -small_dmat_impl!(DMat2, 2, 0, 1, - 2, 3); +small_dmat_impl!(DMat2, DVec2, 2, 0, 1, + 2, 3); small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(), ::zero(), ::zero()); @@ -159,9 +159,9 @@ pub struct DMat3 { mij: [N; 3 * 3], } -small_dmat_impl!(DMat3, 3, 0, 1, 2, - 3, 4, 5, - 6, 7, 8); +small_dmat_impl!(DMat3, DVec3, 3, 0, 1, 2, + 3, 4, 5, + 6, 7, 8); small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero()); @@ -173,10 +173,10 @@ pub struct DMat4 { mij: [N; 4 * 4], } -small_dmat_impl!(DMat4, 4, 0, 1, 2, 3, - 4, 5, 6, 7, - 8, 9, 10, 11, - 12, 13, 14, 15); +small_dmat_impl!(DMat4, DVec4, 4, 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15); small_dmat_from_impl!(DMat4, 4, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), @@ -189,11 +189,11 @@ pub struct DMat5 { mij: [N; 5 * 5], } -small_dmat_impl!(DMat5, 5, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24); +small_dmat_impl!(DMat5, DVec5, 5, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24); small_dmat_from_impl!(DMat5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), @@ -207,12 +207,12 @@ pub struct DMat6 { mij: [N; 6 * 6], } -small_dmat_impl!(DMat6, 6, 0, 1, 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, 33, 34, 35); +small_dmat_impl!(DMat6, DVec6, 6, 0, 1, 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, 33, 34, 35); small_dmat_from_impl!(DMat6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), diff --git a/src/structs/dmat_macros.rs b/src/structs/dmat_macros.rs index efef4bf2..4492bff9 100644 --- a/src/structs/dmat_macros.rs +++ b/src/structs/dmat_macros.rs @@ -1,7 +1,7 @@ #![macro_use] macro_rules! dmat_impl( - ($dmat: ident) => ( + ($dmat: ident, $dvec: ident) => ( impl $dmat { /// Builds a matrix filled with zeros. /// @@ -219,13 +219,13 @@ macro_rules! dmat_impl( } } - impl + Mul + Zero> Mul> for $dmat { - type Output = DVec; + impl + Mul + Zero> Mul<$dvec> for $dmat { + type Output = $dvec; - fn mul(self, right: DVec) -> DVec { - assert!(self.ncols == right.at.len()); + fn mul(self, right: $dvec) -> $dvec { + assert!(self.ncols == right.len()); - let mut res : DVec = unsafe { DVec::new_uninitialized(self.nrows) }; + let mut res : $dvec = unsafe { $dvec::new_uninitialized(self.nrows) }; for i in 0..self.nrows { let mut acc: N = ::zero(); @@ -236,7 +236,9 @@ macro_rules! dmat_impl( } } - res.at[i] = acc; + unsafe { + res.unsafe_set(i, acc); + } } res @@ -244,13 +246,13 @@ macro_rules! dmat_impl( } - impl + Mul + Zero> Mul<$dmat> for DVec { - type Output = DVec; + impl + Mul + Zero> Mul<$dmat> for $dvec { + type Output = $dvec; - fn mul(self, right: $dmat) -> DVec { - assert!(right.nrows == self.at.len()); + fn mul(self, right: $dmat) -> $dvec { + assert!(right.nrows == self.len()); - let mut res : DVec = unsafe { DVec::new_uninitialized(right.ncols) }; + let mut res : $dvec = unsafe { $dvec::new_uninitialized(right.ncols) }; for i in 0..right.ncols { let mut acc: N = ::zero(); @@ -261,7 +263,9 @@ macro_rules! dmat_impl( } } - res.at[i] = acc; + unsafe { + res.unsafe_set(i, acc); + } } res @@ -399,10 +403,10 @@ macro_rules! dmat_impl( } } - impl + Clone> Mean> for $dmat { - fn mean(&self) -> DVec { - let mut res: DVec = DVec::new_zeros(self.ncols); - let normalizer: N = Cast::from(1.0f64 / self.nrows as f64); + impl + Clone> Mean<$dvec> for $dmat { + fn mean(&self) -> $dvec { + let mut res: $dvec = $dvec::new_zeros(self.ncols); + let normalizer: N = Cast::from(1.0f64 / self.nrows as f64); for i in 0 .. self.nrows { for j in 0 .. self.ncols { @@ -443,14 +447,14 @@ macro_rules! dmat_impl( } } - impl Col> for $dmat { + impl Col<$dvec> for $dmat { #[inline] fn ncols(&self) -> usize { self.ncols } #[inline] - fn set_col(&mut self, col_id: usize, v: DVec) { + fn set_col(&mut self, col_id: usize, v: $dvec) { assert!(col_id < self.ncols); assert!(self.nrows == v.len()); @@ -462,9 +466,9 @@ macro_rules! dmat_impl( } #[inline] - fn col(&self, col_id: usize) -> DVec { - let mut res: DVec = unsafe { - DVec::new_uninitialized(self.nrows) + 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() { @@ -475,8 +479,8 @@ macro_rules! dmat_impl( } } - impl ColSlice> for $dmat { - fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> DVec { + impl ColSlice<$dvec> for $dmat { + fn col_slice(&self, col_id :usize, row_start: usize, row_end: usize) -> $dvec { assert!(col_id < self.ncols); assert!(row_start < row_end); assert!(row_end <= self.nrows); @@ -484,20 +488,20 @@ macro_rules! dmat_impl( // We can init from slice thanks to the matrix being column-major. let start= self.offset(row_start, col_id); let stop = self.offset(row_end, col_id); - let slice = DVec::from_slice(row_end - row_start, &self.mij[start .. stop]); + let slice = $dvec::from_slice(row_end - row_start, &self.mij[start .. stop]); slice } } - impl Row> for $dmat { + impl Row<$dvec> for $dmat { #[inline] fn nrows(&self) -> usize { self.nrows } #[inline] - fn set_row(&mut self, row_id: usize, v: DVec) { + fn set_row(&mut self, row_id: usize, v: $dvec) { assert!(row_id < self.nrows); assert!(self.ncols == v.len()); @@ -509,9 +513,9 @@ macro_rules! dmat_impl( } #[inline] - fn row(&self, row_id: usize) -> DVec { - let mut res: DVec = unsafe { - DVec::new_uninitialized(self.ncols) + 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() { @@ -522,14 +526,14 @@ macro_rules! dmat_impl( } } - impl RowSlice> for $dmat { - fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> DVec { + impl RowSlice<$dvec> for $dmat { + fn row_slice(&self, row_id :usize, col_start: usize, col_end: usize) -> $dvec { assert!(row_id < self.nrows); assert!(col_start < col_end); assert!(col_end <= self.ncols); - let mut slice : DVec = unsafe { - DVec::new_uninitialized(col_end - col_start) + let mut slice : $dvec = unsafe { + $dvec::new_uninitialized(col_end - col_start) }; let mut slice_idx = 0; for col_id in col_start..col_end { @@ -543,9 +547,9 @@ macro_rules! dmat_impl( } } - impl Diag> for $dmat { + impl Diag<$dvec> for $dmat { #[inline] - fn from_diag(diag: &DVec) -> $dmat { + fn from_diag(diag: &$dvec) -> $dmat { let mut res = $dmat::new_zeros(diag.len(), diag.len()); res.set_diag(diag); @@ -554,10 +558,10 @@ macro_rules! dmat_impl( } #[inline] - fn diag(&self) -> DVec { + fn diag(&self) -> $dvec { let smallest_dim = cmp::min(self.nrows, self.ncols); - let mut diag: DVec = DVec::new_zeros(smallest_dim); + let mut diag: $dvec = $dvec::new_zeros(smallest_dim); for i in 0..smallest_dim { unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) } @@ -567,9 +571,9 @@ macro_rules! dmat_impl( } } - impl DiagMut> for $dmat { + impl DiagMut<$dvec> for $dmat { #[inline] - fn set_diag(&mut self, diag: &DVec) { + fn set_diag(&mut self, diag: &$dvec) { let smallest_dim = cmp::min(self.nrows, self.ncols); assert!(diag.len() == smallest_dim); @@ -761,7 +765,7 @@ macro_rules! dmat_impl( ); macro_rules! small_dmat_impl ( - ($dmat: ident, $dim: expr, $($idx: expr),*) => ( + ($dmat: ident, $dvec: ident, $dim: expr, $($idx: expr),*) => ( impl PartialEq for $dmat { #[inline] fn eq(&self, other: &$dmat) -> bool { @@ -792,7 +796,7 @@ macro_rules! small_dmat_impl ( } } - dmat_impl!($dmat); + dmat_impl!($dmat, $dvec); ) ); diff --git a/src/structs/dvec.rs b/src/structs/dvec.rs index 63e32aff..c9eb91ce 100644 --- a/src/structs/dvec.rs +++ b/src/structs/dvec.rs @@ -6,6 +6,7 @@ use std::slice::{Iter, IterMut}; use std::iter::{FromIterator, IntoIterator}; use std::iter::repeat; use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut}; +use std::mem; use rand::{self, Rand}; use num::{Zero, One}; use traits::operations::{ApproxEq, Axpy, Mean}; diff --git a/src/structs/dvec_macros.rs b/src/structs/dvec_macros.rs index b637827d..35d6c10f 100644 --- a/src/structs/dvec_macros.rs +++ b/src/structs/dvec_macros.rs @@ -387,10 +387,24 @@ macro_rules! dvec_impl( macro_rules! small_dvec_impl ( ($dvec: ident, $dim: expr, $($idx: expr),*) => ( impl $dvec { + /// The number of elements of this vector. #[inline] pub fn len(&self) -> usize { self.dim } + + /// Creates an uninitialized vec of dimension `dim`. + #[inline] + pub unsafe fn new_uninitialized(dim: usize) -> $dvec { + assert!(dim <= $dim, "The chosen dimension is too high for that type of \ + stack-allocated dynamic vector. Consider using the \ + heap-allocated vector: DVec."); + + $dvec { + at: mem::uninitialized(), + dim: dim + } + } } impl PartialEq for $dvec {