7

I can't figure out if and how it's possible to map a two-dimensional double array to an Eigen::Matrix. Is it possible to map an array double d[][] which I receive as double** p to an Eigen::Matrix?

While one-dimensinal arrays work fine, I wasn't able to map p to Eigen::Map<Eigen::Matrix<double, n, n>>. Is that possible and how could it be done? The size n is not really constant, but I could accept a hard coded size.


I tried several versions, but none worked. I thought the following should work (assume the size n would be 4).

Eigen::Map<Eigen::Matrix<double, 4, 4>> p_OUTPUT(&p[0][0]);

The code compiles and runs, but only the elements of the first column and the first element of the second column map the correct values. Using p[0] as argument yields the same result. Other versions I tried (for example without the &) did not compile.

4
  • Can you show what you tried and what you want to achieve? Is n a compile time constant? And are you sure p is a double**? Commented Nov 9, 2016 at 15:13
  • @AviGinsburg Thanks for your reply, I completed my question. The size n is not a constant, but a hard coded size would be OK. And yes, I'm quite sure p is a double** because p[row][col] += ... works.
    – Pontis
    Commented Nov 9, 2016 at 15:41
  • See this post. Commented Nov 9, 2016 at 16:54
  • @AviGinsburg Many thanks, I upvoted your answer at the linked post! I found a very similar solution just at this moment.
    – Pontis
    Commented Nov 9, 2016 at 17:36

2 Answers 2

9

For the sake of completeness, I found a solution. As mentioned here or here the storage in not contiguous memory is the problem.

The following solution worked for me.

Eigen::MatrixXd ConvertToEigenMatrix(std::vector<std::vector<double>> data)
{
    Eigen::MatrixXd eMatrix(data.size(), data[0].size());
    for (int i = 0; i < data.size(); ++i)
        eMatrix.row(i) = Eigen::VectorXd::Map(&data[i][0], data[0].size());
    return eMatrix;
}
2

The answer you gave yourself is kind of a clue: Eigen, by default, stores matrices in column-major format, meaning that elements from this matrix:

m(0,0)  m(0,1)  m(0,2)
m(1,0)  m(1,1)  m(1,2)
m(2,0)  m(2,1)  m(2,2)

Are stored in a big linear array as:

[m(0,0), m(1,0), m(2,0), m(0,1), m(1,1), m(2,1), m(0,2), m(1,2), m(2,2)]

Your data (judging from your answer) is in row-major format, which is why you're pulling out memory-contiguous rows from your array and assigning them into rows in your result. You can tell Map that your data is in RowMajor format, and it should read your data correctly:

Eigen::Map<Eigen::Matrix<double, 4, 4, Eigen::RowMajor>> p_OUTPUT(p);
2
  • No, you assume that p points to a contiguous section of memory. For a double** that is not guaranteed. Commented Nov 13, 2016 at 8:35
  • The original question says that it's a double[][] that is passed to the function as a double**; if it's declared as an array, then it will be contiguous in memory. Commented Nov 14, 2016 at 16:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.