nalgebra/base/
matrix.rs

1use num::{One, Zero};
2
3use approx::{AbsDiffEq, RelativeEq, UlpsEq};
4use std::any::TypeId;
5use std::cmp::Ordering;
6use std::fmt;
7use std::hash::{Hash, Hasher};
8use std::marker::PhantomData;
9use std::mem;
10
11#[cfg(feature = "serde-serialize-no-std")]
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13
14#[cfg(feature = "rkyv-serialize-no-std")]
15use super::rkyv_wrappers::CustomPhantom;
16#[cfg(feature = "rkyv-serialize")]
17use rkyv::bytecheck;
18#[cfg(feature = "rkyv-serialize-no-std")]
19use rkyv::{with::With, Archive, Archived};
20
21use simba::scalar::{ClosedAddAssign, ClosedMulAssign, ClosedSubAssign, Field, SupersetOf};
22use simba::simd::SimdPartialOrd;
23
24use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR};
25use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
26use crate::base::dimension::{Dim, DimAdd, DimSum, IsNotStaticOne, U1, U2, U3};
27use crate::base::iter::{
28    ColumnIter, ColumnIterMut, MatrixIter, MatrixIterMut, RowIter, RowIterMut,
29};
30use crate::base::storage::{Owned, RawStorage, RawStorageMut, SameShapeStorage};
31use crate::base::{Const, DefaultAllocator, OMatrix, OVector, Scalar, Unit};
32use crate::{ArrayStorage, SMatrix, SimdComplexField, Storage, UninitMatrix};
33
34use crate::storage::IsContiguous;
35use crate::uninit::{Init, InitStatus, Uninit};
36#[cfg(any(feature = "std", feature = "alloc"))]
37use crate::{DMatrix, DVector, Dyn, RowDVector, VecStorage};
38use std::mem::MaybeUninit;
39
40/// A square matrix.
41pub type SquareMatrix<T, D, S> = Matrix<T, D, D, S>;
42
43/// A matrix with one column and `D` rows.
44pub type Vector<T, D, S> = Matrix<T, D, U1, S>;
45
46/// A matrix with one row and `D` columns .
47pub type RowVector<T, D, S> = Matrix<T, U1, D, S>;
48
49/// The type of the result of a matrix sum.
50pub type MatrixSum<T, R1, C1, R2, C2> =
51    Matrix<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>, SameShapeStorage<T, R1, C1, R2, C2>>;
52
53/// The type of the result of a matrix sum.
54pub type VectorSum<T, R1, R2> =
55    Matrix<T, SameShapeR<R1, R2>, U1, SameShapeStorage<T, R1, U1, R2, U1>>;
56
57/// The type of the result of a matrix cross product.
58pub type MatrixCross<T, R1, C1, R2, C2> =
59    Matrix<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>, SameShapeStorage<T, R1, C1, R2, C2>>;
60
61/// The most generic column-major matrix (and vector) type.
62///
63/// # Methods summary
64/// Because `Matrix` is the most generic types used as a common representation of all matrices and
65/// vectors of **nalgebra** this documentation page contains every single matrix/vector-related
66/// method. In order to make browsing this page simpler, the next subsections contain direct links
67/// to groups of methods related to a specific topic.
68///
69/// #### Vector and matrix construction
70/// - [Constructors of statically-sized vectors or statically-sized matrices](#constructors-of-statically-sized-vectors-or-statically-sized-matrices)
71///   (`Vector3`, `Matrix3x6`…)
72/// - [Constructors of fully dynamic matrices](#constructors-of-fully-dynamic-matrices) (`DMatrix`)
73/// - [Constructors of dynamic vectors and matrices with a dynamic number of rows](#constructors-of-dynamic-vectors-and-matrices-with-a-dynamic-number-of-rows)
74///   (`DVector`, `MatrixXx3`…)
75/// - [Constructors of matrices with a dynamic number of columns](#constructors-of-matrices-with-a-dynamic-number-of-columns)
76///   (`Matrix2xX`…)
77/// - [Generic constructors](#generic-constructors)
78///   (For code generic wrt. the vectors or matrices dimensions.)
79///
80/// #### Computer graphics utilities for transformations
81/// - [2D transformations as a Matrix3 <span style="float:right;">`new_rotation`…</span>](#2d-transformations-as-a-matrix3)
82/// - [3D transformations as a Matrix4 <span style="float:right;">`new_rotation`, `new_perspective`, `look_at_rh`…</span>](#3d-transformations-as-a-matrix4)
83/// - [Translation and scaling in any dimension <span style="float:right;">`new_scaling`, `new_translation`…</span>](#translation-and-scaling-in-any-dimension)
84/// - [Append/prepend translation and scaling <span style="float:right;">`append_scaling`, `prepend_translation_mut`…</span>](#appendprepend-translation-and-scaling)
85/// - [Transformation of vectors and points <span style="float:right;">`transform_vector`, `transform_point`…</span>](#transformation-of-vectors-and-points)
86///
87/// #### Common math operations
88/// - [Componentwise operations <span style="float:right;">`component_mul`, `component_div`, `inf`…</span>](#componentwise-operations)
89/// - [Special multiplications <span style="float:right;">`tr_mul`, `ad_mul`, `kronecker`…</span>](#special-multiplications)
90/// - [Dot/scalar product <span style="float:right;">`dot`, `dotc`, `tr_dot`…</span>](#dotscalar-product)
91/// - [Cross product <span style="float:right;">`cross`, `perp`…</span>](#cross-product)
92/// - [Magnitude and norms <span style="float:right;">`norm`, `normalize`, `metric_distance`…</span>](#magnitude-and-norms)
93/// - [In-place normalization <span style="float:right;">`normalize_mut`, `try_normalize_mut`…</span>](#in-place-normalization)
94/// - [Interpolation <span style="float:right;">`lerp`, `slerp`…</span>](#interpolation)
95/// - [BLAS functions <span style="float:right;">`gemv`, `gemm`, `syger`…</span>](#blas-functions)
96/// - [Swizzling <span style="float:right;">`xx`, `yxz`…</span>](#swizzling)
97/// - [Triangular matrix extraction <span style="float:right;">`upper_triangle`, `lower_triangle`</span>](#triangular-matrix-extraction)
98///
99/// #### Statistics
100/// - [Common operations <span style="float:right;">`row_sum`, `column_mean`, `variance`…</span>](#common-statistics-operations)
101/// - [Find the min and max components <span style="float:right;">`min`, `max`, `amin`, `amax`, `camin`, `cmax`…</span>](#find-the-min-and-max-components)
102/// - [Find the min and max components (vector-specific methods) <span style="float:right;">`argmin`, `argmax`, `icamin`, `icamax`…</span>](#find-the-min-and-max-components-vector-specific-methods)
103///
104/// #### Iteration, map, and fold
105/// - [Iteration on components, rows, and columns <span style="float:right;">`iter`, `column_iter`…</span>](#iteration-on-components-rows-and-columns)
106/// - [Parallel iterators using rayon <span style="float:right;">`par_column_iter`, `par_column_iter_mut`…</span>](#parallel-iterators-using-rayon)
107/// - [Elementwise mapping and folding <span style="float:right;">`map`, `fold`, `zip_map`…</span>](#elementwise-mapping-and-folding)
108/// - [Folding or columns and rows <span style="float:right;">`compress_rows`, `compress_columns`…</span>](#folding-on-columns-and-rows)
109///
110/// #### Vector and matrix views
111/// - [Creating matrix views from `&[T]` <span style="float:right;">`from_slice`, `from_slice_with_strides`…</span>](#creating-matrix-views-from-t)
112/// - [Creating mutable matrix views from `&mut [T]` <span style="float:right;">`from_slice_mut`, `from_slice_with_strides_mut`…</span>](#creating-mutable-matrix-views-from-mut-t)
113/// - [Views based on index and length <span style="float:right;">`row`, `columns`, `view`…</span>](#views-based-on-index-and-length)
114/// - [Mutable views based on index and length <span style="float:right;">`row_mut`, `columns_mut`, `view_mut`…</span>](#mutable-views-based-on-index-and-length)
115/// - [Views based on ranges <span style="float:right;">`rows_range`, `columns_range`…</span>](#views-based-on-ranges)
116/// - [Mutable views based on ranges <span style="float:right;">`rows_range_mut`, `columns_range_mut`…</span>](#mutable-views-based-on-ranges)
117///
118/// #### In-place modification of a single matrix or vector
119/// - [In-place filling <span style="float:right;">`fill`, `fill_diagonal`, `fill_with_identity`…</span>](#in-place-filling)
120/// - [In-place swapping <span style="float:right;">`swap`, `swap_columns`…</span>](#in-place-swapping)
121/// - [Set rows, columns, and diagonal <span style="float:right;">`set_column`, `set_diagonal`…</span>](#set-rows-columns-and-diagonal)
122///
123/// #### Vector and matrix size modification
124/// - [Rows and columns insertion <span style="float:right;">`insert_row`, `insert_column`…</span>](#rows-and-columns-insertion)
125/// - [Rows and columns removal <span style="float:right;">`remove_row`, `remove column`…</span>](#rows-and-columns-removal)
126/// - [Rows and columns extraction <span style="float:right;">`select_rows`, `select_columns`…</span>](#rows-and-columns-extraction)
127/// - [Resizing and reshaping <span style="float:right;">`resize`, `reshape_generic`…</span>](#resizing-and-reshaping)
128/// - [In-place resizing <span style="float:right;">`resize_mut`, `resize_vertically_mut`…</span>](#in-place-resizing)
129///
130/// #### Matrix decomposition
131/// - [Rectangular matrix decomposition <span style="float:right;">`qr`, `lu`, `svd`…</span>](#rectangular-matrix-decomposition)
132/// - [Square matrix decomposition <span style="float:right;">`cholesky`, `symmetric_eigen`…</span>](#square-matrix-decomposition)
133///
134/// #### Vector basis computation
135/// - [Basis and orthogonalization <span style="float:right;">`orthonormal_subspace_basis`, `orthonormalize`…</span>](#basis-and-orthogonalization)
136///
137/// # Type parameters
138/// The generic `Matrix` type has four type parameters:
139/// - `T`: for the matrix components scalar type.
140/// - `R`: for the matrix number of rows.
141/// - `C`: for the matrix number of columns.
142/// - `S`: for the matrix data storage, i.e., the buffer that actually contains the matrix
143///   components.
144///
145/// The matrix dimensions parameters `R` and `C` can either be:
146/// - type-level unsigned integer constants (e.g. `U1`, `U124`) from the `nalgebra::` root module.
147///   All numbers from 0 to 127 are defined that way.
148/// - type-level unsigned integer constants (e.g. `U1024`, `U10000`) from the `typenum::` crate.
149///   Using those, you will not get error messages as nice as for numbers smaller than 128 defined on
150///   the `nalgebra::` module.
151/// - the special value `Dyn` from the `nalgebra::` root module. This indicates that the
152///   specified dimension is not known at compile-time. Note that this will generally imply that the
153///   matrix data storage `S` performs a dynamic allocation and contains extra metadata for the
154///   matrix shape.
155///
156/// Note that mixing `Dyn` with type-level unsigned integers is allowed. Actually, a
157/// dynamically-sized column vector should be represented as a `Matrix<T, Dyn, U1, S>` (given
158/// some concrete types for `T` and a compatible data storage type `S`).
159#[repr(C)]
160#[derive(Clone, Copy)]
161#[cfg_attr(
162    feature = "rkyv-serialize-no-std",
163    derive(Archive, rkyv::Serialize, rkyv::Deserialize),
164    archive(
165        as = "Matrix<T::Archived, R, C, S::Archived>",
166        bound(archive = "
167        T: Archive,
168        S: Archive,
169        With<PhantomData<(T, R, C)>, CustomPhantom<(Archived<T>, R, C)>>: Archive<Archived = PhantomData<(Archived<T>, R, C)>>
170    ")
171    )
172)]
173#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
174pub struct Matrix<T, R, C, S> {
175    /// The data storage that contains all the matrix components. Disappointed?
176    ///
177    /// Well, if you came here to see how you can access the matrix components,
178    /// you may be in luck: you can access the individual components of all vectors with compile-time
179    /// dimensions <= 6 using field notation like this:
180    /// `vec.x`, `vec.y`, `vec.z`, `vec.w`, `vec.a`, `vec.b`. Reference and assignation work too:
181    /// ```
182    /// # use nalgebra::Vector3;
183    /// let mut vec = Vector3::new(1.0, 2.0, 3.0);
184    /// vec.x = 10.0;
185    /// vec.y += 30.0;
186    /// assert_eq!(vec.x, 10.0);
187    /// assert_eq!(vec.y + 100.0, 132.0);
188    /// ```
189    /// Similarly, for matrices with compile-time dimensions <= 6, you can use field notation
190    /// like this: `mat.m11`, `mat.m42`, etc. The first digit identifies the row to address
191    /// and the second digit identifies the column to address. So `mat.m13` identifies the component
192    /// at the first row and third column (note that the count of rows and columns start at 1 instead
193    /// of 0 here. This is so we match the mathematical notation).
194    ///
195    /// For all matrices and vectors, independently from their size, individual components can
196    /// be accessed and modified using indexing: `vec[20]`, `mat[(20, 19)]`. Here the indexing
197    /// starts at 0 as you would expect.
198    pub data: S,
199
200    // NOTE: the fact that this field is private is important because
201    //       this prevents the user from constructing a matrix with
202    //       dimensions R, C that don't match the dimension of the
203    //       storage S. Instead they have to use the unsafe function
204    //       from_data_statically_unchecked.
205    //       Note that it would probably make sense to just have
206    //       the type `Matrix<S>`, and have `T, R, C` be associated-types
207    //       of the `RawStorage` trait. However, because we don't have
208    //       specialization, this is not possible because these `T, R, C`
209    //       allows us to desambiguate a lot of configurations.
210    #[cfg_attr(feature = "rkyv-serialize-no-std", with(CustomPhantom<(T::Archived, R, C)>))]
211    _phantoms: PhantomData<(T, R, C)>,
212}
213
214impl<T, R: Dim, C: Dim, S: fmt::Debug> fmt::Debug for Matrix<T, R, C, S> {
215    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
216        self.data.fmt(formatter)
217    }
218}
219
220impl<T, R, C, S> Default for Matrix<T, R, C, S>
221where
222    T: Scalar,
223    R: Dim,
224    C: Dim,
225    S: Default,
226{
227    fn default() -> Self {
228        Matrix {
229            data: Default::default(),
230            _phantoms: PhantomData,
231        }
232    }
233}
234
235#[cfg(feature = "serde-serialize-no-std")]
236impl<T, R, C, S> Serialize for Matrix<T, R, C, S>
237where
238    T: Scalar,
239    R: Dim,
240    C: Dim,
241    S: Serialize,
242{
243    fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
244    where
245        Ser: Serializer,
246    {
247        self.data.serialize(serializer)
248    }
249}
250
251#[cfg(feature = "serde-serialize-no-std")]
252impl<'de, T, R, C, S> Deserialize<'de> for Matrix<T, R, C, S>
253where
254    T: Scalar,
255    R: Dim,
256    C: Dim,
257    S: Deserialize<'de>,
258{
259    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
260    where
261        D: Deserializer<'de>,
262    {
263        S::deserialize(deserializer).map(|x| Matrix {
264            data: x,
265            _phantoms: PhantomData,
266        })
267    }
268}
269
270#[cfg(feature = "compare")]
271impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> matrixcompare_core::Matrix<T>
272    for Matrix<T, R, C, S>
273{
274    fn rows(&self) -> usize {
275        self.nrows()
276    }
277
278    fn cols(&self) -> usize {
279        self.ncols()
280    }
281
282    fn access(&self) -> matrixcompare_core::Access<'_, T> {
283        matrixcompare_core::Access::Dense(self)
284    }
285}
286
287#[cfg(feature = "compare")]
288impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> matrixcompare_core::DenseAccess<T>
289    for Matrix<T, R, C, S>
290{
291    fn fetch_single(&self, row: usize, col: usize) -> T {
292        self.index((row, col)).clone()
293    }
294}
295
296#[cfg(feature = "bytemuck")]
297unsafe impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> bytemuck::Zeroable
298    for Matrix<T, R, C, S>
299where
300    S: bytemuck::Zeroable,
301{
302}
303
304#[cfg(feature = "bytemuck")]
305unsafe impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> bytemuck::Pod for Matrix<T, R, C, S>
306where
307    S: bytemuck::Pod,
308    Self: Copy,
309{
310}
311
312impl<T, R, C, S> Matrix<T, R, C, S> {
313    /// Creates a new matrix with the given data without statically checking that the matrix
314    /// dimension matches the storage dimension.
315    ///
316    /// # Safety
317    ///
318    /// The storage dimension must match the given dimensions.
319    #[inline(always)]
320    pub const unsafe fn from_data_statically_unchecked(data: S) -> Matrix<T, R, C, S> {
321        Matrix {
322            data,
323            _phantoms: PhantomData,
324        }
325    }
326}
327
328impl<T, const R: usize, const C: usize> SMatrix<T, R, C> {
329    /// Creates a new statically-allocated matrix from the given [`ArrayStorage`].
330    ///
331    /// This method exists primarily as a workaround for the fact that `from_data` can not
332    /// work in `const fn` contexts.
333    #[inline(always)]
334    pub const fn from_array_storage(storage: ArrayStorage<T, R, C>) -> Self {
335        // This is sound because the row and column types are exactly the same as that of the
336        // storage, so there can be no mismatch
337        unsafe { Self::from_data_statically_unchecked(storage) }
338    }
339}
340
341// TODO: Consider removing/deprecating `from_vec_storage` once we are able to make
342// `from_data` const fn compatible
343#[cfg(any(feature = "std", feature = "alloc"))]
344impl<T> DMatrix<T> {
345    /// Creates a new heap-allocated matrix from the given [`VecStorage`].
346    ///
347    /// This method exists primarily as a workaround for the fact that `from_data` can not
348    /// work in `const fn` contexts.
349    pub const fn from_vec_storage(storage: VecStorage<T, Dyn, Dyn>) -> Self {
350        // This is sound because the dimensions of the matrix and the storage are guaranteed
351        // to be the same
352        unsafe { Self::from_data_statically_unchecked(storage) }
353    }
354}
355
356// TODO: Consider removing/deprecating `from_vec_storage` once we are able to make
357// `from_data` const fn compatible
358#[cfg(any(feature = "std", feature = "alloc"))]
359impl<T> DVector<T> {
360    /// Creates a new heap-allocated matrix from the given [`VecStorage`].
361    ///
362    /// This method exists primarily as a workaround for the fact that `from_data` can not
363    /// work in `const fn` contexts.
364    pub const fn from_vec_storage(storage: VecStorage<T, Dyn, U1>) -> Self {
365        // This is sound because the dimensions of the matrix and the storage are guaranteed
366        // to be the same
367        unsafe { Self::from_data_statically_unchecked(storage) }
368    }
369}
370
371// TODO: Consider removing/deprecating `from_vec_storage` once we are able to make
372// `from_data` const fn compatible
373#[cfg(any(feature = "std", feature = "alloc"))]
374impl<T> RowDVector<T> {
375    /// Creates a new heap-allocated matrix from the given [`VecStorage`].
376    ///
377    /// This method exists primarily as a workaround for the fact that `from_data` can not
378    /// work in `const fn` contexts.
379    pub const fn from_vec_storage(storage: VecStorage<T, U1, Dyn>) -> Self {
380        // This is sound because the dimensions of the matrix and the storage are guaranteed
381        // to be the same
382        unsafe { Self::from_data_statically_unchecked(storage) }
383    }
384}
385
386impl<T: Scalar, R: Dim, C: Dim> UninitMatrix<T, R, C>
387where
388    DefaultAllocator: Allocator<R, C>,
389{
390    /// Assumes a matrix's entries to be initialized. This operation should be near zero-cost.
391    ///
392    /// # Safety
393    /// The user must make sure that every single entry of the buffer has been initialized,
394    /// or Undefined Behavior will immediately occur.
395    #[inline(always)]
396    pub unsafe fn assume_init(self) -> OMatrix<T, R, C> {
397        OMatrix::from_data(<DefaultAllocator as Allocator<R, C>>::assume_init(
398            self.data,
399        ))
400    }
401}
402
403impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
404    /// Creates a new matrix with the given data.
405    #[inline(always)]
406    pub fn from_data(data: S) -> Self {
407        unsafe { Self::from_data_statically_unchecked(data) }
408    }
409
410    /// The shape of this matrix returned as the tuple (number of rows, number of columns).
411    ///
412    /// # Example
413    /// ```
414    /// # use nalgebra::Matrix3x4;
415    /// let mat = Matrix3x4::<f32>::zeros();
416    /// assert_eq!(mat.shape(), (3, 4));
417    /// ```
418    #[inline]
419    #[must_use]
420    pub fn shape(&self) -> (usize, usize) {
421        let (nrows, ncols) = self.shape_generic();
422        (nrows.value(), ncols.value())
423    }
424
425    /// The shape of this matrix wrapped into their representative types (`Const` or `Dyn`).
426    #[inline]
427    #[must_use]
428    pub fn shape_generic(&self) -> (R, C) {
429        self.data.shape()
430    }
431
432    /// The number of rows of this matrix.
433    ///
434    /// # Example
435    /// ```
436    /// # use nalgebra::Matrix3x4;
437    /// let mat = Matrix3x4::<f32>::zeros();
438    /// assert_eq!(mat.nrows(), 3);
439    /// ```
440    #[inline]
441    #[must_use]
442    pub fn nrows(&self) -> usize {
443        self.shape().0
444    }
445
446    /// The number of columns of this matrix.
447    ///
448    /// # Example
449    /// ```
450    /// # use nalgebra::Matrix3x4;
451    /// let mat = Matrix3x4::<f32>::zeros();
452    /// assert_eq!(mat.ncols(), 4);
453    /// ```
454    #[inline]
455    #[must_use]
456    pub fn ncols(&self) -> usize {
457        self.shape().1
458    }
459
460    /// The strides (row stride, column stride) of this matrix.
461    ///
462    /// # Example
463    /// ```
464    /// # use nalgebra::DMatrix;
465    /// let mat = DMatrix::<f32>::zeros(10, 10);
466    /// let view = mat.view_with_steps((0, 0), (5, 3), (1, 2));
467    /// // The column strides is the number of steps (here 2) multiplied by the corresponding dimension.
468    /// assert_eq!(mat.strides(), (1, 10));
469    /// ```
470    #[inline]
471    #[must_use]
472    pub fn strides(&self) -> (usize, usize) {
473        let (srows, scols) = self.data.strides();
474        (srows.value(), scols.value())
475    }
476
477    /// Computes the row and column coordinates of the i-th element of this matrix seen as a
478    /// vector.
479    ///
480    /// # Example
481    /// ```
482    /// # use nalgebra::Matrix2;
483    /// let m = Matrix2::new(1, 2,
484    ///                      3, 4);
485    /// let i = m.vector_to_matrix_index(3);
486    /// assert_eq!(i, (1, 1));
487    /// assert_eq!(m[i], m[3]);
488    /// ```
489    #[inline]
490    #[must_use]
491    pub fn vector_to_matrix_index(&self, i: usize) -> (usize, usize) {
492        let (nrows, ncols) = self.shape();
493
494        // Two most common uses that should be optimized by the compiler for statically-sized
495        // matrices.
496        if nrows == 1 {
497            (0, i)
498        } else if ncols == 1 {
499            (i, 0)
500        } else {
501            (i % nrows, i / nrows)
502        }
503    }
504
505    /// Returns a pointer to the start of the matrix.
506    ///
507    /// If the matrix is not empty, this pointer is guaranteed to be aligned
508    /// and non-null.
509    ///
510    /// # Example
511    /// ```
512    /// # use nalgebra::Matrix2;
513    /// let m = Matrix2::new(1, 2,
514    ///                      3, 4);
515    /// let ptr = m.as_ptr();
516    /// assert_eq!(unsafe { *ptr }, m[0]);
517    /// ```
518    #[inline]
519    #[must_use]
520    pub fn as_ptr(&self) -> *const T {
521        self.data.ptr()
522    }
523
524    /// Tests whether `self` and `rhs` are equal up to a given epsilon.
525    ///
526    /// See `relative_eq` from the `RelativeEq` trait for more details.
527    #[inline]
528    #[must_use]
529    pub fn relative_eq<R2, C2, SB>(
530        &self,
531        other: &Matrix<T, R2, C2, SB>,
532        eps: T::Epsilon,
533        max_relative: T::Epsilon,
534    ) -> bool
535    where
536        T: RelativeEq + Scalar,
537        R2: Dim,
538        C2: Dim,
539        SB: Storage<T, R2, C2>,
540        T::Epsilon: Clone,
541        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
542    {
543        assert!(self.shape() == other.shape());
544        self.iter()
545            .zip(other.iter())
546            .all(|(a, b)| a.relative_eq(b, eps.clone(), max_relative.clone()))
547    }
548
549    /// Tests whether `self` and `rhs` are exactly equal.
550    #[inline]
551    #[must_use]
552    #[allow(clippy::should_implement_trait)]
553    pub fn eq<R2, C2, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> bool
554    where
555        T: PartialEq,
556        R2: Dim,
557        C2: Dim,
558        SB: RawStorage<T, R2, C2>,
559        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
560    {
561        assert!(self.shape() == other.shape());
562        self.iter().zip(other.iter()).all(|(a, b)| *a == *b)
563    }
564
565    /// Moves this matrix into one that owns its data.
566    #[inline]
567    pub fn into_owned(self) -> OMatrix<T, R, C>
568    where
569        T: Scalar,
570        S: Storage<T, R, C>,
571        DefaultAllocator: Allocator<R, C>,
572    {
573        Matrix::from_data(self.data.into_owned())
574    }
575
576    // TODO: this could probably benefit from specialization.
577    // XXX: bad name.
578    /// Moves this matrix into one that owns its data. The actual type of the result depends on
579    /// matrix storage combination rules for addition.
580    #[inline]
581    pub fn into_owned_sum<R2, C2>(self) -> MatrixSum<T, R, C, R2, C2>
582    where
583        T: Scalar,
584        S: Storage<T, R, C>,
585        R2: Dim,
586        C2: Dim,
587        DefaultAllocator: SameShapeAllocator<R, C, R2, C2>,
588        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
589    {
590        if TypeId::of::<SameShapeStorage<T, R, C, R2, C2>>() == TypeId::of::<Owned<T, R, C>>() {
591            // We can just return `self.into_owned()`.
592
593            unsafe {
594                // TODO: check that those copies are optimized away by the compiler.
595                let owned = self.into_owned();
596                let res = mem::transmute_copy(&owned);
597                mem::forget(owned);
598                res
599            }
600        } else {
601            self.clone_owned_sum()
602        }
603    }
604
605    /// Clones this matrix to one that owns its data.
606    #[inline]
607    #[must_use]
608    pub fn clone_owned(&self) -> OMatrix<T, R, C>
609    where
610        T: Scalar,
611        S: Storage<T, R, C>,
612        DefaultAllocator: Allocator<R, C>,
613    {
614        Matrix::from_data(self.data.clone_owned())
615    }
616
617    /// Clones this matrix into one that owns its data. The actual type of the result depends on
618    /// matrix storage combination rules for addition.
619    #[inline]
620    #[must_use]
621    pub fn clone_owned_sum<R2, C2>(&self) -> MatrixSum<T, R, C, R2, C2>
622    where
623        T: Scalar,
624        S: Storage<T, R, C>,
625        R2: Dim,
626        C2: Dim,
627        DefaultAllocator: SameShapeAllocator<R, C, R2, C2>,
628        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
629    {
630        let (nrows, ncols) = self.shape();
631        let nrows: SameShapeR<R, R2> = Dim::from_usize(nrows);
632        let ncols: SameShapeC<C, C2> = Dim::from_usize(ncols);
633
634        let mut res = Matrix::uninit(nrows, ncols);
635
636        unsafe {
637            // TODO: use copy_from?
638            for j in 0..res.ncols() {
639                for i in 0..res.nrows() {
640                    *res.get_unchecked_mut((i, j)) =
641                        MaybeUninit::new(self.get_unchecked((i, j)).clone());
642                }
643            }
644
645            // SAFETY: the output has been initialized above.
646            res.assume_init()
647        }
648    }
649
650    /// Transposes `self` and store the result into `out`.
651    #[inline]
652    fn transpose_to_uninit<Status, R2, C2, SB>(
653        &self,
654        _status: Status,
655        out: &mut Matrix<Status::Value, R2, C2, SB>,
656    ) where
657        Status: InitStatus<T>,
658        T: Scalar,
659        R2: Dim,
660        C2: Dim,
661        SB: RawStorageMut<Status::Value, R2, C2>,
662        ShapeConstraint: SameNumberOfRows<R, C2> + SameNumberOfColumns<C, R2>,
663    {
664        let (nrows, ncols) = self.shape();
665        assert!(
666            (ncols, nrows) == out.shape(),
667            "Incompatible shape for transposition."
668        );
669
670        // TODO: optimize that.
671        for i in 0..nrows {
672            for j in 0..ncols {
673                // Safety: the indices are in range.
674                unsafe {
675                    Status::init(
676                        out.get_unchecked_mut((j, i)),
677                        self.get_unchecked((i, j)).clone(),
678                    );
679                }
680            }
681        }
682    }
683
684    /// Transposes `self` and store the result into `out`.
685    #[inline]
686    pub fn transpose_to<R2, C2, SB>(&self, out: &mut Matrix<T, R2, C2, SB>)
687    where
688        T: Scalar,
689        R2: Dim,
690        C2: Dim,
691        SB: RawStorageMut<T, R2, C2>,
692        ShapeConstraint: SameNumberOfRows<R, C2> + SameNumberOfColumns<C, R2>,
693    {
694        self.transpose_to_uninit(Init, out)
695    }
696
697    /// Transposes `self`.
698    #[inline]
699    #[must_use = "Did you mean to use transpose_mut()?"]
700    pub fn transpose(&self) -> OMatrix<T, C, R>
701    where
702        T: Scalar,
703        DefaultAllocator: Allocator<C, R>,
704    {
705        let (nrows, ncols) = self.shape_generic();
706
707        let mut res = Matrix::uninit(ncols, nrows);
708        self.transpose_to_uninit(Uninit, &mut res);
709        // Safety: res is now fully initialized.
710        unsafe { res.assume_init() }
711    }
712}
713
714/// # Elementwise mapping and folding
715impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
716    /// Returns a matrix containing the result of `f` applied to each of its entries.
717    #[inline]
718    #[must_use]
719    pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
720    where
721        T: Scalar,
722        DefaultAllocator: Allocator<R, C>,
723    {
724        let (nrows, ncols) = self.shape_generic();
725        let mut res = Matrix::uninit(nrows, ncols);
726
727        for j in 0..ncols.value() {
728            for i in 0..nrows.value() {
729                // Safety: all indices are in range.
730                unsafe {
731                    let a = self.data.get_unchecked(i, j).clone();
732                    *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a));
733                }
734            }
735        }
736
737        // Safety: res is now fully initialized.
738        unsafe { res.assume_init() }
739    }
740
741    /// Cast the components of `self` to another type.
742    ///
743    /// # Example
744    /// ```
745    /// # use nalgebra::Vector3;
746    /// let q = Vector3::new(1.0f64, 2.0, 3.0);
747    /// let q2 = q.cast::<f32>();
748    /// assert_eq!(q2, Vector3::new(1.0f32, 2.0, 3.0));
749    /// ```
750    pub fn cast<T2: Scalar>(self) -> OMatrix<T2, R, C>
751    where
752        T: Scalar,
753        OMatrix<T2, R, C>: SupersetOf<Self>,
754        DefaultAllocator: Allocator<R, C>,
755    {
756        crate::convert(self)
757    }
758
759    /// Attempts to cast the components of `self` to another type.
760    ///
761    /// # Example
762    /// ```
763    /// # use nalgebra::Vector3;
764    /// let q = Vector3::new(1.0f64, 2.0, 3.0);
765    /// let q2 = q.try_cast::<i32>();
766    /// assert_eq!(q2, Some(Vector3::new(1, 2, 3)));
767    /// ```
768    pub fn try_cast<T2: Scalar>(self) -> Option<OMatrix<T2, R, C>>
769    where
770        T: Scalar,
771        Self: SupersetOf<OMatrix<T2, R, C>>,
772        DefaultAllocator: Allocator<R, C>,
773    {
774        crate::try_convert(self)
775    }
776
777    /// Similar to `self.iter().fold(init, f)` except that `init` is replaced by a closure.
778    ///
779    /// The initialization closure is given the first component of this matrix:
780    /// - If the matrix has no component (0 rows or 0 columns) then `init_f` is called with `None`
781    ///   and its return value is the value returned by this method.
782    /// - If the matrix has has least one component, then `init_f` is called with the first component
783    ///   to compute the initial value. Folding then continues on all the remaining components of the matrix.
784    #[inline]
785    #[must_use]
786    pub fn fold_with<T2>(
787        &self,
788        init_f: impl FnOnce(Option<&T>) -> T2,
789        f: impl FnMut(T2, &T) -> T2,
790    ) -> T2
791    where
792        T: Scalar,
793    {
794        let mut it = self.iter();
795        let init = init_f(it.next());
796        it.fold(init, f)
797    }
798
799    /// Returns a matrix containing the result of `f` applied to each of its entries. Unlike `map`,
800    /// `f` also gets passed the row and column index, i.e. `f(row, col, value)`.
801    #[inline]
802    #[must_use]
803    pub fn map_with_location<T2: Scalar, F: FnMut(usize, usize, T) -> T2>(
804        &self,
805        mut f: F,
806    ) -> OMatrix<T2, R, C>
807    where
808        T: Scalar,
809        DefaultAllocator: Allocator<R, C>,
810    {
811        let (nrows, ncols) = self.shape_generic();
812        let mut res = Matrix::uninit(nrows, ncols);
813
814        for j in 0..ncols.value() {
815            for i in 0..nrows.value() {
816                // Safety: all indices are in range.
817                unsafe {
818                    let a = self.data.get_unchecked(i, j).clone();
819                    *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(i, j, a));
820                }
821            }
822        }
823
824        // Safety: res is now fully initialized.
825        unsafe { res.assume_init() }
826    }
827
828    /// Returns a matrix containing the result of `f` applied to each entries of `self` and
829    /// `rhs`.
830    #[inline]
831    #[must_use]
832    pub fn zip_map<T2, N3, S2, F>(&self, rhs: &Matrix<T2, R, C, S2>, mut f: F) -> OMatrix<N3, R, C>
833    where
834        T: Scalar,
835        T2: Scalar,
836        N3: Scalar,
837        S2: RawStorage<T2, R, C>,
838        F: FnMut(T, T2) -> N3,
839        DefaultAllocator: Allocator<R, C>,
840    {
841        let (nrows, ncols) = self.shape_generic();
842        let mut res = Matrix::uninit(nrows, ncols);
843
844        assert_eq!(
845            (nrows.value(), ncols.value()),
846            rhs.shape(),
847            "Matrix simultaneous traversal error: dimension mismatch."
848        );
849
850        for j in 0..ncols.value() {
851            for i in 0..nrows.value() {
852                // Safety: all indices are in range.
853                unsafe {
854                    let a = self.data.get_unchecked(i, j).clone();
855                    let b = rhs.data.get_unchecked(i, j).clone();
856                    *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b))
857                }
858            }
859        }
860
861        // Safety: res is now fully initialized.
862        unsafe { res.assume_init() }
863    }
864
865    /// Returns a matrix containing the result of `f` applied to each entries of `self` and
866    /// `b`, and `c`.
867    #[inline]
868    #[must_use]
869    pub fn zip_zip_map<T2, N3, N4, S2, S3, F>(
870        &self,
871        b: &Matrix<T2, R, C, S2>,
872        c: &Matrix<N3, R, C, S3>,
873        mut f: F,
874    ) -> OMatrix<N4, R, C>
875    where
876        T: Scalar,
877        T2: Scalar,
878        N3: Scalar,
879        N4: Scalar,
880        S2: RawStorage<T2, R, C>,
881        S3: RawStorage<N3, R, C>,
882        F: FnMut(T, T2, N3) -> N4,
883        DefaultAllocator: Allocator<R, C>,
884    {
885        let (nrows, ncols) = self.shape_generic();
886        let mut res = Matrix::uninit(nrows, ncols);
887
888        assert_eq!(
889            (nrows.value(), ncols.value()),
890            b.shape(),
891            "Matrix simultaneous traversal error: dimension mismatch."
892        );
893        assert_eq!(
894            (nrows.value(), ncols.value()),
895            c.shape(),
896            "Matrix simultaneous traversal error: dimension mismatch."
897        );
898
899        for j in 0..ncols.value() {
900            for i in 0..nrows.value() {
901                // Safety: all indices are in range.
902                unsafe {
903                    let a = self.data.get_unchecked(i, j).clone();
904                    let b = b.data.get_unchecked(i, j).clone();
905                    let c = c.data.get_unchecked(i, j).clone();
906                    *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b, c))
907                }
908            }
909        }
910
911        // Safety: res is now fully initialized.
912        unsafe { res.assume_init() }
913    }
914
915    /// Folds a function `f` on each entry of `self`.
916    #[inline]
917    #[must_use]
918    pub fn fold<Acc>(&self, init: Acc, mut f: impl FnMut(Acc, T) -> Acc) -> Acc
919    where
920        T: Scalar,
921    {
922        let (nrows, ncols) = self.shape_generic();
923
924        let mut res = init;
925
926        for j in 0..ncols.value() {
927            for i in 0..nrows.value() {
928                // Safety: all indices are in range.
929                unsafe {
930                    let a = self.data.get_unchecked(i, j).clone();
931                    res = f(res, a)
932                }
933            }
934        }
935
936        res
937    }
938
939    /// Folds a function `f` on each pairs of entries from `self` and `rhs`.
940    #[inline]
941    #[must_use]
942    pub fn zip_fold<T2, R2, C2, S2, Acc>(
943        &self,
944        rhs: &Matrix<T2, R2, C2, S2>,
945        init: Acc,
946        mut f: impl FnMut(Acc, T, T2) -> Acc,
947    ) -> Acc
948    where
949        T: Scalar,
950        T2: Scalar,
951        R2: Dim,
952        C2: Dim,
953        S2: RawStorage<T2, R2, C2>,
954        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
955    {
956        let (nrows, ncols) = self.shape_generic();
957
958        let mut res = init;
959
960        assert_eq!(
961            (nrows.value(), ncols.value()),
962            rhs.shape(),
963            "Matrix simultaneous traversal error: dimension mismatch."
964        );
965
966        for j in 0..ncols.value() {
967            for i in 0..nrows.value() {
968                unsafe {
969                    let a = self.data.get_unchecked(i, j).clone();
970                    let b = rhs.data.get_unchecked(i, j).clone();
971                    res = f(res, a, b)
972                }
973            }
974        }
975
976        res
977    }
978
979    /// Applies a closure `f` to modify each component of `self`.
980    #[inline]
981    pub fn apply<F: FnMut(&mut T)>(&mut self, mut f: F)
982    where
983        S: RawStorageMut<T, R, C>,
984    {
985        let (nrows, ncols) = self.shape();
986
987        for j in 0..ncols {
988            for i in 0..nrows {
989                unsafe {
990                    let e = self.data.get_unchecked_mut(i, j);
991                    f(e)
992                }
993            }
994        }
995    }
996
997    /// Replaces each component of `self` by the result of a closure `f` applied on its components
998    /// joined with the components from `rhs`.
999    #[inline]
1000    pub fn zip_apply<T2, R2, C2, S2>(
1001        &mut self,
1002        rhs: &Matrix<T2, R2, C2, S2>,
1003        mut f: impl FnMut(&mut T, T2),
1004    ) where
1005        S: RawStorageMut<T, R, C>,
1006        T2: Scalar,
1007        R2: Dim,
1008        C2: Dim,
1009        S2: RawStorage<T2, R2, C2>,
1010        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
1011    {
1012        let (nrows, ncols) = self.shape();
1013
1014        assert_eq!(
1015            (nrows, ncols),
1016            rhs.shape(),
1017            "Matrix simultaneous traversal error: dimension mismatch."
1018        );
1019
1020        for j in 0..ncols {
1021            for i in 0..nrows {
1022                unsafe {
1023                    let e = self.data.get_unchecked_mut(i, j);
1024                    let rhs = rhs.get_unchecked((i, j)).clone();
1025                    f(e, rhs)
1026                }
1027            }
1028        }
1029    }
1030
1031    /// Replaces each component of `self` by the result of a closure `f` applied on its components
1032    /// joined with the components from `b` and `c`.
1033    #[inline]
1034    pub fn zip_zip_apply<T2, R2, C2, S2, N3, R3, C3, S3>(
1035        &mut self,
1036        b: &Matrix<T2, R2, C2, S2>,
1037        c: &Matrix<N3, R3, C3, S3>,
1038        mut f: impl FnMut(&mut T, T2, N3),
1039    ) where
1040        S: RawStorageMut<T, R, C>,
1041        T2: Scalar,
1042        R2: Dim,
1043        C2: Dim,
1044        S2: RawStorage<T2, R2, C2>,
1045        N3: Scalar,
1046        R3: Dim,
1047        C3: Dim,
1048        S3: RawStorage<N3, R3, C3>,
1049        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
1050        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
1051    {
1052        let (nrows, ncols) = self.shape();
1053
1054        assert_eq!(
1055            (nrows, ncols),
1056            b.shape(),
1057            "Matrix simultaneous traversal error: dimension mismatch."
1058        );
1059        assert_eq!(
1060            (nrows, ncols),
1061            c.shape(),
1062            "Matrix simultaneous traversal error: dimension mismatch."
1063        );
1064
1065        for j in 0..ncols {
1066            for i in 0..nrows {
1067                unsafe {
1068                    let e = self.data.get_unchecked_mut(i, j);
1069                    let b = b.get_unchecked((i, j)).clone();
1070                    let c = c.get_unchecked((i, j)).clone();
1071                    f(e, b, c)
1072                }
1073            }
1074        }
1075    }
1076}
1077
1078/// # Iteration on components, rows, and columns
1079impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
1080    /// Iterates through this matrix coordinates in column-major order.
1081    ///
1082    /// # Example
1083    /// ```
1084    /// # use nalgebra::Matrix2x3;
1085    /// let mat = Matrix2x3::new(11, 12, 13,
1086    ///                          21, 22, 23);
1087    /// let mut it = mat.iter();
1088    /// assert_eq!(*it.next().unwrap(), 11);
1089    /// assert_eq!(*it.next().unwrap(), 21);
1090    /// assert_eq!(*it.next().unwrap(), 12);
1091    /// assert_eq!(*it.next().unwrap(), 22);
1092    /// assert_eq!(*it.next().unwrap(), 13);
1093    /// assert_eq!(*it.next().unwrap(), 23);
1094    /// assert!(it.next().is_none());
1095    /// ```
1096    #[inline]
1097    pub fn iter(&self) -> MatrixIter<'_, T, R, C, S> {
1098        MatrixIter::new(&self.data)
1099    }
1100
1101    /// Iterate through the rows of this matrix.
1102    ///
1103    /// # Example
1104    /// ```
1105    /// # use nalgebra::Matrix2x3;
1106    /// let mut a = Matrix2x3::new(1, 2, 3,
1107    ///                            4, 5, 6);
1108    /// for (i, row) in a.row_iter().enumerate() {
1109    ///     assert_eq!(row, a.row(i))
1110    /// }
1111    /// ```
1112    #[inline]
1113    pub fn row_iter(&self) -> RowIter<'_, T, R, C, S> {
1114        RowIter::new(self)
1115    }
1116
1117    /// Iterate through the columns of this matrix.
1118    ///
1119    /// # Example
1120    /// ```
1121    /// # use nalgebra::Matrix2x3;
1122    /// let mut a = Matrix2x3::new(1, 2, 3,
1123    ///                            4, 5, 6);
1124    /// for (i, column) in a.column_iter().enumerate() {
1125    ///     assert_eq!(column, a.column(i))
1126    /// }
1127    /// ```
1128    #[inline]
1129    pub fn column_iter(&self) -> ColumnIter<'_, T, R, C, S> {
1130        ColumnIter::new(self)
1131    }
1132
1133    /// Mutably iterates through this matrix coordinates.
1134    #[inline]
1135    pub fn iter_mut(&mut self) -> MatrixIterMut<'_, T, R, C, S>
1136    where
1137        S: RawStorageMut<T, R, C>,
1138    {
1139        MatrixIterMut::new(&mut self.data)
1140    }
1141
1142    /// Mutably iterates through this matrix rows.
1143    ///
1144    /// # Example
1145    /// ```
1146    /// # use nalgebra::Matrix2x3;
1147    /// let mut a = Matrix2x3::new(1, 2, 3,
1148    ///                            4, 5, 6);
1149    /// for (i, mut row) in a.row_iter_mut().enumerate() {
1150    ///     row *= (i + 1) * 10;
1151    /// }
1152    ///
1153    /// let expected = Matrix2x3::new(10, 20, 30,
1154    ///                               80, 100, 120);
1155    /// assert_eq!(a, expected);
1156    /// ```
1157    #[inline]
1158    pub fn row_iter_mut(&mut self) -> RowIterMut<'_, T, R, C, S>
1159    where
1160        S: RawStorageMut<T, R, C>,
1161    {
1162        RowIterMut::new(self)
1163    }
1164
1165    /// Mutably iterates through this matrix columns.
1166    ///
1167    /// # Example
1168    /// ```
1169    /// # use nalgebra::Matrix2x3;
1170    /// let mut a = Matrix2x3::new(1, 2, 3,
1171    ///                            4, 5, 6);
1172    /// for (i, mut col) in a.column_iter_mut().enumerate() {
1173    ///     col *= (i + 1) * 10;
1174    /// }
1175    ///
1176    /// let expected = Matrix2x3::new(10, 40, 90,
1177    ///                               40, 100, 180);
1178    /// assert_eq!(a, expected);
1179    /// ```
1180    #[inline]
1181    pub fn column_iter_mut(&mut self) -> ColumnIterMut<'_, T, R, C, S>
1182    where
1183        S: RawStorageMut<T, R, C>,
1184    {
1185        ColumnIterMut::new(self)
1186    }
1187}
1188
1189impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
1190    /// Returns a mutable pointer to the start of the matrix.
1191    ///
1192    /// If the matrix is not empty, this pointer is guaranteed to be aligned
1193    /// and non-null.
1194    #[inline]
1195    pub fn as_mut_ptr(&mut self) -> *mut T {
1196        self.data.ptr_mut()
1197    }
1198
1199    /// Swaps two entries without bound-checking.
1200    ///
1201    /// # Safety
1202    ///
1203    /// Both `(r, c)` must have `r < nrows(), c < ncols()`.
1204    #[inline]
1205    pub unsafe fn swap_unchecked(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) {
1206        debug_assert!(row_cols1.0 < self.nrows() && row_cols1.1 < self.ncols());
1207        debug_assert!(row_cols2.0 < self.nrows() && row_cols2.1 < self.ncols());
1208        self.data.swap_unchecked(row_cols1, row_cols2)
1209    }
1210
1211    /// Swaps two entries.
1212    #[inline]
1213    pub fn swap(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) {
1214        let (nrows, ncols) = self.shape();
1215        assert!(
1216            row_cols1.0 < nrows && row_cols1.1 < ncols,
1217            "Matrix elements swap index out of bounds."
1218        );
1219        assert!(
1220            row_cols2.0 < nrows && row_cols2.1 < ncols,
1221            "Matrix elements swap index out of bounds."
1222        );
1223        unsafe { self.swap_unchecked(row_cols1, row_cols2) }
1224    }
1225
1226    /// Fills this matrix with the content of a slice. Both must hold the same number of elements.
1227    ///
1228    /// The components of the slice are assumed to be ordered in column-major order.
1229    #[inline]
1230    pub fn copy_from_slice(&mut self, slice: &[T])
1231    where
1232        T: Scalar,
1233    {
1234        let (nrows, ncols) = self.shape();
1235
1236        assert!(
1237            nrows * ncols == slice.len(),
1238            "The slice must contain the same number of elements as the matrix."
1239        );
1240
1241        for j in 0..ncols {
1242            for i in 0..nrows {
1243                unsafe {
1244                    *self.get_unchecked_mut((i, j)) = slice.get_unchecked(i + j * nrows).clone();
1245                }
1246            }
1247        }
1248    }
1249
1250    /// Fills this matrix with the content of another one. Both must have the same shape.
1251    #[inline]
1252    pub fn copy_from<R2, C2, SB>(&mut self, other: &Matrix<T, R2, C2, SB>)
1253    where
1254        T: Scalar,
1255        R2: Dim,
1256        C2: Dim,
1257        SB: RawStorage<T, R2, C2>,
1258        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
1259    {
1260        assert!(
1261            self.shape() == other.shape(),
1262            "Unable to copy from a matrix with a different shape."
1263        );
1264
1265        for j in 0..self.ncols() {
1266            for i in 0..self.nrows() {
1267                unsafe {
1268                    *self.get_unchecked_mut((i, j)) = other.get_unchecked((i, j)).clone();
1269                }
1270            }
1271        }
1272    }
1273
1274    /// Fills this matrix with the content of the transpose another one.
1275    #[inline]
1276    pub fn tr_copy_from<R2, C2, SB>(&mut self, other: &Matrix<T, R2, C2, SB>)
1277    where
1278        T: Scalar,
1279        R2: Dim,
1280        C2: Dim,
1281        SB: RawStorage<T, R2, C2>,
1282        ShapeConstraint: DimEq<R, C2> + SameNumberOfColumns<C, R2>,
1283    {
1284        let (nrows, ncols) = self.shape();
1285        assert!(
1286            (ncols, nrows) == other.shape(),
1287            "Unable to copy from a matrix with incompatible shape."
1288        );
1289
1290        for j in 0..ncols {
1291            for i in 0..nrows {
1292                unsafe {
1293                    *self.get_unchecked_mut((i, j)) = other.get_unchecked((j, i)).clone();
1294                }
1295            }
1296        }
1297    }
1298
1299    // TODO: rename `apply` to `apply_mut` and `apply_into` to `apply`?
1300    /// Returns `self` with each of its components replaced by the result of a closure `f` applied on it.
1301    #[inline]
1302    pub fn apply_into<F: FnMut(&mut T)>(mut self, f: F) -> Self {
1303        self.apply(f);
1304        self
1305    }
1306}
1307
1308impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
1309    /// Gets a reference to the i-th element of this column vector without bound checking.
1310    /// # Safety
1311    /// `i` must be less than `D`.
1312    #[inline]
1313    #[must_use]
1314    pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
1315        debug_assert!(i < self.nrows(), "Vector index out of bounds.");
1316        let i = i * self.strides().0;
1317        self.data.get_unchecked_linear(i)
1318    }
1319}
1320
1321impl<T, D: Dim, S: RawStorageMut<T, D>> Vector<T, D, S> {
1322    /// Gets a mutable reference to the i-th element of this column vector without bound checking.
1323    /// # Safety
1324    /// `i` must be less than `D`.
1325    #[inline]
1326    #[must_use]
1327    pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T {
1328        debug_assert!(i < self.nrows(), "Vector index out of bounds.");
1329        let i = i * self.strides().0;
1330        self.data.get_unchecked_linear_mut(i)
1331    }
1332}
1333
1334impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C> + IsContiguous> Matrix<T, R, C, S> {
1335    /// Extracts a slice containing the entire matrix entries ordered column-by-columns.
1336    #[inline]
1337    #[must_use]
1338    pub fn as_slice(&self) -> &[T] {
1339        // Safety: this is OK thanks to the IsContiguous trait.
1340        unsafe { self.data.as_slice_unchecked() }
1341    }
1342}
1343
1344impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C> + IsContiguous> AsRef<[T]> for Matrix<T, R, C, S> {
1345    /// Extracts a slice containing the entire matrix entries ordered column-by-columns.
1346    #[inline]
1347    fn as_ref(&self) -> &[T] {
1348        self.as_slice()
1349    }
1350}
1351
1352impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C> + IsContiguous> Matrix<T, R, C, S> {
1353    /// Extracts a mutable slice containing the entire matrix entries ordered column-by-columns.
1354    #[inline]
1355    #[must_use]
1356    pub fn as_mut_slice(&mut self) -> &mut [T] {
1357        // Safety: this is OK thanks to the IsContiguous trait.
1358        unsafe { self.data.as_mut_slice_unchecked() }
1359    }
1360}
1361
1362impl<T: Scalar, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S> {
1363    /// Transposes the square matrix `self` in-place.
1364    pub fn transpose_mut(&mut self) {
1365        assert!(
1366            self.is_square(),
1367            "Unable to transpose a non-square matrix in-place."
1368        );
1369
1370        let dim = self.shape().0;
1371
1372        for i in 1..dim {
1373            for j in 0..i {
1374                unsafe { self.swap_unchecked((i, j), (j, i)) }
1375            }
1376        }
1377    }
1378}
1379
1380impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
1381    /// Takes the adjoint (aka. conjugate-transpose) of `self` and store the result into `out`.
1382    #[inline]
1383    fn adjoint_to_uninit<Status, R2, C2, SB>(
1384        &self,
1385        _status: Status,
1386        out: &mut Matrix<Status::Value, R2, C2, SB>,
1387    ) where
1388        Status: InitStatus<T>,
1389        R2: Dim,
1390        C2: Dim,
1391        SB: RawStorageMut<Status::Value, R2, C2>,
1392        ShapeConstraint: SameNumberOfRows<R, C2> + SameNumberOfColumns<C, R2>,
1393    {
1394        let (nrows, ncols) = self.shape();
1395        assert!(
1396            (ncols, nrows) == out.shape(),
1397            "Incompatible shape for transpose-copy."
1398        );
1399
1400        // TODO: optimize that.
1401        for i in 0..nrows {
1402            for j in 0..ncols {
1403                // Safety: all indices are in range.
1404                unsafe {
1405                    Status::init(
1406                        out.get_unchecked_mut((j, i)),
1407                        self.get_unchecked((i, j)).clone().simd_conjugate(),
1408                    );
1409                }
1410            }
1411        }
1412    }
1413
1414    /// Takes the adjoint (aka. conjugate-transpose) of `self` and store the result into `out`.
1415    #[inline]
1416    pub fn adjoint_to<R2, C2, SB>(&self, out: &mut Matrix<T, R2, C2, SB>)
1417    where
1418        R2: Dim,
1419        C2: Dim,
1420        SB: RawStorageMut<T, R2, C2>,
1421        ShapeConstraint: SameNumberOfRows<R, C2> + SameNumberOfColumns<C, R2>,
1422    {
1423        self.adjoint_to_uninit(Init, out)
1424    }
1425
1426    /// The adjoint (aka. conjugate-transpose) of `self`.
1427    #[inline]
1428    #[must_use = "Did you mean to use adjoint_mut()?"]
1429    pub fn adjoint(&self) -> OMatrix<T, C, R>
1430    where
1431        DefaultAllocator: Allocator<C, R>,
1432    {
1433        let (nrows, ncols) = self.shape_generic();
1434
1435        let mut res = Matrix::uninit(ncols, nrows);
1436        self.adjoint_to_uninit(Uninit, &mut res);
1437
1438        // Safety: res is now fully initialized.
1439        unsafe { res.assume_init() }
1440    }
1441
1442    /// Takes the conjugate and transposes `self` and store the result into `out`.
1443    #[deprecated(note = "Renamed `self.adjoint_to(out)`.")]
1444    #[inline]
1445    pub fn conjugate_transpose_to<R2, C2, SB>(&self, out: &mut Matrix<T, R2, C2, SB>)
1446    where
1447        R2: Dim,
1448        C2: Dim,
1449        SB: RawStorageMut<T, R2, C2>,
1450        ShapeConstraint: SameNumberOfRows<R, C2> + SameNumberOfColumns<C, R2>,
1451    {
1452        self.adjoint_to(out)
1453    }
1454
1455    /// The conjugate transposition of `self`.
1456    #[deprecated(note = "Renamed `self.adjoint()`.")]
1457    #[inline]
1458    pub fn conjugate_transpose(&self) -> OMatrix<T, C, R>
1459    where
1460        DefaultAllocator: Allocator<C, R>,
1461    {
1462        self.adjoint()
1463    }
1464
1465    /// The conjugate of `self`.
1466    #[inline]
1467    #[must_use = "Did you mean to use conjugate_mut()?"]
1468    pub fn conjugate(&self) -> OMatrix<T, R, C>
1469    where
1470        DefaultAllocator: Allocator<R, C>,
1471    {
1472        self.map(|e| e.simd_conjugate())
1473    }
1474
1475    /// Divides each component of the complex matrix `self` by the given real.
1476    #[inline]
1477    #[must_use = "Did you mean to use unscale_mut()?"]
1478    pub fn unscale(&self, real: T::SimdRealField) -> OMatrix<T, R, C>
1479    where
1480        DefaultAllocator: Allocator<R, C>,
1481    {
1482        self.map(|e| e.simd_unscale(real.clone()))
1483    }
1484
1485    /// Multiplies each component of the complex matrix `self` by the given real.
1486    #[inline]
1487    #[must_use = "Did you mean to use scale_mut()?"]
1488    pub fn scale(&self, real: T::SimdRealField) -> OMatrix<T, R, C>
1489    where
1490        DefaultAllocator: Allocator<R, C>,
1491    {
1492        self.map(|e| e.simd_scale(real.clone()))
1493    }
1494}
1495
1496impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
1497    /// The conjugate of the complex matrix `self` computed in-place.
1498    #[inline]
1499    pub fn conjugate_mut(&mut self) {
1500        self.apply(|e| *e = e.clone().simd_conjugate())
1501    }
1502
1503    /// Divides each component of the complex matrix `self` by the given real.
1504    #[inline]
1505    pub fn unscale_mut(&mut self, real: T::SimdRealField) {
1506        self.apply(|e| *e = e.clone().simd_unscale(real.clone()))
1507    }
1508
1509    /// Multiplies each component of the complex matrix `self` by the given real.
1510    #[inline]
1511    pub fn scale_mut(&mut self, real: T::SimdRealField) {
1512        self.apply(|e| *e = e.clone().simd_scale(real.clone()))
1513    }
1514}
1515
1516impl<T: SimdComplexField, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S> {
1517    /// Sets `self` to its adjoint.
1518    #[deprecated(note = "Renamed to `self.adjoint_mut()`.")]
1519    pub fn conjugate_transform_mut(&mut self) {
1520        self.adjoint_mut()
1521    }
1522
1523    /// Sets `self` to its adjoint (aka. conjugate-transpose).
1524    pub fn adjoint_mut(&mut self) {
1525        assert!(
1526            self.is_square(),
1527            "Unable to transpose a non-square matrix in-place."
1528        );
1529
1530        let dim = self.shape().0;
1531
1532        for i in 0..dim {
1533            for j in 0..i {
1534                unsafe {
1535                    let ref_ij = self.get_unchecked((i, j)).clone();
1536                    let ref_ji = self.get_unchecked((j, i)).clone();
1537                    let conj_ij = ref_ij.simd_conjugate();
1538                    let conj_ji = ref_ji.simd_conjugate();
1539                    *self.get_unchecked_mut((i, j)) = conj_ji;
1540                    *self.get_unchecked_mut((j, i)) = conj_ij;
1541                }
1542            }
1543
1544            {
1545                let diag = unsafe { self.get_unchecked_mut((i, i)) };
1546                *diag = diag.clone().simd_conjugate();
1547            }
1548        }
1549    }
1550}
1551
1552impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
1553    /// The diagonal of this matrix.
1554    #[inline]
1555    #[must_use]
1556    pub fn diagonal(&self) -> OVector<T, D>
1557    where
1558        DefaultAllocator: Allocator<D>,
1559    {
1560        self.map_diagonal(|e| e)
1561    }
1562
1563    /// Apply the given function to this matrix's diagonal and returns it.
1564    ///
1565    /// This is a more efficient version of `self.diagonal().map(f)` since this
1566    /// allocates only once.
1567    #[must_use]
1568    pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D>
1569    where
1570        DefaultAllocator: Allocator<D>,
1571    {
1572        assert!(
1573            self.is_square(),
1574            "Unable to get the diagonal of a non-square matrix."
1575        );
1576
1577        let dim = self.shape_generic().0;
1578        let mut res = Matrix::uninit(dim, Const::<1>);
1579
1580        for i in 0..dim.value() {
1581            // Safety: all indices are in range.
1582            unsafe {
1583                *res.vget_unchecked_mut(i) =
1584                    MaybeUninit::new(f(self.get_unchecked((i, i)).clone()));
1585            }
1586        }
1587
1588        // Safety: res is now fully initialized.
1589        unsafe { res.assume_init() }
1590    }
1591
1592    /// Computes a trace of a square matrix, i.e., the sum of its diagonal elements.
1593    #[inline]
1594    #[must_use]
1595    pub fn trace(&self) -> T
1596    where
1597        T: Scalar + Zero + ClosedAddAssign,
1598    {
1599        assert!(
1600            self.is_square(),
1601            "Cannot compute the trace of non-square matrix."
1602        );
1603
1604        let dim = self.shape_generic().0;
1605        let mut res = T::zero();
1606
1607        for i in 0..dim.value() {
1608            res += unsafe { self.get_unchecked((i, i)).clone() };
1609        }
1610
1611        res
1612    }
1613}
1614
1615impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
1616    /// The symmetric part of `self`, i.e., `0.5 * (self + self.transpose())`.
1617    #[inline]
1618    #[must_use]
1619    pub fn symmetric_part(&self) -> OMatrix<T, D, D>
1620    where
1621        DefaultAllocator: Allocator<D, D>,
1622    {
1623        assert!(
1624            self.is_square(),
1625            "Cannot compute the symmetric part of a non-square matrix."
1626        );
1627        let mut tr = self.transpose();
1628        tr += self;
1629        tr *= crate::convert::<_, T>(0.5);
1630        tr
1631    }
1632
1633    /// The hermitian part of `self`, i.e., `0.5 * (self + self.adjoint())`.
1634    #[inline]
1635    #[must_use]
1636    pub fn hermitian_part(&self) -> OMatrix<T, D, D>
1637    where
1638        DefaultAllocator: Allocator<D, D>,
1639    {
1640        assert!(
1641            self.is_square(),
1642            "Cannot compute the hermitian part of a non-square matrix."
1643        );
1644
1645        let mut tr = self.adjoint();
1646        tr += self;
1647        tr *= crate::convert::<_, T>(0.5);
1648        tr
1649    }
1650}
1651
1652impl<T: Scalar + Zero + One, D: DimAdd<U1> + IsNotStaticOne, S: RawStorage<T, D, D>>
1653    Matrix<T, D, D, S>
1654{
1655    /// Yields the homogeneous matrix for this matrix, i.e., appending an additional dimension and
1656    /// and setting the diagonal element to `1`.
1657    #[inline]
1658    #[must_use]
1659    pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>>
1660    where
1661        DefaultAllocator: Allocator<DimSum<D, U1>, DimSum<D, U1>>,
1662    {
1663        assert!(
1664            self.is_square(),
1665            "Only square matrices can currently be transformed to homogeneous coordinates."
1666        );
1667        let dim = DimSum::<D, U1>::from_usize(self.nrows() + 1);
1668        let mut res = OMatrix::identity_generic(dim, dim);
1669        res.generic_view_mut::<D, D>((0, 0), self.shape_generic())
1670            .copy_from(self);
1671        res
1672    }
1673}
1674
1675impl<T: Scalar + Zero, D: DimAdd<U1>, S: RawStorage<T, D>> Vector<T, D, S> {
1676    /// Computes the coordinates in projective space of this vector, i.e., appends a `0` to its
1677    /// coordinates.
1678    #[inline]
1679    #[must_use]
1680    pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>>
1681    where
1682        DefaultAllocator: Allocator<DimSum<D, U1>>,
1683    {
1684        self.push(T::zero())
1685    }
1686
1687    /// Constructs a vector from coordinates in projective space, i.e., removes a `0` at the end of
1688    /// `self`. Returns `None` if this last component is not zero.
1689    #[inline]
1690    pub fn from_homogeneous<SB>(v: Vector<T, DimSum<D, U1>, SB>) -> Option<OVector<T, D>>
1691    where
1692        SB: RawStorage<T, DimSum<D, U1>>,
1693        DefaultAllocator: Allocator<D>,
1694    {
1695        if v[v.len() - 1].is_zero() {
1696            let nrows = D::from_usize(v.len() - 1);
1697            Some(v.generic_view((0, 0), (nrows, Const::<1>)).into_owned())
1698        } else {
1699            None
1700        }
1701    }
1702}
1703
1704impl<T: Scalar, D: DimAdd<U1>, S: RawStorage<T, D>> Vector<T, D, S> {
1705    /// Constructs a new vector of higher dimension by appending `element` to the end of `self`.
1706    #[inline]
1707    #[must_use]
1708    pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>>
1709    where
1710        DefaultAllocator: Allocator<DimSum<D, U1>>,
1711    {
1712        let len = self.len();
1713        let hnrows = DimSum::<D, U1>::from_usize(len + 1);
1714        let mut res = Matrix::uninit(hnrows, Const::<1>);
1715        // This is basically a copy_from except that we warp the copied
1716        // values into MaybeUninit.
1717        res.generic_view_mut((0, 0), self.shape_generic())
1718            .zip_apply(self, |out, e| *out = MaybeUninit::new(e));
1719        res[(len, 0)] = MaybeUninit::new(element);
1720
1721        // Safety: res has been fully initialized.
1722        unsafe { res.assume_init() }
1723    }
1724}
1725
1726impl<T, R: Dim, C: Dim, S> AbsDiffEq for Matrix<T, R, C, S>
1727where
1728    T: Scalar + AbsDiffEq,
1729    S: RawStorage<T, R, C>,
1730    T::Epsilon: Clone,
1731{
1732    type Epsilon = T::Epsilon;
1733
1734    #[inline]
1735    fn default_epsilon() -> Self::Epsilon {
1736        T::default_epsilon()
1737    }
1738
1739    #[inline]
1740    fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
1741        self.iter()
1742            .zip(other.iter())
1743            .all(|(a, b)| a.abs_diff_eq(b, epsilon.clone()))
1744    }
1745}
1746
1747impl<T, R: Dim, C: Dim, S> RelativeEq for Matrix<T, R, C, S>
1748where
1749    T: Scalar + RelativeEq,
1750    S: Storage<T, R, C>,
1751    T::Epsilon: Clone,
1752{
1753    #[inline]
1754    fn default_max_relative() -> Self::Epsilon {
1755        T::default_max_relative()
1756    }
1757
1758    #[inline]
1759    fn relative_eq(
1760        &self,
1761        other: &Self,
1762        epsilon: Self::Epsilon,
1763        max_relative: Self::Epsilon,
1764    ) -> bool {
1765        self.relative_eq(other, epsilon, max_relative)
1766    }
1767}
1768
1769impl<T, R: Dim, C: Dim, S> UlpsEq for Matrix<T, R, C, S>
1770where
1771    T: Scalar + UlpsEq,
1772    S: RawStorage<T, R, C>,
1773    T::Epsilon: Clone,
1774{
1775    #[inline]
1776    fn default_max_ulps() -> u32 {
1777        T::default_max_ulps()
1778    }
1779
1780    #[inline]
1781    fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
1782        assert!(self.shape() == other.shape());
1783        self.iter()
1784            .zip(other.iter())
1785            .all(|(a, b)| a.ulps_eq(b, epsilon.clone(), max_ulps))
1786    }
1787}
1788
1789impl<T, R: Dim, C: Dim, S> PartialOrd for Matrix<T, R, C, S>
1790where
1791    T: Scalar + PartialOrd,
1792    S: RawStorage<T, R, C>,
1793{
1794    #[inline]
1795    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1796        if self.shape() != other.shape() {
1797            return None;
1798        }
1799
1800        if self.nrows() == 0 || self.ncols() == 0 {
1801            return Some(Ordering::Equal);
1802        }
1803
1804        let mut first_ord = unsafe {
1805            self.data
1806                .get_unchecked_linear(0)
1807                .partial_cmp(other.data.get_unchecked_linear(0))
1808        };
1809
1810        if let Some(first_ord) = first_ord.as_mut() {
1811            let mut it = self.iter().zip(other.iter());
1812            let _ = it.next(); // Drop the first elements (we already tested it).
1813
1814            for (left, right) in it {
1815                if let Some(ord) = left.partial_cmp(right) {
1816                    match ord {
1817                        Ordering::Equal => { /* Does not change anything. */ }
1818                        Ordering::Less => {
1819                            if *first_ord == Ordering::Greater {
1820                                return None;
1821                            }
1822                            *first_ord = ord
1823                        }
1824                        Ordering::Greater => {
1825                            if *first_ord == Ordering::Less {
1826                                return None;
1827                            }
1828                            *first_ord = ord
1829                        }
1830                    }
1831                } else {
1832                    return None;
1833                }
1834            }
1835        }
1836
1837        first_ord
1838    }
1839
1840    #[inline]
1841    fn lt(&self, right: &Self) -> bool {
1842        assert_eq!(
1843            self.shape(),
1844            right.shape(),
1845            "Matrix comparison error: dimensions mismatch."
1846        );
1847        self.iter().zip(right.iter()).all(|(a, b)| a.lt(b))
1848    }
1849
1850    #[inline]
1851    fn le(&self, right: &Self) -> bool {
1852        assert_eq!(
1853            self.shape(),
1854            right.shape(),
1855            "Matrix comparison error: dimensions mismatch."
1856        );
1857        self.iter().zip(right.iter()).all(|(a, b)| a.le(b))
1858    }
1859
1860    #[inline]
1861    fn gt(&self, right: &Self) -> bool {
1862        assert_eq!(
1863            self.shape(),
1864            right.shape(),
1865            "Matrix comparison error: dimensions mismatch."
1866        );
1867        self.iter().zip(right.iter()).all(|(a, b)| a.gt(b))
1868    }
1869
1870    #[inline]
1871    fn ge(&self, right: &Self) -> bool {
1872        assert_eq!(
1873            self.shape(),
1874            right.shape(),
1875            "Matrix comparison error: dimensions mismatch."
1876        );
1877        self.iter().zip(right.iter()).all(|(a, b)| a.ge(b))
1878    }
1879}
1880
1881impl<T, R: Dim, C: Dim, S> Eq for Matrix<T, R, C, S>
1882where
1883    T: Eq,
1884    S: RawStorage<T, R, C>,
1885{
1886}
1887
1888impl<T, R, R2, C, C2, S, S2> PartialEq<Matrix<T, R2, C2, S2>> for Matrix<T, R, C, S>
1889where
1890    T: PartialEq,
1891    C: Dim,
1892    C2: Dim,
1893    R: Dim,
1894    R2: Dim,
1895    S: RawStorage<T, R, C>,
1896    S2: RawStorage<T, R2, C2>,
1897{
1898    #[inline]
1899    fn eq(&self, right: &Matrix<T, R2, C2, S2>) -> bool {
1900        self.shape() == right.shape() && self.iter().zip(right.iter()).all(|(l, r)| l == r)
1901    }
1902}
1903
1904macro_rules! impl_fmt {
1905    ($trait: path, $fmt_str_without_precision: expr, $fmt_str_with_precision: expr) => {
1906        impl<T, R: Dim, C: Dim, S> $trait for Matrix<T, R, C, S>
1907        where
1908            T: Scalar + $trait,
1909            S: RawStorage<T, R, C>,
1910        {
1911            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1912                #[cfg(feature = "std")]
1913                fn val_width<T: Scalar + $trait>(val: &T, f: &mut fmt::Formatter<'_>) -> usize {
1914                    match f.precision() {
1915                        Some(precision) => format!($fmt_str_with_precision, val, precision)
1916                            .chars()
1917                            .count(),
1918                        None => format!($fmt_str_without_precision, val).chars().count(),
1919                    }
1920                }
1921
1922                #[cfg(not(feature = "std"))]
1923                fn val_width<T: Scalar + $trait>(_: &T, _: &mut fmt::Formatter<'_>) -> usize {
1924                    4
1925                }
1926
1927                let (nrows, ncols) = self.shape();
1928
1929                if nrows == 0 || ncols == 0 {
1930                    return write!(f, "[ ]");
1931                }
1932
1933                let mut max_length = 0;
1934
1935                for i in 0..nrows {
1936                    for j in 0..ncols {
1937                        max_length = crate::max(max_length, val_width(&self[(i, j)], f));
1938                    }
1939                }
1940
1941                let max_length_with_space = max_length + 1;
1942
1943                writeln!(f)?;
1944                writeln!(
1945                    f,
1946                    "  ┌ {:>width$} ┐",
1947                    "",
1948                    width = max_length_with_space * ncols - 1
1949                )?;
1950
1951                for i in 0..nrows {
1952                    write!(f, "  │")?;
1953                    for j in 0..ncols {
1954                        let number_length = val_width(&self[(i, j)], f) + 1;
1955                        let pad = max_length_with_space - number_length;
1956                        write!(f, " {:>thepad$}", "", thepad = pad)?;
1957                        match f.precision() {
1958                            Some(precision) => {
1959                                write!(f, $fmt_str_with_precision, (*self)[(i, j)], precision)?
1960                            }
1961                            None => write!(f, $fmt_str_without_precision, (*self)[(i, j)])?,
1962                        }
1963                    }
1964                    writeln!(f, " │")?;
1965                }
1966
1967                writeln!(
1968                    f,
1969                    "  └ {:>width$} ┘",
1970                    "",
1971                    width = max_length_with_space * ncols - 1
1972                )?;
1973                writeln!(f)
1974            }
1975        }
1976    };
1977}
1978impl_fmt!(fmt::Display, "{}", "{:.1$}");
1979impl_fmt!(fmt::LowerExp, "{:e}", "{:.1$e}");
1980impl_fmt!(fmt::UpperExp, "{:E}", "{:.1$E}");
1981impl_fmt!(fmt::Octal, "{:o}", "{:1$o}");
1982impl_fmt!(fmt::LowerHex, "{:x}", "{:1$x}");
1983impl_fmt!(fmt::UpperHex, "{:X}", "{:1$X}");
1984impl_fmt!(fmt::Binary, "{:b}", "{:.1$b}");
1985impl_fmt!(fmt::Pointer, "{:p}", "{:.1$p}");
1986
1987#[cfg(test)]
1988mod tests {
1989    #[test]
1990    fn empty_display() {
1991        let vec: Vec<f64> = Vec::new();
1992        let dvector = crate::DVector::from_vec(vec);
1993        assert_eq!(format!("{}", dvector), "[ ]")
1994    }
1995
1996    #[test]
1997    fn lower_exp() {
1998        let test = crate::Matrix2::new(1e6, 2e5, 2e-5, 1.);
1999        assert_eq!(
2000            format!("{:e}", test),
2001            r"
2002  ┌           ┐
2003  │  1e6  2e5 │
2004  │ 2e-5  1e0 │
2005  └           ┘
2006
2007"
2008        )
2009    }
2010}
2011
2012/// # Cross product
2013impl<
2014        T: Scalar + ClosedAddAssign + ClosedSubAssign + ClosedMulAssign,
2015        R: Dim,
2016        C: Dim,
2017        S: RawStorage<T, R, C>,
2018    > Matrix<T, R, C, S>
2019{
2020    /// The perpendicular product between two 2D column vectors, i.e. `a.x * b.y - a.y * b.x`.
2021    #[inline]
2022    #[must_use]
2023    pub fn perp<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> T
2024    where
2025        R2: Dim,
2026        C2: Dim,
2027        SB: RawStorage<T, R2, C2>,
2028        ShapeConstraint: SameNumberOfRows<R, U2>
2029            + SameNumberOfColumns<C, U1>
2030            + SameNumberOfRows<R2, U2>
2031            + SameNumberOfColumns<C2, U1>,
2032    {
2033        let shape = self.shape();
2034        assert_eq!(
2035            shape,
2036            b.shape(),
2037            "2D vector perpendicular product dimension mismatch."
2038        );
2039        assert_eq!(
2040            shape,
2041            (2, 1),
2042            "2D perpendicular product requires (2, 1) vectors {:?}",
2043            shape
2044        );
2045
2046        // SAFETY: assertion above ensures correct shape
2047        let ax = unsafe { self.get_unchecked((0, 0)).clone() };
2048        let ay = unsafe { self.get_unchecked((1, 0)).clone() };
2049        let bx = unsafe { b.get_unchecked((0, 0)).clone() };
2050        let by = unsafe { b.get_unchecked((1, 0)).clone() };
2051
2052        ax * by - ay * bx
2053    }
2054
2055    // TODO: use specialization instead of an assertion.
2056    /// The 3D cross product between two vectors.
2057    ///
2058    /// Panics if the shape is not 3D vector. In the future, this will be implemented only for
2059    /// dynamically-sized matrices and statically-sized 3D matrices.
2060    #[inline]
2061    #[must_use]
2062    pub fn cross<R2, C2, SB>(&self, b: &Matrix<T, R2, C2, SB>) -> MatrixCross<T, R, C, R2, C2>
2063    where
2064        R2: Dim,
2065        C2: Dim,
2066        SB: RawStorage<T, R2, C2>,
2067        DefaultAllocator: SameShapeAllocator<R, C, R2, C2>,
2068        ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
2069    {
2070        let shape = self.shape();
2071        assert_eq!(shape, b.shape(), "Vector cross product dimension mismatch.");
2072        assert!(
2073            shape == (3, 1) || shape == (1, 3),
2074            "Vector cross product dimension mismatch: must be (3, 1) or (1, 3) but found {:?}.",
2075            shape
2076        );
2077
2078        if shape.0 == 3 {
2079            unsafe {
2080                let mut res = Matrix::uninit(Dim::from_usize(3), Dim::from_usize(1));
2081
2082                let ax = self.get_unchecked((0, 0));
2083                let ay = self.get_unchecked((1, 0));
2084                let az = self.get_unchecked((2, 0));
2085
2086                let bx = b.get_unchecked((0, 0));
2087                let by = b.get_unchecked((1, 0));
2088                let bz = b.get_unchecked((2, 0));
2089
2090                *res.get_unchecked_mut((0, 0)) =
2091                    MaybeUninit::new(ay.clone() * bz.clone() - az.clone() * by.clone());
2092                *res.get_unchecked_mut((1, 0)) =
2093                    MaybeUninit::new(az.clone() * bx.clone() - ax.clone() * bz.clone());
2094                *res.get_unchecked_mut((2, 0)) =
2095                    MaybeUninit::new(ax.clone() * by.clone() - ay.clone() * bx.clone());
2096
2097                // Safety: res is now fully initialized.
2098                res.assume_init()
2099            }
2100        } else {
2101            unsafe {
2102                let mut res = Matrix::uninit(Dim::from_usize(1), Dim::from_usize(3));
2103
2104                let ax = self.get_unchecked((0, 0));
2105                let ay = self.get_unchecked((0, 1));
2106                let az = self.get_unchecked((0, 2));
2107
2108                let bx = b.get_unchecked((0, 0));
2109                let by = b.get_unchecked((0, 1));
2110                let bz = b.get_unchecked((0, 2));
2111
2112                *res.get_unchecked_mut((0, 0)) =
2113                    MaybeUninit::new(ay.clone() * bz.clone() - az.clone() * by.clone());
2114                *res.get_unchecked_mut((0, 1)) =
2115                    MaybeUninit::new(az.clone() * bx.clone() - ax.clone() * bz.clone());
2116                *res.get_unchecked_mut((0, 2)) =
2117                    MaybeUninit::new(ax.clone() * by.clone() - ay.clone() * bx.clone());
2118
2119                // Safety: res is now fully initialized.
2120                res.assume_init()
2121            }
2122        }
2123    }
2124}
2125
2126impl<T: Scalar + Field, S: RawStorage<T, U3>> Vector<T, U3, S> {
2127    /// Computes the matrix `M` such that for all vector `v` we have `M * v == self.cross(&v)`.
2128    #[inline]
2129    #[must_use]
2130    pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
2131        OMatrix::<T, U3, U3>::new(
2132            T::zero(),
2133            -self[2].clone(),
2134            self[1].clone(),
2135            self[2].clone(),
2136            T::zero(),
2137            -self[0].clone(),
2138            -self[1].clone(),
2139            self[0].clone(),
2140            T::zero(),
2141        )
2142    }
2143}
2144
2145impl<T: SimdComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
2146    /// The smallest angle between two vectors.
2147    #[inline]
2148    #[must_use]
2149    pub fn angle<R2: Dim, C2: Dim, SB>(&self, other: &Matrix<T, R2, C2, SB>) -> T::SimdRealField
2150    where
2151        SB: Storage<T, R2, C2>,
2152        ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
2153    {
2154        let prod = self.dotc(other);
2155        let n1 = self.norm();
2156        let n2 = other.norm();
2157
2158        if n1.is_zero() || n2.is_zero() {
2159            T::SimdRealField::zero()
2160        } else {
2161            let cang = prod.simd_real() / (n1 * n2);
2162            cang.simd_clamp(-T::SimdRealField::one(), T::SimdRealField::one())
2163                .simd_acos()
2164        }
2165    }
2166}
2167
2168impl<T, R: Dim, C: Dim, S> AbsDiffEq for Unit<Matrix<T, R, C, S>>
2169where
2170    T: Scalar + AbsDiffEq,
2171    S: RawStorage<T, R, C>,
2172    T::Epsilon: Clone,
2173{
2174    type Epsilon = T::Epsilon;
2175
2176    #[inline]
2177    fn default_epsilon() -> Self::Epsilon {
2178        T::default_epsilon()
2179    }
2180
2181    #[inline]
2182    fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
2183        self.as_ref().abs_diff_eq(other.as_ref(), epsilon)
2184    }
2185}
2186
2187impl<T, R: Dim, C: Dim, S> RelativeEq for Unit<Matrix<T, R, C, S>>
2188where
2189    T: Scalar + RelativeEq,
2190    S: Storage<T, R, C>,
2191    T::Epsilon: Clone,
2192{
2193    #[inline]
2194    fn default_max_relative() -> Self::Epsilon {
2195        T::default_max_relative()
2196    }
2197
2198    #[inline]
2199    fn relative_eq(
2200        &self,
2201        other: &Self,
2202        epsilon: Self::Epsilon,
2203        max_relative: Self::Epsilon,
2204    ) -> bool {
2205        self.as_ref()
2206            .relative_eq(other.as_ref(), epsilon, max_relative)
2207    }
2208}
2209
2210impl<T, R: Dim, C: Dim, S> UlpsEq for Unit<Matrix<T, R, C, S>>
2211where
2212    T: Scalar + UlpsEq,
2213    S: RawStorage<T, R, C>,
2214    T::Epsilon: Clone,
2215{
2216    #[inline]
2217    fn default_max_ulps() -> u32 {
2218        T::default_max_ulps()
2219    }
2220
2221    #[inline]
2222    fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
2223        self.as_ref().ulps_eq(other.as_ref(), epsilon, max_ulps)
2224    }
2225}
2226
2227impl<T, R, C, S> Hash for Matrix<T, R, C, S>
2228where
2229    T: Scalar + Hash,
2230    R: Dim,
2231    C: Dim,
2232    S: RawStorage<T, R, C>,
2233{
2234    fn hash<H: Hasher>(&self, state: &mut H) {
2235        let (nrows, ncols) = self.shape();
2236        (nrows, ncols).hash(state);
2237
2238        for j in 0..ncols {
2239            for i in 0..nrows {
2240                unsafe {
2241                    self.get_unchecked((i, j)).hash(state);
2242                }
2243            }
2244        }
2245    }
2246}
2247
2248impl<T, D, S> Unit<Vector<T, D, S>>
2249where
2250    T: Scalar,
2251    D: Dim,
2252    S: RawStorage<T, D, U1>,
2253{
2254    /// Cast the components of `self` to another type.
2255    ///
2256    /// # Example
2257    /// ```
2258    /// # use nalgebra::Vector3;
2259    /// let v = Vector3::<f64>::y_axis();
2260    /// let v2 = v.cast::<f32>();
2261    /// assert_eq!(v2, Vector3::<f32>::y_axis());
2262    /// ```
2263    pub fn cast<T2: Scalar>(self) -> Unit<OVector<T2, D>>
2264    where
2265        T: Scalar,
2266        OVector<T2, D>: SupersetOf<Vector<T, D, S>>,
2267        DefaultAllocator: Allocator<D, U1>,
2268    {
2269        Unit::new_unchecked(crate::convert_ref(self.as_ref()))
2270    }
2271}
2272
2273impl<T, S> Matrix<T, U1, U1, S>
2274where
2275    S: RawStorage<T, U1, U1>,
2276{
2277    /// Returns a reference to the single element in this matrix.
2278    ///
2279    /// As opposed to indexing, using this provides type-safety
2280    /// when flattening dimensions.
2281    ///
2282    /// # Example
2283    /// ```
2284    /// # use nalgebra::Vector3;
2285    /// let v = Vector3::new(0., 0., 1.);
2286    /// let inner_product: f32 = *(v.transpose() * v).as_scalar();
2287    /// ```
2288    ///
2289    ///```compile_fail
2290    /// # use nalgebra::Vector3;
2291    /// let v = Vector3::new(0., 0., 1.);
2292    /// let inner_product = (v * v.transpose()).item(); // Typo, does not compile.
2293    ///```
2294    pub fn as_scalar(&self) -> &T {
2295        &self[(0, 0)]
2296    }
2297    /// Get a mutable reference to the single element in this matrix
2298    ///
2299    /// As opposed to indexing, using this provides type-safety
2300    /// when flattening dimensions.
2301    ///
2302    /// # Example
2303    /// ```
2304    /// # use nalgebra::Vector3;
2305    /// let v = Vector3::new(0., 0., 1.);
2306    /// let mut inner_product = (v.transpose() * v);
2307    /// *inner_product.as_scalar_mut() = 3.;
2308    /// ```
2309    ///
2310    ///```compile_fail
2311    /// # use nalgebra::Vector3;
2312    /// let v = Vector3::new(0., 0., 1.);
2313    /// let mut inner_product = (v * v.transpose());
2314    /// *inner_product.as_scalar_mut() = 3.;
2315    ///```
2316    pub fn as_scalar_mut(&mut self) -> &mut T
2317    where
2318        S: RawStorageMut<T, U1>,
2319    {
2320        &mut self[(0, 0)]
2321    }
2322    /// Convert this 1x1 matrix by reference into a scalar.
2323    ///
2324    /// As opposed to indexing, using this provides type-safety
2325    /// when flattening dimensions.
2326    ///
2327    /// # Example
2328    /// ```
2329    /// # use nalgebra::Vector3;
2330    /// let v = Vector3::new(0., 0., 1.);
2331    /// let mut inner_product: f32 = (v.transpose() * v).to_scalar();
2332    /// ```
2333    ///
2334    ///```compile_fail
2335    /// # use nalgebra::Vector3;
2336    /// let v = Vector3::new(0., 0., 1.);
2337    /// let mut inner_product: f32 = (v * v.transpose()).to_scalar();
2338    ///```
2339    pub fn to_scalar(&self) -> T
2340    where
2341        T: Clone,
2342    {
2343        self.as_scalar().clone()
2344    }
2345}
2346
2347impl<T> super::alias::Matrix1<T> {
2348    /// Convert this 1x1 matrix into a scalar.
2349    ///
2350    /// As opposed to indexing, using this provides type-safety
2351    /// when flattening dimensions.
2352    ///
2353    /// # Example
2354    /// ```
2355    /// # use nalgebra::{Vector3, Matrix2, U1};
2356    /// let v = Vector3::new(0., 0., 1.);
2357    /// let inner_product: f32 = (v.transpose() * v).into_scalar();
2358    /// assert_eq!(inner_product, 1.);
2359    /// ```
2360    ///
2361    ///```compile_fail
2362    /// # use nalgebra::Vector3;
2363    /// let v = Vector3::new(0., 0., 1.);
2364    /// let mut inner_product: f32 = (v * v.transpose()).into_scalar();
2365    ///```
2366    pub fn into_scalar(self) -> T {
2367        let [[scalar]] = self.data.0;
2368        scalar
2369    }
2370}