2011-07-13 25 views
35

現在、仕事をしているnumpyを使用しています。しかし、私は数千の行/列を持つ行列を扱っているので、この数値は数万に上がります。この種の計算を高速に実行できるパッケージが存在するかどうか疑問に思っていましたか?Pythonで固有値/ベクトルを見つける最速の方法は何ですか?

+2

numpyはスケールがよくないですか?私はそれがそのようなもののために設計されたと思った。ベクトル化された操作の全体的なポイントではありませんか? – JAB

答えて

48
  • :MPIを使用して並列に計算trixが疎である場合、scipy.sparseのコンストラクタを使用して行列をインスタンス化し、次にspicy.sparse.linalgの類似の固有ベクトル/固有値メソッドを使用します。パフォーマンスの観点からは、これは二つの利点があります:

    • あなたの行列を、spicy.sparseコンストラクタから構築され、それがどのようにスパースに比例して小さくなります。

    • スパース行列のeigenvalue/eigenvector methods

    • 関数eigseigsh)オプションの引数を受け入れ、返して欲しい固有ベクトル/固有値のペアの数がk個 。ほとんどの場合、分散の> 99%を占めるのに必要な数は列の数よりはるかに少なく、元のポストを確認できます。つまり、あなたは、固有ベクトル/固有値ペアのすべてを計算して返さないようにメソッドを指示することができます。分散を考慮する必要がある(通常は)小さなサブセットを超えると、残りの部分が必要になることはほとんどありません。

  • にscipyのダウンロードscipy.linalg、同じ名前のnumpyのライブラリーの代わりに を線形代数ライブラリを使用します。これら2つのライブラリには同じ名前の があり、同じメソッド名が使用されています。しかし、パフォーマンスには違いがあります。 この差はnumpy.linalgは は(移植性と利便性のためにそのnumpyの設計目標を遵守するため、すなわち、 をいくつかのパフォーマンスを犠牲に類似したLAPACKルーチンの 少ない忠実なラッパーであることに起因しますNumPyライブラリ は、Fortranコンパイラなしでビルドする必要があります。 linalg にscipyのダウンロードに他の手はLAPACKのより完全ラッパーであると はf2pyを使用します。

  • 使用例に応じて適切な機能を選択してください。;言い換えれば、必要以上に機能を使用しないでください。 scipy.linalg 固有値を計算する関数がいくつかあります。 の違いは大きくはありませんが、固有値を計算するために関数 を慎重に選択すると、パフォーマンスが向上するはずです。 例えば:

    • scipy.linalg.eig戻り両方固有値および固有ベクトル
    • scipy.linalg.eigvals、固有値のみを返します。したがって、行列の固有値が必要な場合はを使用しないでください。linalg.eigを使用する場合は、代わりにlinalg.eigvalsを使用してください。あなたは(その転置に等しい)の実数値正方対称行列を持っている場合
    • はその後scipy.linalg.eigsh
  • を使用し、あなたのscipyのダウンロードは、あなたのscipyのダウンロードビルドenvironement をされ準備を構築し最適化します主にSciPyのsetup.pyスクリプトで行われます。おそらく 最も重要なオプションの性能面は任意の最適化 LAPACKライ​​ブラリを識別しているようなATLASまたはscipyのダウンロードはそれらを検出し、それらに対して構築することができるように/ VECLIBフレームワーク(OS X のみ?)加速。 現在のリグに応じてSciPy をビルドして再インストールすると、実質的なパフォーマンスが向上します SciPyコアチームの追加のメモはhereです。

これらの機能は大きなマトリックスで機能しますか?

私はそう考えるべきです。これらは工業用強度マトリックス分解法であり、類似のFortranの上の単なる薄いラッパーです。これは、ルーチンFortran LAPACKルーチンです。

私はlinalgライブラリのほとんどのメソッドを使用して、行列の数が通常約5から50までで、行の数が通常50万を超える行列を分解しました。 SVD固有値の方法も、このサイズの行列を扱うには問題がないようです。を関数eigあなたはこのライブラリからいくつかの方法のいずれかを使用して、1回の呼び出しで、固有ベクトルと固有値を計算することができますscipyのダウンロードライブラリlinalgを使用して

eigvalsh、およびeigh

>>> import numpy as NP 
>>> from scipy import linalg as LA 

>>> A = NP.random.randint(0, 10, 25).reshape(5, 5) 
>>> A 
    array([[9, 5, 4, 3, 7], 
      [3, 3, 2, 9, 7], 
      [6, 5, 3, 4, 0], 
      [7, 3, 5, 5, 5], 
      [2, 5, 4, 7, 8]]) 

>>> e_vals, e_vecs = LA.eig(A) 
+1

私のマシンでは、numpyのeigvalsは実際にscipyより速いです。 –

+0

私は40,000対40,000の対称スパース行列に対してscipy.sparse.linalg.eign.eigshを使用しています。 125個の最小固有ベクトルを見つけるのに30分ほどかかります。だから私はまた、最も効率的な固有ベクトルソルバーがPythonで何であるのだろうかと思っています。 – Wedoso

8

あなたの行列が疎である場合は、より高速であるべき、scipyのダウンロードのスパース固有値機能を使用して試すことができます:あなたはまた、Pythonバインディングを持つ、SLEPcのような専門的なパッケージをチェックアウトするかもしれないと行うことができます

http://docs.scipy.org/doc/scipy/reference/sparse.linalg.html

あなたミリアンペア場合**

http://code.google.com/p/slepc4py/

関連する問題