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 pub mod generic {
11 use core::fmt::Debug;
12 use reborrow::*;
13
14 #[derive(Copy, Clone)]
16 #[repr(transparent)]
17 pub struct SymbolicSparseRowMat<Inner>(pub Inner);
18
19 impl<Inner: Debug> Debug for SymbolicSparseRowMat<Inner> {
20 #[inline(always)]
21 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22 self.0.fmt(f)
23 }
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
40 impl<Inner> core::ops::Deref for SymbolicSparseRowMat<Inner> {
41 type Target = Inner;
42
43 #[inline(always)]
44 fn deref(&self) -> &Self::Target {
45 &self.0
46 }
47 }
48
49 impl<Inner> core::ops::DerefMut for SymbolicSparseRowMat<Inner> {
50 #[inline(always)]
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.0
53 }
54 }
55
56 impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for SymbolicSparseRowMat<Inner> {
57 type Target = SymbolicSparseRowMat<Inner::Target>;
58
59 #[inline(always)]
60 fn rb(&'short self) -> Self::Target {
61 SymbolicSparseRowMat(self.0.rb())
62 }
63 }
64
65 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for SymbolicSparseRowMat<Inner> {
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
74 impl<Inner: IntoConst> IntoConst for SymbolicSparseRowMat<Inner> {
75 type Target = SymbolicSparseRowMat<Inner::Target>;
76
77 #[inline(always)]
78 fn into_const(self) -> Self::Target {
79 SymbolicSparseRowMat(self.0.into_const())
80 }
81 }
82 }
83
84 pub struct Ref<'a, I, Rows = usize, Cols = usize> {
86 pub(crate) nrows: Rows,
87 pub(crate) ncols: Cols,
88 pub(crate) row_ptr: &'a [I],
89 pub(crate) row_nnz: Option<&'a [I]>,
90 pub(crate) col_idx: &'a [I],
91 }
92
93 #[derive(Clone)]
95 pub struct Own<I, Rows = usize, Cols = usize> {
96 pub(crate) nrows: Rows,
97 pub(crate) ncols: Cols,
98 pub(crate) row_ptr: alloc::vec::Vec<I>,
99 pub(crate) row_nnz: Option<alloc::vec::Vec<I>>,
100 pub(crate) col_idx: alloc::vec::Vec<I>,
101 }
102}
103
104pub mod numeric {
106 pub mod generic {
108 use core::fmt::Debug;
109 use reborrow::*;
110
111 #[derive(Copy, Clone)]
113 #[repr(transparent)]
114 pub struct SparseRowMat<Inner>(pub Inner);
115
116 impl<Inner: Debug> Debug for SparseRowMat<Inner> {
117 #[inline(always)]
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119 self.0.fmt(f)
120 }
121 }
122
123 impl<Inner> SparseRowMat<Inner> {
124 #[inline(always)]
126 pub fn from_inner_ref(inner: &Inner) -> &Self {
127 unsafe { &*(inner as *const Inner as *const Self) }
128 }
129
130 #[inline(always)]
132 pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
133 unsafe { &mut *(inner as *mut Inner as *mut Self) }
134 }
135 }
136
137 impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for SparseRowMat<Inner> {
138 type Target = SparseRowMat<Inner::Target>;
139
140 #[inline(always)]
141 fn rb(&'short self) -> Self::Target {
142 SparseRowMat(self.0.rb())
143 }
144 }
145
146 impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for SparseRowMat<Inner> {
147 type Target = SparseRowMat<Inner::Target>;
148
149 #[inline(always)]
150 fn rb_mut(&'short mut self) -> Self::Target {
151 SparseRowMat(self.0.rb_mut())
152 }
153 }
154
155 impl<Inner: IntoConst> IntoConst for SparseRowMat<Inner> {
156 type Target = SparseRowMat<Inner::Target>;
157
158 #[inline(always)]
159 fn into_const(self) -> Self::Target {
160 SparseRowMat(self.0.into_const())
161 }
162 }
163 }
164
165 pub struct Ref<'a, I, T, Rows = usize, Cols = usize> {
167 pub(crate) symbolic: super::SymbolicSparseRowMatRef<'a, I, Rows, Cols>,
168 pub(crate) val: &'a [T],
169 }
170
171 pub struct Mut<'a, I, T, Rows = usize, Cols = usize> {
173 pub(crate) symbolic: super::SymbolicSparseRowMatRef<'a, I, Rows, Cols>,
174 pub(crate) val: &'a mut [T],
175 }
176
177 #[derive(Clone)]
179 pub struct Own<I, T, Rows = usize, Cols = usize> {
180 pub(crate) symbolic: super::SymbolicSparseRowMat<I, Rows, Cols>,
181 pub(crate) val: alloc::vec::Vec<T>,
182 }
183}
184
185pub type SymbolicSparseRowMatRef<'a, I, Rows = usize, Cols = usize> = symbolic::generic::SymbolicSparseRowMat<symbolic::Ref<'a, I, Rows, Cols>>;
210
211pub type SymbolicSparseRowMat<I, Rows = usize, Cols = usize> = symbolic::generic::SymbolicSparseRowMat<symbolic::Own<I, Rows, Cols>>;
216
217pub type SparseRowMatRef<'a, I, T, Rows = usize, Cols = usize> = numeric::generic::SparseRowMat<numeric::Ref<'a, I, T, Rows, Cols>>;
221
222pub type SparseRowMatMut<'a, I, T, Rows = usize, Cols = usize> = numeric::generic::SparseRowMat<numeric::Mut<'a, I, T, Rows, Cols>>;
226
227pub type SparseRowMat<I, T, Rows = usize, Cols = usize> = numeric::generic::SparseRowMat<numeric::Own<I, T, Rows, Cols>>;
231
232impl<'a, I, Rows: Copy, Cols: Copy> Copy for symbolic::Ref<'a, I, Rows, Cols> {}
233impl<'a, I, T, Rows: Copy, Cols: Copy> Copy for numeric::Ref<'a, I, T, Rows, Cols> {}
234
235impl<'a, I, Rows: Copy, Cols: Copy> Clone for symbolic::Ref<'a, I, Rows, Cols> {
236 #[inline]
237 fn clone(&self) -> Self {
238 *self
239 }
240}
241impl<'a, I, T, Rows: Copy, Cols: Copy> Clone for numeric::Ref<'a, I, T, Rows, Cols> {
242 #[inline]
243 fn clone(&self) -> Self {
244 *self
245 }
246}
247
248impl<'a, I, Rows: Copy, Cols: Copy> IntoConst for symbolic::Ref<'a, I, Rows, Cols> {
249 type Target = symbolic::Ref<'a, I, Rows, Cols>;
250
251 #[inline]
252 fn into_const(self) -> Self::Target {
253 self
254 }
255}
256
257impl<'short, 'a, I, Rows: Copy, Cols: Copy> ReborrowMut<'short> for symbolic::Ref<'a, I, Rows, Cols> {
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}
265
266impl<'short, 'a, I, Rows: Copy, Cols: Copy> Reborrow<'short> for symbolic::Ref<'a, I, Rows, Cols> {
267 type Target = symbolic::Ref<'short, I, Rows, Cols>;
268
269 #[inline]
270 fn rb(&'short self) -> Self::Target {
271 *self
272 }
273}
274
275impl<'a, I, T, Rows: Copy, Cols: Copy> IntoConst for numeric::Ref<'a, I, T, Rows, Cols> {
276 type Target = numeric::Ref<'a, I, T, Rows, Cols>;
277
278 #[inline]
279 fn into_const(self) -> Self::Target {
280 self
281 }
282}
283
284impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short> for numeric::Ref<'a, I, T, Rows, Cols> {
285 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
286
287 #[inline]
288 fn rb_mut(&'short mut self) -> Self::Target {
289 *self
290 }
291}
292
293impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> Reborrow<'short> for numeric::Ref<'a, I, T, Rows, Cols> {
294 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
295
296 #[inline]
297 fn rb(&'short self) -> Self::Target {
298 *self
299 }
300}
301
302impl<'a, I, T, Rows: Copy, Cols: Copy> IntoConst for numeric::Mut<'a, I, T, Rows, Cols> {
303 type Target = numeric::Ref<'a, I, T, Rows, Cols>;
304
305 #[inline]
306 fn into_const(self) -> Self::Target {
307 numeric::Ref {
308 symbolic: self.symbolic,
309 val: self.val,
310 }
311 }
312}
313
314impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short> for numeric::Mut<'a, I, T, Rows, Cols> {
315 type Target = numeric::Mut<'short, I, T, Rows, Cols>;
316
317 #[inline]
318 fn rb_mut(&'short mut self) -> Self::Target {
319 numeric::Mut {
320 symbolic: self.symbolic,
321 val: self.val,
322 }
323 }
324}
325
326impl<'short, 'a, I, T, Rows: Copy, Cols: Copy> Reborrow<'short> for numeric::Mut<'a, I, T, Rows, Cols> {
327 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
328
329 #[inline]
330 fn rb(&'short self) -> Self::Target {
331 numeric::Ref {
332 symbolic: self.symbolic,
333 val: self.val,
334 }
335 }
336}
337
338impl<'short, I, T, Rows: Copy, Cols: Copy> ReborrowMut<'short> for numeric::Own<I, T, Rows, Cols> {
339 type Target = numeric::Mut<'short, I, T, Rows, Cols>;
340
341 #[inline]
342 fn rb_mut(&'short mut self) -> Self::Target {
343 numeric::Mut {
344 symbolic: self.symbolic.rb(),
345 val: &mut self.val,
346 }
347 }
348}
349
350impl<'short, I, T, Rows: Copy, Cols: Copy> Reborrow<'short> for numeric::Own<I, T, Rows, Cols> {
351 type Target = numeric::Ref<'short, I, T, Rows, Cols>;
352
353 #[inline]
354 fn rb(&'short self) -> Self::Target {
355 numeric::Ref {
356 symbolic: self.symbolic.rb(),
357 val: &self.val,
358 }
359 }
360}
361
362impl<'short, I, Rows: Copy, Cols: Copy> Reborrow<'short> for symbolic::Own<I, Rows, Cols> {
363 type Target = symbolic::Ref<'short, I, Rows, Cols>;
364
365 #[inline]
366 fn rb(&'short self) -> Self::Target {
367 symbolic::Ref {
368 nrows: self.nrows,
369 ncols: self.ncols,
370 row_ptr: &self.row_ptr,
371 row_nnz: self.row_nnz.as_deref(),
372 col_idx: &self.col_idx,
373 }
374 }
375}
376
377#[inline(always)]
378#[track_caller]
379fn assume_row_ptr<I: Index>(nrows: usize, ncols: usize, row_ptr: &[I], row_nnz: Option<&[I]>, col_idx: &[I]) {
380 assert!(all(ncols <= I::Signed::MAX.zx(), nrows <= I::Signed::MAX.zx(),));
381 assert!(row_ptr.len() == nrows + 1);
382 assert!(row_ptr[nrows].zx() <= col_idx.len());
383 if let Some(row_nnz) = row_nnz {
384 assert!(row_nnz.len() == nrows);
385 }
386}
387
388#[track_caller]
389fn check_row_ptr<I: Index>(nrows: usize, ncols: usize, row_ptr: &[I], row_nnz: Option<&[I]>, col_idx: &[I]) {
390 assert!(all(ncols <= I::Signed::MAX.zx(), nrows <= I::Signed::MAX.zx(),));
391 assert!(row_ptr.len() == nrows + 1);
392 if let Some(row_nnz) = row_nnz {
393 assert!(row_nnz.len() == nrows);
394 for (&nnz_i, &[row, row_next]) in iter::zip(row_nnz, windows2(row_ptr)) {
395 assert!(row <= row_next);
396 assert!(nnz_i <= row_next - row);
397 }
398 } else {
399 for &[row, row_next] in windows2(row_ptr) {
400 assert!(row <= row_next);
401 }
402 }
403 assert!(row_ptr[nrows].zx() <= col_idx.len());
404}
405
406#[track_caller]
407fn check_col_idx<I: Index>(nrows: usize, ncols: usize, row_ptr: &[I], row_nnz: Option<&[I]>, col_idx: &[I]) {
408 _ = nrows;
409 if let Some(row_nnz) = row_nnz {
410 for (nnz, &r) in iter::zip(row_nnz, row_ptr) {
411 let r = r.zx();
412 let nnz = nnz.zx();
413 let col_idx = &col_idx[r..r + nnz];
414 if !col_idx.is_empty() {
415 let mut j = col_idx[0].zx();
416 for &j_next in &col_idx[1..] {
417 let j_next = j_next.zx();
418 assert!(j < j_next);
419 j = j_next;
420 }
421 assert!(j < ncols);
422 }
423 }
424 } else {
425 for &[r, r_next] in windows2(row_ptr) {
426 let col_idx = &col_idx[r.zx()..r_next.zx()];
427 if !col_idx.is_empty() {
428 let mut j = col_idx[0].zx();
429 for &j_next in &col_idx[1..] {
430 let j_next = j_next.zx();
431 assert!(j < j_next);
432 j = j_next;
433 }
434 assert!(j < ncols);
435 }
436 }
437 }
438}
439
440#[track_caller]
441fn check_col_idx_unsorted<I: Index>(nrows: usize, ncols: usize, row_ptr: &[I], row_nnz: Option<&[I]>, col_idx: &[I]) {
442 _ = nrows;
443
444 if let Some(row_nnz) = row_nnz {
445 for (&nnz, &r) in iter::zip(row_nnz, row_ptr) {
446 let r = r.zx();
447 let nnz = nnz.zx();
448 for &j in &col_idx[r..r + nnz] {
449 let j = j.zx();
450 assert!(j < ncols);
451 }
452 }
453 } else {
454 for &[r, r_next] in windows2(row_ptr) {
455 for &j in &col_idx[r.zx()..r_next.zx()] {
456 let j = j.zx();
457 assert!(j < ncols);
458 }
459 }
460 }
461}
462
463impl<'a, Rows: Shape, Cols: Shape, I: Index> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
464 #[inline]
469 #[track_caller]
470 pub unsafe fn new_unchecked(nrows: Rows, ncols: Cols, row_ptr: &'a [I], row_nnz: Option<&'a [I]>, col_idx: &'a [I]) -> Self {
471 assume_row_ptr(nrows.unbound(), ncols.unbound(), row_ptr, row_nnz, col_idx);
472
473 Self {
474 0: symbolic::Ref {
475 nrows,
476 ncols,
477 row_ptr,
478 row_nnz,
479 col_idx,
480 },
481 }
482 }
483
484 #[inline]
489 #[track_caller]
490 pub fn new_checked(nrows: Rows, ncols: Cols, row_ptr: &'a [I], row_nnz: Option<&'a [I]>, col_idx: &'a [I]) -> Self {
491 check_row_ptr(nrows.unbound(), ncols.unbound(), row_ptr, row_nnz, col_idx);
492 check_col_idx(nrows.unbound(), ncols.unbound(), row_ptr, row_nnz, col_idx);
493
494 Self {
495 0: symbolic::Ref {
496 nrows,
497 ncols,
498 row_ptr,
499 row_nnz,
500 col_idx,
501 },
502 }
503 }
504
505 #[inline]
510 #[track_caller]
511 pub fn new_unsorted_checked(nrows: Rows, ncols: Cols, row_ptr: &'a [I], row_nnz: Option<&'a [I]>, col_idx: &'a [I]) -> Self {
512 check_row_ptr(nrows.unbound(), ncols.unbound(), row_ptr, row_nnz, col_idx);
513 check_col_idx_unsorted(nrows.unbound(), ncols.unbound(), row_ptr, row_nnz, col_idx);
514
515 Self {
516 0: symbolic::Ref {
517 nrows,
518 ncols,
519 row_ptr,
520 row_nnz,
521 col_idx,
522 },
523 }
524 }
525
526 #[inline]
533 pub fn parts(self) -> (Rows, Cols, &'a [I], Option<&'a [I]>, &'a [I]) {
534 (self.nrows, self.ncols, self.0.row_ptr, self.0.row_nnz, self.0.col_idx)
535 }
536
537 #[inline]
539 pub fn nrows(&self) -> Rows {
540 self.nrows
541 }
542
543 #[inline]
545 pub fn ncols(&self) -> Cols {
546 self.ncols
547 }
548
549 #[inline]
551 pub fn shape(&self) -> (Rows, Cols) {
552 (self.nrows, self.ncols)
553 }
554
555 #[inline]
557 pub fn transpose(self) -> SymbolicSparseColMatRef<'a, I, Cols, Rows> {
558 SymbolicSparseColMatRef {
559 0: super::csc::symbolic::Ref {
560 nrows: self.ncols,
561 ncols: self.nrows,
562 col_ptr: self.0.row_ptr,
563 col_nnz: self.0.row_nnz,
564 row_idx: self.0.col_idx,
565 },
566 }
567 }
568
569 #[inline]
571 pub fn to_owned(&self) -> Result<SymbolicSparseRowMat<I, Rows, Cols>, FaerError> {
572 Ok(self.transpose().to_owned()?.into_transpose())
573 }
574
575 #[inline]
577 pub fn to_col_major(&self) -> Result<SymbolicSparseColMat<I, Rows, Cols>, FaerError> {
578 Ok(self.transpose().to_row_major()?.into_transpose())
579 }
580
581 #[inline]
583 pub fn compute_nnz(&self) -> usize {
584 self.transpose().compute_nnz()
585 }
586
587 #[inline]
589 pub fn row_ptr(&self) -> &'a [I] {
590 self.0.row_ptr
591 }
592
593 #[inline]
595 pub fn row_nnz(&self) -> Option<&'a [I]> {
596 self.0.row_nnz
597 }
598
599 #[inline]
601 pub fn col_idx(&self) -> &'a [I] {
602 self.0.col_idx
603 }
604
605 #[inline]
607 #[track_caller]
608 pub fn row_range(&self, i: Idx<Rows>) -> Range<usize> {
609 assert!(i < self.nrows());
610 unsafe { self.row_range_unchecked(i) }
611 }
612
613 #[inline]
615 #[track_caller]
616 pub unsafe fn row_range_unchecked(&self, i: Idx<Rows>) -> Range<usize> {
617 debug_assert!(i < self.nrows());
618
619 self.transpose().col_range_unchecked(i)
620 }
621
622 #[inline]
624 #[track_caller]
625 pub fn col_idx_of_row_raw(&self, i: Idx<Rows>) -> &'a [Idx<Cols, I>] {
626 unsafe {
627 let slice = self.0.col_idx.get_unchecked(self.row_range(i));
628 let len = slice.len();
629 core::slice::from_raw_parts(slice.as_ptr() as *const Idx<Cols, I>, len)
630 }
631 }
632
633 #[inline]
635 #[track_caller]
636 pub fn col_idx_of_row(&self, i: Idx<Rows>) -> impl 'a + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Cols>>
637 where
638 Rows: 'a,
639 Cols: 'a,
640 {
641 self.col_idx_of_row_raw(i)
642 .iter()
643 .map(|&j| unsafe { Idx::<Cols>::new_unbound(j.unbound().zx()) })
644 }
645
646 #[inline]
649 #[track_caller]
650 pub fn as_shape<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> SymbolicSparseRowMatRef<'a, I, V, H> {
651 assert!(all(self.nrows.unbound() == nrows.unbound(), self.ncols.unbound() == ncols.unbound()));
652
653 SymbolicSparseRowMatRef {
654 0: symbolic::Ref {
655 nrows,
656 ncols,
657 row_ptr: self.0.row_ptr,
658 row_nnz: self.0.row_nnz,
659 col_idx: self.0.col_idx,
660 },
661 }
662 }
663
664 #[inline]
666 pub fn as_dyn(self) -> SymbolicSparseRowMatRef<'a, I> {
667 SymbolicSparseRowMatRef {
668 0: symbolic::Ref {
669 nrows: self.nrows.unbound(),
670 ncols: self.ncols.unbound(),
671 row_ptr: self.0.row_ptr,
672 row_nnz: self.0.row_nnz,
673 col_idx: self.0.col_idx,
674 },
675 }
676 }
677
678 #[inline]
680 pub fn as_ref(self) -> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
681 SymbolicSparseRowMatRef {
682 0: symbolic::Ref {
683 nrows: self.nrows,
684 ncols: self.ncols,
685 row_ptr: self.0.row_ptr,
686 row_nnz: self.0.row_nnz,
687 col_idx: self.0.col_idx,
688 },
689 }
690 }
691}
692
693impl<Rows: Shape, Cols: Shape, I: Index> SymbolicSparseRowMat<I, Rows, Cols> {
694 #[inline]
695 #[track_caller]
696 pub unsafe fn new_unchecked(
698 nrows: Rows,
699 ncols: Cols,
700 row_ptr: alloc::vec::Vec<I>,
701 row_nnz: Option<alloc::vec::Vec<I>>,
702 col_idx: alloc::vec::Vec<I>,
703 ) -> Self {
704 assume_row_ptr(nrows.unbound(), ncols.unbound(), &row_ptr, row_nnz.as_deref(), &col_idx);
705
706 Self {
707 0: symbolic::Own {
708 nrows,
709 ncols,
710 row_ptr,
711 row_nnz,
712 col_idx,
713 },
714 }
715 }
716
717 #[inline]
718 #[track_caller]
719 pub fn new_checked(
721 nrows: Rows,
722 ncols: Cols,
723 row_ptr: alloc::vec::Vec<I>,
724 row_nnz: Option<alloc::vec::Vec<I>>,
725 col_idx: alloc::vec::Vec<I>,
726 ) -> Self {
727 check_row_ptr(nrows.unbound(), ncols.unbound(), &row_ptr, row_nnz.as_deref(), &col_idx);
728 check_col_idx(nrows.unbound(), ncols.unbound(), &row_ptr, row_nnz.as_deref(), &col_idx);
729
730 Self {
731 0: symbolic::Own {
732 nrows,
733 ncols,
734 row_ptr,
735 row_nnz,
736 col_idx,
737 },
738 }
739 }
740
741 #[inline]
742 #[track_caller]
743 pub fn new_unsorted_checked(
745 nrows: Rows,
746 ncols: Cols,
747 row_ptr: alloc::vec::Vec<I>,
748 row_nnz: Option<alloc::vec::Vec<I>>,
749 col_idx: alloc::vec::Vec<I>,
750 ) -> Self {
751 check_row_ptr(nrows.unbound(), ncols.unbound(), &row_ptr, row_nnz.as_deref(), &col_idx);
752 check_col_idx_unsorted(nrows.unbound(), ncols.unbound(), &row_ptr, row_nnz.as_deref(), &col_idx);
753
754 Self {
755 0: symbolic::Own {
756 nrows,
757 ncols,
758 row_ptr,
759 row_nnz,
760 col_idx,
761 },
762 }
763 }
764
765 #[inline]
766 pub fn parts(&self) -> (Rows, Cols, &'_ [I], Option<&'_ [I]>, &'_ [I]) {
768 (self.nrows, self.ncols, &self.0.row_ptr, self.0.row_nnz.as_deref(), &self.0.col_idx)
769 }
770
771 #[inline]
772 pub fn into_parts(self) -> (Rows, Cols, alloc::vec::Vec<I>, Option<alloc::vec::Vec<I>>, alloc::vec::Vec<I>) {
774 (self.nrows, self.ncols, self.0.row_ptr, self.0.row_nnz, self.0.col_idx)
775 }
776
777 #[inline]
778 pub fn nrows(&self) -> Rows {
780 self.nrows
781 }
782
783 #[inline]
784 pub fn ncols(&self) -> Cols {
786 self.ncols
787 }
788
789 #[inline]
790 pub fn shape(&self) -> (Rows, Cols) {
792 (self.nrows, self.ncols)
793 }
794
795 #[inline]
796 pub fn transpose(&self) -> SymbolicSparseColMatRef<'_, I, Cols, Rows> {
798 self.rb().transpose()
799 }
800
801 #[inline]
802 pub fn into_transpose(self) -> SymbolicSparseColMat<I, Cols, Rows> {
804 SymbolicSparseColMat {
805 0: super::csc::symbolic::Own {
806 nrows: self.ncols,
807 ncols: self.nrows,
808 col_ptr: self.0.row_ptr,
809 col_nnz: self.0.row_nnz,
810 row_idx: self.0.col_idx,
811 },
812 }
813 }
814
815 #[inline]
816 pub fn to_owned(&self) -> Result<SymbolicSparseRowMat<I, Rows, Cols>, FaerError> {
818 self.rb().to_owned()
819 }
820
821 #[inline]
822 pub fn to_col_major(&self) -> Result<SymbolicSparseColMat<I, Rows, Cols>, FaerError> {
824 self.rb().to_col_major()
825 }
826
827 #[inline]
828 pub fn compute_nnz(&self) -> usize {
830 self.rb().compute_nnz()
831 }
832
833 #[inline]
834 pub fn row_ptr(&self) -> &'_ [I] {
836 &self.0.row_ptr
837 }
838
839 #[inline]
840 pub fn row_nnz(&self) -> Option<&'_ [I]> {
842 self.0.row_nnz.as_deref()
843 }
844
845 #[inline]
846 pub fn col_idx(&self) -> &'_ [I] {
848 &self.0.col_idx
849 }
850
851 #[inline]
852 #[track_caller]
853 pub fn row_range(&self, i: Idx<Rows>) -> Range<usize> {
855 self.rb().row_range(i)
856 }
857
858 #[inline]
859 #[track_caller]
860 pub unsafe fn row_range_unchecked(&self, i: Idx<Rows>) -> Range<usize> {
862 self.rb().row_range_unchecked(i)
863 }
864
865 #[inline]
866 #[track_caller]
867 pub fn col_idx_of_row_raw(&self, i: Idx<Rows>) -> &'_ [Idx<Cols, I>] {
869 self.rb().col_idx_of_row_raw(i)
870 }
871
872 #[inline]
873 #[track_caller]
874 pub fn col_idx_of_row(&self, i: Idx<Rows>) -> impl '_ + Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Cols>> {
876 self.rb().col_idx_of_row(i)
877 }
878
879 #[inline]
880 #[track_caller]
881 pub fn as_shape<V: Shape, H: Shape>(&self, nrows: V, ncols: H) -> SymbolicSparseRowMatRef<'_, I, V, H> {
883 self.rb().as_shape(nrows, ncols)
884 }
885
886 #[inline]
887 #[track_caller]
888 pub fn into_shape<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> SymbolicSparseRowMat<I, V, H> {
890 assert!(all(self.nrows().unbound() == nrows.unbound(), self.ncols().unbound() == ncols.unbound()));
891 SymbolicSparseRowMat {
892 0: symbolic::Own {
893 nrows,
894 ncols,
895 row_ptr: self.0.row_ptr,
896 row_nnz: self.0.row_nnz,
897 col_idx: self.0.col_idx,
898 },
899 }
900 }
901
902 #[inline]
903 pub fn as_dyn(&self) -> SymbolicSparseRowMatRef<'_, I> {
905 self.rb().as_dyn()
906 }
907
908 #[inline]
909 pub fn into_dyn(self) -> SymbolicSparseRowMat<I> {
911 SymbolicSparseRowMat {
912 0: symbolic::Own {
913 nrows: self.nrows.unbound(),
914 ncols: self.ncols.unbound(),
915 row_ptr: self.0.row_ptr,
916 row_nnz: self.0.row_nnz,
917 col_idx: self.0.col_idx,
918 },
919 }
920 }
921
922 #[inline]
923 pub fn as_ref(&self) -> SymbolicSparseRowMatRef<'_, I, Rows, Cols> {
925 SymbolicSparseRowMatRef {
926 0: symbolic::Ref {
927 nrows: self.nrows,
928 ncols: self.ncols,
929 row_ptr: &self.0.row_ptr,
930 row_nnz: self.0.row_nnz.as_deref(),
931 col_idx: &self.0.col_idx,
932 },
933 }
934 }
935
936 #[inline]
937 pub fn try_new_from_indices(nrows: Rows, ncols: Cols, idx: &[Pair<Idx<Rows, I>, Idx<Cols, I>>]) -> Result<(Self, Argsort<I>), CreationError> {
940 let (symbolic, argsort) = SymbolicSparseColMat::try_new_from_indices_impl(
941 ncols,
942 nrows,
943 |i| Pair {
944 row: idx[i].col,
945 col: idx[i].row,
946 },
947 |_, _| false,
948 idx.len(),
949 )?;
950
951 Ok((symbolic.into_transpose(), argsort))
952 }
953
954 #[inline]
955 pub fn try_new_from_nonnegative_indices(
960 nrows: Rows,
961 ncols: Cols,
962 idx: &[Pair<MaybeIdx<Rows, I>, MaybeIdx<Cols, I>>],
963 ) -> Result<(Self, Argsort<I>), CreationError> {
964 let (symbolic, argsort) = SymbolicSparseColMat::try_new_from_indices_impl(
965 ncols,
966 nrows,
967 |i| Pair {
968 row: unsafe { Idx::<Cols, I>::new_unbound(I::from_signed(idx[i].col.unbound())) },
969 col: unsafe { Idx::<Rows, I>::new_unbound(I::from_signed(idx[i].row.unbound())) },
970 },
971 |row, col| {
972 let row = row.unbound().to_signed();
973 let col = col.unbound().to_signed();
974 let zero = I::Signed::truncate(0);
975
976 row < zero || col < zero
977 },
978 idx.len(),
979 )?;
980 Ok((symbolic.into_transpose(), argsort))
981 }
982}
983
984impl<'a, Rows: Shape, Cols: Shape, I: Index, T> SparseRowMatRef<'a, I, T, Rows, Cols> {
985 #[inline]
991 #[track_caller]
992 pub fn new(symbolic: SymbolicSparseRowMatRef<'a, I, Rows, Cols>, val: &'a [T]) -> Self {
993 assert!(symbolic.col_idx().len() == val.len());
994 Self {
995 0: numeric::Ref { symbolic, val },
996 }
997 }
998
999 #[inline]
1001 pub fn parts(self) -> (SymbolicSparseRowMatRef<'a, I, Rows, Cols>, &'a [T]) {
1002 (self.0.symbolic, self.0.val)
1003 }
1004
1005 #[inline]
1007 pub fn symbolic(&self) -> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
1008 self.0.symbolic
1009 }
1010
1011 #[inline]
1013 pub fn val(self) -> &'a [T] {
1014 self.0.val
1015 }
1016
1017 #[inline]
1019 #[track_caller]
1020 pub fn val_of_row(self, i: Idx<Rows>) -> &'a [T] {
1021 unsafe { self.0.val.get_unchecked(self.row_range(i)) }
1022 }
1023
1024 #[inline]
1027 #[track_caller]
1028 pub fn as_shape<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> SparseRowMatRef<'a, I, T, V, H> {
1029 SparseRowMatRef {
1030 0: numeric::Ref {
1031 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1032 val: self.0.val,
1033 },
1034 }
1035 }
1036
1037 #[track_caller]
1044 pub fn get(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a T> {
1045 assert!(row < self.nrows());
1046 assert!(col < self.ncols());
1047 let col = I::truncate(col.unbound());
1048 let rowl = row.unbound();
1049 let start = self
1050 .symbolic()
1051 .as_dyn()
1052 .col_idx_of_row_raw(rowl)
1053 .partition_point(super::csc::partition_by_lt(col));
1054 let end = start + self.symbolic().as_dyn().col_idx_of_row_raw(rowl)[start..].partition_point(super::csc::partition_by_le(col));
1055
1056 if end == start + 1 { Some(&self.val_of_row(row)[start]) } else { None }
1057 }
1058
1059 #[inline]
1061 pub fn as_dyn(self) -> SparseRowMatRef<'a, I, T> {
1062 SparseRowMatRef {
1063 0: numeric::Ref {
1064 symbolic: self.0.symbolic.as_dyn(),
1065 val: self.0.val,
1066 },
1067 }
1068 }
1069
1070 #[inline]
1072 pub fn as_ref(self) -> SparseRowMatRef<'a, I, T, Rows, Cols> {
1073 SparseRowMatRef {
1074 0: numeric::Ref {
1075 symbolic: self.0.symbolic,
1076 val: self.0.val,
1077 },
1078 }
1079 }
1080
1081 #[inline]
1083 pub fn transpose(self) -> SparseColMatRef<'a, I, T, Cols, Rows> {
1084 SparseColMatRef {
1085 0: super::csc::numeric::Ref {
1086 symbolic: self.0.symbolic.transpose(),
1087 val: self.0.val,
1088 },
1089 }
1090 }
1091
1092 #[inline]
1094 pub fn conjugate(self) -> SparseRowMatRef<'a, I, T::Conj, Rows, Cols>
1095 where
1096 T: Conjugate,
1097 {
1098 self.transpose().conjugate().transpose()
1099 }
1100
1101 #[inline]
1103 pub fn adjoint(self) -> SparseColMatRef<'a, I, T::Conj, Cols, Rows>
1104 where
1105 T: Conjugate,
1106 {
1107 self.transpose().conjugate()
1108 }
1109
1110 #[inline]
1112 pub fn canonical(self) -> SparseRowMatRef<'a, I, T::Canonical, Rows, Cols>
1113 where
1114 T: Conjugate,
1115 {
1116 self.transpose().canonical().transpose()
1117 }
1118
1119 #[inline]
1122 pub fn to_col_major(&self) -> Result<SparseColMat<I, T::Canonical, Rows, Cols>, FaerError>
1123 where
1124 T: Conjugate,
1125 {
1126 Ok(self.transpose().to_row_major()?.into_transpose())
1127 }
1128
1129 #[inline]
1131 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1132 where
1133 T: Conjugate,
1134 {
1135 fn imp<'ROWS, 'COLS, I: Index, T: Conjugate>(
1136 src: SparseRowMatRef<'_, I, T, Dim<'ROWS>, Dim<'COLS>>,
1137 ) -> Mat<T::Canonical, Dim<'ROWS>, Dim<'COLS>> {
1138 let src = src.canonical();
1139
1140 let mut out = Mat::zeros(src.nrows(), src.ncols());
1141 let M = src.nrows();
1142
1143 for i in M.indices() {
1144 for (j, val) in iter::zip(src.col_idx_of_row(i), src.val_of_row(i)) {
1145 if try_const! { Conj::get::<T>().is_conj() } {
1146 out[(i, j)] = add(&out[(i, j)], &conj(val));
1147 } else {
1148 out[(i, j)] = add(&out[(i, j)], val);
1149 }
1150 }
1151 }
1152
1153 out
1154 }
1155 with_dim!(ROWS, self.nrows().unbound());
1156 with_dim!(COLS, self.ncols().unbound());
1157 let this = self.as_shape(ROWS, COLS);
1158
1159 imp(this).into_shape(self.nrows(), self.ncols())
1160 }
1161
1162 pub fn triplet_iter(self) -> impl 'a + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'a T>>
1164 where
1165 Rows: 'a,
1166 Cols: 'a,
1167 {
1168 self.transpose().triplet_iter().map(
1169 #[inline(always)]
1170 |Triplet { row, col, val }| Triplet { row: col, col: row, val },
1171 )
1172 }
1173}
1174
1175impl<'a, Rows: Shape, Cols: Shape, I: Index, T> SparseRowMatMut<'a, I, T, Rows, Cols> {
1176 #[inline]
1177 #[track_caller]
1178 pub fn new(symbolic: SymbolicSparseRowMatRef<'a, I, Rows, Cols>, val: &'a mut [T]) -> Self {
1180 assert!(symbolic.col_idx().len() == val.len());
1181 Self {
1182 0: numeric::Mut { symbolic, val },
1183 }
1184 }
1185
1186 #[inline]
1187 pub fn parts(self) -> (SymbolicSparseRowMatRef<'a, I, Rows, Cols>, &'a [T]) {
1189 (self.0.symbolic, self.0.val)
1190 }
1191
1192 #[inline]
1193 pub fn parts_mut(self) -> (SymbolicSparseRowMatRef<'a, I, Rows, Cols>, &'a mut [T]) {
1195 (self.0.symbolic, self.0.val)
1196 }
1197
1198 #[inline]
1199 pub fn symbolic(&self) -> SymbolicSparseRowMatRef<'a, I, Rows, Cols> {
1201 self.0.symbolic
1202 }
1203
1204 #[inline]
1205 pub fn val(self) -> &'a [T] {
1207 self.0.val
1208 }
1209
1210 #[inline]
1211 pub fn val_mut(self) -> &'a mut [T] {
1213 self.0.val
1214 }
1215
1216 #[inline]
1217 #[track_caller]
1218 pub fn val_of_row(self, i: Idx<Rows>) -> &'a [T] {
1220 unsafe { self.0.val.get_unchecked(self.row_range(i)) }
1221 }
1222
1223 #[inline]
1224 #[track_caller]
1225 pub fn val_of_row_mut(self, j: Idx<Rows>) -> &'a mut [T] {
1227 unsafe { self.0.val.get_unchecked_mut(self.row_range(j)) }
1228 }
1229
1230 #[inline]
1231 #[track_caller]
1232 pub fn as_shape<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> SparseRowMatRef<'a, I, T, V, H> {
1234 SparseRowMatRef {
1235 0: numeric::Ref {
1236 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1237 val: self.0.val,
1238 },
1239 }
1240 }
1241
1242 #[inline]
1243 #[track_caller]
1244 pub fn as_shape_mut<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> SparseRowMatMut<'a, I, T, V, H> {
1246 SparseRowMatMut {
1247 0: numeric::Mut {
1248 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1249 val: self.0.val,
1250 },
1251 }
1252 }
1253
1254 #[track_caller]
1256 #[inline]
1257 pub fn get(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a T> {
1258 self.into_const().get(row, col)
1259 }
1260
1261 #[track_caller]
1268 pub fn get_mut(self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&'a mut T> {
1270 assert!(row < self.nrows());
1271 assert!(col < self.ncols());
1272 let col = I::truncate(col.unbound());
1273 let rowl = row.unbound();
1274 let start = self
1275 .symbolic()
1276 .as_dyn()
1277 .col_idx_of_row_raw(rowl)
1278 .partition_point(super::csc::partition_by_lt(col));
1279 let end = start + self.symbolic().as_dyn().col_idx_of_row_raw(rowl)[start..].partition_point(super::csc::partition_by_le(col));
1280
1281 if end == start + 1 {
1282 Some(&mut self.val_of_row_mut(row)[start])
1283 } else {
1284 None
1285 }
1286 }
1287
1288 #[inline]
1289 pub fn as_dyn(self) -> SparseRowMatRef<'a, I, T> {
1291 SparseRowMatRef {
1292 0: numeric::Ref {
1293 symbolic: self.0.symbolic.as_dyn(),
1294 val: self.0.val,
1295 },
1296 }
1297 }
1298
1299 #[inline]
1300 pub fn as_dyn_mut(self) -> SparseRowMatMut<'a, I, T> {
1302 SparseRowMatMut {
1303 0: numeric::Mut {
1304 symbolic: self.0.symbolic.as_dyn(),
1305 val: self.0.val,
1306 },
1307 }
1308 }
1309
1310 #[inline]
1311 pub fn transpose(self) -> SparseColMatRef<'a, I, T, Cols, Rows> {
1313 SparseColMatRef {
1314 0: super::csc::numeric::Ref {
1315 symbolic: self.0.symbolic.transpose(),
1316 val: self.0.val,
1317 },
1318 }
1319 }
1320
1321 #[inline]
1322 pub fn transpose_mut(self) -> SparseColMatMut<'a, I, T, Cols, Rows> {
1324 SparseColMatMut {
1325 0: super::csc::numeric::Mut {
1326 symbolic: self.0.symbolic.transpose(),
1327 val: self.0.val,
1328 },
1329 }
1330 }
1331
1332 #[inline]
1333 pub fn conjugate(self) -> SparseRowMatRef<'a, I, T::Conj, Rows, Cols>
1335 where
1336 T: Conjugate,
1337 {
1338 let len = self.0.val.len();
1339 SparseRowMatRef {
1340 0: numeric::Ref {
1341 symbolic: self.0.symbolic,
1342 val: unsafe { core::slice::from_raw_parts(self.0.val.as_ptr() as *const T::Conj, len) },
1343 },
1344 }
1345 }
1346
1347 #[inline]
1348 pub fn conjugate_mut(self) -> SparseRowMatMut<'a, I, T::Conj, Rows, Cols>
1350 where
1351 T: Conjugate,
1352 {
1353 let len = self.0.val.len();
1354 SparseRowMatMut {
1355 0: numeric::Mut {
1356 symbolic: self.0.symbolic,
1357 val: unsafe { core::slice::from_raw_parts_mut(self.0.val.as_mut_ptr() as *mut T::Conj, len) },
1358 },
1359 }
1360 }
1361
1362 #[inline]
1363 pub fn adjoint(self) -> SparseColMatRef<'a, I, T::Conj, Cols, Rows>
1365 where
1366 T: Conjugate,
1367 {
1368 self.conjugate().transpose()
1369 }
1370
1371 #[inline]
1372 pub fn adjoint_mut(self) -> SparseColMatMut<'a, I, T::Conj, Cols, Rows>
1374 where
1375 T: Conjugate,
1376 {
1377 self.conjugate_mut().transpose_mut()
1378 }
1379
1380 #[inline]
1381 pub fn canonical(self) -> SparseRowMatRef<'a, I, T::Canonical, Rows, Cols>
1383 where
1384 T: Conjugate,
1385 {
1386 let len = self.0.val.len();
1387 SparseRowMatRef {
1388 0: numeric::Ref {
1389 symbolic: self.0.symbolic,
1390 val: unsafe { core::slice::from_raw_parts(self.0.val.as_ptr() as *const T::Canonical, len) },
1391 },
1392 }
1393 }
1394
1395 #[inline]
1396 pub fn canonical_mut(self) -> SparseRowMatMut<'a, I, T::Canonical, Rows, Cols>
1398 where
1399 T: Conjugate,
1400 {
1401 let len = self.0.val.len();
1402 SparseRowMatMut {
1403 0: numeric::Mut {
1404 symbolic: self.0.symbolic,
1405 val: unsafe { core::slice::from_raw_parts_mut(self.0.val.as_mut_ptr() as *mut T::Canonical, len) },
1406 },
1407 }
1408 }
1409
1410 #[inline]
1411 pub fn to_col_major(&self) -> Result<SparseColMat<I, T::Canonical, Rows, Cols>, FaerError>
1413 where
1414 T: Conjugate,
1415 {
1416 self.rb().to_col_major()
1417 }
1418
1419 #[inline]
1420 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1422 where
1423 T: Conjugate,
1424 {
1425 self.rb().to_dense()
1426 }
1427
1428 #[inline]
1430 pub fn triplet_iter(self) -> impl 'a + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'a T>>
1431 where
1432 Rows: 'a,
1433 Cols: 'a,
1434 {
1435 self.into_const().triplet_iter()
1436 }
1437}
1438
1439impl<Rows: Shape, Cols: Shape, I: Index, T> SparseRowMat<I, T, Rows, Cols> {
1440 #[inline]
1441 #[track_caller]
1442 pub fn new(symbolic: SymbolicSparseRowMat<I, Rows, Cols>, val: alloc::vec::Vec<T>) -> Self {
1444 assert!(symbolic.col_idx().len() == val.len());
1445 Self {
1446 0: numeric::Own { symbolic, val },
1447 }
1448 }
1449
1450 #[inline]
1451 pub fn parts(&self) -> (SymbolicSparseRowMatRef<'_, I, Rows, Cols>, &'_ [T]) {
1453 (self.0.symbolic.rb(), &self.0.val)
1454 }
1455
1456 #[inline]
1457 pub fn parts_mut(&mut self) -> (SymbolicSparseRowMatRef<'_, I, Rows, Cols>, &'_ mut [T]) {
1459 (self.0.symbolic.rb(), &mut self.0.val)
1460 }
1461
1462 #[inline]
1463 pub fn into_parts(self) -> (SymbolicSparseRowMat<I, Rows, Cols>, alloc::vec::Vec<T>) {
1465 (self.0.symbolic, self.0.val)
1466 }
1467
1468 #[inline]
1469 pub fn symbolic(&self) -> SymbolicSparseRowMatRef<'_, I, Rows, Cols> {
1471 self.0.symbolic.rb()
1472 }
1473
1474 #[inline]
1475 pub fn val(&self) -> &'_ [T] {
1477 &self.0.val
1478 }
1479
1480 #[inline]
1481 pub fn val_mut(&mut self) -> &'_ mut [T] {
1483 &mut self.0.val
1484 }
1485
1486 #[inline]
1487 #[track_caller]
1488 pub fn val_of_row(&self, j: Idx<Rows>) -> &'_ [T] {
1490 unsafe { self.0.val.get_unchecked(self.row_range(j)) }
1491 }
1492
1493 #[inline]
1494 #[track_caller]
1495 pub fn val_of_row_mut(&mut self, j: Idx<Rows>) -> &'_ mut [T] {
1497 unsafe { self.0.val.get_unchecked_mut(self.0.symbolic.row_range(j)) }
1498 }
1499
1500 #[inline]
1501 #[track_caller]
1502 pub fn as_shape<V: Shape, H: Shape>(&self, nrows: V, ncols: H) -> SparseRowMatRef<'_, I, T, V, H> {
1504 SparseRowMatRef {
1505 0: numeric::Ref {
1506 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1507 val: &self.0.val,
1508 },
1509 }
1510 }
1511
1512 #[inline]
1513 #[track_caller]
1514 pub fn as_shape_mut<V: Shape, H: Shape>(&mut self, nrows: V, ncols: H) -> SparseRowMatMut<'_, I, T, V, H> {
1516 SparseRowMatMut {
1517 0: numeric::Mut {
1518 symbolic: self.0.symbolic.as_shape(nrows, ncols),
1519 val: &mut self.0.val,
1520 },
1521 }
1522 }
1523
1524 #[inline]
1525 #[track_caller]
1526 pub fn into_shape<V: Shape, H: Shape>(self, nrows: V, ncols: H) -> SparseRowMat<I, T, V, H> {
1528 SparseRowMat {
1529 0: numeric::Own {
1530 symbolic: self.0.symbolic.into_shape(nrows, ncols),
1531 val: self.0.val,
1532 },
1533 }
1534 }
1535
1536 #[inline]
1537 pub fn as_dyn(&self) -> SparseRowMatRef<'_, I, T> {
1539 SparseRowMatRef {
1540 0: numeric::Ref {
1541 symbolic: self.0.symbolic.as_dyn(),
1542 val: &self.0.val,
1543 },
1544 }
1545 }
1546
1547 #[inline]
1548 pub fn as_dyn_mut(&mut self) -> SparseRowMatMut<'_, I, T> {
1550 SparseRowMatMut {
1551 0: numeric::Mut {
1552 symbolic: self.0.symbolic.as_dyn(),
1553 val: &mut self.0.val,
1554 },
1555 }
1556 }
1557
1558 #[inline]
1559 pub fn into_dyn(self) -> SparseRowMat<I, T> {
1561 SparseRowMat {
1562 0: numeric::Own {
1563 symbolic: self.0.symbolic.into_dyn(),
1564 val: self.0.val,
1565 },
1566 }
1567 }
1568
1569 #[inline]
1570 pub fn as_ref(&self) -> SparseRowMatRef<'_, I, T, Rows, Cols> {
1572 SparseRowMatRef {
1573 0: numeric::Ref {
1574 symbolic: self.0.symbolic.as_ref(),
1575 val: &self.0.val,
1576 },
1577 }
1578 }
1579
1580 #[inline]
1581 pub fn transpose(&self) -> SparseColMatRef<'_, I, T, Cols, Rows> {
1583 SparseColMatRef {
1584 0: super::csc::numeric::Ref {
1585 symbolic: self.0.symbolic.transpose(),
1586 val: &self.0.val,
1587 },
1588 }
1589 }
1590
1591 #[inline]
1592 pub fn transpose_mut(&mut self) -> SparseColMatMut<'_, I, T, Cols, Rows> {
1594 SparseColMatMut {
1595 0: super::csc::numeric::Mut {
1596 symbolic: self.0.symbolic.transpose(),
1597 val: &mut self.0.val,
1598 },
1599 }
1600 }
1601
1602 #[inline]
1603 pub fn into_transpose(self) -> SparseColMat<I, T, Cols, Rows> {
1605 SparseColMat {
1606 0: super::csc::numeric::Own {
1607 symbolic: self.0.symbolic.into_transpose(),
1608 val: self.0.val,
1609 },
1610 }
1611 }
1612
1613 #[inline]
1614 pub fn conjugate(&self) -> SparseRowMatRef<'_, I, T::Conj, Rows, Cols>
1616 where
1617 T: Conjugate,
1618 {
1619 self.rb().conjugate()
1620 }
1621
1622 #[inline]
1623 pub fn conjugate_mut(&mut self) -> SparseRowMatMut<'_, I, T::Conj, Rows, Cols>
1625 where
1626 T: Conjugate,
1627 {
1628 self.rb_mut().conjugate_mut()
1629 }
1630
1631 #[inline]
1632 pub fn into_conjugate(self) -> SparseRowMat<I, T::Conj, Rows, Cols>
1634 where
1635 T: Conjugate,
1636 {
1637 let mut vec = core::mem::ManuallyDrop::new(self.0.val);
1638 let len = vec.len();
1639 let cap = vec.capacity();
1640 let ptr = vec.as_mut_ptr();
1641
1642 SparseRowMat {
1643 0: numeric::Own {
1644 symbolic: self.0.symbolic,
1645 val: unsafe { alloc::vec::Vec::from_raw_parts(ptr as *mut T::Conj, len, cap) },
1646 },
1647 }
1648 }
1649
1650 #[inline]
1651 pub fn adjoint(&self) -> SparseColMatRef<'_, I, T::Conj, Cols, Rows>
1653 where
1654 T: Conjugate,
1655 {
1656 self.conjugate().transpose()
1657 }
1658
1659 #[inline]
1660 pub fn adjoint_mut(&mut self) -> SparseColMatMut<'_, I, T::Conj, Cols, Rows>
1662 where
1663 T: Conjugate,
1664 {
1665 self.conjugate_mut().transpose_mut()
1666 }
1667
1668 #[inline]
1669 pub fn into_adjoint(self) -> SparseColMat<I, T::Conj, Cols, Rows>
1671 where
1672 T: Conjugate,
1673 {
1674 self.into_conjugate().into_transpose()
1675 }
1676
1677 #[inline]
1678 pub fn canonical(&self) -> SparseRowMatRef<'_, I, T::Canonical, Rows, Cols>
1680 where
1681 T: Conjugate,
1682 {
1683 let len = self.0.val.len();
1684 SparseRowMatRef {
1685 0: numeric::Ref {
1686 symbolic: self.0.symbolic.rb(),
1687 val: unsafe { core::slice::from_raw_parts(self.0.val.as_ptr() as *const T::Canonical, len) },
1688 },
1689 }
1690 }
1691
1692 #[inline]
1693 pub fn canonical_mut(&mut self) -> SparseRowMatMut<'_, I, T::Canonical, Rows, Cols>
1695 where
1696 T: Conjugate,
1697 {
1698 let len = self.0.val.len();
1699 SparseRowMatMut {
1700 0: numeric::Mut {
1701 symbolic: self.0.symbolic.rb(),
1702 val: unsafe { core::slice::from_raw_parts_mut(self.0.val.as_mut_ptr() as *mut T::Canonical, len) },
1703 },
1704 }
1705 }
1706
1707 #[inline]
1708 pub fn into_canonical(self) -> SparseRowMat<I, T::Canonical, Rows, Cols>
1710 where
1711 T: Conjugate,
1712 {
1713 let mut vec = core::mem::ManuallyDrop::new(self.0.val);
1714 let len = vec.len();
1715 let cap = vec.capacity();
1716 let ptr = vec.as_mut_ptr();
1717
1718 SparseRowMat {
1719 0: numeric::Own {
1720 symbolic: self.0.symbolic,
1721 val: unsafe { alloc::vec::Vec::from_raw_parts(ptr as *mut T::Canonical, len, cap) },
1722 },
1723 }
1724 }
1725
1726 #[inline]
1727 pub fn to_col_major(&self) -> Result<SparseColMat<I, T::Canonical, Rows, Cols>, FaerError>
1729 where
1730 T: Conjugate,
1731 {
1732 self.rb().to_col_major()
1733 }
1734
1735 #[inline]
1736 pub fn to_dense(&self) -> Mat<T::Canonical, Rows, Cols>
1738 where
1739 T: Conjugate,
1740 {
1741 self.rb().to_dense()
1742 }
1743
1744 #[track_caller]
1745 pub fn new_from_argsort(symbolic: SymbolicSparseRowMat<I, Rows, Cols>, argsort: &Argsort<I>, val: &[T]) -> Result<Self, FaerError>
1750 where
1751 T: ComplexField,
1752 {
1753 Ok(SparseColMat::new_from_argsort(symbolic.into_transpose(), argsort, val)?.into_transpose())
1754 }
1755
1756 #[track_caller]
1757 pub fn try_new_from_triplets(nrows: Rows, ncols: Cols, entries: &[Triplet<Idx<Rows, I>, Idx<Cols, I>, T>]) -> Result<Self, CreationError>
1759 where
1760 T: ComplexField,
1761 {
1762 let (symbolic, argsort) = SymbolicSparseColMat::try_new_from_indices_impl(
1763 ncols,
1764 nrows,
1765 |i| Pair {
1766 row: entries[i].col,
1767 col: entries[i].row,
1768 },
1769 |_, _| false,
1770 entries.len(),
1771 )?;
1772
1773 Ok(SparseColMat::new_from_argsort_impl(symbolic, &argsort, |i| entries[i].val.clone(), entries.len())?.into_transpose())
1774 }
1775
1776 #[track_caller]
1777 pub fn try_new_from_nonnegative_triplets(
1781 nrows: Rows,
1782 ncols: Cols,
1783 entries: &[Triplet<MaybeIdx<Rows, I>, MaybeIdx<Cols, I>, T>],
1784 ) -> Result<Self, CreationError>
1785 where
1786 T: ComplexField,
1787 {
1788 let (symbolic, argsort) = SymbolicSparseColMat::try_new_from_indices_impl(
1789 ncols,
1790 nrows,
1791 |i| Pair {
1792 row: unsafe { Idx::<Cols, I>::new_unbound(I::from_signed(entries[i].col.unbound())) },
1793 col: unsafe { Idx::<Rows, I>::new_unbound(I::from_signed(entries[i].row.unbound())) },
1794 },
1795 |row, col| {
1796 let row = row.unbound().to_signed();
1797 let col = col.unbound().to_signed();
1798 let zero = I::Signed::truncate(0);
1799 row < zero || col < zero
1800 },
1801 entries.len(),
1802 )?;
1803
1804 Ok(SparseColMat::new_from_argsort_impl(symbolic, &argsort, |i| entries[i].val.clone(), entries.len())?.into_transpose())
1805 }
1806
1807 #[track_caller]
1809 #[inline]
1810 pub fn get(&self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&T> {
1811 self.rb().get(row, col)
1812 }
1813
1814 #[track_caller]
1816 #[inline]
1817 pub fn get_mut(&mut self, row: Idx<Rows>, col: Idx<Cols>) -> Option<&mut T> {
1818 self.rb_mut().get_mut(row, col)
1819 }
1820
1821 #[inline]
1823 pub fn triplet_iter(&self) -> impl '_ + Iterator<Item = Triplet<Idx<Rows>, Idx<Cols>, &'_ T>> {
1824 self.rb().triplet_iter()
1825 }
1826}
1827
1828impl<'a, Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref for SparseRowMatRef<'a, I, T, Rows, Cols> {
1829 type Target = SymbolicSparseRowMatRef<'a, I, Rows, Cols>;
1830
1831 #[inline]
1832 fn deref(&self) -> &Self::Target {
1833 &self.0.symbolic
1834 }
1835}
1836
1837impl<'a, Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref for SparseRowMatMut<'a, I, T, Rows, Cols> {
1838 type Target = SymbolicSparseRowMatRef<'a, I, Rows, Cols>;
1839
1840 #[inline]
1841 fn deref(&self) -> &Self::Target {
1842 &self.0.symbolic
1843 }
1844}
1845
1846impl<Rows: Shape, Cols: Shape, I: Index, T> core::ops::Deref for SparseRowMat<I, T, Rows, Cols> {
1847 type Target = SymbolicSparseRowMat<I, Rows, Cols>;
1848
1849 #[inline]
1850 fn deref(&self) -> &Self::Target {
1851 &self.0.symbolic
1852 }
1853}
1854
1855impl<Rows: Shape, Cols: Shape, I: Index> fmt::Debug for symbolic::Ref<'_, I, Rows, Cols> {
1856 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1857 fn imp<'ROWS, 'COLS, I: Index>(mat: SymbolicSparseRowMatRef<'_, I, Dim<'ROWS>, Dim<'COLS>>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1858 struct Entries<'a, 'ROWS, 'COLS, I>(SymbolicSparseRowMatRef<'a, I, Dim<'ROWS>, Dim<'COLS>>);
1859
1860 impl<'ROWS, 'COLS, I: Index> fmt::Debug for Entries<'_, 'ROWS, 'COLS, I> {
1861 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1862 let mat = self.0;
1863
1864 f.debug_list()
1865 .entries(
1866 mat.nrows()
1867 .indices()
1868 .flat_map(|row| mat.col_idx_of_row(row).map(move |col| Pair { row, col })),
1869 )
1870 .finish()
1871 }
1872 }
1873
1874 f.debug_struct("SymbolicSparseRowMat")
1875 .field("nrows", &mat.nrows)
1876 .field("ncols", &mat.ncols)
1877 .field("entries", &Entries(mat))
1878 .finish()
1879 }
1880 let this = symbolic::generic::SymbolicSparseRowMat::from_inner_ref(self);
1881 with_dim!(ROWS, this.nrows().unbound());
1882 with_dim!(COLS, this.ncols().unbound());
1883
1884 imp(this.as_shape(ROWS, COLS), f)
1885 }
1886}
1887
1888impl<Rows: Shape, Cols: Shape, I: Index> fmt::Debug for symbolic::Own<I, Rows, Cols> {
1889 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1890 self.rb().fmt(f)
1891 }
1892}
1893
1894impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug for SparseRowMatRef<'_, I, T, Rows, Cols> {
1895 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1896 fn imp<'ROWS, 'COLS, I: Index, T: fmt::Debug>(
1897 mat: SparseRowMatRef<'_, I, T, Dim<'ROWS>, Dim<'COLS>>,
1898 f: &mut fmt::Formatter<'_>,
1899 ) -> fmt::Result {
1900 struct Entries<'a, 'ROWS, 'COLS, I, T>(SparseRowMatRef<'a, I, T, Dim<'ROWS>, Dim<'COLS>>);
1901
1902 impl<'ROWS, 'COLS, I: Index, T: fmt::Debug> fmt::Debug for Entries<'_, 'ROWS, 'COLS, I, T> {
1903 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1904 let mat = self.0;
1905
1906 f.debug_list()
1907 .entries(mat.nrows().indices().flat_map(|row| {
1908 let col_idx = mat.col_idx_of_row(row);
1909 let val = mat.val_of_row(row);
1910
1911 iter::zip(col_idx, val).map(move |(col, val)| Triplet {
1912 row,
1913 col,
1914 val: crate::hacks::hijack_debug(val),
1915 })
1916 }))
1917 .finish()
1918 }
1919 }
1920
1921 f.debug_struct("SparseRowMat")
1922 .field("nrows", &mat.nrows)
1923 .field("ncols", &mat.ncols)
1924 .field("entries", &Entries(mat))
1925 .finish()
1926 }
1927
1928 with_dim!(ROWS, self.nrows().unbound());
1929 with_dim!(COLS, self.ncols().unbound());
1930
1931 imp(self.as_shape(ROWS, COLS), f)
1932 }
1933}
1934
1935impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug for SparseRowMatMut<'_, I, T, Rows, Cols> {
1936 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1937 self.rb().fmt(f)
1938 }
1939}
1940
1941impl<Rows: Shape, Cols: Shape, I: Index, T: fmt::Debug> fmt::Debug for SparseRowMat<I, T, Rows, Cols> {
1942 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1943 self.rb().fmt(f)
1944 }
1945}