2021-03-01 01:39:18 +08:00
|
|
|
use na::{DMatrix, Matrix3x5};
|
2018-10-22 13:00:10 +08:00
|
|
|
use nl::SVD;
|
2017-08-03 01:38:28 +08:00
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
use crate::proptest::*;
|
|
|
|
use proptest::{prop_assert, proptest};
|
2017-08-03 01:38:28 +08:00
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
proptest! {
|
|
|
|
#[test]
|
|
|
|
fn svd(m in dmatrix()) {
|
|
|
|
let svd = SVD::new(m.clone()).unwrap();
|
|
|
|
let sm = DMatrix::from_partial_diagonal(m.nrows(), m.ncols(), svd.singular_values.as_slice());
|
2017-08-03 01:38:28 +08:00
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
let reconstructed_m = &svd.u * sm * &svd.vt;
|
|
|
|
let reconstructed_m2 = svd.recompose();
|
|
|
|
|
|
|
|
prop_assert!(relative_eq!(reconstructed_m, m, epsilon = 1.0e-7));
|
|
|
|
prop_assert!(relative_eq!(reconstructed_m2, reconstructed_m, epsilon = 1.0e-7));
|
2017-08-03 01:38:28 +08:00
|
|
|
}
|
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
#[test]
|
|
|
|
fn svd_static(m in matrix3x5()) {
|
2017-08-03 01:38:28 +08:00
|
|
|
let svd = SVD::new(m).unwrap();
|
2021-03-01 01:39:18 +08:00
|
|
|
let sm = Matrix3x5::from_partial_diagonal(svd.singular_values.as_slice());
|
2017-08-03 01:38:28 +08:00
|
|
|
|
|
|
|
let reconstructed_m = &svd.u * &sm * &svd.vt;
|
2017-08-14 01:53:04 +08:00
|
|
|
let reconstructed_m2 = svd.recompose();
|
2017-08-03 01:38:28 +08:00
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
prop_assert!(relative_eq!(reconstructed_m, m, epsilon = 1.0e-7));
|
|
|
|
prop_assert!(relative_eq!(reconstructed_m2, m, epsilon = 1.0e-7));
|
2017-08-03 01:38:28 +08:00
|
|
|
}
|
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
#[test]
|
|
|
|
fn pseudo_inverse(m in dmatrix()) {
|
2017-08-03 01:38:28 +08:00
|
|
|
let svd = SVD::new(m.clone()).unwrap();
|
|
|
|
let im = svd.pseudo_inverse(1.0e-7);
|
|
|
|
|
|
|
|
if m.nrows() <= m.ncols() {
|
2021-03-01 01:39:18 +08:00
|
|
|
prop_assert!((&m * &im).is_identity(1.0e-7));
|
2017-08-03 01:38:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if m.nrows() >= m.ncols() {
|
2021-03-01 01:39:18 +08:00
|
|
|
prop_assert!((im * m).is_identity(1.0e-7));
|
2017-08-03 01:38:28 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
#[test]
|
|
|
|
fn pseudo_inverse_static(m in matrix3x5()) {
|
2017-08-03 01:38:28 +08:00
|
|
|
let svd = SVD::new(m).unwrap();
|
|
|
|
let im = svd.pseudo_inverse(1.0e-7);
|
|
|
|
|
2021-03-01 01:39:18 +08:00
|
|
|
prop_assert!((m * im).is_identity(1.0e-7))
|
2017-08-03 01:38:28 +08:00
|
|
|
}
|
|
|
|
}
|