How can i pass a column (or row) of a Matrix to a function as an l-value Vector reference? Here is an example for dynamically allocated matrices:
#include "eigen3/Eigen/Eigen"
void f2(Eigen::VectorXd &v) {
v(0) = 0e0;
}
void f1(Eigen::MatrixXd &m) {
if (m(0,0) == 0e0) {
// both calls below fail to compile
// f2(m.col(0)); // ERROR
// f2(m(Eigen::all, 0)); //ERROR
}
return;
}
int main() {
Eigen::MatrixXd m = Eigen::MatrixXd::Random(3,3);
f1(m);
return 0;
}
the call to f2
inside f1
triggers a compilation error, of type:
error: cannot bind non-const lvalue reference of type ‘Eigen::VectorXd&’ {aka ‘Eigen::Matrix<double, -1, 1>&’} to an rvalue of type ‘Eigen::VectorXd’ {aka ‘Eigen::Matrix<double, -1, 1>’}
I face the same issue with compile-time sized matrices, e.g.
constexpr const int N = 3;
void f2(Eigen::Matrix<double,N,1> &v) {
v(0) = 0e0;
}
void f1(Eigen::Matrix<double,N,N> &m) {
if (m(0,0) == 0e0) {
// all calls below fail to compile
// f2(m.col(0)); ERROR
// f2(m(Eigen::all, 0)); ERROR
// f2(m.block<N,1>(0,0)); ERROR
}
return;
}
int main() {
Eigen::Matrix<double,N,N> m = Eigen::Matrix<double,N,N>::Random();
f1(m);
return 0;
}
CodePudding user response:
This is what Eigen::Ref is designed to do.
void f2(Eigen::Ref<Eigen::VectorXd> v) {
v[0] = 123.;
}
void f1(Eigen::Ref<Eigen::MatrixXd> m) {
m(1, 0) = 245.;
}
int main()
{
Eigen::MatrixXd m(10, 10);
f1(m);
f2(m.col(0));
assert(m(0,0) == 123.);
assert(m(1,0) == 245.);
// also works with parts of a matrix, or segments of a vector
f1(m.bottomRightCorner(4, 4));
}
Note that mutable references only work if elements along the inner dimension are consecutive. So it works with a single column of a column-major matrix (the default) but not a row. For row-major matrices it is vice-versa.
const refs (const Eigen::Ref<const Eigen::VectorXd>&
) do work in these cases but they create a temporary copy.