quantrs2_core/
linalg_stubs.rs1use crate::error::QuantRS2Result;
5use scirs2_core::ndarray::{Array1, Array2, ArrayView2};
6use scirs2_core::Complex64;
7
8#[derive(Debug, Clone)]
10pub struct CsrMatrix<T> {
11 pub data: Vec<T>,
12 pub indices: Vec<usize>,
13 pub indptr: Vec<usize>,
14 pub shape: (usize, usize),
15}
16
17impl<T: Clone + Default> CsrMatrix<T> {
18 pub fn zeros(shape: (usize, usize)) -> Self {
19 Self {
20 data: Vec::new(),
21 indices: Vec::new(),
22 indptr: vec![0; shape.0 + 1],
23 shape,
24 }
25 }
26
27 pub fn new(
28 data: Vec<T>,
29 indices: Vec<usize>,
30 indptr: Vec<usize>,
31 shape: (usize, usize),
32 ) -> Result<Self, String> {
33 Ok(Self {
34 data,
35 indices,
36 indptr,
37 shape,
38 })
39 }
40
41 pub fn shape(&self) -> (usize, usize) {
42 self.shape
43 }
44
45 pub fn nnz(&self) -> usize {
46 self.data.len()
47 }
48}
49
50impl CsrMatrix<Complex64> {
51 pub fn to_dense(&self) -> Array2<Complex64> {
52 let (rows, cols) = self.shape;
53 let mut dense = Array2::zeros((rows, cols));
54
55 for row in 0..rows {
56 let start = self.indptr[row];
57 let end = self.indptr[row + 1];
58
59 for idx in start..end {
60 let col = self.indices[idx];
61 let val = self.data[idx];
62 dense[(row, col)] = val;
63 }
64 }
65
66 dense
67 }
68}
69
70pub struct SvdResult {
72 pub u: Array2<f64>,
73 pub s: Array1<f64>,
74 pub vt: Array2<f64>,
75}
76
77pub fn svd(
79 matrix: &ArrayView2<f64>,
80 full_matrices: bool,
81 compute_uv: Option<bool>,
82) -> QuantRS2Result<(Array2<f64>, Array1<f64>, Array2<f64>)> {
83 use ndarray_linalg::SVD;
84
85 let compute = compute_uv.unwrap_or(true);
86 let (u, s, vt) = matrix
87 .to_owned()
88 .svd(compute, compute)
89 .map_err(|e| crate::error::QuantRS2Error::ComputationError(format!("SVD failed: {}", e)))?;
90
91 Ok((
92 u.unwrap_or_else(|| Array2::zeros((matrix.nrows(), matrix.nrows()))),
93 s,
94 vt.unwrap_or_else(|| Array2::zeros((matrix.ncols(), matrix.ncols()))),
95 ))
96}
97
98pub fn svd_simple(matrix: &Array2<f64>) -> QuantRS2Result<SvdResult> {
100 let (u, s, vt) = svd(&matrix.view(), true, Some(true))?;
101 Ok(SvdResult { u, s, vt })
102}
103
104pub fn randomized_svd(
106 matrix: &ArrayView2<f64>,
107 rank: usize,
108 oversampling: Option<usize>,
109 n_iter: Option<usize>,
110 random_state: Option<u64>,
111) -> QuantRS2Result<(Array2<f64>, Array1<f64>, Array2<f64>)> {
112 let (u, s, vt) = svd(matrix, false, Some(true))?;
114 let k = rank.min(s.len());
115
116 Ok((
117 u.slice(scirs2_core::ndarray::s![.., ..k]).to_owned(),
118 s.slice(scirs2_core::ndarray::s![..k]).to_owned(),
119 vt.slice(scirs2_core::ndarray::s![..k, ..]).to_owned(),
120 ))
121}
122
123pub fn truncated_svd(
125 matrix: &ArrayView2<f64>,
126 rank: usize,
127 random_state: Option<u64>,
128) -> QuantRS2Result<(Array2<f64>, Array1<f64>, Array2<f64>)> {
129 randomized_svd(matrix, rank, Some(10), Some(2), random_state)
130}