1use super::{MatRef, *};
2use crate::internal_prelude::*;
3use crate::utils::bound::{Dim, Partition};
4use crate::{Conj, ContiguousFwd, Idx, IdxInc};
5
6use equator::assert;
7use faer_traits::ComplexField;
8use generativity::Guard;
9use linalg::zip::Last;
10pub struct Mut<
12 'a,
13 T,
14 Rows = usize,
15 Cols = usize,
16 RStride = isize,
17 CStride = isize,
18> {
19 pub(super) imp: MatView<T, Rows, Cols, RStride, CStride>,
20 pub(super) __marker: PhantomData<&'a mut T>,
21}
22#[repr(transparent)]
23pub(crate) struct SyncCell<T>(T);
24unsafe impl<T> Sync for SyncCell<T> {}
25impl<'short, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy>
26 Reborrow<'short> for Mut<'_, T, Rows, Cols, RStride, CStride>
27{
28 type Target = Ref<'short, T, Rows, Cols, RStride, CStride>;
29
30 #[inline]
31 fn rb(&'short self) -> Self::Target {
32 Ref {
33 imp: self.imp,
34 __marker: PhantomData,
35 }
36 }
37}
38impl<'short, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy>
39 ReborrowMut<'short> for Mut<'_, T, Rows, Cols, RStride, CStride>
40{
41 type Target = Mut<'short, T, Rows, Cols, RStride, CStride>;
42
43 #[inline]
44 fn rb_mut(&'short mut self) -> Self::Target {
45 Mut {
46 imp: self.imp,
47 __marker: PhantomData,
48 }
49 }
50}
51impl<'a, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> IntoConst
52 for Mut<'a, T, Rows, Cols, RStride, CStride>
53{
54 type Target = Ref<'a, T, Rows, Cols, RStride, CStride>;
55
56 #[inline]
57 fn into_const(self) -> Self::Target {
58 Ref {
59 imp: self.imp,
60 __marker: PhantomData,
61 }
62 }
63}
64unsafe impl<T: Sync, Rows: Sync, Cols: Sync, RStride: Sync, CStride: Sync> Sync
65 for Mut<'_, T, Rows, Cols, RStride, CStride>
66{
67}
68unsafe impl<T: Send, Rows: Send, Cols: Send, RStride: Send, CStride: Send> Send
69 for Mut<'_, T, Rows, Cols, RStride, CStride>
70{
71}
72impl<'a, T> MatMut<'a, T> {
73 #[inline]
76 pub fn from_row_major_array_mut<const ROWS: usize, const COLS: usize>(
77 array: &'a mut [[T; COLS]; ROWS],
78 ) -> Self {
79 unsafe {
80 Self::from_raw_parts_mut(
81 array as *mut _ as *mut T,
82 ROWS,
83 COLS,
84 COLS as isize,
85 1,
86 )
87 }
88 }
89
90 #[inline]
94 pub fn from_column_major_array_mut<const ROWS: usize, const COLS: usize>(
95 array: &'a mut [[T; ROWS]; COLS],
96 ) -> Self {
97 unsafe {
98 Self::from_raw_parts_mut(
99 array as *mut _ as *mut T,
100 ROWS,
101 COLS,
102 1,
103 ROWS as isize,
104 )
105 }
106 }
107}
108impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride>
109 MatMut<'a, T, Rows, Cols, RStride, CStride>
110{
111 #[inline]
157 #[track_caller]
158 pub const unsafe fn from_raw_parts_mut(
159 ptr: *mut T,
160 nrows: Rows,
161 ncols: Cols,
162 row_stride: RStride,
163 col_stride: CStride,
164 ) -> Self {
165 MatMut {
166 0: Mut {
167 imp: MatView {
168 ptr: NonNull::new_unchecked(ptr),
169 nrows,
170 ncols,
171 row_stride,
172 col_stride,
173 },
174 __marker: PhantomData,
175 },
176 }
177 }
178
179 #[inline]
181 pub fn as_ptr(&self) -> *const T {
182 self.imp.ptr.as_ptr()
183 }
184
185 #[inline]
187 pub fn nrows(&self) -> Rows {
188 self.imp.nrows
189 }
190
191 #[inline]
193 pub fn ncols(&self) -> Cols {
194 self.imp.ncols
195 }
196
197 #[inline]
199 pub fn shape(&self) -> (Rows, Cols) {
200 (self.nrows(), self.ncols())
201 }
202
203 #[inline]
206 pub fn row_stride(&self) -> RStride {
207 self.imp.row_stride
208 }
209
210 #[inline]
213 pub fn col_stride(&self) -> CStride {
214 self.imp.col_stride
215 }
216
217 #[inline]
218 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Mat<U, Rows, Cols> {
219 self.rb().map(f)
220 }
221
222 #[inline]
223 pub fn for_each(&self, f: impl Fn(&T)) {
224 self.rb().for_each(f)
225 }
226
227 #[inline]
228 pub fn map_mut<U>(
229 &mut self,
230 f: impl FnMut(&mut T) -> U,
231 ) -> Mat<U, Rows, Cols> {
232 let mut f = f;
233 zip!(self).map(|unzip!(x)| f(x))
234 }
235
236 #[inline]
237 pub fn for_each_mut(&mut self, f: impl FnMut(&mut T)) {
238 let mut f = f;
239 zip!(self).for_each(|unzip!(x)| f(x))
240 }
241
242 #[inline]
244 pub fn ptr_at(&self, row: IdxInc<Rows>, col: IdxInc<Cols>) -> *const T {
245 self.rb().ptr_at(row, col)
246 }
247
248 #[inline]
257 #[track_caller]
258 pub unsafe fn ptr_inbounds_at(
259 &self,
260 row: Idx<Rows>,
261 col: Idx<Cols>,
262 ) -> *const T {
263 self.rb().ptr_inbounds_at(row, col)
264 }
265
266 #[inline]
267 #[track_caller]
268 pub fn split_at(
270 self,
271 row: IdxInc<Rows>,
272 col: IdxInc<Cols>,
273 ) -> (
274 MatRef<'a, T, usize, usize, RStride, CStride>,
275 MatRef<'a, T, usize, usize, RStride, CStride>,
276 MatRef<'a, T, usize, usize, RStride, CStride>,
277 MatRef<'a, T, usize, usize, RStride, CStride>,
278 ) {
279 self.into_const().split_at(row, col)
280 }
281
282 #[inline]
283 #[track_caller]
284 pub fn split_at_row(
286 self,
287 row: IdxInc<Rows>,
288 ) -> (
289 MatRef<'a, T, usize, Cols, RStride, CStride>,
290 MatRef<'a, T, usize, Cols, RStride, CStride>,
291 ) {
292 self.into_const().split_at_row(row)
293 }
294
295 #[inline]
296 #[track_caller]
297 pub fn split_at_col(
299 self,
300 col: IdxInc<Cols>,
301 ) -> (
302 MatRef<'a, T, Rows, usize, RStride, CStride>,
303 MatRef<'a, T, Rows, usize, RStride, CStride>,
304 ) {
305 self.into_const().split_at_col(col)
306 }
307
308 #[inline]
309 pub fn transpose(self) -> MatRef<'a, T, Cols, Rows, CStride, RStride> {
311 MatRef {
312 0: Ref {
313 imp: MatView {
314 ptr: self.imp.ptr,
315 nrows: self.imp.ncols,
316 ncols: self.imp.nrows,
317 row_stride: self.imp.col_stride,
318 col_stride: self.imp.row_stride,
319 },
320 __marker: PhantomData,
321 },
322 }
323 }
324
325 #[inline]
326 pub fn conjugate(self) -> MatRef<'a, T::Conj, Rows, Cols, RStride, CStride>
328 where
329 T: Conjugate,
330 {
331 self.into_const().conjugate()
332 }
333
334 #[inline]
335 pub fn canonical(
337 self,
338 ) -> MatRef<'a, T::Canonical, Rows, Cols, RStride, CStride>
339 where
340 T: Conjugate,
341 {
342 self.into_const().canonical()
343 }
344
345 #[inline]
346 pub fn adjoint(self) -> MatRef<'a, T::Conj, Cols, Rows, CStride, RStride>
348 where
349 T: Conjugate,
350 {
351 self.into_const().adjoint()
352 }
353
354 #[inline]
355 pub fn reverse_rows(
357 self,
358 ) -> MatRef<'a, T, Rows, Cols, RStride::Rev, CStride> {
359 self.into_const().reverse_rows()
360 }
361
362 #[inline]
363 pub fn reverse_cols(
365 self,
366 ) -> MatRef<'a, T, Rows, Cols, RStride, CStride::Rev> {
367 self.into_const().reverse_cols()
368 }
369
370 #[inline]
371 pub fn reverse_rows_and_cols(
373 self,
374 ) -> MatRef<'a, T, Rows, Cols, RStride::Rev, CStride::Rev> {
375 self.into_const().reverse_rows_and_cols()
376 }
377
378 #[inline]
379 #[track_caller]
380 pub fn submatrix<V: Shape, H: Shape>(
382 self,
383 row_start: IdxInc<Rows>,
384 col_start: IdxInc<Cols>,
385 nrows: V,
386 ncols: H,
387 ) -> MatRef<'a, T, V, H, RStride, CStride> {
388 self.into_const()
389 .submatrix(row_start, col_start, nrows, ncols)
390 }
391
392 #[inline]
393 #[track_caller]
394 pub fn subrows<V: Shape>(
396 self,
397 row_start: IdxInc<Rows>,
398 nrows: V,
399 ) -> MatRef<'a, T, V, Cols, RStride, CStride> {
400 self.into_const().subrows(row_start, nrows)
401 }
402
403 #[inline]
404 #[track_caller]
405 pub fn subcols<H: Shape>(
407 self,
408 col_start: IdxInc<Cols>,
409 ncols: H,
410 ) -> MatRef<'a, T, Rows, H, RStride, CStride> {
411 self.into_const().subcols(col_start, ncols)
412 }
413
414 #[inline]
415 #[track_caller]
416 pub fn as_shape<V: Shape, H: Shape>(
418 self,
419 nrows: V,
420 ncols: H,
421 ) -> MatRef<'a, T, V, H, RStride, CStride> {
422 self.into_const().as_shape(nrows, ncols)
423 }
424
425 #[inline]
426 #[track_caller]
427 pub fn as_row_shape<V: Shape>(
429 self,
430 nrows: V,
431 ) -> MatRef<'a, T, V, Cols, RStride, CStride> {
432 self.into_const().as_row_shape(nrows)
433 }
434
435 #[inline]
436 #[track_caller]
437 pub fn as_col_shape<H: Shape>(
439 self,
440 ncols: H,
441 ) -> MatRef<'a, T, Rows, H, RStride, CStride> {
442 self.into_const().as_col_shape(ncols)
443 }
444
445 #[inline]
446 pub fn as_dyn_stride(self) -> MatRef<'a, T, Rows, Cols, isize, isize> {
448 self.into_const().as_dyn_stride()
449 }
450
451 #[inline]
452 pub fn as_dyn(self) -> MatRef<'a, T, usize, usize, RStride, CStride> {
454 self.into_const().as_dyn()
455 }
456
457 #[inline]
458 pub fn as_dyn_rows(self) -> MatRef<'a, T, usize, Cols, RStride, CStride> {
460 self.into_const().as_dyn_rows()
461 }
462
463 #[inline]
464 pub fn as_dyn_cols(self) -> MatRef<'a, T, Rows, usize, RStride, CStride> {
466 self.into_const().as_dyn_cols()
467 }
468
469 #[inline]
470 #[track_caller]
471 pub fn row(self, i: Idx<Rows>) -> RowRef<'a, T, Cols, CStride> {
473 self.into_const().row(i)
474 }
475
476 #[inline]
477 #[track_caller]
478 pub fn col(self, j: Idx<Cols>) -> ColRef<'a, T, Rows, RStride> {
480 self.into_const().col(j)
481 }
482
483 #[inline]
484 pub fn col_iter(
486 self,
487 ) -> impl 'a
488 + ExactSizeIterator
489 + DoubleEndedIterator<Item = ColRef<'a, T, Rows, RStride>>
490 where
491 Rows: 'a,
492 Cols: 'a,
493 {
494 self.into_const().col_iter()
495 }
496
497 #[inline]
498 pub fn row_iter(
500 self,
501 ) -> impl 'a
502 + ExactSizeIterator
503 + DoubleEndedIterator<Item = RowRef<'a, T, Cols, CStride>>
504 where
505 Rows: 'a,
506 Cols: 'a,
507 {
508 self.into_const().row_iter()
509 }
510
511 #[inline]
512 #[cfg(feature = "rayon")]
513 pub fn par_col_iter(
515 self,
516 ) -> impl 'a
517 + rayon::iter::IndexedParallelIterator<
518 Item = ColRef<'a, T, Rows, RStride>,
519 >
520 where
521 T: Sync,
522 Rows: 'a,
523 Cols: 'a,
524 {
525 self.into_const().par_col_iter()
526 }
527
528 #[inline]
529 #[cfg(feature = "rayon")]
530 pub fn par_row_iter(
532 self,
533 ) -> impl 'a
534 + rayon::iter::IndexedParallelIterator<
535 Item = RowRef<'a, T, Cols, CStride>,
536 >
537 where
538 T: Sync,
539 Rows: 'a,
540 Cols: 'a,
541 {
542 self.into_const().par_row_iter()
543 }
544
545 #[inline]
546 #[track_caller]
547 #[cfg(feature = "rayon")]
548 pub fn par_col_chunks(
550 self,
551 chunk_size: usize,
552 ) -> impl 'a
553 + rayon::iter::IndexedParallelIterator<
554 Item = MatRef<'a, T, Rows, usize, RStride, CStride>,
555 >
556 where
557 T: Sync,
558 Rows: 'a,
559 Cols: 'a,
560 {
561 self.into_const().par_col_chunks(chunk_size)
562 }
563
564 #[inline]
565 #[track_caller]
566 #[cfg(feature = "rayon")]
567 pub fn par_col_partition(
569 self,
570 count: usize,
571 ) -> impl 'a
572 + rayon::iter::IndexedParallelIterator<
573 Item = MatRef<'a, T, Rows, usize, RStride, CStride>,
574 >
575 where
576 T: Sync,
577 Rows: 'a,
578 Cols: 'a,
579 {
580 self.into_const().par_col_partition(count)
581 }
582
583 #[inline]
584 #[track_caller]
585 #[cfg(feature = "rayon")]
586 pub fn par_row_chunks(
588 self,
589 chunk_size: usize,
590 ) -> impl 'a
591 + rayon::iter::IndexedParallelIterator<
592 Item = MatRef<'a, T, usize, Cols, RStride, CStride>,
593 >
594 where
595 T: Sync,
596 Rows: 'a,
597 Cols: 'a,
598 {
599 self.into_const().par_row_chunks(chunk_size)
600 }
601
602 #[inline]
603 #[track_caller]
604 #[cfg(feature = "rayon")]
605 pub fn par_row_partition(
607 self,
608 count: usize,
609 ) -> impl 'a
610 + rayon::iter::IndexedParallelIterator<
611 Item = MatRef<'a, T, usize, Cols, RStride, CStride>,
612 >
613 where
614 T: Sync,
615 Rows: 'a,
616 Cols: 'a,
617 {
618 self.into_const().par_row_partition(count)
619 }
620
621 #[inline]
622 pub fn try_as_col_major(
624 self,
625 ) -> Option<MatRef<'a, T, Rows, Cols, ContiguousFwd, CStride>> {
626 self.into_const().try_as_col_major()
627 }
628
629 #[inline]
630 pub fn try_as_row_major(
632 self,
633 ) -> Option<MatRef<'a, T, Rows, Cols, RStride, ContiguousFwd>> {
634 self.into_const().try_as_row_major()
635 }
636
637 #[doc(hidden)]
638 #[inline]
639 pub unsafe fn const_cast(
640 self,
641 ) -> MatMut<'a, T, Rows, Cols, RStride, CStride> {
642 self
643 }
644
645 #[inline]
647 pub fn bind<'M, 'N>(
648 self,
649 row: Guard<'M>,
650 col: Guard<'N>,
651 ) -> MatMut<'a, T, Dim<'M>, Dim<'N>, RStride, CStride> {
652 unsafe {
653 MatMut::from_raw_parts_mut(
654 self.as_ptr_mut(),
655 self.nrows().bind(row),
656 self.ncols().bind(col),
657 self.row_stride(),
658 self.col_stride(),
659 )
660 }
661 }
662
663 #[doc(hidden)]
664 #[inline]
665 pub fn bind_r<'M>(
666 self,
667 row: Guard<'M>,
668 ) -> MatMut<'a, T, Dim<'M>, Cols, RStride, CStride> {
669 unsafe {
670 MatMut::from_raw_parts_mut(
671 self.as_ptr_mut(),
672 self.nrows().bind(row),
673 self.ncols(),
674 self.row_stride(),
675 self.col_stride(),
676 )
677 }
678 }
679
680 #[doc(hidden)]
681 #[inline]
682 pub fn bind_c<'N>(
683 self,
684 col: Guard<'N>,
685 ) -> MatMut<'a, T, Rows, Dim<'N>, RStride, CStride> {
686 unsafe {
687 MatMut::from_raw_parts_mut(
688 self.as_ptr_mut(),
689 self.nrows(),
690 self.ncols().bind(col),
691 self.row_stride(),
692 self.col_stride(),
693 )
694 }
695 }
696
697 #[track_caller]
698 #[inline]
699 pub fn get<RowRange, ColRange>(
701 self,
702 row: RowRange,
703 col: ColRange,
704 ) -> <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
705 RowRange,
706 ColRange,
707 >>::Target
708 where
709 MatRef<'a, T, Rows, Cols, RStride, CStride>:
710 MatIndex<RowRange, ColRange>,
711 {
712 <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
713 RowRange,
714 ColRange,
715 >>::get(self.into_const(), row, col)
716 }
717
718 #[track_caller]
719 #[inline]
720 pub unsafe fn get_unchecked<RowRange, ColRange>(
725 self,
726 row: RowRange,
727 col: ColRange,
728 ) -> <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
729 RowRange,
730 ColRange,
731 >>::Target
732 where
733 MatRef<'a, T, Rows, Cols, RStride, CStride>:
734 MatIndex<RowRange, ColRange>,
735 {
736 unsafe {
737 <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
738 RowRange,
739 ColRange,
740 >>::get_unchecked(self.into_const(), row, col)
741 }
742 }
743
744 #[track_caller]
746 #[inline]
747 pub fn get_mut<RowRange, ColRange>(
748 self,
749 row: RowRange,
750 col: ColRange,
751 ) -> <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
752 RowRange,
753 ColRange,
754 >>::Target
755 where
756 MatMut<'a, T, Rows, Cols, RStride, CStride>:
757 MatIndex<RowRange, ColRange>,
758 {
759 <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
760 RowRange,
761 ColRange,
762 >>::get(self, row, col)
763 }
764
765 #[track_caller]
770 #[inline]
771 pub unsafe fn get_mut_unchecked<RowRange, ColRange>(
772 self,
773 row: RowRange,
774 col: ColRange,
775 ) -> <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
776 RowRange,
777 ColRange,
778 >>::Target
779 where
780 MatMut<'a, T, Rows, Cols, RStride, CStride>:
781 MatIndex<RowRange, ColRange>,
782 {
783 unsafe {
784 <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<
785 RowRange,
786 ColRange,
787 >>::get_unchecked(self, row, col)
788 }
789 }
790}
791impl<
792 T,
793 Rows: Shape,
794 Cols: Shape,
795 RStride: Stride,
796 CStride: Stride,
797 Inner: for<'short> ReborrowMut<
798 'short,
799 Target = Mut<'short, T, Rows, Cols, RStride, CStride>,
800 >,
801> generic::Mat<Inner>
802{
803 #[inline]
805 pub fn as_mut(&mut self) -> MatMut<'_, T, Rows, Cols, RStride, CStride> {
806 self.rb_mut()
807 }
808
809 #[inline]
812 #[track_caller]
813 pub fn copy_from_triangular_lower<RhsT: Conjugate<Canonical = T>>(
814 &mut self,
815 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
816 ) where
817 T: ComplexField,
818 {
819 let other = other.as_mat_ref();
820 let mut this = self.rb_mut();
821 assert!(all(
822 this.nrows() == other.nrows(),
823 this.ncols() == other.ncols(),
824 ));
825 let (m, n) = this.shape();
826 make_guard!(M);
827 make_guard!(N);
828 let M = m.bind(M);
829 let N = n.bind(N);
830 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
831 let other = other.as_shape(M, N);
832 imp(this, other.canonical(), Conj::get::<RhsT>());
833 pub fn imp<'M, 'N, T: ComplexField>(
834 this: MatMut<'_, T, Dim<'M>, Dim<'N>>,
835 other: MatRef<'_, T, Dim<'M>, Dim<'N>>,
836 conj_: Conj,
837 ) {
838 match conj_ {
839 Conj::No => {
840 zip!(this, other).for_each_triangular_lower(
841 crate::linalg::zip::Diag::Include,
842 |unzip!(dst, src)| *dst = src.copy(),
843 );
844 },
845 Conj::Yes => {
846 zip!(this, other).for_each_triangular_lower(
847 crate::linalg::zip::Diag::Include,
848 |unzip!(dst, src)| *dst = src.conj(),
849 );
850 },
851 }
852 }
853 }
854
855 #[inline]
858 #[track_caller]
859 pub fn copy_from_triangular_upper<RhsT: Conjugate<Canonical = T>>(
860 &mut self,
861 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
862 ) where
863 T: ComplexField,
864 {
865 (*self)
866 .rb_mut()
867 .transpose_mut()
868 .copy_from_triangular_lower(other.as_mat_ref().transpose())
869 }
870
871 #[inline]
873 #[track_caller]
874 pub fn copy_from<RhsT: Conjugate<Canonical = T>>(
875 &mut self,
876 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
877 ) where
878 T: ComplexField,
879 {
880 let other = other.as_mat_ref();
881 let mut this = self.rb_mut();
882 assert!(all(
883 this.nrows() == other.nrows(),
884 this.ncols() == other.ncols(),
885 ));
886 let (m, n) = this.shape();
887 make_guard!(M);
888 make_guard!(N);
889 let M = m.bind(M);
890 let N = n.bind(N);
891 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
892 let other = other.as_shape(M, N);
893 imp(this, other.canonical(), Conj::get::<RhsT>());
894 pub fn imp<'M, 'N, T: ComplexField>(
895 this: MatMut<'_, T, Dim<'M>, Dim<'N>>,
896 other: MatRef<'_, T, Dim<'M>, Dim<'N>>,
897 conj_: Conj,
898 ) {
899 match conj_ {
900 Conj::No => {
901 zip!(this, other)
902 .for_each(|unzip!(dst, src)| *dst = src.copy());
903 },
904 Conj::Yes => {
905 zip!(this, other)
906 .for_each(|unzip!(dst, src)| *dst = src.conj());
907 },
908 }
909 }
910 }
911
912 #[inline]
915 #[track_caller]
916 pub fn copy_from_strict_triangular_lower<RhsT: Conjugate<Canonical = T>>(
917 &mut self,
918 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
919 ) where
920 T: ComplexField,
921 {
922 let other = other.as_mat_ref();
923 let mut this = self.rb_mut();
924 assert!(all(
925 this.nrows() == other.nrows(),
926 this.ncols() == other.ncols(),
927 ));
928 let (m, n) = this.shape();
929 make_guard!(M);
930 make_guard!(N);
931 let M = m.bind(M);
932 let N = n.bind(N);
933 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
934 let other = other.as_shape(M, N);
935 imp(this, other.canonical(), Conj::get::<RhsT>());
936 pub fn imp<'M, 'N, T: ComplexField>(
937 this: MatMut<'_, T, Dim<'M>, Dim<'N>>,
938 other: MatRef<'_, T, Dim<'M>, Dim<'N>>,
939 conj_: Conj,
940 ) {
941 match conj_ {
942 Conj::No => {
943 zip!(this, other).for_each_triangular_lower(
944 crate::linalg::zip::Diag::Skip,
945 |unzip!(dst, src)| *dst = src.copy(),
946 );
947 },
948 Conj::Yes => {
949 zip!(this, other).for_each_triangular_lower(
950 crate::linalg::zip::Diag::Skip,
951 |unzip!(dst, src)| *dst = src.conj(),
952 );
953 },
954 }
955 }
956 }
957
958 #[inline]
961 #[track_caller]
962 pub fn copy_from_strict_triangular_upper<RhsT: Conjugate<Canonical = T>>(
963 &mut self,
964 other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>,
965 ) where
966 T: ComplexField,
967 {
968 (*self)
969 .rb_mut()
970 .transpose_mut()
971 .copy_from_strict_triangular_lower(other.as_mat_ref().transpose())
972 }
973
974 #[inline]
976 pub fn fill(&mut self, value: T)
977 where
978 T: Clone,
979 {
980 fn cloner<T: Clone>(value: T) -> impl for<'a> FnMut(Last<&'a mut T>) {
981 #[inline]
982 move |x| *x.0 = value.clone()
983 }
984 z!(self.rb_mut().as_dyn_mut()).for_each(cloner::<T>(value));
985 }
986}
987impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride>
988 MatMut<'a, T, Rows, Cols, RStride, CStride>
989{
990 #[inline]
991 pub fn as_ptr_mut(&self) -> *mut T {
993 self.imp.ptr.as_ptr()
994 }
995
996 #[inline]
997 pub fn ptr_at_mut(&self, row: IdxInc<Rows>, col: IdxInc<Cols>) -> *mut T {
999 self.rb().ptr_at(row, col) as *mut T
1000 }
1001
1002 #[inline]
1003 #[track_caller]
1004 pub unsafe fn ptr_inbounds_at_mut(
1006 &self,
1007 row: Idx<Rows>,
1008 col: Idx<Cols>,
1009 ) -> *mut T {
1010 self.rb().ptr_inbounds_at(row, col) as *mut T
1011 }
1012
1013 #[inline]
1014 #[track_caller]
1015 pub fn split_at_mut(
1017 self,
1018 row: IdxInc<Rows>,
1019 col: IdxInc<Cols>,
1020 ) -> (
1021 MatMut<'a, T, usize, usize, RStride, CStride>,
1022 MatMut<'a, T, usize, usize, RStride, CStride>,
1023 MatMut<'a, T, usize, usize, RStride, CStride>,
1024 MatMut<'a, T, usize, usize, RStride, CStride>,
1025 ) {
1026 let (a, b, c, d) = self.into_const().split_at(row, col);
1027 unsafe {
1028 (
1029 a.const_cast(),
1030 b.const_cast(),
1031 c.const_cast(),
1032 d.const_cast(),
1033 )
1034 }
1035 }
1036
1037 #[inline]
1038 #[track_caller]
1039 pub fn split_at_row_mut(
1041 self,
1042 row: IdxInc<Rows>,
1043 ) -> (
1044 MatMut<'a, T, usize, Cols, RStride, CStride>,
1045 MatMut<'a, T, usize, Cols, RStride, CStride>,
1046 ) {
1047 let (a, b) = self.into_const().split_at_row(row);
1048 unsafe { (a.const_cast(), b.const_cast()) }
1049 }
1050
1051 #[inline]
1052 #[track_caller]
1053 pub fn split_at_col_mut(
1055 self,
1056 col: IdxInc<Cols>,
1057 ) -> (
1058 MatMut<'a, T, Rows, usize, RStride, CStride>,
1059 MatMut<'a, T, Rows, usize, RStride, CStride>,
1060 ) {
1061 let (a, b) = self.into_const().split_at_col(col);
1062 unsafe { (a.const_cast(), b.const_cast()) }
1063 }
1064
1065 #[inline]
1066 pub fn transpose_mut(self) -> MatMut<'a, T, Cols, Rows, CStride, RStride> {
1068 MatMut {
1069 0: Mut {
1070 imp: MatView {
1071 ptr: self.imp.ptr,
1072 nrows: self.imp.ncols,
1073 ncols: self.imp.nrows,
1074 row_stride: self.imp.col_stride,
1075 col_stride: self.imp.row_stride,
1076 },
1077 __marker: PhantomData,
1078 },
1079 }
1080 }
1081
1082 #[inline]
1083 pub fn conjugate_mut(
1085 self,
1086 ) -> MatMut<'a, T::Conj, Rows, Cols, RStride, CStride>
1087 where
1088 T: Conjugate,
1089 {
1090 unsafe { self.into_const().conjugate().const_cast() }
1091 }
1092
1093 #[inline]
1094 pub fn canonical_mut(
1096 self,
1097 ) -> MatMut<'a, T::Canonical, Rows, Cols, RStride, CStride>
1098 where
1099 T: Conjugate,
1100 {
1101 unsafe { self.into_const().canonical().const_cast() }
1102 }
1103
1104 #[inline]
1105 pub fn adjoint_mut(
1107 self,
1108 ) -> MatMut<'a, T::Conj, Cols, Rows, CStride, RStride>
1109 where
1110 T: Conjugate,
1111 {
1112 unsafe { self.into_const().adjoint().const_cast() }
1113 }
1114
1115 #[inline]
1116 #[track_caller]
1117 pub(crate) fn at_mut(self, row: Idx<Rows>, col: Idx<Cols>) -> &'a mut T {
1118 assert!(all(row < self.nrows(), col < self.ncols()));
1119 unsafe { self.at_mut_unchecked(row, col) }
1120 }
1121
1122 #[inline]
1123 #[track_caller]
1124 pub(crate) unsafe fn at_mut_unchecked(
1125 self,
1126 row: Idx<Rows>,
1127 col: Idx<Cols>,
1128 ) -> &'a mut T {
1129 &mut *self.ptr_inbounds_at_mut(row, col)
1130 }
1131
1132 #[inline]
1133 pub fn reverse_rows_mut(
1135 self,
1136 ) -> MatMut<'a, T, Rows, Cols, RStride::Rev, CStride> {
1137 unsafe { self.into_const().reverse_rows().const_cast() }
1138 }
1139
1140 #[inline]
1141 pub fn reverse_cols_mut(
1143 self,
1144 ) -> MatMut<'a, T, Rows, Cols, RStride, CStride::Rev> {
1145 unsafe { self.into_const().reverse_cols().const_cast() }
1146 }
1147
1148 #[inline]
1149 pub fn reverse_rows_and_cols_mut(
1151 self,
1152 ) -> MatMut<'a, T, Rows, Cols, RStride::Rev, CStride::Rev> {
1153 unsafe { self.into_const().reverse_rows_and_cols().const_cast() }
1154 }
1155
1156 #[inline]
1157 #[track_caller]
1158 pub fn submatrix_mut<V: Shape, H: Shape>(
1160 self,
1161 row_start: IdxInc<Rows>,
1162 col_start: IdxInc<Cols>,
1163 nrows: V,
1164 ncols: H,
1165 ) -> MatMut<'a, T, V, H, RStride, CStride> {
1166 unsafe {
1167 self.into_const()
1168 .submatrix(row_start, col_start, nrows, ncols)
1169 .const_cast()
1170 }
1171 }
1172
1173 #[inline]
1174 #[track_caller]
1175 pub fn subrows_mut<V: Shape>(
1177 self,
1178 row_start: IdxInc<Rows>,
1179 nrows: V,
1180 ) -> MatMut<'a, T, V, Cols, RStride, CStride> {
1181 unsafe { self.into_const().subrows(row_start, nrows).const_cast() }
1182 }
1183
1184 #[inline]
1185 #[track_caller]
1186 pub fn subcols_mut<H: Shape>(
1188 self,
1189 col_start: IdxInc<Cols>,
1190 ncols: H,
1191 ) -> MatMut<'a, T, Rows, H, RStride, CStride> {
1192 unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
1193 }
1194
1195 #[inline]
1196 #[track_caller]
1197 pub fn as_shape_mut<V: Shape, H: Shape>(
1199 self,
1200 nrows: V,
1201 ncols: H,
1202 ) -> MatMut<'a, T, V, H, RStride, CStride> {
1203 unsafe { self.into_const().as_shape(nrows, ncols).const_cast() }
1204 }
1205
1206 #[inline]
1207 #[track_caller]
1208 pub fn as_row_shape_mut<V: Shape>(
1210 self,
1211 nrows: V,
1212 ) -> MatMut<'a, T, V, Cols, RStride, CStride> {
1213 unsafe { self.into_const().as_row_shape(nrows).const_cast() }
1214 }
1215
1216 #[inline]
1217 #[track_caller]
1218 pub fn as_col_shape_mut<H: Shape>(
1220 self,
1221 ncols: H,
1222 ) -> MatMut<'a, T, Rows, H, RStride, CStride> {
1223 unsafe { self.into_const().as_col_shape(ncols).const_cast() }
1224 }
1225
1226 #[inline]
1227 pub fn as_dyn_stride_mut(self) -> MatMut<'a, T, Rows, Cols, isize, isize> {
1229 unsafe { self.into_const().as_dyn_stride().const_cast() }
1230 }
1231
1232 #[inline]
1233 pub fn as_dyn_mut(self) -> MatMut<'a, T, usize, usize, RStride, CStride> {
1235 unsafe { self.into_const().as_dyn().const_cast() }
1236 }
1237
1238 #[inline]
1239 pub fn as_dyn_rows_mut(
1241 self,
1242 ) -> MatMut<'a, T, usize, Cols, RStride, CStride> {
1243 unsafe { self.into_const().as_dyn_rows().const_cast() }
1244 }
1245
1246 #[inline]
1247 pub fn as_dyn_cols_mut(
1249 self,
1250 ) -> MatMut<'a, T, Rows, usize, RStride, CStride> {
1251 unsafe { self.into_const().as_dyn_cols().const_cast() }
1252 }
1253
1254 #[inline]
1255 #[track_caller]
1256 pub fn row_mut(self, i: Idx<Rows>) -> RowMut<'a, T, Cols, CStride> {
1258 unsafe { self.into_const().row(i).const_cast() }
1259 }
1260
1261 #[inline]
1262 #[track_caller]
1263 pub fn col_mut(self, j: Idx<Cols>) -> ColMut<'a, T, Rows, RStride> {
1265 unsafe { self.into_const().col(j).const_cast() }
1266 }
1267
1268 #[inline]
1269 pub fn col_iter_mut(
1271 self,
1272 ) -> impl 'a
1273 + ExactSizeIterator
1274 + DoubleEndedIterator<Item = ColMut<'a, T, Rows, RStride>>
1275 where
1276 Rows: 'a,
1277 Cols: 'a,
1278 {
1279 self.into_const()
1280 .col_iter()
1281 .map(|x| unsafe { x.const_cast() })
1282 }
1283
1284 #[inline]
1285 pub fn row_iter_mut(
1287 self,
1288 ) -> impl 'a
1289 + ExactSizeIterator
1290 + DoubleEndedIterator<Item = RowMut<'a, T, Cols, CStride>>
1291 where
1292 Rows: 'a,
1293 Cols: 'a,
1294 {
1295 self.into_const()
1296 .row_iter()
1297 .map(|x| unsafe { x.const_cast() })
1298 }
1299
1300 #[inline]
1301 pub(crate) unsafe fn as_type<U>(
1302 self,
1303 ) -> MatMut<'a, U, Rows, Cols, RStride, CStride> {
1304 MatMut::from_raw_parts_mut(
1305 self.as_ptr_mut() as *mut U,
1306 self.nrows(),
1307 self.ncols(),
1308 self.row_stride(),
1309 self.col_stride(),
1310 )
1311 }
1312
1313 #[inline]
1314 #[cfg(feature = "rayon")]
1315 pub fn par_col_iter_mut(
1317 self,
1318 ) -> impl 'a
1319 + rayon::iter::IndexedParallelIterator<
1320 Item = ColMut<'a, T, Rows, RStride>,
1321 >
1322 where
1323 T: Send,
1324 Rows: 'a,
1325 Cols: 'a,
1326 {
1327 use rayon::prelude::*;
1328 unsafe {
1329 self.as_type::<SyncCell<T>>()
1330 .into_const()
1331 .par_col_iter()
1332 .map(|x| x.const_cast())
1333 .map(|x| x.as_type())
1334 }
1335 }
1336
1337 #[inline]
1338 #[cfg(feature = "rayon")]
1339 pub fn par_row_iter_mut(
1341 self,
1342 ) -> impl 'a
1343 + rayon::iter::IndexedParallelIterator<
1344 Item = RowMut<'a, T, Cols, CStride>,
1345 >
1346 where
1347 T: Send,
1348 Rows: 'a,
1349 Cols: 'a,
1350 {
1351 use rayon::prelude::*;
1352 unsafe {
1353 self.as_type::<SyncCell<T>>()
1354 .into_const()
1355 .par_row_iter()
1356 .map(|x| x.const_cast())
1357 .map(|x| x.as_type())
1358 }
1359 }
1360
1361 #[inline]
1362 #[track_caller]
1363 #[cfg(feature = "rayon")]
1364 pub fn par_col_chunks_mut(
1366 self,
1367 chunk_size: usize,
1368 ) -> impl 'a
1369 + rayon::iter::IndexedParallelIterator<
1370 Item = MatMut<'a, T, Rows, usize, RStride, CStride>,
1371 >
1372 where
1373 T: Send,
1374 Rows: 'a,
1375 Cols: 'a,
1376 {
1377 use rayon::prelude::*;
1378 unsafe {
1379 self.as_type::<SyncCell<T>>()
1380 .into_const()
1381 .par_col_chunks(chunk_size)
1382 .map(|x| x.const_cast())
1383 .map(|x| x.as_type())
1384 }
1385 }
1386
1387 #[inline]
1388 #[track_caller]
1389 #[cfg(feature = "rayon")]
1390 pub fn par_col_partition_mut(
1392 self,
1393 count: usize,
1394 ) -> impl 'a
1395 + rayon::iter::IndexedParallelIterator<
1396 Item = MatMut<'a, T, Rows, usize, RStride, CStride>,
1397 >
1398 where
1399 T: Send,
1400 Rows: 'a,
1401 Cols: 'a,
1402 {
1403 use rayon::prelude::*;
1404 unsafe {
1405 self.as_type::<SyncCell<T>>()
1406 .into_const()
1407 .par_col_partition(count)
1408 .map(|x| x.const_cast())
1409 .map(|x| x.as_type())
1410 }
1411 }
1412
1413 #[inline]
1414 #[track_caller]
1415 #[cfg(feature = "rayon")]
1416 pub fn par_row_chunks_mut(
1418 self,
1419 chunk_size: usize,
1420 ) -> impl 'a
1421 + rayon::iter::IndexedParallelIterator<
1422 Item = MatMut<'a, T, usize, Cols, RStride, CStride>,
1423 >
1424 where
1425 T: Send,
1426 Rows: 'a,
1427 Cols: 'a,
1428 {
1429 use rayon::prelude::*;
1430 unsafe {
1431 self.as_type::<SyncCell<T>>()
1432 .into_const()
1433 .par_row_chunks(chunk_size)
1434 .map(|x| x.const_cast())
1435 .map(|x| x.as_type())
1436 }
1437 }
1438
1439 #[inline]
1440 #[track_caller]
1441 #[cfg(feature = "rayon")]
1442 pub fn par_row_partition_mut(
1444 self,
1445 count: usize,
1446 ) -> impl 'a
1447 + rayon::iter::IndexedParallelIterator<
1448 Item = MatMut<'a, T, usize, Cols, RStride, CStride>,
1449 >
1450 where
1451 T: Send,
1452 Rows: 'a,
1453 Cols: 'a,
1454 {
1455 use rayon::prelude::*;
1456 unsafe {
1457 self.as_type::<SyncCell<T>>()
1458 .into_const()
1459 .par_row_partition(count)
1460 .map(|x| x.const_cast())
1461 .map(|x| x.as_type())
1462 }
1463 }
1464
1465 #[inline]
1466 pub fn split_first_row_mut(
1468 self,
1469 ) -> Option<(
1470 RowMut<'a, T, Cols, CStride>,
1471 MatMut<'a, T, usize, Cols, RStride, CStride>,
1472 )> {
1473 if let Some(i0) = self.nrows().idx_inc(1) {
1474 let (head, tail) = self.split_at_row_mut(i0);
1475 Some((head.row_mut(0), tail))
1476 } else {
1477 None
1478 }
1479 }
1480
1481 #[inline]
1482 pub fn split_first_col_mut(
1484 self,
1485 ) -> Option<(
1486 ColMut<'a, T, Rows, RStride>,
1487 MatMut<'a, T, Rows, usize, RStride, CStride>,
1488 )> {
1489 if let Some(i0) = self.ncols().idx_inc(1) {
1490 let (head, tail) = self.split_at_col_mut(i0);
1491 Some((head.col_mut(0), tail))
1492 } else {
1493 None
1494 }
1495 }
1496
1497 #[inline]
1498 pub fn split_last_row_mut(
1500 self,
1501 ) -> Option<(
1502 RowMut<'a, T, Cols, CStride>,
1503 MatMut<'a, T, usize, Cols, RStride, CStride>,
1504 )> {
1505 if self.nrows().unbound() > 0 {
1506 let i0 = self.nrows().checked_idx_inc(self.nrows().unbound() - 1);
1507 let (head, tail) = self.split_at_row_mut(i0);
1508 Some((tail.row_mut(0), head))
1509 } else {
1510 None
1511 }
1512 }
1513
1514 #[inline]
1515 pub fn split_last_col_mut(
1517 self,
1518 ) -> Option<(
1519 ColMut<'a, T, Rows, RStride>,
1520 MatMut<'a, T, Rows, usize, RStride, CStride>,
1521 )> {
1522 if self.ncols().unbound() > 0 {
1523 let i0 = self.ncols().checked_idx_inc(self.ncols().unbound() - 1);
1524 let (head, tail) = self.split_at_col_mut(i0);
1525 Some((tail.col_mut(0), head))
1526 } else {
1527 None
1528 }
1529 }
1530
1531 #[inline]
1532 pub fn split_first_row(
1534 self,
1535 ) -> Option<(
1536 RowRef<'a, T, Cols, CStride>,
1537 MatRef<'a, T, usize, Cols, RStride, CStride>,
1538 )> {
1539 self.into_const().split_first_row()
1540 }
1541
1542 #[inline]
1543 pub fn split_first_col(
1545 self,
1546 ) -> Option<(
1547 ColRef<'a, T, Rows, RStride>,
1548 MatRef<'a, T, Rows, usize, RStride, CStride>,
1549 )> {
1550 self.into_const().split_first_col()
1551 }
1552
1553 #[inline]
1554 pub fn split_last_row(
1556 self,
1557 ) -> Option<(
1558 RowRef<'a, T, Cols, CStride>,
1559 MatRef<'a, T, usize, Cols, RStride, CStride>,
1560 )> {
1561 self.into_const().split_last_row()
1562 }
1563
1564 #[inline]
1565 pub fn split_last_col(
1567 self,
1568 ) -> Option<(
1569 ColRef<'a, T, Rows, RStride>,
1570 MatRef<'a, T, Rows, usize, RStride, CStride>,
1571 )> {
1572 self.into_const().split_last_col()
1573 }
1574
1575 #[inline]
1576 pub fn try_as_col_major_mut(
1578 self,
1579 ) -> Option<MatMut<'a, T, Rows, Cols, ContiguousFwd, CStride>> {
1580 self.into_const()
1581 .try_as_col_major()
1582 .map(|x| unsafe { x.const_cast() })
1583 }
1584
1585 #[inline]
1586 pub fn try_as_row_major_mut(
1588 self,
1589 ) -> Option<MatMut<'a, T, Rows, Cols, RStride, ContiguousFwd>> {
1590 self.into_const()
1591 .try_as_row_major()
1592 .map(|x| unsafe { x.const_cast() })
1593 }
1594
1595 #[inline]
1600 #[track_caller]
1601 pub fn two_cols_mut(
1602 self,
1603 i0: Idx<Cols>,
1604 i1: Idx<Cols>,
1605 ) -> (ColMut<'a, T, Rows, RStride>, ColMut<'a, T, Rows, RStride>) {
1606 assert!(i0 != i1);
1607 let this = self.into_const();
1608 unsafe { (this.col(i0).const_cast(), this.col(i1).const_cast()) }
1609 }
1610
1611 #[inline]
1616 #[track_caller]
1617 pub fn two_rows_mut(
1618 self,
1619 i0: Idx<Rows>,
1620 i1: Idx<Rows>,
1621 ) -> (RowMut<'a, T, Cols, CStride>, RowMut<'a, T, Cols, CStride>) {
1622 assert!(i0 != i1);
1623 let this = self.into_const();
1624 unsafe { (this.row(i0).const_cast(), this.row(i1).const_cast()) }
1625 }
1626
1627 #[inline]
1628 pub(crate) fn __at_mut(self, (i, j): (Idx<Rows>, Idx<Cols>)) -> &'a mut T {
1629 self.at_mut(i, j)
1630 }
1631}
1632impl<'a, T, Rows: Shape, Cols: Shape> MatMut<'a, T, Rows, Cols> {
1633 #[inline]
1652 #[track_caller]
1653 pub fn from_column_major_slice_mut(
1654 slice: &'a mut [T],
1655 nrows: Rows,
1656 ncols: Cols,
1657 ) -> Self
1658 where
1659 T: Sized,
1660 {
1661 from_slice_assert(nrows.unbound(), ncols.unbound(), slice.len());
1662 unsafe {
1663 Self::from_raw_parts_mut(
1664 slice.as_mut_ptr(),
1665 nrows,
1666 ncols,
1667 1,
1668 nrows.unbound() as isize,
1669 )
1670 }
1671 }
1672
1673 #[inline]
1678 #[track_caller]
1679 pub fn from_column_major_slice_with_stride_mut(
1680 slice: &'a mut [T],
1681 nrows: Rows,
1682 ncols: Cols,
1683 col_stride: usize,
1684 ) -> Self
1685 where
1686 T: Sized,
1687 {
1688 from_strided_column_major_slice_mut_assert(
1689 nrows.unbound(),
1690 ncols.unbound(),
1691 col_stride,
1692 slice.len(),
1693 );
1694 unsafe {
1695 Self::from_raw_parts_mut(
1696 slice.as_mut_ptr(),
1697 nrows,
1698 ncols,
1699 1,
1700 col_stride as isize,
1701 )
1702 }
1703 }
1704
1705 #[inline]
1724 #[track_caller]
1725 pub fn from_row_major_slice_mut(
1726 slice: &'a mut [T],
1727 nrows: Rows,
1728 ncols: Cols,
1729 ) -> Self
1730 where
1731 T: Sized,
1732 {
1733 MatMut::from_column_major_slice_mut(slice, ncols, nrows).transpose_mut()
1734 }
1735
1736 #[inline]
1741 #[track_caller]
1742 pub fn from_row_major_slice_with_stride_mut(
1743 slice: &'a mut [T],
1744 nrows: Rows,
1745 ncols: Cols,
1746 row_stride: usize,
1747 ) -> Self
1748 where
1749 T: Sized,
1750 {
1751 from_strided_row_major_slice_mut_assert(
1752 nrows.unbound(),
1753 ncols.unbound(),
1754 row_stride,
1755 slice.len(),
1756 );
1757 unsafe {
1758 Self::from_raw_parts_mut(
1759 slice.as_mut_ptr(),
1760 nrows,
1761 ncols,
1762 1,
1763 row_stride as isize,
1764 )
1765 }
1766 }
1767}
1768impl<'ROWS, 'COLS, 'a, T, RStride: Stride, CStride: Stride>
1769 MatMut<'a, T, Dim<'ROWS>, Dim<'COLS>, RStride, CStride>
1770{
1771 #[doc(hidden)]
1772 #[inline]
1773 pub fn split_with_mut<'TOP, 'BOT, 'LEFT, 'RIGHT>(
1774 self,
1775 row: Partition<'TOP, 'BOT, 'ROWS>,
1776 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1777 ) -> (
1778 MatMut<'a, T, Dim<'TOP>, Dim<'LEFT>, RStride, CStride>,
1779 MatMut<'a, T, Dim<'TOP>, Dim<'RIGHT>, RStride, CStride>,
1780 MatMut<'a, T, Dim<'BOT>, Dim<'LEFT>, RStride, CStride>,
1781 MatMut<'a, T, Dim<'BOT>, Dim<'RIGHT>, RStride, CStride>,
1782 ) {
1783 let (a, b, c, d) = self.split_at_mut(row.midpoint(), col.midpoint());
1784 (
1785 a.as_shape_mut(row.head, col.head),
1786 b.as_shape_mut(row.head, col.tail),
1787 c.as_shape_mut(row.tail, col.head),
1788 d.as_shape_mut(row.tail, col.tail),
1789 )
1790 }
1791}
1792impl<'ROWS, 'a, T, Cols: Shape, RStride: Stride, CStride: Stride>
1793 MatMut<'a, T, Dim<'ROWS>, Cols, RStride, CStride>
1794{
1795 #[doc(hidden)]
1796 #[inline]
1797 pub fn split_rows_with_mut<'TOP, 'BOT>(
1798 self,
1799 row: Partition<'TOP, 'BOT, 'ROWS>,
1800 ) -> (
1801 MatMut<'a, T, Dim<'TOP>, Cols, RStride, CStride>,
1802 MatMut<'a, T, Dim<'BOT>, Cols, RStride, CStride>,
1803 ) {
1804 let (a, b) = self.split_at_row_mut(row.midpoint());
1805 (a.as_row_shape_mut(row.head), b.as_row_shape_mut(row.tail))
1806 }
1807}
1808impl<'COLS, 'a, T, Rows: Shape, RStride: Stride, CStride: Stride>
1809 MatMut<'a, T, Rows, Dim<'COLS>, RStride, CStride>
1810{
1811 #[doc(hidden)]
1812 #[inline]
1813 pub fn split_cols_with_mut<'LEFT, 'RIGHT>(
1814 self,
1815 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1816 ) -> (
1817 MatMut<'a, T, Rows, Dim<'LEFT>, RStride, CStride>,
1818 MatMut<'a, T, Rows, Dim<'RIGHT>, RStride, CStride>,
1819 ) {
1820 let (a, b) = self.split_at_col_mut(col.midpoint());
1821 (a.as_col_shape_mut(col.head), b.as_col_shape_mut(col.tail))
1822 }
1823}
1824impl<'ROWS, 'COLS, 'a, T, RStride: Stride, CStride: Stride>
1825 MatMut<'a, T, Dim<'ROWS>, Dim<'COLS>, RStride, CStride>
1826{
1827 #[doc(hidden)]
1828 #[inline]
1829 pub fn split_with<'TOP, 'BOT, 'LEFT, 'RIGHT>(
1830 self,
1831 row: Partition<'TOP, 'BOT, 'ROWS>,
1832 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1833 ) -> (
1834 MatRef<'a, T, Dim<'TOP>, Dim<'LEFT>, RStride, CStride>,
1835 MatRef<'a, T, Dim<'TOP>, Dim<'RIGHT>, RStride, CStride>,
1836 MatRef<'a, T, Dim<'BOT>, Dim<'LEFT>, RStride, CStride>,
1837 MatRef<'a, T, Dim<'BOT>, Dim<'RIGHT>, RStride, CStride>,
1838 ) {
1839 let (a, b, c, d) = self.split_at(row.midpoint(), col.midpoint());
1840 (
1841 a.as_shape(row.head, col.head),
1842 b.as_shape(row.head, col.tail),
1843 c.as_shape(row.tail, col.head),
1844 d.as_shape(row.tail, col.tail),
1845 )
1846 }
1847}
1848impl<'ROWS, 'a, T, Cols: Shape, RStride: Stride, CStride: Stride>
1849 MatMut<'a, T, Dim<'ROWS>, Cols, RStride, CStride>
1850{
1851 #[doc(hidden)]
1852 #[inline]
1853 pub fn split_rows_with<'TOP, 'BOT>(
1854 self,
1855 row: Partition<'TOP, 'BOT, 'ROWS>,
1856 ) -> (
1857 MatRef<'a, T, Dim<'TOP>, Cols, RStride, CStride>,
1858 MatRef<'a, T, Dim<'BOT>, Cols, RStride, CStride>,
1859 ) {
1860 let (a, b) = self.split_at_row(row.midpoint());
1861 (a.as_row_shape(row.head), b.as_row_shape(row.tail))
1862 }
1863}
1864impl<'COLS, 'a, T, Rows: Shape, RStride: Stride, CStride: Stride>
1865 MatMut<'a, T, Rows, Dim<'COLS>, RStride, CStride>
1866{
1867 #[doc(hidden)]
1868 #[inline]
1869 pub fn split_cols_with<'LEFT, 'RIGHT>(
1870 self,
1871 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1872 ) -> (
1873 MatRef<'a, T, Rows, Dim<'LEFT>, RStride, CStride>,
1874 MatRef<'a, T, Rows, Dim<'RIGHT>, RStride, CStride>,
1875 ) {
1876 let (a, b) = self.split_at_col(col.midpoint());
1877 (a.as_col_shape(col.head), b.as_col_shape(col.tail))
1878 }
1879}
1880impl<'a, T, Dim: Shape, RStride: Stride, CStride: Stride>
1881 MatMut<'a, T, Dim, Dim, RStride, CStride>
1882{
1883 #[inline]
1885 pub fn diagonal(self) -> DiagRef<'a, T, Dim, isize> {
1886 self.into_const().diagonal()
1887 }
1888}
1889impl<'a, T, Dim: Shape, RStride: Stride, CStride: Stride>
1890 MatMut<'a, T, Dim, Dim, RStride, CStride>
1891{
1892 #[inline]
1894 pub fn diagonal_mut(self) -> DiagMut<'a, T, Dim, isize> {
1895 unsafe {
1896 self.into_const()
1897 .diagonal()
1898 .column_vector()
1899 .const_cast()
1900 .as_diagonal_mut()
1901 }
1902 }
1903}
1904impl<
1905 'a,
1906 T: core::fmt::Debug,
1907 Rows: Shape,
1908 Cols: Shape,
1909 RStride: Stride,
1910 CStride: Stride,
1911> core::fmt::Debug for Mut<'a, T, Rows, Cols, RStride, CStride>
1912{
1913 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1914 self.rb().fmt(f)
1915 }
1916}
1917impl<'a, T, Rows: Shape, Cols: Shape> MatMut<'a, T, Rows, Cols>
1918where
1919 T: RealField,
1920{
1921 pub fn min(self) -> Option<T> {
1923 MatRef::internal_min(self.rb().as_dyn())
1924 }
1925
1926 pub fn max(self) -> Option<T> {
1928 MatRef::internal_max(self.rb().as_dyn())
1929 }
1930}
1931#[track_caller]
1932#[inline]
1933fn from_strided_column_major_slice_mut_assert(
1934 nrows: usize,
1935 ncols: usize,
1936 col_stride: usize,
1937 len: usize,
1938) {
1939 if nrows > 0 && ncols > 0 {
1940 let last = usize::checked_mul(col_stride, ncols - 1)
1941 .and_then(|last_col| last_col.checked_add(nrows - 1));
1942 let Some(last) = last else {
1943 panic!("address computation of the last matrix element overflowed");
1944 };
1945 assert!(all(col_stride >= nrows, last < len));
1946 }
1947}
1948#[track_caller]
1949#[inline]
1950fn from_strided_row_major_slice_mut_assert(
1951 nrows: usize,
1952 ncols: usize,
1953 row_stride: usize,
1954 len: usize,
1955) {
1956 if nrows > 0 && ncols > 0 {
1957 let last = usize::checked_mul(row_stride, nrows - 1)
1958 .and_then(|last_row| last_row.checked_add(ncols - 1));
1959 let Some(last) = last else {
1960 panic!("address computation of the last matrix element overflowed");
1961 };
1962 assert!(all(row_stride >= ncols, last < len));
1963 }
1964}
1965#[cfg(test)]
1966mod tests {
1967 use super::*;
1968 #[test]
1969 fn test_min() {
1970 let mut m = mat![[1.0, 5.0, 3.0], [4.0, 2.0, 9.0], [7.0, 8.0, 6.0],];
1971 assert_eq!(m.as_mut().min(), Some(1.0));
1972 let mut empty: Mat<f64> = Mat::new();
1973 assert_eq!(empty.as_mut().min(), None);
1974 }
1975 #[test]
1976 fn test_max() {
1977 let mut m = mat![[1.0, 5.0, 3.0], [4.0, 2.0, 9.0], [7.0, 8.0, 6.0],];
1978 assert_eq!(m.as_mut().max(), Some(9.0));
1979 let mut empty: Mat<f64> = Mat::new();
1980 assert_eq!(empty.as_mut().max(), None);
1981 }
1982}