7

假设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_依赖于[]操作符在其交互中的实现。这让我觉得我可能会遇到与上面显示的简单(但损坏)解决方案相同的内存问题。

你认为什么可以解释这种行为?

4

2 回答 2

7

我还得到了 libflann 的作者 Marius Muja 的确认,它flann::Matrix以行优先顺序存储,而 Eigen 默认使用列优先。这是他通过电子邮件给我的答案:

问题很可能是 Eigen 以列优先顺序存储矩阵 > 而 FLANN 要求它们以行优先顺序存储。

一个解决方案是使用Matrix<double, Dynamic, Dynamic, RowMajor>代替MatrixXd,然后 FLANN 和 Eigen 矩阵可以共享相同的内存,否则将需要一个副本。马吕斯·穆加

于 2012-11-26T19:33:34.807 回答
1

Eigen::Matrix 连续存储数据,因此您不应该遇到跨步问题。如果您尝试在其上构造 Eigen::Matrix ,则对齐可能是问题(但我无法想象这是怎么可能的)。默认情况下 Eigen::Matrix 是列优先的,这可能是你的问题。我不知道 flann 如何处理矩阵,如果它们是行优先的,那么就是这样。以下示例使用 Eigen::Matrix< double, -1, -1, Eigen::RowMajor > for mat,但使用 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 的抱怨。将某些数据视为特征矩阵(请注意,默认情况下它仍然是列优先的),从矩阵子类化或实现自定义特征表达式可能是痛苦的,这是最好的方法。

于 2012-11-22T13:48:19.860 回答