Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map two-dimensional array to Eigen::Matrix

Tags:

c++

eigen

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.

like image 548
theBridge Avatar asked Nov 09 '16 15:11

theBridge


People also ask

How is a two-dimensional array related to a matrix?

The two-dimensional array can be defined as an array of arrays. The 2D array is organized as matrices which can be represented as the collection of rows and columns. However, 2D arrays are created to implement a relational database lookalike data structure.

Is a map a 2D array?

Map Method for 2-dimensional Arrays Also called a map within a map: Sometimes you'll come across a multidimensional array -- that is, an array with nested arrays inside of it.

How is a two-dimensional array mapped in memory?

A 2D array is stored in the computer's memory one row following another. The address of the first byte of memory is considered as the memory location of the entire 2D array.

Is 2D array same as matrix?

A matrix is a 2D array with which follows the rules for linear algebra. It is, therefore, a subset of more general arrays which may be of higher dimension or not necessarily follow matrix algebra rules.


2 Answers

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;
}
like image 99
theBridge Avatar answered Sep 25 '22 23:09

theBridge


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);
like image 21
Haldean Brown Avatar answered Sep 25 '22 23:09

Haldean Brown