1use super::*;
2use crate::mat::matmut::SyncCell;
3use crate::utils::bound::{Array, Dim, Partition};
4use crate::{ContiguousFwd, Idx, IdxInc};
5use core::marker::PhantomData;
6use core::ptr::NonNull;
7use equator::assert;
8use generativity::Guard;
9pub struct Mut<'a, T, Rows = usize, RStride = isize> {
11 pub(super) imp: ColView<T, Rows, RStride>,
12 pub(super) __marker: PhantomData<&'a mut T>,
13}
14impl<'short, T, Rows: Copy, RStride: Copy> Reborrow<'short>
15 for Mut<'_, T, Rows, RStride>
16{
17 type Target = Ref<'short, T, Rows, RStride>;
18
19 #[inline]
20 fn rb(&'short self) -> Self::Target {
21 Ref {
22 imp: self.imp,
23 __marker: PhantomData,
24 }
25 }
26}
27impl<'short, T, Rows: Copy, RStride: Copy> ReborrowMut<'short>
28 for Mut<'_, T, Rows, RStride>
29{
30 type Target = Mut<'short, T, Rows, RStride>;
31
32 #[inline]
33 fn rb_mut(&'short mut self) -> Self::Target {
34 Mut {
35 imp: self.imp,
36 __marker: PhantomData,
37 }
38 }
39}
40impl<'a, T, Rows: Copy, RStride: Copy> IntoConst for Mut<'a, T, Rows, RStride> {
41 type Target = Ref<'a, T, Rows, RStride>;
42
43 #[inline]
44 fn into_const(self) -> Self::Target {
45 Ref {
46 imp: self.imp,
47 __marker: PhantomData,
48 }
49 }
50}
51unsafe impl<T: Sync, Rows: Sync, RStride: Sync> Sync
52 for Mut<'_, T, Rows, RStride>
53{
54}
55unsafe impl<T: Send, Rows: Send, RStride: Send> Send
56 for Mut<'_, T, Rows, RStride>
57{
58}
59impl<'a, T> ColMut<'a, T> {
60 #[inline]
62 pub fn from_mut(value: &'a mut T) -> Self {
63 unsafe { ColMut::from_raw_parts_mut(value as *mut T, 1, 1) }
64 }
65
66 #[inline]
69 pub fn from_slice_mut(slice: &'a mut [T]) -> Self {
70 let len = slice.len();
71 unsafe { Self::from_raw_parts_mut(slice.as_mut_ptr(), len, 1) }
72 }
73}
74impl<'a, T, Rows: Shape, RStride: Stride> ColMut<'a, T, Rows, RStride> {
75 #[inline(always)]
82 #[track_caller]
83 pub const unsafe fn from_raw_parts_mut(
84 ptr: *mut T,
85 nrows: Rows,
86 row_stride: RStride,
87 ) -> Self {
88 Self {
89 0: Mut {
90 imp: ColView {
91 ptr: NonNull::new_unchecked(ptr),
92 nrows,
93 row_stride,
94 },
95 __marker: PhantomData,
96 },
97 }
98 }
99
100 #[inline(always)]
102 pub fn as_ptr(&self) -> *const T {
103 self.rb().as_ptr()
104 }
105
106 #[inline(always)]
108 pub fn nrows(&self) -> Rows {
109 self.imp.nrows
110 }
111
112 #[inline(always)]
114 pub fn ncols(&self) -> usize {
115 1
116 }
117
118 #[inline(always)]
120 pub fn shape(&self) -> (Rows, usize) {
121 (self.nrows(), self.ncols())
122 }
123
124 #[inline(always)]
127 pub fn row_stride(&self) -> RStride {
128 self.imp.row_stride
129 }
130
131 #[inline]
132 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Col<U, Rows> {
133 self.rb().map(f)
134 }
135
136 #[inline]
137 pub fn for_each(&self, f: impl Fn(&T)) {
138 self.rb().for_each(f)
139 }
140
141 #[inline]
142 pub fn map_mut<U>(&mut self, f: impl FnMut(&mut T) -> U) -> Col<U, Rows> {
143 let mut f = f;
144 zip!(self).map(|unzip!(x)| f(x))
145 }
146
147 #[inline]
148 pub fn for_each_mut(&mut self, f: impl FnMut(&mut T)) {
149 let mut f = f;
150 zip!(self).for_each(|unzip!(x)| f(x))
151 }
152
153 #[inline(always)]
155 pub fn ptr_at(&self, row: IdxInc<Rows>) -> *const T {
156 self.rb().ptr_at(row)
157 }
158
159 #[inline(always)]
167 #[track_caller]
168 pub unsafe fn ptr_inbounds_at(&self, row: Idx<Rows>) -> *const T {
169 self.rb().ptr_inbounds_at(row)
170 }
171
172 #[inline]
173 #[track_caller]
174 pub fn split_at_row(
176 self,
177 row: IdxInc<Rows>,
178 ) -> (ColRef<'a, T, usize, RStride>, ColRef<'a, T, usize, RStride>) {
179 self.into_const().split_at_row(row)
180 }
181
182 #[inline(always)]
183 pub fn transpose(self) -> RowRef<'a, T, Rows, RStride> {
185 self.into_const().transpose()
186 }
187
188 #[inline(always)]
189 pub fn conjugate(self) -> ColRef<'a, T::Conj, Rows, RStride>
191 where
192 T: Conjugate,
193 {
194 self.into_const().conjugate()
195 }
196
197 #[inline(always)]
198 pub fn canonical(self) -> ColRef<'a, T::Canonical, Rows, RStride>
200 where
201 T: Conjugate,
202 {
203 self.into_const().canonical()
204 }
205
206 #[inline(always)]
207 pub fn adjoint(self) -> RowRef<'a, T::Conj, Rows, RStride>
209 where
210 T: Conjugate,
211 {
212 self.into_const().adjoint()
213 }
214
215 #[track_caller]
216 #[inline(always)]
217 pub fn get<RowRange>(
219 self,
220 row: RowRange,
221 ) -> <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::Target
222 where
223 ColRef<'a, T, Rows, RStride>: ColIndex<RowRange>,
224 {
225 <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::get(
226 self.into_const(),
227 row,
228 )
229 }
230
231 #[track_caller]
232 #[inline(always)]
233 pub unsafe fn get_unchecked<RowRange>(
235 self,
236 row: RowRange,
237 ) -> <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::Target
238 where
239 ColRef<'a, T, Rows, RStride>: ColIndex<RowRange>,
240 {
241 unsafe {
242 <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::get_unchecked(
243 self.into_const(),
244 row,
245 )
246 }
247 }
248
249 #[inline]
250 pub fn reverse_rows(self) -> ColRef<'a, T, Rows, RStride::Rev> {
252 self.into_const().reverse_rows()
253 }
254
255 #[inline]
256 pub fn subrows<V: Shape>(
258 self,
259 row_start: IdxInc<Rows>,
260 nrows: V,
261 ) -> ColRef<'a, T, V, RStride> {
262 self.into_const().subrows(row_start, nrows)
263 }
264
265 #[inline]
266 #[track_caller]
267 pub fn as_row_shape<V: Shape>(self, nrows: V) -> ColRef<'a, T, V, RStride> {
269 self.into_const().as_row_shape(nrows)
270 }
271
272 #[inline]
273 pub fn as_dyn_rows(self) -> ColRef<'a, T, usize, RStride> {
275 self.into_const().as_dyn_rows()
276 }
277
278 #[inline]
279 pub fn as_dyn_stride(self) -> ColRef<'a, T, Rows, isize> {
281 self.into_const().as_dyn_stride()
282 }
283
284 #[inline]
285 pub fn iter(
287 self,
288 ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a T>
289 where
290 Rows: 'a,
291 {
292 self.into_const().iter()
293 }
294
295 #[inline]
296 #[cfg(feature = "rayon")]
297 pub fn par_iter(
299 self,
300 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a T>
301 where
302 T: Sync,
303 Rows: 'a,
304 {
305 self.into_const().par_iter()
306 }
307
308 #[inline]
309 #[track_caller]
310 #[cfg(feature = "rayon")]
311 pub fn par_partition(
313 self,
314 count: usize,
315 ) -> impl 'a
316 + rayon::iter::IndexedParallelIterator<
317 Item = ColRef<'a, T, usize, RStride>,
318 >
319 where
320 T: Sync,
321 Rows: 'a,
322 {
323 self.into_const().par_partition(count)
324 }
325
326 #[inline]
327 pub fn try_as_col_major(
329 self,
330 ) -> Option<ColRef<'a, T, Rows, ContiguousFwd>> {
331 self.into_const().try_as_col_major()
332 }
333
334 #[inline]
335 pub fn try_as_col_major_mut(
337 self,
338 ) -> Option<ColMut<'a, T, Rows, ContiguousFwd>> {
339 self.into_const()
340 .try_as_col_major()
341 .map(|x| unsafe { x.const_cast() })
342 }
343
344 #[inline(always)]
345 #[doc(hidden)]
346 pub unsafe fn const_cast(self) -> ColMut<'a, T, Rows, RStride> {
347 self
348 }
349
350 #[inline]
351 #[doc(hidden)]
352 pub fn bind_r<'N>(self, row: Guard<'N>) -> ColMut<'a, T, Dim<'N>, RStride> {
353 unsafe {
354 ColMut::from_raw_parts_mut(
355 self.as_ptr_mut(),
356 self.nrows().bind(row),
357 self.row_stride(),
358 )
359 }
360 }
361
362 #[inline]
363 pub fn as_mat(self) -> MatRef<'a, T, Rows, usize, RStride, isize> {
365 self.into_const().as_mat()
366 }
367
368 #[inline]
369 pub fn as_mat_mut(self) -> MatMut<'a, T, Rows, usize, RStride, isize> {
371 unsafe { self.into_const().as_mat().const_cast() }
372 }
373
374 #[inline]
375 pub fn as_diagonal(self) -> DiagRef<'a, T, Rows, RStride> {
377 DiagRef {
378 0: crate::diag::Ref {
379 inner: self.into_const(),
380 },
381 }
382 }
383}
384impl<
385 T,
386 Rows: Shape,
387 RStride: Stride,
388 Inner: for<'short> ReborrowMut<'short, Target = Mut<'short, T, Rows, RStride>>,
389> generic::Col<Inner>
390{
391 #[inline]
393 pub fn copy_from<RhsT: Conjugate<Canonical = T>>(
394 &mut self,
395 other: impl AsColRef<T = RhsT, Rows = Rows>,
396 ) where
397 T: ComplexField,
398 {
399 let other = other.as_col_ref();
400 let this = self.rb_mut();
401 assert!(all(
402 this.nrows() == other.nrows(),
403 this.ncols() == other.ncols(),
404 ));
405 let m = this.nrows();
406 with_dim!(M, m.unbound());
407 imp(
408 self.rb_mut().as_row_shape_mut(M).as_dyn_stride_mut(),
409 other.as_row_shape(M).canonical(),
410 Conj::get::<RhsT>(),
411 );
412 pub fn imp<'M, 'N, T: ComplexField>(
413 this: ColMut<'_, T, Dim<'M>>,
414 other: ColRef<'_, T, Dim<'M>>,
415 conj_: Conj,
416 ) {
417 match conj_ {
418 Conj::No => {
419 zip!(this, other)
420 .for_each(|unzip!(dst, src)| *dst = src.copy());
421 },
422 Conj::Yes => {
423 zip!(this, other)
424 .for_each(|unzip!(dst, src)| *dst = src.conj());
425 },
426 }
427 }
428 }
429
430 #[inline]
432 pub fn fill(&mut self, value: T)
433 where
434 T: Clone,
435 {
436 fn cloner<T: Clone>(
437 value: T,
438 ) -> impl for<'a> FnMut(crate::linalg::zip::Last<&'a mut T>) {
439 #[inline(always)]
440 move |x| *x.0 = value.clone()
441 }
442 z!(self.rb_mut().as_dyn_rows_mut()).for_each(cloner::<T>(value));
443 }
444
445 #[inline]
446 pub fn as_mut(&mut self) -> ColMut<'_, T, Rows, RStride> {
448 self.rb_mut()
449 }
450}
451impl<'a, T, Rows: Shape, RStride: Stride> ColMut<'a, T, Rows, RStride> {
452 #[inline(always)]
453 pub fn as_ptr_mut(&self) -> *mut T {
455 self.rb().as_ptr() as *mut T
456 }
457
458 #[inline(always)]
459 pub fn ptr_at_mut(&self, row: IdxInc<Rows>) -> *mut T {
461 self.rb().ptr_at(row) as *mut T
462 }
463
464 #[inline(always)]
465 #[track_caller]
466 pub unsafe fn ptr_inbounds_at_mut(&self, row: Idx<Rows>) -> *mut T {
468 self.rb().ptr_inbounds_at(row) as *mut T
469 }
470
471 #[inline]
472 #[track_caller]
473 pub fn split_at_row_mut(
475 self,
476 row: IdxInc<Rows>,
477 ) -> (ColMut<'a, T, usize, RStride>, ColMut<'a, T, usize, RStride>) {
478 let (a, b) = self.into_const().split_at_row(row);
479 unsafe { (a.const_cast(), b.const_cast()) }
480 }
481
482 #[inline(always)]
483 pub fn transpose_mut(self) -> RowMut<'a, T, Rows, RStride> {
485 unsafe { self.into_const().transpose().const_cast() }
486 }
487
488 #[inline(always)]
489 pub fn conjugate_mut(self) -> ColMut<'a, T::Conj, Rows, RStride>
491 where
492 T: Conjugate,
493 {
494 unsafe { self.into_const().conjugate().const_cast() }
495 }
496
497 #[inline(always)]
498 pub fn canonical_mut(self) -> ColMut<'a, T::Canonical, Rows, RStride>
500 where
501 T: Conjugate,
502 {
503 unsafe { self.into_const().canonical().const_cast() }
504 }
505
506 #[inline(always)]
507 pub fn adjoint_mut(self) -> RowMut<'a, T::Conj, Rows, RStride>
509 where
510 T: Conjugate,
511 {
512 unsafe { self.into_const().adjoint().const_cast() }
513 }
514
515 #[inline(always)]
516 #[track_caller]
517 pub(crate) fn at_mut(self, row: Idx<Rows>) -> &'a mut T {
518 assert!(all(row < self.nrows()));
519 unsafe { self.at_mut_unchecked(row) }
520 }
521
522 #[inline(always)]
523 #[track_caller]
524 pub(crate) unsafe fn at_mut_unchecked(self, row: Idx<Rows>) -> &'a mut T {
525 &mut *self.ptr_inbounds_at_mut(row)
526 }
527
528 #[track_caller]
529 #[inline(always)]
530 pub fn get_mut<RowRange>(
532 self,
533 row: RowRange,
534 ) -> <ColMut<'a, T, Rows, RStride> as ColIndex<RowRange>>::Target
535 where
536 ColMut<'a, T, Rows, RStride>: ColIndex<RowRange>,
537 {
538 <ColMut<'a, T, Rows, RStride> as ColIndex<RowRange>>::get(self, row)
539 }
540
541 #[track_caller]
542 #[inline(always)]
543 pub unsafe fn get_mut_unchecked<RowRange>(
545 self,
546 row: RowRange,
547 ) -> <ColMut<'a, T, Rows, RStride> as ColIndex<RowRange>>::Target
548 where
549 ColMut<'a, T, Rows, RStride>: ColIndex<RowRange>,
550 {
551 unsafe {
552 <ColMut<'a, T, Rows, RStride> as ColIndex<RowRange>>::get_unchecked(
553 self, row,
554 )
555 }
556 }
557
558 #[inline]
559 pub fn reverse_rows_mut(self) -> ColMut<'a, T, Rows, RStride::Rev> {
561 unsafe { self.into_const().reverse_rows().const_cast() }
562 }
563
564 #[inline]
565 #[track_caller]
566 pub fn subrows_mut<V: Shape>(
568 self,
569 row_start: IdxInc<Rows>,
570 nrows: V,
571 ) -> ColMut<'a, T, V, RStride> {
572 unsafe { self.into_const().subrows(row_start, nrows).const_cast() }
573 }
574
575 #[inline]
576 #[track_caller]
577 pub fn as_row_shape_mut<V: Shape>(
579 self,
580 nrows: V,
581 ) -> ColMut<'a, T, V, RStride> {
582 unsafe { self.into_const().as_row_shape(nrows).const_cast() }
583 }
584
585 #[inline]
586 pub fn as_dyn_rows_mut(self) -> ColMut<'a, T, usize, RStride> {
588 unsafe { self.into_const().as_dyn_rows().const_cast() }
589 }
590
591 #[inline]
592 pub fn as_dyn_stride_mut(self) -> ColMut<'a, T, Rows, isize> {
594 unsafe { self.into_const().as_dyn_stride().const_cast() }
595 }
596
597 #[inline]
598 pub fn iter_mut(
600 self,
601 ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a mut T>
602 where
603 Rows: 'a,
604 {
605 let this = self.into_const();
606 Rows::indices(Rows::start(), this.nrows().end())
607 .map(move |j| unsafe { this.const_cast().at_mut_unchecked(j) })
608 }
609
610 #[inline]
611 #[cfg(feature = "rayon")]
612 pub fn par_iter_mut(
614 self,
615 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a mut T>
616 where
617 T: Send,
618 Rows: 'a,
619 {
620 unsafe {
621 let this = self.as_type::<SyncCell<T>>().into_const();
622 use rayon::prelude::*;
623 (0..this.nrows().unbound()).into_par_iter().map(move |j| {
624 let ptr = this
625 .const_cast()
626 .at_mut_unchecked(Idx::<Rows>::new_unbound(j));
627 &mut *(ptr as *mut SyncCell<T> as *mut T)
628 })
629 }
630 }
631
632 #[inline]
633 #[track_caller]
634 #[cfg(feature = "rayon")]
635 pub fn par_partition_mut(
637 self,
638 count: usize,
639 ) -> impl 'a
640 + rayon::iter::IndexedParallelIterator<
641 Item = ColMut<'a, T, usize, RStride>,
642 >
643 where
644 T: Send,
645 Rows: 'a,
646 {
647 use rayon::prelude::*;
648 unsafe {
649 self.as_type::<SyncCell<T>>()
650 .into_const()
651 .par_partition(count)
652 .map(|col| col.const_cast().as_type::<T>())
653 }
654 }
655
656 pub(crate) unsafe fn as_type<U>(self) -> ColMut<'a, U, Rows, RStride> {
657 ColMut::from_raw_parts_mut(
658 self.as_ptr_mut() as *mut U,
659 self.nrows(),
660 self.row_stride(),
661 )
662 }
663
664 #[inline]
665 pub fn as_diagonal_mut(self) -> DiagMut<'a, T, Rows, RStride> {
667 DiagMut {
668 0: crate::diag::Mut { inner: self },
669 }
670 }
671
672 #[inline]
673 #[track_caller]
674 pub(crate) fn __at_mut(self, i: Idx<Rows>) -> &'a mut T {
675 self.at_mut(i)
676 }
677}
678impl<'a, T, Rows: Shape> ColMut<'a, T, Rows, ContiguousFwd> {
679 #[inline]
681 pub fn as_slice_mut(self) -> &'a mut [T] {
682 unsafe {
683 core::slice::from_raw_parts_mut(
684 self.as_ptr_mut(),
685 self.nrows().unbound(),
686 )
687 }
688 }
689}
690impl<'a, 'ROWS, T> ColMut<'a, T, Dim<'ROWS>, ContiguousFwd> {
691 #[inline]
693 pub fn as_array_mut(self) -> &'a mut Array<'ROWS, T> {
694 unsafe {
695 &mut *(self.as_slice_mut() as *mut [_] as *mut Array<'ROWS, T>)
696 }
697 }
698}
699impl<'ROWS, 'a, T, RStride: Stride> ColMut<'a, T, Dim<'ROWS>, RStride> {
700 #[doc(hidden)]
701 #[inline]
702 pub fn split_rows_with<'TOP, 'BOT>(
703 self,
704 row: Partition<'TOP, 'BOT, 'ROWS>,
705 ) -> (
706 ColRef<'a, T, Dim<'TOP>, RStride>,
707 ColRef<'a, T, Dim<'BOT>, RStride>,
708 ) {
709 let (a, b) = self.split_at_row(row.midpoint());
710 (a.as_row_shape(row.head), b.as_row_shape(row.tail))
711 }
712}
713impl<'ROWS, 'a, T, RStride: Stride> ColMut<'a, T, Dim<'ROWS>, RStride> {
714 #[doc(hidden)]
715 #[inline]
716 pub fn split_rows_with_mut<'TOP, 'BOT>(
717 self,
718 row: Partition<'TOP, 'BOT, 'ROWS>,
719 ) -> (
720 ColMut<'a, T, Dim<'TOP>, RStride>,
721 ColMut<'a, T, Dim<'BOT>, RStride>,
722 ) {
723 let (a, b) = self.split_at_row_mut(row.midpoint());
724 (a.as_row_shape_mut(row.head), b.as_row_shape_mut(row.tail))
725 }
726}
727impl<T: core::fmt::Debug, Rows: Shape, RStride: Stride> core::fmt::Debug
728 for Mut<'_, T, Rows, RStride>
729{
730 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
731 self.rb().fmt(f)
732 }
733}
734impl<'a, T, Rows: Shape> ColMut<'a, T, Rows>
735where
736 T: RealField,
737{
738 pub fn max(&self) -> Option<T> {
741 self.rb().as_dyn_rows().as_dyn_stride().internal_max()
742 }
743
744 pub fn min(&self) -> Option<T> {
747 self.rb().as_dyn_rows().as_dyn_stride().internal_min()
748 }
749}
750#[cfg(test)]
751mod tests {
752 use crate::Col;
753 #[test]
754 fn test_col_min() {
755 let mut col: Col<f64> = Col::from_fn(5, |x| (x + 1) as f64);
756 let colmut = col.as_mut();
757 assert_eq!(colmut.min(), Some(1.0));
758 let mut empty: Col<f64> = Col::from_fn(0, |_| 0.0);
759 let emptymut = empty.as_mut();
760 assert_eq!(emptymut.min(), None);
761 }
762 #[test]
763 fn test_col_max() {
764 let mut col: Col<f64> = Col::from_fn(5, |x| (x + 1) as f64);
765 let colmut = col.as_mut();
766 assert_eq!(colmut.max(), Some(5.0));
767 let mut empty: Col<f64> = Col::from_fn(0, |_| 0.0);
768 let emptymut = empty.as_mut();
769 assert_eq!(emptymut.max(), None);
770 }
771}