nalgebra/src/structs/dmatrix.rs
Sébastien Crozet 88a74ca4e5 Macro groupping.
2016-08-11 23:28:08 +02:00

227 lines
8.4 KiB
Rust

//! 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<N> {
nrows: usize,
ncols: usize,
mij: Vec<N>
}
impl<N> DMatrix<N> {
/// Creates an uninitialized matrix.
#[inline]
pub unsafe fn new_uninitialized(nrows: usize, ncols: usize) -> DMatrix<N> {
let mut vector = Vec::with_capacity(nrows * ncols);
vector.set_len(nrows * ncols);
DMatrix {
nrows: nrows,
ncols: ncols,
mij: vector
}
}
}
impl<N: Clone + Copy> DMatrix<N> {
/// Builds a matrix filled with a given constant.
#[inline]
pub fn from_element(nrows: usize, ncols: usize, val: N) -> DMatrix<N> {
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<N> {
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<N> {
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<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
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<I: IntoIterator<Item = N>>(nrows: usize, ncols: usize, param: I) -> DMatrix<N> {
let mij: Vec<N> = 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<N> DMatrix<N> {
/// Builds a matrix filled with the results of a function applied to each of its component coordinates.
#[inline]
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix<N> {
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<N> {
self.mij
}
}
dmat_impl!(DMatrix, DVector);
/// A stack-allocated dynamically sized matrix with at most one row and column.
pub struct DMatrix1<N> {
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<N> {
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<N> {
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<N> {
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<N> {
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<N> {
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());