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