私は線形代数C++ライブラリEigen3でランダム対称行列を得ようとしています。私は次のようにしています:C++ Eigen3行列の不思議な振る舞い
Eigen::MatrixXd m(3, 3);
m.setRandom();
m = 0.5 * (m + m.transpose());
しかし、再考は全く間違っています。しかし、変数mを書き換えずに単純にコンソールに出力すると、次のようになります。
Eigen::MatrixXd m(3, 3);
m.setRandom();
cout << 0.5 * (m + m.transpose()) << endl;
すべてが正しく動作しているようです。私はどこに問題があるのか理解できません。それは、transposeや*や+のようなメソッドは、怠惰なやり方で行列mを参照する代わりに、新しい行列を即座に作成しないからですか?しかし、どうすれば正式な文書からそれを知るべきですか?そして、圧倒的にエラーを起こしやすいこのような行動ではないのですか?
更新: はい、私は怠惰な計算についての私の推測は正しいと思います。だから今
/** \returns an expression of the transpose of *this.
*
* Example: \include MatrixBase_transpose.cpp
* Output: \verbinclude MatrixBase_transpose.out
*
* \warning If you want to replace a matrix by its own transpose, do \b NOT do this:
* \code
* m = m.transpose(); // bug!!! caused by aliasing effect
* \endcode
* Instead, use the transposeInPlace() method:
* \code
* m.transposeInPlace();
* \endcode
* which gives Eigen good opportunities for optimization, or alternatively you can also do:
* \code
* m = m.transpose().eval();
* \endcode
*
* \sa transposeInPlace(), adjoint() */
を私は計算の長鎖を実行するときに私が使用すべきかのパターン疑問に思って:それはtranspose
方法のdocummentationに記載されていますか?どこでも.eval()を書く?正直言って、それはかなり醜いですが、まだ誤りがちです。
@Someprogrammerdude m.transpose()の場所に行列Mを転置が、結果を返すので、それは問題ないはずはありません –
@Someprogrammerdudeだから私はそれが重複しているとは思わない、少なくともリンクされた質問ではない –
'm =(0.5 +(m + m.transpose()))。eval();'式の最後に単一の 'eval()'をddします。あなたの場合など、エイリアシングの問題が発生した場合は、 'eval()'を追加する必要があります。 –