使用 nanoflann 的 Stange 行为
Stange behaviour using nanoflann
使用 nanoflann-library 进行基于 KDTrees 的 k 最近邻搜索我遇到了一个非常奇怪的行为。我的代码是一组简单的查询:
#include <vector>
#include <iostream>
#include <nanoflann.hpp>
#include <eigen3/Eigen/Dense>
using Eigen::MatrixX3d;
using Eigen::Vector3d;
using nanoflann::KNNResultSet;
using nanoflann::SearchParams;
using kdt = nanoflann::KDTreeEigenMatrixAdaptor<MatrixX3d, 3, nanoflann::metric_L2>;
int main()
{
// Create simple matrix
MatrixX3d matrix(10, 3);
for(unsigned int i = 0; i < 10; i++)
{
double f_i = static_cast<double>(i);
matrix.row(i) = Vector3d(f_i, 0, 0);
}
// Create test points
std::vector<Vector3d> test_vecs;
for(unsigned int i = 0; i < 10; i++)
{
double f_i = static_cast<double>(i);
test_vecs.push_back(Vector3d(f_i, f_i, f_i));
}
// Result buffer
double distance;
size_t index;
KNNResultSet<double> result_set(1);
result_set.init(&index, &distance);
SearchParams sp;
// KDTree
kdt matrix_index(3, std::ref(matrix), 10);
matrix_index.index->buildIndex();
//Query points backwards
for(int i = 9; i >= 0; i--)
{
Vector3d curr_vec = test_vecs.at(i);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
std::cout << i << std::endl;
std::cout << index << " " << distance << std::endl << std::endl;
}
// Query points forwards
for(unsigned int i = 0; i < 10; i++)
{
Vector3d curr_vec = test_vecs.at(i);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
std::cout << i << std::endl;
std::cout << index << " " << distance << std::endl << std::endl;
}
}
反向查询(BQ
)returns预期结果。然而,前向查询(FQ
)只产生零(索引和距离)。 FQ
似乎也完全破坏了 KDTree。如果您更改两个查询的顺序(最后两个 for 循环),那么 FQ
在 BQ
之前执行,现在两者都只会产生零。
为什么会出现这种行为以及如何规避它?
结果集似乎是有状态的 - 它总是向您显示所有点的最近整体邻居。例如,如果从 5 循环到 10,每次迭代都会得到 5 50
每次迭代都重新初始化结果集,您将获得所需的行为:
result_set.init(&index, &distance);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
使用 nanoflann-library 进行基于 KDTrees 的 k 最近邻搜索我遇到了一个非常奇怪的行为。我的代码是一组简单的查询:
#include <vector>
#include <iostream>
#include <nanoflann.hpp>
#include <eigen3/Eigen/Dense>
using Eigen::MatrixX3d;
using Eigen::Vector3d;
using nanoflann::KNNResultSet;
using nanoflann::SearchParams;
using kdt = nanoflann::KDTreeEigenMatrixAdaptor<MatrixX3d, 3, nanoflann::metric_L2>;
int main()
{
// Create simple matrix
MatrixX3d matrix(10, 3);
for(unsigned int i = 0; i < 10; i++)
{
double f_i = static_cast<double>(i);
matrix.row(i) = Vector3d(f_i, 0, 0);
}
// Create test points
std::vector<Vector3d> test_vecs;
for(unsigned int i = 0; i < 10; i++)
{
double f_i = static_cast<double>(i);
test_vecs.push_back(Vector3d(f_i, f_i, f_i));
}
// Result buffer
double distance;
size_t index;
KNNResultSet<double> result_set(1);
result_set.init(&index, &distance);
SearchParams sp;
// KDTree
kdt matrix_index(3, std::ref(matrix), 10);
matrix_index.index->buildIndex();
//Query points backwards
for(int i = 9; i >= 0; i--)
{
Vector3d curr_vec = test_vecs.at(i);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
std::cout << i << std::endl;
std::cout << index << " " << distance << std::endl << std::endl;
}
// Query points forwards
for(unsigned int i = 0; i < 10; i++)
{
Vector3d curr_vec = test_vecs.at(i);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
std::cout << i << std::endl;
std::cout << index << " " << distance << std::endl << std::endl;
}
}
反向查询(BQ
)returns预期结果。然而,前向查询(FQ
)只产生零(索引和距离)。 FQ
似乎也完全破坏了 KDTree。如果您更改两个查询的顺序(最后两个 for 循环),那么 FQ
在 BQ
之前执行,现在两者都只会产生零。
为什么会出现这种行为以及如何规避它?
结果集似乎是有状态的 - 它总是向您显示所有点的最近整体邻居。例如,如果从 5 循环到 10,每次迭代都会得到 5 50
每次迭代都重新初始化结果集,您将获得所需的行为:
result_set.init(&index, &distance);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);