Skip to content

Commit ed1121e

Browse files
author
Ian
committed
added sparse matrix improvement for extremely sparse matrices
1 parent bbe5933 commit ed1121e

File tree

5 files changed

+280
-59
lines changed

5 files changed

+280
-59
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
/target
2+
.idea
3+
.idea/

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description = "A Rust port of LAS2 from SVDLIBC"
44
keywords = ["svd"]
55
categories = ["algorithms", "data-structures", "mathematics", "science"]
66
name = "single-svdlib"
7-
version = "0.2.0"
7+
version = "0.3.0"
88
edition = "2021"
99
license-file = "SVDLIBC-LICENSE.txt"
1010

src/lib.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,46 @@ mod simple_comparison_tests {
1515
use rand::{Rng, SeedableRng};
1616
use rand::rngs::StdRng;
1717

18+
fn create_sparse_matrix(rows: usize, cols: usize, density: f64) -> nalgebra_sparse::coo::CooMatrix<f64> {
19+
use rand::{rngs::StdRng, Rng, SeedableRng};
20+
use std::collections::HashSet;
21+
22+
let mut coo = nalgebra_sparse::coo::CooMatrix::new(rows, cols);
23+
24+
let mut rng = StdRng::seed_from_u64(42);
25+
26+
let nnz = (rows as f64 * cols as f64 * density).round() as usize;
27+
28+
let nnz = nnz.max(1);
29+
30+
let mut positions = HashSet::new();
31+
32+
while positions.len() < nnz {
33+
let i = rng.gen_range(0..rows);
34+
let j = rng.gen_range(0..cols);
35+
36+
if positions.insert((i, j)) {
37+
let val = loop {
38+
let v: f64 = rng.gen_range(-10.0..10.0);
39+
if v.abs() > 1e-10 { // Ensure it's not too close to zero
40+
break v;
41+
}
42+
};
43+
44+
coo.push(i, j, val);
45+
}
46+
}
47+
48+
// Verify the density is as expected
49+
let actual_density = coo.nnz() as f64 / (rows as f64 * cols as f64);
50+
println!("Created sparse matrix: {} x {}", rows, cols);
51+
println!(" - Requested density: {:.6}", density);
52+
println!(" - Actual density: {:.6}", actual_density);
53+
println!(" - Sparsity: {:.4}%", (1.0 - actual_density) * 100.0);
54+
println!(" - Non-zeros: {}", coo.nnz());
55+
56+
coo
57+
}
1858
#[test]
1959
fn simple_matrix_comparison() {
2060
// Create a small, predefined test matrix
@@ -108,6 +148,18 @@ mod simple_comparison_tests {
108148
);
109149
}
110150
}
151+
152+
153+
154+
#[test]
155+
fn test_real_sparse_matrix() {
156+
// Create a matrix with similar sparsity to your real one (99.02%)
157+
let test_matrix = create_sparse_matrix(100, 100, 0.0098); // 0.98% non-zeros
158+
159+
// Should no longer fail with convergence error
160+
let result = svd(&test_matrix); // Using your modified imtqlb
161+
assert!(result.is_ok(), "{}", format!("SVD failed on 99.02% sparse matrix, {:?}", result.err().unwrap()));
162+
}
111163

112164
#[test]
113165
fn f32_precision_test() {

0 commit comments

Comments
 (0)