Skip to main content

faer/mat/
matmut.rs

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;
11/// see [`super::MatMut`]
12pub 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
24/// write-only mutable matrix view over possibly uninitialized storage.
25///
26/// This type deliberately does not implement any operation that forms a
27/// reference to `T`. It is used by overwrite-only kernels, which write through
28/// the raw pointer and return an initialized view only after a full write.
29pub 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	/// creates a write-only matrix view from a raw pointer.
54	///
55	/// # safety
56	/// the pointed-to memory must contain the complete matrix described by the
57	/// dimensions and strides, be properly aligned for `MaybeUninit<T>`, and
58	/// remain exclusively borrowed for `'a`. Matrix elements must not overlap
59	/// each other. Unlike [`MatMut::from_raw_parts_mut`], the elements do not
60	/// need to be initialized.
61	#[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	/// returns the raw pointer to the first matrix element.
83	#[inline]
84	pub fn as_ptr_mut(&self) -> *mut MaybeUninit<T> {
85		self.imp.ptr.as_ptr()
86	}
87
88	/// returns the number of rows.
89	#[inline]
90	pub fn nrows(&self) -> Rows {
91		self.imp.nrows
92	}
93
94	/// returns the number of columns.
95	#[inline]
96	pub fn ncols(&self) -> Cols {
97		self.imp.ncols
98	}
99
100	/// returns the row stride in elements.
101	#[inline]
102	pub fn row_stride(&self) -> RStride {
103		self.imp.row_stride
104	}
105
106	/// returns the column stride in elements.
107	#[inline]
108	pub fn col_stride(&self) -> CStride {
109		self.imp.col_stride
110	}
111
112	/// converts this view to dynamic dimensions and strides.
113	#[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	/// creates a column-major write-only view over a `MaybeUninit` slice.
132	#[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	/// creates a row-major write-only view over a `MaybeUninit` slice.
152	#[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	/// equivalent to
223	/// `MatMut::from_row_major_slice_mut(array.as_flattened_mut(), ROWS, COLS)`
224	#[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	/// equivalent to
240	/// `MatMut::from_column_major_slice_mut(array.as_flattened_mut(), ROWS,
241	/// COLS)`
242	#[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	/// creates a `MatMut` from a pointer to the matrix data, dimensions, and
261	/// strides
262	///
263	/// the row (resp. column) stride is the offset from the memory address of a
264	/// given matrix element at index `(row: i, col: j)`, to the memory address
265	/// of the matrix element at index `(row: i + 1, col: 0)` (resp. `(row: 0,
266	/// col: i + 1)`). this offset is specified in number of elements, not in
267	/// bytes
268	///
269	/// # safety
270	/// the behavior is undefined if any of the following conditions are
271	/// violated:
272	/// * for each matrix unit, the entire memory region addressed by the matrix
273	///   must be contained
274	/// within a single allocation, accessible in its entirety by the
275	/// corresponding pointer in `ptr`
276	/// * for each matrix unit, the corresponding pointer must be non null and
277	///   properly aligned,
278	/// even for a zero-sized matrix.
279	/// * the values accessible by the matrix must be initialized at some point
280	///   before they are read, or
281	/// references to them are formed
282	/// * no aliasing (including self aliasing) is allowed. in other words, none
283	///   of the elements
284	/// accessible by any matrix unit may be accessed for reads or writes by any
285	/// other means for the duration of the lifetime `'a`. no two elements
286	/// within a single matrix unit may point to the same address (such a thing
287	/// can be achieved with a zero stride, for example), and no two
288	/// matrix units may point to the same address
289	///
290	/// # example
291	///
292	/// ```
293	/// use faer::{MatMut, mat};
294	/// // row major matrix with 2 rows, 3 columns, with a column at the end that we want to skip.
295	/// // the row stride is the pointer offset from the address of 1.0 to the address of 4.0,
296	/// // which is 4
297	/// // the column stride is the pointer offset from the address of 1.0 to the address of 2.0,
298	/// // which is 1
299	/// let mut data = [[1.0, 2.0, 3.0, f64::NAN], [4.0, 5.0, 6.0, f64::NAN]];
300	/// let mut matrix =
301	/// 	unsafe { MatMut::from_raw_parts_mut(data.as_mut_ptr() as *mut f64, 2, 3, 4, 1) };
302	/// let expected = mat![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
303	/// assert_eq!(expected.as_ref(), matrix);
304	/// ```
305	#[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	/// returns a pointer to the matrix data
329	#[inline]
330	pub fn as_ptr(&self) -> *const T {
331		self.imp.ptr.as_ptr()
332	}
333
334	/// returns the number of rows of the matrix
335	#[inline]
336	pub fn nrows(&self) -> Rows {
337		self.imp.nrows
338	}
339
340	/// returns the number of columns of the matrix
341	#[inline]
342	pub fn ncols(&self) -> Cols {
343		self.imp.ncols
344	}
345
346	/// returns the number of rows and columns of the matrix
347	#[inline]
348	pub fn shape(&self) -> (Rows, Cols) {
349		(self.nrows(), self.ncols())
350	}
351
352	/// returns the row stride of the matrix, specified in number of elements,
353	/// not in bytes
354	#[inline]
355	pub fn row_stride(&self) -> RStride {
356		self.imp.row_stride
357	}
358
359	/// returns the column stride of the matrix, specified in number of
360	/// elements, not in bytes
361	#[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	/// returns a raw pointer to the element at the given index
392	#[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	/// returns a raw pointer to the element at the given index, assuming the
398	/// provided index is within the matrix bounds
399	///
400	/// # safety
401	/// the behavior is undefined if any of the following conditions are
402	/// violated:
403	/// * `row < self.nrows()`
404	/// * `col < self.ncols()`
405	#[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	/// see [`MatRef::split_at`]
418	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	/// see [`MatRef::split_at_row`]
434	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	/// see [`MatRef::split_at_col`]
447	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	/// see [`MatRef::transpose`]
459	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	/// see [`MatRef::conjugate`]
476	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	/// see [`MatRef::canonical`]
485	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	/// see [`MatRef::adjoint`]
496	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	/// see [`MatRef::reverse_rows`]
505	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	/// see [`MatRef::reverse_cols`]
513	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	/// see [`MatRef::reverse_rows_and_cols`]
521	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	/// see [`MatRef::submatrix`]
530	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	/// see [`MatRef::subrows`]
544	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	/// see [`MatRef::subcols`]
555	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	/// see [`MatRef::as_shape`]
566	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	/// see [`MatRef::as_row_shape`]
577	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	/// see [`MatRef::as_col_shape`]
587	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	/// see [`MatRef::as_dyn_stride`]
596	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	/// see [`MatRef::as_dyn`]
602	pub fn as_dyn(self) -> MatRef<'a, T, usize, usize, RStride, CStride> {
603		self.into_const().as_dyn()
604	}
605
606	#[inline]
607	/// see [`MatRef::as_dyn_rows`]
608	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	/// see [`MatRef::as_dyn_cols`]
614	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	/// see [`MatRef::row`]
621	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	/// see [`MatRef::col`]
628	pub fn col(self, j: Idx<Cols>) -> ColRef<'a, T, Rows, RStride> {
629		self.into_const().col(j)
630	}
631
632	#[inline]
633	/// see [`MatRef::col_iter`]
634	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	/// see [`MatRef::row_iter`]
648	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	/// see [`MatRef::par_col_iter`]
663	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	/// see [`MatRef::par_row_iter`]
680	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	/// see [`MatRef::par_col_chunks`]
698	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	/// see [`MatRef::par_col_partition`]
717	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	/// see [`MatRef::par_row_chunks`]
736	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	/// see [`MatRef::par_row_partition`]
755	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	/// see [`MatRef::try_as_col_major`]
772	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	/// see [`MatRef::try_as_row_major`]
780	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	/// see [`MatRef::)]`]	#[doc(hidden)]
795	#[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	/// see [`MatRef::get`]
849	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	/// see [`MatRef::get_unchecked`]
870	///
871	/// # safety
872	/// same as [`MatRef::get_unchecked`]
873	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	/// see [`MatRef::get`]
894	#[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	/// see [`MatRef::get_unchecked`]
915	///
916	/// # safety
917	/// same as [`MatRef::get_unchecked`]
918	#[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	/// returns a view over `self`
953	#[inline]
954	pub fn as_mut(&mut self) -> MatMut<'_, T, Rows, Cols, RStride, CStride> {
955		self.rb_mut()
956	}
957
958	/// copies the lower triangular half of `other`, including the diagonal,
959	/// into `self`
960	#[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	/// copies the upper triangular half of `other`, including the diagonal,
1005	/// into `self`
1006	#[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	/// copies `other` into `self`
1021	#[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	/// copies the lower triangular half of `other`, excluding the diagonal,
1062	/// into `self`
1063	#[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	/// copies the upper triangular half of `other`, excluding the diagonal,
1108	/// into `self`
1109	#[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	/// fills all the elements of `self` with `value`
1124	#[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	/// see [`MatRef::as_ptr`]
1141	pub fn as_ptr_mut(&self) -> *mut T {
1142		self.imp.ptr.as_ptr()
1143	}
1144
1145	#[inline]
1146	/// see [`MatRef::ptr_at`]
1147	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	/// see [`MatRef::ptr_inbounds_at`]
1154	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	/// see [`MatRef::split_at`]
1165	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	/// see [`MatRef::split_at_row`]
1189	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	/// see [`MatRef::split_at_col`]
1203	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	/// see [`MatRef::transpose`]
1216	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	/// see [`MatRef::conjugate`]
1233	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	/// see [`MatRef::canonical`]
1244	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	/// see [`MatRef::adjoint`]
1255	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	/// see [`MatRef::reverse_rows`]
1283	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	/// see [`MatRef::reverse_cols`]
1291	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	/// see [`MatRef::reverse_rows_and_cols`]
1299	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	/// see [`MatRef::submatrix`]
1308	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	/// see [`MatRef::subrows`]
1325	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	/// see [`MatRef::subcols`]
1336	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	/// see [`MatRef::as_shape`]
1347	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	/// see [`MatRef::as_row_shape`]
1358	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	/// see [`MatRef::as_col_shape`]
1368	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	/// see [`MatRef::as_dyn_stride`]
1377	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	/// see [`MatRef::as_dyn`]
1383	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	/// see [`MatRef::as_dyn_rows`]
1389	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	/// see [`MatRef::as_dyn_cols`]
1397	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	/// see [`MatRef::row`]
1406	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	/// see [`MatRef::col`]
1413	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	/// see [`MatRef::col_iter`]
1419	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	/// see [`MatRef::row_iter`]
1435	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	/// see [`MatRef::par_col_iter`]
1465	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	/// see [`MatRef::par_row_iter`]
1489	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	/// see [`MatRef::par_col_chunks`]
1514	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	/// see [`MatRef::par_col_partition`]
1540	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	/// see [`MatRef::par_row_chunks`]
1566	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	/// see [`MatRef::par_row_partition`]
1592	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	/// see [`MatRef::split_first_row`]
1616	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	/// see [`MatRef::split_first_col`]
1632	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	/// see [`MatRef::split_last_row`]
1648	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	/// see [`MatRef::split_last_col`]
1665	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	/// see [`MatRef::split_first_row`]
1682	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	/// see [`MatRef::split_first_col`]
1693	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	/// see [`MatRef::split_last_row`]
1704	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	/// see [`MatRef::split_last_col`]
1715	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	/// see [`MatRef::try_as_col_major`]
1726	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	/// see [`MatRef::try_as_row_major`]
1736	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	/// returns two views over the given columns
1745	///
1746	/// # panics
1747	/// panics if `i0 == i1`
1748	#[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	/// returns two views over the given rows
1761	///
1762	/// # panics
1763	/// panics if `i0 == i1`
1764	#[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	/// creates a `MatMut` from slice views over the matrix data, and the matrix
1783	/// dimensions. the data is interpreted in a column-major format, so that
1784	/// the first chunk of `nrows` values from the slices goes in the first
1785	/// column of the matrix, the second chunk of `nrows` values goes in the
1786	/// second column, and so on
1787	///
1788	/// # panics
1789	/// the function panics if any of the following conditions are violated:
1790	/// * `nrows * ncols == slice.len()`
1791	///
1792	/// # example
1793	/// ```
1794	/// use faer::{MatMut, mat};
1795	/// let mut slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
1796	/// let view = MatMut::from_column_major_slice_mut(&mut slice, 3, 2);
1797	/// let expected = mat![[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]];
1798	/// assert_eq!(expected, view);
1799	/// ```
1800	#[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	/// creates a `MatMut` from slice views over the matrix data, and the matrix
1823	/// dimensions. the data is interpreted in a column-major format, where the
1824	/// beginnings of two consecutive columns are separated by `col_stride`
1825	/// elements.
1826	#[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	/// creates a `MatMut` from slice views over the matrix data, and the matrix
1855	/// dimensions. the data is interpreted in a row-major format, so that the
1856	/// first chunk of `ncols` values from the slices goes in the first column
1857	/// of the matrix, the second chunk of `ncols` values goes in the second
1858	/// column, and so on
1859	///
1860	/// # panics
1861	/// the function panics if any of the following conditions are violated:
1862	/// * `nrows * ncols == slice.len()`
1863	///
1864	/// # example
1865	/// ```
1866	/// use faer::{MatMut, mat};
1867	/// let mut slice = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0_f64];
1868	/// let view = MatMut::from_row_major_slice_mut(&mut slice, 3, 2);
1869	/// let expected = mat![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];
1870	/// assert_eq!(expected, view);
1871	/// ```
1872	#[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	/// creates a `MatMut` from slice views over the matrix data, and the matrix
1886	/// dimensions. the data is interpreted in a row-major format, where the
1887	/// beginnings of two consecutive rows are separated by `row_stride`
1888	/// elements.
1889	#[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	/// see [`MatRef::diagonal`]
2033	#[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	/// see [`MatRef::diagonal`]
2042	#[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	/// see [MatRef::min]
2071	pub fn min(self) -> Option<T> {
2072		MatRef::internal_min(self.rb().as_dyn())
2073	}
2074
2075	/// see [MatRef::min]
2076	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}