I am trying to compute the SVD of matrices, as a toy example I used a vector.
I ran my code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=00110137fbcbda27c95e9d8791bb97cf
use nalgebra::*;
fn main() {
let x = dmatrix![
1., 0., 0.
];
println!("{}", x);
let svd = x.transpose().svd(true, true);
// dbg!(&svd);
let rank = svd.rank(1e-9);
dbg!(rank);
let x = svd.v_t.as_ref().unwrap().transpose();
println!("v\n{}", svd.v_t.as_ref().unwrap().transpose());
println!("u\n{}", svd.u.as_ref().unwrap().transpose());
let null: OMatrix<_, _, _> = x.columns(rank, 3 - rank).clone_owned();
println!("{}", null);
}
And I get this output before it crashes:
┌ ┐
│ 1 0 0 │
└ ┘
v
┌ ┐
│ 1 │
└ ┘
u
┌ ┐
│ 1 0 0 │
└ ┘
Which is nonsense. u should be a 3x3 matrix by definition, and it should be the identity matrix in this case, where are the missing vectors???
I think nalgebra::linalg::SVD
seems to be a performance-optimized version that deviates from the 'classic' definition of an SVD for MxN
matrices.
If you want this behaviour, use nalgebra_lapack::SVD
instead:
use nalgebra::dmatrix;
use nalgebra_lapack::SVD;
fn main() {
let x = dmatrix![1., 0., 0.];
let svd = SVD::new(x).unwrap();
println!("U: {}", svd.u);
println!("Σ: {}", svd.singular_values);
println!("V_t: {}", svd.vt);
}
U:
┌ ┐
│ 1 │
└ ┘
Σ:
┌ ┐
│ 1 │
└ ┘
V_t:
┌ ┐
│ 1 0 0 │
│ 0 1 0 │
│ 0 0 1 │
└ ┘