nalgebra/src/core/construction.rs
2017-02-12 18:17:09 +01:00

658 lines
24 KiB
Rust
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use std::iter;
use num::{Zero, One, Bounded};
use rand::{self, Rand, Rng};
use typenum::{self, Cmp, Greater};
use alga::general::{ClosedAdd, ClosedMul};
use core::{Scalar, Matrix, SquareMatrix, ColumnVector, Unit};
use core::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6};
use core::allocator::{Allocator, OwnedAllocator};
use core::storage::{Storage, OwnedStorage};
/*
*
* Generic constructors.
*
*/
impl<N: Scalar, R: Dim, C: Dim, S: OwnedStorage<N, R, C>> Matrix<N, R, C, S>
// XXX: needed because of a compiler bug. See the rust compiler issue #26026.
where S::Alloc: OwnedAllocator<N, R, C, S> {
/// 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]
pub unsafe fn new_uninitialized_generic(nrows: R, ncols: C) -> Matrix<N, R, C, S> {
Matrix::from_data(S::Alloc::allocate_uninitialized(nrows, ncols))
}
/// Creates a matrix with all its elements set to `elem`.
#[inline]
pub fn from_element_generic(nrows: R, ncols: C, elem: N) -> Matrix<N, R, C, S> {
let len = nrows.value() * ncols.value();
Matrix::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
}
/// Creates a matrix with all its elements filled by an iterator.
#[inline]
pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Matrix<N, R, C, S>
where I: IntoIterator<Item = N> {
Matrix::from_data(S::Alloc::allocate_from_iterator(nrows, ncols, iter))
}
/// 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]
pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Matrix<N, R, C, S> {
assert!(slice.len() == nrows.value() * ncols.value(),
"Matrix init. error: the slice did not contain the right number of elements.");
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) };
let mut iter = slice.iter();
for i in 0 .. nrows.value() {
for j in 0 .. ncols.value() {
unsafe {
*res.get_unchecked_mut(i, j) = *iter.next().unwrap()
}
}
}
res
}
/// Creates a matrix with its elements filled with the components provided by a slice. The
/// components must have the same layout as the matrix data storage (i.e. row-major or column-major).
#[inline]
pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Matrix<N, R, C, S> {
Matrix::from_iterator_generic(nrows, ncols, slice.iter().cloned())
}
/// Creates a matrix filled with the results of a function applied to each of its component
/// coordinates.
#[inline]
pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Matrix<N, R, C, S>
where F: FnMut(usize, usize) -> N {
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) };
for i in 0 .. nrows.value() {
for j in 0 .. ncols.value() {
unsafe { *res.get_unchecked_mut(i, j) = f(i, j) }
}
}
res
}
/// Creates a new indentity matrix.
///
/// 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]
pub fn identity_generic(nrows: R, ncols: C) -> Matrix<N, R, C, S>
where N: Zero + One {
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]
pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: N) -> Matrix<N, R, C, S>
where N: Zero + One {
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) };
res.fill(N::zero());
for i in 0 .. ::min(nrows.value(), ncols.value()) {
unsafe { *res.get_unchecked_mut(i, i) = elt }
}
res
}
/// 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.
#[inline]
pub fn from_rows<SB>(rows: &[Matrix<N, U1, C, SB>]) -> Matrix<N, R, C, S>
where SB: Storage<N, U1, C> {
assert!(rows.len() > 0, "At least one row must be given.");
let nrows = R::try_to_usize().unwrap_or(rows.len());
let ncols = rows[0].len();
assert!(rows.len() == nrows, "Invalid number of rows provided to build this matrix.");
if C::try_to_usize().is_none() {
assert!(rows.iter().all(|r| r.len() == ncols),
"The provided rows must all have the same dimension.");
}
// FIXME: optimize that.
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| rows[i][(0, j)])
}
/// 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.
#[inline]
pub fn from_columns<SB>(columns: &[ColumnVector<N, R, SB>]) -> Matrix<N, R, C, S>
where SB: Storage<N, R, U1> {
assert!(columns.len() > 0, "At least one column must be given.");
let ncols = C::try_to_usize().unwrap_or(columns.len());
let nrows = columns[0].len();
assert!(columns.len() == ncols, "Invalid number of columns provided to build this matrix.");
if R::try_to_usize().is_none() {
assert!(columns.iter().all(|r| r.len() == nrows),
"The columns provided must all have the same dimension.");
}
// FIXME: optimize that.
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| columns[j][i])
}
}
impl<N, R: Dim, C: Dim, S> Matrix<N, R, C, S>
where N: Scalar + Rand,
S: OwnedStorage<N, R, C>,
S::Alloc: OwnedAllocator<N, R, C, S> {
/// Creates a matrix filled with random values.
#[inline]
pub fn new_random_generic(nrows: R, ncols: C) -> Matrix<N, R, C, S> {
Matrix::from_fn_generic(nrows, ncols, |_, _| rand::random())
}
}
impl<N, D: Dim, S> SquareMatrix<N, D, S>
where N: Scalar + Zero,
S: OwnedStorage<N, D, D>,
S::Alloc: OwnedAllocator<N, D, D, S> {
/// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
#[inline]
pub fn from_diagonal<SB: Storage<N, D, U1>>(diag: &ColumnVector<N, D, SB>) -> Self {
let (dim, _) = diag.data.shape();
let mut res = Self::from_element_generic(dim, dim, N::zero());
for i in 0 .. diag.len() {
unsafe { *res.get_unchecked_mut(i, i) = *diag.get_unchecked(i, 0); }
}
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),*) => {
impl<N: Scalar, $($DimIdent: $DimBound, )* S> Matrix<N $(, $Dims)*, S>
where S: OwnedStorage<N $(, $Dims)*>,
S::Alloc: OwnedAllocator<N $(, $Dims)*, S> {
/// Creates a new uninitialized matrix.
#[inline]
pub unsafe fn new_uninitialized($($args: usize),*) -> Matrix<N $(, $Dims)*, S> {
Self::new_uninitialized_generic($($gargs),*)
}
/// Creates a matrix with all its elements set to `elem`.
#[inline]
pub fn from_element($($args: usize,)* elem: N) -> Matrix<N $(, $Dims)*, S> {
Self::from_element_generic($($gargs, )* elem)
}
/// Creates a matrix with all its elements filled by an iterator.
#[inline]
pub fn from_iterator<I>($($args: usize,)* iter: I) -> Matrix<N $(, $Dims)*, S>
where I: IntoIterator<Item = N> {
Self::from_iterator_generic($($gargs, )* iter)
}
/// 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]
pub fn from_row_slice($($args: usize,)* slice: &[N]) -> Matrix<N $(, $Dims)*, S> {
Self::from_row_slice_generic($($gargs, )* slice)
}
/// Creates a matrix with its elements filled with the components provided by a slice
/// in column-major order.
#[inline]
pub fn from_column_slice($($args: usize,)* slice: &[N]) -> Matrix<N $(, $Dims)*, S> {
Self::from_column_slice_generic($($gargs, )* slice)
}
/// Creates a matrix filled with the results of a function applied to each of its
/// component coordinates.
// FIXME: don't take a dimension of the matrix is statically sized.
#[inline]
pub fn from_fn<F>($($args: usize,)* f: F) -> Matrix<N $(, $Dims)*, S>
where F: FnMut(usize, usize) -> N {
Self::from_fn_generic($($gargs, )* f)
}
/// 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.
#[inline]
pub fn identity($($args: usize,)*) -> Matrix<N $(, $Dims)*, S>
where N: Zero + One {
Self::identity_generic($($gargs),* )
}
/// Creates a matrix filled with its diagonal filled with `elt` and all other
/// components set to zero.
#[inline]
pub fn from_diagonal_element($($args: usize,)* elt: N) -> Matrix<N $(, $Dims)*, S>
where N: Zero + One {
Self::from_diagonal_element_generic($($gargs, )* elt)
}
}
impl<N: Scalar + Rand, $($DimIdent: $DimBound, )* S> Matrix<N $(, $Dims)*, S>
where S: OwnedStorage<N $(, $Dims)*>,
S::Alloc: OwnedAllocator<N $(, $Dims)*, S> {
/// Creates a matrix filled with random values.
#[inline]
pub fn new_random($($args: usize),*) -> Matrix<N $(, $Dims)*, S> {
Self::new_random_generic($($gargs),*)
}
}
}
);
// FIXME: this is not very pretty. We could find a better call syntax.
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.
impl_constructors!(R, Dynamic;
=> R: DimName;
R::name(), Dynamic::new(ncols);
ncols);
impl_constructors!(Dynamic, C;
=> C: DimName;
Dynamic::new(nrows), C::name();
nrows);
impl_constructors!(Dynamic, Dynamic;
;
Dynamic::new(nrows), Dynamic::new(ncols);
nrows, ncols);
/*
*
* Zero, One, Rand traits.
*
*/
impl<N, R: DimName, C: DimName, S> Zero for Matrix<N, R, C, S>
where N: Scalar + Zero + ClosedAdd,
S: OwnedStorage<N, R, C>,
S::Alloc: OwnedAllocator<N, R, C, S> {
#[inline]
fn zero() -> Self {
Self::from_element(N::zero())
}
#[inline]
fn is_zero(&self) -> bool {
self.iter().all(|e| e.is_zero())
}
}
impl<N, D: DimName, S> One for Matrix<N, D, D, S>
where N: Scalar + Zero + One + ClosedMul + ClosedAdd,
S: OwnedStorage<N, D, D>,
S::Alloc: OwnedAllocator<N, D, D, S> {
#[inline]
fn one() -> Self {
Self::identity()
}
}
impl<N, R: DimName, C: DimName, S> Bounded for Matrix<N, R, C, S>
where N: Scalar + Bounded,
S: OwnedStorage<N, R, C>,
S::Alloc: OwnedAllocator<N, R, C, S> {
#[inline]
fn max_value() -> Self {
Self::from_element(N::max_value())
}
#[inline]
fn min_value() -> Self {
Self::from_element(N::min_value())
}
}
impl<N: Scalar + Rand, R: Dim, C: Dim, S> Rand for Matrix<N, R, C, S>
where S: OwnedStorage<N, R, C>,
S::Alloc: OwnedAllocator<N, R, C, S> {
#[inline]
fn rand<G: Rng>(rng: &mut G) -> Self {
let nrows = R::try_to_usize().unwrap_or(rng.gen_range(0, 10));
let ncols = C::try_to_usize().unwrap_or(rng.gen_range(0, 10));
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
}
}
#[cfg(feature = "arbitrary")]
impl<N, R, C, S> Arbitrary for Matrix<N, R, C, S>
where R: Dim, C: Dim,
N: Scalar + Arbitrary + Send,
S: OwnedStorage<N, R, C> + Send,
S::Alloc: OwnedAllocator<N, R, C, S> {
#[inline]
fn arbitrary<G: Gen>(g: &mut G) -> Self {
let nrows = R::try_to_usize().unwrap_or(g.gen_range(0, 10));
let ncols = C::try_to_usize().unwrap_or(g.gen_range(0, 10));
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| N::arbitrary(g))
}
}
/*
*
* Constructors for small matrices and vectors.
*
*/
macro_rules! componentwise_constructors_impl(
($($R: ty, $C: ty, $($args: ident:($irow: expr,$icol: expr)),*);* $(;)*) => {$(
impl<N, S> Matrix<N, $R, $C, S>
where N: Scalar,
S: OwnedStorage<N, $R, $C>,
S::Alloc: OwnedAllocator<N, $R, $C, S> {
/// Initializes this matrix from its components.
#[inline]
pub fn new($($args: N),*) -> Matrix<N, $R, $C, S> {
unsafe {
let mut res = Self::new_uninitialized();
$( *res.get_unchecked_mut($irow, $icol) = $args; )*
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.
*
*/
impl<N, R: DimName, S> ColumnVector<N, R, S>
where N: Scalar + Zero + One,
S: OwnedStorage<N, R, U1>,
S::Alloc: OwnedAllocator<N, R, U1, S> {
/// The column vector with a 1 as its first component, and zero elsewhere.
#[inline]
pub fn x() -> Self
where R::Value: Cmp<typenum::U0, Output = Greater> {
let mut res = Self::from_element(N::zero());
unsafe { *res.get_unchecked_mut(0, 0) = N::one(); }
res
}
/// The column vector with a 1 as its second component, and zero elsewhere.
#[inline]
pub fn y() -> Self
where R::Value: Cmp<typenum::U1, Output = Greater> {
let mut res = Self::from_element(N::zero());
unsafe { *res.get_unchecked_mut(1, 0) = N::one(); }
res
}
/// The column vector with a 1 as its third component, and zero elsewhere.
#[inline]
pub fn z() -> Self
where R::Value: Cmp<typenum::U2, Output = Greater> {
let mut res = Self::from_element(N::zero());
unsafe { *res.get_unchecked_mut(2, 0) = N::one(); }
res
}
/// The column vector with a 1 as its fourth component, and zero elsewhere.
#[inline]
pub fn w() -> Self
where R::Value: Cmp<typenum::U3, Output = Greater> {
let mut res = Self::from_element(N::zero());
unsafe { *res.get_unchecked_mut(3, 0) = N::one(); }
res
}
/// The column vector with a 1 as its fifth component, and zero elsewhere.
#[inline]
pub fn a() -> Self
where R::Value: Cmp<typenum::U4, Output = Greater> {
let mut res = Self::from_element(N::zero());
unsafe { *res.get_unchecked_mut(4, 0) = N::one(); }
res
}
/// The column vector with a 1 as its sixth component, and zero elsewhere.
#[inline]
pub fn b() -> Self
where R::Value: Cmp<typenum::U5, Output = Greater> {
let mut res = Self::from_element(N::zero());
unsafe { *res.get_unchecked_mut(5, 0) = N::one(); }
res
}
/// The unit column vector with a 1 as its first component, and zero elsewhere.
#[inline]
pub fn x_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U0, Output = Greater> {
Unit::new_unchecked(Self::x())
}
/// The unit column vector with a 1 as its second component, and zero elsewhere.
#[inline]
pub fn y_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U1, Output = Greater> {
Unit::new_unchecked(Self::y())
}
/// The unit column vector with a 1 as its third component, and zero elsewhere.
#[inline]
pub fn z_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U2, Output = Greater> {
Unit::new_unchecked(Self::z())
}
/// The unit column vector with a 1 as its fourth component, and zero elsewhere.
#[inline]
pub fn w_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U3, Output = Greater> {
Unit::new_unchecked(Self::w())
}
/// The unit column vector with a 1 as its fifth component, and zero elsewhere.
#[inline]
pub fn a_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U4, Output = Greater> {
Unit::new_unchecked(Self::a())
}
/// The unit column vector with a 1 as its sixth component, and zero elsewhere.
#[inline]
pub fn b_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U5, Output = Greater> {
Unit::new_unchecked(Self::b())
}
}