6
votes

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.

2
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**?Avi Ginsburg
@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.theBridge
See this post.Avi Ginsburg
@AviGinsburg Many thanks, I upvoted your answer at the linked post! I found a very similar solution just at this moment.theBridge

2 Answers

7
votes

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;
}
1
votes

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);