2020-11-19 23:18:42 +08:00
|
|
|
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
|
|
|
|
use alloc::vec::Vec;
|
|
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[cfg(feature = "arbitrary")]
|
2019-03-23 21:29:07 +08:00
|
|
|
|
use crate::base::storage::Owned;
|
2018-05-17 21:03:31 +08:00
|
|
|
|
#[cfg(feature = "arbitrary")]
|
|
|
|
|
use quickcheck::{Arbitrary, Gen};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2018-02-02 19:26:35 +08:00
|
|
|
|
use num::{Bounded, One, Zero};
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand-no-std")]
|
|
|
|
|
use rand::{
|
|
|
|
|
distributions::{Distribution, Standard},
|
|
|
|
|
Rng,
|
|
|
|
|
};
|
|
|
|
|
|
2018-05-17 21:03:31 +08:00
|
|
|
|
use std::iter;
|
2020-11-27 12:25:36 +08:00
|
|
|
|
use std::mem;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
use typenum::{self, Cmp, Greater};
|
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
use simba::scalar::{ClosedAdd, ClosedMul};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2019-03-23 21:29:07 +08:00
|
|
|
|
use crate::base::allocator::Allocator;
|
|
|
|
|
use crate::base::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6};
|
|
|
|
|
use crate::base::storage::Storage;
|
|
|
|
|
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-28 04:58:48 +08:00
|
|
|
|
/// When "no_unsound_assume_init" is enabled, expands to `unimplemented!()` instead of `new_uninitialized_generic().assume_init()`.
|
|
|
|
|
/// Intended as a placeholder, each callsite should be refactored to use uninitialized memory soundly
|
2020-11-27 12:25:36 +08:00
|
|
|
|
#[macro_export]
|
2020-11-28 04:58:48 +08:00
|
|
|
|
macro_rules! unimplemented_or_uninitialized_generic {
|
2020-11-27 12:25:36 +08:00
|
|
|
|
($nrows:expr, $ncols:expr) => {{
|
2020-11-28 04:58:48 +08:00
|
|
|
|
#[cfg(feature="no_unsound_assume_init")] {
|
|
|
|
|
// Some of the call sites need the number of rows and columns from this to infer a type, so
|
|
|
|
|
// uninitialized memory is used to infer the type, as `N: Zero` isn't available at all callsites.
|
|
|
|
|
// This may technically still be UB even though the assume_init is dead code, but all callsites should be fixed before #556 is closed.
|
|
|
|
|
let typeinference_helper = crate::base::Matrix::new_uninitialized_generic($nrows, $ncols);
|
|
|
|
|
unimplemented!();
|
|
|
|
|
typeinference_helper.assume_init()
|
|
|
|
|
}
|
2020-11-27 12:25:36 +08:00
|
|
|
|
#[cfg(not(feature="no_unsound_assume_init"))] { crate::base::Matrix::new_uninitialized_generic($nrows, $ncols).assume_init() }
|
|
|
|
|
}}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// # Generic constructors
|
|
|
|
|
/// This set of matrix and vector construction functions are all generic
|
|
|
|
|
/// with-regard to the matrix dimensions. They all expect to be given
|
|
|
|
|
/// the dimension as inputs.
|
|
|
|
|
///
|
|
|
|
|
/// These functions should only be used when working on dimension-generic code.
|
2019-12-17 07:09:14 +08:00
|
|
|
|
impl<N: Scalar, R: Dim, C: Dim> MatrixMN<N, R, C>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, R, C>,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
/// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics
|
|
|
|
|
/// if `nrows != R::to_usize()` or `ncols != C::to_usize()`.
|
|
|
|
|
#[inline]
|
2020-11-27 12:25:36 +08:00
|
|
|
|
pub unsafe fn new_uninitialized_generic(nrows: R, ncols: C) -> mem::MaybeUninit<Self> {
|
|
|
|
|
Self::from_uninitialized_data(DefaultAllocator::allocate_uninitialized(nrows, ncols))
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix with all its elements set to `elem`.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_element_generic(nrows: R, ncols: C, elem: N) -> Self {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let len = nrows.value() * ncols.value();
|
2017-08-03 01:37:44 +08:00
|
|
|
|
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 19:26:16 +08:00
|
|
|
|
/// Creates a matrix with all its elements set to `elem`.
|
2018-02-02 19:26:35 +08:00
|
|
|
|
///
|
2018-02-02 19:26:16 +08:00
|
|
|
|
/// Same as `from_element_generic`.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn repeat_generic(nrows: R, ncols: C, elem: N) -> Self {
|
|
|
|
|
let len = nrows.value() * ncols.value();
|
|
|
|
|
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
/// Creates a matrix with all its elements set to 0.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn zeros_generic(nrows: R, ncols: C) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
N: Zero,
|
|
|
|
|
{
|
2017-08-03 01:37:44 +08:00
|
|
|
|
Self::from_element_generic(nrows, ncols, N::zero())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix with all its elements filled by an iterator.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
I: IntoIterator<Item = N>,
|
|
|
|
|
{
|
2017-08-03 01:37:44 +08:00
|
|
|
|
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix with its elements filled with the components provided by a slice in
|
|
|
|
|
/// row-major order.
|
|
|
|
|
///
|
|
|
|
|
/// The order of elements in the slice must follow the usual mathematic writing, i.e.,
|
|
|
|
|
/// row-by-row.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Self {
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
slice.len() == nrows.value() * ncols.value(),
|
|
|
|
|
"Matrix init. error: the slice did not contain the right number of elements."
|
|
|
|
|
);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-28 04:58:48 +08:00
|
|
|
|
let mut res = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let mut iter = slice.iter();
|
|
|
|
|
|
2018-02-02 19:26:35 +08:00
|
|
|
|
for i in 0..nrows.value() {
|
|
|
|
|
for j in 0..ncols.value() {
|
2019-12-06 06:54:17 +08:00
|
|
|
|
unsafe { *res.get_unchecked_mut((i, j)) = iter.next().unwrap().inlined_clone() }
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix with its elements filled with the components provided by a slice. The
|
2018-07-07 23:37:15 +08:00
|
|
|
|
/// components must have the same layout as the matrix data storage (i.e. column-major).
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Self {
|
|
|
|
|
Self::from_iterator_generic(nrows, ncols, slice.iter().cloned())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix filled with the results of a function applied to each of its component
|
|
|
|
|
/// coordinates.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
F: FnMut(usize, usize) -> N,
|
|
|
|
|
{
|
2020-11-28 04:58:48 +08:00
|
|
|
|
let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2018-06-16 18:57:57 +08:00
|
|
|
|
for j in 0..ncols.value() {
|
|
|
|
|
for i in 0..nrows.value() {
|
2018-12-03 04:00:08 +08:00
|
|
|
|
unsafe { *res.get_unchecked_mut((i, j)) = f(i, j) }
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-04 17:22:24 +08:00
|
|
|
|
/// Creates a new identity matrix.
|
2016-12-05 05:44:42 +08:00
|
|
|
|
///
|
|
|
|
|
/// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
|
|
|
|
|
/// to the identity matrix. All other entries are set to zero.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn identity_generic(nrows: R, ncols: C) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
N: Zero + One,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
Self::from_diagonal_element_generic(nrows, ncols, N::one())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a new matrix with its diagonal filled with copies of `elt`.
|
|
|
|
|
///
|
|
|
|
|
/// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
|
|
|
|
|
/// to the identity matrix. All other entries are set to zero.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: N) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
N: Zero + One,
|
|
|
|
|
{
|
2017-08-03 01:37:44 +08:00
|
|
|
|
let mut res = Self::zeros_generic(nrows, ncols);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2019-03-23 21:29:07 +08:00
|
|
|
|
for i in 0..crate::min(nrows.value(), ncols.value()) {
|
2019-12-06 06:54:17 +08:00
|
|
|
|
unsafe { *res.get_unchecked_mut((i, i)) = elt.inlined_clone() }
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
/// Creates a new matrix that may be rectangular. The first `elts.len()` diagonal elements are
|
|
|
|
|
/// filled with the content of `elts`. Others are set to 0.
|
|
|
|
|
///
|
|
|
|
|
/// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[N]) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
N: Zero,
|
|
|
|
|
{
|
2017-08-03 01:37:44 +08:00
|
|
|
|
let mut res = Self::zeros_generic(nrows, ncols);
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
2019-03-23 21:29:07 +08:00
|
|
|
|
elts.len() <= crate::min(nrows.value(), ncols.value()),
|
2018-02-02 19:26:35 +08:00
|
|
|
|
"Too many diagonal elements provided."
|
|
|
|
|
);
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
|
|
|
|
for (i, elt) in elts.iter().enumerate() {
|
2019-12-06 06:54:17 +08:00
|
|
|
|
unsafe { *res.get_unchecked_mut((i, i)) = elt.inlined_clone() }
|
2017-08-03 01:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-13 01:17:09 +08:00
|
|
|
|
/// Builds a new matrix from its rows.
|
|
|
|
|
///
|
|
|
|
|
/// Panics if not enough rows are provided (for statically-sized matrices), or if all rows do
|
|
|
|
|
/// not have the same dimensions.
|
2018-10-20 17:36:52 +08:00
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{RowVector3, Matrix3};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix3::from_rows(&[ RowVector3::new(1.0, 2.0, 3.0), RowVector3::new(4.0, 5.0, 6.0), RowVector3::new(7.0, 8.0, 9.0) ]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 1.0 && m.m12 == 2.0 && m.m13 == 3.0 &&
|
|
|
|
|
/// m.m21 == 4.0 && m.m22 == 5.0 && m.m23 == 6.0 &&
|
|
|
|
|
/// m.m31 == 7.0 && m.m32 == 8.0 && m.m33 == 9.0);
|
|
|
|
|
/// ```
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_rows<SB>(rows: &[Matrix<N, U1, C, SB>]) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
SB: Storage<N, U1, C>,
|
|
|
|
|
{
|
2020-11-16 19:11:24 +08:00
|
|
|
|
assert!(!rows.is_empty(), "At least one row must be given.");
|
2020-10-26 21:07:52 +08:00
|
|
|
|
let nrows = R::try_to_usize().unwrap_or_else(|| rows.len());
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let ncols = rows[0].len();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
rows.len() == nrows,
|
|
|
|
|
"Invalid number of rows provided to build this matrix."
|
|
|
|
|
);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
if C::try_to_usize().is_none() {
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
rows.iter().all(|r| r.len() == ncols),
|
|
|
|
|
"The provided rows must all have the same dimension."
|
|
|
|
|
);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: optimize that.
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
|
2019-12-06 06:54:17 +08:00
|
|
|
|
rows[i][(0, j)].inlined_clone()
|
2018-02-02 19:26:35 +08:00
|
|
|
|
})
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-13 01:17:09 +08:00
|
|
|
|
/// Builds a new matrix from its columns.
|
|
|
|
|
///
|
|
|
|
|
/// Panics if not enough columns are provided (for statically-sized matrices), or if all
|
|
|
|
|
/// columns do not have the same dimensions.
|
2018-10-20 17:36:52 +08:00
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Vector3, Matrix3};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix3::from_columns(&[ Vector3::new(1.0, 2.0, 3.0), Vector3::new(4.0, 5.0, 6.0), Vector3::new(7.0, 8.0, 9.0) ]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 1.0 && m.m12 == 4.0 && m.m13 == 7.0 &&
|
|
|
|
|
/// m.m21 == 2.0 && m.m22 == 5.0 && m.m23 == 8.0 &&
|
|
|
|
|
/// m.m31 == 3.0 && m.m32 == 6.0 && m.m33 == 9.0);
|
|
|
|
|
/// ```
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_columns<SB>(columns: &[Vector<N, R, SB>]) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
SB: Storage<N, R>,
|
|
|
|
|
{
|
2020-11-16 19:11:24 +08:00
|
|
|
|
assert!(!columns.is_empty(), "At least one column must be given.");
|
2020-11-16 22:17:10 +08:00
|
|
|
|
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let nrows = columns[0].len();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
columns.len() == ncols,
|
|
|
|
|
"Invalid number of columns provided to build this matrix."
|
|
|
|
|
);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
if R::try_to_usize().is_none() {
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
columns.iter().all(|r| r.len() == nrows),
|
|
|
|
|
"The columns provided must all have the same dimension."
|
|
|
|
|
);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: optimize that.
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
|
2019-12-06 06:54:17 +08:00
|
|
|
|
columns[j][i].inlined_clone()
|
2018-02-02 19:26:35 +08:00
|
|
|
|
})
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix filled with random values.
|
|
|
|
|
#[inline]
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand")]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn new_random_generic(nrows: R, ncols: C) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
Standard: Distribution<N>,
|
|
|
|
|
{
|
2021-04-10 14:13:46 +08:00
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
Self::from_fn_generic(nrows, ncols, |_, _| rng.gen())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
2018-05-17 21:03:31 +08:00
|
|
|
|
|
|
|
|
|
/// Creates a matrix filled with random values from the given distribution.
|
|
|
|
|
#[inline]
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand-no-std")]
|
2018-05-23 05:58:14 +08:00
|
|
|
|
pub fn from_distribution_generic<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
|
2018-05-17 21:03:31 +08:00
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
2018-11-07 02:24:20 +08:00
|
|
|
|
distribution: &Distr,
|
2018-05-17 21:03:31 +08:00
|
|
|
|
rng: &mut G,
|
2020-04-06 00:49:48 +08:00
|
|
|
|
) -> Self {
|
2018-05-17 21:03:31 +08:00
|
|
|
|
Self::from_fn_generic(nrows, ncols, |_, _| distribution.sample(rng))
|
|
|
|
|
}
|
2018-11-07 08:46:28 +08:00
|
|
|
|
|
2018-11-08 07:33:17 +08:00
|
|
|
|
/// Creates a matrix backed by a given `Vec`.
|
|
|
|
|
///
|
|
|
|
|
/// The output matrix is filled column-by-column.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Dynamic, DMatrix, Matrix, U1};
|
|
|
|
|
///
|
|
|
|
|
/// let vec = vec![0, 1, 2, 3, 4, 5];
|
|
|
|
|
/// let vec_ptr = vec.as_ptr();
|
|
|
|
|
///
|
|
|
|
|
/// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), U1, vec);
|
2019-02-03 18:47:23 +08:00
|
|
|
|
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
|
2018-11-08 07:33:17 +08:00
|
|
|
|
///
|
|
|
|
|
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
|
|
|
|
|
/// assert_eq!(matrix_storage_ptr, vec_ptr);
|
|
|
|
|
/// ```
|
2018-11-07 08:46:28 +08:00
|
|
|
|
#[inline]
|
2020-11-19 23:18:42 +08:00
|
|
|
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
2018-11-08 07:03:12 +08:00
|
|
|
|
pub fn from_vec_generic(nrows: R, ncols: C, data: Vec<N>) -> Self {
|
2018-11-07 08:46:28 +08:00
|
|
|
|
Self::from_iterator_generic(nrows, ncols, data)
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N, D: Dim> MatrixN<N, D>
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
2019-12-17 07:09:14 +08:00
|
|
|
|
N: Scalar,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, D, D>,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
/// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
|
2018-10-20 17:36:52 +08:00
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Vector3, DVector, Matrix3, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix3::from_diagonal(&Vector3::new(1.0, 2.0, 3.0));
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
2018-12-09 19:22:10 +08:00
|
|
|
|
/// let dm = DMatrix::from_diagonal(&DVector::from_row_slice(&[1.0, 2.0, 3.0]));
|
2018-10-20 17:36:52 +08:00
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 1.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
|
|
|
|
|
/// m.m21 == 0.0 && m.m22 == 2.0 && m.m23 == 0.0 &&
|
|
|
|
|
/// m.m31 == 0.0 && m.m32 == 0.0 && m.m33 == 3.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 1.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 3.0);
|
|
|
|
|
/// ```
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn from_diagonal<SB: Storage<N, D>>(diag: &Vector<N, D, SB>) -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
N: Zero,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
let (dim, _) = diag.data.shape();
|
2017-08-03 01:37:44 +08:00
|
|
|
|
let mut res = Self::zeros_generic(dim, dim);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2018-02-02 19:26:35 +08:00
|
|
|
|
for i in 0..diag.len() {
|
|
|
|
|
unsafe {
|
2019-12-06 06:54:17 +08:00
|
|
|
|
*res.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).inlined_clone();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Generate constructors with varying number of arguments, depending on the object type.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
macro_rules! impl_constructors(
|
|
|
|
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a new uninitialized matrix or vector.
|
|
|
|
|
#[inline]
|
2020-11-27 12:25:36 +08:00
|
|
|
|
pub unsafe fn new_uninitialized($($args: usize),*) -> mem::MaybeUninit<Self> {
|
2020-11-14 01:34:47 +08:00
|
|
|
|
Self::new_uninitialized_generic($($gargs),*)
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix or vector with all its elements set to `elem`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::from_element(2.0);
|
|
|
|
|
/// // The additional argument represents the vector dimension.
|
|
|
|
|
/// let dv = DVector::from_element(3, 2.0);
|
|
|
|
|
/// let m = Matrix2x3::from_element(2.0);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_element(2, 3, 2.0);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 2.0 && v.y == 2.0 && v.z == 2.0);
|
|
|
|
|
/// assert!(dv[0] == 2.0 && dv[1] == 2.0 && dv[2] == 2.0);
|
|
|
|
|
/// assert!(m.m11 == 2.0 && m.m12 == 2.0 && m.m13 == 2.0 &&
|
|
|
|
|
/// m.m21 == 2.0 && m.m22 == 2.0 && m.m23 == 2.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 2.0 && dm[(0, 1)] == 2.0 && dm[(0, 2)] == 2.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_element($($args: usize,)* elem: N) -> Self {
|
|
|
|
|
Self::from_element_generic($($gargs, )* elem)
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix or vector with all its elements set to `elem`.
|
|
|
|
|
///
|
|
|
|
|
/// Same as `.from_element`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::repeat(2.0);
|
|
|
|
|
/// // The additional argument represents the vector dimension.
|
|
|
|
|
/// let dv = DVector::repeat(3, 2.0);
|
|
|
|
|
/// let m = Matrix2x3::repeat(2.0);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::repeat(2, 3, 2.0);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 2.0 && v.y == 2.0 && v.z == 2.0);
|
|
|
|
|
/// assert!(dv[0] == 2.0 && dv[1] == 2.0 && dv[2] == 2.0);
|
|
|
|
|
/// assert!(m.m11 == 2.0 && m.m12 == 2.0 && m.m13 == 2.0 &&
|
|
|
|
|
/// m.m21 == 2.0 && m.m22 == 2.0 && m.m23 == 2.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 2.0 && dm[(0, 1)] == 2.0 && dm[(0, 2)] == 2.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn repeat($($args: usize,)* elem: N) -> Self {
|
|
|
|
|
Self::repeat_generic($($gargs, )* elem)
|
|
|
|
|
}
|
2018-02-02 19:26:16 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix or vector with all its elements set to `0`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::<f32>::zeros();
|
|
|
|
|
/// // The argument represents the vector dimension.
|
|
|
|
|
/// let dv = DVector::<f32>::zeros(3);
|
|
|
|
|
/// let m = Matrix2x3::<f32>::zeros();
|
|
|
|
|
/// // The two arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::<f32>::zeros(2, 3);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 0.0 && v.y == 0.0 && v.z == 0.0);
|
|
|
|
|
/// assert!(dv[0] == 0.0 && dv[1] == 0.0 && dv[2] == 0.0);
|
|
|
|
|
/// assert!(m.m11 == 0.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
|
|
|
|
|
/// m.m21 == 0.0 && m.m22 == 0.0 && m.m23 == 0.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 0.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 0.0 && dm[(1, 2)] == 0.0);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn zeros($($args: usize),*) -> Self
|
|
|
|
|
where N: Zero {
|
|
|
|
|
Self::zeros_generic($($gargs),*)
|
|
|
|
|
}
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix or vector with all its elements filled by an iterator.
|
|
|
|
|
///
|
|
|
|
|
/// The output matrix is filled column-by-column.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::from_iterator((0..3).into_iter());
|
|
|
|
|
/// // The additional argument represents the vector dimension.
|
|
|
|
|
/// let dv = DVector::from_iterator(3, (0..3).into_iter());
|
|
|
|
|
/// let m = Matrix2x3::from_iterator((0..6).into_iter());
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_iterator(2, 3, (0..6).into_iter());
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
|
|
|
|
|
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
|
|
|
|
|
/// assert!(m.m11 == 0 && m.m12 == 2 && m.m13 == 4 &&
|
|
|
|
|
/// m.m21 == 1 && m.m22 == 3 && m.m23 == 5);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 2 && dm[(0, 2)] == 4 &&
|
|
|
|
|
/// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_iterator<I>($($args: usize,)* iter: I) -> Self
|
|
|
|
|
where I: IntoIterator<Item = N> {
|
|
|
|
|
Self::from_iterator_generic($($gargs, )* iter)
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix or vector filled with the results of a function applied to each of its
|
|
|
|
|
/// component coordinates.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::from_fn(|i, _| i);
|
|
|
|
|
/// // The additional argument represents the vector dimension.
|
|
|
|
|
/// let dv = DVector::from_fn(3, |i, _| i);
|
|
|
|
|
/// let m = Matrix2x3::from_fn(|i, j| i * 3 + j);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_fn(2, 3, |i, j| i * 3 + j);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
|
|
|
|
|
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
|
|
|
|
|
/// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
|
|
|
|
|
/// m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
|
|
|
|
|
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_fn<F>($($args: usize,)* f: F) -> Self
|
|
|
|
|
where F: FnMut(usize, usize) -> N {
|
|
|
|
|
Self::from_fn_generic($($gargs, )* f)
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates an identity matrix. If the matrix is not square, the largest square
|
|
|
|
|
/// submatrix (starting at the first row and column) is set to the identity while all
|
|
|
|
|
/// other entries are set to zero.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix2x3::<f32>::identity();
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::<f32>::identity(2, 3);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 1.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
|
|
|
|
|
/// m.m21 == 0.0 && m.m22 == 1.0 && m.m23 == 0.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 1.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 1.0 && dm[(1, 2)] == 0.0);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn identity($($args: usize,)*) -> Self
|
|
|
|
|
where N: Zero + One {
|
|
|
|
|
Self::identity_generic($($gargs),* )
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix filled with its diagonal filled with `elt` and all other
|
|
|
|
|
/// components set to zero.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix2x3::from_diagonal_element(5.0);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_diagonal_element(2, 3, 5.0);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 5.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
|
|
|
|
|
/// m.m21 == 0.0 && m.m22 == 5.0 && m.m23 == 0.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 5.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_diagonal_element($($args: usize,)* elt: N) -> Self
|
|
|
|
|
where N: Zero + One {
|
|
|
|
|
Self::from_diagonal_element_generic($($gargs, )* elt)
|
|
|
|
|
}
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a new matrix that may be rectangular. The first `elts.len()` diagonal
|
|
|
|
|
/// elements are filled with the content of `elts`. Others are set to 0.
|
|
|
|
|
///
|
|
|
|
|
/// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix3, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix3::from_partial_diagonal(&[1.0, 2.0]);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_partial_diagonal(3, 3, &[1.0, 2.0]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 1.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
|
|
|
|
|
/// m.m21 == 0.0 && m.m22 == 2.0 && m.m23 == 0.0 &&
|
|
|
|
|
/// m.m31 == 0.0 && m.m32 == 0.0 && m.m33 == 0.0);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 1.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 0.0 &&
|
|
|
|
|
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 0.0);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_partial_diagonal($($args: usize,)* elts: &[N]) -> Self
|
|
|
|
|
where N: Zero {
|
|
|
|
|
Self::from_partial_diagonal_generic($($gargs, )* elts)
|
|
|
|
|
}
|
2018-05-17 21:03:31 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix or vector filled with random values from the given distribution.
|
|
|
|
|
#[inline]
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand-no-std")]
|
2020-11-14 01:34:47 +08:00
|
|
|
|
pub fn from_distribution<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
|
|
|
|
|
$($args: usize,)*
|
|
|
|
|
distribution: &Distr,
|
|
|
|
|
rng: &mut G,
|
|
|
|
|
) -> Self {
|
|
|
|
|
Self::from_distribution_generic($($gargs, )* distribution, rng)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// Creates a matrix filled with random values.
|
|
|
|
|
#[inline]
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand")]
|
2020-11-14 01:34:47 +08:00
|
|
|
|
pub fn new_random($($args: usize),*) -> Self
|
|
|
|
|
where Standard: Distribution<N> {
|
|
|
|
|
Self::new_random_generic($($gargs),*)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// # Constructors of statically-sized vectors or statically-sized matrices
|
|
|
|
|
impl<N: Scalar, R: DimName, C: DimName> MatrixMN<N, R, C>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, R, C>,
|
|
|
|
|
{
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: this is not very pretty. We could find a better call syntax.
|
2020-11-14 01:34:47 +08:00
|
|
|
|
impl_constructors!(R, C; // Arguments for Matrix<N, ..., S>
|
|
|
|
|
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
|
|
|
|
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
|
|
|
|
); // Arguments for non-generic constructors.
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// # Constructors of matrices with a dynamic number of columns
|
|
|
|
|
impl<N: Scalar, R: DimName> MatrixMN<N, R, Dynamic>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, R, Dynamic>,
|
|
|
|
|
{
|
|
|
|
|
impl_constructors!(R, Dynamic;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
=> R: DimName;
|
|
|
|
|
R::name(), Dynamic::new(ncols);
|
|
|
|
|
ncols);
|
2020-11-14 01:34:47 +08:00
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows
|
|
|
|
|
impl<N: Scalar, C: DimName> MatrixMN<N, Dynamic, C>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, Dynamic, C>,
|
|
|
|
|
{
|
|
|
|
|
impl_constructors!(Dynamic, C;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
=> C: DimName;
|
|
|
|
|
Dynamic::new(nrows), C::name();
|
|
|
|
|
nrows);
|
2020-11-14 01:34:47 +08:00
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-11-14 01:34:47 +08:00
|
|
|
|
/// # Constructors of fully dynamic matrices
|
|
|
|
|
impl<N: Scalar> MatrixMN<N, Dynamic, Dynamic>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, Dynamic, Dynamic>,
|
|
|
|
|
{
|
|
|
|
|
impl_constructors!(Dynamic, Dynamic;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
;
|
|
|
|
|
Dynamic::new(nrows), Dynamic::new(ncols);
|
|
|
|
|
nrows, ncols);
|
2020-11-14 01:34:47 +08:00
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2018-12-09 18:22:21 +08:00
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Constructors that don't necessarily require all dimensions
|
2020-11-14 01:34:47 +08:00
|
|
|
|
* to be specified when one dimension is already known.
|
2018-12-09 18:22:21 +08:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
macro_rules! impl_constructors_from_data(
|
|
|
|
|
($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
2019-12-17 07:09:14 +08:00
|
|
|
|
impl<N: Scalar, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*>
|
2018-12-09 18:22:21 +08:00
|
|
|
|
where DefaultAllocator: Allocator<N $(, $Dims)*> {
|
|
|
|
|
/// Creates a matrix with its elements filled with the components provided by a slice
|
|
|
|
|
/// in row-major order.
|
|
|
|
|
///
|
|
|
|
|
/// The order of elements in the slice must follow the usual mathematic writing, i.e.,
|
|
|
|
|
/// row-by-row.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::from_row_slice(&[0, 1, 2]);
|
|
|
|
|
/// // The additional argument represents the vector dimension.
|
2018-12-09 19:22:10 +08:00
|
|
|
|
/// let dv = DVector::from_row_slice(&[0, 1, 2]);
|
2018-12-09 18:22:21 +08:00
|
|
|
|
/// let m = Matrix2x3::from_row_slice(&[0, 1, 2, 3, 4, 5]);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_row_slice(2, 3, &[0, 1, 2, 3, 4, 5]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
|
|
|
|
|
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
|
|
|
|
|
/// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
|
|
|
|
|
/// m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
|
|
|
|
|
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_row_slice($($args: usize,)* $data: &[N]) -> Self {
|
|
|
|
|
Self::from_row_slice_generic($($gargs, )* $data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix with its elements filled with the components provided by a slice
|
|
|
|
|
/// in column-major order.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
|
|
|
|
/// # use std::iter;
|
|
|
|
|
///
|
|
|
|
|
/// let v = Vector3::from_column_slice(&[0, 1, 2]);
|
|
|
|
|
/// // The additional argument represents the vector dimension.
|
2018-12-09 19:22:10 +08:00
|
|
|
|
/// let dv = DVector::from_column_slice(&[0, 1, 2]);
|
2018-12-09 18:22:21 +08:00
|
|
|
|
/// let m = Matrix2x3::from_column_slice(&[0, 1, 2, 3, 4, 5]);
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_column_slice(2, 3, &[0, 1, 2, 3, 4, 5]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
|
|
|
|
|
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
|
|
|
|
|
/// assert!(m.m11 == 0 && m.m12 == 2 && m.m13 == 4 &&
|
|
|
|
|
/// m.m21 == 1 && m.m22 == 3 && m.m23 == 5);
|
|
|
|
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 2 && dm[(0, 2)] == 4 &&
|
|
|
|
|
/// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn from_column_slice($($args: usize,)* $data: &[N]) -> Self {
|
|
|
|
|
Self::from_column_slice_generic($($gargs, )* $data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a matrix backed by a given `Vec`.
|
|
|
|
|
///
|
|
|
|
|
/// The output matrix is filled column-by-column.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use nalgebra::{DMatrix, Matrix2x3};
|
|
|
|
|
///
|
|
|
|
|
/// let m = Matrix2x3::from_vec(vec![0, 1, 2, 3, 4, 5]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(m.m11 == 0 && m.m12 == 2 && m.m13 == 4 &&
|
|
|
|
|
/// m.m21 == 1 && m.m22 == 3 && m.m23 == 5);
|
|
|
|
|
///
|
|
|
|
|
///
|
|
|
|
|
/// // The two additional arguments represent the matrix dimensions.
|
|
|
|
|
/// let dm = DMatrix::from_vec(2, 3, vec![0, 1, 2, 3, 4, 5]);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 2 && dm[(0, 2)] == 4 &&
|
|
|
|
|
/// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
2020-11-19 23:18:42 +08:00
|
|
|
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
2018-12-09 18:22:21 +08:00
|
|
|
|
pub fn from_vec($($args: usize,)* $data: Vec<N>) -> Self {
|
|
|
|
|
Self::from_vec_generic($($gargs, )* $data)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: this is not very pretty. We could find a better call syntax.
|
2018-12-09 18:22:21 +08:00
|
|
|
|
impl_constructors_from_data!(data; R, C; // Arguments for Matrix<N, ..., S>
|
2020-03-21 19:16:46 +08:00
|
|
|
|
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
|
|
|
|
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
|
|
|
|
); // Arguments for non-generic constructors.
|
2018-12-09 18:22:21 +08:00
|
|
|
|
|
|
|
|
|
impl_constructors_from_data!(data; R, Dynamic;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
=> R: DimName;
|
|
|
|
|
R::name(), Dynamic::new(data.len() / R::dim());
|
|
|
|
|
);
|
2018-12-09 18:22:21 +08:00
|
|
|
|
|
|
|
|
|
impl_constructors_from_data!(data; Dynamic, C;
|
2020-03-21 19:16:46 +08:00
|
|
|
|
=> C: DimName;
|
|
|
|
|
Dynamic::new(data.len() / C::dim()), C::name();
|
|
|
|
|
);
|
2018-12-09 18:22:21 +08:00
|
|
|
|
|
|
|
|
|
impl_constructors_from_data!(data; Dynamic, Dynamic;
|
|
|
|
|
;
|
|
|
|
|
Dynamic::new(nrows), Dynamic::new(ncols);
|
|
|
|
|
nrows, ncols);
|
|
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Zero, One, Rand traits.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N, R: DimName, C: DimName> Zero for MatrixMN<N, R, C>
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
2019-12-17 07:09:14 +08:00
|
|
|
|
N: Scalar + Zero + ClosedAdd,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, R, C>,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn zero() -> Self {
|
|
|
|
|
Self::from_element(N::zero())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
|
self.iter().all(|e| e.is_zero())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N, D: DimName> One for MatrixN<N, D>
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
2019-12-17 07:09:14 +08:00
|
|
|
|
N: Scalar + Zero + One + ClosedMul + ClosedAdd,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, D, D>,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn one() -> Self {
|
|
|
|
|
Self::identity()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N, R: DimName, C: DimName> Bounded for MatrixMN<N, R, C>
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
2019-12-17 07:09:14 +08:00
|
|
|
|
N: Scalar + Bounded,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, R, C>,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn max_value() -> Self {
|
|
|
|
|
Self::from_element(N::max_value())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn min_value() -> Self {
|
|
|
|
|
Self::from_element(N::min_value())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand-no-std")]
|
2019-12-17 07:09:14 +08:00
|
|
|
|
impl<N: Scalar, R: Dim, C: Dim> Distribution<MatrixMN<N, R, C>> for Standard
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, R, C>,
|
2018-05-23 05:58:14 +08:00
|
|
|
|
Standard: Distribution<N>,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2018-05-23 05:58:14 +08:00
|
|
|
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> MatrixMN<N, R, C> {
|
2021-03-01 00:52:14 +08:00
|
|
|
|
let nrows = R::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
|
|
|
|
|
let ncols = C::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2018-05-23 05:58:14 +08:00
|
|
|
|
MatrixMN::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "arbitrary")]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N, R, C> Arbitrary for MatrixMN<N, R, C>
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
|
|
|
|
R: Dim,
|
|
|
|
|
C: Dim,
|
2019-12-17 07:09:14 +08:00
|
|
|
|
N: Scalar + Arbitrary + Send,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, R, C>,
|
|
|
|
|
Owned<N, R, C>: Clone + Send,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2021-03-01 00:52:14 +08:00
|
|
|
|
fn arbitrary(g: &mut Gen) -> Self {
|
|
|
|
|
let nrows = R::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
|
|
|
|
|
let ncols = C::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| {
|
|
|
|
|
N::arbitrary(g)
|
|
|
|
|
})
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-10 14:31:38 +08:00
|
|
|
|
// TODO(specialization): faster impls possible for D≤4 (see rand_distr::{UnitCircle, UnitSphere})
|
2021-03-02 19:25:12 +08:00
|
|
|
|
#[cfg(feature = "rand")]
|
|
|
|
|
impl<N: crate::RealField, D: DimName> Distribution<Unit<VectorN<N, D>>> for Standard
|
2018-07-04 10:06:03 +08:00
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<N, D>,
|
2021-03-02 19:25:12 +08:00
|
|
|
|
rand_distr::StandardNormal: Distribution<N>,
|
2018-07-04 10:06:03 +08:00
|
|
|
|
{
|
2018-07-08 07:03:08 +08:00
|
|
|
|
/// Generate a uniformly distributed random unit vector.
|
2018-07-04 10:06:03 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<VectorN<N, D>> {
|
2018-07-20 22:10:12 +08:00
|
|
|
|
Unit::new_normalize(VectorN::from_distribution_generic(
|
|
|
|
|
D::name(),
|
|
|
|
|
U1,
|
2021-03-02 19:25:12 +08:00
|
|
|
|
&rand_distr::StandardNormal,
|
2018-07-20 22:10:12 +08:00
|
|
|
|
rng,
|
|
|
|
|
))
|
2018-07-04 10:06:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Constructors for small matrices and vectors.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
macro_rules! componentwise_constructors_impl(
|
|
|
|
|
($($R: ty, $C: ty, $($args: ident:($irow: expr,$icol: expr)),*);* $(;)*) => {$(
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N> MatrixMN<N, $R, $C>
|
2019-12-17 07:09:14 +08:00
|
|
|
|
where N: Scalar,
|
2017-08-03 01:37:44 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, $R, $C> {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
/// Initializes this matrix from its components.
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
|
pub fn new($($args: N),*) -> Self {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
unsafe {
|
2020-11-27 12:25:36 +08:00
|
|
|
|
#[cfg(feature="no_unsound_assume_init")]
|
|
|
|
|
let mut res: Self = unimplemented!();
|
|
|
|
|
#[cfg(not(feature="no_unsound_assume_init"))]
|
|
|
|
|
let mut res = Self::new_uninitialized().assume_init();
|
2018-12-03 04:00:08 +08:00
|
|
|
|
$( *res.get_unchecked_mut(($irow, $icol)) = $args; )*
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)*}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
componentwise_constructors_impl!(
|
|
|
|
|
/*
|
|
|
|
|
* Square matrices 1 .. 6.
|
|
|
|
|
*/
|
|
|
|
|
U2, U2, m11:(0,0), m12:(0,1),
|
|
|
|
|
m21:(1,0), m22:(1,1);
|
|
|
|
|
U3, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2);
|
|
|
|
|
U4, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3);
|
|
|
|
|
U5, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4);
|
|
|
|
|
U6, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4), m46:(3,5),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4), m56:(4,5),
|
|
|
|
|
m61:(5,0), m62:(5,1), m63:(5,2), m64:(5,3), m65:(5,4), m66:(5,5);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rectangular matrices with 2 rows.
|
|
|
|
|
*/
|
|
|
|
|
U2, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2);
|
|
|
|
|
U2, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3);
|
|
|
|
|
U2, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4);
|
|
|
|
|
U2, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rectangular matrices with 3 rows.
|
|
|
|
|
*/
|
|
|
|
|
U3, U2, m11:(0,0), m12:(0,1),
|
|
|
|
|
m21:(1,0), m22:(1,1),
|
|
|
|
|
m31:(2,0), m32:(2,1);
|
|
|
|
|
U3, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3);
|
|
|
|
|
U3, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4);
|
|
|
|
|
U3, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rectangular matrices with 4 rows.
|
|
|
|
|
*/
|
|
|
|
|
U4, U2, m11:(0,0), m12:(0,1),
|
|
|
|
|
m21:(1,0), m22:(1,1),
|
|
|
|
|
m31:(2,0), m32:(2,1),
|
|
|
|
|
m41:(3,0), m42:(3,1);
|
|
|
|
|
U4, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2);
|
|
|
|
|
U4, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4);
|
|
|
|
|
U4, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4), m46:(3,5);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rectangular matrices with 5 rows.
|
|
|
|
|
*/
|
|
|
|
|
U5, U2, m11:(0,0), m12:(0,1),
|
|
|
|
|
m21:(1,0), m22:(1,1),
|
|
|
|
|
m31:(2,0), m32:(2,1),
|
|
|
|
|
m41:(3,0), m42:(3,1),
|
|
|
|
|
m51:(4,0), m52:(4,1);
|
|
|
|
|
U5, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2);
|
|
|
|
|
U5, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3);
|
|
|
|
|
U5, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4), m46:(3,5),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4), m56:(4,5);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Rectangular matrices with 6 rows.
|
|
|
|
|
*/
|
|
|
|
|
U6, U2, m11:(0,0), m12:(0,1),
|
|
|
|
|
m21:(1,0), m22:(1,1),
|
|
|
|
|
m31:(2,0), m32:(2,1),
|
|
|
|
|
m41:(3,0), m42:(3,1),
|
|
|
|
|
m51:(4,0), m52:(4,1),
|
|
|
|
|
m61:(5,0), m62:(5,1);
|
|
|
|
|
U6, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2),
|
|
|
|
|
m61:(5,0), m62:(5,1), m63:(5,2);
|
|
|
|
|
U6, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3),
|
|
|
|
|
m61:(5,0), m62:(5,1), m63:(5,2), m64:(5,3);
|
|
|
|
|
U6, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
|
|
|
|
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
|
|
|
|
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4),
|
|
|
|
|
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4),
|
|
|
|
|
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4),
|
|
|
|
|
m61:(5,0), m62:(5,1), m63:(5,2), m64:(5,3), m65:(5,4);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Row vectors 1 .. 6.
|
|
|
|
|
*/
|
|
|
|
|
U1, U1, x:(0,0);
|
|
|
|
|
U1, U2, x:(0,0), y:(0,1);
|
|
|
|
|
U1, U3, x:(0,0), y:(0,1), z:(0,2);
|
|
|
|
|
U1, U4, x:(0,0), y:(0,1), z:(0,2), w:(0,3);
|
|
|
|
|
U1, U5, x:(0,0), y:(0,1), z:(0,2), w:(0,3), a:(0,4);
|
|
|
|
|
U1, U6, x:(0,0), y:(0,1), z:(0,2), w:(0,3), a:(0,4), b:(0,5);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Column vectors 1 .. 6.
|
|
|
|
|
*/
|
|
|
|
|
U2, U1, x:(0,0), y:(1,0);
|
|
|
|
|
U3, U1, x:(0,0), y:(1,0), z:(2,0);
|
|
|
|
|
U4, U1, x:(0,0), y:(1,0), z:(2,0), w:(3,0);
|
|
|
|
|
U5, U1, x:(0,0), y:(1,0), z:(2,0), w:(3,0), a:(4,0);
|
|
|
|
|
U6, U1, x:(0,0), y:(1,0), z:(2,0), w:(3,0), a:(4,0), b:(5,0);
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Axis constructors.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2017-08-03 01:37:44 +08:00
|
|
|
|
impl<N, R: DimName> VectorN<N, R>
|
2018-02-02 19:26:35 +08:00
|
|
|
|
where
|
2019-12-17 07:09:14 +08:00
|
|
|
|
N: Scalar + Zero + One,
|
2018-02-02 19:26:35 +08:00
|
|
|
|
DefaultAllocator: Allocator<N, R>,
|
|
|
|
|
{
|
2020-06-13 16:06:48 +08:00
|
|
|
|
/// The column vector with `val` as its i-th component.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn ith(i: usize, val: N) -> Self {
|
|
|
|
|
let mut res = Self::zeros();
|
|
|
|
|
res[i] = val;
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-25 18:25:38 +08:00
|
|
|
|
/// The column unit vector with `N::one()` as its i-th component.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn ith_axis(i: usize) -> Unit<Self> {
|
|
|
|
|
Unit::new_unchecked(Self::ith(i, N::one()))
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
|
/// The column vector with a 1 as its first component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn x() -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U0, Output = Greater>,
|
|
|
|
|
{
|
2017-08-14 01:52:57 +08:00
|
|
|
|
let mut res = Self::zeros();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
*res.vget_unchecked_mut(0) = N::one();
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The column vector with a 1 as its second component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn y() -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U1, Output = Greater>,
|
|
|
|
|
{
|
2017-08-14 01:52:57 +08:00
|
|
|
|
let mut res = Self::zeros();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
*res.vget_unchecked_mut(1) = N::one();
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The column vector with a 1 as its third component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn z() -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U2, Output = Greater>,
|
|
|
|
|
{
|
2017-08-14 01:52:57 +08:00
|
|
|
|
let mut res = Self::zeros();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
*res.vget_unchecked_mut(2) = N::one();
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The column vector with a 1 as its fourth component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn w() -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U3, Output = Greater>,
|
|
|
|
|
{
|
2017-08-14 01:52:57 +08:00
|
|
|
|
let mut res = Self::zeros();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
*res.vget_unchecked_mut(3) = N::one();
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The column vector with a 1 as its fifth component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn a() -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U4, Output = Greater>,
|
|
|
|
|
{
|
2017-08-14 01:52:57 +08:00
|
|
|
|
let mut res = Self::zeros();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
*res.vget_unchecked_mut(4) = N::one();
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The column vector with a 1 as its sixth component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn b() -> Self
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U5, Output = Greater>,
|
|
|
|
|
{
|
2017-08-14 01:52:57 +08:00
|
|
|
|
let mut res = Self::zeros();
|
2018-02-02 19:26:35 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
*res.vget_unchecked_mut(5) = N::one();
|
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The unit column vector with a 1 as its first component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn x_axis() -> Unit<Self>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U0, Output = Greater>,
|
|
|
|
|
{
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Unit::new_unchecked(Self::x())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The unit column vector with a 1 as its second component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn y_axis() -> Unit<Self>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U1, Output = Greater>,
|
|
|
|
|
{
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Unit::new_unchecked(Self::y())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The unit column vector with a 1 as its third component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn z_axis() -> Unit<Self>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U2, Output = Greater>,
|
|
|
|
|
{
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Unit::new_unchecked(Self::z())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The unit column vector with a 1 as its fourth component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn w_axis() -> Unit<Self>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U3, Output = Greater>,
|
|
|
|
|
{
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Unit::new_unchecked(Self::w())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The unit column vector with a 1 as its fifth component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn a_axis() -> Unit<Self>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U4, Output = Greater>,
|
|
|
|
|
{
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Unit::new_unchecked(Self::a())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The unit column vector with a 1 as its sixth component, and zero elsewhere.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn b_axis() -> Unit<Self>
|
2020-04-06 00:49:48 +08:00
|
|
|
|
where
|
|
|
|
|
R::Value: Cmp<typenum::U5, Output = Greater>,
|
|
|
|
|
{
|
2018-02-02 19:26:35 +08:00
|
|
|
|
Unit::new_unchecked(Self::b())
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|