2012-08-28 7 views
14

大きなNxNの高密度対称行列を持ち、k個の最大固有値に対応する固有ベクトルが必要です。それらを見つける最良の方法は何ですか(できればnumpyを使用しますが、一般的にはblas/atlas/lapackを使用してください)。一般に、Nはkよりはるかに大きい(例えば、N> 5000、k < 10)。k個の最大固有値とそれに対応する固有ベクトルをnumpyで計算する最速の方法

Numpyは、開始行列が疎である場合にk個の最大固有値を見つける関数しかないようです。

答えて

12

linalg.eigh機能を使用して、eigvalsパラメータを使用することができます。

eigvals:タプル固有値および対応する固有ベクトル( 昇順で)最小および最大の(LO、HI)インデックス すべき返さ:0 < = LO < HI < = M-1。省略すると、すべての固有値と 固有ベクトルが返されます。

(N-k,N-1)に設定する必要があります。

+0

非スパース法が私のために最速の方法であった(それが終了するまで友人とおいしいコーヒーを取るために行きます)。私は eighの経過時間を取得し、K = 2とジュリアーノのベンチマークスクリプトを使用する:93.704689 時間を経過eigsh:353.433379 時間経過EIG:870.060089 最後の時間がnumpy.linalg.eigためです。これは私のMacBook Proにあります。 –

3

実際にスパースルーチンは、私は、それがもしあなたのk < < Nを意味し、したがって、彼らはいくつかの行列 - ベクトル 製品を計算する必要がある、彼らはクリロフ部分空間反復の一部 種類を使用すると思います、また、高密度のnumpyのアレイのために働きます疎なルーチンは(わずかに?) より速いでしょう。

ドキュメント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'を試してみましたが、' 'k = 2'のときは' 'k = 1'(奇妙なことに、 )または 'k'が"大きい "' eigsh'はかなり遅く、 'eigh'は約44秒かかります。 これを行うには、より効率的なアルゴリズムが必要です。これは、最大固有値ペアが多くの/すべてよりも時間が短いことがわかるでしょう... –

+0

そのため、私は 'could'本当に知っている! AFAIKの支配的な固有値を決定するためのほとんどの方法は、A * xを何度もやり直さなければならないことを意味し、N = 5000であり、これは理想的ではない可能性があることを意味する、いずれにせよ、OPはnumpy/scipyで利用可能だったものを求めていました。彼は2つの方法の中から選択することができました。 – Giuliano

+0

そして私は答えがそうだと思います:OPのケースではスパースルーチン*が高速です! :) –

関連する問題