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