use russell_lab::{complex_vec_approx_eq, cpx, vec_approx_eq, Complex64, ComplexVector, Vector};
use russell_sparse::prelude::*;
use russell_sparse::Samples;
fn test_solver(genie: Genie) {
println!("----------------------------------------------------------------------\n");
match genie {
Genie::Klu => println!("Testing KLU solver\n"),
Genie::Mumps => println!("Testing MUMPS solver\n"),
Genie::Umfpack => println!("Testing UMFPACK solver\n"),
}
let mut solver = match LinSolver::new(genie) {
Ok(v) => v,
Err(e) => {
println!("FAIL(new solver): {}", e);
return;
}
};
let (coo, _, _, _) = Samples::umfpack_unsymmetric_5x5();
match solver.actual.factorize(&coo, None) {
Err(e) => {
println!("FAIL(factorize): {}", e);
return;
}
_ => (),
};
let mut x = Vector::new(5);
let rhs = Vector::from(&[8.0, 45.0, -3.0, 3.0, 19.0]);
match solver.actual.solve(&mut x, &rhs, false) {
Err(e) => {
println!("FAIL(solve): {}", e);
return;
}
_ => (),
}
match solver.actual.solve(&mut x, &rhs, false) {
Err(e) => {
println!("FAIL(solve again): {}", e);
return;
}
_ => (),
}
println!("x =\n{}", x);
let x_correct = &[1.0, 2.0, 3.0, 4.0, 5.0];
vec_approx_eq(&x, x_correct, 1e-14);
}
fn test_complex_solver(genie: Genie) {
println!("----------------------------------------------------------------------\n");
match genie {
Genie::Klu => println!("Testing Complex KLU solver\n"),
Genie::Mumps => println!("Testing Complex MUMPS solver\n"),
Genie::Umfpack => println!("Testing Complex UMFPACK solver\n"),
}
let mut solver = match ComplexLinSolver::new(genie) {
Ok(v) => v,
Err(e) => {
println!("FAIL(new solver): {}", e);
return;
}
};
let coo = match genie {
Genie::Klu => Samples::complex_symmetric_3x3_full().0,
Genie::Mumps => Samples::complex_symmetric_3x3_lower().0,
Genie::Umfpack => Samples::complex_symmetric_3x3_full().0,
};
match solver.actual.factorize(&coo, None) {
Err(e) => {
println!("FAIL(factorize): {}", e);
return;
}
_ => (),
};
let mut x = ComplexVector::new(3);
let rhs = ComplexVector::from(&[cpx!(-3.0, 3.0), cpx!(2.0, -2.0), cpx!(9.0, 7.0)]);
match solver.actual.solve(&mut x, &rhs, false) {
Err(e) => {
println!("FAIL(solve): {}", e);
return;
}
_ => (),
}
match solver.actual.solve(&mut x, &rhs, false) {
Err(e) => {
println!("FAIL(solve again): {}", e);
return;
}
_ => (),
}
println!("x =\n{}", x);
let x_correct = &[cpx!(1.0, 1.0), cpx!(2.0, -2.0), cpx!(3.0, 3.0)];
complex_vec_approx_eq(&x, x_correct, 1e-14);
}
fn test_solver_singular(genie: Genie) {
println!("----------------------------------------------------------------------\n");
match genie {
Genie::Klu => println!("Testing KLU solver (singular matrix)\n"),
Genie::Mumps => println!("Testing MUMPS solver (singular matrix)\n"),
Genie::Umfpack => println!("Testing UMFPACK solver (singular matrix)\n"),
}
let (ndim, nnz) = (2, 2);
let mut solver = match LinSolver::new(genie) {
Ok(v) => v,
Err(e) => {
println!("FAIL(new solver): {}", e);
return;
}
};
let mut coo_singular = match CooMatrix::new(ndim, ndim, nnz, Sym::No) {
Ok(v) => v,
Err(e) => {
println!("FAIL(new CooMatrix): {}", e);
return;
}
};
coo_singular.put(0, 0, 1.0).unwrap();
coo_singular.put(1, 0, 1.0).unwrap();
match solver.actual.factorize(&coo_singular, None) {
Err(e) => println!("Ok(factorize singular matrix): {}\n", e),
_ => (),
};
}
fn main() {
test_solver(Genie::Klu);
test_solver(Genie::Mumps);
test_solver(Genie::Umfpack);
test_complex_solver(Genie::Klu);
test_complex_solver(Genie::Mumps);
test_complex_solver(Genie::Umfpack);
test_solver_singular(Genie::Klu);
test_solver_singular(Genie::Mumps);
test_solver_singular(Genie::Umfpack);
println!("----------------------------------------------------------------------\n");
}