use russell_lab::{vec_approx_eq, Vector}; use russell_sparse::prelude::*; use russell_sparse::StrError; fn main() -> Result<(), StrError> { // constants let ndim = 5; // number of rows = number of columns let nnz = 13; // number of non-zero values, including duplicates // allocate solver let mut umfpack = SolverUMFPACK::new()?; // allocate the coefficient matrix // 2 3 . . . // 3 . 4 . 6 // . -1 -3 2 . // . . 1 . . // . 4 2 . 1 let mut coo = SparseMatrix::new_coo(ndim, ndim, nnz, Sym::No)?; coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate coo.put(1, 0, 3.0)?; coo.put(0, 1, 3.0)?; coo.put(2, 1, -1.0)?; coo.put(4, 1, 4.0)?; coo.put(1, 2, 4.0)?; coo.put(2, 2, -3.0)?; coo.put(3, 2, 1.0)?; coo.put(4, 2, 2.0)?; coo.put(2, 3, 2.0)?; coo.put(1, 4, 6.0)?; coo.put(4, 4, 1.0)?; // parameters let mut params = LinSolParams::new(); params.verbose = false; params.compute_determinant = true; // call factorize umfpack.factorize(&mut coo, Some(params))?; // allocate x and rhs let mut x = Vector::new(ndim); let rhs = Vector::from(&[8.0, 45.0, -3.0, 3.0, 19.0]); // calculate the solution umfpack.solve(&mut x, &coo, &rhs, false)?; println!("x =\n{}", x); // check the results let correct = vec![1.0, 2.0, 3.0, 4.0, 5.0]; vec_approx_eq(&x, &correct, 1e-14); // analysis let mut stats = StatsLinSol::new(); umfpack.update_stats(&mut stats); let (mx, ex) = (stats.determinant.mantissa_real, stats.determinant.exponent); println!("det(a) = {:?}", mx * f64::powf(10.0, ex)); println!("rcond = {:?}", stats.output.umfpack_rcond_estimate); Ok(()) }