1use super::*;
2use crate::internal_prelude::*;
3use crate::{Idx, MaybeIdx, assert, debug_assert};
4use core::ops::Range;
5use core::{fmt, iter};
6
7pub mod symbolic {
9 #[doc(hidden)]
10 pub mod generic {
12 use core::fmt::Debug;
13 use reborrow::*;
14 #[derive(Copy, Clone)]
16 #[repr(transparent)]
17 pub struct SymbolicSparseColMat<Inner>(pub Inner);
18 impl<Inner: Debug> Debug for SymbolicSparseColMat<Inner> {
19 #[inline(always)]
20 fn fmt(
21 &self,
22 f: &mut core::fmt::Formatter<'_>,
23 ) -> core::fmt::Result {
24 self.0.fmt(f)
25 }
26 }
27 impl<Inner> SymbolicSparseColMat<Inner> {
28 #[inline(always)]
30 pub fn from_inner_ref(inner: &Inner) -> &Self {
31 unsafe { &*(inner as *const Inner as *const Self) }
32 }
33
34 #[inline(always)]
36 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
37 unsafe { &mut *(inner as *mut Inner as *mut Self) }
38 }
39 }
40 impl<Inner> core::ops::Deref for SymbolicSparseColMat<Inner> {
41 type Target = Inner;
42
43 #[inline(always)]
44 fn deref(&self) -> &Self::Target {
45 &self.0
46 }
47 }
48 impl<Inner> core::ops::DerefMut for SymbolicSparseColMat<Inner> {
49 #[inline(always)]
50 fn deref_mut(&mut self) -> &mut Self::Target {
51 &mut self.0
52 }
53 }
54 impl<'short, Inner: Reborrow<'short>> Reborrow<'short>
55 for SymbolicSparseColMat<Inner>
56 {
57 type Target = SymbolicSparseColMat<Inner::Target>;
58
59 #[inline(always)]
60 fn rb(&'short self) -> Self::Target {
61 SymbolicSparseColMat(self.0.rb())
62 }
63 }
64 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short>
65 for SymbolicSparseColMat<Inner>
66 {
67 type Target = SymbolicSparseColMat<Inner::Target>;
68
69 #[inline(always)]
70 fn rb_mut(&'short mut self) -> Self::Target {
71 SymbolicSparseColMat(self.0.rb_mut())
72 }
73 }
74 impl<Inner: IntoConst> IntoConst for SymbolicSparseColMat<Inner> {
75 type Target = SymbolicSparseColMat<Inner::Target>;
76
77 #[inline(always)]
78 fn into_const(self) -> Self::Target {
79 SymbolicSparseColMat(self.0.into_const())
80 }
81 }
82 }
83 pub struct Ref<'a, I, Rows = usize, Cols = usize> {
85 pub(crate) nrows: Rows,
86 pub(crate) ncols: Cols,
87 pub(crate) col_ptr: &'a [I],
88 pub(crate) col_nnz: Option<&'a [I]>,
89 pub(crate) row_idx: &'a [I],
90 }
91 #[derive(Clone)]
93 pub struct Own<I, Rows = usize, Cols = usize> {
94 pub(crate) nrows: Rows,
95 pub(crate) ncols: Cols,
96 pub(crate) col_ptr: alloc::vec::Vec<I>,
97 pub(crate) col_nnz: Option<alloc::vec::Vec<I>>,
98 pub(crate) row_idx: alloc::vec::Vec<I>,
99 }
100}
101pub mod numeric {
103 #[doc(hidden)]
104 pub mod generic {
106 use core::fmt::Debug;
107 use reborrow::*;
108 #[derive(Copy, Clone)]
110 #[repr(transparent)]
111 pub struct SparseColMat<Inner>(pub Inner);
112 impl<Inner: Debug> Debug for SparseColMat<Inner> {
113 #[inline(always)]
114 fn fmt(
115 &self,
116 f: &mut core::fmt::Formatter<'_>,
117 ) -> core::fmt::Result {
118 self.0.fmt(f)
119 }
120 }
121 impl<Inner> SparseColMat<Inner> {
122 #[inline(always)]
124 pub fn from_inner_ref(inner: &Inner) -> &Self {
125 unsafe { &*(inner as *const Inner as *const Self) }
126 }
127
128 #[inline(always)]
130 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
131 unsafe { &mut *(inner as *mut Inner as *mut Self) }
132 }
133 }
134 impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for SparseColMat<Inner> {
135 type Target = SparseColMat<Inner::Target>;
136
137 #[inline(always)]
138 fn rb(&'short self) -> Self::Target {
139 SparseColMat(self.0.rb())
140 }
141 }
142 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short>
143 for SparseColMat<Inner>
144 {
145 type Target = SparseColMat<Inner::Target>;
146
147 #[inline(always)]
148 fn rb_mut(&'short mut self) -> Self::Target {
149 SparseColMat(self.0.rb_mut())
150 }
151 }
152 impl<Inner: IntoConst> IntoConst for SparseColMat<Inner> {
153 type Target = SparseColMat<Inner::Target>;
154
155 #[inline(always)]
156 fn into_const(self) -> Self::Target {
157 SparseColMat(self.0.into_const())
158 }
159 }
160 }
161 pub struct Ref<'a, I, T, Rows = usize, Cols = usize> {
163 pub(crate) symbolic: super::SymbolicSparseColMatRef<'a, I, Rows, Cols>,
164 pub(crate) val: &'a [T],
165 }
166 pub struct Mut<'a, I, T, Rows = usize, Cols = usize> {
168 pub(crate) symbolic: super::SymbolicSparseColMatRef<'a, I, Rows, Cols>,
169 pub(crate) val: &'a mut [T],
170 }
171 #[derive(Clone)]
173 pub struct Own<I, T, Rows = usize, Cols = usize> {
174 pub(crate) symbolic: super::SymbolicSparseColMat<I, Rows, Cols>,
175 pub(crate) val: alloc::vec::Vec<T>,
176 }
177}
178pub type SymbolicSparseColMatRef<'a, I, Rows = usize, Cols = usize> =
205 symbolic::generic::SymbolicSparseColMat<symbolic::Ref<'a, I, Rows, Cols>>;
206pub type SymbolicSparseColMat<I, Rows = usize, Cols = usize> =
211 symbolic::generic::SymbolicSparseColMat<symbolic::Own<I, Rows, Cols>>;
212pub type SparseColMatRef<'a, I, T, Rows = usize, Cols = usize> =
216 numeric::generic::SparseColMat<numeric::Ref<'a, I, T, Rows, Cols>>;
217pub type SparseColMatMut<'a, I, T, Rows = usize, Cols = usize> =
221 numeric::generic::SparseColMat<numeric::Mut<'a, I, T, Rows, Cols>>;
222pub type SparseColMat<I, T, Rows = usize, Cols = usize> =
226 numeric::generic::SparseColMat<numeric::Own<I, T, Rows, Cols>>;
227pub(crate) fn partition_by_lt<I: Index>(upper: I) -> impl Fn(&I) -> bool {
228 move |&p| p < upper
229}
230pub(crate) fn partition_by_le<I: Index>(upper: I) -> impl Fn(&I) -> bool {
231 move |&p| p <= upper
232}
233impl<'a, I, Rows: Copy, Cols: Copy> Copy for symbolic::Ref<'a, I, Rows, Cols> {}
234impl<'a, I, T, Rows: Copy, Cols: Copy> Copy
235 for numeric::Ref<'a, I, T, Rows, Cols>
236{
237}
238impl<'a, I, Rows: Copy, Cols: Copy> Clone for symbolic::Ref<'a, I, Rows, Cols> {
239 #[inline]
240 fn clone(&self) -> Self {
241 *self
242 }
243}
244impl<'a, I, T, Rows: Copy, Cols: Copy> Clone
245 for numeric::Ref<'a, I, T, Rows, Cols>
246{
247 #[inline]
248 fn clone(&self) -> Self {
249 *self
250 }
251}
252impl<'a, I, Rows: Copy, Cols: Copy> IntoConst
253 for symbolic::Ref<'a, I, Rows, Cols>
254{
255 type Target = symbolic::Ref<'a, I, Rows, Cols>;
256
257 #[inline]
258 fn into_const(self) -> Self::Target {
259 self
260 }
261}
262impl<'short, 'a, I, Rows: Copy, Cols: Copy> ReborrowMut<'short>
263 for symbolic::Ref<'a, I, Rows, Cols>
264{
265 type Target = symbolic::Ref<'short, I, Rows, Cols>;
266
267 #[inline]
268 fn rb_mut(&'short mut self) -> Self::Target {
269 *self
270 }
271}
272impl<'short, 'a, I, Rows: Copy, Cols: Copy> Reborrow<'short>
273 for symbolic::Ref<'a, I, Rows, Cols>
274{
275 type Target = symbolic::Ref<'short, I, Rows, Cols>;
276
277 #[inline]
278 fn rb(&'short self) -> Self::Target {
279 *self
280 }
281}
282impl<'a, I, T, Rows: Copy, Cols: Copy> IntoConst
283 for numeric::Ref<'a, I, T, Rows, Cols>
284{
285 type Target = numeric::Ref<'a, I, T, Rows, Cols>;
286
287 #[inline]
288 fn into_const(self) -> Self::Target {
289 self
290 }
291}
292impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short>
293 for numeric::Ref<'a, I, T, Rows, Cols>
294{
295 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
296
297 #[inline]
298 fn rb_mut(&'short mut self) -> Self::Target {
299 *self
300 }
301}
302impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> Reborrow<'short>
303 for numeric::Ref<'a, I, T, Rows, Cols>
304{
305 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
306
307 #[inline]
308 fn rb(&'short self) -> Self::Target {
309 *self
310 }
311}
312impl<'a, I, T, Rows: Copy, Cols: Copy> IntoConst
313 for numeric::Mut<'a, I, T, Rows, Cols>
314{
315 type Target = numeric::Ref<'a, I, T, Rows, Cols>;
316
317 #[inline]
318 fn into_const(self) -> Self::Target {
319 numeric::Ref {
320 symbolic: self.symbolic,
321 val: self.val,
322 }
323 }
324}
325impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short>
326 for numeric::Mut<'a, I, T, Rows, Cols>
327{
328 type Target = numeric::Mut<'short, I, T, Rows, Cols>;
329
330 #[inline]
331 fn rb_mut(&'short mut self) -> Self::Target {
332 numeric::Mut {
333 symbolic: self.symbolic,
334 val: self.val,
335 }
336 }
337}
338impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> Reborrow<'short>
339 for numeric::Mut<'a, I, T, Rows, Cols>
340{
341 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
342
343 #[inline]
344 fn rb(&'short self) -> Self::Target {
345 numeric::Ref {
346 symbolic: self.symbolic,
347 val: self.val,
348 }
349 }
350}
351impl<'short, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short>
352 for numeric::Own<I, T, Rows, Cols>
353{
354 type Target = numeric::Mut<'short, I, T, Rows, Cols>;
355
356 #[inline]
357 fn rb_mut(&'short mut self) -> Self::Target {
358 numeric::Mut {
359 symbolic: self.symbolic.rb(),
360 val: &mut self.val,
361 }
362 }
363}
364impl<'short, I, T, Rows: Copy, Cols: Copy> Reborrow<'short>
365 for numeric::Own<I, T, Rows, Cols>
366{
367 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
368
369 #[inline]
370 fn rb(&'short self) -> Self::Target {
371 numeric::Ref {
372 symbolic: self.symbolic.rb(),
373 val: &self.val,
374 }
375 }
376}
377impl<'short, I, Rows: Copy, Cols: Copy> Reborrow<'short>
378 for symbolic::Own<I, Rows, Cols>
379{
380 type Target = symbolic::Ref<'short, I, Rows, Cols>;
381
382 #[inline]
383 fn rb(&'short self) -> Self::Target {
384 symbolic::Ref {
385 nrows: self.nrows,
386 ncols: self.ncols,
387 col_ptr: &self.col_ptr,
388 col_nnz: self.col_nnz.as_deref(),
389 row_idx: &self.row_idx,
390 }
391 }
392}
393#[inline(always)]
394#[track_caller]
395fn assume_col_ptr<I: Index>(
396 nrows: usize,
397 ncols: usize,
398 col_ptr: &[I],
399 col_nnz: Option<&[I]>,
400 row_idx: &[I],
401) {
402 assert!(all(
403 ncols <= I::Signed::MAX.zx(),
404 nrows <= I::Signed::MAX.zx(),
405 ));
406 assert!(col_ptr.len() == ncols + 1);
407 assert!(col_ptr[ncols].zx() <= row_idx.len());
408 if let Some(col_nnz) = col_nnz {
409 assert!(col_nnz.len() == ncols);
410 }
411}
412#[track_caller]
413fn check_col_ptr<I: Index>(
414 nrows: usize,
415 ncols: usize,
416 col_ptr: &[I],
417 col_nnz: Option<&[I]>,
418 row_idx: &[I],
419) {
420 assert!(all(
421 ncols <= I::Signed::MAX.zx(),
422 nrows <= I::Signed::MAX.zx(),
423 ));
424 assert!(col_ptr.len() == ncols + 1);
425 if let Some(nnz_per_col) = col_nnz {
426 assert!(nnz_per_col.len() == ncols);
427 for (&nnz_j, &[col, col_next]) in
428 iter::zip(nnz_per_col, windows2(col_ptr))
429 {
430 assert!(col <= col_next);
431 assert!(nnz_j <= col_next - col);
432 }
433 } else {
434 for &[col, col_next] in windows2(col_ptr) {
435 assert!(col <= col_next);
436 }
437 }
438 assert!(col_ptr[ncols].zx() <= row_idx.len());
439}
440#[track_caller]
441fn check_row_idx<I: Index>(
442 nrows: usize,
443 ncols: usize,
444 col_ptr: &[I],
445 col_nnz: Option<&[I]>,
446 row_idx: &[I],
447) {
448 _ = ncols;
449 if let Some(col_nnz) = col_nnz {
450 for (nnz, &c) in iter::zip(col_nnz, col_ptr) {
451 let c = c.zx();
452 let nnz = nnz.zx();
453 let row_idx = &row_idx[c..c + nnz];
454 if !row_idx.is_empty() {
455 let mut i = row_idx[0].zx();
456 for &i_next in &row_idx[1..] {
457 let i_next = i_next.zx();
458 assert!(i < i_next);
459 i = i_next;
460 }
461 assert!(i < nrows);
462 }
463 }
464 } else {
465 for &[c, c_next] in windows2(col_ptr) {
466 let row_idx = &row_idx[c.zx()..c_next.zx()];
467 if !row_idx.is_empty() {
468 let mut i = row_idx[0].zx();
469 for &i_next in &row_idx[1..] {
470 let i_next = i_next.zx();
471 assert!(i < i_next);
472 i = i_next;
473 }
474 assert!(i < nrows);
475 }
476 }
477 }
478}
479#[track_caller]
480fn check_row_idx_unsorted<I: Index>(
481 nrows: usize,
482 ncols: usize,
483 col_ptr: &[I],
484 col_nnz: Option<&[I]>,
485 row_idx: &[I],
486) {
487 _ = ncols;
488 if let Some(col_nnz) = col_nnz {
489 for (&nnz, &c) in iter::zip(col_nnz, col_ptr) {
490 let c = c.zx();
491 let nnz = nnz.zx();
492 for &i in &row_idx[c..c + nnz] {
493 let i = i.zx();
494 assert!(i < nrows);
495 }
496 }
497 } else {
498 for &[c, c_next] in windows2(col_ptr) {
499 for &i in &row_idx[c.zx()..c_next.zx()] {
500 let i = i.zx();
501 assert!(i < nrows);
502 }
503 }
504 }
505}
506impl<'a, Rows: Shape, Cols: Shape, I: Index>
507 SymbolicSparseColMatRef<'a, I, Rows, Cols>
508{
509 #[inline]
514 #[track_caller]
515 pub unsafe fn new_unchecked(
516 nrows: Rows,
517 ncols: Cols,
518 col_ptr: &'a [I],
519 col_nnz: Option<&'a [I]>,
520 row_idx: &'a [I],
521 ) -> Self {
522 assume_col_ptr(
523 nrows.unbound(),
524 ncols.unbound(),
525 col_ptr,
526 col_nnz,
527 row_idx,
528 );
529 Self {
530 0: symbolic::Ref {
531 nrows,
532 ncols,
533 col_ptr,
534 col_nnz,
535 row_idx,
536 },
537 }
538 }
539
540 #[inline]
545 #[track_caller]
546 pub fn new_checked(
547 nrows: Rows,
548 ncols: Cols,
549 col_ptr: &'a [I],
550 col_nnz: Option<&'a [I]>,
551 row_idx: &'a [I],
552 ) -> Self {
553 check_col_ptr(
554 nrows.unbound(),
555 ncols.unbound(),
556 col_ptr,
557 col_nnz,
558 row_idx,
559 );
560 check_row_idx(
561 nrows.unbound(),
562 ncols.unbound(),
563 col_ptr,
564 col_nnz,
565 row_idx,
566 );
567 Self {
568 0: symbolic::Ref {
569 nrows,
570 ncols,
571 col_ptr,
572 col_nnz,
573 row_idx,
574 },
575 }
576 }
577
578 #[inline]
584 #[track_caller]
585 pub fn new_unsorted_checked(
586 nrows: Rows,
587 ncols: Cols,
588 col_ptr: &'a [I],
589 col_nnz: Option<&'a [I]>,
590 row_idx: &'a [I],
591 ) -> Self {
592 check_col_ptr(
593 nrows.unbound(),
594 ncols.unbound(),
595 col_ptr,
596 col_nnz,
597 row_idx,
598 );
599 check_row_idx_unsorted(
600 nrows.unbound(),
601 ncols.unbound(),
602 col_ptr,
603 col_nnz,
604 row_idx,
605 );
606 Self {
607 0: symbolic::Ref {
608 nrows,
609 ncols,
610 col_ptr,
611 col_nnz,
612 row_idx,
613 },
614 }
615 }
616
617 #[inline]
624 pub fn parts(self) -> (Rows, Cols, &'a [I], Option<&'a [I]>, &'a [I]) {
625 (
626 self.nrows,
627 self.ncols,
628 self.col_ptr,
629 self.col_nnz,
630 self.row_idx,
631 )
632 }
633
634 #[inline]
636 pub fn nrows(&self) -> Rows {
637 self.nrows
638 }
639
640 #[inline]
642 pub fn ncols(&self) -> Cols {
643 self.ncols
644 }
645
646 #[inline]
648 pub fn shape(&self) -> (Rows, Cols) {
649 (self.nrows, self.ncols)
650 }
651
652 #[inline]
654 pub fn transpose(self) -> SymbolicSparseRowMatRef<'a, I, Cols, Rows> {
655 SymbolicSparseRowMatRef {
656 0: super::csr::symbolic::Ref {
657 nrows: self.ncols,
658 ncols: self.nrows,
659 row_ptr: self.col_ptr,
660 row_nnz: self.col_nnz,
661 col_idx: self.row_idx,
662 },
663 }
664 }
665
666 #[inline]
668 pub fn to_owned(
669 &self,
670 ) -> Result<SymbolicSparseColMat<I, Rows, Cols>, FaerError> {
671 Ok(SymbolicSparseColMat {
672 0: symbolic::Own {
673 nrows: self.nrows,
674 ncols: self.ncols,
675 col_ptr: try_collect(self.col_ptr.iter().copied())?,
676 col_nnz: self
677 .col_nnz
678 .map(|col_nnz| try_collect(col_nnz.iter().copied()))
679 .transpose()?,
680 row_idx: try_collect(self.row_idx.iter().copied())?,
681 },
682 })
683 }
684
685 #[inline]
688 pub fn to_row_major(
689 &self,
690 ) -> Result<SymbolicSparseRowMat<I, Rows, Cols>, FaerError> {
691 let mat = SparseColMatRef::new(
692 *self,
693 Symbolic::materialize(self.row_idx.len()),
694 );
695 Ok(mat.to_row_major()?.0.symbolic)
696 }
697
698 #[inline]
700 pub fn compute_nnz(&self) -> usize {
701 fn imp<I: Index>(
702 col_ptr: &[I],
703 col_nnz: Option<&[I]>,
704 ncols: usize,
705 ) -> usize {
706 match col_nnz {
707 Some(col_nnz) => {
708 let mut nnz = 0usize;
709 for &nnz_j in col_nnz {
710 nnz += nnz_j.zx();
711 }
712 nnz
713 },
714 None => col_ptr[ncols].zx() - col_ptr[0].zx(),
715 }
716 }
717 imp(self.col_ptr, self.col_nnz, self.ncols.unbound())
718 }
719
720 #[inline]
722 pub fn col_ptr(&self) -> &'a [I] {
723 self.col_ptr
724 }
725
726 #[inline]
728 pub fn col_nnz(&self) -> Option<&'a [I]> {
729 self.col_nnz
730 }
731
732 #[inline]
734 pub fn row_idx(&self) -> &'a [I] {
735 self.row_idx
736 }
737
738 #[inline]
740 #[track_caller]
741 pub fn col_range(&self, j: Idx<Cols>) -> Range<usize> {
742 assert!(j < self.ncols());
743 unsafe { self.col_range_unchecked(j) }
744 }
745
746 #[inline]
749 #[track_caller]
750 pub unsafe fn col_range_unchecked(&self, j: Idx<Cols>) -> Range<usize> {
751 debug_assert!(j < self.ncols());
752 let j = j.unbound();
753 let start = self.col_ptr.get_unchecked(j).zx();
754 let end = self
755 .col_nnz
756 .map(|col_nnz| col_nnz.get_unchecked(j).zx() + start)
757 .unwrap_or(self.col_ptr.get_unchecked(j + 1).zx());
758 start..end
759 }
760
761 #[inline]
763 #[track_caller]
764 pub fn row_idx_of_col_raw(&self, j: Idx<Cols>) -> &'a [Idx<Rows, I>] {
765 unsafe {
766 let slice = self.row_idx.get_unchecked(self.col_range(j));
767 let len = slice.len();
768 core::slice::from_raw_parts(
769 slice.as_ptr() as *const Idx<Rows, I>,
770 len,
771 )
772 }
773 }
774
775 #[inline]
777 #[track_caller]
778 pub fn row_idx_of_col(
779 &self,
780 j: Idx<Cols>,
781 ) -> impl 'a + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Rows>>
782 where
783 Rows: 'a,
784 Cols: 'a,
785 {
786 self.row_idx_of_col_raw(j)
787 .iter()
788 .map(|&i| unsafe { Idx::<Rows>::new_unbound(i.unbound().zx()) })
789 }
790
791 #[inline]
794 #[track_caller]
795 pub fn as_shape<V: Shape, H: Shape>(
796 self,
797 nrows: V,
798 ncols: H,
799 ) -> SymbolicSparseColMatRef<'a, I, V, H> {
800 assert!(all(
801 self.nrows.unbound() == nrows.unbound(),
802 self.ncols.unbound() == ncols.unbound()
803 ));
804 SymbolicSparseColMatRef {
805 0: symbolic::Ref {
806 nrows,
807 ncols,
808 col_ptr: self.col_ptr,
809 col_nnz: self.col_nnz,
810 row_idx: self.row_idx,
811 },
812 }
813 }
814
815 #[inline]
817 pub fn as_dyn(self) -> SymbolicSparseColMatRef<'a, I> {
818 SymbolicSparseColMatRef {
819 0: symbolic::Ref {
820 nrows: self.nrows.unbound(),
821 ncols: self.ncols.unbound(),
822 col_ptr: self.col_ptr,
823 col_nnz: self.col_nnz,
824 row_idx: self.row_idx,
825 },
826 }
827 }
828
829 #[inline]
831 pub fn as_ref(self) -> SymbolicSparseColMatRef<'a, I, Rows, Cols> {
832 SymbolicSparseColMatRef {
833 0: symbolic::Ref {
834 nrows: self.nrows,
835 ncols: self.ncols,
836 col_ptr: self.col_ptr,
837 col_nnz: self.col_nnz,
838 row_idx: self.row_idx,
839 },
840 }
841 }
842}
843impl<Rows: Shape, Cols: Shape, I: Index> SymbolicSparseColMat<I, Rows, Cols> {
844 #[inline]
849 #[track_caller]
850 pub unsafe fn new_unchecked(
851 nrows: Rows,
852 ncols: Cols,
853 col_ptr: alloc::vec::Vec<I>,
854 col_nnz: Option<alloc::vec::Vec<I>>,
855 row_idx: alloc::vec::Vec<I>,
856 ) -> Self {
857 assume_col_ptr(
858 nrows.unbound(),
859 ncols.unbound(),
860 &col_ptr,
861 col_nnz.as_deref(),
862 &row_idx,
863 );
864 Self {
865 0: symbolic::Own {
866 nrows,
867 ncols,
868 col_ptr,
869 col_nnz,
870 row_idx,
871 },
872 }
873 }
874
875 #[inline]
880 #[track_caller]
881 pub fn new_checked(
882 nrows: Rows,
883 ncols: Cols,
884 col_ptr: alloc::vec::Vec<I>,
885 col_nnz: Option<alloc::vec::Vec<I>>,
886 row_idx: alloc::vec::Vec<I>,
887 ) -> Self {
888 check_col_ptr(
889 nrows.unbound(),
890 ncols.unbound(),
891 &col_ptr,
892 col_nnz.as_deref(),
893 &row_idx,
894 );
895 check_row_idx(
896 nrows.unbound(),
897 ncols.unbound(),
898 &col_ptr,
899 col_nnz.as_deref(),
900 &row_idx,
901 );
902 Self {
903 0: symbolic::Own {
904 nrows,
905 ncols,
906 col_ptr,
907 col_nnz,
908 row_idx,
909 },
910 }
911 }
912
913 #[inline]
919 #[track_caller]
920 pub fn new_unsorted_checked(
921 nrows: Rows,
922 ncols: Cols,
923 col_ptr: alloc::vec::Vec<I>,
924 col_nnz: Option<alloc::vec::Vec<I>>,
925 row_idx: alloc::vec::Vec<I>,
926 ) -> Self {
927 check_col_ptr(
928 nrows.unbound(),
929 ncols.unbound(),
930 &col_ptr,
931 col_nnz.as_deref(),
932 &row_idx,
933 );
934 check_row_idx_unsorted(
935 nrows.unbound(),
936 ncols.unbound(),
937 &col_ptr,
938 col_nnz.as_deref(),
939 &row_idx,
940 );
941 Self {
942 0: symbolic::Own {
943 nrows,
944 ncols,
945 col_ptr,
946 col_nnz,
947 row_idx,
948 },
949 }
950 }
951
952 #[inline]
953 pub fn parts(&self) -> (Rows, Cols, &'_ [I], Option<&'_ [I]>, &'_ [I]) {
955 (
956 self.nrows,
957 self.ncols,
958 &self.col_ptr,
959 self.col_nnz.as_deref(),
960 &self.row_idx,
961 )
962 }
963
964 #[inline]
965 pub fn into_parts(
967 self,
968 ) -> (
969 Rows,
970 Cols,
971 alloc::vec::Vec<I>,
972 Option<alloc::vec::Vec<I>>,
973 alloc::vec::Vec<I>,
974 ) {
975 (
976 self.0.nrows,
977 self.0.ncols,
978 self.0.col_ptr,
979 self.0.col_nnz,
980 self.0.row_idx,
981 )
982 }
983
984 #[inline]
985 pub fn nrows(&self) -> Rows {
987 self.nrows
988 }
989
990 #[inline]
991 pub fn ncols(&self) -> Cols {
993 self.ncols
994 }
995
996 #[inline]
997 pub fn shape(&self) -> (Rows, Cols) {
999 (self.nrows, self.ncols)
1000 }
1001
1002 #[inline]
1003 pub fn transpose(&self) -> SymbolicSparseRowMatRef<'_, I, Cols, Rows> {
1005 self.rb().transpose()
1006 }
1007
1008 #[inline]
1009 pub fn into_transpose(self) -> SymbolicSparseRowMat<I, Cols, Rows> {
1011 SymbolicSparseRowMat {
1012 0: super::csr::symbolic::Own {
1013 nrows: self.0.ncols,
1014 ncols: self.0.nrows,
1015 row_ptr: self.0.col_ptr,
1016 row_nnz: self.0.col_nnz,
1017 col_idx: self.0.row_idx,
1018 },
1019 }
1020 }
1021
1022 #[inline]
1023 pub fn to_owned(
1025 &self,
1026 ) -> Result<SymbolicSparseColMat<I, Rows, Cols>, FaerError> {
1027 self.rb().to_owned()
1028 }
1029
1030 #[inline]
1031 pub fn to_row_major(
1033 &self,
1034 ) -> Result<SymbolicSparseRowMat<I, Rows, Cols>, FaerError> {
1035 self.rb().to_row_major()
1036 }
1037
1038 #[inline]
1039 pub fn compute_nnz(&self) -> usize {
1041 self.rb().compute_nnz()
1042 }
1043
1044 #[inline]
1045 pub fn col_ptr(&self) -> &'_ [I] {
1047 &self.col_ptr
1048 }
1049
1050 #[inline]
1051 pub fn col_nnz(&self) -> Option<&'_ [I]> {
1053 self.col_nnz.as_deref()
1054 }
1055
1056 #[inline]
1057 pub fn row_idx(&self) -> &'_ [I] {
1059 &self.row_idx
1060 }
1061
1062 #[inline]
1063 #[track_caller]
1064 pub fn col_range(&self, j: Idx<Cols>) -> Range<usize> {
1066 self.rb().col_range(j)
1067 }
1068
1069 #[inline]
1070 #[track_caller]
1071 pub unsafe fn col_range_unchecked(&self, j: Idx<Cols>) -> Range<usize> {
1073 self.rb().col_range_unchecked(j)
1074 }
1075
1076 #[inline]
1077 #[track_caller]
1078 pub fn row_idx_of_col_raw(&self, j: Idx<Cols>) -> &'_ [Idx<Rows, I>] {
1080 self.rb().row_idx_of_col_raw(j)
1081 }
1082
1083 #[inline]
1084 #[track_caller]
1085 pub fn row_idx_of_col(
1087 &self,
1088 j: Idx<Cols>,
1089 ) -> impl '_ + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Rows>>
1090 {
1091 self.rb().row_idx_of_col(j)
1092 }
1093
1094 #[inline]
1095 #[track_caller]
1096 pub fn as_shape<V: Shape, H: Shape>(
1098 &self,
1099 nrows: V,
1100 ncols: H,
1101 ) -> SymbolicSparseColMatRef<'_, I, V, H> {
1102 self.rb().as_shape(nrows, ncols)
1103 }
1104
1105 #[inline]
1106 #[track_caller]
1107 pub fn into_shape<V: Shape, H: Shape>(
1109 self,
1110 nrows: V,
1111 ncols: H,
1112 ) -> SymbolicSparseColMat<I, V, H> {
1113 assert!(all(
1114 self.nrows().unbound() == nrows.unbound(),
1115 self.ncols().unbound() == ncols.unbound()
1116 ));
1117 SymbolicSparseColMat {
1118 0: symbolic::Own {
1119 nrows,
1120 ncols,
1121 col_ptr: self.0.col_ptr,
1122 col_nnz: self.0.col_nnz,
1123 row_idx: self.0.row_idx,
1124 },
1125 }
1126 }
1127
1128 #[inline]
1129 pub fn as_dyn(&self) -> SymbolicSparseColMatRef<'_, I> {
1131 self.rb().as_dyn()
1132 }
1133
1134 #[inline]
1135 pub fn into_dyn(self) -> SymbolicSparseColMat<I> {
1137 SymbolicSparseColMat {
1138 0: symbolic::Own {
1139 nrows: self.0.nrows.unbound(),
1140 ncols: self.0.ncols.unbound(),
1141 col_ptr: self.0.col_ptr,
1142 col_nnz: self.0.col_nnz,
1143 row_idx: self.0.row_idx,
1144 },
1145 }
1146 }
1147
1148 #[inline]
1150 pub fn as_ref(&self) -> SymbolicSparseColMatRef<'_, I, Rows, Cols> {
1151 SymbolicSparseColMatRef {
1152 0: symbolic::Ref {
1153 nrows: self.nrows,
1154 ncols: self.ncols,
1155 col_ptr: &self.col_ptr,
1156 col_nnz: self.col_nnz.as_deref(),
1157 row_idx: &self.row_idx,
1158 },
1159 }
1160 }
1161
1162 #[inline]
1163 pub(crate) fn try_new_from_indices_impl(
1164 nrows: Rows,
1165 ncols: Cols,
1166 idx: impl Fn(usize) -> Pair<Idx<Rows, I>, Idx<Cols, I>>,
1167 ignore: impl Fn(Idx<Rows, I>, Idx<Cols, I>) -> bool,
1168 all_nnz: usize,
1169 ) -> Result<(Self, Argsort<I>), CreationError> {
1170 if nrows.unbound() > I::Signed::MAX.zx()
1171 || ncols.unbound() > I::Signed::MAX.zx()
1172 || all_nnz > I::Signed::MAX.zx()
1173 {
1174 return Err(CreationError::Generic(FaerError::IndexOverflow));
1175 }
1176 if all_nnz == 0 {
1177 return Ok((
1178 Self {
1179 0: symbolic::Own {
1180 nrows,
1181 ncols,
1182 col_ptr: try_zeroed(ncols.unbound() + 1)?,
1183 col_nnz: None,
1184 row_idx: alloc::vec::Vec::new(),
1185 },
1186 },
1187 Argsort {
1188 idx: alloc::vec::Vec::new(),
1189 all_nnz,
1190 nnz: 0,
1191 },
1192 ));
1193 }
1194 let mut nnz_by_col = try_zeroed::<I>(ncols.unbound() + 1)?;
1195 for i in 0..all_nnz {
1196 let Pair { row, col } = idx(i);
1197 if !ignore(row, col) {
1198 *nnz_by_col.get_mut(col.unbound().zx() + 1).ok_or(
1199 CreationError::OutOfBounds {
1200 row: row.unbound().zx(),
1201 col: col.unbound().zx(),
1202 },
1203 )? += I::truncate(1);
1204 }
1205 }
1206
1207 let mut prev_nnz = I::truncate(0);
1208 for val in nnz_by_col.iter_mut() {
1209 let new_val = prev_nnz;
1210 prev_nnz += *val;
1211 *val = new_val;
1212 }
1213
1214 let mut argsort = try_zeroed::<I>(all_nnz)?;
1215 for i in 0..all_nnz {
1216 let Pair { row, col } = idx(i);
1217 if !ignore(row, col) {
1218 let off = nnz_by_col.get_mut(col.unbound().zx() + 1).unwrap();
1219 argsort[off.zx()] = I::truncate(i);
1220 *off += I::truncate(1);
1221 }
1222 }
1223 let all_nnz = prev_nnz.zx();
1224
1225 for w in nnz_by_col.windows(2) {
1226 argsort[w[0].zx()..w[1].zx()].sort_unstable_by_key(|i| {
1227 let Pair { row, col } = idx(i.zx());
1228 (row, col)
1229 });
1230 }
1231
1232 let mut n_dup = 0usize;
1233 let mut prev = (I::truncate(usize::MAX), I::truncate(usize::MAX));
1234 let top_bit = I::truncate(1 << (I::BITS - 1));
1235 for i in 0..all_nnz {
1236 let idx = idx(argsort[i].zx());
1237 let idx @ (row, col) = (idx.row.unbound(), idx.col.unbound());
1238 let valid_row = if const { Rows::IS_BOUND } {
1239 true
1240 } else {
1241 row.zx() < nrows.unbound()
1242 };
1243 let valid_col = if const { Cols::IS_BOUND } {
1244 true
1245 } else {
1246 col.zx() < ncols.unbound()
1247 };
1248 if !(valid_row && valid_col) {
1249 return Err(CreationError::OutOfBounds {
1250 row: row.zx(),
1251 col: col.zx(),
1252 });
1253 }
1254 let same = idx == prev;
1255 argsort[i] =
1256 argsort[i] | (if same { top_bit } else { I::truncate(0) });
1257 n_dup += same as usize;
1258 prev = idx;
1259 }
1260 let nnz = all_nnz - n_dup;
1261 let mut col_ptr = nnz_by_col;
1262 let mut row_idx = try_zeroed::<I>(nnz)?;
1263 let mut reader = 0usize;
1264 let mut writer = 0usize;
1265 for j in Cols::indices(Cols::start(), ncols.end()) {
1266 let jj = I::truncate(j.unbound());
1267 let mut n_unique = 0usize;
1268 let mut prev = I::truncate(usize::MAX);
1269 while reader < all_nnz {
1270 let Pair { row, col } = idx((argsort[reader] & !top_bit).zx());
1271 if col.unbound() != jj {
1272 break;
1273 }
1274 reader += 1;
1275 let row = row.unbound();
1276 if row == prev {
1277 continue;
1278 }
1279 prev = row;
1280 row_idx[writer] = row;
1281 writer += 1;
1282 n_unique += 1;
1283 }
1284 col_ptr[j.unbound() + 1] =
1285 col_ptr[j.unbound()] + I::truncate(n_unique);
1286 }
1287 Ok((
1288 unsafe {
1289 Self::new_unchecked(nrows, ncols, col_ptr, None, row_idx)
1290 },
1291 Argsort {
1292 idx: argsort,
1293 all_nnz,
1294 nnz,
1295 },
1296 ))
1297 }
1298
1299 #[inline]
1302 pub fn try_new_from_indices(
1303 nrows: Rows,
1304 ncols: Cols,
1305 idx: &[Pair<Idx<Rows, I>, Idx<Cols, I>>],
1306 ) -> Result<(Self, Argsort<I>), CreationError> {
1307 Self::try_new_from_indices_impl(
1308 nrows,
1309 ncols,
1310 |i| idx[i],
1311 |_, _| false,
1312 idx.len(),
1313 )
1314 }
1315
1316 #[inline]
1321 pub fn try_new_from_nonnegative_indices(
1322 nrows: Rows,
1323 ncols: Cols,
1324 idx: &[Pair<MaybeIdx<Rows, I>, MaybeIdx<Cols, I>>],
1325 ) -> Result<(Self, Argsort<I>), CreationError> {
1326 Self::try_new_from_indices_impl(
1327 nrows,
1328 ncols,
1329 |i| Pair {
1330 row: unsafe {
1331 Idx::<Rows, I>::new_unbound(I::from_signed(
1332 idx[i].row.unbound(),
1333 ))
1334 },
1335 col: unsafe {
1336 Idx::<Cols, I>::new_unbound(I::from_signed(
1337 idx[i].col.unbound(),
1338 ))
1339 },
1340 },
1341 |row, col| {
1342 let row = row.unbound().to_signed();
1343 let col = col.unbound().to_signed();
1344 let zero = I::Signed::truncate(0);
1345 row < zero || col < zero
1346 },
1347 idx.len(),
1348 )
1349 }
1350}
1351impl<'a, Rows: Shape, Cols: Shape, I: Index, T>
1352 SparseColMatRef<'a, I, T, Rows, Cols>
1353{
1354 #[inline]
1360 #[track_caller]
1361 pub fn new(
1362 symbolic: SymbolicSparseColMatRef<'a, I, Rows, Cols>,
1363 val: &'a [T],
1364 ) -> Self {
1365 assert!(symbolic.row_idx().len() == val.len());
1366 Self {
1367 0: numeric::Ref { symbolic, val },
1368 }
1369 }
1370
1371 #[inline]
1373 pub fn parts(
1374 self,
1375 ) -> (SymbolicSparseColMatRef<'a, I, Rows, Cols>, &'a [T]) {
1376 (self.0.symbolic, self.0.val)
1377 }
1378
1379 #[inline]
1381 pub fn symbolic(&self) -> SymbolicSparseColMatRef<'a, I, Rows, Cols> {
1382 self.0.symbolic
1383 }
1384
1385 #[inline]
1387 pub fn val(self) -> &'a [T] {
1388 self.0.val
1389 }
1390
1391 #[inline]
1393 #[track_caller]
1394 pub fn val_of_col(self, j: Idx<Cols>) -> &'a [T] {
1395 unsafe { self.0.val.get_unchecked(self.col_range(j)) }
1396 }
1397
1398 #[inline]
1401 #[track_caller]
1402 pub fn as_shape<V: Shape, H: Shape>(
1403 self,
1404 nrows: V,
1405 ncols: H,
1406 ) -> SparseColMatRef<'a, I, T, V, H> {
1407 SparseColMatRef {
1408 0: numeric::Ref {
1409 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1410 val: self.0.val,
1411 },
1412 }
1413 }
1414
1415 #[track_caller]
1423 pub fn get(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a T> {
1424 assert!(row < self.nrows());
1425 assert!(col < self.ncols());
1426 let row = I::truncate(row.unbound());
1427 let coll = col.unbound();
1428 let start = self
1429 .symbolic()
1430 .as_dyn()
1431 .row_idx_of_col_raw(coll)
1432 .partition_point(partition_by_lt(row));
1433 let end = start
1434 + self.symbolic().as_dyn().row_idx_of_col_raw(coll)[start..]
1435 .partition_point(partition_by_le(row));
1436 if end == start + 1 {
1437 Some(&self.val_of_col(col)[start])
1438 } else {
1439 None
1440 }
1441 }
1442
1443 #[inline]
1445 pub fn as_dyn(self) -> SparseColMatRef<'a, I, T> {
1446 SparseColMatRef {
1447 0: numeric::Ref {
1448 symbolic: self.0.symbolic.as_dyn(),
1449 val: self.0.val,
1450 },
1451 }
1452 }
1453
1454 #[inline]
1456 pub fn as_ref(self) -> SparseColMatRef<'a, I, T, Rows, Cols> {
1457 SparseColMatRef {
1458 0: numeric::Ref {
1459 symbolic: self.0.symbolic,
1460 val: self.0.val,
1461 },
1462 }
1463 }
1464
1465 #[inline]
1467 pub fn transpose(self) -> SparseRowMatRef<'a, I, T, Cols, Rows> {
1468 SparseRowMatRef {
1469 0: super::csr::numeric::Ref {
1470 symbolic: self.0.symbolic.transpose(),
1471 val: self.0.val,
1472 },
1473 }
1474 }
1475
1476 #[inline]
1478 pub fn conjugate(self) -> SparseColMatRef<'a, I, T::Conj, Rows, Cols>
1479 where
1480 T: Conjugate,
1481 {
1482 let len = self.0.val.len();
1483 SparseColMatRef {
1484 0: numeric::Ref {
1485 symbolic: self.0.symbolic,
1486 val: unsafe {
1487 core::slice::from_raw_parts(
1488 self.0.val.as_ptr() as *const T::Conj,
1489 len,
1490 )
1491 },
1492 },
1493 }
1494 }
1495
1496 #[inline]
1498 pub fn adjoint(self) -> SparseRowMatRef<'a, I, T::Conj, Cols, Rows>
1499 where
1500 T: Conjugate,
1501 {
1502 self.conjugate().transpose()
1503 }
1504
1505 #[inline]
1507 pub fn canonical(self) -> SparseColMatRef<'a, I, T::Canonical, Rows, Cols>
1508 where
1509 T: Conjugate,
1510 {
1511 let len = self.0.val.len();
1512 SparseColMatRef {
1513 0: numeric::Ref {
1514 symbolic: self.0.symbolic,
1515 val: unsafe {
1516 core::slice::from_raw_parts(
1517 self.0.val.as_ptr() as *const T::Canonical,
1518 len,
1519 )
1520 },
1521 },
1522 }
1523 }
1524
1525 #[inline]
1528 pub fn to_row_major(
1529 &self,
1530 ) -> Result<SparseRowMat<I, T::Canonical, Rows, Cols>, FaerError>
1531 where
1532 T: Conjugate,
1533 {
1534 let max = self.row_idx().len();
1535 let mut new_col_ptr = try_zeroed::<I>(self.nrows().unbound() + 1)?;
1536 let mut new_row_idx = try_zeroed::<I>(max)?;
1537 let mut new_val = try_collect(repeat_n!(zero::<T::Canonical>(), max))?;
1538 let nnz = utils::transpose_dedup(
1539 &mut new_val,
1540 &mut new_col_ptr,
1541 &mut new_row_idx,
1542 *self,
1543 MemStack::new(&mut dyn_stack::MemBuffer::try_new(
1544 utils::transpose_dedup_scratch::<I>(
1545 self.nrows().unbound(),
1546 self.ncols().unbound(),
1547 ),
1548 )?),
1549 )
1550 .compute_nnz();
1551 new_val.truncate(nnz);
1552 new_row_idx.truncate(nnz);
1553 Ok(SparseRowMat::new(
1554 unsafe {
1555 SymbolicSparseRowMat::new_unchecked(
1556 self.nrows(),
1557 self.ncols(),
1558 new_col_ptr,
1559 None,
1560 new_row_idx,
1561 )
1562 },
1563 new_val,
1564 ))
1565 }
1566
1567 #[inline]
1570 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1571 where
1572 T: Conjugate,
1573 {
1574 fn imp<'ROWS, 'COLS, I: Index, T: Conjugate>(
1575 src: SparseColMatRef<'_, I, T, Dim<'ROWS>, Dim<'COLS>>,
1576 ) -> Mat<T::Canonical, Dim<'ROWS>, Dim<'COLS>> {
1577 let src = src.canonical();
1578 let mut out = Mat::zeros(src.nrows(), src.ncols());
1579 let N = src.ncols();
1580 for j in N.indices() {
1581 for (i, val) in
1582 iter::zip(src.row_idx_of_col(j), src.val_of_col(j))
1583 {
1584 if const { Conj::get::<T>().is_conj() } {
1585 out[(i, j)] = (&out[(i, j)]) + (&val.conj());
1586 } else {
1587 out[(i, j)] = (&out[(i, j)]) + val;
1588 }
1589 }
1590 }
1591 out
1592 }
1593 with_dim!(ROWS, self.nrows().unbound());
1594 with_dim!(COLS, self.ncols().unbound());
1595 let this = self.as_shape(ROWS, COLS);
1596 imp(this).into_shape(self.nrows(), self.ncols())
1597 }
1598
1599 pub fn triplet_iter(
1601 self,
1602 ) -> impl 'a + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'a T>>
1603 where
1604 Rows: 'a,
1605 Cols: 'a,
1606 {
1607 (0..self.ncols.unbound()).flat_map(
1608 #[inline(always)]
1609 move |j| {
1610 let j = unsafe { self.ncols.unchecked_idx(j) };
1611 let range = self.col_range(j);
1612 iter::zip(
1613 iter::zip(
1614 self.0.symbolic.row_idx[range.clone()].iter().map(
1615 #[inline(always)]
1616 move |i| unsafe {
1617 self.nrows.unchecked_idx(i.zx())
1618 },
1619 ),
1620 iter::repeat_n(j, range.len()),
1621 ),
1622 &self.0.val[range],
1623 )
1624 .map(
1625 #[inline(always)]
1626 move |((i, j), v)| Triplet::new(i, j, v),
1627 )
1628 },
1629 )
1630 }
1631}
1632impl<'a, Rows: Shape, Cols: Shape, I: Index, T>
1633 SparseColMatMut<'a, I, T, Rows, Cols>
1634{
1635 #[inline]
1636 #[track_caller]
1637 pub fn new(
1639 symbolic: SymbolicSparseColMatRef<'a, I, Rows, Cols>,
1640 val: &'a mut [T],
1641 ) -> Self {
1642 assert!(symbolic.row_idx().len() == val.len());
1643 Self {
1644 0: numeric::Mut { symbolic, val },
1645 }
1646 }
1647
1648 #[inline]
1649 pub fn parts(
1651 self,
1652 ) -> (SymbolicSparseColMatRef<'a, I, Rows, Cols>, &'a [T]) {
1653 (self.0.symbolic, self.0.val)
1654 }
1655
1656 #[inline]
1657 pub fn parts_mut(
1659 self,
1660 ) -> (SymbolicSparseColMatRef<'a, I, Rows, Cols>, &'a mut [T]) {
1661 (self.0.symbolic, self.0.val)
1662 }
1663
1664 #[inline]
1665 pub fn symbolic(&self) -> SymbolicSparseColMatRef<'a, I, Rows, Cols> {
1667 self.0.symbolic
1668 }
1669
1670 #[inline]
1671 pub fn val(self) -> &'a [T] {
1673 self.0.val
1674 }
1675
1676 #[inline]
1677 pub fn val_mut(self) -> &'a mut [T] {
1679 self.0.val
1680 }
1681
1682 #[inline]
1683 #[track_caller]
1684 pub fn val_of_col(self, j: Idx<Cols>) -> &'a [T] {
1686 unsafe { self.0.val.get_unchecked(self.col_range(j)) }
1687 }
1688
1689 #[inline]
1690 #[track_caller]
1691 pub fn val_of_col_mut(self, j: Idx<Cols>) -> &'a mut [T] {
1693 unsafe { self.0.val.get_unchecked_mut(self.col_range(j)) }
1694 }
1695
1696 #[inline]
1697 #[track_caller]
1698 pub fn idx_val_of_col_mut(
1701 self,
1702 j: Idx<Cols>,
1703 ) -> (
1704 impl 'a + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Rows>>,
1705 &'a mut [T],
1706 )
1707 where
1708 Rows: 'a,
1709 Cols: 'a,
1710 {
1711 let range = self.col_range(j);
1712 unsafe {
1713 (
1714 self.0.symbolic.row_idx_of_col(j),
1715 self.0.val.get_unchecked_mut(range),
1716 )
1717 }
1718 }
1719
1720 #[inline]
1721 #[track_caller]
1722 pub fn as_shape<V: Shape, H: Shape>(
1724 self,
1725 nrows: V,
1726 ncols: H,
1727 ) -> SparseColMatRef<'a, I, T, V, H> {
1728 SparseColMatRef {
1729 0: numeric::Ref {
1730 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1731 val: self.0.val,
1732 },
1733 }
1734 }
1735
1736 #[inline]
1737 #[track_caller]
1738 pub fn as_shape_mut<V: Shape, H: Shape>(
1740 self,
1741 nrows: V,
1742 ncols: H,
1743 ) -> SparseColMatMut<'a, I, T, V, H> {
1744 SparseColMatMut {
1745 0: numeric::Mut {
1746 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1747 val: self.0.val,
1748 },
1749 }
1750 }
1751
1752 #[inline]
1753 pub fn as_dyn(self) -> SparseColMatRef<'a, I, T> {
1755 SparseColMatRef {
1756 0: numeric::Ref {
1757 symbolic: self.0.symbolic.as_dyn(),
1758 val: self.0.val,
1759 },
1760 }
1761 }
1762
1763 #[track_caller]
1765 #[inline]
1766 pub fn get(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a T> {
1767 self.into_const().get(row, col)
1768 }
1769
1770 #[track_caller]
1771 pub fn get_mut(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a mut T> {
1773 assert!(row < self.nrows());
1774 assert!(col < self.ncols());
1775 let row = I::truncate(row.unbound());
1776 let coll = col.unbound();
1777 let start = self
1778 .symbolic()
1779 .as_dyn()
1780 .row_idx_of_col_raw(coll)
1781 .partition_point(partition_by_lt(row));
1782 let end = start
1783 + self.symbolic().as_dyn().row_idx_of_col_raw(coll)[start..]
1784 .partition_point(partition_by_le(row));
1785 if end == start + 1 {
1786 Some(&mut self.val_of_col_mut(col)[start])
1787 } else {
1788 None
1789 }
1790 }
1791
1792 #[inline]
1793 pub fn as_dyn_mut(self) -> SparseColMatMut<'a, I, T> {
1795 SparseColMatMut {
1796 0: numeric::Mut {
1797 symbolic: self.0.symbolic.as_dyn(),
1798 val: self.0.val,
1799 },
1800 }
1801 }
1802
1803 #[inline]
1804 pub fn transpose(self) -> SparseRowMatRef<'a, I, T, Cols, Rows> {
1806 SparseRowMatRef {
1807 0: super::csr::numeric::Ref {
1808 symbolic: self.0.symbolic.transpose(),
1809 val: self.0.val,
1810 },
1811 }
1812 }
1813
1814 #[inline]
1815 pub fn transpose_mut(self) -> SparseRowMatMut<'a, I, T, Cols, Rows> {
1817 SparseRowMatMut {
1818 0: super::csr::numeric::Mut {
1819 symbolic: self.0.symbolic.transpose(),
1820 val: self.0.val,
1821 },
1822 }
1823 }
1824
1825 #[inline]
1826 pub fn conjugate(self) -> SparseColMatRef<'a, I, T::Conj, Rows, Cols>
1828 where
1829 T: Conjugate,
1830 {
1831 let len = self.0.val.len();
1832 SparseColMatRef {
1833 0: numeric::Ref {
1834 symbolic: self.0.symbolic,
1835 val: unsafe {
1836 core::slice::from_raw_parts(
1837 self.0.val.as_ptr() as *const T::Conj,
1838 len,
1839 )
1840 },
1841 },
1842 }
1843 }
1844
1845 #[inline]
1846 pub fn conjugate_mut(self) -> SparseColMatMut<'a, I, T::Conj, Rows, Cols>
1848 where
1849 T: Conjugate,
1850 {
1851 let len = self.0.val.len();
1852 SparseColMatMut {
1853 0: numeric::Mut {
1854 symbolic: self.0.symbolic,
1855 val: unsafe {
1856 core::slice::from_raw_parts_mut(
1857 self.0.val.as_mut_ptr() as *mut T::Conj,
1858 len,
1859 )
1860 },
1861 },
1862 }
1863 }
1864
1865 #[inline]
1866 pub fn adjoint(self) -> SparseRowMatRef<'a, I, T::Conj, Cols, Rows>
1868 where
1869 T: Conjugate,
1870 {
1871 self.conjugate().transpose()
1872 }
1873
1874 #[inline]
1875 pub fn adjoint_mut(self) -> SparseRowMatMut<'a, I, T::Conj, Cols, Rows>
1877 where
1878 T: Conjugate,
1879 {
1880 self.conjugate_mut().transpose_mut()
1881 }
1882
1883 #[inline]
1884 pub fn canonical(self) -> SparseColMatRef<'a, I, T::Canonical, Rows, Cols>
1886 where
1887 T: Conjugate,
1888 {
1889 let len = self.0.val.len();
1890 SparseColMatRef {
1891 0: numeric::Ref {
1892 symbolic: self.0.symbolic,
1893 val: unsafe {
1894 core::slice::from_raw_parts(
1895 self.0.val.as_ptr() as *const T::Canonical,
1896 len,
1897 )
1898 },
1899 },
1900 }
1901 }
1902
1903 #[inline]
1904 pub fn canonical_mut(
1906 self,
1907 ) -> SparseColMatMut<'a, I, T::Canonical, Rows, Cols>
1908 where
1909 T: Conjugate,
1910 {
1911 let len = self.0.val.len();
1912 SparseColMatMut {
1913 0: numeric::Mut {
1914 symbolic: self.0.symbolic,
1915 val: unsafe {
1916 core::slice::from_raw_parts_mut(
1917 self.0.val.as_mut_ptr() as *mut T::Canonical,
1918 len,
1919 )
1920 },
1921 },
1922 }
1923 }
1924
1925 #[inline]
1926 pub fn to_row_major(
1928 &self,
1929 ) -> Result<SparseRowMat<I, T::Canonical, Rows, Cols>, FaerError>
1930 where
1931 T: Conjugate,
1932 {
1933 self.rb().to_row_major()
1934 }
1935
1936 #[inline]
1937 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1939 where
1940 T: Conjugate,
1941 {
1942 self.rb().to_dense()
1943 }
1944
1945 #[inline]
1947 pub fn triplet_iter(
1948 self,
1949 ) -> impl 'a + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'a T>>
1950 where
1951 Rows: 'a,
1952 Cols: 'a,
1953 {
1954 self.into_const().triplet_iter()
1955 }
1956}
1957impl<Rows: Shape, Cols: Shape, I: Index, T> SparseColMat<I, T, Rows, Cols> {
1958 #[inline]
1959 #[track_caller]
1960 pub fn new(
1962 symbolic: SymbolicSparseColMat<I, Rows, Cols>,
1963 val: alloc::vec::Vec<T>,
1964 ) -> Self {
1965 assert!(symbolic.row_idx().len() == val.len());
1966 Self {
1967 0: numeric::Own { symbolic, val },
1968 }
1969 }
1970
1971 #[inline]
1972 pub fn parts(
1974 &self,
1975 ) -> (SymbolicSparseColMatRef<'_, I, Rows, Cols>, &'_ [T]) {
1976 (self.0.symbolic.rb(), &self.0.val)
1977 }
1978
1979 #[inline]
1980 pub fn parts_mut(
1982 &mut self,
1983 ) -> (SymbolicSparseColMatRef<'_, I, Rows, Cols>, &'_ mut [T]) {
1984 (self.0.symbolic.rb(), &mut self.0.val)
1985 }
1986
1987 #[inline]
1988 pub fn into_parts(
1990 self,
1991 ) -> (SymbolicSparseColMat<I, Rows, Cols>, alloc::vec::Vec<T>) {
1992 (self.0.symbolic, self.0.val)
1993 }
1994
1995 #[inline]
1996 pub fn symbolic(&self) -> SymbolicSparseColMatRef<'_, I, Rows, Cols> {
1998 self.0.symbolic.rb()
1999 }
2000
2001 #[inline]
2002 pub fn val(&self) -> &'_ [T] {
2004 &self.0.val
2005 }
2006
2007 #[inline]
2008 pub fn val_mut(&mut self) -> &'_ mut [T] {
2010 &mut self.0.val
2011 }
2012
2013 #[inline]
2014 #[track_caller]
2015 pub fn val_of_col(&self, j: Idx<Cols>) -> &'_ [T] {
2017 unsafe { self.0.val.get_unchecked(self.col_range(j)) }
2018 }
2019
2020 #[inline]
2021 #[track_caller]
2022 pub fn val_of_col_mut(&mut self, j: Idx<Cols>) -> &'_ mut [T] {
2024 unsafe { self.0.val.get_unchecked_mut(self.0.symbolic.col_range(j)) }
2025 }
2026
2027 #[inline]
2028 #[track_caller]
2029 pub fn as_shape<V: Shape, H: Shape>(
2031 &self,
2032 nrows: V,
2033 ncols: H,
2034 ) -> SparseColMatRef<'_, I, T, V, H> {
2035 SparseColMatRef {
2036 0: numeric::Ref {
2037 symbolic: self.0.symbolic.as_shape(nrows, ncols),
2038 val: &self.0.val,
2039 },
2040 }
2041 }
2042
2043 #[inline]
2044 #[track_caller]
2045 pub fn as_shape_mut<V: Shape, H: Shape>(
2047 &mut self,
2048 nrows: V,
2049 ncols: H,
2050 ) -> SparseColMatMut<'_, I, T, V, H> {
2051 SparseColMatMut {
2052 0: numeric::Mut {
2053 symbolic: self.0.symbolic.as_shape(nrows, ncols),
2054 val: &mut self.0.val,
2055 },
2056 }
2057 }
2058
2059 #[inline]
2060 #[track_caller]
2061 pub fn into_shape<V: Shape, H: Shape>(
2063 self,
2064 nrows: V,
2065 ncols: H,
2066 ) -> SparseColMat<I, T, V, H> {
2067 SparseColMat {
2068 0: numeric::Own {
2069 symbolic: self.0.symbolic.into_shape(nrows, ncols),
2070 val: self.0.val,
2071 },
2072 }
2073 }
2074
2075 #[inline]
2076 pub fn as_dyn(&self) -> SparseColMatRef<'_, I, T> {
2078 SparseColMatRef {
2079 0: numeric::Ref {
2080 symbolic: self.0.symbolic.as_dyn(),
2081 val: &self.0.val,
2082 },
2083 }
2084 }
2085
2086 #[inline]
2087 pub fn as_dyn_mut(&mut self) -> SparseColMatMut<'_, I, T> {
2089 SparseColMatMut {
2090 0: numeric::Mut {
2091 symbolic: self.0.symbolic.as_dyn(),
2092 val: &mut self.0.val,
2093 },
2094 }
2095 }
2096
2097 #[inline]
2098 pub fn into_dyn(self) -> SparseColMat<I, T> {
2100 SparseColMat {
2101 0: numeric::Own {
2102 symbolic: self.0.symbolic.into_dyn(),
2103 val: self.0.val,
2104 },
2105 }
2106 }
2107
2108 #[inline]
2109 pub fn as_ref(&self) -> SparseColMatRef<'_, I, T, Rows, Cols> {
2111 SparseColMatRef {
2112 0: numeric::Ref {
2113 symbolic: self.0.symbolic.as_ref(),
2114 val: &self.0.val,
2115 },
2116 }
2117 }
2118
2119 #[inline]
2120 pub fn transpose(&self) -> SparseRowMatRef<'_, I, T, Cols, Rows> {
2122 SparseRowMatRef {
2123 0: super::csr::numeric::Ref {
2124 symbolic: self.0.symbolic.transpose(),
2125 val: &self.0.val,
2126 },
2127 }
2128 }
2129
2130 #[inline]
2131 pub fn transpose_mut(&mut self) -> SparseRowMatMut<'_, I, T, Cols, Rows> {
2133 SparseRowMatMut {
2134 0: super::csr::numeric::Mut {
2135 symbolic: self.0.symbolic.transpose(),
2136 val: &mut self.0.val,
2137 },
2138 }
2139 }
2140
2141 #[inline]
2142 pub fn into_transpose(self) -> SparseRowMat<I, T, Cols, Rows> {
2144 SparseRowMat {
2145 0: super::csr::numeric::Own {
2146 symbolic: self.0.symbolic.into_transpose(),
2147 val: self.0.val,
2148 },
2149 }
2150 }
2151
2152 #[inline]
2153 pub fn conjugate(&self) -> SparseColMatRef<'_, I, T::Conj, Rows, Cols>
2155 where
2156 T: Conjugate,
2157 {
2158 self.rb().conjugate()
2159 }
2160
2161 #[inline]
2162 pub fn conjugate_mut(
2164 &mut self,
2165 ) -> SparseColMatMut<'_, I, T::Conj, Rows, Cols>
2166 where
2167 T: Conjugate,
2168 {
2169 self.rb_mut().conjugate_mut()
2170 }
2171
2172 #[inline]
2173 pub fn into_conjugate(self) -> SparseColMat<I, T::Conj, Rows, Cols>
2175 where
2176 T: Conjugate,
2177 {
2178 let mut vec = core::mem::ManuallyDrop::new(self.0.val);
2179 let len = vec.len();
2180 let cap = vec.capacity();
2181 let ptr = vec.as_mut_ptr();
2182 SparseColMat {
2183 0: numeric::Own {
2184 symbolic: self.0.symbolic,
2185 val: unsafe {
2186 alloc::vec::Vec::from_raw_parts(
2187 ptr as *mut T::Conj,
2188 len,
2189 cap,
2190 )
2191 },
2192 },
2193 }
2194 }
2195
2196 #[inline]
2197 pub fn adjoint(&self) -> SparseRowMatRef<'_, I, T::Conj, Cols, Rows>
2199 where
2200 T: Conjugate,
2201 {
2202 self.conjugate().transpose()
2203 }
2204
2205 #[inline]
2206 pub fn adjoint_mut(&mut self) -> SparseRowMatMut<'_, I, T::Conj, Cols, Rows>
2208 where
2209 T: Conjugate,
2210 {
2211 self.conjugate_mut().transpose_mut()
2212 }
2213
2214 #[inline]
2215 pub fn into_adjoint(self) -> SparseRowMat<I, T::Conj, Cols, Rows>
2217 where
2218 T: Conjugate,
2219 {
2220 self.into_conjugate().into_transpose()
2221 }
2222
2223 #[inline]
2224 pub fn canonical(&self) -> SparseColMatRef<'_, I, T::Canonical, Rows, Cols>
2226 where
2227 T: Conjugate,
2228 {
2229 let len = self.0.val.len();
2230 SparseColMatRef {
2231 0: numeric::Ref {
2232 symbolic: self.0.symbolic.rb(),
2233 val: unsafe {
2234 core::slice::from_raw_parts(
2235 self.0.val.as_ptr() as *const T::Canonical,
2236 len,
2237 )
2238 },
2239 },
2240 }
2241 }
2242
2243 #[inline]
2244 pub fn canonical_mut(
2246 &mut self,
2247 ) -> SparseColMatMut<'_, I, T::Canonical, Rows, Cols>
2248 where
2249 T: Conjugate,
2250 {
2251 let len = self.0.val.len();
2252 SparseColMatMut {
2253 0: numeric::Mut {
2254 symbolic: self.0.symbolic.rb(),
2255 val: unsafe {
2256 core::slice::from_raw_parts_mut(
2257 self.0.val.as_mut_ptr() as *mut T::Canonical,
2258 len,
2259 )
2260 },
2261 },
2262 }
2263 }
2264
2265 #[inline]
2266 pub fn into_canonical(self) -> SparseColMat<I, T::Canonical, Rows, Cols>
2268 where
2269 T: Conjugate,
2270 {
2271 let mut vec = core::mem::ManuallyDrop::new(self.0.val);
2272 let len = vec.len();
2273 let cap = vec.capacity();
2274 let ptr = vec.as_mut_ptr();
2275 SparseColMat {
2276 0: numeric::Own {
2277 symbolic: self.0.symbolic,
2278 val: unsafe {
2279 alloc::vec::Vec::from_raw_parts(
2280 ptr as *mut T::Canonical,
2281 len,
2282 cap,
2283 )
2284 },
2285 },
2286 }
2287 }
2288
2289 #[inline]
2290 pub fn to_row_major(
2292 &self,
2293 ) -> Result<SparseRowMat<I, T::Canonical, Rows, Cols>, FaerError>
2294 where
2295 T: Conjugate,
2296 {
2297 self.rb().to_row_major()
2298 }
2299
2300 #[inline]
2301 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
2303 where
2304 T: Conjugate,
2305 {
2306 self.rb().to_dense()
2307 }
2308
2309 #[track_caller]
2310 pub(crate) fn new_from_argsort_impl(
2311 symbolic: SymbolicSparseColMat<I, Rows, Cols>,
2312 argsort: &Argsort<I>,
2313 all_values: impl Fn(usize) -> T,
2314 values_len: usize,
2315 ) -> Result<Self, FaerError>
2316 where
2317 T: ComplexField,
2318 {
2319 {
2320 let nnz = argsort.idx.len();
2321 assert!(values_len == nnz);
2322 }
2323 let all_nnz = argsort.all_nnz;
2324 let mut val = alloc::vec::Vec::new();
2325 if val.try_reserve_exact(argsort.nnz).is_err() {
2326 return Err(FaerError::OutOfMemory);
2327 }
2328 let mut pos = 0usize;
2329 let mut pos_unique = usize::MAX;
2330 let top_bit = I::truncate(1 << (I::BITS - 1));
2331 while pos < all_nnz {
2332 let argsort_pos = argsort.idx[pos];
2333 let extracted_bit = argsort_pos & top_bit;
2334 let argsort_pos = (argsort_pos & !top_bit).zx();
2335 let v = all_values(argsort_pos);
2336 if extracted_bit != I::truncate(0) {
2337 val[pos_unique] = add(&val[pos_unique], &v);
2338 } else {
2339 val.push(v);
2340 pos_unique = pos_unique.wrapping_add(1);
2341 }
2342 pos += 1;
2343 }
2344 Ok(Self {
2345 0: numeric::Own { symbolic, val },
2346 })
2347 }
2348
2349 #[track_caller]
2355 pub fn new_from_argsort(
2356 symbolic: SymbolicSparseColMat<I, Rows, Cols>,
2357 argsort: &Argsort<I>,
2358 val: &[T],
2359 ) -> Result<Self, FaerError>
2360 where
2361 T: ComplexField,
2362 {
2363 Self::new_from_argsort_impl(
2364 symbolic,
2365 argsort,
2366 |i| val[i].clone(),
2367 val.len(),
2368 )
2369 }
2370
2371 #[track_caller]
2373 pub fn try_new_from_triplets(
2374 nrows: Rows,
2375 ncols: Cols,
2376 entries: &[Triplet<Idx<Rows, I>, Idx<Cols, I>, T>],
2377 ) -> Result<Self, CreationError>
2378 where
2379 T: ComplexField,
2380 {
2381 let (symbolic, argsort) =
2382 SymbolicSparseColMat::try_new_from_indices_impl(
2383 nrows,
2384 ncols,
2385 |i| Pair {
2386 row: entries[i].row,
2387 col: entries[i].col,
2388 },
2389 |_, _| false,
2390 entries.len(),
2391 )?;
2392 Ok(Self::new_from_argsort_impl(
2393 symbolic,
2394 &argsort,
2395 |i| entries[i].val.clone(),
2396 entries.len(),
2397 )?)
2398 }
2399
2400 #[track_caller]
2404 pub fn try_new_from_nonnegative_triplets(
2405 nrows: Rows,
2406 ncols: Cols,
2407 entries: &[Triplet<MaybeIdx<Rows, I>, MaybeIdx<Cols, I>, T>],
2408 ) -> Result<Self, CreationError>
2409 where
2410 T: ComplexField,
2411 {
2412 let (symbolic, argsort) =
2413 SymbolicSparseColMat::try_new_from_indices_impl(
2414 nrows,
2415 ncols,
2416 |i| Pair {
2417 row: unsafe {
2418 Idx::<Rows, I>::new_unbound(I::from_signed(
2419 entries[i].row.unbound(),
2420 ))
2421 },
2422 col: unsafe {
2423 Idx::<Cols, I>::new_unbound(I::from_signed(
2424 entries[i].col.unbound(),
2425 ))
2426 },
2427 },
2428 |row, col| {
2429 let row = row.unbound().to_signed();
2430 let col = col.unbound().to_signed();
2431 let zero = I::Signed::truncate(0);
2432 row < zero || col < zero
2433 },
2434 entries.len(),
2435 )?;
2436 Ok(Self::new_from_argsort_impl(
2437 symbolic,
2438 &argsort,
2439 |i| entries[i].val.clone(),
2440 entries.len(),
2441 )?)
2442 }
2443
2444 #[track_caller]
2446 #[inline]
2447 pub fn get(&self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&T> {
2448 self.rb().get(row, col)
2449 }
2450
2451 #[track_caller]
2453 #[inline]
2454 pub fn get_mut(
2455 &mut self,
2456 row: Idx<Rows>,
2457 col: Idx<Cols>,
2458 ) -> Option<&mut T> {
2459 self.rb_mut().get_mut(row, col)
2460 }
2461
2462 #[inline]
2464 pub fn triplet_iter(
2465 &self,
2466 ) -> impl '_ + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'_ T>> {
2467 self.rb().triplet_iter()
2468 }
2469}
2470impl<'a, Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref
2471 for SparseColMatRef<'a, I, T, Rows, Cols>
2472{
2473 type Target = SymbolicSparseColMatRef<'a, I, Rows, Cols>;
2474
2475 #[inline]
2476 fn deref(&self) -> &Self::Target {
2477 &self.0.symbolic
2478 }
2479}
2480impl<'a, Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref
2481 for SparseColMatMut<'a, I, T, Rows, Cols>
2482{
2483 type Target = SymbolicSparseColMatRef<'a, I, Rows, Cols>;
2484
2485 #[inline]
2486 fn deref(&self) -> &Self::Target {
2487 &self.0.symbolic
2488 }
2489}
2490impl<Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref
2491 for SparseColMat<I, T, Rows, Cols>
2492{
2493 type Target = SymbolicSparseColMat<I, Rows, Cols>;
2494
2495 #[inline]
2496 fn deref(&self) -> &Self::Target {
2497 &self.0.symbolic
2498 }
2499}
2500impl<Rows: Shape, Cols: Shape, I: Index> fmt::Debug
2501 for symbolic::Ref<'_, I, Rows, Cols>
2502{
2503 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2504 fn imp<'ROWS, 'COLS, I: Index>(
2505 mat: SymbolicSparseColMatRef<'_, I, Dim<'ROWS>, Dim<'COLS>>,
2506 f: &mut fmt::Formatter<'_>,
2507 ) -> fmt::Result {
2508 struct Entries<'a, 'ROWS, 'COLS, I>(
2509 SymbolicSparseColMatRef<'a, I, Dim<'ROWS>, Dim<'COLS>>,
2510 );
2511 impl<'ROWS, 'COLS, I: Index> fmt::Debug for Entries<'_, 'ROWS, 'COLS, I> {
2512 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2513 let mat = self.0;
2514 f.debug_list()
2515 .entries(mat.ncols().indices().flat_map(|col| {
2516 mat.row_idx_of_col(col)
2517 .map(move |row| Pair { row, col })
2518 }))
2519 .finish()
2520 }
2521 }
2522 f.debug_struct("SymbolicSparseColMat")
2523 .field("nrows", &mat.nrows)
2524 .field("ncols", &mat.ncols)
2525 .field("entries", &Entries(mat))
2526 .finish()
2527 }
2528 let this =
2529 symbolic::generic::SymbolicSparseColMat::from_inner_ref(self);
2530 with_dim!(ROWS, this.nrows().unbound());
2531 with_dim!(COLS, this.ncols().unbound());
2532 imp(this.as_shape(ROWS, COLS), f)
2533 }
2534}
2535impl<Rows: Shape, Cols: Shape, I: Index> fmt::Debug
2536 for symbolic::Own<I, Rows, Cols>
2537{
2538 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2539 self.rb().fmt(f)
2540 }
2541}
2542impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug
2543 for numeric::Ref<'_, I, T, Rows, Cols>
2544{
2545 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2546 fn imp<'ROWS, 'COLS, I: Index, T: fmt::Debug>(
2547 mat: SparseColMatRef<'_, I, T, Dim<'ROWS>, Dim<'COLS>>,
2548 f: &mut fmt::Formatter<'_>,
2549 ) -> fmt::Result {
2550 struct Entries<'a, 'ROWS, 'COLS, I, T>(
2551 SparseColMatRef<'a, I, T, Dim<'ROWS>, Dim<'COLS>>,
2552 );
2553 impl<'ROWS, 'COLS, I: Index, T: fmt::Debug> fmt::Debug
2554 for Entries<'_, 'ROWS, 'COLS, I, T>
2555 {
2556 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2557 let mat = self.0;
2558 f.debug_list()
2559 .entries(mat.ncols().indices().flat_map(|col| {
2560 let row_idx = mat.row_idx_of_col(col);
2561 let val = mat.val_of_col(col);
2562 iter::zip(row_idx, val).map(move |(row, val)| {
2563 Triplet {
2564 row,
2565 col,
2566 val: crate::hacks::hijack_debug(val),
2567 }
2568 })
2569 }))
2570 .finish()
2571 }
2572 }
2573 f.debug_struct("SparseColMat")
2574 .field("nrows", &mat.nrows)
2575 .field("ncols", &mat.ncols)
2576 .field("entries", &Entries(mat))
2577 .finish()
2578 }
2579 let this = numeric::generic::SparseColMat::from_inner_ref(self);
2580 with_dim!(ROWS, this.nrows().unbound());
2581 with_dim!(COLS, this.ncols().unbound());
2582 imp(this.as_shape(ROWS, COLS), f)
2583 }
2584}
2585impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug
2586 for SparseColMatMut<'_, I, T, Rows, Cols>
2587{
2588 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2589 self.rb().fmt(f)
2590 }
2591}
2592impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug
2593 for SparseColMat<I, T, Rows, Cols>
2594{
2595 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2596 self.rb().fmt(f)
2597 }
2598}