1use super::*;
2use crate::internal_prelude::*;
3use crate::{Idx, MaybeIdx, assert, debug_assert};
4use core::ops::Range;
5use core::{fmt, iter};
6pub mod symbolic {
8 #[doc(hidden)]
9 pub mod generic {
11 use core::fmt::Debug;
12 use reborrow::*;
13 #[derive(Copy, Clone)]
15 #[repr(transparent)]
16 pub struct SymbolicSparseRowMat<Inner>(pub Inner);
17 impl<Inner: Debug> Debug for SymbolicSparseRowMat<Inner> {
18 #[inline(always)]
19 fn fmt(
20 &self,
21 f: &mut core::fmt::Formatter<'_>,
22 ) -> core::fmt::Result {
23 self.0.fmt(f)
24 }
25 }
26 impl<Inner> SymbolicSparseRowMat<Inner> {
27 #[inline(always)]
29 pub fn from_inner_ref(inner: &Inner) -> &Self {
30 unsafe { &*(inner as *const Inner as *const Self) }
31 }
32
33 #[inline(always)]
35 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
36 unsafe { &mut *(inner as *mut Inner as *mut Self) }
37 }
38 }
39 impl<Inner> core::ops::Deref for SymbolicSparseRowMat<Inner> {
40 type Target = Inner;
41
42 #[inline(always)]
43 fn deref(&self) -> &Self::Target {
44 &self.0
45 }
46 }
47 impl<Inner> core::ops::DerefMut for SymbolicSparseRowMat<Inner> {
48 #[inline(always)]
49 fn deref_mut(&mut self) -> &mut Self::Target {
50 &mut self.0
51 }
52 }
53 impl<'short, Inner: Reborrow<'short>> Reborrow<'short>
54 for SymbolicSparseRowMat<Inner>
55 {
56 type Target = SymbolicSparseRowMat<Inner::Target>;
57
58 #[inline(always)]
59 fn rb(&'short self) -> Self::Target {
60 SymbolicSparseRowMat(self.0.rb())
61 }
62 }
63 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short>
64 for SymbolicSparseRowMat<Inner>
65 {
66 type Target = SymbolicSparseRowMat<Inner::Target>;
67
68 #[inline(always)]
69 fn rb_mut(&'short mut self) -> Self::Target {
70 SymbolicSparseRowMat(self.0.rb_mut())
71 }
72 }
73 impl<Inner: IntoConst> IntoConst for SymbolicSparseRowMat<Inner> {
74 type Target = SymbolicSparseRowMat<Inner::Target>;
75
76 #[inline(always)]
77 fn into_const(self) -> Self::Target {
78 SymbolicSparseRowMat(self.0.into_const())
79 }
80 }
81 }
82 pub struct Ref<'a, I, Rows = usize, Cols = usize> {
84 pub(crate) nrows: Rows,
85 pub(crate) ncols: Cols,
86 pub(crate) row_ptr: &'a [I],
87 pub(crate) row_nnz: Option<&'a [I]>,
88 pub(crate) col_idx: &'a [I],
89 }
90 #[derive(Clone)]
92 pub struct Own<I, Rows = usize, Cols = usize> {
93 pub(crate) nrows: Rows,
94 pub(crate) ncols: Cols,
95 pub(crate) row_ptr: alloc::vec::Vec<I>,
96 pub(crate) row_nnz: Option<alloc::vec::Vec<I>>,
97 pub(crate) col_idx: alloc::vec::Vec<I>,
98 }
99}
100pub mod numeric {
102 #[doc(hidden)]
103 pub mod generic {
105 use core::fmt::Debug;
106 use reborrow::*;
107 #[derive(Copy, Clone)]
109 #[repr(transparent)]
110 pub struct SparseRowMat<Inner>(pub Inner);
111 impl<Inner: Debug> Debug for SparseRowMat<Inner> {
112 #[inline(always)]
113 fn fmt(
114 &self,
115 f: &mut core::fmt::Formatter<'_>,
116 ) -> core::fmt::Result {
117 self.0.fmt(f)
118 }
119 }
120 impl<Inner> SparseRowMat<Inner> {
121 #[inline(always)]
123 pub fn from_inner_ref(inner: &Inner) -> &Self {
124 unsafe { &*(inner as *const Inner as *const Self) }
125 }
126
127 #[inline(always)]
129 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
130 unsafe { &mut *(inner as *mut Inner as *mut Self) }
131 }
132 }
133 impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for SparseRowMat<Inner> {
134 type Target = SparseRowMat<Inner::Target>;
135
136 #[inline(always)]
137 fn rb(&'short self) -> Self::Target {
138 SparseRowMat(self.0.rb())
139 }
140 }
141 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short>
142 for SparseRowMat<Inner>
143 {
144 type Target = SparseRowMat<Inner::Target>;
145
146 #[inline(always)]
147 fn rb_mut(&'short mut self) -> Self::Target {
148 SparseRowMat(self.0.rb_mut())
149 }
150 }
151 impl<Inner: IntoConst> IntoConst for SparseRowMat<Inner> {
152 type Target = SparseRowMat<Inner::Target>;
153
154 #[inline(always)]
155 fn into_const(self) -> Self::Target {
156 SparseRowMat(self.0.into_const())
157 }
158 }
159 }
160 pub struct Ref<'a, I, T, Rows = usize, Cols = usize> {
162 pub(crate) symbolic: super::SymbolicSparseRowMatRef<'a, I, Rows, Cols>,
163 pub(crate) val: &'a [T],
164 }
165 pub struct Mut<'a, I, T, Rows = usize, Cols = usize> {
167 pub(crate) symbolic: super::SymbolicSparseRowMatRef<'a, I, Rows, Cols>,
168 pub(crate) val: &'a mut [T],
169 }
170 #[derive(Clone)]
172 pub struct Own<I, T, Rows = usize, Cols = usize> {
173 pub(crate) symbolic: super::SymbolicSparseRowMat<I, Rows, Cols>,
174 pub(crate) val: alloc::vec::Vec<T>,
175 }
176}
177pub type SymbolicSparseRowMatRef<'a, I, Rows = usize, Cols = usize> =
204 symbolic::generic::SymbolicSparseRowMat<symbolic::Ref<'a, I, Rows, Cols>>;
205pub type SymbolicSparseRowMat<I, Rows = usize, Cols = usize> =
210 symbolic::generic::SymbolicSparseRowMat<symbolic::Own<I, Rows, Cols>>;
211pub type SparseRowMatRef<'a, I, T, Rows = usize, Cols = usize> =
215 numeric::generic::SparseRowMat<numeric::Ref<'a, I, T, Rows, Cols>>;
216pub type SparseRowMatMut<'a, I, T, Rows = usize, Cols = usize> =
220 numeric::generic::SparseRowMat<numeric::Mut<'a, I, T, Rows, Cols>>;
221pub type SparseRowMat<I, T, Rows = usize, Cols = usize> =
225 numeric::generic::SparseRowMat<numeric::Own<I, T, Rows, Cols>>;
226impl<'a, I, Rows: Copy, Cols: Copy> Copy for symbolic::Ref<'a, I, Rows, Cols> {}
227impl<'a, I, T, Rows: Copy, Cols: Copy> Copy
228 for numeric::Ref<'a, I, T, Rows, Cols>
229{
230}
231impl<'a, I, Rows: Copy, Cols: Copy> Clone for symbolic::Ref<'a, I, Rows, Cols> {
232 #[inline]
233 fn clone(&self) -> Self {
234 *self
235 }
236}
237impl<'a, I, T, Rows: Copy, Cols: Copy> Clone
238 for numeric::Ref<'a, I, T, Rows, Cols>
239{
240 #[inline]
241 fn clone(&self) -> Self {
242 *self
243 }
244}
245impl<'a, I, Rows: Copy, Cols: Copy> IntoConst
246 for symbolic::Ref<'a, I, Rows, Cols>
247{
248 type Target = symbolic::Ref<'a, I, Rows, Cols>;
249
250 #[inline]
251 fn into_const(self) -> Self::Target {
252 self
253 }
254}
255impl<'short, 'a, I, Rows: Copy, Cols: Copy> ReborrowMut<'short>
256 for symbolic::Ref<'a, I, Rows, Cols>
257{
258 type Target = symbolic::Ref<'short, I, Rows, Cols>;
259
260 #[inline]
261 fn rb_mut(&'short mut self) -> Self::Target {
262 *self
263 }
264}
265impl<'short, 'a, I, Rows: Copy, Cols: Copy> Reborrow<'short>
266 for symbolic::Ref<'a, I, Rows, Cols>
267{
268 type Target = symbolic::Ref<'short, I, Rows, Cols>;
269
270 #[inline]
271 fn rb(&'short self) -> Self::Target {
272 *self
273 }
274}
275impl<'a, I, T, Rows: Copy, Cols: Copy> IntoConst
276 for numeric::Ref<'a, I, T, Rows, Cols>
277{
278 type Target = numeric::Ref<'a, I, T, Rows, Cols>;
279
280 #[inline]
281 fn into_const(self) -> Self::Target {
282 self
283 }
284}
285impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short>
286 for numeric::Ref<'a, I, T, Rows, Cols>
287{
288 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
289
290 #[inline]
291 fn rb_mut(&'short mut self) -> Self::Target {
292 *self
293 }
294}
295impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> Reborrow<'short>
296 for numeric::Ref<'a, I, T, Rows, Cols>
297{
298 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
299
300 #[inline]
301 fn rb(&'short self) -> Self::Target {
302 *self
303 }
304}
305impl<'a, I, T, Rows: Copy, Cols: Copy> IntoConst
306 for numeric::Mut<'a, I, T, Rows, Cols>
307{
308 type Target = numeric::Ref<'a, I, T, Rows, Cols>;
309
310 #[inline]
311 fn into_const(self) -> Self::Target {
312 numeric::Ref {
313 symbolic: self.symbolic,
314 val: self.val,
315 }
316 }
317}
318impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short>
319 for numeric::Mut<'a, I, T, Rows, Cols>
320{
321 type Target = numeric::Mut<'short, I, T, Rows, Cols>;
322
323 #[inline]
324 fn rb_mut(&'short mut self) -> Self::Target {
325 numeric::Mut {
326 symbolic: self.symbolic,
327 val: self.val,
328 }
329 }
330}
331impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> Reborrow<'short>
332 for numeric::Mut<'a, I, T, Rows, Cols>
333{
334 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
335
336 #[inline]
337 fn rb(&'short self) -> Self::Target {
338 numeric::Ref {
339 symbolic: self.symbolic,
340 val: self.val,
341 }
342 }
343}
344impl<'short, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short>
345 for numeric::Own<I, T, Rows, Cols>
346{
347 type Target = numeric::Mut<'short, I, T, Rows, Cols>;
348
349 #[inline]
350 fn rb_mut(&'short mut self) -> Self::Target {
351 numeric::Mut {
352 symbolic: self.symbolic.rb(),
353 val: &mut self.val,
354 }
355 }
356}
357impl<'short, I, T, Rows: Copy, Cols: Copy> Reborrow<'short>
358 for numeric::Own<I, T, Rows, Cols>
359{
360 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
361
362 #[inline]
363 fn rb(&'short self) -> Self::Target {
364 numeric::Ref {
365 symbolic: self.symbolic.rb(),
366 val: &self.val,
367 }
368 }
369}
370impl<'short, I, Rows: Copy, Cols: Copy> Reborrow<'short>
371 for symbolic::Own<I, Rows, Cols>
372{
373 type Target = symbolic::Ref<'short, I, Rows, Cols>;
374
375 #[inline]
376 fn rb(&'short self) -> Self::Target {
377 symbolic::Ref {
378 nrows: self.nrows,
379 ncols: self.ncols,
380 row_ptr: &self.row_ptr,
381 row_nnz: self.row_nnz.as_deref(),
382 col_idx: &self.col_idx,
383 }
384 }
385}
386#[inline(always)]
387#[track_caller]
388fn assume_row_ptr<I: Index>(
389 nrows: usize,
390 ncols: usize,
391 row_ptr: &[I],
392 row_nnz: Option<&[I]>,
393 col_idx: &[I],
394) {
395 assert!(all(
396 ncols <= I::Signed::MAX.zx(),
397 nrows <= I::Signed::MAX.zx(),
398 ));
399 assert!(row_ptr.len() == nrows + 1);
400 assert!(row_ptr[nrows].zx() <= col_idx.len());
401 if let Some(row_nnz) = row_nnz {
402 assert!(row_nnz.len() == nrows);
403 }
404}
405#[track_caller]
406fn check_row_ptr<I: Index>(
407 nrows: usize,
408 ncols: usize,
409 row_ptr: &[I],
410 row_nnz: Option<&[I]>,
411 col_idx: &[I],
412) {
413 assert!(all(
414 ncols <= I::Signed::MAX.zx(),
415 nrows <= I::Signed::MAX.zx(),
416 ));
417 assert!(row_ptr.len() == nrows + 1);
418 if let Some(row_nnz) = row_nnz {
419 assert!(row_nnz.len() == nrows);
420 for (&nnz_i, &[row, row_next]) in iter::zip(row_nnz, windows2(row_ptr))
421 {
422 assert!(row <= row_next);
423 assert!(nnz_i <= row_next - row);
424 }
425 } else {
426 for &[row, row_next] in windows2(row_ptr) {
427 assert!(row <= row_next);
428 }
429 }
430 assert!(row_ptr[nrows].zx() <= col_idx.len());
431}
432#[track_caller]
433fn check_col_idx<I: Index>(
434 nrows: usize,
435 ncols: usize,
436 row_ptr: &[I],
437 row_nnz: Option<&[I]>,
438 col_idx: &[I],
439) {
440 _ = nrows;
441 if let Some(row_nnz) = row_nnz {
442 for (nnz, &r) in iter::zip(row_nnz, row_ptr) {
443 let r = r.zx();
444 let nnz = nnz.zx();
445 let col_idx = &col_idx[r..r + nnz];
446 if !col_idx.is_empty() {
447 let mut j = col_idx[0].zx();
448 for &j_next in &col_idx[1..] {
449 let j_next = j_next.zx();
450 assert!(j < j_next);
451 j = j_next;
452 }
453 assert!(j < ncols);
454 }
455 }
456 } else {
457 for &[r, r_next] in windows2(row_ptr) {
458 let col_idx = &col_idx[r.zx()..r_next.zx()];
459 if !col_idx.is_empty() {
460 let mut j = col_idx[0].zx();
461 for &j_next in &col_idx[1..] {
462 let j_next = j_next.zx();
463 assert!(j < j_next);
464 j = j_next;
465 }
466 assert!(j < ncols);
467 }
468 }
469 }
470}
471#[track_caller]
472fn check_col_idx_unsorted<I: Index>(
473 nrows: usize,
474 ncols: usize,
475 row_ptr: &[I],
476 row_nnz: Option<&[I]>,
477 col_idx: &[I],
478) {
479 _ = nrows;
480 if let Some(row_nnz) = row_nnz {
481 for (&nnz, &r) in iter::zip(row_nnz, row_ptr) {
482 let r = r.zx();
483 let nnz = nnz.zx();
484 for &j in &col_idx[r..r + nnz] {
485 let j = j.zx();
486 assert!(j < ncols);
487 }
488 }
489 } else {
490 for &[r, r_next] in windows2(row_ptr) {
491 for &j in &col_idx[r.zx()..r_next.zx()] {
492 let j = j.zx();
493 assert!(j < ncols);
494 }
495 }
496 }
497}
498impl<'a, Rows: Shape, Cols: Shape, I: Index>
499 SymbolicSparseRowMatRef<'a, I, Rows, Cols>
500{
501 #[inline]
506 #[track_caller]
507 pub unsafe fn new_unchecked(
508 nrows: Rows,
509 ncols: Cols,
510 row_ptr: &'a [I],
511 row_nnz: Option<&'a [I]>,
512 col_idx: &'a [I],
513 ) -> Self {
514 assume_row_ptr(
515 nrows.unbound(),
516 ncols.unbound(),
517 row_ptr,
518 row_nnz,
519 col_idx,
520 );
521 Self {
522 0: symbolic::Ref {
523 nrows,
524 ncols,
525 row_ptr,
526 row_nnz,
527 col_idx,
528 },
529 }
530 }
531
532 #[inline]
537 #[track_caller]
538 pub fn new_checked(
539 nrows: Rows,
540 ncols: Cols,
541 row_ptr: &'a [I],
542 row_nnz: Option<&'a [I]>,
543 col_idx: &'a [I],
544 ) -> Self {
545 check_row_ptr(
546 nrows.unbound(),
547 ncols.unbound(),
548 row_ptr,
549 row_nnz,
550 col_idx,
551 );
552 check_col_idx(
553 nrows.unbound(),
554 ncols.unbound(),
555 row_ptr,
556 row_nnz,
557 col_idx,
558 );
559 Self {
560 0: symbolic::Ref {
561 nrows,
562 ncols,
563 row_ptr,
564 row_nnz,
565 col_idx,
566 },
567 }
568 }
569
570 #[inline]
576 #[track_caller]
577 pub fn new_unsorted_checked(
578 nrows: Rows,
579 ncols: Cols,
580 row_ptr: &'a [I],
581 row_nnz: Option<&'a [I]>,
582 col_idx: &'a [I],
583 ) -> Self {
584 check_row_ptr(
585 nrows.unbound(),
586 ncols.unbound(),
587 row_ptr,
588 row_nnz,
589 col_idx,
590 );
591 check_col_idx_unsorted(
592 nrows.unbound(),
593 ncols.unbound(),
594 row_ptr,
595 row_nnz,
596 col_idx,
597 );
598 Self {
599 0: symbolic::Ref {
600 nrows,
601 ncols,
602 row_ptr,
603 row_nnz,
604 col_idx,
605 },
606 }
607 }
608
609 #[inline]
616 pub fn parts(self) -> (Rows, Cols, &'a [I], Option<&'a [I]>, &'a [I]) {
617 (
618 self.nrows,
619 self.ncols,
620 self.0.row_ptr,
621 self.0.row_nnz,
622 self.0.col_idx,
623 )
624 }
625
626 #[inline]
628 pub fn nrows(&self) -> Rows {
629 self.nrows
630 }
631
632 #[inline]
634 pub fn ncols(&self) -> Cols {
635 self.ncols
636 }
637
638 #[inline]
640 pub fn shape(&self) -> (Rows, Cols) {
641 (self.nrows, self.ncols)
642 }
643
644 #[inline]
646 pub fn transpose(self) -> SymbolicSparseColMatRef<'a, I, Cols, Rows> {
647 SymbolicSparseColMatRef {
648 0: super::csc::symbolic::Ref {
649 nrows: self.ncols,
650 ncols: self.nrows,
651 col_ptr: self.0.row_ptr,
652 col_nnz: self.0.row_nnz,
653 row_idx: self.0.col_idx,
654 },
655 }
656 }
657
658 #[inline]
660 pub fn to_owned(
661 &self,
662 ) -> Result<SymbolicSparseRowMat<I, Rows, Cols>, FaerError> {
663 Ok(self.transpose().to_owned()?.into_transpose())
664 }
665
666 #[inline]
669 pub fn to_col_major(
670 &self,
671 ) -> Result<SymbolicSparseColMat<I, Rows, Cols>, FaerError> {
672 Ok(self.transpose().to_row_major()?.into_transpose())
673 }
674
675 #[inline]
677 pub fn compute_nnz(&self) -> usize {
678 self.transpose().compute_nnz()
679 }
680
681 #[inline]
683 pub fn row_ptr(&self) -> &'a [I] {
684 self.0.row_ptr
685 }
686
687 #[inline]
689 pub fn row_nnz(&self) -> Option<&'a [I]> {
690 self.0.row_nnz
691 }
692
693 #[inline]
695 pub fn col_idx(&self) -> &'a [I] {
696 self.0.col_idx
697 }
698
699 #[inline]
701 #[track_caller]
702 pub fn row_range(&self, i: Idx<Rows>) -> Range<usize> {
703 assert!(i < self.nrows());
704 unsafe { self.row_range_unchecked(i) }
705 }
706
707 #[inline]
710 #[track_caller]
711 pub unsafe fn row_range_unchecked(&self, i: Idx<Rows>) -> Range<usize> {
712 debug_assert!(i < self.nrows());
713 self.transpose().col_range_unchecked(i)
714 }
715
716 #[inline]
718 #[track_caller]
719 pub fn col_idx_of_row_raw(&self, i: Idx<Rows>) -> &'a [Idx<Cols, I>] {
720 unsafe {
721 let slice = self.0.col_idx.get_unchecked(self.row_range(i));
722 let len = slice.len();
723 core::slice::from_raw_parts(
724 slice.as_ptr() as *const Idx<Cols, I>,
725 len,
726 )
727 }
728 }
729
730 #[inline]
732 #[track_caller]
733 pub fn col_idx_of_row(
734 &self,
735 i: Idx<Rows>,
736 ) -> impl 'a + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Cols>>
737 where
738 Rows: 'a,
739 Cols: 'a,
740 {
741 self.col_idx_of_row_raw(i)
742 .iter()
743 .map(|&j| unsafe { Idx::<Cols>::new_unbound(j.unbound().zx()) })
744 }
745
746 #[inline]
749 #[track_caller]
750 pub fn as_shape<V: Shape, H: Shape>(
751 self,
752 nrows: V,
753 ncols: H,
754 ) -> SymbolicSparseRowMatRef<'a, I, V, H> {
755 assert!(all(
756 self.nrows.unbound() == nrows.unbound(),
757 self.ncols.unbound() == ncols.unbound()
758 ));
759 SymbolicSparseRowMatRef {
760 0: symbolic::Ref {
761 nrows,
762 ncols,
763 row_ptr: self.0.row_ptr,
764 row_nnz: self.0.row_nnz,
765 col_idx: self.0.col_idx,
766 },
767 }
768 }
769
770 #[inline]
772 pub fn as_dyn(self) -> SymbolicSparseRowMatRef<'a, I> {
773 SymbolicSparseRowMatRef {
774 0: symbolic::Ref {
775 nrows: self.nrows.unbound(),
776 ncols: self.ncols.unbound(),
777 row_ptr: self.0.row_ptr,
778 row_nnz: self.0.row_nnz,
779 col_idx: self.0.col_idx,
780 },
781 }
782 }
783
784 #[inline]
786 pub fn as_ref(self) -> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
787 SymbolicSparseRowMatRef {
788 0: symbolic::Ref {
789 nrows: self.nrows,
790 ncols: self.ncols,
791 row_ptr: self.0.row_ptr,
792 row_nnz: self.0.row_nnz,
793 col_idx: self.0.col_idx,
794 },
795 }
796 }
797}
798impl<Rows: Shape, Cols: Shape, I: Index> SymbolicSparseRowMat<I, Rows, Cols> {
799 #[inline]
800 #[track_caller]
801 pub unsafe fn new_unchecked(
803 nrows: Rows,
804 ncols: Cols,
805 row_ptr: alloc::vec::Vec<I>,
806 row_nnz: Option<alloc::vec::Vec<I>>,
807 col_idx: alloc::vec::Vec<I>,
808 ) -> Self {
809 assume_row_ptr(
810 nrows.unbound(),
811 ncols.unbound(),
812 &row_ptr,
813 row_nnz.as_deref(),
814 &col_idx,
815 );
816 Self {
817 0: symbolic::Own {
818 nrows,
819 ncols,
820 row_ptr,
821 row_nnz,
822 col_idx,
823 },
824 }
825 }
826
827 #[inline]
828 #[track_caller]
829 pub fn new_checked(
831 nrows: Rows,
832 ncols: Cols,
833 row_ptr: alloc::vec::Vec<I>,
834 row_nnz: Option<alloc::vec::Vec<I>>,
835 col_idx: alloc::vec::Vec<I>,
836 ) -> Self {
837 check_row_ptr(
838 nrows.unbound(),
839 ncols.unbound(),
840 &row_ptr,
841 row_nnz.as_deref(),
842 &col_idx,
843 );
844 check_col_idx(
845 nrows.unbound(),
846 ncols.unbound(),
847 &row_ptr,
848 row_nnz.as_deref(),
849 &col_idx,
850 );
851 Self {
852 0: symbolic::Own {
853 nrows,
854 ncols,
855 row_ptr,
856 row_nnz,
857 col_idx,
858 },
859 }
860 }
861
862 #[inline]
863 #[track_caller]
864 pub fn new_unsorted_checked(
866 nrows: Rows,
867 ncols: Cols,
868 row_ptr: alloc::vec::Vec<I>,
869 row_nnz: Option<alloc::vec::Vec<I>>,
870 col_idx: alloc::vec::Vec<I>,
871 ) -> Self {
872 check_row_ptr(
873 nrows.unbound(),
874 ncols.unbound(),
875 &row_ptr,
876 row_nnz.as_deref(),
877 &col_idx,
878 );
879 check_col_idx_unsorted(
880 nrows.unbound(),
881 ncols.unbound(),
882 &row_ptr,
883 row_nnz.as_deref(),
884 &col_idx,
885 );
886 Self {
887 0: symbolic::Own {
888 nrows,
889 ncols,
890 row_ptr,
891 row_nnz,
892 col_idx,
893 },
894 }
895 }
896
897 #[inline]
898 pub fn parts(&self) -> (Rows, Cols, &'_ [I], Option<&'_ [I]>, &'_ [I]) {
900 (
901 self.nrows,
902 self.ncols,
903 &self.0.row_ptr,
904 self.0.row_nnz.as_deref(),
905 &self.0.col_idx,
906 )
907 }
908
909 #[inline]
910 pub fn into_parts(
912 self,
913 ) -> (
914 Rows,
915 Cols,
916 alloc::vec::Vec<I>,
917 Option<alloc::vec::Vec<I>>,
918 alloc::vec::Vec<I>,
919 ) {
920 (
921 self.nrows,
922 self.ncols,
923 self.0.row_ptr,
924 self.0.row_nnz,
925 self.0.col_idx,
926 )
927 }
928
929 #[inline]
930 pub fn nrows(&self) -> Rows {
932 self.nrows
933 }
934
935 #[inline]
936 pub fn ncols(&self) -> Cols {
938 self.ncols
939 }
940
941 #[inline]
942 pub fn shape(&self) -> (Rows, Cols) {
944 (self.nrows, self.ncols)
945 }
946
947 #[inline]
948 pub fn transpose(&self) -> SymbolicSparseColMatRef<'_, I, Cols, Rows> {
950 self.rb().transpose()
951 }
952
953 #[inline]
954 pub fn into_transpose(self) -> SymbolicSparseColMat<I, Cols, Rows> {
956 SymbolicSparseColMat {
957 0: super::csc::symbolic::Own {
958 nrows: self.ncols,
959 ncols: self.nrows,
960 col_ptr: self.0.row_ptr,
961 col_nnz: self.0.row_nnz,
962 row_idx: self.0.col_idx,
963 },
964 }
965 }
966
967 #[inline]
968 pub fn to_owned(
970 &self,
971 ) -> Result<SymbolicSparseRowMat<I, Rows, Cols>, FaerError> {
972 self.rb().to_owned()
973 }
974
975 #[inline]
976 pub fn to_col_major(
978 &self,
979 ) -> Result<SymbolicSparseColMat<I, Rows, Cols>, FaerError> {
980 self.rb().to_col_major()
981 }
982
983 #[inline]
984 pub fn compute_nnz(&self) -> usize {
986 self.rb().compute_nnz()
987 }
988
989 #[inline]
990 pub fn row_ptr(&self) -> &'_ [I] {
992 &self.0.row_ptr
993 }
994
995 #[inline]
996 pub fn row_nnz(&self) -> Option<&'_ [I]> {
998 self.0.row_nnz.as_deref()
999 }
1000
1001 #[inline]
1002 pub fn col_idx(&self) -> &'_ [I] {
1004 &self.0.col_idx
1005 }
1006
1007 #[inline]
1008 #[track_caller]
1009 pub fn row_range(&self, i: Idx<Rows>) -> Range<usize> {
1011 self.rb().row_range(i)
1012 }
1013
1014 #[inline]
1015 #[track_caller]
1016 pub unsafe fn row_range_unchecked(&self, i: Idx<Rows>) -> Range<usize> {
1018 self.rb().row_range_unchecked(i)
1019 }
1020
1021 #[inline]
1022 #[track_caller]
1023 pub fn col_idx_of_row_raw(&self, i: Idx<Rows>) -> &'_ [Idx<Cols, I>] {
1025 self.rb().col_idx_of_row_raw(i)
1026 }
1027
1028 #[inline]
1029 #[track_caller]
1030 pub fn col_idx_of_row(
1032 &self,
1033 i: Idx<Rows>,
1034 ) -> impl '_ + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Cols>>
1035 {
1036 self.rb().col_idx_of_row(i)
1037 }
1038
1039 #[inline]
1040 #[track_caller]
1041 pub fn as_shape<V: Shape, H: Shape>(
1043 &self,
1044 nrows: V,
1045 ncols: H,
1046 ) -> SymbolicSparseRowMatRef<'_, I, V, H> {
1047 self.rb().as_shape(nrows, ncols)
1048 }
1049
1050 #[inline]
1051 #[track_caller]
1052 pub fn into_shape<V: Shape, H: Shape>(
1054 self,
1055 nrows: V,
1056 ncols: H,
1057 ) -> SymbolicSparseRowMat<I, V, H> {
1058 assert!(all(
1059 self.nrows().unbound() == nrows.unbound(),
1060 self.ncols().unbound() == ncols.unbound()
1061 ));
1062 SymbolicSparseRowMat {
1063 0: symbolic::Own {
1064 nrows,
1065 ncols,
1066 row_ptr: self.0.row_ptr,
1067 row_nnz: self.0.row_nnz,
1068 col_idx: self.0.col_idx,
1069 },
1070 }
1071 }
1072
1073 #[inline]
1074 pub fn as_dyn(&self) -> SymbolicSparseRowMatRef<'_, I> {
1076 self.rb().as_dyn()
1077 }
1078
1079 #[inline]
1080 pub fn into_dyn(self) -> SymbolicSparseRowMat<I> {
1082 SymbolicSparseRowMat {
1083 0: symbolic::Own {
1084 nrows: self.nrows.unbound(),
1085 ncols: self.ncols.unbound(),
1086 row_ptr: self.0.row_ptr,
1087 row_nnz: self.0.row_nnz,
1088 col_idx: self.0.col_idx,
1089 },
1090 }
1091 }
1092
1093 #[inline]
1094 pub fn as_ref(&self) -> SymbolicSparseRowMatRef<'_, I, Rows, Cols> {
1096 SymbolicSparseRowMatRef {
1097 0: symbolic::Ref {
1098 nrows: self.nrows,
1099 ncols: self.ncols,
1100 row_ptr: &self.0.row_ptr,
1101 row_nnz: self.0.row_nnz.as_deref(),
1102 col_idx: &self.0.col_idx,
1103 },
1104 }
1105 }
1106
1107 #[inline]
1108 pub fn try_new_from_indices(
1111 nrows: Rows,
1112 ncols: Cols,
1113 idx: &[Pair<Idx<Rows, I>, Idx<Cols, I>>],
1114 ) -> Result<(Self, Argsort<I>), CreationError> {
1115 let (symbolic, argsort) =
1116 SymbolicSparseColMat::try_new_from_indices_impl(
1117 ncols,
1118 nrows,
1119 |i| Pair {
1120 row: idx[i].col,
1121 col: idx[i].row,
1122 },
1123 |_, _| false,
1124 idx.len(),
1125 )?;
1126 Ok((symbolic.into_transpose(), argsort))
1127 }
1128
1129 #[inline]
1130 pub fn try_new_from_nonnegative_indices(
1135 nrows: Rows,
1136 ncols: Cols,
1137 idx: &[Pair<MaybeIdx<Rows, I>, MaybeIdx<Cols, I>>],
1138 ) -> Result<(Self, Argsort<I>), CreationError> {
1139 let (symbolic, argsort) =
1140 SymbolicSparseColMat::try_new_from_indices_impl(
1141 ncols,
1142 nrows,
1143 |i| Pair {
1144 row: unsafe {
1145 Idx::<Cols, I>::new_unbound(I::from_signed(
1146 idx[i].col.unbound(),
1147 ))
1148 },
1149 col: unsafe {
1150 Idx::<Rows, I>::new_unbound(I::from_signed(
1151 idx[i].row.unbound(),
1152 ))
1153 },
1154 },
1155 |row, col| {
1156 let row = row.unbound().to_signed();
1157 let col = col.unbound().to_signed();
1158 let zero = I::Signed::truncate(0);
1159 row < zero || col < zero
1160 },
1161 idx.len(),
1162 )?;
1163 Ok((symbolic.into_transpose(), argsort))
1164 }
1165}
1166impl<'a, Rows: Shape, Cols: Shape, I: Index, T>
1167 SparseRowMatRef<'a, I, T, Rows, Cols>
1168{
1169 #[inline]
1175 #[track_caller]
1176 pub fn new(
1177 symbolic: SymbolicSparseRowMatRef<'a, I, Rows, Cols>,
1178 val: &'a [T],
1179 ) -> Self {
1180 assert!(symbolic.col_idx().len() == val.len());
1181 Self {
1182 0: numeric::Ref { symbolic, val },
1183 }
1184 }
1185
1186 #[inline]
1188 pub fn parts(
1189 self,
1190 ) -> (SymbolicSparseRowMatRef<'a, I, Rows, Cols>, &'a [T]) {
1191 (self.0.symbolic, self.0.val)
1192 }
1193
1194 #[inline]
1196 pub fn symbolic(&self) -> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
1197 self.0.symbolic
1198 }
1199
1200 #[inline]
1202 pub fn val(self) -> &'a [T] {
1203 self.0.val
1204 }
1205
1206 #[inline]
1208 #[track_caller]
1209 pub fn val_of_row(self, i: Idx<Rows>) -> &'a [T] {
1210 unsafe { self.0.val.get_unchecked(self.row_range(i)) }
1211 }
1212
1213 #[inline]
1216 #[track_caller]
1217 pub fn as_shape<V: Shape, H: Shape>(
1218 self,
1219 nrows: V,
1220 ncols: H,
1221 ) -> SparseRowMatRef<'a, I, T, V, H> {
1222 SparseRowMatRef {
1223 0: numeric::Ref {
1224 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1225 val: self.0.val,
1226 },
1227 }
1228 }
1229
1230 #[track_caller]
1238 pub fn get(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a T> {
1239 assert!(row < self.nrows());
1240 assert!(col < self.ncols());
1241 let col = I::truncate(col.unbound());
1242 let rowl = row.unbound();
1243 let start = self
1244 .symbolic()
1245 .as_dyn()
1246 .col_idx_of_row_raw(rowl)
1247 .partition_point(super::csc::partition_by_lt(col));
1248 let end = start
1249 + self.symbolic().as_dyn().col_idx_of_row_raw(rowl)[start..]
1250 .partition_point(super::csc::partition_by_le(col));
1251 if end == start + 1 {
1252 Some(&self.val_of_row(row)[start])
1253 } else {
1254 None
1255 }
1256 }
1257
1258 #[inline]
1260 pub fn as_dyn(self) -> SparseRowMatRef<'a, I, T> {
1261 SparseRowMatRef {
1262 0: numeric::Ref {
1263 symbolic: self.0.symbolic.as_dyn(),
1264 val: self.0.val,
1265 },
1266 }
1267 }
1268
1269 #[inline]
1271 pub fn as_ref(self) -> SparseRowMatRef<'a, I, T, Rows, Cols> {
1272 SparseRowMatRef {
1273 0: numeric::Ref {
1274 symbolic: self.0.symbolic,
1275 val: self.0.val,
1276 },
1277 }
1278 }
1279
1280 #[inline]
1282 pub fn transpose(self) -> SparseColMatRef<'a, I, T, Cols, Rows> {
1283 SparseColMatRef {
1284 0: super::csc::numeric::Ref {
1285 symbolic: self.0.symbolic.transpose(),
1286 val: self.0.val,
1287 },
1288 }
1289 }
1290
1291 #[inline]
1293 pub fn conjugate(self) -> SparseRowMatRef<'a, I, T::Conj, Rows, Cols>
1294 where
1295 T: Conjugate,
1296 {
1297 self.transpose().conjugate().transpose()
1298 }
1299
1300 #[inline]
1302 pub fn adjoint(self) -> SparseColMatRef<'a, I, T::Conj, Cols, Rows>
1303 where
1304 T: Conjugate,
1305 {
1306 self.transpose().conjugate()
1307 }
1308
1309 #[inline]
1311 pub fn canonical(self) -> SparseRowMatRef<'a, I, T::Canonical, Rows, Cols>
1312 where
1313 T: Conjugate,
1314 {
1315 self.transpose().canonical().transpose()
1316 }
1317
1318 #[inline]
1321 pub fn to_col_major(
1322 &self,
1323 ) -> Result<SparseColMat<I, T::Canonical, Rows, Cols>, FaerError>
1324 where
1325 T: Conjugate,
1326 {
1327 Ok(self.transpose().to_row_major()?.into_transpose())
1328 }
1329
1330 #[inline]
1333 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1334 where
1335 T: Conjugate,
1336 {
1337 fn imp<'ROWS, 'COLS, I: Index, T: Conjugate>(
1338 src: SparseRowMatRef<'_, I, T, Dim<'ROWS>, Dim<'COLS>>,
1339 ) -> Mat<T::Canonical, Dim<'ROWS>, Dim<'COLS>> {
1340 let src = src.canonical();
1341 let mut out = Mat::zeros(src.nrows(), src.ncols());
1342 let M = src.nrows();
1343 for i in M.indices() {
1344 for (j, val) in
1345 iter::zip(src.col_idx_of_row(i), src.val_of_row(i))
1346 {
1347 if const { Conj::get::<T>().is_conj() } {
1348 out[(i, j)] = (&out[(i, j)]) + (&val.conj());
1349 } else {
1350 out[(i, j)] = (&out[(i, j)]) + val;
1351 }
1352 }
1353 }
1354 out
1355 }
1356 with_dim!(ROWS, self.nrows().unbound());
1357 with_dim!(COLS, self.ncols().unbound());
1358 let this = self.as_shape(ROWS, COLS);
1359 imp(this).into_shape(self.nrows(), self.ncols())
1360 }
1361
1362 pub fn triplet_iter(
1364 self,
1365 ) -> impl 'a + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'a T>>
1366 where
1367 Rows: 'a,
1368 Cols: 'a,
1369 {
1370 self.transpose().triplet_iter().map(
1371 #[inline(always)]
1372 |Triplet { row, col, val }| Triplet {
1373 row: col,
1374 col: row,
1375 val,
1376 },
1377 )
1378 }
1379}
1380impl<'a, Rows: Shape, Cols: Shape, I: Index, T>
1381 SparseRowMatMut<'a, I, T, Rows, Cols>
1382{
1383 #[inline]
1384 #[track_caller]
1385 pub fn new(
1387 symbolic: SymbolicSparseRowMatRef<'a, I, Rows, Cols>,
1388 val: &'a mut [T],
1389 ) -> Self {
1390 assert!(symbolic.col_idx().len() == val.len());
1391 Self {
1392 0: numeric::Mut { symbolic, val },
1393 }
1394 }
1395
1396 #[inline]
1397 pub fn parts(
1399 self,
1400 ) -> (SymbolicSparseRowMatRef<'a, I, Rows, Cols>, &'a [T]) {
1401 (self.0.symbolic, self.0.val)
1402 }
1403
1404 #[inline]
1405 pub fn parts_mut(
1407 self,
1408 ) -> (SymbolicSparseRowMatRef<'a, I, Rows, Cols>, &'a mut [T]) {
1409 (self.0.symbolic, self.0.val)
1410 }
1411
1412 #[inline]
1413 pub fn symbolic(&self) -> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
1415 self.0.symbolic
1416 }
1417
1418 #[inline]
1419 pub fn val(self) -> &'a [T] {
1421 self.0.val
1422 }
1423
1424 #[inline]
1425 pub fn val_mut(self) -> &'a mut [T] {
1427 self.0.val
1428 }
1429
1430 #[inline]
1431 #[track_caller]
1432 pub fn val_of_row(self, i: Idx<Rows>) -> &'a [T] {
1434 unsafe { self.0.val.get_unchecked(self.row_range(i)) }
1435 }
1436
1437 #[inline]
1438 #[track_caller]
1439 pub fn val_of_row_mut(self, j: Idx<Rows>) -> &'a mut [T] {
1441 unsafe { self.0.val.get_unchecked_mut(self.row_range(j)) }
1442 }
1443
1444 #[inline]
1445 #[track_caller]
1446 pub fn as_shape<V: Shape, H: Shape>(
1448 self,
1449 nrows: V,
1450 ncols: H,
1451 ) -> SparseRowMatRef<'a, I, T, V, H> {
1452 SparseRowMatRef {
1453 0: numeric::Ref {
1454 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1455 val: self.0.val,
1456 },
1457 }
1458 }
1459
1460 #[inline]
1461 #[track_caller]
1462 pub fn as_shape_mut<V: Shape, H: Shape>(
1464 self,
1465 nrows: V,
1466 ncols: H,
1467 ) -> SparseRowMatMut<'a, I, T, V, H> {
1468 SparseRowMatMut {
1469 0: numeric::Mut {
1470 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1471 val: self.0.val,
1472 },
1473 }
1474 }
1475
1476 #[track_caller]
1478 #[inline]
1479 pub fn get(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a T> {
1480 self.into_const().get(row, col)
1481 }
1482
1483 #[track_caller]
1491 pub fn get_mut(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a mut T> {
1493 assert!(row < self.nrows());
1494 assert!(col < self.ncols());
1495 let col = I::truncate(col.unbound());
1496 let rowl = row.unbound();
1497 let start = self
1498 .symbolic()
1499 .as_dyn()
1500 .col_idx_of_row_raw(rowl)
1501 .partition_point(super::csc::partition_by_lt(col));
1502 let end = start
1503 + self.symbolic().as_dyn().col_idx_of_row_raw(rowl)[start..]
1504 .partition_point(super::csc::partition_by_le(col));
1505 if end == start + 1 {
1506 Some(&mut self.val_of_row_mut(row)[start])
1507 } else {
1508 None
1509 }
1510 }
1511
1512 #[inline]
1513 pub fn as_dyn(self) -> SparseRowMatRef<'a, I, T> {
1515 SparseRowMatRef {
1516 0: numeric::Ref {
1517 symbolic: self.0.symbolic.as_dyn(),
1518 val: self.0.val,
1519 },
1520 }
1521 }
1522
1523 #[inline]
1524 pub fn as_dyn_mut(self) -> SparseRowMatMut<'a, I, T> {
1526 SparseRowMatMut {
1527 0: numeric::Mut {
1528 symbolic: self.0.symbolic.as_dyn(),
1529 val: self.0.val,
1530 },
1531 }
1532 }
1533
1534 #[inline]
1535 pub fn transpose(self) -> SparseColMatRef<'a, I, T, Cols, Rows> {
1537 SparseColMatRef {
1538 0: super::csc::numeric::Ref {
1539 symbolic: self.0.symbolic.transpose(),
1540 val: self.0.val,
1541 },
1542 }
1543 }
1544
1545 #[inline]
1546 pub fn transpose_mut(self) -> SparseColMatMut<'a, I, T, Cols, Rows> {
1548 SparseColMatMut {
1549 0: super::csc::numeric::Mut {
1550 symbolic: self.0.symbolic.transpose(),
1551 val: self.0.val,
1552 },
1553 }
1554 }
1555
1556 #[inline]
1557 pub fn conjugate(self) -> SparseRowMatRef<'a, I, T::Conj, Rows, Cols>
1559 where
1560 T: Conjugate,
1561 {
1562 let len = self.0.val.len();
1563 SparseRowMatRef {
1564 0: numeric::Ref {
1565 symbolic: self.0.symbolic,
1566 val: unsafe {
1567 core::slice::from_raw_parts(
1568 self.0.val.as_ptr() as *const T::Conj,
1569 len,
1570 )
1571 },
1572 },
1573 }
1574 }
1575
1576 #[inline]
1577 pub fn conjugate_mut(self) -> SparseRowMatMut<'a, I, T::Conj, Rows, Cols>
1579 where
1580 T: Conjugate,
1581 {
1582 let len = self.0.val.len();
1583 SparseRowMatMut {
1584 0: numeric::Mut {
1585 symbolic: self.0.symbolic,
1586 val: unsafe {
1587 core::slice::from_raw_parts_mut(
1588 self.0.val.as_mut_ptr() as *mut T::Conj,
1589 len,
1590 )
1591 },
1592 },
1593 }
1594 }
1595
1596 #[inline]
1597 pub fn adjoint(self) -> SparseColMatRef<'a, I, T::Conj, Cols, Rows>
1599 where
1600 T: Conjugate,
1601 {
1602 self.conjugate().transpose()
1603 }
1604
1605 #[inline]
1606 pub fn adjoint_mut(self) -> SparseColMatMut<'a, I, T::Conj, Cols, Rows>
1608 where
1609 T: Conjugate,
1610 {
1611 self.conjugate_mut().transpose_mut()
1612 }
1613
1614 #[inline]
1615 pub fn canonical(self) -> SparseRowMatRef<'a, I, T::Canonical, Rows, Cols>
1617 where
1618 T: Conjugate,
1619 {
1620 let len = self.0.val.len();
1621 SparseRowMatRef {
1622 0: numeric::Ref {
1623 symbolic: self.0.symbolic,
1624 val: unsafe {
1625 core::slice::from_raw_parts(
1626 self.0.val.as_ptr() as *const T::Canonical,
1627 len,
1628 )
1629 },
1630 },
1631 }
1632 }
1633
1634 #[inline]
1635 pub fn canonical_mut(
1637 self,
1638 ) -> SparseRowMatMut<'a, I, T::Canonical, Rows, Cols>
1639 where
1640 T: Conjugate,
1641 {
1642 let len = self.0.val.len();
1643 SparseRowMatMut {
1644 0: numeric::Mut {
1645 symbolic: self.0.symbolic,
1646 val: unsafe {
1647 core::slice::from_raw_parts_mut(
1648 self.0.val.as_mut_ptr() as *mut T::Canonical,
1649 len,
1650 )
1651 },
1652 },
1653 }
1654 }
1655
1656 #[inline]
1657 pub fn to_col_major(
1659 &self,
1660 ) -> Result<SparseColMat<I, T::Canonical, Rows, Cols>, FaerError>
1661 where
1662 T: Conjugate,
1663 {
1664 self.rb().to_col_major()
1665 }
1666
1667 #[inline]
1668 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1670 where
1671 T: Conjugate,
1672 {
1673 self.rb().to_dense()
1674 }
1675
1676 #[inline]
1678 pub fn triplet_iter(
1679 self,
1680 ) -> impl 'a + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'a T>>
1681 where
1682 Rows: 'a,
1683 Cols: 'a,
1684 {
1685 self.into_const().triplet_iter()
1686 }
1687}
1688impl<Rows: Shape, Cols: Shape, I: Index, T> SparseRowMat<I, T, Rows, Cols> {
1689 #[inline]
1690 #[track_caller]
1691 pub fn new(
1693 symbolic: SymbolicSparseRowMat<I, Rows, Cols>,
1694 val: alloc::vec::Vec<T>,
1695 ) -> Self {
1696 assert!(symbolic.col_idx().len() == val.len());
1697 Self {
1698 0: numeric::Own { symbolic, val },
1699 }
1700 }
1701
1702 #[inline]
1703 pub fn parts(
1705 &self,
1706 ) -> (SymbolicSparseRowMatRef<'_, I, Rows, Cols>, &'_ [T]) {
1707 (self.0.symbolic.rb(), &self.0.val)
1708 }
1709
1710 #[inline]
1711 pub fn parts_mut(
1713 &mut self,
1714 ) -> (SymbolicSparseRowMatRef<'_, I, Rows, Cols>, &'_ mut [T]) {
1715 (self.0.symbolic.rb(), &mut self.0.val)
1716 }
1717
1718 #[inline]
1719 pub fn into_parts(
1721 self,
1722 ) -> (SymbolicSparseRowMat<I, Rows, Cols>, alloc::vec::Vec<T>) {
1723 (self.0.symbolic, self.0.val)
1724 }
1725
1726 #[inline]
1727 pub fn symbolic(&self) -> SymbolicSparseRowMatRef<'_, I, Rows, Cols> {
1729 self.0.symbolic.rb()
1730 }
1731
1732 #[inline]
1733 pub fn val(&self) -> &'_ [T] {
1735 &self.0.val
1736 }
1737
1738 #[inline]
1739 pub fn val_mut(&mut self) -> &'_ mut [T] {
1741 &mut self.0.val
1742 }
1743
1744 #[inline]
1745 #[track_caller]
1746 pub fn val_of_row(&self, j: Idx<Rows>) -> &'_ [T] {
1748 unsafe { self.0.val.get_unchecked(self.row_range(j)) }
1749 }
1750
1751 #[inline]
1752 #[track_caller]
1753 pub fn val_of_row_mut(&mut self, j: Idx<Rows>) -> &'_ mut [T] {
1755 unsafe { self.0.val.get_unchecked_mut(self.0.symbolic.row_range(j)) }
1756 }
1757
1758 #[inline]
1759 #[track_caller]
1760 pub fn as_shape<V: Shape, H: Shape>(
1762 &self,
1763 nrows: V,
1764 ncols: H,
1765 ) -> SparseRowMatRef<'_, I, T, V, H> {
1766 SparseRowMatRef {
1767 0: numeric::Ref {
1768 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1769 val: &self.0.val,
1770 },
1771 }
1772 }
1773
1774 #[inline]
1775 #[track_caller]
1776 pub fn as_shape_mut<V: Shape, H: Shape>(
1778 &mut self,
1779 nrows: V,
1780 ncols: H,
1781 ) -> SparseRowMatMut<'_, I, T, V, H> {
1782 SparseRowMatMut {
1783 0: numeric::Mut {
1784 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1785 val: &mut self.0.val,
1786 },
1787 }
1788 }
1789
1790 #[inline]
1791 #[track_caller]
1792 pub fn into_shape<V: Shape, H: Shape>(
1794 self,
1795 nrows: V,
1796 ncols: H,
1797 ) -> SparseRowMat<I, T, V, H> {
1798 SparseRowMat {
1799 0: numeric::Own {
1800 symbolic: self.0.symbolic.into_shape(nrows, ncols),
1801 val: self.0.val,
1802 },
1803 }
1804 }
1805
1806 #[inline]
1807 pub fn as_dyn(&self) -> SparseRowMatRef<'_, I, T> {
1809 SparseRowMatRef {
1810 0: numeric::Ref {
1811 symbolic: self.0.symbolic.as_dyn(),
1812 val: &self.0.val,
1813 },
1814 }
1815 }
1816
1817 #[inline]
1818 pub fn as_dyn_mut(&mut self) -> SparseRowMatMut<'_, I, T> {
1820 SparseRowMatMut {
1821 0: numeric::Mut {
1822 symbolic: self.0.symbolic.as_dyn(),
1823 val: &mut self.0.val,
1824 },
1825 }
1826 }
1827
1828 #[inline]
1829 pub fn into_dyn(self) -> SparseRowMat<I, T> {
1831 SparseRowMat {
1832 0: numeric::Own {
1833 symbolic: self.0.symbolic.into_dyn(),
1834 val: self.0.val,
1835 },
1836 }
1837 }
1838
1839 #[inline]
1840 pub fn as_ref(&self) -> SparseRowMatRef<'_, I, T, Rows, Cols> {
1842 SparseRowMatRef {
1843 0: numeric::Ref {
1844 symbolic: self.0.symbolic.as_ref(),
1845 val: &self.0.val,
1846 },
1847 }
1848 }
1849
1850 #[inline]
1851 pub fn transpose(&self) -> SparseColMatRef<'_, I, T, Cols, Rows> {
1853 SparseColMatRef {
1854 0: super::csc::numeric::Ref {
1855 symbolic: self.0.symbolic.transpose(),
1856 val: &self.0.val,
1857 },
1858 }
1859 }
1860
1861 #[inline]
1862 pub fn transpose_mut(&mut self) -> SparseColMatMut<'_, I, T, Cols, Rows> {
1864 SparseColMatMut {
1865 0: super::csc::numeric::Mut {
1866 symbolic: self.0.symbolic.transpose(),
1867 val: &mut self.0.val,
1868 },
1869 }
1870 }
1871
1872 #[inline]
1873 pub fn into_transpose(self) -> SparseColMat<I, T, Cols, Rows> {
1875 SparseColMat {
1876 0: super::csc::numeric::Own {
1877 symbolic: self.0.symbolic.into_transpose(),
1878 val: self.0.val,
1879 },
1880 }
1881 }
1882
1883 #[inline]
1884 pub fn conjugate(&self) -> SparseRowMatRef<'_, I, T::Conj, Rows, Cols>
1886 where
1887 T: Conjugate,
1888 {
1889 self.rb().conjugate()
1890 }
1891
1892 #[inline]
1893 pub fn conjugate_mut(
1895 &mut self,
1896 ) -> SparseRowMatMut<'_, I, T::Conj, Rows, Cols>
1897 where
1898 T: Conjugate,
1899 {
1900 self.rb_mut().conjugate_mut()
1901 }
1902
1903 #[inline]
1904 pub fn into_conjugate(self) -> SparseRowMat<I, T::Conj, Rows, Cols>
1906 where
1907 T: Conjugate,
1908 {
1909 let mut vec = core::mem::ManuallyDrop::new(self.0.val);
1910 let len = vec.len();
1911 let cap = vec.capacity();
1912 let ptr = vec.as_mut_ptr();
1913 SparseRowMat {
1914 0: numeric::Own {
1915 symbolic: self.0.symbolic,
1916 val: unsafe {
1917 alloc::vec::Vec::from_raw_parts(
1918 ptr as *mut T::Conj,
1919 len,
1920 cap,
1921 )
1922 },
1923 },
1924 }
1925 }
1926
1927 #[inline]
1928 pub fn adjoint(&self) -> SparseColMatRef<'_, I, T::Conj, Cols, Rows>
1930 where
1931 T: Conjugate,
1932 {
1933 self.conjugate().transpose()
1934 }
1935
1936 #[inline]
1937 pub fn adjoint_mut(&mut self) -> SparseColMatMut<'_, I, T::Conj, Cols, Rows>
1939 where
1940 T: Conjugate,
1941 {
1942 self.conjugate_mut().transpose_mut()
1943 }
1944
1945 #[inline]
1946 pub fn into_adjoint(self) -> SparseColMat<I, T::Conj, Cols, Rows>
1948 where
1949 T: Conjugate,
1950 {
1951 self.into_conjugate().into_transpose()
1952 }
1953
1954 #[inline]
1955 pub fn canonical(&self) -> SparseRowMatRef<'_, I, T::Canonical, Rows, Cols>
1957 where
1958 T: Conjugate,
1959 {
1960 let len = self.0.val.len();
1961 SparseRowMatRef {
1962 0: numeric::Ref {
1963 symbolic: self.0.symbolic.rb(),
1964 val: unsafe {
1965 core::slice::from_raw_parts(
1966 self.0.val.as_ptr() as *const T::Canonical,
1967 len,
1968 )
1969 },
1970 },
1971 }
1972 }
1973
1974 #[inline]
1975 pub fn canonical_mut(
1977 &mut self,
1978 ) -> SparseRowMatMut<'_, I, T::Canonical, Rows, Cols>
1979 where
1980 T: Conjugate,
1981 {
1982 let len = self.0.val.len();
1983 SparseRowMatMut {
1984 0: numeric::Mut {
1985 symbolic: self.0.symbolic.rb(),
1986 val: unsafe {
1987 core::slice::from_raw_parts_mut(
1988 self.0.val.as_mut_ptr() as *mut T::Canonical,
1989 len,
1990 )
1991 },
1992 },
1993 }
1994 }
1995
1996 #[inline]
1997 pub fn into_canonical(self) -> SparseRowMat<I, T::Canonical, Rows, Cols>
1999 where
2000 T: Conjugate,
2001 {
2002 let mut vec = core::mem::ManuallyDrop::new(self.0.val);
2003 let len = vec.len();
2004 let cap = vec.capacity();
2005 let ptr = vec.as_mut_ptr();
2006 SparseRowMat {
2007 0: numeric::Own {
2008 symbolic: self.0.symbolic,
2009 val: unsafe {
2010 alloc::vec::Vec::from_raw_parts(
2011 ptr as *mut T::Canonical,
2012 len,
2013 cap,
2014 )
2015 },
2016 },
2017 }
2018 }
2019
2020 #[inline]
2021 pub fn to_col_major(
2023 &self,
2024 ) -> Result<SparseColMat<I, T::Canonical, Rows, Cols>, FaerError>
2025 where
2026 T: Conjugate,
2027 {
2028 self.rb().to_col_major()
2029 }
2030
2031 #[inline]
2032 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
2034 where
2035 T: Conjugate,
2036 {
2037 self.rb().to_dense()
2038 }
2039
2040 #[track_caller]
2041 pub fn new_from_argsort(
2047 symbolic: SymbolicSparseRowMat<I, Rows, Cols>,
2048 argsort: &Argsort<I>,
2049 val: &[T],
2050 ) -> Result<Self, FaerError>
2051 where
2052 T: ComplexField,
2053 {
2054 Ok(SparseColMat::new_from_argsort(
2055 symbolic.into_transpose(),
2056 argsort,
2057 val,
2058 )?
2059 .into_transpose())
2060 }
2061
2062 #[track_caller]
2063 pub fn try_new_from_triplets(
2065 nrows: Rows,
2066 ncols: Cols,
2067 entries: &[Triplet<Idx<Rows, I>, Idx<Cols, I>, T>],
2068 ) -> Result<Self, CreationError>
2069 where
2070 T: ComplexField,
2071 {
2072 let (symbolic, argsort) =
2073 SymbolicSparseColMat::try_new_from_indices_impl(
2074 ncols,
2075 nrows,
2076 |i| Pair {
2077 row: entries[i].col,
2078 col: entries[i].row,
2079 },
2080 |_, _| false,
2081 entries.len(),
2082 )?;
2083 Ok(SparseColMat::new_from_argsort_impl(
2084 symbolic,
2085 &argsort,
2086 |i| entries[i].val.clone(),
2087 entries.len(),
2088 )?
2089 .into_transpose())
2090 }
2091
2092 #[track_caller]
2093 pub fn try_new_from_nonnegative_triplets(
2097 nrows: Rows,
2098 ncols: Cols,
2099 entries: &[Triplet<MaybeIdx<Rows, I>, MaybeIdx<Cols, I>, T>],
2100 ) -> Result<Self, CreationError>
2101 where
2102 T: ComplexField,
2103 {
2104 let (symbolic, argsort) =
2105 SymbolicSparseColMat::try_new_from_indices_impl(
2106 ncols,
2107 nrows,
2108 |i| Pair {
2109 row: unsafe {
2110 Idx::<Cols, I>::new_unbound(I::from_signed(
2111 entries[i].col.unbound(),
2112 ))
2113 },
2114 col: unsafe {
2115 Idx::<Rows, I>::new_unbound(I::from_signed(
2116 entries[i].row.unbound(),
2117 ))
2118 },
2119 },
2120 |row, col| {
2121 let row = row.unbound().to_signed();
2122 let col = col.unbound().to_signed();
2123 let zero = I::Signed::truncate(0);
2124 row < zero || col < zero
2125 },
2126 entries.len(),
2127 )?;
2128 Ok(SparseColMat::new_from_argsort_impl(
2129 symbolic,
2130 &argsort,
2131 |i| entries[i].val.clone(),
2132 entries.len(),
2133 )?
2134 .into_transpose())
2135 }
2136
2137 #[track_caller]
2139 #[inline]
2140 pub fn get(&self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&T> {
2141 self.rb().get(row, col)
2142 }
2143
2144 #[track_caller]
2146 #[inline]
2147 pub fn get_mut(
2148 &mut self,
2149 row: Idx<Rows>,
2150 col: Idx<Cols>,
2151 ) -> Option<&mut T> {
2152 self.rb_mut().get_mut(row, col)
2153 }
2154
2155 #[inline]
2157 pub fn triplet_iter(
2158 &self,
2159 ) -> impl '_ + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'_ T>> {
2160 self.rb().triplet_iter()
2161 }
2162}
2163impl<'a, Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref
2164 for SparseRowMatRef<'a, I, T, Rows, Cols>
2165{
2166 type Target = SymbolicSparseRowMatRef<'a, I, Rows, Cols>;
2167
2168 #[inline]
2169 fn deref(&self) -> &Self::Target {
2170 &self.0.symbolic
2171 }
2172}
2173impl<'a, Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref
2174 for SparseRowMatMut<'a, I, T, Rows, Cols>
2175{
2176 type Target = SymbolicSparseRowMatRef<'a, I, Rows, Cols>;
2177
2178 #[inline]
2179 fn deref(&self) -> &Self::Target {
2180 &self.0.symbolic
2181 }
2182}
2183impl<Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref
2184 for SparseRowMat<I, T, Rows, Cols>
2185{
2186 type Target = SymbolicSparseRowMat<I, Rows, Cols>;
2187
2188 #[inline]
2189 fn deref(&self) -> &Self::Target {
2190 &self.0.symbolic
2191 }
2192}
2193impl<Rows: Shape, Cols: Shape, I: Index> fmt::Debug
2194 for symbolic::Ref<'_, I, Rows, Cols>
2195{
2196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2197 fn imp<'ROWS, 'COLS, I: Index>(
2198 mat: SymbolicSparseRowMatRef<'_, I, Dim<'ROWS>, Dim<'COLS>>,
2199 f: &mut fmt::Formatter<'_>,
2200 ) -> fmt::Result {
2201 struct Entries<'a, 'ROWS, 'COLS, I>(
2202 SymbolicSparseRowMatRef<'a, I, Dim<'ROWS>, Dim<'COLS>>,
2203 );
2204 impl<'ROWS, 'COLS, I: Index> fmt::Debug for Entries<'_, 'ROWS, 'COLS, I> {
2205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2206 let mat = self.0;
2207 f.debug_list()
2208 .entries(mat.nrows().indices().flat_map(|row| {
2209 mat.col_idx_of_row(row)
2210 .map(move |col| Pair { row, col })
2211 }))
2212 .finish()
2213 }
2214 }
2215 f.debug_struct("SymbolicSparseRowMat")
2216 .field("nrows", &mat.nrows)
2217 .field("ncols", &mat.ncols)
2218 .field("entries", &Entries(mat))
2219 .finish()
2220 }
2221 let this =
2222 symbolic::generic::SymbolicSparseRowMat::from_inner_ref(self);
2223 with_dim!(ROWS, this.nrows().unbound());
2224 with_dim!(COLS, this.ncols().unbound());
2225 imp(this.as_shape(ROWS, COLS), f)
2226 }
2227}
2228impl<Rows: Shape, Cols: Shape, I: Index> fmt::Debug
2229 for symbolic::Own<I, Rows, Cols>
2230{
2231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2232 self.rb().fmt(f)
2233 }
2234}
2235impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug
2236 for SparseRowMatRef<'_, I, T, Rows, Cols>
2237{
2238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2239 fn imp<'ROWS, 'COLS, I: Index, T: fmt::Debug>(
2240 mat: SparseRowMatRef<'_, I, T, Dim<'ROWS>, Dim<'COLS>>,
2241 f: &mut fmt::Formatter<'_>,
2242 ) -> fmt::Result {
2243 struct Entries<'a, 'ROWS, 'COLS, I, T>(
2244 SparseRowMatRef<'a, I, T, Dim<'ROWS>, Dim<'COLS>>,
2245 );
2246 impl<'ROWS, 'COLS, I: Index, T: fmt::Debug> fmt::Debug
2247 for Entries<'_, 'ROWS, 'COLS, I, T>
2248 {
2249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2250 let mat = self.0;
2251 f.debug_list()
2252 .entries(mat.nrows().indices().flat_map(|row| {
2253 let col_idx = mat.col_idx_of_row(row);
2254 let val = mat.val_of_row(row);
2255 iter::zip(col_idx, val).map(move |(col, val)| {
2256 Triplet {
2257 row,
2258 col,
2259 val: crate::hacks::hijack_debug(val),
2260 }
2261 })
2262 }))
2263 .finish()
2264 }
2265 }
2266 f.debug_struct("SparseRowMat")
2267 .field("nrows", &mat.nrows)
2268 .field("ncols", &mat.ncols)
2269 .field("entries", &Entries(mat))
2270 .finish()
2271 }
2272 with_dim!(ROWS, self.nrows().unbound());
2273 with_dim!(COLS, self.ncols().unbound());
2274 imp(self.as_shape(ROWS, COLS), f)
2275 }
2276}
2277impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug
2278 for SparseRowMatMut<'_, I, T, Rows, Cols>
2279{
2280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2281 self.rb().fmt(f)
2282 }
2283}
2284impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug
2285 for SparseRowMat<I, T, Rows, Cols>
2286{
2287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2288 self.rb().fmt(f)
2289 }
2290}