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.
This commit is contained in:
Sébastien Crozet 2016-01-10 15:23:18 +01:00
parent 1338e0c358
commit 58de7f461e
4 changed files with 84 additions and 65 deletions

View File

@ -9,7 +9,7 @@ use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};
use std::fmt::{Debug, Formatter, Result}; use std::fmt::{Debug, Formatter, Result};
use rand::{self, Rand}; use rand::{self, Rand};
use num::{Zero, One}; 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::operations::{ApproxEq, Inv, Transpose, Mean, Cov};
use traits::structure::{Cast, Col, ColSlice, Row, 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")]
@ -128,7 +128,7 @@ impl<N> DMat<N> {
} }
} }
dmat_impl!(DMat); dmat_impl!(DMat, DVec);
pub struct DMat1<N> { pub struct DMat1<N> {
@ -137,7 +137,7 @@ pub struct DMat1<N> {
mij: [N; 1 * 1], mij: [N; 1 * 1],
} }
small_dmat_impl!(DMat1, 1, 0); small_dmat_impl!(DMat1, DVec1, 1, 0);
small_dmat_from_impl!(DMat1, 1, ::zero()); small_dmat_from_impl!(DMat1, 1, ::zero());
@ -147,7 +147,7 @@ pub struct DMat2<N> {
mij: [N; 2 * 2], mij: [N; 2 * 2],
} }
small_dmat_impl!(DMat2, 2, 0, 1, small_dmat_impl!(DMat2, DVec2, 2, 0, 1,
2, 3); 2, 3);
small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(), small_dmat_from_impl!(DMat2, 2, ::zero(), ::zero(),
::zero(), ::zero()); ::zero(), ::zero());
@ -159,7 +159,7 @@ pub struct DMat3<N> {
mij: [N; 3 * 3], mij: [N; 3 * 3],
} }
small_dmat_impl!(DMat3, 3, 0, 1, 2, small_dmat_impl!(DMat3, DVec3, 3, 0, 1, 2,
3, 4, 5, 3, 4, 5,
6, 7, 8); 6, 7, 8);
small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(), small_dmat_from_impl!(DMat3, 3, ::zero(), ::zero(), ::zero(),
@ -173,7 +173,7 @@ pub struct DMat4<N> {
mij: [N; 4 * 4], mij: [N; 4 * 4],
} }
small_dmat_impl!(DMat4, 4, 0, 1, 2, 3, small_dmat_impl!(DMat4, DVec4, 4, 0, 1, 2, 3,
4, 5, 6, 7, 4, 5, 6, 7,
8, 9, 10, 11, 8, 9, 10, 11,
12, 13, 14, 15); 12, 13, 14, 15);
@ -189,7 +189,7 @@ pub struct DMat5<N> {
mij: [N; 5 * 5], mij: [N; 5 * 5],
} }
small_dmat_impl!(DMat5, 5, 0, 1, 2, 3, 4, small_dmat_impl!(DMat5, DVec5, 5, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 15, 16, 17, 18, 19,
@ -207,7 +207,7 @@ pub struct DMat6<N> {
mij: [N; 6 * 6], mij: [N; 6 * 6],
} }
small_dmat_impl!(DMat6, 6, 0, 1, 2, 3, 4, 5, small_dmat_impl!(DMat6, DVec6, 6, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 18, 19, 20, 21, 22, 23,

View File

@ -1,7 +1,7 @@
#![macro_use] #![macro_use]
macro_rules! dmat_impl( macro_rules! dmat_impl(
($dmat: ident) => ( ($dmat: ident, $dvec: ident) => (
impl<N: Zero + Clone + Copy> $dmat<N> { impl<N: Zero + Clone + Copy> $dmat<N> {
/// Builds a matrix filled with zeros. /// Builds a matrix filled with zeros.
/// ///
@ -219,13 +219,13 @@ macro_rules! dmat_impl(
} }
} }
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero> Mul<DVec<N>> for $dmat<N> { impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero> Mul<$dvec<N>> for $dmat<N> {
type Output = DVec<N>; type Output = $dvec<N>;
fn mul(self, right: DVec<N>) -> DVec<N> { fn mul(self, right: $dvec<N>) -> $dvec<N> {
assert!(self.ncols == right.at.len()); assert!(self.ncols == right.len());
let mut res : DVec<N> = unsafe { DVec::new_uninitialized(self.nrows) }; let mut res : $dvec<N> = unsafe { $dvec::new_uninitialized(self.nrows) };
for i in 0..self.nrows { for i in 0..self.nrows {
let mut acc: N = ::zero(); let mut acc: N = ::zero();
@ -236,7 +236,9 @@ macro_rules! dmat_impl(
} }
} }
res.at[i] = acc; unsafe {
res.unsafe_set(i, acc);
}
} }
res res
@ -244,13 +246,13 @@ macro_rules! dmat_impl(
} }
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero> Mul<$dmat<N>> for DVec<N> { impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero> Mul<$dmat<N>> for $dvec<N> {
type Output = DVec<N>; type Output = $dvec<N>;
fn mul(self, right: $dmat<N>) -> DVec<N> { fn mul(self, right: $dmat<N>) -> $dvec<N> {
assert!(right.nrows == self.at.len()); assert!(right.nrows == self.len());
let mut res : DVec<N> = unsafe { DVec::new_uninitialized(right.ncols) }; let mut res : $dvec<N> = unsafe { $dvec::new_uninitialized(right.ncols) };
for i in 0..right.ncols { for i in 0..right.ncols {
let mut acc: N = ::zero(); let mut acc: N = ::zero();
@ -261,7 +263,9 @@ macro_rules! dmat_impl(
} }
} }
res.at[i] = acc; unsafe {
res.unsafe_set(i, acc);
}
} }
res res
@ -399,9 +403,9 @@ macro_rules! dmat_impl(
} }
} }
impl<N: BaseNum + Cast<f64> + Clone> Mean<DVec<N>> for $dmat<N> { impl<N: BaseNum + Cast<f64> + Clone> Mean<$dvec<N>> for $dmat<N> {
fn mean(&self) -> DVec<N> { fn mean(&self) -> $dvec<N> {
let mut res: DVec<N> = DVec::new_zeros(self.ncols); let mut res: $dvec<N> = $dvec::new_zeros(self.ncols);
let normalizer: N = Cast::from(1.0f64 / self.nrows as f64); let normalizer: N = Cast::from(1.0f64 / self.nrows as f64);
for i in 0 .. self.nrows { for i in 0 .. self.nrows {
@ -443,14 +447,14 @@ macro_rules! dmat_impl(
} }
} }
impl<N: Copy + Zero> Col<DVec<N>> for $dmat<N> { impl<N: Copy + Zero> Col<$dvec<N>> for $dmat<N> {
#[inline] #[inline]
fn ncols(&self) -> usize { fn ncols(&self) -> usize {
self.ncols self.ncols
} }
#[inline] #[inline]
fn set_col(&mut self, col_id: usize, v: DVec<N>) { fn set_col(&mut self, col_id: usize, v: $dvec<N>) {
assert!(col_id < self.ncols); assert!(col_id < self.ncols);
assert!(self.nrows == v.len()); assert!(self.nrows == v.len());
@ -462,9 +466,9 @@ macro_rules! dmat_impl(
} }
#[inline] #[inline]
fn col(&self, col_id: usize) -> DVec<N> { fn col(&self, col_id: usize) -> $dvec<N> {
let mut res: DVec<N> = unsafe { let mut res: $dvec<N> = unsafe {
DVec::new_uninitialized(self.nrows) $dvec::new_uninitialized(self.nrows)
}; };
for (row_id, e) in res[..].iter_mut().enumerate() { for (row_id, e) in res[..].iter_mut().enumerate() {
@ -475,8 +479,8 @@ macro_rules! dmat_impl(
} }
} }
impl<N: Copy + Clone> ColSlice<DVec<N>> for $dmat<N> { impl<N: Copy + Clone + Zero> 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);
assert!(row_start < row_end); assert!(row_start < row_end);
assert!(row_end <= self.nrows); 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. // We can init from slice thanks to the matrix being column-major.
let start= self.offset(row_start, col_id); let start= self.offset(row_start, col_id);
let stop = self.offset(row_end, 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 slice
} }
} }
impl<N: Copy + Zero> Row<DVec<N>> for $dmat<N> { impl<N: Copy + Zero> Row<$dvec<N>> for $dmat<N> {
#[inline] #[inline]
fn nrows(&self) -> usize { fn nrows(&self) -> usize {
self.nrows self.nrows
} }
#[inline] #[inline]
fn set_row(&mut self, row_id: usize, v: DVec<N>) { fn set_row(&mut self, row_id: usize, v: $dvec<N>) {
assert!(row_id < self.nrows); assert!(row_id < self.nrows);
assert!(self.ncols == v.len()); assert!(self.ncols == v.len());
@ -509,9 +513,9 @@ macro_rules! dmat_impl(
} }
#[inline] #[inline]
fn row(&self, row_id: usize) -> DVec<N> { fn row(&self, row_id: usize) -> $dvec<N> {
let mut res: DVec<N> = unsafe { let mut res: $dvec<N> = unsafe {
DVec::new_uninitialized(self.ncols) $dvec::new_uninitialized(self.ncols)
}; };
for (col_id, e) in res[..].iter_mut().enumerate() { for (col_id, e) in res[..].iter_mut().enumerate() {
@ -522,14 +526,14 @@ macro_rules! dmat_impl(
} }
} }
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);
assert!(col_start < col_end); assert!(col_start < col_end);
assert!(col_end <= self.ncols); assert!(col_end <= self.ncols);
let mut slice : DVec<N> = unsafe { let mut slice : $dvec<N> = unsafe {
DVec::new_uninitialized(col_end - col_start) $dvec::new_uninitialized(col_end - col_start)
}; };
let mut slice_idx = 0; let mut slice_idx = 0;
for col_id in col_start..col_end { for col_id in col_start..col_end {
@ -543,9 +547,9 @@ macro_rules! dmat_impl(
} }
} }
impl<N: Copy + Clone + Zero> Diag<DVec<N>> for $dmat<N> { impl<N: Copy + Clone + Zero> Diag<$dvec<N>> for $dmat<N> {
#[inline] #[inline]
fn from_diag(diag: &DVec<N>) -> $dmat<N> { fn from_diag(diag: &$dvec<N>) -> $dmat<N> {
let mut res = $dmat::new_zeros(diag.len(), diag.len()); let mut res = $dmat::new_zeros(diag.len(), diag.len());
res.set_diag(diag); res.set_diag(diag);
@ -554,10 +558,10 @@ macro_rules! dmat_impl(
} }
#[inline] #[inline]
fn diag(&self) -> DVec<N> { fn diag(&self) -> $dvec<N> {
let smallest_dim = cmp::min(self.nrows, self.ncols); let smallest_dim = cmp::min(self.nrows, self.ncols);
let mut diag: DVec<N> = DVec::new_zeros(smallest_dim); let mut diag: $dvec<N> = $dvec::new_zeros(smallest_dim);
for i in 0..smallest_dim { for i in 0..smallest_dim {
unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) } unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) }
@ -567,9 +571,9 @@ macro_rules! dmat_impl(
} }
} }
impl<N: Copy + Clone + Zero> DiagMut<DVec<N>> for $dmat<N> { impl<N: Copy + Clone + Zero> DiagMut<$dvec<N>> for $dmat<N> {
#[inline] #[inline]
fn set_diag(&mut self, diag: &DVec<N>) { fn set_diag(&mut self, diag: &$dvec<N>) {
let smallest_dim = cmp::min(self.nrows, self.ncols); let smallest_dim = cmp::min(self.nrows, self.ncols);
assert!(diag.len() == smallest_dim); assert!(diag.len() == smallest_dim);
@ -761,7 +765,7 @@ macro_rules! dmat_impl(
); );
macro_rules! small_dmat_impl ( macro_rules! small_dmat_impl (
($dmat: ident, $dim: expr, $($idx: expr),*) => ( ($dmat: ident, $dvec: ident, $dim: expr, $($idx: expr),*) => (
impl<N: PartialEq> PartialEq for $dmat<N> { impl<N: PartialEq> PartialEq for $dmat<N> {
#[inline] #[inline]
fn eq(&self, other: &$dmat<N>) -> bool { fn eq(&self, other: &$dmat<N>) -> bool {
@ -792,7 +796,7 @@ macro_rules! small_dmat_impl (
} }
} }
dmat_impl!($dmat); dmat_impl!($dmat, $dvec);
) )
); );

View File

@ -6,6 +6,7 @@ use std::slice::{Iter, IterMut};
use std::iter::{FromIterator, IntoIterator}; use std::iter::{FromIterator, IntoIterator};
use std::iter::repeat; use std::iter::repeat;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut}; use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
use std::mem;
use rand::{self, Rand}; use rand::{self, Rand};
use num::{Zero, One}; use num::{Zero, One};
use traits::operations::{ApproxEq, Axpy, Mean}; use traits::operations::{ApproxEq, Axpy, Mean};

View File

@ -387,10 +387,24 @@ macro_rules! dvec_impl(
macro_rules! small_dvec_impl ( macro_rules! small_dvec_impl (
($dvec: ident, $dim: expr, $($idx: expr),*) => ( ($dvec: ident, $dim: expr, $($idx: expr),*) => (
impl<N> $dvec<N> { impl<N> $dvec<N> {
/// The number of elements of this vector.
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.dim self.dim
} }
/// Creates an uninitialized vec of dimension `dim`.
#[inline]
pub unsafe fn new_uninitialized(dim: usize) -> $dvec<N> {
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<N: PartialEq> PartialEq for $dvec<N> { impl<N: PartialEq> PartialEq for $dvec<N> {