4

I am trying to bring code from Matlab to C++. There is some information related to my case in the KDE Eigen Forums.

What I try to achieve is related to Matlab's meshgrid, for which the solution given over there is

X = RowVectorXd::LinSpaced(1,3,3).replicate(5,1);
Y = VectorXd::LinSpaced(10,14,5).replicate(1,3);

i.e., .replicate the vectors the amount of the other dimension. In my case I have two existing (n x 1) vectors and want to create a (n^2, 2) matrix which contains all combinations of vector elements, that is:

[1 3 6]^T and [7 8]^T ==> [1 7, 3 7, 6 7, 1 8, 3 8, 6 8]^T

where ^T just means transposed, lines are comma-separated. (In my case the vectors use floats, but that shouldn't matter).

The first column of the matrix [1 3 6 1 3 6]^T is easily created by Eigen's .replicate function. However, I struggle to create the second column [7 7 7 8 8 8]^T.

My idea was to use .replicate in the other dimension (obtaining a matrix) and then use a rowWise Eigen::Map to bring it to a linear (vector) view (as suggested in the docs), but I understand the arising compiler error such that Eigen::Map doesn't work with an Eigen::Replicate type.

#include <Eigen/Core>
using namespace Eigen;
int main()
{
    MatrixXd reptest1(1, 5);
    reptest1 << 1, 2, 3, 4, 5;
    auto result2 = reptest1.replicate(2, 1); // cols, rows: 5, 2
    auto result3 = Map<Matrix<double, 1, Dynamic, Eigen::RowMajor> >(result2);  // this doesn't work
return 0;
}

VS2017 complains: error C2440: '<function-style-cast>': cannot convert from 'Eigen::Replicate<Derived,-1,-1>' to 'Eigen::Map<Eigen::Matrix<double,1,-1,1,1,-1>,0,Eigen::Stride<0,0>>' GCC also complains. no matching function for call (can't copy&paste exact message as it is on another machine).

Am I doing this too complicated? Should using Map work?

glennsl
  • 28,186
  • 12
  • 57
  • 75

1 Answers1

2

Map can only work on matrices, not on expressions. So replace auto result2 by MatrixXd result2, and you're done. See common pitfalls.

ggael
  • 28,425
  • 2
  • 65
  • 71
  • Thank you for that extraordinarily quick answer. However, even without auto it doesn't work `MatrixXd result2 = reptest1.replicate(2, 1); // cols, rows: 5, 2 VectorXd result3 = Map >(result2);` – AverageCoder Mar 16 '17 at 09:22
  • `Map resultAsCol(result2.data(), result2.size());` seems to do what I want. I accept your answer and thanks to the link to the common pitfalls. Have overlooked it and this is important to know as I usually try to embrace C++11 and C++14 as much as possible. – AverageCoder Mar 16 '17 at 09:33
  • Right, I overlooked this second mistake. – ggael Mar 16 '17 at 11:50