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