use scirs2_io::error::Result;
use scirs2_io::serialize::{
deserialize_enhanced_sparse_matrix, serialize_enhanced_sparse_matrix, sparse_ops,
SerializationFormat, SparseMatrix,
};
use std::time::Instant;
#[allow(dead_code)]
fn main() -> Result<()> {
println!("=== Enhanced Sparse Matrix Serialization Example ===");
demonstrate_sparse_formats()?;
demonstrate_format_conversion()?;
demonstrate_sparse_operations()?;
demonstrate_serialization()?;
demonstrate_memory_analysis()?;
println!("Enhanced sparse matrix example completed successfully!");
Ok(())
}
#[allow(dead_code)]
fn demonstrate_sparse_formats() -> Result<()> {
println!("\n1. Demonstrating different sparse matrix formats...");
let size = 1000;
let mut sparse = SparseMatrix::new(size, size);
println!(" Creating tridiagonal matrix ({}x{})...", size, size);
for i in 0..size {
sparse.insert(i, i, 2.0_f64);
}
for i in 0..size - 1 {
sparse.insert(i, i + 1, -1.0_f64);
}
for i in 1..size {
sparse.insert(i, i - 1, -1.0_f64);
}
println!(" Matrix properties:");
println!(
" Dimensions: {}x{}",
sparse.shape().0,
sparse.shape().1
);
println!(" Non-zeros: {}", sparse.nnz());
println!(" Sparsity: {:.4}%", sparse.sparsity() * 100.0);
println!(" Memory usage: {} bytes", sparse.memory_usage());
println!(" Converting to different formats...");
let start = Instant::now();
let _csr = sparse.to_csr()?;
let csr_time = start.elapsed();
println!(" COO -> CSR conversion: {:?}", csr_time);
let start = Instant::now();
let _csc = sparse.to_csc()?;
let csc_time = start.elapsed();
println!(" COO -> CSC conversion: {:?}", csc_time);
println!(
" Memory usage after conversions: {} bytes",
sparse.memory_usage()
);
Ok(())
}
#[allow(dead_code)]
fn demonstrate_format_conversion() -> Result<()> {
println!("\n2. Demonstrating format conversion performance...");
let sizes = vec![100, 500, 1000];
for size in sizes {
println!(" Testing {}x{} matrix:", size, size);
let mut sparse = create_sample_sparse_matrix(size);
let start = Instant::now();
let csr = sparse.to_csr()?;
let csr_time = start.elapsed();
let csr_nnz = csr.nnz();
let start = Instant::now();
for i in 0..std::cmp::min(100, size) {
if let Some((cols, vals)) = csr.row(i) {
let _row_nnz = cols.len();
}
}
let row_access_time = start.elapsed();
let _ = csr;
let start = Instant::now();
let csc = sparse.to_csc()?;
let csc_time = start.elapsed();
let csc_nnz = csc.nnz();
let start = Instant::now();
for j in 0..std::cmp::min(100, size) {
if let Some((rows, vals)) = csc.column(j) {
let _col_nnz = rows.len();
}
}
let col_access_time = start.elapsed();
println!(" COO -> CSR: {:?} ({} nnz)", csr_time, csr_nnz);
println!(" COO -> CSC: {:?} ({} nnz)", csc_time, csc_nnz);
println!(" CSR row access (100 rows): {:?}", row_access_time);
println!(" CSC column access (100 cols): {:?}", col_access_time);
println!();
}
Ok(())
}
#[allow(dead_code)]
fn demonstrate_sparse_operations() -> Result<()> {
println!("3. Demonstrating sparse matrix operations...");
let size = 100;
let mut matrix_a = create_sample_sparse_matrix(size);
let mut matrix_b = create_sample_sparse_matrix(size);
for i in 0..size / 2 {
matrix_b.insert(i, i, 0.5);
}
println!(
" Matrix A: {}x{} with {} non-zeros",
matrix_a.shape().0,
matrix_a.shape().1,
matrix_a.nnz()
);
println!(
" Matrix B: {}x{} with {} non-zeros",
matrix_b.shape().0,
matrix_b.shape().1,
matrix_b.nnz()
);
println!(" Testing sparse matrix addition...");
let start = Instant::now();
let sum_result = sparse_ops::add_coo(&matrix_a.coo_data, &matrix_b.coo_data)?;
let add_time = start.elapsed();
println!(" Addition completed in {:?}", add_time);
println!(
" Result: {}x{} with {} non-zeros",
sum_result.rows,
sum_result.cols,
sum_result.nnz()
);
println!(" Testing matrix transpose...");
let start = Instant::now();
let transpose_result = sparse_ops::transpose_coo(&matrix_a.coo_data);
let transpose_time = start.elapsed();
println!(" Transpose completed in {:?}", transpose_time);
println!(
" Original: {}x{}, Transposed: {}x{}",
matrix_a.shape().0,
matrix_a.shape().1,
transpose_result.rows,
transpose_result.cols
);
println!(" Testing matrix-vector multiplication...");
let vector = vec![1.0_f64; size];
let csr = matrix_a.to_csr()?;
let start = Instant::now();
let matvec_result = sparse_ops::csr_matvec(csr, &vector)?;
let matvec_time = start.elapsed();
println!(
" Matrix-vector multiplication completed in {:?}",
matvec_time
);
println!(" Result vector length: {}", matvec_result.len());
if matvec_result.len() >= 5 {
println!(" First 5 elements: {:?}", &matvec_result[0..5]);
}
Ok(())
}
#[allow(dead_code)]
fn demonstrate_serialization() -> Result<()> {
println!("\n4. Demonstrating sparse matrix serialization...");
let size = 500;
let mut sparse = create_sample_sparse_matrix(size);
sparse.metadata.insert(
"description".to_string(),
"Test tridiagonal matrix".to_string(),
);
sparse.metadata.insert(
"created_by".to_string(),
"Enhanced sparse example".to_string(),
);
sparse
.metadata
.insert("matrix_type".to_string(), "tridiagonal".to_string());
println!(
" Original matrix: {}x{} with {} non-zeros",
sparse.shape().0,
sparse.shape().1,
sparse.nnz()
);
let formats = vec![
(SerializationFormat::JSON, "sparse_enhanced.json"),
(SerializationFormat::Binary, "sparse_enhanced.bin"),
(SerializationFormat::MessagePack, "sparse_enhanced.msgpack"),
];
for (format, filename) in formats {
println!(" Testing {:?} format...", format);
let start = Instant::now();
serialize_enhanced_sparse_matrix(filename, &sparse, format)?;
let serialize_time = start.elapsed();
let file_size = std::fs::metadata(filename)
.map(|metadata| metadata.len())
.unwrap_or(0);
let start = Instant::now();
let loaded: SparseMatrix<f64> = deserialize_enhanced_sparse_matrix(filename, format)?;
let deserialize_time = start.elapsed();
println!(
" Serialize: {:?}, Deserialize: {:?}",
serialize_time, deserialize_time
);
println!(" File size: {} bytes", file_size);
println!(
" Loaded matrix: {}x{} with {} non-zeros",
loaded.shape().0,
loaded.shape().1,
loaded.nnz()
);
if let Some(description) = loaded.metadata.get("description") {
println!(" Metadata preserved: description = '{}'", description);
}
println!();
}
Ok(())
}
#[allow(dead_code)]
fn demonstrate_memory_analysis() -> Result<()> {
println!("5. Demonstrating memory efficiency analysis...");
let sizes = vec![100, 500, 1000, 2000];
println!(" Matrix Size | Dense Memory | Sparse Memory | Memory Ratio | Sparsity");
println!(" -----------|--------------|---------------|--------------|----------");
for size in sizes {
let sparse = create_sample_sparse_matrix(size);
let dense_memory = size * size * std::mem::size_of::<f64>();
let sparse_memory = sparse.memory_usage();
let memory_ratio = dense_memory as f64 / sparse_memory as f64;
println!(
" {:^10} | {:^11} | {:^12} | {:^11.2} | {:^7.2}%",
format!("{}x{}", size, size),
format_bytes(dense_memory),
format_bytes(sparse_memory),
memory_ratio,
sparse.sparsity() * 100.0
);
}
println!("\n Format efficiency comparison:");
let size = 1000;
let mut sparse = create_sample_sparse_matrix(size);
let coo_memory = sparse.coo_data.values.len()
* (std::mem::size_of::<f64>() + 2 * std::mem::size_of::<usize>());
let csr = sparse.to_csr()?;
let csr_memory = csr.values.len() * std::mem::size_of::<f64>()
+ csr.col_indices.len() * std::mem::size_of::<usize>()
+ csr.row_ptrs.len() * std::mem::size_of::<usize>();
let csc = sparse.to_csc()?;
let csc_memory = csc.values.len() * std::mem::size_of::<f64>()
+ csc.row_indices.len() * std::mem::size_of::<usize>()
+ csc.col_ptrs.len() * std::mem::size_of::<usize>();
println!(" COO format: {} bytes", format_bytes(coo_memory));
println!(" CSR format: {} bytes", format_bytes(csr_memory));
println!(" CSC format: {} bytes", format_bytes(csc_memory));
Ok(())
}
#[allow(dead_code)]
fn create_sample_sparse_matrix(size: usize) -> SparseMatrix<f64> {
let mut sparse = SparseMatrix::new(size, size);
for i in 0..size {
sparse.insert(i, i, 2.0);
}
for i in 0..size - 1 {
sparse.insert(i, i + 1, -1.0);
}
for i in 1..size {
sparse.insert(i, i - 1, -1.0);
}
sparse
}
#[allow(dead_code)]
fn format_bytes(bytes: usize) -> String {
if bytes < 1024 {
format!("{}B", bytes)
} else if bytes < 1024 * 1024 {
format!("{:.1}KB", bytes as f64 / 1024.0)
} else {
format!("{:.1}MB", bytes as f64 / (1024.0 * 1024.0))
}
}
#[allow(dead_code)]
fn demonstrate_matrix_market_integration() -> Result<()> {
println!("6. Demonstrating Matrix Market integration...");
Ok(())
}
#[allow(dead_code)]
mod benchmarks {
use super::*;
pub fn benchmark_format_conversions(size: usize, iterations: usize) -> Result<()> {
println!(
"Benchmarking format conversions for {}x{} matrix ({} iterations):",
size, size, iterations
);
let mut total_csr_time = std::time::Duration::new(0, 0);
let mut total_csc_time = std::time::Duration::new(0, 0);
for _ in 0..iterations {
let mut sparse = create_sample_sparse_matrix(size);
let start = Instant::now();
let _csr = sparse.to_csr()?;
total_csr_time += start.elapsed();
let start = Instant::now();
let _csc = sparse.to_csc()?;
total_csc_time += start.elapsed();
}
println!(
" Average COO -> CSR: {:?}",
total_csr_time / iterations as u32
);
println!(
" Average COO -> CSC: {:?}",
total_csc_time / iterations as u32
);
Ok(())
}
}