Construction & Conversion
Sparse matrices can be built directly in CSR or CSC format, or assembled from unordered
(row, col, value) triplets via CooMatrix and converted afterward. The three examples
below construct a matrix in each of the three formats:
#![allow(unused)]
fn main() {
use rustebra::sparse::CooMatrix;
pub(crate) fn run() {
println!("\n== CooMatrix ==");
let eye = CooMatrix::new(3, 3, vec![0, 1, 2], vec![0, 1, 2], vec![1.0_f64, 1.0, 1.0])
.expect("valid COO triplets");
println!("3×3 identity:");
println!(
" rows={}, cols={}, nnz={}",
eye.rows(),
eye.cols(),
eye.nnz()
);
println!(" row_indices = {:?}", eye.row_indices());
println!(" col_indices = {:?}", eye.col_indices());
println!(" values = {:?}", eye.values());
// Duplicate (row, col) entries are legal — they are summed on conversion.
let dup = CooMatrix::new(2, 2, vec![0, 0, 1], vec![0, 0, 1], vec![3.0_f64, 4.0, 5.0])
.expect("valid COO with duplicate at (0,0)");
println!(
"with duplicate at (0,0): nnz={} (summed on coo_to_csr)",
dup.nnz()
);
}
}
#![allow(unused)]
fn main() {
use rustebra::sparse::CsrMatrix;
pub(crate) fn run() {
println!("\n== CsrMatrix ==");
// row_ptr has rows+1 entries; row_ptr[i]..row_ptr[i+1] spans row i.
let eye = CsrMatrix::new(
3,
3,
vec![0, 1, 2, 3],
vec![0, 1, 2],
vec![1.0_f64, 1.0, 1.0],
)
.expect("valid CSR arrays");
println!("3×3 identity:");
println!(
" rows={}, cols={}, nnz={}",
eye.rows(),
eye.cols(),
eye.nnz()
);
println!(" row_ptr = {:?}", eye.row_ptr());
println!(" col_indices = {:?}", eye.col_indices());
println!(" values = {:?}", eye.values());
println!(" row_range(1) = {:?}", eye.row_range(1));
}
}
#![allow(unused)]
fn main() {
use rustebra::sparse::CscMatrix;
pub(crate) fn run() {
println!("\n== CscMatrix ==");
// col_ptr has cols+1 entries; col_ptr[j]..col_ptr[j+1] spans column j.
let eye = CscMatrix::new(
3,
3,
vec![0, 1, 2, 3],
vec![0, 1, 2],
vec![1.0_f64, 1.0, 1.0],
)
.expect("valid CSC arrays");
println!("3×3 identity:");
println!(
" rows={}, cols={}, nnz={}",
eye.rows(),
eye.cols(),
eye.nnz()
);
println!(" col_ptr = {:?}", eye.col_ptr());
println!(" row_indices = {:?}", eye.row_indices());
println!(" values = {:?}", eye.values());
println!(" col_range(2) = {:?}", eye.col_range(2));
}
}
CooMatrix tolerates duplicate (row, col) triplets — they’re logically summed when the
matrix is later used, e.g. by conversion to CSR. Converting between formats is a distinct
step from construction; the example below covers all four conversion functions
(coo_to_csr, csr_to_coo, csr_to_csc, csc_to_csr):
#![allow(unused)]
fn main() {
use rustebra::sparse::{
CooMatrix, CscMatrix, CsrMatrix, SortedCsrMatrix, coo_to_csr, csc_to_csr, csr_to_coo,
csr_to_csc,
};
pub(crate) fn run() {
println!("\n== convert ==");
// coo_to_csr: duplicate (row, col) entries are summed; columns sorted per row.
let coo = CooMatrix::new(2, 2, vec![0, 0, 1], vec![0, 0, 1], vec![3.0_f64, 4.0, 5.0])
.expect("valid COO");
let csr: SortedCsrMatrix<f64> = coo_to_csr(coo).expect("dimensions fit within limits");
println!("coo_to_csr (duplicate (0,0) summed: 3+4=7):");
println!(
" row_ptr={:?} col_indices={:?} values={:?}",
csr.row_ptr(),
csr.col_indices(),
csr.values()
);
// csr_to_coo: expands row_ptr into explicit row indices.
let csr_eye = CsrMatrix::new(
3,
3,
vec![0, 1, 2, 3],
vec![0, 1, 2],
vec![1.0_f64, 1.0, 1.0],
)
.expect("valid CSR");
let coo_out = csr_to_coo(csr_eye).expect("dimensions fit within limits");
println!(
"\ncsr_to_coo (3×3 identity): row_indices={:?}",
coo_out.row_indices()
);
// csr_to_csc: transposes storage layout, sorted by (col, row).
let csr_rect = CsrMatrix::new(
2,
3,
vec![0, 2, 4],
vec![0, 2, 1, 2],
vec![1.0_f64, 2.0, 3.0, 4.0],
)
.expect("valid 2×3 CSR");
let csc_out = csr_to_csc(csr_rect).expect("dimensions fit within limits");
println!("\ncsr_to_csc (2×3):");
println!(
" col_ptr={:?} row_indices={:?} values={:?}",
csc_out.col_ptr(),
csc_out.row_indices(),
csc_out.values()
);
// csc_to_csr: transposes back, sorted by (row, col).
let csc_eye = CscMatrix::new(
3,
3,
vec![0, 1, 2, 3],
vec![0, 1, 2],
vec![1.0_f64, 1.0, 1.0],
)
.expect("valid CSC");
let csr_back = csc_to_csr(csc_eye).expect("dimensions fit within limits");
println!(
"\ncsc_to_csr (3×3 identity): row_ptr={:?}",
csr_back.row_ptr()
);
}
}
Gotchas
coo_to_csrsums duplicate(row, col)entries and sorts column indices within each row as a side effect, which is why it returns aSortedCsrMatrixrather than a plainCsrMatrix— you get the stronger guarantee “for free” from the conversion algorithm.CsrMatrix::new/CscMatrix::new/CooMatrix::newall returnResultrather than panicking on malformed input (mismatched array lengths, out-of-bounds indices, an invalid pointer array) — check the result rather than assuming construction always succeeds.