mod lu;
mod cholesky;
mod qr;
mod utils;
pub use lu::*;
pub use cholesky::*;
pub use qr::*;
use crate::{linalg, FloatDType, NdArray, Result};
#[derive(Debug, Clone, Copy)]
pub enum SolveMethod {
Lu,
Plu,
Cholesky,
Qr
}
pub fn solve<T: FloatDType>(a: &NdArray<T>, y: &NdArray<T>, method: SolveMethod) -> Result<NdArray<T>> {
match method {
SolveMethod::Lu => linalg::lu_solve(a, y),
SolveMethod::Plu => linalg::plu_solve(a, y),
SolveMethod::Cholesky => linalg::cholesky_solve(a, y),
SolveMethod::Qr => linalg::qr_solve(a, y),
}
}
#[cfg(test)]
mod test {
use crate::{linalg, NdArray};
#[test]
fn test_solve_compare_methods() {
let a = NdArray::new(&[
[4., 2., 0.],
[2., 5., 1.],
[0., 1., 3.],
]).unwrap();
let y = NdArray::from_vec([2., 1., 3.].to_vec(), 3).unwrap();
let x_lu = linalg::solve(&a, &y, linalg::SolveMethod::Lu).unwrap();
let x_chol = linalg::solve(&a, &y, linalg::SolveMethod::Cholesky).unwrap();
let x_qr = linalg::solve(&a, &y, linalg::SolveMethod::Qr).unwrap();
assert!(x_lu.allclose(&x_chol, 1e-6, 1e-6));
assert!(x_lu.allclose(&x_qr, 1e-6, 1e-6));
assert!(x_chol.allclose(&x_qr, 1e-6, 1e-6));
}
#[test]
fn test_big_solve() {
let a = NdArray::<f64>::randn(0.0, 1.0, (7, 7)).unwrap();
let y = NdArray::<f64>::randn(0.0, 1.0, (7,)).unwrap();
let x = linalg::solve(&a, &y, linalg::SolveMethod::Qr).unwrap();
let execpt = a.matmul(&x.unsqueeze(1).unwrap()).unwrap().squeeze(1).unwrap();
assert!(execpt.allclose(&y, 1e-5, 1e-5));
}
}