2019-03-23 21:29:07 +08:00
|
|
|
use crate::allocator::Allocator;
|
2021-08-03 00:41:46 +08:00
|
|
|
use crate::storage::RawStorage;
|
2022-11-14 16:33:08 +08:00
|
|
|
use crate::{Const, DefaultAllocator, Dim, Matrix, OVector, RowOVector, Scalar, VectorView, U1};
|
2021-10-06 16:44:46 +08:00
|
|
|
use num::{One, Zero};
|
|
|
|
use simba::scalar::{ClosedAdd, ClosedMul, Field, SupersetOf};
|
2021-08-03 00:41:46 +08:00
|
|
|
use std::mem::MaybeUninit;
|
2018-12-09 18:21:15 +08:00
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
/// # Folding on columns and rows
|
2021-08-03 00:41:46 +08:00
|
|
|
impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
2019-02-03 15:33:07 +08:00
|
|
|
/// Returns a row vector where each element is the result of the application of `f` on the
|
|
|
|
/// corresponding column of the original matrix.
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2020-03-21 19:16:46 +08:00
|
|
|
pub fn compress_rows(
|
|
|
|
&self,
|
2022-11-14 16:33:08 +08:00
|
|
|
f: impl Fn(VectorView<'_, T, R, S::RStride, S::CStride>) -> T,
|
2021-04-11 17:00:38 +08:00
|
|
|
) -> RowOVector<T, C>
|
2020-03-21 19:16:46 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
DefaultAllocator: Allocator<T, U1, C>,
|
2020-03-21 19:16:46 +08:00
|
|
|
{
|
2021-08-03 00:41:46 +08:00
|
|
|
let ncols = self.shape_generic().1;
|
|
|
|
let mut res = Matrix::uninit(Const::<1>, ncols);
|
2018-12-09 18:21:15 +08:00
|
|
|
|
|
|
|
for i in 0..ncols.value() {
|
2020-11-15 23:57:49 +08:00
|
|
|
// TODO: avoid bound checking of column.
|
2021-08-03 00:41:46 +08:00
|
|
|
// Safety: all indices are in range.
|
2020-03-21 19:16:46 +08:00
|
|
|
unsafe {
|
2021-07-16 14:53:28 +08:00
|
|
|
*res.get_unchecked_mut((0, i)) = MaybeUninit::new(f(self.column(i)));
|
2020-03-21 19:16:46 +08:00
|
|
|
}
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
// Safety: res is now fully initialized.
|
2021-07-16 14:53:28 +08:00
|
|
|
unsafe { res.assume_init() }
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// 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()`.
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2020-03-21 19:16:46 +08:00
|
|
|
pub fn compress_rows_tr(
|
|
|
|
&self,
|
2022-11-14 16:33:08 +08:00
|
|
|
f: impl Fn(VectorView<'_, T, R, S::RStride, S::CStride>) -> T,
|
2021-04-11 17:00:38 +08:00
|
|
|
) -> OVector<T, C>
|
2020-03-21 19:16:46 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
DefaultAllocator: Allocator<T, C>,
|
2020-03-21 19:16:46 +08:00
|
|
|
{
|
2021-08-03 00:41:46 +08:00
|
|
|
let ncols = self.shape_generic().1;
|
|
|
|
let mut res = Matrix::uninit(ncols, Const::<1>);
|
2018-12-09 18:21:15 +08:00
|
|
|
|
|
|
|
for i in 0..ncols.value() {
|
2020-11-15 23:57:49 +08:00
|
|
|
// TODO: avoid bound checking of column.
|
2021-08-03 00:41:46 +08:00
|
|
|
// Safety: all indices are in range.
|
2020-03-21 19:16:46 +08:00
|
|
|
unsafe {
|
2021-07-16 12:56:58 +08:00
|
|
|
*res.vget_unchecked_mut(i) = MaybeUninit::new(f(self.column(i)));
|
2020-03-21 19:16:46 +08:00
|
|
|
}
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
// Safety: res is now fully initialized.
|
2021-07-16 12:56:58 +08:00
|
|
|
unsafe { res.assume_init() }
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// Returns a column vector resulting from the folding of `f` on each column of this matrix.
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2020-03-21 19:16:46 +08:00
|
|
|
pub fn compress_columns(
|
|
|
|
&self,
|
2021-08-03 00:41:46 +08:00
|
|
|
init: OVector<T, R>,
|
2022-11-14 16:33:08 +08:00
|
|
|
f: impl Fn(&mut OVector<T, R>, VectorView<'_, T, R, S::RStride, S::CStride>),
|
2021-04-11 17:00:38 +08:00
|
|
|
) -> OVector<T, R>
|
2020-03-21 19:16:46 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
DefaultAllocator: Allocator<T, R>,
|
2020-03-21 19:16:46 +08:00
|
|
|
{
|
2021-08-03 00:41:46 +08:00
|
|
|
let mut res = init;
|
|
|
|
|
2018-12-09 18:21:15 +08:00
|
|
|
for i in 0..self.ncols() {
|
2021-08-03 00:41:46 +08:00
|
|
|
f(&mut res, self.column(i))
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
|
2021-08-03 00:41:46 +08:00
|
|
|
res
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
/// # Common statistics operations
|
2021-08-03 00:41:46 +08:00
|
|
|
impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
2018-12-09 18:21:15 +08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Sum computation.
|
|
|
|
*
|
|
|
|
*/
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The sum of all the elements of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::Matrix2x3;
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.sum(), 21.0);
|
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn sum(&self) -> T
|
2020-11-15 23:57:49 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: ClosedAdd + Zero,
|
2020-11-15 23:57:49 +08:00
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
self.iter().cloned().fold(T::zero(), |a, b| a + b)
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The sum of all the rows of this matrix.
|
2019-02-03 18:06:06 +08:00
|
|
|
///
|
2021-08-07 18:06:15 +08:00
|
|
|
/// Use `.row_sum_tr` if you need the result in a column vector instead.
|
2019-02-03 18:06:06 +08:00
|
|
|
///
|
2019-02-03 17:56:30 +08:00
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
2019-06-20 07:02:28 +08:00
|
|
|
/// # use nalgebra::{Matrix2x3, Matrix3x2};
|
|
|
|
/// # use nalgebra::{RowVector2, RowVector3};
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.row_sum(), RowVector3::new(5.0, 7.0, 9.0));
|
2019-06-20 07:02:28 +08:00
|
|
|
///
|
2021-10-06 16:44:46 +08:00
|
|
|
/// let mint = Matrix3x2::new(1, 2,
|
|
|
|
/// 3, 4,
|
|
|
|
/// 5, 6);
|
2019-06-20 07:02:28 +08:00
|
|
|
/// assert_eq!(mint.row_sum(), RowVector2::new(9,12));
|
2019-02-03 17:56:30 +08:00
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn row_sum(&self) -> RowOVector<T, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: ClosedAdd + Zero,
|
|
|
|
DefaultAllocator: Allocator<T, U1, C>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_rows(|col| col.sum())
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The sum of all the rows of this matrix. The result is transposed and returned as a column vector.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
2019-06-20 07:02:28 +08:00
|
|
|
/// # use nalgebra::{Matrix2x3, Matrix3x2};
|
|
|
|
/// # use nalgebra::{Vector2, Vector3};
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.row_sum_tr(), Vector3::new(5.0, 7.0, 9.0));
|
2019-06-20 07:02:28 +08:00
|
|
|
///
|
2021-10-06 16:44:46 +08:00
|
|
|
/// let mint = Matrix3x2::new(1, 2,
|
|
|
|
/// 3, 4,
|
|
|
|
/// 5, 6);
|
|
|
|
/// assert_eq!(mint.row_sum_tr(), Vector2::new(9, 12));
|
2019-02-03 17:56:30 +08:00
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn row_sum_tr(&self) -> OVector<T, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: ClosedAdd + Zero,
|
|
|
|
DefaultAllocator: Allocator<T, C>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_rows_tr(|col| col.sum())
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The sum of all the columns of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
2019-06-20 07:02:28 +08:00
|
|
|
/// # use nalgebra::{Matrix2x3, Matrix3x2};
|
|
|
|
/// # use nalgebra::{Vector2, Vector3};
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.column_sum(), Vector2::new(6.0, 15.0));
|
2019-06-20 07:02:28 +08:00
|
|
|
///
|
2021-10-06 16:44:46 +08:00
|
|
|
/// let mint = Matrix3x2::new(1, 2,
|
|
|
|
/// 3, 4,
|
|
|
|
/// 5, 6);
|
|
|
|
/// assert_eq!(mint.column_sum(), Vector3::new(3, 7, 11));
|
2019-02-03 17:56:30 +08:00
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn column_sum(&self) -> OVector<T, R>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: ClosedAdd + Zero,
|
|
|
|
DefaultAllocator: Allocator<T, R>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2021-08-03 00:41:46 +08:00
|
|
|
let nrows = self.shape_generic().0;
|
2021-04-11 17:00:38 +08:00
|
|
|
self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
|
2019-06-20 07:02:28 +08:00
|
|
|
*out += col;
|
2018-12-09 18:21:15 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-10-06 16:44:46 +08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Product computation.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
/// The product of all the elements of this matrix.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::Matrix2x3;
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.product(), 720.0);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn product(&self) -> T
|
|
|
|
where
|
|
|
|
T: ClosedMul + One,
|
|
|
|
{
|
|
|
|
self.iter().cloned().fold(T::one(), |a, b| a * b)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The product of all the rows of this matrix.
|
|
|
|
///
|
|
|
|
/// Use `.row_sum_tr` if you need the result in a column vector instead.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, Matrix3x2};
|
|
|
|
/// # use nalgebra::{RowVector2, RowVector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.row_product(), RowVector3::new(4.0, 10.0, 18.0));
|
|
|
|
///
|
|
|
|
/// let mint = Matrix3x2::new(1, 2,
|
|
|
|
/// 3, 4,
|
|
|
|
/// 5, 6);
|
|
|
|
/// assert_eq!(mint.row_product(), RowVector2::new(15, 48));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn row_product(&self) -> RowOVector<T, C>
|
|
|
|
where
|
|
|
|
T: ClosedMul + One,
|
|
|
|
DefaultAllocator: Allocator<T, U1, C>,
|
|
|
|
{
|
|
|
|
self.compress_rows(|col| col.product())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The product of all the rows of this matrix. The result is transposed and returned as a column vector.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, Matrix3x2};
|
|
|
|
/// # use nalgebra::{Vector2, Vector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.row_product_tr(), Vector3::new(4.0, 10.0, 18.0));
|
|
|
|
///
|
|
|
|
/// let mint = Matrix3x2::new(1, 2,
|
|
|
|
/// 3, 4,
|
|
|
|
/// 5, 6);
|
|
|
|
/// assert_eq!(mint.row_product_tr(), Vector2::new(15, 48));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn row_product_tr(&self) -> OVector<T, C>
|
|
|
|
where
|
|
|
|
T: ClosedMul + One,
|
|
|
|
DefaultAllocator: Allocator<T, C>,
|
|
|
|
{
|
|
|
|
self.compress_rows_tr(|col| col.product())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The product of all the columns of this matrix.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, Matrix3x2};
|
|
|
|
/// # use nalgebra::{Vector2, Vector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.column_product(), Vector2::new(6.0, 120.0));
|
|
|
|
///
|
|
|
|
/// let mint = Matrix3x2::new(1, 2,
|
|
|
|
/// 3, 4,
|
|
|
|
/// 5, 6);
|
|
|
|
/// assert_eq!(mint.column_product(), Vector3::new(2, 12, 30));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[must_use]
|
|
|
|
pub fn column_product(&self) -> OVector<T, R>
|
|
|
|
where
|
|
|
|
T: ClosedMul + One,
|
|
|
|
DefaultAllocator: Allocator<T, R>,
|
|
|
|
{
|
|
|
|
let nrows = self.shape_generic().0;
|
|
|
|
self.compress_columns(
|
|
|
|
OVector::repeat_generic(nrows, Const::<1>, T::one()),
|
|
|
|
|out, col| {
|
|
|
|
out.component_mul_assign(&col);
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-12-09 18:21:15 +08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Variance computation.
|
|
|
|
*
|
|
|
|
*/
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The variance of all the elements of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
2019-02-03 18:06:06 +08:00
|
|
|
/// # #[macro_use] extern crate approx;
|
2019-02-03 17:56:30 +08:00
|
|
|
/// # use nalgebra::Matrix2x3;
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
2019-02-03 18:06:06 +08:00
|
|
|
/// assert_relative_eq!(m.variance(), 35.0 / 12.0, epsilon = 1.0e-8);
|
2019-02-03 17:56:30 +08:00
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn variance(&self) -> T
|
2020-11-15 23:57:49 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
2020-11-15 23:57:49 +08:00
|
|
|
{
|
2020-11-16 19:11:24 +08:00
|
|
|
if self.is_empty() {
|
2021-04-11 17:00:38 +08:00
|
|
|
T::zero()
|
2018-12-09 18:21:15 +08:00
|
|
|
} else {
|
2023-04-25 06:25:36 +08:00
|
|
|
let n_elements: T = crate::convert(self.len() as f64);
|
|
|
|
let mean = self.mean();
|
2023-04-24 06:22:57 +08:00
|
|
|
|
2023-04-25 06:25:36 +08:00
|
|
|
self.iter().cloned().fold(T::zero(), |acc, x| {
|
2023-12-17 05:54:38 +08:00
|
|
|
acc + (x.clone() - mean.clone()) * (x - mean.clone())
|
2023-04-25 06:25:36 +08:00
|
|
|
}) / n_elements
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The variance of all the rows of this matrix.
|
2019-02-03 18:06:06 +08:00
|
|
|
///
|
|
|
|
/// Use `.row_variance_tr` if you need the result in a column vector instead.
|
2019-02-03 17:56:30 +08:00
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, RowVector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
2019-02-03 18:06:06 +08:00
|
|
|
/// assert_eq!(m.row_variance(), RowVector3::new(2.25, 2.25, 2.25));
|
2019-02-03 17:56:30 +08:00
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn row_variance(&self) -> RowOVector<T, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
|
|
|
DefaultAllocator: Allocator<T, U1, C>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_rows(|col| col.variance())
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The variance of all the rows of this matrix. The result is transposed and returned as a column vector.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
2019-02-03 18:06:06 +08:00
|
|
|
/// assert_eq!(m.row_variance_tr(), Vector3::new(2.25, 2.25, 2.25));
|
2019-02-03 17:56:30 +08:00
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn row_variance_tr(&self) -> OVector<T, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
|
|
|
DefaultAllocator: Allocator<T, C>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_rows_tr(|col| col.variance())
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The variance of all the columns of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # #[macro_use] extern crate approx;
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector2};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_relative_eq!(m.column_variance(), Vector2::new(2.0 / 3.0, 2.0 / 3.0), epsilon = 1.0e-8);
|
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn column_variance(&self) -> OVector<T, R>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
|
|
|
DefaultAllocator: Allocator<T, R>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2021-08-03 00:41:46 +08:00
|
|
|
let (nrows, ncols) = self.shape_generic();
|
2018-12-09 18:21:15 +08:00
|
|
|
|
|
|
|
let mut mean = self.column_mean();
|
2021-08-04 23:34:25 +08:00
|
|
|
mean.apply(|e| *e = -(e.clone() * e.clone()));
|
2018-12-09 18:21:15 +08:00
|
|
|
|
2021-04-11 17:00:38 +08:00
|
|
|
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_columns(mean, |out, col| {
|
|
|
|
for i in 0..nrows.value() {
|
|
|
|
unsafe {
|
|
|
|
let val = col.vget_unchecked(i);
|
2021-08-04 23:34:25 +08:00
|
|
|
*out.vget_unchecked_mut(i) += denom.clone() * val.clone() * val.clone()
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Mean computation.
|
|
|
|
*
|
|
|
|
*/
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The mean of all the elements of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::Matrix2x3;
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.mean(), 3.5);
|
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn mean(&self) -> T
|
2020-11-15 23:57:49 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
2020-11-15 23:57:49 +08:00
|
|
|
{
|
2020-11-16 19:11:24 +08:00
|
|
|
if self.is_empty() {
|
2021-04-11 17:00:38 +08:00
|
|
|
T::zero()
|
2018-12-09 18:21:15 +08:00
|
|
|
} else {
|
2019-03-23 21:29:07 +08:00
|
|
|
self.sum() / crate::convert(self.len() as f64)
|
2018-12-09 18:21:15 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The mean of all the rows of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
2019-02-03 18:06:06 +08:00
|
|
|
/// Use `.row_mean_tr` if you need the result in a column vector instead.
|
|
|
|
///
|
2019-02-03 17:56:30 +08:00
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, RowVector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.row_mean(), RowVector3::new(2.5, 3.5, 4.5));
|
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn row_mean(&self) -> RowOVector<T, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
|
|
|
DefaultAllocator: Allocator<T, U1, C>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_rows(|col| col.mean())
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The mean of all the rows of this matrix. The result is transposed and returned as a column vector.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.row_mean_tr(), Vector3::new(2.5, 3.5, 4.5));
|
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn row_mean_tr(&self) -> OVector<T, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
|
|
|
DefaultAllocator: Allocator<T, C>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2018-12-09 18:21:15 +08:00
|
|
|
self.compress_rows_tr(|col| col.mean())
|
|
|
|
}
|
|
|
|
|
2019-02-03 15:33:07 +08:00
|
|
|
/// The mean of all the columns of this matrix.
|
2019-02-03 17:56:30 +08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector2};
|
|
|
|
///
|
|
|
|
/// let m = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
|
|
/// 4.0, 5.0, 6.0);
|
|
|
|
/// assert_eq!(m.column_mean(), Vector2::new(2.0, 5.0));
|
|
|
|
/// ```
|
2018-12-09 18:21:15 +08:00
|
|
|
#[inline]
|
2021-06-07 22:34:03 +08:00
|
|
|
#[must_use]
|
2021-04-11 17:00:38 +08:00
|
|
|
pub fn column_mean(&self) -> OVector<T, R>
|
2020-04-06 00:49:48 +08:00
|
|
|
where
|
2021-04-11 17:00:38 +08:00
|
|
|
T: Field + SupersetOf<f64>,
|
|
|
|
DefaultAllocator: Allocator<T, R>,
|
2020-04-06 00:49:48 +08:00
|
|
|
{
|
2021-08-03 00:41:46 +08:00
|
|
|
let (nrows, ncols) = self.shape_generic();
|
2021-04-11 17:00:38 +08:00
|
|
|
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
|
|
|
|
self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
|
2021-08-04 23:34:25 +08:00
|
|
|
out.axpy(denom.clone(), &col, T::one())
|
2018-12-09 18:21:15 +08:00
|
|
|
})
|
|
|
|
}
|
2019-02-03 17:56:30 +08:00
|
|
|
}
|