//! Matrix with dimensions unknown at compile-time. use std::cmp; use std::mem; use std::iter::repeat; use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, Index, IndexMut}; use std::fmt::{Debug, Formatter, Result}; use rand::{self, Rand}; use num::{Zero, One}; use structs::dvector::{DVector, DVector1, DVector2, DVector3, DVector4, DVector5, DVector6}; use traits::operations::{ApproxEq, Inverse, Transpose, Mean, Covariance}; use traits::structure::{Cast, Column, ColumnSlice, Row, RowSlice, Diagonal, DiagonalMut, Eye, Indexable, Shape, BaseNum}; #[cfg(feature="arbitrary")] use quickcheck::{Arbitrary, Gen}; /// Matrix with dimensions unknown at compile-time. #[derive(Eq, PartialEq, Clone)] pub struct DMatrix { nrows: usize, ncols: usize, mij: Vec } impl DMatrix { /// Creates an uninitialized matrix. #[inline] pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMatrix { let mut vector = Vec::with_capacity(nrows * ncols); vector.set_len(nrows * ncols); DMatrix { nrows: nrows, ncols: ncols, mij: vector } } } impl DMatrix { /// Builds a matrix filled with a given constant. #[inline] pub fn from_element(nrows: usize, ncols: usize, val: N) -> DMatrix { DMatrix { nrows: nrows, ncols: ncols, mij: repeat(val).take(nrows * ncols).collect() } } /// Builds a matrix filled with the components provided by a vector. /// The vector contains the matrix data in row-major order. /// Note that `from_column_vector` is much faster than `from_row_vector` since a `DMatrix` stores its data /// in column-major order. /// /// The vector must have exactly `nrows * ncols` elements. #[inline] pub fn from_row_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix { DMatrix::from_row_iter(nrows, ncols, vector.to_vec()) } /// Builds a matrix filled with the components provided by a vector. /// The vector contains the matrix data in column-major order. /// Note that `from_column_vector` is much faster than `from_row_vector` since a `DMatrix` stores its data /// in column-major order. /// /// The vector must have exactly `nrows * ncols` elements. #[inline] pub fn from_column_vector(nrows: usize, ncols: usize, vector: &[N]) -> DMatrix { DMatrix::from_column_iter(nrows, ncols, vector.to_vec()) } /// Builds a matrix filled with the components provided by a source that may be moved into an iterator. /// The source contains the matrix data in row-major order. /// Note that `from_column_iter` is much faster than `from_row_iter` since a `DMatrix` stores its data /// in column-major order. /// /// The source must have exactly `nrows * ncols` elements. #[inline] pub fn from_row_iter>(nrows: usize, ncols: usize, param: I) -> DMatrix { let mut res = DMatrix::from_column_iter(ncols, nrows, param); // we transpose because the buffer is row_major res.transpose_mut(); res } /// Builds a matrix filled with the components provided by a source that may be moved into an iterator. /// The source contains the matrix data in column-major order. /// Note that `from_column_iter` is much faster than `from_row_iter` since a `DMatrix` stores its data /// in column-major order. /// /// The source must have exactly `nrows * ncols` elements. #[inline] pub fn from_column_iter>(nrows: usize, ncols: usize, param: I) -> DMatrix { let mij: Vec = param.into_iter().collect(); assert!(nrows * ncols == mij.len(), "The ammount of data provided does not matches the matrix size."); DMatrix { nrows: nrows, ncols: ncols, mij: mij } } } impl DMatrix { /// Builds a matrix filled with the results of a function applied to each of its component coordinates. #[inline] pub fn from_fn N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix { DMatrix { nrows: nrows, ncols: ncols, mij: (0 .. nrows * ncols).map(|i| { let m = i / nrows; f(i - m * nrows, m) }).collect() } } /// Transforms this matrix into an array. This consumes the matrix and is O(1). /// The returned vector contains the matrix data in column-major order. #[inline] pub fn into_vector(self) -> Vec { self.mij } } dmat_impl!(DMatrix, DVector); /// A stack-allocated dynamically sized matrix with at most one row and column. pub struct DMatrix1 { nrows: usize, ncols: usize, mij: [N; 1], } small_dmat_impl!(DMatrix1, DVector1, 1, 0); small_dmat_from_impl!(DMatrix1, 1, ::zero()); /// A stack-allocated dynamically sized square or rectangular matrix with at most 2 rows and columns. pub struct DMatrix2 { nrows: usize, ncols: usize, mij: [N; 2 * 2], } small_dmat_impl!(DMatrix2, DVector2, 2, 0, 1, 2, 3); small_dmat_from_impl!(DMatrix2, 2, ::zero(), ::zero(), ::zero(), ::zero()); /// A stack-allocated dynamically sized square or rectangular matrix with at most 3 rows and columns. pub struct DMatrix3 { nrows: usize, ncols: usize, mij: [N; 3 * 3], } small_dmat_impl!(DMatrix3, DVector3, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8); small_dmat_from_impl!(DMatrix3, 3, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero()); /// A stack-allocated dynamically sized square or rectangular matrix with at most 4 rows and columns. pub struct DMatrix4 { nrows: usize, ncols: usize, mij: [N; 4 * 4], } small_dmat_impl!(DMatrix4, DVector4, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); small_dmat_from_impl!(DMatrix4, 4, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero()); /// A stack-allocated dynamically sized square or rectangular matrix with at most 5 rows and columns. pub struct DMatrix5 { nrows: usize, ncols: usize, mij: [N; 5 * 5], } small_dmat_impl!(DMatrix5, DVector5, 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!(DMatrix5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero()); /// A stack-allocated dynamically sized square or rectangular matrix with at most 6 rows and columns. pub struct DMatrix6 { nrows: usize, ncols: usize, mij: [N; 6 * 6], } small_dmat_impl!(DMatrix6, DVector6, 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!(DMatrix6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());