1use super::*;
2use crate::utils::bound::{Array, Dim, Partition};
3use crate::{ContiguousFwd, Idx, IdxInc};
4use core::marker::PhantomData;
5use core::ptr::NonNull;
6use equator::assert;
7use faer_traits::Real;
8use generativity::Guard;
9pub struct Ref<'a, T, Rows = usize, RStride = isize> {
11 pub(super) imp: ColView<T, Rows, RStride>,
12 pub(super) __marker: PhantomData<&'a T>,
13}
14impl<T, Rows: Copy, RStride: Copy> Copy for Ref<'_, T, Rows, RStride> {}
15impl<T, Rows: Copy, RStride: Copy> Clone for Ref<'_, T, Rows, RStride> {
16 #[inline]
17 fn clone(&self) -> Self {
18 *self
19 }
20}
21impl<'short, T, Rows: Copy, RStride: Copy> Reborrow<'short>
22 for Ref<'_, T, Rows, RStride>
23{
24 type Target = Ref<'short, T, Rows, RStride>;
25
26 #[inline]
27 fn rb(&'short self) -> Self::Target {
28 *self
29 }
30}
31impl<'short, T, Rows: Copy, RStride: Copy> ReborrowMut<'short>
32 for Ref<'_, T, Rows, RStride>
33{
34 type Target = Ref<'short, T, Rows, RStride>;
35
36 #[inline]
37 fn rb_mut(&'short mut self) -> Self::Target {
38 *self
39 }
40}
41impl<'a, T, Rows: Copy, RStride: Copy> IntoConst for Ref<'a, T, Rows, RStride> {
42 type Target = Ref<'a, T, Rows, RStride>;
43
44 #[inline]
45 fn into_const(self) -> Self::Target {
46 self
47 }
48}
49unsafe impl<T: Sync, Rows: Sync, RStride: Sync> Sync
50 for Ref<'_, T, Rows, RStride>
51{
52}
53unsafe impl<T: Sync, Rows: Send, RStride: Send> Send
54 for Ref<'_, T, Rows, RStride>
55{
56}
57impl<'a, T> ColRef<'a, T> {
58 #[inline]
60 pub fn from_ref(value: &'a T) -> Self {
61 unsafe { ColRef::from_raw_parts(value as *const T, 1, 1) }
62 }
63
64 #[inline]
67 pub fn from_slice(slice: &'a [T]) -> Self {
68 let len = slice.len();
69 unsafe { Self::from_raw_parts(slice.as_ptr(), len, 1) }
70 }
71}
72impl<'a, T, Rows: Shape, RStride: Stride> ColRef<'a, T, Rows, RStride> {
73 #[inline(always)]
80 #[track_caller]
81 pub const unsafe fn from_raw_parts(
82 ptr: *const T,
83 nrows: Rows,
84 row_stride: RStride,
85 ) -> Self {
86 Self {
87 0: Ref {
88 imp: ColView {
89 ptr: NonNull::new_unchecked(ptr as *mut T),
90 nrows,
91 row_stride,
92 },
93 __marker: PhantomData,
94 },
95 }
96 }
97
98 #[inline(always)]
100 pub fn as_ptr(&self) -> *const T {
101 self.imp.ptr.as_ptr() as *const T
102 }
103
104 #[inline(always)]
106 pub fn nrows(&self) -> Rows {
107 self.imp.nrows
108 }
109
110 #[inline(always)]
112 pub fn ncols(&self) -> usize {
113 1
114 }
115
116 #[inline(always)]
118 pub fn shape(&self) -> (Rows, usize) {
119 (self.nrows(), self.ncols())
120 }
121
122 #[inline(always)]
125 pub fn row_stride(&self) -> RStride {
126 self.imp.row_stride
127 }
128
129 #[inline]
130 pub fn map<U>(&self, f: impl FnMut(&T) -> U) -> Col<U, Rows> {
131 let mut f = f;
132 zip!(self).map(|unzip!(x)| f(x))
133 }
134
135 #[inline]
136 pub fn for_each(&self, f: impl FnMut(&T)) {
137 let mut f = f;
138 zip!(self).for_each(|unzip!(x)| f(x))
139 }
140
141 #[inline(always)]
143 pub fn ptr_at(&self, row: IdxInc<Rows>) -> *const T {
144 let ptr = self.as_ptr();
145 if row >= self.nrows() {
146 ptr
147 } else {
148 ptr.wrapping_offset(
149 row.unbound() as isize * self.row_stride().element_stride(),
150 )
151 }
152 }
153
154 #[inline(always)]
162 #[track_caller]
163 pub unsafe fn ptr_inbounds_at(&self, row: Idx<Rows>) -> *const T {
164 self.as_ptr()
165 .offset(row.unbound() as isize * self.row_stride().element_stride())
166 }
167
168 #[inline]
177 #[track_caller]
178 pub fn split_at_row(
179 self,
180 row: IdxInc<Rows>,
181 ) -> (ColRef<'a, T, usize, RStride>, ColRef<'a, T, usize, RStride>) {
182 assert!(all(row <= self.nrows()));
183 let rs = self.row_stride();
184 let top = self.as_ptr();
185 let bot = self.ptr_at(row);
186 unsafe {
187 (
188 ColRef::from_raw_parts(top, row.unbound(), rs),
189 ColRef::from_raw_parts(
190 bot,
191 self.nrows().unbound() - row.unbound(),
192 rs,
193 ),
194 )
195 }
196 }
197
198 #[inline(always)]
200 pub fn transpose(self) -> RowRef<'a, T, Rows, RStride> {
201 RowRef {
202 0: crate::row::Ref { trans: self },
203 }
204 }
205
206 #[inline(always)]
208 pub fn conjugate(self) -> ColRef<'a, T::Conj, Rows, RStride>
209 where
210 T: Conjugate,
211 {
212 unsafe {
213 ColRef::from_raw_parts(
214 self.as_ptr() as *const T::Conj,
215 self.nrows(),
216 self.row_stride(),
217 )
218 }
219 }
220
221 #[inline(always)]
223 pub fn canonical(self) -> ColRef<'a, T::Canonical, Rows, RStride>
224 where
225 T: Conjugate,
226 {
227 unsafe {
228 ColRef::from_raw_parts(
229 self.as_ptr() as *const T::Canonical,
230 self.nrows(),
231 self.row_stride(),
232 )
233 }
234 }
235
236 #[inline(always)]
238 pub fn adjoint(self) -> RowRef<'a, T::Conj, Rows, RStride>
239 where
240 T: Conjugate,
241 {
242 self.conjugate().transpose()
243 }
244
245 #[inline(always)]
246 #[track_caller]
247 pub(crate) fn at(self, row: Idx<Rows>) -> &'a T {
248 assert!(all(row < self.nrows()));
249 unsafe { self.at_unchecked(row) }
250 }
251
252 #[inline(always)]
253 #[track_caller]
254 pub(crate) unsafe fn at_unchecked(self, row: Idx<Rows>) -> &'a T {
255 &*self.ptr_inbounds_at(row)
256 }
257
258 #[track_caller]
265 #[inline(always)]
266 pub fn get<RowRange>(
267 self,
268 row: RowRange,
269 ) -> <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::Target
270 where
271 ColRef<'a, T, Rows, RStride>: ColIndex<RowRange>,
272 {
273 <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::get(self, row)
274 }
275
276 #[track_caller]
284 #[inline(always)]
285 pub unsafe fn get_unchecked<RowRange>(
286 self,
287 row: RowRange,
288 ) -> <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::Target
289 where
290 ColRef<'a, T, Rows, RStride>: ColIndex<RowRange>,
291 {
292 unsafe {
293 <ColRef<'a, T, Rows, RStride> as ColIndex<RowRange>>::get_unchecked(
294 self, row,
295 )
296 }
297 }
298
299 #[inline]
301 pub fn reverse_rows(self) -> ColRef<'a, T, Rows, RStride::Rev> {
302 let row = unsafe {
303 IdxInc::<Rows>::new_unbound(
304 self.nrows().unbound().saturating_sub(1),
305 )
306 };
307 let ptr = self.ptr_at(row);
308 unsafe {
309 ColRef::from_raw_parts(ptr, self.nrows(), self.row_stride().rev())
310 }
311 }
312
313 #[inline]
321 #[track_caller]
322 pub fn subrows<V: Shape>(
323 self,
324 row_start: IdxInc<Rows>,
325 nrows: V,
326 ) -> ColRef<'a, T, V, RStride> {
327 assert!(all(row_start <= self.nrows()));
328 {
329 let nrows = nrows.unbound();
330 let full_nrows = self.nrows().unbound();
331 let row_start = row_start.unbound();
332 assert!(all(nrows <= full_nrows - row_start));
333 }
334 let rs = self.row_stride();
335 unsafe { ColRef::from_raw_parts(self.ptr_at(row_start), nrows, rs) }
336 }
337
338 #[inline]
341 #[track_caller]
342 pub fn as_row_shape<V: Shape>(self, nrows: V) -> ColRef<'a, T, V, RStride> {
343 assert!(all(self.nrows().unbound() == nrows.unbound()));
344 unsafe {
345 ColRef::from_raw_parts(self.as_ptr(), nrows, self.row_stride())
346 }
347 }
348
349 #[inline]
351 pub fn as_dyn_rows(self) -> ColRef<'a, T, usize, RStride> {
352 unsafe {
353 ColRef::from_raw_parts(
354 self.as_ptr(),
355 self.nrows().unbound(),
356 self.row_stride(),
357 )
358 }
359 }
360
361 #[inline]
363 pub fn as_dyn_stride(self) -> ColRef<'a, T, Rows, isize> {
364 unsafe {
365 ColRef::from_raw_parts(
366 self.as_ptr(),
367 self.nrows(),
368 self.row_stride().element_stride(),
369 )
370 }
371 }
372
373 #[inline]
375 pub fn iter(
376 self,
377 ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a T>
378 where
379 Rows: 'a,
380 {
381 Rows::indices(Rows::start(), self.nrows().end())
382 .map(move |j| unsafe { self.at_unchecked(j) })
383 }
384
385 #[inline]
387 #[cfg(feature = "rayon")]
388 pub fn par_iter(
389 self,
390 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a T>
391 where
392 T: Sync,
393 Rows: 'a,
394 {
395 use rayon::prelude::*;
396 (0..self.nrows().unbound())
397 .into_par_iter()
398 .map(move |j| unsafe {
399 self.at_unchecked(Idx::<Rows>::new_unbound(j))
400 })
401 }
402
403 #[inline]
408 #[track_caller]
409 #[cfg(feature = "rayon")]
410 pub fn par_partition(
411 self,
412 count: usize,
413 ) -> impl 'a
414 + rayon::iter::IndexedParallelIterator<
415 Item = ColRef<'a, T, usize, RStride>,
416 >
417 where
418 T: Sync,
419 Rows: 'a,
420 {
421 use rayon::prelude::*;
422 let this = self.as_dyn_rows();
423 assert!(count > 0);
424 (0..count).into_par_iter().map(move |chunk_idx| {
425 let (start, len) = crate::utils::thread::par_split_indices(
426 this.nrows(),
427 chunk_idx,
428 count,
429 );
430 this.subrows(start, len)
431 })
432 }
433
434 #[inline]
437 pub fn try_as_col_major(
438 self,
439 ) -> Option<ColRef<'a, T, Rows, ContiguousFwd>> {
440 if self.row_stride().element_stride() == 1 {
441 Some(unsafe {
442 ColRef::from_raw_parts(
443 self.as_ptr(),
444 self.nrows(),
445 ContiguousFwd,
446 )
447 })
448 } else {
449 None
450 }
451 }
452
453 #[inline(always)]
454 #[doc(hidden)]
455 pub unsafe fn const_cast(self) -> ColMut<'a, T, Rows, RStride> {
456 ColMut::from_raw_parts_mut(
457 self.as_ptr() as *mut T,
458 self.nrows(),
459 self.row_stride(),
460 )
461 }
462
463 #[inline]
465 pub fn as_mat(self) -> MatRef<'a, T, Rows, usize, RStride, isize> {
466 unsafe {
467 MatRef::from_raw_parts(
468 self.as_ptr(),
469 self.nrows(),
470 self.ncols(),
471 self.row_stride(),
472 0,
473 )
474 }
475 }
476
477 #[inline]
478 #[doc(hidden)]
479 pub fn bind_r<'N>(self, row: Guard<'N>) -> ColRef<'a, T, Dim<'N>, RStride> {
480 unsafe {
481 ColRef::from_raw_parts(
482 self.as_ptr(),
483 self.nrows().bind(row),
484 self.row_stride(),
485 )
486 }
487 }
488
489 #[inline]
490 #[track_caller]
491 pub(crate) fn __at(self, i: Idx<Rows>) -> &'a T {
492 self.at(i)
493 }
494
495 #[inline]
497 pub fn as_diagonal(self) -> DiagRef<'a, T, Rows, RStride> {
498 DiagRef {
499 0: crate::diag::Ref { inner: self },
500 }
501 }
502}
503impl<
504 T,
505 Rows: Shape,
506 RStride: Stride,
507 Inner: for<'short> Reborrow<'short, Target = Ref<'short, T, Rows, RStride>>,
508> generic::Col<Inner>
509{
510 #[inline]
512 pub fn cloned(&self) -> Col<T, Rows>
513 where
514 T: Clone,
515 {
516 fn imp<'M, T: Clone, RStride: Stride>(
517 this: ColRef<'_, T, Dim<'M>, RStride>,
518 ) -> Col<T, Dim<'M>> {
519 Col::from_fn(this.nrows(), |i| this.at(i).clone())
520 }
521 let this = self.rb();
522 with_dim!(M, this.nrows().unbound());
523 imp(this.as_row_shape(M)).into_row_shape(this.nrows())
524 }
525
526 #[inline]
529 pub fn to_owned(&self) -> Col<T::Canonical, Rows>
530 where
531 T: Conjugate,
532 {
533 fn imp<'M, T, RStride: Stride>(
534 this: ColRef<'_, T, Dim<'M>, RStride>,
535 ) -> Col<T::Canonical, Dim<'M>>
536 where
537 T: Conjugate,
538 {
539 Col::from_fn(this.nrows(), |i| Conj::apply::<T>(this.at(i)))
540 }
541 let this = self.rb();
542 with_dim!(M, this.nrows().unbound());
543 imp(this.as_row_shape(M)).into_row_shape(this.nrows())
544 }
545
546 #[inline]
548 pub fn norm_max(&self) -> Real<T>
549 where
550 T: Conjugate,
551 {
552 self.rb().as_mat().norm_max()
553 }
554
555 #[inline]
557 pub fn norm_l2(&self) -> Real<T>
558 where
559 T: Conjugate,
560 {
561 self.rb().as_mat().norm_l2()
562 }
563
564 #[inline]
566 pub fn squared_norm_l2(&self) -> Real<T>
567 where
568 T: Conjugate,
569 {
570 self.rb().as_mat().squared_norm_l2()
571 }
572
573 #[inline]
575 pub fn norm_l1(&self) -> Real<T>
576 where
577 T: Conjugate,
578 {
579 self.rb().as_mat().norm_l1()
580 }
581
582 #[inline]
584 pub fn sum(&self) -> T::Canonical
585 where
586 T: Conjugate,
587 {
588 self.rb().as_mat().sum()
589 }
590
591 #[inline]
593 pub fn as_ref(&self) -> ColRef<'_, T, Rows, RStride> {
594 self.rb()
595 }
596
597 #[inline]
599 pub fn kron(
600 &self,
601 rhs: impl AsMatRef<T: Conjugate<Canonical = T::Canonical>>,
602 ) -> Mat<T::Canonical>
603 where
604 T: Conjugate,
605 {
606 fn imp<T: ComplexField>(
607 lhs: MatRef<impl Conjugate<Canonical = T>>,
608 rhs: MatRef<impl Conjugate<Canonical = T>>,
609 ) -> Mat<T> {
610 let mut out = Mat::zeros(
611 lhs.nrows() * rhs.nrows(),
612 lhs.ncols() * rhs.ncols(),
613 );
614 linalg::kron::kron(out.rb_mut(), lhs, rhs);
615 out
616 }
617 imp(
618 self.rb().as_mat().as_dyn().as_dyn_stride(),
619 rhs.as_mat_ref().as_dyn().as_dyn_stride(),
620 )
621 }
622
623 #[inline]
626 pub fn is_all_finite(&self) -> bool
627 where
628 T: Conjugate,
629 {
630 fn imp<T: ComplexField>(A: ColRef<'_, T>) -> bool {
631 with_dim!({
632 let M = A.nrows();
633 });
634 let A = A.as_row_shape(M);
635 for i in M.indices() {
636 if !A[i].is_finite() {
637 return false;
638 }
639 }
640 true
641 }
642 imp(self.rb().as_dyn_rows().as_dyn_stride().canonical())
643 }
644
645 #[inline]
648 pub fn has_nan(&self) -> bool
649 where
650 T: Conjugate,
651 {
652 fn imp<T: ComplexField>(A: ColRef<'_, T>) -> bool {
653 with_dim!({
654 let M = A.nrows();
655 });
656 let A = A.as_row_shape(M);
657 for i in M.indices() {
658 if A[i].is_nan() {
659 return true;
660 }
661 }
662 false
663 }
664 imp(self.rb().as_dyn_rows().as_dyn_stride().canonical())
665 }
666}
667impl<'a, T, Rows: Shape> ColRef<'a, T, Rows, ContiguousFwd> {
668 #[inline]
670 pub fn as_slice(self) -> &'a [T] {
671 unsafe {
672 core::slice::from_raw_parts(self.as_ptr(), self.nrows().unbound())
673 }
674 }
675}
676impl<'a, 'ROWS, T> ColRef<'a, T, Dim<'ROWS>, ContiguousFwd> {
677 #[inline]
679 pub fn as_array(self) -> &'a Array<'ROWS, T> {
680 unsafe { &*(self.as_slice() as *const [_] as *const Array<'ROWS, T>) }
681 }
682}
683impl<'ROWS, 'a, T, RStride: Stride> ColRef<'a, T, Dim<'ROWS>, RStride> {
684 #[doc(hidden)]
685 #[inline]
686 pub fn split_rows_with<'TOP, 'BOT>(
687 self,
688 row: Partition<'TOP, 'BOT, 'ROWS>,
689 ) -> (
690 ColRef<'a, T, Dim<'TOP>, RStride>,
691 ColRef<'a, T, Dim<'BOT>, RStride>,
692 ) {
693 let (a, b) = self.split_at_row(row.midpoint());
694 (a.as_row_shape(row.head), b.as_row_shape(row.tail))
695 }
696}
697impl<T: core::fmt::Debug, Rows: Shape, RStride: Stride> core::fmt::Debug
698 for Ref<'_, T, Rows, RStride>
699{
700 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
701 generic::Col::from_inner_ref(self).transpose().fmt(f)
702 }
703}
704impl<'a, T> ColRef<'a, T, usize, isize>
705where
706 T: RealField,
707{
708 pub(crate) fn internal_max(self) -> Option<T> {
709 if self.nrows().unbound() == 0 || self.ncols() == 0 {
710 return None;
711 }
712 let mut max_val = self.get(0);
713 self.iter().for_each(|val| {
714 if val > max_val {
715 max_val = val;
716 }
717 });
718 Some((*max_val).clone())
719 }
720
721 pub(crate) fn internal_min(self) -> Option<T> {
724 if self.nrows().unbound() == 0 || self.ncols() == 0 {
725 return None;
726 }
727 let mut min_val = self.get(0);
728 self.iter().for_each(|val| {
729 if val < min_val {
730 min_val = val;
731 }
732 });
733 Some((*min_val).clone())
734 }
735}
736impl<'a, T, Rows: Shape, RStride: Stride> ColRef<'a, T, Rows, RStride>
737where
738 T: RealField,
739{
740 pub fn max(&self) -> Option<T> {
743 self.as_dyn_rows().as_dyn_stride().internal_max()
744 }
745
746 pub fn min(&self) -> Option<T> {
749 self.as_dyn_rows().as_dyn_stride().internal_min()
750 }
751}
752#[cfg(test)]
753mod tests {
754 use crate::Col;
755 #[test]
756 fn test_col_min() {
757 let col: Col<f64> = Col::from_fn(5, |x| (x + 1) as f64);
758 let colref = col.as_ref();
759 assert_eq!(colref.min(), Some(1.0));
760 let empty: Col<f64> = Col::from_fn(0, |_| 0.0);
761 let emptyref = empty.as_ref();
762 assert_eq!(emptyref.min(), None);
763 }
764 #[test]
765 fn test_col_max() {
766 let col: Col<f64> = Col::from_fn(5, |x| (x + 1) as f64);
767 let colref = col.as_ref();
768 assert_eq!(colref.max(), Some(5.0));
769 let empty: Col<f64> = Col::from_fn(0, |_| 0.0);
770 let emptyref = empty.as_ref();
771 assert_eq!(emptyref.max(), None);
772 }
773}