1use super::*;
2use crate::utils::bound::{Array, Dim, Partition};
3use crate::{ContiguousFwd, Idx, IdxInc};
4use equator::{assert, debug_assert};
5use faer_traits::Real;
6pub struct Ref<'a, T, Cols = usize, CStride = isize> {
8 pub(crate) trans: ColRef<'a, T, Cols, CStride>,
9}
10impl<T, Rows: Copy, CStride: Copy> Copy for Ref<'_, T, Rows, CStride> {}
11impl<T, Rows: Copy, CStride: Copy> Clone for Ref<'_, T, Rows, CStride> {
12 #[inline]
13 fn clone(&self) -> Self {
14 *self
15 }
16}
17impl<'short, T, Rows: Copy, CStride: Copy> Reborrow<'short>
18 for Ref<'_, T, Rows, CStride>
19{
20 type Target = Ref<'short, T, Rows, CStride>;
21
22 #[inline]
23 fn rb(&'short self) -> Self::Target {
24 *self
25 }
26}
27impl<'short, T, Rows: Copy, CStride: Copy> ReborrowMut<'short>
28 for Ref<'_, T, Rows, CStride>
29{
30 type Target = Ref<'short, T, Rows, CStride>;
31
32 #[inline]
33 fn rb_mut(&'short mut self) -> Self::Target {
34 *self
35 }
36}
37impl<'a, T, Rows: Copy, CStride: Copy> IntoConst for Ref<'a, T, Rows, CStride> {
38 type Target = Ref<'a, T, Rows, CStride>;
39
40 #[inline]
41 fn into_const(self) -> Self::Target {
42 self
43 }
44}
45unsafe impl<T: Sync, Rows: Sync, CStride: Sync> Sync
46 for Ref<'_, T, Rows, CStride>
47{
48}
49unsafe impl<T: Sync, Rows: Send, CStride: Send> Send
50 for Ref<'_, T, Rows, CStride>
51{
52}
53impl<'a, T> RowRef<'a, T> {
54 #[inline]
56 pub fn from_ref(value: &'a T) -> Self {
57 unsafe { RowRef::from_raw_parts(value as *const T, 1, 1) }
58 }
59
60 #[inline]
63 pub fn from_slice(slice: &'a [T]) -> Self {
64 let len = slice.len();
65 unsafe { Self::from_raw_parts(slice.as_ptr(), len, 1) }
66 }
67}
68impl<'a, T, Cols: Shape, CStride: Stride> RowRef<'a, T, Cols, CStride> {
69 #[inline(always)]
76 #[track_caller]
77 pub const unsafe fn from_raw_parts(
78 ptr: *const T,
79 ncols: Cols,
80 col_stride: CStride,
81 ) -> Self {
82 Self {
83 0: Ref {
84 trans: ColRef::from_raw_parts(ptr, ncols, col_stride),
85 },
86 }
87 }
88
89 #[inline(always)]
91 pub fn as_ptr(&self) -> *const T {
92 self.trans.as_ptr()
93 }
94
95 #[inline(always)]
97 pub fn nrows(&self) -> usize {
98 1
99 }
100
101 #[inline(always)]
103 pub fn ncols(&self) -> Cols {
104 self.trans.nrows()
105 }
106
107 #[inline(always)]
109 pub fn shape(&self) -> (usize, Cols) {
110 (self.nrows(), self.ncols())
111 }
112
113 #[inline(always)]
115 pub fn col_stride(&self) -> CStride {
116 self.trans.row_stride()
117 }
118
119 #[inline]
120 pub fn map<U>(&self, f: impl FnMut(&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(&self, f: impl FnMut(&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]
160 #[track_caller]
161 pub fn split_at_col(
162 self,
163 col: IdxInc<Cols>,
164 ) -> (RowRef<'a, T, usize, CStride>, RowRef<'a, T, usize, CStride>) {
165 assert!(all(col <= self.ncols()));
166 let rs = self.col_stride();
167 let top = self.as_ptr();
168 let bot = self.ptr_at(col);
169 unsafe {
170 (
171 RowRef::from_raw_parts(top, col.unbound(), rs),
172 RowRef::from_raw_parts(
173 bot,
174 self.ncols().unbound() - col.unbound(),
175 rs,
176 ),
177 )
178 }
179 }
180
181 #[inline(always)]
183 pub fn transpose(self) -> ColRef<'a, T, Cols, CStride> {
184 self.trans
185 }
186
187 #[inline(always)]
189 pub fn conjugate(self) -> RowRef<'a, T::Conj, Cols, CStride>
190 where
191 T: Conjugate,
192 {
193 RowRef {
194 0: Ref {
195 trans: self.trans.conjugate(),
196 },
197 }
198 }
199
200 #[inline(always)]
202 pub fn canonical(self) -> RowRef<'a, T::Canonical, Cols, CStride>
203 where
204 T: Conjugate,
205 {
206 RowRef {
207 0: Ref {
208 trans: self.trans.canonical(),
209 },
210 }
211 }
212
213 #[inline(always)]
215 pub fn adjoint(self) -> ColRef<'a, T::Conj, Cols, CStride>
216 where
217 T: Conjugate,
218 {
219 self.conjugate().transpose()
220 }
221
222 #[inline(always)]
223 #[track_caller]
224 pub(crate) fn at(self, col: Idx<Cols>) -> &'a T {
225 assert!(all(col < self.ncols()));
226 unsafe { self.at_unchecked(col) }
227 }
228
229 #[inline(always)]
230 #[track_caller]
231 pub(crate) unsafe fn at_unchecked(self, col: Idx<Cols>) -> &'a T {
232 &*self.ptr_inbounds_at(col)
233 }
234
235 #[track_caller]
242 #[inline(always)]
243 pub fn get<ColRange>(
244 self,
245 col: ColRange,
246 ) -> <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
247 where
248 RowRef<'a, T, Cols, CStride>: RowIndex<ColRange>,
249 {
250 <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::get(self, col)
251 }
252
253 #[track_caller]
261 #[inline(always)]
262 pub unsafe fn get_unchecked<ColRange>(
263 self,
264 col: ColRange,
265 ) -> <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::Target
266 where
267 RowRef<'a, T, Cols, CStride>: RowIndex<ColRange>,
268 {
269 unsafe {
270 <RowRef<'a, T, Cols, CStride> as RowIndex<ColRange>>::get_unchecked(
271 self, col,
272 )
273 }
274 }
275
276 #[inline]
278 pub fn reverse_cols(self) -> RowRef<'a, T, Cols, CStride::Rev> {
279 RowRef {
280 0: Ref {
281 trans: self.trans.reverse_rows(),
282 },
283 }
284 }
285
286 #[inline]
294 pub fn subcols<V: Shape>(
295 self,
296 col_start: IdxInc<Cols>,
297 ncols: V,
298 ) -> RowRef<'a, T, V, CStride> {
299 assert!(all(col_start <= self.ncols()));
300 {
301 let ncols = ncols.unbound();
302 let full_ncols = self.ncols().unbound();
303 let col_start = col_start.unbound();
304 assert!(all(ncols <= full_ncols - col_start));
305 }
306 let cs = self.col_stride();
307 unsafe { RowRef::from_raw_parts(self.ptr_at(col_start), ncols, cs) }
308 }
309
310 #[inline]
313 #[track_caller]
314 pub fn as_col_shape<V: Shape>(self, ncols: V) -> RowRef<'a, T, V, CStride> {
315 assert!(all(self.ncols().unbound() == ncols.unbound()));
316 unsafe {
317 RowRef::from_raw_parts(self.as_ptr(), ncols, self.col_stride())
318 }
319 }
320
321 #[inline]
323 pub fn as_dyn_cols(self) -> RowRef<'a, T, usize, CStride> {
324 unsafe {
325 RowRef::from_raw_parts(
326 self.as_ptr(),
327 self.ncols().unbound(),
328 self.col_stride(),
329 )
330 }
331 }
332
333 #[inline]
335 pub fn as_dyn_stride(self) -> RowRef<'a, T, Cols, isize> {
336 unsafe {
337 RowRef::from_raw_parts(
338 self.as_ptr(),
339 self.ncols(),
340 self.col_stride().element_stride(),
341 )
342 }
343 }
344
345 #[inline]
347 pub fn iter(
348 self,
349 ) -> impl 'a + ExactSizeIterator + DoubleEndedIterator<Item = &'a T>
350 where
351 Cols: 'a,
352 {
353 self.trans.iter()
354 }
355
356 #[inline]
358 #[cfg(feature = "rayon")]
359 pub fn par_iter(
360 self,
361 ) -> impl 'a + rayon::iter::IndexedParallelIterator<Item = &'a T>
362 where
363 T: Sync,
364 Cols: 'a,
365 {
366 self.trans.par_iter()
367 }
368
369 #[inline]
374 #[track_caller]
375 #[cfg(feature = "rayon")]
376 pub fn par_partition(
377 self,
378 count: usize,
379 ) -> impl 'a
380 + rayon::iter::IndexedParallelIterator<
381 Item = RowRef<'a, T, usize, CStride>,
382 >
383 where
384 T: Sync,
385 Cols: 'a,
386 {
387 use rayon::prelude::*;
388 self.transpose().par_partition(count).map(ColRef::transpose)
389 }
390
391 #[inline]
394 pub fn try_as_row_major(
395 self,
396 ) -> Option<RowRef<'a, T, Cols, ContiguousFwd>> {
397 if self.col_stride().element_stride() == 1 {
398 Some(unsafe {
399 RowRef::from_raw_parts(
400 self.as_ptr(),
401 self.ncols(),
402 ContiguousFwd,
403 )
404 })
405 } else {
406 None
407 }
408 }
409
410 #[inline(always)]
411 #[doc(hidden)]
412 pub unsafe fn const_cast(self) -> RowMut<'a, T, Cols, CStride> {
413 RowMut {
414 0: Mut {
415 trans: self.trans.const_cast(),
416 },
417 }
418 }
419
420 #[inline]
422 pub fn as_mat(self) -> MatRef<'a, T, usize, Cols, isize, CStride> {
423 self.transpose().as_mat().transpose()
424 }
425
426 #[inline]
428 pub fn as_diagonal(self) -> DiagRef<'a, T, Cols, CStride> {
429 DiagRef {
430 0: crate::diag::Ref { inner: self.trans },
431 }
432 }
433
434 #[inline]
435 pub(crate) fn __at(self, i: Idx<Cols>) -> &'a T {
436 self.at(i)
437 }
438}
439impl<
440 T,
441 Cols: Shape,
442 CStride: Stride,
443 Inner: for<'short> Reborrow<'short, Target = Ref<'short, T, Cols, CStride>>,
444> generic::Row<Inner>
445{
446 #[inline]
448 pub fn as_ref(&self) -> RowRef<'_, T, Cols, CStride> {
449 self.rb()
450 }
451
452 #[inline]
454 pub fn norm_max(&self) -> Real<T>
455 where
456 T: Conjugate,
457 {
458 self.rb().as_mat().norm_max()
459 }
460
461 #[inline]
463 pub fn norm_l2(&self) -> Real<T>
464 where
465 T: Conjugate,
466 {
467 self.rb().as_mat().norm_l2()
468 }
469
470 #[inline]
472 pub fn squared_norm_l2(&self) -> Real<T>
473 where
474 T: Conjugate,
475 {
476 self.rb().as_mat().squared_norm_l2()
477 }
478
479 #[inline]
481 pub fn norm_l1(&self) -> Real<T>
482 where
483 T: Conjugate,
484 {
485 self.rb().as_mat().norm_l1()
486 }
487
488 #[inline]
490 pub fn sum(&self) -> T::Canonical
491 where
492 T: Conjugate,
493 {
494 self.rb().as_mat().sum()
495 }
496
497 #[inline]
499 pub fn kron(
500 &self,
501 rhs: impl AsMatRef<T: Conjugate<Canonical = T::Canonical>>,
502 ) -> Mat<T::Canonical>
503 where
504 T: Conjugate,
505 {
506 fn imp<T: ComplexField>(
507 lhs: MatRef<impl Conjugate<Canonical = T>>,
508 rhs: MatRef<impl Conjugate<Canonical = T>>,
509 ) -> Mat<T> {
510 let mut out = Mat::zeros(
511 lhs.nrows() * rhs.nrows(),
512 lhs.ncols() * rhs.ncols(),
513 );
514 linalg::kron::kron(out.rb_mut(), lhs, rhs);
515 out
516 }
517 imp(
518 self.rb().as_mat().as_dyn().as_dyn_stride(),
519 rhs.as_mat_ref().as_dyn().as_dyn_stride(),
520 )
521 }
522
523 #[inline]
526 pub fn is_all_finite(&self) -> bool
527 where
528 T: Conjugate,
529 {
530 self.rb().transpose().is_all_finite()
531 }
532
533 #[inline]
536 pub fn has_nan(&self) -> bool
537 where
538 T: Conjugate,
539 {
540 self.rb().transpose().has_nan()
541 }
542
543 #[inline]
545 pub fn cloned(&self) -> Row<T, Cols>
546 where
547 T: Clone,
548 {
549 self.rb().transpose().cloned().into_transpose()
550 }
551
552 #[inline]
555 pub fn to_owned(&self) -> Row<T::Canonical, Cols>
556 where
557 T: Conjugate,
558 {
559 self.rb().transpose().to_owned().into_transpose()
560 }
561}
562impl<'a, T, Rows: Shape> RowRef<'a, T, Rows, ContiguousFwd> {
563 #[inline]
565 pub fn as_slice(self) -> &'a [T] {
566 self.transpose().as_slice()
567 }
568}
569impl<'a, 'ROWS, T> RowRef<'a, T, Dim<'ROWS>, ContiguousFwd> {
570 #[inline]
572 pub fn as_array(self) -> &'a Array<'ROWS, T> {
573 self.transpose().as_array()
574 }
575}
576impl<'COLS, 'a, T, CStride: Stride> RowRef<'a, T, Dim<'COLS>, CStride> {
577 #[doc(hidden)]
578 #[inline]
579 pub fn split_cols_with<'LEFT, 'RIGHT>(
580 self,
581 col: Partition<'LEFT, 'RIGHT, 'COLS>,
582 ) -> (
583 RowRef<'a, T, Dim<'LEFT>, CStride>,
584 RowRef<'a, T, Dim<'RIGHT>, CStride>,
585 ) {
586 let (a, b) = self.split_at_col(col.midpoint());
587 (a.as_col_shape(col.head), b.as_col_shape(col.tail))
588 }
589}
590impl<T: core::fmt::Debug, Cols: Shape, CStride: Stride> core::fmt::Debug
591 for Ref<'_, T, Cols, CStride>
592{
593 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
594 fn imp<T: core::fmt::Debug>(
595 f: &mut core::fmt::Formatter<'_>,
596 this: RowRef<'_, T, Dim<'_>>,
597 ) -> core::fmt::Result {
598 f.debug_list()
599 .entries(
600 this.ncols()
601 .indices()
602 .map(|j| crate::hacks::hijack_debug(this.at(j))),
603 )
604 .finish()
605 }
606 let this = generic::Row::from_inner_ref(self);
607 with_dim!(N, this.ncols().unbound());
608 imp(f, this.as_col_shape(N).as_dyn_stride())
609 }
610}
611impl<'a, T> RowRef<'a, T, usize, isize>
612where
613 T: RealField,
614{
615 pub(crate) fn internal_max(self) -> Option<T> {
617 if self.nrows().unbound() == 0 || self.ncols() == 0 {
618 return None;
619 }
620 let mut max_val = self.get(0);
621 self.iter().for_each(|val| {
622 if val > max_val {
623 max_val = val;
624 }
625 });
626 Some((*max_val).clone())
627 }
628
629 pub(crate) fn internal_min(self) -> Option<T> {
631 if self.nrows().unbound() == 0 || self.ncols() == 0 {
632 return None;
633 }
634 let mut min_val = self.get(0);
635 self.iter().for_each(|val| {
636 if val < min_val {
637 min_val = val;
638 }
639 });
640 Some((*min_val).clone())
641 }
642}
643impl<'a, T, Cols: Shape, CStride: Stride> RowRef<'a, T, Cols, CStride>
644where
645 T: RealField,
646{
647 pub fn max(&self) -> Option<T> {
649 self.as_dyn_cols().as_dyn_stride().internal_max()
650 }
651
652 pub fn min(&self) -> Option<T> {
654 self.as_dyn_cols().as_dyn_stride().internal_min()
655 }
656}
657#[cfg(test)]
658mod tests {
659 use crate::Row;
660 #[test]
661 fn test_row_min() {
662 let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
663 let rowref = row.as_ref();
664 assert_eq!(rowref.min(), Some(1.0));
665 let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
666 let emptyref = empty.as_ref();
667 assert_eq!(emptyref.min(), None);
668 }
669 #[test]
670 fn test_row_max() {
671 let row: Row<f64> = Row::from_fn(5, |x| (x + 1) as f64);
672 let rowref = row.as_ref();
673 assert_eq!(rowref.max(), Some(5.0));
674 let empty: Row<f64> = Row::from_fn(0, |_| 0.0);
675 let emptyref = empty.as_ref();
676 assert_eq!(emptyref.max(), None);
677 }
678}