faer_core/
lib.rs

1//! `faer` is a linear algebra library for Rust, with a focus on high performance for
2//! medium/large matrices.
3//!
4//! The core module contains the building blocks of linear algebra:
5//! * Matrix structure definitions: [`Mat`], [`MatRef`], and [`MatMut`].
6//! * Coefficient-wise matrix operations, like addition and subtraction: either using the builtin
7//! `+` and `-` operators or using the low level api [`zipped!`].
8//! * Matrix multiplication: either using the builtin `*` operator or the low level [`mul`] module.
9//! * Triangular matrix solve: the [`solve`] module.
10//! * Triangular matrix inverse: the [`inverse`] module.
11//! * Householder matrix multiplication: the [`householder`] module.
12//!
13//! # Example
14//! ```
15//! use faer_core::{mat, scale, Mat};
16//!
17//! let a = mat![
18//!     [1.0, 5.0, 9.0],
19//!     [2.0, 6.0, 10.0],
20//!     [3.0, 7.0, 11.0],
21//!     [4.0, 8.0, 12.0f64],
22//! ];
23//!
24//! let b = Mat::<f64>::from_fn(4, 3, |i, j| (i + j) as f64);
25//!
26//! let add = &a + &b;
27//! let sub = &a - &b;
28//! let scale = scale(3.0) * &a;
29//! let mul = &a * b.transpose();
30//! ```
31//!
32//! # Entity trait
33//! Matrices are built on top of the [`Entity`] trait, which describes the prefered memory storage
34//! layout for a given type `E`. An entity can be decomposed into a group of units: for a natively
35//! supported type ([`f32`], [`f64`], [`c32`], [`c64`]), the unit is simply the type itself, and a
36//! group contains a single element. On the other hand, for a type with a more specific preferred
37//! layout, like an extended precision floating point type, or a dual number type, the unit would
38//! be one of the natively supported types, and the group would be a structure holding the
39//! components that build up the full value.
40//!
41//! To take a more specific example: [`num_complex::Complex<f64>`] has a storage memory layout that
42//! differs from that of [`c64`] (see [`complex_native`] for more details). Its real and complex
43//! components are stored separately, so its unit type is `f64`, while its group type is `Complex`.
44//! In practice, this means that for a `Mat<f64>`, methods such as [`Mat::col_as_slice`] will return
45//! a `&[f64]`. Meanwhile, for a `Mat<Complex<f64>>`, [`Mat::col_as_slice`] will return
46//! `Complex<&[f64]>`, which holds two slices, each pointing respectively to a view over the real
47//! and the imaginary components.
48//!
49//! While the design of the entity trait is unconventional, it helps us achieve much higher
50//! performance when targetting non native types, due to the design matching the typical preffered
51//! CPU layout for SIMD operations. And for native types, since [`Group<T>` is just
52//! `T`](Entity#impl-Entity-for-f64), the entity layer is a no-op, and the matrix layout is
53//! compatible with the classic contiguous layout that's commonly used by other libraries.
54//!
55//! # Memory allocation
56//! Since most `faer` crates aim to expose a low level api for optimal performance, most algorithms
57//! try to defer memory allocation to the user.
58//!
59//! However, since a lot of algorithms need some form of temporary space for intermediate
60//! computations, they may ask for a slice of memory for that purpose, by taking a [`stack:
61//! PodStack`](dyn_stack::PodStack) parameter. A `PodStack` is a thin wrapper over a slice of
62//! memory bytes. This memory may come from any valid source (heap allocation, fixed-size array on
63//! the stack, etc.). The functions taking a `PodStack` parameter have a corresponding function
64//! with a similar name ending in `_req` that returns the memory requirements of the algorithm. For
65//! example:
66//! [`householder::apply_block_householder_on_the_left_in_place_with_conj`] and
67//! [`householder::apply_block_householder_on_the_left_in_place_req`].
68//!
69//! The memory stack may be reused in user-code to avoid repeated allocations, and it is also
70//! possible to compute the sum ([`dyn_stack::StackReq::all_of`]) or union
71//! ([`dyn_stack::StackReq::any_of`]) of multiple requirements, in order to optimally combine them
72//! into a single allocation.
73//!
74//! After computing a [`dyn_stack::StackReq`], one can query its size and alignment to allocate the
75//! required memory. The simplest way to do so is through [`dyn_stack::GlobalMemBuffer::new`].
76
77#![allow(non_snake_case)]
78#![allow(clippy::type_complexity)]
79#![allow(clippy::too_many_arguments)]
80#![warn(missing_docs)]
81#![cfg_attr(docsrs, feature(doc_cfg))]
82#![cfg_attr(not(feature = "std"), no_std)]
83
84use faer_entity::*;
85pub use faer_entity::{
86    ComplexField, Conjugate, Entity, GroupFor, IdentityGroup, RealField, SimdCtx, SimpleEntity,
87};
88
89#[doc(hidden)]
90pub use equator::{assert, debug_assert};
91
92pub use dyn_stack;
93pub use reborrow;
94pub use faer_entity::pulp;
95
96use coe::Coerce;
97use core::{
98    fmt::Debug, marker::PhantomData, mem::ManuallyDrop, ptr::NonNull, sync::atomic::AtomicUsize,
99};
100use dyn_stack::{PodStack, SizeOverflow, StackReq};
101use group_helpers::{SliceGroup, SliceGroupMut};
102use num_complex::Complex;
103use pulp::Simd;
104use reborrow::*;
105
106#[cfg(feature = "perf-warn")]
107#[macro_export]
108#[doc(hidden)]
109macro_rules! __perf_warn {
110    ($name: ident) => {{
111        #[inline(always)]
112        #[allow(non_snake_case)]
113        fn $name() -> &'static ::core::sync::atomic::AtomicBool {
114            static $name: ::core::sync::atomic::AtomicBool =
115                ::core::sync::atomic::AtomicBool::new(false);
116            &$name
117        }
118        ::core::matches!(
119            $name().compare_exchange(
120                false,
121                true,
122                ::core::sync::atomic::Ordering::Relaxed,
123                ::core::sync::atomic::Ordering::Relaxed,
124            ),
125            Ok(_)
126        )
127    }};
128}
129
130#[doc(hidden)]
131pub trait DivCeil: Sized {
132    fn msrv_div_ceil(self, rhs: Self) -> Self;
133    fn msrv_next_multiple_of(self, rhs: Self) -> Self;
134    fn msrv_checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
135}
136
137impl DivCeil for usize {
138    #[inline]
139    fn msrv_div_ceil(self, rhs: Self) -> Self {
140        let d = self / rhs;
141        let r = self % rhs;
142        if r > 0 {
143            d + 1
144        } else {
145            d
146        }
147    }
148
149    #[inline]
150    fn msrv_next_multiple_of(self, rhs: Self) -> Self {
151        match self % rhs {
152            0 => self,
153            r => self + (rhs - r),
154        }
155    }
156
157    #[inline]
158    fn msrv_checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
159        {
160            match self.checked_rem(rhs)? {
161                0 => Some(self),
162                r => self.checked_add(rhs - r),
163            }
164        }
165    }
166}
167
168/// Specifies whether the triangular lower or upper part of a matrix should be accessed.
169#[derive(Copy, Clone, Debug, PartialEq)]
170pub enum Side {
171    /// Lower half should be accessed.
172    Lower,
173    /// Upper half should be accessed.
174    Upper,
175}
176
177/// Errors that can occur in sparse algorithms.
178#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
179#[non_exhaustive]
180pub enum FaerError {
181    /// An index exceeding the maximum value (`I::Signed::MAX` for a given index type `I`).
182    IndexOverflow,
183    /// Memory allocation failed.
184    OutOfMemory,
185}
186
187impl core::fmt::Display for FaerError {
188    #[inline]
189    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
190        core::fmt::Debug::fmt(self, f)
191    }
192}
193
194#[cfg(feature = "std")]
195impl std::error::Error for FaerError {}
196
197extern crate alloc;
198
199pub mod householder;
200#[doc(hidden)]
201pub mod jacobi;
202
203pub mod inverse;
204pub mod mul;
205pub mod permutation;
206pub mod solve;
207
208pub mod matrix_ops;
209
210#[cfg(feature = "serde")]
211pub mod serde_impl;
212pub mod sparse;
213
214/// Thin wrapper used for scalar multiplication of a matrix by a scalar value.
215pub use matrix_ops::scale;
216
217#[doc(hidden)]
218pub mod simd;
219
220#[doc(hidden)]
221pub use faer_entity::transmute_unchecked;
222
223pub mod complex_native;
224pub use complex_native::*;
225
226mod sort;
227
228/// Whether a matrix should be implicitly conjugated when read or not.
229#[derive(Copy, Clone, Debug, PartialEq, Eq)]
230pub enum Conj {
231    /// Do conjugate.
232    Yes,
233    /// Do not conjugate.
234    No,
235}
236
237impl Conj {
238    /// Combine `self` and `other` to create a new conjugation object.
239    #[inline]
240    pub fn compose(self, other: Conj) -> Conj {
241        if self == other {
242            Conj::No
243        } else {
244            Conj::Yes
245        }
246    }
247}
248
249/// Trait for types that can be converted to a row view.
250pub trait AsRowRef<E: Entity> {
251    /// Convert to a row view.
252    fn as_row_ref(&self) -> RowRef<'_, E>;
253}
254/// Trait for types that can be converted to a mutable row view.
255pub trait AsRowMut<E: Entity> {
256    /// Convert to a mutable row view.
257    fn as_row_mut(&mut self) -> RowMut<'_, E>;
258}
259
260/// Trait for types that can be converted to a column view.
261pub trait AsColRef<E: Entity> {
262    /// Convert to a column view.
263    fn as_col_ref(&self) -> ColRef<'_, E>;
264}
265/// Trait for types that can be converted to a mutable col view.
266pub trait AsColMut<E: Entity> {
267    /// Convert to a mutable column view.
268    fn as_col_mut(&mut self) -> ColMut<'_, E>;
269}
270
271/// Trait for types that can be converted to a matrix view.
272///
273/// This trait is implemented for types of the matrix family, like [`Mat`],
274/// [`MatRef`], and [`MatMut`], but not for types like [`Col`], [`Row`], or
275/// their families. For a more general trait, see [`As2D`].
276pub trait AsMatRef<E: Entity> {
277    /// Convert to a matrix view.
278    fn as_mat_ref(&self) -> MatRef<'_, E>;
279}
280/// Trait for types that can be converted to a mutable matrix view.
281///
282/// This trait is implemented for types of the matrix family, like [`Mat`],
283/// [`MatRef`], and [`MatMut`], but not for types like [`Col`], [`Row`], or
284/// their families. For a more general trait, see [`As2D`].
285pub trait AsMatMut<E: Entity> {
286    /// Convert to a mutable matrix view.
287    fn as_mat_mut(&mut self) -> MatMut<'_, E>;
288}
289
290/// Trait for types that can be converted to a 2D matrix view.
291///
292/// This trait is implemented for any type that can be represented as a
293/// 2D matrix view, like [`Mat`], [`Row`], [`Col`], and their respective
294/// references and mutable references. For a trait specific to the matrix
295/// family, see [`AsMatRef`] or [`AsMatMut`].
296pub trait As2D<E: Entity> {
297    /// Convert to a 2D matrix view.
298    fn as_2d_ref(&self) -> MatRef<'_, E>;
299}
300/// Trait for types that can be converted to a mutable 2D matrix view.
301///
302/// This trait is implemented for any type that can be represented as a
303/// 2D matrix view, like [`Mat`], [`Row`], [`Col`], and their respective
304/// references and mutable references. For a trait specific to the matrix
305/// family, see [`AsMatRef`] or [`AsMatMut`].
306pub trait As2DMut<E: Entity> {
307    /// Convert to a mutable 2D matrix view.
308    fn as_2d_mut(&mut self) -> MatMut<'_, E>;
309}
310
311// AS COL
312const _: () = {
313    impl<E: Entity> AsColRef<E> for ColRef<'_, E> {
314        #[inline]
315        fn as_col_ref(&self) -> ColRef<'_, E> {
316            *self
317        }
318    }
319    impl<E: Entity> AsColRef<E> for &'_ ColRef<'_, E> {
320        #[inline]
321        fn as_col_ref(&self) -> ColRef<'_, E> {
322            **self
323        }
324    }
325    impl<E: Entity> AsColRef<E> for ColMut<'_, E> {
326        #[inline]
327        fn as_col_ref(&self) -> ColRef<'_, E> {
328            (*self).rb()
329        }
330    }
331    impl<E: Entity> AsColRef<E> for &'_ ColMut<'_, E> {
332        #[inline]
333        fn as_col_ref(&self) -> ColRef<'_, E> {
334            (**self).rb()
335        }
336    }
337    impl<E: Entity> AsColRef<E> for Col<E> {
338        #[inline]
339        fn as_col_ref(&self) -> ColRef<'_, E> {
340            (*self).as_ref()
341        }
342    }
343    impl<E: Entity> AsColRef<E> for &'_ Col<E> {
344        #[inline]
345        fn as_col_ref(&self) -> ColRef<'_, E> {
346            (**self).as_ref()
347        }
348    }
349
350    impl<E: Entity> AsColMut<E> for ColMut<'_, E> {
351        #[inline]
352        fn as_col_mut(&mut self) -> ColMut<'_, E> {
353            (*self).rb_mut()
354        }
355    }
356
357    impl<E: Entity> AsColMut<E> for &'_ mut ColMut<'_, E> {
358        #[inline]
359        fn as_col_mut(&mut self) -> ColMut<'_, E> {
360            (**self).rb_mut()
361        }
362    }
363
364    impl<E: Entity> AsColMut<E> for Col<E> {
365        #[inline]
366        fn as_col_mut(&mut self) -> ColMut<'_, E> {
367            (*self).as_mut()
368        }
369    }
370
371    impl<E: Entity> AsColMut<E> for &'_ mut Col<E> {
372        #[inline]
373        fn as_col_mut(&mut self) -> ColMut<'_, E> {
374            (**self).as_mut()
375        }
376    }
377};
378
379// AS ROW
380const _: () = {
381    impl<E: Entity> AsRowRef<E> for RowRef<'_, E> {
382        #[inline]
383        fn as_row_ref(&self) -> RowRef<'_, E> {
384            *self
385        }
386    }
387    impl<E: Entity> AsRowRef<E> for &'_ RowRef<'_, E> {
388        #[inline]
389        fn as_row_ref(&self) -> RowRef<'_, E> {
390            **self
391        }
392    }
393    impl<E: Entity> AsRowRef<E> for RowMut<'_, E> {
394        #[inline]
395        fn as_row_ref(&self) -> RowRef<'_, E> {
396            (*self).rb()
397        }
398    }
399    impl<E: Entity> AsRowRef<E> for &'_ RowMut<'_, E> {
400        #[inline]
401        fn as_row_ref(&self) -> RowRef<'_, E> {
402            (**self).rb()
403        }
404    }
405    impl<E: Entity> AsRowRef<E> for Row<E> {
406        #[inline]
407        fn as_row_ref(&self) -> RowRef<'_, E> {
408            (*self).as_ref()
409        }
410    }
411    impl<E: Entity> AsRowRef<E> for &'_ Row<E> {
412        #[inline]
413        fn as_row_ref(&self) -> RowRef<'_, E> {
414            (**self).as_ref()
415        }
416    }
417
418    impl<E: Entity> AsRowMut<E> for RowMut<'_, E> {
419        #[inline]
420        fn as_row_mut(&mut self) -> RowMut<'_, E> {
421            (*self).rb_mut()
422        }
423    }
424
425    impl<E: Entity> AsRowMut<E> for &'_ mut RowMut<'_, E> {
426        #[inline]
427        fn as_row_mut(&mut self) -> RowMut<'_, E> {
428            (**self).rb_mut()
429        }
430    }
431
432    impl<E: Entity> AsRowMut<E> for Row<E> {
433        #[inline]
434        fn as_row_mut(&mut self) -> RowMut<'_, E> {
435            (*self).as_mut()
436        }
437    }
438
439    impl<E: Entity> AsRowMut<E> for &'_ mut Row<E> {
440        #[inline]
441        fn as_row_mut(&mut self) -> RowMut<'_, E> {
442            (**self).as_mut()
443        }
444    }
445};
446
447// AS MAT
448const _: () = {
449    impl<E: Entity> AsMatRef<E> for MatRef<'_, E> {
450        #[inline]
451        fn as_mat_ref(&self) -> MatRef<'_, E> {
452            *self
453        }
454    }
455    impl<E: Entity> AsMatRef<E> for &'_ MatRef<'_, E> {
456        #[inline]
457        fn as_mat_ref(&self) -> MatRef<'_, E> {
458            **self
459        }
460    }
461    impl<E: Entity> AsMatRef<E> for MatMut<'_, E> {
462        #[inline]
463        fn as_mat_ref(&self) -> MatRef<'_, E> {
464            (*self).rb()
465        }
466    }
467    impl<E: Entity> AsMatRef<E> for &'_ MatMut<'_, E> {
468        #[inline]
469        fn as_mat_ref(&self) -> MatRef<'_, E> {
470            (**self).rb()
471        }
472    }
473    impl<E: Entity> AsMatRef<E> for Mat<E> {
474        #[inline]
475        fn as_mat_ref(&self) -> MatRef<'_, E> {
476            (*self).as_ref()
477        }
478    }
479    impl<E: Entity> AsMatRef<E> for &'_ Mat<E> {
480        #[inline]
481        fn as_mat_ref(&self) -> MatRef<'_, E> {
482            (**self).as_ref()
483        }
484    }
485
486    impl<E: Entity> AsMatMut<E> for MatMut<'_, E> {
487        #[inline]
488        fn as_mat_mut(&mut self) -> MatMut<'_, E> {
489            (*self).rb_mut()
490        }
491    }
492
493    impl<E: Entity> AsMatMut<E> for &'_ mut MatMut<'_, E> {
494        #[inline]
495        fn as_mat_mut(&mut self) -> MatMut<'_, E> {
496            (**self).rb_mut()
497        }
498    }
499
500    impl<E: Entity> AsMatMut<E> for Mat<E> {
501        #[inline]
502        fn as_mat_mut(&mut self) -> MatMut<'_, E> {
503            (*self).as_mut()
504        }
505    }
506
507    impl<E: Entity> AsMatMut<E> for &'_ mut Mat<E> {
508        #[inline]
509        fn as_mat_mut(&mut self) -> MatMut<'_, E> {
510            (**self).as_mut()
511        }
512    }
513};
514
515// AS 2D
516const _: () = {
517    // Matrix family
518    impl<E: Entity> As2D<E> for &'_ MatRef<'_, E> {
519        #[inline]
520        fn as_2d_ref(&self) -> MatRef<'_, E> {
521            **self
522        }
523    }
524
525    impl<E: Entity> As2D<E> for MatRef<'_, E> {
526        #[inline]
527        fn as_2d_ref(&self) -> MatRef<'_, E> {
528            *self
529        }
530    }
531
532    impl<E: Entity> As2D<E> for &'_ MatMut<'_, E> {
533        #[inline]
534        fn as_2d_ref(&self) -> MatRef<'_, E> {
535            (**self).rb()
536        }
537    }
538
539    impl<E: Entity> As2D<E> for MatMut<'_, E> {
540        #[inline]
541        fn as_2d_ref(&self) -> MatRef<'_, E> {
542            (*self).rb()
543        }
544    }
545
546    impl<E: Entity> As2D<E> for &'_ Mat<E> {
547        #[inline]
548        fn as_2d_ref(&self) -> MatRef<'_, E> {
549            (**self).as_ref()
550        }
551    }
552
553    impl<E: Entity> As2D<E> for Mat<E> {
554        #[inline]
555        fn as_2d_ref(&self) -> MatRef<'_, E> {
556            (*self).as_ref()
557        }
558    }
559
560    // Row Family
561    impl<E: Entity> As2D<E> for &'_ RowRef<'_, E> {
562        #[inline]
563        fn as_2d_ref(&self) -> MatRef<'_, E> {
564            self.as_2d()
565        }
566    }
567
568    impl<E: Entity> As2D<E> for RowRef<'_, E> {
569        #[inline]
570        fn as_2d_ref(&self) -> MatRef<'_, E> {
571            self.as_2d()
572        }
573    }
574
575    impl<E: Entity> As2D<E> for &'_ RowMut<'_, E> {
576        #[inline]
577        fn as_2d_ref(&self) -> MatRef<'_, E> {
578            (**self).rb().as_2d()
579        }
580    }
581
582    impl<E: Entity> As2D<E> for RowMut<'_, E> {
583        #[inline]
584        fn as_2d_ref(&self) -> MatRef<'_, E> {
585            self.rb().as_2d()
586        }
587    }
588
589    impl<E: Entity> As2D<E> for &'_ Row<E> {
590        #[inline]
591        fn as_2d_ref(&self) -> MatRef<'_, E> {
592            (**self).as_ref().as_2d()
593        }
594    }
595
596    impl<E: Entity> As2D<E> for Row<E> {
597        #[inline]
598        fn as_2d_ref(&self) -> MatRef<'_, E> {
599            self.as_ref().as_2d()
600        }
601    }
602
603    // Col Family
604    impl<E: Entity> As2D<E> for &'_ ColRef<'_, E> {
605        #[inline]
606        fn as_2d_ref(&self) -> MatRef<'_, E> {
607            self.as_2d()
608        }
609    }
610
611    impl<E: Entity> As2D<E> for ColRef<'_, E> {
612        #[inline]
613        fn as_2d_ref(&self) -> MatRef<'_, E> {
614            self.as_2d()
615        }
616    }
617
618    impl<E: Entity> As2D<E> for &'_ ColMut<'_, E> {
619        #[inline]
620        fn as_2d_ref(&self) -> MatRef<'_, E> {
621            (**self).rb().as_2d()
622        }
623    }
624
625    impl<E: Entity> As2D<E> for ColMut<'_, E> {
626        #[inline]
627        fn as_2d_ref(&self) -> MatRef<'_, E> {
628            self.rb().as_2d()
629        }
630    }
631
632    impl<E: Entity> As2D<E> for &'_ Col<E> {
633        #[inline]
634        fn as_2d_ref(&self) -> MatRef<'_, E> {
635            (**self).as_ref().as_2d()
636        }
637    }
638
639    impl<E: Entity> As2D<E> for Col<E> {
640        #[inline]
641        fn as_2d_ref(&self) -> MatRef<'_, E> {
642            self.as_ref().as_2d()
643        }
644    }
645};
646
647// AS 2D MUT
648const _: () = {
649    // Matrix family
650    impl<E: Entity> As2DMut<E> for &'_ mut MatMut<'_, E> {
651        #[inline]
652        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
653            (**self).rb_mut()
654        }
655    }
656
657    impl<E: Entity> As2DMut<E> for MatMut<'_, E> {
658        #[inline]
659        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
660            (*self).rb_mut()
661        }
662    }
663
664    impl<E: Entity> As2DMut<E> for &'_ mut Mat<E> {
665        #[inline]
666        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
667            (**self).as_mut()
668        }
669    }
670
671    impl<E: Entity> As2DMut<E> for Mat<E> {
672        #[inline]
673        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
674            (*self).as_mut()
675        }
676    }
677
678    // Row Family
679    impl<E: Entity> As2DMut<E> for &'_ mut RowMut<'_, E> {
680        #[inline]
681        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
682            (**self).rb_mut().as_2d_mut()
683        }
684    }
685
686    impl<E: Entity> As2DMut<E> for RowMut<'_, E> {
687        #[inline]
688        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
689            self.rb_mut().as_2d_mut()
690        }
691    }
692
693    impl<E: Entity> As2DMut<E> for &'_ mut Row<E> {
694        #[inline]
695        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
696            (**self).as_mut().as_2d_mut()
697        }
698    }
699
700    impl<E: Entity> As2DMut<E> for Row<E> {
701        #[inline]
702        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
703            self.as_mut().as_2d_mut()
704        }
705    }
706
707    // Col Family
708    impl<E: Entity> As2DMut<E> for &'_ mut ColMut<'_, E> {
709        #[inline]
710        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
711            (**self).rb_mut().as_2d_mut()
712        }
713    }
714
715    impl<E: Entity> As2DMut<E> for ColMut<'_, E> {
716        #[inline]
717        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
718            self.rb_mut().as_2d_mut()
719        }
720    }
721
722    impl<E: Entity> As2DMut<E> for &'_ mut Col<E> {
723        #[inline]
724        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
725            (**self).as_mut().as_2d_mut()
726        }
727    }
728
729    impl<E: Entity> As2DMut<E> for Col<E> {
730        #[inline]
731        fn as_2d_mut(&mut self) -> MatMut<'_, E> {
732            self.as_mut().as_2d_mut()
733        }
734    }
735};
736
737#[cfg(feature = "std")]
738#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
739impl<E: Entity> matrixcompare_core::Matrix<E> for MatRef<'_, E> {
740    #[inline]
741    fn rows(&self) -> usize {
742        self.nrows()
743    }
744    #[inline]
745    fn cols(&self) -> usize {
746        self.ncols()
747    }
748    #[inline]
749    fn access(&self) -> matrixcompare_core::Access<'_, E> {
750        matrixcompare_core::Access::Dense(self)
751    }
752}
753
754#[cfg(feature = "std")]
755#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
756impl<E: Entity> matrixcompare_core::DenseAccess<E> for MatRef<'_, E> {
757    #[inline]
758    fn fetch_single(&self, row: usize, col: usize) -> E {
759        self.read(row, col)
760    }
761}
762
763#[cfg(feature = "std")]
764#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
765impl<E: Entity> matrixcompare_core::Matrix<E> for MatMut<'_, E> {
766    #[inline]
767    fn rows(&self) -> usize {
768        self.nrows()
769    }
770    #[inline]
771    fn cols(&self) -> usize {
772        self.ncols()
773    }
774    #[inline]
775    fn access(&self) -> matrixcompare_core::Access<'_, E> {
776        matrixcompare_core::Access::Dense(self)
777    }
778}
779
780#[cfg(feature = "std")]
781#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
782impl<E: Entity> matrixcompare_core::DenseAccess<E> for MatMut<'_, E> {
783    #[inline]
784    fn fetch_single(&self, row: usize, col: usize) -> E {
785        self.read(row, col)
786    }
787}
788
789#[cfg(feature = "std")]
790#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
791impl<E: Entity> matrixcompare_core::Matrix<E> for Mat<E> {
792    #[inline]
793    fn rows(&self) -> usize {
794        self.nrows()
795    }
796    #[inline]
797    fn cols(&self) -> usize {
798        self.ncols()
799    }
800    #[inline]
801    fn access(&self) -> matrixcompare_core::Access<'_, E> {
802        matrixcompare_core::Access::Dense(self)
803    }
804}
805
806#[cfg(feature = "std")]
807#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
808impl<E: Entity> matrixcompare_core::DenseAccess<E> for Mat<E> {
809    #[inline]
810    fn fetch_single(&self, row: usize, col: usize) -> E {
811        self.read(row, col)
812    }
813}
814
815#[repr(C)]
816struct VecImpl<E: Entity> {
817    ptr: GroupCopyFor<E, NonNull<E::Unit>>,
818    len: usize,
819    stride: isize,
820}
821#[repr(C)]
822struct VecOwnImpl<E: Entity> {
823    ptr: GroupCopyFor<E, NonNull<E::Unit>>,
824    len: usize,
825}
826
827#[repr(C)]
828struct MatImpl<E: Entity> {
829    ptr: GroupCopyFor<E, NonNull<E::Unit>>,
830    nrows: usize,
831    ncols: usize,
832    row_stride: isize,
833    col_stride: isize,
834}
835#[repr(C)]
836struct MatOwnImpl<E: Entity> {
837    ptr: GroupCopyFor<E, NonNull<E::Unit>>,
838    nrows: usize,
839    ncols: usize,
840}
841
842impl<E: Entity> Copy for VecImpl<E> {}
843impl<E: Entity> Clone for VecImpl<E> {
844    #[inline(always)]
845    fn clone(&self) -> Self {
846        *self
847    }
848}
849
850impl<E: Entity> Copy for MatImpl<E> {}
851impl<E: Entity> Clone for MatImpl<E> {
852    #[inline(always)]
853    fn clone(&self) -> Self {
854        *self
855    }
856}
857
858/// Generic matrix container.
859#[derive(Copy, Clone)]
860pub struct Matrix<M> {
861    inner: M,
862}
863
864/// Specialized containers that are used with [`Matrix`].
865pub mod inner {
866    use super::*;
867    use crate::group_helpers::VecGroup;
868
869    impl<E: Entity> Copy for DiagRef<'_, E> {}
870    impl<E: Entity> Clone for DiagRef<'_, E> {
871        #[inline(always)]
872        fn clone(&self) -> Self {
873            *self
874        }
875    }
876
877    impl<E: Entity> Copy for DenseRowRef<'_, E> {}
878    impl<E: Entity> Clone for DenseRowRef<'_, E> {
879        #[inline(always)]
880        fn clone(&self) -> Self {
881            *self
882        }
883    }
884
885    impl<E: Entity> Copy for DenseColRef<'_, E> {}
886    impl<E: Entity> Clone for DenseColRef<'_, E> {
887        #[inline(always)]
888        fn clone(&self) -> Self {
889            *self
890        }
891    }
892
893    impl<E: Entity> Copy for DenseRef<'_, E> {}
894    impl<E: Entity> Clone for DenseRef<'_, E> {
895        #[inline(always)]
896        fn clone(&self) -> Self {
897            *self
898        }
899    }
900
901    impl<I, E: Entity> Copy for PermRef<'_, I, E> {}
902    impl<I, E: Entity> Clone for PermRef<'_, I, E> {
903        #[inline(always)]
904        fn clone(&self) -> Self {
905            *self
906        }
907    }
908
909    /// Immutable permutation view.
910    #[repr(C)]
911    #[derive(Debug)]
912    pub struct PermRef<'a, I, E: Entity> {
913        pub(crate) forward: &'a [I],
914        pub(crate) inverse: &'a [I],
915        pub(crate) __marker: PhantomData<E>,
916    }
917    /// Mutable permutation view.
918    #[repr(C)]
919    #[derive(Debug)]
920    pub struct PermMut<'a, I, E: Entity> {
921        pub(crate) forward: &'a mut [I],
922        pub(crate) inverse: &'a mut [I],
923        pub(crate) __marker: PhantomData<E>,
924    }
925    /// Owned permutation.
926    #[repr(C)]
927    #[derive(Debug)]
928    pub struct PermOwn<I, E: Entity> {
929        pub(crate) forward: alloc::boxed::Box<[I]>,
930        pub(crate) inverse: alloc::boxed::Box<[I]>,
931        pub(crate) __marker: PhantomData<E>,
932    }
933
934    /// Immutable diagonal matrix view.
935    #[repr(C)]
936    pub struct DiagRef<'a, E: Entity> {
937        pub(crate) inner: ColRef<'a, E>,
938    }
939
940    /// Mutable diagonal matrix view.
941    #[repr(C)]
942    pub struct DiagMut<'a, E: Entity> {
943        pub(crate) inner: ColMut<'a, E>,
944    }
945
946    /// Owned diagonal matrix.
947    #[repr(C)]
948    pub struct DiagOwn<E: Entity> {
949        pub(crate) inner: Col<E>,
950    }
951
952    /// Immutable column vector view.
953    #[repr(C)]
954    pub struct DenseColRef<'a, E: Entity> {
955        pub(crate) inner: VecImpl<E>,
956        pub(crate) __marker: PhantomData<&'a E>,
957    }
958
959    /// Mutable column vector view.
960    #[repr(C)]
961    pub struct DenseColMut<'a, E: Entity> {
962        pub(crate) inner: VecImpl<E>,
963        pub(crate) __marker: PhantomData<&'a mut E>,
964    }
965
966    /// Owned column vector.
967    #[repr(C)]
968    pub struct DenseColOwn<E: Entity> {
969        pub(crate) inner: VecOwnImpl<E>,
970        pub(crate) row_capacity: usize,
971    }
972
973    /// Immutable row vector view.
974    #[repr(C)]
975    pub struct DenseRowRef<'a, E: Entity> {
976        pub(crate) inner: VecImpl<E>,
977        pub(crate) __marker: PhantomData<&'a E>,
978    }
979
980    /// Mutable row vector view.
981    #[repr(C)]
982    pub struct DenseRowMut<'a, E: Entity> {
983        pub(crate) inner: VecImpl<E>,
984        pub(crate) __marker: PhantomData<&'a mut E>,
985    }
986
987    /// Owned row vector.
988    #[repr(C)]
989    pub struct DenseRowOwn<E: Entity> {
990        pub(crate) inner: VecOwnImpl<E>,
991        pub(crate) col_capacity: usize,
992    }
993
994    /// Immutable dense matrix view.
995    #[repr(C)]
996    pub struct DenseRef<'a, E: Entity> {
997        pub(crate) inner: MatImpl<E>,
998        pub(crate) __marker: PhantomData<&'a E>,
999    }
1000
1001    /// Mutable dense matrix view.
1002    #[repr(C)]
1003    pub struct DenseMut<'a, E: Entity> {
1004        pub(crate) inner: MatImpl<E>,
1005        pub(crate) __marker: PhantomData<&'a mut E>,
1006    }
1007
1008    /// Owned dense matrix.
1009    #[repr(C)]
1010    pub struct DenseOwn<E: Entity> {
1011        pub(crate) inner: MatOwnImpl<E>,
1012        pub(crate) row_capacity: usize,
1013        pub(crate) col_capacity: usize,
1014    }
1015
1016    /// Scaling factor.
1017    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
1018    #[repr(transparent)]
1019    pub struct Scale<E: Entity>(pub E);
1020
1021    use permutation::Index;
1022
1023    /// Immutable sparse matrix view, in column-major order.
1024    #[derive(Debug)]
1025    pub struct SparseColMatRef<'a, I: Index, E: Entity> {
1026        pub(crate) symbolic: sparse::SymbolicSparseColMatRef<'a, I>,
1027        pub(crate) values: SliceGroup<'a, E>,
1028    }
1029
1030    /// Immutable sparse matrix view, in row-major order.
1031    #[derive(Debug)]
1032    pub struct SparseRowMatRef<'a, I: Index, E: Entity> {
1033        pub(crate) symbolic: sparse::SymbolicSparseRowMatRef<'a, I>,
1034        pub(crate) values: SliceGroup<'a, E>,
1035    }
1036
1037    /// Mutable sparse matrix view, in column-major order.
1038    #[derive(Debug)]
1039    pub struct SparseColMatMut<'a, I: Index, E: Entity> {
1040        pub(crate) symbolic: sparse::SymbolicSparseColMatRef<'a, I>,
1041        pub(crate) values: SliceGroupMut<'a, E>,
1042    }
1043
1044    /// Mutable sparse matrix view, in row-major order.
1045    #[derive(Debug)]
1046    pub struct SparseRowMatMut<'a, I: Index, E: Entity> {
1047        pub(crate) symbolic: sparse::SymbolicSparseRowMatRef<'a, I>,
1048        pub(crate) values: SliceGroupMut<'a, E>,
1049    }
1050
1051    /// Owned sparse matrix, in column-major order.
1052    #[derive(Debug, Clone)]
1053    pub struct SparseColMat<I: Index, E: Entity> {
1054        pub(crate) symbolic: sparse::SymbolicSparseColMat<I>,
1055        pub(crate) values: VecGroup<E>,
1056    }
1057
1058    /// Owned sparse matrix, in row-major order.
1059    #[derive(Debug, Clone)]
1060    pub struct SparseRowMat<I: Index, E: Entity> {
1061        pub(crate) symbolic: sparse::SymbolicSparseRowMat<I>,
1062        pub(crate) values: VecGroup<E>,
1063    }
1064
1065    impl<I: Index, E: Entity> Copy for SparseRowMatRef<'_, I, E> {}
1066    impl<I: Index, E: Entity> Clone for SparseRowMatRef<'_, I, E> {
1067        #[inline]
1068        fn clone(&self) -> Self {
1069            *self
1070        }
1071    }
1072    impl<I: Index, E: Entity> Copy for SparseColMatRef<'_, I, E> {}
1073    impl<I: Index, E: Entity> Clone for SparseColMatRef<'_, I, E> {
1074        #[inline]
1075        fn clone(&self) -> Self {
1076            *self
1077        }
1078    }
1079}
1080
1081/// Advanced: Helper types for working with [`GroupFor`] in generic contexts.
1082pub mod group_helpers {
1083    pub use pulp::{Read, Write};
1084
1085    /// Analogous to [`alloc::vec::Vec`] for groups.
1086    pub struct VecGroup<E: Entity, T = UnitFor<E>> {
1087        inner: GroupFor<E, alloc::vec::Vec<T>>,
1088    }
1089
1090    impl<E: Entity, T: Clone> Clone for VecGroup<E, T> {
1091        #[inline]
1092        fn clone(&self) -> Self {
1093            Self {
1094                inner: E::faer_map(E::faer_as_ref(&self.inner), |v| (*v).clone()),
1095            }
1096        }
1097    }
1098
1099    impl<E: Entity, T: Debug> Debug for VecGroup<E, T> {
1100        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1101            self.as_slice().fmt(f)
1102        }
1103    }
1104
1105    unsafe impl<E: Entity, T: Sync> Sync for VecGroup<E, T> {}
1106    unsafe impl<E: Entity, T: Send> Send for VecGroup<E, T> {}
1107
1108    impl<E: Entity, T> VecGroup<E, T> {
1109        /// Create a new [`VecGroup`] from a group of [`alloc::vec::Vec`].
1110        #[inline]
1111        pub fn from_inner(inner: GroupFor<E, alloc::vec::Vec<T>>) -> Self {
1112            Self { inner }
1113        }
1114
1115        /// Consume `self` to return a group of [`alloc::vec::Vec`].
1116        #[inline]
1117        pub fn into_inner(self) -> GroupFor<E, alloc::vec::Vec<T>> {
1118            self.inner
1119        }
1120
1121        /// Return a reference to the inner group of [`alloc::vec::Vec`].
1122        #[inline]
1123        pub fn as_inner_ref(&self) -> GroupFor<E, &alloc::vec::Vec<T>> {
1124            E::faer_as_ref(&self.inner)
1125        }
1126
1127        /// Return a mutable reference to the inner group of [`alloc::vec::Vec`].
1128        #[inline]
1129        pub fn as_inner_mut(&mut self) -> GroupFor<E, &mut alloc::vec::Vec<T>> {
1130            E::faer_as_mut(&mut self.inner)
1131        }
1132
1133        /// Return a [`SliceGroup`] view over the elements of `self`.
1134        #[inline]
1135        pub fn as_slice(&self) -> SliceGroup<'_, E, T> {
1136            SliceGroup::new(E::faer_map(
1137                E::faer_as_ref(&self.inner),
1138                #[inline]
1139                |slice| &**slice,
1140            ))
1141        }
1142
1143        /// Return a [`SliceGroupMut`] mutable view over the elements of `self`.
1144        #[inline]
1145        pub fn as_slice_mut(&mut self) -> SliceGroupMut<'_, E, T> {
1146            SliceGroupMut::new(E::faer_map(
1147                E::faer_as_mut(&mut self.inner),
1148                #[inline]
1149                |slice| &mut **slice,
1150            ))
1151        }
1152
1153        /// Create an empty [`VecGroup`].
1154        #[inline]
1155        pub fn new() -> Self {
1156            Self {
1157                inner: E::faer_map(E::UNIT, |()| alloc::vec::Vec::new()),
1158            }
1159        }
1160
1161        /// Returns the length of the vector group.
1162        #[inline]
1163        pub fn len(&self) -> usize {
1164            let mut len = usize::MAX;
1165            E::faer_map(
1166                E::faer_as_ref(&self.inner),
1167                #[inline(always)]
1168                |slice| len = Ord::min(len, slice.len()),
1169            );
1170            len
1171        }
1172
1173        /// Returns the capacity of the vector group.
1174        #[inline]
1175        pub fn capacity(&self) -> usize {
1176            let mut cap = usize::MAX;
1177            E::faer_map(
1178                E::faer_as_ref(&self.inner),
1179                #[inline(always)]
1180                |slice| cap = Ord::min(cap, slice.capacity()),
1181            );
1182            cap
1183        }
1184
1185        /// Reserve enough capacity for extra `additional` elements.
1186        pub fn reserve(&mut self, additional: usize) {
1187            E::faer_map(E::faer_as_mut(&mut self.inner), |v| v.reserve(additional));
1188        }
1189
1190        /// Reserve exactly enough capacity for extra `additional` elements.
1191        pub fn reserve_exact(&mut self, additional: usize) {
1192            E::faer_map(E::faer_as_mut(&mut self.inner), |v| {
1193                v.reserve_exact(additional)
1194            });
1195        }
1196
1197        /// Try to reserve enough capacity for extra `additional` elements.
1198        pub fn try_reserve(
1199            &mut self,
1200            additional: usize,
1201        ) -> Result<(), alloc::collections::TryReserveError> {
1202            let mut result = Ok(());
1203            E::faer_map(E::faer_as_mut(&mut self.inner), |v| match &result {
1204                Ok(()) => result = v.try_reserve(additional),
1205                Err(_) => {}
1206            });
1207            result
1208        }
1209
1210        /// Try to reserve exactly enough capacity for extra `additional` elements.
1211        pub fn try_reserve_exact(
1212            &mut self,
1213            additional: usize,
1214        ) -> Result<(), alloc::collections::TryReserveError> {
1215            let mut result = Ok(());
1216            E::faer_map(E::faer_as_mut(&mut self.inner), |v| match &result {
1217                Ok(()) => result = v.try_reserve_exact(additional),
1218                Err(_) => {}
1219            });
1220            result
1221        }
1222
1223        /// Truncate the length of the vector to `len`.
1224        pub fn truncate(&mut self, len: usize) {
1225            E::faer_map(E::faer_as_mut(&mut self.inner), |v| v.truncate(len));
1226        }
1227
1228        /// Clear the vector, making it empty.
1229        pub fn clear(&mut self) {
1230            E::faer_map(E::faer_as_mut(&mut self.inner), |v| v.clear());
1231        }
1232
1233        /// Resize the vector to `new_len`, filling the new elements with
1234        /// `value`.
1235        pub fn resize(&mut self, new_len: usize, value: GroupFor<E, T>)
1236        where
1237            T: Clone,
1238        {
1239            E::faer_map(
1240                E::faer_zip(E::faer_as_mut(&mut self.inner), value),
1241                |(v, value)| v.resize(new_len, value),
1242            );
1243        }
1244
1245        /// Resize the vector to `new_len`, filling the new elements with
1246        /// the output of `f`.
1247        pub fn resize_with(&mut self, new_len: usize, f: impl FnMut() -> GroupFor<E, T>) {
1248            let len = self.len();
1249            let mut f = f;
1250            if new_len <= len {
1251                self.truncate(new_len);
1252            } else {
1253                self.reserve(new_len - len);
1254                for _ in len..new_len {
1255                    self.push(f())
1256                }
1257            }
1258        }
1259
1260        /// Push a new element to the end of `self`.
1261        #[inline]
1262        pub fn push(&mut self, value: GroupFor<E, T>) {
1263            E::faer_map(
1264                E::faer_zip(E::faer_as_mut(&mut self.inner), value),
1265                #[inline]
1266                |(v, value)| v.push(value),
1267            );
1268        }
1269
1270        /// Remove a new element from the end of `self`, and return it.
1271        #[inline]
1272        pub fn pop(&mut self) -> Option<GroupFor<E, T>> {
1273            if self.len() >= 1 {
1274                Some(E::faer_map(
1275                    E::faer_as_mut(&mut self.inner),
1276                    #[inline]
1277                    |v| v.pop().unwrap(),
1278                ))
1279            } else {
1280                None
1281            }
1282        }
1283
1284        /// Remove a new element from position `index`, and return it.
1285        #[inline]
1286        pub fn remove(&mut self, index: usize) -> GroupFor<E, T> {
1287            E::faer_map(
1288                E::faer_as_mut(&mut self.inner),
1289                #[inline]
1290                |v| v.remove(index),
1291            )
1292        }
1293    }
1294
1295    /// Do conjugate.
1296    #[derive(Copy, Clone, Debug)]
1297    pub struct YesConj;
1298    /// Do not conjugate.
1299    #[derive(Copy, Clone, Debug)]
1300    pub struct NoConj;
1301
1302    /// Similar to [`Conj`], but determined at compile time instead of runtime.
1303    pub trait ConjTy: Copy + Debug {
1304        /// The corresponding [`Conj`] value.
1305        const CONJ: Conj;
1306        /// The opposing conjugation type.
1307        type Flip: ConjTy;
1308
1309        /// Returns an instance of the corresponding conjugation type.
1310        fn flip(self) -> Self::Flip;
1311    }
1312
1313    impl ConjTy for YesConj {
1314        const CONJ: Conj = Conj::Yes;
1315        type Flip = NoConj;
1316        #[inline(always)]
1317        fn flip(self) -> Self::Flip {
1318            NoConj
1319        }
1320    }
1321    impl ConjTy for NoConj {
1322        const CONJ: Conj = Conj::No;
1323        type Flip = YesConj;
1324        #[inline(always)]
1325        fn flip(self) -> Self::Flip {
1326            YesConj
1327        }
1328    }
1329
1330    use super::*;
1331    use crate::{assert, debug_assert};
1332    use core::ops::Range;
1333
1334    /// Wrapper for simd operations for type `E`.
1335    pub struct SimdFor<E: Entity, S: pulp::Simd> {
1336        /// Simd token.
1337        pub simd: S,
1338        __marker: PhantomData<E>,
1339    }
1340
1341    impl<E: Entity, S: pulp::Simd> Copy for SimdFor<E, S> {}
1342    impl<E: Entity, S: pulp::Simd> Clone for SimdFor<E, S> {
1343        #[inline]
1344        fn clone(&self) -> Self {
1345            *self
1346        }
1347    }
1348
1349    impl<E: ComplexField, S: pulp::Simd> SimdFor<E, S> {
1350        /// Create a new wrapper from a simd token.
1351        #[inline(always)]
1352        pub fn new(simd: S) -> Self {
1353            Self {
1354                simd,
1355                __marker: PhantomData,
1356            }
1357        }
1358
1359        /// Computes the alignment offset for subsequent aligned loads.
1360        #[inline(always)]
1361        pub fn align_offset(self, slice: SliceGroup<'_, E>) -> pulp::Offset<E::SimdMask<S>> {
1362            let slice = E::faer_first(slice.into_inner());
1363            E::faer_align_offset(self.simd, slice.as_ptr(), slice.len())
1364        }
1365
1366        /// Computes the alignment offset for subsequent aligned loads from a pointer.
1367        #[inline(always)]
1368        pub fn align_offset_ptr(
1369            self,
1370            ptr: GroupFor<E, *const E::Unit>,
1371            len: usize,
1372        ) -> pulp::Offset<E::SimdMask<S>> {
1373            E::faer_align_offset(self.simd, E::faer_first(ptr), len)
1374        }
1375
1376        /// Convert a slice to a slice over vector registers, and a scalar tail.
1377        #[inline(always)]
1378        pub fn as_simd(
1379            self,
1380            slice: SliceGroup<'_, E>,
1381        ) -> (SliceGroup<'_, E, SimdUnitFor<E, S>>, SliceGroup<'_, E>) {
1382            let (head, tail) = slice_as_simd::<E, S>(slice.into_inner());
1383            (SliceGroup::new(head), SliceGroup::new(tail))
1384        }
1385
1386        /// Convert a mutable slice to a slice over vector registers, and a scalar tail.
1387        #[inline(always)]
1388        pub fn as_simd_mut(
1389            self,
1390            slice: SliceGroupMut<'_, E>,
1391        ) -> (
1392            SliceGroupMut<'_, E, SimdUnitFor<E, S>>,
1393            SliceGroupMut<'_, E>,
1394        ) {
1395            let (head, tail) = slice_as_mut_simd::<E, S>(slice.into_inner());
1396            (SliceGroupMut::new(head), SliceGroupMut::new(tail))
1397        }
1398
1399        /// Convert a slice to a partial register prefix and suffix, and a vector register slice
1400        /// (body).
1401        #[inline(always)]
1402        pub fn as_aligned_simd(
1403            self,
1404            slice: SliceGroup<'_, E>,
1405            offset: pulp::Offset<E::SimdMask<S>>,
1406        ) -> (
1407            Prefix<'_, E, S>,
1408            SliceGroup<'_, E, SimdUnitFor<E, S>>,
1409            Suffix<'_, E, S>,
1410        ) {
1411            let (head_tail, body) = E::faer_unzip(E::faer_map(slice.into_inner(), |slice| {
1412                let (head, body, tail) = E::faer_slice_as_aligned_simd(self.simd, slice, offset);
1413                ((head, tail), body)
1414            }));
1415
1416            let (head, tail) = E::faer_unzip(head_tail);
1417
1418            unsafe {
1419                (
1420                    Prefix(
1421                        transmute_unchecked::<
1422                            GroupCopyFor<E, E::PrefixUnit<'_, S>>,
1423                            GroupCopyFor<E, E::PrefixUnit<'static, S>>,
1424                        >(into_copy::<E, _>(head)),
1425                        PhantomData,
1426                    ),
1427                    SliceGroup::new(body),
1428                    Suffix(
1429                        transmute_unchecked::<
1430                            GroupCopyFor<E, E::SuffixUnit<'_, S>>,
1431                            GroupCopyFor<E, E::SuffixUnit<'static, S>>,
1432                        >(into_copy::<E, _>(tail)),
1433                        PhantomData,
1434                    ),
1435                )
1436            }
1437        }
1438
1439        /// Convert a mutable slice to a partial register prefix and suffix, and a vector register
1440        /// slice (body).
1441        #[inline(always)]
1442        pub fn as_aligned_simd_mut(
1443            self,
1444            slice: SliceGroupMut<'_, E>,
1445            offset: pulp::Offset<E::SimdMask<S>>,
1446        ) -> (
1447            PrefixMut<'_, E, S>,
1448            SliceGroupMut<'_, E, SimdUnitFor<E, S>>,
1449            SuffixMut<'_, E, S>,
1450        ) {
1451            let (head_tail, body) = E::faer_unzip(E::faer_map(slice.into_inner(), |slice| {
1452                let (head, body, tail) =
1453                    E::faer_slice_as_aligned_simd_mut(self.simd, slice, offset);
1454                ((head, tail), body)
1455            }));
1456
1457            let (head, tail) = E::faer_unzip(head_tail);
1458
1459            (
1460                PrefixMut(
1461                    unsafe {
1462                        transmute_unchecked::<
1463                            GroupFor<E, E::PrefixMutUnit<'_, S>>,
1464                            GroupFor<E, E::PrefixMutUnit<'static, S>>,
1465                        >(head)
1466                    },
1467                    PhantomData,
1468                ),
1469                SliceGroupMut::new(body),
1470                SuffixMut(
1471                    unsafe {
1472                        transmute_unchecked::<
1473                            GroupFor<E, E::SuffixMutUnit<'_, S>>,
1474                            GroupFor<E, E::SuffixMutUnit<'static, S>>,
1475                        >(tail)
1476                    },
1477                    PhantomData,
1478                ),
1479            )
1480        }
1481
1482        /// Fill all the register lanes with the same value.
1483        #[inline(always)]
1484        pub fn splat(self, value: E) -> SimdGroupFor<E, S> {
1485            E::faer_simd_splat(self.simd, value)
1486        }
1487
1488        /// Returns `lhs * rhs`.
1489        #[inline(always)]
1490        pub fn scalar_mul(self, lhs: E, rhs: E) -> E {
1491            E::faer_simd_scalar_mul(self.simd, lhs, rhs)
1492        }
1493        /// Returns `conj(lhs) * rhs`.
1494        #[inline(always)]
1495        pub fn scalar_conj_mul(self, lhs: E, rhs: E) -> E {
1496            E::faer_simd_scalar_conj_mul(self.simd, lhs, rhs)
1497        }
1498        /// Returns an estimate of `lhs * rhs + acc`.
1499        #[inline(always)]
1500        pub fn scalar_mul_add_e(self, lhs: E, rhs: E, acc: E) -> E {
1501            E::faer_simd_scalar_mul_adde(self.simd, lhs, rhs, acc)
1502        }
1503        /// Returns an estimate of `conj(lhs) * rhs + acc`.
1504        #[inline(always)]
1505        pub fn scalar_conj_mul_add_e(self, lhs: E, rhs: E, acc: E) -> E {
1506            E::faer_simd_scalar_conj_mul_adde(self.simd, lhs, rhs, acc)
1507        }
1508
1509        /// Returns an estimate of `op(lhs) * rhs`, where `op` is either the conjugation
1510        /// or the identity operation.
1511        #[inline(always)]
1512        pub fn scalar_conditional_conj_mul<C: ConjTy>(self, conj: C, lhs: E, rhs: E) -> E {
1513            let _ = conj;
1514            if C::CONJ == Conj::Yes {
1515                self.scalar_conj_mul(lhs, rhs)
1516            } else {
1517                self.scalar_mul(lhs, rhs)
1518            }
1519        }
1520        /// Returns an estimate of `op(lhs) * rhs + acc`, where `op` is either the conjugation or
1521        /// the identity operation.
1522        #[inline(always)]
1523        pub fn scalar_conditional_conj_mul_add_e<C: ConjTy>(
1524            self,
1525            conj: C,
1526            lhs: E,
1527            rhs: E,
1528            acc: E,
1529        ) -> E {
1530            let _ = conj;
1531            if C::CONJ == Conj::Yes {
1532                self.scalar_conj_mul_add_e(lhs, rhs, acc)
1533            } else {
1534                self.scalar_mul_add_e(lhs, rhs, acc)
1535            }
1536        }
1537
1538        /// Returns `lhs + rhs`.
1539        #[inline(always)]
1540        pub fn add(self, lhs: SimdGroupFor<E, S>, rhs: SimdGroupFor<E, S>) -> SimdGroupFor<E, S> {
1541            E::faer_simd_add(self.simd, lhs, rhs)
1542        }
1543        /// Returns `lhs - rhs`.
1544        #[inline(always)]
1545        pub fn sub(self, lhs: SimdGroupFor<E, S>, rhs: SimdGroupFor<E, S>) -> SimdGroupFor<E, S> {
1546            E::faer_simd_sub(self.simd, lhs, rhs)
1547        }
1548        /// Returns `-a`.
1549        #[inline(always)]
1550        pub fn neg(self, a: SimdGroupFor<E, S>) -> SimdGroupFor<E, S> {
1551            E::faer_simd_neg(self.simd, a)
1552        }
1553        /// Returns `lhs * rhs`.
1554        #[inline(always)]
1555        pub fn scale_real(
1556            self,
1557            lhs: SimdGroupFor<E::Real, S>,
1558            rhs: SimdGroupFor<E, S>,
1559        ) -> SimdGroupFor<E, S> {
1560            E::faer_simd_scale_real(self.simd, lhs, rhs)
1561        }
1562        /// Returns `lhs * rhs`.
1563        #[inline(always)]
1564        pub fn mul(self, lhs: SimdGroupFor<E, S>, rhs: SimdGroupFor<E, S>) -> SimdGroupFor<E, S> {
1565            E::faer_simd_mul(self.simd, lhs, rhs)
1566        }
1567        /// Returns `conj(lhs) * rhs`.
1568        #[inline(always)]
1569        pub fn conj_mul(
1570            self,
1571            lhs: SimdGroupFor<E, S>,
1572            rhs: SimdGroupFor<E, S>,
1573        ) -> SimdGroupFor<E, S> {
1574            E::faer_simd_conj_mul(self.simd, lhs, rhs)
1575        }
1576        /// Returns `op(lhs) * rhs`, where `op` is either the conjugation or the identity
1577        /// operation.
1578        #[inline(always)]
1579        pub fn conditional_conj_mul<C: ConjTy>(
1580            self,
1581            conj: C,
1582            lhs: SimdGroupFor<E, S>,
1583            rhs: SimdGroupFor<E, S>,
1584        ) -> SimdGroupFor<E, S> {
1585            let _ = conj;
1586            if C::CONJ == Conj::Yes {
1587                self.conj_mul(lhs, rhs)
1588            } else {
1589                self.mul(lhs, rhs)
1590            }
1591        }
1592
1593        /// Returns `lhs * rhs + acc`.
1594        #[inline(always)]
1595        pub fn mul_add_e(
1596            self,
1597            lhs: SimdGroupFor<E, S>,
1598            rhs: SimdGroupFor<E, S>,
1599            acc: SimdGroupFor<E, S>,
1600        ) -> SimdGroupFor<E, S> {
1601            E::faer_simd_mul_adde(self.simd, lhs, rhs, acc)
1602        }
1603        /// Returns `conj(lhs) * rhs + acc`.
1604        #[inline(always)]
1605        pub fn conj_mul_add_e(
1606            self,
1607            lhs: SimdGroupFor<E, S>,
1608            rhs: SimdGroupFor<E, S>,
1609            acc: SimdGroupFor<E, S>,
1610        ) -> SimdGroupFor<E, S> {
1611            E::faer_simd_conj_mul_adde(self.simd, lhs, rhs, acc)
1612        }
1613        /// Returns `op(lhs) * rhs + acc`, where `op` is either the conjugation or the identity
1614        /// operation.
1615        #[inline(always)]
1616        pub fn conditional_conj_mul_add_e<C: ConjTy>(
1617            self,
1618            conj: C,
1619            lhs: SimdGroupFor<E, S>,
1620            rhs: SimdGroupFor<E, S>,
1621            acc: SimdGroupFor<E, S>,
1622        ) -> SimdGroupFor<E, S> {
1623            let _ = conj;
1624            if C::CONJ == Conj::Yes {
1625                self.conj_mul_add_e(lhs, rhs, acc)
1626            } else {
1627                self.mul_add_e(lhs, rhs, acc)
1628            }
1629        }
1630
1631        /// Returns `abs(values) * abs(values) + acc`.
1632        #[inline(always)]
1633        pub fn abs2_add_e(
1634            self,
1635            values: SimdGroupFor<E, S>,
1636            acc: SimdGroupFor<E::Real, S>,
1637        ) -> SimdGroupFor<E::Real, S> {
1638            E::faer_simd_abs2_adde(self.simd, values, acc)
1639        }
1640        /// Returns `abs(values) * abs(values)`.
1641        #[inline(always)]
1642        pub fn abs2(self, values: SimdGroupFor<E, S>) -> SimdGroupFor<E::Real, S> {
1643            E::faer_simd_abs2(self.simd, values)
1644        }
1645        /// Returns `abs(values)` or `abs(values) * abs(values)`, whichever is cheaper to compute.
1646        #[inline(always)]
1647        pub fn score(self, values: SimdGroupFor<E, S>) -> SimdGroupFor<E::Real, S> {
1648            E::faer_simd_score(self.simd, values)
1649        }
1650
1651        /// Sum the components of a vector register into a single accumulator.
1652        #[inline(always)]
1653        pub fn reduce_add(self, values: SimdGroupFor<E, S>) -> E {
1654            E::faer_simd_reduce_add(self.simd, values)
1655        }
1656
1657        /// Rotate `values` to the left, with overflowing entries wrapping around to the right side
1658        /// of the register.
1659        #[inline(always)]
1660        pub fn rotate_left(self, values: SimdGroupFor<E, S>, amount: usize) -> SimdGroupFor<E, S> {
1661            E::faer_simd_rotate_left(self.simd, values, amount)
1662        }
1663    }
1664
1665    impl<E: RealField, S: pulp::Simd> SimdFor<E, S> {
1666        /// Returns `abs(values)`.
1667        #[inline(always)]
1668        pub fn abs(self, values: SimdGroupFor<E, S>) -> SimdGroupFor<E::Real, S> {
1669            E::faer_simd_abs(self.simd, values)
1670        }
1671        /// Returns `a < b`.
1672        #[inline(always)]
1673        pub fn less_than(self, a: SimdGroupFor<E, S>, b: SimdGroupFor<E, S>) -> SimdMaskFor<E, S> {
1674            E::faer_simd_less_than(self.simd, a, b)
1675        }
1676        /// Returns `a <= b`.
1677        #[inline(always)]
1678        pub fn less_than_or_equal(
1679            self,
1680            a: SimdGroupFor<E, S>,
1681            b: SimdGroupFor<E, S>,
1682        ) -> SimdMaskFor<E, S> {
1683            E::faer_simd_less_than_or_equal(self.simd, a, b)
1684        }
1685        /// Returns `a > b`.
1686        #[inline(always)]
1687        pub fn greater_than(
1688            self,
1689            a: SimdGroupFor<E, S>,
1690            b: SimdGroupFor<E, S>,
1691        ) -> SimdMaskFor<E, S> {
1692            E::faer_simd_greater_than(self.simd, a, b)
1693        }
1694        /// Returns `a >= b`.
1695        #[inline(always)]
1696        pub fn greater_than_or_equal(
1697            self,
1698            a: SimdGroupFor<E, S>,
1699            b: SimdGroupFor<E, S>,
1700        ) -> SimdMaskFor<E, S> {
1701            E::faer_simd_greater_than_or_equal(self.simd, a, b)
1702        }
1703
1704        /// Returns `if mask { if_true } else { if_false }`
1705        #[inline(always)]
1706        pub fn select(
1707            self,
1708            mask: SimdMaskFor<E, S>,
1709            if_true: SimdGroupFor<E, S>,
1710            if_false: SimdGroupFor<E, S>,
1711        ) -> SimdGroupFor<E, S> {
1712            E::faer_simd_select(self.simd, mask, if_true, if_false)
1713        }
1714        /// Returns `if mask { if_true } else { if_false }`
1715        #[inline(always)]
1716        pub fn index_select(
1717            self,
1718            mask: SimdMaskFor<E, S>,
1719            if_true: SimdIndexFor<E, S>,
1720            if_false: SimdIndexFor<E, S>,
1721        ) -> SimdIndexFor<E, S> {
1722            E::faer_simd_index_select(self.simd, mask, if_true, if_false)
1723        }
1724        /// Returns `[0, 1, 2, 3, ..., REGISTER_SIZE - 1]`
1725        #[inline(always)]
1726        pub fn index_seq(self) -> SimdIndexFor<E, S> {
1727            E::faer_simd_index_seq(self.simd)
1728        }
1729        /// Fill all the register lanes with the same value.
1730        #[inline(always)]
1731        pub fn index_splat(self, value: IndexFor<E>) -> SimdIndexFor<E, S> {
1732            E::faer_simd_index_splat(self.simd, value)
1733        }
1734        /// Returns `a + b`.
1735        #[inline(always)]
1736        pub fn index_add(self, a: SimdIndexFor<E, S>, b: SimdIndexFor<E, S>) -> SimdIndexFor<E, S> {
1737            E::faer_simd_index_add(self.simd, a, b)
1738        }
1739    }
1740
1741    /// Analogous to an immutable reference to a [prim@slice] for groups.
1742    pub struct SliceGroup<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1743        GroupCopyFor<E, *const [T]>,
1744        PhantomData<&'a ()>,
1745    );
1746    /// Analogous to a mutable reference to a [prim@slice] for groups.
1747    pub struct SliceGroupMut<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1748        GroupFor<E, *mut [T]>,
1749        PhantomData<&'a mut ()>,
1750    );
1751
1752    /// Simd prefix, contains the elements before the body.
1753    pub struct Prefix<'a, E: Entity, S: pulp::Simd>(
1754        GroupCopyFor<E, E::PrefixUnit<'static, S>>,
1755        PhantomData<&'a ()>,
1756    );
1757    /// Simd suffix, contains the elements after the body.
1758    pub struct Suffix<'a, E: Entity, S: pulp::Simd>(
1759        GroupCopyFor<E, E::SuffixUnit<'static, S>>,
1760        PhantomData<&'a mut ()>,
1761    );
1762    /// Simd prefix (mutable), contains the elements before the body.
1763    pub struct PrefixMut<'a, E: Entity, S: pulp::Simd>(
1764        GroupFor<E, E::PrefixMutUnit<'static, S>>,
1765        PhantomData<&'a ()>,
1766    );
1767    /// Simd suffix (mutable), contains the elements after the body.
1768    pub struct SuffixMut<'a, E: Entity, S: pulp::Simd>(
1769        GroupFor<E, E::SuffixMutUnit<'static, S>>,
1770        PhantomData<&'a mut ()>,
1771    );
1772
1773    impl<E: Entity, T: Copy + Debug> Read for RefGroupMut<'_, E, T> {
1774        type Output = GroupCopyFor<E, T>;
1775        #[inline(always)]
1776        fn read_or(&self, _or: Self::Output) -> Self::Output {
1777            self.get()
1778        }
1779    }
1780    impl<E: Entity, T: Copy + Debug> Write for RefGroupMut<'_, E, T> {
1781        #[inline(always)]
1782        fn write(&mut self, values: Self::Output) {
1783            self.set(values)
1784        }
1785    }
1786    impl<E: Entity, T: Copy + Debug> Read for RefGroup<'_, E, T> {
1787        type Output = GroupCopyFor<E, T>;
1788        #[inline(always)]
1789        fn read_or(&self, _or: Self::Output) -> Self::Output {
1790            self.get()
1791        }
1792    }
1793
1794    impl<E: Entity, S: pulp::Simd> Read for Prefix<'_, E, S> {
1795        type Output = SimdGroupFor<E, S>;
1796        #[inline(always)]
1797        fn read_or(&self, or: Self::Output) -> Self::Output {
1798            into_copy::<E, _>(E::faer_map(
1799                E::faer_zip(from_copy::<E, _>(self.0), from_copy::<E, _>(or)),
1800                #[inline(always)]
1801                |(prefix, or)| prefix.read_or(or),
1802            ))
1803        }
1804    }
1805    impl<E: Entity, S: pulp::Simd> Read for PrefixMut<'_, E, S> {
1806        type Output = SimdGroupFor<E, S>;
1807        #[inline(always)]
1808        fn read_or(&self, or: Self::Output) -> Self::Output {
1809            self.rb().read_or(or)
1810        }
1811    }
1812    impl<E: Entity, S: pulp::Simd> Write for PrefixMut<'_, E, S> {
1813        #[inline(always)]
1814        fn write(&mut self, values: Self::Output) {
1815            E::faer_map(
1816                E::faer_zip(self.rb_mut().0, from_copy::<E, _>(values)),
1817                #[inline(always)]
1818                |(mut prefix, values)| prefix.write(values),
1819            );
1820        }
1821    }
1822
1823    impl<E: Entity, S: pulp::Simd> Read for Suffix<'_, E, S> {
1824        type Output = SimdGroupFor<E, S>;
1825        #[inline(always)]
1826        fn read_or(&self, or: Self::Output) -> Self::Output {
1827            into_copy::<E, _>(E::faer_map(
1828                E::faer_zip(from_copy::<E, _>(self.0), from_copy::<E, _>(or)),
1829                #[inline(always)]
1830                |(suffix, or)| suffix.read_or(or),
1831            ))
1832        }
1833    }
1834    impl<E: Entity, S: pulp::Simd> Read for SuffixMut<'_, E, S> {
1835        type Output = SimdGroupFor<E, S>;
1836        #[inline(always)]
1837        fn read_or(&self, or: Self::Output) -> Self::Output {
1838            self.rb().read_or(or)
1839        }
1840    }
1841    impl<E: Entity, S: pulp::Simd> Write for SuffixMut<'_, E, S> {
1842        #[inline(always)]
1843        fn write(&mut self, values: Self::Output) {
1844            E::faer_map(
1845                E::faer_zip(self.rb_mut().0, from_copy::<E, _>(values)),
1846                #[inline(always)]
1847                |(mut suffix, values)| suffix.write(values),
1848            );
1849        }
1850    }
1851
1852    impl<'short, E: Entity, S: pulp::Simd> Reborrow<'short> for PrefixMut<'_, E, S> {
1853        type Target = Prefix<'short, E, S>;
1854        #[inline]
1855        fn rb(&'short self) -> Self::Target {
1856            unsafe {
1857                Prefix(
1858                    into_copy::<E, _>(transmute_unchecked::<
1859                        GroupFor<E, <E::PrefixMutUnit<'static, S> as Reborrow<'_>>::Target>,
1860                        GroupFor<E, E::PrefixUnit<'static, S>>,
1861                    >(E::faer_map(
1862                        E::faer_as_ref(&self.0),
1863                        |x| (*x).rb(),
1864                    ))),
1865                    PhantomData,
1866                )
1867            }
1868        }
1869    }
1870    impl<'short, E: Entity, S: pulp::Simd> ReborrowMut<'short> for PrefixMut<'_, E, S> {
1871        type Target = PrefixMut<'short, E, S>;
1872        #[inline]
1873        fn rb_mut(&'short mut self) -> Self::Target {
1874            unsafe {
1875                PrefixMut(
1876                    transmute_unchecked::<
1877                        GroupFor<E, <E::PrefixMutUnit<'static, S> as ReborrowMut<'_>>::Target>,
1878                        GroupFor<E, E::PrefixMutUnit<'static, S>>,
1879                    >(E::faer_map(E::faer_as_mut(&mut self.0), |x| {
1880                        (*x).rb_mut()
1881                    })),
1882                    PhantomData,
1883                )
1884            }
1885        }
1886    }
1887    impl<'short, E: Entity, S: pulp::Simd> Reborrow<'short> for SuffixMut<'_, E, S> {
1888        type Target = Suffix<'short, E, S>;
1889        #[inline]
1890        fn rb(&'short self) -> Self::Target {
1891            unsafe {
1892                Suffix(
1893                    into_copy::<E, _>(transmute_unchecked::<
1894                        GroupFor<E, <E::SuffixMutUnit<'static, S> as Reborrow<'_>>::Target>,
1895                        GroupFor<E, E::SuffixUnit<'static, S>>,
1896                    >(E::faer_map(
1897                        E::faer_as_ref(&self.0),
1898                        |x| (*x).rb(),
1899                    ))),
1900                    PhantomData,
1901                )
1902            }
1903        }
1904    }
1905    impl<'short, E: Entity, S: pulp::Simd> ReborrowMut<'short> for SuffixMut<'_, E, S> {
1906        type Target = SuffixMut<'short, E, S>;
1907        #[inline]
1908        fn rb_mut(&'short mut self) -> Self::Target {
1909            unsafe {
1910                SuffixMut(
1911                    transmute_unchecked::<
1912                        GroupFor<E, <E::SuffixMutUnit<'static, S> as ReborrowMut<'_>>::Target>,
1913                        GroupFor<E, E::SuffixMutUnit<'static, S>>,
1914                    >(E::faer_map(E::faer_as_mut(&mut self.0), |x| {
1915                        (*x).rb_mut()
1916                    })),
1917                    PhantomData,
1918                )
1919            }
1920        }
1921    }
1922
1923    impl<'short, E: Entity, S: pulp::Simd> Reborrow<'short> for Prefix<'_, E, S> {
1924        type Target = Prefix<'short, E, S>;
1925        #[inline]
1926        fn rb(&'short self) -> Self::Target {
1927            *self
1928        }
1929    }
1930    impl<'short, E: Entity, S: pulp::Simd> ReborrowMut<'short> for Prefix<'_, E, S> {
1931        type Target = Prefix<'short, E, S>;
1932        #[inline]
1933        fn rb_mut(&'short mut self) -> Self::Target {
1934            *self
1935        }
1936    }
1937    impl<'short, E: Entity, S: pulp::Simd> Reborrow<'short> for Suffix<'_, E, S> {
1938        type Target = Suffix<'short, E, S>;
1939        #[inline]
1940        fn rb(&'short self) -> Self::Target {
1941            *self
1942        }
1943    }
1944    impl<'short, E: Entity, S: pulp::Simd> ReborrowMut<'short> for Suffix<'_, E, S> {
1945        type Target = Suffix<'short, E, S>;
1946        #[inline]
1947        fn rb_mut(&'short mut self) -> Self::Target {
1948            *self
1949        }
1950    }
1951
1952    impl<E: Entity, S: pulp::Simd> Copy for Prefix<'_, E, S> {}
1953    impl<E: Entity, S: pulp::Simd> Clone for Prefix<'_, E, S> {
1954        #[inline]
1955        fn clone(&self) -> Self {
1956            *self
1957        }
1958    }
1959    impl<E: Entity, S: pulp::Simd> Copy for Suffix<'_, E, S> {}
1960    impl<E: Entity, S: pulp::Simd> Clone for Suffix<'_, E, S> {
1961        #[inline]
1962        fn clone(&self) -> Self {
1963            *self
1964        }
1965    }
1966
1967    /// Wrapper around a group of references.
1968    pub struct RefGroup<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1969        GroupCopyFor<E, *const T>,
1970        PhantomData<&'a ()>,
1971    );
1972    /// Wrapper around a group of mutable references.
1973    pub struct RefGroupMut<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1974        GroupFor<E, *mut T>,
1975        PhantomData<&'a mut ()>,
1976    );
1977
1978    unsafe impl<E: Entity, T: Sync> Send for SliceGroup<'_, E, T> {}
1979    unsafe impl<E: Entity, T: Sync> Sync for SliceGroup<'_, E, T> {}
1980    unsafe impl<E: Entity, T: Send> Send for SliceGroupMut<'_, E, T> {}
1981    unsafe impl<E: Entity, T: Sync> Sync for SliceGroupMut<'_, E, T> {}
1982
1983    impl<E: Entity, T> Copy for SliceGroup<'_, E, T> {}
1984    impl<E: Entity, T> Copy for RefGroup<'_, E, T> {}
1985    impl<E: Entity, T> Clone for SliceGroup<'_, E, T> {
1986        #[inline]
1987        fn clone(&self) -> Self {
1988            *self
1989        }
1990    }
1991    impl<E: Entity, T> Clone for RefGroup<'_, E, T> {
1992        #[inline]
1993        fn clone(&self) -> Self {
1994            *self
1995        }
1996    }
1997
1998    impl<'a, E: Entity, T> RefGroup<'a, E, T> {
1999        /// Create a new [`RefGroup`] from a group of references.
2000        #[inline(always)]
2001        pub fn new(reference: GroupFor<E, &'a T>) -> Self {
2002            Self(
2003                into_copy::<E, _>(E::faer_map(
2004                    reference,
2005                    #[inline(always)]
2006                    |reference| reference as *const T,
2007                )),
2008                PhantomData,
2009            )
2010        }
2011
2012        /// Consume `self` to return the internally stored group of references.
2013        #[inline(always)]
2014        pub fn into_inner(self) -> GroupFor<E, &'a T> {
2015            E::faer_map(
2016                from_copy::<E, _>(self.0),
2017                #[inline(always)]
2018                |ptr| unsafe { &*ptr },
2019            )
2020        }
2021
2022        /// Copies and returns the value pointed to by the references.
2023        #[inline(always)]
2024        pub fn get(self) -> GroupCopyFor<E, T>
2025        where
2026            T: Copy,
2027        {
2028            into_copy::<E, _>(E::faer_deref(self.into_inner()))
2029        }
2030    }
2031
2032    impl<'a, E: Entity, T, const N: usize> RefGroup<'a, E, [T; N]> {
2033        /// Convert a reference to an array to an array of references.
2034        #[inline(always)]
2035        pub fn unzip(self) -> [RefGroup<'a, E, T>; N] {
2036            unsafe {
2037                let mut out = transmute_unchecked::<
2038                    core::mem::MaybeUninit<[RefGroup<'a, E, T>; N]>,
2039                    [core::mem::MaybeUninit<RefGroup<'a, E, T>>; N],
2040                >(
2041                    core::mem::MaybeUninit::<[RefGroup<'a, E, T>; N]>::uninit()
2042                );
2043                for (out, inp) in
2044                    core::iter::zip(out.iter_mut(), E::faer_into_iter(self.into_inner()))
2045                {
2046                    out.write(RefGroup::new(inp));
2047                }
2048                transmute_unchecked::<
2049                    [core::mem::MaybeUninit<RefGroup<'a, E, T>>; N],
2050                    [RefGroup<'a, E, T>; N],
2051                >(out)
2052            }
2053        }
2054    }
2055
2056    impl<'a, E: Entity, T, const N: usize> RefGroupMut<'a, E, [T; N]> {
2057        /// Convert a mutable reference to an array to an array of mutable references.
2058        #[inline(always)]
2059        pub fn unzip(self) -> [RefGroupMut<'a, E, T>; N] {
2060            unsafe {
2061                let mut out = transmute_unchecked::<
2062                    core::mem::MaybeUninit<[RefGroupMut<'a, E, T>; N]>,
2063                    [core::mem::MaybeUninit<RefGroupMut<'a, E, T>>; N],
2064                >(
2065                    core::mem::MaybeUninit::<[RefGroupMut<'a, E, T>; N]>::uninit()
2066                );
2067                for (out, inp) in
2068                    core::iter::zip(out.iter_mut(), E::faer_into_iter(self.into_inner()))
2069                {
2070                    out.write(RefGroupMut::new(inp));
2071                }
2072                transmute_unchecked::<
2073                    [core::mem::MaybeUninit<RefGroupMut<'a, E, T>>; N],
2074                    [RefGroupMut<'a, E, T>; N],
2075                >(out)
2076            }
2077        }
2078    }
2079
2080    impl<'a, E: Entity, T> RefGroupMut<'a, E, T> {
2081        /// Create a new [`RefGroupMut`] from a group of mutable references.
2082        #[inline(always)]
2083        pub fn new(reference: GroupFor<E, &'a mut T>) -> Self {
2084            Self(
2085                E::faer_map(
2086                    reference,
2087                    #[inline(always)]
2088                    |reference| reference as *mut T,
2089                ),
2090                PhantomData,
2091            )
2092        }
2093
2094        /// Consume `self` to return the internally stored group of references.
2095        #[inline(always)]
2096        pub fn into_inner(self) -> GroupFor<E, &'a mut T> {
2097            E::faer_map(
2098                self.0,
2099                #[inline(always)]
2100                |ptr| unsafe { &mut *ptr },
2101            )
2102        }
2103
2104        /// Copies and returns the value pointed to by the references.
2105        #[inline(always)]
2106        pub fn get(&self) -> GroupCopyFor<E, T>
2107        where
2108            T: Copy,
2109        {
2110            self.rb().get()
2111        }
2112
2113        /// Writes `value` to the location pointed to by the references.
2114        #[inline(always)]
2115        pub fn set(&mut self, value: GroupCopyFor<E, T>)
2116        where
2117            T: Copy,
2118        {
2119            E::faer_map(
2120                E::faer_zip(self.rb_mut().into_inner(), from_copy::<E, _>(value)),
2121                #[inline(always)]
2122                |(r, value)| *r = value,
2123            );
2124        }
2125    }
2126
2127    impl<'a, E: Entity, T> IntoConst for SliceGroup<'a, E, T> {
2128        type Target = SliceGroup<'a, E, T>;
2129
2130        #[inline(always)]
2131        fn into_const(self) -> Self::Target {
2132            self
2133        }
2134    }
2135    impl<'a, E: Entity, T> IntoConst for SliceGroupMut<'a, E, T> {
2136        type Target = SliceGroup<'a, E, T>;
2137
2138        #[inline(always)]
2139        fn into_const(self) -> Self::Target {
2140            SliceGroup::new(E::faer_map(
2141                self.into_inner(),
2142                #[inline(always)]
2143                |slice| &*slice,
2144            ))
2145        }
2146    }
2147
2148    impl<'a, E: Entity, T> IntoConst for RefGroup<'a, E, T> {
2149        type Target = RefGroup<'a, E, T>;
2150
2151        #[inline(always)]
2152        fn into_const(self) -> Self::Target {
2153            self
2154        }
2155    }
2156    impl<'a, E: Entity, T> IntoConst for RefGroupMut<'a, E, T> {
2157        type Target = RefGroup<'a, E, T>;
2158
2159        #[inline(always)]
2160        fn into_const(self) -> Self::Target {
2161            RefGroup::new(E::faer_map(
2162                self.into_inner(),
2163                #[inline(always)]
2164                |slice| &*slice,
2165            ))
2166        }
2167    }
2168
2169    impl<'short, 'a, E: Entity, T> ReborrowMut<'short> for RefGroup<'a, E, T> {
2170        type Target = RefGroup<'short, E, T>;
2171
2172        #[inline(always)]
2173        fn rb_mut(&'short mut self) -> Self::Target {
2174            *self
2175        }
2176    }
2177
2178    impl<'short, 'a, E: Entity, T> Reborrow<'short> for RefGroup<'a, E, T> {
2179        type Target = RefGroup<'short, E, T>;
2180
2181        #[inline(always)]
2182        fn rb(&'short self) -> Self::Target {
2183            *self
2184        }
2185    }
2186
2187    impl<'short, 'a, E: Entity, T> ReborrowMut<'short> for RefGroupMut<'a, E, T> {
2188        type Target = RefGroupMut<'short, E, T>;
2189
2190        #[inline(always)]
2191        fn rb_mut(&'short mut self) -> Self::Target {
2192            RefGroupMut::new(E::faer_map(
2193                E::faer_as_mut(&mut self.0),
2194                #[inline(always)]
2195                |this| unsafe { &mut **this },
2196            ))
2197        }
2198    }
2199
2200    impl<'short, 'a, E: Entity, T> Reborrow<'short> for RefGroupMut<'a, E, T> {
2201        type Target = RefGroup<'short, E, T>;
2202
2203        #[inline(always)]
2204        fn rb(&'short self) -> Self::Target {
2205            RefGroup::new(E::faer_map(
2206                E::faer_as_ref(&self.0),
2207                #[inline(always)]
2208                |this| unsafe { &**this },
2209            ))
2210        }
2211    }
2212
2213    impl<'a, E: Entity, T> SliceGroup<'a, E, T> {
2214        /// Create a new [`SliceGroup`] from a group of slice references.
2215        #[inline(always)]
2216        pub fn new(slice: GroupFor<E, &'a [T]>) -> Self {
2217            Self(
2218                into_copy::<E, _>(E::faer_map(slice, |slice| slice as *const [T])),
2219                PhantomData,
2220            )
2221        }
2222
2223        /// Consume `self` to return the internally stored group of slice references.
2224        #[inline(always)]
2225        pub fn into_inner(self) -> GroupFor<E, &'a [T]> {
2226            unsafe { E::faer_map(from_copy::<E, _>(self.0), |ptr| &*ptr) }
2227        }
2228
2229        /// Decompose `self` into a slice of arrays of size `N`, and a remainder part with length
2230        /// `< N`.
2231        #[inline(always)]
2232        pub fn as_arrays<const N: usize>(
2233            self,
2234        ) -> (SliceGroup<'a, E, [T; N]>, SliceGroup<'a, E, T>) {
2235            let (head, tail) = E::faer_as_arrays::<N, _>(self.into_inner());
2236            (SliceGroup::new(head), SliceGroup::new(tail))
2237        }
2238    }
2239
2240    impl<'a, E: Entity, T> SliceGroupMut<'a, E, T> {
2241        /// Create a new [`SliceGroup`] from a group of mutable slice references.
2242        #[inline(always)]
2243        pub fn new(slice: GroupFor<E, &'a mut [T]>) -> Self {
2244            Self(E::faer_map(slice, |slice| slice as *mut [T]), PhantomData)
2245        }
2246
2247        /// Consume `self` to return the internally stored group of mutable slice references.
2248        #[inline(always)]
2249        pub fn into_inner(self) -> GroupFor<E, &'a mut [T]> {
2250            unsafe { E::faer_map(self.0, |ptr| &mut *ptr) }
2251        }
2252
2253        /// Decompose `self` into a mutable slice of arrays of size `N`, and a remainder part with
2254        /// length `< N`.
2255        #[inline(always)]
2256        pub fn as_arrays_mut<const N: usize>(
2257            self,
2258        ) -> (SliceGroupMut<'a, E, [T; N]>, SliceGroupMut<'a, E, T>) {
2259            let (head, tail) = E::faer_as_arrays_mut::<N, _>(self.into_inner());
2260            (SliceGroupMut::new(head), SliceGroupMut::new(tail))
2261        }
2262    }
2263
2264    impl<'short, 'a, E: Entity, T> ReborrowMut<'short> for SliceGroup<'a, E, T> {
2265        type Target = SliceGroup<'short, E, T>;
2266
2267        #[inline(always)]
2268        fn rb_mut(&'short mut self) -> Self::Target {
2269            *self
2270        }
2271    }
2272
2273    impl<'short, 'a, E: Entity, T> Reborrow<'short> for SliceGroup<'a, E, T> {
2274        type Target = SliceGroup<'short, E, T>;
2275
2276        #[inline(always)]
2277        fn rb(&'short self) -> Self::Target {
2278            *self
2279        }
2280    }
2281
2282    impl<'short, 'a, E: Entity, T> ReborrowMut<'short> for SliceGroupMut<'a, E, T> {
2283        type Target = SliceGroupMut<'short, E, T>;
2284
2285        #[inline(always)]
2286        fn rb_mut(&'short mut self) -> Self::Target {
2287            SliceGroupMut::new(E::faer_map(
2288                E::faer_as_mut(&mut self.0),
2289                #[inline(always)]
2290                |this| unsafe { &mut **this },
2291            ))
2292        }
2293    }
2294
2295    impl<'short, 'a, E: Entity, T> Reborrow<'short> for SliceGroupMut<'a, E, T> {
2296        type Target = SliceGroup<'short, E, T>;
2297
2298        #[inline(always)]
2299        fn rb(&'short self) -> Self::Target {
2300            SliceGroup::new(E::faer_map(
2301                E::faer_as_ref(&self.0),
2302                #[inline(always)]
2303                |this| unsafe { &**this },
2304            ))
2305        }
2306    }
2307
2308    impl<'a, E: Entity> RefGroup<'a, E> {
2309        /// Read the element pointed to by the references.
2310        #[inline(always)]
2311        pub fn read(&self) -> E {
2312            E::faer_from_units(E::faer_deref(self.into_inner()))
2313        }
2314    }
2315
2316    impl<'a, E: Entity> RefGroupMut<'a, E> {
2317        /// Read the element pointed to by the references.
2318        #[inline(always)]
2319        pub fn read(&self) -> E {
2320            self.rb().read()
2321        }
2322
2323        /// Write `value` to the location pointed to by the references.
2324        #[inline(always)]
2325        pub fn write(&mut self, value: E) {
2326            E::faer_map(
2327                E::faer_zip(self.rb_mut().into_inner(), value.faer_into_units()),
2328                #[inline(always)]
2329                |(r, value)| *r = value,
2330            );
2331        }
2332    }
2333
2334    impl<'a, E: Entity> SliceGroup<'a, E> {
2335        /// Read the element at position `idx`.
2336        #[inline(always)]
2337        #[track_caller]
2338        pub fn read(&self, idx: usize) -> E {
2339            assert!(idx < self.len());
2340            unsafe { self.read_unchecked(idx) }
2341        }
2342
2343        /// Read the element at position `idx`, without bound checks.
2344        ///
2345        /// # Safety
2346        /// The behavior is undefined if `idx >= self.len()`.
2347        #[inline(always)]
2348        #[track_caller]
2349        pub unsafe fn read_unchecked(&self, idx: usize) -> E {
2350            debug_assert!(idx < self.len());
2351            E::faer_from_units(E::faer_map(
2352                self.into_inner(),
2353                #[inline(always)]
2354                |slice| *slice.get_unchecked(idx),
2355            ))
2356        }
2357    }
2358    impl<'a, E: Entity, T> SliceGroup<'a, E, T> {
2359        /// Get a [`RefGroup`] pointing to the element at position `idx`.
2360        #[inline(always)]
2361        #[track_caller]
2362        pub fn get(self, idx: usize) -> RefGroup<'a, E, T> {
2363            assert!(idx < self.len());
2364            unsafe { self.get_unchecked(idx) }
2365        }
2366
2367        /// Get a [`RefGroup`] pointing to the element at position `idx`, without bound checks.
2368        ///
2369        /// # Safety
2370        /// The behavior is undefined if `idx >= self.len()`.
2371        #[inline(always)]
2372        #[track_caller]
2373        pub unsafe fn get_unchecked(self, idx: usize) -> RefGroup<'a, E, T> {
2374            debug_assert!(idx < self.len());
2375            RefGroup::new(E::faer_map(
2376                self.into_inner(),
2377                #[inline(always)]
2378                |slice| slice.get_unchecked(idx),
2379            ))
2380        }
2381
2382        /// Checks whether the slice is empty.
2383        #[inline]
2384        pub fn is_empty(&self) -> bool {
2385            self.len() == 0
2386        }
2387
2388        /// Returns the length of the slice.
2389        #[inline]
2390        pub fn len(&self) -> usize {
2391            let mut len = usize::MAX;
2392            E::faer_map(
2393                self.into_inner(),
2394                #[inline(always)]
2395                |slice| len = Ord::min(len, slice.len()),
2396            );
2397            len
2398        }
2399
2400        /// Returns the subslice of `self` from the start to the end of the provided range.
2401        #[inline(always)]
2402        #[track_caller]
2403        pub fn subslice(self, range: Range<usize>) -> Self {
2404            assert!(all(range.start <= range.end, range.end <= self.len()));
2405            unsafe { self.subslice_unchecked(range) }
2406        }
2407
2408        /// Split `self` at the midpoint `idx`, and return the two parts.
2409        #[inline(always)]
2410        #[track_caller]
2411        pub fn split_at(self, idx: usize) -> (Self, Self) {
2412            assert!(idx <= self.len());
2413            let (head, tail) = E::faer_unzip(E::faer_map(
2414                self.into_inner(),
2415                #[inline(always)]
2416                |slice| slice.split_at(idx),
2417            ));
2418            (Self::new(head), Self::new(tail))
2419        }
2420
2421        /// Returns the subslice of `self` from the start to the end of the provided range, without
2422        /// bound checks.
2423        ///
2424        /// # Safety
2425        /// The behavior is undefined if `range.start > range.end` or `range.end > self.len()`.
2426        #[inline(always)]
2427        #[track_caller]
2428        pub unsafe fn subslice_unchecked(self, range: Range<usize>) -> Self {
2429            debug_assert!(all(range.start <= range.end, range.end <= self.len()));
2430            Self::new(E::faer_map(
2431                self.into_inner(),
2432                #[inline(always)]
2433                |slice| slice.get_unchecked(range.start..range.end),
2434            ))
2435        }
2436
2437        /// Returns an iterator of [`RefGroup`] over the elements of the slice.
2438        #[inline(always)]
2439        pub fn into_ref_iter(self) -> impl Iterator<Item = RefGroup<'a, E, T>> {
2440            E::faer_into_iter(self.into_inner()).map(RefGroup::new)
2441        }
2442
2443        /// Returns an iterator of slices over chunks of size `chunk_size`, and the remainder of
2444        /// the slice.
2445        #[inline(always)]
2446        pub fn into_chunks_exact(
2447            self,
2448            chunk_size: usize,
2449        ) -> (impl Iterator<Item = SliceGroup<'a, E, T>>, Self) {
2450            let len = self.len();
2451            let mid = len / chunk_size * chunk_size;
2452            let (head, tail) = E::faer_unzip(E::faer_map(
2453                self.into_inner(),
2454                #[inline(always)]
2455                |slice| slice.split_at(mid),
2456            ));
2457            let head = E::faer_map(
2458                head,
2459                #[inline(always)]
2460                |head| head.chunks_exact(chunk_size),
2461            );
2462            (
2463                E::faer_into_iter(head).map(SliceGroup::new),
2464                SliceGroup::new(tail),
2465            )
2466        }
2467    }
2468
2469    impl<'a, E: Entity> SliceGroupMut<'a, E> {
2470        /// Read the element at position `idx`.
2471        #[inline(always)]
2472        #[track_caller]
2473        pub fn read(&self, idx: usize) -> E {
2474            self.rb().read(idx)
2475        }
2476
2477        /// Read the element at position `idx`, without bound checks.
2478        ///
2479        /// # Safety
2480        /// The behavior is undefined if `idx >= self.len()`.
2481        #[inline(always)]
2482        #[track_caller]
2483        pub unsafe fn read_unchecked(&self, idx: usize) -> E {
2484            self.rb().read_unchecked(idx)
2485        }
2486
2487        /// Write `value` to the location at position `idx`.
2488        #[inline(always)]
2489        #[track_caller]
2490        pub fn write(&mut self, idx: usize, value: E) {
2491            assert!(idx < self.len());
2492            unsafe { self.write_unchecked(idx, value) }
2493        }
2494
2495        /// Write `value` to the location at position `idx`, without bound checks.
2496        ///
2497        /// # Safety
2498        /// The behavior is undefined if `idx >= self.len()`.
2499        #[inline(always)]
2500        #[track_caller]
2501        pub unsafe fn write_unchecked(&mut self, idx: usize, value: E) {
2502            debug_assert!(idx < self.len());
2503            E::faer_map(
2504                E::faer_zip(self.rb_mut().into_inner(), value.faer_into_units()),
2505                #[inline(always)]
2506                |(slice, value)| *slice.get_unchecked_mut(idx) = value,
2507            );
2508        }
2509
2510        /// Fill the slice with zeros.
2511        #[inline]
2512        pub fn fill_zero(&mut self) {
2513            E::faer_map(self.rb_mut().into_inner(), |slice| unsafe {
2514                let len = slice.len();
2515                core::ptr::write_bytes(slice.as_mut_ptr(), 0u8, len);
2516            });
2517        }
2518    }
2519
2520    impl<'a, E: Entity, T> SliceGroupMut<'a, E, T> {
2521        /// Get a [`RefGroupMut`] pointing to the element at position `idx`.
2522        #[inline(always)]
2523        #[track_caller]
2524        pub fn get_mut(self, idx: usize) -> RefGroupMut<'a, E, T> {
2525            assert!(idx < self.len());
2526            unsafe { self.get_unchecked_mut(idx) }
2527        }
2528
2529        /// Get a [`RefGroupMut`] pointing to the element at position `idx`.
2530        ///
2531        /// # Safety
2532        /// The behavior is undefined if `idx >= self.len()`.
2533        #[inline(always)]
2534        #[track_caller]
2535        pub unsafe fn get_unchecked_mut(self, idx: usize) -> RefGroupMut<'a, E, T> {
2536            debug_assert!(idx < self.len());
2537            RefGroupMut::new(E::faer_map(
2538                self.into_inner(),
2539                #[inline(always)]
2540                |slice| slice.get_unchecked_mut(idx),
2541            ))
2542        }
2543
2544        /// Get a [`RefGroup`] pointing to the element at position `idx`.
2545        #[inline(always)]
2546        #[track_caller]
2547        pub fn get(self, idx: usize) -> RefGroup<'a, E, T> {
2548            self.into_const().get(idx)
2549        }
2550
2551        /// Get a [`RefGroup`] pointing to the element at position `idx`, without bound checks.
2552        ///
2553        /// # Safety
2554        /// The behavior is undefined if `idx >= self.len()`.
2555        #[inline(always)]
2556        #[track_caller]
2557        pub unsafe fn get_unchecked(self, idx: usize) -> RefGroup<'a, E, T> {
2558            self.into_const().get_unchecked(idx)
2559        }
2560
2561        /// Checks whether the slice is empty.
2562        #[inline]
2563        pub fn is_empty(&self) -> bool {
2564            self.rb().is_empty()
2565        }
2566
2567        /// Returns the length of the slice.
2568        #[inline]
2569        pub fn len(&self) -> usize {
2570            self.rb().len()
2571        }
2572
2573        /// Returns the subslice of `self` from the start to the end of the provided range.
2574        #[inline(always)]
2575        #[track_caller]
2576        pub fn subslice(self, range: Range<usize>) -> Self {
2577            assert!(all(range.start <= range.end, range.end <= self.len()));
2578            unsafe { self.subslice_unchecked(range) }
2579        }
2580
2581        /// Returns the subslice of `self` from the start to the end of the provided range, without
2582        /// bound checks.
2583        ///
2584        /// # Safety
2585        /// The behavior is undefined if `range.start > range.end` or `range.end > self.len()`.
2586        #[inline(always)]
2587        #[track_caller]
2588        pub unsafe fn subslice_unchecked(self, range: Range<usize>) -> Self {
2589            debug_assert!(all(range.start <= range.end, range.end <= self.len()));
2590            Self::new(E::faer_map(
2591                self.into_inner(),
2592                #[inline(always)]
2593                |slice| slice.get_unchecked_mut(range.start..range.end),
2594            ))
2595        }
2596
2597        /// Returns an iterator of [`RefGroupMut`] over the elements of the slice.
2598        #[inline(always)]
2599        pub fn into_mut_iter(self) -> impl Iterator<Item = RefGroupMut<'a, E, T>> {
2600            E::faer_into_iter(self.into_inner()).map(RefGroupMut::new)
2601        }
2602
2603        /// Split `self` at the midpoint `idx`, and return the two parts.
2604        #[inline(always)]
2605        #[track_caller]
2606        pub fn split_at(self, idx: usize) -> (Self, Self) {
2607            assert!(idx <= self.len());
2608            let (head, tail) = E::faer_unzip(E::faer_map(
2609                self.into_inner(),
2610                #[inline(always)]
2611                |slice| slice.split_at_mut(idx),
2612            ));
2613            (Self::new(head), Self::new(tail))
2614        }
2615
2616        /// Returns an iterator of slices over chunks of size `chunk_size`, and the remainder of
2617        /// the slice.
2618        #[inline(always)]
2619        pub fn into_chunks_exact(
2620            self,
2621            chunk_size: usize,
2622        ) -> (impl Iterator<Item = SliceGroupMut<'a, E, T>>, Self) {
2623            let len = self.len();
2624            let mid = len % chunk_size * chunk_size;
2625            let (head, tail) = E::faer_unzip(E::faer_map(
2626                self.into_inner(),
2627                #[inline(always)]
2628                |slice| slice.split_at_mut(mid),
2629            ));
2630            let head = E::faer_map(
2631                head,
2632                #[inline(always)]
2633                |head| head.chunks_exact_mut(chunk_size),
2634            );
2635            (
2636                E::faer_into_iter(head).map(SliceGroupMut::new),
2637                SliceGroupMut::new(tail),
2638            )
2639        }
2640    }
2641
2642    impl<E: Entity, S: pulp::Simd> core::fmt::Debug for Prefix<'_, E, S> {
2643        #[inline]
2644        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2645            unsafe {
2646                transmute_unchecked::<SimdGroupFor<E, S>, GroupDebugFor<E, SimdUnitFor<E, S>>>(
2647                    self.read_or(core::mem::zeroed()),
2648                )
2649                .fmt(f)
2650            }
2651        }
2652    }
2653    impl<E: Entity, S: pulp::Simd> core::fmt::Debug for PrefixMut<'_, E, S> {
2654        #[inline]
2655        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2656            self.rb().fmt(f)
2657        }
2658    }
2659    impl<E: Entity, S: pulp::Simd> core::fmt::Debug for Suffix<'_, E, S> {
2660        #[inline]
2661        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2662            unsafe {
2663                transmute_unchecked::<SimdGroupFor<E, S>, GroupDebugFor<E, SimdUnitFor<E, S>>>(
2664                    self.read_or(core::mem::zeroed()),
2665                )
2666                .fmt(f)
2667            }
2668        }
2669    }
2670    impl<E: Entity, S: pulp::Simd> core::fmt::Debug for SuffixMut<'_, E, S> {
2671        #[inline]
2672        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2673            self.rb().fmt(f)
2674        }
2675    }
2676    impl<E: Entity, T: Debug> core::fmt::Debug for RefGroup<'_, E, T> {
2677        #[inline]
2678        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2679            unsafe {
2680                transmute_unchecked::<GroupFor<E, &T>, GroupDebugFor<E, &T>>(self.into_inner())
2681                    .fmt(f)
2682            }
2683        }
2684    }
2685    impl<E: Entity, T: Debug> core::fmt::Debug for RefGroupMut<'_, E, T> {
2686        #[inline]
2687        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2688            self.rb().fmt(f)
2689        }
2690    }
2691    impl<E: Entity, T: Debug> core::fmt::Debug for SliceGroup<'_, E, T> {
2692        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2693            f.debug_list().entries(self.into_ref_iter()).finish()
2694        }
2695    }
2696    impl<E: Entity, T: Debug> core::fmt::Debug for SliceGroupMut<'_, E, T> {
2697        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2698            self.rb().fmt(f)
2699        }
2700    }
2701}
2702
2703/// Immutable view over a column vector, similar to an immutable reference to a strided
2704/// [prim@slice].
2705///
2706/// # Note
2707///
2708/// Unlike a slice, the data pointed to by `ColRef<'_, E>` is allowed to be partially or fully
2709/// uninitialized under certain conditions. In this case, care must be taken to not perform any
2710/// operations that read the uninitialized values, or form references to them, either directly
2711/// through [`ColRef::read`], or indirectly through any of the numerical library routines, unless
2712/// it is explicitly permitted.
2713pub type ColRef<'a, E> = Matrix<inner::DenseColRef<'a, E>>;
2714
2715/// Immutable view over a row vector, similar to an immutable reference to a strided [prim@slice].
2716///
2717/// # Note
2718///
2719/// Unlike a slice, the data pointed to by `RowRef<'_, E>` is allowed to be partially or fully
2720/// uninitialized under certain conditions. In this case, care must be taken to not perform any
2721/// operations that read the uninitialized values, or form references to them, either directly
2722/// through [`RowRef::read`], or indirectly through any of the numerical library routines, unless
2723/// it is explicitly permitted.
2724pub type RowRef<'a, E> = Matrix<inner::DenseRowRef<'a, E>>;
2725
2726/// Immutable view over a matrix, similar to an immutable reference to a 2D strided [prim@slice].
2727///
2728/// # Note
2729///
2730/// Unlike a slice, the data pointed to by `MatRef<'_, E>` is allowed to be partially or fully
2731/// uninitialized under certain conditions. In this case, care must be taken to not perform any
2732/// operations that read the uninitialized values, or form references to them, either directly
2733/// through [`MatRef::read`], or indirectly through any of the numerical library routines, unless
2734/// it is explicitly permitted.
2735pub type MatRef<'a, E> = Matrix<inner::DenseRef<'a, E>>;
2736
2737/// Mutable view over a column vector, similar to a mutable reference to a strided [prim@slice].
2738///
2739/// # Note
2740///
2741/// Unlike a slice, the data pointed to by `ColMut<'_, E>` is allowed to be partially or fully
2742/// uninitialized under certain conditions. In this case, care must be taken to not perform any
2743/// operations that read the uninitialized values, or form references to them, either directly
2744/// through [`ColMut::read`], or indirectly through any of the numerical library routines, unless
2745/// it is explicitly permitted.
2746pub type ColMut<'a, E> = Matrix<inner::DenseColMut<'a, E>>;
2747
2748/// Mutable view over a row vector, similar to a mutable reference to a strided [prim@slice].
2749///
2750/// # Note
2751///
2752/// Unlike a slice, the data pointed to by `RowMut<'_, E>` is allowed to be partially or fully
2753/// uninitialized under certain conditions. In this case, care must be taken to not perform any
2754/// operations that read the uninitialized values, or form references to them, either directly
2755/// through [`RowMut::read`], or indirectly through any of the numerical library routines, unless
2756/// it is explicitly permitted.
2757pub type RowMut<'a, E> = Matrix<inner::DenseRowMut<'a, E>>;
2758
2759/// Mutable view over a matrix, similar to a mutable reference to a 2D strided [prim@slice].
2760///
2761/// # Note
2762///
2763/// Unlike a slice, the data pointed to by `MatMut<'_, E>` is allowed to be partially or fully
2764/// uninitialized under certain conditions. In this case, care must be taken to not perform any
2765/// operations that read the uninitialized values, or form references to them, either directly
2766/// through [`MatMut::read`], or indirectly through any of the numerical library routines, unless
2767/// it is explicitly permitted.
2768///
2769/// # Move semantics
2770/// Since `MatMut` mutably borrows data, it cannot be [`Copy`]. This means that if we pass a
2771/// `MatMut` to a function that takes it by value, or use a method that consumes `self` like
2772/// [`MatMut::transpose`], this renders the original variable unusable.
2773/// ```compile_fail
2774/// use faer_core::{Mat, MatMut};
2775///
2776/// fn takes_matmut(view: MatMut<'_, f64>) {}
2777///
2778/// let mut matrix = Mat::new();
2779/// let view = matrix.as_mut();
2780///
2781/// takes_matmut(view); // `view` is moved (passed by value)
2782/// takes_matmut(view); // this fails to compile since `view` was moved
2783/// ```
2784/// The way to get around it is to use the [`reborrow::ReborrowMut`] trait, which allows us to
2785/// mutably borrow a `MatMut` to obtain another `MatMut` for the lifetime of the borrow.
2786/// It's also similarly possible to immutably borrow a `MatMut` to obtain a `MatRef` for the
2787/// lifetime of the borrow, using [`reborrow::Reborrow`].
2788/// ```
2789/// use faer_core::{Mat, MatMut, MatRef};
2790/// use reborrow::*;
2791///
2792/// fn takes_matmut(view: MatMut<'_, f64>) {}
2793/// fn takes_matref(view: MatRef<'_, f64>) {}
2794///
2795/// let mut matrix = Mat::new();
2796/// let mut view = matrix.as_mut();
2797///
2798/// takes_matmut(view.rb_mut());
2799/// takes_matmut(view.rb_mut());
2800/// takes_matref(view.rb());
2801/// // view is still usable here
2802/// ```
2803pub type MatMut<'a, E> = Matrix<inner::DenseMut<'a, E>>;
2804
2805/// Wrapper around a scalar value that allows scalar multiplication by matrices.
2806pub type MatScale<E> = Matrix<inner::Scale<E>>;
2807
2808impl<E: Entity> MatScale<E> {
2809    /// Returns a new scaling factor with the given value.
2810    #[inline(always)]
2811    pub fn new(value: E) -> Self {
2812        Self {
2813            inner: inner::Scale(value),
2814        }
2815    }
2816
2817    /// Returns the value of the scaling factor.
2818    #[inline(always)]
2819    pub fn value(self) -> E {
2820        self.inner.0
2821    }
2822}
2823
2824// COL_REBORROW
2825const _: () = {
2826    impl<'a, E: Entity> IntoConst for ColMut<'a, E> {
2827        type Target = ColRef<'a, E>;
2828
2829        #[inline(always)]
2830        fn into_const(self) -> Self::Target {
2831            ColRef {
2832                inner: inner::DenseColRef {
2833                    inner: self.inner.inner,
2834                    __marker: PhantomData,
2835                },
2836            }
2837        }
2838    }
2839
2840    impl<'short, 'a, E: Entity> Reborrow<'short> for ColMut<'a, E> {
2841        type Target = ColRef<'short, E>;
2842
2843        #[inline(always)]
2844        fn rb(&'short self) -> Self::Target {
2845            ColRef {
2846                inner: inner::DenseColRef {
2847                    inner: self.inner.inner,
2848                    __marker: PhantomData,
2849                },
2850            }
2851        }
2852    }
2853
2854    impl<'short, 'a, E: Entity> ReborrowMut<'short> for ColMut<'a, E> {
2855        type Target = ColMut<'short, E>;
2856
2857        #[inline(always)]
2858        fn rb_mut(&'short mut self) -> Self::Target {
2859            ColMut {
2860                inner: inner::DenseColMut {
2861                    inner: self.inner.inner,
2862                    __marker: PhantomData,
2863                },
2864            }
2865        }
2866    }
2867
2868    impl<'a, E: Entity> IntoConst for ColRef<'a, E> {
2869        type Target = ColRef<'a, E>;
2870
2871        #[inline(always)]
2872        fn into_const(self) -> Self::Target {
2873            self
2874        }
2875    }
2876
2877    impl<'short, 'a, E: Entity> Reborrow<'short> for ColRef<'a, E> {
2878        type Target = ColRef<'short, E>;
2879
2880        #[inline(always)]
2881        fn rb(&'short self) -> Self::Target {
2882            *self
2883        }
2884    }
2885
2886    impl<'short, 'a, E: Entity> ReborrowMut<'short> for ColRef<'a, E> {
2887        type Target = ColRef<'short, E>;
2888
2889        #[inline(always)]
2890        fn rb_mut(&'short mut self) -> Self::Target {
2891            *self
2892        }
2893    }
2894};
2895
2896// ROW REBORROW
2897const _: () = {
2898    impl<'a, E: Entity> IntoConst for RowMut<'a, E> {
2899        type Target = RowRef<'a, E>;
2900
2901        #[inline(always)]
2902        fn into_const(self) -> Self::Target {
2903            RowRef {
2904                inner: inner::DenseRowRef {
2905                    inner: self.inner.inner,
2906                    __marker: PhantomData,
2907                },
2908            }
2909        }
2910    }
2911
2912    impl<'short, 'a, E: Entity> Reborrow<'short> for RowMut<'a, E> {
2913        type Target = RowRef<'short, E>;
2914
2915        #[inline(always)]
2916        fn rb(&'short self) -> Self::Target {
2917            RowRef {
2918                inner: inner::DenseRowRef {
2919                    inner: self.inner.inner,
2920                    __marker: PhantomData,
2921                },
2922            }
2923        }
2924    }
2925
2926    impl<'short, 'a, E: Entity> ReborrowMut<'short> for RowMut<'a, E> {
2927        type Target = RowMut<'short, E>;
2928
2929        #[inline(always)]
2930        fn rb_mut(&'short mut self) -> Self::Target {
2931            RowMut {
2932                inner: inner::DenseRowMut {
2933                    inner: self.inner.inner,
2934                    __marker: PhantomData,
2935                },
2936            }
2937        }
2938    }
2939
2940    impl<'a, E: Entity> IntoConst for RowRef<'a, E> {
2941        type Target = RowRef<'a, E>;
2942
2943        #[inline(always)]
2944        fn into_const(self) -> Self::Target {
2945            self
2946        }
2947    }
2948
2949    impl<'short, 'a, E: Entity> Reborrow<'short> for RowRef<'a, E> {
2950        type Target = RowRef<'short, E>;
2951
2952        #[inline(always)]
2953        fn rb(&'short self) -> Self::Target {
2954            *self
2955        }
2956    }
2957
2958    impl<'short, 'a, E: Entity> ReborrowMut<'short> for RowRef<'a, E> {
2959        type Target = RowRef<'short, E>;
2960
2961        #[inline(always)]
2962        fn rb_mut(&'short mut self) -> Self::Target {
2963            *self
2964        }
2965    }
2966};
2967
2968// MAT_REBORROW
2969const _: () = {
2970    impl<'a, E: Entity> IntoConst for MatMut<'a, E> {
2971        type Target = MatRef<'a, E>;
2972
2973        #[inline(always)]
2974        fn into_const(self) -> Self::Target {
2975            MatRef {
2976                inner: inner::DenseRef {
2977                    inner: self.inner.inner,
2978                    __marker: PhantomData,
2979                },
2980            }
2981        }
2982    }
2983
2984    impl<'short, 'a, E: Entity> Reborrow<'short> for MatMut<'a, E> {
2985        type Target = MatRef<'short, E>;
2986
2987        #[inline(always)]
2988        fn rb(&'short self) -> Self::Target {
2989            MatRef {
2990                inner: inner::DenseRef {
2991                    inner: self.inner.inner,
2992                    __marker: PhantomData,
2993                },
2994            }
2995        }
2996    }
2997
2998    impl<'short, 'a, E: Entity> ReborrowMut<'short> for MatMut<'a, E> {
2999        type Target = MatMut<'short, E>;
3000
3001        #[inline(always)]
3002        fn rb_mut(&'short mut self) -> Self::Target {
3003            MatMut {
3004                inner: inner::DenseMut {
3005                    inner: self.inner.inner,
3006                    __marker: PhantomData,
3007                },
3008            }
3009        }
3010    }
3011
3012    impl<'a, E: Entity> IntoConst for MatRef<'a, E> {
3013        type Target = MatRef<'a, E>;
3014
3015        #[inline(always)]
3016        fn into_const(self) -> Self::Target {
3017            self
3018        }
3019    }
3020
3021    impl<'short, 'a, E: Entity> Reborrow<'short> for MatRef<'a, E> {
3022        type Target = MatRef<'short, E>;
3023
3024        #[inline(always)]
3025        fn rb(&'short self) -> Self::Target {
3026            *self
3027        }
3028    }
3029
3030    impl<'short, 'a, E: Entity> ReborrowMut<'short> for MatRef<'a, E> {
3031        type Target = MatRef<'short, E>;
3032
3033        #[inline(always)]
3034        fn rb_mut(&'short mut self) -> Self::Target {
3035            *self
3036        }
3037    }
3038};
3039
3040impl<'a, E: Entity> IntoConst for Matrix<inner::DiagMut<'a, E>> {
3041    type Target = Matrix<inner::DiagRef<'a, E>>;
3042
3043    #[inline(always)]
3044    fn into_const(self) -> Self::Target {
3045        Matrix {
3046            inner: inner::DiagRef {
3047                inner: self.inner.inner.into_const(),
3048            },
3049        }
3050    }
3051}
3052
3053impl<'short, 'a, E: Entity> Reborrow<'short> for Matrix<inner::DiagMut<'a, E>> {
3054    type Target = Matrix<inner::DiagRef<'short, E>>;
3055
3056    #[inline(always)]
3057    fn rb(&'short self) -> Self::Target {
3058        Matrix {
3059            inner: inner::DiagRef {
3060                inner: self.inner.inner.rb(),
3061            },
3062        }
3063    }
3064}
3065
3066impl<'short, 'a, E: Entity> ReborrowMut<'short> for Matrix<inner::DiagMut<'a, E>> {
3067    type Target = Matrix<inner::DiagMut<'short, E>>;
3068
3069    #[inline(always)]
3070    fn rb_mut(&'short mut self) -> Self::Target {
3071        Matrix {
3072            inner: inner::DiagMut {
3073                inner: self.inner.inner.rb_mut(),
3074            },
3075        }
3076    }
3077}
3078
3079impl<'a, E: Entity> IntoConst for Matrix<inner::DiagRef<'a, E>> {
3080    type Target = Matrix<inner::DiagRef<'a, E>>;
3081
3082    #[inline(always)]
3083    fn into_const(self) -> Self::Target {
3084        self
3085    }
3086}
3087
3088impl<'short, 'a, E: Entity> Reborrow<'short> for Matrix<inner::DiagRef<'a, E>> {
3089    type Target = Matrix<inner::DiagRef<'short, E>>;
3090
3091    #[inline(always)]
3092    fn rb(&'short self) -> Self::Target {
3093        *self
3094    }
3095}
3096
3097impl<'short, 'a, E: Entity> ReborrowMut<'short> for Matrix<inner::DiagRef<'a, E>> {
3098    type Target = Matrix<inner::DiagRef<'short, E>>;
3099
3100    #[inline(always)]
3101    fn rb_mut(&'short mut self) -> Self::Target {
3102        *self
3103    }
3104}
3105
3106unsafe impl<E: Entity + Send + Sync> Send for VecImpl<E> {}
3107unsafe impl<E: Entity + Send + Sync> Sync for VecImpl<E> {}
3108unsafe impl<E: Entity + Send + Sync> Send for VecOwnImpl<E> {}
3109unsafe impl<E: Entity + Send + Sync> Sync for VecOwnImpl<E> {}
3110
3111unsafe impl<E: Entity + Send + Sync> Send for MatImpl<E> {}
3112unsafe impl<E: Entity + Send + Sync> Sync for MatImpl<E> {}
3113unsafe impl<E: Entity + Send + Sync> Send for MatOwnImpl<E> {}
3114unsafe impl<E: Entity + Send + Sync> Sync for MatOwnImpl<E> {}
3115
3116#[doc(hidden)]
3117#[inline]
3118pub fn par_split_indices(n: usize, idx: usize, chunk_count: usize) -> (usize, usize) {
3119    let chunk_size = n / chunk_count;
3120    let rem = n % chunk_count;
3121
3122    let idx_to_col_start = move |idx| {
3123        if idx < rem {
3124            idx * (chunk_size + 1)
3125        } else {
3126            rem + idx * chunk_size
3127        }
3128    };
3129
3130    let start = idx_to_col_start(idx);
3131    let end = idx_to_col_start(idx + 1);
3132    (start, end - start)
3133}
3134
3135mod seal {
3136    pub trait Seal {}
3137}
3138impl<'a, E: Entity> seal::Seal for MatRef<'a, E> {}
3139impl<'a, E: Entity> seal::Seal for MatMut<'a, E> {}
3140impl<'a, E: Entity> seal::Seal for ColRef<'a, E> {}
3141impl<'a, E: Entity> seal::Seal for ColMut<'a, E> {}
3142impl<'a, E: Entity> seal::Seal for RowRef<'a, E> {}
3143impl<'a, E: Entity> seal::Seal for RowMut<'a, E> {}
3144
3145/// Represents a type that can be used to slice a row, such as an index or a range of indices.
3146pub trait RowIndex<ColRange>: seal::Seal + Sized {
3147    /// Resulting type of the indexing operation.
3148    type Target;
3149
3150    /// Index the row at `col`, without bound checks.
3151    #[allow(clippy::missing_safety_doc)]
3152    unsafe fn get_unchecked(this: Self, col: ColRange) -> Self::Target {
3153        <Self as RowIndex<ColRange>>::get(this, col)
3154    }
3155    /// Index the row at `col`.
3156    fn get(this: Self, col: ColRange) -> Self::Target;
3157}
3158
3159/// Represents a type that can be used to slice a column, such as an index or a range of indices.
3160pub trait ColIndex<RowRange>: seal::Seal + Sized {
3161    /// Resulting type of the indexing operation.
3162    type Target;
3163
3164    /// Index the column at `row`, without bound checks.
3165    #[allow(clippy::missing_safety_doc)]
3166    unsafe fn get_unchecked(this: Self, row: RowRange) -> Self::Target {
3167        <Self as ColIndex<RowRange>>::get(this, row)
3168    }
3169    /// Index the column at `row`.
3170    fn get(this: Self, row: RowRange) -> Self::Target;
3171}
3172
3173/// Represents a type that can be used to slice a matrix, such as an index or a range of indices.
3174pub trait MatIndex<RowRange, ColRange>: seal::Seal + Sized {
3175    /// Resulting type of the indexing operation.
3176    type Target;
3177
3178    /// Index the matrix at `(row, col)`, without bound checks.
3179    #[allow(clippy::missing_safety_doc)]
3180    unsafe fn get_unchecked(this: Self, row: RowRange, col: ColRange) -> Self::Target {
3181        <Self as MatIndex<RowRange, ColRange>>::get(this, row, col)
3182    }
3183    /// Index the matrix at `(row, col)`.
3184    fn get(this: Self, row: RowRange, col: ColRange) -> Self::Target;
3185}
3186
3187// MAT INDEX
3188const _: () = {
3189    // RangeFull
3190    // Range
3191    // RangeInclusive
3192    // RangeTo
3193    // RangeToInclusive
3194    // usize
3195
3196    use core::ops::RangeFull;
3197    type Range = core::ops::Range<usize>;
3198    type RangeInclusive = core::ops::RangeInclusive<usize>;
3199    type RangeFrom = core::ops::RangeFrom<usize>;
3200    type RangeTo = core::ops::RangeTo<usize>;
3201    type RangeToInclusive = core::ops::RangeToInclusive<usize>;
3202
3203    impl<E: Entity, RowRange> MatIndex<RowRange, RangeFrom> for MatRef<'_, E>
3204    where
3205        Self: MatIndex<RowRange, Range>,
3206    {
3207        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3208
3209        #[track_caller]
3210        #[inline(always)]
3211        fn get(
3212            this: Self,
3213            row: RowRange,
3214            col: RangeFrom,
3215        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3216            let ncols = this.ncols();
3217            <Self as MatIndex<RowRange, Range>>::get(this, row, col.start..ncols)
3218        }
3219    }
3220    impl<E: Entity, RowRange> MatIndex<RowRange, RangeTo> for MatRef<'_, E>
3221    where
3222        Self: MatIndex<RowRange, Range>,
3223    {
3224        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3225
3226        #[track_caller]
3227        #[inline(always)]
3228        fn get(
3229            this: Self,
3230            row: RowRange,
3231            col: RangeTo,
3232        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3233            <Self as MatIndex<RowRange, Range>>::get(this, row, 0..col.end)
3234        }
3235    }
3236    impl<E: Entity, RowRange> MatIndex<RowRange, RangeToInclusive> for MatRef<'_, E>
3237    where
3238        Self: MatIndex<RowRange, Range>,
3239    {
3240        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3241
3242        #[track_caller]
3243        #[inline(always)]
3244        fn get(
3245            this: Self,
3246            row: RowRange,
3247            col: RangeToInclusive,
3248        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3249            assert!(col.end != usize::MAX);
3250            <Self as MatIndex<RowRange, Range>>::get(this, row, 0..col.end + 1)
3251        }
3252    }
3253    impl<E: Entity, RowRange> MatIndex<RowRange, RangeInclusive> for MatRef<'_, E>
3254    where
3255        Self: MatIndex<RowRange, Range>,
3256    {
3257        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3258
3259        #[track_caller]
3260        #[inline(always)]
3261        fn get(
3262            this: Self,
3263            row: RowRange,
3264            col: RangeInclusive,
3265        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3266            assert!(*col.end() != usize::MAX);
3267            <Self as MatIndex<RowRange, Range>>::get(this, row, *col.start()..*col.end() + 1)
3268        }
3269    }
3270    impl<E: Entity, RowRange> MatIndex<RowRange, RangeFull> for MatRef<'_, E>
3271    where
3272        Self: MatIndex<RowRange, Range>,
3273    {
3274        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3275
3276        #[track_caller]
3277        #[inline(always)]
3278        fn get(
3279            this: Self,
3280            row: RowRange,
3281            col: RangeFull,
3282        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3283            let _ = col;
3284            let ncols = this.ncols();
3285            <Self as MatIndex<RowRange, Range>>::get(this, row, 0..ncols)
3286        }
3287    }
3288
3289    impl<E: Entity> MatIndex<RangeFull, Range> for MatRef<'_, E> {
3290        type Target = Self;
3291
3292        #[track_caller]
3293        #[inline(always)]
3294        fn get(this: Self, row: RangeFull, col: Range) -> Self {
3295            let _ = row;
3296            this.subcols(col.start, col.end - col.start)
3297        }
3298    }
3299    impl<'a, E: Entity> MatIndex<RangeFull, usize> for MatRef<'a, E> {
3300        type Target = ColRef<'a, E>;
3301
3302        #[track_caller]
3303        #[inline(always)]
3304        fn get(this: Self, row: RangeFull, col: usize) -> Self::Target {
3305            let _ = row;
3306            this.col(col)
3307        }
3308    }
3309
3310    impl<E: Entity> MatIndex<Range, Range> for MatRef<'_, E> {
3311        type Target = Self;
3312
3313        #[track_caller]
3314        #[inline(always)]
3315        fn get(this: Self, row: Range, col: Range) -> Self {
3316            this.submatrix(
3317                row.start,
3318                col.start,
3319                row.end - row.start,
3320                col.end - col.start,
3321            )
3322        }
3323    }
3324    impl<E: Entity> MatIndex<Range, usize> for MatRef<'_, E> {
3325        type Target = Self;
3326
3327        #[track_caller]
3328        #[inline(always)]
3329        fn get(this: Self, row: Range, col: usize) -> Self {
3330            this.submatrix(row.start, col, row.end - row.start, 1)
3331        }
3332    }
3333
3334    impl<E: Entity> MatIndex<RangeInclusive, Range> for MatRef<'_, E> {
3335        type Target = Self;
3336
3337        #[track_caller]
3338        #[inline(always)]
3339        fn get(this: Self, row: RangeInclusive, col: Range) -> Self {
3340            assert!(*row.end() != usize::MAX);
3341            <Self as MatIndex<Range, Range>>::get(this, *row.start()..*row.end() + 1, col)
3342        }
3343    }
3344    impl<E: Entity> MatIndex<RangeInclusive, usize> for MatRef<'_, E> {
3345        type Target = Self;
3346
3347        #[track_caller]
3348        #[inline(always)]
3349        fn get(this: Self, row: RangeInclusive, col: usize) -> Self {
3350            assert!(*row.end() != usize::MAX);
3351            <Self as MatIndex<Range, usize>>::get(this, *row.start()..*row.end() + 1, col)
3352        }
3353    }
3354
3355    impl<E: Entity> MatIndex<RangeFrom, Range> for MatRef<'_, E> {
3356        type Target = Self;
3357
3358        #[track_caller]
3359        #[inline(always)]
3360        fn get(this: Self, row: RangeFrom, col: Range) -> Self {
3361            let nrows = this.nrows();
3362            <Self as MatIndex<Range, Range>>::get(this, row.start..nrows, col)
3363        }
3364    }
3365    impl<E: Entity> MatIndex<RangeFrom, usize> for MatRef<'_, E> {
3366        type Target = Self;
3367
3368        #[track_caller]
3369        #[inline(always)]
3370        fn get(this: Self, row: RangeFrom, col: usize) -> Self {
3371            let nrows = this.nrows();
3372            <Self as MatIndex<Range, usize>>::get(this, row.start..nrows, col)
3373        }
3374    }
3375    impl<E: Entity> MatIndex<RangeTo, Range> for MatRef<'_, E> {
3376        type Target = Self;
3377
3378        #[track_caller]
3379        #[inline(always)]
3380        fn get(this: Self, row: RangeTo, col: Range) -> Self {
3381            <Self as MatIndex<Range, Range>>::get(this, 0..row.end, col)
3382        }
3383    }
3384    impl<E: Entity> MatIndex<RangeTo, usize> for MatRef<'_, E> {
3385        type Target = Self;
3386
3387        #[track_caller]
3388        #[inline(always)]
3389        fn get(this: Self, row: RangeTo, col: usize) -> Self {
3390            <Self as MatIndex<Range, usize>>::get(this, 0..row.end, col)
3391        }
3392    }
3393
3394    impl<E: Entity> MatIndex<RangeToInclusive, Range> for MatRef<'_, E> {
3395        type Target = Self;
3396
3397        #[track_caller]
3398        #[inline(always)]
3399        fn get(this: Self, row: RangeToInclusive, col: Range) -> Self {
3400            assert!(row.end != usize::MAX);
3401            <Self as MatIndex<Range, Range>>::get(this, 0..row.end + 1, col)
3402        }
3403    }
3404    impl<E: Entity> MatIndex<RangeToInclusive, usize> for MatRef<'_, E> {
3405        type Target = Self;
3406
3407        #[track_caller]
3408        #[inline(always)]
3409        fn get(this: Self, row: RangeToInclusive, col: usize) -> Self {
3410            assert!(row.end != usize::MAX);
3411            <Self as MatIndex<Range, usize>>::get(this, 0..row.end + 1, col)
3412        }
3413    }
3414
3415    impl<E: Entity> MatIndex<usize, Range> for MatRef<'_, E> {
3416        type Target = Self;
3417
3418        #[track_caller]
3419        #[inline(always)]
3420        fn get(this: Self, row: usize, col: Range) -> Self {
3421            this.submatrix(row, col.start, 1, col.end - col.start)
3422        }
3423    }
3424
3425    impl<E: Entity, RowRange> MatIndex<RowRange, RangeFrom> for MatMut<'_, E>
3426    where
3427        Self: MatIndex<RowRange, Range>,
3428    {
3429        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3430
3431        #[track_caller]
3432        #[inline(always)]
3433        fn get(
3434            this: Self,
3435            row: RowRange,
3436            col: RangeFrom,
3437        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3438            let ncols = this.ncols();
3439            <Self as MatIndex<RowRange, Range>>::get(this, row, col.start..ncols)
3440        }
3441    }
3442    impl<E: Entity, RowRange> MatIndex<RowRange, RangeTo> for MatMut<'_, E>
3443    where
3444        Self: MatIndex<RowRange, Range>,
3445    {
3446        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3447
3448        #[track_caller]
3449        #[inline(always)]
3450        fn get(
3451            this: Self,
3452            row: RowRange,
3453            col: RangeTo,
3454        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3455            <Self as MatIndex<RowRange, Range>>::get(this, row, 0..col.end)
3456        }
3457    }
3458    impl<E: Entity, RowRange> MatIndex<RowRange, RangeToInclusive> for MatMut<'_, E>
3459    where
3460        Self: MatIndex<RowRange, Range>,
3461    {
3462        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3463
3464        #[track_caller]
3465        #[inline(always)]
3466        fn get(
3467            this: Self,
3468            row: RowRange,
3469            col: RangeToInclusive,
3470        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3471            assert!(col.end != usize::MAX);
3472            <Self as MatIndex<RowRange, Range>>::get(this, row, 0..col.end + 1)
3473        }
3474    }
3475    impl<E: Entity, RowRange> MatIndex<RowRange, RangeInclusive> for MatMut<'_, E>
3476    where
3477        Self: MatIndex<RowRange, Range>,
3478    {
3479        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3480
3481        #[track_caller]
3482        #[inline(always)]
3483        fn get(
3484            this: Self,
3485            row: RowRange,
3486            col: RangeInclusive,
3487        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3488            assert!(*col.end() != usize::MAX);
3489            <Self as MatIndex<RowRange, Range>>::get(this, row, *col.start()..*col.end() + 1)
3490        }
3491    }
3492    impl<E: Entity, RowRange> MatIndex<RowRange, RangeFull> for MatMut<'_, E>
3493    where
3494        Self: MatIndex<RowRange, Range>,
3495    {
3496        type Target = <Self as MatIndex<RowRange, Range>>::Target;
3497
3498        #[track_caller]
3499        #[inline(always)]
3500        fn get(
3501            this: Self,
3502            row: RowRange,
3503            col: RangeFull,
3504        ) -> <Self as MatIndex<RowRange, Range>>::Target {
3505            let _ = col;
3506            let ncols = this.ncols();
3507            <Self as MatIndex<RowRange, Range>>::get(this, row, 0..ncols)
3508        }
3509    }
3510
3511    impl<E: Entity> MatIndex<RangeFull, Range> for MatMut<'_, E> {
3512        type Target = Self;
3513
3514        #[track_caller]
3515        #[inline(always)]
3516        fn get(this: Self, row: RangeFull, col: Range) -> Self {
3517            let _ = row;
3518            this.subcols_mut(col.start, col.end - col.start)
3519        }
3520    }
3521    impl<'a, E: Entity> MatIndex<RangeFull, usize> for MatMut<'a, E> {
3522        type Target = ColMut<'a, E>;
3523
3524        #[track_caller]
3525        #[inline(always)]
3526        fn get(this: Self, row: RangeFull, col: usize) -> Self::Target {
3527            let _ = row;
3528            this.col_mut(col)
3529        }
3530    }
3531
3532    impl<E: Entity> MatIndex<Range, Range> for MatMut<'_, E> {
3533        type Target = Self;
3534
3535        #[track_caller]
3536        #[inline(always)]
3537        fn get(this: Self, row: Range, col: Range) -> Self {
3538            this.submatrix_mut(
3539                row.start,
3540                col.start,
3541                row.end - row.start,
3542                col.end - col.start,
3543            )
3544        }
3545    }
3546    impl<E: Entity> MatIndex<Range, usize> for MatMut<'_, E> {
3547        type Target = Self;
3548
3549        #[track_caller]
3550        #[inline(always)]
3551        fn get(this: Self, row: Range, col: usize) -> Self {
3552            this.submatrix_mut(row.start, col, row.end - row.start, 1)
3553        }
3554    }
3555
3556    impl<E: Entity> MatIndex<RangeInclusive, Range> for MatMut<'_, E> {
3557        type Target = Self;
3558
3559        #[track_caller]
3560        #[inline(always)]
3561        fn get(this: Self, row: RangeInclusive, col: Range) -> Self {
3562            assert!(*row.end() != usize::MAX);
3563            <Self as MatIndex<Range, Range>>::get(this, *row.start()..*row.end() + 1, col)
3564        }
3565    }
3566    impl<E: Entity> MatIndex<RangeInclusive, usize> for MatMut<'_, E> {
3567        type Target = Self;
3568
3569        #[track_caller]
3570        #[inline(always)]
3571        fn get(this: Self, row: RangeInclusive, col: usize) -> Self {
3572            assert!(*row.end() != usize::MAX);
3573            <Self as MatIndex<Range, usize>>::get(this, *row.start()..*row.end() + 1, col)
3574        }
3575    }
3576
3577    impl<E: Entity> MatIndex<RangeFrom, Range> for MatMut<'_, E> {
3578        type Target = Self;
3579
3580        #[track_caller]
3581        #[inline(always)]
3582        fn get(this: Self, row: RangeFrom, col: Range) -> Self {
3583            let nrows = this.nrows();
3584            <Self as MatIndex<Range, Range>>::get(this, row.start..nrows, col)
3585        }
3586    }
3587    impl<E: Entity> MatIndex<RangeFrom, usize> for MatMut<'_, E> {
3588        type Target = Self;
3589
3590        #[track_caller]
3591        #[inline(always)]
3592        fn get(this: Self, row: RangeFrom, col: usize) -> Self {
3593            let nrows = this.nrows();
3594            <Self as MatIndex<Range, usize>>::get(this, row.start..nrows, col)
3595        }
3596    }
3597    impl<E: Entity> MatIndex<RangeTo, Range> for MatMut<'_, E> {
3598        type Target = Self;
3599
3600        #[track_caller]
3601        #[inline(always)]
3602        fn get(this: Self, row: RangeTo, col: Range) -> Self {
3603            <Self as MatIndex<Range, Range>>::get(this, 0..row.end, col)
3604        }
3605    }
3606    impl<E: Entity> MatIndex<RangeTo, usize> for MatMut<'_, E> {
3607        type Target = Self;
3608
3609        #[track_caller]
3610        #[inline(always)]
3611        fn get(this: Self, row: RangeTo, col: usize) -> Self {
3612            <Self as MatIndex<Range, usize>>::get(this, 0..row.end, col)
3613        }
3614    }
3615
3616    impl<E: Entity> MatIndex<RangeToInclusive, Range> for MatMut<'_, E> {
3617        type Target = Self;
3618
3619        #[track_caller]
3620        #[inline(always)]
3621        fn get(this: Self, row: RangeToInclusive, col: Range) -> Self {
3622            assert!(row.end != usize::MAX);
3623            <Self as MatIndex<Range, Range>>::get(this, 0..row.end + 1, col)
3624        }
3625    }
3626    impl<E: Entity> MatIndex<RangeToInclusive, usize> for MatMut<'_, E> {
3627        type Target = Self;
3628
3629        #[track_caller]
3630        #[inline(always)]
3631        fn get(this: Self, row: RangeToInclusive, col: usize) -> Self {
3632            assert!(row.end != usize::MAX);
3633            <Self as MatIndex<Range, usize>>::get(this, 0..row.end + 1, col)
3634        }
3635    }
3636
3637    impl<E: Entity> MatIndex<usize, Range> for MatMut<'_, E> {
3638        type Target = Self;
3639
3640        #[track_caller]
3641        #[inline(always)]
3642        fn get(this: Self, row: usize, col: Range) -> Self {
3643            this.submatrix_mut(row, col.start, 1, col.end - col.start)
3644        }
3645    }
3646
3647    impl<'a, E: Entity> MatIndex<usize, usize> for MatRef<'a, E> {
3648        type Target = GroupFor<E, &'a E::Unit>;
3649
3650        #[track_caller]
3651        #[inline(always)]
3652        unsafe fn get_unchecked(this: Self, row: usize, col: usize) -> Self::Target {
3653            unsafe { E::faer_map(this.ptr_inbounds_at(row, col), |ptr| &*ptr) }
3654        }
3655
3656        #[track_caller]
3657        #[inline(always)]
3658        fn get(this: Self, row: usize, col: usize) -> Self::Target {
3659            assert!(all(row < this.nrows(), col < this.ncols()));
3660            unsafe { <Self as MatIndex<usize, usize>>::get_unchecked(this, row, col) }
3661        }
3662    }
3663
3664    impl<'a, E: Entity> MatIndex<usize, usize> for MatMut<'a, E> {
3665        type Target = GroupFor<E, &'a mut E::Unit>;
3666
3667        #[track_caller]
3668        #[inline(always)]
3669        unsafe fn get_unchecked(this: Self, row: usize, col: usize) -> Self::Target {
3670            unsafe { E::faer_map(this.ptr_inbounds_at_mut(row, col), |ptr| &mut *ptr) }
3671        }
3672
3673        #[track_caller]
3674        #[inline(always)]
3675        fn get(this: Self, row: usize, col: usize) -> Self::Target {
3676            assert!(all(row < this.nrows(), col < this.ncols()));
3677            unsafe { <Self as MatIndex<usize, usize>>::get_unchecked(this, row, col) }
3678        }
3679    }
3680};
3681
3682// COL INDEX
3683const _: () = {
3684    // RangeFull
3685    // Range
3686    // RangeInclusive
3687    // RangeTo
3688    // RangeToInclusive
3689    // usize
3690
3691    use core::ops::RangeFull;
3692    type Range = core::ops::Range<usize>;
3693    type RangeInclusive = core::ops::RangeInclusive<usize>;
3694    type RangeFrom = core::ops::RangeFrom<usize>;
3695    type RangeTo = core::ops::RangeTo<usize>;
3696    type RangeToInclusive = core::ops::RangeToInclusive<usize>;
3697
3698    impl<E: Entity> ColIndex<RangeFull> for ColRef<'_, E> {
3699        type Target = Self;
3700
3701        #[track_caller]
3702        #[inline(always)]
3703        fn get(this: Self, row: RangeFull) -> Self {
3704            let _ = row;
3705            this
3706        }
3707    }
3708
3709    impl<E: Entity> ColIndex<Range> for ColRef<'_, E> {
3710        type Target = Self;
3711
3712        #[track_caller]
3713        #[inline(always)]
3714        fn get(this: Self, row: Range) -> Self {
3715            this.subrows(row.start, row.end - row.start)
3716        }
3717    }
3718
3719    impl<E: Entity> ColIndex<RangeInclusive> for ColRef<'_, E> {
3720        type Target = Self;
3721
3722        #[track_caller]
3723        #[inline(always)]
3724        fn get(this: Self, row: RangeInclusive) -> Self {
3725            assert!(*row.end() != usize::MAX);
3726            <Self as ColIndex<Range>>::get(this, *row.start()..*row.end() + 1)
3727        }
3728    }
3729
3730    impl<E: Entity> ColIndex<RangeFrom> for ColRef<'_, E> {
3731        type Target = Self;
3732
3733        #[track_caller]
3734        #[inline(always)]
3735        fn get(this: Self, row: RangeFrom) -> Self {
3736            let nrows = this.nrows();
3737            <Self as ColIndex<Range>>::get(this, row.start..nrows)
3738        }
3739    }
3740    impl<E: Entity> ColIndex<RangeTo> for ColRef<'_, E> {
3741        type Target = Self;
3742
3743        #[track_caller]
3744        #[inline(always)]
3745        fn get(this: Self, row: RangeTo) -> Self {
3746            <Self as ColIndex<Range>>::get(this, 0..row.end)
3747        }
3748    }
3749
3750    impl<E: Entity> ColIndex<RangeToInclusive> for ColRef<'_, E> {
3751        type Target = Self;
3752
3753        #[track_caller]
3754        #[inline(always)]
3755        fn get(this: Self, row: RangeToInclusive) -> Self {
3756            assert!(row.end != usize::MAX);
3757            <Self as ColIndex<Range>>::get(this, 0..row.end + 1)
3758        }
3759    }
3760
3761    impl<'a, E: Entity> ColIndex<usize> for ColRef<'a, E> {
3762        type Target = GroupFor<E, &'a E::Unit>;
3763
3764        #[track_caller]
3765        #[inline(always)]
3766        unsafe fn get_unchecked(this: Self, row: usize) -> Self::Target {
3767            unsafe { E::faer_map(this.ptr_inbounds_at(row), |ptr: *const _| &*ptr) }
3768        }
3769
3770        #[track_caller]
3771        #[inline(always)]
3772        fn get(this: Self, row: usize) -> Self::Target {
3773            assert!(row < this.nrows());
3774            unsafe { <Self as ColIndex<usize>>::get_unchecked(this, row) }
3775        }
3776    }
3777
3778    impl<E: Entity> ColIndex<RangeFull> for ColMut<'_, E> {
3779        type Target = Self;
3780
3781        #[track_caller]
3782        #[inline(always)]
3783        fn get(this: Self, row: RangeFull) -> Self {
3784            let _ = row;
3785            this
3786        }
3787    }
3788
3789    impl<E: Entity> ColIndex<Range> for ColMut<'_, E> {
3790        type Target = Self;
3791
3792        #[track_caller]
3793        #[inline(always)]
3794        fn get(this: Self, row: Range) -> Self {
3795            this.subrows_mut(row.start, row.end - row.start)
3796        }
3797    }
3798
3799    impl<E: Entity> ColIndex<RangeInclusive> for ColMut<'_, E> {
3800        type Target = Self;
3801
3802        #[track_caller]
3803        #[inline(always)]
3804        fn get(this: Self, row: RangeInclusive) -> Self {
3805            assert!(*row.end() != usize::MAX);
3806            <Self as ColIndex<Range>>::get(this, *row.start()..*row.end() + 1)
3807        }
3808    }
3809
3810    impl<E: Entity> ColIndex<RangeFrom> for ColMut<'_, E> {
3811        type Target = Self;
3812
3813        #[track_caller]
3814        #[inline(always)]
3815        fn get(this: Self, row: RangeFrom) -> Self {
3816            let nrows = this.nrows();
3817            <Self as ColIndex<Range>>::get(this, row.start..nrows)
3818        }
3819    }
3820    impl<E: Entity> ColIndex<RangeTo> for ColMut<'_, E> {
3821        type Target = Self;
3822
3823        #[track_caller]
3824        #[inline(always)]
3825        fn get(this: Self, row: RangeTo) -> Self {
3826            <Self as ColIndex<Range>>::get(this, 0..row.end)
3827        }
3828    }
3829
3830    impl<E: Entity> ColIndex<RangeToInclusive> for ColMut<'_, E> {
3831        type Target = Self;
3832
3833        #[track_caller]
3834        #[inline(always)]
3835        fn get(this: Self, row: RangeToInclusive) -> Self {
3836            assert!(row.end != usize::MAX);
3837            <Self as ColIndex<Range>>::get(this, 0..row.end + 1)
3838        }
3839    }
3840
3841    impl<'a, E: Entity> ColIndex<usize> for ColMut<'a, E> {
3842        type Target = GroupFor<E, &'a mut E::Unit>;
3843
3844        #[track_caller]
3845        #[inline(always)]
3846        unsafe fn get_unchecked(this: Self, row: usize) -> Self::Target {
3847            unsafe { E::faer_map(this.ptr_inbounds_at_mut(row), |ptr: *mut _| &mut *ptr) }
3848        }
3849
3850        #[track_caller]
3851        #[inline(always)]
3852        fn get(this: Self, row: usize) -> Self::Target {
3853            assert!(row < this.nrows());
3854            unsafe { <Self as ColIndex<usize>>::get_unchecked(this, row) }
3855        }
3856    }
3857};
3858
3859// ROW INDEX
3860const _: () = {
3861    // RangeFull
3862    // Range
3863    // RangeInclusive
3864    // RangeTo
3865    // RangeToInclusive
3866    // usize
3867
3868    use core::ops::RangeFull;
3869    type Range = core::ops::Range<usize>;
3870    type RangeInclusive = core::ops::RangeInclusive<usize>;
3871    type RangeFrom = core::ops::RangeFrom<usize>;
3872    type RangeTo = core::ops::RangeTo<usize>;
3873    type RangeToInclusive = core::ops::RangeToInclusive<usize>;
3874
3875    impl<E: Entity> RowIndex<RangeFull> for RowRef<'_, E> {
3876        type Target = Self;
3877
3878        #[track_caller]
3879        #[inline(always)]
3880        fn get(this: Self, col: RangeFull) -> Self {
3881            let _ = col;
3882            this
3883        }
3884    }
3885
3886    impl<E: Entity> RowIndex<Range> for RowRef<'_, E> {
3887        type Target = Self;
3888
3889        #[track_caller]
3890        #[inline(always)]
3891        fn get(this: Self, col: Range) -> Self {
3892            this.subcols(col.start, col.end - col.start)
3893        }
3894    }
3895
3896    impl<E: Entity> RowIndex<RangeInclusive> for RowRef<'_, E> {
3897        type Target = Self;
3898
3899        #[track_caller]
3900        #[inline(always)]
3901        fn get(this: Self, col: RangeInclusive) -> Self {
3902            assert!(*col.end() != usize::MAX);
3903            <Self as RowIndex<Range>>::get(this, *col.start()..*col.end() + 1)
3904        }
3905    }
3906
3907    impl<E: Entity> RowIndex<RangeFrom> for RowRef<'_, E> {
3908        type Target = Self;
3909
3910        #[track_caller]
3911        #[inline(always)]
3912        fn get(this: Self, col: RangeFrom) -> Self {
3913            let ncols = this.ncols();
3914            <Self as RowIndex<Range>>::get(this, col.start..ncols)
3915        }
3916    }
3917    impl<E: Entity> RowIndex<RangeTo> for RowRef<'_, E> {
3918        type Target = Self;
3919
3920        #[track_caller]
3921        #[inline(always)]
3922        fn get(this: Self, col: RangeTo) -> Self {
3923            <Self as RowIndex<Range>>::get(this, 0..col.end)
3924        }
3925    }
3926
3927    impl<E: Entity> RowIndex<RangeToInclusive> for RowRef<'_, E> {
3928        type Target = Self;
3929
3930        #[track_caller]
3931        #[inline(always)]
3932        fn get(this: Self, col: RangeToInclusive) -> Self {
3933            assert!(col.end != usize::MAX);
3934            <Self as RowIndex<Range>>::get(this, 0..col.end + 1)
3935        }
3936    }
3937
3938    impl<'a, E: Entity> RowIndex<usize> for RowRef<'a, E> {
3939        type Target = GroupFor<E, &'a E::Unit>;
3940
3941        #[track_caller]
3942        #[inline(always)]
3943        unsafe fn get_unchecked(this: Self, col: usize) -> Self::Target {
3944            unsafe { E::faer_map(this.ptr_inbounds_at(col), |ptr: *const _| &*ptr) }
3945        }
3946
3947        #[track_caller]
3948        #[inline(always)]
3949        fn get(this: Self, col: usize) -> Self::Target {
3950            assert!(col < this.ncols());
3951            unsafe { <Self as RowIndex<usize>>::get_unchecked(this, col) }
3952        }
3953    }
3954
3955    impl<E: Entity> RowIndex<RangeFull> for RowMut<'_, E> {
3956        type Target = Self;
3957
3958        #[track_caller]
3959        #[inline(always)]
3960        fn get(this: Self, col: RangeFull) -> Self {
3961            let _ = col;
3962            this
3963        }
3964    }
3965
3966    impl<E: Entity> RowIndex<Range> for RowMut<'_, E> {
3967        type Target = Self;
3968
3969        #[track_caller]
3970        #[inline(always)]
3971        fn get(this: Self, col: Range) -> Self {
3972            this.subcols_mut(col.start, col.end - col.start)
3973        }
3974    }
3975
3976    impl<E: Entity> RowIndex<RangeInclusive> for RowMut<'_, E> {
3977        type Target = Self;
3978
3979        #[track_caller]
3980        #[inline(always)]
3981        fn get(this: Self, col: RangeInclusive) -> Self {
3982            assert!(*col.end() != usize::MAX);
3983            <Self as RowIndex<Range>>::get(this, *col.start()..*col.end() + 1)
3984        }
3985    }
3986
3987    impl<E: Entity> RowIndex<RangeFrom> for RowMut<'_, E> {
3988        type Target = Self;
3989
3990        #[track_caller]
3991        #[inline(always)]
3992        fn get(this: Self, col: RangeFrom) -> Self {
3993            let ncols = this.ncols();
3994            <Self as RowIndex<Range>>::get(this, col.start..ncols)
3995        }
3996    }
3997
3998    impl<E: Entity> RowIndex<RangeTo> for RowMut<'_, E> {
3999        type Target = Self;
4000
4001        #[track_caller]
4002        #[inline(always)]
4003        fn get(this: Self, col: RangeTo) -> Self {
4004            <Self as RowIndex<Range>>::get(this, 0..col.end)
4005        }
4006    }
4007
4008    impl<E: Entity> RowIndex<RangeToInclusive> for RowMut<'_, E> {
4009        type Target = Self;
4010
4011        #[track_caller]
4012        #[inline(always)]
4013        fn get(this: Self, col: RangeToInclusive) -> Self {
4014            assert!(col.end != usize::MAX);
4015            <Self as RowIndex<Range>>::get(this, 0..col.end + 1)
4016        }
4017    }
4018
4019    impl<'a, E: Entity> RowIndex<usize> for RowMut<'a, E> {
4020        type Target = GroupFor<E, &'a mut E::Unit>;
4021
4022        #[track_caller]
4023        #[inline(always)]
4024        unsafe fn get_unchecked(this: Self, col: usize) -> Self::Target {
4025            unsafe { E::faer_map(this.ptr_inbounds_at_mut(col), |ptr: *mut _| &mut *ptr) }
4026        }
4027
4028        #[track_caller]
4029        #[inline(always)]
4030        fn get(this: Self, col: usize) -> Self::Target {
4031            assert!(col < this.ncols());
4032            unsafe { <Self as RowIndex<usize>>::get_unchecked(this, col) }
4033        }
4034    }
4035};
4036
4037impl<'a, E: Entity> Matrix<inner::DiagRef<'a, E>> {
4038    /// Returns the diagonal as a column vector view.
4039    #[inline(always)]
4040    pub fn column_vector(self) -> ColRef<'a, E> {
4041        self.inner.inner
4042    }
4043}
4044
4045impl<'a, E: Entity> Matrix<inner::DiagMut<'a, E>> {
4046    /// Returns the diagonal as a mutable column vector view.
4047    #[inline(always)]
4048    pub fn column_vector_mut(self) -> ColMut<'a, E> {
4049        self.inner.inner
4050    }
4051}
4052
4053impl<E: Entity> Matrix<inner::DiagOwn<E>> {
4054    /// Returns the diagonal as a column vector.
4055    #[inline(always)]
4056    pub fn into_column_vector(self) -> Col<E> {
4057        self.inner.inner
4058    }
4059
4060    /// Returns a view over `self`.
4061    #[inline(always)]
4062    pub fn as_ref(&self) -> Matrix<inner::DiagRef<'_, E>> {
4063        Matrix {
4064            inner: inner::DiagRef {
4065                inner: self.inner.inner.as_ref(),
4066            },
4067        }
4068    }
4069
4070    /// Returns a mutable view over `self`.
4071    #[inline(always)]
4072    pub fn as_mut(&mut self) -> Matrix<inner::DiagMut<'_, E>> {
4073        Matrix {
4074            inner: inner::DiagMut {
4075                inner: self.inner.inner.as_mut(),
4076            },
4077        }
4078    }
4079}
4080
4081#[track_caller]
4082#[inline]
4083fn from_slice_assert(nrows: usize, ncols: usize, len: usize) {
4084    // we don't have to worry about size == usize::MAX == slice.len(), because the length of a
4085    // slice can never exceed isize::MAX in bytes, unless the type is zero sized, in which case
4086    // we don't care
4087    let size = usize::checked_mul(nrows, ncols).unwrap_or(usize::MAX);
4088    assert!(size == len);
4089}
4090
4091#[track_caller]
4092#[inline]
4093fn from_strided_column_major_slice_assert(
4094    nrows: usize,
4095    ncols: usize,
4096    col_stride: usize,
4097    len: usize,
4098) {
4099    // we don't have to worry about size == usize::MAX == slice.len(), because the length of a
4100    // slice can never exceed isize::MAX in bytes, unless the type is zero sized, in which case
4101    // we don't care
4102    let last = usize::checked_mul(col_stride, ncols - 1)
4103        .and_then(|last_col| last_col.checked_add(nrows - 1))
4104        .unwrap_or(usize::MAX);
4105    assert!(last < len);
4106}
4107
4108#[track_caller]
4109#[inline]
4110fn from_strided_column_major_slice_mut_assert(
4111    nrows: usize,
4112    ncols: usize,
4113    col_stride: usize,
4114    len: usize,
4115) {
4116    // we don't have to worry about size == usize::MAX == slice.len(), because the length of a
4117    // slice can never exceed isize::MAX in bytes, unless the type is zero sized, in which case
4118    // we don't care
4119    let last = usize::checked_mul(col_stride, ncols - 1)
4120        .and_then(|last_col| last_col.checked_add(nrows - 1))
4121        .unwrap_or(usize::MAX);
4122    assert!(all(col_stride >= nrows, last < len));
4123}
4124
4125#[inline(always)]
4126unsafe fn unchecked_mul(a: usize, b: isize) -> isize {
4127    let (sum, overflow) = (a as isize).overflowing_mul(b);
4128    if overflow {
4129        core::hint::unreachable_unchecked();
4130    }
4131    sum
4132}
4133
4134#[inline(always)]
4135unsafe fn unchecked_add(a: isize, b: isize) -> isize {
4136    let (sum, overflow) = a.overflowing_add(b);
4137    if overflow {
4138        core::hint::unreachable_unchecked();
4139    }
4140    sum
4141}
4142
4143// COL IMPL
4144const _: () = {
4145    impl<'a, E: Entity> ColRef<'a, E> {
4146        #[track_caller]
4147        #[inline(always)]
4148        #[doc(hidden)]
4149        pub fn try_get_contiguous_col(self) -> GroupFor<E, &'a [E::Unit]> {
4150            assert!(self.row_stride() == 1);
4151            let m = self.nrows();
4152            E::faer_map(
4153                self.as_ptr(),
4154                #[inline(always)]
4155                |ptr| unsafe { core::slice::from_raw_parts(ptr, m) },
4156            )
4157        }
4158
4159        /// Returns the number of rows of the column.
4160        #[inline(always)]
4161        pub fn nrows(&self) -> usize {
4162            self.inner.inner.len
4163        }
4164        /// Returns the number of columns of the column. This is always equal to `1`.
4165        #[inline(always)]
4166        pub fn ncols(&self) -> usize {
4167            1
4168        }
4169
4170        /// Returns pointers to the matrix data.
4171        #[inline(always)]
4172        pub fn as_ptr(self) -> GroupFor<E, *const E::Unit> {
4173            E::faer_map(
4174                from_copy::<E, _>(self.inner.inner.ptr),
4175                #[inline(always)]
4176                |ptr| ptr.as_ptr() as *const E::Unit,
4177            )
4178        }
4179
4180        /// Returns the row stride of the matrix, specified in number of elements, not in bytes.
4181        #[inline(always)]
4182        pub fn row_stride(&self) -> isize {
4183            self.inner.inner.stride
4184        }
4185
4186        /// Returns `self` as a matrix view.
4187        #[inline(always)]
4188        pub fn as_2d(self) -> MatRef<'a, E> {
4189            let nrows = self.nrows();
4190            let row_stride = self.row_stride();
4191            unsafe { mat::from_raw_parts(self.as_ptr(), nrows, 1, row_stride, 0) }
4192        }
4193
4194        /// Returns raw pointers to the element at the given index.
4195        #[inline(always)]
4196        pub fn ptr_at(self, row: usize) -> GroupFor<E, *const E::Unit> {
4197            let offset = (row as isize).wrapping_mul(self.inner.inner.stride);
4198
4199            E::faer_map(
4200                self.as_ptr(),
4201                #[inline(always)]
4202                |ptr| ptr.wrapping_offset(offset),
4203            )
4204        }
4205
4206        #[inline(always)]
4207        unsafe fn unchecked_ptr_at(self, row: usize) -> GroupFor<E, *const E::Unit> {
4208            let offset = unchecked_mul(row, self.inner.inner.stride);
4209            E::faer_map(
4210                self.as_ptr(),
4211                #[inline(always)]
4212                |ptr| ptr.offset(offset),
4213            )
4214        }
4215
4216        #[inline(always)]
4217        unsafe fn overflowing_ptr_at(self, row: usize) -> GroupFor<E, *const E::Unit> {
4218            unsafe {
4219                let cond = row != self.nrows();
4220                let offset = (cond as usize).wrapping_neg() as isize
4221                    & (row as isize).wrapping_mul(self.inner.inner.stride);
4222                E::faer_map(
4223                    self.as_ptr(),
4224                    #[inline(always)]
4225                    |ptr| ptr.offset(offset),
4226                )
4227            }
4228        }
4229
4230        /// Returns raw pointers to the element at the given index, assuming the provided index
4231        /// is within the size of the vector.
4232        ///
4233        /// # Safety
4234        /// The behavior is undefined if any of the following conditions are violated:
4235        /// * `row < self.nrows()`.
4236        #[inline(always)]
4237        #[track_caller]
4238        pub unsafe fn ptr_inbounds_at(self, row: usize) -> GroupFor<E, *const E::Unit> {
4239            debug_assert!(row < self.nrows());
4240            self.unchecked_ptr_at(row)
4241        }
4242
4243        /// Splits the column vector at the given index into two parts and
4244        /// returns an array of each subvector, in the following order:
4245        /// * top.
4246        /// * bottom.
4247        ///
4248        /// # Safety
4249        /// The behavior is undefined if any of the following conditions are violated:
4250        /// * `row <= self.nrows()`.
4251        #[inline(always)]
4252        #[track_caller]
4253        pub unsafe fn split_at_unchecked(self, row: usize) -> (Self, Self) {
4254            debug_assert!(row <= self.nrows());
4255
4256            let row_stride = self.row_stride();
4257
4258            let nrows = self.nrows();
4259
4260            unsafe {
4261                let top = self.as_ptr();
4262                let bot = self.overflowing_ptr_at(row);
4263
4264                (
4265                    col::from_raw_parts(top, row, row_stride),
4266                    col::from_raw_parts(bot, nrows - row, row_stride),
4267                )
4268            }
4269        }
4270
4271        /// Splits the column vector at the given index into two parts and
4272        /// returns an array of each subvector, in the following order:
4273        /// * top.
4274        /// * bottom.
4275        ///
4276        /// # Panics
4277        /// The function panics if any of the following conditions are violated:
4278        /// * `row <= self.nrows()`.
4279        #[inline(always)]
4280        #[track_caller]
4281        pub unsafe fn split_at(self, row: usize) -> (Self, Self) {
4282            assert!(row <= self.nrows());
4283            unsafe { self.split_at_unchecked(row) }
4284        }
4285
4286        /// Returns references to the element at the given index, or subvector if `row` is a
4287        /// range.
4288        ///
4289        /// # Note
4290        /// The values pointed to by the references are expected to be initialized, even if the
4291        /// pointed-to value is not read, otherwise the behavior is undefined.
4292        ///
4293        /// # Safety
4294        /// The behavior is undefined if any of the following conditions are violated:
4295        /// * `row` must be contained in `[0, self.nrows())`.
4296        #[inline(always)]
4297        #[track_caller]
4298        pub unsafe fn get_unchecked<RowRange>(
4299            self,
4300            row: RowRange,
4301        ) -> <Self as ColIndex<RowRange>>::Target
4302        where
4303            Self: ColIndex<RowRange>,
4304        {
4305            <Self as ColIndex<RowRange>>::get_unchecked(self, row)
4306        }
4307
4308        /// Returns references to the element at the given index, or subvector if `row` is a
4309        /// range, with bound checks.
4310        ///
4311        /// # Note
4312        /// The values pointed to by the references are expected to be initialized, even if the
4313        /// pointed-to value is not read, otherwise the behavior is undefined.
4314        ///
4315        /// # Panics
4316        /// The function panics if any of the following conditions are violated:
4317        /// * `row` must be contained in `[0, self.nrows())`.
4318        #[inline(always)]
4319        #[track_caller]
4320        pub fn get<RowRange>(self, row: RowRange) -> <Self as ColIndex<RowRange>>::Target
4321        where
4322            Self: ColIndex<RowRange>,
4323        {
4324            <Self as ColIndex<RowRange>>::get(self, row)
4325        }
4326
4327        /// Reads the value of the element at the given index.
4328        ///
4329        /// # Safety
4330        /// The behavior is undefined if any of the following conditions are violated:
4331        /// * `row < self.nrows()`.
4332        #[inline(always)]
4333        #[track_caller]
4334        pub unsafe fn read_unchecked(&self, row: usize) -> E {
4335            E::faer_from_units(E::faer_map(
4336                self.get_unchecked(row),
4337                #[inline(always)]
4338                |ptr| *ptr,
4339            ))
4340        }
4341
4342        /// Reads the value of the element at the given index, with bound checks.
4343        ///
4344        /// # Panics
4345        /// The function panics if any of the following conditions are violated:
4346        /// * `row < self.nrows()`.
4347        #[inline(always)]
4348        #[track_caller]
4349        pub fn read(&self, row: usize) -> E {
4350            E::faer_from_units(E::faer_map(
4351                self.get(row),
4352                #[inline(always)]
4353                |ptr| *ptr,
4354            ))
4355        }
4356
4357        /// Returns a view over the transpose of `self`.
4358        #[inline(always)]
4359        #[must_use]
4360        pub fn transpose(self) -> RowRef<'a, E> {
4361            unsafe { row::from_raw_parts(self.as_ptr(), self.nrows(), self.row_stride()) }
4362        }
4363
4364        /// Returns a view over the conjugate of `self`.
4365        #[inline(always)]
4366        #[must_use]
4367        pub fn conjugate(self) -> ColRef<'a, E::Conj>
4368        where
4369            E: Conjugate,
4370        {
4371            unsafe {
4372                // SAFETY: Conjugate requires that E::Unit and E::Conj::Unit have the same layout
4373                // and that GroupCopyFor<E,X> == E::Conj::GroupCopy<X>
4374                col::from_raw_parts::<'_, E::Conj>(
4375                    transmute_unchecked::<
4376                        GroupFor<E, *const UnitFor<E>>,
4377                        GroupFor<E::Conj, *const UnitFor<E::Conj>>,
4378                    >(self.as_ptr()),
4379                    self.nrows(),
4380                    self.row_stride(),
4381                )
4382            }
4383        }
4384
4385        /// Returns a view over the conjugate transpose of `self`.
4386        #[inline(always)]
4387        pub fn adjoint(self) -> RowRef<'a, E::Conj>
4388        where
4389            E: Conjugate,
4390        {
4391            self.conjugate().transpose()
4392        }
4393
4394        /// Returns a view over the canonical representation of `self`, as well as a flag declaring
4395        /// whether `self` is implicitly conjugated or not.
4396        #[inline(always)]
4397        pub fn canonicalize(self) -> (ColRef<'a, E::Canonical>, Conj)
4398        where
4399            E: Conjugate,
4400        {
4401            (
4402                unsafe {
4403                    // SAFETY: see Self::conjugate
4404                    col::from_raw_parts::<'_, E::Canonical>(
4405                        transmute_unchecked::<
4406                            GroupFor<E, *const E::Unit>,
4407                            GroupFor<E::Canonical, *const UnitFor<E::Canonical>>,
4408                        >(self.as_ptr()),
4409                        self.nrows(),
4410                        self.row_stride(),
4411                    )
4412                },
4413                if coe::is_same::<E, E::Canonical>() {
4414                    Conj::No
4415                } else {
4416                    Conj::Yes
4417                },
4418            )
4419        }
4420
4421        /// Returns a view over the `self`, with the rows in reversed order.
4422        #[inline(always)]
4423        #[must_use]
4424        pub fn reverse_rows(self) -> Self {
4425            let nrows = self.nrows();
4426            let row_stride = self.row_stride().wrapping_neg();
4427
4428            let ptr = unsafe { self.unchecked_ptr_at(nrows.saturating_sub(1)) };
4429            unsafe { col::from_raw_parts(ptr, nrows, row_stride) }
4430        }
4431
4432        /// Returns a view over the subvector starting at row `row_start`, and with number of rows
4433        /// `nrows`.
4434        ///
4435        /// # Safety
4436        /// The behavior is undefined if any of the following conditions are violated:
4437        /// * `row_start <= self.nrows()`.
4438        /// * `nrows <= self.nrows() - row_start`.
4439        #[track_caller]
4440        #[inline(always)]
4441        pub unsafe fn subrows_unchecked(self, row_start: usize, nrows: usize) -> Self {
4442            debug_assert!(all(
4443                row_start <= self.nrows(),
4444                nrows <= self.nrows() - row_start
4445            ));
4446            let row_stride = self.row_stride();
4447            unsafe { col::from_raw_parts(self.overflowing_ptr_at(row_start), nrows, row_stride) }
4448        }
4449
4450        /// Returns a view over the subvector starting at row `row_start`, and with number of rows
4451        /// `nrows`.
4452        ///
4453        /// # Safety
4454        /// The behavior is undefined if any of the following conditions are violated:
4455        /// * `row_start <= self.nrows()`.
4456        /// * `nrows <= self.nrows() - row_start`.
4457        #[track_caller]
4458        #[inline(always)]
4459        pub fn subrows(self, row_start: usize, nrows: usize) -> Self {
4460            assert!(all(
4461                row_start <= self.nrows(),
4462                nrows <= self.nrows() - row_start
4463            ));
4464            unsafe { self.subrows_unchecked(row_start, nrows) }
4465        }
4466
4467        /// Given a matrix with a single column, returns an object that interprets
4468        /// the column as a diagonal matrix, whoes diagonal elements are values in the column.
4469        #[track_caller]
4470        #[inline(always)]
4471        pub fn column_vector_as_diagonal(self) -> Matrix<inner::DiagRef<'a, E>> {
4472            Matrix {
4473                inner: inner::DiagRef { inner: self },
4474            }
4475        }
4476
4477        /// Returns an owning [`Col`] of the data.
4478        #[inline]
4479        pub fn to_owned(&self) -> Col<E::Canonical>
4480        where
4481            E: Conjugate,
4482        {
4483            let mut mat = Col::new();
4484            mat.resize_with(
4485                self.nrows(),
4486                #[inline(always)]
4487                |row| unsafe { self.read_unchecked(row).canonicalize() },
4488            );
4489            mat
4490        }
4491
4492        /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
4493        #[inline]
4494        pub fn has_nan(&self) -> bool
4495        where
4496            E: ComplexField,
4497        {
4498            (*self).as_2d().has_nan()
4499        }
4500
4501        /// Returns `true` if all of the elements are finite, otherwise returns `false`.
4502        #[inline]
4503        pub fn is_all_finite(&self) -> bool
4504        where
4505            E: ComplexField,
4506        {
4507            (*self).rb().as_2d().is_all_finite()
4508        }
4509
4510        /// Returns the maximum norm of `self`.
4511        #[inline]
4512        pub fn norm_max(&self) -> E::Real
4513        where
4514            E: ComplexField,
4515        {
4516            norm_max((*self).rb().as_2d())
4517        }
4518        /// Returns the L2 norm of `self`.
4519        #[inline]
4520        pub fn norm_l2(&self) -> E::Real
4521        where
4522            E: ComplexField,
4523        {
4524            norm_l2((*self).rb().as_2d())
4525        }
4526
4527        /// Returns the sum of `self`.
4528        #[inline]
4529        pub fn sum(&self) -> E
4530        where
4531            E: ComplexField,
4532        {
4533            sum((*self).rb().as_2d())
4534        }
4535
4536        /// Kroneckor product of `self` and `rhs`.
4537        ///
4538        /// This is an allocating operation; see [`kron`] for the
4539        /// allocation-free version or more info in general.
4540        #[inline]
4541        #[track_caller]
4542        pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
4543        where
4544            E: ComplexField,
4545        {
4546            self.as_2d_ref().kron(rhs)
4547        }
4548
4549        /// Returns a view over the matrix.
4550        #[inline]
4551        pub fn as_ref(&self) -> ColRef<'_, E> {
4552            *self
4553        }
4554
4555        #[doc(hidden)]
4556        #[inline(always)]
4557        pub unsafe fn const_cast(self) -> ColMut<'a, E> {
4558            ColMut {
4559                inner: inner::DenseColMut {
4560                    inner: self.inner.inner,
4561                    __marker: PhantomData,
4562                },
4563            }
4564        }
4565    }
4566
4567    impl<E: SimpleEntity> core::ops::Index<usize> for ColRef<'_, E> {
4568        type Output = E;
4569
4570        #[inline]
4571        #[track_caller]
4572        fn index(&self, row: usize) -> &E {
4573            self.get(row)
4574        }
4575    }
4576
4577    impl<E: SimpleEntity> core::ops::Index<usize> for ColMut<'_, E> {
4578        type Output = E;
4579
4580        #[inline]
4581        #[track_caller]
4582        fn index(&self, row: usize) -> &E {
4583            (*self).rb().get(row)
4584        }
4585    }
4586
4587    impl<E: SimpleEntity> core::ops::IndexMut<usize> for ColMut<'_, E> {
4588        #[inline]
4589        #[track_caller]
4590        fn index_mut(&mut self, row: usize) -> &mut E {
4591            (*self).rb_mut().get_mut(row)
4592        }
4593    }
4594
4595    impl<E: SimpleEntity> core::ops::Index<usize> for Col<E> {
4596        type Output = E;
4597
4598        #[inline]
4599        #[track_caller]
4600        fn index(&self, row: usize) -> &E {
4601            self.as_ref().get(row)
4602        }
4603    }
4604
4605    impl<E: SimpleEntity> core::ops::IndexMut<usize> for Col<E> {
4606        #[inline]
4607        #[track_caller]
4608        fn index_mut(&mut self, row: usize) -> &mut E {
4609            self.as_mut().get_mut(row)
4610        }
4611    }
4612
4613    impl<'a, E: Entity> ColMut<'a, E> {
4614        #[track_caller]
4615        #[inline(always)]
4616        #[doc(hidden)]
4617        pub fn try_get_contiguous_col_mut(self) -> GroupFor<E, &'a mut [E::Unit]> {
4618            assert!(self.row_stride() == 1);
4619            let m = self.nrows();
4620            E::faer_map(
4621                self.as_ptr_mut(),
4622                #[inline(always)]
4623                |ptr| unsafe { core::slice::from_raw_parts_mut(ptr, m) },
4624            )
4625        }
4626
4627        /// Returns the number of rows of the column.
4628        #[inline(always)]
4629        pub fn nrows(&self) -> usize {
4630            self.inner.inner.len
4631        }
4632        /// Returns the number of columns of the column. This is always equal to `1`.
4633        #[inline(always)]
4634        pub fn ncols(&self) -> usize {
4635            1
4636        }
4637
4638        /// Returns pointers to the matrix data.
4639        #[inline(always)]
4640        pub fn as_ptr_mut(self) -> GroupFor<E, *mut E::Unit> {
4641            E::faer_map(
4642                from_copy::<E, _>(self.inner.inner.ptr),
4643                #[inline(always)]
4644                |ptr| ptr.as_ptr() as *mut E::Unit,
4645            )
4646        }
4647
4648        /// Returns the row stride of the matrix, specified in number of elements, not in bytes.
4649        #[inline(always)]
4650        pub fn row_stride(&self) -> isize {
4651            self.inner.inner.stride
4652        }
4653
4654        /// Returns `self` as a mutable matrix view.
4655        #[inline(always)]
4656        pub fn as_2d_mut(self) -> MatMut<'a, E> {
4657            let nrows = self.nrows();
4658            let row_stride = self.row_stride();
4659            unsafe { mat::from_raw_parts_mut(self.as_ptr_mut(), nrows, 1, row_stride, 0) }
4660        }
4661
4662        /// Returns raw pointers to the element at the given index.
4663        #[inline(always)]
4664        pub fn ptr_at_mut(self, row: usize) -> GroupFor<E, *mut E::Unit> {
4665            let offset = (row as isize).wrapping_mul(self.inner.inner.stride);
4666
4667            E::faer_map(
4668                self.as_ptr_mut(),
4669                #[inline(always)]
4670                |ptr| ptr.wrapping_offset(offset),
4671            )
4672        }
4673
4674        #[inline(always)]
4675        unsafe fn ptr_at_mut_unchecked(self, row: usize) -> GroupFor<E, *mut E::Unit> {
4676            let offset = unchecked_mul(row, self.inner.inner.stride);
4677            E::faer_map(
4678                self.as_ptr_mut(),
4679                #[inline(always)]
4680                |ptr| ptr.offset(offset),
4681            )
4682        }
4683
4684        /// Returns raw pointers to the element at the given index, assuming the provided index
4685        /// is within the size of the vector.
4686        ///
4687        /// # Safety
4688        /// The behavior is undefined if any of the following conditions are violated:
4689        /// * `row < self.nrows()`.
4690        #[inline(always)]
4691        #[track_caller]
4692        pub unsafe fn ptr_inbounds_at_mut(self, row: usize) -> GroupFor<E, *mut E::Unit> {
4693            debug_assert!(row < self.nrows());
4694            self.ptr_at_mut_unchecked(row)
4695        }
4696
4697        /// Splits the column vector at the given index into two parts and
4698        /// returns an array of each subvector, in the following order:
4699        /// * top.
4700        /// * bottom.
4701        ///
4702        /// # Safety
4703        /// The behavior is undefined if any of the following conditions are violated:
4704        /// * `row <= self.nrows()`.
4705        #[inline(always)]
4706        #[track_caller]
4707        pub unsafe fn split_at_mut_unchecked(self, row: usize) -> (Self, Self) {
4708            let (top, bot) = self.into_const().split_at_unchecked(row);
4709            unsafe { (top.const_cast(), bot.const_cast()) }
4710        }
4711
4712        /// Splits the column vector at the given index into two parts and
4713        /// returns an array of each subvector, in the following order:
4714        /// * top.
4715        /// * bottom.
4716        ///
4717        /// # Panics
4718        /// The function panics if any of the following conditions are violated:
4719        /// * `row <= self.nrows()`.
4720        #[inline(always)]
4721        #[track_caller]
4722        pub fn split_at_mut(self, row: usize) -> (Self, Self) {
4723            assert!(row <= self.nrows());
4724            unsafe { self.split_at_mut_unchecked(row) }
4725        }
4726
4727        /// Returns references to the element at the given index, or subvector if `row` is a
4728        /// range.
4729        ///
4730        /// # Note
4731        /// The values pointed to by the references are expected to be initialized, even if the
4732        /// pointed-to value is not read, otherwise the behavior is undefined.
4733        ///
4734        /// # Safety
4735        /// The behavior is undefined if any of the following conditions are violated:
4736        /// * `row` must be contained in `[0, self.nrows())`.
4737        #[inline(always)]
4738        #[track_caller]
4739        pub unsafe fn get_unchecked_mut<RowRange>(
4740            self,
4741            row: RowRange,
4742        ) -> <Self as ColIndex<RowRange>>::Target
4743        where
4744            Self: ColIndex<RowRange>,
4745        {
4746            <Self as ColIndex<RowRange>>::get_unchecked(self, row)
4747        }
4748
4749        /// Returns references to the element at the given index, or subvector if `row` is a
4750        /// range, with bound checks.
4751        ///
4752        /// # Note
4753        /// The values pointed to by the references are expected to be initialized, even if the
4754        /// pointed-to value is not read, otherwise the behavior is undefined.
4755        ///
4756        /// # Panics
4757        /// The function panics if any of the following conditions are violated:
4758        /// * `row` must be contained in `[0, self.nrows())`.
4759        #[inline(always)]
4760        #[track_caller]
4761        pub fn get_mut<RowRange>(self, row: RowRange) -> <Self as ColIndex<RowRange>>::Target
4762        where
4763            Self: ColIndex<RowRange>,
4764        {
4765            <Self as ColIndex<RowRange>>::get(self, row)
4766        }
4767
4768        /// Reads the value of the element at the given index.
4769        ///
4770        /// # Safety
4771        /// The behavior is undefined if any of the following conditions are violated:
4772        /// * `row < self.nrows()`.
4773        #[inline(always)]
4774        #[track_caller]
4775        pub unsafe fn read_unchecked(&self, row: usize) -> E {
4776            self.rb().read_unchecked(row)
4777        }
4778
4779        /// Reads the value of the element at the given index, with bound checks.
4780        ///
4781        /// # Panics
4782        /// The function panics if any of the following conditions are violated:
4783        /// * `row < self.nrows()`.
4784        #[inline(always)]
4785        #[track_caller]
4786        pub fn read(&self, row: usize) -> E {
4787            self.rb().read(row)
4788        }
4789
4790        /// Writes the value to the element at the given index.
4791        ///
4792        /// # Safety
4793        /// The behavior is undefined if any of the following conditions are violated:
4794        /// * `row < self.nrows()`.
4795        #[inline(always)]
4796        #[track_caller]
4797        pub unsafe fn write_unchecked(&mut self, row: usize, value: E) {
4798            let units = value.faer_into_units();
4799            let zipped = E::faer_zip(units, (*self).rb_mut().ptr_inbounds_at_mut(row));
4800            E::faer_map(
4801                zipped,
4802                #[inline(always)]
4803                |(unit, ptr)| *ptr = unit,
4804            );
4805        }
4806
4807        /// Writes the value to the element at the given index, with bound checks.
4808        ///
4809        /// # Panics
4810        /// The function panics if any of the following conditions are violated:
4811        /// * `row < self.nrows()`.
4812        #[inline(always)]
4813        #[track_caller]
4814        pub fn write(&mut self, row: usize, value: E) {
4815            assert!(row < self.nrows());
4816            unsafe { self.write_unchecked(row, value) };
4817        }
4818
4819        /// Copies the values from `other` into `self`.
4820        ///
4821        /// # Panics
4822        /// The function panics if any of the following conditions are violated:
4823        /// * `self.nrows() == other.nrows()`.
4824        /// * `self.ncols() == other.ncols()`.
4825        #[track_caller]
4826        pub fn copy_from(&mut self, other: impl AsColRef<E>) {
4827            #[track_caller]
4828            #[inline(always)]
4829            fn implementation<E: Entity>(this: ColMut<'_, E>, other: ColRef<'_, E>) {
4830                zipped!(this.as_2d_mut(), other.as_2d())
4831                    .for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
4832            }
4833            implementation(self.rb_mut(), other.as_col_ref())
4834        }
4835
4836        /// Fills the elements of `self` with zeros.
4837        #[track_caller]
4838        pub fn fill_zero(&mut self)
4839        where
4840            E: ComplexField,
4841        {
4842            zipped!(self.rb_mut().as_2d_mut()).for_each(
4843                #[inline(always)]
4844                |unzipped!(mut x)| x.write(E::faer_zero()),
4845            );
4846        }
4847
4848        /// Fills the elements of `self` with copies of `constant`.
4849        #[track_caller]
4850        pub fn fill(&mut self, constant: E) {
4851            zipped!((*self).rb_mut().as_2d_mut()).for_each(
4852                #[inline(always)]
4853                |unzipped!(mut x)| x.write(constant),
4854            );
4855        }
4856
4857        /// Returns a view over the transpose of `self`.
4858        #[inline(always)]
4859        #[must_use]
4860        pub fn transpose_mut(self) -> RowMut<'a, E> {
4861            unsafe { self.into_const().transpose().const_cast() }
4862        }
4863
4864        /// Returns a view over the conjugate of `self`.
4865        #[inline(always)]
4866        #[must_use]
4867        pub fn conjugate_mut(self) -> ColMut<'a, E::Conj>
4868        where
4869            E: Conjugate,
4870        {
4871            unsafe { self.into_const().conjugate().const_cast() }
4872        }
4873
4874        /// Returns a view over the conjugate transpose of `self`.
4875        #[inline(always)]
4876        pub fn adjoint_mut(self) -> RowMut<'a, E::Conj>
4877        where
4878            E: Conjugate,
4879        {
4880            self.conjugate_mut().transpose_mut()
4881        }
4882
4883        /// Returns a view over the canonical representation of `self`, as well as a flag declaring
4884        /// whether `self` is implicitly conjugated or not.
4885        #[inline(always)]
4886        pub fn canonicalize_mut(self) -> (ColMut<'a, E::Canonical>, Conj)
4887        where
4888            E: Conjugate,
4889        {
4890            let (canon, conj) = self.into_const().canonicalize();
4891            unsafe { (canon.const_cast(), conj) }
4892        }
4893
4894        /// Returns a view over the `self`, with the rows in reversed order.
4895        #[inline(always)]
4896        #[must_use]
4897        pub fn reverse_rows_mut(self) -> Self {
4898            unsafe { self.into_const().reverse_rows().const_cast() }
4899        }
4900
4901        /// Returns a view over the subvector starting at row `row_start`, and with number of rows
4902        /// `nrows`.
4903        ///
4904        /// # Safety
4905        /// The behavior is undefined if any of the following conditions are violated:
4906        /// * `row_start <= self.nrows()`.
4907        /// * `nrows <= self.nrows() - row_start`.
4908        #[track_caller]
4909        #[inline(always)]
4910        pub unsafe fn subrows_mut_unchecked(self, row_start: usize, nrows: usize) -> Self {
4911            self.into_const()
4912                .subrows_unchecked(row_start, nrows)
4913                .const_cast()
4914        }
4915
4916        /// Returns a view over the subvector starting at row `row_start`, and with number of rows
4917        /// `nrows`.
4918        ///
4919        /// # Safety
4920        /// The behavior is undefined if any of the following conditions are violated:
4921        /// * `row_start <= self.nrows()`.
4922        /// * `nrows <= self.nrows() - row_start`.
4923        #[track_caller]
4924        #[inline(always)]
4925        pub fn subrows_mut(self, row_start: usize, nrows: usize) -> Self {
4926            unsafe { self.into_const().subrows(row_start, nrows).const_cast() }
4927        }
4928
4929        /// Given a matrix with a single column, returns an object that interprets
4930        /// the column as a diagonal matrix, whoes diagonal elements are values in the column.
4931        #[track_caller]
4932        #[inline(always)]
4933        pub fn column_vector_as_diagonal(self) -> Matrix<inner::DiagMut<'a, E>> {
4934            Matrix {
4935                inner: inner::DiagMut { inner: self },
4936            }
4937        }
4938
4939        /// Returns an owning [`Col`] of the data.
4940        #[inline]
4941        pub fn to_owned(&self) -> Col<E::Canonical>
4942        where
4943            E: Conjugate,
4944        {
4945            (*self).rb().to_owned()
4946        }
4947
4948        /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
4949        #[inline]
4950        pub fn has_nan(&self) -> bool
4951        where
4952            E: ComplexField,
4953        {
4954            (*self).rb().as_2d().has_nan()
4955        }
4956
4957        /// Returns `true` if all of the elements are finite, otherwise returns `false`.
4958        #[inline]
4959        pub fn is_all_finite(&self) -> bool
4960        where
4961            E: ComplexField,
4962        {
4963            (*self).rb().as_2d().is_all_finite()
4964        }
4965
4966        /// Returns the maximum norm of `self`.
4967        #[inline]
4968        pub fn norm_max(&self) -> E::Real
4969        where
4970            E: ComplexField,
4971        {
4972            norm_max((*self).rb().as_2d())
4973        }
4974        /// Returns the L2 norm of `self`.
4975        #[inline]
4976        pub fn norm_l2(&self) -> E::Real
4977        where
4978            E: ComplexField,
4979        {
4980            norm_l2((*self).rb().as_2d())
4981        }
4982
4983        /// Returns the sum of `self`.
4984        #[inline]
4985        pub fn sum(&self) -> E
4986        where
4987            E: ComplexField,
4988        {
4989            sum((*self).rb().as_2d())
4990        }
4991
4992        /// Kroneckor product of `self` and `rhs`.
4993        ///
4994        /// This is an allocating operation; see [`kron`] for the
4995        /// allocation-free version or more info in general.
4996        #[inline]
4997        #[track_caller]
4998        pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
4999        where
5000            E: ComplexField,
5001        {
5002            self.as_2d_ref().kron(rhs)
5003        }
5004
5005        /// Returns a view over the matrix.
5006        #[inline]
5007        pub fn as_ref(&self) -> ColRef<'_, E> {
5008            (*self).rb()
5009        }
5010    }
5011};
5012
5013// ROW IMPL
5014const _: () = {
5015    impl<'a, E: Entity> RowRef<'a, E> {
5016        /// Returns the number of rows of the row. This is always equal to `1`.
5017        #[inline(always)]
5018        pub fn nrows(&self) -> usize {
5019            1
5020        }
5021        /// Returns the number of columns of the row.
5022        #[inline(always)]
5023        pub fn ncols(&self) -> usize {
5024            self.inner.inner.len
5025        }
5026
5027        /// Returns pointers to the matrix data.
5028        #[inline(always)]
5029        pub fn as_ptr(self) -> GroupFor<E, *const E::Unit> {
5030            E::faer_map(
5031                from_copy::<E, _>(self.inner.inner.ptr),
5032                #[inline(always)]
5033                |ptr| ptr.as_ptr() as *const E::Unit,
5034            )
5035        }
5036
5037        /// Returns the column stride of the matrix, specified in number of elements, not in bytes.
5038        #[inline(always)]
5039        pub fn col_stride(&self) -> isize {
5040            self.inner.inner.stride
5041        }
5042
5043        /// Returns `self` as a matrix view.
5044        #[inline(always)]
5045        pub fn as_2d(self) -> MatRef<'a, E> {
5046            let ncols = self.ncols();
5047            let col_stride = self.col_stride();
5048            unsafe { mat::from_raw_parts(self.as_ptr(), 1, ncols, 0, col_stride) }
5049        }
5050
5051        /// Returns raw pointers to the element at the given index.
5052        #[inline(always)]
5053        pub fn ptr_at(self, col: usize) -> GroupFor<E, *const E::Unit> {
5054            let offset = (col as isize).wrapping_mul(self.inner.inner.stride);
5055
5056            E::faer_map(
5057                self.as_ptr(),
5058                #[inline(always)]
5059                |ptr| ptr.wrapping_offset(offset),
5060            )
5061        }
5062
5063        #[inline(always)]
5064        unsafe fn unchecked_ptr_at(self, col: usize) -> GroupFor<E, *const E::Unit> {
5065            let offset = unchecked_mul(col, self.inner.inner.stride);
5066            E::faer_map(
5067                self.as_ptr(),
5068                #[inline(always)]
5069                |ptr| ptr.offset(offset),
5070            )
5071        }
5072
5073        #[inline(always)]
5074        unsafe fn overflowing_ptr_at(self, col: usize) -> GroupFor<E, *const E::Unit> {
5075            unsafe {
5076                let cond = col != self.ncols();
5077                let offset = (cond as usize).wrapping_neg() as isize
5078                    & (col as isize).wrapping_mul(self.inner.inner.stride);
5079                E::faer_map(
5080                    self.as_ptr(),
5081                    #[inline(always)]
5082                    |ptr| ptr.offset(offset),
5083                )
5084            }
5085        }
5086
5087        /// Returns raw pointers to the element at the given index, assuming the provided index
5088        /// is within the size of the vector.
5089        ///
5090        /// # Safety
5091        /// The behavior is undefined if any of the following conditions are violated:
5092        /// * `col < self.ncols()`.
5093        #[inline(always)]
5094        #[track_caller]
5095        pub unsafe fn ptr_inbounds_at(self, col: usize) -> GroupFor<E, *const E::Unit> {
5096            debug_assert!(col < self.ncols());
5097            self.unchecked_ptr_at(col)
5098        }
5099
5100        /// Splits the column vector at the given index into two parts and
5101        /// returns an array of each subvector, in the following order:
5102        /// * left.
5103        /// * right.
5104        ///
5105        /// # Safety
5106        /// The behavior is undefined if any of the following conditions are violated:
5107        /// * `col <= self.ncols()`.
5108        #[inline(always)]
5109        #[track_caller]
5110        pub unsafe fn split_at_unchecked(self, col: usize) -> (Self, Self) {
5111            debug_assert!(col <= self.ncols());
5112
5113            let col_stride = self.col_stride();
5114
5115            let ncols = self.ncols();
5116
5117            unsafe {
5118                let top = self.as_ptr();
5119                let bot = self.overflowing_ptr_at(col);
5120
5121                (
5122                    row::from_raw_parts(top, col, col_stride),
5123                    row::from_raw_parts(bot, ncols - col, col_stride),
5124                )
5125            }
5126        }
5127
5128        /// Splits the column vector at the given index into two parts and
5129        /// returns an array of each subvector, in the following order:
5130        /// * top.
5131        /// * bottom.
5132        ///
5133        /// # Panics
5134        /// The function panics if any of the following conditions are violated:
5135        /// * `col <= self.ncols()`.
5136        #[inline(always)]
5137        #[track_caller]
5138        pub unsafe fn split_at(self, col: usize) -> (Self, Self) {
5139            assert!(col <= self.ncols());
5140            unsafe { self.split_at_unchecked(col) }
5141        }
5142
5143        /// Returns references to the element at the given index, or subvector if `row` is a
5144        /// range.
5145        ///
5146        /// # Note
5147        /// The values pointed to by the references are expected to be initialized, even if the
5148        /// pointed-to value is not read, otherwise the behavior is undefined.
5149        ///
5150        /// # Safety
5151        /// The behavior is undefined if any of the following conditions are violated:
5152        /// * `col` must be contained in `[0, self.ncols())`.
5153        #[inline(always)]
5154        #[track_caller]
5155        pub unsafe fn get_unchecked<ColRange>(
5156            self,
5157            col: ColRange,
5158        ) -> <Self as RowIndex<ColRange>>::Target
5159        where
5160            Self: RowIndex<ColRange>,
5161        {
5162            <Self as RowIndex<ColRange>>::get_unchecked(self, col)
5163        }
5164
5165        /// Returns references to the element at the given index, or subvector if `col` is a
5166        /// range, with bound checks.
5167        ///
5168        /// # Note
5169        /// The values pointed to by the references are expected to be initialized, even if the
5170        /// pointed-to value is not read, otherwise the behavior is undefined.
5171        ///
5172        /// # Panics
5173        /// The function panics if any of the following conditions are violated:
5174        /// * `col` must be contained in `[0, self.ncols())`.
5175        #[inline(always)]
5176        #[track_caller]
5177        pub fn get<ColRange>(self, col: ColRange) -> <Self as RowIndex<ColRange>>::Target
5178        where
5179            Self: RowIndex<ColRange>,
5180        {
5181            <Self as RowIndex<ColRange>>::get(self, col)
5182        }
5183
5184        /// Reads the value of the element at the given index.
5185        ///
5186        /// # Safety
5187        /// The behavior is undefined if any of the following conditions are violated:
5188        /// * `col < self.ncols()`.
5189        #[inline(always)]
5190        #[track_caller]
5191        pub unsafe fn read_unchecked(&self, col: usize) -> E {
5192            E::faer_from_units(E::faer_map(
5193                self.get_unchecked(col),
5194                #[inline(always)]
5195                |ptr| *ptr,
5196            ))
5197        }
5198
5199        /// Reads the value of the element at the given index, with bound checks.
5200        ///
5201        /// # Panics
5202        /// The function panics if any of the following conditions are violated:
5203        /// * `col < self.ncols()`.
5204        #[inline(always)]
5205        #[track_caller]
5206        pub fn read(&self, col: usize) -> E {
5207            E::faer_from_units(E::faer_map(
5208                self.get(col),
5209                #[inline(always)]
5210                |ptr| *ptr,
5211            ))
5212        }
5213
5214        /// Returns a view over the transpose of `self`.
5215        #[inline(always)]
5216        #[must_use]
5217        pub fn transpose(self) -> ColRef<'a, E> {
5218            unsafe { col::from_raw_parts(self.as_ptr(), self.ncols(), self.col_stride()) }
5219        }
5220
5221        /// Returns a view over the conjugate of `self`.
5222        #[inline(always)]
5223        #[must_use]
5224        pub fn conjugate(self) -> RowRef<'a, E::Conj>
5225        where
5226            E: Conjugate,
5227        {
5228            unsafe {
5229                // SAFETY: Conjugate requires that E::Unit and E::Conj::Unit have the same layout
5230                // and that GroupCopyFor<E,X> == E::Conj::GroupCopy<X>
5231                row::from_raw_parts::<'_, E::Conj>(
5232                    transmute_unchecked::<
5233                        GroupFor<E, *const UnitFor<E>>,
5234                        GroupFor<E::Conj, *const UnitFor<E::Conj>>,
5235                    >(self.as_ptr()),
5236                    self.ncols(),
5237                    self.col_stride(),
5238                )
5239            }
5240        }
5241
5242        /// Returns a view over the conjugate transpose of `self`.
5243        #[inline(always)]
5244        pub fn adjoint(self) -> ColRef<'a, E::Conj>
5245        where
5246            E: Conjugate,
5247        {
5248            self.conjugate().transpose()
5249        }
5250
5251        /// Returns a view over the canonical representation of `self`, as well as a flag declaring
5252        /// whether `self` is implicitly conjugated or not.
5253        #[inline(always)]
5254        pub fn canonicalize(self) -> (RowRef<'a, E::Canonical>, Conj)
5255        where
5256            E: Conjugate,
5257        {
5258            (
5259                unsafe {
5260                    // SAFETY: see Self::conjugate
5261                    row::from_raw_parts::<'_, E::Canonical>(
5262                        transmute_unchecked::<
5263                            GroupFor<E, *const E::Unit>,
5264                            GroupFor<E::Canonical, *const UnitFor<E::Canonical>>,
5265                        >(self.as_ptr()),
5266                        self.ncols(),
5267                        self.col_stride(),
5268                    )
5269                },
5270                if coe::is_same::<E, E::Canonical>() {
5271                    Conj::No
5272                } else {
5273                    Conj::Yes
5274                },
5275            )
5276        }
5277
5278        /// Returns a view over the `self`, with the columnss in reversed order.
5279        #[inline(always)]
5280        #[must_use]
5281        pub fn reverse_cols(self) -> Self {
5282            let ncols = self.ncols();
5283            let col_stride = self.col_stride().wrapping_neg();
5284
5285            let ptr = unsafe { self.unchecked_ptr_at(ncols.saturating_sub(1)) };
5286            unsafe { row::from_raw_parts(ptr, ncols, col_stride) }
5287        }
5288
5289        /// Returns a view over the subvector starting at column `col_start`, and with number of
5290        /// columns `ncols`.
5291        ///
5292        /// # Safety
5293        /// The behavior is undefined if any of the following conditions are violated:
5294        /// * `col_start <= self.ncols()`.
5295        /// * `ncols <= self.ncols() - col_start`.
5296        #[track_caller]
5297        #[inline(always)]
5298        pub unsafe fn subcols_unchecked(self, col_start: usize, ncols: usize) -> Self {
5299            debug_assert!(col_start <= self.ncols());
5300            debug_assert!(ncols <= self.ncols() - col_start);
5301            let col_stride = self.col_stride();
5302            unsafe { row::from_raw_parts(self.overflowing_ptr_at(col_start), ncols, col_stride) }
5303        }
5304
5305        /// Returns a view over the subvector starting at col `col_start`, and with number of cols
5306        /// `ncols`.
5307        ///
5308        /// # Panics
5309        /// The function panics if any of the following conditions are violated:
5310        /// * `col_start <= self.ncols()`.
5311        /// * `ncols <= self.ncols() - col_start`.
5312        #[track_caller]
5313        #[inline(always)]
5314        pub fn subcols(self, col_start: usize, ncols: usize) -> Self {
5315            assert!(col_start <= self.ncols());
5316            assert!(ncols <= self.ncols() - col_start);
5317            unsafe { self.subcols_unchecked(col_start, ncols) }
5318        }
5319
5320        /// Returns an owning [`Row`] of the data.
5321        #[inline]
5322        pub fn to_owned(&self) -> Row<E::Canonical>
5323        where
5324            E: Conjugate,
5325        {
5326            let mut mat = Row::new();
5327            mat.resize_with(
5328                self.ncols(),
5329                #[inline(always)]
5330                |col| unsafe { self.read_unchecked(col).canonicalize() },
5331            );
5332            mat
5333        }
5334
5335        /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
5336        #[inline]
5337        pub fn has_nan(&self) -> bool
5338        where
5339            E: ComplexField,
5340        {
5341            (*self).rb().as_2d().has_nan()
5342        }
5343
5344        /// Returns `true` if all of the elements are finite, otherwise returns `false`.
5345        #[inline]
5346        pub fn is_all_finite(&self) -> bool
5347        where
5348            E: ComplexField,
5349        {
5350            (*self).rb().as_2d().is_all_finite()
5351        }
5352
5353        /// Returns the maximum norm of `self`.
5354        #[inline]
5355        pub fn norm_max(&self) -> E::Real
5356        where
5357            E: ComplexField,
5358        {
5359            norm_max((*self).rb().as_2d())
5360        }
5361        /// Returns the L2 norm of `self`.
5362        #[inline]
5363        pub fn norm_l2(&self) -> E::Real
5364        where
5365            E: ComplexField,
5366        {
5367            norm_l2((*self).rb().as_2d())
5368        }
5369
5370        /// Returns the sum of `self`.
5371        #[inline]
5372        pub fn sum(&self) -> E
5373        where
5374            E: ComplexField,
5375        {
5376            sum((*self).rb().as_2d())
5377        }
5378
5379        /// Kroneckor product of `self` and `rhs`.
5380        ///
5381        /// This is an allocating operation; see [`kron`] for the
5382        /// allocation-free version or more info in general.
5383        #[inline]
5384        #[track_caller]
5385        pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
5386        where
5387            E: ComplexField,
5388        {
5389            self.as_2d_ref().kron(rhs)
5390        }
5391
5392        /// Returns a view over the matrix.
5393        #[inline]
5394        pub fn as_ref(&self) -> RowRef<'_, E> {
5395            *self
5396        }
5397
5398        #[doc(hidden)]
5399        #[inline(always)]
5400        pub unsafe fn const_cast(self) -> RowMut<'a, E> {
5401            RowMut {
5402                inner: inner::DenseRowMut {
5403                    inner: self.inner.inner,
5404                    __marker: PhantomData,
5405                },
5406            }
5407        }
5408    }
5409
5410    impl<E: SimpleEntity> core::ops::Index<usize> for RowRef<'_, E> {
5411        type Output = E;
5412
5413        #[inline]
5414        #[track_caller]
5415        fn index(&self, col: usize) -> &E {
5416            self.get(col)
5417        }
5418    }
5419
5420    impl<E: SimpleEntity> core::ops::Index<usize> for RowMut<'_, E> {
5421        type Output = E;
5422
5423        #[inline]
5424        #[track_caller]
5425        fn index(&self, col: usize) -> &E {
5426            (*self).rb().get(col)
5427        }
5428    }
5429
5430    impl<E: SimpleEntity> core::ops::IndexMut<usize> for RowMut<'_, E> {
5431        #[inline]
5432        #[track_caller]
5433        fn index_mut(&mut self, col: usize) -> &mut E {
5434            (*self).rb_mut().get_mut(col)
5435        }
5436    }
5437
5438    impl<E: SimpleEntity> core::ops::Index<usize> for Row<E> {
5439        type Output = E;
5440
5441        #[inline]
5442        #[track_caller]
5443        fn index(&self, col: usize) -> &E {
5444            self.as_ref().get(col)
5445        }
5446    }
5447
5448    impl<E: SimpleEntity> core::ops::IndexMut<usize> for Row<E> {
5449        #[inline]
5450        #[track_caller]
5451        fn index_mut(&mut self, col: usize) -> &mut E {
5452            self.as_mut().get_mut(col)
5453        }
5454    }
5455
5456    impl<'a, E: Entity> RowMut<'a, E> {
5457        /// Returns the number of rows of the row. This is always equal to `1`.
5458        #[inline(always)]
5459        pub fn nrows(&self) -> usize {
5460            1
5461        }
5462        /// Returns the number of columns of the row.
5463        #[inline(always)]
5464        pub fn ncols(&self) -> usize {
5465            self.inner.inner.len
5466        }
5467
5468        /// Returns pointers to the matrix data.
5469        #[inline(always)]
5470        pub fn as_ptr_mut(self) -> GroupFor<E, *mut E::Unit> {
5471            E::faer_map(
5472                from_copy::<E, _>(self.inner.inner.ptr),
5473                #[inline(always)]
5474                |ptr| ptr.as_ptr() as *mut E::Unit,
5475            )
5476        }
5477
5478        /// Returns the column stride of the matrix, specified in number of elements, not in bytes.
5479        #[inline(always)]
5480        pub fn col_stride(&self) -> isize {
5481            self.inner.inner.stride
5482        }
5483
5484        /// Returns `self` as a mutable matrix view.
5485        #[inline(always)]
5486        pub fn as_2d_mut(self) -> MatMut<'a, E> {
5487            let ncols = self.ncols();
5488            let col_stride = self.col_stride();
5489            unsafe { mat::from_raw_parts_mut(self.as_ptr_mut(), 1, ncols, 0, col_stride) }
5490        }
5491
5492        /// Returns raw pointers to the element at the given index.
5493        #[inline(always)]
5494        pub fn ptr_at_mut(self, col: usize) -> GroupFor<E, *mut E::Unit> {
5495            let offset = (col as isize).wrapping_mul(self.inner.inner.stride);
5496
5497            E::faer_map(
5498                self.as_ptr_mut(),
5499                #[inline(always)]
5500                |ptr| ptr.wrapping_offset(offset),
5501            )
5502        }
5503
5504        #[inline(always)]
5505        unsafe fn ptr_at_mut_unchecked(self, col: usize) -> GroupFor<E, *mut E::Unit> {
5506            let offset = unchecked_mul(col, self.inner.inner.stride);
5507            E::faer_map(
5508                self.as_ptr_mut(),
5509                #[inline(always)]
5510                |ptr| ptr.offset(offset),
5511            )
5512        }
5513
5514        /// Returns raw pointers to the element at the given index, assuming the provided index
5515        /// is within the size of the vector.
5516        ///
5517        /// # Safety
5518        /// The behavior is undefined if any of the following conditions are violated:
5519        /// * `col < self.ncols()`.
5520        #[inline(always)]
5521        #[track_caller]
5522        pub unsafe fn ptr_inbounds_at_mut(self, col: usize) -> GroupFor<E, *mut E::Unit> {
5523            debug_assert!(col < self.ncols());
5524            self.ptr_at_mut_unchecked(col)
5525        }
5526
5527        /// Splits the column vector at the given index into two parts and
5528        /// returns an array of each subvector, in the following order:
5529        /// * left.
5530        /// * right.
5531        ///
5532        /// # Safety
5533        /// The behavior is undefined if any of the following conditions are violated:
5534        /// * `col <= self.ncols()`.
5535        #[inline(always)]
5536        #[track_caller]
5537        pub unsafe fn split_at_mut_unchecked(self, col: usize) -> (Self, Self) {
5538            let (left, right) = self.into_const().split_at_unchecked(col);
5539            unsafe { (left.const_cast(), right.const_cast()) }
5540        }
5541
5542        /// Splits the column vector at the given index into two parts and
5543        /// returns an array of each subvector, in the following order:
5544        /// * top.
5545        /// * bottom.
5546        ///
5547        /// # Panics
5548        /// The function panics if any of the following conditions are violated:
5549        /// * `col <= self.ncols()`.
5550        #[inline(always)]
5551        #[track_caller]
5552        pub fn split_at_mut(self, col: usize) -> (Self, Self) {
5553            assert!(col <= self.ncols());
5554            unsafe { self.split_at_mut_unchecked(col) }
5555        }
5556
5557        /// Returns references to the element at the given index, or subvector if `col` is a
5558        /// range.
5559        ///
5560        /// # Note
5561        /// The values pointed to by the references are expected to be initialized, even if the
5562        /// pointed-to value is not read, otherwise the behavior is undefined.
5563        ///
5564        /// # Safety
5565        /// The behavior is undefined if any of the following conditions are violated:
5566        /// * `col` must be contained in `[0, self.ncols())`.
5567        #[inline(always)]
5568        #[track_caller]
5569        pub unsafe fn get_mut_unchecked<ColRange>(
5570            self,
5571            col: ColRange,
5572        ) -> <Self as RowIndex<ColRange>>::Target
5573        where
5574            Self: RowIndex<ColRange>,
5575        {
5576            <Self as RowIndex<ColRange>>::get_unchecked(self, col)
5577        }
5578
5579        /// Returns references to the element at the given index, or subvector if `col` is a
5580        /// range, with bound checks.
5581        ///
5582        /// # Note
5583        /// The values pointed to by the references are expected to be initialized, even if the
5584        /// pointed-to value is not read, otherwise the behavior is undefined.
5585        ///
5586        /// # Panics
5587        /// The function panics if any of the following conditions are violated:
5588        /// * `col` must be contained in `[0, self.ncols())`.
5589        #[inline(always)]
5590        #[track_caller]
5591        pub fn get_mut<ColRange>(self, col: ColRange) -> <Self as RowIndex<ColRange>>::Target
5592        where
5593            Self: RowIndex<ColRange>,
5594        {
5595            <Self as RowIndex<ColRange>>::get(self, col)
5596        }
5597
5598        /// Reads the value of the element at the given index.
5599        ///
5600        /// # Safety
5601        /// The behavior is undefined if any of the following conditions are violated:
5602        /// * `col < self.ncols()`.
5603        #[inline(always)]
5604        #[track_caller]
5605        pub unsafe fn read_unchecked(&self, col: usize) -> E {
5606            self.rb().read_unchecked(col)
5607        }
5608
5609        /// Reads the value of the element at the given index, with bound checks.
5610        ///
5611        /// # Panics
5612        /// The function panics if any of the following conditions are violated:
5613        /// * `col < self.ncols()`.
5614        #[inline(always)]
5615        #[track_caller]
5616        pub fn read(&self, col: usize) -> E {
5617            self.rb().read(col)
5618        }
5619
5620        /// Writes the value to the element at the given index.
5621        ///
5622        /// # Safety
5623        /// The behavior is undefined if any of the following conditions are violated:
5624        /// * `col < self.ncols()`.
5625        #[inline(always)]
5626        #[track_caller]
5627        pub unsafe fn write_unchecked(&mut self, col: usize, value: E) {
5628            let units = value.faer_into_units();
5629            let zipped = E::faer_zip(units, (*self).rb_mut().ptr_inbounds_at_mut(col));
5630            E::faer_map(
5631                zipped,
5632                #[inline(always)]
5633                |(unit, ptr)| *ptr = unit,
5634            );
5635        }
5636
5637        /// Writes the value to the element at the given index, with bound checks.
5638        ///
5639        /// # Panics
5640        /// The function panics if any of the following conditions are violated:
5641        /// * `col < self.ncols()`.
5642        #[inline(always)]
5643        #[track_caller]
5644        pub fn write(&mut self, col: usize, value: E) {
5645            assert!(col < self.ncols());
5646            unsafe { self.write_unchecked(col, value) };
5647        }
5648
5649        /// Copies the values from `other` into `self`.
5650        ///
5651        /// # Panics
5652        /// The function panics if any of the following conditions are violated:
5653        /// * `self.ncols() == other.ncols()`.
5654        #[track_caller]
5655        pub fn copy_from(&mut self, other: impl AsRowRef<E>) {
5656            #[track_caller]
5657            #[inline(always)]
5658            fn implementation<E: Entity>(this: RowMut<'_, E>, other: RowRef<'_, E>) {
5659                zipped!(this.as_2d_mut(), other.as_2d())
5660                    .for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
5661            }
5662            implementation(self.rb_mut(), other.as_row_ref())
5663        }
5664
5665        /// Fills the elements of `self` with zeros.
5666        #[track_caller]
5667        pub fn fill_zero(&mut self)
5668        where
5669            E: ComplexField,
5670        {
5671            zipped!(self.rb_mut().as_2d_mut()).for_each(
5672                #[inline(always)]
5673                |unzipped!(mut x)| x.write(E::faer_zero()),
5674            );
5675        }
5676
5677        /// Fills the elements of `self` with copies of `constant`.
5678        #[track_caller]
5679        pub fn fill(&mut self, constant: E) {
5680            zipped!((*self).rb_mut().as_2d_mut()).for_each(
5681                #[inline(always)]
5682                |unzipped!(mut x)| x.write(constant),
5683            );
5684        }
5685
5686        /// Returns a view over the transpose of `self`.
5687        #[inline(always)]
5688        #[must_use]
5689        pub fn transpose_mut(self) -> ColMut<'a, E> {
5690            unsafe { self.into_const().transpose().const_cast() }
5691        }
5692
5693        /// Returns a view over the conjugate of `self`.
5694        #[inline(always)]
5695        #[must_use]
5696        pub fn conjugate_mut(self) -> RowMut<'a, E::Conj>
5697        where
5698            E: Conjugate,
5699        {
5700            unsafe { self.into_const().conjugate().const_cast() }
5701        }
5702
5703        /// Returns a view over the conjugate transpose of `self`.
5704        #[inline(always)]
5705        pub fn adjoint_mut(self) -> ColMut<'a, E::Conj>
5706        where
5707            E: Conjugate,
5708        {
5709            self.conjugate_mut().transpose_mut()
5710        }
5711
5712        /// Returns a view over the canonical representation of `self`, as well as a flag declaring
5713        /// whether `self` is implicitly conjugated or not.
5714        #[inline(always)]
5715        pub fn canonicalize_mut(self) -> (RowMut<'a, E::Canonical>, Conj)
5716        where
5717            E: Conjugate,
5718        {
5719            let (canon, conj) = self.into_const().canonicalize();
5720            unsafe { (canon.const_cast(), conj) }
5721        }
5722
5723        /// Returns a view over the `self`, with the columnss in reversed order.
5724        #[inline(always)]
5725        #[must_use]
5726        pub fn reverse_cols_mut(self) -> Self {
5727            unsafe { self.into_const().reverse_cols().const_cast() }
5728        }
5729
5730        /// Returns a view over the subvector starting at col `col_start`, and with number of
5731        /// columns `ncols`.
5732        ///
5733        /// # Safety
5734        /// The behavior is undefined if any of the following conditions are violated:
5735        /// * `col_start <= self.ncols()`.
5736        /// * `ncols <= self.ncols() - col_start`.
5737        #[track_caller]
5738        #[inline(always)]
5739        pub unsafe fn subcols_mut_unchecked(self, col_start: usize, ncols: usize) -> Self {
5740            self.into_const()
5741                .subcols_unchecked(col_start, ncols)
5742                .const_cast()
5743        }
5744
5745        /// Returns a view over the subvector starting at col `col_start`, and with number of
5746        /// columns `ncols`.
5747        ///
5748        /// # Safety
5749        /// The behavior is undefined if any of the following conditions are violated:
5750        /// * `col_start <= self.ncols()`.
5751        /// * `ncols <= self.ncols() - col_start`.
5752        #[track_caller]
5753        #[inline(always)]
5754        pub fn subcols_mut(self, col_start: usize, ncols: usize) -> Self {
5755            unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
5756        }
5757
5758        /// Returns an owning [`Row`] of the data.
5759        #[inline]
5760        pub fn to_owned(&self) -> Row<E::Canonical>
5761        where
5762            E: Conjugate,
5763        {
5764            (*self).rb().to_owned()
5765        }
5766
5767        /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
5768        #[inline]
5769        pub fn has_nan(&self) -> bool
5770        where
5771            E: ComplexField,
5772        {
5773            (*self).rb().as_2d().has_nan()
5774        }
5775
5776        /// Returns `true` if all of the elements are finite, otherwise returns `false`.
5777        #[inline]
5778        pub fn is_all_finite(&self) -> bool
5779        where
5780            E: ComplexField,
5781        {
5782            (*self).rb().as_2d().is_all_finite()
5783        }
5784
5785        /// Returns the maximum norm of `self`.
5786        #[inline]
5787        pub fn norm_max(&self) -> E::Real
5788        where
5789            E: ComplexField,
5790        {
5791            norm_max((*self).rb().as_2d())
5792        }
5793        /// Returns the L2 norm of `self`.
5794        #[inline]
5795        pub fn norm_l2(&self) -> E::Real
5796        where
5797            E: ComplexField,
5798        {
5799            norm_l2((*self).rb().as_2d())
5800        }
5801
5802        /// Returns the sum of `self`.
5803        #[inline]
5804        pub fn sum(&self) -> E
5805        where
5806            E: ComplexField,
5807        {
5808            sum((*self).rb().as_2d())
5809        }
5810
5811        /// Kroneckor product of `self` and `rhs`.
5812        ///
5813        /// This is an allocating operation; see [`kron`] for the
5814        /// allocation-free version or more info in general.
5815        #[inline]
5816        #[track_caller]
5817        pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
5818        where
5819            E: ComplexField,
5820        {
5821            self.as_2d_ref().kron(rhs)
5822        }
5823
5824        /// Returns a view over the matrix.
5825        #[inline]
5826        pub fn as_ref(&self) -> RowRef<'_, E> {
5827            (*self).rb()
5828        }
5829    }
5830};
5831
5832// MAT IMPL
5833const _: () = {
5834    impl<'a, E: Entity> MatRef<'a, E> {
5835        #[track_caller]
5836        #[inline(always)]
5837        #[doc(hidden)]
5838        pub fn try_get_contiguous_col(self, j: usize) -> GroupFor<E, &'a [E::Unit]> {
5839            assert!(self.row_stride() == 1);
5840            let col = self.col(j);
5841            if col.nrows() == 0 {
5842                E::faer_map(
5843                    E::UNIT,
5844                    #[inline(always)]
5845                    |()| &[] as &[E::Unit],
5846                )
5847            } else {
5848                let m = col.nrows();
5849                E::faer_map(
5850                    col.as_ptr(),
5851                    #[inline(always)]
5852                    |ptr| unsafe { core::slice::from_raw_parts(ptr, m) },
5853                )
5854            }
5855        }
5856
5857        /// Returns the number of rows of the matrix.
5858        #[inline(always)]
5859        pub fn nrows(&self) -> usize {
5860            self.inner.inner.nrows
5861        }
5862        /// Returns the number of columns of the matrix.
5863        #[inline(always)]
5864        pub fn ncols(&self) -> usize {
5865            self.inner.inner.ncols
5866        }
5867
5868        /// Returns pointers to the matrix data.
5869        #[inline(always)]
5870        pub fn as_ptr(self) -> GroupFor<E, *const E::Unit> {
5871            E::faer_map(
5872                from_copy::<E, _>(self.inner.inner.ptr),
5873                #[inline(always)]
5874                |ptr| ptr.as_ptr() as *const E::Unit,
5875            )
5876        }
5877
5878        /// Returns the row stride of the matrix, specified in number of elements, not in bytes.
5879        #[inline(always)]
5880        pub fn row_stride(&self) -> isize {
5881            self.inner.inner.row_stride
5882        }
5883
5884        /// Returns the column stride of the matrix, specified in number of elements, not in bytes.
5885        #[inline(always)]
5886        pub fn col_stride(&self) -> isize {
5887            self.inner.inner.col_stride
5888        }
5889
5890        /// Returns raw pointers to the element at the given indices.
5891        #[inline(always)]
5892        pub fn ptr_at(self, row: usize, col: usize) -> GroupFor<E, *const E::Unit> {
5893            let offset = ((row as isize).wrapping_mul(self.inner.inner.row_stride))
5894                .wrapping_add((col as isize).wrapping_mul(self.inner.inner.col_stride));
5895
5896            E::faer_map(
5897                self.as_ptr(),
5898                #[inline(always)]
5899                |ptr| ptr.wrapping_offset(offset),
5900            )
5901        }
5902
5903        #[inline(always)]
5904        unsafe fn unchecked_ptr_at(self, row: usize, col: usize) -> GroupFor<E, *const E::Unit> {
5905            let offset = unchecked_add(
5906                unchecked_mul(row, self.inner.inner.row_stride),
5907                unchecked_mul(col, self.inner.inner.col_stride),
5908            );
5909            E::faer_map(
5910                self.as_ptr(),
5911                #[inline(always)]
5912                |ptr| ptr.offset(offset),
5913            )
5914        }
5915
5916        #[inline(always)]
5917        unsafe fn overflowing_ptr_at(self, row: usize, col: usize) -> GroupFor<E, *const E::Unit> {
5918            unsafe {
5919                let cond = (row != self.nrows()) & (col != self.ncols());
5920                let offset = (cond as usize).wrapping_neg() as isize
5921                    & (isize::wrapping_add(
5922                        (row as isize).wrapping_mul(self.inner.inner.row_stride),
5923                        (col as isize).wrapping_mul(self.inner.inner.col_stride),
5924                    ));
5925                E::faer_map(
5926                    self.as_ptr(),
5927                    #[inline(always)]
5928                    |ptr| ptr.offset(offset),
5929                )
5930            }
5931        }
5932
5933        /// Returns raw pointers to the element at the given indices, assuming the provided indices
5934        /// are within the matrix dimensions.
5935        ///
5936        /// # Safety
5937        /// The behavior is undefined if any of the following conditions are violated:
5938        /// * `row < self.nrows()`.
5939        /// * `col < self.ncols()`.
5940        #[inline(always)]
5941        #[track_caller]
5942        pub unsafe fn ptr_inbounds_at(self, row: usize, col: usize) -> GroupFor<E, *const E::Unit> {
5943            debug_assert!(all(row < self.nrows(), col < self.ncols()));
5944            self.unchecked_ptr_at(row, col)
5945        }
5946
5947        /// Splits the matrix horizontally and vertically at the given indices into four corners and
5948        /// returns an array of each submatrix, in the following order:
5949        /// * top left.
5950        /// * top right.
5951        /// * bottom left.
5952        /// * bottom right.
5953        ///
5954        /// # Safety
5955        /// The behavior is undefined if any of the following conditions are violated:
5956        /// * `row <= self.nrows()`.
5957        /// * `col <= self.ncols()`.
5958        #[inline(always)]
5959        #[track_caller]
5960        pub unsafe fn split_at_unchecked(self, row: usize, col: usize) -> (Self, Self, Self, Self) {
5961            debug_assert!(all(row <= self.nrows(), col <= self.ncols()));
5962
5963            let row_stride = self.row_stride();
5964            let col_stride = self.col_stride();
5965
5966            let nrows = self.nrows();
5967            let ncols = self.ncols();
5968
5969            unsafe {
5970                let top_left = self.overflowing_ptr_at(0, 0);
5971                let top_right = self.overflowing_ptr_at(0, col);
5972                let bot_left = self.overflowing_ptr_at(row, 0);
5973                let bot_right = self.overflowing_ptr_at(row, col);
5974
5975                (
5976                    mat::from_raw_parts(top_left, row, col, row_stride, col_stride),
5977                    mat::from_raw_parts(top_right, row, ncols - col, row_stride, col_stride),
5978                    mat::from_raw_parts(bot_left, nrows - row, col, row_stride, col_stride),
5979                    mat::from_raw_parts(
5980                        bot_right,
5981                        nrows - row,
5982                        ncols - col,
5983                        row_stride,
5984                        col_stride,
5985                    ),
5986                )
5987            }
5988        }
5989
5990        /// Splits the matrix horizontally and vertically at the given indices into four corners and
5991        /// returns an array of each submatrix, in the following order:
5992        /// * top left.
5993        /// * top right.
5994        /// * bottom left.
5995        /// * bottom right.
5996        ///
5997        /// # Panics
5998        /// The function panics if any of the following conditions are violated:
5999        /// * `row <= self.nrows()`.
6000        /// * `col <= self.ncols()`.
6001        #[inline(always)]
6002        #[track_caller]
6003        pub fn split_at(self, row: usize, col: usize) -> (Self, Self, Self, Self) {
6004            assert!(all(row <= self.nrows(), col <= self.ncols()));
6005            unsafe { self.split_at_unchecked(row, col) }
6006        }
6007
6008        /// Splits the matrix horizontally at the given row into two parts and returns an array of
6009        /// each submatrix, in the following order:
6010        /// * top.
6011        /// * bottom.
6012        ///
6013        /// # Safety
6014        /// The behavior is undefined if the following condition is violated:
6015        /// * `row <= self.nrows()`.
6016        #[inline(always)]
6017        #[track_caller]
6018        pub unsafe fn split_at_row_unchecked(self, row: usize) -> (Self, Self) {
6019            debug_assert!(row <= self.nrows());
6020
6021            let row_stride = self.row_stride();
6022            let col_stride = self.col_stride();
6023
6024            let nrows = self.nrows();
6025            let ncols = self.ncols();
6026
6027            unsafe {
6028                let top_right = self.overflowing_ptr_at(0, 0);
6029                let bot_right = self.overflowing_ptr_at(row, 0);
6030
6031                (
6032                    mat::from_raw_parts(top_right, row, ncols, row_stride, col_stride),
6033                    mat::from_raw_parts(bot_right, nrows - row, ncols, row_stride, col_stride),
6034                )
6035            }
6036        }
6037
6038        /// Splits the matrix horizontally at the given row into two parts and returns an array of
6039        /// each submatrix, in the following order:
6040        /// * top.
6041        /// * bottom.
6042        ///
6043        /// # Panics
6044        /// The function panics if the following condition is violated:
6045        /// * `row <= self.nrows()`.
6046        #[inline(always)]
6047        #[track_caller]
6048        pub fn split_at_row(self, row: usize) -> (Self, Self) {
6049            assert!(row <= self.nrows());
6050            unsafe { self.split_at_row_unchecked(row) }
6051        }
6052
6053        /// Splits the matrix vertically at the given row into two parts and returns an array of
6054        /// each submatrix, in the following order:
6055        /// * left.
6056        /// * right.
6057        ///
6058        /// # Safety
6059        /// The behavior is undefined if the following condition is violated:
6060        /// * `col <= self.ncols()`.
6061        #[inline(always)]
6062        #[track_caller]
6063        pub unsafe fn split_at_col_unchecked(self, col: usize) -> (Self, Self) {
6064            debug_assert!(col <= self.ncols());
6065
6066            let row_stride = self.row_stride();
6067            let col_stride = self.col_stride();
6068
6069            let nrows = self.nrows();
6070            let ncols = self.ncols();
6071
6072            unsafe {
6073                let bot_left = self.overflowing_ptr_at(0, 0);
6074                let bot_right = self.overflowing_ptr_at(0, col);
6075
6076                (
6077                    mat::from_raw_parts(bot_left, nrows, col, row_stride, col_stride),
6078                    mat::from_raw_parts(bot_right, nrows, ncols - col, row_stride, col_stride),
6079                )
6080            }
6081        }
6082
6083        /// Splits the matrix vertically at the given row into two parts and returns an array of
6084        /// each submatrix, in the following order:
6085        /// * left.
6086        /// * right.
6087        ///
6088        /// # Panics
6089        /// The function panics if the following condition is violated:
6090        /// * `col <= self.ncols()`.
6091        #[inline(always)]
6092        #[track_caller]
6093        pub fn split_at_col(self, col: usize) -> (Self, Self) {
6094            assert!(col <= self.ncols());
6095            unsafe { self.split_at_col_unchecked(col) }
6096        }
6097
6098        /// Returns references to the element at the given indices, or submatrices if either `row`
6099        /// or `col` is a range.
6100        ///
6101        /// # Note
6102        /// The values pointed to by the references are expected to be initialized, even if the
6103        /// pointed-to value is not read, otherwise the behavior is undefined.
6104        ///
6105        /// # Safety
6106        /// The behavior is undefined if any of the following conditions are violated:
6107        /// * `row` must be contained in `[0, self.nrows())`.
6108        /// * `col` must be contained in `[0, self.ncols())`.
6109        #[inline(always)]
6110        #[track_caller]
6111        pub unsafe fn get_unchecked<RowRange, ColRange>(
6112            self,
6113            row: RowRange,
6114            col: ColRange,
6115        ) -> <Self as MatIndex<RowRange, ColRange>>::Target
6116        where
6117            Self: MatIndex<RowRange, ColRange>,
6118        {
6119            <Self as MatIndex<RowRange, ColRange>>::get_unchecked(self, row, col)
6120        }
6121
6122        /// Returns references to the element at the given indices, or submatrices if either `row`
6123        /// or `col` is a range, with bound checks.
6124        ///
6125        /// # Note
6126        /// The values pointed to by the references are expected to be initialized, even if the
6127        /// pointed-to value is not read, otherwise the behavior is undefined.
6128        ///
6129        /// # Panics
6130        /// The function panics if any of the following conditions are violated:
6131        /// * `row` must be contained in `[0, self.nrows())`.
6132        /// * `col` must be contained in `[0, self.ncols())`.
6133        #[inline(always)]
6134        #[track_caller]
6135        pub fn get<RowRange, ColRange>(
6136            self,
6137            row: RowRange,
6138            col: ColRange,
6139        ) -> <Self as MatIndex<RowRange, ColRange>>::Target
6140        where
6141            Self: MatIndex<RowRange, ColRange>,
6142        {
6143            <Self as MatIndex<RowRange, ColRange>>::get(self, row, col)
6144        }
6145
6146        /// Reads the value of the element at the given indices.
6147        ///
6148        /// # Safety
6149        /// The behavior is undefined if any of the following conditions are violated:
6150        /// * `row < self.nrows()`.
6151        /// * `col < self.ncols()`.
6152        #[inline(always)]
6153        #[track_caller]
6154        pub unsafe fn read_unchecked(&self, row: usize, col: usize) -> E {
6155            E::faer_from_units(E::faer_map(
6156                self.get_unchecked(row, col),
6157                #[inline(always)]
6158                |ptr| *ptr,
6159            ))
6160        }
6161
6162        /// Reads the value of the element at the given indices, with bound checks.
6163        ///
6164        /// # Panics
6165        /// The function panics if any of the following conditions are violated:
6166        /// * `row < self.nrows()`.
6167        /// * `col < self.ncols()`.
6168        #[inline(always)]
6169        #[track_caller]
6170        pub fn read(&self, row: usize, col: usize) -> E {
6171            E::faer_from_units(E::faer_map(
6172                self.get(row, col),
6173                #[inline(always)]
6174                |ptr| *ptr,
6175            ))
6176        }
6177
6178        /// Returns a view over the transpose of `self`.
6179        ///
6180        /// # Example
6181        /// ```
6182        /// use faer_core::mat;
6183        ///
6184        /// let matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
6185        /// let view = matrix.as_ref();
6186        /// let transpose = view.transpose();
6187        ///
6188        /// let expected = mat![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]];
6189        /// assert_eq!(expected.as_ref(), transpose);
6190        /// ```
6191        #[inline(always)]
6192        #[must_use]
6193        pub fn transpose(self) -> Self {
6194            unsafe {
6195                mat::from_raw_parts(
6196                    self.as_ptr(),
6197                    self.ncols(),
6198                    self.nrows(),
6199                    self.col_stride(),
6200                    self.row_stride(),
6201                )
6202            }
6203        }
6204
6205        /// Returns a view over the conjugate of `self`.
6206        #[inline(always)]
6207        #[must_use]
6208        pub fn conjugate(self) -> MatRef<'a, E::Conj>
6209        where
6210            E: Conjugate,
6211        {
6212            unsafe {
6213                // SAFETY: Conjugate requires that E::Unit and E::Conj::Unit have the same layout
6214                // and that GroupCopyFor<E,X> == E::Conj::GroupCopy<X>
6215                mat::from_raw_parts::<'_, E::Conj>(
6216                    transmute_unchecked::<
6217                        GroupFor<E, *const UnitFor<E>>,
6218                        GroupFor<E::Conj, *const UnitFor<E::Conj>>,
6219                    >(self.as_ptr()),
6220                    self.nrows(),
6221                    self.ncols(),
6222                    self.row_stride(),
6223                    self.col_stride(),
6224                )
6225            }
6226        }
6227
6228        /// Returns a view over the conjugate transpose of `self`.
6229        #[inline(always)]
6230        pub fn adjoint(self) -> MatRef<'a, E::Conj>
6231        where
6232            E: Conjugate,
6233        {
6234            self.transpose().conjugate()
6235        }
6236
6237        /// Returns a view over the canonical representation of `self`, as well as a flag declaring
6238        /// whether `self` is implicitly conjugated or not.
6239        #[inline(always)]
6240        pub fn canonicalize(self) -> (MatRef<'a, E::Canonical>, Conj)
6241        where
6242            E: Conjugate,
6243        {
6244            (
6245                unsafe {
6246                    // SAFETY: see Self::conjugate
6247                    mat::from_raw_parts::<'_, E::Canonical>(
6248                        transmute_unchecked::<
6249                            GroupFor<E, *const E::Unit>,
6250                            GroupFor<E::Canonical, *const UnitFor<E::Canonical>>,
6251                        >(self.as_ptr()),
6252                        self.nrows(),
6253                        self.ncols(),
6254                        self.row_stride(),
6255                        self.col_stride(),
6256                    )
6257                },
6258                if coe::is_same::<E, E::Canonical>() {
6259                    Conj::No
6260                } else {
6261                    Conj::Yes
6262                },
6263            )
6264        }
6265
6266        /// Returns a view over the `self`, with the rows in reversed order.
6267        ///
6268        /// # Example
6269        /// ```
6270        /// use faer_core::mat;
6271        ///
6272        /// let matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
6273        /// let view = matrix.as_ref();
6274        /// let reversed_rows = view.reverse_rows();
6275        ///
6276        /// let expected = mat![[4.0, 5.0, 6.0], [1.0, 2.0, 3.0]];
6277        /// assert_eq!(expected.as_ref(), reversed_rows);
6278        /// ```
6279        #[inline(always)]
6280        #[must_use]
6281        pub fn reverse_rows(self) -> Self {
6282            let nrows = self.nrows();
6283            let ncols = self.ncols();
6284            let row_stride = self.row_stride().wrapping_neg();
6285            let col_stride = self.col_stride();
6286
6287            let ptr = unsafe { self.unchecked_ptr_at(nrows.saturating_sub(1), 0) };
6288            unsafe { mat::from_raw_parts(ptr, nrows, ncols, row_stride, col_stride) }
6289        }
6290
6291        /// Returns a view over the `self`, with the columns in reversed order.
6292        ///
6293        /// # Example
6294        /// ```
6295        /// use faer_core::mat;
6296        ///
6297        /// let matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
6298        /// let view = matrix.as_ref();
6299        /// let reversed_cols = view.reverse_cols();
6300        ///
6301        /// let expected = mat![[3.0, 2.0, 1.0], [6.0, 5.0, 4.0]];
6302        /// assert_eq!(expected.as_ref(), reversed_cols);
6303        /// ```
6304        #[inline(always)]
6305        #[must_use]
6306        pub fn reverse_cols(self) -> Self {
6307            let nrows = self.nrows();
6308            let ncols = self.ncols();
6309            let row_stride = self.row_stride();
6310            let col_stride = self.col_stride().wrapping_neg();
6311            let ptr = unsafe { self.unchecked_ptr_at(0, ncols.saturating_sub(1)) };
6312            unsafe { mat::from_raw_parts(ptr, nrows, ncols, row_stride, col_stride) }
6313        }
6314
6315        /// Returns a view over the `self`, with the rows and the columns in reversed order.
6316        ///
6317        /// # Example
6318        /// ```
6319        /// use faer_core::mat;
6320        ///
6321        /// let matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
6322        /// let view = matrix.as_ref();
6323        /// let reversed = view.reverse_rows_and_cols();
6324        ///
6325        /// let expected = mat![[6.0, 5.0, 4.0], [3.0, 2.0, 1.0]];
6326        /// assert_eq!(expected.as_ref(), reversed);
6327        /// ```
6328        #[inline(always)]
6329        #[must_use]
6330        pub fn reverse_rows_and_cols(self) -> Self {
6331            let nrows = self.nrows();
6332            let ncols = self.ncols();
6333            let row_stride = -self.row_stride();
6334            let col_stride = -self.col_stride();
6335
6336            let ptr =
6337                unsafe { self.unchecked_ptr_at(nrows.saturating_sub(1), ncols.saturating_sub(1)) };
6338            unsafe { mat::from_raw_parts(ptr, nrows, ncols, row_stride, col_stride) }
6339        }
6340
6341        /// Returns a view over the submatrix starting at indices `(row_start, col_start)`, and with
6342        /// dimensions `(nrows, ncols)`.
6343        ///
6344        /// # Safety
6345        /// The behavior is undefined if any of the following conditions are violated:
6346        /// * `row_start <= self.nrows()`.
6347        /// * `col_start <= self.ncols()`.
6348        /// * `nrows <= self.nrows() - row_start`.
6349        /// * `ncols <= self.ncols() - col_start`.
6350        #[track_caller]
6351        #[inline(always)]
6352        pub unsafe fn submatrix_unchecked(
6353            self,
6354            row_start: usize,
6355            col_start: usize,
6356            nrows: usize,
6357            ncols: usize,
6358        ) -> Self {
6359            debug_assert!(all(row_start <= self.nrows(), col_start <= self.ncols()));
6360            debug_assert!(all(
6361                nrows <= self.nrows() - row_start,
6362                ncols <= self.ncols() - col_start,
6363            ));
6364            let row_stride = self.row_stride();
6365            let col_stride = self.col_stride();
6366
6367            unsafe {
6368                mat::from_raw_parts(
6369                    self.overflowing_ptr_at(row_start, col_start),
6370                    nrows,
6371                    ncols,
6372                    row_stride,
6373                    col_stride,
6374                )
6375            }
6376        }
6377
6378        /// Returns a view over the submatrix starting at indices `(row_start, col_start)`, and with
6379        /// dimensions `(nrows, ncols)`.
6380        ///
6381        /// # Panics
6382        /// The function panics if any of the following conditions are violated:
6383        /// * `row_start <= self.nrows()`.
6384        /// * `col_start <= self.ncols()`.
6385        /// * `nrows <= self.nrows() - row_start`.
6386        /// * `ncols <= self.ncols() - col_start`.
6387        ///
6388        /// # Example
6389        /// ```
6390        /// use faer_core::mat;
6391        ///
6392        /// let matrix = mat![
6393        ///     [1.0, 5.0, 9.0],
6394        ///     [2.0, 6.0, 10.0],
6395        ///     [3.0, 7.0, 11.0],
6396        ///     [4.0, 8.0, 12.0f64],
6397        /// ];
6398        ///
6399        /// let view = matrix.as_ref();
6400        /// let submatrix = view.submatrix(2, 1, 2, 2);
6401        ///
6402        /// let expected = mat![[7.0, 11.0], [8.0, 12.0f64]];
6403        /// assert_eq!(expected.as_ref(), submatrix);
6404        /// ```
6405        #[track_caller]
6406        #[inline(always)]
6407        pub fn submatrix(
6408            self,
6409            row_start: usize,
6410            col_start: usize,
6411            nrows: usize,
6412            ncols: usize,
6413        ) -> Self {
6414            assert!(all(row_start <= self.nrows(), col_start <= self.ncols()));
6415            assert!(all(
6416                nrows <= self.nrows() - row_start,
6417                ncols <= self.ncols() - col_start,
6418            ));
6419            unsafe { self.submatrix_unchecked(row_start, col_start, nrows, ncols) }
6420        }
6421
6422        /// Returns a view over the submatrix starting at row `row_start`, and with number of rows
6423        /// `nrows`.
6424        ///
6425        /// # Safety
6426        /// The behavior is undefined if any of the following conditions are violated:
6427        /// * `row_start <= self.nrows()`.
6428        /// * `nrows <= self.nrows() - row_start`.
6429        #[track_caller]
6430        #[inline(always)]
6431        pub unsafe fn subrows_unchecked(self, row_start: usize, nrows: usize) -> Self {
6432            debug_assert!(row_start <= self.nrows());
6433            debug_assert!(nrows <= self.nrows() - row_start);
6434            let row_stride = self.row_stride();
6435            let col_stride = self.col_stride();
6436            unsafe {
6437                mat::from_raw_parts(
6438                    self.overflowing_ptr_at(row_start, 0),
6439                    nrows,
6440                    self.ncols(),
6441                    row_stride,
6442                    col_stride,
6443                )
6444            }
6445        }
6446
6447        /// Returns a view over the submatrix starting at row `row_start`, and with number of rows
6448        /// `nrows`.
6449        ///
6450        /// # Panics
6451        /// The function panics if any of the following conditions are violated:
6452        /// * `row_start <= self.nrows()`.
6453        /// * `nrows <= self.nrows() - row_start`.
6454        ///
6455        /// # Example
6456        /// ```
6457        /// use faer_core::mat;
6458        ///
6459        /// let matrix = mat![
6460        ///     [1.0, 5.0, 9.0],
6461        ///     [2.0, 6.0, 10.0],
6462        ///     [3.0, 7.0, 11.0],
6463        ///     [4.0, 8.0, 12.0f64],
6464        /// ];
6465        ///
6466        /// let view = matrix.as_ref();
6467        /// let subrows = view.subrows(1, 2);
6468        ///
6469        /// let expected = mat![[2.0, 6.0, 10.0], [3.0, 7.0, 11.0],];
6470        /// assert_eq!(expected.as_ref(), subrows);
6471        /// ```
6472        #[track_caller]
6473        #[inline(always)]
6474        pub fn subrows(self, row_start: usize, nrows: usize) -> Self {
6475            assert!(row_start <= self.nrows());
6476            assert!(nrows <= self.nrows() - row_start);
6477            unsafe { self.subrows_unchecked(row_start, nrows) }
6478        }
6479
6480        /// Returns a view over the submatrix starting at column `col_start`, and with number of
6481        /// columns `ncols`.
6482        ///
6483        /// # Safety
6484        /// The behavior is undefined if any of the following conditions are violated:
6485        /// * `col_start <= self.ncols()`.
6486        /// * `ncols <= self.ncols() - col_start`.
6487        #[track_caller]
6488        #[inline(always)]
6489        pub unsafe fn subcols_unchecked(self, col_start: usize, ncols: usize) -> Self {
6490            debug_assert!(col_start <= self.ncols());
6491            debug_assert!(ncols <= self.ncols() - col_start);
6492            let row_stride = self.row_stride();
6493            let col_stride = self.col_stride();
6494            unsafe {
6495                mat::from_raw_parts(
6496                    self.overflowing_ptr_at(0, col_start),
6497                    self.nrows(),
6498                    ncols,
6499                    row_stride,
6500                    col_stride,
6501                )
6502            }
6503        }
6504
6505        /// Returns a view over the submatrix starting at column `col_start`, and with number of
6506        /// columns `ncols`.
6507        ///
6508        /// # Panics
6509        /// The function panics if any of the following conditions are violated:
6510        /// * `col_start <= self.ncols()`.
6511        /// * `ncols <= self.ncols() - col_start`.
6512        ///
6513        /// # Example
6514        /// ```
6515        /// use faer_core::mat;
6516        ///
6517        /// let matrix = mat![
6518        ///     [1.0, 5.0, 9.0],
6519        ///     [2.0, 6.0, 10.0],
6520        ///     [3.0, 7.0, 11.0],
6521        ///     [4.0, 8.0, 12.0f64],
6522        /// ];
6523        ///
6524        /// let view = matrix.as_ref();
6525        /// let subcols = view.subcols(2, 1);
6526        ///
6527        /// let expected = mat![[9.0], [10.0], [11.0], [12.0f64]];
6528        /// assert_eq!(expected.as_ref(), subcols);
6529        /// ```
6530        #[track_caller]
6531        #[inline(always)]
6532        pub fn subcols(self, col_start: usize, ncols: usize) -> Self {
6533            debug_assert!(col_start <= self.ncols());
6534            debug_assert!(ncols <= self.ncols() - col_start);
6535            unsafe { self.subcols_unchecked(col_start, ncols) }
6536        }
6537
6538        /// Returns a view over the row at the given index.
6539        ///
6540        /// # Safety
6541        /// The function panics if any of the following conditions are violated:
6542        /// * `row_idx < self.nrows()`.
6543        #[track_caller]
6544        #[inline(always)]
6545        pub unsafe fn row_unchecked(self, row_idx: usize) -> RowRef<'a, E> {
6546            debug_assert!(row_idx < self.nrows());
6547            unsafe {
6548                row::from_raw_parts(
6549                    self.overflowing_ptr_at(row_idx, 0),
6550                    self.ncols(),
6551                    self.col_stride(),
6552                )
6553            }
6554        }
6555
6556        /// Returns a view over the row at the given index.
6557        ///
6558        /// # Panics
6559        /// The function panics if any of the following conditions are violated:
6560        /// * `row_idx < self.nrows()`.
6561        #[track_caller]
6562        #[inline(always)]
6563        pub fn row(self, row_idx: usize) -> RowRef<'a, E> {
6564            assert!(row_idx < self.nrows());
6565            unsafe { self.row_unchecked(row_idx) }
6566        }
6567
6568        /// Returns a view over the column at the given index.
6569        ///
6570        /// # Safety
6571        /// The behavior is undefined if any of the following conditions are violated:
6572        /// * `col_idx < self.ncols()`.
6573        #[track_caller]
6574        #[inline(always)]
6575        pub unsafe fn col_unchecked(self, col_idx: usize) -> ColRef<'a, E> {
6576            debug_assert!(col_idx < self.ncols());
6577            unsafe {
6578                col::from_raw_parts(
6579                    self.overflowing_ptr_at(0, col_idx),
6580                    self.nrows(),
6581                    self.row_stride(),
6582                )
6583            }
6584        }
6585
6586        /// Returns a view over the column at the given index.
6587        ///
6588        /// # Panics
6589        /// The function panics if any of the following conditions are violated:
6590        /// * `col_idx < self.ncols()`.
6591        #[track_caller]
6592        #[inline(always)]
6593        pub fn col(self, col_idx: usize) -> ColRef<'a, E> {
6594            assert!(col_idx < self.ncols());
6595            unsafe { self.col_unchecked(col_idx) }
6596        }
6597
6598        /// Given a matrix with a single column, returns an object that interprets
6599        /// the column as a diagonal matrix, whoes diagonal elements are values in the column.
6600        #[track_caller]
6601        #[inline(always)]
6602        pub fn column_vector_as_diagonal(self) -> Matrix<inner::DiagRef<'a, E>> {
6603            assert!(self.ncols() == 1);
6604            Matrix {
6605                inner: inner::DiagRef { inner: self.col(0) },
6606            }
6607        }
6608
6609        /// Returns the diagonal of the matrix.
6610        #[inline(always)]
6611        pub fn diagonal(self) -> Matrix<inner::DiagRef<'a, E>> {
6612            let size = self.nrows().min(self.ncols());
6613            let row_stride = self.row_stride();
6614            let col_stride = self.col_stride();
6615            unsafe {
6616                Matrix {
6617                    inner: inner::DiagRef {
6618                        inner: col::from_raw_parts(self.as_ptr(), size, row_stride + col_stride),
6619                    },
6620                }
6621            }
6622        }
6623
6624        /// Returns an owning [`Mat`] of the data.
6625        #[inline]
6626        pub fn to_owned(&self) -> Mat<E::Canonical>
6627        where
6628            E: Conjugate,
6629        {
6630            let mut mat = Mat::new();
6631            mat.resize_with(
6632                self.nrows(),
6633                self.ncols(),
6634                #[inline(always)]
6635                |row, col| unsafe { self.read_unchecked(row, col).canonicalize() },
6636            );
6637            mat
6638        }
6639
6640        /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
6641        #[inline]
6642        pub fn has_nan(&self) -> bool
6643        where
6644            E: ComplexField,
6645        {
6646            let mut found_nan = false;
6647            zipped!(*self).for_each(|unzipped!(x)| {
6648                found_nan |= x.read().faer_is_nan();
6649            });
6650            found_nan
6651        }
6652
6653        /// Returns `true` if all of the elements are finite, otherwise returns `false`.
6654        #[inline]
6655        pub fn is_all_finite(&self) -> bool
6656        where
6657            E: ComplexField,
6658        {
6659            let mut all_finite = true;
6660            zipped!(*self).for_each(|unzipped!(x)| {
6661                all_finite &= x.read().faer_is_finite();
6662            });
6663            all_finite
6664        }
6665
6666        /// Returns the maximum norm of `self`.
6667        #[inline]
6668        pub fn norm_max(&self) -> E::Real
6669        where
6670            E: ComplexField,
6671        {
6672            norm_max((*self).rb())
6673        }
6674        /// Returns the L2 norm of `self`.
6675        #[inline]
6676        pub fn norm_l2(&self) -> E::Real
6677        where
6678            E: ComplexField,
6679        {
6680            norm_l2((*self).rb())
6681        }
6682
6683        /// Returns the sum of `self`.
6684        #[inline]
6685        pub fn sum(&self) -> E
6686        where
6687            E: ComplexField,
6688        {
6689            sum((*self).rb())
6690        }
6691
6692        /// Kroneckor product of `self` and `rhs`.
6693        ///
6694        /// This is an allocating operation; see [`kron`] for the
6695        /// allocation-free version or more info in general.
6696        #[inline]
6697        #[track_caller]
6698        pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
6699        where
6700            E: ComplexField,
6701        {
6702            let lhs = (*self).rb();
6703            let rhs = rhs.as_2d_ref();
6704            let mut dst = Mat::new();
6705            dst.resize_with(
6706                lhs.nrows() * rhs.nrows(),
6707                lhs.ncols() * rhs.ncols(),
6708                |_, _| E::zeroed(),
6709            );
6710            kron(dst.as_mut(), lhs, rhs);
6711            dst
6712        }
6713
6714        /// Returns a view over the matrix.
6715        #[inline]
6716        pub fn as_ref(&self) -> MatRef<'_, E> {
6717            *self
6718        }
6719
6720        #[doc(hidden)]
6721        #[inline(always)]
6722        pub unsafe fn const_cast(self) -> MatMut<'a, E> {
6723            MatMut {
6724                inner: inner::DenseMut {
6725                    inner: self.inner.inner,
6726                    __marker: PhantomData,
6727                },
6728            }
6729        }
6730
6731        /// Returns an iterator that provides successive chunks of the columns of this matrix, with
6732        /// each having at most `chunk_size` columns.
6733        ///
6734        /// If the number of columns is a multiple of `chunk_size`, then all chunks have
6735        /// `chunk_size` columns.
6736        #[inline]
6737        #[track_caller]
6738        pub fn col_chunks(
6739            self,
6740            chunk_size: usize,
6741        ) -> impl 'a + DoubleEndedIterator<Item = MatRef<'a, E>> {
6742            assert!(chunk_size > 0);
6743            let chunk_count = self.ncols().msrv_div_ceil(chunk_size);
6744            (0..chunk_count).map(move |chunk_idx| {
6745                let pos = chunk_size * chunk_idx;
6746                self.subcols(pos, Ord::min(chunk_size, self.ncols() - pos))
6747            })
6748        }
6749
6750        /// Returns an iterator that provides successive chunks of the rows of this matrix, with
6751        /// each having at most `chunk_size` rows.
6752        ///
6753        /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
6754        /// rows.
6755        #[inline]
6756        #[track_caller]
6757        pub fn row_chunks(
6758            self,
6759            chunk_size: usize,
6760        ) -> impl 'a + DoubleEndedIterator<Item = MatRef<'a, E>> {
6761            self.transpose()
6762                .col_chunks(chunk_size)
6763                .map(|chunk| chunk.transpose())
6764        }
6765
6766        /// Returns a parallel iterator that provides successive chunks of the columns of this
6767        /// matrix, with each having at most `chunk_size` columns.
6768        ///
6769        /// If the number of columns is a multiple of `chunk_size`, then all chunks have
6770        /// `chunk_size` columns.
6771        ///
6772        /// Only available with the `rayon` feature.
6773        #[cfg(feature = "rayon")]
6774        #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
6775        #[inline]
6776        #[track_caller]
6777        pub fn par_col_chunks(
6778            self,
6779            chunk_size: usize,
6780        ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, E>> {
6781            use rayon::prelude::*;
6782
6783            assert!(chunk_size > 0);
6784            let chunk_count = self.ncols().msrv_div_ceil(chunk_size);
6785            (0..chunk_count).into_par_iter().map(move |chunk_idx| {
6786                let pos = chunk_size * chunk_idx;
6787                self.subcols(pos, Ord::min(chunk_size, self.ncols() - pos))
6788            })
6789        }
6790
6791        /// Returns a parallel iterator that provides successive chunks of the rows of this matrix,
6792        /// with each having at most `chunk_size` rows.
6793        ///
6794        /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
6795        /// rows.
6796        ///
6797        /// Only available with the `rayon` feature.
6798        #[cfg(feature = "rayon")]
6799        #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
6800        #[inline]
6801        #[track_caller]
6802        pub fn par_row_chunks(
6803            self,
6804            chunk_size: usize,
6805        ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, E>> {
6806            use rayon::prelude::*;
6807
6808            self.transpose()
6809                .par_col_chunks(chunk_size)
6810                .map(|chunk| chunk.transpose())
6811        }
6812
6813        /// Returns a parallel iterator that provides successive chunks of the rows of this matrix,
6814        /// with each having at most `chunk_size` rows.
6815        ///
6816        /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
6817        /// rows.
6818        ///
6819        /// Only available with the `rayon` feature.
6820        #[cfg(feature = "rayon")]
6821        #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
6822        #[inline]
6823        #[track_caller]
6824        #[deprecated = "replaced by `MatRef::par_row_chunks`"]
6825        pub fn into_par_row_chunks(
6826            self,
6827            chunk_size: usize,
6828        ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, E>> {
6829            self.par_row_chunks(chunk_size)
6830        }
6831    }
6832
6833    impl<E: SimpleEntity> core::ops::Index<(usize, usize)> for MatRef<'_, E> {
6834        type Output = E;
6835
6836        #[inline]
6837        #[track_caller]
6838        fn index(&self, (row, col): (usize, usize)) -> &E {
6839            self.get(row, col)
6840        }
6841    }
6842
6843    impl<E: SimpleEntity> core::ops::Index<(usize, usize)> for MatMut<'_, E> {
6844        type Output = E;
6845
6846        #[inline]
6847        #[track_caller]
6848        fn index(&self, (row, col): (usize, usize)) -> &E {
6849            (*self).rb().get(row, col)
6850        }
6851    }
6852
6853    impl<E: SimpleEntity> core::ops::IndexMut<(usize, usize)> for MatMut<'_, E> {
6854        #[inline]
6855        #[track_caller]
6856        fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut E {
6857            (*self).rb_mut().get_mut(row, col)
6858        }
6859    }
6860
6861    impl<E: SimpleEntity> core::ops::Index<(usize, usize)> for Mat<E> {
6862        type Output = E;
6863
6864        #[inline]
6865        #[track_caller]
6866        fn index(&self, (row, col): (usize, usize)) -> &E {
6867            self.as_ref().get(row, col)
6868        }
6869    }
6870
6871    impl<E: SimpleEntity> core::ops::IndexMut<(usize, usize)> for Mat<E> {
6872        #[inline]
6873        #[track_caller]
6874        fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut E {
6875            self.as_mut().get_mut(row, col)
6876        }
6877    }
6878
6879    impl<'a, E: Entity> MatMut<'a, E> {
6880        #[track_caller]
6881        #[inline(always)]
6882        #[doc(hidden)]
6883        pub fn try_get_contiguous_col_mut(self, j: usize) -> GroupFor<E, &'a mut [E::Unit]> {
6884            assert!(self.row_stride() == 1);
6885            let col = self.col_mut(j);
6886            if col.nrows() == 0 {
6887                E::faer_map(
6888                    E::UNIT,
6889                    #[inline(always)]
6890                    |()| &mut [] as &mut [E::Unit],
6891                )
6892            } else {
6893                let m = col.nrows();
6894                E::faer_map(
6895                    col.as_ptr_mut(),
6896                    #[inline(always)]
6897                    |ptr| unsafe { core::slice::from_raw_parts_mut(ptr, m) },
6898                )
6899            }
6900        }
6901
6902        /// Returns the number of rows of the matrix.
6903        #[inline(always)]
6904        pub fn nrows(&self) -> usize {
6905            self.inner.inner.nrows
6906        }
6907        /// Returns the number of columns of the matrix.
6908        #[inline(always)]
6909        pub fn ncols(&self) -> usize {
6910            self.inner.inner.ncols
6911        }
6912
6913        /// Returns pointers to the matrix data.
6914        #[inline(always)]
6915        pub fn as_ptr_mut(self) -> GroupFor<E, *mut E::Unit> {
6916            E::faer_map(
6917                from_copy::<E, _>(self.inner.inner.ptr),
6918                #[inline(always)]
6919                |ptr| ptr.as_ptr(),
6920            )
6921        }
6922
6923        /// Returns the row stride of the matrix, specified in number of elements, not in bytes.
6924        #[inline(always)]
6925        pub fn row_stride(&self) -> isize {
6926            self.inner.inner.row_stride
6927        }
6928
6929        /// Returns the column stride of the matrix, specified in number of elements, not in bytes.
6930        #[inline(always)]
6931        pub fn col_stride(&self) -> isize {
6932            self.inner.inner.col_stride
6933        }
6934
6935        /// Returns raw pointers to the element at the given indices.
6936        #[inline(always)]
6937        pub fn ptr_at_mut(self, row: usize, col: usize) -> GroupFor<E, *mut E::Unit> {
6938            let offset = ((row as isize).wrapping_mul(self.inner.inner.row_stride))
6939                .wrapping_add((col as isize).wrapping_mul(self.inner.inner.col_stride));
6940            E::faer_map(
6941                self.as_ptr_mut(),
6942                #[inline(always)]
6943                |ptr| ptr.wrapping_offset(offset),
6944            )
6945        }
6946
6947        #[inline(always)]
6948        unsafe fn ptr_at_mut_unchecked(self, row: usize, col: usize) -> GroupFor<E, *mut E::Unit> {
6949            let offset = unchecked_add(
6950                unchecked_mul(row, self.inner.inner.row_stride),
6951                unchecked_mul(col, self.inner.inner.col_stride),
6952            );
6953            E::faer_map(
6954                self.as_ptr_mut(),
6955                #[inline(always)]
6956                |ptr| ptr.offset(offset),
6957            )
6958        }
6959
6960        /// Returns raw pointers to the element at the given indices, assuming the provided indices
6961        /// are within the matrix dimensions.
6962        ///
6963        /// # Safety
6964        /// The behavior is undefined if any of the following conditions are violated:
6965        /// * `row < self.nrows()`.
6966        /// * `col < self.ncols()`.
6967        #[inline(always)]
6968        #[track_caller]
6969        pub unsafe fn ptr_inbounds_at_mut(
6970            self,
6971            row: usize,
6972            col: usize,
6973        ) -> GroupFor<E, *mut E::Unit> {
6974            debug_assert!(all(row < self.nrows(), col < self.ncols()));
6975            self.ptr_at_mut_unchecked(row, col)
6976        }
6977
6978        /// Splits the matrix horizontally and vertically at the given indices into four corners and
6979        /// returns an array of each submatrix, in the following order:
6980        /// * top left.
6981        /// * top right.
6982        /// * bottom left.
6983        /// * bottom right.
6984        ///
6985        /// # Safety
6986        /// The behavior is undefined if any of the following conditions are violated:
6987        /// * `row <= self.nrows()`.
6988        /// * `col <= self.ncols()`.
6989        #[inline(always)]
6990        #[track_caller]
6991        pub unsafe fn split_at_mut_unchecked(
6992            self,
6993            row: usize,
6994            col: usize,
6995        ) -> (Self, Self, Self, Self) {
6996            let (top_left, top_right, bot_left, bot_right) =
6997                self.into_const().split_at_unchecked(row, col);
6998            (
6999                top_left.const_cast(),
7000                top_right.const_cast(),
7001                bot_left.const_cast(),
7002                bot_right.const_cast(),
7003            )
7004        }
7005
7006        /// Splits the matrix horizontally and vertically at the given indices into four corners and
7007        /// returns an array of each submatrix, in the following order:
7008        /// * top left.
7009        /// * top right.
7010        /// * bottom left.
7011        /// * bottom right.
7012        ///
7013        /// # Panics
7014        /// The function panics if any of the following conditions are violated:
7015        /// * `row <= self.nrows()`.
7016        /// * `col <= self.ncols()`.
7017        #[inline(always)]
7018        #[track_caller]
7019        pub fn split_at_mut(self, row: usize, col: usize) -> (Self, Self, Self, Self) {
7020            let (top_left, top_right, bot_left, bot_right) = self.into_const().split_at(row, col);
7021            unsafe {
7022                (
7023                    top_left.const_cast(),
7024                    top_right.const_cast(),
7025                    bot_left.const_cast(),
7026                    bot_right.const_cast(),
7027                )
7028            }
7029        }
7030
7031        /// Splits the matrix horizontally at the given row into two parts and returns an array of
7032        /// each submatrix, in the following order:
7033        /// * top.
7034        /// * bottom.
7035        ///
7036        /// # Safety
7037        /// The behavior is undefined if the following condition is violated:
7038        /// * `row <= self.nrows()`.
7039        #[inline(always)]
7040        #[track_caller]
7041        pub unsafe fn split_at_row_mut_unchecked(self, row: usize) -> (Self, Self) {
7042            let (top, bot) = self.into_const().split_at_row_unchecked(row);
7043            (top.const_cast(), bot.const_cast())
7044        }
7045
7046        /// Splits the matrix horizontally at the given row into two parts and returns an array of
7047        /// each submatrix, in the following order:
7048        /// * top.
7049        /// * bottom.
7050        ///
7051        /// # Panics
7052        /// The function panics if the following condition is violated:
7053        /// * `row <= self.nrows()`.
7054        #[inline(always)]
7055        #[track_caller]
7056        pub fn split_at_row_mut(self, row: usize) -> (Self, Self) {
7057            let (top, bot) = self.into_const().split_at_row(row);
7058            unsafe { (top.const_cast(), bot.const_cast()) }
7059        }
7060
7061        /// Splits the matrix vertically at the given row into two parts and returns an array of
7062        /// each submatrix, in the following order:
7063        /// * left.
7064        /// * right.
7065        ///
7066        /// # Safety
7067        /// The behavior is undefined if the following condition is violated:
7068        /// * `col <= self.ncols()`.
7069        #[inline(always)]
7070        #[track_caller]
7071        pub unsafe fn split_at_col_mut_unchecked(self, col: usize) -> (Self, Self) {
7072            let (left, right) = self.into_const().split_at_col_unchecked(col);
7073            (left.const_cast(), right.const_cast())
7074        }
7075
7076        /// Splits the matrix vertically at the given row into two parts and returns an array of
7077        /// each submatrix, in the following order:
7078        /// * left.
7079        /// * right.
7080        ///
7081        /// # Panics
7082        /// The function panics if the following condition is violated:
7083        /// * `col <= self.ncols()`.
7084        #[inline(always)]
7085        #[track_caller]
7086        pub fn split_at_col_mut(self, col: usize) -> (Self, Self) {
7087            let (left, right) = self.into_const().split_at_col(col);
7088            unsafe { (left.const_cast(), right.const_cast()) }
7089        }
7090
7091        /// Returns mutable references to the element at the given indices, or submatrices if either
7092        /// `row` or `col` is a range.
7093        ///
7094        /// # Note
7095        /// The values pointed to by the references are expected to be initialized, even if the
7096        /// pointed-to value is not read, otherwise the behavior is undefined.
7097        ///
7098        /// # Safety
7099        /// The behavior is undefined if any of the following conditions are violated:
7100        /// * `row` must be contained in `[0, self.nrows())`.
7101        /// * `col` must be contained in `[0, self.ncols())`.
7102        #[inline(always)]
7103        #[track_caller]
7104        pub unsafe fn get_mut_unchecked<RowRange, ColRange>(
7105            self,
7106            row: RowRange,
7107            col: ColRange,
7108        ) -> <Self as MatIndex<RowRange, ColRange>>::Target
7109        where
7110            Self: MatIndex<RowRange, ColRange>,
7111        {
7112            <Self as MatIndex<RowRange, ColRange>>::get_unchecked(self, row, col)
7113        }
7114
7115        /// Returns mutable references to the element at the given indices, or submatrices if either
7116        /// `row` or `col` is a range, with bound checks.
7117        ///
7118        /// # Note
7119        /// The values pointed to by the references are expected to be initialized, even if the
7120        /// pointed-to value is not read, otherwise the behavior is undefined.
7121        ///
7122        /// # Panics
7123        /// The function panics if any of the following conditions are violated:
7124        /// * `row` must be contained in `[0, self.nrows())`.
7125        /// * `col` must be contained in `[0, self.ncols())`.
7126        #[inline(always)]
7127        #[track_caller]
7128        pub fn get_mut<RowRange, ColRange>(
7129            self,
7130            row: RowRange,
7131            col: ColRange,
7132        ) -> <Self as MatIndex<RowRange, ColRange>>::Target
7133        where
7134            Self: MatIndex<RowRange, ColRange>,
7135        {
7136            <Self as MatIndex<RowRange, ColRange>>::get(self, row, col)
7137        }
7138
7139        /// Reads the value of the element at the given indices.
7140        ///
7141        /// # Safety
7142        /// The behavior is undefined if any of the following conditions are violated:
7143        /// * `row < self.nrows()`.
7144        /// * `col < self.ncols()`.
7145        #[inline(always)]
7146        #[track_caller]
7147        pub unsafe fn read_unchecked(&self, row: usize, col: usize) -> E {
7148            self.rb().read_unchecked(row, col)
7149        }
7150
7151        /// Reads the value of the element at the given indices, with bound checks.
7152        ///
7153        /// # Panics
7154        /// The function panics if any of the following conditions are violated:
7155        /// * `row < self.nrows()`.
7156        /// * `col < self.ncols()`.
7157        #[inline(always)]
7158        #[track_caller]
7159        pub fn read(&self, row: usize, col: usize) -> E {
7160            self.rb().read(row, col)
7161        }
7162
7163        /// Writes the value to the element at the given indices.
7164        ///
7165        /// # Safety
7166        /// The behavior is undefined if any of the following conditions are violated:
7167        /// * `row < self.nrows()`.
7168        /// * `col < self.ncols()`.
7169        #[inline(always)]
7170        #[track_caller]
7171        pub unsafe fn write_unchecked(&mut self, row: usize, col: usize, value: E) {
7172            let units = value.faer_into_units();
7173            let zipped = E::faer_zip(units, (*self).rb_mut().ptr_inbounds_at_mut(row, col));
7174            E::faer_map(
7175                zipped,
7176                #[inline(always)]
7177                |(unit, ptr)| *ptr = unit,
7178            );
7179        }
7180
7181        /// Writes the value to the element at the given indices, with bound checks.
7182        ///
7183        /// # Panics
7184        /// The function panics if any of the following conditions are violated:
7185        /// * `row < self.nrows()`.
7186        /// * `col < self.ncols()`.
7187        #[inline(always)]
7188        #[track_caller]
7189        pub fn write(&mut self, row: usize, col: usize, value: E) {
7190            assert!(all(row < self.nrows(), col < self.ncols()));
7191            unsafe { self.write_unchecked(row, col, value) };
7192        }
7193
7194        /// Copies the values from the lower triangular part of `other` into the lower triangular
7195        /// part of `self`. The diagonal part is included.
7196        ///
7197        /// # Panics
7198        /// The function panics if any of the following conditions are violated:
7199        /// * `self.nrows() == other.nrows()`.
7200        /// * `self.ncols() == other.ncols()`.
7201        /// * `self.nrows() == self.ncols()`.
7202        #[track_caller]
7203        pub fn copy_from_triangular_lower(&mut self, other: impl AsMatRef<E>) {
7204            #[track_caller]
7205            #[inline(always)]
7206            fn implementation<E: Entity>(this: MatMut<'_, E>, other: MatRef<'_, E>) {
7207                zipped!(this, other).for_each_triangular_lower(
7208                    zip::Diag::Include,
7209                    #[inline(always)]
7210                    |unzipped!(mut dst, src)| dst.write(src.read()),
7211                );
7212            }
7213            implementation(self.rb_mut(), other.as_mat_ref())
7214        }
7215
7216        /// Copies the values from the lower triangular part of `other` into the lower triangular
7217        /// part of `self`. The diagonal part is excluded.
7218        ///
7219        /// # Panics
7220        /// The function panics if any of the following conditions are violated:
7221        /// * `self.nrows() == other.nrows()`.
7222        /// * `self.ncols() == other.ncols()`.
7223        /// * `self.nrows() == self.ncols()`.
7224        #[track_caller]
7225        pub fn copy_from_strict_triangular_lower(&mut self, other: impl AsMatRef<E>) {
7226            #[track_caller]
7227            #[inline(always)]
7228            fn implementation<E: Entity>(this: MatMut<'_, E>, other: MatRef<'_, E>) {
7229                zipped!(this, other).for_each_triangular_lower(
7230                    zip::Diag::Skip,
7231                    #[inline(always)]
7232                    |unzipped!(mut dst, src)| dst.write(src.read()),
7233                );
7234            }
7235            implementation(self.rb_mut(), other.as_mat_ref())
7236        }
7237
7238        /// Copies the values from the upper triangular part of `other` into the upper triangular
7239        /// part of `self`. The diagonal part is included.
7240        ///
7241        /// # Panics
7242        /// The function panics if any of the following conditions are violated:
7243        /// * `self.nrows() == other.nrows()`.
7244        /// * `self.ncols() == other.ncols()`.
7245        /// * `self.nrows() == self.ncols()`.
7246        #[track_caller]
7247        #[inline(always)]
7248        pub fn copy_from_triangular_upper(&mut self, other: impl AsMatRef<E>) {
7249            (*self)
7250                .rb_mut()
7251                .transpose_mut()
7252                .copy_from_triangular_lower(other.as_mat_ref().transpose())
7253        }
7254
7255        /// Copies the values from the upper triangular part of `other` into the upper triangular
7256        /// part of `self`. The diagonal part is excluded.
7257        ///
7258        /// # Panics
7259        /// The function panics if any of the following conditions are violated:
7260        /// * `self.nrows() == other.nrows()`.
7261        /// * `self.ncols() == other.ncols()`.
7262        /// * `self.nrows() == self.ncols()`.
7263        #[track_caller]
7264        #[inline(always)]
7265        pub fn copy_from_strict_triangular_upper(&mut self, other: impl AsMatRef<E>) {
7266            (*self)
7267                .rb_mut()
7268                .transpose_mut()
7269                .copy_from_strict_triangular_lower(other.as_mat_ref().transpose())
7270        }
7271
7272        /// Copies the values from `other` into `self`.
7273        ///
7274        /// # Panics
7275        /// The function panics if any of the following conditions are violated:
7276        /// * `self.nrows() == other.nrows()`.
7277        /// * `self.ncols() == other.ncols()`.
7278        #[track_caller]
7279        pub fn copy_from(&mut self, other: impl AsMatRef<E>) {
7280            #[track_caller]
7281            #[inline(always)]
7282            fn implementation<E: Entity>(this: MatMut<'_, E>, other: MatRef<'_, E>) {
7283                zipped!(this, other).for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
7284            }
7285            implementation(self.rb_mut(), other.as_mat_ref())
7286        }
7287
7288        /// Fills the elements of `self` with zeros.
7289        #[track_caller]
7290        pub fn fill_zero(&mut self)
7291        where
7292            E: ComplexField,
7293        {
7294            zipped!(self.rb_mut()).for_each(
7295                #[inline(always)]
7296                |unzipped!(mut x)| x.write(E::faer_zero()),
7297            );
7298        }
7299
7300        /// Fills the elements of `self` with copies of `constant`.
7301        #[track_caller]
7302        pub fn fill(&mut self, constant: E) {
7303            zipped!((*self).rb_mut()).for_each(
7304                #[inline(always)]
7305                |unzipped!(mut x)| x.write(constant),
7306            );
7307        }
7308
7309        /// Returns a view over the transpose of `self`.
7310        ///
7311        /// # Example
7312        /// ```
7313        /// use faer_core::mat;
7314        ///
7315        /// let mut matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
7316        /// let view = matrix.as_mut();
7317        /// let transpose = view.transpose_mut();
7318        ///
7319        /// let mut expected = mat![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]];
7320        /// assert_eq!(expected.as_mut(), transpose);
7321        /// ```
7322        #[inline(always)]
7323        #[must_use]
7324        pub fn transpose_mut(self) -> Self {
7325            unsafe {
7326                mat::from_raw_parts_mut(
7327                    E::faer_map(
7328                        from_copy::<E, _>(self.inner.inner.ptr),
7329                        #[inline(always)]
7330                        |ptr| ptr.as_ptr(),
7331                    ),
7332                    self.ncols(),
7333                    self.nrows(),
7334                    self.col_stride(),
7335                    self.row_stride(),
7336                )
7337            }
7338        }
7339
7340        /// Returns a view over the conjugate of `self`.
7341        #[inline(always)]
7342        #[must_use]
7343        pub fn conjugate_mut(self) -> MatMut<'a, E::Conj>
7344        where
7345            E: Conjugate,
7346        {
7347            unsafe { self.into_const().conjugate().const_cast() }
7348        }
7349
7350        /// Returns a view over the conjugate transpose of `self`.
7351        #[inline(always)]
7352        #[must_use]
7353        pub fn adjoint_mut(self) -> MatMut<'a, E::Conj>
7354        where
7355            E: Conjugate,
7356        {
7357            self.transpose_mut().conjugate_mut()
7358        }
7359
7360        /// Returns a view over the canonical representation of `self`, as well as a flag declaring
7361        /// whether `self` is implicitly conjugated or not.
7362        #[inline(always)]
7363        #[must_use]
7364        pub fn canonicalize_mut(self) -> (MatMut<'a, E::Canonical>, Conj)
7365        where
7366            E: Conjugate,
7367        {
7368            let (canonical, conj) = self.into_const().canonicalize();
7369            unsafe { (canonical.const_cast(), conj) }
7370        }
7371
7372        /// Returns a view over the `self`, with the rows in reversed order.
7373        ///
7374        /// # Example
7375        /// ```
7376        /// use faer_core::mat;
7377        ///
7378        /// let mut matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
7379        /// let view = matrix.as_mut();
7380        /// let reversed_rows = view.reverse_rows_mut();
7381        ///
7382        /// let mut expected = mat![[4.0, 5.0, 6.0], [1.0, 2.0, 3.0]];
7383        /// assert_eq!(expected.as_mut(), reversed_rows);
7384        /// ```
7385        #[inline(always)]
7386        #[must_use]
7387        pub fn reverse_rows_mut(self) -> Self {
7388            unsafe { self.into_const().reverse_rows().const_cast() }
7389        }
7390
7391        /// Returns a view over the `self`, with the columns in reversed order.
7392        ///
7393        /// # Example
7394        /// ```
7395        /// use faer_core::mat;
7396        ///
7397        /// let mut matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
7398        /// let view = matrix.as_mut();
7399        /// let reversed_cols = view.reverse_cols_mut();
7400        ///
7401        /// let mut expected = mat![[3.0, 2.0, 1.0], [6.0, 5.0, 4.0]];
7402        /// assert_eq!(expected.as_mut(), reversed_cols);
7403        /// ```
7404        #[inline(always)]
7405        #[must_use]
7406        pub fn reverse_cols_mut(self) -> Self {
7407            unsafe { self.into_const().reverse_cols().const_cast() }
7408        }
7409
7410        /// Returns a view over the `self`, with the rows and the columns in reversed order.
7411        ///
7412        /// # Example
7413        /// ```
7414        /// use faer_core::mat;
7415        ///
7416        /// let mut matrix = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
7417        /// let view = matrix.as_mut();
7418        /// let reversed = view.reverse_rows_and_cols_mut();
7419        ///
7420        /// let mut expected = mat![[6.0, 5.0, 4.0], [3.0, 2.0, 1.0]];
7421        /// assert_eq!(expected.as_mut(), reversed);
7422        /// ```
7423        #[inline(always)]
7424        #[must_use]
7425        pub fn reverse_rows_and_cols_mut(self) -> Self {
7426            unsafe { self.into_const().reverse_rows_and_cols().const_cast() }
7427        }
7428
7429        /// Returns a view over the submatrix starting at indices `(row_start, col_start)`, and with
7430        /// dimensions `(nrows, ncols)`.
7431        ///
7432        /// # Panics
7433        /// The function panics if any of the following conditions are violated:
7434        /// * `row_start <= self.nrows()`.
7435        /// * `col_start <= self.ncols()`.
7436        /// * `nrows <= self.nrows() - row_start`.
7437        /// * `ncols <= self.ncols() - col_start`.
7438        ///
7439        /// # Example
7440        /// ```
7441        /// use faer_core::mat;
7442        ///
7443        /// let mut matrix = mat![
7444        ///     [1.0, 5.0, 9.0],
7445        ///     [2.0, 6.0, 10.0],
7446        ///     [3.0, 7.0, 11.0],
7447        ///     [4.0, 8.0, 12.0f64],
7448        /// ];
7449        ///
7450        /// let view = matrix.as_mut();
7451        /// let submatrix = view.submatrix_mut(2, 1, 2, 2);
7452        ///
7453        /// let mut expected = mat![[7.0, 11.0], [8.0, 12.0f64]];
7454        /// assert_eq!(expected.as_mut(), submatrix);
7455        /// ```
7456        #[track_caller]
7457        #[inline(always)]
7458        pub fn submatrix_mut(
7459            self,
7460            row_start: usize,
7461            col_start: usize,
7462            nrows: usize,
7463            ncols: usize,
7464        ) -> Self {
7465            unsafe {
7466                self.into_const()
7467                    .submatrix(row_start, col_start, nrows, ncols)
7468                    .const_cast()
7469            }
7470        }
7471
7472        /// Returns a view over the submatrix starting at row `row_start`, and with number of rows
7473        /// `nrows`.
7474        ///
7475        /// # Panics
7476        /// The function panics if any of the following conditions are violated:
7477        /// * `row_start <= self.nrows()`.
7478        /// * `nrows <= self.nrows() - row_start`.
7479        ///
7480        /// # Example
7481        /// ```
7482        /// use faer_core::mat;
7483        ///
7484        /// let mut matrix = mat![
7485        ///     [1.0, 5.0, 9.0],
7486        ///     [2.0, 6.0, 10.0],
7487        ///     [3.0, 7.0, 11.0],
7488        ///     [4.0, 8.0, 12.0f64],
7489        /// ];
7490        ///
7491        /// let view = matrix.as_mut();
7492        /// let subrows = view.subrows_mut(1, 2);
7493        ///
7494        /// let mut expected = mat![[2.0, 6.0, 10.0], [3.0, 7.0, 11.0],];
7495        /// assert_eq!(expected.as_mut(), subrows);
7496        /// ```
7497        #[track_caller]
7498        #[inline(always)]
7499        pub fn subrows_mut(self, row_start: usize, nrows: usize) -> Self {
7500            unsafe { self.into_const().subrows(row_start, nrows).const_cast() }
7501        }
7502
7503        /// Returns a view over the submatrix starting at column `col_start`, and with number of
7504        /// columns `ncols`.
7505        ///
7506        /// # Panics
7507        /// The function panics if any of the following conditions are violated:
7508        /// * `col_start <= self.ncols()`.
7509        /// * `ncols <= self.ncols() - col_start`.
7510        ///
7511        /// # Example
7512        /// ```
7513        /// use faer_core::mat;
7514        ///
7515        /// let mut matrix = mat![
7516        ///     [1.0, 5.0, 9.0],
7517        ///     [2.0, 6.0, 10.0],
7518        ///     [3.0, 7.0, 11.0],
7519        ///     [4.0, 8.0, 12.0f64],
7520        /// ];
7521        ///
7522        /// let view = matrix.as_mut();
7523        /// let subcols = view.subcols_mut(2, 1);
7524        ///
7525        /// let mut expected = mat![[9.0], [10.0], [11.0], [12.0f64]];
7526        /// assert_eq!(expected.as_mut(), subcols);
7527        /// ```
7528        #[track_caller]
7529        #[inline(always)]
7530        pub fn subcols_mut(self, col_start: usize, ncols: usize) -> Self {
7531            unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
7532        }
7533
7534        /// Returns a view over the row at the given index.
7535        ///
7536        /// # Panics
7537        /// The function panics if any of the following conditions are violated:
7538        /// * `row_idx < self.nrows()`.
7539        #[track_caller]
7540        #[inline(always)]
7541        pub fn row_mut(self, row_idx: usize) -> RowMut<'a, E> {
7542            unsafe { self.into_const().row(row_idx).const_cast() }
7543        }
7544
7545        /// Returns a view over the column at the given index.
7546        ///
7547        /// # Panics
7548        /// The function panics if any of the following conditions are violated:
7549        /// * `col_idx < self.ncols()`.
7550        #[track_caller]
7551        #[inline(always)]
7552        pub fn col_mut(self, col_idx: usize) -> ColMut<'a, E> {
7553            unsafe { self.into_const().col(col_idx).const_cast() }
7554        }
7555
7556        /// Given a matrix with a single column, returns an object that interprets
7557        /// the column as a diagonal matrix, whoes diagonal elements are values in the column.
7558        #[track_caller]
7559        #[inline(always)]
7560        pub fn column_vector_as_diagonal_mut(self) -> Matrix<inner::DiagMut<'a, E>> {
7561            assert!(self.ncols() == 1);
7562            Matrix {
7563                inner: inner::DiagMut {
7564                    inner: self.col_mut(0),
7565                },
7566            }
7567        }
7568
7569        /// Returns the diagonal of the matrix.
7570        #[inline(always)]
7571        pub fn diagonal_mut(self) -> Matrix<inner::DiagMut<'a, E>> {
7572            let size = self.nrows().min(self.ncols());
7573            let row_stride = self.row_stride();
7574            let col_stride = self.col_stride();
7575            unsafe {
7576                Matrix {
7577                    inner: inner::DiagMut {
7578                        inner: col::from_raw_parts_mut(
7579                            self.as_ptr_mut(),
7580                            size,
7581                            row_stride + col_stride,
7582                        ),
7583                    },
7584                }
7585            }
7586        }
7587
7588        /// Returns an owning [`Mat`] of the data
7589        #[inline]
7590        pub fn to_owned(&self) -> Mat<E::Canonical>
7591        where
7592            E: Conjugate,
7593        {
7594            self.rb().to_owned()
7595        }
7596
7597        /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
7598        #[inline]
7599        pub fn has_nan(&self) -> bool
7600        where
7601            E: ComplexField,
7602        {
7603            self.rb().has_nan()
7604        }
7605
7606        /// Returns `true` if all of the elements are finite, otherwise returns `false`.
7607        #[inline]
7608        pub fn is_all_finite(&self) -> bool
7609        where
7610            E: ComplexField,
7611        {
7612            self.rb().is_all_finite()
7613        }
7614
7615        /// Returns the maximum norm of `self`.
7616        #[inline]
7617        pub fn norm_max(&self) -> E::Real
7618        where
7619            E: ComplexField,
7620        {
7621            norm_max((*self).rb())
7622        }
7623        /// Returns the L2 norm of `self`.
7624        #[inline]
7625        pub fn norm_l2(&self) -> E::Real
7626        where
7627            E: ComplexField,
7628        {
7629            norm_l2((*self).rb())
7630        }
7631
7632        /// Returns the sum of `self`.
7633        #[inline]
7634        pub fn sum(&self) -> E
7635        where
7636            E: ComplexField,
7637        {
7638            sum((*self).rb())
7639        }
7640
7641        /// Kroneckor product of `self` and `rhs`.
7642        ///
7643        /// This is an allocating operation; see [`kron`] for the
7644        /// allocation-free version or more info in general.
7645        #[inline]
7646        #[track_caller]
7647        pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
7648        where
7649            E: ComplexField,
7650        {
7651            self.as_2d_ref().kron(rhs)
7652        }
7653
7654        /// Returns a view over the matrix.
7655        #[inline]
7656        pub fn as_ref(&self) -> MatRef<'_, E> {
7657            self.rb()
7658        }
7659
7660        /// Returns a mutable view over the matrix.
7661        #[inline]
7662        pub fn as_mut(&mut self) -> MatMut<'_, E> {
7663            self.rb_mut()
7664        }
7665
7666        /// Returns an iterator that provides successive chunks of the columns of this matrix, with
7667        /// each having at most `chunk_size` columns.
7668        ///
7669        /// If the number of columns is a multiple of `chunk_size`, then all chunks have
7670        /// `chunk_size` columns.
7671        #[inline]
7672        #[track_caller]
7673        pub fn col_chunks_mut(
7674            self,
7675            chunk_size: usize,
7676        ) -> impl 'a + DoubleEndedIterator<Item = MatMut<'a, E>> {
7677            self.into_const()
7678                .col_chunks(chunk_size)
7679                .map(|chunk| unsafe { chunk.const_cast() })
7680        }
7681
7682        /// Returns an iterator that provides successive chunks of the rows of this matrix,
7683        /// with each having at most `chunk_size` rows.
7684        ///
7685        /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
7686        /// rows.
7687        #[inline]
7688        #[track_caller]
7689        pub fn row_chunks_mut(
7690            self,
7691            chunk_size: usize,
7692        ) -> impl 'a + DoubleEndedIterator<Item = MatMut<'a, E>> {
7693            self.into_const()
7694                .row_chunks(chunk_size)
7695                .map(|chunk| unsafe { chunk.const_cast() })
7696        }
7697
7698        /// Returns a parallel iterator that provides successive chunks of the columns of this
7699        /// matrix, with each having at most `chunk_size` columns.
7700        ///
7701        /// If the number of columns is a multiple of `chunk_size`, then all chunks have
7702        /// `chunk_size` columns.
7703        ///
7704        /// Only available with the `rayon` feature.
7705        #[cfg(feature = "rayon")]
7706        #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
7707        #[inline]
7708        #[track_caller]
7709        pub fn par_col_chunks_mut(
7710            self,
7711            chunk_size: usize,
7712        ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatMut<'a, E>> {
7713            use rayon::prelude::*;
7714            self.into_const()
7715                .par_col_chunks(chunk_size)
7716                .map(|chunk| unsafe { chunk.const_cast() })
7717        }
7718
7719        /// Returns a parallel iterator that provides successive chunks of the rows of this matrix,
7720        /// with each having at most `chunk_size` rows.
7721        ///
7722        /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
7723        /// rows.
7724        ///
7725        /// Only available with the `rayon` feature.
7726        #[cfg(feature = "rayon")]
7727        #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
7728        #[inline]
7729        #[track_caller]
7730        pub fn par_row_chunks_mut(
7731            self,
7732            chunk_size: usize,
7733        ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatMut<'a, E>> {
7734            use rayon::prelude::*;
7735            self.into_const()
7736                .par_row_chunks(chunk_size)
7737                .map(|chunk| unsafe { chunk.const_cast() })
7738        }
7739    }
7740
7741    impl<'a, E: RealField> MatRef<'a, Complex<E>> {
7742        /// Returns the real and imaginary components of `self`.
7743        #[inline(always)]
7744        pub fn real_imag(self) -> Complex<MatRef<'a, E>> {
7745            let row_stride = self.row_stride();
7746            let col_stride = self.col_stride();
7747            let nrows = self.nrows();
7748            let ncols = self.ncols();
7749            let Complex { re, im } = self.as_ptr();
7750            unsafe {
7751                Complex {
7752                    re: mat::from_raw_parts(re, nrows, ncols, row_stride, col_stride),
7753                    im: mat::from_raw_parts(im, nrows, ncols, row_stride, col_stride),
7754                }
7755            }
7756        }
7757    }
7758
7759    impl<'a, E: RealField> MatMut<'a, Complex<E>> {
7760        /// Returns the real and imaginary components of `self`.
7761        #[inline(always)]
7762        pub fn real_imag_mut(self) -> Complex<MatMut<'a, E>> {
7763            let Complex { re, im } = self.into_const().real_imag();
7764            unsafe {
7765                Complex {
7766                    re: re.const_cast(),
7767                    im: im.const_cast(),
7768                }
7769            }
7770        }
7771    }
7772};
7773
7774#[repr(C)]
7775struct RawMatUnit<T: 'static> {
7776    ptr: NonNull<T>,
7777    row_capacity: usize,
7778    col_capacity: usize,
7779}
7780
7781impl<T: 'static> RawMatUnit<T> {
7782    pub fn new(row_capacity: usize, col_capacity: usize) -> Self {
7783        let dangling = NonNull::<T>::dangling();
7784        if core::mem::size_of::<T>() == 0 {
7785            Self {
7786                ptr: dangling,
7787                row_capacity,
7788                col_capacity,
7789            }
7790        } else {
7791            let cap = row_capacity
7792                .checked_mul(col_capacity)
7793                .unwrap_or_else(capacity_overflow);
7794            let cap_bytes = cap
7795                .checked_mul(core::mem::size_of::<T>())
7796                .unwrap_or_else(capacity_overflow);
7797            if cap_bytes > isize::MAX as usize {
7798                capacity_overflow::<()>();
7799            }
7800
7801            use alloc::alloc::{alloc, handle_alloc_error, Layout};
7802
7803            let layout = Layout::from_size_align(cap_bytes, align_for::<T>())
7804                .ok()
7805                .unwrap_or_else(capacity_overflow);
7806
7807            let ptr = if layout.size() == 0 {
7808                dangling
7809            } else {
7810                // SAFETY: we checked that layout has non zero size
7811                let ptr = unsafe { alloc(layout) } as *mut T;
7812                if ptr.is_null() {
7813                    handle_alloc_error(layout)
7814                } else {
7815                    // SAFETY: we checked that the pointer is not null
7816                    unsafe { NonNull::<T>::new_unchecked(ptr) }
7817                }
7818            };
7819
7820            Self {
7821                ptr,
7822                row_capacity,
7823                col_capacity,
7824            }
7825        }
7826    }
7827}
7828
7829impl<T: 'static> Drop for RawMatUnit<T> {
7830    fn drop(&mut self) {
7831        use alloc::alloc::{dealloc, Layout};
7832        // this cannot overflow because we already allocated this much memory
7833        // self.row_capacity.wrapping_mul(self.col_capacity) may overflow if T is a zst
7834        // but that's fine since we immediately multiply it by 0.
7835        let alloc_size =
7836            self.row_capacity.wrapping_mul(self.col_capacity) * core::mem::size_of::<T>();
7837        if alloc_size != 0 {
7838            // SAFETY: pointer was allocated with alloc::alloc::alloc
7839            unsafe {
7840                dealloc(
7841                    self.ptr.as_ptr() as *mut u8,
7842                    Layout::from_size_align_unchecked(alloc_size, align_for::<T>()),
7843                );
7844            }
7845        }
7846    }
7847}
7848
7849#[repr(C)]
7850struct RawMat<E: Entity> {
7851    ptr: GroupCopyFor<E, NonNull<E::Unit>>,
7852    row_capacity: usize,
7853    col_capacity: usize,
7854}
7855
7856#[cold]
7857fn capacity_overflow_impl() -> ! {
7858    panic!("capacity overflow")
7859}
7860
7861#[inline(always)]
7862fn capacity_overflow<T>() -> T {
7863    capacity_overflow_impl();
7864}
7865
7866#[doc(hidden)]
7867#[inline(always)]
7868pub fn is_vectorizable<T: 'static>() -> bool {
7869    coe::is_same::<f32, T>()
7870        || coe::is_same::<f64, T>()
7871        || coe::is_same::<c32, T>()
7872        || coe::is_same::<c64, T>()
7873        || coe::is_same::<c32conj, T>()
7874        || coe::is_same::<c64conj, T>()
7875}
7876
7877// https://rust-lang.github.io/hashbrown/src/crossbeam_utils/cache_padded.rs.html#128-130
7878#[doc(hidden)]
7879pub const CACHELINE_ALIGN: usize = {
7880    #[cfg(any(
7881        target_arch = "x86_64",
7882        target_arch = "aarch64",
7883        target_arch = "powerpc64",
7884    ))]
7885    {
7886        128
7887    }
7888    #[cfg(any(
7889        target_arch = "arm",
7890        target_arch = "mips",
7891        target_arch = "mips64",
7892        target_arch = "riscv64",
7893    ))]
7894    {
7895        32
7896    }
7897    #[cfg(target_arch = "s390x")]
7898    {
7899        256
7900    }
7901    #[cfg(not(any(
7902        target_arch = "x86_64",
7903        target_arch = "aarch64",
7904        target_arch = "powerpc64",
7905        target_arch = "arm",
7906        target_arch = "mips",
7907        target_arch = "mips64",
7908        target_arch = "riscv64",
7909        target_arch = "s390x",
7910    )))]
7911    {
7912        64
7913    }
7914};
7915
7916#[doc(hidden)]
7917#[inline(always)]
7918pub fn align_for<T: 'static>() -> usize {
7919    if is_vectorizable::<T>() {
7920        Ord::max(
7921            core::mem::size_of::<T>(),
7922            Ord::max(core::mem::align_of::<T>(), CACHELINE_ALIGN),
7923        )
7924    } else {
7925        core::mem::align_of::<T>()
7926    }
7927}
7928
7929impl<E: Entity> RawMat<E> {
7930    pub fn new(row_capacity: usize, col_capacity: usize) -> Self {
7931        // allocate the unit matrices
7932        let group = E::faer_map(E::UNIT, |()| {
7933            RawMatUnit::<E::Unit>::new(row_capacity, col_capacity)
7934        });
7935
7936        let group = E::faer_map(group, ManuallyDrop::new);
7937
7938        Self {
7939            ptr: into_copy::<E, _>(E::faer_map(group, |mat| mat.ptr)),
7940            row_capacity,
7941            col_capacity,
7942        }
7943    }
7944}
7945
7946impl<E: Entity> Drop for RawMat<E> {
7947    fn drop(&mut self) {
7948        drop(E::faer_map(from_copy::<E, _>(self.ptr), |ptr| RawMatUnit {
7949            ptr,
7950            row_capacity: self.row_capacity,
7951            col_capacity: self.col_capacity,
7952        }));
7953    }
7954}
7955
7956/// Heap allocated resizable matrix, similar to a 2D [`Vec`].
7957///
7958/// # Note
7959///
7960/// The memory layout of `Mat` is guaranteed to be column-major, meaning that it has a row stride
7961/// of `1`, and an unspecified column stride that can be queried with [`Mat::col_stride`].
7962///
7963/// This implies that while each individual column is stored contiguously in memory, the matrix as
7964/// a whole may not necessarily be contiguous. The implementation may add padding at the end of
7965/// each column when overaligning each column can provide a performance gain.
7966///
7967/// Let us consider a 3×4 matrix
7968///
7969/// ```notcode
7970///  0 │ 3 │ 6 │  9
7971/// ───┼───┼───┼───
7972///  1 │ 4 │ 7 │ 10
7973/// ───┼───┼───┼───
7974///  2 │ 5 │ 8 │ 11
7975/// ```
7976/// The memory representation of the data held by such a matrix could look like the following:
7977///
7978/// ```notcode
7979/// 0 1 2 X 3 4 5 X 6 7 8 X 9 10 11 X
7980/// ```
7981///
7982/// where X represents padding elements.
7983pub type Mat<E> = Matrix<inner::DenseOwn<E>>;
7984
7985/// Heap allocated resizable column vector.
7986///
7987/// # Note
7988///
7989/// The memory layout of `Col` is guaranteed to be column-major, meaning that it has a row stride
7990/// of `1`.
7991pub type Col<E> = Matrix<inner::DenseColOwn<E>>;
7992
7993/// Heap allocated resizable row vector.
7994///
7995/// # Note
7996///
7997/// The memory layout of `Col` is guaranteed to be row-major, meaning that it has a column stride
7998/// of `1`.
7999pub type Row<E> = Matrix<inner::DenseRowOwn<E>>;
8000
8001#[repr(C)]
8002struct MatUnit<T: 'static> {
8003    raw: RawMatUnit<T>,
8004    nrows: usize,
8005    ncols: usize,
8006}
8007
8008impl<E: Entity> Clone for Mat<E> {
8009    fn clone(&self) -> Self {
8010        let this = self.as_ref();
8011        unsafe {
8012            Self::from_fn(self.nrows(), self.ncols(), |i, j| {
8013                E::faer_from_units(E::faer_deref(this.get_unchecked(i, j)))
8014            })
8015        }
8016    }
8017}
8018
8019impl<T> MatUnit<T> {
8020    #[cold]
8021    fn do_reserve_exact(&mut self, mut new_row_capacity: usize, mut new_col_capacity: usize) {
8022        new_row_capacity = self.raw.row_capacity.max(new_row_capacity);
8023        new_col_capacity = self.raw.col_capacity.max(new_col_capacity);
8024
8025        let new_ptr = if self.raw.row_capacity == new_row_capacity
8026            && self.raw.row_capacity != 0
8027            && self.raw.col_capacity != 0
8028        {
8029            // case 1:
8030            // we have enough row capacity, and we've already allocated memory.
8031            // use realloc to get extra column memory
8032
8033            use alloc::alloc::{handle_alloc_error, realloc, Layout};
8034
8035            // this shouldn't overflow since we already hold this many bytes
8036            let old_cap = self.raw.row_capacity * self.raw.col_capacity;
8037            let old_cap_bytes = old_cap * core::mem::size_of::<T>();
8038
8039            let new_cap = new_row_capacity
8040                .checked_mul(new_col_capacity)
8041                .unwrap_or_else(capacity_overflow);
8042            let new_cap_bytes = new_cap
8043                .checked_mul(core::mem::size_of::<T>())
8044                .unwrap_or_else(capacity_overflow);
8045
8046            if new_cap_bytes > isize::MAX as usize {
8047                capacity_overflow::<()>();
8048            }
8049
8050            // SAFETY: this shouldn't overflow since we already checked that it's valid during
8051            // allocation
8052            let old_layout =
8053                unsafe { Layout::from_size_align_unchecked(old_cap_bytes, align_for::<T>()) };
8054            let new_layout = Layout::from_size_align(new_cap_bytes, align_for::<T>())
8055                .ok()
8056                .unwrap_or_else(capacity_overflow);
8057
8058            // SAFETY:
8059            // * old_ptr is non null and is the return value of some previous call to alloc
8060            // * old_layout is the same layout that was used to provide the old allocation
8061            // * new_cap_bytes is non zero since new_row_capacity and new_col_capacity are larger
8062            // than self.raw.row_capacity and self.raw.col_capacity respectively, and the computed
8063            // product doesn't overflow.
8064            // * new_cap_bytes, when rounded up to the nearest multiple of the alignment does not
8065            // overflow, since we checked that we can create new_layout with it.
8066            unsafe {
8067                let old_ptr = self.raw.ptr.as_ptr();
8068                let new_ptr = realloc(old_ptr as *mut u8, old_layout, new_cap_bytes);
8069                if new_ptr.is_null() {
8070                    handle_alloc_error(new_layout);
8071                }
8072                new_ptr as *mut T
8073            }
8074        } else {
8075            // case 2:
8076            // use alloc and move stuff manually.
8077
8078            // allocate new memory region
8079            let new_ptr = {
8080                let m = ManuallyDrop::new(RawMatUnit::<T>::new(new_row_capacity, new_col_capacity));
8081                m.ptr.as_ptr()
8082            };
8083
8084            let old_ptr = self.raw.ptr.as_ptr();
8085
8086            // copy each column to new matrix
8087            for j in 0..self.ncols {
8088                // SAFETY:
8089                // * pointer offsets can't overflow since they're within an already allocated
8090                // memory region less than isize::MAX bytes in size.
8091                // * new and old allocation can't overlap, so copy_nonoverlapping is fine here.
8092                unsafe {
8093                    let old_ptr = old_ptr.add(j * self.raw.row_capacity);
8094                    let new_ptr = new_ptr.add(j * new_row_capacity);
8095                    core::ptr::copy_nonoverlapping(old_ptr, new_ptr, self.nrows);
8096                }
8097            }
8098
8099            // deallocate old matrix memory
8100            let _ = RawMatUnit::<T> {
8101                // SAFETY: this ptr was checked to be non null, or was acquired from a NonNull
8102                // pointer.
8103                ptr: unsafe { NonNull::new_unchecked(old_ptr) },
8104                row_capacity: self.raw.row_capacity,
8105                col_capacity: self.raw.col_capacity,
8106            };
8107
8108            new_ptr
8109        };
8110        self.raw.row_capacity = new_row_capacity;
8111        self.raw.col_capacity = new_col_capacity;
8112        self.raw.ptr = unsafe { NonNull::<T>::new_unchecked(new_ptr) };
8113    }
8114}
8115
8116impl<E: Entity> Drop for inner::DenseOwn<E> {
8117    fn drop(&mut self) {
8118        drop(RawMat::<E> {
8119            ptr: self.inner.ptr,
8120            row_capacity: self.row_capacity,
8121            col_capacity: self.col_capacity,
8122        });
8123    }
8124}
8125impl<E: Entity> Drop for inner::DenseColOwn<E> {
8126    fn drop(&mut self) {
8127        drop(RawMat::<E> {
8128            ptr: self.inner.ptr,
8129            row_capacity: self.row_capacity,
8130            col_capacity: 1,
8131        });
8132    }
8133}
8134impl<E: Entity> Drop for inner::DenseRowOwn<E> {
8135    fn drop(&mut self) {
8136        drop(RawMat::<E> {
8137            ptr: self.inner.ptr,
8138            row_capacity: self.col_capacity,
8139            col_capacity: 1,
8140        });
8141    }
8142}
8143
8144impl<E: Entity> Default for Mat<E> {
8145    #[inline]
8146    fn default() -> Self {
8147        Self::new()
8148    }
8149}
8150impl<E: Entity> Default for Col<E> {
8151    #[inline]
8152    fn default() -> Self {
8153        Self::new()
8154    }
8155}
8156impl<E: Entity> Default for Row<E> {
8157    #[inline]
8158    fn default() -> Self {
8159        Self::new()
8160    }
8161}
8162
8163impl<E: Entity> Col<E> {
8164    /// Returns an empty column of dimension `0`.
8165    #[inline]
8166    pub fn new() -> Self {
8167        Self {
8168            inner: inner::DenseColOwn {
8169                inner: VecOwnImpl {
8170                    ptr: into_copy::<E, _>(E::faer_map(E::UNIT, |()| {
8171                        NonNull::<E::Unit>::dangling()
8172                    })),
8173                    len: 0,
8174                },
8175                row_capacity: 0,
8176            },
8177        }
8178    }
8179
8180    /// Returns a new column vector with 0 rows, with enough capacity to hold a maximum of
8181    /// `row_capacity` rows columns without reallocating. If `row_capacity` is `0`,
8182    /// the function will not allocate.
8183    ///
8184    /// # Panics
8185    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
8186    #[inline]
8187    pub fn with_capacity(row_capacity: usize) -> Self {
8188        let raw = ManuallyDrop::new(RawMat::<E>::new(row_capacity, 1));
8189        Self {
8190            inner: inner::DenseColOwn {
8191                inner: VecOwnImpl {
8192                    ptr: raw.ptr,
8193                    len: 0,
8194                },
8195                row_capacity: raw.row_capacity,
8196            },
8197        }
8198    }
8199
8200    /// Returns a new matrix with number of rows `nrows`, filled with the provided function.
8201    ///
8202    /// # Panics
8203    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
8204    #[inline]
8205    pub fn from_fn(nrows: usize, f: impl FnMut(usize) -> E) -> Self {
8206        let mut this = Self::new();
8207        this.resize_with(nrows, f);
8208        this
8209    }
8210
8211    /// Returns a new matrix with number of rows `nrows`, filled with zeros.
8212    ///
8213    /// # Panics
8214    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
8215    #[inline]
8216    pub fn zeros(nrows: usize) -> Self
8217    where
8218        E: ComplexField,
8219    {
8220        Self::from_fn(nrows, |_| E::faer_zero())
8221    }
8222
8223    /// Returns the number of rows of the column.
8224    #[inline(always)]
8225    pub fn nrows(&self) -> usize {
8226        self.inner.inner.len
8227    }
8228    /// Returns the number of columns of the column. This is always equal to `1`.
8229    #[inline(always)]
8230    pub fn ncols(&self) -> usize {
8231        1
8232    }
8233
8234    /// Set the dimensions of the matrix.
8235    ///
8236    /// # Safety
8237    /// The behavior is undefined if any of the following conditions are violated:
8238    /// * `nrows < self.row_capacity()`.
8239    /// * The elements that were previously out of bounds but are now in bounds must be
8240    /// initialized.
8241    #[inline]
8242    pub unsafe fn set_nrows(&mut self, nrows: usize) {
8243        self.inner.inner.len = nrows;
8244    }
8245
8246    /// Returns a pointer to the data of the matrix.
8247    #[inline]
8248    pub fn as_ptr(&self) -> GroupFor<E, *const E::Unit> {
8249        E::faer_map(from_copy::<E, _>(self.inner.inner.ptr), |ptr| {
8250            ptr.as_ptr() as *const E::Unit
8251        })
8252    }
8253
8254    /// Returns a mutable pointer to the data of the matrix.
8255    #[inline]
8256    pub fn as_ptr_mut(&mut self) -> GroupFor<E, *mut E::Unit> {
8257        E::faer_map(from_copy::<E, _>(self.inner.inner.ptr), |ptr| ptr.as_ptr())
8258    }
8259
8260    /// Returns the row capacity, that is, the number of rows that the matrix is able to hold
8261    /// without needing to reallocate, excluding column insertions.
8262    #[inline]
8263    pub fn row_capacity(&self) -> usize {
8264        self.inner.row_capacity
8265    }
8266
8267    /// Returns the offset between the first elements of two successive rows in the matrix.
8268    /// Always returns `1` since the matrix is column major.
8269    #[inline]
8270    pub fn row_stride(&self) -> isize {
8271        1
8272    }
8273
8274    #[cold]
8275    fn do_reserve_exact(&mut self, mut new_row_capacity: usize) {
8276        if is_vectorizable::<E::Unit>() {
8277            let align_factor = align_for::<E::Unit>() / core::mem::size_of::<E::Unit>();
8278            new_row_capacity = new_row_capacity
8279                .msrv_checked_next_multiple_of(align_factor)
8280                .unwrap();
8281        }
8282
8283        let nrows = self.inner.inner.len;
8284        let old_row_capacity = self.inner.row_capacity;
8285
8286        let mut this = ManuallyDrop::new(core::mem::take(self));
8287        {
8288            let mut this_group =
8289                E::faer_map(from_copy::<E, _>(this.inner.inner.ptr), |ptr| MatUnit {
8290                    raw: RawMatUnit {
8291                        ptr,
8292                        row_capacity: old_row_capacity,
8293                        col_capacity: 1,
8294                    },
8295                    nrows,
8296                    ncols: 1,
8297                });
8298
8299            E::faer_map(E::faer_as_mut(&mut this_group), |mat_unit| {
8300                mat_unit.do_reserve_exact(new_row_capacity, 1);
8301            });
8302
8303            let this_group = E::faer_map(this_group, ManuallyDrop::new);
8304            this.inner.inner.ptr =
8305                into_copy::<E, _>(E::faer_map(this_group, |mat_unit| mat_unit.raw.ptr));
8306            this.inner.row_capacity = new_row_capacity;
8307        }
8308        *self = ManuallyDrop::into_inner(this);
8309    }
8310
8311    /// Reserves the minimum capacity for `row_capacity` rows without reallocating. Does nothing if
8312    /// the capacity is already sufficient.
8313    ///
8314    /// # Panics
8315    /// The function panics if the new total capacity in bytes exceeds `isize::MAX`.
8316    #[inline]
8317    pub fn reserve_exact(&mut self, row_capacity: usize) {
8318        if self.row_capacity() >= row_capacity {
8319            // do nothing
8320        } else if core::mem::size_of::<E::Unit>() == 0 {
8321            self.inner.row_capacity = self.row_capacity().max(row_capacity);
8322        } else {
8323            self.do_reserve_exact(row_capacity);
8324        }
8325    }
8326
8327    unsafe fn insert_block_with<F: FnMut(usize) -> E>(
8328        &mut self,
8329        f: &mut F,
8330        row_start: usize,
8331        row_end: usize,
8332    ) {
8333        debug_assert!(row_start <= row_end);
8334
8335        let ptr = self.as_ptr_mut();
8336
8337        for i in row_start..row_end {
8338            // SAFETY:
8339            // * pointer to element at index (i, j), which is within the
8340            // allocation since we reserved enough space
8341            // * writing to this memory region is sound since it is properly
8342            // aligned and valid for writes
8343            let ptr_ij = E::faer_map(E::faer_copy(&ptr), |ptr| ptr.add(i));
8344            let value = E::faer_into_units(f(i));
8345
8346            E::faer_map(E::faer_zip(ptr_ij, value), |(ptr_ij, value)| {
8347                core::ptr::write(ptr_ij, value)
8348            });
8349        }
8350    }
8351
8352    fn erase_last_rows(&mut self, new_nrows: usize) {
8353        let old_nrows = self.nrows();
8354        debug_assert!(new_nrows <= old_nrows);
8355        self.inner.inner.len = new_nrows;
8356    }
8357
8358    unsafe fn insert_last_rows_with<F: FnMut(usize) -> E>(&mut self, f: &mut F, new_nrows: usize) {
8359        let old_nrows = self.nrows();
8360
8361        debug_assert!(new_nrows > old_nrows);
8362
8363        self.insert_block_with(f, old_nrows, new_nrows);
8364        self.inner.inner.len = new_nrows;
8365    }
8366
8367    /// Resizes the vector in-place so that the new number of rows is `new_nrows`.
8368    /// New elements are created with the given function `f`, so that elements at index `i`
8369    /// are created by calling `f(i)`.
8370    pub fn resize_with(&mut self, new_nrows: usize, f: impl FnMut(usize) -> E) {
8371        let mut f = f;
8372        let old_nrows = self.nrows();
8373
8374        if new_nrows <= old_nrows {
8375            self.erase_last_rows(new_nrows);
8376        } else {
8377            self.reserve_exact(new_nrows);
8378            unsafe {
8379                self.insert_last_rows_with(&mut f, new_nrows);
8380            }
8381        }
8382    }
8383
8384    /// Returns a reference to a slice over the column.
8385    #[inline]
8386    #[track_caller]
8387    pub fn as_slice(&self) -> GroupFor<E, &[E::Unit]> {
8388        let nrows = self.nrows();
8389        let ptr = self.as_ref().as_ptr();
8390        E::faer_map(
8391            ptr,
8392            #[inline(always)]
8393            |ptr| unsafe { core::slice::from_raw_parts(ptr, nrows) },
8394        )
8395    }
8396
8397    /// Returns a mutable reference to a slice over the column.
8398    #[inline]
8399    #[track_caller]
8400    pub fn as_slice_mut(&mut self) -> GroupFor<E, &mut [E::Unit]> {
8401        let nrows = self.nrows();
8402        let ptr = self.as_ptr_mut();
8403        E::faer_map(
8404            ptr,
8405            #[inline(always)]
8406            |ptr| unsafe { core::slice::from_raw_parts_mut(ptr, nrows) },
8407        )
8408    }
8409
8410    /// Returns a view over the vector.
8411    #[inline]
8412    pub fn as_ref(&self) -> ColRef<'_, E> {
8413        unsafe { col::from_raw_parts(self.as_ptr(), self.nrows(), 1) }
8414    }
8415
8416    /// Returns a mutable view over the vector.
8417    #[inline]
8418    pub fn as_mut(&mut self) -> ColMut<'_, E> {
8419        unsafe { col::from_raw_parts_mut(self.as_ptr_mut(), self.nrows(), 1) }
8420    }
8421
8422    /// Returns references to the element at the given index, or submatrices if `row` is a range.
8423    ///
8424    /// # Note
8425    /// The values pointed to by the references are expected to be initialized, even if the
8426    /// pointed-to value is not read, otherwise the behavior is undefined.
8427    ///
8428    /// # Safety
8429    /// The behavior is undefined if any of the following conditions are violated:
8430    /// * `row` must be contained in `[0, self.nrows())`.
8431    #[inline]
8432    pub unsafe fn get_unchecked<RowRange>(
8433        &self,
8434        row: RowRange,
8435    ) -> <ColRef<'_, E> as ColIndex<RowRange>>::Target
8436    where
8437        for<'a> ColRef<'a, E>: ColIndex<RowRange>,
8438    {
8439        self.as_ref().get_unchecked(row)
8440    }
8441
8442    /// Returns references to the element at the given index, or submatrices if `row` is a range,
8443    /// with bound checks.
8444    ///
8445    /// # Note
8446    /// The values pointed to by the references are expected to be initialized, even if the
8447    /// pointed-to value is not read, otherwise the behavior is undefined.
8448    ///
8449    /// # Panics
8450    /// The function panics if any of the following conditions are violated:
8451    /// * `row` must be contained in `[0, self.nrows())`.
8452    #[inline]
8453    pub fn get<RowRange>(&self, row: RowRange) -> <ColRef<'_, E> as ColIndex<RowRange>>::Target
8454    where
8455        for<'a> ColRef<'a, E>: ColIndex<RowRange>,
8456    {
8457        self.as_ref().get(row)
8458    }
8459
8460    /// Returns mutable references to the element at the given index, or submatrices if
8461    /// `row` is a range.
8462    ///
8463    /// # Note
8464    /// The values pointed to by the references are expected to be initialized, even if the
8465    /// pointed-to value is not read, otherwise the behavior is undefined.
8466    ///
8467    /// # Safety
8468    /// The behavior is undefined if any of the following conditions are violated:
8469    /// * `row` must be contained in `[0, self.nrows())`.
8470    #[inline]
8471    pub unsafe fn get_mut_unchecked<RowRange>(
8472        &mut self,
8473        row: RowRange,
8474    ) -> <ColMut<'_, E> as ColIndex<RowRange>>::Target
8475    where
8476        for<'a> ColMut<'a, E>: ColIndex<RowRange>,
8477    {
8478        self.as_mut().get_unchecked_mut(row)
8479    }
8480
8481    /// Returns mutable references to the element at the given index, or submatrices if
8482    /// `row` is a range, with bound checks.
8483    ///
8484    /// # Note
8485    /// The values pointed to by the references are expected to be initialized, even if the
8486    /// pointed-to value is not read, otherwise the behavior is undefined.
8487    ///
8488    /// # Panics
8489    /// The function panics if any of the following conditions are violated:
8490    /// * `row` must be contained in `[0, self.nrows())`.
8491    #[inline]
8492    pub fn get_mut<RowRange>(
8493        &mut self,
8494        row: RowRange,
8495    ) -> <ColMut<'_, E> as ColIndex<RowRange>>::Target
8496    where
8497        for<'a> ColMut<'a, E>: ColIndex<RowRange>,
8498    {
8499        self.as_mut().get_mut(row)
8500    }
8501
8502    /// Reads the value of the element at the given index.
8503    ///
8504    /// # Safety
8505    /// The behavior is undefined if any of the following conditions are violated:
8506    /// * `row < self.nrows()`.
8507    #[inline(always)]
8508    #[track_caller]
8509    pub unsafe fn read_unchecked(&self, row: usize) -> E {
8510        self.as_ref().read_unchecked(row)
8511    }
8512
8513    /// Reads the value of the element at the given index, with bound checks.
8514    ///
8515    /// # Panics
8516    /// The function panics if any of the following conditions are violated:
8517    /// * `row < self.nrows()`.
8518    #[inline(always)]
8519    #[track_caller]
8520    pub fn read(&self, row: usize) -> E {
8521        self.as_ref().read(row)
8522    }
8523
8524    /// Writes the value to the element at the given index.
8525    ///
8526    /// # Safety
8527    /// The behavior is undefined if any of the following conditions are violated:
8528    /// * `row < self.nrows()`.
8529    #[inline(always)]
8530    #[track_caller]
8531    pub unsafe fn write_unchecked(&mut self, row: usize, value: E) {
8532        self.as_mut().write_unchecked(row, value);
8533    }
8534
8535    /// Writes the value to the element at the given index, with bound checks.
8536    ///
8537    /// # Panics
8538    /// The function panics if any of the following conditions are violated:
8539    /// * `row < self.nrows()`.
8540    #[inline(always)]
8541    #[track_caller]
8542    pub fn write(&mut self, row: usize, value: E) {
8543        self.as_mut().write(row, value);
8544    }
8545
8546    /// Copies the values from `other` into `self`.
8547    #[inline(always)]
8548    #[track_caller]
8549    pub fn copy_from(&mut self, other: impl AsColRef<E>) {
8550        #[track_caller]
8551        #[inline(always)]
8552        fn implementation<E: Entity>(this: &mut Col<E>, other: ColRef<'_, E>) {
8553            let mut mat = Col::<E>::new();
8554            mat.resize_with(
8555                other.nrows(),
8556                #[inline(always)]
8557                |row| unsafe { other.read_unchecked(row) },
8558            );
8559            *this = mat;
8560        }
8561        implementation(self, other.as_col_ref());
8562    }
8563
8564    /// Fills the elements of `self` with zeros.
8565    #[inline(always)]
8566    #[track_caller]
8567    pub fn fill_zero(&mut self)
8568    where
8569        E: ComplexField,
8570    {
8571        self.as_mut().fill_zero()
8572    }
8573
8574    /// Fills the elements of `self` with copies of `constant`.
8575    #[inline(always)]
8576    #[track_caller]
8577    pub fn fill(&mut self, constant: E) {
8578        self.as_mut().fill(constant)
8579    }
8580
8581    /// Returns a view over the transpose of `self`.
8582    #[inline]
8583    pub fn transpose(&self) -> RowRef<'_, E> {
8584        self.as_ref().transpose()
8585    }
8586
8587    /// Returns a view over the conjugate of `self`.
8588    #[inline]
8589    pub fn conjugate(&self) -> ColRef<'_, E::Conj>
8590    where
8591        E: Conjugate,
8592    {
8593        self.as_ref().conjugate()
8594    }
8595
8596    /// Returns a view over the conjugate transpose of `self`.
8597    #[inline]
8598    pub fn adjoint(&self) -> RowRef<'_, E::Conj>
8599    where
8600        E: Conjugate,
8601    {
8602        self.as_ref().adjoint()
8603    }
8604
8605    /// Returns an owning [`Col`] of the data
8606    #[inline]
8607    pub fn to_owned(&self) -> Col<E::Canonical>
8608    where
8609        E: Conjugate,
8610    {
8611        self.as_ref().to_owned()
8612    }
8613
8614    /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
8615    #[inline]
8616    pub fn has_nan(&self) -> bool
8617    where
8618        E: ComplexField,
8619    {
8620        self.as_ref().has_nan()
8621    }
8622
8623    /// Returns `true` if all of the elements are finite, otherwise returns `false`.
8624    #[inline]
8625    pub fn is_all_finite(&self) -> bool
8626    where
8627        E: ComplexField,
8628    {
8629        self.as_ref().is_all_finite()
8630    }
8631
8632    /// Returns the maximum norm of `self`.
8633    #[inline]
8634    pub fn norm_max(&self) -> E::Real
8635    where
8636        E: ComplexField,
8637    {
8638        norm_max((*self).as_ref().as_2d())
8639    }
8640    /// Returns the L2 norm of `self`.
8641    #[inline]
8642    pub fn norm_l2(&self) -> E::Real
8643    where
8644        E: ComplexField,
8645    {
8646        norm_l2((*self).as_ref().as_2d())
8647    }
8648
8649    /// Returns the sum of `self`.
8650    #[inline]
8651    pub fn sum(&self) -> E
8652    where
8653        E: ComplexField,
8654    {
8655        sum((*self).as_ref().as_2d())
8656    }
8657
8658    /// Kroneckor product of `self` and `rhs`.
8659    ///
8660    /// This is an allocating operation; see [`kron`] for the
8661    /// allocation-free version or more info in general.
8662    #[inline]
8663    #[track_caller]
8664    pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
8665    where
8666        E: ComplexField,
8667    {
8668        self.as_2d_ref().kron(rhs)
8669    }
8670}
8671
8672impl<E: Entity> Row<E> {
8673    /// Returns an empty row of dimension `0`.
8674    #[inline]
8675    pub fn new() -> Self {
8676        Self {
8677            inner: inner::DenseRowOwn {
8678                inner: VecOwnImpl {
8679                    ptr: into_copy::<E, _>(E::faer_map(E::UNIT, |()| {
8680                        NonNull::<E::Unit>::dangling()
8681                    })),
8682                    len: 0,
8683                },
8684                col_capacity: 0,
8685            },
8686        }
8687    }
8688
8689    /// Returns a new column vector with 0 columns, with enough capacity to hold a maximum of
8690    /// `col_capacity` columnss columns without reallocating. If `col_capacity` is `0`,
8691    /// the function will not allocate.
8692    ///
8693    /// # Panics
8694    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
8695    #[inline]
8696    pub fn with_capacity(col_capacity: usize) -> Self {
8697        let raw = ManuallyDrop::new(RawMat::<E>::new(col_capacity, 1));
8698        Self {
8699            inner: inner::DenseRowOwn {
8700                inner: VecOwnImpl {
8701                    ptr: raw.ptr,
8702                    len: 0,
8703                },
8704                col_capacity: raw.row_capacity,
8705            },
8706        }
8707    }
8708
8709    /// Returns a new matrix with number of columns `ncols`, filled with the provided function.
8710    ///
8711    /// # Panics
8712    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
8713    #[inline]
8714    pub fn from_fn(ncols: usize, f: impl FnMut(usize) -> E) -> Self {
8715        let mut this = Self::new();
8716        this.resize_with(ncols, f);
8717        this
8718    }
8719
8720    /// Returns a new matrix with number of columns `ncols`, filled with zeros.
8721    ///
8722    /// # Panics
8723    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
8724    #[inline]
8725    pub fn zeros(ncols: usize) -> Self
8726    where
8727        E: ComplexField,
8728    {
8729        Self::from_fn(ncols, |_| E::faer_zero())
8730    }
8731
8732    /// Returns the number of rows of the row. This is always equal to `1`.
8733    #[inline(always)]
8734    pub fn nrows(&self) -> usize {
8735        1
8736    }
8737    /// Returns the number of columns of the row.
8738    #[inline(always)]
8739    pub fn ncols(&self) -> usize {
8740        self.inner.inner.len
8741    }
8742
8743    /// Set the dimensions of the matrix.
8744    ///
8745    /// # Safety
8746    /// The behavior is undefined if any of the following conditions are violated:
8747    /// * `ncols < self.col_capacity()`.
8748    /// * The elements that were previously out of bounds but are now in bounds must be
8749    /// initialized.
8750    #[inline]
8751    pub unsafe fn set_ncols(&mut self, ncols: usize) {
8752        self.inner.inner.len = ncols;
8753    }
8754
8755    /// Returns a pointer to the data of the matrix.
8756    #[inline]
8757    pub fn as_ptr(&self) -> GroupFor<E, *const E::Unit> {
8758        E::faer_map(from_copy::<E, _>(self.inner.inner.ptr), |ptr| {
8759            ptr.as_ptr() as *const E::Unit
8760        })
8761    }
8762
8763    /// Returns a mutable pointer to the data of the matrix.
8764    #[inline]
8765    pub fn as_ptr_mut(&mut self) -> GroupFor<E, *mut E::Unit> {
8766        E::faer_map(from_copy::<E, _>(self.inner.inner.ptr), |ptr| ptr.as_ptr())
8767    }
8768
8769    /// Returns the col capacity, that is, the number of cols that the matrix is able to hold
8770    /// without needing to reallocate, excluding column insertions.
8771    #[inline]
8772    pub fn col_capacity(&self) -> usize {
8773        self.inner.col_capacity
8774    }
8775
8776    /// Returns the offset between the first elements of two successive columns in the matrix.
8777    /// Always returns `1` since the matrix is column major.
8778    #[inline]
8779    pub fn col_stride(&self) -> isize {
8780        1
8781    }
8782
8783    #[cold]
8784    fn do_reserve_exact(&mut self, mut new_col_capacity: usize) {
8785        if is_vectorizable::<E::Unit>() {
8786            let align_factor = align_for::<E::Unit>() / core::mem::size_of::<E::Unit>();
8787            new_col_capacity = new_col_capacity
8788                .msrv_checked_next_multiple_of(align_factor)
8789                .unwrap();
8790        }
8791
8792        let ncols = self.inner.inner.len;
8793        let old_col_capacity = self.inner.col_capacity;
8794
8795        let mut this = ManuallyDrop::new(core::mem::take(self));
8796        {
8797            let mut this_group =
8798                E::faer_map(from_copy::<E, _>(this.inner.inner.ptr), |ptr| MatUnit {
8799                    raw: RawMatUnit {
8800                        ptr,
8801                        row_capacity: old_col_capacity,
8802                        col_capacity: 1,
8803                    },
8804                    ncols,
8805                    nrows: 1,
8806                });
8807
8808            E::faer_map(E::faer_as_mut(&mut this_group), |mat_unit| {
8809                mat_unit.do_reserve_exact(new_col_capacity, 1);
8810            });
8811
8812            let this_group = E::faer_map(this_group, ManuallyDrop::new);
8813            this.inner.inner.ptr =
8814                into_copy::<E, _>(E::faer_map(this_group, |mat_unit| mat_unit.raw.ptr));
8815            this.inner.col_capacity = new_col_capacity;
8816        }
8817        *self = ManuallyDrop::into_inner(this);
8818    }
8819
8820    /// Reserves the minimum capacity for `col_capacity` columns without reallocating. Does nothing
8821    /// if the capacity is already sufficient.
8822    ///
8823    /// # Panics
8824    /// The function panics if the new total capacity in bytes exceeds `isize::MAX`.
8825    #[inline]
8826    pub fn reserve_exact(&mut self, col_capacity: usize) {
8827        if self.col_capacity() >= col_capacity {
8828            // do nothing
8829        } else if core::mem::size_of::<E::Unit>() == 0 {
8830            self.inner.col_capacity = self.col_capacity().max(col_capacity);
8831        } else {
8832            self.do_reserve_exact(col_capacity);
8833        }
8834    }
8835
8836    unsafe fn insert_block_with<F: FnMut(usize) -> E>(
8837        &mut self,
8838        f: &mut F,
8839        col_start: usize,
8840        col_end: usize,
8841    ) {
8842        debug_assert!(col_start <= col_end);
8843
8844        let ptr = self.as_ptr_mut();
8845
8846        for j in col_start..col_end {
8847            // SAFETY:
8848            // * pointer to element at index (i, j), which is within the
8849            // allocation since we reserved enough space
8850            // * writing to this memory region is sound since it is properly
8851            // aligned and valid for writes
8852            let ptr_ij = E::faer_map(E::faer_copy(&ptr), |ptr| ptr.add(j));
8853            let value = E::faer_into_units(f(j));
8854
8855            E::faer_map(E::faer_zip(ptr_ij, value), |(ptr_ij, value)| {
8856                core::ptr::write(ptr_ij, value)
8857            });
8858        }
8859    }
8860
8861    fn erase_last_cols(&mut self, new_ncols: usize) {
8862        let old_ncols = self.ncols();
8863        debug_assert!(new_ncols <= old_ncols);
8864        self.inner.inner.len = new_ncols;
8865    }
8866
8867    unsafe fn insert_last_cols_with<F: FnMut(usize) -> E>(&mut self, f: &mut F, new_ncols: usize) {
8868        let old_ncols = self.ncols();
8869
8870        debug_assert!(new_ncols > old_ncols);
8871
8872        self.insert_block_with(f, old_ncols, new_ncols);
8873        self.inner.inner.len = new_ncols;
8874    }
8875
8876    /// Resizes the vector in-place so that the new number of columns is `new_ncols`.
8877    /// New elements are created with the given function `f`, so that elements at index `i`
8878    /// are created by calling `f(i)`.
8879    pub fn resize_with(&mut self, new_ncols: usize, f: impl FnMut(usize) -> E) {
8880        let mut f = f;
8881        let old_ncols = self.ncols();
8882
8883        if new_ncols <= old_ncols {
8884            self.erase_last_cols(new_ncols);
8885        } else {
8886            self.reserve_exact(new_ncols);
8887            unsafe {
8888                self.insert_last_cols_with(&mut f, new_ncols);
8889            }
8890        }
8891    }
8892
8893    /// Returns a reference to a slice over the row.
8894    #[inline]
8895    #[track_caller]
8896    pub fn as_slice(&self) -> GroupFor<E, &[E::Unit]> {
8897        let ncols = self.ncols();
8898        let ptr = self.as_ref().as_ptr();
8899        E::faer_map(
8900            ptr,
8901            #[inline(always)]
8902            |ptr| unsafe { core::slice::from_raw_parts(ptr, ncols) },
8903        )
8904    }
8905
8906    /// Returns a mutable reference to a slice over the row.
8907    #[inline]
8908    #[track_caller]
8909    pub fn as_slice_mut(&mut self) -> GroupFor<E, &mut [E::Unit]> {
8910        let ncols = self.ncols();
8911        let ptr = self.as_ptr_mut();
8912        E::faer_map(
8913            ptr,
8914            #[inline(always)]
8915            |ptr| unsafe { core::slice::from_raw_parts_mut(ptr, ncols) },
8916        )
8917    }
8918
8919    /// Returns a view over the vector.
8920    #[inline]
8921    pub fn as_ref(&self) -> RowRef<'_, E> {
8922        unsafe { row::from_raw_parts(self.as_ptr(), self.ncols(), 1) }
8923    }
8924
8925    /// Returns a mutable view over the vector.
8926    #[inline]
8927    pub fn as_mut(&mut self) -> RowMut<'_, E> {
8928        unsafe { row::from_raw_parts_mut(self.as_ptr_mut(), self.ncols(), 1) }
8929    }
8930
8931    /// Returns references to the element at the given index, or submatrices if `col` is a range.
8932    ///
8933    /// # Note
8934    /// The values pointed to by the references are expected to be initialized, even if the
8935    /// pointed-to value is not read, otherwise the behavior is undefined.
8936    ///
8937    /// # Safety
8938    /// The behavior is undefined if any of the following conditions are violated:
8939    /// * `col` must be contained in `[0, self.ncols())`.
8940    #[inline]
8941    pub unsafe fn get_unchecked<ColRange>(
8942        &self,
8943        col: ColRange,
8944    ) -> <RowRef<'_, E> as RowIndex<ColRange>>::Target
8945    where
8946        for<'a> RowRef<'a, E>: RowIndex<ColRange>,
8947    {
8948        self.as_ref().get_unchecked(col)
8949    }
8950
8951    /// Returns references to the element at the given index, or submatrices if `col` is a range,
8952    /// with bound checks.
8953    ///
8954    /// # Note
8955    /// The values pointed to by the references are expected to be initialized, even if the
8956    /// pointed-to value is not read, otherwise the behavior is undefined.
8957    ///
8958    /// # Panics
8959    /// The function panics if any of the following conditions are violated:
8960    /// * `col` must be contained in `[0, self.ncols())`.
8961    #[inline]
8962    pub fn get<ColRange>(&self, col: ColRange) -> <RowRef<'_, E> as RowIndex<ColRange>>::Target
8963    where
8964        for<'a> RowRef<'a, E>: RowIndex<ColRange>,
8965    {
8966        self.as_ref().get(col)
8967    }
8968
8969    /// Returns mutable references to the element at the given index, or submatrices if
8970    /// `col` is a range.
8971    ///
8972    /// # Note
8973    /// The values pointed to by the references are expected to be initialized, even if the
8974    /// pointed-to value is not read, otherwise the behavior is undefined.
8975    ///
8976    /// # Safety
8977    /// The behavior is undefined if any of the following conditions are violated:
8978    /// * `col` must be contained in `[0, self.ncols())`.
8979    #[inline]
8980    pub unsafe fn get_mut_unchecked<ColRange>(
8981        &mut self,
8982        col: ColRange,
8983    ) -> <RowMut<'_, E> as RowIndex<ColRange>>::Target
8984    where
8985        for<'a> RowMut<'a, E>: RowIndex<ColRange>,
8986    {
8987        self.as_mut().get_mut_unchecked(col)
8988    }
8989
8990    /// Returns mutable references to the element at the given index, or submatrices if
8991    /// `col` is a range, with bound checks.
8992    ///
8993    /// # Note
8994    /// The values pointed to by the references are expected to be initialized, even if the
8995    /// pointed-to value is not read, otherwise the behavior is undefined.
8996    ///
8997    /// # Panics
8998    /// The function panics if any of the following conditions are violated:
8999    /// * `col` must be contained in `[0, self.ncols())`.
9000    #[inline]
9001    pub fn get_mut<ColRange>(
9002        &mut self,
9003        col: ColRange,
9004    ) -> <RowMut<'_, E> as RowIndex<ColRange>>::Target
9005    where
9006        for<'a> RowMut<'a, E>: RowIndex<ColRange>,
9007    {
9008        self.as_mut().get_mut(col)
9009    }
9010
9011    /// Reads the value of the element at the given index.
9012    ///
9013    /// # Safety
9014    /// The behavior is undefined if any of the following conditions are violated:
9015    /// * `col < self.ncols()`.
9016    #[inline(always)]
9017    #[track_caller]
9018    pub unsafe fn read_unchecked(&self, col: usize) -> E {
9019        self.as_ref().read_unchecked(col)
9020    }
9021
9022    /// Reads the value of the element at the given index, with bound checks.
9023    ///
9024    /// # Panics
9025    /// The function panics if any of the following conditions are violated:
9026    /// * `col < self.ncols()`.
9027    #[inline(always)]
9028    #[track_caller]
9029    pub fn read(&self, col: usize) -> E {
9030        self.as_ref().read(col)
9031    }
9032
9033    /// Writes the value to the element at the given index.
9034    ///
9035    /// # Safety
9036    /// The behavior is undefined if any of the following conditions are violated:
9037    /// * `col < self.ncols()`.
9038    #[inline(always)]
9039    #[track_caller]
9040    pub unsafe fn write_unchecked(&mut self, col: usize, value: E) {
9041        self.as_mut().write_unchecked(col, value);
9042    }
9043
9044    /// Writes the value to the element at the given index, with bound checks.
9045    ///
9046    /// # Panics
9047    /// The function panics if any of the following conditions are violated:
9048    /// * `col < self.ncols()`.
9049    #[inline(always)]
9050    #[track_caller]
9051    pub fn write(&mut self, col: usize, value: E) {
9052        self.as_mut().write(col, value);
9053    }
9054
9055    /// Copies the values from `other` into `self`.
9056    #[inline(always)]
9057    #[track_caller]
9058    pub fn copy_from(&mut self, other: impl AsRowRef<E>) {
9059        #[track_caller]
9060        #[inline(always)]
9061        fn implementation<E: Entity>(this: &mut Row<E>, other: RowRef<'_, E>) {
9062            let mut mat = Row::<E>::new();
9063            mat.resize_with(
9064                other.nrows(),
9065                #[inline(always)]
9066                |row| unsafe { other.read_unchecked(row) },
9067            );
9068            *this = mat;
9069        }
9070        implementation(self, other.as_row_ref());
9071    }
9072
9073    /// Fills the elements of `self` with zeros.
9074    #[inline(always)]
9075    #[track_caller]
9076    pub fn fill_zero(&mut self)
9077    where
9078        E: ComplexField,
9079    {
9080        self.as_mut().fill_zero()
9081    }
9082
9083    /// Fills the elements of `self` with copies of `constant`.
9084    #[inline(always)]
9085    #[track_caller]
9086    pub fn fill(&mut self, constant: E) {
9087        self.as_mut().fill(constant)
9088    }
9089
9090    /// Returns a view over the transpose of `self`.
9091    #[inline]
9092    pub fn transpose(&self) -> ColRef<'_, E> {
9093        self.as_ref().transpose()
9094    }
9095
9096    /// Returns a view over the conjugate of `self`.
9097    #[inline]
9098    pub fn conjugate(&self) -> RowRef<'_, E::Conj>
9099    where
9100        E: Conjugate,
9101    {
9102        self.as_ref().conjugate()
9103    }
9104
9105    /// Returns a view over the conjugate transpose of `self`.
9106    #[inline]
9107    pub fn adjoint(&self) -> ColRef<'_, E::Conj>
9108    where
9109        E: Conjugate,
9110    {
9111        self.as_ref().adjoint()
9112    }
9113
9114    /// Returns an owning [`Row`] of the data
9115    #[inline]
9116    pub fn to_owned(&self) -> Row<E::Canonical>
9117    where
9118        E: Conjugate,
9119    {
9120        self.as_ref().to_owned()
9121    }
9122
9123    /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
9124    #[inline]
9125    pub fn has_nan(&self) -> bool
9126    where
9127        E: ComplexField,
9128    {
9129        self.as_ref().has_nan()
9130    }
9131
9132    /// Returns `true` if all of the elements are finite, otherwise returns `false`.
9133    #[inline]
9134    pub fn is_all_finite(&self) -> bool
9135    where
9136        E: ComplexField,
9137    {
9138        self.as_ref().is_all_finite()
9139    }
9140
9141    /// Returns the maximum norm of `self`.
9142    #[inline]
9143    pub fn norm_max(&self) -> E::Real
9144    where
9145        E: ComplexField,
9146    {
9147        norm_max((*self).as_ref().as_2d())
9148    }
9149    /// Returns the L2 norm of `self`.
9150    #[inline]
9151    pub fn norm_l2(&self) -> E::Real
9152    where
9153        E: ComplexField,
9154    {
9155        norm_l2((*self).as_ref().as_2d())
9156    }
9157
9158    /// Returns the sum of `self`.
9159    #[inline]
9160    pub fn sum(&self) -> E
9161    where
9162        E: ComplexField,
9163    {
9164        sum((*self).as_ref().as_2d())
9165    }
9166
9167    /// Kroneckor product of `self` and `rhs`.
9168    ///
9169    /// This is an allocating operation; see [`kron`] for the
9170    /// allocation-free version or more info in general.
9171    #[inline]
9172    #[track_caller]
9173    pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
9174    where
9175        E: ComplexField,
9176    {
9177        self.as_2d_ref().kron(rhs)
9178    }
9179}
9180
9181impl<E: Entity> Mat<E> {
9182    /// Returns an empty matrix of dimension `0×0`.
9183    #[inline]
9184    pub fn new() -> Self {
9185        Self {
9186            inner: inner::DenseOwn {
9187                inner: MatOwnImpl {
9188                    ptr: into_copy::<E, _>(E::faer_map(E::UNIT, |()| {
9189                        NonNull::<E::Unit>::dangling()
9190                    })),
9191                    nrows: 0,
9192                    ncols: 0,
9193                },
9194                row_capacity: 0,
9195                col_capacity: 0,
9196            },
9197        }
9198    }
9199
9200    /// Returns a new matrix with dimensions `(0, 0)`, with enough capacity to hold a maximum of
9201    /// `row_capacity` rows and `col_capacity` columns without reallocating. If either is `0`,
9202    /// the matrix will not allocate.
9203    ///
9204    /// # Panics
9205    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
9206    #[inline]
9207    pub fn with_capacity(row_capacity: usize, col_capacity: usize) -> Self {
9208        let raw = ManuallyDrop::new(RawMat::<E>::new(row_capacity, col_capacity));
9209        Self {
9210            inner: inner::DenseOwn {
9211                inner: MatOwnImpl {
9212                    ptr: raw.ptr,
9213                    nrows: 0,
9214                    ncols: 0,
9215                },
9216                row_capacity: raw.row_capacity,
9217                col_capacity: raw.col_capacity,
9218            },
9219        }
9220    }
9221
9222    /// Returns a new matrix with dimensions `(nrows, ncols)`, filled with the provided function.
9223    ///
9224    /// # Panics
9225    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
9226    #[inline]
9227    pub fn from_fn(nrows: usize, ncols: usize, f: impl FnMut(usize, usize) -> E) -> Self {
9228        let mut this = Self::new();
9229        this.resize_with(nrows, ncols, f);
9230        this
9231    }
9232
9233    /// Returns a new matrix with dimensions `(nrows, ncols)`, filled with zeros.
9234    ///
9235    /// # Panics
9236    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
9237    #[inline]
9238    pub fn zeros(nrows: usize, ncols: usize) -> Self
9239    where
9240        E: ComplexField,
9241    {
9242        Self::from_fn(nrows, ncols, |_, _| E::faer_zero())
9243    }
9244
9245    /// Returns a new matrix with dimensions `(nrows, ncols)`, filled with zeros, except the main
9246    /// diagonal which is filled with ones.
9247    ///
9248    /// # Panics
9249    /// The function panics if the total capacity in bytes exceeds `isize::MAX`.
9250    #[inline]
9251    pub fn identity(nrows: usize, ncols: usize) -> Self
9252    where
9253        E: ComplexField,
9254    {
9255        let mut matrix = Self::zeros(nrows, ncols);
9256        matrix
9257            .as_mut()
9258            .diagonal_mut()
9259            .column_vector_mut()
9260            .fill(E::faer_one());
9261        matrix
9262    }
9263
9264    /// Returns the number of rows of the matrix.
9265    #[inline(always)]
9266    pub fn nrows(&self) -> usize {
9267        self.inner.inner.nrows
9268    }
9269    /// Returns the number of columns of the matrix.
9270    #[inline(always)]
9271    pub fn ncols(&self) -> usize {
9272        self.inner.inner.ncols
9273    }
9274
9275    /// Set the dimensions of the matrix.
9276    ///
9277    /// # Safety
9278    /// The behavior is undefined if any of the following conditions are violated:
9279    /// * `nrows < self.row_capacity()`.
9280    /// * `ncols < self.col_capacity()`.
9281    /// * The elements that were previously out of bounds but are now in bounds must be
9282    /// initialized.
9283    #[inline]
9284    pub unsafe fn set_dims(&mut self, nrows: usize, ncols: usize) {
9285        self.inner.inner.nrows = nrows;
9286        self.inner.inner.ncols = ncols;
9287    }
9288
9289    /// Returns a pointer to the data of the matrix.
9290    #[inline]
9291    pub fn as_ptr(&self) -> GroupFor<E, *const E::Unit> {
9292        E::faer_map(from_copy::<E, _>(self.inner.inner.ptr), |ptr| {
9293            ptr.as_ptr() as *const E::Unit
9294        })
9295    }
9296
9297    /// Returns a mutable pointer to the data of the matrix.
9298    #[inline]
9299    pub fn as_ptr_mut(&mut self) -> GroupFor<E, *mut E::Unit> {
9300        E::faer_map(from_copy::<E, _>(self.inner.inner.ptr), |ptr| ptr.as_ptr())
9301    }
9302
9303    /// Returns the row capacity, that is, the number of rows that the matrix is able to hold
9304    /// without needing to reallocate, excluding column insertions.
9305    #[inline]
9306    pub fn row_capacity(&self) -> usize {
9307        self.inner.row_capacity
9308    }
9309
9310    /// Returns the column capacity, that is, the number of columns that the matrix is able to hold
9311    /// without needing to reallocate, excluding row insertions.
9312    #[inline]
9313    pub fn col_capacity(&self) -> usize {
9314        self.inner.col_capacity
9315    }
9316
9317    /// Returns the offset between the first elements of two successive rows in the matrix.
9318    /// Always returns `1` since the matrix is column major.
9319    #[inline]
9320    pub fn row_stride(&self) -> isize {
9321        1
9322    }
9323
9324    /// Returns the offset between the first elements of two successive columns in the matrix.
9325    #[inline]
9326    pub fn col_stride(&self) -> isize {
9327        self.row_capacity() as isize
9328    }
9329
9330    #[cold]
9331    fn do_reserve_exact(&mut self, mut new_row_capacity: usize, new_col_capacity: usize) {
9332        if is_vectorizable::<E::Unit>() {
9333            let align_factor = align_for::<E::Unit>() / core::mem::size_of::<E::Unit>();
9334            new_row_capacity = new_row_capacity
9335                .msrv_checked_next_multiple_of(align_factor)
9336                .unwrap();
9337        }
9338
9339        let nrows = self.inner.inner.nrows;
9340        let ncols = self.inner.inner.ncols;
9341        let old_row_capacity = self.inner.row_capacity;
9342        let old_col_capacity = self.inner.col_capacity;
9343
9344        let mut this = ManuallyDrop::new(core::mem::take(self));
9345        {
9346            let mut this_group =
9347                E::faer_map(from_copy::<E, _>(this.inner.inner.ptr), |ptr| MatUnit {
9348                    raw: RawMatUnit {
9349                        ptr,
9350                        row_capacity: old_row_capacity,
9351                        col_capacity: old_col_capacity,
9352                    },
9353                    nrows,
9354                    ncols,
9355                });
9356
9357            E::faer_map(E::faer_as_mut(&mut this_group), |mat_unit| {
9358                mat_unit.do_reserve_exact(new_row_capacity, new_col_capacity);
9359            });
9360
9361            let this_group = E::faer_map(this_group, ManuallyDrop::new);
9362            this.inner.inner.ptr =
9363                into_copy::<E, _>(E::faer_map(this_group, |mat_unit| mat_unit.raw.ptr));
9364            this.inner.row_capacity = new_row_capacity;
9365            this.inner.col_capacity = new_col_capacity;
9366        }
9367        *self = ManuallyDrop::into_inner(this);
9368    }
9369
9370    /// Reserves the minimum capacity for `row_capacity` rows and `col_capacity`
9371    /// columns without reallocating. Does nothing if the capacity is already sufficient.
9372    ///
9373    /// # Panics
9374    /// The function panics if the new total capacity in bytes exceeds `isize::MAX`.
9375    #[inline]
9376    pub fn reserve_exact(&mut self, row_capacity: usize, col_capacity: usize) {
9377        if self.row_capacity() >= row_capacity && self.col_capacity() >= col_capacity {
9378            // do nothing
9379        } else if core::mem::size_of::<E::Unit>() == 0 {
9380            self.inner.row_capacity = self.row_capacity().max(row_capacity);
9381            self.inner.col_capacity = self.col_capacity().max(col_capacity);
9382        } else {
9383            self.do_reserve_exact(row_capacity, col_capacity);
9384        }
9385    }
9386
9387    unsafe fn insert_block_with<F: FnMut(usize, usize) -> E>(
9388        &mut self,
9389        f: &mut F,
9390        row_start: usize,
9391        row_end: usize,
9392        col_start: usize,
9393        col_end: usize,
9394    ) {
9395        debug_assert!(all(row_start <= row_end, col_start <= col_end));
9396
9397        let ptr = self.as_ptr_mut();
9398
9399        for j in col_start..col_end {
9400            let ptr_j = E::faer_map(E::faer_copy(&ptr), |ptr| {
9401                ptr.wrapping_offset(j as isize * self.col_stride())
9402            });
9403
9404            for i in row_start..row_end {
9405                // SAFETY:
9406                // * pointer to element at index (i, j), which is within the
9407                // allocation since we reserved enough space
9408                // * writing to this memory region is sound since it is properly
9409                // aligned and valid for writes
9410                let ptr_ij = E::faer_map(E::faer_copy(&ptr_j), |ptr_j| ptr_j.add(i));
9411                let value = E::faer_into_units(f(i, j));
9412
9413                E::faer_map(E::faer_zip(ptr_ij, value), |(ptr_ij, value)| {
9414                    core::ptr::write(ptr_ij, value)
9415                });
9416            }
9417        }
9418    }
9419
9420    fn erase_last_cols(&mut self, new_ncols: usize) {
9421        let old_ncols = self.ncols();
9422        debug_assert!(new_ncols <= old_ncols);
9423        self.inner.inner.ncols = new_ncols;
9424    }
9425
9426    fn erase_last_rows(&mut self, new_nrows: usize) {
9427        let old_nrows = self.nrows();
9428        debug_assert!(new_nrows <= old_nrows);
9429        self.inner.inner.nrows = new_nrows;
9430    }
9431
9432    unsafe fn insert_last_cols_with<F: FnMut(usize, usize) -> E>(
9433        &mut self,
9434        f: &mut F,
9435        new_ncols: usize,
9436    ) {
9437        let old_ncols = self.ncols();
9438
9439        debug_assert!(new_ncols > old_ncols);
9440
9441        self.insert_block_with(f, 0, self.nrows(), old_ncols, new_ncols);
9442        self.inner.inner.ncols = new_ncols;
9443    }
9444
9445    unsafe fn insert_last_rows_with<F: FnMut(usize, usize) -> E>(
9446        &mut self,
9447        f: &mut F,
9448        new_nrows: usize,
9449    ) {
9450        let old_nrows = self.nrows();
9451
9452        debug_assert!(new_nrows > old_nrows);
9453
9454        self.insert_block_with(f, old_nrows, new_nrows, 0, self.ncols());
9455        self.inner.inner.nrows = new_nrows;
9456    }
9457
9458    /// Resizes the matrix in-place so that the new dimensions are `(new_nrows, new_ncols)`.
9459    /// New elements are created with the given function `f`, so that elements at indices `(i, j)`
9460    /// are created by calling `f(i, j)`.
9461    pub fn resize_with(
9462        &mut self,
9463        new_nrows: usize,
9464        new_ncols: usize,
9465        f: impl FnMut(usize, usize) -> E,
9466    ) {
9467        let mut f = f;
9468        let old_nrows = self.nrows();
9469        let old_ncols = self.ncols();
9470
9471        if new_ncols <= old_ncols {
9472            self.erase_last_cols(new_ncols);
9473            if new_nrows <= old_nrows {
9474                self.erase_last_rows(new_nrows);
9475            } else {
9476                self.reserve_exact(new_nrows, new_ncols);
9477                unsafe {
9478                    self.insert_last_rows_with(&mut f, new_nrows);
9479                }
9480            }
9481        } else {
9482            if new_nrows <= old_nrows {
9483                self.erase_last_rows(new_nrows);
9484            } else {
9485                self.reserve_exact(new_nrows, new_ncols);
9486                unsafe {
9487                    self.insert_last_rows_with(&mut f, new_nrows);
9488                }
9489            }
9490            self.reserve_exact(new_nrows, new_ncols);
9491            unsafe {
9492                self.insert_last_cols_with(&mut f, new_ncols);
9493            }
9494        }
9495    }
9496
9497    /// Returns a reference to a slice over the column at the given index.
9498    #[inline]
9499    #[track_caller]
9500    pub fn col_as_slice(&self, col: usize) -> GroupFor<E, &[E::Unit]> {
9501        assert!(col < self.ncols());
9502        let nrows = self.nrows();
9503        let ptr = self.as_ref().ptr_at(0, col);
9504        E::faer_map(
9505            ptr,
9506            #[inline(always)]
9507            |ptr| unsafe { core::slice::from_raw_parts(ptr, nrows) },
9508        )
9509    }
9510
9511    /// Returns a mutable reference to a slice over the column at the given index.
9512    #[inline]
9513    #[track_caller]
9514    pub fn col_as_slice_mut(&mut self, col: usize) -> GroupFor<E, &mut [E::Unit]> {
9515        assert!(col < self.ncols());
9516        let nrows = self.nrows();
9517        let ptr = self.as_mut().ptr_at_mut(0, col);
9518        E::faer_map(
9519            ptr,
9520            #[inline(always)]
9521            |ptr| unsafe { core::slice::from_raw_parts_mut(ptr, nrows) },
9522        )
9523    }
9524
9525    /// Returns a reference to a slice over the column at the given index.
9526    #[inline]
9527    #[track_caller]
9528    #[deprecated = "replaced by `Mat::col_as_slice`"]
9529    pub fn col_ref(&self, col: usize) -> GroupFor<E, &[E::Unit]> {
9530        self.col_as_slice(col)
9531    }
9532
9533    /// Returns a mutable reference to a slice over the column at the given index.
9534    #[inline]
9535    #[track_caller]
9536    #[deprecated = "replaced by `Mat::col_as_slice_mut`"]
9537    pub fn col_mut(&mut self, col: usize) -> GroupFor<E, &mut [E::Unit]> {
9538        self.col_as_slice_mut(col)
9539    }
9540
9541    /// Returns a view over the matrix.
9542    #[inline]
9543    pub fn as_ref(&self) -> MatRef<'_, E> {
9544        unsafe {
9545            mat::from_raw_parts(
9546                self.as_ptr(),
9547                self.nrows(),
9548                self.ncols(),
9549                1,
9550                self.col_stride(),
9551            )
9552        }
9553    }
9554
9555    /// Returns a mutable view over the matrix.
9556    #[inline]
9557    pub fn as_mut(&mut self) -> MatMut<'_, E> {
9558        unsafe {
9559            mat::from_raw_parts_mut(
9560                self.as_ptr_mut(),
9561                self.nrows(),
9562                self.ncols(),
9563                1,
9564                self.col_stride(),
9565            )
9566        }
9567    }
9568
9569    /// Returns references to the element at the given indices, or submatrices if either `row` or
9570    /// `col` is a range.
9571    ///
9572    /// # Note
9573    /// The values pointed to by the references are expected to be initialized, even if the
9574    /// pointed-to value is not read, otherwise the behavior is undefined.
9575    ///
9576    /// # Safety
9577    /// The behavior is undefined if any of the following conditions are violated:
9578    /// * `row` must be contained in `[0, self.nrows())`.
9579    /// * `col` must be contained in `[0, self.ncols())`.
9580    #[inline]
9581    pub unsafe fn get_unchecked<RowRange, ColRange>(
9582        &self,
9583        row: RowRange,
9584        col: ColRange,
9585    ) -> <MatRef<'_, E> as MatIndex<RowRange, ColRange>>::Target
9586    where
9587        for<'a> MatRef<'a, E>: MatIndex<RowRange, ColRange>,
9588    {
9589        self.as_ref().get_unchecked(row, col)
9590    }
9591
9592    /// Returns references to the element at the given indices, or submatrices if either `row` or
9593    /// `col` is a range, with bound checks.
9594    ///
9595    /// # Note
9596    /// The values pointed to by the references are expected to be initialized, even if the
9597    /// pointed-to value is not read, otherwise the behavior is undefined.
9598    ///
9599    /// # Panics
9600    /// The function panics if any of the following conditions are violated:
9601    /// * `row` must be contained in `[0, self.nrows())`.
9602    /// * `col` must be contained in `[0, self.ncols())`.
9603    #[inline]
9604    pub fn get<RowRange, ColRange>(
9605        &self,
9606        row: RowRange,
9607        col: ColRange,
9608    ) -> <MatRef<'_, E> as MatIndex<RowRange, ColRange>>::Target
9609    where
9610        for<'a> MatRef<'a, E>: MatIndex<RowRange, ColRange>,
9611    {
9612        self.as_ref().get(row, col)
9613    }
9614
9615    /// Returns mutable references to the element at the given indices, or submatrices if either
9616    /// `row` or `col` is a range.
9617    ///
9618    /// # Note
9619    /// The values pointed to by the references are expected to be initialized, even if the
9620    /// pointed-to value is not read, otherwise the behavior is undefined.
9621    ///
9622    /// # Safety
9623    /// The behavior is undefined if any of the following conditions are violated:
9624    /// * `row` must be contained in `[0, self.nrows())`.
9625    /// * `col` must be contained in `[0, self.ncols())`.
9626    #[inline]
9627    pub unsafe fn get_mut_unchecked<RowRange, ColRange>(
9628        &mut self,
9629        row: RowRange,
9630        col: ColRange,
9631    ) -> <MatMut<'_, E> as MatIndex<RowRange, ColRange>>::Target
9632    where
9633        for<'a> MatMut<'a, E>: MatIndex<RowRange, ColRange>,
9634    {
9635        self.as_mut().get_mut_unchecked(row, col)
9636    }
9637
9638    /// Returns mutable references to the element at the given indices, or submatrices if either
9639    /// `row` or `col` is a range, with bound checks.
9640    ///
9641    /// # Note
9642    /// The values pointed to by the references are expected to be initialized, even if the
9643    /// pointed-to value is not read, otherwise the behavior is undefined.
9644    ///
9645    /// # Panics
9646    /// The function panics if any of the following conditions are violated:
9647    /// * `row` must be contained in `[0, self.nrows())`.
9648    /// * `col` must be contained in `[0, self.ncols())`.
9649    #[inline]
9650    pub fn get_mut<RowRange, ColRange>(
9651        &mut self,
9652        row: RowRange,
9653        col: ColRange,
9654    ) -> <MatMut<'_, E> as MatIndex<RowRange, ColRange>>::Target
9655    where
9656        for<'a> MatMut<'a, E>: MatIndex<RowRange, ColRange>,
9657    {
9658        self.as_mut().get_mut(row, col)
9659    }
9660
9661    /// Reads the value of the element at the given indices.
9662    ///
9663    /// # Safety
9664    /// The behavior is undefined if any of the following conditions are violated:
9665    /// * `row < self.nrows()`.
9666    /// * `col < self.ncols()`.
9667    #[inline(always)]
9668    #[track_caller]
9669    pub unsafe fn read_unchecked(&self, row: usize, col: usize) -> E {
9670        self.as_ref().read_unchecked(row, col)
9671    }
9672
9673    /// Reads the value of the element at the given indices, with bound checks.
9674    ///
9675    /// # Panics
9676    /// The function panics if any of the following conditions are violated:
9677    /// * `row < self.nrows()`.
9678    /// * `col < self.ncols()`.
9679    #[inline(always)]
9680    #[track_caller]
9681    pub fn read(&self, row: usize, col: usize) -> E {
9682        self.as_ref().read(row, col)
9683    }
9684
9685    /// Writes the value to the element at the given indices.
9686    ///
9687    /// # Safety
9688    /// The behavior is undefined if any of the following conditions are violated:
9689    /// * `row < self.nrows()`.
9690    /// * `col < self.ncols()`.
9691    #[inline(always)]
9692    #[track_caller]
9693    pub unsafe fn write_unchecked(&mut self, row: usize, col: usize, value: E) {
9694        self.as_mut().write_unchecked(row, col, value);
9695    }
9696
9697    /// Writes the value to the element at the given indices, with bound checks.
9698    ///
9699    /// # Panics
9700    /// The function panics if any of the following conditions are violated:
9701    /// * `row < self.nrows()`.
9702    /// * `col < self.ncols()`.
9703    #[inline(always)]
9704    #[track_caller]
9705    pub fn write(&mut self, row: usize, col: usize, value: E) {
9706        self.as_mut().write(row, col, value);
9707    }
9708
9709    /// Copies the values from `other` into `self`.
9710    #[inline(always)]
9711    #[track_caller]
9712    pub fn copy_from(&mut self, other: impl AsMatRef<E>) {
9713        #[track_caller]
9714        #[inline(always)]
9715        fn implementation<E: Entity>(this: &mut Mat<E>, other: MatRef<'_, E>) {
9716            let mut mat = Mat::<E>::new();
9717            mat.resize_with(
9718                other.nrows(),
9719                other.ncols(),
9720                #[inline(always)]
9721                |row, col| unsafe { other.read_unchecked(row, col) },
9722            );
9723            *this = mat;
9724        }
9725        implementation(self, other.as_mat_ref());
9726    }
9727
9728    /// Fills the elements of `self` with zeros.
9729    #[inline(always)]
9730    #[track_caller]
9731    pub fn fill_zero(&mut self)
9732    where
9733        E: ComplexField,
9734    {
9735        self.as_mut().fill_zero()
9736    }
9737
9738    /// Fills the elements of `self` with copies of `constant`.
9739    #[inline(always)]
9740    #[track_caller]
9741    pub fn fill(&mut self, constant: E) {
9742        self.as_mut().fill(constant)
9743    }
9744
9745    /// Returns a view over the transpose of `self`.
9746    #[inline]
9747    pub fn transpose(&self) -> MatRef<'_, E> {
9748        self.as_ref().transpose()
9749    }
9750
9751    /// Returns a view over the conjugate of `self`.
9752    #[inline]
9753    pub fn conjugate(&self) -> MatRef<'_, E::Conj>
9754    where
9755        E: Conjugate,
9756    {
9757        self.as_ref().conjugate()
9758    }
9759
9760    /// Returns a view over the conjugate transpose of `self`.
9761    #[inline]
9762    pub fn adjoint(&self) -> MatRef<'_, E::Conj>
9763    where
9764        E: Conjugate,
9765    {
9766        self.as_ref().adjoint()
9767    }
9768
9769    /// Returns a view over the diagonal of the matrix.
9770    #[inline]
9771    pub fn diagonal(&self) -> Matrix<inner::DiagRef<'_, E>> {
9772        self.as_ref().diagonal()
9773    }
9774
9775    /// Returns an owning [`Mat`] of the data
9776    #[inline]
9777    pub fn to_owned(&self) -> Mat<E::Canonical>
9778    where
9779        E: Conjugate,
9780    {
9781        self.as_ref().to_owned()
9782    }
9783
9784    /// Returns `true` if any of the elements is NaN, otherwise returns `false`.
9785    #[inline]
9786    pub fn has_nan(&self) -> bool
9787    where
9788        E: ComplexField,
9789    {
9790        self.as_ref().has_nan()
9791    }
9792
9793    /// Returns `true` if all of the elements are finite, otherwise returns `false`.
9794    #[inline]
9795    pub fn is_all_finite(&self) -> bool
9796    where
9797        E: ComplexField,
9798    {
9799        self.as_ref().is_all_finite()
9800    }
9801
9802    /// Returns the maximum norm of `self`.
9803    #[inline]
9804    pub fn norm_max(&self) -> E::Real
9805    where
9806        E: ComplexField,
9807    {
9808        norm_max((*self).as_ref())
9809    }
9810    /// Returns the L2 norm of `self`.
9811    #[inline]
9812    pub fn norm_l2(&self) -> E::Real
9813    where
9814        E: ComplexField,
9815    {
9816        norm_l2((*self).as_ref())
9817    }
9818
9819    /// Returns the sum of `self`.
9820    #[inline]
9821    pub fn sum(&self) -> E
9822    where
9823        E: ComplexField,
9824    {
9825        sum((*self).as_ref())
9826    }
9827
9828    /// Kroneckor product of `self` and `rhs`.
9829    ///
9830    /// This is an allocating operation; see [`kron`] for the
9831    /// allocation-free version or more info in general.
9832    #[inline]
9833    #[track_caller]
9834    pub fn kron(&self, rhs: impl As2D<E>) -> Mat<E>
9835    where
9836        E: ComplexField,
9837    {
9838        self.as_2d_ref().kron(rhs)
9839    }
9840
9841    /// Returns an iterator that provides successive chunks of the columns of a view over this
9842    /// matrix, with each having at most `chunk_size` columns.
9843    ///
9844    /// If the number of columns is a multiple of `chunk_size`, then all chunks have `chunk_size`
9845    /// columns.
9846    #[inline]
9847    #[track_caller]
9848    pub fn col_chunks(
9849        &self,
9850        chunk_size: usize,
9851    ) -> impl '_ + DoubleEndedIterator<Item = MatRef<'_, E>> {
9852        self.as_ref().col_chunks(chunk_size)
9853    }
9854
9855    /// Returns an iterator that provides successive chunks of the columns of a mutable view over
9856    /// this matrix, with each having at most `chunk_size` columns.
9857    ///
9858    /// If the number of columns is a multiple of `chunk_size`, then all chunks have `chunk_size`
9859    /// columns.
9860    #[inline]
9861    #[track_caller]
9862    pub fn col_chunks_mut(
9863        &mut self,
9864        chunk_size: usize,
9865    ) -> impl '_ + DoubleEndedIterator<Item = MatMut<'_, E>> {
9866        self.as_mut().col_chunks_mut(chunk_size)
9867    }
9868
9869    /// Returns a parallel iterator that provides successive chunks of the columns of a view over
9870    /// this matrix, with each having at most `chunk_size` columns.
9871    ///
9872    /// If the number of columns is a multiple of `chunk_size`, then all chunks have `chunk_size`
9873    /// columns.
9874    ///
9875    /// Only available with the `rayon` feature.
9876    #[cfg(feature = "rayon")]
9877    #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
9878    #[inline]
9879    #[track_caller]
9880    pub fn par_col_chunks(
9881        &self,
9882        chunk_size: usize,
9883    ) -> impl '_ + rayon::iter::IndexedParallelIterator<Item = MatRef<'_, E>> {
9884        self.as_ref().par_col_chunks(chunk_size)
9885    }
9886
9887    /// Returns a parallel iterator that provides successive chunks of the columns of a mutable view
9888    /// over this matrix, with each having at most `chunk_size` columns.
9889    ///
9890    /// If the number of columns is a multiple of `chunk_size`, then all chunks have `chunk_size`
9891    /// columns.
9892    ///
9893    /// Only available with the `rayon` feature.
9894    #[cfg(feature = "rayon")]
9895    #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
9896    #[inline]
9897    #[track_caller]
9898    pub fn par_col_chunks_mut(
9899        &mut self,
9900        chunk_size: usize,
9901    ) -> impl '_ + rayon::iter::IndexedParallelIterator<Item = MatMut<'_, E>> {
9902        self.as_mut().par_col_chunks_mut(chunk_size)
9903    }
9904
9905    /// Returns an iterator that provides successive chunks of the rows of a view over this
9906    /// matrix, with each having at most `chunk_size` rows.
9907    ///
9908    /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
9909    /// rows.
9910    #[inline]
9911    #[track_caller]
9912    pub fn row_chunks(
9913        &self,
9914        chunk_size: usize,
9915    ) -> impl '_ + DoubleEndedIterator<Item = MatRef<'_, E>> {
9916        self.as_ref().row_chunks(chunk_size)
9917    }
9918
9919    /// Returns an iterator that provides successive chunks of the rows of a mutable view over
9920    /// this matrix, with each having at most `chunk_size` rows.
9921    ///
9922    /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
9923    /// rows.
9924    #[inline]
9925    #[track_caller]
9926    pub fn row_chunks_mut(
9927        &mut self,
9928        chunk_size: usize,
9929    ) -> impl '_ + DoubleEndedIterator<Item = MatMut<'_, E>> {
9930        self.as_mut().row_chunks_mut(chunk_size)
9931    }
9932
9933    /// Returns a parallel iterator that provides successive chunks of the rows of a view over this
9934    /// matrix, with each having at most `chunk_size` rows.
9935    ///
9936    /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
9937    /// rows.
9938    ///
9939    /// Only available with the `rayon` feature.
9940    #[cfg(feature = "rayon")]
9941    #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
9942    #[inline]
9943    #[track_caller]
9944    pub fn par_row_chunks(
9945        &self,
9946        chunk_size: usize,
9947    ) -> impl '_ + rayon::iter::IndexedParallelIterator<Item = MatRef<'_, E>> {
9948        self.as_ref().par_row_chunks(chunk_size)
9949    }
9950
9951    /// Returns a parallel iterator that provides successive chunks of the rows of a mutable view
9952    /// over this matrix, with each having at most `chunk_size` rows.
9953    ///
9954    /// If the number of rows is a multiple of `chunk_size`, then all chunks have `chunk_size`
9955    /// rows.
9956    ///
9957    /// Only available with the `rayon` feature.
9958    #[cfg(feature = "rayon")]
9959    #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
9960    #[inline]
9961    #[track_caller]
9962    pub fn par_row_chunks_mut(
9963        &mut self,
9964        chunk_size: usize,
9965    ) -> impl '_ + rayon::iter::IndexedParallelIterator<Item = MatMut<'_, E>> {
9966        self.as_mut().par_row_chunks_mut(chunk_size)
9967    }
9968}
9969
9970#[doc(hidden)]
9971#[inline(always)]
9972pub fn ref_to_ptr<T>(ptr: &T) -> *const T {
9973    ptr
9974}
9975
9976#[macro_export]
9977#[doc(hidden)]
9978macro_rules! __transpose_impl {
9979    ([$([$($col:expr),*])*] $($v:expr;)* ) => {
9980        [$([$($col,)*],)* [$($v,)*]]
9981    };
9982    ([$([$($col:expr),*])*] $($v0:expr, $($v:expr),* ;)*) => {
9983        $crate::__transpose_impl!([$([$($col),*])* [$($v0),*]] $($($v),* ;)*)
9984    };
9985}
9986
9987/// Creates a [`Mat`] containing the arguments.
9988///
9989/// ```
9990/// use faer_core::mat;
9991///
9992/// let matrix = mat![
9993///     [1.0, 5.0, 9.0],
9994///     [2.0, 6.0, 10.0],
9995///     [3.0, 7.0, 11.0],
9996///     [4.0, 8.0, 12.0f64],
9997/// ];
9998///
9999/// assert_eq!(matrix.read(0, 0), 1.0);
10000/// assert_eq!(matrix.read(1, 0), 2.0);
10001/// assert_eq!(matrix.read(2, 0), 3.0);
10002/// assert_eq!(matrix.read(3, 0), 4.0);
10003///
10004/// assert_eq!(matrix.read(0, 1), 5.0);
10005/// assert_eq!(matrix.read(1, 1), 6.0);
10006/// assert_eq!(matrix.read(2, 1), 7.0);
10007/// assert_eq!(matrix.read(3, 1), 8.0);
10008///
10009/// assert_eq!(matrix.read(0, 2), 9.0);
10010/// assert_eq!(matrix.read(1, 2), 10.0);
10011/// assert_eq!(matrix.read(2, 2), 11.0);
10012/// assert_eq!(matrix.read(3, 2), 12.0);
10013/// ```
10014#[macro_export]
10015macro_rules! mat {
10016    () => {
10017        {
10018            compile_error!("number of columns in the matrix is ambiguous");
10019        }
10020    };
10021
10022    ($([$($v:expr),* $(,)?] ),* $(,)?) => {
10023        {
10024            let data = ::core::mem::ManuallyDrop::new($crate::__transpose_impl!([] $($($v),* ;)*));
10025            let data = &*data;
10026            let ncols = data.len();
10027            let nrows = (*data.get(0).unwrap()).len();
10028
10029            #[allow(unused_unsafe)]
10030            unsafe {
10031                $crate::Mat::<_>::from_fn(nrows, ncols, |i, j| $crate::ref_to_ptr(&data[j][i]).read())
10032            }
10033        }
10034    };
10035}
10036
10037/// Concatenates the matrices in each row horizontally,
10038/// then concatenates the results vertically.
10039/// `concat![[a0, a1, a2], [b1, b2]]` results in the matrix
10040///
10041/// ```notcode
10042/// [a0 | a1 | a2][b0 | b1]
10043/// ```
10044#[macro_export]
10045macro_rules! concat {
10046    () => {
10047        {
10048            compile_error!("number of columns in the matrix is ambiguous");
10049        }
10050    };
10051
10052    ($([$($v:expr),* $(,)?] ),* $(,)?) => {
10053        {
10054            $crate::__concat_impl(&[$(&[$(($v).as_ref(),)*],)*])
10055        }
10056    };
10057}
10058
10059/// Creates a [`Col`] containing the arguments.
10060///
10061/// ```
10062/// use faer_core::col;
10063///
10064/// let col_vec = col![3.0, 5.0, 7.0, 9.0];
10065///
10066/// assert_eq!(col_vec.read(0), 3.0);
10067/// assert_eq!(col_vec.read(1), 5.0);
10068/// assert_eq!(col_vec.read(2), 7.0);
10069/// assert_eq!(col_vec.read(3), 9.0);
10070/// ```
10071#[macro_export]
10072macro_rules! col {
10073    () => {
10074        $crate::Col::<_>::new()
10075    };
10076
10077    ($($v:expr),+ $(,)?) => {{
10078        let data = &[$($v),+];
10079        let n = data.len();
10080
10081        #[allow(unused_unsafe)]
10082        unsafe {
10083            $crate::Col::<_>::from_fn(n, |i| $crate::ref_to_ptr(&data[i]).read())
10084        }
10085    }};
10086}
10087
10088/// Creates a [`Row`] containing the arguments.
10089///
10090/// ```
10091/// use faer_core::row;
10092///
10093/// let row_vec = row![3.0, 5.0, 7.0, 9.0];
10094///
10095/// assert_eq!(row_vec.read(0), 3.0);
10096/// assert_eq!(row_vec.read(1), 5.0);
10097/// assert_eq!(row_vec.read(2), 7.0);
10098/// assert_eq!(row_vec.read(3), 9.0);
10099/// ```
10100#[macro_export]
10101macro_rules! row {
10102    () => {
10103        $crate::Row::<_>::new()
10104    };
10105
10106    ($($v:expr),+ $(,)?) => {{
10107        let data = &[$($v),+];
10108        let n = data.len();
10109
10110        #[allow(unused_unsafe)]
10111        unsafe {
10112            $crate::Row::<_>::from_fn(n, |i| $crate::ref_to_ptr(&data[i]).read())
10113        }
10114    }};
10115}
10116
10117/// Parallelism strategy that can be passed to most of the routines in the library.
10118#[derive(Copy, Clone, Debug, PartialEq, Eq)]
10119pub enum Parallelism {
10120    /// No parallelism.
10121    ///
10122    /// The code is executed sequentially on the same thread that calls a function
10123    /// and passes this argument.
10124    None,
10125    /// Rayon parallelism. Only avaialble with the `rayon` feature.
10126    ///
10127    /// The code is possibly executed in parallel on the current thread, as well as the currently
10128    /// active rayon thread pool.
10129    ///
10130    /// The contained value represents a hint about the number of threads an implementation should
10131    /// use, but there is no way to guarantee how many or which threads will be used.
10132    ///
10133    /// A value of `0` treated as equivalent to `rayon::current_num_threads()`.
10134    #[cfg(feature = "rayon")]
10135    #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
10136    Rayon(usize),
10137}
10138
10139/// 0: Disable
10140/// 1: None
10141/// n >= 2: Rayon(n - 2)
10142///
10143/// default: Rayon(0)
10144static GLOBAL_PARALLELISM: AtomicUsize = {
10145    #[cfg(feature = "rayon")]
10146    {
10147        AtomicUsize::new(2)
10148    }
10149    #[cfg(not(feature = "rayon"))]
10150    {
10151        AtomicUsize::new(1)
10152    }
10153};
10154
10155/// Causes functions that access global parallelism settings to panic.
10156pub fn disable_global_parallelism() {
10157    GLOBAL_PARALLELISM.store(0, core::sync::atomic::Ordering::Relaxed);
10158}
10159
10160/// Sets the global parallelism settings.
10161pub fn set_global_parallelism(parallelism: Parallelism) {
10162    let value = match parallelism {
10163        Parallelism::None => 1,
10164        #[cfg(feature = "rayon")]
10165        Parallelism::Rayon(n) => n.saturating_add(2),
10166    };
10167    GLOBAL_PARALLELISM.store(value, core::sync::atomic::Ordering::Relaxed);
10168}
10169
10170/// Gets the global parallelism settings.
10171///
10172/// # Panics
10173/// Panics if global parallelism is disabled.
10174#[track_caller]
10175pub fn get_global_parallelism() -> Parallelism {
10176    let value = GLOBAL_PARALLELISM.load(core::sync::atomic::Ordering::Relaxed);
10177    match value {
10178        0 => panic!("Global parallelism is disabled."),
10179        1 => Parallelism::None,
10180        #[cfg(feature = "rayon")]
10181        n => Parallelism::Rayon(n - 2),
10182        #[cfg(not(feature = "rayon"))]
10183        _ => unreachable!(),
10184    }
10185}
10186
10187#[inline]
10188#[doc(hidden)]
10189pub fn join_raw(
10190    op_a: impl Send + FnOnce(Parallelism),
10191    op_b: impl Send + FnOnce(Parallelism),
10192    parallelism: Parallelism,
10193) {
10194    fn implementation(
10195        op_a: &mut (dyn Send + FnMut(Parallelism)),
10196        op_b: &mut (dyn Send + FnMut(Parallelism)),
10197        parallelism: Parallelism,
10198    ) {
10199        match parallelism {
10200            Parallelism::None => (op_a(parallelism), op_b(parallelism)),
10201            #[cfg(feature = "rayon")]
10202            Parallelism::Rayon(n_threads) => {
10203                if n_threads == 1 {
10204                    (op_a(Parallelism::None), op_b(Parallelism::None))
10205                } else {
10206                    let n_threads = if n_threads > 0 {
10207                        n_threads
10208                    } else {
10209                        rayon::current_num_threads()
10210                    };
10211                    let parallelism = Parallelism::Rayon(n_threads - n_threads / 2);
10212                    rayon::join(|| op_a(parallelism), || op_b(parallelism))
10213                }
10214            }
10215        };
10216    }
10217    let mut op_a = Some(op_a);
10218    let mut op_b = Some(op_b);
10219    implementation(
10220        &mut |parallelism| (op_a.take().unwrap())(parallelism),
10221        &mut |parallelism| (op_b.take().unwrap())(parallelism),
10222        parallelism,
10223    )
10224}
10225
10226#[inline]
10227#[doc(hidden)]
10228pub fn for_each_raw(n_tasks: usize, op: impl Send + Sync + Fn(usize), parallelism: Parallelism) {
10229    fn implementation(
10230        n_tasks: usize,
10231        op: &(dyn Send + Sync + Fn(usize)),
10232        parallelism: Parallelism,
10233    ) {
10234        if n_tasks == 1 {
10235            op(0);
10236            return;
10237        }
10238
10239        match parallelism {
10240            Parallelism::None => (0..n_tasks).for_each(op),
10241            #[cfg(feature = "rayon")]
10242            Parallelism::Rayon(n_threads) => {
10243                let n_threads = if n_threads > 0 {
10244                    n_threads
10245                } else {
10246                    rayon::current_num_threads()
10247                };
10248
10249                use rayon::prelude::*;
10250                let min_len = n_tasks / n_threads;
10251                (0..n_tasks)
10252                    .into_par_iter()
10253                    .with_min_len(min_len)
10254                    .for_each(op);
10255            }
10256        }
10257    }
10258    implementation(n_tasks, &op, parallelism);
10259}
10260
10261#[doc(hidden)]
10262pub struct Ptr<T>(pub *mut T);
10263unsafe impl<T> Send for Ptr<T> {}
10264unsafe impl<T> Sync for Ptr<T> {}
10265impl<T> Copy for Ptr<T> {}
10266impl<T> Clone for Ptr<T> {
10267    #[inline]
10268    fn clone(&self) -> Self {
10269        *self
10270    }
10271}
10272
10273#[inline]
10274#[doc(hidden)]
10275pub fn parallelism_degree(parallelism: Parallelism) -> usize {
10276    match parallelism {
10277        Parallelism::None => 1,
10278        #[cfg(feature = "rayon")]
10279        Parallelism::Rayon(0) => rayon::current_num_threads(),
10280        #[cfg(feature = "rayon")]
10281        Parallelism::Rayon(n_threads) => n_threads,
10282    }
10283}
10284
10285/// Creates a temporary matrix of constant values, from the given memory stack.
10286pub fn temp_mat_constant<E: ComplexField>(
10287    nrows: usize,
10288    ncols: usize,
10289    value: E,
10290    stack: PodStack<'_>,
10291) -> (MatMut<'_, E>, PodStack<'_>) {
10292    let (mut mat, stack) = temp_mat_uninit::<E>(nrows, ncols, stack);
10293    mat.as_mut().fill(value);
10294    (mat, stack)
10295}
10296
10297/// Creates a temporary matrix of zero values, from the given memory stack.
10298pub fn temp_mat_zeroed<E: ComplexField>(
10299    nrows: usize,
10300    ncols: usize,
10301    stack: PodStack<'_>,
10302) -> (MatMut<'_, E>, PodStack<'_>) {
10303    let (mut mat, stack) = temp_mat_uninit::<E>(nrows, ncols, stack);
10304    mat.as_mut().fill_zero();
10305    (mat, stack)
10306}
10307
10308/// Creates a temporary matrix of untouched values, from the given memory stack.
10309pub fn temp_mat_uninit<E: ComplexField>(
10310    nrows: usize,
10311    ncols: usize,
10312    stack: PodStack<'_>,
10313) -> (MatMut<'_, E>, PodStack<'_>) {
10314    let col_stride = col_stride::<E::Unit>(nrows);
10315    let alloc_size = ncols.checked_mul(col_stride).unwrap();
10316
10317    let (stack, alloc) = E::faer_map_with_context(stack, E::UNIT, &mut {
10318        #[inline(always)]
10319        |stack, ()| {
10320            let (alloc, stack) =
10321                stack.make_aligned_raw::<E::Unit>(alloc_size, align_for::<E::Unit>());
10322            (stack, alloc)
10323        }
10324    });
10325    (
10326        unsafe {
10327            mat::from_raw_parts_mut(
10328                E::faer_map(alloc, |alloc| alloc.as_mut_ptr()),
10329                nrows,
10330                ncols,
10331                1,
10332                col_stride as isize,
10333            )
10334        },
10335        stack,
10336    )
10337}
10338
10339#[doc(hidden)]
10340#[inline]
10341pub fn col_stride<Unit: 'static>(nrows: usize) -> usize {
10342    if !is_vectorizable::<Unit>() || nrows >= isize::MAX as usize {
10343        nrows
10344    } else {
10345        nrows
10346            .msrv_checked_next_multiple_of(align_for::<Unit>() / core::mem::size_of::<Unit>())
10347            .unwrap()
10348    }
10349}
10350
10351/// Returns the stack requirements for creating a temporary matrix with the given dimensions.
10352#[inline]
10353pub fn temp_mat_req<E: Entity>(nrows: usize, ncols: usize) -> Result<StackReq, SizeOverflow> {
10354    let col_stride = col_stride::<E::Unit>(nrows);
10355    let alloc_size = ncols.checked_mul(col_stride).ok_or(SizeOverflow)?;
10356    let additional = StackReq::try_new_aligned::<E::Unit>(alloc_size, align_for::<E::Unit>())?;
10357
10358    let req = Ok(StackReq::empty());
10359    let (req, _) = E::faer_map_with_context(req, E::UNIT, &mut {
10360        #[inline(always)]
10361        |req, ()| {
10362            let req = match req {
10363                Ok(req) => req.try_and(additional),
10364                _ => Err(SizeOverflow),
10365            };
10366
10367            (req, ())
10368        }
10369    });
10370
10371    req
10372}
10373
10374impl<'a, FromE: Entity, ToE: Entity> Coerce<MatRef<'a, ToE>> for MatRef<'a, FromE> {
10375    #[inline(always)]
10376    fn coerce(self) -> MatRef<'a, ToE> {
10377        assert!(coe::is_same::<FromE, ToE>());
10378        unsafe { transmute_unchecked::<MatRef<'a, FromE>, MatRef<'a, ToE>>(self) }
10379    }
10380}
10381impl<'a, FromE: Entity, ToE: Entity> Coerce<MatMut<'a, ToE>> for MatMut<'a, FromE> {
10382    #[inline(always)]
10383    fn coerce(self) -> MatMut<'a, ToE> {
10384        assert!(coe::is_same::<FromE, ToE>());
10385        unsafe { transmute_unchecked::<MatMut<'a, FromE>, MatMut<'a, ToE>>(self) }
10386    }
10387}
10388
10389/// Zips together matrix of the same size, so that coefficient-wise operations can be performed on
10390/// their elements.
10391///
10392/// # Note
10393/// The order in which the matrix elements are traversed is unspecified.
10394///
10395/// # Example
10396/// ```
10397/// use faer_core::{mat, unzipped, zipped, Mat};
10398///
10399/// let nrows = 2;
10400/// let ncols = 3;
10401///
10402/// let a = mat![[1.0, 3.0, 5.0], [2.0, 4.0, 6.0]];
10403/// let b = mat![[7.0, 9.0, 11.0], [8.0, 10.0, 12.0]];
10404/// let mut sum = Mat::<f64>::zeros(nrows, ncols);
10405///
10406/// zipped!(sum.as_mut(), a.as_ref(), b.as_ref()).for_each(|unzipped!(mut sum, a, b)| {
10407///     let a = a.read();
10408///     let b = b.read();
10409///     sum.write(a + b);
10410/// });
10411///
10412/// for i in 0..nrows {
10413///     for j in 0..ncols {
10414///         assert_eq!(sum.read(i, j), a.read(i, j) + b.read(i, j));
10415///     }
10416/// }
10417/// ```
10418#[macro_export]
10419macro_rules! zipped {
10420    ($head: expr $(,)?) => {
10421        $crate::zip::LastEq($crate::zip::ViewMut::view_mut(&mut { $head }))
10422    };
10423
10424    ($head: expr, $($tail: expr),* $(,)?) => {
10425        $crate::zip::ZipEq::new($crate::zip::ViewMut::view_mut(&mut { $head }), $crate::zipped!($($tail,)*))
10426    };
10427}
10428
10429/// Used to undo the zipping by the [`zipped!`] macro.
10430#[macro_export]
10431macro_rules! unzipped {
10432    ($head: pat $(,)?) => {
10433        $crate::zip::Last($head)
10434    };
10435
10436    ($head: pat, $($tail: pat),* $(,)?) => {
10437        $crate::zip::Zip($head, $crate::unzipped!($($tail,)*))
10438    };
10439}
10440
10441impl<'a, E: Entity> Debug for RowRef<'a, E> {
10442    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10443        self.as_2d().fmt(f)
10444    }
10445}
10446impl<'a, E: Entity> Debug for RowMut<'a, E> {
10447    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10448        self.rb().fmt(f)
10449    }
10450}
10451
10452impl<'a, E: Entity> Debug for ColRef<'a, E> {
10453    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10454        self.as_2d().fmt(f)
10455    }
10456}
10457impl<'a, E: Entity> Debug for ColMut<'a, E> {
10458    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10459        self.rb().fmt(f)
10460    }
10461}
10462
10463impl<'a, E: Entity> Debug for MatRef<'a, E> {
10464    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10465        struct DebugRow<'a, T: Entity>(MatRef<'a, T>);
10466
10467        impl<'a, T: Entity> Debug for DebugRow<'a, T> {
10468            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10469                let mut j = 0;
10470                f.debug_list()
10471                    .entries(core::iter::from_fn(|| {
10472                        let ret = if j < self.0.ncols() {
10473                            Some(T::faer_from_units(T::faer_deref(self.0.get(0, j))))
10474                        } else {
10475                            None
10476                        };
10477                        j += 1;
10478                        ret
10479                    }))
10480                    .finish()
10481            }
10482        }
10483
10484        writeln!(f, "[")?;
10485        for i in 0..self.nrows() {
10486            let row = self.subrows(i, 1);
10487            DebugRow(row).fmt(f)?;
10488            f.write_str(",\n")?;
10489        }
10490        write!(f, "]")
10491    }
10492}
10493
10494impl<'a, E: Entity> Debug for MatMut<'a, E> {
10495    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10496        self.rb().fmt(f)
10497    }
10498}
10499
10500impl<E: Entity> Debug for Mat<E> {
10501    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10502        self.as_ref().fmt(f)
10503    }
10504}
10505
10506/// Advanced: Module for index and matrix types with compile time checks, instead of bound checking
10507/// at runtime.
10508pub mod constrained {
10509    use core::ops::Range;
10510
10511    use super::*;
10512    use crate::{
10513        assert, debug_assert,
10514        permutation::{Index, SignedIndex},
10515    };
10516
10517    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10518    #[repr(transparent)]
10519    struct Branded<'a, T: ?Sized> {
10520        __marker: PhantomData<fn(&'a ()) -> &'a ()>,
10521        inner: T,
10522    }
10523
10524    /// `usize` value tied to the lifetime `'n`.
10525    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10526    #[repr(transparent)]
10527    pub struct Size<'n>(Branded<'n, usize>);
10528
10529    /// `I` value smaller than the size corresponding to the lifetime `'n`.
10530    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10531    #[repr(transparent)]
10532    pub struct Idx<'n, I>(Branded<'n, I>);
10533
10534    /// `I` value smaller or equal to the size corresponding to the lifetime `'n`.
10535    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10536    #[repr(transparent)]
10537    pub struct IdxInclusive<'n, I>(Branded<'n, I>);
10538
10539    /// `I` value smaller than the size corresponding to the lifetime `'n`, or `None`.
10540    #[derive(Copy, Clone, PartialEq, Eq)]
10541    #[repr(transparent)]
10542    pub struct MaybeIdx<'n, I: Index>(Branded<'n, I>);
10543
10544    impl core::ops::Deref for Size<'_> {
10545        type Target = usize;
10546        #[inline]
10547        fn deref(&self) -> &Self::Target {
10548            &self.0.inner
10549        }
10550    }
10551    impl<I> core::ops::Deref for Idx<'_, I> {
10552        type Target = I;
10553        #[inline]
10554        fn deref(&self) -> &Self::Target {
10555            &self.0.inner
10556        }
10557    }
10558    impl<I: Index> core::ops::Deref for MaybeIdx<'_, I> {
10559        type Target = I::Signed;
10560        #[inline]
10561        fn deref(&self) -> &Self::Target {
10562            bytemuck::cast_ref(&self.0.inner)
10563        }
10564    }
10565    impl<I> core::ops::Deref for IdxInclusive<'_, I> {
10566        type Target = I;
10567        #[inline]
10568        fn deref(&self) -> &Self::Target {
10569            &self.0.inner
10570        }
10571    }
10572
10573    /// Array of length equal to the value tied to `'n`.
10574    #[derive(PartialEq, Eq, PartialOrd, Ord)]
10575    #[repr(transparent)]
10576    pub struct Array<'n, T>(Branded<'n, [T]>);
10577
10578    /// Immutable dense matrix view with dimensions equal to the values tied to `('nrows, 'ncols)`.
10579    #[repr(transparent)]
10580    pub struct MatRef<'nrows, 'ncols, 'a, E: Entity>(
10581        Branded<'ncols, Branded<'nrows, super::MatRef<'a, E>>>,
10582    );
10583    /// Mutable dense matrix view with dimensions equal to the values tied to `('nrows, 'ncols)`.
10584    #[repr(transparent)]
10585    pub struct MatMut<'nrows, 'ncols, 'a, E: Entity>(
10586        Branded<'ncols, Branded<'nrows, super::MatMut<'a, E>>>,
10587    );
10588
10589    /// Permutations with compile-time checks.
10590    pub mod permutation {
10591        use super::*;
10592        use crate::assert;
10593
10594        /// Permutation of length equal to the value tied to `'n`.
10595        #[repr(transparent)]
10596        pub struct PermutationRef<'n, 'a, I, E: Entity>(
10597            Branded<'n, crate::permutation::PermutationRef<'a, I, E>>,
10598        );
10599
10600        impl<'n, 'a, I: Index, E: Entity> PermutationRef<'n, 'a, I, E> {
10601            /// Returns a new permutation after checking that it matches the size tied to `'n`.
10602            #[inline]
10603            #[track_caller]
10604            pub fn new(perm: crate::permutation::PermutationRef<'a, I, E>, size: Size<'n>) -> Self {
10605                let (fwd, inv) = perm.into_arrays();
10606                assert!(all(
10607                    fwd.len() == size.into_inner(),
10608                    inv.len() == size.into_inner(),
10609                ));
10610                Self(Branded {
10611                    __marker: PhantomData,
10612                    inner: perm,
10613                })
10614            }
10615
10616            /// Returns the inverse permutation.
10617            #[inline]
10618            pub fn inverse(self) -> PermutationRef<'n, 'a, I, E> {
10619                PermutationRef(Branded {
10620                    __marker: PhantomData,
10621                    inner: self.0.inner.inverse(),
10622                })
10623            }
10624
10625            /// Returns the forward and inverse permutation indices.
10626            #[inline]
10627            pub fn into_arrays(self) -> (&'a Array<'n, Idx<'n, I>>, &'a Array<'n, Idx<'n, I>>) {
10628                unsafe {
10629                    let (fwd, inv) = self.0.inner.into_arrays();
10630                    let fwd = &*(fwd as *const [I] as *const Array<'n, Idx<'n, I>>);
10631                    let inv = &*(inv as *const [I] as *const Array<'n, Idx<'n, I>>);
10632                    (fwd, inv)
10633                }
10634            }
10635
10636            /// Returns the unconstrained permutation.
10637            #[inline]
10638            pub fn into_inner(self) -> crate::permutation::PermutationRef<'a, I, E> {
10639                self.0.inner
10640            }
10641
10642            /// Returns the length of the permutation.
10643            #[inline]
10644            pub fn len(&self) -> Size<'n> {
10645                unsafe { Size::new_raw_unchecked(self.into_inner().len()) }
10646            }
10647
10648            /// Casts the permutation to one with a different type.
10649            pub fn cast<T: Entity>(self) -> PermutationRef<'n, 'a, I, T> {
10650                PermutationRef(Branded {
10651                    __marker: PhantomData,
10652                    inner: self.into_inner().cast(),
10653                })
10654            }
10655        }
10656
10657        impl<I, E: Entity> Clone for PermutationRef<'_, '_, I, E> {
10658            #[inline]
10659            fn clone(&self) -> Self {
10660                *self
10661            }
10662        }
10663        impl<I, E: Entity> Copy for PermutationRef<'_, '_, I, E> {}
10664
10665        impl<I: Debug, E: Entity> Debug for PermutationRef<'_, '_, I, E> {
10666            #[inline]
10667            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10668                self.0.inner.fmt(f)
10669            }
10670        }
10671    }
10672
10673    /// Sparse matrices with compile-time checks.
10674    pub mod sparse {
10675        use super::*;
10676        use crate::{assert, group_helpers::SliceGroup, sparse::__get_unchecked};
10677        use core::ops::Range;
10678
10679        /// Symbolic structure view with dimensions equal to the values tied to `('nrows, 'ncols)`,
10680        /// in column-major order.
10681        #[repr(transparent)]
10682        pub struct SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>(
10683            Branded<'ncols, Branded<'nrows, crate::sparse::SymbolicSparseColMatRef<'a, I>>>,
10684        );
10685        /// Immutable sparse matrix view with dimensions equal to the values tied to `('nrows,
10686        /// 'ncols)`, in column-major order.
10687        pub struct SparseColMatRef<'nrows, 'ncols, 'a, I, E: Entity> {
10688            symbolic: SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>,
10689            values: SliceGroup<'a, E>,
10690        }
10691        /// Mutable sparse matrix view with dimensions equal to the values tied to `('nrows,
10692        /// 'ncols)`, in column-major order.
10693        pub struct SparseColMatMut<'nrows, 'ncols, 'a, I, E: Entity> {
10694            symbolic: SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>,
10695            values: SliceGroupMut<'a, E>,
10696        }
10697
10698        impl<'nrows, 'ncols, 'a, I: Index> SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I> {
10699            /// Returns a new symbolic structure after checking that its dimensions match the
10700            /// dimensions tied to `('nrows, 'ncols)`.
10701            #[inline]
10702            pub fn new(
10703                inner: crate::sparse::SymbolicSparseColMatRef<'a, I>,
10704                nrows: Size<'nrows>,
10705                ncols: Size<'ncols>,
10706            ) -> Self {
10707                assert!(all(
10708                    inner.nrows() == nrows.into_inner(),
10709                    inner.ncols() == ncols.into_inner(),
10710                ));
10711                Self(Branded {
10712                    __marker: PhantomData,
10713                    inner: Branded {
10714                        __marker: PhantomData,
10715                        inner,
10716                    },
10717                })
10718            }
10719
10720            /// Returns the unconstrained symbolic structure.
10721            #[inline]
10722            pub fn into_inner(self) -> crate::sparse::SymbolicSparseColMatRef<'a, I> {
10723                self.0.inner.inner
10724            }
10725
10726            /// Returns the number of rows of the matrix.
10727            #[inline]
10728            pub fn nrows(&self) -> Size<'nrows> {
10729                unsafe { Size::new_raw_unchecked(self.0.inner.inner.nrows()) }
10730            }
10731
10732            /// Returns the number of columns of the matrix.
10733            #[inline]
10734            pub fn ncols(&self) -> Size<'ncols> {
10735                unsafe { Size::new_raw_unchecked(self.0.inner.inner.ncols()) }
10736            }
10737
10738            #[inline]
10739            #[track_caller]
10740            #[doc(hidden)]
10741            pub fn col_range(&self, j: Idx<'ncols, usize>) -> Range<usize> {
10742                unsafe { self.into_inner().col_range_unchecked(j.into_inner()) }
10743            }
10744
10745            /// Returns the row indices in column `j`.
10746            #[inline]
10747            #[track_caller]
10748            pub fn row_indices_of_col_raw(&self, j: Idx<'ncols, usize>) -> &'a [Idx<'nrows, I>] {
10749                unsafe {
10750                    &*(__get_unchecked(self.into_inner().row_indices(), self.col_range(j))
10751                        as *const [I] as *const [Idx<'_, I>])
10752                }
10753            }
10754
10755            /// Returns the row indices in column `j`.
10756            #[inline]
10757            #[track_caller]
10758            pub fn row_indices_of_col(
10759                &self,
10760                j: Idx<'ncols, usize>,
10761            ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = Idx<'nrows, usize>>
10762            {
10763                unsafe {
10764                    __get_unchecked(
10765                        self.into_inner().row_indices(),
10766                        self.into_inner().col_range_unchecked(j.into_inner()),
10767                    )
10768                    .iter()
10769                    .map(
10770                        #[inline(always)]
10771                        move |&row| Idx::new_raw_unchecked(row.zx()),
10772                    )
10773                }
10774            }
10775        }
10776
10777        impl<'nrows, 'ncols, 'a, I: Index, E: Entity> SparseColMatRef<'nrows, 'ncols, 'a, I, E> {
10778            /// Returns a new matrix view after checking that its dimensions match the
10779            /// dimensions tied to `('nrows, 'ncols)`.
10780            pub fn new(
10781                inner: crate::sparse::SparseColMatRef<'a, I, E>,
10782                nrows: Size<'nrows>,
10783                ncols: Size<'ncols>,
10784            ) -> Self {
10785                assert!(all(
10786                    inner.nrows() == nrows.into_inner(),
10787                    inner.ncols() == ncols.into_inner(),
10788                ));
10789                Self {
10790                    symbolic: SymbolicSparseColMatRef::new(inner.symbolic(), nrows, ncols),
10791                    values: SliceGroup::new(inner.values()),
10792                }
10793            }
10794
10795            /// Returns the unconstrained matrix.
10796            #[inline]
10797            pub fn into_inner(self) -> crate::sparse::SparseColMatRef<'a, I, E> {
10798                crate::sparse::SparseColMatRef::new(
10799                    self.symbolic.into_inner(),
10800                    self.values.into_inner(),
10801                )
10802            }
10803
10804            /// Returns the values in column `j`.
10805            #[inline]
10806            pub fn values_of_col(&self, j: Idx<'ncols, usize>) -> GroupFor<E, &'a [E::Unit]> {
10807                unsafe {
10808                    self.values
10809                        .subslice_unchecked(self.col_range(j))
10810                        .into_inner()
10811                }
10812            }
10813        }
10814
10815        impl<'nrows, 'ncols, 'a, I: Index, E: Entity> SparseColMatMut<'nrows, 'ncols, 'a, I, E> {
10816            /// Returns a new matrix view after checking that its dimensions match the
10817            /// dimensions tied to `('nrows, 'ncols)`.
10818            pub fn new(
10819                inner: crate::sparse::SparseColMatMut<'a, I, E>,
10820                nrows: Size<'nrows>,
10821                ncols: Size<'ncols>,
10822            ) -> Self {
10823                assert!(all(
10824                    inner.nrows() == nrows.into_inner(),
10825                    inner.ncols() == ncols.into_inner(),
10826                ));
10827                Self {
10828                    symbolic: SymbolicSparseColMatRef::new(inner.symbolic(), nrows, ncols),
10829                    values: SliceGroupMut::new(inner.values_mut()),
10830                }
10831            }
10832
10833            /// Returns the unconstrained matrix.
10834            #[inline]
10835            pub fn into_inner(self) -> crate::sparse::SparseColMatMut<'a, I, E> {
10836                crate::sparse::SparseColMatMut::new(
10837                    self.symbolic.into_inner(),
10838                    self.values.into_inner(),
10839                )
10840            }
10841
10842            /// Returns the values in column `j`.
10843            #[inline]
10844            pub fn values_of_col_mut(
10845                &mut self,
10846                j: Idx<'ncols, usize>,
10847            ) -> GroupFor<E, &'_ mut [E::Unit]> {
10848                unsafe {
10849                    let range = self.col_range(j);
10850                    self.values.rb_mut().subslice_unchecked(range).into_inner()
10851                }
10852            }
10853        }
10854
10855        impl<I, E: Entity> Copy for SparseColMatRef<'_, '_, '_, I, E> {}
10856        impl<I, E: Entity> Clone for SparseColMatRef<'_, '_, '_, I, E> {
10857            #[inline]
10858            fn clone(&self) -> Self {
10859                *self
10860            }
10861        }
10862        impl<I> Copy for SymbolicSparseColMatRef<'_, '_, '_, I> {}
10863        impl<I> Clone for SymbolicSparseColMatRef<'_, '_, '_, I> {
10864            #[inline]
10865            fn clone(&self) -> Self {
10866                *self
10867            }
10868        }
10869
10870        impl<'nrows, 'ncols, 'a, I, E: Entity> core::ops::Deref
10871            for SparseColMatRef<'nrows, 'ncols, 'a, I, E>
10872        {
10873            type Target = SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>;
10874
10875            #[inline]
10876            fn deref(&self) -> &Self::Target {
10877                &self.symbolic
10878            }
10879        }
10880
10881        impl<'nrows, 'ncols, 'a, I, E: Entity> core::ops::Deref
10882            for SparseColMatMut<'nrows, 'ncols, 'a, I, E>
10883        {
10884            type Target = SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>;
10885
10886            #[inline]
10887            fn deref(&self) -> &Self::Target {
10888                &self.symbolic
10889            }
10890        }
10891
10892        impl<'short, 'nrows, 'ncols, 'a, I, E: Entity> ReborrowMut<'short>
10893            for SparseColMatRef<'nrows, 'ncols, 'a, I, E>
10894        {
10895            type Target = SparseColMatRef<'nrows, 'ncols, 'short, I, E>;
10896
10897            #[inline]
10898            fn rb_mut(&'short mut self) -> Self::Target {
10899                *self
10900            }
10901        }
10902
10903        impl<'short, 'nrows, 'ncols, 'a, I, E: Entity> Reborrow<'short>
10904            for SparseColMatRef<'nrows, 'ncols, 'a, I, E>
10905        {
10906            type Target = SparseColMatRef<'nrows, 'ncols, 'short, I, E>;
10907
10908            #[inline]
10909            fn rb(&'short self) -> Self::Target {
10910                *self
10911            }
10912        }
10913
10914        impl<'nrows, 'ncols, 'a, I, E: Entity> IntoConst for SparseColMatRef<'nrows, 'ncols, 'a, I, E> {
10915            type Target = SparseColMatRef<'nrows, 'ncols, 'a, I, E>;
10916
10917            #[inline]
10918            fn into_const(self) -> Self::Target {
10919                self
10920            }
10921        }
10922
10923        impl<'short, 'nrows, 'ncols, 'a, I, E: Entity> ReborrowMut<'short>
10924            for SparseColMatMut<'nrows, 'ncols, 'a, I, E>
10925        {
10926            type Target = SparseColMatMut<'nrows, 'ncols, 'short, I, E>;
10927
10928            #[inline]
10929            fn rb_mut(&'short mut self) -> Self::Target {
10930                SparseColMatMut::<'nrows, 'ncols, 'short, I, E> {
10931                    symbolic: self.symbolic,
10932                    values: self.values.rb_mut(),
10933                }
10934            }
10935        }
10936
10937        impl<'short, 'nrows, 'ncols, 'a, I, E: Entity> Reborrow<'short>
10938            for SparseColMatMut<'nrows, 'ncols, 'a, I, E>
10939        {
10940            type Target = SparseColMatRef<'nrows, 'ncols, 'short, I, E>;
10941
10942            #[inline]
10943            fn rb(&'short self) -> Self::Target {
10944                SparseColMatRef::<'nrows, 'ncols, 'short, I, E> {
10945                    symbolic: self.symbolic,
10946                    values: self.values.rb(),
10947                }
10948            }
10949        }
10950
10951        impl<'nrows, 'ncols, 'a, I, E: Entity> IntoConst for SparseColMatMut<'nrows, 'ncols, 'a, I, E> {
10952            type Target = SparseColMatRef<'nrows, 'ncols, 'a, I, E>;
10953
10954            #[inline]
10955            fn into_const(self) -> Self::Target {
10956                SparseColMatRef::<'nrows, 'ncols, 'a, I, E> {
10957                    symbolic: self.symbolic,
10958                    values: self.values.into_const(),
10959                }
10960            }
10961        }
10962    }
10963
10964    /// Group helpers with compile-time checks.
10965    pub mod group_helpers {
10966        use super::*;
10967        use crate::{
10968            assert,
10969            group_helpers::{SliceGroup, SliceGroupMut},
10970        };
10971        use core::ops::Range;
10972
10973        /// Immutable array group of length equal to the value tied to `'n`.
10974        pub struct ArrayGroup<'n, 'a, E: Entity>(Branded<'n, SliceGroup<'a, E>>);
10975        /// Mutable array group of length equal to the value tied to `'n`.
10976        pub struct ArrayGroupMut<'n, 'a, E: Entity>(Branded<'n, SliceGroupMut<'a, E>>);
10977
10978        impl<E: Entity> Debug for ArrayGroup<'_, '_, E> {
10979            #[inline]
10980            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10981                self.0.inner.fmt(f)
10982            }
10983        }
10984        impl<E: Entity> Debug for ArrayGroupMut<'_, '_, E> {
10985            #[inline]
10986            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10987                self.0.inner.fmt(f)
10988            }
10989        }
10990
10991        impl<E: Entity> Copy for ArrayGroup<'_, '_, E> {}
10992        impl<E: Entity> Clone for ArrayGroup<'_, '_, E> {
10993            #[inline]
10994            fn clone(&self) -> Self {
10995                *self
10996            }
10997        }
10998
10999        impl<'short, 'n, 'a, E: Entity> reborrow::ReborrowMut<'short> for ArrayGroup<'n, 'a, E> {
11000            type Target = ArrayGroup<'n, 'short, E>;
11001
11002            #[inline]
11003            fn rb_mut(&'short mut self) -> Self::Target {
11004                *self
11005            }
11006        }
11007
11008        impl<'short, 'n, 'a, E: Entity> reborrow::Reborrow<'short> for ArrayGroup<'n, 'a, E> {
11009            type Target = ArrayGroup<'n, 'short, E>;
11010
11011            #[inline]
11012            fn rb(&'short self) -> Self::Target {
11013                *self
11014            }
11015        }
11016
11017        impl<'short, 'n, 'a, E: Entity> reborrow::ReborrowMut<'short> for ArrayGroupMut<'n, 'a, E> {
11018            type Target = ArrayGroupMut<'n, 'short, E>;
11019
11020            #[inline]
11021            fn rb_mut(&'short mut self) -> Self::Target {
11022                ArrayGroupMut(Branded {
11023                    __marker: PhantomData,
11024                    inner: self.0.inner.rb_mut(),
11025                })
11026            }
11027        }
11028
11029        impl<'short, 'n, 'a, E: Entity> reborrow::Reborrow<'short> for ArrayGroupMut<'n, 'a, E> {
11030            type Target = ArrayGroup<'n, 'short, E>;
11031
11032            #[inline]
11033            fn rb(&'short self) -> Self::Target {
11034                ArrayGroup(Branded {
11035                    __marker: PhantomData,
11036                    inner: self.0.inner.rb(),
11037                })
11038            }
11039        }
11040
11041        impl<'n, 'a, E: Entity> ArrayGroupMut<'n, 'a, E> {
11042            /// Returns an array group with length after checking that its length matches
11043            /// the value tied to `'n`.
11044            #[inline]
11045            pub fn new(slice: GroupFor<E, &'a mut [E::Unit]>, len: Size<'n>) -> Self {
11046                let slice = SliceGroupMut::<'_, E>::new(slice);
11047                assert!(slice.rb().len() == len.into_inner());
11048                ArrayGroupMut(Branded {
11049                    __marker: PhantomData,
11050                    inner: slice,
11051                })
11052            }
11053
11054            /// Returns the unconstrained slice.
11055            #[inline]
11056            pub fn into_slice(self) -> GroupFor<E, &'a mut [E::Unit]> {
11057                self.0.inner.into_inner()
11058            }
11059
11060            /// Returns a subslice at from the range start to its end.
11061            #[inline]
11062            pub fn subslice(
11063                self,
11064                range: Range<IdxInclusive<'n, usize>>,
11065            ) -> GroupFor<E, &'a mut [E::Unit]> {
11066                unsafe {
11067                    SliceGroupMut::<'_, E>::new(self.into_slice())
11068                        .subslice_unchecked(range.start.into_inner()..range.end.into_inner())
11069                        .into_inner()
11070                }
11071            }
11072
11073            /// Read the element at position `j`.
11074            #[inline]
11075            pub fn read(&self, j: Idx<'n, usize>) -> E {
11076                self.rb().read(j)
11077            }
11078
11079            /// Write `value` to the location at position `j`.
11080            #[inline]
11081            pub fn write(&mut self, j: Idx<'n, usize>, value: E) {
11082                unsafe {
11083                    SliceGroupMut::new(self.rb_mut().into_slice())
11084                        .write_unchecked(j.into_inner(), value)
11085                }
11086            }
11087        }
11088
11089        impl<'n, 'a, E: Entity> ArrayGroup<'n, 'a, E> {
11090            /// Returns an array group with length after checking that its length matches
11091            /// the value tied to `'n`.
11092            #[inline]
11093            pub fn new(slice: GroupFor<E, &'a [E::Unit]>, len: Size<'n>) -> Self {
11094                let slice = SliceGroup::<'_, E>::new(slice);
11095                assert!(slice.rb().len() == len.into_inner());
11096                ArrayGroup(Branded {
11097                    __marker: PhantomData,
11098                    inner: slice,
11099                })
11100            }
11101
11102            /// Returns the unconstrained slice.
11103            #[inline]
11104            pub fn into_slice(self) -> GroupFor<E, &'a [E::Unit]> {
11105                self.0.inner.into_inner()
11106            }
11107
11108            /// Returns a subslice at from the range start to its end.
11109            #[inline]
11110            pub fn subslice(
11111                self,
11112                range: Range<IdxInclusive<'n, usize>>,
11113            ) -> GroupFor<E, &'a [E::Unit]> {
11114                unsafe {
11115                    SliceGroup::<'_, E>::new(self.into_slice())
11116                        .subslice_unchecked(range.start.into_inner()..range.end.into_inner())
11117                        .into_inner()
11118                }
11119            }
11120
11121            /// Read the element at position `j`.
11122            #[inline]
11123            pub fn read(&self, j: Idx<'n, usize>) -> E {
11124                unsafe { SliceGroup::new(self.into_slice()).read_unchecked(j.into_inner()) }
11125            }
11126        }
11127    }
11128
11129    impl<'size> Size<'size> {
11130        /// Create a new [`Size`] with a lifetime tied to `n`.
11131        #[track_caller]
11132        #[inline]
11133        pub fn with<R>(n: usize, f: impl for<'n> FnOnce(Size<'n>) -> R) -> R {
11134            f(Size(Branded {
11135                __marker: PhantomData,
11136                inner: n,
11137            }))
11138        }
11139
11140        /// Create two new [`Size`] with lifetimes tied to `m` and `n`.
11141        #[track_caller]
11142        #[inline]
11143        pub fn with2<R>(
11144            m: usize,
11145            n: usize,
11146            f: impl for<'m, 'n> FnOnce(Size<'m>, Size<'n>) -> R,
11147        ) -> R {
11148            f(
11149                Size(Branded {
11150                    __marker: PhantomData,
11151                    inner: m,
11152                }),
11153                Size(Branded {
11154                    __marker: PhantomData,
11155                    inner: n,
11156                }),
11157            )
11158        }
11159
11160        /// Create a new [`Size`] tied to the lifetime `'n`.
11161        #[inline]
11162        pub unsafe fn new_raw_unchecked(n: usize) -> Self {
11163            Size(Branded {
11164                __marker: PhantomData,
11165                inner: n,
11166            })
11167        }
11168
11169        /// Returns the unconstrained value.
11170        #[inline]
11171        pub fn into_inner(self) -> usize {
11172            self.0.inner
11173        }
11174
11175        /// Returns an iterator of the indices smaller than `self`.
11176        #[inline]
11177        pub fn indices(self) -> impl DoubleEndedIterator<Item = Idx<'size, usize>> {
11178            (0..self.0.inner).map(|i| unsafe { Idx::new_raw_unchecked(i) })
11179        }
11180
11181        /// Check that the index is bounded by `self`, or panic otherwise.
11182        #[track_caller]
11183        #[inline]
11184        pub fn check<I: Index>(self, idx: I) -> Idx<'size, I> {
11185            Idx::new_checked(idx, self)
11186        }
11187
11188        /// Check that the index is bounded by `self`, or return `None` otherwise.
11189        #[inline]
11190        pub fn try_check<I: Index>(self, idx: I) -> Option<Idx<'size, I>> {
11191            if idx.zx() < self.into_inner() {
11192                Some(Idx(Branded {
11193                    __marker: PhantomData,
11194                    inner: idx,
11195                }))
11196            } else {
11197                None
11198            }
11199        }
11200    }
11201
11202    impl<'n> Idx<'n, usize> {
11203        /// Truncate `self` to a smaller type `I`.
11204        pub fn truncate<I: Index>(self) -> Idx<'n, I> {
11205            unsafe { Idx::new_raw_unchecked(I::truncate(self.into_inner())) }
11206        }
11207    }
11208
11209    impl<'n, I: Index> Idx<'n, I> {
11210        /// Returns a new index after asserting that it's bounded by `size`.
11211        #[track_caller]
11212        #[inline]
11213        pub fn new_checked(idx: I, size: Size<'n>) -> Self {
11214            assert!(idx.zx() < size.into_inner());
11215            Self(Branded {
11216                __marker: PhantomData,
11217                inner: idx,
11218            })
11219        }
11220        /// Returns a new index without asserting that it's bounded by `size`.
11221        #[track_caller]
11222        #[inline]
11223        pub unsafe fn new_unchecked(idx: I, size: Size<'n>) -> Self {
11224            debug_assert!(idx.zx() < size.into_inner());
11225            Self(Branded {
11226                __marker: PhantomData,
11227                inner: idx,
11228            })
11229        }
11230
11231        /// Returns a new index without asserting that it's bounded by the value tied to the
11232        /// lifetime `'n`.
11233        #[inline]
11234        pub unsafe fn new_raw_unchecked(idx: I) -> Self {
11235            Self(Branded {
11236                __marker: PhantomData,
11237                inner: idx,
11238            })
11239        }
11240
11241        /// Returns the unconstrained value.
11242        #[inline]
11243        pub fn into_inner(self) -> I {
11244            self.0.inner
11245        }
11246
11247        /// Zero extend the value.
11248        #[inline]
11249        pub fn zx(self) -> Idx<'n, usize> {
11250            unsafe { Idx::new_raw_unchecked(self.0.inner.zx()) }
11251        }
11252
11253        /// Unimplemented: Sign extend the value.
11254        #[inline]
11255        pub fn sx(self) -> ! {
11256            unimplemented!()
11257        }
11258
11259        /// Returns the index, bounded inclusively by the value tied to `'n`.
11260        #[inline]
11261        pub fn to_inclusive(self) -> IdxInclusive<'n, I> {
11262            unsafe { IdxInclusive::new_raw_unchecked(self.into_inner()) }
11263        }
11264        /// Returns the next index, bounded inclusively by the value tied to `'n`.
11265        #[inline]
11266        pub fn next(self) -> IdxInclusive<'n, I> {
11267            unsafe { IdxInclusive::new_raw_unchecked(self.into_inner() + I::truncate(1)) }
11268        }
11269
11270        /// Assert that the values of `slice` are all bounded by `size`.
11271        #[track_caller]
11272        #[inline]
11273        pub fn from_slice_mut_checked<'a>(
11274            slice: &'a mut [I],
11275            size: Size<'n>,
11276        ) -> &'a mut [Idx<'n, I>] {
11277            Self::from_slice_ref_checked(slice, size);
11278            unsafe { &mut *(slice as *mut _ as *mut _) }
11279        }
11280
11281        /// Assume that the values of `slice` are all bounded by the value tied to `'n`.
11282        #[track_caller]
11283        #[inline]
11284        pub unsafe fn from_slice_mut_unchecked<'a>(slice: &'a mut [I]) -> &'a mut [Idx<'n, I>] {
11285            unsafe { &mut *(slice as *mut _ as *mut _) }
11286        }
11287
11288        /// Assert that the values of `slice` are all bounded by `size`.
11289        #[track_caller]
11290        pub fn from_slice_ref_checked<'a>(slice: &'a [I], size: Size<'n>) -> &'a [Idx<'n, I>] {
11291            for &idx in slice {
11292                Self::new_checked(idx, size);
11293            }
11294            unsafe { &*(slice as *const _ as *const _) }
11295        }
11296
11297        /// Assume that the values of `slice` are all bounded by the value tied to `'n`.
11298        #[track_caller]
11299        #[inline]
11300        pub unsafe fn from_slice_ref_unchecked<'a>(slice: &'a [I]) -> &'a [Idx<'n, I>] {
11301            unsafe { &*(slice as *const _ as *const _) }
11302        }
11303    }
11304
11305    impl<'n, I: Index> MaybeIdx<'n, I> {
11306        /// Returns an index value.
11307        #[inline]
11308        pub fn from_index(idx: Idx<'n, I>) -> Self {
11309            unsafe { Self::new_raw_unchecked(idx.into_inner()) }
11310        }
11311        /// Returns a `None` value.
11312        #[inline]
11313        pub fn none() -> Self {
11314            unsafe { Self::new_raw_unchecked(I::truncate(usize::MAX)) }
11315        }
11316
11317        /// Returns a constrained index value if `idx` is nonnegative, `None` otherwise.
11318        #[inline]
11319        pub fn new_checked(idx: I::Signed, size: Size<'n>) -> Self {
11320            assert!((idx.sx() as isize) < size.into_inner() as isize);
11321            Self(Branded {
11322                __marker: PhantomData,
11323                inner: I::from_signed(idx),
11324            })
11325        }
11326
11327        /// Returns a constrained index value if `idx` is nonnegative, `None` otherwise.
11328        #[inline]
11329        pub unsafe fn new_unchecked(idx: I::Signed, size: Size<'n>) -> Self {
11330            debug_assert!((idx.sx() as isize) < size.into_inner() as isize);
11331            Self(Branded {
11332                __marker: PhantomData,
11333                inner: I::from_signed(idx),
11334            })
11335        }
11336
11337        /// Returns a constrained index value if `idx` is nonnegative, `None` otherwise.
11338        #[inline]
11339        pub unsafe fn new_raw_unchecked(idx: I) -> Self {
11340            Self(Branded {
11341                __marker: PhantomData,
11342                inner: idx,
11343            })
11344        }
11345
11346        /// Returns the inner value.
11347        #[inline]
11348        pub fn into_inner(self) -> I {
11349            self.0.inner
11350        }
11351
11352        /// Returns the index if available, or `None` otherwise.
11353        #[inline]
11354        pub fn idx(self) -> Option<Idx<'n, I>> {
11355            if self.0.inner.to_signed() >= I::Signed::truncate(0) {
11356                Some(unsafe { Idx::new_raw_unchecked(self.into_inner()) })
11357            } else {
11358                None
11359            }
11360        }
11361
11362        /// Unimplemented: Zero extend the value.
11363        #[inline]
11364        pub fn zx(self) -> ! {
11365            unimplemented!()
11366        }
11367
11368        /// Sign extend the value.
11369        #[inline]
11370        pub fn sx(self) -> MaybeIdx<'n, usize> {
11371            unsafe { MaybeIdx::new_raw_unchecked(self.0.inner.to_signed().sx()) }
11372        }
11373
11374        /// Assert that the values of `slice` are all bounded by `size`.
11375        #[track_caller]
11376        #[inline]
11377        pub fn from_slice_mut_checked<'a>(
11378            slice: &'a mut [I::Signed],
11379            size: Size<'n>,
11380        ) -> &'a mut [MaybeIdx<'n, I>] {
11381            Self::from_slice_ref_checked(slice, size);
11382            unsafe { &mut *(slice as *mut _ as *mut _) }
11383        }
11384
11385        /// Assume that the values of `slice` are all bounded by the value tied to `'n`.
11386        #[track_caller]
11387        #[inline]
11388        pub unsafe fn from_slice_mut_unchecked<'a>(
11389            slice: &'a mut [I::Signed],
11390        ) -> &'a mut [MaybeIdx<'n, I>] {
11391            unsafe { &mut *(slice as *mut _ as *mut _) }
11392        }
11393
11394        /// Assert that the values of `slice` are all bounded by `size`.
11395        #[track_caller]
11396        pub fn from_slice_ref_checked<'a>(
11397            slice: &'a [I::Signed],
11398            size: Size<'n>,
11399        ) -> &'a [MaybeIdx<'n, I>] {
11400            for &idx in slice {
11401                Self::new_checked(idx, size);
11402            }
11403            unsafe { &*(slice as *const _ as *const _) }
11404        }
11405
11406        /// Convert a constrained slice to an unconstrained one.
11407        #[track_caller]
11408        pub fn as_slice_ref<'a>(slice: &'a [MaybeIdx<'n, I>]) -> &'a [I::Signed] {
11409            unsafe { &*(slice as *const _ as *const _) }
11410        }
11411
11412        /// Assume that the values of `slice` are all bounded by the value tied to `'n`.
11413        #[track_caller]
11414        #[inline]
11415        pub unsafe fn from_slice_ref_unchecked<'a>(
11416            slice: &'a [I::Signed],
11417        ) -> &'a [MaybeIdx<'n, I>] {
11418            unsafe { &*(slice as *const _ as *const _) }
11419        }
11420    }
11421
11422    impl<'n> IdxInclusive<'n, usize> {
11423        /// Returns an iterator over constrained indices from `0` to `self` (exclusive).
11424        #[inline]
11425        pub fn range_to(self, last: Self) -> impl DoubleEndedIterator<Item = Idx<'n, usize>> {
11426            (*self..*last).map(
11427                #[inline(always)]
11428                |idx| unsafe { Idx::new_raw_unchecked(idx) },
11429            )
11430        }
11431    }
11432
11433    impl<'n, I: Index> IdxInclusive<'n, I> {
11434        /// Returns a constrained inclusive index after checking that it's bounded (inclusively) by
11435        /// `size`.
11436        #[inline]
11437        pub fn new_checked(idx: I, size: Size<'n>) -> Self {
11438            assert!(idx.zx() <= size.into_inner());
11439            Self(Branded {
11440                __marker: PhantomData,
11441                inner: idx,
11442            })
11443        }
11444        /// Returns a constrained inclusive index, assuming that it's bounded (inclusively) by
11445        /// `size`.
11446        #[inline]
11447        pub unsafe fn new_unchecked(idx: I, size: Size<'n>) -> Self {
11448            debug_assert!(idx.zx() <= size.into_inner());
11449            Self(Branded {
11450                __marker: PhantomData,
11451                inner: idx,
11452            })
11453        }
11454
11455        /// Returns a constrained inclusive index, assuming that it's bounded (inclusively) by
11456        /// the size tied to `'n`.
11457        #[inline]
11458        pub unsafe fn new_raw_unchecked(idx: I) -> Self {
11459            Self(Branded {
11460                __marker: PhantomData,
11461                inner: idx,
11462            })
11463        }
11464
11465        /// Returns the unconstrained value.
11466        #[inline]
11467        pub fn into_inner(self) -> I {
11468            self.0.inner
11469        }
11470
11471        /// Unimplemented: Sign extend the value.
11472        #[inline]
11473        pub fn sx(self) -> ! {
11474            unimplemented!()
11475        }
11476        /// Unimplemented: Zero extend the value.
11477        #[inline]
11478        pub fn zx(self) -> ! {
11479            unimplemented!()
11480        }
11481    }
11482
11483    impl<'n, T> Array<'n, T> {
11484        /// Returns a constrained array after checking that its length matches `size`.
11485        #[inline]
11486        #[track_caller]
11487        pub fn from_ref<'a>(slice: &'a [T], size: Size<'n>) -> &'a Self {
11488            assert!(slice.len() == size.into_inner());
11489            unsafe { &*(slice as *const [T] as *const Self) }
11490        }
11491
11492        /// Returns a constrained array after checking that its length matches `size`.
11493        #[inline]
11494        #[track_caller]
11495        pub fn from_mut<'a>(slice: &'a mut [T], size: Size<'n>) -> &'a mut Self {
11496            assert!(slice.len() == size.into_inner());
11497            unsafe { &mut *(slice as *mut [T] as *mut Self) }
11498        }
11499
11500        /// Returns the unconstrained slice.
11501        #[inline]
11502        #[track_caller]
11503        pub fn as_ref(&self) -> &[T] {
11504            unsafe { &*(self as *const _ as *const _) }
11505        }
11506
11507        /// Returns the unconstrained slice.
11508        #[inline]
11509        #[track_caller]
11510        pub fn as_mut<'a>(&mut self) -> &'a mut [T] {
11511            unsafe { &mut *(self as *mut _ as *mut _) }
11512        }
11513
11514        /// Returns the length of `self`.
11515        #[inline]
11516        pub fn len(&self) -> Size<'n> {
11517            unsafe { Size::new_raw_unchecked(self.0.inner.len()) }
11518        }
11519    }
11520
11521    impl<'nrows, 'ncols, 'a, E: Entity> MatRef<'nrows, 'ncols, 'a, E> {
11522        /// Returns a new matrix view after checking that its dimensions match the
11523        /// dimensions tied to `('nrows, 'ncols)`.
11524        #[inline]
11525        #[track_caller]
11526        pub fn new(inner: super::MatRef<'a, E>, nrows: Size<'nrows>, ncols: Size<'ncols>) -> Self {
11527            assert!(all(
11528                inner.nrows() == nrows.into_inner(),
11529                inner.ncols() == ncols.into_inner(),
11530            ));
11531            Self(Branded {
11532                __marker: PhantomData,
11533                inner: Branded {
11534                    __marker: PhantomData,
11535                    inner,
11536                },
11537            })
11538        }
11539
11540        /// Returns the number of rows of the matrix.
11541        #[inline]
11542        pub fn nrows(&self) -> Size<'nrows> {
11543            unsafe { Size::new_raw_unchecked(self.0.inner.inner.nrows()) }
11544        }
11545
11546        /// Returns the number of columns of the matrix.
11547        #[inline]
11548        pub fn ncols(&self) -> Size<'ncols> {
11549            unsafe { Size::new_raw_unchecked(self.0.inner.inner.ncols()) }
11550        }
11551
11552        /// Returns the unconstrained matrix.
11553        #[inline]
11554        pub fn into_inner(self) -> super::MatRef<'a, E> {
11555            self.0.inner.inner
11556        }
11557
11558        /// Returns the element at position `(i, j)`.
11559        #[inline]
11560        #[track_caller]
11561        pub fn read(&self, i: Idx<'nrows, usize>, j: Idx<'ncols, usize>) -> E {
11562            unsafe {
11563                self.0
11564                    .inner
11565                    .inner
11566                    .read_unchecked(i.into_inner(), j.into_inner())
11567            }
11568        }
11569    }
11570
11571    impl<'nrows, 'ncols, 'a, E: Entity> MatMut<'nrows, 'ncols, 'a, E> {
11572        /// Returns a new matrix view after checking that its dimensions match the
11573        /// dimensions tied to `('nrows, 'ncols)`.
11574        #[inline]
11575        #[track_caller]
11576        pub fn new(inner: super::MatMut<'a, E>, nrows: Size<'nrows>, ncols: Size<'ncols>) -> Self {
11577            assert!(all(
11578                inner.nrows() == nrows.into_inner(),
11579                inner.ncols() == ncols.into_inner(),
11580            ));
11581            Self(Branded {
11582                __marker: PhantomData,
11583                inner: Branded {
11584                    __marker: PhantomData,
11585                    inner,
11586                },
11587            })
11588        }
11589
11590        /// Returns the number of rows of the matrix.
11591        #[inline]
11592        pub fn nrows(&self) -> Size<'nrows> {
11593            unsafe { Size::new_raw_unchecked(self.0.inner.inner.nrows()) }
11594        }
11595
11596        /// Returns the number of columns of the matrix.
11597        #[inline]
11598        pub fn ncols(&self) -> Size<'ncols> {
11599            unsafe { Size::new_raw_unchecked(self.0.inner.inner.ncols()) }
11600        }
11601
11602        /// Returns the unconstrained matrix.
11603        #[inline]
11604        pub fn into_inner(self) -> super::MatMut<'a, E> {
11605            self.0.inner.inner
11606        }
11607
11608        /// Returns the element at position `(i, j)`.
11609        #[inline]
11610        #[track_caller]
11611        pub fn read(&self, i: Idx<'nrows, usize>, j: Idx<'ncols, usize>) -> E {
11612            unsafe {
11613                self.0
11614                    .inner
11615                    .inner
11616                    .read_unchecked(i.into_inner(), j.into_inner())
11617            }
11618        }
11619
11620        /// Writes `value` to the location at position `(i, j)`.
11621        #[inline]
11622        #[track_caller]
11623        pub fn write(&mut self, i: Idx<'nrows, usize>, j: Idx<'ncols, usize>, value: E) {
11624            unsafe {
11625                self.0
11626                    .inner
11627                    .inner
11628                    .write_unchecked(i.into_inner(), j.into_inner(), value)
11629            };
11630        }
11631    }
11632
11633    impl<E: Entity> Clone for MatRef<'_, '_, '_, E> {
11634        #[inline]
11635        fn clone(&self) -> Self {
11636            *self
11637        }
11638    }
11639    impl<E: Entity> Copy for MatRef<'_, '_, '_, E> {}
11640
11641    impl<'nrows, 'ncols, 'a, E: Entity> IntoConst for MatRef<'nrows, 'ncols, 'a, E> {
11642        type Target = MatRef<'nrows, 'ncols, 'a, E>;
11643        #[inline]
11644        fn into_const(self) -> Self::Target {
11645            self
11646        }
11647    }
11648    impl<'nrows, 'ncols, 'a, 'short, E: Entity> Reborrow<'short> for MatRef<'nrows, 'ncols, 'a, E> {
11649        type Target = MatRef<'nrows, 'ncols, 'short, E>;
11650        #[inline]
11651        fn rb(&'short self) -> Self::Target {
11652            *self
11653        }
11654    }
11655    impl<'nrows, 'ncols, 'a, 'short, E: Entity> ReborrowMut<'short> for MatRef<'nrows, 'ncols, 'a, E> {
11656        type Target = MatRef<'nrows, 'ncols, 'short, E>;
11657        #[inline]
11658        fn rb_mut(&'short mut self) -> Self::Target {
11659            *self
11660        }
11661    }
11662
11663    impl<'nrows, 'ncols, 'a, E: Entity> IntoConst for MatMut<'nrows, 'ncols, 'a, E> {
11664        type Target = MatRef<'nrows, 'ncols, 'a, E>;
11665        #[inline]
11666        fn into_const(self) -> Self::Target {
11667            let inner = self.0.inner.inner.into_const();
11668            MatRef(Branded {
11669                __marker: PhantomData,
11670                inner: Branded {
11671                    __marker: PhantomData,
11672                    inner,
11673                },
11674            })
11675        }
11676    }
11677    impl<'nrows, 'ncols, 'a, 'short, E: Entity> Reborrow<'short> for MatMut<'nrows, 'ncols, 'a, E> {
11678        type Target = MatRef<'nrows, 'ncols, 'short, E>;
11679        #[inline]
11680        fn rb(&'short self) -> Self::Target {
11681            let inner = self.0.inner.inner.rb();
11682            MatRef(Branded {
11683                __marker: PhantomData,
11684                inner: Branded {
11685                    __marker: PhantomData,
11686                    inner,
11687                },
11688            })
11689        }
11690    }
11691    impl<'nrows, 'ncols, 'a, 'short, E: Entity> ReborrowMut<'short> for MatMut<'nrows, 'ncols, 'a, E> {
11692        type Target = MatMut<'nrows, 'ncols, 'short, E>;
11693        #[inline]
11694        fn rb_mut(&'short mut self) -> Self::Target {
11695            let inner = self.0.inner.inner.rb_mut();
11696            MatMut(Branded {
11697                __marker: PhantomData,
11698                inner: Branded {
11699                    __marker: PhantomData,
11700                    inner,
11701                },
11702            })
11703        }
11704    }
11705
11706    impl Debug for Size<'_> {
11707        #[inline]
11708        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11709            self.0.inner.fmt(f)
11710        }
11711    }
11712    impl<I: Debug> Debug for Idx<'_, I> {
11713        #[inline]
11714        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11715            self.0.inner.fmt(f)
11716        }
11717    }
11718    impl<I: Debug> Debug for IdxInclusive<'_, I> {
11719        #[inline]
11720        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11721            self.0.inner.fmt(f)
11722        }
11723    }
11724    impl<I: Debug + Index> Debug for MaybeIdx<'_, I> {
11725        #[inline]
11726        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11727            #[derive(Debug)]
11728            struct None;
11729
11730            match self.idx() {
11731                Some(idx) => idx.fmt(f),
11732                Option::None => None.fmt(f),
11733            }
11734        }
11735    }
11736    impl<T: Debug> Debug for Array<'_, T> {
11737        #[inline]
11738        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11739            self.0.inner.fmt(f)
11740        }
11741    }
11742    impl<E: Entity> Debug for MatRef<'_, '_, '_, E> {
11743        #[inline]
11744        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11745            self.0.inner.inner.fmt(f)
11746        }
11747    }
11748    impl<E: Entity> Debug for MatMut<'_, '_, '_, E> {
11749        #[inline]
11750        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11751            self.0.inner.inner.fmt(f)
11752        }
11753    }
11754
11755    impl<'n, T> core::ops::Index<Range<IdxInclusive<'n, usize>>> for Array<'n, T> {
11756        type Output = [T];
11757        #[track_caller]
11758        fn index(&self, idx: Range<IdxInclusive<'n, usize>>) -> &Self::Output {
11759            #[cfg(debug_assertions)]
11760            {
11761                &self.0.inner[idx.start.into_inner()..idx.end.into_inner()]
11762            }
11763            #[cfg(not(debug_assertions))]
11764            unsafe {
11765                self.0
11766                    .inner
11767                    .get_unchecked(idx.start.into_inner()..idx.end.into_inner())
11768            }
11769        }
11770    }
11771    impl<'n, T> core::ops::IndexMut<Range<IdxInclusive<'n, usize>>> for Array<'n, T> {
11772        #[track_caller]
11773        fn index_mut(&mut self, idx: Range<IdxInclusive<'n, usize>>) -> &mut Self::Output {
11774            #[cfg(debug_assertions)]
11775            {
11776                &mut self.0.inner[idx.start.into_inner()..idx.end.into_inner()]
11777            }
11778            #[cfg(not(debug_assertions))]
11779            unsafe {
11780                self.0
11781                    .inner
11782                    .get_unchecked_mut(idx.start.into_inner()..idx.end.into_inner())
11783            }
11784        }
11785    }
11786    impl<'n, T> core::ops::Index<Idx<'n, usize>> for Array<'n, T> {
11787        type Output = T;
11788        #[track_caller]
11789        fn index(&self, idx: Idx<'n, usize>) -> &Self::Output {
11790            #[cfg(debug_assertions)]
11791            {
11792                &self.0.inner[idx.into_inner()]
11793            }
11794            #[cfg(not(debug_assertions))]
11795            unsafe {
11796                self.0.inner.get_unchecked(idx.into_inner())
11797            }
11798        }
11799    }
11800    impl<'n, T> core::ops::IndexMut<Idx<'n, usize>> for Array<'n, T> {
11801        #[track_caller]
11802        fn index_mut(&mut self, idx: Idx<'n, usize>) -> &mut Self::Output {
11803            #[cfg(debug_assertions)]
11804            {
11805                &mut self.0.inner[idx.into_inner()]
11806            }
11807            #[cfg(not(debug_assertions))]
11808            unsafe {
11809                self.0.inner.get_unchecked_mut(idx.into_inner())
11810            }
11811        }
11812    }
11813}
11814
11815/// Kronecker product of two matrices.
11816///
11817/// The Kronecker product of two matrices `A` and `B` is a block matrix
11818/// `C` with the following structure:
11819///
11820/// ```text
11821/// C = [ a[(0, 0)] * B    , a[(0, 1)] * B    , ... , a[(0, n-1)] * B    ]
11822///     [ a[(1, 0)] * B    , a[(1, 1)] * B    , ... , a[(1, n-1)] * B    ]
11823///     [ ...              , ...              , ... , ...              ]
11824///     [ a[(m-1, 0)] * B  , a[(m-1, 1)] * B  , ... , a[(m-1, n-1)] * B  ]
11825/// ```
11826///
11827/// # Panics
11828///
11829/// Panics if `dst` does not have the correct dimensions. The dimensions
11830/// of `dst` must be `nrows(A) * nrows(B)` by `ncols(A) * ncols(B)`.
11831///
11832/// # Example
11833///
11834/// ```
11835/// use faer_core::{kron, mat, Mat};
11836///
11837/// let a = mat![[1.0, 2.0], [3.0, 4.0]];
11838/// let b = mat![[0.0, 5.0], [6.0, 7.0]];
11839/// let c = mat![
11840///     [0.0, 5.0, 0.0, 10.0],
11841///     [6.0, 7.0, 12.0, 14.0],
11842///     [0.0, 15.0, 0.0, 20.0],
11843///     [18.0, 21.0, 24.0, 28.0],
11844/// ];
11845/// let mut dst = Mat::new();
11846/// dst.resize_with(4, 4, |_, _| 0f64);
11847/// kron(dst.as_mut(), a.as_ref(), b.as_ref());
11848/// assert_eq!(dst, c);
11849/// ```
11850#[track_caller]
11851pub fn kron<E: ComplexField>(dst: MatMut<E>, lhs: MatRef<E>, rhs: MatRef<E>) {
11852    assert!(Some(dst.nrows()) == lhs.nrows().checked_mul(rhs.nrows()));
11853    assert!(Some(dst.ncols()) == lhs.ncols().checked_mul(rhs.ncols()));
11854
11855    let mut dst = dst;
11856    let mut lhs = lhs;
11857    let mut rhs = rhs;
11858    if dst.col_stride().unsigned_abs() < dst.row_stride().unsigned_abs() {
11859        dst = dst.transpose_mut();
11860        lhs = lhs.transpose();
11861        rhs = rhs.transpose();
11862    }
11863
11864    for lhs_j in 0..lhs.ncols() {
11865        for lhs_i in 0..lhs.nrows() {
11866            let lhs_val = lhs.read(lhs_i, lhs_j);
11867            let mut dst = dst.rb_mut().submatrix_mut(
11868                lhs_i * rhs.nrows(),
11869                lhs_j * rhs.ncols(),
11870                rhs.nrows(),
11871                rhs.ncols(),
11872            );
11873
11874            for rhs_i in 0..rhs.nrows() {
11875                for rhs_j in 0..rhs.ncols() {
11876                    // SAFETY: Bounds have been checked.
11877                    unsafe {
11878                        let rhs_val = rhs.read_unchecked(rhs_i, rhs_j);
11879                        dst.write_unchecked(rhs_i, rhs_j, lhs_val.faer_mul(rhs_val));
11880                    }
11881                }
11882            }
11883        }
11884    }
11885}
11886
11887#[inline(always)]
11888fn norm_l2_with_simd_and_offset_prologue<E: ComplexField, S: pulp::Simd>(
11889    simd: S,
11890    data: SliceGroup<'_, E>,
11891    offset: pulp::Offset<SimdMaskFor<E, S>>,
11892) -> (
11893    SimdGroupFor<E::Real, S>,
11894    SimdGroupFor<E::Real, S>,
11895    SimdGroupFor<E::Real, S>,
11896) {
11897    use group_helpers::*;
11898
11899    let simd_real = SimdFor::<E::Real, S>::new(simd);
11900    let simd = SimdFor::<E, S>::new(simd);
11901    let half_big = simd_real.splat(E::Real::faer_min_positive_sqrt_inv());
11902    let half_small = simd_real.splat(E::Real::faer_min_positive_sqrt());
11903    let zero = simd.splat(E::faer_zero());
11904    let zero_real = simd_real.splat(E::Real::faer_zero());
11905
11906    let (head, body, tail) = simd.as_aligned_simd(data, offset);
11907    let (body2, body1) = body.as_arrays::<2>();
11908
11909    let mut acc0 = simd.abs2(head.read_or(zero));
11910    let mut acc1 = zero_real;
11911
11912    let mut acc_small0 = simd.abs2(simd.scale_real(half_small, head.read_or(zero)));
11913    let mut acc_small1 = zero_real;
11914
11915    let mut acc_big0 = simd.abs2(simd.scale_real(half_big, head.read_or(zero)));
11916    let mut acc_big1 = zero_real;
11917
11918    for [x0, x1] in body2.into_ref_iter().map(RefGroup::unzip) {
11919        let x0 = x0.get();
11920        let x1 = x1.get();
11921        acc0 = simd.abs2_add_e(x0, acc0);
11922        acc1 = simd.abs2_add_e(x1, acc1);
11923
11924        acc_small0 = simd.abs2_add_e(simd.scale_real(half_small, x0), acc_small0);
11925        acc_small1 = simd.abs2_add_e(simd.scale_real(half_small, x1), acc_small1);
11926
11927        acc_big0 = simd.abs2_add_e(simd.scale_real(half_big, x0), acc_big0);
11928        acc_big1 = simd.abs2_add_e(simd.scale_real(half_big, x1), acc_big1);
11929    }
11930
11931    for x0 in body1.into_ref_iter() {
11932        let x0 = x0.get();
11933        acc0 = simd.abs2_add_e(x0, acc0);
11934        acc_small0 = simd.abs2_add_e(simd.scale_real(half_small, x0), acc_small0);
11935        acc_big0 = simd.abs2_add_e(simd.scale_real(half_big, x0), acc_big0);
11936    }
11937
11938    acc0 = simd.abs2_add_e(tail.read_or(zero), acc0);
11939    acc_small0 = simd.abs2_add_e(simd.scale_real(half_small, tail.read_or(zero)), acc_small0);
11940    acc_big0 = simd.abs2_add_e(simd.scale_real(half_big, tail.read_or(zero)), acc_big0);
11941
11942    acc0 = simd_real.add(acc0, acc1);
11943    acc_small0 = simd_real.add(acc_small0, acc_small1);
11944    acc_big0 = simd_real.add(acc_big0, acc_big1);
11945
11946    (acc_small0, acc0, acc_big0)
11947}
11948
11949#[inline(always)]
11950fn sum_with_simd_and_offset_prologue<E: ComplexField, S: pulp::Simd>(
11951    simd: S,
11952    data: SliceGroup<'_, E>,
11953    offset: pulp::Offset<SimdMaskFor<E, S>>,
11954) -> SimdGroupFor<E, S> {
11955    use group_helpers::*;
11956
11957    let simd = SimdFor::<E, S>::new(simd);
11958
11959    let zero = simd.splat(E::faer_zero());
11960
11961    let mut acc0 = zero;
11962    let mut acc1 = zero;
11963    let mut acc2 = zero;
11964    let mut acc3 = zero;
11965    let (head, body, tail) = simd.as_aligned_simd(data, offset);
11966    let (body4, body1) = body.as_arrays::<4>();
11967    let head = head.read_or(zero);
11968    acc0 = simd.add(acc0, head);
11969
11970    for [x0, x1, x2, x3] in body4.into_ref_iter().map(RefGroup::unzip) {
11971        let x0 = x0.get();
11972        let x1 = x1.get();
11973        let x2 = x2.get();
11974        let x3 = x3.get();
11975        acc0 = simd.add(acc0, x0);
11976        acc1 = simd.add(acc1, x1);
11977        acc2 = simd.add(acc2, x2);
11978        acc3 = simd.add(acc3, x3);
11979    }
11980
11981    for x0 in body1.into_ref_iter() {
11982        let x0 = x0.get();
11983        acc0 = simd.add(acc0, x0);
11984    }
11985
11986    let tail = tail.read_or(zero);
11987    acc3 = simd.add(acc3, tail);
11988
11989    acc0 = simd.add(acc0, acc1);
11990    acc2 = simd.add(acc2, acc3);
11991    simd.add(acc0, acc2)
11992}
11993
11994#[inline(always)]
11995fn norm_max_contiguous<E: RealField>(data: MatRef<'_, E>) -> E {
11996    struct Impl<'a, E: RealField> {
11997        data: MatRef<'a, E>,
11998    }
11999
12000    impl<E: RealField> pulp::WithSimd for Impl<'_, E> {
12001        type Output = E;
12002
12003        #[inline(always)]
12004        fn with_simd<S: pulp::Simd>(self, simd: S) -> Self::Output {
12005            let Self { data } = self;
12006            use group_helpers::*;
12007            let m = data.nrows();
12008            let n = data.ncols();
12009
12010            let offset = SimdFor::<E, S>::new(simd).align_offset_ptr(data.as_ptr(), m);
12011
12012            let simd = SimdFor::<E, S>::new(simd);
12013
12014            let zero = simd.splat(E::faer_zero());
12015
12016            let mut acc0 = zero;
12017            let mut acc1 = zero;
12018            let mut acc2 = zero;
12019            let mut acc3 = zero;
12020            for j in 0..n {
12021                let col = SliceGroup::<'_, E>::new(data.try_get_contiguous_col(j));
12022                let (head, body, tail) = simd.as_aligned_simd(col, offset);
12023                let (body4, body1) = body.as_arrays::<4>();
12024
12025                let head = simd.abs(head.read_or(zero));
12026                acc0 = simd.select(simd.greater_than(head, acc0), head, acc0);
12027
12028                for [x0, x1, x2, x3] in body4.into_ref_iter().map(RefGroup::unzip) {
12029                    let x0 = simd.abs(x0.get());
12030                    let x1 = simd.abs(x1.get());
12031                    let x2 = simd.abs(x2.get());
12032                    let x3 = simd.abs(x3.get());
12033                    acc0 = simd.select(simd.greater_than(x0, acc0), x0, acc0);
12034                    acc1 = simd.select(simd.greater_than(x1, acc1), x1, acc1);
12035                    acc2 = simd.select(simd.greater_than(x2, acc2), x2, acc2);
12036                    acc3 = simd.select(simd.greater_than(x3, acc3), x3, acc3);
12037                }
12038
12039                for x0 in body1.into_ref_iter() {
12040                    let x0 = simd.abs(x0.get());
12041                    acc0 = simd.select(simd.greater_than(x0, acc0), x0, acc0);
12042                }
12043
12044                let tail = simd.abs(tail.read_or(zero));
12045                acc3 = simd.select(simd.greater_than(tail, acc3), tail, acc3);
12046            }
12047            acc0 = simd.select(simd.greater_than(acc0, acc1), acc0, acc1);
12048            acc2 = simd.select(simd.greater_than(acc2, acc3), acc2, acc3);
12049            acc0 = simd.select(simd.greater_than(acc0, acc2), acc0, acc2);
12050
12051            let acc0 = from_copy::<E, _>(simd.rotate_left(acc0, offset.rotate_left_amount()));
12052            let acc = SliceGroup::<'_, E>::new(E::faer_map(
12053                E::faer_as_ref(&acc0),
12054                #[inline(always)]
12055                |acc| bytemuck::cast_slice::<_, <E as Entity>::Unit>(core::slice::from_ref(acc)),
12056            ));
12057            let mut acc_scalar = E::faer_zero();
12058            for x in acc.into_ref_iter() {
12059                let x = x.read();
12060                acc_scalar = if acc_scalar > x { acc_scalar } else { x };
12061            }
12062            acc_scalar
12063        }
12064    }
12065
12066    E::Simd::default().dispatch(Impl { data })
12067}
12068
12069const NORM_L2_THRESHOLD: usize = 128;
12070
12071#[inline(always)]
12072fn norm_l2_with_simd_and_offset_pairwise_rows<E: ComplexField, S: Simd>(
12073    simd: S,
12074    data: SliceGroup<'_, E>,
12075    offset: pulp::Offset<SimdMaskFor<E, S>>,
12076    last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12077) -> (
12078    SimdGroupFor<E::Real, S>,
12079    SimdGroupFor<E::Real, S>,
12080    SimdGroupFor<E::Real, S>,
12081) {
12082    struct Impl<'a, E: ComplexField, S: Simd> {
12083        simd: S,
12084        data: SliceGroup<'a, E>,
12085        offset: pulp::Offset<SimdMaskFor<E, S>>,
12086        last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12087    }
12088
12089    impl<E: ComplexField, S: Simd> pulp::NullaryFnOnce for Impl<'_, E, S> {
12090        type Output = (
12091            SimdGroupFor<E::Real, S>,
12092            SimdGroupFor<E::Real, S>,
12093            SimdGroupFor<E::Real, S>,
12094        );
12095
12096        #[inline(always)]
12097        fn call(self) -> Self::Output {
12098            let Self {
12099                simd,
12100                data,
12101                offset,
12102                last_offset,
12103            } = self;
12104
12105            if data.len() == NORM_L2_THRESHOLD {
12106                norm_l2_with_simd_and_offset_prologue(simd, data, offset)
12107            } else if data.len() < NORM_L2_THRESHOLD {
12108                norm_l2_with_simd_and_offset_prologue(simd, data, last_offset)
12109            } else {
12110                let split_point = ((data.len() + 1) / 2).next_power_of_two();
12111                let (head, tail) = data.split_at(split_point);
12112                let (acc_small0, acc0, acc_big0) =
12113                    norm_l2_with_simd_and_offset_pairwise_rows(simd, head, offset, last_offset);
12114                let (acc_small1, acc1, acc_big1) =
12115                    norm_l2_with_simd_and_offset_pairwise_rows(simd, tail, offset, last_offset);
12116
12117                use group_helpers::*;
12118                let simd = SimdFor::<E::Real, S>::new(simd);
12119                (
12120                    simd.add(acc_small0, acc_small1),
12121                    simd.add(acc0, acc1),
12122                    simd.add(acc_big0, acc_big1),
12123                )
12124            }
12125        }
12126    }
12127
12128    simd.vectorize(Impl {
12129        simd,
12130        data,
12131        offset,
12132        last_offset,
12133    })
12134}
12135
12136#[inline(always)]
12137fn sum_with_simd_and_offset_pairwise_rows<E: ComplexField, S: Simd>(
12138    simd: S,
12139    data: SliceGroup<'_, E>,
12140    offset: pulp::Offset<SimdMaskFor<E, S>>,
12141    last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12142) -> SimdGroupFor<E, S> {
12143    struct Impl<'a, E: ComplexField, S: Simd> {
12144        simd: S,
12145        data: SliceGroup<'a, E>,
12146        offset: pulp::Offset<SimdMaskFor<E, S>>,
12147        last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12148    }
12149
12150    impl<E: ComplexField, S: Simd> pulp::NullaryFnOnce for Impl<'_, E, S> {
12151        type Output = SimdGroupFor<E, S>;
12152
12153        #[inline(always)]
12154        fn call(self) -> Self::Output {
12155            let Self {
12156                simd,
12157                data,
12158                offset,
12159                last_offset,
12160            } = self;
12161
12162            if data.len() == NORM_L2_THRESHOLD {
12163                sum_with_simd_and_offset_prologue(simd, data, offset)
12164            } else if data.len() < NORM_L2_THRESHOLD {
12165                sum_with_simd_and_offset_prologue(simd, data, last_offset)
12166            } else {
12167                let split_point = ((data.len() + 1) / 2).next_power_of_two();
12168                let (head, tail) = data.split_at(split_point);
12169                let acc0 = sum_with_simd_and_offset_pairwise_rows(simd, head, offset, last_offset);
12170                let acc1 = sum_with_simd_and_offset_pairwise_rows(simd, tail, offset, last_offset);
12171
12172                use group_helpers::*;
12173                let simd = SimdFor::<E, S>::new(simd);
12174                simd.add(acc0, acc1)
12175            }
12176        }
12177    }
12178
12179    simd.vectorize(Impl {
12180        simd,
12181        data,
12182        offset,
12183        last_offset,
12184    })
12185}
12186
12187#[inline(always)]
12188fn norm_l2_with_simd_and_offset_pairwise_cols<E: ComplexField, S: Simd>(
12189    simd: S,
12190    data: MatRef<'_, E>,
12191    offset: pulp::Offset<SimdMaskFor<E, S>>,
12192    last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12193) -> (
12194    SimdGroupFor<E::Real, S>,
12195    SimdGroupFor<E::Real, S>,
12196    SimdGroupFor<E::Real, S>,
12197) {
12198    struct Impl<'a, E: ComplexField, S: Simd> {
12199        simd: S,
12200        data: MatRef<'a, E>,
12201        offset: pulp::Offset<SimdMaskFor<E, S>>,
12202        last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12203    }
12204
12205    impl<E: ComplexField, S: Simd> pulp::NullaryFnOnce for Impl<'_, E, S> {
12206        type Output = (
12207            SimdGroupFor<E::Real, S>,
12208            SimdGroupFor<E::Real, S>,
12209            SimdGroupFor<E::Real, S>,
12210        );
12211
12212        #[inline(always)]
12213        fn call(self) -> Self::Output {
12214            use group_helpers::*;
12215
12216            let Self {
12217                simd,
12218                data,
12219                offset,
12220                last_offset,
12221            } = self;
12222            if data.ncols() == 1 {
12223                norm_l2_with_simd_and_offset_pairwise_rows(
12224                    simd,
12225                    SliceGroup::<'_, E>::new(data.try_get_contiguous_col(0)),
12226                    offset,
12227                    last_offset,
12228                )
12229            } else {
12230                let split_point = (data.ncols() / 2).next_power_of_two();
12231
12232                let (head, tail) = data.split_at_col(split_point);
12233
12234                let (acc_small0, acc0, acc_big0) =
12235                    norm_l2_with_simd_and_offset_pairwise_cols(simd, head, offset, last_offset);
12236                let (acc_small1, acc1, acc_big1) =
12237                    norm_l2_with_simd_and_offset_pairwise_cols(simd, tail, offset, last_offset);
12238
12239                let simd = SimdFor::<E::Real, S>::new(simd);
12240                (
12241                    simd.add(acc_small0, acc_small1),
12242                    simd.add(acc0, acc1),
12243                    simd.add(acc_big0, acc_big1),
12244                )
12245            }
12246        }
12247    }
12248
12249    simd.vectorize(Impl {
12250        simd,
12251        data,
12252        offset,
12253        last_offset,
12254    })
12255}
12256
12257#[inline(always)]
12258fn sum_with_simd_and_offset_pairwise_cols<E: ComplexField, S: Simd>(
12259    simd: S,
12260    data: MatRef<'_, E>,
12261    offset: pulp::Offset<SimdMaskFor<E, S>>,
12262    last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12263) -> SimdGroupFor<E, S> {
12264    struct Impl<'a, E: ComplexField, S: Simd> {
12265        simd: S,
12266        data: MatRef<'a, E>,
12267        offset: pulp::Offset<SimdMaskFor<E, S>>,
12268        last_offset: pulp::Offset<SimdMaskFor<E, S>>,
12269    }
12270
12271    impl<E: ComplexField, S: Simd> pulp::NullaryFnOnce for Impl<'_, E, S> {
12272        type Output = SimdGroupFor<E, S>;
12273
12274        #[inline(always)]
12275        fn call(self) -> Self::Output {
12276            use group_helpers::*;
12277
12278            let Self {
12279                simd,
12280                data,
12281                offset,
12282                last_offset,
12283            } = self;
12284            if data.ncols() == 1 {
12285                sum_with_simd_and_offset_pairwise_rows(
12286                    simd,
12287                    SliceGroup::<'_, E>::new(data.try_get_contiguous_col(0)),
12288                    offset,
12289                    last_offset,
12290                )
12291            } else {
12292                let split_point = (data.ncols() / 2).next_power_of_two();
12293
12294                let (head, tail) = data.split_at_col(split_point);
12295
12296                let acc0 = sum_with_simd_and_offset_pairwise_cols(simd, head, offset, last_offset);
12297                let acc1 = sum_with_simd_and_offset_pairwise_cols(simd, tail, offset, last_offset);
12298
12299                let simd = SimdFor::<E, S>::new(simd);
12300                simd.add(acc0, acc1)
12301            }
12302        }
12303    }
12304
12305    simd.vectorize(Impl {
12306        simd,
12307        data,
12308        offset,
12309        last_offset,
12310    })
12311}
12312
12313fn norm_l2_contiguous<E: ComplexField>(data: MatRef<'_, E>) -> (E::Real, E::Real, E::Real) {
12314    struct Impl<'a, E: ComplexField> {
12315        data: MatRef<'a, E>,
12316    }
12317
12318    impl<E: ComplexField> pulp::WithSimd for Impl<'_, E> {
12319        type Output = (E::Real, E::Real, E::Real);
12320
12321        #[inline(always)]
12322        fn with_simd<S: pulp::Simd>(self, simd: S) -> Self::Output {
12323            let Self { data } = self;
12324            use group_helpers::*;
12325
12326            let offset =
12327                SimdFor::<E, S>::new(simd).align_offset_ptr(data.as_ptr(), NORM_L2_THRESHOLD);
12328
12329            let last_offset = SimdFor::<E, S>::new(simd)
12330                .align_offset_ptr(data.as_ptr(), data.nrows() % NORM_L2_THRESHOLD);
12331
12332            let (acc_small, acc, acc_big) =
12333                norm_l2_with_simd_and_offset_pairwise_cols(simd, data, offset, last_offset);
12334
12335            let simd = SimdFor::<E::Real, S>::new(simd);
12336            (
12337                simd.reduce_add(simd.rotate_left(acc_small, offset.rotate_left_amount())),
12338                simd.reduce_add(simd.rotate_left(acc, offset.rotate_left_amount())),
12339                simd.reduce_add(simd.rotate_left(acc_big, offset.rotate_left_amount())),
12340            )
12341        }
12342    }
12343
12344    E::Simd::default().dispatch(Impl { data })
12345}
12346
12347fn sum_contiguous<E: ComplexField>(data: MatRef<'_, E>) -> E {
12348    struct Impl<'a, E: ComplexField> {
12349        data: MatRef<'a, E>,
12350    }
12351
12352    impl<E: ComplexField> pulp::WithSimd for Impl<'_, E> {
12353        type Output = E;
12354
12355        #[inline(always)]
12356        fn with_simd<S: pulp::Simd>(self, simd: S) -> Self::Output {
12357            let Self { data } = self;
12358            use group_helpers::*;
12359
12360            let offset =
12361                SimdFor::<E, S>::new(simd).align_offset_ptr(data.as_ptr(), NORM_L2_THRESHOLD);
12362
12363            let last_offset = SimdFor::<E, S>::new(simd)
12364                .align_offset_ptr(data.as_ptr(), data.nrows() % NORM_L2_THRESHOLD);
12365
12366            let acc = sum_with_simd_and_offset_pairwise_cols(simd, data, offset, last_offset);
12367
12368            let simd = SimdFor::<E, S>::new(simd);
12369            simd.reduce_add(simd.rotate_left(acc, offset.rotate_left_amount()))
12370        }
12371    }
12372
12373    E::Simd::default().dispatch(Impl { data })
12374}
12375
12376fn norm_l2<E: ComplexField>(mut mat: MatRef<'_, E>) -> E::Real {
12377    if mat.ncols() > 1 && mat.col_stride().unsigned_abs() < mat.row_stride().unsigned_abs() {
12378        mat = mat.transpose();
12379    }
12380    if mat.row_stride() < 0 {
12381        mat = mat.reverse_rows();
12382    }
12383
12384    if mat.nrows() == 0 || mat.ncols() == 0 {
12385        E::Real::faer_zero()
12386    } else {
12387        let m = mat.nrows();
12388        let n = mat.ncols();
12389
12390        let half_small = E::Real::faer_min_positive_sqrt();
12391        let half_big = E::Real::faer_min_positive_sqrt_inv();
12392
12393        let mut acc_small = E::Real::faer_zero();
12394        let mut acc = E::Real::faer_zero();
12395        let mut acc_big = E::Real::faer_zero();
12396
12397        if mat.row_stride() == 1 {
12398            if coe::is_same::<E, c32>() {
12399                let mat: MatRef<'_, c32> = coe::coerce(mat);
12400                let mat = unsafe {
12401                    mat::from_raw_parts(
12402                        mat.as_ptr() as *const f32,
12403                        2 * mat.nrows(),
12404                        mat.ncols(),
12405                        1,
12406                        2 * mat.col_stride(),
12407                    )
12408                };
12409                let (acc_small_, acc_, acc_big_) = norm_l2_contiguous::<f32>(mat);
12410                acc_small = coe::coerce_static(acc_small_);
12411                acc = coe::coerce_static(acc_);
12412                acc_big = coe::coerce_static(acc_big_);
12413            } else if coe::is_same::<E, c64>() {
12414                let mat: MatRef<'_, c64> = coe::coerce(mat);
12415                let mat = unsafe {
12416                    mat::from_raw_parts(
12417                        mat.as_ptr() as *const f64,
12418                        2 * mat.nrows(),
12419                        mat.ncols(),
12420                        1,
12421                        2 * mat.col_stride(),
12422                    )
12423                };
12424                let (acc_small_, acc_, acc_big_) = norm_l2_contiguous::<f64>(mat);
12425                acc_small = coe::coerce_static(acc_small_);
12426                acc = coe::coerce_static(acc_);
12427                acc_big = coe::coerce_static(acc_big_);
12428            } else {
12429                (acc_small, acc, acc_big) = norm_l2_contiguous(mat);
12430            }
12431        } else {
12432            for j in 0..n {
12433                for i in 0..m {
12434                    let val = mat.read(i, j);
12435                    let val_small = val.faer_scale_power_of_two(half_small);
12436                    let val_big = val.faer_scale_power_of_two(half_big);
12437
12438                    acc_small = acc_small.faer_add(val_small.faer_abs2());
12439                    acc = acc.faer_add(val.faer_abs2());
12440                    acc_big = acc_big.faer_add(val_big.faer_abs2());
12441                }
12442            }
12443        }
12444
12445        if acc_small >= E::Real::faer_one() {
12446            acc_small.faer_sqrt().faer_mul(half_big)
12447        } else if acc_big <= E::Real::faer_one() {
12448            acc_big.faer_sqrt().faer_mul(half_small)
12449        } else {
12450            acc.faer_sqrt()
12451        }
12452    }
12453}
12454
12455fn sum<E: ComplexField>(mut mat: MatRef<'_, E>) -> E {
12456    if mat.ncols() > 1 && mat.col_stride().unsigned_abs() < mat.row_stride().unsigned_abs() {
12457        mat = mat.transpose();
12458    }
12459    if mat.row_stride() < 0 {
12460        mat = mat.reverse_rows();
12461    }
12462
12463    if mat.nrows() == 0 || mat.ncols() == 0 {
12464        E::faer_zero()
12465    } else {
12466        let m = mat.nrows();
12467        let n = mat.ncols();
12468
12469        let mut acc = E::faer_zero();
12470
12471        if mat.row_stride() == 1 {
12472            acc = sum_contiguous(mat);
12473        } else {
12474            for j in 0..n {
12475                for i in 0..m {
12476                    acc = acc.faer_add(mat.read(i, j));
12477                }
12478            }
12479        }
12480
12481        acc
12482    }
12483}
12484fn norm_max<E: ComplexField>(mut mat: MatRef<'_, E>) -> E::Real {
12485    if mat.ncols() > 1 && mat.col_stride().unsigned_abs() < mat.row_stride().unsigned_abs() {
12486        mat = mat.transpose();
12487    }
12488    if mat.row_stride() < 0 {
12489        mat = mat.reverse_rows();
12490    }
12491
12492    if mat.nrows() == 0 || mat.ncols() == 0 {
12493        E::Real::faer_zero()
12494    } else {
12495        let m = mat.nrows();
12496        let n = mat.ncols();
12497
12498        if mat.row_stride() == 1 {
12499            if coe::is_same::<E, c32>() {
12500                let mat: MatRef<'_, c32> = coe::coerce(mat);
12501                let mat = unsafe {
12502                    mat::from_raw_parts(
12503                        mat.as_ptr() as *const f32,
12504                        2 * mat.nrows(),
12505                        mat.ncols(),
12506                        1,
12507                        2 * mat.col_stride(),
12508                    )
12509                };
12510                return coe::coerce_static(norm_max_contiguous::<f32>(mat));
12511            } else if coe::is_same::<E, c64>() {
12512                let mat: MatRef<'_, c64> = coe::coerce(mat);
12513                let mat = unsafe {
12514                    mat::from_raw_parts(
12515                        mat.as_ptr() as *const f64,
12516                        2 * mat.nrows(),
12517                        mat.ncols(),
12518                        1,
12519                        2 * mat.col_stride(),
12520                    )
12521                };
12522                return coe::coerce_static(norm_max_contiguous::<f64>(mat));
12523            } else if coe::is_same::<E, num_complex::Complex<E::Real>>() {
12524                let mat: MatRef<'_, num_complex::Complex<E::Real>> = coe::coerce(mat);
12525                let num_complex::Complex { re, im } = mat.real_imag();
12526                let re = norm_max_contiguous(re);
12527                let im = norm_max_contiguous(im);
12528                return if re > im { re } else { im };
12529            } else if coe::is_same::<E, E::Real>() {
12530                let mat: MatRef<'_, E::Real> = coe::coerce(mat);
12531                return norm_max_contiguous(mat);
12532            }
12533        }
12534
12535        let mut acc = E::Real::faer_zero();
12536        for j in 0..n {
12537            for i in 0..m {
12538                let val = mat.read(i, j);
12539                let re = val.faer_real();
12540                let im = val.faer_imag();
12541                acc = if re > acc { re } else { acc };
12542                acc = if im > acc { im } else { acc };
12543            }
12544        }
12545        acc
12546    }
12547}
12548
12549/// Matrix view creation module.
12550pub mod mat {
12551    use super::*;
12552
12553    /// Creates a `MatRef` from pointers to the matrix data, dimensions, and strides.
12554    ///
12555    /// The row (resp. column) stride is the offset from the memory address of a given matrix
12556    /// element at indices `(row: i, col: j)`, to the memory address of the matrix element at
12557    /// indices `(row: i + 1, col: 0)` (resp. `(row: 0, col: i + 1)`). This offset is specified in
12558    /// number of elements, not in bytes.
12559    ///
12560    /// # Safety
12561    /// The behavior is undefined if any of the following conditions are violated:
12562    /// * For each matrix unit, the entire memory region addressed by the matrix must be contained
12563    /// within a single allocation, accessible in its entirety by the corresponding pointer in
12564    /// `ptr`.
12565    /// * For each matrix unit, the corresponding pointer must be properly aligned,
12566    /// even for a zero-sized matrix.
12567    /// * The values accessible by the matrix must be initialized at some point before they are
12568    /// read, or references to them are formed.
12569    /// * No mutable aliasing is allowed. In other words, none of the elements accessible by any
12570    /// matrix unit may be accessed for writes by any other means for the duration of the lifetime
12571    /// `'a`.
12572    ///
12573    /// # Example
12574    ///
12575    /// ```
12576    /// use faer_core::mat;
12577    ///
12578    /// // row major matrix with 2 rows, 3 columns, with a column at the end that we want to skip.
12579    /// // the row stride is the pointer offset from the address of 1.0 to the address of 4.0,
12580    /// // which is 4.
12581    /// // the column stride is the pointer offset from the address of 1.0 to the address of 2.0,
12582    /// // which is 1.
12583    /// let data = [[1.0, 2.0, 3.0, f64::NAN], [4.0, 5.0, 6.0, f64::NAN]];
12584    /// let matrix = unsafe { mat::from_raw_parts::<f64>(data.as_ptr() as *const f64, 2, 3, 4, 1) };
12585    ///
12586    /// let expected = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
12587    /// assert_eq!(expected.as_ref(), matrix);
12588    /// ```
12589    #[inline(always)]
12590    pub unsafe fn from_raw_parts<'a, E: Entity>(
12591        ptr: GroupFor<E, *const E::Unit>,
12592        nrows: usize,
12593        ncols: usize,
12594        row_stride: isize,
12595        col_stride: isize,
12596    ) -> MatRef<'a, E> {
12597        MatRef {
12598            inner: inner::DenseRef {
12599                inner: MatImpl {
12600                    ptr: into_copy::<E, _>(E::faer_map(ptr, |ptr| {
12601                        NonNull::new_unchecked(ptr as *mut E::Unit)
12602                    })),
12603                    nrows,
12604                    ncols,
12605                    row_stride,
12606                    col_stride,
12607                },
12608                __marker: PhantomData,
12609            },
12610        }
12611    }
12612
12613    /// Creates a `MatMut` from pointers to the matrix data, dimensions, and strides.
12614    ///
12615    /// The row (resp. column) stride is the offset from the memory address of a given matrix
12616    /// element at indices `(row: i, col: j)`, to the memory address of the matrix element at
12617    /// indices `(row: i + 1, col: 0)` (resp. `(row: 0, col: i + 1)`). This offset is specified in
12618    /// number of elements, not in bytes.
12619    ///
12620    /// # Safety
12621    /// The behavior is undefined if any of the following conditions are violated:
12622    /// * For each matrix unit, the entire memory region addressed by the matrix must be contained
12623    /// within a single allocation, accessible in its entirety by the corresponding pointer in
12624    /// `ptr`.
12625    /// * For each matrix unit, the corresponding pointer must be non null and properly aligned,
12626    /// even for a zero-sized matrix.
12627    /// * The values accessible by the matrix must be initialized at some point before they are
12628    ///   read, or
12629    /// references to them are formed.
12630    /// * No aliasing (including self aliasing) is allowed. In other words, none of the elements
12631    /// accessible by any matrix unit may be accessed for reads or writes by any other means for
12632    /// the duration of the lifetime `'a`. No two elements within a single matrix unit may point to
12633    /// the same address (such a thing can be achieved with a zero stride, for example), and no two
12634    /// matrix units may point to the same address.
12635    ///
12636    /// # Example
12637    ///
12638    /// ```
12639    /// use faer_core::mat;
12640    ///
12641    /// // row major matrix with 2 rows, 3 columns, with a column at the end that we want to skip.
12642    /// // the row stride is the pointer offset from the address of 1.0 to the address of 4.0,
12643    /// // which is 4.
12644    /// // the column stride is the pointer offset from the address of 1.0 to the address of 2.0,
12645    /// // which is 1.
12646    /// let mut data = [[1.0, 2.0, 3.0, f64::NAN], [4.0, 5.0, 6.0, f64::NAN]];
12647    /// let mut matrix =
12648    ///     unsafe { mat::from_raw_parts_mut::<f64>(data.as_mut_ptr() as *mut f64, 2, 3, 4, 1) };
12649    ///
12650    /// let expected = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
12651    /// assert_eq!(expected.as_ref(), matrix);
12652    /// ```
12653    #[inline(always)]
12654    pub unsafe fn from_raw_parts_mut<'a, E: Entity>(
12655        ptr: GroupFor<E, *mut E::Unit>,
12656        nrows: usize,
12657        ncols: usize,
12658        row_stride: isize,
12659        col_stride: isize,
12660    ) -> MatMut<'a, E> {
12661        MatMut {
12662            inner: inner::DenseMut {
12663                inner: MatImpl {
12664                    ptr: into_copy::<E, _>(E::faer_map(ptr, |ptr| {
12665                        NonNull::new_unchecked(ptr as *mut E::Unit)
12666                    })),
12667                    nrows,
12668                    ncols,
12669                    row_stride,
12670                    col_stride,
12671                },
12672                __marker: PhantomData,
12673            },
12674        }
12675    }
12676
12677    /// Creates a `MatRef` from slice views over the matrix data, and the matrix dimensions.
12678    /// The data is interpreted in a column-major format, so that the first chunk of `nrows`
12679    /// values from the slices goes in the first column of the matrix, the second chunk of `nrows`
12680    /// values goes in the second column, and so on.
12681    ///
12682    /// # Panics
12683    /// The function panics if any of the following conditions are violated:
12684    /// * `nrows * ncols == slice.len()`
12685    ///
12686    /// # Example
12687    /// ```
12688    /// use faer_core::mat;
12689    ///
12690    /// let slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
12691    /// let view = mat::from_column_major_slice::<f64>(&slice, 3, 2);
12692    ///
12693    /// let expected = mat![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]];
12694    /// assert_eq!(expected, view);
12695    /// ```
12696    #[track_caller]
12697    #[inline(always)]
12698    pub fn from_column_major_slice<'a, E: Entity>(
12699        slice: GroupFor<E, &'a [E::Unit]>,
12700        nrows: usize,
12701        ncols: usize,
12702    ) -> MatRef<'a, E> {
12703        from_slice_assert(
12704            nrows,
12705            ncols,
12706            SliceGroup::<'_, E>::new(E::faer_copy(&slice)).len(),
12707        );
12708
12709        unsafe {
12710            from_raw_parts(
12711                E::faer_map(
12712                    slice,
12713                    #[inline(always)]
12714                    |slice| slice.as_ptr(),
12715                ),
12716                nrows,
12717                ncols,
12718                1,
12719                nrows as isize,
12720            )
12721        }
12722    }
12723
12724    /// Creates a `MatRef` from slice views over the matrix data, and the matrix dimensions.
12725    /// The data is interpreted in a row-major format, so that the first chunk of `ncols`
12726    /// values from the slices goes in the first column of the matrix, the second chunk of `ncols`
12727    /// values goes in the second column, and so on.
12728    ///
12729    /// # Panics
12730    /// The function panics if any of the following conditions are violated:
12731    /// * `nrows * ncols == slice.len()`
12732    ///
12733    /// # Example
12734    /// ```
12735    /// use faer_core::mat;
12736    ///
12737    /// let slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
12738    /// let view = mat::from_row_major_slice::<f64>(&slice, 3, 2);
12739    ///
12740    /// let expected = mat![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];
12741    /// assert_eq!(expected, view);
12742    /// ```
12743    #[track_caller]
12744    #[inline(always)]
12745    pub fn from_row_major_slice<'a, E: Entity>(
12746        slice: GroupFor<E, &'a [E::Unit]>,
12747        nrows: usize,
12748        ncols: usize,
12749    ) -> MatRef<'a, E> {
12750        from_column_major_slice(slice, ncols, nrows).transpose()
12751    }
12752
12753    /// Creates a `MatRef` from slice views over the matrix data, and the matrix dimensions.
12754    /// The data is interpreted in a column-major format, where the beginnings of two consecutive
12755    /// columns are separated by `col_stride` elements.
12756    #[track_caller]
12757    pub fn from_column_major_slice_with_stride<'a, E: Entity>(
12758        slice: GroupFor<E, &'a [E::Unit]>,
12759        nrows: usize,
12760        ncols: usize,
12761        col_stride: usize,
12762    ) -> MatRef<'a, E> {
12763        from_strided_column_major_slice_assert(
12764            nrows,
12765            ncols,
12766            col_stride,
12767            SliceGroup::<'_, E>::new(E::faer_copy(&slice)).len(),
12768        );
12769
12770        unsafe {
12771            from_raw_parts(
12772                E::faer_map(
12773                    slice,
12774                    #[inline(always)]
12775                    |slice| slice.as_ptr(),
12776                ),
12777                nrows,
12778                ncols,
12779                1,
12780                col_stride as isize,
12781            )
12782        }
12783    }
12784
12785    /// Creates a `MatMut` from slice views over the matrix data, and the matrix dimensions.
12786    /// The data is interpreted in a column-major format, so that the first chunk of `nrows`
12787    /// values from the slices goes in the first column of the matrix, the second chunk of `nrows`
12788    /// values goes in the second column, and so on.
12789    ///
12790    /// # Panics
12791    /// The function panics if any of the following conditions are violated:
12792    /// * `nrows * ncols == slice.len()`
12793    ///
12794    /// # Example
12795    /// ```
12796    /// use faer_core::mat;
12797    ///
12798    /// let mut slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
12799    /// let view = mat::from_column_major_slice_mut::<f64>(&mut slice, 3, 2);
12800    ///
12801    /// let expected = mat![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]];
12802    /// assert_eq!(expected, view);
12803    /// ```
12804    #[track_caller]
12805    pub fn from_column_major_slice_mut<'a, E: Entity>(
12806        slice: GroupFor<E, &'a mut [E::Unit]>,
12807        nrows: usize,
12808        ncols: usize,
12809    ) -> MatMut<'a, E> {
12810        from_slice_assert(
12811            nrows,
12812            ncols,
12813            SliceGroup::<'_, E>::new(E::faer_rb(E::faer_as_ref(&slice))).len(),
12814        );
12815        unsafe {
12816            from_raw_parts_mut(
12817                E::faer_map(
12818                    slice,
12819                    #[inline(always)]
12820                    |slice| slice.as_mut_ptr(),
12821                ),
12822                nrows,
12823                ncols,
12824                1,
12825                nrows as isize,
12826            )
12827        }
12828    }
12829
12830    /// Creates a `MatMut` from slice views over the matrix data, and the matrix dimensions.
12831    /// The data is interpreted in a row-major format, so that the first chunk of `ncols`
12832    /// values from the slices goes in the first column of the matrix, the second chunk of `ncols`
12833    /// values goes in the second column, and so on.
12834    ///
12835    /// # Panics
12836    /// The function panics if any of the following conditions are violated:
12837    /// * `nrows * ncols == slice.len()`
12838    ///
12839    /// # Example
12840    /// ```
12841    /// use faer_core::mat;
12842    ///
12843    /// let mut slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
12844    /// let view = mat::from_row_major_slice_mut::<f64>(&mut slice, 3, 2);
12845    ///
12846    /// let expected = mat![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];
12847    /// assert_eq!(expected, view);
12848    /// ```
12849    #[inline(always)]
12850    #[track_caller]
12851    pub fn from_row_major_slice_mut<'a, E: Entity>(
12852        slice: GroupFor<E, &'a mut [E::Unit]>,
12853        nrows: usize,
12854        ncols: usize,
12855    ) -> MatMut<'a, E> {
12856        from_column_major_slice_mut(slice, ncols, nrows).transpose_mut()
12857    }
12858
12859    /// Creates a `MatMut` from slice views over the matrix data, and the matrix dimensions.
12860    /// The data is interpreted in a column-major format, where the beginnings of two consecutive
12861    /// columns are separated by `col_stride` elements.
12862    #[track_caller]
12863    pub fn from_column_major_slice_with_stride_mut<'a, E: Entity>(
12864        slice: GroupFor<E, &'a mut [E::Unit]>,
12865        nrows: usize,
12866        ncols: usize,
12867        col_stride: usize,
12868    ) -> MatMut<'a, E> {
12869        from_strided_column_major_slice_mut_assert(
12870            nrows,
12871            ncols,
12872            col_stride,
12873            SliceGroup::<'_, E>::new(E::faer_rb(E::faer_as_ref(&slice))).len(),
12874        );
12875        unsafe {
12876            from_raw_parts_mut(
12877                E::faer_map(
12878                    slice,
12879                    #[inline(always)]
12880                    |slice| slice.as_mut_ptr(),
12881                ),
12882                nrows,
12883                ncols,
12884                1,
12885                col_stride as isize,
12886            )
12887        }
12888    }
12889}
12890
12891/// Column view creation module.
12892pub mod col {
12893    use super::*;
12894
12895    /// Creates a `ColRef` from pointers to the column vector data, number of rows, and row stride.
12896    ///
12897    /// # Safety:
12898    /// This function has the same safety requirements as
12899    /// [`mat::from_raw_parts(ptr, nrows, 1, row_stride, 0)`]
12900    #[inline(always)]
12901    pub unsafe fn from_raw_parts<'a, E: Entity>(
12902        ptr: GroupFor<E, *const E::Unit>,
12903        nrows: usize,
12904        row_stride: isize,
12905    ) -> ColRef<'a, E> {
12906        ColRef {
12907            inner: inner::DenseColRef {
12908                inner: VecImpl {
12909                    ptr: into_copy::<E, _>(E::faer_map(ptr, |ptr| {
12910                        NonNull::new_unchecked(ptr as *mut E::Unit)
12911                    })),
12912                    len: nrows,
12913                    stride: row_stride,
12914                },
12915                __marker: PhantomData,
12916            },
12917        }
12918    }
12919
12920    /// Creates a `ColMut` from pointers to the column vector data, number of rows, and row stride.
12921    ///
12922    /// # Safety:
12923    /// This function has the same safety requirements as
12924    /// [`mat::from_raw_parts_mut(ptr, nrows, 1, row_stride, 0)`]
12925    #[inline(always)]
12926    pub unsafe fn from_raw_parts_mut<'a, E: Entity>(
12927        ptr: GroupFor<E, *mut E::Unit>,
12928        nrows: usize,
12929        row_stride: isize,
12930    ) -> ColMut<'a, E> {
12931        ColMut {
12932            inner: inner::DenseColMut {
12933                inner: VecImpl {
12934                    ptr: into_copy::<E, _>(E::faer_map(ptr, |ptr| {
12935                        NonNull::new_unchecked(ptr as *mut E::Unit)
12936                    })),
12937                    len: nrows,
12938                    stride: row_stride,
12939                },
12940                __marker: PhantomData,
12941            },
12942        }
12943    }
12944
12945    /// Creates a `ColRef` from slice views over the column vector data, The result has the same
12946    /// number of rows as the length of the input slice.
12947    #[inline(always)]
12948    pub fn from_slice<'a, E: Entity>(slice: GroupFor<E, &'a [E::Unit]>) -> ColRef<'a, E> {
12949        let nrows = SliceGroup::<'_, E>::new(E::faer_copy(&slice)).len();
12950
12951        unsafe {
12952            from_raw_parts(
12953                E::faer_map(
12954                    slice,
12955                    #[inline(always)]
12956                    |slice| slice.as_ptr(),
12957                ),
12958                nrows,
12959                1,
12960            )
12961        }
12962    }
12963
12964    /// Creates a `ColMut` from slice views over the column vector data, The result has the same
12965    /// number of rows as the length of the input slice.
12966    #[inline(always)]
12967    pub fn from_slice_mut<'a, E: Entity>(slice: GroupFor<E, &'a mut [E::Unit]>) -> ColMut<'a, E> {
12968        let nrows = SliceGroup::<'_, E>::new(E::faer_rb(E::faer_as_ref(&slice))).len();
12969
12970        unsafe {
12971            from_raw_parts_mut(
12972                E::faer_map(
12973                    slice,
12974                    #[inline(always)]
12975                    |slice| slice.as_mut_ptr(),
12976                ),
12977                nrows,
12978                1,
12979            )
12980        }
12981    }
12982}
12983
12984/// Row view creation module.
12985pub mod row {
12986    use super::*;
12987
12988    /// Creates a `RowRef` from pointers to the row vector data, number of columns, and column
12989    /// stride.
12990    ///
12991    /// # Safety:
12992    /// This function has the same safety requirements as
12993    /// [`mat::from_raw_parts(ptr, 1, ncols, 0, col_stride)`]
12994    #[inline(always)]
12995    pub unsafe fn from_raw_parts<'a, E: Entity>(
12996        ptr: GroupFor<E, *const E::Unit>,
12997        ncols: usize,
12998        col_stride: isize,
12999    ) -> RowRef<'a, E> {
13000        RowRef {
13001            inner: inner::DenseRowRef {
13002                inner: VecImpl {
13003                    ptr: into_copy::<E, _>(E::faer_map(ptr, |ptr| {
13004                        NonNull::new_unchecked(ptr as *mut E::Unit)
13005                    })),
13006                    len: ncols,
13007                    stride: col_stride,
13008                },
13009                __marker: PhantomData,
13010            },
13011        }
13012    }
13013
13014    /// Creates a `RowMut` from pointers to the row vector data, number of columns, and column
13015    /// stride.
13016    ///
13017    /// # Safety:
13018    /// This function has the same safety requirements as
13019    /// [`mat::from_raw_parts_mut(ptr, 1, ncols, 0, col_stride)`]
13020    #[inline(always)]
13021    pub unsafe fn from_raw_parts_mut<'a, E: Entity>(
13022        ptr: GroupFor<E, *mut E::Unit>,
13023        ncols: usize,
13024        col_stride: isize,
13025    ) -> RowMut<'a, E> {
13026        RowMut {
13027            inner: inner::DenseRowMut {
13028                inner: VecImpl {
13029                    ptr: into_copy::<E, _>(E::faer_map(ptr, |ptr| {
13030                        NonNull::new_unchecked(ptr as *mut E::Unit)
13031                    })),
13032                    len: ncols,
13033                    stride: col_stride,
13034                },
13035                __marker: PhantomData,
13036            },
13037        }
13038    }
13039
13040    /// Creates a `RowRef` from slice views over the row vector data, The result has the same
13041    /// number of columns as the length of the input slice.
13042    #[inline(always)]
13043    pub fn from_slice<'a, E: Entity>(slice: GroupFor<E, &'a [E::Unit]>) -> RowRef<'a, E> {
13044        let nrows = SliceGroup::<'_, E>::new(E::faer_copy(&slice)).len();
13045
13046        unsafe {
13047            from_raw_parts(
13048                E::faer_map(
13049                    slice,
13050                    #[inline(always)]
13051                    |slice| slice.as_ptr(),
13052                ),
13053                nrows,
13054                1,
13055            )
13056        }
13057    }
13058
13059    /// Creates a `RowMut` from slice views over the row vector data, The result has the same
13060    /// number of columns as the length of the input slice.
13061    #[inline(always)]
13062    pub fn from_slice_mut<'a, E: Entity>(slice: GroupFor<E, &'a mut [E::Unit]>) -> RowMut<'a, E> {
13063        let nrows = SliceGroup::<'_, E>::new(E::faer_rb(E::faer_as_ref(&slice))).len();
13064
13065        unsafe {
13066            from_raw_parts_mut(
13067                E::faer_map(
13068                    slice,
13069                    #[inline(always)]
13070                    |slice| slice.as_mut_ptr(),
13071                ),
13072                nrows,
13073                1,
13074            )
13075        }
13076    }
13077}
13078
13079/// Convenience function to concatonate a nested list of matrices into a single
13080/// big ['Mat']. Concatonation pattern follows the numpy.block convention that
13081/// each sub-list must have an equal number of columns (net) but the boundaries
13082/// do not need to align. In other words, this sort of thing:
13083/// ```notcode
13084///   AAAbb
13085///   AAAbb
13086///   cDDDD
13087/// ```
13088/// is perfectly acceptable.
13089#[doc(hidden)]
13090#[track_caller]
13091pub fn __concat_impl<E: ComplexField>(blocks: &[&[MatRef<'_, E>]]) -> Mat<E> {
13092    #[inline(always)]
13093    fn count_total_columns<E: ComplexField>(block_row: &[MatRef<'_, E>]) -> usize {
13094        let mut out: usize = 0;
13095        for elem in block_row.iter() {
13096            out += elem.ncols();
13097        }
13098        out
13099    }
13100
13101    #[inline(always)]
13102    #[track_caller]
13103    fn count_rows<E: ComplexField>(block_row: &[MatRef<'_, E>]) -> usize {
13104        let mut out: usize = 0;
13105        for (i, e) in block_row.iter().enumerate() {
13106            if i.eq(&0) {
13107                out = e.nrows();
13108            } else {
13109                assert!(e.nrows().eq(&out));
13110            }
13111        }
13112        out
13113    }
13114
13115    // get size of result while doing checks
13116    let mut n: usize = 0;
13117    let mut m: usize = 0;
13118    for row in blocks.iter() {
13119        n += count_rows(row);
13120    }
13121    for (i, row) in blocks.iter().enumerate() {
13122        let cols = count_total_columns(row);
13123        if i.eq(&0) {
13124            m = cols;
13125        } else {
13126            assert!(cols.eq(&m));
13127        }
13128    }
13129
13130    let mut mat = Mat::<E>::zeros(n, m);
13131    let mut ni: usize = 0;
13132    let mut mj: usize;
13133    for row in blocks.iter() {
13134        mj = 0;
13135
13136        for elem in row.iter() {
13137            mat.as_mut()
13138                .submatrix_mut(ni, mj, elem.nrows(), elem.ncols())
13139                .copy_from(elem);
13140            mj += elem.ncols();
13141        }
13142        ni += row[0].nrows();
13143    }
13144
13145    mat
13146}
13147
13148#[cfg(test)]
13149mod tests {
13150    macro_rules! impl_unit_entity {
13151        ($ty: ty) => {
13152            unsafe impl Entity for $ty {
13153                type Unit = Self;
13154                type Index = ();
13155                type SimdUnit<S: $crate::pulp::Simd> = ();
13156                type SimdMask<S: $crate::pulp::Simd> = ();
13157                type SimdIndex<S: $crate::pulp::Simd> = ();
13158                type Group = IdentityGroup;
13159                type Iter<I: Iterator> = I;
13160
13161                type PrefixUnit<'a, S: Simd> = &'a [()];
13162                type SuffixUnit<'a, S: Simd> = &'a [()];
13163                type PrefixMutUnit<'a, S: Simd> = &'a mut [()];
13164                type SuffixMutUnit<'a, S: Simd> = &'a mut [()];
13165
13166                const N_COMPONENTS: usize = 1;
13167                const UNIT: GroupCopyFor<Self, ()> = ();
13168
13169                #[inline(always)]
13170                fn faer_first<T>(group: GroupFor<Self, T>) -> T {
13171                    group
13172                }
13173
13174                #[inline(always)]
13175                fn faer_from_units(group: GroupFor<Self, Self::Unit>) -> Self {
13176                    group
13177                }
13178
13179                #[inline(always)]
13180                fn faer_into_units(self) -> GroupFor<Self, Self::Unit> {
13181                    self
13182                }
13183
13184                #[inline(always)]
13185                fn faer_as_ref<T>(group: &GroupFor<Self, T>) -> GroupFor<Self, &T> {
13186                    group
13187                }
13188
13189                #[inline(always)]
13190                fn faer_as_mut<T>(group: &mut GroupFor<Self, T>) -> GroupFor<Self, &mut T> {
13191                    group
13192                }
13193
13194                #[inline(always)]
13195                fn faer_as_ptr<T>(group: *mut GroupFor<Self, T>) -> GroupFor<Self, *mut T> {
13196                    group
13197                }
13198
13199                #[inline(always)]
13200                fn faer_map_impl<T, U>(
13201                    group: GroupFor<Self, T>,
13202                    f: &mut impl FnMut(T) -> U,
13203                ) -> GroupFor<Self, U> {
13204                    (*f)(group)
13205                }
13206
13207                #[inline(always)]
13208                fn faer_map_with_context<Ctx, T, U>(
13209                    ctx: Ctx,
13210                    group: GroupFor<Self, T>,
13211                    f: &mut impl FnMut(Ctx, T) -> (Ctx, U),
13212                ) -> (Ctx, GroupFor<Self, U>) {
13213                    (*f)(ctx, group)
13214                }
13215
13216                #[inline(always)]
13217                fn faer_zip<T, U>(
13218                    first: GroupFor<Self, T>,
13219                    second: GroupFor<Self, U>,
13220                ) -> GroupFor<Self, (T, U)> {
13221                    (first, second)
13222                }
13223                #[inline(always)]
13224                fn faer_unzip<T, U>(
13225                    zipped: GroupFor<Self, (T, U)>,
13226                ) -> (GroupFor<Self, T>, GroupFor<Self, U>) {
13227                    zipped
13228                }
13229
13230                #[inline(always)]
13231                fn faer_into_iter<I: IntoIterator>(
13232                    iter: GroupFor<Self, I>,
13233                ) -> Self::Iter<I::IntoIter> {
13234                    iter.into_iter()
13235                }
13236            }
13237        };
13238    }
13239
13240    use super::*;
13241    use crate::assert;
13242
13243    #[test]
13244    fn basic_slice() {
13245        let data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
13246        let slice = unsafe { mat::from_raw_parts::<'_, f64>(data.as_ptr(), 2, 3, 3, 1) };
13247
13248        assert!(slice.get(0, 0) == &1.0);
13249        assert!(slice.get(0, 1) == &2.0);
13250        assert!(slice.get(0, 2) == &3.0);
13251
13252        assert!(slice.get(1, 0) == &4.0);
13253        assert!(slice.get(1, 1) == &5.0);
13254        assert!(slice.get(1, 2) == &6.0);
13255    }
13256
13257    #[test]
13258    fn empty() {
13259        {
13260            let m = Mat::<f64>::new();
13261            assert!(m.nrows() == 0);
13262            assert!(m.ncols() == 0);
13263            assert!(m.row_capacity() == 0);
13264            assert!(m.col_capacity() == 0);
13265        }
13266
13267        {
13268            let m = Mat::<f64>::with_capacity(100, 120);
13269            assert!(m.nrows() == 0);
13270            assert!(m.ncols() == 0);
13271            assert!(m.row_capacity() == 100);
13272            assert!(m.col_capacity() == 120);
13273        }
13274    }
13275
13276    #[test]
13277    fn reserve() {
13278        let mut m = Mat::<f64>::new();
13279
13280        m.reserve_exact(0, 0);
13281        assert!(m.row_capacity() == 0);
13282        assert!(m.col_capacity() == 0);
13283
13284        m.reserve_exact(1, 1);
13285        assert!(m.row_capacity() >= 1);
13286        assert!(m.col_capacity() == 1);
13287
13288        m.reserve_exact(2, 0);
13289        assert!(m.row_capacity() >= 2);
13290        assert!(m.col_capacity() == 1);
13291
13292        m.reserve_exact(2, 3);
13293        assert!(m.row_capacity() >= 2);
13294        assert!(m.col_capacity() == 3);
13295    }
13296
13297    #[derive(Debug, PartialEq, Clone, Copy)]
13298    struct Zst;
13299    unsafe impl bytemuck::Zeroable for Zst {}
13300    unsafe impl bytemuck::Pod for Zst {}
13301
13302    #[test]
13303    fn reserve_zst() {
13304        impl_unit_entity!(Zst);
13305
13306        let mut m = Mat::<Zst>::new();
13307
13308        m.reserve_exact(0, 0);
13309        assert!(m.row_capacity() == 0);
13310        assert!(m.col_capacity() == 0);
13311
13312        m.reserve_exact(1, 1);
13313        assert!(m.row_capacity() == 1);
13314        assert!(m.col_capacity() == 1);
13315
13316        m.reserve_exact(2, 0);
13317        assert!(m.row_capacity() == 2);
13318        assert!(m.col_capacity() == 1);
13319
13320        m.reserve_exact(2, 3);
13321        assert!(m.row_capacity() == 2);
13322        assert!(m.col_capacity() == 3);
13323
13324        m.reserve_exact(usize::MAX, usize::MAX);
13325    }
13326
13327    #[test]
13328    fn resize() {
13329        let mut m = Mat::new();
13330        let f = |i, j| i as f64 - j as f64;
13331        m.resize_with(2, 3, f);
13332        assert!(m.read(0, 0) == 0.0);
13333        assert!(m.read(0, 1) == -1.0);
13334        assert!(m.read(0, 2) == -2.0);
13335        assert!(m.read(1, 0) == 1.0);
13336        assert!(m.read(1, 1) == 0.0);
13337        assert!(m.read(1, 2) == -1.0);
13338
13339        m.resize_with(1, 2, f);
13340        assert!(m.read(0, 0) == 0.0);
13341        assert!(m.read(0, 1) == -1.0);
13342
13343        m.resize_with(2, 1, f);
13344        assert!(m.read(0, 0) == 0.0);
13345        assert!(m.read(1, 0) == 1.0);
13346
13347        m.resize_with(1, 2, f);
13348        assert!(m.read(0, 0) == 0.0);
13349        assert!(m.read(0, 1) == -1.0);
13350    }
13351
13352    #[test]
13353    fn resize_zst() {
13354        // miri test
13355        let mut m = Mat::new();
13356        let f = |_i, _j| Zst;
13357        m.resize_with(2, 3, f);
13358        m.resize_with(1, 2, f);
13359        m.resize_with(2, 1, f);
13360        m.resize_with(1, 2, f);
13361    }
13362
13363    #[test]
13364    #[should_panic]
13365    fn cap_overflow_1() {
13366        let _ = Mat::<f64>::with_capacity(isize::MAX as usize, 1);
13367    }
13368
13369    #[test]
13370    #[should_panic]
13371    fn cap_overflow_2() {
13372        let _ = Mat::<f64>::with_capacity(isize::MAX as usize, isize::MAX as usize);
13373    }
13374
13375    #[test]
13376    fn matrix_macro() {
13377        let mut x = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
13378
13379        assert!(x[(0, 0)] == 1.0);
13380        assert!(x[(0, 1)] == 2.0);
13381        assert!(x[(0, 2)] == 3.0);
13382
13383        assert!(x[(1, 0)] == 4.0);
13384        assert!(x[(1, 1)] == 5.0);
13385        assert!(x[(1, 2)] == 6.0);
13386
13387        assert!(x[(2, 0)] == 7.0);
13388        assert!(x[(2, 1)] == 8.0);
13389        assert!(x[(2, 2)] == 9.0);
13390
13391        x[(0, 0)] = 13.0;
13392        assert!(x[(0, 0)] == 13.0);
13393
13394        assert!(x.get(.., ..) == x);
13395        assert!(x.get(.., 1..3) == x.as_ref().submatrix(0, 1, 3, 2));
13396    }
13397
13398    #[test]
13399    fn matrix_macro_cplx() {
13400        let new = Complex::new;
13401        let mut x = mat![
13402            [new(1.0, 2.0), new(3.0, 4.0), new(5.0, 6.0)],
13403            [new(7.0, 8.0), new(9.0, 10.0), new(11.0, 12.0)],
13404            [new(13.0, 14.0), new(15.0, 16.0), new(17.0, 18.0)]
13405        ];
13406
13407        assert!(x.read(0, 0) == Complex::new(1.0, 2.0));
13408        assert!(x.read(0, 1) == Complex::new(3.0, 4.0));
13409        assert!(x.read(0, 2) == Complex::new(5.0, 6.0));
13410
13411        assert!(x.read(1, 0) == Complex::new(7.0, 8.0));
13412        assert!(x.read(1, 1) == Complex::new(9.0, 10.0));
13413        assert!(x.read(1, 2) == Complex::new(11.0, 12.0));
13414
13415        assert!(x.read(2, 0) == Complex::new(13.0, 14.0));
13416        assert!(x.read(2, 1) == Complex::new(15.0, 16.0));
13417        assert!(x.read(2, 2) == Complex::new(17.0, 18.0));
13418
13419        x.write(1, 0, Complex::new(3.0, 2.0));
13420        assert!(x.read(1, 0) == Complex::new(3.0, 2.0));
13421    }
13422
13423    #[test]
13424    fn matrix_macro_native_cplx() {
13425        let new = Complex::new;
13426        let mut x = mat![
13427            [new(1.0, 2.0), new(3.0, 4.0), new(5.0, 6.0)],
13428            [new(7.0, 8.0), new(9.0, 10.0), new(11.0, 12.0)],
13429            [new(13.0, 14.0), new(15.0, 16.0), new(17.0, 18.0)]
13430        ];
13431
13432        assert!(x.read(0, 0) == Complex::new(1.0, 2.0));
13433        assert!(x.read(0, 1) == Complex::new(3.0, 4.0));
13434        assert!(x.read(0, 2) == Complex::new(5.0, 6.0));
13435
13436        assert!(x.read(1, 0) == Complex::new(7.0, 8.0));
13437        assert!(x.read(1, 1) == Complex::new(9.0, 10.0));
13438        assert!(x.read(1, 2) == Complex::new(11.0, 12.0));
13439
13440        assert!(x.read(2, 0) == Complex::new(13.0, 14.0));
13441        assert!(x.read(2, 1) == Complex::new(15.0, 16.0));
13442        assert!(x.read(2, 2) == Complex::new(17.0, 18.0));
13443
13444        x.write(1, 0, Complex::new(3.0, 2.0));
13445        assert!(x.read(1, 0) == Complex::new(3.0, 2.0));
13446    }
13447
13448    #[test]
13449    fn col_macro() {
13450        let mut x = col![3.0, 5.0, 7.0, 9.0];
13451
13452        assert!(x[0] == 3.0);
13453        assert!(x[1] == 5.0);
13454        assert!(x[2] == 7.0);
13455        assert!(x[3] == 9.0);
13456
13457        x[0] = 13.0;
13458        assert!(x[0] == 13.0);
13459
13460        // TODO:
13461        // Col::get() seems to be missing
13462        // assert!(x.get(...) == x);
13463    }
13464
13465    #[test]
13466    fn col_macro_cplx() {
13467        let new = Complex::new;
13468        let mut x = col![new(1.0, 2.0), new(3.0, 4.0), new(5.0, 6.0),];
13469
13470        assert!(x.read(0) == Complex::new(1.0, 2.0));
13471        assert!(x.read(1) == Complex::new(3.0, 4.0));
13472        assert!(x.read(2) == Complex::new(5.0, 6.0));
13473
13474        x.write(0, Complex::new(3.0, 2.0));
13475        assert!(x.read(0) == Complex::new(3.0, 2.0));
13476    }
13477
13478    #[test]
13479    fn col_macro_native_cplx() {
13480        let new = Complex::new;
13481        let mut x = col![new(1.0, 2.0), new(3.0, 4.0), new(5.0, 6.0),];
13482
13483        assert!(x.read(0) == Complex::new(1.0, 2.0));
13484        assert!(x.read(1) == Complex::new(3.0, 4.0));
13485        assert!(x.read(2) == Complex::new(5.0, 6.0));
13486
13487        x.write(0, Complex::new(3.0, 2.0));
13488        assert!(x.read(0) == Complex::new(3.0, 2.0));
13489    }
13490
13491    #[test]
13492    fn row_macro() {
13493        let mut x = row![3.0, 5.0, 7.0, 9.0];
13494
13495        assert!(x[0] == 3.0);
13496        assert!(x[1] == 5.0);
13497        assert!(x[2] == 7.0);
13498        assert!(x[3] == 9.0);
13499
13500        x.write(0, 13.0);
13501        assert!(x.read(0) == 13.0);
13502    }
13503
13504    #[test]
13505    fn row_macro_cplx() {
13506        let new = Complex::new;
13507        let mut x = row![new(1.0, 2.0), new(3.0, 4.0), new(5.0, 6.0),];
13508
13509        assert!(x.read(0) == Complex::new(1.0, 2.0));
13510        assert!(x.read(1) == Complex::new(3.0, 4.0));
13511        assert!(x.read(2) == Complex::new(5.0, 6.0));
13512
13513        x.write(0, Complex::new(3.0, 2.0));
13514        assert!(x.read(0) == Complex::new(3.0, 2.0));
13515    }
13516
13517    #[test]
13518    fn row_macro_native_cplx() {
13519        let new = Complex::new;
13520        let mut x = row![new(1.0, 2.0), new(3.0, 4.0), new(5.0, 6.0),];
13521
13522        assert!(x.read(0) == new(1.0, 2.0));
13523        assert!(x.read(1) == new(3.0, 4.0));
13524        assert!(x.read(2) == new(5.0, 6.0));
13525
13526        x.write(0, new(3.0, 2.0));
13527        assert!(x.read(0) == new(3.0, 2.0));
13528    }
13529
13530    #[test]
13531    fn null_col_and_row() {
13532        let null_col: Col<f64> = col![];
13533        assert!(null_col == Col::<f64>::new());
13534
13535        let null_row: Row<f64> = row![];
13536        assert!(null_row == Row::<f64>::new());
13537    }
13538
13539    #[test]
13540    fn positive_concat_f64() {
13541        let a0: Mat<f64> = Mat::from_fn(2, 2, |_, _| 1f64);
13542        let a1: Mat<f64> = Mat::from_fn(2, 3, |_, _| 2f64);
13543        let a2: Mat<f64> = Mat::from_fn(2, 4, |_, _| 3f64);
13544
13545        let b0: Mat<f64> = Mat::from_fn(1, 6, |_, _| 4f64);
13546        let b1: Mat<f64> = Mat::from_fn(1, 3, |_, _| 5f64);
13547
13548        let c0: Mat<f64> = Mat::from_fn(6, 1, |_, _| 6f64);
13549        let c1: Mat<f64> = Mat::from_fn(6, 3, |_, _| 7f64);
13550        let c2: Mat<f64> = Mat::from_fn(6, 2, |_, _| 8f64);
13551        let c3: Mat<f64> = Mat::from_fn(6, 3, |_, _| 9f64);
13552
13553        let x = __concat_impl(&[
13554            &[a0.as_ref(), a1.as_ref(), a2.as_ref()],
13555            &[b0.as_ref(), b1.as_ref()],
13556            &[c0.as_ref(), c1.as_ref(), c2.as_ref(), c3.as_ref()],
13557        ]);
13558
13559        assert!(x == concat![[a0, a1, a2], [b0, b1], [c0, c1, c2, &c3]]);
13560
13561        assert!(x[(0, 0)] == 1f64);
13562        assert!(x[(1, 1)] == 1f64);
13563        assert!(x[(2, 2)] == 4f64);
13564        assert!(x[(3, 3)] == 7f64);
13565        assert!(x[(4, 4)] == 8f64);
13566        assert!(x[(5, 5)] == 8f64);
13567        assert!(x[(6, 6)] == 9f64);
13568        assert!(x[(7, 7)] == 9f64);
13569        assert!(x[(8, 8)] == 9f64);
13570    }
13571
13572    #[test]
13573    fn to_owned_equality() {
13574        use num_complex::Complex as C;
13575        let mut mf32: Mat<f32> = mat![[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]];
13576        let mut mf64: Mat<f64> = mat![[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]];
13577        let mut mf32c: Mat<Complex<f32>> = mat![
13578            [C::new(1., 1.), C::new(2., 2.), C::new(3., 3.)],
13579            [C::new(4., 4.), C::new(5., 5.), C::new(6., 6.)],
13580            [C::new(7., 7.), C::new(8., 8.), C::new(9., 9.)]
13581        ];
13582        let mut mf64c: Mat<Complex<f64>> = mat![
13583            [C::new(1., 1.), C::new(2., 2.), C::new(3., 3.)],
13584            [C::new(4., 4.), C::new(5., 5.), C::new(6., 6.)],
13585            [C::new(7., 7.), C::new(8., 8.), C::new(9., 9.)]
13586        ];
13587
13588        assert!(mf32.transpose().to_owned().as_ref() == mf32.transpose());
13589        assert!(mf64.transpose().to_owned().as_ref() == mf64.transpose());
13590        assert!(mf32c.transpose().to_owned().as_ref() == mf32c.transpose());
13591        assert!(mf64c.transpose().to_owned().as_ref() == mf64c.transpose());
13592
13593        assert!(mf32.as_mut().transpose_mut().to_owned().as_ref() == mf32.transpose());
13594        assert!(mf64.as_mut().transpose_mut().to_owned().as_ref() == mf64.transpose());
13595        assert!(mf32c.as_mut().transpose_mut().to_owned().as_ref() == mf32c.transpose());
13596        assert!(mf64c.as_mut().transpose_mut().to_owned().as_ref() == mf64c.transpose());
13597    }
13598
13599    #[test]
13600    fn conj_to_owned_equality() {
13601        use num_complex::Complex as C;
13602        let mut mf32: Mat<f32> = mat![[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]];
13603        let mut mf64: Mat<f64> = mat![[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]];
13604        let mut mf32c: Mat<Complex<f32>> = mat![
13605            [C::new(1., 1.), C::new(2., 2.), C::new(3., 3.)],
13606            [C::new(4., 4.), C::new(5., 5.), C::new(6., 6.)],
13607            [C::new(7., 7.), C::new(8., 8.), C::new(9., 9.)]
13608        ];
13609        let mut mf64c: Mat<Complex<f64>> = mat![
13610            [C::new(1., 1.), C::new(2., 2.), C::new(3., 3.)],
13611            [C::new(4., 4.), C::new(5., 5.), C::new(6., 6.)],
13612            [C::new(7., 7.), C::new(8., 8.), C::new(9., 9.)]
13613        ];
13614
13615        assert!(mf32.as_ref().adjoint().to_owned().as_ref() == mf32.adjoint());
13616        assert!(mf64.as_ref().adjoint().to_owned().as_ref() == mf64.adjoint());
13617        assert!(mf32c.as_ref().adjoint().to_owned().as_ref() == mf32c.adjoint());
13618        assert!(mf64c.as_ref().adjoint().to_owned().as_ref() == mf64c.adjoint());
13619
13620        assert!(mf32.as_mut().adjoint_mut().to_owned().as_ref() == mf32.adjoint());
13621        assert!(mf64.as_mut().adjoint_mut().to_owned().as_ref() == mf64.adjoint());
13622        assert!(mf32c.as_mut().adjoint_mut().to_owned().as_ref() == mf32c.adjoint());
13623        assert!(mf64c.as_mut().adjoint_mut().to_owned().as_ref() == mf64c.adjoint());
13624    }
13625
13626    #[test]
13627    fn mat_mul_assign_scalar() {
13628        let mut x = mat![[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]];
13629
13630        let expected = mat![[0.0, 2.0], [4.0, 6.0], [8.0, 10.0]];
13631        x *= scale(2.0);
13632        assert_eq!(x, expected);
13633
13634        let expected = mat![[0.0, 4.0], [8.0, 12.0], [16.0, 20.0]];
13635        let mut x_mut = x.as_mut();
13636        x_mut *= scale(2.0);
13637        assert_eq!(x, expected);
13638    }
13639
13640    #[test]
13641    fn test_col_slice() {
13642        let mut matrix = mat![[1.0, 5.0, 9.0], [2.0, 6.0, 10.0], [3.0, 7.0, 11.0f64]];
13643
13644        assert_eq!(matrix.col_as_slice(1), &[5.0, 6.0, 7.0]);
13645        assert_eq!(matrix.col_as_slice_mut(0), &[1.0, 2.0, 3.0]);
13646
13647        matrix
13648            .col_as_slice_mut(0)
13649            .copy_from_slice(&[-1.0, -2.0, -3.0]);
13650
13651        let expected = mat![[-1.0, 5.0, 9.0], [-2.0, 6.0, 10.0], [-3.0, 7.0, 11.0f64]];
13652        assert_eq!(matrix, expected);
13653    }
13654
13655    #[test]
13656    fn from_slice() {
13657        let mut slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
13658
13659        let expected = mat![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]];
13660        let view = mat::from_column_major_slice::<'_, f64>(&slice, 3, 2);
13661        assert_eq!(expected, view);
13662        let view = mat::from_column_major_slice::<'_, f64>(&mut slice, 3, 2);
13663        assert_eq!(expected, view);
13664
13665        let expected = mat![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];
13666        let view = mat::from_row_major_slice::<'_, f64>(&slice, 3, 2);
13667        assert_eq!(expected, view);
13668        let view = mat::from_row_major_slice::<'_, f64>(&mut slice, 3, 2);
13669        assert_eq!(expected, view);
13670    }
13671
13672    #[test]
13673    #[should_panic]
13674    fn from_slice_too_big() {
13675        let slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0_f64];
13676        mat::from_column_major_slice::<'_, f64>(&slice, 3, 2);
13677    }
13678
13679    #[test]
13680    #[should_panic]
13681    fn from_slice_too_small() {
13682        let slice = [1.0, 2.0, 3.0, 4.0, 5.0_f64];
13683        mat::from_column_major_slice::<'_, f64>(&slice, 3, 2);
13684    }
13685
13686    #[test]
13687    fn test_is_finite() {
13688        let inf = f32::INFINITY;
13689        let nan = f32::NAN;
13690
13691        {
13692            assert!(<f32 as ComplexField>::faer_is_finite(&1.0));
13693            assert!(!<f32 as ComplexField>::faer_is_finite(&inf));
13694            assert!(!<f32 as ComplexField>::faer_is_finite(&-inf));
13695            assert!(!<f32 as ComplexField>::faer_is_finite(&nan));
13696        }
13697        {
13698            let x = c32::new(1.0, 2.0);
13699            assert!(<c32 as ComplexField>::faer_is_finite(&x));
13700
13701            let x = c32::new(inf, 2.0);
13702            assert!(!<c32 as ComplexField>::faer_is_finite(&x));
13703
13704            let x = c32::new(1.0, inf);
13705            assert!(!<c32 as ComplexField>::faer_is_finite(&x));
13706
13707            let x = c32::new(inf, inf);
13708            assert!(!<c32 as ComplexField>::faer_is_finite(&x));
13709
13710            let x = c32::new(nan, 2.0);
13711            assert!(!<c32 as ComplexField>::faer_is_finite(&x));
13712
13713            let x = c32::new(1.0, nan);
13714            assert!(!<c32 as ComplexField>::faer_is_finite(&x));
13715
13716            let x = c32::new(nan, nan);
13717            assert!(!<c32 as ComplexField>::faer_is_finite(&x));
13718        }
13719    }
13720
13721    #[test]
13722    fn test_iter() {
13723        let mut mat = Mat::from_fn(9, 10, |i, j| (i + j) as f64);
13724        let mut iter = mat.row_chunks_mut(4);
13725
13726        let first = iter.next();
13727        let second = iter.next();
13728        let last = iter.next();
13729        let none = iter.next();
13730
13731        assert!(first == Some(Mat::from_fn(4, 10, |i, j| (i + j) as f64).as_mut()));
13732        assert!(second == Some(Mat::from_fn(4, 10, |i, j| (i + j + 4) as f64).as_mut()));
13733        assert!(last == Some(Mat::from_fn(1, 10, |i, j| (i + j + 8) as f64).as_mut()));
13734        assert!(none == None);
13735    }
13736
13737    #[test]
13738    fn test_norm_l2() {
13739        let relative_err = |a: f64, b: f64| (a - b).abs() / f64::max(a.abs(), b.abs());
13740
13741        for (m, n) in [(9, 10), (1023, 5), (42, 1)] {
13742            for factor in [0.0, 1.0, 1e30, 1e250, 1e-30, 1e-250] {
13743                let mat = Mat::from_fn(m, n, |i, j| factor * ((i + j) as f64));
13744                let mut target = 0.0;
13745                zipped!(mat.as_ref()).for_each(|unzipped!(x)| {
13746                    target = f64::hypot(*x, target);
13747                });
13748
13749                if factor == 0.0 {
13750                    assert!(mat.norm_l2() == target);
13751                } else {
13752                    assert!(relative_err(mat.norm_l2(), target) < 1e-14);
13753                }
13754            }
13755        }
13756
13757        let mat = Col::from_fn(10000000, |_| 0.3);
13758        let target = (0.3 * 0.3 * 10000000.0f64).sqrt();
13759        assert!(relative_err(mat.norm_l2(), target) < 1e-14);
13760    }
13761
13762    #[test]
13763    fn test_sum() {
13764        let relative_err = |a: f64, b: f64| (a - b).abs() / f64::max(a.abs(), b.abs());
13765
13766        for (m, n) in [(9, 10), (1023, 5), (42, 1)] {
13767            for factor in [0.0, 1.0, 1e30, 1e250, 1e-30, 1e-250] {
13768                let mat = Mat::from_fn(m, n, |i, j| factor * ((i + j) as f64));
13769                let mut target = 0.0;
13770                zipped!(mat.as_ref()).for_each(|unzipped!(x)| {
13771                    target += *x;
13772                });
13773
13774                if factor == 0.0 {
13775                    assert!(mat.sum() == target);
13776                } else {
13777                    assert!(relative_err(mat.sum(), target) < 1e-14);
13778                }
13779            }
13780        }
13781
13782        let mat = Col::from_fn(10000000, |_| 0.3);
13783        let target = 0.3 * 10000000.0f64;
13784        assert!(relative_err(mat.sum(), target) < 1e-14);
13785    }
13786
13787    #[test]
13788    fn test_kron_ones() {
13789        for (m, n, p, q) in [(2, 3, 4, 5), (3, 2, 5, 4), (1, 1, 1, 1)] {
13790            let a = Mat::from_fn(m, n, |_, _| 1 as f64);
13791            let b = Mat::from_fn(p, q, |_, _| 1 as f64);
13792            let expected = Mat::from_fn(m * p, n * q, |_, _| 1 as f64);
13793            assert!(a.kron(&b) == expected);
13794        }
13795
13796        for (m, n, p) in [(2, 3, 4), (3, 2, 5), (1, 1, 1)] {
13797            let a = Mat::from_fn(m, n, |_, _| 1 as f64);
13798            let b = Col::from_fn(p, |_| 1 as f64);
13799            let expected = Mat::from_fn(m * p, n, |_, _| 1 as f64);
13800            assert!(a.kron(&b) == expected);
13801            assert!(b.kron(&a) == expected);
13802
13803            let a = Mat::from_fn(m, n, |_, _| 1 as f64);
13804            let b = Row::from_fn(p, |_| 1 as f64);
13805            let expected = Mat::from_fn(m, n * p, |_, _| 1 as f64);
13806            assert!(a.kron(&b) == expected);
13807            assert!(b.kron(&a) == expected);
13808        }
13809
13810        for (m, n) in [(2, 3), (3, 2), (1, 1)] {
13811            let a = Row::from_fn(m, |_| 1 as f64);
13812            let b = Col::from_fn(n, |_| 1 as f64);
13813            let expected = Mat::from_fn(n, m, |_, _| 1 as f64);
13814            assert!(a.kron(&b) == expected);
13815            assert!(b.kron(&a) == expected);
13816
13817            let c = Row::from_fn(n, |_| 1 as f64);
13818            let expected = Mat::from_fn(1, m * n, |_, _| 1 as f64);
13819            assert!(a.kron(&c) == expected);
13820
13821            let d = Col::from_fn(m, |_| 1 as f64);
13822            let expected = Mat::from_fn(m * n, 1, |_, _| 1 as f64);
13823            assert!(d.kron(&b) == expected);
13824        }
13825    }
13826
13827    #[test]
13828    fn test_col_index() {
13829        let mut col_32: Col<f32> = Col::from_fn(3, |i| i as f32);
13830        col_32.as_mut()[1] = 10f32;
13831        let tval: f32 = (10f32 - col_32[1]).abs();
13832        assert!(tval < 1e-14);
13833
13834        let mut col_64: Col<f64> = Col::from_fn(3, |i| i as f64);
13835        col_64.as_mut()[1] = 10f64;
13836        let tval: f64 = (10f64 - col_64[1]).abs();
13837        assert!(tval < 1e-14);
13838    }
13839
13840    #[test]
13841    fn test_row_index() {
13842        let mut row_32: Row<f32> = Row::from_fn(3, |i| i as f32);
13843        row_32.as_mut()[1] = 10f32;
13844        let tval: f32 = (10f32 - row_32[1]).abs();
13845        assert!(tval < 1e-14);
13846
13847        let mut row_64: Row<f64> = Row::from_fn(3, |i| i as f64);
13848        row_64.as_mut()[1] = 10f64;
13849        let tval: f64 = (10f64 - row_64[1]).abs();
13850        assert!(tval < 1e-14);
13851    }
13852}
13853
13854/// Implementation of [`zipped!`] structures.
13855pub mod zip {
13856    use super::{assert, debug_assert, *};
13857    use core::mem::MaybeUninit;
13858
13859    /// Read only view over a single matrix element.
13860    pub struct Read<'a, E: Entity> {
13861        ptr: GroupFor<E, &'a MaybeUninit<E::Unit>>,
13862    }
13863    /// Read-write view over a single matrix element.
13864    pub struct ReadWrite<'a, E: Entity> {
13865        ptr: GroupFor<E, &'a mut MaybeUninit<E::Unit>>,
13866    }
13867
13868    /// Type that can be converted to a view.
13869    pub trait ViewMut {
13870        /// View type.
13871        type Target<'a>
13872        where
13873            Self: 'a;
13874
13875        /// Returns the view over self.
13876        fn view_mut(&mut self) -> Self::Target<'_>;
13877    }
13878
13879    impl<E: Entity> ViewMut for Row<E> {
13880        type Target<'a> = RowRef<'a, E>
13881        where
13882            Self: 'a;
13883
13884        #[inline]
13885        fn view_mut(&mut self) -> Self::Target<'_> {
13886            self.as_ref()
13887        }
13888    }
13889    impl<E: Entity> ViewMut for &Row<E> {
13890        type Target<'a> = RowRef<'a, E>
13891        where
13892            Self: 'a;
13893
13894        #[inline]
13895        fn view_mut(&mut self) -> Self::Target<'_> {
13896            (*self).as_ref()
13897        }
13898    }
13899    impl<E: Entity> ViewMut for &mut Row<E> {
13900        type Target<'a> = RowMut<'a, E>
13901        where
13902            Self: 'a;
13903
13904        #[inline]
13905        fn view_mut(&mut self) -> Self::Target<'_> {
13906            (*self).as_mut()
13907        }
13908    }
13909
13910    impl<E: Entity> ViewMut for RowRef<'_, E> {
13911        type Target<'a> = RowRef<'a, E>
13912        where
13913            Self: 'a;
13914
13915        #[inline]
13916        fn view_mut(&mut self) -> Self::Target<'_> {
13917            *self
13918        }
13919    }
13920    impl<E: Entity> ViewMut for RowMut<'_, E> {
13921        type Target<'a> = RowMut<'a, E>
13922        where
13923            Self: 'a;
13924
13925        #[inline]
13926        fn view_mut(&mut self) -> Self::Target<'_> {
13927            (*self).rb_mut()
13928        }
13929    }
13930    impl<E: Entity> ViewMut for &mut RowRef<'_, E> {
13931        type Target<'a> = RowRef<'a, E>
13932        where
13933            Self: 'a;
13934
13935        #[inline]
13936        fn view_mut(&mut self) -> Self::Target<'_> {
13937            **self
13938        }
13939    }
13940    impl<E: Entity> ViewMut for &mut RowMut<'_, E> {
13941        type Target<'a> = RowMut<'a, E>
13942        where
13943            Self: 'a;
13944
13945        #[inline]
13946        fn view_mut(&mut self) -> Self::Target<'_> {
13947            (**self).rb_mut()
13948        }
13949    }
13950    impl<E: Entity> ViewMut for &RowRef<'_, E> {
13951        type Target<'a> = RowRef<'a, E>
13952        where
13953            Self: 'a;
13954
13955        #[inline]
13956        fn view_mut(&mut self) -> Self::Target<'_> {
13957            **self
13958        }
13959    }
13960    impl<E: Entity> ViewMut for &RowMut<'_, E> {
13961        type Target<'a> = RowRef<'a, E>
13962        where
13963            Self: 'a;
13964
13965        #[inline]
13966        fn view_mut(&mut self) -> Self::Target<'_> {
13967            (**self).rb()
13968        }
13969    }
13970
13971    impl<E: Entity> ViewMut for Col<E> {
13972        type Target<'a> = ColRef<'a, E>
13973        where
13974            Self: 'a;
13975
13976        #[inline]
13977        fn view_mut(&mut self) -> Self::Target<'_> {
13978            self.as_ref()
13979        }
13980    }
13981    impl<E: Entity> ViewMut for &Col<E> {
13982        type Target<'a> = ColRef<'a, E>
13983        where
13984            Self: 'a;
13985
13986        #[inline]
13987        fn view_mut(&mut self) -> Self::Target<'_> {
13988            (*self).as_ref()
13989        }
13990    }
13991    impl<E: Entity> ViewMut for &mut Col<E> {
13992        type Target<'a> = ColMut<'a, E>
13993        where
13994            Self: 'a;
13995
13996        #[inline]
13997        fn view_mut(&mut self) -> Self::Target<'_> {
13998            (*self).as_mut()
13999        }
14000    }
14001
14002    impl<E: Entity> ViewMut for ColRef<'_, E> {
14003        type Target<'a> = ColRef<'a, E>
14004        where
14005            Self: 'a;
14006
14007        #[inline]
14008        fn view_mut(&mut self) -> Self::Target<'_> {
14009            *self
14010        }
14011    }
14012    impl<E: Entity> ViewMut for ColMut<'_, E> {
14013        type Target<'a> = ColMut<'a, E>
14014        where
14015            Self: 'a;
14016
14017        #[inline]
14018        fn view_mut(&mut self) -> Self::Target<'_> {
14019            (*self).rb_mut()
14020        }
14021    }
14022    impl<E: Entity> ViewMut for &mut ColRef<'_, E> {
14023        type Target<'a> = ColRef<'a, E>
14024        where
14025            Self: 'a;
14026
14027        #[inline]
14028        fn view_mut(&mut self) -> Self::Target<'_> {
14029            **self
14030        }
14031    }
14032    impl<E: Entity> ViewMut for &mut ColMut<'_, E> {
14033        type Target<'a> = ColMut<'a, E>
14034        where
14035            Self: 'a;
14036
14037        #[inline]
14038        fn view_mut(&mut self) -> Self::Target<'_> {
14039            (**self).rb_mut()
14040        }
14041    }
14042    impl<E: Entity> ViewMut for &ColRef<'_, E> {
14043        type Target<'a> = ColRef<'a, E>
14044        where
14045            Self: 'a;
14046
14047        #[inline]
14048        fn view_mut(&mut self) -> Self::Target<'_> {
14049            **self
14050        }
14051    }
14052    impl<E: Entity> ViewMut for &ColMut<'_, E> {
14053        type Target<'a> = ColRef<'a, E>
14054        where
14055            Self: 'a;
14056
14057        #[inline]
14058        fn view_mut(&mut self) -> Self::Target<'_> {
14059            (**self).rb()
14060        }
14061    }
14062
14063    impl<E: Entity> ViewMut for Mat<E> {
14064        type Target<'a> = MatRef<'a, E>
14065        where
14066            Self: 'a;
14067
14068        #[inline]
14069        fn view_mut(&mut self) -> Self::Target<'_> {
14070            self.as_ref()
14071        }
14072    }
14073    impl<E: Entity> ViewMut for &Mat<E> {
14074        type Target<'a> = MatRef<'a, E>
14075        where
14076            Self: 'a;
14077
14078        #[inline]
14079        fn view_mut(&mut self) -> Self::Target<'_> {
14080            (*self).as_ref()
14081        }
14082    }
14083    impl<E: Entity> ViewMut for &mut Mat<E> {
14084        type Target<'a> = MatMut<'a, E>
14085        where
14086            Self: 'a;
14087
14088        #[inline]
14089        fn view_mut(&mut self) -> Self::Target<'_> {
14090            (*self).as_mut()
14091        }
14092    }
14093
14094    impl<E: Entity> ViewMut for MatRef<'_, E> {
14095        type Target<'a> = MatRef<'a, E>
14096        where
14097            Self: 'a;
14098
14099        #[inline]
14100        fn view_mut(&mut self) -> Self::Target<'_> {
14101            *self
14102        }
14103    }
14104    impl<E: Entity> ViewMut for MatMut<'_, E> {
14105        type Target<'a> = MatMut<'a, E>
14106        where
14107            Self: 'a;
14108
14109        #[inline]
14110        fn view_mut(&mut self) -> Self::Target<'_> {
14111            (*self).rb_mut()
14112        }
14113    }
14114    impl<E: Entity> ViewMut for &mut MatRef<'_, E> {
14115        type Target<'a> = MatRef<'a, E>
14116        where
14117            Self: 'a;
14118
14119        #[inline]
14120        fn view_mut(&mut self) -> Self::Target<'_> {
14121            **self
14122        }
14123    }
14124    impl<E: Entity> ViewMut for &mut MatMut<'_, E> {
14125        type Target<'a> = MatMut<'a, E>
14126        where
14127            Self: 'a;
14128
14129        #[inline]
14130        fn view_mut(&mut self) -> Self::Target<'_> {
14131            (**self).rb_mut()
14132        }
14133    }
14134    impl<E: Entity> ViewMut for &MatRef<'_, E> {
14135        type Target<'a> = MatRef<'a, E>
14136        where
14137            Self: 'a;
14138
14139        #[inline]
14140        fn view_mut(&mut self) -> Self::Target<'_> {
14141            **self
14142        }
14143    }
14144    impl<E: Entity> ViewMut for &MatMut<'_, E> {
14145        type Target<'a> = MatRef<'a, E>
14146        where
14147            Self: 'a;
14148
14149        #[inline]
14150        fn view_mut(&mut self) -> Self::Target<'_> {
14151            (**self).rb()
14152        }
14153    }
14154
14155    impl<E: SimpleEntity> core::ops::Deref for Read<'_, E> {
14156        type Target = E;
14157        #[inline(always)]
14158        fn deref(&self) -> &Self::Target {
14159            unsafe { &*(self.ptr as *const _ as *const E::Unit) }
14160        }
14161    }
14162    impl<E: SimpleEntity> core::ops::Deref for ReadWrite<'_, E> {
14163        type Target = E;
14164        #[inline(always)]
14165        fn deref(&self) -> &Self::Target {
14166            unsafe { &*(self.ptr as *const _ as *const E::Unit) }
14167        }
14168    }
14169    impl<E: SimpleEntity> core::ops::DerefMut for ReadWrite<'_, E> {
14170        #[inline(always)]
14171        fn deref_mut(&mut self) -> &mut Self::Target {
14172            unsafe { &mut *(self.ptr as *mut _ as *mut E::Unit) }
14173        }
14174    }
14175
14176    impl<E: Entity> Read<'_, E> {
14177        /// Read the value of the element.
14178        #[inline(always)]
14179        pub fn read(&self) -> E {
14180            E::faer_from_units(E::faer_map(
14181                E::faer_as_ref(&self.ptr),
14182                #[inline(always)]
14183                |ptr| unsafe { ptr.assume_init_read() },
14184            ))
14185        }
14186    }
14187    impl<E: Entity> ReadWrite<'_, E> {
14188        /// Read the value of the element.
14189        #[inline(always)]
14190        pub fn read(&self) -> E {
14191            E::faer_from_units(E::faer_map(
14192                E::faer_as_ref(&self.ptr),
14193                #[inline(always)]
14194                |ptr| unsafe { *ptr.assume_init_ref() },
14195            ))
14196        }
14197
14198        /// Write to the location of the element.
14199        #[inline(always)]
14200        pub fn write(&mut self, value: E) {
14201            let value = E::faer_into_units(value);
14202            E::faer_map(
14203                E::faer_zip(E::faer_as_mut(&mut self.ptr), value),
14204                #[inline(always)]
14205                |(ptr, value)| unsafe { *ptr.assume_init_mut() = value },
14206            );
14207        }
14208    }
14209
14210    /// Specifies whether the main diagonal should be traversed, when iterating over a triangular
14211    /// chunk of the matrix.
14212    #[derive(Copy, Clone, Debug, PartialEq, Eq)]
14213    pub enum Diag {
14214        /// Do not include diagonal of matrix
14215        Skip,
14216        /// Include diagonal of matrix
14217        Include,
14218    }
14219
14220    /// Matrix layout transformation. Used for zipping optimizations.
14221    #[derive(Copy, Clone)]
14222    pub enum MatLayoutTransform {
14223        /// Matrix is used as-is.
14224        None,
14225        /// Matrix rows are reversed.
14226        ReverseRows,
14227        /// Matrix is transposed.
14228        Transpose,
14229        /// Matrix is transposed, then rows are reversed.
14230        TransposeReverseRows,
14231    }
14232
14233    /// Vector layout transformation. Used for zipping optimizations.
14234    #[derive(Copy, Clone)]
14235    pub enum VecLayoutTransform {
14236        /// Vector is used as-is.
14237        None,
14238        /// Vector is reversed.
14239        Reverse,
14240    }
14241
14242    /// Type with a given matrix shape.
14243    pub trait MatShape {
14244        /// Type of rows.
14245        type Rows: Copy + Eq;
14246        /// Type of columns.
14247        type Cols: Copy + Eq;
14248        /// Returns the number of rows.
14249        fn nrows(&self) -> Self::Rows;
14250        /// Returns the number of columns.
14251        fn ncols(&self) -> Self::Cols;
14252    }
14253
14254    /// Zipped matrix views.
14255    pub unsafe trait MaybeContiguous: MatShape {
14256        /// Indexing type.
14257        type Index: Copy;
14258        /// Contiguous slice type.
14259        type Slice;
14260        /// Layout transformation type.
14261        type LayoutTransform: Copy;
14262        /// Returns slice at index of length `n_elems`.
14263        unsafe fn get_slice_unchecked(&mut self, idx: Self::Index, n_elems: usize) -> Self::Slice;
14264    }
14265
14266    /// Zipped matrix views.
14267    pub unsafe trait MatIndex<'a, _Outlives = &'a Self>: MaybeContiguous {
14268        /// Item produced by the zipped views.
14269        type Item;
14270
14271        /// Get the item at the given index, skipping bound checks.
14272        unsafe fn get_unchecked(&'a mut self, index: Self::Index) -> Self::Item;
14273        /// Get the item at the given slice position, skipping bound checks.
14274        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item;
14275
14276        /// Checks if the zipped matrices are contiguous.
14277        fn is_contiguous(&self) -> bool;
14278        /// Computes the preferred iteration layout of the matrices.
14279        fn preferred_layout(&self) -> Self::LayoutTransform;
14280        /// Applies the layout transformation to the matrices.
14281        fn with_layout(self, layout: Self::LayoutTransform) -> Self;
14282    }
14283
14284    /// Single element.
14285    #[derive(Copy, Clone, Debug)]
14286    pub struct Last<Mat>(pub Mat);
14287
14288    /// Zipped elements.
14289    #[derive(Copy, Clone, Debug)]
14290    pub struct Zip<Head, Tail>(pub Head, pub Tail);
14291
14292    /// Single matrix view.
14293    #[derive(Copy, Clone, Debug)]
14294    pub struct LastEq<Rows, Cols, Mat: MatShape<Rows = Rows, Cols = Cols>>(pub Mat);
14295    /// Zipped matrix views.
14296    #[derive(Copy, Clone, Debug)]
14297    pub struct ZipEq<
14298        Rows,
14299        Cols,
14300        Head: MatShape<Rows = Rows, Cols = Cols>,
14301        Tail: MatShape<Rows = Rows, Cols = Cols>,
14302    >(Head, Tail);
14303
14304    impl<
14305            Rows: Copy + Eq,
14306            Cols: Copy + Eq,
14307            Head: MatShape<Rows = Rows, Cols = Cols>,
14308            Tail: MatShape<Rows = Rows, Cols = Cols>,
14309        > ZipEq<Rows, Cols, Head, Tail>
14310    {
14311        /// Creates a zipped matrix, after asserting that the dimensions match.
14312        #[inline(always)]
14313        pub fn new(head: Head, tail: Tail) -> Self {
14314            assert!((head.nrows(), head.ncols()) == (tail.nrows(), tail.ncols()));
14315            Self(head, tail)
14316        }
14317
14318        /// Creates a zipped matrix, assuming that the dimensions match.
14319        #[inline(always)]
14320        pub fn new_unchecked(head: Head, tail: Tail) -> Self {
14321            debug_assert!((head.nrows(), head.ncols()) == (tail.nrows(), tail.ncols()));
14322            Self(head, tail)
14323        }
14324    }
14325
14326    impl<Rows: Copy + Eq, Cols: Copy + Eq, Mat: MatShape<Rows = Rows, Cols = Cols>> MatShape
14327        for LastEq<Rows, Cols, Mat>
14328    {
14329        type Rows = Rows;
14330        type Cols = Cols;
14331        #[inline(always)]
14332        fn nrows(&self) -> Self::Rows {
14333            self.0.nrows()
14334        }
14335        #[inline(always)]
14336        fn ncols(&self) -> Self::Cols {
14337            self.0.ncols()
14338        }
14339    }
14340
14341    impl<
14342            Rows: Copy + Eq,
14343            Cols: Copy + Eq,
14344            Head: MatShape<Rows = Rows, Cols = Cols>,
14345            Tail: MatShape<Rows = Rows, Cols = Cols>,
14346        > MatShape for ZipEq<Rows, Cols, Head, Tail>
14347    {
14348        type Rows = Rows;
14349        type Cols = Cols;
14350        #[inline(always)]
14351        fn nrows(&self) -> Self::Rows {
14352            self.0.nrows()
14353        }
14354        #[inline(always)]
14355        fn ncols(&self) -> Self::Cols {
14356            self.0.ncols()
14357        }
14358    }
14359
14360    impl<E: Entity> MatShape for ColRef<'_, E> {
14361        type Rows = usize;
14362        type Cols = ();
14363        #[inline(always)]
14364        fn nrows(&self) -> Self::Rows {
14365            (*self).nrows()
14366        }
14367        #[inline(always)]
14368        fn ncols(&self) -> Self::Cols {
14369            ()
14370        }
14371    }
14372
14373    impl<E: Entity> MatShape for ColMut<'_, E> {
14374        type Rows = usize;
14375        type Cols = ();
14376        #[inline(always)]
14377        fn nrows(&self) -> Self::Rows {
14378            (*self).nrows()
14379        }
14380        #[inline(always)]
14381        fn ncols(&self) -> Self::Cols {
14382            ()
14383        }
14384    }
14385
14386    impl<E: Entity> MatShape for RowRef<'_, E> {
14387        type Rows = ();
14388        type Cols = usize;
14389        #[inline(always)]
14390        fn nrows(&self) -> Self::Rows {
14391            ()
14392        }
14393        #[inline(always)]
14394        fn ncols(&self) -> Self::Cols {
14395            (*self).ncols()
14396        }
14397    }
14398    impl<E: Entity> MatShape for RowMut<'_, E> {
14399        type Rows = ();
14400        type Cols = usize;
14401        #[inline(always)]
14402        fn nrows(&self) -> Self::Rows {
14403            ()
14404        }
14405        #[inline(always)]
14406        fn ncols(&self) -> Self::Cols {
14407            (*self).ncols()
14408        }
14409    }
14410
14411    impl<E: Entity> MatShape for MatRef<'_, E> {
14412        type Rows = usize;
14413        type Cols = usize;
14414        #[inline(always)]
14415        fn nrows(&self) -> Self::Rows {
14416            (*self).nrows()
14417        }
14418        #[inline(always)]
14419        fn ncols(&self) -> Self::Cols {
14420            (*self).ncols()
14421        }
14422    }
14423
14424    impl<E: Entity> MatShape for MatMut<'_, E> {
14425        type Rows = usize;
14426        type Cols = usize;
14427        #[inline(always)]
14428        fn nrows(&self) -> Self::Rows {
14429            (*self).nrows()
14430        }
14431        #[inline(always)]
14432        fn ncols(&self) -> Self::Cols {
14433            (*self).ncols()
14434        }
14435    }
14436
14437    unsafe impl<Rows: Copy + Eq, Cols: Copy + Eq, Mat: MaybeContiguous<Rows = Rows, Cols = Cols>>
14438        MaybeContiguous for LastEq<Rows, Cols, Mat>
14439    {
14440        type Index = Mat::Index;
14441        type Slice = Last<Mat::Slice>;
14442        type LayoutTransform = Mat::LayoutTransform;
14443        #[inline(always)]
14444        unsafe fn get_slice_unchecked(&mut self, idx: Self::Index, n_elems: usize) -> Self::Slice {
14445            Last(self.0.get_slice_unchecked(idx, n_elems))
14446        }
14447    }
14448
14449    unsafe impl<'a, Rows: Copy + Eq, Cols: Copy + Eq, Mat: MatIndex<'a, Rows = Rows, Cols = Cols>>
14450        MatIndex<'a> for LastEq<Rows, Cols, Mat>
14451    {
14452        type Item = Last<Mat::Item>;
14453
14454        #[inline(always)]
14455        unsafe fn get_unchecked(&'a mut self, index: Self::Index) -> Self::Item {
14456            Last(self.0.get_unchecked(index))
14457        }
14458
14459        #[inline(always)]
14460        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14461            Last(Mat::get_from_slice_unchecked(&mut slice.0, idx))
14462        }
14463
14464        #[inline(always)]
14465        fn is_contiguous(&self) -> bool {
14466            self.0.is_contiguous()
14467        }
14468        #[inline(always)]
14469        fn preferred_layout(&self) -> Self::LayoutTransform {
14470            self.0.preferred_layout()
14471        }
14472        #[inline(always)]
14473        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14474            Self(self.0.with_layout(layout))
14475        }
14476    }
14477
14478    unsafe impl<
14479            Rows: Copy + Eq,
14480            Cols: Copy + Eq,
14481            Head: MaybeContiguous<Rows = Rows, Cols = Cols>,
14482            Tail: MaybeContiguous<
14483                Rows = Rows,
14484                Cols = Cols,
14485                Index = Head::Index,
14486                LayoutTransform = Head::LayoutTransform,
14487            >,
14488        > MaybeContiguous for ZipEq<Rows, Cols, Head, Tail>
14489    {
14490        type Index = Head::Index;
14491        type Slice = Zip<Head::Slice, Tail::Slice>;
14492        type LayoutTransform = Head::LayoutTransform;
14493        #[inline(always)]
14494        unsafe fn get_slice_unchecked(&mut self, idx: Self::Index, n_elems: usize) -> Self::Slice {
14495            Zip(
14496                self.0.get_slice_unchecked(idx, n_elems),
14497                self.1.get_slice_unchecked(idx, n_elems),
14498            )
14499        }
14500    }
14501
14502    unsafe impl<
14503            'a,
14504            Rows: Copy + Eq,
14505            Cols: Copy + Eq,
14506            Head: MatIndex<'a, Rows = Rows, Cols = Cols>,
14507            Tail: MatIndex<
14508                'a,
14509                Rows = Rows,
14510                Cols = Cols,
14511                Index = Head::Index,
14512                LayoutTransform = Head::LayoutTransform,
14513            >,
14514        > MatIndex<'a> for ZipEq<Rows, Cols, Head, Tail>
14515    {
14516        type Item = Zip<Head::Item, Tail::Item>;
14517
14518        #[inline(always)]
14519        unsafe fn get_unchecked(&'a mut self, index: Self::Index) -> Self::Item {
14520            Zip(self.0.get_unchecked(index), self.1.get_unchecked(index))
14521        }
14522
14523        #[inline(always)]
14524        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14525            Zip(
14526                Head::get_from_slice_unchecked(&mut slice.0, idx),
14527                Tail::get_from_slice_unchecked(&mut slice.1, idx),
14528            )
14529        }
14530
14531        #[inline(always)]
14532        fn is_contiguous(&self) -> bool {
14533            self.0.is_contiguous() && self.1.is_contiguous()
14534        }
14535        #[inline(always)]
14536        fn preferred_layout(&self) -> Self::LayoutTransform {
14537            self.0.preferred_layout()
14538        }
14539        #[inline(always)]
14540        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14541            ZipEq(self.0.with_layout(layout), self.1.with_layout(layout))
14542        }
14543    }
14544
14545    unsafe impl<E: Entity> MaybeContiguous for ColRef<'_, E> {
14546        type Index = (usize, ());
14547        type Slice = GroupFor<E, &'static [MaybeUninit<E::Unit>]>;
14548        type LayoutTransform = VecLayoutTransform;
14549
14550        #[inline(always)]
14551        unsafe fn get_slice_unchecked(
14552            &mut self,
14553            (i, _): Self::Index,
14554            n_elems: usize,
14555        ) -> Self::Slice {
14556            E::faer_map(
14557                (*self).rb().ptr_at(i),
14558                #[inline(always)]
14559                |ptr| core::slice::from_raw_parts(ptr as *const MaybeUninit<E::Unit>, n_elems),
14560            )
14561        }
14562    }
14563    unsafe impl<'a, E: Entity> MatIndex<'a> for ColRef<'_, E> {
14564        type Item = Read<'a, E>;
14565
14566        #[inline(always)]
14567        unsafe fn get_unchecked(&'a mut self, (i, _): Self::Index) -> Self::Item {
14568            Read {
14569                ptr: E::faer_map(
14570                    self.rb().ptr_inbounds_at(i),
14571                    #[inline(always)]
14572                    |ptr| &*(ptr as *const MaybeUninit<E::Unit>),
14573                ),
14574            }
14575        }
14576
14577        #[inline(always)]
14578        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14579            let slice = E::faer_rb(E::faer_as_ref(slice));
14580            Read {
14581                ptr: E::faer_map(
14582                    slice,
14583                    #[inline(always)]
14584                    |slice| slice.get_unchecked(idx),
14585                ),
14586            }
14587        }
14588
14589        #[inline(always)]
14590        fn is_contiguous(&self) -> bool {
14591            self.row_stride() == 1
14592        }
14593        #[inline(always)]
14594        fn preferred_layout(&self) -> Self::LayoutTransform {
14595            let rs = self.row_stride();
14596            if self.nrows() > 1 && rs == 1 {
14597                VecLayoutTransform::None
14598            } else if self.nrows() > 1 && rs == -1 {
14599                VecLayoutTransform::Reverse
14600            } else {
14601                VecLayoutTransform::None
14602            }
14603        }
14604        #[inline(always)]
14605        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14606            use VecLayoutTransform::*;
14607            match layout {
14608                None => self,
14609                Reverse => self.reverse_rows(),
14610            }
14611        }
14612    }
14613
14614    unsafe impl<E: Entity> MaybeContiguous for ColMut<'_, E> {
14615        type Index = (usize, ());
14616        type Slice = GroupFor<E, &'static mut [MaybeUninit<E::Unit>]>;
14617        type LayoutTransform = VecLayoutTransform;
14618
14619        #[inline(always)]
14620        unsafe fn get_slice_unchecked(
14621            &mut self,
14622            (i, _): Self::Index,
14623            n_elems: usize,
14624        ) -> Self::Slice {
14625            E::faer_map(
14626                (*self).rb_mut().ptr_at_mut(i),
14627                #[inline(always)]
14628                |ptr| core::slice::from_raw_parts_mut(ptr as *mut MaybeUninit<E::Unit>, n_elems),
14629            )
14630        }
14631    }
14632    unsafe impl<'a, E: Entity> MatIndex<'a> for ColMut<'_, E> {
14633        type Item = ReadWrite<'a, E>;
14634
14635        #[inline(always)]
14636        unsafe fn get_unchecked(&'a mut self, (i, _): Self::Index) -> Self::Item {
14637            ReadWrite {
14638                ptr: E::faer_map(
14639                    self.rb_mut().ptr_inbounds_at_mut(i),
14640                    #[inline(always)]
14641                    |ptr| &mut *(ptr as *mut MaybeUninit<E::Unit>),
14642                ),
14643            }
14644        }
14645
14646        #[inline(always)]
14647        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14648            let slice = E::faer_rb_mut(E::faer_as_mut(slice));
14649            ReadWrite {
14650                ptr: E::faer_map(
14651                    slice,
14652                    #[inline(always)]
14653                    |slice| slice.get_unchecked_mut(idx),
14654                ),
14655            }
14656        }
14657
14658        #[inline(always)]
14659        fn is_contiguous(&self) -> bool {
14660            self.row_stride() == 1
14661        }
14662        #[inline(always)]
14663        fn preferred_layout(&self) -> Self::LayoutTransform {
14664            let rs = self.row_stride();
14665            if self.nrows() > 1 && rs == 1 {
14666                VecLayoutTransform::None
14667            } else if self.nrows() > 1 && rs == -1 {
14668                VecLayoutTransform::Reverse
14669            } else {
14670                VecLayoutTransform::None
14671            }
14672        }
14673        #[inline(always)]
14674        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14675            use VecLayoutTransform::*;
14676            match layout {
14677                None => self,
14678                Reverse => self.reverse_rows_mut(),
14679            }
14680        }
14681    }
14682
14683    unsafe impl<E: Entity> MaybeContiguous for RowRef<'_, E> {
14684        type Index = ((), usize);
14685        type Slice = GroupFor<E, &'static [MaybeUninit<E::Unit>]>;
14686        type LayoutTransform = VecLayoutTransform;
14687
14688        #[inline(always)]
14689        unsafe fn get_slice_unchecked(
14690            &mut self,
14691            (_, j): Self::Index,
14692            n_elems: usize,
14693        ) -> Self::Slice {
14694            E::faer_map(
14695                (*self).rb().ptr_at(j),
14696                #[inline(always)]
14697                |ptr| core::slice::from_raw_parts(ptr as *const MaybeUninit<E::Unit>, n_elems),
14698            )
14699        }
14700    }
14701    unsafe impl<'a, E: Entity> MatIndex<'a> for RowRef<'_, E> {
14702        type Item = Read<'a, E>;
14703
14704        #[inline(always)]
14705        unsafe fn get_unchecked(&'a mut self, (_, j): Self::Index) -> Self::Item {
14706            Read {
14707                ptr: E::faer_map(
14708                    self.rb().ptr_inbounds_at(j),
14709                    #[inline(always)]
14710                    |ptr| &*(ptr as *const MaybeUninit<E::Unit>),
14711                ),
14712            }
14713        }
14714
14715        #[inline(always)]
14716        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14717            let slice = E::faer_rb(E::faer_as_ref(slice));
14718            Read {
14719                ptr: E::faer_map(
14720                    slice,
14721                    #[inline(always)]
14722                    |slice| slice.get_unchecked(idx),
14723                ),
14724            }
14725        }
14726
14727        #[inline(always)]
14728        fn is_contiguous(&self) -> bool {
14729            self.col_stride() == 1
14730        }
14731        #[inline(always)]
14732        fn preferred_layout(&self) -> Self::LayoutTransform {
14733            let cs = self.col_stride();
14734            if self.ncols() > 1 && cs == 1 {
14735                VecLayoutTransform::None
14736            } else if self.ncols() > 1 && cs == -1 {
14737                VecLayoutTransform::Reverse
14738            } else {
14739                VecLayoutTransform::None
14740            }
14741        }
14742        #[inline(always)]
14743        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14744            use VecLayoutTransform::*;
14745            match layout {
14746                None => self,
14747                Reverse => self.reverse_cols(),
14748            }
14749        }
14750    }
14751
14752    unsafe impl<E: Entity> MaybeContiguous for RowMut<'_, E> {
14753        type Index = ((), usize);
14754        type Slice = GroupFor<E, &'static mut [MaybeUninit<E::Unit>]>;
14755        type LayoutTransform = VecLayoutTransform;
14756
14757        #[inline(always)]
14758        unsafe fn get_slice_unchecked(
14759            &mut self,
14760            (_, j): Self::Index,
14761            n_elems: usize,
14762        ) -> Self::Slice {
14763            E::faer_map(
14764                (*self).rb_mut().ptr_at_mut(j),
14765                #[inline(always)]
14766                |ptr| core::slice::from_raw_parts_mut(ptr as *mut MaybeUninit<E::Unit>, n_elems),
14767            )
14768        }
14769    }
14770    unsafe impl<'a, E: Entity> MatIndex<'a> for RowMut<'_, E> {
14771        type Item = ReadWrite<'a, E>;
14772
14773        #[inline(always)]
14774        unsafe fn get_unchecked(&'a mut self, (_, j): Self::Index) -> Self::Item {
14775            ReadWrite {
14776                ptr: E::faer_map(
14777                    self.rb_mut().ptr_inbounds_at_mut(j),
14778                    #[inline(always)]
14779                    |ptr| &mut *(ptr as *mut MaybeUninit<E::Unit>),
14780                ),
14781            }
14782        }
14783
14784        #[inline(always)]
14785        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14786            let slice = E::faer_rb_mut(E::faer_as_mut(slice));
14787            ReadWrite {
14788                ptr: E::faer_map(
14789                    slice,
14790                    #[inline(always)]
14791                    |slice| slice.get_unchecked_mut(idx),
14792                ),
14793            }
14794        }
14795
14796        #[inline(always)]
14797        fn is_contiguous(&self) -> bool {
14798            self.col_stride() == 1
14799        }
14800        #[inline(always)]
14801        fn preferred_layout(&self) -> Self::LayoutTransform {
14802            let cs = self.col_stride();
14803            if self.ncols() > 1 && cs == 1 {
14804                VecLayoutTransform::None
14805            } else if self.ncols() > 1 && cs == -1 {
14806                VecLayoutTransform::Reverse
14807            } else {
14808                VecLayoutTransform::None
14809            }
14810        }
14811        #[inline(always)]
14812        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14813            use VecLayoutTransform::*;
14814            match layout {
14815                None => self,
14816                Reverse => self.reverse_cols_mut(),
14817            }
14818        }
14819    }
14820
14821    unsafe impl<E: Entity> MaybeContiguous for MatRef<'_, E> {
14822        type Index = (usize, usize);
14823        type Slice = GroupFor<E, &'static [MaybeUninit<E::Unit>]>;
14824        type LayoutTransform = MatLayoutTransform;
14825
14826        #[inline(always)]
14827        unsafe fn get_slice_unchecked(
14828            &mut self,
14829            (i, j): Self::Index,
14830            n_elems: usize,
14831        ) -> Self::Slice {
14832            E::faer_map(
14833                (*self).rb().overflowing_ptr_at(i, j),
14834                #[inline(always)]
14835                |ptr| core::slice::from_raw_parts(ptr as *const MaybeUninit<E::Unit>, n_elems),
14836            )
14837        }
14838    }
14839    unsafe impl<'a, E: Entity> MatIndex<'a> for MatRef<'_, E> {
14840        type Item = Read<'a, E>;
14841
14842        #[inline(always)]
14843        unsafe fn get_unchecked(&'a mut self, (i, j): Self::Index) -> Self::Item {
14844            Read {
14845                ptr: E::faer_map(
14846                    self.rb().ptr_inbounds_at(i, j),
14847                    #[inline(always)]
14848                    |ptr| &*(ptr as *const MaybeUninit<E::Unit>),
14849                ),
14850            }
14851        }
14852
14853        #[inline(always)]
14854        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14855            let slice = E::faer_rb(E::faer_as_ref(slice));
14856            Read {
14857                ptr: E::faer_map(
14858                    slice,
14859                    #[inline(always)]
14860                    |slice| slice.get_unchecked(idx),
14861                ),
14862            }
14863        }
14864
14865        #[inline(always)]
14866        fn is_contiguous(&self) -> bool {
14867            self.row_stride() == 1
14868        }
14869        #[inline(always)]
14870        fn preferred_layout(&self) -> Self::LayoutTransform {
14871            let rs = self.row_stride();
14872            let cs = self.col_stride();
14873            if self.nrows() > 1 && rs == 1 {
14874                MatLayoutTransform::None
14875            } else if self.nrows() > 1 && rs == -1 {
14876                MatLayoutTransform::ReverseRows
14877            } else if self.ncols() > 1 && cs == 1 {
14878                MatLayoutTransform::Transpose
14879            } else if self.ncols() > 1 && cs == -1 {
14880                MatLayoutTransform::TransposeReverseRows
14881            } else {
14882                MatLayoutTransform::None
14883            }
14884        }
14885        #[inline(always)]
14886        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14887            use MatLayoutTransform::*;
14888            match layout {
14889                None => self,
14890                ReverseRows => self.reverse_rows(),
14891                Transpose => self.transpose(),
14892                TransposeReverseRows => self.transpose().reverse_rows(),
14893            }
14894        }
14895    }
14896
14897    unsafe impl<E: Entity> MaybeContiguous for MatMut<'_, E> {
14898        type Index = (usize, usize);
14899        type Slice = GroupFor<E, &'static mut [MaybeUninit<E::Unit>]>;
14900        type LayoutTransform = MatLayoutTransform;
14901
14902        #[inline(always)]
14903        unsafe fn get_slice_unchecked(
14904            &mut self,
14905            (i, j): Self::Index,
14906            n_elems: usize,
14907        ) -> Self::Slice {
14908            E::faer_map(
14909                (*self).rb().overflowing_ptr_at(i, j),
14910                #[inline(always)]
14911                |ptr| core::slice::from_raw_parts_mut(ptr as *mut MaybeUninit<E::Unit>, n_elems),
14912            )
14913        }
14914    }
14915
14916    unsafe impl<'a, E: Entity> MatIndex<'a> for MatMut<'_, E> {
14917        type Item = ReadWrite<'a, E>;
14918
14919        #[inline(always)]
14920        unsafe fn get_unchecked(&'a mut self, (i, j): Self::Index) -> Self::Item {
14921            ReadWrite {
14922                ptr: E::faer_map(
14923                    self.rb_mut().ptr_inbounds_at_mut(i, j),
14924                    #[inline(always)]
14925                    |ptr| &mut *(ptr as *mut MaybeUninit<E::Unit>),
14926                ),
14927            }
14928        }
14929
14930        #[inline(always)]
14931        unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item {
14932            let slice = E::faer_rb_mut(E::faer_as_mut(slice));
14933            ReadWrite {
14934                ptr: E::faer_map(
14935                    slice,
14936                    #[inline(always)]
14937                    |slice| slice.get_unchecked_mut(idx),
14938                ),
14939            }
14940        }
14941
14942        #[inline(always)]
14943        fn is_contiguous(&self) -> bool {
14944            self.row_stride() == 1
14945        }
14946        #[inline(always)]
14947        fn preferred_layout(&self) -> Self::LayoutTransform {
14948            let rs = self.row_stride();
14949            let cs = self.col_stride();
14950            if self.nrows() > 1 && rs == 1 {
14951                MatLayoutTransform::None
14952            } else if self.nrows() > 1 && rs == -1 {
14953                MatLayoutTransform::ReverseRows
14954            } else if self.ncols() > 1 && cs == 1 {
14955                MatLayoutTransform::Transpose
14956            } else if self.ncols() > 1 && cs == -1 {
14957                MatLayoutTransform::TransposeReverseRows
14958            } else {
14959                MatLayoutTransform::None
14960            }
14961        }
14962        #[inline(always)]
14963        fn with_layout(self, layout: Self::LayoutTransform) -> Self {
14964            use MatLayoutTransform::*;
14965            match layout {
14966                None => self,
14967                ReverseRows => self.reverse_rows_mut(),
14968                Transpose => self.transpose_mut(),
14969                TransposeReverseRows => self.transpose_mut().reverse_rows_mut(),
14970            }
14971        }
14972    }
14973
14974    #[inline(always)]
14975    fn annotate_noalias_mat<Z: for<'a> MatIndex<'a>>(
14976        f: &mut impl for<'a> FnMut(<Z as MatIndex<'a>>::Item),
14977        mut slice: Z::Slice,
14978        i_begin: usize,
14979        i_end: usize,
14980        _j: usize,
14981    ) {
14982        for i in i_begin..i_end {
14983            unsafe { f(Z::get_from_slice_unchecked(&mut slice, i - i_begin)) };
14984        }
14985    }
14986
14987    #[inline(always)]
14988    fn annotate_noalias_col<Z: for<'a> MatIndex<'a>>(
14989        f: &mut impl for<'a> FnMut(<Z as MatIndex<'a>>::Item),
14990        mut slice: Z::Slice,
14991        i_begin: usize,
14992        i_end: usize,
14993    ) {
14994        for i in i_begin..i_end {
14995            unsafe { f(Z::get_from_slice_unchecked(&mut slice, i - i_begin)) };
14996        }
14997    }
14998
14999    #[inline(always)]
15000    fn for_each_mat<Z: for<'a> MatIndex<'a, Rows = usize, Cols = usize, Index = (usize, usize)>>(
15001        z: Z,
15002        mut f: impl for<'a> FnMut(<Z as MatIndex<'a>>::Item),
15003    ) {
15004        let layout = z.preferred_layout();
15005        let mut z = z.with_layout(layout);
15006
15007        let m = z.nrows();
15008        let n = z.ncols();
15009        if m == 0 || n == 0 {
15010            return;
15011        }
15012
15013        unsafe {
15014            if z.is_contiguous() {
15015                for j in 0..n {
15016                    annotate_noalias_mat::<Z>(&mut f, z.get_slice_unchecked((0, j), m), 0, m, j);
15017                }
15018            } else {
15019                for j in 0..n {
15020                    for i in 0..m {
15021                        f(z.get_unchecked((i, j)))
15022                    }
15023                }
15024            }
15025        }
15026    }
15027
15028    #[inline(always)]
15029    fn for_each_mat_triangular_lower<
15030        Z: for<'a> MatIndex<
15031            'a,
15032            Rows = usize,
15033            Cols = usize,
15034            Index = (usize, usize),
15035            LayoutTransform = MatLayoutTransform,
15036        >,
15037    >(
15038        z: Z,
15039        diag: Diag,
15040        transpose: bool,
15041        mut f: impl for<'a> FnMut(<Z as MatIndex<'a>>::Item),
15042    ) {
15043        use MatLayoutTransform::*;
15044
15045        let z = if transpose {
15046            z.with_layout(MatLayoutTransform::Transpose)
15047        } else {
15048            z
15049        };
15050        let layout = z.preferred_layout();
15051        let mut z = z.with_layout(layout);
15052
15053        let m = z.nrows();
15054        let n = z.ncols();
15055        let n = match layout {
15056            None | ReverseRows => Ord::min(m, n),
15057            Transpose | TransposeReverseRows => n,
15058        };
15059        if m == 0 || n == 0 {
15060            return;
15061        }
15062
15063        let strict = match diag {
15064            Diag::Skip => true,
15065            Diag::Include => false,
15066        };
15067
15068        unsafe {
15069            if z.is_contiguous() {
15070                for j in 0..n {
15071                    let (start, end) = match layout {
15072                        None => (j + strict as usize, m),
15073                        ReverseRows => (0, (m - (j + strict as usize))),
15074                        Transpose => (0, (j + !strict as usize).min(m)),
15075                        TransposeReverseRows => (m - ((j + !strict as usize).min(m)), m),
15076                    };
15077
15078                    let len = end - start;
15079
15080                    annotate_noalias_mat::<Z>(
15081                        &mut f,
15082                        z.get_slice_unchecked((start, j), len),
15083                        start,
15084                        end,
15085                        j,
15086                    );
15087                }
15088            } else {
15089                for j in 0..n {
15090                    let (start, end) = match layout {
15091                        None => (j + strict as usize, m),
15092                        ReverseRows => (0, (m - (j + strict as usize))),
15093                        Transpose => (0, (j + !strict as usize).min(m)),
15094                        TransposeReverseRows => (m - ((j + !strict as usize).min(m)), m),
15095                    };
15096
15097                    for i in start..end {
15098                        f(z.get_unchecked((i, j)))
15099                    }
15100                }
15101            }
15102        }
15103    }
15104
15105    #[inline(always)]
15106    fn for_each_col<Z: for<'a> MatIndex<'a, Rows = usize, Cols = (), Index = (usize, ())>>(
15107        z: Z,
15108        mut f: impl for<'a> FnMut(<Z as MatIndex<'a>>::Item),
15109    ) {
15110        let layout = z.preferred_layout();
15111        let mut z = z.with_layout(layout);
15112
15113        let m = z.nrows();
15114        if m == 0 {
15115            return;
15116        }
15117
15118        unsafe {
15119            if z.is_contiguous() {
15120                annotate_noalias_col::<Z>(&mut f, z.get_slice_unchecked((0, ()), m), 0, m);
15121            } else {
15122                for i in 0..m {
15123                    f(z.get_unchecked((i, ())))
15124                }
15125            }
15126        }
15127    }
15128
15129    #[inline(always)]
15130    fn for_each_row<Z: for<'a> MatIndex<'a, Rows = (), Cols = usize, Index = ((), usize)>>(
15131        z: Z,
15132        mut f: impl for<'a> FnMut(<Z as MatIndex<'a>>::Item),
15133    ) {
15134        let layout = z.preferred_layout();
15135        let mut z = z.with_layout(layout);
15136
15137        let n = z.ncols();
15138        if n == 0 {
15139            return;
15140        }
15141
15142        unsafe {
15143            if z.is_contiguous() {
15144                annotate_noalias_col::<Z>(&mut f, z.get_slice_unchecked(((), 0), n), 0, n);
15145            } else {
15146                for j in 0..n {
15147                    f(z.get_unchecked(((), j)))
15148                }
15149            }
15150        }
15151    }
15152
15153    impl<
15154            M: for<'a> MatIndex<
15155                'a,
15156                Rows = usize,
15157                Cols = usize,
15158                Index = (usize, usize),
15159                LayoutTransform = MatLayoutTransform,
15160            >,
15161        > LastEq<usize, usize, M>
15162    {
15163        /// Applies `f` to each element of `self`.
15164        #[inline(always)]
15165        pub fn for_each(self, f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item)) {
15166            for_each_mat(self, f);
15167        }
15168
15169        /// Applies `f` to each element of the lower triangular half of `self`.
15170        ///
15171        /// `diag` specifies whether the diagonal should be included or excluded.
15172        #[inline(always)]
15173        pub fn for_each_triangular_lower(
15174            self,
15175            diag: Diag,
15176            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item),
15177        ) {
15178            for_each_mat_triangular_lower(self, diag, false, f);
15179        }
15180
15181        /// Applies `f` to each element of the upper triangular half of `self`.
15182        ///
15183        /// `diag` specifies whether the diagonal should be included or excluded.
15184        #[inline(always)]
15185        pub fn for_each_triangular_upper(
15186            self,
15187            diag: Diag,
15188            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item),
15189        ) {
15190            for_each_mat_triangular_lower(self, diag, true, f);
15191        }
15192
15193        /// Applies `f` to each element of `self` and collect its result into a new matrix.
15194        #[inline(always)]
15195        pub fn map<E: Entity>(
15196            self,
15197            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item) -> E,
15198        ) -> Mat<E> {
15199            let (m, n) = (self.nrows(), self.ncols());
15200            let mut out = Mat::<E>::with_capacity(m, n);
15201            let rs = 1;
15202            let cs = out.col_stride();
15203            let out_view =
15204                unsafe { mat::from_raw_parts_mut::<'_, E>(out.as_ptr_mut(), m, n, rs, cs) };
15205            let mut f = f;
15206            ZipEq::new(out_view, self).for_each(
15207                #[inline(always)]
15208                |Zip(mut out, item)| out.write(f(item)),
15209            );
15210            unsafe { out.set_dims(m, n) };
15211            out
15212        }
15213    }
15214
15215    impl<
15216            M: for<'a> MatIndex<
15217                'a,
15218                Rows = (),
15219                Cols = usize,
15220                Index = ((), usize),
15221                LayoutTransform = VecLayoutTransform,
15222            >,
15223        > LastEq<(), usize, M>
15224    {
15225        /// Applies `f` to each element of `self`.
15226        #[inline(always)]
15227        pub fn for_each(self, f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item)) {
15228            for_each_row(self, f);
15229        }
15230
15231        /// Applies `f` to each element of `self` and collect its result into a new row.
15232        #[inline(always)]
15233        pub fn map<E: Entity>(
15234            self,
15235            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item) -> E,
15236        ) -> Row<E> {
15237            let (_, n) = (self.nrows(), self.ncols());
15238            let mut out = Row::<E>::with_capacity(n);
15239            let out_view = unsafe { row::from_raw_parts_mut::<'_, E>(out.as_ptr_mut(), n, 1) };
15240            let mut f = f;
15241            ZipEq::new(out_view, self).for_each(
15242                #[inline(always)]
15243                |Zip(mut out, item)| out.write(f(item)),
15244            );
15245            unsafe { out.set_ncols(n) };
15246            out
15247        }
15248    }
15249
15250    impl<
15251            M: for<'a> MatIndex<
15252                'a,
15253                Rows = usize,
15254                Cols = (),
15255                Index = (usize, ()),
15256                LayoutTransform = VecLayoutTransform,
15257            >,
15258        > LastEq<usize, (), M>
15259    {
15260        /// Applies `f` to each element of `self`.
15261        #[inline(always)]
15262        pub fn for_each(self, f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item)) {
15263            for_each_col(self, f);
15264        }
15265
15266        /// Applies `f` to each element of `self` and collect its result into a new column.
15267        #[inline(always)]
15268        pub fn map<E: Entity>(
15269            self,
15270            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item) -> E,
15271        ) -> Col<E> {
15272            let (m, _) = (self.nrows(), self.ncols());
15273            let mut out = Col::<E>::with_capacity(m);
15274            let out_view = unsafe { col::from_raw_parts_mut::<'_, E>(out.as_ptr_mut(), m, 1) };
15275            let mut f = f;
15276            ZipEq::new(out_view, self).for_each(
15277                #[inline(always)]
15278                |Zip(mut out, item)| out.write(f(item)),
15279            );
15280            unsafe { out.set_nrows(m) };
15281            out
15282        }
15283    }
15284
15285    impl<
15286            Head: for<'a> MatIndex<
15287                'a,
15288                Rows = (),
15289                Cols = usize,
15290                Index = ((), usize),
15291                LayoutTransform = VecLayoutTransform,
15292            >,
15293            Tail: for<'a> MatIndex<
15294                'a,
15295                Rows = (),
15296                Cols = usize,
15297                Index = ((), usize),
15298                LayoutTransform = VecLayoutTransform,
15299            >,
15300        > ZipEq<(), usize, Head, Tail>
15301    {
15302        /// Applies `f` to each element of `self`.
15303        #[inline(always)]
15304        pub fn for_each(self, f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item)) {
15305            for_each_row(self, f);
15306        }
15307
15308        /// Applies `f` to each element of `self` and collect its result into a new row.
15309        #[inline(always)]
15310        pub fn map<E: Entity>(
15311            self,
15312            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item) -> E,
15313        ) -> Row<E> {
15314            let (_, n) = (self.nrows(), self.ncols());
15315            let mut out = Row::<E>::with_capacity(n);
15316            let out_view = unsafe { row::from_raw_parts_mut::<'_, E>(out.as_ptr_mut(), n, 1) };
15317            let mut f = f;
15318            ZipEq::new(out_view, self).for_each(
15319                #[inline(always)]
15320                |Zip(mut out, item)| out.write(f(item)),
15321            );
15322            unsafe { out.set_ncols(n) };
15323            out
15324        }
15325    }
15326
15327    impl<
15328            Head: for<'a> MatIndex<
15329                'a,
15330                Rows = usize,
15331                Cols = (),
15332                Index = (usize, ()),
15333                LayoutTransform = VecLayoutTransform,
15334            >,
15335            Tail: for<'a> MatIndex<
15336                'a,
15337                Rows = usize,
15338                Cols = (),
15339                Index = (usize, ()),
15340                LayoutTransform = VecLayoutTransform,
15341            >,
15342        > ZipEq<usize, (), Head, Tail>
15343    {
15344        /// Applies `f` to each element of `self`.
15345        #[inline(always)]
15346        pub fn for_each(self, f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item)) {
15347            for_each_col(self, f);
15348        }
15349
15350        /// Applies `f` to each element of `self` and collect its result into a new column.
15351        #[inline(always)]
15352        pub fn map<E: Entity>(
15353            self,
15354            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item) -> E,
15355        ) -> Col<E> {
15356            let (m, _) = (self.nrows(), self.ncols());
15357            let mut out = Col::<E>::with_capacity(m);
15358            let out_view = unsafe { col::from_raw_parts_mut::<'_, E>(out.as_ptr_mut(), m, 1) };
15359            let mut f = f;
15360            ZipEq::new(out_view, self).for_each(
15361                #[inline(always)]
15362                |Zip(mut out, item)| out.write(f(item)),
15363            );
15364            unsafe { out.set_nrows(m) };
15365            out
15366        }
15367    }
15368
15369    impl<
15370            Head: for<'a> MatIndex<
15371                'a,
15372                Rows = usize,
15373                Cols = usize,
15374                Index = (usize, usize),
15375                LayoutTransform = MatLayoutTransform,
15376            >,
15377            Tail: for<'a> MatIndex<
15378                'a,
15379                Rows = usize,
15380                Cols = usize,
15381                Index = (usize, usize),
15382                LayoutTransform = MatLayoutTransform,
15383            >,
15384        > ZipEq<usize, usize, Head, Tail>
15385    {
15386        /// Applies `f` to each element of `self`.
15387        #[inline(always)]
15388        pub fn for_each(self, f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item)) {
15389            for_each_mat(self, f);
15390        }
15391
15392        /// Applies `f` to each element of the lower triangular half of `self`.
15393        ///
15394        /// `diag` specifies whether the diagonal should be included or excluded.
15395        #[inline(always)]
15396        pub fn for_each_triangular_lower(
15397            self,
15398            diag: Diag,
15399            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item),
15400        ) {
15401            for_each_mat_triangular_lower(self, diag, false, f);
15402        }
15403
15404        /// Applies `f` to each element of the upper triangular half of `self`.
15405        ///
15406        /// `diag` specifies whether the diagonal should be included or excluded.
15407        #[inline(always)]
15408        pub fn for_each_triangular_upper(
15409            self,
15410            diag: Diag,
15411            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item),
15412        ) {
15413            for_each_mat_triangular_lower(self, diag, true, f);
15414        }
15415
15416        /// Applies `f` to each element of `self` and collect its result into a new matrix.
15417        #[inline(always)]
15418        pub fn map<E: Entity>(
15419            self,
15420            f: impl for<'a> FnMut(<Self as MatIndex<'a>>::Item) -> E,
15421        ) -> Mat<E> {
15422            let (m, n) = (self.nrows(), self.ncols());
15423            let mut out = Mat::<E>::with_capacity(m, n);
15424            let rs = 1;
15425            let cs = out.col_stride();
15426            let out_view =
15427                unsafe { mat::from_raw_parts_mut::<'_, E>(out.as_ptr_mut(), m, n, rs, cs) };
15428            let mut f = f;
15429            ZipEq::new(out_view, self).for_each(
15430                #[inline(always)]
15431                |Zip(mut out, item)| out.write(f(item)),
15432            );
15433            unsafe { out.set_dims(m, n) };
15434            out
15435        }
15436    }
15437
15438    #[cfg(test)]
15439    mod tests {
15440        use super::*;
15441        use crate::{assert, unzipped, zipped, ComplexField, Mat};
15442
15443        #[test]
15444        fn test_zip() {
15445            for (m, n) in [(2, 2), (4, 2), (2, 4)] {
15446                for rev_dst in [false, true] {
15447                    for rev_src in [false, true] {
15448                        for transpose_dst in [false, true] {
15449                            for transpose_src in [false, true] {
15450                                for diag in [Diag::Include, Diag::Skip] {
15451                                    let mut dst = Mat::from_fn(
15452                                        if transpose_dst { n } else { m },
15453                                        if transpose_dst { m } else { n },
15454                                        |_, _| f64::faer_zero(),
15455                                    );
15456                                    let src = Mat::from_fn(
15457                                        if transpose_src { n } else { m },
15458                                        if transpose_src { m } else { n },
15459                                        |_, _| f64::faer_one(),
15460                                    );
15461
15462                                    let mut target = Mat::from_fn(m, n, |_, _| f64::faer_zero());
15463                                    let target_src = Mat::from_fn(m, n, |_, _| f64::faer_one());
15464
15465                                    zipped!(target.as_mut(), target_src.as_ref())
15466                                        .for_each_triangular_lower(
15467                                            diag,
15468                                            |unzipped!(mut dst, src)| dst.write(src.read()),
15469                                        );
15470
15471                                    let mut dst = dst.as_mut();
15472                                    let mut src = src.as_ref();
15473
15474                                    if transpose_dst {
15475                                        dst = dst.transpose_mut();
15476                                    }
15477                                    if rev_dst {
15478                                        dst = dst.reverse_rows_mut();
15479                                    }
15480
15481                                    if transpose_src {
15482                                        src = src.transpose();
15483                                    }
15484                                    if rev_src {
15485                                        src = src.reverse_rows();
15486                                    }
15487
15488                                    zipped!(dst.rb_mut(), src).for_each_triangular_lower(
15489                                        diag,
15490                                        |unzipped!(mut dst, src)| dst.write(src.read()),
15491                                    );
15492
15493                                    assert!(dst.rb() == target.as_ref());
15494                                }
15495                            }
15496                        }
15497                    }
15498                }
15499            }
15500
15501            {
15502                let m = 3;
15503                for rev_dst in [false, true] {
15504                    for rev_src in [false, true] {
15505                        let mut dst = Col::<f64>::zeros(m);
15506                        let src = Col::from_fn(m, |i| (i + 1) as f64);
15507
15508                        let mut target = Col::<f64>::zeros(m);
15509                        let target_src =
15510                            Col::from_fn(m, |i| if rev_src { m - i } else { i + 1 } as f64);
15511
15512                        zipped!(target.as_mut(), target_src.as_ref())
15513                            .for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
15514
15515                        let mut dst = dst.as_mut();
15516                        let mut src = src.as_ref();
15517
15518                        if rev_dst {
15519                            dst = dst.reverse_rows_mut();
15520                        }
15521                        if rev_src {
15522                            src = src.reverse_rows();
15523                        }
15524
15525                        zipped!(dst.rb_mut(), src)
15526                            .for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
15527
15528                        assert!(dst.rb() == target.as_ref());
15529                    }
15530                }
15531            }
15532
15533            {
15534                let m = 3;
15535                for rev_dst in [false, true] {
15536                    for rev_src in [false, true] {
15537                        let mut dst = Row::<f64>::zeros(m);
15538                        let src = Row::from_fn(m, |i| (i + 1) as f64);
15539
15540                        let mut target = Row::<f64>::zeros(m);
15541                        let target_src =
15542                            Row::from_fn(m, |i| if rev_src { m - i } else { i + 1 } as f64);
15543
15544                        zipped!(target.as_mut(), target_src.as_ref())
15545                            .for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
15546
15547                        let mut dst = dst.as_mut();
15548                        let mut src = src.as_ref();
15549
15550                        if rev_dst {
15551                            dst = dst.reverse_cols_mut();
15552                        }
15553                        if rev_src {
15554                            src = src.reverse_cols();
15555                        }
15556
15557                        zipped!(&mut dst, src)
15558                            .for_each(|unzipped!(mut dst, src)| dst.write(src.read()));
15559
15560                        assert!(dst.rb() == target.as_ref());
15561                    }
15562                }
15563            }
15564        }
15565    }
15566}