1use crate::coo::CooMatrix;
7use crate::csc::CscMatrix;
8use crate::csr::CsrMatrix;
9use crate::error::SparseResult;
10use scirs2_core::ndarray::Array2;
11
12#[allow(dead_code)]
37pub fn dense_to_csr(dense: &Array2<f64>) -> SparseResult<CsrMatrix<f64>> {
38 let shape = dense.dim();
39 let (rows, cols) = (shape.0, shape.1);
40
41 let mut data = Vec::new();
42 let mut row_indices = Vec::new();
43 let mut col_indices = Vec::new();
44
45 for i in 0..rows {
46 for j in 0..cols {
47 let val = dense[[i, j]];
48 if val != 0.0 {
49 data.push(val);
50 row_indices.push(i);
51 col_indices.push(j);
52 }
53 }
54 }
55
56 CsrMatrix::new(data, row_indices, col_indices, (rows, cols))
57}
58
59#[allow(dead_code)]
69pub fn dense_to_csc(dense: &Array2<f64>) -> SparseResult<CscMatrix<f64>> {
70 let shape = dense.dim();
71 let (rows, cols) = (shape.0, shape.1);
72
73 let mut data = Vec::new();
74 let mut row_indices = Vec::new();
75 let mut col_indices = Vec::new();
76
77 for i in 0..rows {
78 for j in 0..cols {
79 let val = dense[[i, j]];
80 if val != 0.0 {
81 data.push(val);
82 row_indices.push(i);
83 col_indices.push(j);
84 }
85 }
86 }
87
88 CscMatrix::new(data, row_indices, col_indices, (rows, cols))
89}
90
91#[allow(dead_code)]
101pub fn dense_to_coo(dense: &Array2<f64>) -> SparseResult<CooMatrix<f64>> {
102 let shape = dense.dim();
103 let (rows, cols) = (shape.0, shape.1);
104
105 let mut data = Vec::new();
106 let mut row_indices = Vec::new();
107 let mut col_indices = Vec::new();
108
109 for i in 0..rows {
110 for j in 0..cols {
111 let val = dense[[i, j]];
112 if val != 0.0 {
113 data.push(val);
114 row_indices.push(i);
115 col_indices.push(j);
116 }
117 }
118 }
119
120 CooMatrix::new(data, row_indices, col_indices, (rows, cols))
121}
122
123#[allow(dead_code)]
133pub fn csr_to_dense(sparse: &CsrMatrix<f64>) -> Array2<f64> {
134 let (rows, cols) = sparse.shape();
135 let mut dense = Array2::zeros((rows, cols));
136
137 let dense_vec = sparse.to_dense();
138 for i in 0..rows {
139 for j in 0..cols {
140 dense[[i, j]] = dense_vec[i][j];
141 }
142 }
143
144 dense
145}
146
147#[allow(dead_code)]
157pub fn csc_to_dense(sparse: &CscMatrix<f64>) -> Array2<f64> {
158 let (rows, cols) = sparse.shape();
159 let mut dense = Array2::zeros((rows, cols));
160
161 let dense_vec = sparse.to_dense();
162 for i in 0..rows {
163 for j in 0..cols {
164 dense[[i, j]] = dense_vec[i][j];
165 }
166 }
167
168 dense
169}
170
171#[allow(dead_code)]
181pub fn coo_to_dense(sparse: &CooMatrix<f64>) -> Array2<f64> {
182 let (rows, cols) = sparse.shape();
183 let mut dense = Array2::zeros((rows, cols));
184
185 let dense_vec = sparse.to_dense();
186 for i in 0..rows {
187 for j in 0..cols {
188 dense[[i, j]] = dense_vec[i][j];
189 }
190 }
191
192 dense
193}
194
195#[allow(dead_code)]
205pub fn csr_to_coo(csr: &CsrMatrix<f64>) -> CooMatrix<f64> {
206 let (rows, cols) = csr.shape();
207 let dense = csr.to_dense();
208
209 let mut data = Vec::new();
210 let mut row_indices = Vec::new();
211 let mut col_indices = Vec::new();
212
213 for (i, row) in dense.iter().enumerate().take(rows) {
214 for (j, &val) in row.iter().enumerate().take(cols) {
215 if val != 0.0 {
216 data.push(val);
217 row_indices.push(i);
218 col_indices.push(j);
219 }
220 }
221 }
222
223 CooMatrix::new(data, row_indices, col_indices, (rows, cols)).expect("Operation failed")
224}
225
226#[allow(dead_code)]
236pub fn csc_to_coo(csc: &CscMatrix<f64>) -> CooMatrix<f64> {
237 let (rows, cols) = csc.shape();
238 let dense = csc.to_dense();
239
240 let mut data = Vec::new();
241 let mut row_indices = Vec::new();
242 let mut col_indices = Vec::new();
243
244 for (i, row) in dense.iter().enumerate().take(rows) {
245 for (j, &val) in row.iter().enumerate().take(cols) {
246 if val != 0.0 {
247 data.push(val);
248 row_indices.push(i);
249 col_indices.push(j);
250 }
251 }
252 }
253
254 CooMatrix::new(data, row_indices, col_indices, (rows, cols)).expect("Operation failed")
255}
256
257#[allow(dead_code)]
267pub fn coo_to_csr(coo: &CooMatrix<f64>) -> CsrMatrix<f64> {
268 let (rows, cols) = coo.shape();
269 let dense = coo.to_dense();
270
271 let mut data = Vec::new();
272 let mut row_indices = Vec::new();
273 let mut col_indices = Vec::new();
274
275 for (i, row) in dense.iter().enumerate().take(rows) {
276 for (j, &val) in row.iter().enumerate().take(cols) {
277 if val != 0.0 {
278 data.push(val);
279 row_indices.push(i);
280 col_indices.push(j);
281 }
282 }
283 }
284
285 CsrMatrix::new(data, row_indices, col_indices, (rows, cols)).expect("Operation failed")
286}
287
288#[allow(dead_code)]
298pub fn coo_to_csc(coo: &CooMatrix<f64>) -> CscMatrix<f64> {
299 let (rows, cols) = coo.shape();
300 let dense = coo.to_dense();
301
302 let mut data = Vec::new();
303 let mut row_indices = Vec::new();
304 let mut col_indices = Vec::new();
305
306 for (i, row) in dense.iter().enumerate().take(rows) {
307 for (j, &val) in row.iter().enumerate().take(cols) {
308 if val != 0.0 {
309 data.push(val);
310 row_indices.push(i);
311 col_indices.push(j);
312 }
313 }
314 }
315
316 CscMatrix::new(data, row_indices, col_indices, (rows, cols)).expect("Operation failed")
317}
318
319#[allow(dead_code)]
329pub fn csr_to_csc<F>(csr: &CsrMatrix<F>) -> SparseResult<CscMatrix<F>>
330where
331 F: Clone
332 + Copy
333 + std::fmt::Debug
334 + PartialEq
335 + scirs2_core::numeric::Zero
336 + scirs2_core::SparseElement,
337{
338 let (rows, cols) = csr.shape();
340 let mut row_indices = Vec::new();
341 let mut col_indices = Vec::new();
342 let mut values = Vec::new();
343
344 for i in 0..rows {
346 for j in csr.indptr[i]..csr.indptr[i + 1] {
347 if j < csr.indices.len() {
348 let col = csr.indices[j];
349 let val = csr.data[j];
350
351 row_indices.push(i);
352 col_indices.push(col);
353 values.push(val);
354 }
355 }
356 }
357
358 let coo = CooMatrix::new(values, row_indices, col_indices, (rows, cols))?;
360
361 Ok(coo.to_csc())
363}
364
365#[cfg(test)]
366mod tests {
367 use super::*;
368 use approx::assert_relative_eq;
369 use scirs2_core::ndarray::Array2;
370
371 #[test]
372 fn test_dense_to_csr_to_dense() {
373 let dense =
375 Array2::from_shape_vec((3, 3), vec![1.0, 0.0, 2.0, 0.0, 0.0, 3.0, 4.0, 5.0, 0.0])
376 .expect("Operation failed");
377
378 let csr = dense_to_csr(&dense).expect("Operation failed");
380
381 let dense2 = csr_to_dense(&csr);
383
384 for i in 0..3 {
386 for j in 0..3 {
387 assert_relative_eq!(dense[[i, j]], dense2[[i, j]], epsilon = 1e-10);
388 }
389 }
390 }
391
392 #[test]
393 fn test_dense_to_csc_to_dense() {
394 let dense =
396 Array2::from_shape_vec((3, 3), vec![1.0, 0.0, 2.0, 0.0, 0.0, 3.0, 4.0, 5.0, 0.0])
397 .expect("Operation failed");
398
399 let csc = dense_to_csc(&dense).expect("Operation failed");
401
402 let dense2 = csc_to_dense(&csc);
404
405 for i in 0..3 {
407 for j in 0..3 {
408 assert_relative_eq!(dense[[i, j]], dense2[[i, j]], epsilon = 1e-10);
409 }
410 }
411 }
412
413 #[test]
414 fn test_dense_to_coo_to_dense() {
415 let dense =
417 Array2::from_shape_vec((3, 3), vec![1.0, 0.0, 2.0, 0.0, 0.0, 3.0, 4.0, 5.0, 0.0])
418 .expect("Operation failed");
419
420 let coo = dense_to_coo(&dense).expect("Operation failed");
422
423 let dense2 = coo_to_dense(&coo);
425
426 for i in 0..3 {
428 for j in 0..3 {
429 assert_relative_eq!(dense[[i, j]], dense2[[i, j]], epsilon = 1e-10);
430 }
431 }
432 }
433
434 #[test]
435 fn test_format_conversions() {
436 let rows = vec![0, 0, 1, 2, 2];
438 let cols = vec![0, 2, 2, 0, 1];
439 let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
440 let shape = (3, 3);
441
442 let coo = CooMatrix::new(data, rows, cols, shape).expect("Operation failed");
443
444 let csr = coo_to_csr(&coo);
446
447 let coo2 = csr_to_coo(&csr);
449
450 let dense1 = coo.to_dense();
452 let dense2 = coo2.to_dense();
453
454 assert_eq!(dense1, dense2);
455 }
456}