1use super::*;
2use crate::utils::bound::{Array, Dim, Partition};
3use crate::{ContiguousFwd, Idx, IdxInc};
4use equator::{assert, debug_assert};
5pub struct Mut<'a, T, Cols = usize, CStride = isize> {
7 pub(crate) trans: ColMut<'a, T, Cols, CStride>,
8}
9impl<'short, T, Rows: Copy, RStride: Copy> Reborrow<'short>
10 for Mut<'_, T, Rows, RStride>
11{
12 type Target = Ref<'short, T, Rows, RStride>;
13
14 #[inline]
15 fn rb(&'short self) -> Self::Target {
16 Ref {
17 trans: self.trans.rb(),
18 }
19 }
20}
21impl<'short, T, Rows: Copy, RStride: Copy> ReborrowMut<'short>
22 for Mut<'_, T, Rows, RStride>
23{
24 type Target = Mut<'short, T, Rows, RStride>;
25
26 #[inline]
27 fn rb_mut(&'short mut self) -> Self::Target {
28 Mut {
29 trans: self.trans.rb_mut(),
30 }
31 }
32}
33impl<'a, T, Rows: Copy, RStride: Copy> IntoConst for Mut<'a, T, Rows, RStride> {
34 type Target = Ref<'a, T, Rows, RStride>;
35
36 #[inline]
37 fn into_const(self) -> Self::Target {
38 Ref {
39 trans: self.trans.into_const(),
40 }
41 }
42}
43impl<'a, T> RowMut<'a, T> {
44 #[inline]
46 pub fn from_mut(value: &'a mut T) -> Self {
47 unsafe { RowMut::from_raw_parts_mut(value as *mut T, 1, 1) }
48 }
49
50 #[inline]
53 pub fn from_slice_mut(slice: &'a mut [T]) -> Self {
54 let len = slice.len();
55 unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), len, 1) }
56 }
57}
58impl<'a, T, Cols: Shape, CStride: Stride> RowMut<'a, T, Cols, CStride> {
59 #[inline(always)]
66 #[track_caller]
67 pub const unsafe fn from_raw_parts_mut(
68 ptr: *mut T,
69 ncols: Cols,
70 col_stride: CStride,
71 ) -> Self {
72 Self {
73 0: Mut {
74 trans: ColMut::from_raw_parts_mut(ptr, ncols, col_stride),
75 },
76 }
77 }
78
79 #[inline(always)]
81 pub fn as_ptr(&self) -> *const T {
82 self.trans.as_ptr()
83 }
84
85 #[inline(always)]
87 pub fn nrows(&self) -> usize {
88 1
89 }
90
91 #[inline(always)]
93 pub fn ncols(&self) -> Cols {
94 self.trans.nrows()
95 }
96
97 #[inline(always)]
99 pub fn shape(&self) -> (usize, Cols) {
100 (self.nrows(), self.ncols())
101 }
102
103 #[inline(always)]
105 pub fn col_stride(&self) -> CStride {
106 self.trans.row_stride()
107 }
108
109 #[inline]
110 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Row<U, Cols> {
111 self.rb().map(f)
112 }
113
114 #[inline]
115 pub fn for_each(&self, f: impl Fn(&T)) {
116 self.rb().for_each(f)
117 }
118
119 #[inline]
120 pub fn map_mut<U>(&mut self, f: impl FnMut(&mut T) -> U) -> Row<U, Cols> {
121 let mut f = f;
122 zip!(self).map(|unzip!(x)| f(x))
123 }
124
125 #[inline]
126 pub fn for_each_mut(&mut self, f: impl FnMut(&mut T)) {
127 let mut f = f;
128 zip!(self).for_each(|unzip!(x)| f(x))
129 }
130
131 #[inline(always)]
133 pub fn ptr_at(&self, col: IdxInc<Cols>) -> *const T {
134 self.trans.ptr_at(col)
135 }
136
137 #[inline(always)]
145 #[track_caller]
146 pub unsafe fn ptr_inbounds_at(&self, col: Idx<Cols>) -> *const T {
147 debug_assert!(all(col < self.ncols()));
148 self.trans.ptr_inbounds_at(col)
149 }
150
151 #[inline]
152 #[track_caller]
153 pub fn split_at_col(
155 self,
156 col: IdxInc<Cols>,
157 ) -> (RowRef<'a, T, usize, CStride>, RowRef<'a, T, usize, CStride>) {
158 self.into_const().split_at_col(col)
159 }
160
161 #[inline(always)]
162 pub fn transpose(self) -> ColRef<'a, T, Cols, CStride> {
164 self.into_const().transpose()
165 }
166
167 #[inline(always)]
168 pub fn conjugate(self) -> RowRef<'a, T::Conj, Cols, CStride>
170 where
171 T: Conjugate,
172 {
173 self.into_const().conjugate()
174 }
175
176 #[inline(always)]
177 pub fn canonical(self) -> RowRef<'a, T::Canonical, Cols, CStride>
179 where
180 T: Conjugate,
181 {
182 self.into_const().canonical()
183 }
184
185 #[inline(always)]
186 pub fn adjoint(self) -> ColRef<'a, T::Conj, Cols, CStride>
188 where
189 T: Conjugate,
190 {
191 self.into_const().adjoint()
192 }
193
194 #[track_caller]
195 #[inline(always)]
196 pub fn get<ColRange>(
198 self,
199 col: ColRange,
200 ) -> <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
201 where
202 RowRef<'a, T, Cols, CStride>: RowIndex<ColRange>,
203 {
204 <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::get(
205 self.into_const(),
206 col,
207 )
208 }
209
210 #[track_caller]
211 #[inline(always)]
212 pub unsafe fn get_unchecked<ColRange>(
214 self,
215 col: ColRange,
216 ) -> <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
217 where
218 RowRef<'a, T, Cols, CStride>: RowIndex<ColRange>,
219 {
220 unsafe {
221 <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::get_unchecked(
222 self.into_const(),
223 col,
224 )
225 }
226 }
227
228 #[inline]
229 pub fn reverse_cols(self) -> RowRef<'a, T, Cols, CStride::Rev> {
231 self.into_const().reverse_cols()
232 }
233
234 #[inline]
235 pub fn subcols<V: Shape>(
237 self,
238 col_start: IdxInc<Cols>,
239 ncols: V,
240 ) -> RowRef<'a, T, V, CStride> {
241 self.into_const().subcols(col_start, ncols)
242 }
243
244 #[inline]
245 #[track_caller]
246 pub fn as_col_shape<V: Shape>(self, ncols: V) -> RowRef<'a, T, V, CStride> {
248 self.into_const().as_col_shape(ncols)
249 }
250
251 #[inline]
252 pub fn as_dyn_cols(self) -> RowRef<'a, T, usize, CStride> {
254 self.into_const().as_dyn_cols()
255 }
256
257 #[inline]
258 pub fn as_dyn_stride(self) -> RowRef<'a, T, Cols, isize> {
260 self.into_const().as_dyn_stride()
261 }
262
263 #[inline]
264 pub fn iter(
266 self,
267 ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a T>
268 where
269 Cols: 'a,
270 {
271 self.0.trans.iter()
272 }
273
274 #[inline]
275 #[cfg(feature = "rayon")]
276 pub fn par_iter(
278 self,
279 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a T>
280 where
281 T: Sync,
282 Cols: 'a,
283 {
284 self.0.trans.par_iter()
285 }
286
287 #[inline]
288 pub fn try_as_row_major(
290 self,
291 ) -> Option<RowRef<'a, T, Cols, ContiguousFwd>> {
292 self.into_const().try_as_row_major()
293 }
294
295 #[inline]
296 pub fn as_diagonal(self) -> DiagRef<'a, T, Cols, CStride> {
298 DiagRef {
299 0: crate::diag::Ref {
300 inner: self.0.trans.into_const(),
301 },
302 }
303 }
304
305 #[inline(always)]
306 #[doc(hidden)]
307 pub unsafe fn const_cast(self) -> RowMut<'a, T, Cols, CStride> {
308 RowMut {
309 0: Mut {
310 trans: self.0.trans.const_cast(),
311 },
312 }
313 }
314
315 #[inline]
316 pub fn as_mat(self) -> MatRef<'a, T, usize, Cols, isize, CStride> {
318 self.into_const().as_mat()
319 }
320
321 #[inline]
322 pub fn as_mat_mut(self) -> MatMut<'a, T, usize, Cols, isize, CStride> {
324 unsafe { self.into_const().as_mat().const_cast() }
325 }
326}
327impl<
328 T,
329 Cols: Shape,
330 CStride: Stride,
331 Inner: for<'short> ReborrowMut<'short, Target = Mut<'short, T, Cols, CStride>>,
332> generic::Row<Inner>
333{
334 #[inline]
335 pub fn as_mut(&mut self) -> RowMut<'_, T, Cols, CStride> {
337 self.rb_mut()
338 }
339
340 #[inline]
341 pub fn copy_from<RhsT: Conjugate<Canonical = T>>(
343 &mut self,
344 other: impl AsRowRef<T = RhsT, Cols = Cols>,
345 ) where
346 T: ComplexField,
347 {
348 self.rb_mut()
349 .transpose_mut()
350 .copy_from(other.as_row_ref().transpose());
351 }
352
353 pub fn fill(&mut self, value: T)
355 where
356 T: Clone,
357 {
358 self.rb_mut().transpose_mut().fill(value)
359 }
360}
361impl<'a, T, Cols: Shape, CStride: Stride> RowMut<'a, T, Cols, CStride> {
362 #[inline(always)]
363 pub fn as_ptr_mut(&self) -> *mut T {
365 self.trans.as_ptr_mut()
366 }
367
368 #[inline(always)]
369 pub fn ptr_at_mut(&self, col: IdxInc<Cols>) -> *mut T {
371 self.trans.ptr_at_mut(col)
372 }
373
374 #[inline(always)]
375 #[track_caller]
376 pub unsafe fn ptr_inbounds_at_mut(&self, col: Idx<Cols>) -> *mut T {
378 debug_assert!(all(col < self.ncols()));
379 self.trans.ptr_inbounds_at_mut(col)
380 }
381
382 #[inline]
383 #[track_caller]
384 pub fn split_at_col_mut(
386 self,
387 col: IdxInc<Cols>,
388 ) -> (RowMut<'a, T, usize, CStride>, RowMut<'a, T, usize, CStride>) {
389 let (a, b) = self.into_const().split_at_col(col);
390 unsafe { (a.const_cast(), b.const_cast()) }
391 }
392
393 #[inline(always)]
394 pub fn transpose_mut(self) -> ColMut<'a, T, Cols, CStride> {
396 self.0.trans
397 }
398
399 #[inline(always)]
400 pub fn conjugate_mut(self) -> RowMut<'a, T::Conj, Cols, CStride>
402 where
403 T: Conjugate,
404 {
405 unsafe { self.into_const().conjugate().const_cast() }
406 }
407
408 #[inline(always)]
409 pub fn canonical_mut(self) -> RowMut<'a, T::Canonical, Cols, CStride>
411 where
412 T: Conjugate,
413 {
414 unsafe { self.into_const().canonical().const_cast() }
415 }
416
417 #[inline(always)]
418 pub fn adjoint_mut(self) -> ColMut<'a, T::Conj, Cols, CStride>
420 where
421 T: Conjugate,
422 {
423 unsafe { self.into_const().adjoint().const_cast() }
424 }
425
426 #[inline(always)]
427 #[track_caller]
428 pub(crate) fn at_mut(self, col: Idx<Cols>) -> &'a mut T {
429 assert!(all(col < self.ncols()));
430 unsafe { self.at_mut_unchecked(col) }
431 }
432
433 #[inline(always)]
434 #[track_caller]
435 pub(crate) unsafe fn at_mut_unchecked(self, col: Idx<Cols>) -> &'a mut T {
436 &mut *self.ptr_inbounds_at_mut(col)
437 }
438
439 #[track_caller]
440 #[inline(always)]
441 pub fn get_mut<ColRange>(
443 self,
444 col: ColRange,
445 ) -> <RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
446 where
447 RowMut<'a, T, Cols, CStride>: RowIndex<ColRange>,
448 {
449 <RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::get(self, col)
450 }
451
452 #[track_caller]
453 #[inline(always)]
454 pub unsafe fn get_mut_unchecked<ColRange>(
456 self,
457 col: ColRange,
458 ) -> <RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
459 where
460 RowMut<'a, T, Cols, CStride>: RowIndex<ColRange>,
461 {
462 unsafe {
463 <RowMut<'a, T, Cols, CStride> as RowIndex<ColRange>>::get_unchecked(
464 self, col,
465 )
466 }
467 }
468
469 #[inline]
470 pub fn reverse_cols_mut(self) -> RowMut<'a, T, Cols, CStride::Rev> {
472 unsafe { self.into_const().reverse_cols().const_cast() }
473 }
474
475 #[inline]
476 pub fn subcols_mut<V: Shape>(
478 self,
479 col_start: IdxInc<Cols>,
480 ncols: V,
481 ) -> RowMut<'a, T, V, CStride> {
482 unsafe { self.into_const().subcols(col_start, ncols).const_cast() }
483 }
484
485 #[inline]
486 #[track_caller]
487 pub fn as_col_shape_mut<V: Shape>(
489 self,
490 ncols: V,
491 ) -> RowMut<'a, T, V, CStride> {
492 unsafe { self.into_const().as_col_shape(ncols).const_cast() }
493 }
494
495 #[inline]
496 pub fn as_dyn_cols_mut(self) -> RowMut<'a, T, usize, CStride> {
498 unsafe { self.into_const().as_dyn_cols().const_cast() }
499 }
500
501 #[inline]
502 pub fn as_dyn_stride_mut(self) -> RowMut<'a, T, Cols, isize> {
504 unsafe { self.into_const().as_dyn_stride().const_cast() }
505 }
506
507 #[inline]
508 pub fn iter_mut(
510 self,
511 ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a mut T>
512 where
513 Cols: 'a,
514 {
515 self.0.trans.iter_mut()
516 }
517
518 #[inline]
519 #[cfg(feature = "rayon")]
520 pub fn par_iter_mut(
522 self,
523 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a mut T>
524 where
525 T: Send,
526 Cols: 'a,
527 {
528 self.0.trans.par_iter_mut()
529 }
530
531 #[inline]
532 #[track_caller]
533 #[cfg(feature = "rayon")]
534 pub fn par_partition(
536 self,
537 count: usize,
538 ) -> impl 'a
539 + rayon::iter::IndexedParallelIterator<
540 Item = RowRef<'a, T, usize, CStride>,
541 >
542 where
543 T: Sync,
544 Cols: 'a,
545 {
546 self.into_const().par_partition(count)
547 }
548
549 #[inline]
550 #[track_caller]
551 #[cfg(feature = "rayon")]
552 pub fn par_partition_mut(
554 self,
555 count: usize,
556 ) -> impl 'a
557 + rayon::iter::IndexedParallelIterator<
558 Item = RowMut<'a, T, usize, CStride>,
559 >
560 where
561 T: Send,
562 Cols: 'a,
563 {
564 use crate::mat::matmut::SyncCell;
565 use rayon::prelude::*;
566 unsafe {
567 self.as_type::<SyncCell<T>>()
568 .into_const()
569 .par_partition(count)
570 .map(|col| col.const_cast().as_type::<T>())
571 }
572 }
573
574 pub(crate) unsafe fn as_type<U>(self) -> RowMut<'a, U, Cols, CStride> {
575 RowMut::from_raw_parts_mut(
576 self.as_ptr_mut() as *mut U,
577 self.ncols(),
578 self.col_stride(),
579 )
580 }
581
582 #[inline]
583 pub fn try_as_row_major_mut(
585 self,
586 ) -> Option<RowMut<'a, T, Cols, ContiguousFwd>> {
587 self.into_const()
588 .try_as_row_major()
589 .map(|x| unsafe { x.const_cast() })
590 }
591
592 #[inline]
593 pub fn as_diagonal_mut(self) -> DiagMut<'a, T, Cols, CStride> {
595 DiagMut {
596 0: crate::diag::Mut {
597 inner: self.0.trans,
598 },
599 }
600 }
601
602 #[inline]
603 pub(crate) fn __at_mut(self, i: Idx<Cols>) -> &'a mut T {
604 self.at_mut(i)
605 }
606}
607impl<'a, T, Rows: Shape> RowMut<'a, T, Rows, ContiguousFwd> {
608 #[inline]
610 pub fn as_slice(self) -> &'a [T] {
611 self.transpose().as_slice()
612 }
613}
614impl<'a, 'ROWS, T> RowMut<'a, T, Dim<'ROWS>, ContiguousFwd> {
615 #[inline]
617 pub fn as_array(self) -> &'a Array<'ROWS, T> {
618 self.transpose().as_array()
619 }
620}
621impl<'a, T, Cols: Shape> RowMut<'a, T, Cols, ContiguousFwd> {
622 #[inline]
624 pub fn as_slice_mut(self) -> &'a mut [T] {
625 self.transpose_mut().as_slice_mut()
626 }
627}
628impl<'a, 'COLS, T> RowMut<'a, T, Dim<'COLS>, ContiguousFwd> {
629 #[inline]
631 pub fn as_array_mut(self) -> &'a mut Array<'COLS, T> {
632 self.transpose_mut().as_array_mut()
633 }
634}
635impl<'COLS, 'a, T, CStride: Stride> RowMut<'a, T, Dim<'COLS>, CStride> {
636 #[doc(hidden)]
637 #[inline]
638 pub fn split_cols_with<'LEFT, 'RIGHT>(
639 self,
640 col: Partition<'LEFT, 'RIGHT, 'COLS>,
641 ) -> (
642 RowRef<'a, T, Dim<'LEFT>, CStride>,
643 RowRef<'a, T, Dim<'RIGHT>, CStride>,
644 ) {
645 let (a, b) = self.split_at_col(col.midpoint());
646 (a.as_col_shape(col.head), b.as_col_shape(col.tail))
647 }
648}
649impl<'COLS, 'a, T, CStride: Stride> RowMut<'a, T, Dim<'COLS>, CStride> {
650 #[doc(hidden)]
651 #[inline]
652 pub fn split_cols_with_mut<'LEFT, 'RIGHT>(
653 self,
654 col: Partition<'LEFT, 'RIGHT, 'COLS>,
655 ) -> (
656 RowMut<'a, T, Dim<'LEFT>, CStride>,
657 RowMut<'a, T, Dim<'RIGHT>, CStride>,
658 ) {
659 let (a, b) = self.split_at_col_mut(col.midpoint());
660 (a.as_col_shape_mut(col.head), b.as_col_shape_mut(col.tail))
661 }
662}
663impl<T: core::fmt::Debug, Cols: Shape, CStride: Stride> core::fmt::Debug
664 for Mut<'_, T, Cols, CStride>
665{
666 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
667 self.rb().fmt(f)
668 }
669}
670impl<'a, T, Cols: Shape, CStride: Stride> RowMut<'a, T, Cols, CStride>
671where
672 T: RealField,
673{
674 pub fn max(&self) -> Option<T> {
676 self.rb().as_dyn_cols().as_dyn_stride().internal_max()
677 }
678
679 pub fn min(&self) -> Option<T> {
681 self.rb().as_dyn_cols().as_dyn_stride().internal_min()
682 }
683}
684#[cfg(test)]
685mod tests {
686 use crate::Row;
687 #[test]
688 fn test_row_min() {
689 let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
690 let rowmut = row.as_ref();
691 assert_eq!(rowmut.min(), Some(1.0));
692 let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
693 let emptymut = empty.as_ref();
694 assert_eq!(emptymut.min(), None);
695 }
696 #[test]
697 fn test_row_max() {
698 let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
699 let rowmut = row.as_ref();
700 assert_eq!(rowmut.max(), Some(5.0));
701 let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
702 let emptymut = empty.as_ref();
703 assert_eq!(emptymut.max(), None);
704 }
705}