scikit-tensor
scikit-tensor copied to clipboard
hosvd fails for sptensor when using full rank along a mode
Hi there, nice package.
I'd like to compute the full hosvd of a large sparse tensor. I thought I could use the method tucker.hosvd, but it breaks for me.
Here is a small example:
T = sptensor(([0,1,2], [0,0,2], [0,2,0]), (1.0,2.0,3.0), (3,3,3))
sktensor.tucker.hosvd(T, (3,3,3))
which results in:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jackkamm/.local/lib/python2.7/site-packages/scikit_tensor-0.1-py2.7.egg/sktensor/tucker.py", line 132, in hosvd
U[d] = array(nvecs(X, d, rank[d]), dtype=dtype)
File "/Users/jackkamm/.local/lib/python2.7/site-packages/scikit_tensor-0.1-py2.7.egg/sktensor/core.py", line 283, in nvecs
_, U = eigsh(Y, rank, which='LM')
File "/Users/jackkamm/anaconda/lib/python2.7/site-packages/scipy/sparse/linalg/eigen/arpack/arpack.py", line 1487, in eigsh
raise ValueError("k must be between 1 and ndim(A)-1")
ValueError: k must be between 1 and ndim(A)-1
The issue appears to be, if T is a sptensor, then scipy.sparse.linalg.eigsh will be used to get the eigendecomposition of the matrix unfolding. However, eigsh cannot return all eigenvalues. And while eigsh works well for the first few eigenvalues of a large sparse matrix, it appears to works poorly for the lower eigenvalues. (or at least, that is what I have read online about the Implicitly Restarted Lanczos Method, which eigsh uses)
I'd prefer not to convert the sptensor to a dtensor, since the tensor dimensions are quite large.
For now I will just use my own code to get the full hosvd. But I would prefer to have the default of nvecs and hosvd always use scipy.linalg.eigh, with a user option to use eigsh instead. If you like, I can submit a PR with this change.
@jackkamm I know this is old, but I just saw this issue and am having the same problem. Do you remember if you solved this problem? If so, could you point me to your solution?
@jtliso I have the same problem. Can you help me?