Crates.io | single-svdlib |
lib.rs | single-svdlib |
version | |
source | src |
created_at | 2024-12-23 12:58:11.190528+00 |
updated_at | 2025-05-04 21:56:50.96762+00 |
description | A Rust port of LAS2 from SVDLIBC |
homepage | |
repository | |
max_upload_size | |
id | 1493048 |
Cargo.toml error: | TOML parse error at line 21, column 1 | 21 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
A high-performance Rust library for computing Singular Value Decomposition (SVD) on sparse matrices, with support for both Lanczos and randomized SVD algorithms.
f32
and f64
precisionAdd this to your Cargo.toml
:
[dependencies]
single-svdlib = "0.6.0"
use nalgebra_sparse::{coo::CooMatrix, csr::CsrMatrix};
use single_svdlib::laczos::svd_dim_seed;
// Create a matrix in COO format
let mut coo = CooMatrix::<f64>::new(3, 3);
coo.push(0, 0, 1.0); coo.push(0, 1, 16.0); coo.push(0, 2, 49.0);
coo.push(1, 0, 4.0); coo.push(1, 1, 25.0); coo.push(1, 2, 64.0);
coo.push(2, 0, 9.0); coo.push(2, 1, 36.0); coo.push(2, 2, 81.0);
// Convert to CSR for better performance
let csr = CsrMatrix::from(&coo);
// Compute SVD with a fixed random seed
let svd = svd_dim_seed(&csr, 3, 42).unwrap();
// Access the results
let singular_values = &svd.s;
let left_singular_vectors = &svd.ut; // Note: These are transposed
let right_singular_vectors = &svd.vt; // Note: These are transposed
// Reconstruct the original matrix
let reconstructed = svd.recompose();
The Lanczos algorithm is well-suited for sparse matrices of moderate size:
use single_svdlib::laczos;
// Basic SVD computation (uses defaults)
let svd = laczos::svd(&matrix)?;
// SVD with specified target rank
let svd = laczos::svd_dim(&matrix, 10)?;
// SVD with specified target rank and fixed random seed
let svd = laczos::svd_dim_seed(&matrix, 10, 42)?;
// Full control over SVD parameters
let svd = laczos::svd_las2(
&matrix,
dimensions, // upper limit of desired number of dimensions
iterations, // number of Lanczos iterations
end_interval, // interval containing unwanted eigenvalues, e.g. [-1e-30, 1e-30]
kappa, // relative accuracy of eigenvalues, e.g. 1e-6
random_seed, // random seed (0 for automatic)
)?;
For very large sparse matrices, the randomized SVD algorithm offers better performance:
use single_svdlib::randomized;
let svd = randomized::randomized_svd(
&matrix,
target_rank, // desired rank
n_oversamples, // oversampling parameter (typically 5-10)
n_power_iterations, // number of power iterations (typically 2-4)
randomized::PowerIterationNormalizer::QR, // normalization method
Some(42), // random seed (None for automatic)
)?;
For operations on specific columns of a matrix:
use single_svdlib::laczos::masked::MaskedCSRMatrix;
// Create a mask for selected columns
let columns = vec![0, 2, 5, 7]; // Only use these columns
let masked_matrix = MaskedCSRMatrix::with_columns(&csr_matrix, &columns);
// Compute SVD on the masked matrix
let svd = laczos::svd(&masked_matrix)?;
The SVD result contains:
struct SvdRec<T> {
d: usize, // Rank (number of singular values)
ut: Array2<T>, // Transpose of left singular vectors (d x m)
s: Array1<T>, // Singular values (d)
vt: Array2<T>, // Transpose of right singular vectors (d x n)
diagnostics: Diagnostics<T>, // Computation diagnostics
}
Note that ut
and vt
are returned in transposed form.
Each SVD computation returns detailed diagnostics:
let svd = laczos::svd(&matrix)?;
println!("Non-zero elements: {}", svd.diagnostics.non_zero);
println!("Transposed during computation: {}", svd.diagnostics.transposed);
println!("Lanczos steps: {}", svd.diagnostics.lanczos_steps);
println!("Significant values found: {}", svd.diagnostics.significant_values);
Choose the right algorithm:
Matrix format matters:
Adjust parameters for very sparse matrices:
kappa
value in Lanczos for very sparse matricesConsider column masking for operations that only need a subset of the data
This crate is licensed under the BSD License, the same as the original SVDLIBC implementation. See the SVDLIBC-LICENSE.txt
file for details.