I'm trying to use the Eigen library for some simple image processing. I'd use Array3f for an RGB triple and an Array to hold an RGB image. This seems to work partially, and I can conveniently do component-wise addition, multiplication and division of images. But certain operations (specifically involving subtraction or negation) seem to create compile errors. Here is a minimal example:
#include <Eigen/Core>
using namespace Eigen;
int main(void)
{
typedef Array<Array3f, Dynamic, Dynamic> MyArray;
MyArray m(2,2);
// all of the following should have the same mathematical effect
Array3f v = -Array3f(5.0f); // this compiles
MyArray a = m + v; // this compiles
MyArray b = m + Array3f(-5.0f); // this compiles
MyArray c = m + (-Array3f(5.0f)); // this doesn't compile
MyArray d = m - Array3f(5.0f); // this doesn't compile
}
The above code gives me three errors:
./Eigen/src/Core/CwiseBinaryOp.h:128:7: error: no member named
'YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY' in
'Eigen::internal::static_assertion<false>'
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
...
./Eigen/src/Core/CwiseBinaryOp.h:187:14: error: no matching function for call to object of type 'const
Eigen::internal::scalar_sum_op<Eigen::Array<float, 3, 1, 0, 3, 1> >'
return derived().functor()(derived().lhs().coeff(index),
...
./Eigen/src/Core/../plugins/ArrayCwiseBinaryOps.h:208:10: error: no viable conversion from 'const
CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Eigen::Array<Eigen::Array<float, 3, 1, 0, 3, 1>, -1, -1, 0, -1, -1>, const
Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, const Eigen::Array<float, 3, 1, 0, 3, 1> > >' to 'const
CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Eigen::Array<Eigen::Array<float, 3, 1, 0, 3, 1>, -1, -1, 0, -1, -1> >'
return *this + (-scalar);
...
In case someone is interested: The above example compiles and runs fine with Eigen 3.3rc1 (most likely anything since Eigen 3.3-alpha is fine as well).
I would still consider this feature as experimental, since it is neither documented, nor part of the test suite (as far as I see).
The problem is that Eigen is using lazy evaluation and that (-Array3f(5.0f))
is actually an expression and not an array. I'm not sure exactly what's failing and I don't have enough time to look into it right now. Before I continue, I have to say that there is no valid constructor for Array3f(float)
and will continue the answer Array3f(5.0f, 4.0f, 3.1f)
instead.
The simple fast and easy hack would be to force evaluation of the negated array and use a +
operation. Not ideal for many reasons, but
MyArray c = m + (-Array3f(5.0f, 4.0f, 3.1f)).eval();
works. Advantage: quickly implemented. Disadvantage: no lazy evaluation, as the eval()
will create a new negated array. Also makes the code much uglier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With