I was wondering if numpy has an efficient implementation for computing the largest or smallest eigenvalue of a symmetric matrix without full spectral decomposition, if possible. I find that the following modules implement their own decomposition:
- scipy.linalg;
- numpy linalg;
- scipy rare linalg.
scipy / sparse / linalg / eigsh can output the k smallest (largest) eigenvalues ββand eigenvectors; scipy / linalg / eigh also provides the ability to select a subset of eigenvalues; numpy / linalg / eigvalsh prints all eigenvalues. However, none of them seems effective if I just want to get a specific eigenvalue.
I am launching some toy example to compare the time spent finding the largest eigenvalue. All methods give a fairly close solution, the self-decomposition function in numpy.linalg seems to be the most effective, considering that it requires a complete decomposition of the spectrum. Is there a better way to do this job?
Here is the test code and solution
import numpy as np
import scipy.linalg
import scipy.sparse.linalg
import time
def test_scipy_eig(a):
p = a.shape[0]
w = scipy.linalg.eigh(a, eigvals=[p-1, p-1], eigvals_only=True)
return w
def test_scipy_sparse_eig(a):
p = a.shape[0]
w = scipy.sparse.linalg.eigsh(a, k=1, which='LA', return_eigenvectors=False)
return w
def test_numpy_eig(a):
w = np.linalg.eigvalsh(a)
return w
p = 2000
a = np.random.normal(0,1,(p,p))
b = a.dot(a.T)
start = time.time()
w1 = test_scipy_eig(b)
t1 = time.time() - start
start = time.time()
w2 = test_numpy_eig(b)
t2 = time.time() - start
start = time.time()
w3 = test_scipy_sparse_eig(b)
t3 = time.time() - start
print "time expense:\n scipy:%f numpy:%f scipy_sparse:%f " % (t1, t2, t3)
print "largest eigenvalue:\n scipy:%f numpy:%f scipy_sparse:%f " % (w1[0], w2[-1], w3[0])
Output
time expense:
scipy:1.427211 numpy:1.395954 scipy_sparse:4.520002
largest eigenvalue:
scipy:7949.429984 numpy:7949.429984 scipy_sparse:7949.429984
source
share