forked from M-Labs/nalgebra
Fix rebase fallback + add missing docs.
This commit is contained in:
parent
414fe8afda
commit
dcae274d2e
@ -39,7 +39,7 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
where I: IntoIterator<Item = &'a usize>,
|
||||
I::IntoIter: ExactSizeIterator + Clone,
|
||||
DefaultAllocator: Allocator<N, Dynamic, C> {
|
||||
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<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
where I: IntoIterator<Item = &'a usize>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
DefaultAllocator: Allocator<N, R, Dynamic> {
|
||||
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())) };
|
||||
|
||||
|
@ -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<N, R, C>> {
|
||||
mat: &'a Matrix<N, R, C, S>,
|
||||
curr: usize
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> RowIter<'a, N, R, C, S> {
|
||||
pub fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
|
||||
pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
|
||||
RowIter {
|
||||
mat, curr: 0
|
||||
}
|
||||
@ -151,15 +152,15 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// An iterator through the mutable rows of a matrix.
|
||||
pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
|
||||
mat: *mut Matrix<N, R, C, S>,
|
||||
curr: usize,
|
||||
phantom: PhantomData<&'a Matrix<N, R, C, S>>
|
||||
phantom: PhantomData<&'a mut Matrix<N, R, C, S>>
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a, N, R, C, S> {
|
||||
pub fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
|
||||
pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
|
||||
RowIterMut {
|
||||
mat,
|
||||
curr: 0,
|
||||
@ -214,13 +215,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
|
||||
*
|
||||
*/
|
||||
#[derive(Clone)]
|
||||
/// An iterator through the columns of a matrix.
|
||||
pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
|
||||
mat: &'a Matrix<N, R, C, S>,
|
||||
curr: usize
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ColumnIter<'a, N, R, C, S> {
|
||||
pub fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
|
||||
pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
|
||||
ColumnIter {
|
||||
mat, curr: 0
|
||||
}
|
||||
@ -261,15 +263,15 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// An iterator through the mutable columns of a matrix.
|
||||
pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
|
||||
mat: *mut Matrix<N, R, C, S>,
|
||||
curr: usize,
|
||||
phantom: PhantomData<&'a Matrix<N, R, C, S>>
|
||||
phantom: PhantomData<&'a mut Matrix<N, R, C, S>>
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'a, N, R, C, S> {
|
||||
pub fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
|
||||
pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self {
|
||||
ColumnIterMut {
|
||||
mat,
|
||||
curr: 0,
|
||||
|
@ -247,11 +247,13 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
MatrixIter::new(&self.data)
|
||||
}
|
||||
|
||||
/// Iterate through the rows of this matrix.
|
||||
#[inline]
|
||||
pub fn row_iter(&self) -> RowIter<N, R, C, S> {
|
||||
RowIter::new(self)
|
||||
}
|
||||
|
||||
/// Iterate through the columns of this matrix.
|
||||
#[inline]
|
||||
pub fn column_iter(&self) -> ColumnIter<N, R, C, S> {
|
||||
ColumnIter::new(self)
|
||||
@ -739,7 +741,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
||||
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<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ mod scalar;
|
||||
mod swizzle;
|
||||
mod unit;
|
||||
mod statistics;
|
||||
pub mod norm;
|
||||
mod norm;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod helper;
|
||||
|
@ -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<N: Scalar> {
|
||||
/// Apply this norm to the given matrix.
|
||||
fn norm<R, C, S>(&self, m: &Matrix<N, R, C, S>) -> N
|
||||
where R: Dim, C: Dim, S: Storage<N, R, C>;
|
||||
/// Use the metric induced by this norm to compute the metric distance between the two given matrices.
|
||||
fn metric_distance<R1, C1, S1, R2, C2, S2>(&self, m1: &Matrix<N, R1, C1, S1>, m2: &Matrix<N, R2, C2, S2>) -> N
|
||||
where R1: Dim, C1: Dim, S1: Storage<N, R1, C1>,
|
||||
R2: Dim, C2: Dim, S2: Storage<N, R2, C2>,
|
||||
@ -104,12 +109,16 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
}
|
||||
|
||||
/// 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<R2, C2, S2>(&self, rhs: &Matrix<N, R2, C2, S2>) -> N
|
||||
where R2: Dim, C2: Dim, S2: Storage<N, R2, C2>,
|
||||
@ -117,11 +126,13 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
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>) -> 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<R2, C2, S2>(&self, rhs: &Matrix<N, R2, C2, S2>, norm: &impl Norm<N>) -> N
|
||||
where R2: Dim, C2: Dim, S2: Storage<N, R2, C2>,
|
||||
|
@ -3,6 +3,8 @@ use storage::Storage;
|
||||
use allocator::Allocator;
|
||||
|
||||
impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
/// 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, R, S::RStride, S::CStride>) -> N) -> RowVectorN<N, C>
|
||||
where DefaultAllocator: Allocator<N, U1, C> {
|
||||
@ -12,12 +14,16 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
|
||||
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, R, S::RStride, S::CStride>) -> N) -> VectorN<N, C>
|
||||
where DefaultAllocator: Allocator<N, C> {
|
||||
@ -33,6 +39,7 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
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<N, R>, f: impl Fn(&mut VectorN<N, R>, VectorSliceN<N, R, S::RStride, S::CStride>)) -> VectorN<N, R>
|
||||
where DefaultAllocator: Allocator<N, R> {
|
||||
@ -52,23 +59,27 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
* 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<N, C>
|
||||
where DefaultAllocator: Allocator<N, U1, C> {
|
||||
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<N, C>
|
||||
where DefaultAllocator: Allocator<N, C> {
|
||||
self.compress_rows_tr(|col| col.sum())
|
||||
}
|
||||
|
||||
/// The sum of all the columns of this matrix.
|
||||
#[inline]
|
||||
pub fn column_sum(&self) -> VectorN<N, R>
|
||||
where DefaultAllocator: Allocator<N, R> {
|
||||
@ -83,6 +94,7 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
* 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<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The variance of all the rows of this matrix.
|
||||
#[inline]
|
||||
pub fn row_variance(&self) -> RowVectorN<N, C>
|
||||
where DefaultAllocator: Allocator<N, U1, C> {
|
||||
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<N, C>
|
||||
where DefaultAllocator: Allocator<N, C> {
|
||||
self.compress_rows_tr(|col| col.variance())
|
||||
}
|
||||
|
||||
/// The variance of all the columns of this matrix.
|
||||
#[inline]
|
||||
pub fn column_variance(&self) -> VectorN<N, R>
|
||||
where DefaultAllocator: Allocator<N, R> {
|
||||
@ -130,6 +145,7 @@ impl<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
* 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<N: Real, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The mean of all the rows of this matrix.
|
||||
#[inline]
|
||||
pub fn row_mean(&self) -> RowVectorN<N, C>
|
||||
where DefaultAllocator: Allocator<N, U1, C> {
|
||||
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<N, C>
|
||||
where DefaultAllocator: Allocator<N, C> {
|
||||
self.compress_rows_tr(|col| col.mean())
|
||||
}
|
||||
|
||||
/// The mean of all the columns of this matrix.
|
||||
#[inline]
|
||||
pub fn column_mean(&self) -> VectorN<N, R>
|
||||
where DefaultAllocator: Allocator<N, R> {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user