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}