1use super::{MatRef, *};
2use crate::internal_prelude::*;
3use crate::utils::bound::{Dim, Partition};
4use crate::{Conj, ContiguousFwd, Idx, IdxInc, unzip, zip};
5use equator::assert;
6use faer_traits::ComplexField;
7use generativity::Guard;
8use linalg::zip::Last;
9
10pub struct Mut<'a, T, Rows = usize, Cols = usize, RStride = isize, CStride = isize> {
12 pub(super) imp: MatView<T, Rows, Cols, RStride, CStride>,
13 pub(super) __marker: PhantomData<&'a mut T>,
14}
15
16#[repr(transparent)]
17pub(crate) struct SyncCell<T>(T);
18unsafe impl<T> Sync for SyncCell<T> {}
19
20impl<'short, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> Reborrow<'short> for Mut<'_, T, Rows, Cols, RStride, CStride> {
21 type Target = Ref<'short, T, Rows, Cols, RStride, CStride>;
22
23 #[inline]
24 fn rb(&'short self) -> Self::Target {
25 Ref {
26 imp: self.imp,
27 __marker: PhantomData,
28 }
29 }
30}
31impl<'short, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> ReborrowMut<'short> for Mut<'_, T, Rows, Cols, RStride, CStride> {
32 type Target = Mut<'short, T, Rows, Cols, RStride, CStride>;
33
34 #[inline]
35 fn rb_mut(&'short mut self) -> Self::Target {
36 Mut {
37 imp: self.imp,
38 __marker: PhantomData,
39 }
40 }
41}
42impl<'a, T, Rows: Copy, Cols: Copy, RStride: Copy, CStride: Copy> IntoConst for Mut<'a, T, Rows, Cols, RStride, CStride> {
43 type Target = Ref<'a, T, Rows, Cols, RStride, CStride>;
44
45 #[inline]
46 fn into_const(self) -> Self::Target {
47 Ref {
48 imp: self.imp,
49 __marker: PhantomData,
50 }
51 }
52}
53
54unsafe impl<T: Sync, Rows: Sync, Cols: Sync, RStride: Sync, CStride: Sync> Sync for Mut<'_, T, Rows, Cols, RStride, CStride> {}
55unsafe impl<T: Send, Rows: Send, Cols: Send, RStride: Send, CStride: Send> Send for Mut<'_, T, Rows, Cols, RStride, CStride> {}
56
57impl<'a, T> MatMut<'a, T> {
58 #[inline]
60 pub fn from_row_major_array_mut<const ROWS: usize, const COLS: usize>(array: &'a mut [[T; COLS]; ROWS]) -> Self {
61 unsafe { Self::from_raw_parts_mut(array as *mut _ as *mut T, ROWS, COLS, COLS as isize, 1) }
62 }
63
64 #[inline]
66 pub fn from_column_major_array_mut<const ROWS: usize, const COLS: usize>(array: &'a mut [[T; ROWS]; COLS]) -> Self {
67 unsafe { Self::from_raw_parts_mut(array as *mut _ as *mut T, ROWS, COLS, 1, ROWS as isize) }
68 }
69}
70
71impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Rows, Cols, RStride, CStride> {
72 #[inline]
113 #[track_caller]
114 pub const unsafe fn from_raw_parts_mut(ptr: *mut T, nrows: Rows, ncols: Cols, row_stride: RStride, col_stride: CStride) -> Self {
115 MatMut {
116 0: Mut {
117 imp: MatView {
118 ptr: NonNull::new_unchecked(ptr),
119 nrows,
120 ncols,
121 row_stride,
122 col_stride,
123 },
124 __marker: PhantomData,
125 },
126 }
127 }
128
129 #[inline]
131 pub fn as_ptr(&self) -> *const T {
132 self.imp.ptr.as_ptr()
133 }
134
135 #[inline]
137 pub fn nrows(&self) -> Rows {
138 self.imp.nrows
139 }
140
141 #[inline]
143 pub fn ncols(&self) -> Cols {
144 self.imp.ncols
145 }
146
147 #[inline]
149 pub fn shape(&self) -> (Rows, Cols) {
150 (self.nrows(), self.ncols())
151 }
152
153 #[inline]
155 pub fn row_stride(&self) -> RStride {
156 self.imp.row_stride
157 }
158
159 #[inline]
161 pub fn col_stride(&self) -> CStride {
162 self.imp.col_stride
163 }
164
165 #[inline]
167 pub fn ptr_at(&self, row: IdxInc<Rows>, col: IdxInc<Cols>) -> *const T {
168 self.rb().ptr_at(row, col)
169 }
170
171 #[inline]
179 #[track_caller]
180 pub unsafe fn ptr_inbounds_at(&self, row: Idx<Rows>, col: Idx<Cols>) -> *const T {
181 self.rb().ptr_inbounds_at(row, col)
182 }
183
184 #[inline]
185 #[track_caller]
186 pub fn split_at(
188 self,
189 row: IdxInc<Rows>,
190 col: IdxInc<Cols>,
191 ) -> (
192 MatRef<'a, T, usize, usize, RStride, CStride>,
193 MatRef<'a, T, usize, usize, RStride, CStride>,
194 MatRef<'a, T, usize, usize, RStride, CStride>,
195 MatRef<'a, T, usize, usize, RStride, CStride>,
196 ) {
197 self.into_const().split_at(row, col)
198 }
199
200 #[inline]
201 #[track_caller]
202 pub fn split_at_row(self, row: IdxInc<Rows>) -> (MatRef<'a, T, usize, Cols, RStride, CStride>, MatRef<'a, T, usize, Cols, RStride, CStride>) {
204 self.into_const().split_at_row(row)
205 }
206
207 #[inline]
208 #[track_caller]
209 pub fn split_at_col(self, col: IdxInc<Cols>) -> (MatRef<'a, T, Rows, usize, RStride, CStride>, MatRef<'a, T, Rows, usize, RStride, CStride>) {
211 self.into_const().split_at_col(col)
212 }
213
214 #[inline]
215 pub fn transpose(self) -> MatRef<'a, T, Cols, Rows, CStride, RStride> {
217 MatRef {
218 0: Ref {
219 imp: MatView {
220 ptr: self.imp.ptr,
221 nrows: self.imp.ncols,
222 ncols: self.imp.nrows,
223 row_stride: self.imp.col_stride,
224 col_stride: self.imp.row_stride,
225 },
226 __marker: PhantomData,
227 },
228 }
229 }
230
231 #[inline]
232 pub fn conjugate(self) -> MatRef<'a, T::Conj, Rows, Cols, RStride, CStride>
234 where
235 T: Conjugate,
236 {
237 self.into_const().conjugate()
238 }
239
240 #[inline]
241 pub fn canonical(self) -> MatRef<'a, T::Canonical, Rows, Cols, RStride, CStride>
243 where
244 T: Conjugate,
245 {
246 self.into_const().canonical()
247 }
248
249 #[inline]
250 pub fn adjoint(self) -> MatRef<'a, T::Conj, Cols, Rows, CStride, RStride>
252 where
253 T: Conjugate,
254 {
255 self.into_const().adjoint()
256 }
257
258 #[inline]
259 pub fn reverse_rows(self) -> MatRef<'a, T, Rows, Cols, RStride::Rev, CStride> {
261 self.into_const().reverse_rows()
262 }
263
264 #[inline]
265 pub fn reverse_cols(self) -> MatRef<'a, T, Rows, Cols, RStride, CStride::Rev> {
267 self.into_const().reverse_cols()
268 }
269
270 #[inline]
271 pub fn reverse_rows_and_cols(self) -> MatRef<'a, T, Rows, Cols, RStride::Rev, CStride::Rev> {
273 self.into_const().reverse_rows_and_cols()
274 }
275
276 #[inline]
277 #[track_caller]
278 pub fn submatrix<V: Shape, H: Shape>(
280 self,
281 row_start: IdxInc<Rows>,
282 col_start: IdxInc<Cols>,
283 nrows: V,
284 ncols: H,
285 ) -> MatRef<'a, T, V, H, RStride, CStride> {
286 self.into_const().submatrix(row_start, col_start, nrows, ncols)
287 }
288
289 #[inline]
290 #[track_caller]
291 pub fn subrows<V: Shape>(self, row_start: IdxInc<Rows>, nrows: V) -> MatRef<'a, T, V, Cols, RStride, CStride> {
293 self.into_const().subrows(row_start, nrows)
294 }
295
296 #[inline]
297 #[track_caller]
298 pub fn subcols<H: Shape>(self, col_start: IdxInc<Cols>, ncols: H) -> MatRef<'a, T, Rows, H, RStride, CStride> {
300 self.into_const().subcols(col_start, ncols)
301 }
302
303 #[inline]
304 #[track_caller]
305 pub fn as_shape<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> MatRef<'a, T, V, H, RStride, CStride> {
307 self.into_const().as_shape(nrows, ncols)
308 }
309
310 #[inline]
311 #[track_caller]
312 pub fn as_row_shape<V: Shape>(self, nrows: V) -> MatRef<'a, T, V, Cols, RStride, CStride> {
314 self.into_const().as_row_shape(nrows)
315 }
316
317 #[inline]
318 #[track_caller]
319 pub fn as_col_shape<H: Shape>(self, ncols: H) -> MatRef<'a, T, Rows, H, RStride, CStride> {
321 self.into_const().as_col_shape(ncols)
322 }
323
324 #[inline]
325 pub fn as_dyn_stride(self) -> MatRef<'a, T, Rows, Cols, isize, isize> {
327 self.into_const().as_dyn_stride()
328 }
329
330 #[inline]
331 pub fn as_dyn(self) -> MatRef<'a, T, usize, usize, RStride, CStride> {
333 self.into_const().as_dyn()
334 }
335
336 #[inline]
337 pub fn as_dyn_rows(self) -> MatRef<'a, T, usize, Cols, RStride, CStride> {
339 self.into_const().as_dyn_rows()
340 }
341
342 #[inline]
343 pub fn as_dyn_cols(self) -> MatRef<'a, T, Rows, usize, RStride, CStride> {
345 self.into_const().as_dyn_cols()
346 }
347
348 #[inline]
349 #[track_caller]
350 pub fn row(self, i: Idx<Rows>) -> RowRef<'a, T, Cols, CStride> {
352 self.into_const().row(i)
353 }
354
355 #[inline]
356 #[track_caller]
357 pub fn col(self, j: Idx<Cols>) -> ColRef<'a, T, Rows, RStride> {
359 self.into_const().col(j)
360 }
361
362 #[inline]
363 pub fn col_iter(self) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = ColRef<'a, T, Rows, RStride>>
365 where
366 Rows: 'a,
367 Cols: 'a,
368 {
369 self.into_const().col_iter()
370 }
371
372 #[inline]
373 pub fn row_iter(self) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = RowRef<'a, T, Cols, CStride>>
375 where
376 Rows: 'a,
377 Cols: 'a,
378 {
379 self.into_const().row_iter()
380 }
381
382 #[inline]
383 #[cfg(feature = "rayon")]
384 pub fn par_col_iter(self) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = ColRef<'a, T, Rows, RStride>>
386 where
387 T: Sync,
388 Rows: 'a,
389 Cols: 'a,
390 {
391 self.into_const().par_col_iter()
392 }
393
394 #[inline]
395 #[cfg(feature = "rayon")]
396 pub fn par_row_iter(self) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = RowRef<'a, T, Cols, CStride>>
398 where
399 T: Sync,
400 Rows: 'a,
401 Cols: 'a,
402 {
403 self.into_const().par_row_iter()
404 }
405
406 #[inline]
407 #[track_caller]
408 #[cfg(feature = "rayon")]
409 pub fn par_col_chunks(
411 self,
412 chunk_size: usize,
413 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, T, Rows, usize, RStride, CStride>>
414 where
415 T: Sync,
416 Rows: 'a,
417 Cols: 'a,
418 {
419 self.into_const().par_col_chunks(chunk_size)
420 }
421
422 #[inline]
423 #[track_caller]
424 #[cfg(feature = "rayon")]
425 pub fn par_col_partition(
427 self,
428 count: usize,
429 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, T, Rows, usize, RStride, CStride>>
430 where
431 T: Sync,
432 Rows: 'a,
433 Cols: 'a,
434 {
435 self.into_const().par_col_partition(count)
436 }
437
438 #[inline]
439 #[track_caller]
440 #[cfg(feature = "rayon")]
441 pub fn par_row_chunks(
443 self,
444 chunk_size: usize,
445 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, T, usize, Cols, RStride, CStride>>
446 where
447 T: Sync,
448 Rows: 'a,
449 Cols: 'a,
450 {
451 self.into_const().par_row_chunks(chunk_size)
452 }
453
454 #[inline]
455 #[track_caller]
456 #[cfg(feature = "rayon")]
457 pub fn par_row_partition(
459 self,
460 count: usize,
461 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatRef<'a, T, usize, Cols, RStride, CStride>>
462 where
463 T: Sync,
464 Rows: 'a,
465 Cols: 'a,
466 {
467 self.into_const().par_row_partition(count)
468 }
469
470 #[inline]
471 pub fn try_as_col_major(self) -> Option<MatRef<'a, T, Rows, Cols, ContiguousFwd, CStride>> {
473 self.into_const().try_as_col_major()
474 }
475
476 #[inline]
477 pub fn try_as_row_major(self) -> Option<MatRef<'a, T, Rows, Cols, RStride, ContiguousFwd>> {
479 self.into_const().try_as_row_major()
480 }
481
482 #[doc(hidden)]
483 #[inline]
484 pub unsafe fn const_cast(self) -> MatMut<'a, T, Rows, Cols, RStride, CStride> {
485 self
486 }
487
488 #[inline]
490 pub fn bind<'M, 'N>(self, row: Guard<'M>, col: Guard<'N>) -> MatMut<'a, T, Dim<'M>, Dim<'N>, RStride, CStride> {
491 unsafe {
492 MatMut::from_raw_parts_mut(
493 self.as_ptr_mut(),
494 self.nrows().bind(row),
495 self.ncols().bind(col),
496 self.row_stride(),
497 self.col_stride(),
498 )
499 }
500 }
501
502 #[doc(hidden)]
503 #[inline]
504 pub fn bind_r<'M>(self, row: Guard<'M>) -> MatMut<'a, T, Dim<'M>, Cols, RStride, CStride> {
505 unsafe {
506 MatMut::from_raw_parts_mut(
507 self.as_ptr_mut(),
508 self.nrows().bind(row),
509 self.ncols(),
510 self.row_stride(),
511 self.col_stride(),
512 )
513 }
514 }
515
516 #[doc(hidden)]
517 #[inline]
518 pub fn bind_c<'N>(self, col: Guard<'N>) -> MatMut<'a, T, Rows, Dim<'N>, RStride, CStride> {
519 unsafe {
520 MatMut::from_raw_parts_mut(
521 self.as_ptr_mut(),
522 self.nrows(),
523 self.ncols().bind(col),
524 self.row_stride(),
525 self.col_stride(),
526 )
527 }
528 }
529
530 #[track_caller]
531 #[inline]
532 pub fn get<RowRange, ColRange>(
534 self,
535 row: RowRange,
536 col: ColRange,
537 ) -> <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::Target
538 where
539 MatRef<'a, T, Rows, Cols, RStride, CStride>: MatIndex<RowRange, ColRange>,
540 {
541 <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::get(self.into_const(), row, col)
542 }
543
544 #[track_caller]
545 #[inline]
546 pub unsafe fn get_unchecked<RowRange, ColRange>(
551 self,
552 row: RowRange,
553 col: ColRange,
554 ) -> <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::Target
555 where
556 MatRef<'a, T, Rows, Cols, RStride, CStride>: MatIndex<RowRange, ColRange>,
557 {
558 unsafe { <MatRef<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::get_unchecked(self.into_const(), row, col) }
559 }
560
561 #[track_caller]
563 #[inline]
564 pub fn get_mut<RowRange, ColRange>(
565 self,
566 row: RowRange,
567 col: ColRange,
568 ) -> <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::Target
569 where
570 MatMut<'a, T, Rows, Cols, RStride, CStride>: MatIndex<RowRange, ColRange>,
571 {
572 <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::get(self, row, col)
573 }
574
575 #[track_caller]
580 #[inline]
581 pub unsafe fn get_mut_unchecked<RowRange, ColRange>(
582 self,
583 row: RowRange,
584 col: ColRange,
585 ) -> <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::Target
586 where
587 MatMut<'a, T, Rows, Cols, RStride, CStride>: MatIndex<RowRange, ColRange>,
588 {
589 unsafe { <MatMut<'a, T, Rows, Cols, RStride, CStride> as MatIndex<RowRange, ColRange>>::get_unchecked(self, row, col) }
590 }
591}
592
593impl<
594 T,
595 Rows: Shape,
596 Cols: Shape,
597 RStride: Stride,
598 CStride: Stride,
599 Inner: for<'short> ReborrowMut<'short, Target = Mut<'short, T, Rows, Cols, RStride, CStride>>,
600> generic::Mat<Inner>
601{
602 #[inline]
604 pub fn as_mut(&mut self) -> MatMut<'_, T, Rows, Cols, RStride, CStride> {
605 self.rb_mut()
606 }
607
608 #[inline]
610 #[track_caller]
611 pub fn copy_from_triangular_lower<RhsT: Conjugate<Canonical = T>>(&mut self, other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>)
612 where
613 T: ComplexField,
614 {
615 let other = other.as_mat_ref();
616 let mut this = self.rb_mut();
617
618 assert!(all(this.nrows() == other.nrows(), this.ncols() == other.ncols(),));
619 let (m, n) = this.shape();
620
621 make_guard!(M);
622 make_guard!(N);
623 let M = m.bind(M);
624 let N = n.bind(N);
625 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
626 let other = other.as_shape(M, N);
627 imp(this, other.canonical(), Conj::get::<RhsT>());
628
629 #[math]
630 pub fn imp<'M, 'N, T: ComplexField>(this: MatMut<'_, T, Dim<'M>, Dim<'N>>, other: MatRef<'_, T, Dim<'M>, Dim<'N>>, conj_: Conj) {
631 match conj_ {
632 Conj::No => {
633 zip!(this, other).for_each_triangular_lower(crate::linalg::zip::Diag::Include, |unzip!(dst, src)| *dst = copy(&src));
634 },
635 Conj::Yes => {
636 zip!(this, other).for_each_triangular_lower(crate::linalg::zip::Diag::Include, |unzip!(dst, src)| *dst = conj(&src));
637 },
638 }
639 }
640 }
641
642 #[inline]
644 #[track_caller]
645 pub fn copy_from_triangular_upper<RhsT: Conjugate<Canonical = T>>(&mut self, other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>)
646 where
647 T: ComplexField,
648 {
649 (*self)
650 .rb_mut()
651 .transpose_mut()
652 .copy_from_triangular_lower(other.as_mat_ref().transpose())
653 }
654
655 #[inline]
657 #[track_caller]
658 pub fn copy_from<RhsT: Conjugate<Canonical = T>>(&mut self, other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>)
659 where
660 T: ComplexField,
661 {
662 let other = other.as_mat_ref();
663 let mut this = self.rb_mut();
664
665 assert!(all(this.nrows() == other.nrows(), this.ncols() == other.ncols(),));
666 let (m, n) = this.shape();
667
668 make_guard!(M);
669 make_guard!(N);
670 let M = m.bind(M);
671 let N = n.bind(N);
672 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
673 let other = other.as_shape(M, N);
674 imp(this, other.canonical(), Conj::get::<RhsT>());
675
676 #[math]
677 pub fn imp<'M, 'N, T: ComplexField>(this: MatMut<'_, T, Dim<'M>, Dim<'N>>, other: MatRef<'_, T, Dim<'M>, Dim<'N>>, conj_: Conj) {
678 match conj_ {
679 Conj::No => {
680 zip!(this, other).for_each(|unzip!(dst, src)| *dst = copy(&src));
681 },
682 Conj::Yes => {
683 zip!(this, other).for_each(|unzip!(dst, src)| *dst = conj(&src));
684 },
685 }
686 }
687 }
688
689 #[inline]
691 #[track_caller]
692 pub fn copy_from_strict_triangular_lower<RhsT: Conjugate<Canonical = T>>(&mut self, other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>)
693 where
694 T: ComplexField,
695 {
696 let other = other.as_mat_ref();
697 let mut this = self.rb_mut();
698
699 assert!(all(this.nrows() == other.nrows(), this.ncols() == other.ncols(),));
700 let (m, n) = this.shape();
701
702 make_guard!(M);
703 make_guard!(N);
704 let M = m.bind(M);
705 let N = n.bind(N);
706 let this = this.rb_mut().as_shape_mut(M, N).as_dyn_stride_mut();
707 let other = other.as_shape(M, N);
708 imp(this, other.canonical(), Conj::get::<RhsT>());
709
710 #[math]
711 pub fn imp<'M, 'N, T: ComplexField>(this: MatMut<'_, T, Dim<'M>, Dim<'N>>, other: MatRef<'_, T, Dim<'M>, Dim<'N>>, conj_: Conj) {
712 match conj_ {
713 Conj::No => {
714 zip!(this, other).for_each_triangular_lower(crate::linalg::zip::Diag::Skip, |unzip!(dst, src)| *dst = copy(&src));
715 },
716 Conj::Yes => {
717 zip!(this, other).for_each_triangular_lower(crate::linalg::zip::Diag::Skip, |unzip!(dst, src)| *dst = conj(&src));
718 },
719 }
720 }
721 }
722
723 #[inline]
725 #[track_caller]
726 pub fn copy_from_strict_triangular_upper<RhsT: Conjugate<Canonical = T>>(&mut self, other: impl AsMatRef<T = RhsT, Rows = Rows, Cols = Cols>)
727 where
728 T: ComplexField,
729 {
730 (*self)
731 .rb_mut()
732 .transpose_mut()
733 .copy_from_strict_triangular_lower(other.as_mat_ref().transpose())
734 }
735
736 #[inline]
738 pub fn fill(&mut self, value: T)
739 where
740 T: Clone,
741 {
742 fn cloner<T: Clone>(value: T) -> impl for<'a> FnMut(Last<&'a mut T>) {
743 #[inline]
744 move |x| *x.0 = value.clone()
745 }
746 z!(self.rb_mut().as_dyn_mut()).for_each(cloner::<T>(value));
747 }
748}
749
750impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Rows, Cols, RStride, CStride> {
751 #[inline]
752 pub fn as_ptr_mut(&self) -> *mut T {
754 self.imp.ptr.as_ptr()
755 }
756
757 #[inline]
758 pub fn ptr_at_mut(&self, row: IdxInc<Rows>, col: IdxInc<Cols>) -> *mut T {
760 self.rb().ptr_at(row, col) as *mut T
761 }
762
763 #[inline]
764 #[track_caller]
765 pub unsafe fn ptr_inbounds_at_mut(&self, row: Idx<Rows>, col: Idx<Cols>) -> *mut T {
767 self.rb().ptr_inbounds_at(row, col) as *mut T
768 }
769
770 #[inline]
771 #[track_caller]
772 pub fn split_at_mut(
774 self,
775 row: IdxInc<Rows>,
776 col: IdxInc<Cols>,
777 ) -> (
778 MatMut<'a, T, usize, usize, RStride, CStride>,
779 MatMut<'a, T, usize, usize, RStride, CStride>,
780 MatMut<'a, T, usize, usize, RStride, CStride>,
781 MatMut<'a, T, usize, usize, RStride, CStride>,
782 ) {
783 let (a, b, c, d) = self.into_const().split_at(row, col);
784 unsafe { (a.const_cast(), b.const_cast(), c.const_cast(), d.const_cast()) }
785 }
786
787 #[inline]
788 #[track_caller]
789 pub fn split_at_row_mut(self, row: IdxInc<Rows>) -> (MatMut<'a, T, usize, Cols, RStride, CStride>, MatMut<'a, T, usize, Cols, RStride, CStride>) {
791 let (a, b) = self.into_const().split_at_row(row);
792 unsafe { (a.const_cast(), b.const_cast()) }
793 }
794
795 #[inline]
796 #[track_caller]
797 pub fn split_at_col_mut(self, col: IdxInc<Cols>) -> (MatMut<'a, T, Rows, usize, RStride, CStride>, MatMut<'a, T, Rows, usize, RStride, CStride>) {
799 let (a, b) = self.into_const().split_at_col(col);
800 unsafe { (a.const_cast(), b.const_cast()) }
801 }
802
803 #[inline]
804 pub fn transpose_mut(self) -> MatMut<'a, T, Cols, Rows, CStride, RStride> {
806 MatMut {
807 0: Mut {
808 imp: MatView {
809 ptr: self.imp.ptr,
810 nrows: self.imp.ncols,
811 ncols: self.imp.nrows,
812 row_stride: self.imp.col_stride,
813 col_stride: self.imp.row_stride,
814 },
815 __marker: PhantomData,
816 },
817 }
818 }
819
820 #[inline]
821 pub fn conjugate_mut(self) -> MatMut<'a, T::Conj, Rows, Cols, RStride, CStride>
823 where
824 T: Conjugate,
825 {
826 unsafe { self.into_const().conjugate().const_cast() }
827 }
828
829 #[inline]
830 pub fn canonical_mut(self) -> MatMut<'a, T::Canonical, Rows, Cols, RStride, CStride>
832 where
833 T: Conjugate,
834 {
835 unsafe { self.into_const().canonical().const_cast() }
836 }
837
838 #[inline]
839 pub fn adjoint_mut(self) -> MatMut<'a, T::Conj, Cols, Rows, CStride, RStride>
841 where
842 T: Conjugate,
843 {
844 unsafe { self.into_const().adjoint().const_cast() }
845 }
846
847 #[inline]
848 #[track_caller]
849 pub(crate) fn at_mut(self, row: Idx<Rows>, col: Idx<Cols>) -> &'a mut T {
850 assert!(all(row < self.nrows(), col < self.ncols()));
851 unsafe { self.at_mut_unchecked(row, col) }
852 }
853
854 #[inline]
855 #[track_caller]
856 pub(crate) unsafe fn at_mut_unchecked(self, row: Idx<Rows>, col: Idx<Cols>) -> &'a mut T {
857 &mut *self.ptr_inbounds_at_mut(row, col)
858 }
859
860 #[inline]
861 pub fn reverse_rows_mut(self) -> MatMut<'a, T, Rows, Cols, RStride::Rev, CStride> {
863 unsafe { self.into_const().reverse_rows().const_cast() }
864 }
865
866 #[inline]
867 pub fn reverse_cols_mut(self) -> MatMut<'a, T, Rows, Cols, RStride, CStride::Rev> {
869 unsafe { self.into_const().reverse_cols().const_cast() }
870 }
871
872 #[inline]
873 pub fn reverse_rows_and_cols_mut(self) -> MatMut<'a, T, Rows, Cols, RStride::Rev, CStride::Rev> {
875 unsafe { self.into_const().reverse_rows_and_cols().const_cast() }
876 }
877
878 #[inline]
879 #[track_caller]
880 pub fn submatrix_mut<V: Shape, H: Shape>(
882 self,
883 row_start: IdxInc<Rows>,
884 col_start: IdxInc<Cols>,
885 nrows: V,
886 ncols: H,
887 ) -> MatMut<'a, T, V, H, RStride, CStride> {
888 unsafe { self.into_const().submatrix(row_start, col_start, nrows, ncols).const_cast() }
889 }
890
891 #[inline]
892 #[track_caller]
893 pub fn subrows_mut<V: Shape>(self, row_start: IdxInc<Rows>, nrows: V) -> MatMut<'a, T, V, Cols, RStride, CStride> {
895 unsafe { self.into_const().subrows(row_start, nrows).const_cast() }
896 }
897
898 #[inline]
899 #[track_caller]
900 pub fn subcols_mut<H: Shape>(self, col_start: IdxInc<Cols>, ncols: H) -> MatMut<'a, T, Rows, H, RStride, CStride> {
902 unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
903 }
904
905 #[inline]
906 #[track_caller]
907 pub fn as_shape_mut<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> MatMut<'a, T, V, H, RStride, CStride> {
909 unsafe { self.into_const().as_shape(nrows, ncols).const_cast() }
910 }
911
912 #[inline]
913 #[track_caller]
914 pub fn as_row_shape_mut<V: Shape>(self, nrows: V) -> MatMut<'a, T, V, Cols, RStride, CStride> {
916 unsafe { self.into_const().as_row_shape(nrows).const_cast() }
917 }
918
919 #[inline]
920 #[track_caller]
921 pub fn as_col_shape_mut<H: Shape>(self, ncols: H) -> MatMut<'a, T, Rows, H, RStride, CStride> {
923 unsafe { self.into_const().as_col_shape(ncols).const_cast() }
924 }
925
926 #[inline]
927 pub fn as_dyn_stride_mut(self) -> MatMut<'a, T, Rows, Cols, isize, isize> {
929 unsafe { self.into_const().as_dyn_stride().const_cast() }
930 }
931
932 #[inline]
933 pub fn as_dyn_mut(self) -> MatMut<'a, T, usize, usize, RStride, CStride> {
935 unsafe { self.into_const().as_dyn().const_cast() }
936 }
937
938 #[inline]
939 pub fn as_dyn_rows_mut(self) -> MatMut<'a, T, usize, Cols, RStride, CStride> {
941 unsafe { self.into_const().as_dyn_rows().const_cast() }
942 }
943
944 #[inline]
945 pub fn as_dyn_cols_mut(self) -> MatMut<'a, T, Rows, usize, RStride, CStride> {
947 unsafe { self.into_const().as_dyn_cols().const_cast() }
948 }
949
950 #[inline]
951 #[track_caller]
952 pub fn row_mut(self, i: Idx<Rows>) -> RowMut<'a, T, Cols, CStride> {
954 unsafe { self.into_const().row(i).const_cast() }
955 }
956
957 #[inline]
958 #[track_caller]
959 pub fn col_mut(self, j: Idx<Cols>) -> ColMut<'a, T, Rows, RStride> {
961 unsafe { self.into_const().col(j).const_cast() }
962 }
963
964 #[inline]
965 pub fn col_iter_mut(self) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = ColMut<'a, T, Rows, RStride>>
967 where
968 Rows: 'a,
969 Cols: 'a,
970 {
971 self.into_const().col_iter().map(|x| unsafe { x.const_cast() })
972 }
973
974 #[inline]
975 pub fn row_iter_mut(self) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = RowMut<'a, T, Cols, CStride>>
977 where
978 Rows: 'a,
979 Cols: 'a,
980 {
981 self.into_const().row_iter().map(|x| unsafe { x.const_cast() })
982 }
983
984 #[inline]
985 pub(crate) unsafe fn as_type<U>(self) -> MatMut<'a, U, Rows, Cols, RStride, CStride> {
986 MatMut::from_raw_parts_mut(
987 self.as_ptr_mut() as *mut U,
988 self.nrows(),
989 self.ncols(),
990 self.row_stride(),
991 self.col_stride(),
992 )
993 }
994
995 #[inline]
996 #[cfg(feature = "rayon")]
997 pub fn par_col_iter_mut(self) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = ColMut<'a, T, Rows, RStride>>
999 where
1000 T: Send,
1001 Rows: 'a,
1002 Cols: 'a,
1003 {
1004 use rayon::prelude::*;
1005 unsafe {
1006 self.as_type::<SyncCell<T>>()
1007 .into_const()
1008 .par_col_iter()
1009 .map(|x| x.const_cast())
1010 .map(|x| x.as_type())
1011 }
1012 }
1013
1014 #[inline]
1015 #[cfg(feature = "rayon")]
1016 pub fn par_row_iter_mut(self) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = RowMut<'a, T, Cols, CStride>>
1018 where
1019 T: Send,
1020 Rows: 'a,
1021 Cols: 'a,
1022 {
1023 use rayon::prelude::*;
1024 unsafe {
1025 self.as_type::<SyncCell<T>>()
1026 .into_const()
1027 .par_row_iter()
1028 .map(|x| x.const_cast())
1029 .map(|x| x.as_type())
1030 }
1031 }
1032
1033 #[inline]
1034 #[track_caller]
1035 #[cfg(feature = "rayon")]
1036 pub fn par_col_chunks_mut(
1038 self,
1039 chunk_size: usize,
1040 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatMut<'a, T, Rows, usize, RStride, CStride>>
1041 where
1042 T: Send,
1043 Rows: 'a,
1044 Cols: 'a,
1045 {
1046 use rayon::prelude::*;
1047 unsafe {
1048 self.as_type::<SyncCell<T>>()
1049 .into_const()
1050 .par_col_chunks(chunk_size)
1051 .map(|x| x.const_cast())
1052 .map(|x| x.as_type())
1053 }
1054 }
1055
1056 #[inline]
1057 #[track_caller]
1058 #[cfg(feature = "rayon")]
1059 pub fn par_col_partition_mut(
1061 self,
1062 count: usize,
1063 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatMut<'a, T, Rows, usize, RStride, CStride>>
1064 where
1065 T: Send,
1066 Rows: 'a,
1067 Cols: 'a,
1068 {
1069 use rayon::prelude::*;
1070 unsafe {
1071 self.as_type::<SyncCell<T>>()
1072 .into_const()
1073 .par_col_partition(count)
1074 .map(|x| x.const_cast())
1075 .map(|x| x.as_type())
1076 }
1077 }
1078
1079 #[inline]
1080 #[track_caller]
1081 #[cfg(feature = "rayon")]
1082 pub fn par_row_chunks_mut(
1084 self,
1085 chunk_size: usize,
1086 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatMut<'a, T, usize, Cols, RStride, CStride>>
1087 where
1088 T: Send,
1089 Rows: 'a,
1090 Cols: 'a,
1091 {
1092 use rayon::prelude::*;
1093 unsafe {
1094 self.as_type::<SyncCell<T>>()
1095 .into_const()
1096 .par_row_chunks(chunk_size)
1097 .map(|x| x.const_cast())
1098 .map(|x| x.as_type())
1099 }
1100 }
1101
1102 #[inline]
1103 #[track_caller]
1104 #[cfg(feature = "rayon")]
1105 pub fn par_row_partition_mut(
1107 self,
1108 count: usize,
1109 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = MatMut<'a, T, usize, Cols, RStride, CStride>>
1110 where
1111 T: Send,
1112 Rows: 'a,
1113 Cols: 'a,
1114 {
1115 use rayon::prelude::*;
1116 unsafe {
1117 self.as_type::<SyncCell<T>>()
1118 .into_const()
1119 .par_row_partition(count)
1120 .map(|x| x.const_cast())
1121 .map(|x| x.as_type())
1122 }
1123 }
1124
1125 #[inline]
1126 pub fn split_first_row_mut(self) -> Option<(RowMut<'a, T, Cols, CStride>, MatMut<'a, T, usize, Cols, RStride, CStride>)> {
1128 if let Some(i0) = self.nrows().idx_inc(1) {
1129 let (head, tail) = self.split_at_row_mut(i0);
1130 Some((head.row_mut(0), tail))
1131 } else {
1132 None
1133 }
1134 }
1135
1136 #[inline]
1137 pub fn split_first_col_mut(self) -> Option<(ColMut<'a, T, Rows, RStride>, MatMut<'a, T, Rows, usize, RStride, CStride>)> {
1139 if let Some(i0) = self.ncols().idx_inc(1) {
1140 let (head, tail) = self.split_at_col_mut(i0);
1141 Some((head.col_mut(0), tail))
1142 } else {
1143 None
1144 }
1145 }
1146
1147 #[inline]
1148 pub fn split_last_row_mut(self) -> Option<(RowMut<'a, T, Cols, CStride>, MatMut<'a, T, usize, Cols, RStride, CStride>)> {
1150 if self.nrows().unbound() > 0 {
1151 let i0 = self.nrows().checked_idx_inc(self.nrows().unbound() - 1);
1152 let (head, tail) = self.split_at_row_mut(i0);
1153 Some((tail.row_mut(0), head))
1154 } else {
1155 None
1156 }
1157 }
1158
1159 #[inline]
1160 pub fn split_last_col_mut(self) -> Option<(ColMut<'a, T, Rows, RStride>, MatMut<'a, T, Rows, usize, RStride, CStride>)> {
1162 if self.ncols().unbound() > 0 {
1163 let i0 = self.ncols().checked_idx_inc(self.ncols().unbound() - 1);
1164 let (head, tail) = self.split_at_col_mut(i0);
1165 Some((tail.col_mut(0), head))
1166 } else {
1167 None
1168 }
1169 }
1170
1171 #[inline]
1172 pub fn split_first_row(self) -> Option<(RowRef<'a, T, Cols, CStride>, MatRef<'a, T, usize, Cols, RStride, CStride>)> {
1174 self.into_const().split_first_row()
1175 }
1176
1177 #[inline]
1178 pub fn split_first_col(self) -> Option<(ColRef<'a, T, Rows, RStride>, MatRef<'a, T, Rows, usize, RStride, CStride>)> {
1180 self.into_const().split_first_col()
1181 }
1182
1183 #[inline]
1184 pub fn split_last_row(self) -> Option<(RowRef<'a, T, Cols, CStride>, MatRef<'a, T, usize, Cols, RStride, CStride>)> {
1186 self.into_const().split_last_row()
1187 }
1188
1189 #[inline]
1190 pub fn split_last_col(self) -> Option<(ColRef<'a, T, Rows, RStride>, MatRef<'a, T, Rows, usize, RStride, CStride>)> {
1192 self.into_const().split_last_col()
1193 }
1194
1195 #[inline]
1196 pub fn try_as_col_major_mut(self) -> Option<MatMut<'a, T, Rows, Cols, ContiguousFwd, CStride>> {
1198 self.into_const().try_as_col_major().map(|x| unsafe { x.const_cast() })
1199 }
1200
1201 #[inline]
1202 pub fn try_as_row_major_mut(self) -> Option<MatMut<'a, T, Rows, Cols, RStride, ContiguousFwd>> {
1204 self.into_const().try_as_row_major().map(|x| unsafe { x.const_cast() })
1205 }
1206
1207 #[inline]
1212 #[track_caller]
1213 pub fn two_cols_mut(self, i0: Idx<Cols>, i1: Idx<Cols>) -> (ColMut<'a, T, Rows, RStride>, ColMut<'a, T, Rows, RStride>) {
1214 assert!(i0 != i1);
1215 let this = self.into_const();
1216 unsafe { (this.col(i0).const_cast(), this.col(i1).const_cast()) }
1217 }
1218
1219 #[inline]
1224 #[track_caller]
1225 pub fn two_rows_mut(self, i0: Idx<Rows>, i1: Idx<Rows>) -> (RowMut<'a, T, Cols, CStride>, RowMut<'a, T, Cols, CStride>) {
1226 assert!(i0 != i1);
1227 let this = self.into_const();
1228 unsafe { (this.row(i0).const_cast(), this.row(i1).const_cast()) }
1229 }
1230
1231 #[inline]
1232 #[track_caller]
1233 pub(crate) fn write(&mut self, i: Idx<Rows>, j: Idx<Cols>, value: T) {
1234 *self.rb_mut().at_mut(i, j) = value;
1235 }
1236
1237 #[inline]
1238 pub(crate) fn __at_mut(self, (i, j): (Idx<Rows>, Idx<Cols>)) -> &'a mut T {
1239 self.at_mut(i, j)
1240 }
1241}
1242
1243impl<'a, T, Rows: Shape, Cols: Shape> MatMut<'a, T, Rows, Cols> {
1244 #[inline]
1264 #[track_caller]
1265 pub fn from_column_major_slice_mut(slice: &'a mut [T], nrows: Rows, ncols: Cols) -> Self
1266 where
1267 T: Sized,
1268 {
1269 from_slice_assert(nrows.unbound(), ncols.unbound(), slice.len());
1270
1271 unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), nrows, ncols, 1, nrows.unbound() as isize) }
1272 }
1273
1274 #[inline]
1278 #[track_caller]
1279 pub fn from_column_major_slice_with_stride_mut(slice: &'a mut [T], nrows: Rows, ncols: Cols, col_stride: usize) -> Self
1280 where
1281 T: Sized,
1282 {
1283 from_strided_column_major_slice_mut_assert(nrows.unbound(), ncols.unbound(), col_stride, slice.len());
1284
1285 unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), nrows, ncols, 1, col_stride as isize) }
1286 }
1287
1288 #[inline]
1308 #[track_caller]
1309 pub fn from_row_major_slice_mut(slice: &'a mut [T], nrows: Rows, ncols: Cols) -> Self
1310 where
1311 T: Sized,
1312 {
1313 MatMut::from_column_major_slice_mut(slice, ncols, nrows).transpose_mut()
1314 }
1315
1316 #[inline]
1320 #[track_caller]
1321 pub fn from_row_major_slice_with_stride_mut(slice: &'a mut [T], nrows: Rows, ncols: Cols, row_stride: usize) -> Self
1322 where
1323 T: Sized,
1324 {
1325 from_strided_row_major_slice_mut_assert(nrows.unbound(), ncols.unbound(), row_stride, slice.len());
1326
1327 unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), nrows, ncols, 1, row_stride as isize) }
1328 }
1329}
1330
1331impl<'ROWS, 'COLS, 'a, T, RStride: Stride, CStride: Stride> MatMut<'a, T, Dim<'ROWS>, Dim<'COLS>, RStride, CStride> {
1332 #[doc(hidden)]
1333 #[inline]
1334 pub fn split_with_mut<'TOP, 'BOT, 'LEFT, 'RIGHT>(
1335 self,
1336 row: Partition<'TOP, 'BOT, 'ROWS>,
1337 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1338 ) -> (
1339 MatMut<'a, T, Dim<'TOP>, Dim<'LEFT>, RStride, CStride>,
1340 MatMut<'a, T, Dim<'TOP>, Dim<'RIGHT>, RStride, CStride>,
1341 MatMut<'a, T, Dim<'BOT>, Dim<'LEFT>, RStride, CStride>,
1342 MatMut<'a, T, Dim<'BOT>, Dim<'RIGHT>, RStride, CStride>,
1343 ) {
1344 let (a, b, c, d) = self.split_at_mut(row.midpoint(), col.midpoint());
1345 (
1346 a.as_shape_mut(row.head, col.head),
1347 b.as_shape_mut(row.head, col.tail),
1348 c.as_shape_mut(row.tail, col.head),
1349 d.as_shape_mut(row.tail, col.tail),
1350 )
1351 }
1352}
1353
1354impl<'ROWS, 'a, T, Cols: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Dim<'ROWS>, Cols, RStride, CStride> {
1355 #[doc(hidden)]
1356 #[inline]
1357 pub fn split_rows_with_mut<'TOP, 'BOT>(
1358 self,
1359 row: Partition<'TOP, 'BOT, 'ROWS>,
1360 ) -> (
1361 MatMut<'a, T, Dim<'TOP>, Cols, RStride, CStride>,
1362 MatMut<'a, T, Dim<'BOT>, Cols, RStride, CStride>,
1363 ) {
1364 let (a, b) = self.split_at_row_mut(row.midpoint());
1365 (a.as_row_shape_mut(row.head), b.as_row_shape_mut(row.tail))
1366 }
1367}
1368
1369impl<'COLS, 'a, T, Rows: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Rows, Dim<'COLS>, RStride, CStride> {
1370 #[doc(hidden)]
1371 #[inline]
1372 pub fn split_cols_with_mut<'LEFT, 'RIGHT>(
1373 self,
1374 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1375 ) -> (
1376 MatMut<'a, T, Rows, Dim<'LEFT>, RStride, CStride>,
1377 MatMut<'a, T, Rows, Dim<'RIGHT>, RStride, CStride>,
1378 ) {
1379 let (a, b) = self.split_at_col_mut(col.midpoint());
1380 (a.as_col_shape_mut(col.head), b.as_col_shape_mut(col.tail))
1381 }
1382}
1383
1384impl<'ROWS, 'COLS, 'a, T, RStride: Stride, CStride: Stride> MatMut<'a, T, Dim<'ROWS>, Dim<'COLS>, RStride, CStride> {
1385 #[doc(hidden)]
1386 #[inline]
1387 pub fn split_with<'TOP, 'BOT, 'LEFT, 'RIGHT>(
1388 self,
1389 row: Partition<'TOP, 'BOT, 'ROWS>,
1390 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1391 ) -> (
1392 MatRef<'a, T, Dim<'TOP>, Dim<'LEFT>, RStride, CStride>,
1393 MatRef<'a, T, Dim<'TOP>, Dim<'RIGHT>, RStride, CStride>,
1394 MatRef<'a, T, Dim<'BOT>, Dim<'LEFT>, RStride, CStride>,
1395 MatRef<'a, T, Dim<'BOT>, Dim<'RIGHT>, RStride, CStride>,
1396 ) {
1397 let (a, b, c, d) = self.split_at(row.midpoint(), col.midpoint());
1398 (
1399 a.as_shape(row.head, col.head),
1400 b.as_shape(row.head, col.tail),
1401 c.as_shape(row.tail, col.head),
1402 d.as_shape(row.tail, col.tail),
1403 )
1404 }
1405}
1406
1407impl<'ROWS, 'a, T, Cols: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Dim<'ROWS>, Cols, RStride, CStride> {
1408 #[doc(hidden)]
1409 #[inline]
1410 pub fn split_rows_with<'TOP, 'BOT>(
1411 self,
1412 row: Partition<'TOP, 'BOT, 'ROWS>,
1413 ) -> (
1414 MatRef<'a, T, Dim<'TOP>, Cols, RStride, CStride>,
1415 MatRef<'a, T, Dim<'BOT>, Cols, RStride, CStride>,
1416 ) {
1417 let (a, b) = self.split_at_row(row.midpoint());
1418 (a.as_row_shape(row.head), b.as_row_shape(row.tail))
1419 }
1420}
1421
1422impl<'COLS, 'a, T, Rows: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Rows, Dim<'COLS>, RStride, CStride> {
1423 #[doc(hidden)]
1424 #[inline]
1425 pub fn split_cols_with<'LEFT, 'RIGHT>(
1426 self,
1427 col: Partition<'LEFT, 'RIGHT, 'COLS>,
1428 ) -> (
1429 MatRef<'a, T, Rows, Dim<'LEFT>, RStride, CStride>,
1430 MatRef<'a, T, Rows, Dim<'RIGHT>, RStride, CStride>,
1431 ) {
1432 let (a, b) = self.split_at_col(col.midpoint());
1433 (a.as_col_shape(col.head), b.as_col_shape(col.tail))
1434 }
1435}
1436
1437impl<'a, T, Dim: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Dim, Dim, RStride, CStride> {
1438 #[inline]
1440 pub fn diagonal(self) -> DiagRef<'a, T, Dim, isize> {
1441 self.into_const().diagonal()
1442 }
1443}
1444
1445impl<'a, T, Dim: Shape, RStride: Stride, CStride: Stride> MatMut<'a, T, Dim, Dim, RStride, CStride> {
1446 #[inline]
1448 pub fn diagonal_mut(self) -> DiagMut<'a, T, Dim, isize> {
1449 unsafe { self.into_const().diagonal().column_vector().const_cast().as_diagonal_mut() }
1450 }
1451}
1452
1453impl<'a, T: core::fmt::Debug, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> core::fmt::Debug
1454 for Mut<'a, T, Rows, Cols, RStride, CStride>
1455{
1456 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1457 self.rb().fmt(f)
1458 }
1459}
1460
1461impl<'a, T, Rows: Shape, Cols: Shape> MatMut<'a, T, Rows, Cols>
1462where
1463 T: RealField,
1464{
1465 pub fn min(self) -> Option<T> {
1467 MatRef::internal_min(self.rb().as_dyn())
1468 }
1469
1470 pub fn max(self) -> Option<T> {
1472 MatRef::internal_max(self.rb().as_dyn())
1473 }
1474}
1475
1476#[track_caller]
1477#[inline]
1478fn from_strided_column_major_slice_mut_assert(nrows: usize, ncols: usize, col_stride: usize, len: usize) {
1479 if nrows > 0 && ncols > 0 {
1480 let last = usize::checked_mul(col_stride, ncols - 1).and_then(|last_col| last_col.checked_add(nrows - 1));
1484 let Some(last) = last else {
1485 panic!("address computation of the last matrix element overflowed");
1486 };
1487 assert!(all(col_stride >= nrows, last < len));
1488 }
1489}
1490
1491#[track_caller]
1492#[inline]
1493fn from_strided_row_major_slice_mut_assert(nrows: usize, ncols: usize, row_stride: usize, len: usize) {
1494 if nrows > 0 && ncols > 0 {
1495 let last = usize::checked_mul(row_stride, nrows - 1).and_then(|last_row| last_row.checked_add(ncols - 1));
1499 let Some(last) = last else {
1500 panic!("address computation of the last matrix element overflowed");
1501 };
1502 assert!(all(row_stride >= ncols, last < len));
1503 }
1504}
1505
1506#[cfg(test)]
1507mod tests {
1508 use super::*;
1509
1510 #[test]
1511 fn test_min() {
1512 let mut m = mat![
1513 [1.0, 5.0, 3.0],
1514 [4.0, 2.0, 9.0],
1515 [7.0, 8.0, 6.0], ];
1517
1518 assert_eq!(m.as_mut().min(), Some(1.0));
1519
1520 let mut empty: Mat<f64> = Mat::new();
1521 assert_eq!(empty.as_mut().min(), None);
1522 }
1523
1524 #[test]
1525 fn test_max() {
1526 let mut m = mat![
1527 [1.0, 5.0, 3.0],
1528 [4.0, 2.0, 9.0],
1529 [7.0, 8.0, 6.0], ];
1531
1532 assert_eq!(m.as_mut().max(), Some(9.0));
1533
1534 let mut empty: Mat<f64> = Mat::new();
1535 assert_eq!(empty.as_mut().max(), None);
1536 }
1537}