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?
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();