0

I have two Eigen::Array which have the same number of columns. One of them, a, has one row, and the other, b, has two rows. What I want to do, is to multiply every column of b with the entry in the respective column in a, so that it behaves like this:

ArrayXXd result;
result.resizeLike(b);
for (int i=0; i<a.cols(); ++i)
    result.col(i) = a.col(i)[0] * b.col(i);

However, it's part of a rather long expression with several of such multiplications, and I don't want to have to evaluate intermediate results in temporaries. Therefore, I'd rather get an Eigen expression of the above, like

auto expr = a * b;

This, of course, triggers an assertion, because a.rows() != b.rows().

What I tried, which works, is:

auto expr = a.replicate(2,1) * b;

However, the resulting code is very slow, so I hope there's a better option.

Possibly related.

RL-S
  • 734
  • 6
  • 21

2 Answers2

1

Eigen provides the possibility to use broadcasting for such cases. However, the one-dimensional array should first be converted into a Vector:

broadcasting operations can only be applied with an object of type Vector

This will work in your case:

RowVectorXd av = a;  
ArrayXXd expr = b.rowwise() * av.array();

Edit

To avoid a copy of the data into a new vector one can use Map:

ArrayXXd expr = b.rowwise() * RowVectorXd::Map(&a(0), a.cols()).array();  
RHertel
  • 23,412
  • 5
  • 38
  • 64
  • Your code requires copying the array ```a``` into the row vector ```av```. Given that this is a performance critical section of the code, that is not really useful to me. – RL-S Aug 20 '20 at 07:53
  • @RL-S I added a variant that does not require copying the array. – RHertel Aug 20 '20 at 08:23
  • right, I forgot about ```Map```, good idea, I'll try that. But I think ```Map(a.data(),...)``` would be a bit cleaner there. – RL-S Aug 20 '20 at 08:45
  • Yeah, using `.data()` is nice syntactic sugar. Doesn't really make a difference though. Since I am using primarily `Matrix` containers I am not immediately aware of all the member functions of the `Array` class. – RHertel Aug 20 '20 at 09:16
  • With the edit, your answer solved my problem. Just one more question: Do you know whether there's a difference between ```RowVectorXd::Map(...)``` and ```Map(...)```? – RL-S Aug 20 '20 at 13:48
  • Glad to hear that it helped. I believe that there is no difference between the two versions of `Map` that you mentioned. Maybe the developers of the Eigen library can say more about this. It would seem that `RowVectorXd::Map(...)` and `Map(...)` behave in the same way. – RHertel Aug 20 '20 at 14:21
0

I have posted the same solution to your previous question but here is my answer again:

  • Define your arrays with fixed number of rows but dynamic number of columns whereas ArrayXXd type yields an array with both dynamic number of rows and columns.
  • Use fixed-size version of operations. This should typically give faster code.
puhu
  • 176
  • 1
  • 8