2012-08-28 97 views
14

我有一個大的NxN稠密對稱矩陣,並且希望特徵向量對應於k個最大特徵值。找到它們的最好方法是什麼(最好是使用numpy,但如果這是唯一的方法,可能通常使用blas/atlas/lapack)?通常N比k大得多(例如N> 5000,k < 10)。計算k個最大特徵值和對應特徵向量的最快方法

如果我的起始矩陣是稀疏的,Numpy似乎只能找到k個最大的特徵值。

回答

12

在SciPy中,可以使用linalg.eigh函數和eigvals參數。

eigvals:元組(LO,HI)的最小和最大(在 升序)特徵值的索引和相應的特徵向量是 返回:0 < = LO <喜< = M-1。如果省略,則返回所有特徵值和特徵向量。

你的情況應該設置爲(N-k,N-1)

+0

非稀疏的方法是最快的方法對我來說。用朱利亞諾的基準腳本k = 2時,我得到 eigh經過時間:93.704689 eigsh經過時間:353.433379 EIG經過時間:870.060089 上一次是numpy.linalg.eig。這是我的MacBook Pro。 –

3

其實稀疏例程密集numpy的陣列的工作還可以,我認爲他們使用一些 樣的Krylov子空間迭代的,因此,他們需要計算幾個矩陣向量 產品,這意味着,如果說明您的K < < N時,稀疏的例程可以(稍微?)更快地加快 。

退房的文檔 http://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

和下面的代碼(去,直到它結束走好咖啡與朋友)

import numpy as np 
from time import clock 
from scipy.linalg import eigh as largest_eigh 
from scipy.sparse.linalg.eigen.arpack import eigsh as largest_eigsh 

np.set_printoptions(suppress=True) 
np.random.seed(0) 
N=5000 
k=10 
X = np.random.random((N,N)) - 0.5 
X = np.dot(X, X.T) #create a symmetric matrix 

# Benchmark the dense routine 
start = clock() 
evals_large, evecs_large = largest_eigh(X, eigvals=(N-k,N-1)) 
elapsed = (clock() - start) 
print "eigh elapsed time: ", elapsed 

# Benchmark the sparse routine 
start = clock() 
evals_large_sparse, evecs_large_sparse = largest_eigsh(X, k, which='LM') 
elapsed = (clock() - start) 
print "eigsh elapsed time: ", elapsed 
+0

有幾個例子我試過了「小」'k',我得到44秒和18秒('eigsh'越快越好),'k = 2'時它們大致相同,當'k = 1'時)或'k'是「大」'eigsh'是相當慢,在所有情況下'eigh'大約需要44秒。 必須有更高效的算法來做到這一點,你可以期望能找到最大的特徵值對比在很多/所有的時間少數量的時間... –

+0

這就是爲什麼我說'可以'...我不知道真的不知道! AFAIK確定主要特徵值的大多數方法是良好的舊功率迭代方法的演變,這意味着它們需要多次執行A * x,並且N = 5000和A滿,這可能不是理想的。在任何情況下,OP都會詢問numpy/scipy中可用的內容,事實證明他可以在兩種方法中進行選擇。 – Giuliano

+0

我認爲答案是:稀疏程序*在OP的情況下更快* :) –

相關問題