Преобразование Eigen::MatrixXd в flann::Matrix‹двойное› преобразование

Предположим, что mat ниже имеет тип Eigen::MatrixXd и уже содержит некоторые данные. Пытаясь избежать дублирования памяти, я попытался создать экземпляр объекта flann::Matrix<double> из указателя на кусок необработанной памяти, выделенный Eigen3:

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

Однако мой алгоритм выводит мусор, а с уродством вполне справляется:

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

}

Я исследовал вариант подкласса базового типа Matrix_ от flann, чтобы создать адаптер для матриц Eigen3. Проблема, однако, в том, что Matrix_ полагается на реализацию оператора [] в своем интерфейсе. Это заставляет меня чувствовать, что я могу столкнуться с той же проблемой памяти, что и в простом (но сломанном) решении, показанном выше.

Как вы думаете, чем можно объяснить такое поведение?

  • Основная проблема со строкой/столбцом
  • Внутренняя, внешняя проблема шага
  • Несовместимость выравнивания памяти
  • Eigen::Map мило, но это не то, что мне нужно. Было бы отстойно переписать мой код, чтобы использовать stl::vector<std::vector<double> > в качестве базовых типов и Eigen::Map их в Eigen::MatrixXd
  • http://nanoflann-reference.mrpt.org/svn/structnanoflannmat1KDTreeEigenMatrixAdaptor.html, к сожалению, слишком далеко от базовая библиотека libflann для использования.

person Pierre-Luc Bacon    schedule 20.11.2012    source источник


Ответы (2)


Я также получил подтверждение от Мариуса Муйи, автора libflann, что flann::Matrix хранит в порядке строк, тогда как Eigen по умолчанию использует порядок столбцов. Вот ответ, который он дал мне по электронной почте:

Проблема, скорее всего, заключается в том, что Eigen хранит матрицы в порядке столбцов>, в то время как FLANN требует их в порядке строк.

Решением было бы использовать Matrix<double, Dynamic, Dynamic, RowMajor> вместо MatrixXd, тогда матрицы FLANN и Eigen могут совместно использовать одну и ту же память, иначе потребуется копия. Мариус Муджа

person Pierre-Luc Bacon    schedule 26.11.2012
comment
У меня была такая же проблема с nanoFLANN (хотя это работало в обоих направлениях, но Column-Major по умолчанию был очень неуклюжим для моего приложения), спасибо! - person Oliver Zendel; 29.08.2013

Eigen::Matrix постоянно хранит данные, поэтому у вас не должно возникнуть проблем с шагом. Выравнивание может быть проблемой, если вы пытаетесь построить на нем Eigen::Matrix (но я не могу представить, как это возможно). По умолчанию Eigen::Matrix имеет основной столбец, это может быть вашей проблемой. Я не знаю, как flann относится к матрицам, если они мажорные по строкам, то все. Следующий пример работает с Eigen::Matrix‹ double, -1, -1, Eigen::RowMajor > для мата и не работает с 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);
}

У меня нет вашей жалобы на Eigen::Map. Это лучший способ обрабатывать некоторые данные как собственную матрицу (обратите внимание, что по умолчанию она все еще будет основной по столбцам), создание подклассов из матрицы или реализация собственного собственного выражения может быть болезненным.

person DikobrAz    schedule 22.11.2012