nalgebra/base/
construction.rs

1#[cfg(all(feature = "alloc", not(feature = "std")))]
2use alloc::vec::Vec;
3
4#[cfg(feature = "arbitrary")]
5use crate::base::storage::Owned;
6#[cfg(feature = "arbitrary")]
7use quickcheck::{Arbitrary, Gen};
8
9use num::{Bounded, One, Zero};
10#[cfg(feature = "rand-no-std")]
11use rand::{
12    distributions::{Distribution, Standard},
13    Rng,
14};
15
16use std::iter;
17use typenum::{self, Cmp, Greater};
18
19use simba::scalar::{ClosedAddAssign, ClosedMulAssign};
20
21use crate::base::allocator::Allocator;
22use crate::base::dimension::{Dim, DimName, Dyn, ToTypenum};
23use crate::base::storage::RawStorage;
24use crate::base::{
25    ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector,
26};
27use crate::UninitMatrix;
28use std::mem::MaybeUninit;
29
30impl<T: Scalar, R: Dim, C: Dim> UninitMatrix<T, R, C>
31where
32    DefaultAllocator: Allocator<R, C>,
33{
34    /// Builds a matrix with uninitialized elements of type `MaybeUninit<T>`.
35    #[inline(always)]
36    pub fn uninit(nrows: R, ncols: C) -> Self {
37        // SAFETY: this is OK because the dimension automatically match the storage
38        //         because we are building an owned storage.
39        unsafe {
40            Self::from_data_statically_unchecked(DefaultAllocator::allocate_uninit(nrows, ncols))
41        }
42    }
43}
44
45/// # Generic constructors
46/// This set of matrix and vector construction functions are all generic
47/// with-regard to the matrix dimensions. They all expect to be given
48/// the dimension as inputs.
49///
50/// These functions should only be used when working on dimension-generic code.
51impl<T: Scalar, R: Dim, C: Dim> OMatrix<T, R, C>
52where
53    DefaultAllocator: Allocator<R, C>,
54{
55    /// Creates a matrix with all its elements set to `elem`.
56    #[inline]
57    pub fn from_element_generic(nrows: R, ncols: C, elem: T) -> Self {
58        let len = nrows.value() * ncols.value();
59        Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
60    }
61
62    /// Creates a matrix with all its elements set to `elem`.
63    ///
64    /// Same as `from_element_generic`.
65    #[inline]
66    pub fn repeat_generic(nrows: R, ncols: C, elem: T) -> Self {
67        let len = nrows.value() * ncols.value();
68        Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
69    }
70
71    /// Creates a matrix with all its elements set to 0.
72    #[inline]
73    pub fn zeros_generic(nrows: R, ncols: C) -> Self
74    where
75        T: Zero,
76    {
77        Self::from_element_generic(nrows, ncols, T::zero())
78    }
79
80    /// Creates a matrix with all its elements filled by an iterator.
81    #[inline]
82    pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
83    where
84        I: IntoIterator<Item = T>,
85    {
86        Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
87    }
88
89    /// Creates a matrix with all its elements filled by an row-major order iterator.
90    #[inline]
91    pub fn from_row_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
92    where
93        I: IntoIterator<Item = T>,
94    {
95        Self::from_data(DefaultAllocator::allocate_from_row_iterator(
96            nrows, ncols, iter,
97        ))
98    }
99
100    /// Creates a matrix with its elements filled with the components provided by a slice in
101    /// row-major order.
102    ///
103    /// The order of elements in the slice must follow the usual mathematic writing, i.e.,
104    /// row-by-row.
105    #[inline]
106    pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[T]) -> Self {
107        assert!(
108            slice.len() == nrows.value() * ncols.value(),
109            "Matrix init. error: the slice did not contain the right number of elements."
110        );
111
112        let mut res = Matrix::uninit(nrows, ncols);
113        let mut iter = slice.iter();
114
115        unsafe {
116            for i in 0..nrows.value() {
117                for j in 0..ncols.value() {
118                    *res.get_unchecked_mut((i, j)) = MaybeUninit::new(iter.next().unwrap().clone())
119                }
120            }
121
122            // SAFETY: the result has been fully initialized above.
123            res.assume_init()
124        }
125    }
126
127    /// Creates a matrix with its elements filled with the components provided by a slice. The
128    /// components must have the same layout as the matrix data storage (i.e. column-major).
129    #[inline]
130    pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[T]) -> Self {
131        Self::from_iterator_generic(nrows, ncols, slice.iter().cloned())
132    }
133
134    /// Creates a matrix filled with the results of a function applied to each of its component
135    /// coordinates.
136    #[inline]
137    pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self
138    where
139        F: FnMut(usize, usize) -> T,
140    {
141        let mut res = Matrix::uninit(nrows, ncols);
142
143        unsafe {
144            for j in 0..ncols.value() {
145                for i in 0..nrows.value() {
146                    *res.get_unchecked_mut((i, j)) = MaybeUninit::new(f(i, j));
147                }
148            }
149
150            // SAFETY: the result has been fully initialized above.
151            res.assume_init()
152        }
153    }
154
155    /// Creates a new identity matrix.
156    ///
157    /// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
158    /// to the identity matrix. All other entries are set to zero.
159    #[inline]
160    pub fn identity_generic(nrows: R, ncols: C) -> Self
161    where
162        T: Zero + One,
163    {
164        Self::from_diagonal_element_generic(nrows, ncols, T::one())
165    }
166
167    /// Creates a new matrix with its diagonal filled with copies of `elt`.
168    ///
169    /// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
170    /// to the identity matrix. All other entries are set to zero.
171    #[inline]
172    pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: T) -> Self
173    where
174        T: Zero + One,
175    {
176        let mut res = Self::zeros_generic(nrows, ncols);
177
178        for i in 0..crate::min(nrows.value(), ncols.value()) {
179            unsafe { *res.get_unchecked_mut((i, i)) = elt.clone() }
180        }
181
182        res
183    }
184
185    /// Creates a new matrix that may be rectangular. The first `elts.len()` diagonal elements are
186    /// filled with the content of `elts`. Others are set to 0.
187    ///
188    /// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
189    #[inline]
190    pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[T]) -> Self
191    where
192        T: Zero,
193    {
194        let mut res = Self::zeros_generic(nrows, ncols);
195        assert!(
196            elts.len() <= crate::min(nrows.value(), ncols.value()),
197            "Too many diagonal elements provided."
198        );
199
200        for (i, elt) in elts.iter().enumerate() {
201            unsafe { *res.get_unchecked_mut((i, i)) = elt.clone() }
202        }
203
204        res
205    }
206
207    /// Builds a new matrix from its rows.
208    ///
209    /// Panics if not enough rows are provided (for statically-sized matrices), or if all rows do
210    /// not have the same dimensions.
211    ///
212    /// # Example
213    /// ```
214    /// # use nalgebra::{RowVector3, Matrix3};
215    /// # use std::iter;
216    ///
217    /// 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) ]);
218    ///
219    /// assert!(m.m11 == 1.0 && m.m12 == 2.0 && m.m13 == 3.0 &&
220    ///         m.m21 == 4.0 && m.m22 == 5.0 && m.m23 == 6.0 &&
221    ///         m.m31 == 7.0 && m.m32 == 8.0 && m.m33 == 9.0);
222    /// ```
223    #[inline]
224    pub fn from_rows<SB>(rows: &[Matrix<T, Const<1>, C, SB>]) -> Self
225    where
226        SB: RawStorage<T, Const<1>, C>,
227    {
228        assert!(!rows.is_empty(), "At least one row must be given.");
229        let nrows = R::try_to_usize().unwrap_or(rows.len());
230        let ncols = rows[0].len();
231        assert!(
232            rows.len() == nrows,
233            "Invalid number of rows provided to build this matrix."
234        );
235
236        if C::try_to_usize().is_none() {
237            assert!(
238                rows.iter().all(|r| r.len() == ncols),
239                "The provided rows must all have the same dimension."
240            );
241        }
242
243        // TODO: optimize that.
244        Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
245            rows[i][(0, j)].clone()
246        })
247    }
248
249    /// Builds a new matrix from its columns.
250    ///
251    /// Panics if not enough columns are provided (for statically-sized matrices), or if all
252    /// columns do not have the same dimensions.
253    ///
254    /// # Example
255    /// ```
256    /// # use nalgebra::{Vector3, Matrix3};
257    /// # use std::iter;
258    ///
259    /// 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) ]);
260    ///
261    /// assert!(m.m11 == 1.0 && m.m12 == 4.0 && m.m13 == 7.0 &&
262    ///         m.m21 == 2.0 && m.m22 == 5.0 && m.m23 == 8.0 &&
263    ///         m.m31 == 3.0 && m.m32 == 6.0 && m.m33 == 9.0);
264    /// ```
265    #[inline]
266    pub fn from_columns<SB>(columns: &[Vector<T, R, SB>]) -> Self
267    where
268        SB: RawStorage<T, R>,
269    {
270        assert!(!columns.is_empty(), "At least one column must be given.");
271        let ncols = C::try_to_usize().unwrap_or(columns.len());
272        let nrows = columns[0].len();
273        assert!(
274            columns.len() == ncols,
275            "Invalid number of columns provided to build this matrix."
276        );
277
278        if R::try_to_usize().is_none() {
279            assert!(
280                columns.iter().all(|r| r.len() == nrows),
281                "The columns provided must all have the same dimension."
282            );
283        }
284
285        // TODO: optimize that.
286        Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
287            columns[j][i].clone()
288        })
289    }
290
291    /// Creates a matrix filled with random values.
292    #[inline]
293    #[cfg(feature = "rand")]
294    pub fn new_random_generic(nrows: R, ncols: C) -> Self
295    where
296        Standard: Distribution<T>,
297    {
298        let mut rng = rand::thread_rng();
299        Self::from_fn_generic(nrows, ncols, |_, _| rng.gen())
300    }
301
302    /// Creates a matrix filled with random values from the given distribution.
303    #[inline]
304    #[cfg(feature = "rand-no-std")]
305    pub fn from_distribution_generic<Distr: Distribution<T> + ?Sized, G: Rng + ?Sized>(
306        nrows: R,
307        ncols: C,
308        distribution: &Distr,
309        rng: &mut G,
310    ) -> Self {
311        Self::from_fn_generic(nrows, ncols, |_, _| distribution.sample(rng))
312    }
313
314    /// Creates a matrix backed by a given `Vec`.
315    ///
316    /// The output matrix is filled column-by-column.
317    ///
318    /// # Example
319    /// ```
320    /// # use nalgebra::{Dyn, DMatrix, Matrix, Const};
321    ///
322    /// let vec = vec![0, 1, 2, 3, 4, 5];
323    /// let vec_ptr = vec.as_ptr();
324    ///
325    /// let matrix = Matrix::from_vec_generic(Dyn(vec.len()), Const::<1>, vec);
326    /// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
327    ///
328    /// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
329    /// assert_eq!(matrix_storage_ptr, vec_ptr);
330    /// ```
331    #[inline]
332    #[cfg(any(feature = "std", feature = "alloc"))]
333    pub fn from_vec_generic(nrows: R, ncols: C, data: Vec<T>) -> Self {
334        Self::from_iterator_generic(nrows, ncols, data)
335    }
336}
337
338impl<T, D: Dim> OMatrix<T, D, D>
339where
340    T: Scalar,
341    DefaultAllocator: Allocator<D, D>,
342{
343    /// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
344    ///
345    /// # Example
346    /// ```
347    /// # use nalgebra::{Vector3, DVector, Matrix3, DMatrix};
348    /// # use std::iter;
349    ///
350    /// let m = Matrix3::from_diagonal(&Vector3::new(1.0, 2.0, 3.0));
351    /// // The two additional arguments represent the matrix dimensions.
352    /// let dm = DMatrix::from_diagonal(&DVector::from_row_slice(&[1.0, 2.0, 3.0]));
353    ///
354    /// assert!(m.m11 == 1.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
355    ///         m.m21 == 0.0 && m.m22 == 2.0 && m.m23 == 0.0 &&
356    ///         m.m31 == 0.0 && m.m32 == 0.0 && m.m33 == 3.0);
357    /// assert!(dm[(0, 0)] == 1.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
358    ///         dm[(1, 0)] == 0.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 0.0 &&
359    ///         dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 3.0);
360    /// ```
361    #[inline]
362    pub fn from_diagonal<SB: RawStorage<T, D>>(diag: &Vector<T, D, SB>) -> Self
363    where
364        T: Zero,
365    {
366        let (dim, _) = diag.shape_generic();
367        let mut res = Self::zeros_generic(dim, dim);
368
369        for i in 0..diag.len() {
370            unsafe {
371                *res.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).clone();
372            }
373        }
374
375        res
376    }
377}
378
379/*
380 *
381 * Generate constructors with varying number of arguments, depending on the object type.
382 *
383 */
384macro_rules! impl_constructors(
385    ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
386        /// Creates a matrix or vector with all its elements set to `elem`.
387        ///
388        /// # Example
389        /// ```
390        /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
391        ///
392        /// let v = Vector3::from_element(2.0);
393        /// // The additional argument represents the vector dimension.
394        /// let dv = DVector::from_element(3, 2.0);
395        /// let m = Matrix2x3::from_element(2.0);
396        /// // The two additional arguments represent the matrix dimensions.
397        /// let dm = DMatrix::from_element(2, 3, 2.0);
398        ///
399        /// assert!(v.x == 2.0 && v.y == 2.0 && v.z == 2.0);
400        /// assert!(dv[0] == 2.0 && dv[1] == 2.0 && dv[2] == 2.0);
401        /// assert!(m.m11 == 2.0 && m.m12 == 2.0 && m.m13 == 2.0 &&
402        ///         m.m21 == 2.0 && m.m22 == 2.0 && m.m23 == 2.0);
403        /// assert!(dm[(0, 0)] == 2.0 && dm[(0, 1)] == 2.0 && dm[(0, 2)] == 2.0 &&
404        ///         dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
405        /// ```
406        #[inline]
407        pub fn from_element($($args: usize,)* elem: T) -> Self {
408            Self::from_element_generic($($gargs, )* elem)
409        }
410
411        /// Creates a matrix or vector with all its elements set to `elem`.
412        ///
413        /// Same as `.from_element`.
414        ///
415        /// # Example
416        /// ```
417        /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
418        ///
419        /// let v = Vector3::repeat(2.0);
420        /// // The additional argument represents the vector dimension.
421        /// let dv = DVector::repeat(3, 2.0);
422        /// let m = Matrix2x3::repeat(2.0);
423        /// // The two additional arguments represent the matrix dimensions.
424        /// let dm = DMatrix::repeat(2, 3, 2.0);
425        ///
426        /// assert!(v.x == 2.0 && v.y == 2.0 && v.z == 2.0);
427        /// assert!(dv[0] == 2.0 && dv[1] == 2.0 && dv[2] == 2.0);
428        /// assert!(m.m11 == 2.0 && m.m12 == 2.0 && m.m13 == 2.0 &&
429        ///         m.m21 == 2.0 && m.m22 == 2.0 && m.m23 == 2.0);
430        /// assert!(dm[(0, 0)] == 2.0 && dm[(0, 1)] == 2.0 && dm[(0, 2)] == 2.0 &&
431        ///         dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
432        /// ```
433        #[inline]
434        pub fn repeat($($args: usize,)* elem: T) -> Self {
435            Self::repeat_generic($($gargs, )* elem)
436        }
437
438        /// Creates a matrix or vector with all its elements set to `0`.
439        ///
440        /// # Example
441        /// ```
442        /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
443        ///
444        /// let v = Vector3::<f32>::zeros();
445        /// // The argument represents the vector dimension.
446        /// let dv = DVector::<f32>::zeros(3);
447        /// let m = Matrix2x3::<f32>::zeros();
448        /// // The two arguments represent the matrix dimensions.
449        /// let dm = DMatrix::<f32>::zeros(2, 3);
450        ///
451        /// assert!(v.x == 0.0 && v.y == 0.0 && v.z == 0.0);
452        /// assert!(dv[0] == 0.0 && dv[1] == 0.0 && dv[2] == 0.0);
453        /// assert!(m.m11 == 0.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
454        ///         m.m21 == 0.0 && m.m22 == 0.0 && m.m23 == 0.0);
455        /// assert!(dm[(0, 0)] == 0.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
456        ///         dm[(1, 0)] == 0.0 && dm[(1, 1)] == 0.0 && dm[(1, 2)] == 0.0);
457        /// ```
458        #[inline]
459        pub fn zeros($($args: usize),*) -> Self
460            where T: Zero {
461            Self::zeros_generic($($gargs),*)
462        }
463
464        /// Creates a matrix or vector with all its elements filled by an iterator.
465        ///
466        /// The output matrix is filled column-by-column.
467        ///
468        /// # Example
469        /// ```
470        /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
471        /// # use std::iter;
472        ///
473        /// let v = Vector3::from_iterator((0..3).into_iter());
474        /// // The additional argument represents the vector dimension.
475        /// let dv = DVector::from_iterator(3, (0..3).into_iter());
476        /// let m = Matrix2x3::from_iterator((0..6).into_iter());
477        /// // The two additional arguments represent the matrix dimensions.
478        /// let dm = DMatrix::from_iterator(2, 3, (0..6).into_iter());
479        ///
480        /// assert!(v.x == 0 && v.y == 1 && v.z == 2);
481        /// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
482        /// assert!(m.m11 == 0 && m.m12 == 2 && m.m13 == 4 &&
483        ///         m.m21 == 1 && m.m22 == 3 && m.m23 == 5);
484        /// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 2 && dm[(0, 2)] == 4 &&
485        ///         dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
486        /// ```
487        #[inline]
488        pub fn from_iterator<I>($($args: usize,)* iter: I) -> Self
489            where I: IntoIterator<Item = T> {
490            Self::from_iterator_generic($($gargs, )* iter)
491        }
492
493        /// Creates a matrix or vector with all its elements filled by a row-major iterator.
494        ///
495        /// The output matrix is filled row-by-row.
496        ///
497        /// ## Example
498        /// ```
499        /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
500        /// # use std::iter;
501        ///
502        /// let v = Vector3::from_row_iterator((0..3).into_iter());
503        /// // The additional argument represents the vector dimension.
504        /// let dv = DVector::from_row_iterator(3, (0..3).into_iter());
505        /// let m = Matrix2x3::from_row_iterator((0..6).into_iter());
506        /// // The two additional arguments represent the matrix dimensions.
507        /// let dm = DMatrix::from_row_iterator(2, 3, (0..6).into_iter());
508        ///
509        /// // For Vectors from_row_iterator is identical to from_iterator
510        /// assert!(v.x == 0 && v.y == 1 && v.z == 2);
511        /// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
512        /// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
513        ///         m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
514        /// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
515        ///         dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
516        /// ```
517        #[inline]
518        pub fn from_row_iterator<I>($($args: usize,)* iter: I) -> Self
519            where I: IntoIterator<Item = T> {
520            Self::from_row_iterator_generic($($gargs, )* iter)
521        }
522
523        /// Creates a matrix or vector filled with the results of a function applied to each of its
524        /// component coordinates.
525        ///
526        /// # Example
527        /// ```
528        /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
529        /// # use std::iter;
530        ///
531        /// let v = Vector3::from_fn(|i, _| i);
532        /// // The additional argument represents the vector dimension.
533        /// let dv = DVector::from_fn(3, |i, _| i);
534        /// let m = Matrix2x3::from_fn(|i, j| i * 3 + j);
535        /// // The two additional arguments represent the matrix dimensions.
536        /// let dm = DMatrix::from_fn(2, 3, |i, j| i * 3 + j);
537        ///
538        /// assert!(v.x == 0 && v.y == 1 && v.z == 2);
539        /// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
540        /// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
541        ///         m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
542        /// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
543        ///         dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
544        /// ```
545        #[inline]
546        pub fn from_fn<F>($($args: usize,)* f: F) -> Self
547            where F: FnMut(usize, usize) -> T {
548            Self::from_fn_generic($($gargs, )* f)
549        }
550
551        /// Creates an identity matrix. If the matrix is not square, the largest square
552        /// submatrix (starting at the first row and column) is set to the identity while all
553        /// other entries are set to zero.
554        ///
555        /// # Example
556        /// ```
557        /// # use nalgebra::{Matrix2x3, DMatrix};
558        /// # use std::iter;
559        ///
560        /// let m = Matrix2x3::<f32>::identity();
561        /// // The two additional arguments represent the matrix dimensions.
562        /// let dm = DMatrix::<f32>::identity(2, 3);
563        ///
564        /// assert!(m.m11 == 1.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
565        ///         m.m21 == 0.0 && m.m22 == 1.0 && m.m23 == 0.0);
566        /// assert!(dm[(0, 0)] == 1.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
567        ///         dm[(1, 0)] == 0.0 && dm[(1, 1)] == 1.0 && dm[(1, 2)] == 0.0);
568        /// ```
569        #[inline]
570        pub fn identity($($args: usize,)*) -> Self
571            where T: Zero + One {
572            Self::identity_generic($($gargs),* )
573        }
574
575        /// Creates a matrix filled with its diagonal filled with `elt` and all other
576        /// components set to zero.
577        ///
578        /// # Example
579        /// ```
580        /// # use nalgebra::{Matrix2x3, DMatrix};
581        /// # use std::iter;
582        ///
583        /// let m = Matrix2x3::from_diagonal_element(5.0);
584        /// // The two additional arguments represent the matrix dimensions.
585        /// let dm = DMatrix::from_diagonal_element(2, 3, 5.0);
586        ///
587        /// assert!(m.m11 == 5.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
588        ///         m.m21 == 0.0 && m.m22 == 5.0 && m.m23 == 0.0);
589        /// assert!(dm[(0, 0)] == 5.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
590        ///         dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0);
591        /// ```
592        #[inline]
593        pub fn from_diagonal_element($($args: usize,)* elt: T) -> Self
594            where T: Zero + One {
595            Self::from_diagonal_element_generic($($gargs, )* elt)
596        }
597
598        /// Creates a new matrix that may be rectangular. The first `elts.len()` diagonal
599        /// elements are filled with the content of `elts`. Others are set to 0.
600        ///
601        /// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
602        ///
603        /// # Example
604        /// ```
605        /// # use nalgebra::{Matrix3, DMatrix};
606        /// # use std::iter;
607        ///
608        /// let m = Matrix3::from_partial_diagonal(&[1.0, 2.0]);
609        /// // The two additional arguments represent the matrix dimensions.
610        /// let dm = DMatrix::from_partial_diagonal(3, 3, &[1.0, 2.0]);
611        ///
612        /// assert!(m.m11 == 1.0 && m.m12 == 0.0 && m.m13 == 0.0 &&
613        ///         m.m21 == 0.0 && m.m22 == 2.0 && m.m23 == 0.0 &&
614        ///         m.m31 == 0.0 && m.m32 == 0.0 && m.m33 == 0.0);
615        /// assert!(dm[(0, 0)] == 1.0 && dm[(0, 1)] == 0.0 && dm[(0, 2)] == 0.0 &&
616        ///         dm[(1, 0)] == 0.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 0.0 &&
617        ///         dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 0.0);
618        /// ```
619        #[inline]
620        pub fn from_partial_diagonal($($args: usize,)* elts: &[T]) -> Self
621            where T: Zero {
622            Self::from_partial_diagonal_generic($($gargs, )* elts)
623        }
624
625        /// Creates a matrix or vector filled with random values from the given distribution.
626        #[inline]
627        #[cfg(feature = "rand-no-std")]
628        pub fn from_distribution<Distr: Distribution<T> + ?Sized, G: Rng + ?Sized>(
629            $($args: usize,)*
630            distribution: &Distr,
631            rng: &mut G,
632        ) -> Self {
633            Self::from_distribution_generic($($gargs, )* distribution, rng)
634        }
635
636        /// Creates a matrix filled with random values.
637        #[inline]
638        #[cfg(feature = "rand")]
639        pub fn new_random($($args: usize),*) -> Self
640            where Standard: Distribution<T> {
641            Self::new_random_generic($($gargs),*)
642        }
643    }
644);
645
646/// # Constructors of statically-sized vectors or statically-sized matrices
647impl<T: Scalar, R: DimName, C: DimName> OMatrix<T, R, C>
648where
649    DefaultAllocator: Allocator<R, C>,
650{
651    // TODO: this is not very pretty. We could find a better call syntax.
652    impl_constructors!(R, C;                         // Arguments for Matrix<T, ..., S>
653    => R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
654    R::name(), C::name();         // Arguments for `_generic` constructors.
655    ); // Arguments for non-generic constructors.
656}
657
658/// # Constructors of matrices with a dynamic number of columns
659impl<T: Scalar, R: DimName> OMatrix<T, R, Dyn>
660where
661    DefaultAllocator: Allocator<R, Dyn>,
662{
663    impl_constructors!(R, Dyn;
664                   => R: DimName;
665                   R::name(), Dyn(ncols);
666                   ncols);
667}
668
669/// # Constructors of dynamic vectors and matrices with a dynamic number of rows
670impl<T: Scalar, C: DimName> OMatrix<T, Dyn, C>
671where
672    DefaultAllocator: Allocator<Dyn, C>,
673{
674    impl_constructors!(Dyn, C;
675                   => C: DimName;
676                   Dyn(nrows), C::name();
677                   nrows);
678}
679
680/// # Constructors of fully dynamic matrices
681#[cfg(any(feature = "std", feature = "alloc"))]
682impl<T: Scalar> OMatrix<T, Dyn, Dyn>
683where
684    DefaultAllocator: Allocator<Dyn, Dyn>,
685{
686    impl_constructors!(Dyn, Dyn;
687                   ;
688                   Dyn(nrows), Dyn(ncols);
689                   nrows, ncols);
690}
691
692/*
693 *
694 * Constructors that don't necessarily require all dimensions
695 * to be specified when one dimension is already known.
696 *
697 */
698macro_rules! impl_constructors_from_data(
699    ($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
700        impl<T: Scalar, $($DimIdent: $DimBound, )*> OMatrix<T $(, $Dims)*>
701        where DefaultAllocator: Allocator<$($Dims),*> {
702            /// Creates a matrix with its elements filled with the components provided by a slice
703            /// in row-major order.
704            ///
705            /// The order of elements in the slice must follow the usual mathematic writing, i.e.,
706            /// row-by-row.
707            ///
708            /// # Example
709            /// ```
710            /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
711            /// # use std::iter;
712            ///
713            /// let v = Vector3::from_row_slice(&[0, 1, 2]);
714            /// // The additional argument represents the vector dimension.
715            /// let dv = DVector::from_row_slice(&[0, 1, 2]);
716            /// let m = Matrix2x3::from_row_slice(&[0, 1, 2, 3, 4, 5]);
717            /// // The two additional arguments represent the matrix dimensions.
718            /// let dm = DMatrix::from_row_slice(2, 3, &[0, 1, 2, 3, 4, 5]);
719            ///
720            /// assert!(v.x == 0 && v.y == 1 && v.z == 2);
721            /// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
722            /// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
723            ///         m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
724            /// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
725            ///         dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
726            /// ```
727            #[inline]
728            pub fn from_row_slice($($args: usize,)* $data: &[T]) -> Self {
729                Self::from_row_slice_generic($($gargs, )* $data)
730            }
731
732            /// Creates a matrix with its elements filled with the components provided by a slice
733            /// in column-major order.
734            ///
735            /// # Example
736            /// ```
737            /// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
738            /// # use std::iter;
739            ///
740            /// let v = Vector3::from_column_slice(&[0, 1, 2]);
741            /// // The additional argument represents the vector dimension.
742            /// let dv = DVector::from_column_slice(&[0, 1, 2]);
743            /// let m = Matrix2x3::from_column_slice(&[0, 1, 2, 3, 4, 5]);
744            /// // The two additional arguments represent the matrix dimensions.
745            /// let dm = DMatrix::from_column_slice(2, 3, &[0, 1, 2, 3, 4, 5]);
746            ///
747            /// assert!(v.x == 0 && v.y == 1 && v.z == 2);
748            /// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
749            /// assert!(m.m11 == 0 && m.m12 == 2 && m.m13 == 4 &&
750            ///         m.m21 == 1 && m.m22 == 3 && m.m23 == 5);
751            /// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 2 && dm[(0, 2)] == 4 &&
752            ///         dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
753            /// ```
754            #[inline]
755            pub fn from_column_slice($($args: usize,)* $data: &[T]) -> Self {
756                Self::from_column_slice_generic($($gargs, )* $data)
757            }
758
759            /// Creates a matrix backed by a given `Vec`.
760            ///
761            /// The output matrix is filled column-by-column.
762            ///
763            /// # Example
764            /// ```
765            /// # use nalgebra::{DMatrix, Matrix2x3};
766            ///
767            /// let m = Matrix2x3::from_vec(vec![0, 1, 2, 3, 4, 5]);
768            ///
769            /// assert!(m.m11 == 0 && m.m12 == 2 && m.m13 == 4 &&
770            ///         m.m21 == 1 && m.m22 == 3 && m.m23 == 5);
771            ///
772            ///
773            /// // The two additional arguments represent the matrix dimensions.
774            /// let dm = DMatrix::from_vec(2, 3, vec![0, 1, 2, 3, 4, 5]);
775            ///
776            /// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 2 && dm[(0, 2)] == 4 &&
777            ///         dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
778            /// ```
779            #[inline]
780            #[cfg(any(feature = "std", feature = "alloc"))]
781            pub fn from_vec($($args: usize,)* $data: Vec<T>) -> Self {
782                Self::from_vec_generic($($gargs, )* $data)
783            }
784        }
785    }
786);
787
788// TODO: this is not very pretty. We could find a better call syntax.
789impl_constructors_from_data!(data; R, C;                  // Arguments for Matrix<T, ..., S>
790=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
791R::name(), C::name();         // Arguments for `_generic` constructors.
792); // Arguments for non-generic constructors.
793
794impl_constructors_from_data!(data; R, Dyn;
795=> R: DimName;
796R::name(), Dyn(data.len() / R::dim());
797);
798
799impl_constructors_from_data!(data; Dyn, C;
800=> C: DimName;
801Dyn(data.len() / C::dim()), C::name();
802);
803
804#[cfg(any(feature = "std", feature = "alloc"))]
805impl_constructors_from_data!(data; Dyn, Dyn;
806                            ;
807                            Dyn(nrows), Dyn(ncols);
808                            nrows, ncols);
809
810/*
811 *
812 * Zero, One, Rand traits.
813 *
814 */
815impl<T, R: DimName, C: DimName> Zero for OMatrix<T, R, C>
816where
817    T: Scalar + Zero + ClosedAddAssign,
818    DefaultAllocator: Allocator<R, C>,
819{
820    #[inline]
821    fn zero() -> Self {
822        Self::from_element(T::zero())
823    }
824
825    #[inline]
826    fn is_zero(&self) -> bool {
827        self.iter().all(|e| e.is_zero())
828    }
829}
830
831impl<T, D: DimName> One for OMatrix<T, D, D>
832where
833    T: Scalar + Zero + One + ClosedMulAssign + ClosedAddAssign,
834    DefaultAllocator: Allocator<D, D>,
835{
836    #[inline]
837    fn one() -> Self {
838        Self::identity()
839    }
840}
841
842impl<T, R: DimName, C: DimName> Bounded for OMatrix<T, R, C>
843where
844    T: Scalar + Bounded,
845    DefaultAllocator: Allocator<R, C>,
846{
847    #[inline]
848    fn max_value() -> Self {
849        Self::from_element(T::max_value())
850    }
851
852    #[inline]
853    fn min_value() -> Self {
854        Self::from_element(T::min_value())
855    }
856}
857
858#[cfg(feature = "rand-no-std")]
859impl<T: Scalar, R: Dim, C: Dim> Distribution<OMatrix<T, R, C>> for Standard
860where
861    DefaultAllocator: Allocator<R, C>,
862    Standard: Distribution<T>,
863{
864    #[inline]
865    fn sample<G: Rng + ?Sized>(&self, rng: &mut G) -> OMatrix<T, R, C> {
866        let nrows = R::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
867        let ncols = C::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
868
869        OMatrix::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
870    }
871}
872
873#[cfg(feature = "arbitrary")]
874impl<T, R, C> Arbitrary for OMatrix<T, R, C>
875where
876    R: Dim,
877    C: Dim,
878    T: Scalar + Arbitrary + Send,
879    DefaultAllocator: Allocator<R, C>,
880    Owned<T, R, C>: Clone + Send,
881{
882    #[inline]
883    fn arbitrary(g: &mut Gen) -> Self {
884        let nrows = R::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
885        let ncols = C::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
886
887        Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| {
888            T::arbitrary(g)
889        })
890    }
891}
892
893// TODO(specialization): faster impls possible for D≤4 (see rand_distr::{UnitCircle, UnitSphere})
894#[cfg(feature = "rand")]
895impl<T: crate::RealField, D: DimName> Distribution<Unit<OVector<T, D>>> for Standard
896where
897    DefaultAllocator: Allocator<D>,
898    rand_distr::StandardNormal: Distribution<T>,
899{
900    /// Generate a uniformly distributed random unit vector.
901    #[inline]
902    fn sample<G: Rng + ?Sized>(&self, rng: &mut G) -> Unit<OVector<T, D>> {
903        Unit::new_normalize(OVector::from_distribution_generic(
904            D::name(),
905            Const::<1>,
906            &rand_distr::StandardNormal,
907            rng,
908        ))
909    }
910}
911
912/*
913 *
914 * Constructors for small matrices and vectors.
915 *
916 */
917
918macro_rules! transpose_array(
919    [$($a: ident),*;] => {
920        [$([$a]),*]
921    };
922    [$($a: ident),*; $($b: ident),*;] => {
923        [$([$a, $b]),*]
924    };
925    [$($a: ident),*; $($b: ident),*; $($c: ident),*;] => {
926        [$([$a, $b, $c]),*]
927    };
928    [$($a: ident),*; $($b: ident),*; $($c: ident),*; $($d: ident),*;] => {
929        [$([$a, $b, $c, $d]),*]
930    };
931    [$($a: ident),*; $($b: ident),*; $($c: ident),*; $($d: ident),*; $($e: ident),*;] => {
932        [$([$a, $b, $c, $d, $e]),*]
933    };
934    [$($a: ident),*; $($b: ident),*; $($c: ident),*; $($d: ident),*; $($e: ident),*; $($f: ident),*;] => {
935        [$([$a, $b, $c, $d, $e, $f]),*]
936    };
937);
938
939macro_rules! componentwise_constructors_impl(
940    ($($R: expr, $C: expr, [$($($args: ident),*);*] $(;)*)*) => {$(
941        impl<T> Matrix<T, Const<$R>, Const<$C>, ArrayStorage<T, $R, $C>> {
942            /// Initializes this matrix from its components.
943            #[inline]
944            #[allow(clippy::too_many_arguments)]
945            pub const fn new($($($args: T),*),*) -> Self {
946                unsafe {
947                    Self::from_data_statically_unchecked(
948                        ArrayStorage(
949                            transpose_array![
950                                $(
951                                    $($args),*
952                                ;)*
953                            ]
954                        )
955                    )
956                }
957            }
958        }
959    )*}
960);
961
962componentwise_constructors_impl!(
963    /*
964     * Square matrices 1 .. 6.
965     */
966    2, 2, [m11, m12;
967           m21, m22];
968    3, 3, [m11, m12, m13;
969          m21, m22, m23;
970          m31, m32, m33];
971    4, 4, [m11, m12, m13, m14;
972          m21, m22, m23, m24;
973          m31, m32, m33, m34;
974          m41, m42, m43, m44];
975    5, 5, [m11, m12, m13, m14, m15;
976          m21, m22, m23, m24, m25;
977          m31, m32, m33, m34, m35;
978          m41, m42, m43, m44, m45;
979          m51, m52, m53, m54, m55];
980    6, 6, [m11, m12, m13, m14, m15, m16;
981          m21, m22, m23, m24, m25, m26;
982          m31, m32, m33, m34, m35, m36;
983          m41, m42, m43, m44, m45, m46;
984          m51, m52, m53, m54, m55, m56;
985          m61, m62, m63, m64, m65, m66];
986
987    /*
988     * Rectangular matrices with 2 rows.
989     */
990    2, 3, [m11, m12, m13;
991          m21, m22, m23];
992    2, 4, [m11, m12, m13, m14;
993          m21, m22, m23, m24];
994    2, 5, [m11, m12, m13, m14, m15;
995          m21, m22, m23, m24, m25];
996    2, 6, [m11, m12, m13, m14, m15, m16;
997          m21, m22, m23, m24, m25, m26];
998
999    /*
1000     * Rectangular matrices with 3 rows.
1001     */
1002    3, 2, [m11, m12;
1003          m21, m22;
1004          m31, m32];
1005    3, 4, [m11, m12, m13, m14;
1006          m21, m22, m23, m24;
1007          m31, m32, m33, m34];
1008    3, 5, [m11, m12, m13, m14, m15;
1009          m21, m22, m23, m24, m25;
1010          m31, m32, m33, m34, m35];
1011    3, 6, [m11, m12, m13, m14, m15, m16;
1012          m21, m22, m23, m24, m25, m26;
1013          m31, m32, m33, m34, m35, m36];
1014
1015    /*
1016     * Rectangular matrices with 4 rows.
1017     */
1018    4, 2, [m11, m12;
1019          m21, m22;
1020          m31, m32;
1021          m41, m42];
1022    4, 3, [m11, m12, m13;
1023          m21, m22, m23;
1024          m31, m32, m33;
1025          m41, m42, m43];
1026    4, 5, [m11, m12, m13, m14, m15;
1027          m21, m22, m23, m24, m25;
1028          m31, m32, m33, m34, m35;
1029          m41, m42, m43, m44, m45];
1030    4, 6, [m11, m12, m13, m14, m15, m16;
1031          m21, m22, m23, m24, m25, m26;
1032          m31, m32, m33, m34, m35, m36;
1033          m41, m42, m43, m44, m45, m46];
1034
1035    /*
1036     * Rectangular matrices with 5 rows.
1037     */
1038    5, 2, [m11, m12;
1039          m21, m22;
1040          m31, m32;
1041          m41, m42;
1042          m51, m52];
1043    5, 3, [m11, m12, m13;
1044          m21, m22, m23;
1045          m31, m32, m33;
1046          m41, m42, m43;
1047          m51, m52, m53];
1048    5, 4, [m11, m12, m13, m14;
1049          m21, m22, m23, m24;
1050          m31, m32, m33, m34;
1051          m41, m42, m43, m44;
1052          m51, m52, m53, m54];
1053    5, 6, [m11, m12, m13, m14, m15, m16;
1054          m21, m22, m23, m24, m25, m26;
1055          m31, m32, m33, m34, m35, m36;
1056          m41, m42, m43, m44, m45, m46;
1057          m51, m52, m53, m54, m55, m56];
1058
1059    /*
1060     * Rectangular matrices with 6 rows.
1061     */
1062    6, 2, [m11, m12;
1063          m21, m22;
1064          m31, m32;
1065          m41, m42;
1066          m51, m52;
1067          m61, m62];
1068    6, 3, [m11, m12, m13;
1069          m21, m22, m23;
1070          m31, m32, m33;
1071          m41, m42, m43;
1072          m51, m52, m53;
1073          m61, m62, m63];
1074    6, 4, [m11, m12, m13, m14;
1075          m21, m22, m23, m24;
1076          m31, m32, m33, m34;
1077          m41, m42, m43, m44;
1078          m51, m52, m53, m54;
1079          m61, m62, m63, m64];
1080    6, 5, [m11, m12, m13, m14, m15;
1081          m21, m22, m23, m24, m25;
1082          m31, m32, m33, m34, m35;
1083          m41, m42, m43, m44, m45;
1084          m51, m52, m53, m54, m55;
1085          m61, m62, m63, m64, m65];
1086
1087    /*
1088     * Row vectors 1 .. 6.
1089     */
1090    1, 1, [x];
1091    1, 2, [x, y];
1092    1, 3, [x, y, z];
1093    1, 4, [x, y, z, w];
1094    1, 5, [x, y, z, w, a];
1095    1, 6, [x, y, z, w, a, b];
1096
1097    /*
1098     * Column vectors 1 .. 6.
1099     */
1100    2, 1, [x; y];
1101    3, 1, [x; y; z];
1102    4, 1, [x; y; z; w];
1103    5, 1, [x; y; z; w; a];
1104    6, 1, [x; y; z; w; a; b];
1105);
1106
1107/*
1108 *
1109 * Axis constructors.
1110 *
1111 */
1112impl<T, R: DimName> OVector<T, R>
1113where
1114    R: ToTypenum,
1115    T: Scalar + Zero + One,
1116    DefaultAllocator: Allocator<R>,
1117{
1118    /// The column vector with `val` as its i-th component.
1119    #[inline]
1120    pub fn ith(i: usize, val: T) -> Self {
1121        let mut res = Self::zeros();
1122        res[i] = val;
1123        res
1124    }
1125
1126    /// The column unit vector with `T::one()` as its i-th component.
1127    #[inline]
1128    pub fn ith_axis(i: usize) -> Unit<Self> {
1129        Unit::new_unchecked(Self::ith(i, T::one()))
1130    }
1131
1132    /// The column vector with a 1 as its first component, and zero elsewhere.
1133    #[inline]
1134    pub fn x() -> Self
1135    where
1136        R::Typenum: Cmp<typenum::U0, Output = Greater>,
1137    {
1138        let mut res = Self::zeros();
1139        unsafe {
1140            *res.vget_unchecked_mut(0) = T::one();
1141        }
1142
1143        res
1144    }
1145
1146    /// The column vector with a 1 as its second component, and zero elsewhere.
1147    #[inline]
1148    pub fn y() -> Self
1149    where
1150        R::Typenum: Cmp<typenum::U1, Output = Greater>,
1151    {
1152        let mut res = Self::zeros();
1153        unsafe {
1154            *res.vget_unchecked_mut(1) = T::one();
1155        }
1156
1157        res
1158    }
1159
1160    /// The column vector with a 1 as its third component, and zero elsewhere.
1161    #[inline]
1162    pub fn z() -> Self
1163    where
1164        R::Typenum: Cmp<typenum::U2, Output = Greater>,
1165    {
1166        let mut res = Self::zeros();
1167        unsafe {
1168            *res.vget_unchecked_mut(2) = T::one();
1169        }
1170
1171        res
1172    }
1173
1174    /// The column vector with a 1 as its fourth component, and zero elsewhere.
1175    #[inline]
1176    pub fn w() -> Self
1177    where
1178        R::Typenum: Cmp<typenum::U3, Output = Greater>,
1179    {
1180        let mut res = Self::zeros();
1181        unsafe {
1182            *res.vget_unchecked_mut(3) = T::one();
1183        }
1184
1185        res
1186    }
1187
1188    /// The column vector with a 1 as its fifth component, and zero elsewhere.
1189    #[inline]
1190    pub fn a() -> Self
1191    where
1192        R::Typenum: Cmp<typenum::U4, Output = Greater>,
1193    {
1194        let mut res = Self::zeros();
1195        unsafe {
1196            *res.vget_unchecked_mut(4) = T::one();
1197        }
1198
1199        res
1200    }
1201
1202    /// The column vector with a 1 as its sixth component, and zero elsewhere.
1203    #[inline]
1204    pub fn b() -> Self
1205    where
1206        R::Typenum: Cmp<typenum::U5, Output = Greater>,
1207    {
1208        let mut res = Self::zeros();
1209        unsafe {
1210            *res.vget_unchecked_mut(5) = T::one();
1211        }
1212
1213        res
1214    }
1215
1216    /// The unit column vector with a 1 as its first component, and zero elsewhere.
1217    #[inline]
1218    pub fn x_axis() -> Unit<Self>
1219    where
1220        R::Typenum: Cmp<typenum::U0, Output = Greater>,
1221    {
1222        Unit::new_unchecked(Self::x())
1223    }
1224
1225    /// The unit column vector with a 1 as its second component, and zero elsewhere.
1226    #[inline]
1227    pub fn y_axis() -> Unit<Self>
1228    where
1229        R::Typenum: Cmp<typenum::U1, Output = Greater>,
1230    {
1231        Unit::new_unchecked(Self::y())
1232    }
1233
1234    /// The unit column vector with a 1 as its third component, and zero elsewhere.
1235    #[inline]
1236    pub fn z_axis() -> Unit<Self>
1237    where
1238        R::Typenum: Cmp<typenum::U2, Output = Greater>,
1239    {
1240        Unit::new_unchecked(Self::z())
1241    }
1242
1243    /// The unit column vector with a 1 as its fourth component, and zero elsewhere.
1244    #[inline]
1245    pub fn w_axis() -> Unit<Self>
1246    where
1247        R::Typenum: Cmp<typenum::U3, Output = Greater>,
1248    {
1249        Unit::new_unchecked(Self::w())
1250    }
1251
1252    /// The unit column vector with a 1 as its fifth component, and zero elsewhere.
1253    #[inline]
1254    pub fn a_axis() -> Unit<Self>
1255    where
1256        R::Typenum: Cmp<typenum::U4, Output = Greater>,
1257    {
1258        Unit::new_unchecked(Self::a())
1259    }
1260
1261    /// The unit column vector with a 1 as its sixth component, and zero elsewhere.
1262    #[inline]
1263    pub fn b_axis() -> Unit<Self>
1264    where
1265        R::Typenum: Cmp<typenum::U5, Output = Greater>,
1266    {
1267        Unit::new_unchecked(Self::b())
1268    }
1269}