diff --git a/src/base/edition.rs b/src/base/edition.rs index 84f0b571..424374b0 100644 --- a/src/base/edition.rs +++ b/src/base/edition.rs @@ -39,7 +39,7 @@ impl> Matrix { where I: IntoIterator, I::IntoIter: ExactSizeIterator + Clone, DefaultAllocator: Allocator { - let mut irows = irows.into_iter(); + let irows = irows.into_iter(); let ncols = self.data.shape().1; let mut res = unsafe { MatrixMN::new_uninitialized_generic(Dynamic::new(irows.len()), ncols) }; @@ -69,7 +69,7 @@ impl> Matrix { where I: IntoIterator, I::IntoIter: ExactSizeIterator, DefaultAllocator: Allocator { - let mut icols = icols.into_iter(); + let icols = icols.into_iter(); let nrows = self.data.shape().0; let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, Dynamic::new(icols.len())) }; diff --git a/src/base/iter.rs b/src/base/iter.rs index 2b5a12d4..8a5f10ab 100644 --- a/src/base/iter.rs +++ b/src/base/iter.rs @@ -5,7 +5,7 @@ use std::mem; use base::dimension::{Dim, U1}; use base::storage::{Storage, StorageMut}; -use base::{Scalar, Matrix, MatrixSlice, MatrixSliceMut, Dynamic}; +use base::{Scalar, Matrix, MatrixSlice, MatrixSliceMut}; macro_rules! iterator { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => { @@ -104,13 +104,14 @@ iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a * */ #[derive(Clone)] +/// An iterator through the rows of a matrix. pub struct RowIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage> { mat: &'a Matrix, curr: usize } impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage> RowIter<'a, N, R, C, S> { - pub fn new(mat: &'a Matrix) -> Self { + pub(crate) fn new(mat: &'a Matrix) -> Self { RowIter { mat, curr: 0 } @@ -151,15 +152,15 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage> ExactSizeIterator } - +/// An iterator through the mutable rows of a matrix. pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut> { mat: *mut Matrix, curr: usize, - phantom: PhantomData<&'a Matrix> + phantom: PhantomData<&'a mut Matrix> } impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut> RowIterMut<'a, N, R, C, S> { - pub fn new(mat: &'a mut Matrix) -> Self { + pub(crate) fn new(mat: &'a mut Matrix) -> Self { RowIterMut { mat, curr: 0, @@ -214,13 +215,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut> ExactSizeIterat * */ #[derive(Clone)] +/// An iterator through the columns of a matrix. pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage> { mat: &'a Matrix, curr: usize } impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage> ColumnIter<'a, N, R, C, S> { - pub fn new(mat: &'a Matrix) -> Self { + pub(crate) fn new(mat: &'a Matrix) -> Self { ColumnIter { mat, curr: 0 } @@ -261,15 +263,15 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage> ExactSizeIterator } - +/// An iterator through the mutable columns of a matrix. pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut> { mat: *mut Matrix, curr: usize, - phantom: PhantomData<&'a Matrix> + phantom: PhantomData<&'a mut Matrix> } impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut> ColumnIterMut<'a, N, R, C, S> { - pub fn new(mat: &'a mut Matrix) -> Self { + pub(crate) fn new(mat: &'a mut Matrix) -> Self { ColumnIterMut { mat, curr: 0, diff --git a/src/base/matrix.rs b/src/base/matrix.rs index 61434bb9..89078943 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -247,11 +247,13 @@ impl> Matrix { MatrixIter::new(&self.data) } + /// Iterate through the rows of this matrix. #[inline] pub fn row_iter(&self) -> RowIter { RowIter::new(self) } + /// Iterate through the columns of this matrix. #[inline] pub fn column_iter(&self) -> ColumnIter { ColumnIter::new(self) @@ -739,7 +741,7 @@ impl> Matrix { for i in 0..nrows { unsafe { let e = self.data.get_unchecked_mut(i, j); - let rhs = rhs.get_unchecked(i, j); + let rhs = rhs.get_unchecked((i, j)); *e = f(*e, *rhs) } } @@ -776,8 +778,8 @@ impl> Matrix { for i in 0..nrows { unsafe { let e = self.data.get_unchecked_mut(i, j); - let b = b.get_unchecked(i, j); - let c = c.get_unchecked(i, j); + let b = b.get_unchecked((i, j)); + let c = c.get_unchecked((i, j)); *e = f(*e, *b, *c) } } diff --git a/src/base/mod.rs b/src/base/mod.rs index be54eb6c..0ec6311c 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -30,7 +30,7 @@ mod scalar; mod swizzle; mod unit; mod statistics; -pub mod norm; +mod norm; #[doc(hidden)] pub mod helper; diff --git a/src/base/norm.rs b/src/base/norm.rs index 6e392bd5..354f2ca3 100644 --- a/src/base/norm.rs +++ b/src/base/norm.rs @@ -1,4 +1,4 @@ -use num::{Signed, Zero}; +use num::Signed; use std::cmp::PartialOrd; use allocator::Allocator; @@ -9,9 +9,14 @@ use constraint::{SameNumberOfRows, SameNumberOfColumns, ShapeConstraint}; // FIXME: this should be be a trait on alga? +/// A trait for abstract matrix norms. +/// +/// This may be moved to the alga crate in the future. pub trait Norm { + /// Apply this norm to the given matrix. fn norm(&self, m: &Matrix) -> N where R: Dim, C: Dim, S: Storage; + /// Use the metric induced by this norm to compute the metric distance between the two given matrices. fn metric_distance(&self, m1: &Matrix, m2: &Matrix) -> N where R1: Dim, C1: Dim, S1: Storage, R2: Dim, C2: Dim, S2: Storage, @@ -104,12 +109,16 @@ impl> Matrix { } /// The L2 norm of this matrix. + /// + /// Use `.apply_norm` to apply a custom norm. #[inline] pub fn norm(&self) -> N { self.norm_squared().sqrt() } - /// Computes the metric distance between `self` and `rhs` using the Euclidean metric. + /// Compute the distance between `self` and `rhs` using the metric induced by the euclidean norm. + /// + /// Use `.apply_metric_distance` to apply a custom norm. #[inline] pub fn metric_distance(&self, rhs: &Matrix) -> N where R2: Dim, C2: Dim, S2: Storage, @@ -117,11 +126,13 @@ impl> Matrix { self.apply_metric_distance(rhs, &EuclideanNorm) } + /// Uses the given `norm` to compute the norm of `self`. #[inline] pub fn apply_norm(&self, norm: &impl Norm) -> N { norm.norm(self) } + /// Uses the metric induced by the given `norm` to compute the metric distance between `self` and `rhs`. #[inline] pub fn apply_metric_distance(&self, rhs: &Matrix, norm: &impl Norm) -> N where R2: Dim, C2: Dim, S2: Storage, diff --git a/src/base/statistics.rs b/src/base/statistics.rs index 8f95e447..106673c4 100644 --- a/src/base/statistics.rs +++ b/src/base/statistics.rs @@ -3,6 +3,8 @@ use storage::Storage; use allocator::Allocator; impl> Matrix { + /// Returns a row vector where each element is the result of the application of `f` on the + /// corresponding column of the original matrix. #[inline] pub fn compress_rows(&self, f: impl Fn(VectorSliceN) -> N) -> RowVectorN where DefaultAllocator: Allocator { @@ -12,12 +14,16 @@ impl> Matrix { for i in 0..ncols.value() { // FIXME: avoid bound checking of column. - unsafe { *res.get_unchecked_mut(0, i) = f(self.column(i)); } + unsafe { *res.get_unchecked_mut((0, i)) = f(self.column(i)); } } res } + /// Returns a column vector where each element is the result of the application of `f` on the + /// corresponding column of the original matrix. + /// + /// This is the same as `self.compress_rows(f).transpose()`. #[inline] pub fn compress_rows_tr(&self, f: impl Fn(VectorSliceN) -> N) -> VectorN where DefaultAllocator: Allocator { @@ -33,6 +39,7 @@ impl> Matrix { res } + /// Returns a column vector resulting from the folding of `f` on each column of this matrix. #[inline] pub fn compress_columns(&self, init: VectorN, f: impl Fn(&mut VectorN, VectorSliceN)) -> VectorN where DefaultAllocator: Allocator { @@ -52,23 +59,27 @@ impl> Matrix { * Sum computation. * */ + /// The sum of all the elements of this matrix. #[inline] pub fn sum(&self) -> N { self.iter().cloned().fold(N::zero(), |a, b| a + b) } + /// The sum of all the rows of this matrix. #[inline] pub fn row_sum(&self) -> RowVectorN where DefaultAllocator: Allocator { self.compress_rows(|col| col.sum()) } + /// The sum of all the rows of this matrix. The result is transposed and returned as a column vector. #[inline] pub fn row_sum_tr(&self) -> VectorN where DefaultAllocator: Allocator { self.compress_rows_tr(|col| col.sum()) } + /// The sum of all the columns of this matrix. #[inline] pub fn column_sum(&self) -> VectorN where DefaultAllocator: Allocator { @@ -83,6 +94,7 @@ impl> Matrix { * Variance computation. * */ + /// The variance of all the elements of this matrix. #[inline] pub fn variance(&self) -> N { if self.len() == 0 { @@ -94,18 +106,21 @@ impl> Matrix { } } + /// The variance of all the rows of this matrix. #[inline] pub fn row_variance(&self) -> RowVectorN where DefaultAllocator: Allocator { self.compress_rows(|col| col.variance()) } + /// The variance of all the rows of this matrix. The result is transposed and returned as a column vector. #[inline] pub fn row_variance_tr(&self) -> VectorN where DefaultAllocator: Allocator { self.compress_rows_tr(|col| col.variance()) } + /// The variance of all the columns of this matrix. #[inline] pub fn column_variance(&self) -> VectorN where DefaultAllocator: Allocator { @@ -130,6 +145,7 @@ impl> Matrix { * Mean computation. * */ + /// The mean of all the elements of this matrix. #[inline] pub fn mean(&self) -> N { if self.len() == 0 { @@ -139,18 +155,21 @@ impl> Matrix { } } + /// The mean of all the rows of this matrix. #[inline] pub fn row_mean(&self) -> RowVectorN where DefaultAllocator: Allocator { self.compress_rows(|col| col.mean()) } + /// The mean of all the rows of this matrix. The result is transposed and returned as a column vector. #[inline] pub fn row_mean_tr(&self) -> VectorN where DefaultAllocator: Allocator { self.compress_rows_tr(|col| col.mean()) } + /// The mean of all the columns of this matrix. #[inline] pub fn column_mean(&self) -> VectorN where DefaultAllocator: Allocator { diff --git a/tests/core/matrix.rs b/tests/core/matrix.rs index 3b624c69..9c6d468a 100644 --- a/tests/core/matrix.rs +++ b/tests/core/matrix.rs @@ -292,8 +292,8 @@ fn push() { let a = Vector3::new(1.0, 2.0, 3.0); let expected_a = Vector4::new(1.0, 2.0, 3.0, 4.0); - let b = DVector::from_row_slice(3, &[1.0, 2.0, 3.0]); - let expected_b = DVector::from_row_slice(4, &[1.0, 2.0, 3.0, 4.0]); + let b = DVector::from_row_slice(&[1.0, 2.0, 3.0]); + let expected_b = DVector::from_row_slice(&[1.0, 2.0, 3.0, 4.0]); assert_eq!(a.push(4.0), expected_a); assert_eq!(b.push(4.0), expected_b);