私は、複数の(ソフト)制約を持つ疎線形システムを構築しています。私はboost :: ublasを使って行列を構築していたいくつかのコードをEigenに変換しています。 boost:ublasは、既知の(または推定された)非ゼロの数を持つ疎行列を作成する便利な方法を持ち、その要素を更新するのにかなり高速の演算子(int row、int col)を持ちます。EigenのSparseMatrix構造
を疎行列:: setFromTripletsを使用して::
私のシステムは多くの制約があり、次のように問題があります。素朴で、やや誇張された例として、500 nnzで10億の冗長制約(つまり、非ゼロのcoeffが10億回変更されている)を持つ100x100の疎な行列があるとしましょう。 setFromTripletsは10億の係数を格納する必要があります。その大部分は、500個の非ゼロ係数のセットを形成するために合計されます。それは本当に効率的でもメモリに優しいものでもありません。 もちろん、私はstd :: vectorをstd :: mapで置き換えることができますが、手動で制約を累積することはできますが、これは何とか疎な行列クラスを持っていて、それも効率的ではありません。
SparseMatrix :: insert(i、j、val)の使用:
要素が既に存在する場合は機能しません。私の問題は、すでに存在する係数を累積することができることです。SparseMatrix :: coeffRef(i、j)を使用して:
はまだありながら固有で疎行列を構築するための最も効率的な方法は何である
これは機能し、私が探している機能になります。しかし、boost :: ubasよりも数桁遅いです。私はそれのためのより良い機能を見ていないことに驚いています。 これは、あらかじめわかっていない非ゼロの数に起因すると考えられ、複数の再割り当てが強制されます(これは実際には起こります)。ただし、SparseMatrix :: reserve()を使用すると、圧縮された行列に対してのみ機能するため、効果はありません(ソース内のコメントには、「アサーションの前に非圧縮モードではこの関数は意味がありません」と記載されています)。ドキュメントが言うように...と、「疎行列に新しい要素の挿入が、これは非圧縮モードへの以降の変換」。
その係数更新することができ、複数回
おかげ
[EDIT:サンプル使用事例:10非ZERを有する10×10マトリックスos。簡単にするために、マトリックスは、=>が動作
SparseMatrix<double> mat(10, 10);
for (int i=0; i<10; i++) {
for (int j=0; j<1000000; j++) {
mat.coeffRef(i, i) += rand()%10;
}
}
]対角線が、(より大きな行列もちろん、より現実的な設定のため)ublasオペレータより遅い桁()です。
std::vector<Eigen::Triplet<double> > triplets(10000000);
int k=0;
for (int i=0; i<10; i++) {
for (int j=0; j<1000000; j++) {
triplets[k++] = Eigen::Triplet<double>(i,i,rand()%10);
}
}
SparseMatrix<double> mat(10, 10);
mat.setFromTriplets(triplets.begin(), triplets.end());
=>ないメモリ優しい... coeffRef
効率的なのinsert
を作るために
私はあなたの問題にかなり従っていません。ユースケースの簡略化されたバージョンを投稿しますか?理想的には、10x10スパース行列、たとえば10以外のゼロ行列でそれを行います。 – Escualo
私はほんの一例を追加しました。 – WhitAngl
あなたの例は意味を持ちません。私はあなたの実際のユースケースとして私の質問を意味した。つまり、あなたは疎な行列を持っています。そしてそれで何かをしてから、何をしますか?あなたは行列を変えますか?係数をシャッフルしますか?新しい係数セットを追加しますか? – Escualo