3

私はScipyを使用してFEMプロジェクトに取り組んでいます。今私の問題は、スパース行列の組み立てが遅すぎるということです。密な小さな行列(要素ごとに1つ)のすべての要素の寄与を計算します。グローバル行列のアセンブリでは、すべての小さな密度行列をループし、行列エントリを次のように設定します。

[i,j] = someList[k][l]
Mglobal[i,j] = Mglobal[i,j] + Mlocal[k,l]

Mglobal適切なサイズのlil_matriceでありsomeList、インデックス変数をマップします。

もちろん、これはかなり遅く、行列の組み立て時間のほとんどを消費します。多くの小さな密行列から大きなスパース行列を組み立てるより良い方法はありますか?scipy.weaveを試しましたが、スパース行列では機能しないようです

4

1 に答える 1

4

私はscipyメーリングリストに返信を投稿しました。スタックオーバーフローへのアクセスは少し簡単なので、バージョンは少し改善されていますが、ここにも投稿します。

秘訣は、IJVストレージ形式を使用することです。これは3つの配列のトリオであり、最初の配列には行のインデックスが含まれ、2番目の配列には列のインデックスが含まれ、3番目の配列にはその場所の行列の値が含まれます。この形式へのアクセスは非常に高速であるため(配列を埋めるだけ)、これは有限要素行列(または私の意見ではスパース行列)を構築するための最良の方法です。

scipyではこれはcoo_matrix;と呼ばれます。クラスは3つの配列を引数として取ります。これは、高速線形代数の別の形式(CSR os CSC)に変換する場合にのみ役立ちます。

有限要素の場合、次のようにして3つの配列のサイズを見積もることができます。

size = number_of_elements * number_of_basis_functions**2

したがって、2D 2次方程式がある場合は、たとえばnumber_of_elements*36を実行します。このアプローチは便利です。ローカル行列がある場合は、グローバル番号とエントリ値が確実にあるためです。これは、3つのIJV配列を構築するために必要なものです。Scipyはゼロエントリをスローするのに十分賢いので、過大評価しても問題ありません。

于 2012-05-13T01:10:52.137 に答える