AlexGrig / svd_update

In this repository there are code for updating SVD decomposition. Updating means recomputing SVD faster when adding new column (or row).
8 stars 3 forks source link

ValueError: LAPACK root finding dlasd4 failed to fine the last singular value #1

Open lucgiffon opened 7 years ago

lucgiffon commented 7 years ago

Hello, I'm currently trying to run your code. I think I succesfully passed the instalation steps but when I am trying to test the specific function of update_svd, I get the following error which I am not able to understand:

Traceback (most recent call last):
  File "/home/luc/tests/svd_update/alexgrigupdate/test_svd_update.py", line 764, in <module>
    test_update_svd(10000,500, 6000, 500)
  File "/home/luc/tests/svd_update/alexgrigupdate/test_svd_update.py", line 495, in test_update_svd
    (uu,su,vu) = update_SVD( um, sm, vm, new_col, a_col_col=True)
  File "/home/luc/tests/svd_update/alexgrigupdate/svd_update.py", line 969, in update_SVD
    U1, new_sigmas, V1 = _SVD_upd_diag(S, m_vec, new_col=True)
  File "/home/luc/tests/svd_update/alexgrigupdate/svd_update.py", line 802, in _SVD_upd_diag
    ret =  find_roots(sigmas, m_vec, method=method)
  File "/home/luc/tests/svd_update/alexgrigupdate/svd_update.py", line 486, in find_roots
    raise ValueError("LAPACK root finding dlasd4 failed to fine the last singular value")
ValueError: LAPACK root finding dlasd4 failed to fine the last singular value

Do you have any idea of what is going on here?

Step to reproduce:

Follow the installation steps Change all print and xrange into print() and range to make it works with python3 Comment the whole block under if __name__ == __main__ in test_svd_update.py Uncomment the line 764: test_update_svd(10000,500, 6000, 500) Run python3 on the file

AlexGrig commented 7 years ago

Hi,

I ll take a look at, hopefully tomorrow.

Cheers, Alex.

On 04.04.2017 15:14, lucgiffon wrote:

Hello, I'm currently trying to run your code. I think I succesfully passed the instalation steps but when I am trying to test the specific function of |update_svd|, I get the following error which I am not able to understand:

|Traceback (most recent call last): File "/home/luc/tests/svd_update/alexgrigupdate/test_svd_update.py", line 764, in test_update_svd(10000,500, 6000, 500) File "/home/luc/tests/svd_update/alexgrigupdate/test_svd_update.py", line 495, in test_update_svd (uu,su,vu) = update_SVD( um, sm, vm, new_col, a_col_col=True) File "/home/luc/tests/svd_update/alexgrigupdate/svd_update.py", line 969, in update_SVD U1, new_sigmas, V1 = _SVD_upd_diag(S, m_vec, new_col=True) File "/home/luc/tests/svd_update/alexgrigupdate/svd_update.py", line 802, in _SVD_upd_diag ret = find_roots(sigmas, m_vec, method=method) File "/home/luc/tests/svd_update/alexgrigupdate/svd_update.py", line 486, in find_roots raise ValueError("LAPACK root finding dlasd4 failed to fine the last singular value") ValueError: LAPACK root finding dlasd4 failed to fine the last singular value |

Do you have any idea of what is going on here?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/AlexGrig/svd_update/issues/1, or mute the thread https://github.com/notifications/unsubscribe-auth/AH5-W0jJ3sgH0K0dPCCdBAyOalaOx7sPks5rsjQNgaJpZM4MyxXR.

InesArous commented 7 years ago

I have the same issue. How can I fix it please?

AlexGrig commented 7 years ago

Hello, Indeed the problem is with the standard LAPACK function dlasd4. It can't find first or last eigenvalue. I did some tests recently but was not able to fix it quickly. Currently, I do not have time to work on that. However, initially, I remember it was not a big problem for me, somehow I was able to provide proper intervals where this problematic eigenvalue could be found.

If I have some time I may take a look at it, but I can't guarantee. If you manage to solve, please let me know.

liqimai commented 5 years ago

I am using scipy 1.1.0, which have already included 'linalg.lapack.dlasd4'. It seems that dlasd4 deals all cases well, as long as you count from 0 instead of 1 (for the first parameter of dlasd4).

Replacing second method in function 'find_roots' (file svd_update.py, line 452-497) with following code snip works for me:

    if method == 2: # Imported lapack function
        d = sigmas[::-1]
        z = m_vec[::-1]
        roots = np.empty_like(d)
        for i in range(len(sigmas)):
            delta, roots[i], work, info = sp.linalg.lapack.dlasd4(i, d, z)
            if (info > 0) or np.isnan(roots[i]):
                raise ValueError("LAPACK root finding dlasd4 failed at {}-th sigma".format(i))
        return roots[::-1]

It is as precise as python implemented interval root finder (method 1), and faster than all other method (method 1,3).