私は結合されたマルチフィジックスシステムのジャコビアを組み立てています。ヤコビアンは、各システムの対角線上のブロック行列と、結合のための対角ブロックとからなる。 アセンブラを使って分離してブロックし、射影行列で総和して完全なヤコビ行列を得ることが最善の方法です。 擬似コード(J [i]は対角要素、C [ij]は結合)、Pは完全行列への射影です。小さなsparsematricesから固有3 sparsematrixを組み立てる
// diagonal blocks
J.setZero();
for(int i=0;i<N;++i){
J+=P[i]J[i]P[i].transpose()
}
// off diagonal elements
for(int i=0;i<N;++i){
for(int j=i+1;j<N;++j){
J+=P[i]C[ij]P[j].transpose()
J+=P[j]C[ji]P[i].transpose()
}
}
これは、全体の20%程度のパフォーマンスを必要とします。これは、組み立てには多すぎます。システムが非常に非線形であるため、毎回ジャコビアを再計算する必要があります。 Valgrindは、リソース消費方法がEigen::internal::assign_sparse_to_sparse
で、このメソッドではEigen::SparseMatrix<>::InsertBackByOuterInner
を呼び出していることを示します。
このようなマトリックスをより効率的に組み立てる方法はありますか?
(私もプログラムの開発をコンパイルするために代わりにP J * J.transposeのP *(J P.transposeを())()を使用しなければならなかった、間違って何かがすでに存在してもよい)
PS:余分なマトリックスにP.transposeを格納することによって、私は少し良いパフォーマンスを得るが、プログラムの開発の15%のため、まだ加算アカウントが
[OK]をクール、私はこれを試してみて、私がプロファイリングしている場合は戻ってくるだろう新しいコード。回答いただきありがとうございます。 – MagunRa
素晴らしい作品です、ありがとうございます。私は列にnnzを過大評価すると、どれくらい悪いことが起こりますか? (私は簡単にいくつかの構成では少し高いかもしれない上限を与えることができます) – MagunRa
少しのメモリの無駄 – ggael