私はスパース行列の最適化と関数にEIGENを使用しています。いくつかのケースを除いて、すべてが "うまく"機能しており、私はこのケースを理解できません。ここでEIGEN:疎行列の乗算は枝刈りされた結果を生成しません
事です:
Matrix A
2 0 0
0 2 0
0 0 2
Matrix B
6 3
0 1
2 8
Result
12 6
0 2
4 16
あなたが見ることができるように、これは正しい結果であり、私は常に正しい結果を抱えています。
問題は「非ゼロ」と考えられる値です。この場合:
SparseMatrix<int, RowMajor> A;
SparseMatrix<int, RowMajor> B;
//Parsing and initializing matrix
SparseMatrix<int, RowMajor> result = A*B;
result.pruned();
cout << result.nonZeros();
nonZeros()
の結果は結果だけで5非ゼロ値を得たので、「通常」の場合である、5です。 さて、このコードを考えてみましょう:
SparseMatrix<int, RowMajor> A;
SparseMatrix<int, RowMajor> B;
//Parsing and initializing matrix
SparseMatrix<int, RowMajor> result = (A*B).pruned();
cout << result.nonZeros();
nonZeros()
の結果は、これはthe documentationで利用可能な構文である理由を私は理解していない6です。
そして今、奇妙な部分はそれが上の非常に大きな行列result = A*B; result.pruned()
では時々、ゼロでないとして0を保存しているが、私は(A*B).pruned();
を使用未満ならば、私は3つの質問だ:
- はなぜ
result = (A*B).pruned()
であり、result=A*B;result.pruned();
は、ゼロ以外の値に関して異なる結果をもたらします(有効な結果ではありません。どちらの場合もそうです)。 - 製品の0値がゼロ値と見なされないのはなぜですか?
- あなたは私と同じ結果を出していますか?
私はVisual Studio Professional 2013とEigen 3.3.2を使用しています。DEBUGモードとWIN32をターゲットにしています。
ありがとうございました。
EDIT: VS2013による疎乗算のベンチマーク、W32のDEBUG /リリースモード(SSE2命令セットの有無にかかわらず、どちらの場合も同じ結果)。結果は常に正しいものなので、ここに貼り付けるわけではありません。何の情報も持ちません。有する:
1 = SparseMatrix<int, RowMajor> resultA = A*B;
2 = SparseMatrix<int, RowMajor> resultB = (A*B);resultB.pruned();
3 = SparseMatrix<int, RowMajor> resultC = (A*B).pruned();
ケース1
Matrix A
2 0 0
0 2 0
0 0 2
Matrix B
5 3
0 1
2 8
期待値= 5
1 = 5
2 = 5
3 = 6
ケース2 行列が大きすぎる、here =ファイル
期待値= 0
2 = 1444
3 = 0
あなたが見ることができるように、入力と私は関数を呼んでいる途中で両方を依存し、結果は最適化されたかどうか、そしてどれも1、2または3のいずれの場合にも取り組んでいます。
EDIT²:問題はggaelソリューションで修正されました(感謝)。
私はコンパイラフラグをSSE2命令セットに変更しましたが、依然として0をゼロ値とみなしました。余分なFPUの精度を無くしてどういう意味ですか?コンバータのようなものを書いていますか?私はベンチマークを行い、その結果に続いて、関数を呼び出す順番によっては結果が異なるため、精度の問題であるとは確信できません。私は最初の投稿にこれを追加します。 – Spazz
あなたは正しいです。 3.3およびdevelブランチで修正された問題 – ggael