Let me summarize what happens and why it is wrong. First of all, create auto instances with the types they accept:
typedef GeneralProduct<MatrixXd,MatrixXd> Prod; Prod c = a * b; GeneralProduct<Transpose<Prod>,Prod> cTc = c.transpose() * c;
Please note that Eigen is an expression template library. Here, GeneralProduct<> is an abstract type representing the work. No calculations are performed. Therefore, if you copy cTc to MatrixXd as:
MatrixXd d = cTc;
which is equivalent to:
MatrixXd d = c.transpose() * c;
then the product a*b will be executed twice! Therefore, in any case, it is much preferable to evaluate a*b within the explicit time value, as well as for c^T*c :
MatrixXd c = a * b; MatrixXd cTc = c.transpose() * c;
Last line:
auto chol = cTc.llt();
also wrong. If cTc is an abstract product type, it tries to create a Cholesky factorization instance that works on an abstract product type that is not possible. Now, if cTc is MatrixXd , then your code should work, but this is still not the preferred way, since the llt() method is more likely to implement a single-line expression, for example:
VectorXd b = ...; VectorXd x = cTc.llt().solve(b);
If you need a named Cholesky object, then rather use its constructor:
LLT<MatrixXd> chol(cTc);
or even:
LLT chol (c.transpose () * c);
which is equivalent if you should not use c.transpose() * c in other calculations.
Finally, depending on the sizes of a and b , it would be preferable to calculate cTc as:
MatrixXd cTc = b.transpose() * (a.transpose() * a) * b;
In the future (i.e. Eigen 3.3), Eigen will be able to see:
auto c = a * b; MatrixXd cTc = c.transpose() * c;
as the product of the four matrices m0.transpose() * m1.transpose() * m2 * m3 and put the brackets in the right place. However, he cannot know that m0==m3 and m1==m2 , and therefore, if the preferred method is to estimate a*b in a temporary order, you still have to do it yourself.