Question

I have a 2D Eigen Array where each item in the array is a 3-element Eigen Vector (e.g. a velocity field over a surface).

I want to multiply each each element of the 2D array with a 3-element Eigen RowVector, effectively taking the dot product.

    Eigen::Array<Eigen::Vector3d, Eigen::Dynamic, Eigen::Dynamic> velField(5, 5);
    Eigen::Vector3d n;
    // ... initialisation of n and velField not shown

    Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic> result(5, 5);
    result = n.transpose() * velField;

This gives a compile error YOU MIXED DIFFERENT NUMERIC TYPES. However, if I don't assign the result, but just compute it:

    n.transpose() * velField;

it compiles. What is the correct return type for 'result' - or how else can I fix this?

EDIT

The same problem can be observed in this simpler case (multiplying by a double):

Eigen::Array<Eigen::Vector3d, Eigen::Dynamic, Eigen::Dynamic> velField(5, 5);
// ... initialisation of velField not shown
Eigen::Array<Eigen::Vector3d, Eigen::Dynamic, Eigen::Dynamic> result(5, 5);
result = 3.0 * velField;

However the same code works when using std::complex<double> instead of Eigen::Vector3d:

Eigen::Array<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> velField(5, 5);
// ... initialisation of velField not shown
Eigen::Array<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> result(5, 5);
result = 3.0 * velField;

I wonder why it works for std::complex but not with Eigen::Vector3d. Both types define the operator * with a double.

Was it helpful?

Solution

After further reading, I found an answer:

According to the reference documentation of the matrix class, the first template parameter _Scalar is:

_Scalar: matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex<float>.
User defined sclar types are supported as well.

It links to this page. It lists the requirements for the "custom scalar types". In the above example Eigen::NumTraits for <Vector3d> is missing. It can't be implemented properly for Vector3d, so one should only store types that represent scalars inside an Eigen::Matrix/Eigen::Array.


Update:

The line without assignment n.transpose() * velField; works because of lazy evalutation. It also works when doing this (in C++11):

auto result = n.transpose() * velField;

But it has done no calculation at that point (check the type of result in the debugger). As soon as you use result it will fail the same way than in your first example.

OTHER TIPS

This is not allowed. I'd recommend to store velField as a Matrix, i.e., a 1D array of 3D vectors, and then use standard linear algebra operators.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top