Let A be a symmetric matrix and let v be a vector. I extract from A a block of n columns starting from j and multiply it by v using
VectorXd a;
a = A.middleCols(j,n).selfadjointView<Lower>() * v // does not compile
As this does not compile, whereas this
a = MatrixXd(A.middleCols(j,n).selfadjointView<Lower>()) * v
does, I am wondering whether the second version makes a copy of
A.middleCols(j,n).selfadjointView<Lower>()
or performs the computation directly?
Thanks for any hint.
EDIT: I suspect the problem has something to do with argument types, as I get the error :
invalid argument type 'typename ConstSelfAdjointViewReturnType.... to unary expression'
Indeed, A is the argument of a function passed by const reference using either of
const MatrixXd& A
const Ref<const MatrixXd>& A
Here is an example:
// this version doesn't compile
MatrixXd returnSymmetricMatrix(const MatrixXd& A, const VectorXd& v, const MatrixXd& B){
// B is a symmetric matrix
VectorXd a;
a = A.middleCols(3, 4).selfadjointView<Lower>() * v;
MatrixXd M(code_fill(){...});
// code_fill is the function filling the lower triangular part of a symmetric matrix
M.block(1, 2, 3, 4).triangularView<Lower>() += B.selfadjointView<Lower>();
return M;
}
// this version compiles
MatrixXd returnSymmetricMatrix(const MatrixXd& A, const VectorXd& v, const MatrixXd& B){
// B is a symmetric matrix
VectorXd a;
a = MatrixXd(A.middleCols(3, 4).selfadjointView<Lower>()) * v;
MatrixXd M(code_fill(){...});
// code_fill is the function filling the lower triangular part of a symmetric matrix
Matrix(M.block(1, 2, 3, 4).triangularView<Lower>()) += B.selfadjointView<Lower>();
return M;
}
EDIT2 Regarding my initial question and the example I've added at the Edit section, I am a bit confused regarding the copying. As I understand the difference between the working and the non-working versions, the line
Matrix(M.block(1, 2, 3, 4).triangularView<Lower>()) += B.selfadjointView<Lower>();
works because its lhs tells to Eigen that M.block(1, 2, 3, 4).triangularView() is actually a matrix rather than a reference to a matrix. Otherwise, the operator += would through an error that this operator is not overloaded for .block(). So my original question is whether Matrix(...) only tells that it's a Matrix to enable the computation, or rather copy the ... into a Matrix? Thanks!