linfa icon indicating copy to clipboard operation
linfa copied to clipboard

linalg svd unwrap issues

Open ADMoreau opened this issue 5 years ago • 8 comments

Maybe this isn't the correct place to ask or maybe I just need a fresh pair of eyes but I'm having trouble using the ndarray-linalg svd function.

the following code throws and error at the unwrap()

    X : &ArrayBase<impl Data<Elem = f64>, Ix2>,
) -> Array2<f64> {
    let temp:Array2<f64> = X.to_owned().clone();
    let (u, s, v) = temp.svd(true, true).unwrap();

while the following does not

    x : &ArrayBase<impl Data<Elem = f64>, Ix2>,
    n_components : f64,
) -> Self {

    let (_n, _m) = x.dim();

    //calculate the array of columnar means
    let mean = x.mean_axis(Axis(0)).unwrap();

    // subtract means from X
    let h:Array2<f64> = Array2::ones((_n, _m));
    let temp:Array2<f64> = h * &mean;
    let b:Array2<f64> = x - &temp;

    // compute SVD
    let (u, sigma, v) = b.svd(true, true).unwrap();

any help would be appreciated

ADMoreau avatar Dec 20 '19 00:12 ADMoreau

Can you post the full backtrace for the case that panics? If the code you are working on is already here on GitHub a link would be useful to clone and reproduce.

LukeMathWalker avatar Dec 22 '19 20:12 LukeMathWalker

Here is the code https://github.com/ADMoreau/Rust-PCA The issue only happens in the rPCA function, PCA works fine. Sorry if the code is hard to read I haven't put all of the docs in yet. backtrace -

[/home/austin/.cargo/registry/src/github.com-1ecc6299db9ec823/ndarray-linalg-0.12.0/src/lapack/svd.rs:83] ldvt = 100

called Result::unwrap() on an Err value: Lapack { return_code: -6 } thread 'rPCA::algorithm::tests::test_rPCA' panicked at 'called Result::unwrap() on an Err value: Lapack { return_code: -6 }', src/libcore/result.rs:1189:5 stack backtrace: 0: backtrace::backtrace::libunwind::trace at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88 1: backtrace::backtrace::trace_unsynchronized at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66 2: std::sys_common::backtrace::_print_fmt at src/libstd/sys_common/backtrace.rs:84 3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt at src/libstd/sys_common/backtrace.rs:61 4: core::fmt::write at src/libcore/fmt/mod.rs:1024 5: std::io::Write::write_fmt at /rustc/4007d4ef26eab44bdabc2b7574d032152264d3ad/src/libstd/io/mod.rs:1428 6: std::io::impls::<impl std::io::Write for alloc::boxed::Box<W>>::write_fmt at src/libstd/io/impls.rs:156 7: std::sys_common::backtrace::_print at src/libstd/sys_common/backtrace.rs:65 8: std::sys_common::backtrace::print at src/libstd/sys_common/backtrace.rs:50 9: std::panicking::default_hook::{{closure}} at src/libstd/panicking.rs:193 10: std::panicking::default_hook at src/libstd/panicking.rs:207 11: std::panicking::rust_panic_with_hook at src/libstd/panicking.rs:471 12: rust_begin_unwind at src/libstd/panicking.rs:375 13: core::panicking::panic_fmt at src/libcore/panicking.rs:82 14: core::result::unwrap_failed at src/libcore/result.rs:1189 15: core::result::Result<T,E>::unwrap at /rustc/4007d4ef26eab44bdabc2b7574d032152264d3ad/src/libcore/result.rs:957 16: processing::rPCA::algorithm::Do at processing/src/rPCA/algorithm.rs:95 17: processing::rPCA::algorithm::rPCA::fit at processing/src/rPCA/algorithm.rs:49 18: processing::rPCA::algorithm::tests::test_rPCA at processing/src/rPCA/algorithm.rs:165 19: processing::rPCA::algorithm::tests::test_rPCA::{{closure}} at processing/src/rPCA/algorithm.rs:158 20: core::ops::function::FnOnce::call_once at /rustc/4007d4ef26eab44bdabc2b7574d032152264d3ad/src/libcore/ops/function.rs:232 21: <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once at /rustc/4007d4ef26eab44bdabc2b7574d032152264d3ad/src/liballoc/boxed.rs:969 22: __rust_maybe_catch_panic at src/libpanic_unwind/lib.rs:81 23: std::panicking::try at /rustc/4007d4ef26eab44bdabc2b7574d032152264d3ad/src/libstd/panicking.rs:270 24: std::panic::catch_unwind at /rustc/4007d4ef26eab44bdabc2b7574d032152264d3ad/src/libstd/panic.rs:394 25: test::run_test_in_process at src/libtest/lib.rs:570 26: test::run_test::run_test_inner::{{closure}} at src/libtest/lib.rs:473 note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

ADMoreau avatar Dec 23 '19 22:12 ADMoreau

If you have any other comments on the code let me know so I can include it before pushing it

ADMoreau avatar Dec 23 '19 22:12 ADMoreau

Ok, I cloned the repo and I managed to reproduce the test panic.

LukeMathWalker avatar Dec 24 '19 16:12 LukeMathWalker

So, the panic doesn't happen the first time Do is called (which contains the call to .svd) - several SVD calls end successfully before you see the one that panics.

The error message on the console says:

thread 'rPCA::algorithm::tests::test_rPCA' panicked at 'called `Result::unwrap()` on an `Err` value: Lapack { return_code: -6 }', src/libcore/result.rs:1188:5

Looking at ndarray-linalg, we can see that the underlying LAPACK routine being called should be dgesvd ( https://github.com/rust-ndarray/ndarray-linalg/blob/cdc6db1fb5442c6e286c57e226933b1285211d92/src/lapack/svd.rs#L83 ).

Checking LAPACK's reference, it seems we are looking at line 291 here - http://www.netlib.org/lapack/explore-html/d1/d7e/group__double_g_esing_ga84fdf22a62b12ff364621e4713ce02f2.html#ga84fdf22a62b12ff364621e4713ce02f2 Now I just need to figure out what it means :sweat_smile:

LukeMathWalker avatar Dec 24 '19 16:12 LukeMathWalker

Could you provide some insights here @termoshtt?

LukeMathWalker avatar Dec 24 '19 17:12 LukeMathWalker

I am bit confused because looking at LAPACK's code, it seems to be erroring because the LDA doesn't satisfy that equation. But this doesn't seem to be the case, given that the LDA is consistently 100 and it doesn't change throughout the computation.

LukeMathWalker avatar Dec 24 '19 17:12 LukeMathWalker

I also reproduced this issue. This unwrap occurs when the input vector temp at https://github.com/ADMoreau/Rust-PCA/blob/1cce2f34e60bfa59faec219fd45a62a14e7471eb/processing/src/rPCA/algorithm.rs#L95 becomes NaN array.

With my some debug code

      let temp: Array2<f64> = X.to_owned().clone();
      println!("temp[0, 0] = {}", temp[(0, 0)]);
      println!("temp[0, 1] = {}", temp[(0, 1)]);
      println!("temp[1, 0] = {}", temp[(1, 0)]);
      let (u, s, v) = temp.svd(true, true).unwrap();

the end of log becomes following:

$ cd preprocessing
$ cargo test --features=intel-mkl
...
[/home/teramura/.cargo/registry/src/github.com-1ecc6299db9ec823/ndarray-linalg-0.12.0/src/lapack/svd.rs:83] ldvt = 100
temp[0, 0] = -483774241208677100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
temp[0, 1] = -1581024226846399000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
temp[1, 0] = -417737396116675400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[/home/teramura/.cargo/registry/src/github.com-1ecc6299db9ec823/ndarray-linalg-0.12.0/src/lapack/svd.rs:83] ldvt = 100
temp[0, 0] = NaN
temp[0, 1] = NaN
temp[1, 0] = NaN
[/home/teramura/.cargo/registry/src/github.com-1ecc6299db9ec823/ndarray-linalg-0.12.0/src/lapack/svd.rs:83] ldvt = 100
thread 'rPCA::algorithm::tests::test_rPCA' panicked at 'called `Result::unwrap()` on an `Err` value: Lapack { return_code: -6 }', src/libcore/result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

I did not trace why it becomes NAN yet... Anyway, this is an error message issue for ndarray-linalg, thanks for notification @LukeMathWalker

termoshtt avatar Dec 27 '19 19:12 termoshtt