Eigen :: MatrixXd for flann :: Matrix <double> conversion

Suppose the mat below is of type Eigen::MatrixXd and already contains some data. To avoid duplication of memory, I tried to instantiate a flann::Matrix<double> object from a pointer to a piece of raw memory allocated by Eigen3:

 flann::Matrix<double> input(const_cast<double *>(mat.data(), mat.rows(), mat.cols()) 

However, my algorithm outputs garbage, but with ugly looks simple:

 flann::Matrix<double> input(new double[mat.rows()*mat.cols()], mat.rows(), mat.cols()); for (int i = 0; i < mat.rows(); i++) { for (int j = 0; j < mat.cols(); j++) { input[i][j] = mat(i, j); } 

}

I explored the possibility of subclassing the base type Matrix_ from flann to create an adapter for Eigen3 matrices. The problem is that Matrix_ relies on the implementation of the [] operator in its interaction. This makes me feel that I may run into the same memory problem as in the simple (but broken) solution shown above.

Do you think this can explain this behavior?

+7
source share
2 answers

I also have confirmation from Marius Muja, author of libflann, that flann::Matrix is stored in a row order, while Eigen uses columns by default. Here is the answer he gave me via email:

The problem is most likely that Eigen stores matrices in the main column order>, while FLANN requires them in row order.

The solution would be to use Matrix<double, Dynamic, Dynamic, RowMajor> instead of MatrixXd , then the FLANN and Eigen matrices can use the same memory, otherwise a copy is required. Marius Mooja

+7
source

Eigen :: Matrix stores data continuously, so you should not create problems with steps. Alignment can be a problem if you are trying to build Eigen :: Matrix on it (but I cannot imagine how this is possible). By default, Eigen :: Matrix is ​​the main column, this may be your problem. I do not know how flann process matrices, if they are ordinary, then this is so. The following example works with Eigen :: Matrix <double, -1, -1, Eigen :: RowMajor> for mat and does not work with Eigen :: MatrixXd.

 int k = 0; for (int i = 0; i<mat.rows(); ++i) { for (int j = 0; j<mat.cols(); ++j, ++k) { mat(i, j) = k; } } double* mptr = mat.data(); for (int i = 0; i<mat.rows() * mat.cols(); ++i) { assert(mptr[i] == i); } 

I am not complaining about Eigen :: Map. This is the finest way to treat some data as a custom matrix (note that it will still be column-significant), subclassing from a matrix, or implementing a custom custom expression can be painful.

0
source

All Articles