russell_lab 1.15.0

Scientific laboratory for linear algebra and numerical mathematics
Documentation
use russell_lab::*;

fn main() -> Result<(), StrError> {
    // matrix
    let s33 = math::SQRT_3 / 3.0;
    #[rustfmt::skip]
    let mut a = Matrix::from(&[
        [-s33, -s33, 1.0],
        [ s33, -s33, 1.0],
        [-s33,  s33, 1.0],
        [ s33,  s33, 1.0],
    ]);
    let a_copy = a.clone();

    // allocate output structures
    let (m, n) = a.dims();
    let min_mn = if m < n { m } else { n };
    let mut s = Vector::new(min_mn);
    let mut u = Matrix::new(m, m);
    let mut vt = Matrix::new(n, n);

    // perform SVD
    mat_svd(&mut s, &mut u, &mut vt, &mut a)?;

    // check
    let s_correct = [2.0, 2.0 / math::SQRT_3, 2.0 / math::SQRT_3];
    vec_approx_eq(&s, &s_correct, 1e-14);

    // check SVD: a == u * s * vt
    let mut usv = Matrix::new(m, n);
    for i in 0..m {
        for j in 0..n {
            for k in 0..min_mn {
                usv.add(i, j, u.get(i, k) * s[k] * vt.get(k, j));
            }
        }
    }
    mat_approx_eq(&usv, &a_copy, 1e-14);
    Ok(())
}