1#![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#[derive(Copy, Clone, Debug, PartialEq)]
170pub enum Side {
171 Lower,
173 Upper,
175}
176
177#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
179#[non_exhaustive]
180pub enum FaerError {
181 IndexOverflow,
183 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
214pub 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#[derive(Copy, Clone, Debug, PartialEq, Eq)]
230pub enum Conj {
231 Yes,
233 No,
235}
236
237impl Conj {
238 #[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
249pub trait AsRowRef<E: Entity> {
251 fn as_row_ref(&self) -> RowRef<'_, E>;
253}
254pub trait AsRowMut<E: Entity> {
256 fn as_row_mut(&mut self) -> RowMut<'_, E>;
258}
259
260pub trait AsColRef<E: Entity> {
262 fn as_col_ref(&self) -> ColRef<'_, E>;
264}
265pub trait AsColMut<E: Entity> {
267 fn as_col_mut(&mut self) -> ColMut<'_, E>;
269}
270
271pub trait AsMatRef<E: Entity> {
277 fn as_mat_ref(&self) -> MatRef<'_, E>;
279}
280pub trait AsMatMut<E: Entity> {
286 fn as_mat_mut(&mut self) -> MatMut<'_, E>;
288}
289
290pub trait As2D<E: Entity> {
297 fn as_2d_ref(&self) -> MatRef<'_, E>;
299}
300pub trait As2DMut<E: Entity> {
307 fn as_2d_mut(&mut self) -> MatMut<'_, E>;
309}
310
311const _: () = {
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
379const _: () = {
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
447const _: () = {
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
515const _: () = {
517 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 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 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
647const _: () = {
649 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 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 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#[derive(Copy, Clone)]
860pub struct Matrix<M> {
861 inner: M,
862}
863
864pub 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 #[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 #[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 #[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 #[repr(C)]
936 pub struct DiagRef<'a, E: Entity> {
937 pub(crate) inner: ColRef<'a, E>,
938 }
939
940 #[repr(C)]
942 pub struct DiagMut<'a, E: Entity> {
943 pub(crate) inner: ColMut<'a, E>,
944 }
945
946 #[repr(C)]
948 pub struct DiagOwn<E: Entity> {
949 pub(crate) inner: Col<E>,
950 }
951
952 #[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 #[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 #[repr(C)]
968 pub struct DenseColOwn<E: Entity> {
969 pub(crate) inner: VecOwnImpl<E>,
970 pub(crate) row_capacity: usize,
971 }
972
973 #[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 #[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 #[repr(C)]
989 pub struct DenseRowOwn<E: Entity> {
990 pub(crate) inner: VecOwnImpl<E>,
991 pub(crate) col_capacity: usize,
992 }
993
994 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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
1081pub mod group_helpers {
1083 pub use pulp::{Read, Write};
1084
1085 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 #[inline]
1111 pub fn from_inner(inner: GroupFor<E, alloc::vec::Vec<T>>) -> Self {
1112 Self { inner }
1113 }
1114
1115 #[inline]
1117 pub fn into_inner(self) -> GroupFor<E, alloc::vec::Vec<T>> {
1118 self.inner
1119 }
1120
1121 #[inline]
1123 pub fn as_inner_ref(&self) -> GroupFor<E, &alloc::vec::Vec<T>> {
1124 E::faer_as_ref(&self.inner)
1125 }
1126
1127 #[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 #[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 #[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 #[inline]
1155 pub fn new() -> Self {
1156 Self {
1157 inner: E::faer_map(E::UNIT, |()| alloc::vec::Vec::new()),
1158 }
1159 }
1160
1161 #[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 #[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 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 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 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 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 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 pub fn clear(&mut self) {
1230 E::faer_map(E::faer_as_mut(&mut self.inner), |v| v.clear());
1231 }
1232
1233 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 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 #[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 #[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 #[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 #[derive(Copy, Clone, Debug)]
1297 pub struct YesConj;
1298 #[derive(Copy, Clone, Debug)]
1300 pub struct NoConj;
1301
1302 pub trait ConjTy: Copy + Debug {
1304 const CONJ: Conj;
1306 type Flip: ConjTy;
1308
1309 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 pub struct SimdFor<E: Entity, S: pulp::Simd> {
1336 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 #[inline(always)]
1352 pub fn new(simd: S) -> Self {
1353 Self {
1354 simd,
1355 __marker: PhantomData,
1356 }
1357 }
1358
1359 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
1484 pub fn splat(self, value: E) -> SimdGroupFor<E, S> {
1485 E::faer_simd_splat(self.simd, value)
1486 }
1487
1488 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
1550 pub fn neg(self, a: SimdGroupFor<E, S>) -> SimdGroupFor<E, S> {
1551 E::faer_simd_neg(self.simd, a)
1552 }
1553 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
1726 pub fn index_seq(self) -> SimdIndexFor<E, S> {
1727 E::faer_simd_index_seq(self.simd)
1728 }
1729 #[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 #[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 pub struct SliceGroup<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1743 GroupCopyFor<E, *const [T]>,
1744 PhantomData<&'a ()>,
1745 );
1746 pub struct SliceGroupMut<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1748 GroupFor<E, *mut [T]>,
1749 PhantomData<&'a mut ()>,
1750 );
1751
1752 pub struct Prefix<'a, E: Entity, S: pulp::Simd>(
1754 GroupCopyFor<E, E::PrefixUnit<'static, S>>,
1755 PhantomData<&'a ()>,
1756 );
1757 pub struct Suffix<'a, E: Entity, S: pulp::Simd>(
1759 GroupCopyFor<E, E::SuffixUnit<'static, S>>,
1760 PhantomData<&'a mut ()>,
1761 );
1762 pub struct PrefixMut<'a, E: Entity, S: pulp::Simd>(
1764 GroupFor<E, E::PrefixMutUnit<'static, S>>,
1765 PhantomData<&'a ()>,
1766 );
1767 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 pub struct RefGroup<'a, E: Entity, T: 'a = <E as Entity>::Unit>(
1969 GroupCopyFor<E, *const T>,
1970 PhantomData<&'a ()>,
1971 );
1972 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
2106 pub fn get(&self) -> GroupCopyFor<E, T>
2107 where
2108 T: Copy,
2109 {
2110 self.rb().get()
2111 }
2112
2113 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
2319 pub fn read(&self) -> E {
2320 self.rb().read()
2321 }
2322
2323 #[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 #[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 #[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 #[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 #[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 #[inline]
2384 pub fn is_empty(&self) -> bool {
2385 self.len() == 0
2386 }
2387
2388 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
2472 #[track_caller]
2473 pub fn read(&self, idx: usize) -> E {
2474 self.rb().read(idx)
2475 }
2476
2477 #[inline(always)]
2482 #[track_caller]
2483 pub unsafe fn read_unchecked(&self, idx: usize) -> E {
2484 self.rb().read_unchecked(idx)
2485 }
2486
2487 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
2563 pub fn is_empty(&self) -> bool {
2564 self.rb().is_empty()
2565 }
2566
2567 #[inline]
2569 pub fn len(&self) -> usize {
2570 self.rb().len()
2571 }
2572
2573 #[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 #[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 #[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 #[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 #[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
2703pub type ColRef<'a, E> = Matrix<inner::DenseColRef<'a, E>>;
2714
2715pub type RowRef<'a, E> = Matrix<inner::DenseRowRef<'a, E>>;
2725
2726pub type MatRef<'a, E> = Matrix<inner::DenseRef<'a, E>>;
2736
2737pub type ColMut<'a, E> = Matrix<inner::DenseColMut<'a, E>>;
2747
2748pub type RowMut<'a, E> = Matrix<inner::DenseRowMut<'a, E>>;
2758
2759pub type MatMut<'a, E> = Matrix<inner::DenseMut<'a, E>>;
2804
2805pub type MatScale<E> = Matrix<inner::Scale<E>>;
2807
2808impl<E: Entity> MatScale<E> {
2809 #[inline(always)]
2811 pub fn new(value: E) -> Self {
2812 Self {
2813 inner: inner::Scale(value),
2814 }
2815 }
2816
2817 #[inline(always)]
2819 pub fn value(self) -> E {
2820 self.inner.0
2821 }
2822}
2823
2824const _: () = {
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
2896const _: () = {
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
2968const _: () = {
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
3145pub trait RowIndex<ColRange>: seal::Seal + Sized {
3147 type Target;
3149
3150 #[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 fn get(this: Self, col: ColRange) -> Self::Target;
3157}
3158
3159pub trait ColIndex<RowRange>: seal::Seal + Sized {
3161 type Target;
3163
3164 #[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 fn get(this: Self, row: RowRange) -> Self::Target;
3171}
3172
3173pub trait MatIndex<RowRange, ColRange>: seal::Seal + Sized {
3175 type Target;
3177
3178 #[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 fn get(this: Self, row: RowRange, col: ColRange) -> Self::Target;
3185}
3186
3187const _: () = {
3189 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
3682const _: () = {
3684 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
3859const _: () = {
3861 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 #[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 #[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 #[inline(always)]
4056 pub fn into_column_vector(self) -> Col<E> {
4057 self.inner.inner
4058 }
4059
4060 #[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 #[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 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 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 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
4143const _: () = {
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 #[inline(always)]
4161 pub fn nrows(&self) -> usize {
4162 self.inner.inner.len
4163 }
4164 #[inline(always)]
4166 pub fn ncols(&self) -> usize {
4167 1
4168 }
4169
4170 #[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 #[inline(always)]
4182 pub fn row_stride(&self) -> isize {
4183 self.inner.inner.stride
4184 }
4185
4186 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
4366 #[must_use]
4367 pub fn conjugate(self) -> ColRef<'a, E::Conj>
4368 where
4369 E: Conjugate,
4370 {
4371 unsafe {
4372 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 #[inline(always)]
4387 pub fn adjoint(self) -> RowRef<'a, E::Conj>
4388 where
4389 E: Conjugate,
4390 {
4391 self.conjugate().transpose()
4392 }
4393
4394 #[inline(always)]
4397 pub fn canonicalize(self) -> (ColRef<'a, E::Canonical>, Conj)
4398 where
4399 E: Conjugate,
4400 {
4401 (
4402 unsafe {
4403 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 #[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 #[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 #[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 #[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 #[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 #[inline]
4494 pub fn has_nan(&self) -> bool
4495 where
4496 E: ComplexField,
4497 {
4498 (*self).as_2d().has_nan()
4499 }
4500
4501 #[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 #[inline]
4512 pub fn norm_max(&self) -> E::Real
4513 where
4514 E: ComplexField,
4515 {
4516 norm_max((*self).rb().as_2d())
4517 }
4518 #[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 #[inline]
4529 pub fn sum(&self) -> E
4530 where
4531 E: ComplexField,
4532 {
4533 sum((*self).rb().as_2d())
4534 }
4535
4536 #[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 #[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 #[inline(always)]
4629 pub fn nrows(&self) -> usize {
4630 self.inner.inner.len
4631 }
4632 #[inline(always)]
4634 pub fn ncols(&self) -> usize {
4635 1
4636 }
4637
4638 #[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 #[inline(always)]
4650 pub fn row_stride(&self) -> isize {
4651 self.inner.inner.stride
4652 }
4653
4654 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
4774 #[track_caller]
4775 pub unsafe fn read_unchecked(&self, row: usize) -> E {
4776 self.rb().read_unchecked(row)
4777 }
4778
4779 #[inline(always)]
4785 #[track_caller]
4786 pub fn read(&self, row: usize) -> E {
4787 self.rb().read(row)
4788 }
4789
4790 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
4941 pub fn to_owned(&self) -> Col<E::Canonical>
4942 where
4943 E: Conjugate,
4944 {
4945 (*self).rb().to_owned()
4946 }
4947
4948 #[inline]
4950 pub fn has_nan(&self) -> bool
4951 where
4952 E: ComplexField,
4953 {
4954 (*self).rb().as_2d().has_nan()
4955 }
4956
4957 #[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 #[inline]
4968 pub fn norm_max(&self) -> E::Real
4969 where
4970 E: ComplexField,
4971 {
4972 norm_max((*self).rb().as_2d())
4973 }
4974 #[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 #[inline]
4985 pub fn sum(&self) -> E
4986 where
4987 E: ComplexField,
4988 {
4989 sum((*self).rb().as_2d())
4990 }
4991
4992 #[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 #[inline]
5007 pub fn as_ref(&self) -> ColRef<'_, E> {
5008 (*self).rb()
5009 }
5010 }
5011};
5012
5013const _: () = {
5015 impl<'a, E: Entity> RowRef<'a, E> {
5016 #[inline(always)]
5018 pub fn nrows(&self) -> usize {
5019 1
5020 }
5021 #[inline(always)]
5023 pub fn ncols(&self) -> usize {
5024 self.inner.inner.len
5025 }
5026
5027 #[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 #[inline(always)]
5039 pub fn col_stride(&self) -> isize {
5040 self.inner.inner.stride
5041 }
5042
5043 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
5223 #[must_use]
5224 pub fn conjugate(self) -> RowRef<'a, E::Conj>
5225 where
5226 E: Conjugate,
5227 {
5228 unsafe {
5229 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 #[inline(always)]
5244 pub fn adjoint(self) -> ColRef<'a, E::Conj>
5245 where
5246 E: Conjugate,
5247 {
5248 self.conjugate().transpose()
5249 }
5250
5251 #[inline(always)]
5254 pub fn canonicalize(self) -> (RowRef<'a, E::Canonical>, Conj)
5255 where
5256 E: Conjugate,
5257 {
5258 (
5259 unsafe {
5260 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 #[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 #[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 #[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 #[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 #[inline]
5337 pub fn has_nan(&self) -> bool
5338 where
5339 E: ComplexField,
5340 {
5341 (*self).rb().as_2d().has_nan()
5342 }
5343
5344 #[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 #[inline]
5355 pub fn norm_max(&self) -> E::Real
5356 where
5357 E: ComplexField,
5358 {
5359 norm_max((*self).rb().as_2d())
5360 }
5361 #[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 #[inline]
5372 pub fn sum(&self) -> E
5373 where
5374 E: ComplexField,
5375 {
5376 sum((*self).rb().as_2d())
5377 }
5378
5379 #[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 #[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 #[inline(always)]
5459 pub fn nrows(&self) -> usize {
5460 1
5461 }
5462 #[inline(always)]
5464 pub fn ncols(&self) -> usize {
5465 self.inner.inner.len
5466 }
5467
5468 #[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 #[inline(always)]
5480 pub fn col_stride(&self) -> isize {
5481 self.inner.inner.stride
5482 }
5483
5484 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
5604 #[track_caller]
5605 pub unsafe fn read_unchecked(&self, col: usize) -> E {
5606 self.rb().read_unchecked(col)
5607 }
5608
5609 #[inline(always)]
5615 #[track_caller]
5616 pub fn read(&self, col: usize) -> E {
5617 self.rb().read(col)
5618 }
5619
5620 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
5760 pub fn to_owned(&self) -> Row<E::Canonical>
5761 where
5762 E: Conjugate,
5763 {
5764 (*self).rb().to_owned()
5765 }
5766
5767 #[inline]
5769 pub fn has_nan(&self) -> bool
5770 where
5771 E: ComplexField,
5772 {
5773 (*self).rb().as_2d().has_nan()
5774 }
5775
5776 #[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 #[inline]
5787 pub fn norm_max(&self) -> E::Real
5788 where
5789 E: ComplexField,
5790 {
5791 norm_max((*self).rb().as_2d())
5792 }
5793 #[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 #[inline]
5804 pub fn sum(&self) -> E
5805 where
5806 E: ComplexField,
5807 {
5808 sum((*self).rb().as_2d())
5809 }
5810
5811 #[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 #[inline]
5826 pub fn as_ref(&self) -> RowRef<'_, E> {
5827 (*self).rb()
5828 }
5829 }
5830};
5831
5832const _: () = {
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 #[inline(always)]
5859 pub fn nrows(&self) -> usize {
5860 self.inner.inner.nrows
5861 }
5862 #[inline(always)]
5864 pub fn ncols(&self) -> usize {
5865 self.inner.inner.ncols
5866 }
5867
5868 #[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 #[inline(always)]
5880 pub fn row_stride(&self) -> isize {
5881 self.inner.inner.row_stride
5882 }
5883
5884 #[inline(always)]
5886 pub fn col_stride(&self) -> isize {
5887 self.inner.inner.col_stride
5888 }
5889
5890 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
6207 #[must_use]
6208 pub fn conjugate(self) -> MatRef<'a, E::Conj>
6209 where
6210 E: Conjugate,
6211 {
6212 unsafe {
6213 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 #[inline(always)]
6230 pub fn adjoint(self) -> MatRef<'a, E::Conj>
6231 where
6232 E: Conjugate,
6233 {
6234 self.transpose().conjugate()
6235 }
6236
6237 #[inline(always)]
6240 pub fn canonicalize(self) -> (MatRef<'a, E::Canonical>, Conj)
6241 where
6242 E: Conjugate,
6243 {
6244 (
6245 unsafe {
6246 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
6668 pub fn norm_max(&self) -> E::Real
6669 where
6670 E: ComplexField,
6671 {
6672 norm_max((*self).rb())
6673 }
6674 #[inline]
6676 pub fn norm_l2(&self) -> E::Real
6677 where
6678 E: ComplexField,
6679 {
6680 norm_l2((*self).rb())
6681 }
6682
6683 #[inline]
6685 pub fn sum(&self) -> E
6686 where
6687 E: ComplexField,
6688 {
6689 sum((*self).rb())
6690 }
6691
6692 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
6904 pub fn nrows(&self) -> usize {
6905 self.inner.inner.nrows
6906 }
6907 #[inline(always)]
6909 pub fn ncols(&self) -> usize {
6910 self.inner.inner.ncols
6911 }
6912
6913 #[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 #[inline(always)]
6925 pub fn row_stride(&self) -> isize {
6926 self.inner.inner.row_stride
6927 }
6928
6929 #[inline(always)]
6931 pub fn col_stride(&self) -> isize {
6932 self.inner.inner.col_stride
6933 }
6934
6935 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
7158 #[track_caller]
7159 pub fn read(&self, row: usize, col: usize) -> E {
7160 self.rb().read(row, col)
7161 }
7162
7163 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
7590 pub fn to_owned(&self) -> Mat<E::Canonical>
7591 where
7592 E: Conjugate,
7593 {
7594 self.rb().to_owned()
7595 }
7596
7597 #[inline]
7599 pub fn has_nan(&self) -> bool
7600 where
7601 E: ComplexField,
7602 {
7603 self.rb().has_nan()
7604 }
7605
7606 #[inline]
7608 pub fn is_all_finite(&self) -> bool
7609 where
7610 E: ComplexField,
7611 {
7612 self.rb().is_all_finite()
7613 }
7614
7615 #[inline]
7617 pub fn norm_max(&self) -> E::Real
7618 where
7619 E: ComplexField,
7620 {
7621 norm_max((*self).rb())
7622 }
7623 #[inline]
7625 pub fn norm_l2(&self) -> E::Real
7626 where
7627 E: ComplexField,
7628 {
7629 norm_l2((*self).rb())
7630 }
7631
7632 #[inline]
7634 pub fn sum(&self) -> E
7635 where
7636 E: ComplexField,
7637 {
7638 sum((*self).rb())
7639 }
7640
7641 #[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 #[inline]
7656 pub fn as_ref(&self) -> MatRef<'_, E> {
7657 self.rb()
7658 }
7659
7660 #[inline]
7662 pub fn as_mut(&mut self) -> MatMut<'_, E> {
7663 self.rb_mut()
7664 }
7665
7666 #[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 #[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 #[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 #[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 #[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 #[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 let ptr = unsafe { alloc(layout) } as *mut T;
7812 if ptr.is_null() {
7813 handle_alloc_error(layout)
7814 } else {
7815 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 let alloc_size =
7836 self.row_capacity.wrapping_mul(self.col_capacity) * core::mem::size_of::<T>();
7837 if alloc_size != 0 {
7838 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#[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 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
7956pub type Mat<E> = Matrix<inner::DenseOwn<E>>;
7984
7985pub type Col<E> = Matrix<inner::DenseColOwn<E>>;
7992
7993pub 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 use alloc::alloc::{handle_alloc_error, realloc, Layout};
8034
8035 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 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 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 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 for j in 0..self.ncols {
8088 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 let _ = RawMatUnit::<T> {
8101 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 #[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 #[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 #[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 #[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 #[inline(always)]
8225 pub fn nrows(&self) -> usize {
8226 self.inner.inner.len
8227 }
8228 #[inline(always)]
8230 pub fn ncols(&self) -> usize {
8231 1
8232 }
8233
8234 #[inline]
8242 pub unsafe fn set_nrows(&mut self, nrows: usize) {
8243 self.inner.inner.len = nrows;
8244 }
8245
8246 #[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 #[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 #[inline]
8263 pub fn row_capacity(&self) -> usize {
8264 self.inner.row_capacity
8265 }
8266
8267 #[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 #[inline]
8317 pub fn reserve_exact(&mut self, row_capacity: usize) {
8318 if self.row_capacity() >= row_capacity {
8319 } 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 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 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 #[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 #[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 #[inline]
8412 pub fn as_ref(&self) -> ColRef<'_, E> {
8413 unsafe { col::from_raw_parts(self.as_ptr(), self.nrows(), 1) }
8414 }
8415
8416 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
8519 #[track_caller]
8520 pub fn read(&self, row: usize) -> E {
8521 self.as_ref().read(row)
8522 }
8523
8524 #[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 #[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 #[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 #[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 #[inline(always)]
8576 #[track_caller]
8577 pub fn fill(&mut self, constant: E) {
8578 self.as_mut().fill(constant)
8579 }
8580
8581 #[inline]
8583 pub fn transpose(&self) -> RowRef<'_, E> {
8584 self.as_ref().transpose()
8585 }
8586
8587 #[inline]
8589 pub fn conjugate(&self) -> ColRef<'_, E::Conj>
8590 where
8591 E: Conjugate,
8592 {
8593 self.as_ref().conjugate()
8594 }
8595
8596 #[inline]
8598 pub fn adjoint(&self) -> RowRef<'_, E::Conj>
8599 where
8600 E: Conjugate,
8601 {
8602 self.as_ref().adjoint()
8603 }
8604
8605 #[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 #[inline]
8616 pub fn has_nan(&self) -> bool
8617 where
8618 E: ComplexField,
8619 {
8620 self.as_ref().has_nan()
8621 }
8622
8623 #[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 #[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 #[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 #[inline]
8651 pub fn sum(&self) -> E
8652 where
8653 E: ComplexField,
8654 {
8655 sum((*self).as_ref().as_2d())
8656 }
8657
8658 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
8734 pub fn nrows(&self) -> usize {
8735 1
8736 }
8737 #[inline(always)]
8739 pub fn ncols(&self) -> usize {
8740 self.inner.inner.len
8741 }
8742
8743 #[inline]
8751 pub unsafe fn set_ncols(&mut self, ncols: usize) {
8752 self.inner.inner.len = ncols;
8753 }
8754
8755 #[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 #[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 #[inline]
8772 pub fn col_capacity(&self) -> usize {
8773 self.inner.col_capacity
8774 }
8775
8776 #[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 #[inline]
8826 pub fn reserve_exact(&mut self, col_capacity: usize) {
8827 if self.col_capacity() >= col_capacity {
8828 } 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 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 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 #[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 #[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 #[inline]
8921 pub fn as_ref(&self) -> RowRef<'_, E> {
8922 unsafe { row::from_raw_parts(self.as_ptr(), self.ncols(), 1) }
8923 }
8924
8925 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
9028 #[track_caller]
9029 pub fn read(&self, col: usize) -> E {
9030 self.as_ref().read(col)
9031 }
9032
9033 #[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 #[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 #[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 #[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 #[inline(always)]
9085 #[track_caller]
9086 pub fn fill(&mut self, constant: E) {
9087 self.as_mut().fill(constant)
9088 }
9089
9090 #[inline]
9092 pub fn transpose(&self) -> ColRef<'_, E> {
9093 self.as_ref().transpose()
9094 }
9095
9096 #[inline]
9098 pub fn conjugate(&self) -> RowRef<'_, E::Conj>
9099 where
9100 E: Conjugate,
9101 {
9102 self.as_ref().conjugate()
9103 }
9104
9105 #[inline]
9107 pub fn adjoint(&self) -> ColRef<'_, E::Conj>
9108 where
9109 E: Conjugate,
9110 {
9111 self.as_ref().adjoint()
9112 }
9113
9114 #[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 #[inline]
9125 pub fn has_nan(&self) -> bool
9126 where
9127 E: ComplexField,
9128 {
9129 self.as_ref().has_nan()
9130 }
9131
9132 #[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 #[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 #[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 #[inline]
9160 pub fn sum(&self) -> E
9161 where
9162 E: ComplexField,
9163 {
9164 sum((*self).as_ref().as_2d())
9165 }
9166
9167 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
9266 pub fn nrows(&self) -> usize {
9267 self.inner.inner.nrows
9268 }
9269 #[inline(always)]
9271 pub fn ncols(&self) -> usize {
9272 self.inner.inner.ncols
9273 }
9274
9275 #[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 #[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 #[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 #[inline]
9306 pub fn row_capacity(&self) -> usize {
9307 self.inner.row_capacity
9308 }
9309
9310 #[inline]
9313 pub fn col_capacity(&self) -> usize {
9314 self.inner.col_capacity
9315 }
9316
9317 #[inline]
9320 pub fn row_stride(&self) -> isize {
9321 1
9322 }
9323
9324 #[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 #[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 } 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 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline(always)]
9740 #[track_caller]
9741 pub fn fill(&mut self, constant: E) {
9742 self.as_mut().fill(constant)
9743 }
9744
9745 #[inline]
9747 pub fn transpose(&self) -> MatRef<'_, E> {
9748 self.as_ref().transpose()
9749 }
9750
9751 #[inline]
9753 pub fn conjugate(&self) -> MatRef<'_, E::Conj>
9754 where
9755 E: Conjugate,
9756 {
9757 self.as_ref().conjugate()
9758 }
9759
9760 #[inline]
9762 pub fn adjoint(&self) -> MatRef<'_, E::Conj>
9763 where
9764 E: Conjugate,
9765 {
9766 self.as_ref().adjoint()
9767 }
9768
9769 #[inline]
9771 pub fn diagonal(&self) -> Matrix<inner::DiagRef<'_, E>> {
9772 self.as_ref().diagonal()
9773 }
9774
9775 #[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 #[inline]
9786 pub fn has_nan(&self) -> bool
9787 where
9788 E: ComplexField,
9789 {
9790 self.as_ref().has_nan()
9791 }
9792
9793 #[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 #[inline]
9804 pub fn norm_max(&self) -> E::Real
9805 where
9806 E: ComplexField,
9807 {
9808 norm_max((*self).as_ref())
9809 }
9810 #[inline]
9812 pub fn norm_l2(&self) -> E::Real
9813 where
9814 E: ComplexField,
9815 {
9816 norm_l2((*self).as_ref())
9817 }
9818
9819 #[inline]
9821 pub fn sum(&self) -> E
9822 where
9823 E: ComplexField,
9824 {
9825 sum((*self).as_ref())
9826 }
9827
9828 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[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#[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#[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#[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#[derive(Copy, Clone, Debug, PartialEq, Eq)]
10119pub enum Parallelism {
10120 None,
10125 #[cfg(feature = "rayon")]
10135 #[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
10136 Rayon(usize),
10137}
10138
10139static 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
10155pub fn disable_global_parallelism() {
10157 GLOBAL_PARALLELISM.store(0, core::sync::atomic::Ordering::Relaxed);
10158}
10159
10160pub 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#[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
10285pub 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
10297pub 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
10308pub 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#[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#[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#[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
10506pub 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 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10526 #[repr(transparent)]
10527 pub struct Size<'n>(Branded<'n, usize>);
10528
10529 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10531 #[repr(transparent)]
10532 pub struct Idx<'n, I>(Branded<'n, I>);
10533
10534 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10536 #[repr(transparent)]
10537 pub struct IdxInclusive<'n, I>(Branded<'n, I>);
10538
10539 #[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 #[derive(PartialEq, Eq, PartialOrd, Ord)]
10575 #[repr(transparent)]
10576 pub struct Array<'n, T>(Branded<'n, [T]>);
10577
10578 #[repr(transparent)]
10580 pub struct MatRef<'nrows, 'ncols, 'a, E: Entity>(
10581 Branded<'ncols, Branded<'nrows, super::MatRef<'a, E>>>,
10582 );
10583 #[repr(transparent)]
10585 pub struct MatMut<'nrows, 'ncols, 'a, E: Entity>(
10586 Branded<'ncols, Branded<'nrows, super::MatMut<'a, E>>>,
10587 );
10588
10589 pub mod permutation {
10591 use super::*;
10592 use crate::assert;
10593
10594 #[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 #[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 #[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 #[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 #[inline]
10638 pub fn into_inner(self) -> crate::permutation::PermutationRef<'a, I, E> {
10639 self.0.inner
10640 }
10641
10642 #[inline]
10644 pub fn len(&self) -> Size<'n> {
10645 unsafe { Size::new_raw_unchecked(self.into_inner().len()) }
10646 }
10647
10648 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 pub mod sparse {
10675 use super::*;
10676 use crate::{assert, group_helpers::SliceGroup, sparse::__get_unchecked};
10677 use core::ops::Range;
10678
10679 #[repr(transparent)]
10682 pub struct SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>(
10683 Branded<'ncols, Branded<'nrows, crate::sparse::SymbolicSparseColMatRef<'a, I>>>,
10684 );
10685 pub struct SparseColMatRef<'nrows, 'ncols, 'a, I, E: Entity> {
10688 symbolic: SymbolicSparseColMatRef<'nrows, 'ncols, 'a, I>,
10689 values: SliceGroup<'a, E>,
10690 }
10691 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 #[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 #[inline]
10722 pub fn into_inner(self) -> crate::sparse::SymbolicSparseColMatRef<'a, I> {
10723 self.0.inner.inner
10724 }
10725
10726 #[inline]
10728 pub fn nrows(&self) -> Size<'nrows> {
10729 unsafe { Size::new_raw_unchecked(self.0.inner.inner.nrows()) }
10730 }
10731
10732 #[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 #[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 #[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 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 #[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 #[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 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 #[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 #[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 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 pub struct ArrayGroup<'n, 'a, E: Entity>(Branded<'n, SliceGroup<'a, E>>);
10975 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 #[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 #[inline]
11056 pub fn into_slice(self) -> GroupFor<E, &'a mut [E::Unit]> {
11057 self.0.inner.into_inner()
11058 }
11059
11060 #[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 #[inline]
11075 pub fn read(&self, j: Idx<'n, usize>) -> E {
11076 self.rb().read(j)
11077 }
11078
11079 #[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 #[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 #[inline]
11104 pub fn into_slice(self) -> GroupFor<E, &'a [E::Unit]> {
11105 self.0.inner.into_inner()
11106 }
11107
11108 #[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 #[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 #[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 #[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 #[inline]
11162 pub unsafe fn new_raw_unchecked(n: usize) -> Self {
11163 Size(Branded {
11164 __marker: PhantomData,
11165 inner: n,
11166 })
11167 }
11168
11169 #[inline]
11171 pub fn into_inner(self) -> usize {
11172 self.0.inner
11173 }
11174
11175 #[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 #[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 #[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 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 #[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 #[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 #[inline]
11234 pub unsafe fn new_raw_unchecked(idx: I) -> Self {
11235 Self(Branded {
11236 __marker: PhantomData,
11237 inner: idx,
11238 })
11239 }
11240
11241 #[inline]
11243 pub fn into_inner(self) -> I {
11244 self.0.inner
11245 }
11246
11247 #[inline]
11249 pub fn zx(self) -> Idx<'n, usize> {
11250 unsafe { Idx::new_raw_unchecked(self.0.inner.zx()) }
11251 }
11252
11253 #[inline]
11255 pub fn sx(self) -> ! {
11256 unimplemented!()
11257 }
11258
11259 #[inline]
11261 pub fn to_inclusive(self) -> IdxInclusive<'n, I> {
11262 unsafe { IdxInclusive::new_raw_unchecked(self.into_inner()) }
11263 }
11264 #[inline]
11266 pub fn next(self) -> IdxInclusive<'n, I> {
11267 unsafe { IdxInclusive::new_raw_unchecked(self.into_inner() + I::truncate(1)) }
11268 }
11269
11270 #[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 #[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 #[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 #[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 #[inline]
11308 pub fn from_index(idx: Idx<'n, I>) -> Self {
11309 unsafe { Self::new_raw_unchecked(idx.into_inner()) }
11310 }
11311 #[inline]
11313 pub fn none() -> Self {
11314 unsafe { Self::new_raw_unchecked(I::truncate(usize::MAX)) }
11315 }
11316
11317 #[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 #[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 #[inline]
11339 pub unsafe fn new_raw_unchecked(idx: I) -> Self {
11340 Self(Branded {
11341 __marker: PhantomData,
11342 inner: idx,
11343 })
11344 }
11345
11346 #[inline]
11348 pub fn into_inner(self) -> I {
11349 self.0.inner
11350 }
11351
11352 #[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 #[inline]
11364 pub fn zx(self) -> ! {
11365 unimplemented!()
11366 }
11367
11368 #[inline]
11370 pub fn sx(self) -> MaybeIdx<'n, usize> {
11371 unsafe { MaybeIdx::new_raw_unchecked(self.0.inner.to_signed().sx()) }
11372 }
11373
11374 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
11458 pub unsafe fn new_raw_unchecked(idx: I) -> Self {
11459 Self(Branded {
11460 __marker: PhantomData,
11461 inner: idx,
11462 })
11463 }
11464
11465 #[inline]
11467 pub fn into_inner(self) -> I {
11468 self.0.inner
11469 }
11470
11471 #[inline]
11473 pub fn sx(self) -> ! {
11474 unimplemented!()
11475 }
11476 #[inline]
11478 pub fn zx(self) -> ! {
11479 unimplemented!()
11480 }
11481 }
11482
11483 impl<'n, T> Array<'n, T> {
11484 #[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 #[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 #[inline]
11502 #[track_caller]
11503 pub fn as_ref(&self) -> &[T] {
11504 unsafe { &*(self as *const _ as *const _) }
11505 }
11506
11507 #[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 #[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 #[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 #[inline]
11542 pub fn nrows(&self) -> Size<'nrows> {
11543 unsafe { Size::new_raw_unchecked(self.0.inner.inner.nrows()) }
11544 }
11545
11546 #[inline]
11548 pub fn ncols(&self) -> Size<'ncols> {
11549 unsafe { Size::new_raw_unchecked(self.0.inner.inner.ncols()) }
11550 }
11551
11552 #[inline]
11554 pub fn into_inner(self) -> super::MatRef<'a, E> {
11555 self.0.inner.inner
11556 }
11557
11558 #[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 #[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 #[inline]
11592 pub fn nrows(&self) -> Size<'nrows> {
11593 unsafe { Size::new_raw_unchecked(self.0.inner.inner.nrows()) }
11594 }
11595
11596 #[inline]
11598 pub fn ncols(&self) -> Size<'ncols> {
11599 unsafe { Size::new_raw_unchecked(self.0.inner.inner.ncols()) }
11600 }
11601
11602 #[inline]
11604 pub fn into_inner(self) -> super::MatMut<'a, E> {
11605 self.0.inner.inner
11606 }
11607
11608 #[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 #[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#[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 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
12549pub mod mat {
12551 use super::*;
12552
12553 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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
12891pub mod col {
12893 use super::*;
12894
12895 #[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 #[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 #[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 #[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
12984pub mod row {
12986 use super::*;
12987
12988 #[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 #[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 #[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 #[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#[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 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 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 }
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
13854pub mod zip {
13856 use super::{assert, debug_assert, *};
13857 use core::mem::MaybeUninit;
13858
13859 pub struct Read<'a, E: Entity> {
13861 ptr: GroupFor<E, &'a MaybeUninit<E::Unit>>,
13862 }
13863 pub struct ReadWrite<'a, E: Entity> {
13865 ptr: GroupFor<E, &'a mut MaybeUninit<E::Unit>>,
13866 }
13867
13868 pub trait ViewMut {
13870 type Target<'a>
13872 where
13873 Self: 'a;
13874
13875 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 #[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 #[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 #[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 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
14213 pub enum Diag {
14214 Skip,
14216 Include,
14218 }
14219
14220 #[derive(Copy, Clone)]
14222 pub enum MatLayoutTransform {
14223 None,
14225 ReverseRows,
14227 Transpose,
14229 TransposeReverseRows,
14231 }
14232
14233 #[derive(Copy, Clone)]
14235 pub enum VecLayoutTransform {
14236 None,
14238 Reverse,
14240 }
14241
14242 pub trait MatShape {
14244 type Rows: Copy + Eq;
14246 type Cols: Copy + Eq;
14248 fn nrows(&self) -> Self::Rows;
14250 fn ncols(&self) -> Self::Cols;
14252 }
14253
14254 pub unsafe trait MaybeContiguous: MatShape {
14256 type Index: Copy;
14258 type Slice;
14260 type LayoutTransform: Copy;
14262 unsafe fn get_slice_unchecked(&mut self, idx: Self::Index, n_elems: usize) -> Self::Slice;
14264 }
14265
14266 pub unsafe trait MatIndex<'a, _Outlives = &'a Self>: MaybeContiguous {
14268 type Item;
14270
14271 unsafe fn get_unchecked(&'a mut self, index: Self::Index) -> Self::Item;
14273 unsafe fn get_from_slice_unchecked(slice: &'a mut Self::Slice, idx: usize) -> Self::Item;
14275
14276 fn is_contiguous(&self) -> bool;
14278 fn preferred_layout(&self) -> Self::LayoutTransform;
14280 fn with_layout(self, layout: Self::LayoutTransform) -> Self;
14282 }
14283
14284 #[derive(Copy, Clone, Debug)]
14286 pub struct Last<Mat>(pub Mat);
14287
14288 #[derive(Copy, Clone, Debug)]
14290 pub struct Zip<Head, Tail>(pub Head, pub Tail);
14291
14292 #[derive(Copy, Clone, Debug)]
14294 pub struct LastEq<Rows, Cols, Mat: MatShape<Rows = Rows, Cols = Cols>>(pub Mat);
14295 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}