1use super::{MatRef, *};
2use crate::internal_prelude::*;
3use crate::utils::bound::{Dim, Partition};
4use crate::{Conj, ContiguousFwd, Idx, IdxInc};
5use core::mem::MaybeUninit;
6
7use equator::assert;
8use faer_traits::ComplexField;
9use generativity::Guard;
10use linalg::zip::Last;
11pub struct Mut<
13 'a,
14 T,
15 Rows = usize,
16 Cols = usize,
17 RStride = isize,
18 CStride = isize,
19> {
20 pub(super) imp: MatView<T, Rows, Cols, RStride, CStride>,
21 pub(super) __marker: PhantomData<&'a mut T>,
22}
23
24pub struct UninitMut<
30 'a,
31 T,
32 Rows = usize,
33 Cols = usize,
34 RStride = isize,
35 CStride = isize,
36> {
37 pub(super) imp: MatView<MaybeUninit<T>, Rows, Cols, RStride, CStride>,
38 pub(super) __marker: PhantomData<&'a mut MaybeUninit<T>>,
39}
40
41unsafe impl<T: Sync, Rows: Sync, Cols: Sync, RStride: Sync, CStride: Sync> Sync
42 for UninitMut<'_, T, Rows, Cols, RStride, CStride>
43{
44}
45unsafe impl<T: Send, Rows: Send, Cols: Send, RStride: Send, CStride: Send> Send
46 for UninitMut<'_, T, Rows, Cols, RStride, CStride>
47{
48}
49
50impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride>
51 MatUninitMut<'a, T, Rows, Cols, RStride, CStride>
52{
53 #[inline]
62 #[track_caller]
63 pub const unsafe fn from_raw_parts_mut(
64 ptr: *mut MaybeUninit<T>,
65 nrows: Rows,
66 ncols: Cols,
67 row_stride: RStride,
68 col_stride: CStride,
69 ) -> Self {
70 generic::Mat(UninitMut {
71 imp: MatView {
72 ptr: NonNull::new_unchecked(ptr),
73 nrows,
74 ncols,
75 row_stride,
76 col_stride,
77 },
78 __marker: PhantomData,
79 })
80 }
81
82 #[inline]
84 pub fn as_ptr_mut(&self) -> *mut MaybeUninit<T> {
85 self.imp.ptr.as_ptr()
86 }
87
88 #[inline]
90 pub fn nrows(&self) -> Rows {
91 self.imp.nrows
92 }
93
94 #[inline]
96 pub fn ncols(&self) -> Cols {
97 self.imp.ncols
98 }
99
100 #[inline]
102 pub fn row_stride(&self) -> RStride {
103 self.imp.row_stride
104 }
105
106 #[inline]
108 pub fn col_stride(&self) -> CStride {
109 self.imp.col_stride
110 }
111
112 #[inline]
114 pub fn as_dyn(self) -> MatUninitMut<'a, T, usize, usize, isize, isize> {
115 let ptr = self.as_ptr_mut();
116 let nrows = self.nrows().unbound();
117 let ncols = self.ncols().unbound();
118 let row_stride = self.row_stride().element_stride();
119 let col_stride = self.col_stride().element_stride();
120 unsafe {
121 MatUninitMut::from_raw_parts_mut(
122 ptr, nrows, ncols, row_stride, col_stride,
123 )
124 }
125 }
126}
127
128impl<'a, T, Rows: Shape, Cols: Shape>
129 MatUninitMut<'a, T, Rows, Cols, isize, isize>
130{
131 #[inline]
133 #[track_caller]
134 pub fn from_column_major_slice_mut(
135 slice: &'a mut [MaybeUninit<T>],
136 nrows: Rows,
137 ncols: Cols,
138 ) -> Self {
139 from_slice_assert(nrows.unbound(), ncols.unbound(), slice.len());
140 unsafe {
141 Self::from_raw_parts_mut(
142 slice.as_mut_ptr(),
143 nrows,
144 ncols,
145 1,
146 nrows.unbound() as isize,
147 )
148 }
149 }
150
151 #[inline]
153 #[track_caller]
154 pub fn from_row_major_slice_mut(
155 slice: &'a mut [MaybeUninit<T>],
156 nrows: Rows,
157 ncols: Cols,
158 ) -> Self {
159 from_slice_assert(nrows.unbound(), ncols.unbound(), slice.len());
160 unsafe {
161 Self::from_raw_parts_mut(
162 slice.as_mut_ptr(),
163 nrows,
164 ncols,
165 ncols.unbound() as isize,
166 1,
167 )
168 }
169 }
170}
171#[repr(transparent)]
172pub(crate) struct SyncCell<T>(T);
173unsafe impl<T> Sync for SyncCell<T> {}
174impl<'short, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy>
175 Reborrow<'short> for Mut<'_, T, Rows, Cols, RStride, CStride>
176{
177 type Target = Ref<'short, T, Rows, Cols, RStride, CStride>;
178
179 #[inline]
180 fn rb(&'short self) -> Self::Target {
181 Ref {
182 imp: self.imp,
183 __marker: PhantomData,
184 }
185 }
186}
187impl<'short, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy>
188 ReborrowMut<'short> for Mut<'_, T, Rows, Cols, RStride, CStride>
189{
190 type Target = Mut<'short, T, Rows, Cols, RStride, CStride>;
191
192 #[inline]
193 fn rb_mut(&'short mut self) -> Self::Target {
194 Mut {
195 imp: self.imp,
196 __marker: PhantomData,
197 }
198 }
199}
200impl<'a, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> IntoConst
201 for Mut<'a, T, Rows, Cols, RStride, CStride>
202{
203 type Target = Ref<'a, T, Rows, Cols, RStride, CStride>;
204
205 #[inline]
206 fn into_const(self) -> Self::Target {
207 Ref {
208 imp: self.imp,
209 __marker: PhantomData,
210 }
211 }
212}
213unsafe impl<T: Sync, Rows: Sync, Cols: Sync, RStride: Sync, CStride: Sync> Sync
214 for Mut<'_, T, Rows, Cols, RStride, CStride>
215{
216}
217unsafe impl<T: Send, Rows: Send, Cols: Send, RStride: Send, CStride: Send> Send
218 for Mut<'_, T, Rows, Cols, RStride, CStride>
219{
220}
221impl<'a, T> MatMut<'a, T> {
222 #[inline]
225 pub fn from_row_major_array_mut<const ROWS: usize, const COLS: usize>(
226 array: &'a mut [[T; COLS]; ROWS],
227 ) -> Self {
228 unsafe {
229 Self::from_raw_parts_mut(
230 array as *mut _ as *mut T,
231 ROWS,
232 COLS,
233 COLS as isize,
234 1,
235 )
236 }
237 }
238
239 #[inline]
243 pub fn from_column_major_array_mut<const ROWS: usize, const COLS: usize>(
244 array: &'a mut [[T; ROWS]; COLS],
245 ) -> Self {
246 unsafe {
247 Self::from_raw_parts_mut(
248 array as *mut _ as *mut T,
249 ROWS,
250 COLS,
251 1,
252 ROWS as isize,
253 )
254 }
255 }
256}
257impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride>
258 MatMut<'a, T, Rows, Cols, RStride, CStride>
259{
260 #[inline]
306 #[track_caller]
307 pub const unsafe fn from_raw_parts_mut(
308 ptr: *mut T,
309 nrows: Rows,
310 ncols: Cols,
311 row_stride: RStride,
312 col_stride: CStride,
313 ) -> Self {
314 MatMut {
315 0: Mut {
316 imp: MatView {
317 ptr: NonNull::new_unchecked(ptr),
318 nrows,
319 ncols,
320 row_stride,
321 col_stride,
322 },
323 __marker: PhantomData,
324 },
325 }
326 }
327
328 #[inline]
330 pub fn as_ptr(&self) -> *const T {
331 self.imp.ptr.as_ptr()
332 }
333
334 #[inline]
336 pub fn nrows(&self) -> Rows {
337 self.imp.nrows
338 }
339
340 #[inline]
342 pub fn ncols(&self) -> Cols {
343 self.imp.ncols
344 }
345
346 #[inline]
348 pub fn shape(&self) -> (Rows, Cols) {
349 (self.nrows(), self.ncols())
350 }
351
352 #[inline]
355 pub fn row_stride(&self) -> RStride {
356 self.imp.row_stride
357 }
358
359 #[inline]
362 pub fn col_stride(&self) -> CStride {
363 self.imp.col_stride
364 }
365
366 #[inline]
367 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Mat<U, Rows, Cols> {
368 self.rb().map(f)
369 }
370
371 #[inline]
372 pub fn for_each(&self, f: impl Fn(&T)) {
373 self.rb().for_each(f)
374 }
375
376 #[inline]
377 pub fn map_mut<U>(
378 &mut self,
379 f: impl FnMut(&mut T) -> U,
380 ) -> Mat<U, Rows, Cols> {
381 let mut f = f;
382 zip!(self).map(|unzip!(x)| f(x))
383 }
384
385 #[inline]
386 pub fn for_each_mut(&mut self, f: impl FnMut(&mut T)) {
387 let mut f = f;
388 zip!(self).for_each(|unzip!(x)| f(x))
389 }
390
391 #[inline]
393 pub fn ptr_at(&self, row: IdxInc<Rows>, col: IdxInc<Cols>) -> *const T {
394 self.rb().ptr_at(row, col)
395 }
396
397 #[inline]
406 #[track_caller]
407 pub unsafe fn ptr_inbounds_at(
408 &self,
409 row: Idx<Rows>,
410 col: Idx<Cols>,
411 ) -> *const T {
412 self.rb().ptr_inbounds_at(row, col)
413 }
414
415 #[inline]
416 #[track_caller]
417 pub fn split_at(
419 self,
420 row: IdxInc<Rows>,
421 col: IdxInc<Cols>,
422 ) -> (
423 MatRef<'a, T, usize, usize, RStride, CStride>,
424 MatRef<'a, T, usize, usize, RStride, CStride>,
425 MatRef<'a, T, usize, usize, RStride, CStride>,
426 MatRef<'a, T, usize, usize, RStride, CStride>,
427 ) {
428 self.into_const().split_at(row, col)
429 }
430
431 #[inline]
432 #[track_caller]
433 pub fn split_at_row(
435 self,
436 row: IdxInc<Rows>,
437 ) -> (
438 MatRef<'a, T, usize, Cols, RStride, CStride>,
439 MatRef<'a, T, usize, Cols, RStride, CStride>,
440 ) {
441 self.into_const().split_at_row(row)
442 }
443
444 #[inline]
445 #[track_caller]
446 pub fn split_at_col(
448 self,
449 col: IdxInc<Cols>,
450 ) -> (
451 MatRef<'a, T, Rows, usize, RStride, CStride>,
452 MatRef<'a, T, Rows, usize, RStride, CStride>,
453 ) {
454 self.into_const().split_at_col(col)
455 }
456
457 #[inline]
458 pub fn transpose(self) -> MatRef<'a, T, Cols, Rows, CStride, RStride> {
460 MatRef {
461 0: Ref {
462 imp: MatView {
463 ptr: self.imp.ptr,
464 nrows: self.imp.ncols,
465 ncols: self.imp.nrows,
466 row_stride: self.imp.col_stride,
467 col_stride: self.imp.row_stride,
468 },
469 __marker: PhantomData,
470 },
471 }
472 }
473
474 #[inline]
475 pub fn conjugate(self) -> MatRef<'a, T::Conj, Rows, Cols, RStride, CStride>
477 where
478 T: Conjugate,
479 {
480 self.into_const().conjugate()
481 }
482
483 #[inline]
484 pub fn canonical(
486 self,
487 ) -> MatRef<'a, T::Canonical, Rows, Cols, RStride, CStride>
488 where
489 T: Conjugate,
490 {
491 self.into_const().canonical()
492 }
493
494 #[inline]
495 pub fn adjoint(self) -> MatRef<'a, T::Conj, Cols, Rows, CStride, RStride>
497 where
498 T: Conjugate,
499 {
500 self.into_const().adjoint()
501 }
502
503 #[inline]
504 pub fn reverse_rows(
506 self,
507 ) -> MatRef<'a, T, Rows, Cols, RStride::Rev, CStride> {
508 self.into_const().reverse_rows()
509 }
510
511 #[inline]
512 pub fn reverse_cols(
514 self,
515 ) -> MatRef<'a, T, Rows, Cols, RStride, CStride::Rev> {
516 self.into_const().reverse_cols()
517 }
518
519 #[inline]
520 pub fn reverse_rows_and_cols(
522 self,
523 ) -> MatRef<'a, T, Rows, Cols, RStride::Rev, CStride::Rev> {
524 self.into_const().reverse_rows_and_cols()
525 }
526
527 #[inline]
528 #[track_caller]
529 pub fn submatrix<V: Shape, H: Shape>(
531 self,
532 row_start: IdxInc<Rows>,
533 col_start: IdxInc<Cols>,
534 nrows: V,
535 ncols: H,
536 ) -> MatRef<'a, T, V, H, RStride, CStride> {
537 self.into_const()
538 .submatrix(row_start, col_start, nrows, ncols)
539 }
540
541 #[inline]
542 #[track_caller]
543 pub fn subrows<V: Shape>(
545 self,
546 row_start: IdxInc<Rows>,
547 nrows: V,
548 ) -> MatRef<'a, T, V, Cols, RStride, CStride> {
549 self.into_const().subrows(row_start, nrows)
550 }
551
552 #[inline]
553 #[track_caller]
554 pub fn subcols<H: Shape>(
556 self,
557 col_start: IdxInc<Cols>,
558 ncols: H,
559 ) -> MatRef<'a, T, Rows, H, RStride, CStride> {
560 self.into_const().subcols(col_start, ncols)
561 }
562
563 #[inline]
564 #[track_caller]
565 pub fn as_shape<V: Shape, H: Shape>(
567 self,
568 nrows: V,
569 ncols: H,
570 ) -> MatRef<'a, T, V, H, RStride, CStride> {
571 self.into_const().as_shape(nrows, ncols)
572 }
573
574 #[inline]
575 #[track_caller]
576 pub fn as_row_shape<V: Shape>(
578 self,
579 nrows: V,
580 ) -> MatRef<'a, T, V, Cols, RStride, CStride> {
581 self.into_const().as_row_shape(nrows)
582 }
583
584 #[inline]
585 #[track_caller]
586 pub fn as_col_shape<H: Shape>(
588 self,
589 ncols: H,
590 ) -> MatRef<'a, T, Rows, H, RStride, CStride> {
591 self.into_const().as_col_shape(ncols)
592 }
593
594 #[inline]
595 pub fn as_dyn_stride(self) -> MatRef<'a, T, Rows, Cols, isize, isize> {
597 self.into_const().as_dyn_stride()
598 }
599
600 #[inline]
601 pub fn as_dyn(self) -> MatRef<'a, T, usize, usize, RStride, CStride> {
603 self.into_const().as_dyn()
604 }
605
606 #[inline]
607 pub fn as_dyn_rows(self) -> MatRef<'a, T, usize, Cols, RStride, CStride> {
609 self.into_const().as_dyn_rows()
610 }
611
612 #[inline]
613 pub fn as_dyn_cols(self) -> MatRef<'a, T, Rows, usize, RStride, CStride> {
615 self.into_const().as_dyn_cols()
616 }
617
618 #[inline]
619 #[track_caller]
620 pub fn row(self, i: Idx<Rows>) -> RowRef<'a, T, Cols, CStride> {
622 self.into_const().row(i)
623 }
624
625 #[inline]
626 #[track_caller]
627 pub fn col(self, j: Idx<Cols>) -> ColRef<'a, T, Rows, RStride> {
629 self.into_const().col(j)
630 }
631
632 #[inline]
633 pub fn col_iter(
635 self,
636 ) -> impl 'a
637 + ExactSizeIterator
638 + DoubleEndedIterator<Item = ColRef<'a, T, Rows, RStride>>
639 where
640 Rows: 'a,
641 Cols: 'a,
642 {
643 self.into_const().col_iter()
644 }
645
646 #[inline]
647 pub fn row_iter(
649 self,
650 ) -> impl 'a
651 + ExactSizeIterator
652 + DoubleEndedIterator<Item = RowRef<'a, T, Cols, CStride>>
653 where
654 Rows: 'a,
655 Cols: 'a,
656 {
657 self.into_const().row_iter()
658 }
659
660 #[inline]
661 #[cfg(feature = "rayon")]
662 pub fn par_col_iter(
664 self,
665 ) -> impl 'a
666 + rayon::iter::IndexedParallelIterator<
667 Item = ColRef<'a, T, Rows, RStride>,
668 >
669 where
670 T: Sync,
671 Rows: 'a,
672 Cols: 'a,
673 {
674 self.into_const().par_col_iter()
675 }
676
677 #[inline]
678 #[cfg(feature = "rayon")]
679 pub fn par_row_iter(
681 self,
682 ) -> impl 'a
683 + rayon::iter::IndexedParallelIterator<
684 Item = RowRef<'a, T, Cols, CStride>,
685 >
686 where
687 T: Sync,
688 Rows: 'a,
689 Cols: 'a,
690 {
691 self.into_const().par_row_iter()
692 }
693
694 #[inline]
695 #[track_caller]
696 #[cfg(feature = "rayon")]
697 pub fn par_col_chunks(
699 self,
700 chunk_size: usize,
701 ) -> impl 'a
702 + rayon::iter::IndexedParallelIterator<
703 Item = MatRef<'a, T, Rows, usize, RStride, CStride>,
704 >
705 where
706 T: Sync,
707 Rows: 'a,
708 Cols: 'a,
709 {
710 self.into_const().par_col_chunks(chunk_size)
711 }
712
713 #[inline]
714 #[track_caller]
715 #[cfg(feature = "rayon")]
716 pub fn par_col_partition(
718 self,
719 count: usize,
720 ) -> impl 'a
721 + rayon::iter::IndexedParallelIterator<
722 Item = MatRef<'a, T, Rows, usize, RStride, CStride>,
723 >
724 where
725 T: Sync,
726 Rows: 'a,
727 Cols: 'a,
728 {
729 self.into_const().par_col_partition(count)
730 }
731
732 #[inline]
733 #[track_caller]
734 #[cfg(feature = "rayon")]
735 pub fn par_row_chunks(
737 self,
738 chunk_size: usize,
739 ) -> impl 'a
740 + rayon::iter::IndexedParallelIterator<
741 Item = MatRef<'a, T, usize, Cols, RStride, CStride>,
742 >
743 where
744 T: Sync,
745 Rows: 'a,
746 Cols: 'a,
747 {
748 self.into_const().par_row_chunks(chunk_size)
749 }
750
751 #[inline]
752 #[track_caller]
753 #[cfg(feature = "rayon")]
754 pub fn par_row_partition(
756 self,
757 count: usize,
758 ) -> impl 'a
759 + rayon::iter::IndexedParallelIterator<
760 Item = MatRef<'a, T, usize, Cols, RStride, CStride>,
761 >
762 where
763 T: Sync,
764 Rows: 'a,
765 Cols: 'a,
766 {
767 self.into_const().par_row_partition(count)
768 }
769
770 #[inline]
771 pub fn try_as_col_major(
773 self,
774 ) -> Option<MatRef<'a, T, Rows, Cols, ContiguousFwd, CStride>> {
775 self.into_const().try_as_col_major()
776 }
777
778 #[inline]
779 pub fn try_as_row_major(
781 self,
782 ) -> Option<MatRef<'a, T, Rows, Cols, RStride, ContiguousFwd>> {
783 self.into_const().try_as_row_major()
784 }
785
786 #[doc(hidden)]
787 #[inline]
788 pub unsafe fn const_cast(
789 self,
790 ) -> MatMut<'a, T, Rows, Cols, RStride, CStride> {
791 self
792 }
793
794 #[inline]
796 pub fn bind<'M, 'N>(
797 self,
798 row: Guard<'M>,
799 col: Guard<'N>,
800 ) -> MatMut<'a, T, Dim<'M>, Dim<'N>, RStride, CStride> {
801 unsafe {
802 MatMut::from_raw_parts_mut(
803 self.as_ptr_mut(),
804 self.nrows().bind(row),
805 self.ncols().bind(col),
806 self.row_stride(),
807 self.col_stride(),
808 )
809 }
810 }
811
812 #[doc(hidden)]
813 #[inline]
814 pub fn bind_r<'M>(
815 self,
816 row: Guard<'M>,
817 ) -> MatMut<'a, T, Dim<'M>, Cols, RStride, CStride> {
818 unsafe {
819 MatMut::from_raw_parts_mut(
820 self.as_ptr_mut(),
821 self.nrows().bind(row),
822 self.ncols(),
823 self.row_stride(),
824 self.col_stride(),
825 )
826 }
827 }
828
829 #[doc(hidden)]
830 #[inline]
831 pub fn bind_c<'N>(
832 self,
833 col: Guard<'N>,
834 ) -> MatMut<'a, T, Rows, Dim<'N>, RStride, CStride> {
835 unsafe {
836 MatMut::from_raw_parts_mut(
837 self.as_ptr_mut(),
838 self.nrows(),
839 self.ncols().bind(col),
840 self.row_stride(),
841 self.col_stride(),
842 )
843 }
844 }
845
846 #[track_caller]
847 #[inline]
848 pub fn get<RowRange, ColRange>(
850 self,
851 row: RowRange,
852 col: ColRange,
853 ) -> <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
854 RowRange,
855 ColRange,
856 >>::Target
857 where
858 MatRef<'a, T, Rows, Cols, RStride, CStride>:
859 MatIndex<RowRange, ColRange>,
860 {
861 <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
862 RowRange,
863 ColRange,
864 >>::get(self.into_const(), row, col)
865 }
866
867 #[track_caller]
868 #[inline]
869 pub unsafe fn get_unchecked<RowRange, ColRange>(
874 self,
875 row: RowRange,
876 col: ColRange,
877 ) -> <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
878 RowRange,
879 ColRange,
880 >>::Target
881 where
882 MatRef<'a, T, Rows, Cols, RStride, CStride>:
883 MatIndex<RowRange, ColRange>,
884 {
885 unsafe {
886 <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
887 RowRange,
888 ColRange,
889 >>::get_unchecked(self.into_const(), row, col)
890 }
891 }
892
893 #[track_caller]
895 #[inline]
896 pub fn get_mut<RowRange, ColRange>(
897 self,
898 row: RowRange,
899 col: ColRange,
900 ) -> <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
901 RowRange,
902 ColRange,
903 >>::Target
904 where
905 MatMut<'a, T, Rows, Cols, RStride, CStride>:
906 MatIndex<RowRange, ColRange>,
907 {
908 <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
909 RowRange,
910 ColRange,
911 >>::get(self, row, col)
912 }
913
914 #[track_caller]
919 #[inline]
920 pub unsafe fn get_mut_unchecked<RowRange, ColRange>(
921 self,
922 row: RowRange,
923 col: ColRange,
924 ) -> <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
925 RowRange,
926 ColRange,
927 >>::Target
928 where
929 MatMut<'a, T, Rows, Cols, RStride, CStride>:
930 MatIndex<RowRange, ColRange>,
931 {
932 unsafe {
933 <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
934 RowRange,
935 ColRange,
936 >>::get_unchecked(self, row, col)
937 }
938 }
939}
940impl<
941 T,
942 Rows: Shape,
943 Cols: Shape,
944 RStride: Stride,
945 CStride: Stride,
946 Inner: for<'short> ReborrowMut<
947 'short,
948 Target = Mut<'short, T, Rows, Cols, RStride, CStride>,
949 >,
950> generic::Mat<Inner>
951{
952 #[inline]
954 pub fn as_mut(&mut self) -> MatMut<'_, T, Rows, Cols, RStride, CStride> {
955 self.rb_mut()
956 }
957
958 #[inline]
961 #[track_caller]
962 pub fn copy_from_triangular_lower<RhsT: Conjugate<Canonical = T>>(
963 &mut self,
964 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
965 ) where
966 T: ComplexField,
967 {
968 let other = other.as_mat_ref();
969 let mut this = self.rb_mut();
970 assert!(all(
971 this.nrows() == other.nrows(),
972 this.ncols() == other.ncols(),
973 ));
974 let (m, n) = this.shape();
975 make_guard!(M);
976 make_guard!(N);
977 let M = m.bind(M);
978 let N = n.bind(N);
979 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
980 let other = other.as_shape(M, N);
981 imp(this, other.canonical(), Conj::get::<RhsT>());
982 pub fn imp<'M, 'N, T: ComplexField>(
983 this: MatMut<'_, T, Dim<'M>, Dim<'N>>,
984 other: MatRef<'_, T, Dim<'M>, Dim<'N>>,
985 conj_: Conj,
986 ) {
987 match conj_ {
988 Conj::No => {
989 zip!(this, other).for_each_triangular_lower(
990 crate::linalg::zip::Diag::Include,
991 |unzip!(dst, src)| *dst = src.copy(),
992 );
993 },
994 Conj::Yes => {
995 zip!(this, other).for_each_triangular_lower(
996 crate::linalg::zip::Diag::Include,
997 |unzip!(dst, src)| *dst = src.conj(),
998 );
999 },
1000 }
1001 }
1002 }
1003
1004 #[inline]
1007 #[track_caller]
1008 pub fn copy_from_triangular_upper<RhsT: Conjugate<Canonical = T>>(
1009 &mut self,
1010 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
1011 ) where
1012 T: ComplexField,
1013 {
1014 (*self)
1015 .rb_mut()
1016 .transpose_mut()
1017 .copy_from_triangular_lower(other.as_mat_ref().transpose())
1018 }
1019
1020 #[inline]
1022 #[track_caller]
1023 pub fn copy_from<RhsT: Conjugate<Canonical = T>>(
1024 &mut self,
1025 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
1026 ) where
1027 T: ComplexField,
1028 {
1029 let other = other.as_mat_ref();
1030 let mut this = self.rb_mut();
1031 assert!(all(
1032 this.nrows() == other.nrows(),
1033 this.ncols() == other.ncols(),
1034 ));
1035 let (m, n) = this.shape();
1036 make_guard!(M);
1037 make_guard!(N);
1038 let M = m.bind(M);
1039 let N = n.bind(N);
1040 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
1041 let other = other.as_shape(M, N);
1042 imp(this, other.canonical(), Conj::get::<RhsT>());
1043 pub fn imp<'M, 'N, T: ComplexField>(
1044 this: MatMut<'_, T, Dim<'M>, Dim<'N>>,
1045 other: MatRef<'_, T, Dim<'M>, Dim<'N>>,
1046 conj_: Conj,
1047 ) {
1048 match conj_ {
1049 Conj::No => {
1050 zip!(this, other)
1051 .for_each(|unzip!(dst, src)| *dst = src.copy());
1052 },
1053 Conj::Yes => {
1054 zip!(this, other)
1055 .for_each(|unzip!(dst, src)| *dst = src.conj());
1056 },
1057 }
1058 }
1059 }
1060
1061 #[inline]
1064 #[track_caller]
1065 pub fn copy_from_strict_triangular_lower<RhsT: Conjugate<Canonical = T>>(
1066 &mut self,
1067 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
1068 ) where
1069 T: ComplexField,
1070 {
1071 let other = other.as_mat_ref();
1072 let mut this = self.rb_mut();
1073 assert!(all(
1074 this.nrows() == other.nrows(),
1075 this.ncols() == other.ncols(),
1076 ));
1077 let (m, n) = this.shape();
1078 make_guard!(M);
1079 make_guard!(N);
1080 let M = m.bind(M);
1081 let N = n.bind(N);
1082 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
1083 let other = other.as_shape(M, N);
1084 imp(this, other.canonical(), Conj::get::<RhsT>());
1085 pub fn imp<'M, 'N, T: ComplexField>(
1086 this: MatMut<'_, T, Dim<'M>, Dim<'N>>,
1087 other: MatRef<'_, T, Dim<'M>, Dim<'N>>,
1088 conj_: Conj,
1089 ) {
1090 match conj_ {
1091 Conj::No => {
1092 zip!(this, other).for_each_triangular_lower(
1093 crate::linalg::zip::Diag::Skip,
1094 |unzip!(dst, src)| *dst = src.copy(),
1095 );
1096 },
1097 Conj::Yes => {
1098 zip!(this, other).for_each_triangular_lower(
1099 crate::linalg::zip::Diag::Skip,
1100 |unzip!(dst, src)| *dst = src.conj(),
1101 );
1102 },
1103 }
1104 }
1105 }
1106
1107 #[inline]
1110 #[track_caller]
1111 pub fn copy_from_strict_triangular_upper<RhsT: Conjugate<Canonical = T>>(
1112 &mut self,
1113 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
1114 ) where
1115 T: ComplexField,
1116 {
1117 (*self)
1118 .rb_mut()
1119 .transpose_mut()
1120 .copy_from_strict_triangular_lower(other.as_mat_ref().transpose())
1121 }
1122
1123 #[inline]
1125 pub fn fill(&mut self, value: T)
1126 where
1127 T: Clone,
1128 {
1129 fn cloner<T: Clone>(value: T) -> impl for<'a> FnMut(Last<&'a mut T>) {
1130 #[inline]
1131 move |x| *x.0 = value.clone()
1132 }
1133 z!(self.rb_mut().as_dyn_mut()).for_each(cloner::<T>(value));
1134 }
1135}
1136impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride>
1137 MatMut<'a, T, Rows, Cols, RStride, CStride>
1138{
1139 #[inline]
1140 pub fn as_ptr_mut(&self) -> *mut T {
1142 self.imp.ptr.as_ptr()
1143 }
1144
1145 #[inline]
1146 pub fn ptr_at_mut(&self, row: IdxInc<Rows>, col: IdxInc<Cols>) -> *mut T {
1148 self.rb().ptr_at(row, col) as *mut T
1149 }
1150
1151 #[inline]
1152 #[track_caller]
1153 pub unsafe fn ptr_inbounds_at_mut(
1155 &self,
1156 row: Idx<Rows>,
1157 col: Idx<Cols>,
1158 ) -> *mut T {
1159 self.rb().ptr_inbounds_at(row, col) as *mut T
1160 }
1161
1162 #[inline]
1163 #[track_caller]
1164 pub fn split_at_mut(
1166 self,
1167 row: IdxInc<Rows>,
1168 col: IdxInc<Cols>,
1169 ) -> (
1170 MatMut<'a, T, usize, usize, RStride, CStride>,
1171 MatMut<'a, T, usize, usize, RStride, CStride>,
1172 MatMut<'a, T, usize, usize, RStride, CStride>,
1173 MatMut<'a, T, usize, usize, RStride, CStride>,
1174 ) {
1175 let (a, b, c, d) = self.into_const().split_at(row, col);
1176 unsafe {
1177 (
1178 a.const_cast(),
1179 b.const_cast(),
1180 c.const_cast(),
1181 d.const_cast(),
1182 )
1183 }
1184 }
1185
1186 #[inline]
1187 #[track_caller]
1188 pub fn split_at_row_mut(
1190 self,
1191 row: IdxInc<Rows>,
1192 ) -> (
1193 MatMut<'a, T, usize, Cols, RStride, CStride>,
1194 MatMut<'a, T, usize, Cols, RStride, CStride>,
1195 ) {
1196 let (a, b) = self.into_const().split_at_row(row);
1197 unsafe { (a.const_cast(), b.const_cast()) }
1198 }
1199
1200 #[inline]
1201 #[track_caller]
1202 pub fn split_at_col_mut(
1204 self,
1205 col: IdxInc<Cols>,
1206 ) -> (
1207 MatMut<'a, T, Rows, usize, RStride, CStride>,
1208 MatMut<'a, T, Rows, usize, RStride, CStride>,
1209 ) {
1210 let (a, b) = self.into_const().split_at_col(col);
1211 unsafe { (a.const_cast(), b.const_cast()) }
1212 }
1213
1214 #[inline]
1215 pub fn transpose_mut(self) -> MatMut<'a, T, Cols, Rows, CStride, RStride> {
1217 MatMut {
1218 0: Mut {
1219 imp: MatView {
1220 ptr: self.imp.ptr,
1221 nrows: self.imp.ncols,
1222 ncols: self.imp.nrows,
1223 row_stride: self.imp.col_stride,
1224 col_stride: self.imp.row_stride,
1225 },
1226 __marker: PhantomData,
1227 },
1228 }
1229 }
1230
1231 #[inline]
1232 pub fn conjugate_mut(
1234 self,
1235 ) -> MatMut<'a, T::Conj, Rows, Cols, RStride, CStride>
1236 where
1237 T: Conjugate,
1238 {
1239 unsafe { self.into_const().conjugate().const_cast() }
1240 }
1241
1242 #[inline]
1243 pub fn canonical_mut(
1245 self,
1246 ) -> MatMut<'a, T::Canonical, Rows, Cols, RStride, CStride>
1247 where
1248 T: Conjugate,
1249 {
1250 unsafe { self.into_const().canonical().const_cast() }
1251 }
1252
1253 #[inline]
1254 pub fn adjoint_mut(
1256 self,
1257 ) -> MatMut<'a, T::Conj, Cols, Rows, CStride, RStride>
1258 where
1259 T: Conjugate,
1260 {
1261 unsafe { self.into_const().adjoint().const_cast() }
1262 }
1263
1264 #[inline]
1265 #[track_caller]
1266 pub(crate) fn at_mut(self, row: Idx<Rows>, col: Idx<Cols>) -> &'a mut T {
1267 assert!(all(row < self.nrows(), col < self.ncols()));
1268 unsafe { self.at_mut_unchecked(row, col) }
1269 }
1270
1271 #[inline]
1272 #[track_caller]
1273 pub(crate) unsafe fn at_mut_unchecked(
1274 self,
1275 row: Idx<Rows>,
1276 col: Idx<Cols>,
1277 ) -> &'a mut T {
1278 &mut *self.ptr_inbounds_at_mut(row, col)
1279 }
1280
1281 #[inline]
1282 pub fn reverse_rows_mut(
1284 self,
1285 ) -> MatMut<'a, T, Rows, Cols, RStride::Rev, CStride> {
1286 unsafe { self.into_const().reverse_rows().const_cast() }
1287 }
1288
1289 #[inline]
1290 pub fn reverse_cols_mut(
1292 self,
1293 ) -> MatMut<'a, T, Rows, Cols, RStride, CStride::Rev> {
1294 unsafe { self.into_const().reverse_cols().const_cast() }
1295 }
1296
1297 #[inline]
1298 pub fn reverse_rows_and_cols_mut(
1300 self,
1301 ) -> MatMut<'a, T, Rows, Cols, RStride::Rev, CStride::Rev> {
1302 unsafe { self.into_const().reverse_rows_and_cols().const_cast() }
1303 }
1304
1305 #[inline]
1306 #[track_caller]
1307 pub fn submatrix_mut<V: Shape, H: Shape>(
1309 self,
1310 row_start: IdxInc<Rows>,
1311 col_start: IdxInc<Cols>,
1312 nrows: V,
1313 ncols: H,
1314 ) -> MatMut<'a, T, V, H, RStride, CStride> {
1315 unsafe {
1316 self.into_const()
1317 .submatrix(row_start, col_start, nrows, ncols)
1318 .const_cast()
1319 }
1320 }
1321
1322 #[inline]
1323 #[track_caller]
1324 pub fn subrows_mut<V: Shape>(
1326 self,
1327 row_start: IdxInc<Rows>,
1328 nrows: V,
1329 ) -> MatMut<'a, T, V, Cols, RStride, CStride> {
1330 unsafe { self.into_const().subrows(row_start, nrows).const_cast() }
1331 }
1332
1333 #[inline]
1334 #[track_caller]
1335 pub fn subcols_mut<H: Shape>(
1337 self,
1338 col_start: IdxInc<Cols>,
1339 ncols: H,
1340 ) -> MatMut<'a, T, Rows, H, RStride, CStride> {
1341 unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
1342 }
1343
1344 #[inline]
1345 #[track_caller]
1346 pub fn as_shape_mut<V: Shape, H: Shape>(
1348 self,
1349 nrows: V,
1350 ncols: H,
1351 ) -> MatMut<'a, T, V, H, RStride, CStride> {
1352 unsafe { self.into_const().as_shape(nrows, ncols).const_cast() }
1353 }
1354
1355 #[inline]
1356 #[track_caller]
1357 pub fn as_row_shape_mut<V: Shape>(
1359 self,
1360 nrows: V,
1361 ) -> MatMut<'a, T, V, Cols, RStride, CStride> {
1362 unsafe { self.into_const().as_row_shape(nrows).const_cast() }
1363 }
1364
1365 #[inline]
1366 #[track_caller]
1367 pub fn as_col_shape_mut<H: Shape>(
1369 self,
1370 ncols: H,
1371 ) -> MatMut<'a, T, Rows, H, RStride, CStride> {
1372 unsafe { self.into_const().as_col_shape(ncols).const_cast() }
1373 }
1374
1375 #[inline]
1376 pub fn as_dyn_stride_mut(self) -> MatMut<'a, T, Rows, Cols, isize, isize> {
1378 unsafe { self.into_const().as_dyn_stride().const_cast() }
1379 }
1380
1381 #[inline]
1382 pub fn as_dyn_mut(self) -> MatMut<'a, T, usize, usize, RStride, CStride> {
1384 unsafe { self.into_const().as_dyn().const_cast() }
1385 }
1386
1387 #[inline]
1388 pub fn as_dyn_rows_mut(
1390 self,
1391 ) -> MatMut<'a, T, usize, Cols, RStride, CStride> {
1392 unsafe { self.into_const().as_dyn_rows().const_cast() }
1393 }
1394
1395 #[inline]
1396 pub fn as_dyn_cols_mut(
1398 self,
1399 ) -> MatMut<'a, T, Rows, usize, RStride, CStride> {
1400 unsafe { self.into_const().as_dyn_cols().const_cast() }
1401 }
1402
1403 #[inline]
1404 #[track_caller]
1405 pub fn row_mut(self, i: Idx<Rows>) -> RowMut<'a, T, Cols, CStride> {
1407 unsafe { self.into_const().row(i).const_cast() }
1408 }
1409
1410 #[inline]
1411 #[track_caller]
1412 pub fn col_mut(self, j: Idx<Cols>) -> ColMut<'a, T, Rows, RStride> {
1414 unsafe { self.into_const().col(j).const_cast() }
1415 }
1416
1417 #[inline]
1418 pub fn col_iter_mut(
1420 self,
1421 ) -> impl 'a
1422 + ExactSizeIterator
1423 + DoubleEndedIterator<Item = ColMut<'a, T, Rows, RStride>>
1424 where
1425 Rows: 'a,
1426 Cols: 'a,
1427 {
1428 self.into_const()
1429 .col_iter()
1430 .map(|x| unsafe { x.const_cast() })
1431 }
1432
1433 #[inline]
1434 pub fn row_iter_mut(
1436 self,
1437 ) -> impl 'a
1438 + ExactSizeIterator
1439 + DoubleEndedIterator<Item = RowMut<'a, T, Cols, CStride>>
1440 where
1441 Rows: 'a,
1442 Cols: 'a,
1443 {
1444 self.into_const()
1445 .row_iter()
1446 .map(|x| unsafe { x.const_cast() })
1447 }
1448
1449 #[inline]
1450 pub(crate) unsafe fn as_type<U>(
1451 self,
1452 ) -> MatMut<'a, U, Rows, Cols, RStride, CStride> {
1453 MatMut::from_raw_parts_mut(
1454 self.as_ptr_mut() as *mut U,
1455 self.nrows(),
1456 self.ncols(),
1457 self.row_stride(),
1458 self.col_stride(),
1459 )
1460 }
1461
1462 #[inline]
1463 #[cfg(feature = "rayon")]
1464 pub fn par_col_iter_mut(
1466 self,
1467 ) -> impl 'a
1468 + rayon::iter::IndexedParallelIterator<
1469 Item = ColMut<'a, T, Rows, RStride>,
1470 >
1471 where
1472 T: Send,
1473 Rows: 'a,
1474 Cols: 'a,
1475 {
1476 use rayon::prelude::*;
1477 unsafe {
1478 self.as_type::<SyncCell<T>>()
1479 .into_const()
1480 .par_col_iter()
1481 .map(|x| x.const_cast())
1482 .map(|x| x.as_type())
1483 }
1484 }
1485
1486 #[inline]
1487 #[cfg(feature = "rayon")]
1488 pub fn par_row_iter_mut(
1490 self,
1491 ) -> impl 'a
1492 + rayon::iter::IndexedParallelIterator<
1493 Item = RowMut<'a, T, Cols, CStride>,
1494 >
1495 where
1496 T: Send,
1497 Rows: 'a,
1498 Cols: 'a,
1499 {
1500 use rayon::prelude::*;
1501 unsafe {
1502 self.as_type::<SyncCell<T>>()
1503 .into_const()
1504 .par_row_iter()
1505 .map(|x| x.const_cast())
1506 .map(|x| x.as_type())
1507 }
1508 }
1509
1510 #[inline]
1511 #[track_caller]
1512 #[cfg(feature = "rayon")]
1513 pub fn par_col_chunks_mut(
1515 self,
1516 chunk_size: usize,
1517 ) -> impl 'a
1518 + rayon::iter::IndexedParallelIterator<
1519 Item = MatMut<'a, T, Rows, usize, RStride, CStride>,
1520 >
1521 where
1522 T: Send,
1523 Rows: 'a,
1524 Cols: 'a,
1525 {
1526 use rayon::prelude::*;
1527 unsafe {
1528 self.as_type::<SyncCell<T>>()
1529 .into_const()
1530 .par_col_chunks(chunk_size)
1531 .map(|x| x.const_cast())
1532 .map(|x| x.as_type())
1533 }
1534 }
1535
1536 #[inline]
1537 #[track_caller]
1538 #[cfg(feature = "rayon")]
1539 pub fn par_col_partition_mut(
1541 self,
1542 count: usize,
1543 ) -> impl 'a
1544 + rayon::iter::IndexedParallelIterator<
1545 Item = MatMut<'a, T, Rows, usize, RStride, CStride>,
1546 >
1547 where
1548 T: Send,
1549 Rows: 'a,
1550 Cols: 'a,
1551 {
1552 use rayon::prelude::*;
1553 unsafe {
1554 self.as_type::<SyncCell<T>>()
1555 .into_const()
1556 .par_col_partition(count)
1557 .map(|x| x.const_cast())
1558 .map(|x| x.as_type())
1559 }
1560 }
1561
1562 #[inline]
1563 #[track_caller]
1564 #[cfg(feature = "rayon")]
1565 pub fn par_row_chunks_mut(
1567 self,
1568 chunk_size: usize,
1569 ) -> impl 'a
1570 + rayon::iter::IndexedParallelIterator<
1571 Item = MatMut<'a, T, usize, Cols, RStride, CStride>,
1572 >
1573 where
1574 T: Send,
1575 Rows: 'a,
1576 Cols: 'a,
1577 {
1578 use rayon::prelude::*;
1579 unsafe {
1580 self.as_type::<SyncCell<T>>()
1581 .into_const()
1582 .par_row_chunks(chunk_size)
1583 .map(|x| x.const_cast())
1584 .map(|x| x.as_type())
1585 }
1586 }
1587
1588 #[inline]
1589 #[track_caller]
1590 #[cfg(feature = "rayon")]
1591 pub fn par_row_partition_mut(
1593 self,
1594 count: usize,
1595 ) -> impl 'a
1596 + rayon::iter::IndexedParallelIterator<
1597 Item = MatMut<'a, T, usize, Cols, RStride, CStride>,
1598 >
1599 where
1600 T: Send,
1601 Rows: 'a,
1602 Cols: 'a,
1603 {
1604 use rayon::prelude::*;
1605 unsafe {
1606 self.as_type::<SyncCell<T>>()
1607 .into_const()
1608 .par_row_partition(count)
1609 .map(|x| x.const_cast())
1610 .map(|x| x.as_type())
1611 }
1612 }
1613
1614 #[inline]
1615 pub fn split_first_row_mut(
1617 self,
1618 ) -> Option<(
1619 RowMut<'a, T, Cols, CStride>,
1620 MatMut<'a, T, usize, Cols, RStride, CStride>,
1621 )> {
1622 if let Some(i0) = self.nrows().idx_inc(1) {
1623 let (head, tail) = self.split_at_row_mut(i0);
1624 Some((head.row_mut(0), tail))
1625 } else {
1626 None
1627 }
1628 }
1629
1630 #[inline]
1631 pub fn split_first_col_mut(
1633 self,
1634 ) -> Option<(
1635 ColMut<'a, T, Rows, RStride>,
1636 MatMut<'a, T, Rows, usize, RStride, CStride>,
1637 )> {
1638 if let Some(i0) = self.ncols().idx_inc(1) {
1639 let (head, tail) = self.split_at_col_mut(i0);
1640 Some((head.col_mut(0), tail))
1641 } else {
1642 None
1643 }
1644 }
1645
1646 #[inline]
1647 pub fn split_last_row_mut(
1649 self,
1650 ) -> Option<(
1651 RowMut<'a, T, Cols, CStride>,
1652 MatMut<'a, T, usize, Cols, RStride, CStride>,
1653 )> {
1654 if self.nrows().unbound() > 0 {
1655 let i0 = self.nrows().checked_idx_inc(self.nrows().unbound() - 1);
1656 let (head, tail) = self.split_at_row_mut(i0);
1657 Some((tail.row_mut(0), head))
1658 } else {
1659 None
1660 }
1661 }
1662
1663 #[inline]
1664 pub fn split_last_col_mut(
1666 self,
1667 ) -> Option<(
1668 ColMut<'a, T, Rows, RStride>,
1669 MatMut<'a, T, Rows, usize, RStride, CStride>,
1670 )> {
1671 if self.ncols().unbound() > 0 {
1672 let i0 = self.ncols().checked_idx_inc(self.ncols().unbound() - 1);
1673 let (head, tail) = self.split_at_col_mut(i0);
1674 Some((tail.col_mut(0), head))
1675 } else {
1676 None
1677 }
1678 }
1679
1680 #[inline]
1681 pub fn split_first_row(
1683 self,
1684 ) -> Option<(
1685 RowRef<'a, T, Cols, CStride>,
1686 MatRef<'a, T, usize, Cols, RStride, CStride>,
1687 )> {
1688 self.into_const().split_first_row()
1689 }
1690
1691 #[inline]
1692 pub fn split_first_col(
1694 self,
1695 ) -> Option<(
1696 ColRef<'a, T, Rows, RStride>,
1697 MatRef<'a, T, Rows, usize, RStride, CStride>,
1698 )> {
1699 self.into_const().split_first_col()
1700 }
1701
1702 #[inline]
1703 pub fn split_last_row(
1705 self,
1706 ) -> Option<(
1707 RowRef<'a, T, Cols, CStride>,
1708 MatRef<'a, T, usize, Cols, RStride, CStride>,
1709 )> {
1710 self.into_const().split_last_row()
1711 }
1712
1713 #[inline]
1714 pub fn split_last_col(
1716 self,
1717 ) -> Option<(
1718 ColRef<'a, T, Rows, RStride>,
1719 MatRef<'a, T, Rows, usize, RStride, CStride>,
1720 )> {
1721 self.into_const().split_last_col()
1722 }
1723
1724 #[inline]
1725 pub fn try_as_col_major_mut(
1727 self,
1728 ) -> Option<MatMut<'a, T, Rows, Cols, ContiguousFwd, CStride>> {
1729 self.into_const()
1730 .try_as_col_major()
1731 .map(|x| unsafe { x.const_cast() })
1732 }
1733
1734 #[inline]
1735 pub fn try_as_row_major_mut(
1737 self,
1738 ) -> Option<MatMut<'a, T, Rows, Cols, RStride, ContiguousFwd>> {
1739 self.into_const()
1740 .try_as_row_major()
1741 .map(|x| unsafe { x.const_cast() })
1742 }
1743
1744 #[inline]
1749 #[track_caller]
1750 pub fn two_cols_mut(
1751 self,
1752 i0: Idx<Cols>,
1753 i1: Idx<Cols>,
1754 ) -> (ColMut<'a, T, Rows, RStride>, ColMut<'a, T, Rows, RStride>) {
1755 assert!(i0 != i1);
1756 let this = self.into_const();
1757 unsafe { (this.col(i0).const_cast(), this.col(i1).const_cast()) }
1758 }
1759
1760 #[inline]
1765 #[track_caller]
1766 pub fn two_rows_mut(
1767 self,
1768 i0: Idx<Rows>,
1769 i1: Idx<Rows>,
1770 ) -> (RowMut<'a, T, Cols, CStride>, RowMut<'a, T, Cols, CStride>) {
1771 assert!(i0 != i1);
1772 let this = self.into_const();
1773 unsafe { (this.row(i0).const_cast(), this.row(i1).const_cast()) }
1774 }
1775
1776 #[inline]
1777 pub(crate) fn __at_mut(self, (i, j): (Idx<Rows>, Idx<Cols>)) -> &'a mut T {
1778 self.at_mut(i, j)
1779 }
1780}
1781impl<'a, T, Rows: Shape, Cols: Shape> MatMut<'a, T, Rows, Cols> {
1782 #[inline]
1801 #[track_caller]
1802 pub fn from_column_major_slice_mut(
1803 slice: &'a mut [T],
1804 nrows: Rows,
1805 ncols: Cols,
1806 ) -> Self
1807 where
1808 T: Sized,
1809 {
1810 from_slice_assert(nrows.unbound(), ncols.unbound(), slice.len());
1811 unsafe {
1812 Self::from_raw_parts_mut(
1813 slice.as_mut_ptr(),
1814 nrows,
1815 ncols,
1816 1,
1817 nrows.unbound() as isize,
1818 )
1819 }
1820 }
1821
1822 #[inline]
1827 #[track_caller]
1828 pub fn from_column_major_slice_with_stride_mut(
1829 slice: &'a mut [T],
1830 nrows: Rows,
1831 ncols: Cols,
1832 col_stride: usize,
1833 ) -> Self
1834 where
1835 T: Sized,
1836 {
1837 from_strided_column_major_slice_mut_assert(
1838 nrows.unbound(),
1839 ncols.unbound(),
1840 col_stride,
1841 slice.len(),
1842 );
1843 unsafe {
1844 Self::from_raw_parts_mut(
1845 slice.as_mut_ptr(),
1846 nrows,
1847 ncols,
1848 1,
1849 col_stride as isize,
1850 )
1851 }
1852 }
1853
1854 #[inline]
1873 #[track_caller]
1874 pub fn from_row_major_slice_mut(
1875 slice: &'a mut [T],
1876 nrows: Rows,
1877 ncols: Cols,
1878 ) -> Self
1879 where
1880 T: Sized,
1881 {
1882 MatMut::from_column_major_slice_mut(slice, ncols, nrows).transpose_mut()
1883 }
1884
1885 #[inline]
1890 #[track_caller]
1891 pub fn from_row_major_slice_with_stride_mut(
1892 slice: &'a mut [T],
1893 nrows: Rows,
1894 ncols: Cols,
1895 row_stride: usize,
1896 ) -> Self
1897 where
1898 T: Sized,
1899 {
1900 from_strided_row_major_slice_mut_assert(
1901 nrows.unbound(),
1902 ncols.unbound(),
1903 row_stride,
1904 slice.len(),
1905 );
1906 unsafe {
1907 Self::from_raw_parts_mut(
1908 slice.as_mut_ptr(),
1909 nrows,
1910 ncols,
1911 row_stride as isize,
1912 1,
1913 )
1914 }
1915 }
1916}
1917impl<'ROWS, 'COLS, 'a, T, RStride: Stride, CStride: Stride>
1918 MatMut<'a, T, Dim<'ROWS>, Dim<'COLS>, RStride, CStride>
1919{
1920 #[doc(hidden)]
1921 #[inline]
1922 pub fn split_with_mut<'TOP, 'BOT, 'LEFT, 'RIGHT>(
1923 self,
1924 row: Partition<'TOP, 'BOT, 'ROWS>,
1925 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1926 ) -> (
1927 MatMut<'a, T, Dim<'TOP>, Dim<'LEFT>, RStride, CStride>,
1928 MatMut<'a, T, Dim<'TOP>, Dim<'RIGHT>, RStride, CStride>,
1929 MatMut<'a, T, Dim<'BOT>, Dim<'LEFT>, RStride, CStride>,
1930 MatMut<'a, T, Dim<'BOT>, Dim<'RIGHT>, RStride, CStride>,
1931 ) {
1932 let (a, b, c, d) = self.split_at_mut(row.midpoint(), col.midpoint());
1933 (
1934 a.as_shape_mut(row.head, col.head),
1935 b.as_shape_mut(row.head, col.tail),
1936 c.as_shape_mut(row.tail, col.head),
1937 d.as_shape_mut(row.tail, col.tail),
1938 )
1939 }
1940}
1941impl<'ROWS, 'a, T, Cols: Shape, RStride: Stride, CStride: Stride>
1942 MatMut<'a, T, Dim<'ROWS>, Cols, RStride, CStride>
1943{
1944 #[doc(hidden)]
1945 #[inline]
1946 pub fn split_rows_with_mut<'TOP, 'BOT>(
1947 self,
1948 row: Partition<'TOP, 'BOT, 'ROWS>,
1949 ) -> (
1950 MatMut<'a, T, Dim<'TOP>, Cols, RStride, CStride>,
1951 MatMut<'a, T, Dim<'BOT>, Cols, RStride, CStride>,
1952 ) {
1953 let (a, b) = self.split_at_row_mut(row.midpoint());
1954 (a.as_row_shape_mut(row.head), b.as_row_shape_mut(row.tail))
1955 }
1956}
1957impl<'COLS, 'a, T, Rows: Shape, RStride: Stride, CStride: Stride>
1958 MatMut<'a, T, Rows, Dim<'COLS>, RStride, CStride>
1959{
1960 #[doc(hidden)]
1961 #[inline]
1962 pub fn split_cols_with_mut<'LEFT, 'RIGHT>(
1963 self,
1964 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1965 ) -> (
1966 MatMut<'a, T, Rows, Dim<'LEFT>, RStride, CStride>,
1967 MatMut<'a, T, Rows, Dim<'RIGHT>, RStride, CStride>,
1968 ) {
1969 let (a, b) = self.split_at_col_mut(col.midpoint());
1970 (a.as_col_shape_mut(col.head), b.as_col_shape_mut(col.tail))
1971 }
1972}
1973impl<'ROWS, 'COLS, 'a, T, RStride: Stride, CStride: Stride>
1974 MatMut<'a, T, Dim<'ROWS>, Dim<'COLS>, RStride, CStride>
1975{
1976 #[doc(hidden)]
1977 #[inline]
1978 pub fn split_with<'TOP, 'BOT, 'LEFT, 'RIGHT>(
1979 self,
1980 row: Partition<'TOP, 'BOT, 'ROWS>,
1981 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1982 ) -> (
1983 MatRef<'a, T, Dim<'TOP>, Dim<'LEFT>, RStride, CStride>,
1984 MatRef<'a, T, Dim<'TOP>, Dim<'RIGHT>, RStride, CStride>,
1985 MatRef<'a, T, Dim<'BOT>, Dim<'LEFT>, RStride, CStride>,
1986 MatRef<'a, T, Dim<'BOT>, Dim<'RIGHT>, RStride, CStride>,
1987 ) {
1988 let (a, b, c, d) = self.split_at(row.midpoint(), col.midpoint());
1989 (
1990 a.as_shape(row.head, col.head),
1991 b.as_shape(row.head, col.tail),
1992 c.as_shape(row.tail, col.head),
1993 d.as_shape(row.tail, col.tail),
1994 )
1995 }
1996}
1997impl<'ROWS, 'a, T, Cols: Shape, RStride: Stride, CStride: Stride>
1998 MatMut<'a, T, Dim<'ROWS>, Cols, RStride, CStride>
1999{
2000 #[doc(hidden)]
2001 #[inline]
2002 pub fn split_rows_with<'TOP, 'BOT>(
2003 self,
2004 row: Partition<'TOP, 'BOT, 'ROWS>,
2005 ) -> (
2006 MatRef<'a, T, Dim<'TOP>, Cols, RStride, CStride>,
2007 MatRef<'a, T, Dim<'BOT>, Cols, RStride, CStride>,
2008 ) {
2009 let (a, b) = self.split_at_row(row.midpoint());
2010 (a.as_row_shape(row.head), b.as_row_shape(row.tail))
2011 }
2012}
2013impl<'COLS, 'a, T, Rows: Shape, RStride: Stride, CStride: Stride>
2014 MatMut<'a, T, Rows, Dim<'COLS>, RStride, CStride>
2015{
2016 #[doc(hidden)]
2017 #[inline]
2018 pub fn split_cols_with<'LEFT, 'RIGHT>(
2019 self,
2020 col: Partition<'LEFT, 'RIGHT, 'COLS>,
2021 ) -> (
2022 MatRef<'a, T, Rows, Dim<'LEFT>, RStride, CStride>,
2023 MatRef<'a, T, Rows, Dim<'RIGHT>, RStride, CStride>,
2024 ) {
2025 let (a, b) = self.split_at_col(col.midpoint());
2026 (a.as_col_shape(col.head), b.as_col_shape(col.tail))
2027 }
2028}
2029impl<'a, T, Dim: Shape, RStride: Stride, CStride: Stride>
2030 MatMut<'a, T, Dim, Dim, RStride, CStride>
2031{
2032 #[inline]
2034 pub fn diagonal(self) -> DiagRef<'a, T, Dim, isize> {
2035 self.into_const().diagonal()
2036 }
2037}
2038impl<'a, T, Dim: Shape, RStride: Stride, CStride: Stride>
2039 MatMut<'a, T, Dim, Dim, RStride, CStride>
2040{
2041 #[inline]
2043 pub fn diagonal_mut(self) -> DiagMut<'a, T, Dim, isize> {
2044 unsafe {
2045 self.into_const()
2046 .diagonal()
2047 .column_vector()
2048 .const_cast()
2049 .as_diagonal_mut()
2050 }
2051 }
2052}
2053impl<
2054 'a,
2055 T: core::fmt::Debug,
2056 Rows: Shape,
2057 Cols: Shape,
2058 RStride: Stride,
2059 CStride: Stride,
2060> core::fmt::Debug for Mut<'a, T, Rows, Cols, RStride, CStride>
2061{
2062 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2063 self.rb().fmt(f)
2064 }
2065}
2066impl<'a, T, Rows: Shape, Cols: Shape> MatMut<'a, T, Rows, Cols>
2067where
2068 T: RealField,
2069{
2070 pub fn min(self) -> Option<T> {
2072 MatRef::internal_min(self.rb().as_dyn())
2073 }
2074
2075 pub fn max(self) -> Option<T> {
2077 MatRef::internal_max(self.rb().as_dyn())
2078 }
2079}
2080#[track_caller]
2081#[inline]
2082fn from_strided_column_major_slice_mut_assert(
2083 nrows: usize,
2084 ncols: usize,
2085 col_stride: usize,
2086 len: usize,
2087) {
2088 if nrows > 0 && ncols > 0 {
2089 let last = usize::checked_mul(col_stride, ncols - 1)
2090 .and_then(|last_col| last_col.checked_add(nrows - 1));
2091 let Some(last) = last else {
2092 panic!("address computation of the last matrix element overflowed");
2093 };
2094 assert!(all(col_stride >= nrows, last < len));
2095 }
2096}
2097#[track_caller]
2098#[inline]
2099fn from_strided_row_major_slice_mut_assert(
2100 nrows: usize,
2101 ncols: usize,
2102 row_stride: usize,
2103 len: usize,
2104) {
2105 if nrows > 0 && ncols > 0 {
2106 let last = usize::checked_mul(row_stride, nrows - 1)
2107 .and_then(|last_row| last_row.checked_add(ncols - 1));
2108 let Some(last) = last else {
2109 panic!("address computation of the last matrix element overflowed");
2110 };
2111 assert!(all(row_stride >= ncols, last < len));
2112 }
2113}
2114#[cfg(test)]
2115mod tests {
2116 use super::*;
2117 #[test]
2118 fn test_min() {
2119 let mut m = mat![[1.0, 5.0, 3.0], [4.0, 2.0, 9.0], [7.0, 8.0, 6.0],];
2120 assert_eq!(m.as_mut().min(), Some(1.0));
2121 let mut empty: Mat<f64> = Mat::new();
2122 assert_eq!(empty.as_mut().min(), None);
2123 }
2124 #[test]
2125 fn test_max() {
2126 let mut m = mat![[1.0, 5.0, 3.0], [4.0, 2.0, 9.0], [7.0, 8.0, 6.0],];
2127 assert_eq!(m.as_mut().max(), Some(9.0));
2128 let mut empty: Mat<f64> = Mat::new();
2129 assert_eq!(empty.as_mut().max(), None);
2130 }
2131 #[test]
2132 fn codeberg_305() {
2133 const PAD: f64 = -42.0;
2134 let mut slice = [0.0, 1.0, 2.0, PAD, 3.0, 4.0, 5.0, PAD, PAD, PAD];
2135 {
2136 let mut mat_view = MatMut::from_row_major_slice_with_stride_mut(
2137 &mut slice, 2, 3, 4,
2138 );
2139 assert_eq!(mat![[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]], mat_view);
2140 mat_view[(1, 2)] = 99.0;
2141 }
2142 assert_eq!(slice, [0.0, 1.0, 2.0, PAD, 3.0, 4.0, 99.0, PAD, PAD, PAD]);
2143 }
2144}