c++eigeneigen3

Elementwise operation between Eigen Matrix and Vector


The following code conduct subtraction between a Matrix and a Vector. The vector is automatically broadcast to shape (30, 7) at runtime. But if num and sub_value are declared as dynamic-shaped Matrix/Vector(as in the commented lines), the code fails at compilation and emits the error msg below.

void func(){
    // MatrixXf sub_value(1, 7);
    // MatrixXf num(30, 7);
    Matrix<float, 1, 7> sub_value;
    Matrix<float, 30, 7> num;
    sub_value << 1, 2, 3, 4, 5, 6, 7;
    num = MatrixXf::Zero(30, 7);
    num.array().rowwise() -= sub_value.array();
    std::cout << num << std::endl;
}
/usr/local/include/Eigen/src/Core/VectorwiseOp.h: In instantiation of ‘ExpressionType& Eigen::VectorwiseOp<ExpressionType, Direction>::operator-=(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::ArrayWrapper<Eigen::Matrix<float, -1, -1> >; ExpressionType = Eigen::ArrayWrapper<Eigen::Matrix<float, -1, -1> >; int Direction = 1]’:
ROBO/test_eigen.cpp:14:46:   required from here
/usr/local/include/Eigen/src/Core/VectorwiseOp.h:521:7: error: static assertion failed: YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX
  521 |       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

What is the difference?


Solution

  • Eigen's .rowwise() wants to see a row vector in conjunction with coefficient-wise operations.

    The problem you have here is that a dynamically allocated MatrixXf sub_value(1, 7); is not a row vector in Eigen's mind, because it can't be determined to be one at compile time.

    What you want to do is:

    RowVectorXf sub_value(7);
    MatrixXf num(30, 7);
    

    If the input object has to be a matrix for some reason (because the same variable is used elsewhere where it may be a matrix), you could change your code to perform a check that it's actually a row vector, and then use .row(0) to select the first (and only) row of that matrix object to make Eigen happy:

    // alternatively throw an exception, the assert is just an example
    assert(sub_value.rows() == 1);
    num.array().rowwise() -= sub_value.row(0).array();