6

Pythonでスパース行列のN個の最小固有値を見つけたいと思います。パッケージを使用してみましたscipy.sparse.linalg.eigen.arpackが、最小の固有値の計算に非常に時間がかかります。どこかでシフト反転モードがあると読んだのですが、使ってみると、シフト反転モードがまだサポートされていないというエラーメッセージが表示されます。私がどのように進めるべきかについてのアイデアはありますか?

4

1 に答える 1

6

SciPy のバージョン

scipy.sparse.linalg.eigsSciPy v0.9のドキュメントとscipy.sparse.linalg.eigsSciPy v0.10のドキュメントを比較すると、 v0.10以降、シフト反転モードが実装され、機能しているように見えます。具体的にはsigma、v0.9 ドキュメントのパラメータの説明には実装されていないと記載されていますが、v0.10 ドキュメントでは実装されていません。

SciPy v0.10 以降をお持ちでない場合は、最新のものをインストールすると、スパース固有値ソルバーでシフト反転モードを利用できるようになります。

小さな固有値を見つけるのが遅い

質問で述べたように、ARPACK インターフェイスを使用して小さな固有値を見つけることができます。これは、 をwhich='SM'呼び出すときに渡すことによって行われscipy.sparse.linalg.eigsます。ただし、質問に記載されているように、遅いです。これは、SciPy チュートリアルのSparse Eigenvalue Problems with ARPACK に関するセクションで確認され、次のように述べられています。

ARPACK は通常、極値固有値 (つまり、大きさが大きい固有値) を見つけるのに優れていることに注意してください。特に、 を使用which = 'SM'すると、実行時間が遅くなったり、異常な結果が生じる可能性があります。より良いアプローチは、シフト反転モードを使用することです。

実験

SciPy の v0.9 と v0.10 の両方で shift-invert を使用しようとしているコードを見てみましょう。どちらの場合も、次のコードを使用します。

from scipy.sparse import identity
from scipy.sparse.linalg import eigs

A = identity(10, format='csc')
A.setdiag(range(1, 11))
eigs(A, 3, sigma=0) # find three eigenvalues near zero using shift-invert mode

SciPy v0.9

SciPy v0.9 でコードを実行すると、例外が発生します。

NotImplementedError: shifted eigenproblem not supported yet

SciPy v0.10

SciPy 0.10 でコードを実行すると、期待どおりの結果が得られます。

(array([ 1.+0.j,  2.+0.j,  3.+0.j]),
 array([[ -1.00000000e+00+0.j,   5.96300068e-17+0.j,   9.95488924e-17+0.j],
       [  3.55591776e-17+0.j,   1.00000000e+00+0.j,  -4.88997616e-16+0.j],
       [ -3.79110898e-17+0.j,   1.16635626e-16+0.j,   1.00000000e+00+0.j],
       [ -1.08397454e-17+0.j,   1.23544164e-17+0.j,   1.78854096e-15+0.j],
       [  1.68486368e-17+0.j,  -9.37965967e-18+0.j,   2.05571432e-16+0.j],
       [ -2.97859557e-19+0.j,  -3.43100887e-18+0.j,   3.35947574e-17+0.j],
       [  1.89565432e-17+0.j,  -3.61479402e-17+0.j,  -1.33021453e-17+0.j],
       [ -1.40925577e-18+0.j,   3.16953070e-18+0.j,   7.91193025e-17+0.j],
       [  6.76947854e-19+0.j,  -3.75674631e-19+0.j,   3.61821551e-17+0.j],
       [ -3.07505146e-17+0.j,  -6.52050102e-17+0.j,  -8.57423599e-16+0.j]]))
于 2012-02-01T05:12:31.970 に答える