use russell_lab::{Vector, vec_approx_eq};
use russell_sparse::StrError;
use russell_sparse::prelude::*;
fn main() -> Result<(), StrError> {
let ndim = 5; let nnz = 13;
let mut umfpack = SolverUMFPACK::new()?;
let mut coo = CooMatrix::new(ndim, ndim, nnz, Sym::No)?;
coo.put(0, 0, 1.0)?; coo.put(0, 0, 1.0)?; 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)?;
let mut params = LinSolParams::new();
params.verbose = false;
params.compute_determinant = true;
umfpack.factorize(&coo, Some(params))?;
let mut x = Vector::new(ndim);
let rhs = Vector::from(&[8.0, 45.0, -3.0, 3.0, 19.0]);
umfpack.solve(&mut x, &rhs, false)?;
println!("x =\n{}", x);
let correct = vec![1.0, 2.0, 3.0, 4.0, 5.0];
vec_approx_eq(&x, &correct, 1e-14);
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(())
}