I'm trying to get a random symmetric matrix with linear algebra c++ library Eigen3. I'm doing it like this:
Eigen::MatrixXd m(3, 3);
m.setRandom();
m = 0.5 * (m + m.transpose());
But the reasult is totally wrong. But if I won't rewrite the m variable and simply output it to console like this:
Eigen::MatrixXd m(3, 3);
m.setRandom();
cout << 0.5 * (m + m.transpose()) << endl;
All seems to work properly. I can not understand where is the problem. Is it because methods like transpose and operations like * and + do not instantly create a new matrix as instead doing it in a lazy manner and holding a reference to matrix m? But how then should I know it from official documentation? And isn't behaviour like this overwhelmingly error-prone?
UPDATE:
Yes, I think my guess about lazy calculations is correct. It is mentioned in the docummentation of the transpose
method:
/** \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() */
So now I am wondering what patterns should I use when I perform long chains of calculations? Everywhere writing .eval()? To be honest, it's pretty ugly and still error-prone.