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?
- Row / column problem
- The internal problem of the outer step
- Memory Alignment Incompatibilities
Eigen::Mapsweet, but not what I'm looking for. It would suck to rewrite my code to usestl::vector<std::vector<double> >as the base types, andEigen::MapforEigen::MatrixXd- http://nanoflann-reference.mrpt.org/svn/structnanoflann_1_1KDTreeEigenMatrixAdaptor.html is unfortunately too far from the libflann base library to use.
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 ofMatrixXd, then the FLANN and Eigen matrices can use the same memory, otherwise a copy is required. Marius Mooja
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.