Skip to content

Commit d8bfec8

Browse files
authored
Merge pull request #276 from LeonardEyer/LeonardEyer-fix-dynamic-tree-sorted
fix: respect SearchParameters::sorted in dynamic index radius search
2 parents d517d20 + ed55543 commit d8bfec8

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

include/nanoflann.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,6 +2267,9 @@ class KDTreeSingleIndexDynamicAdaptor_
22672267
static_cast<typename distance_vector_t::value_type>(0));
22682268
DistanceType dist = this->computeInitialDistances(*this, vec, dists);
22692269
searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
2270+
2271+
if (searchParams.sorted) result.sort();
2272+
22702273
return result.full();
22712274
}
22722275

tests/test_main.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,60 @@ void L2_concurrent_build_vs_L2_test(const size_t nSamples, const size_t DIM)
661661
EXPECT_EQ(mat_index.index->vAcc_, mat_index_concurrent_build.index->vAcc_);
662662
}
663663

664+
665+
template <typename num_t>
666+
void L2_dynamic_sorted_test(const size_t N, const size_t num_results)
667+
{
668+
PointCloud<num_t> cloud;
669+
generateRandomPointCloud(cloud, N);
670+
671+
num_t query_pt[3] = {0.5, 0.5, 0.5};
672+
673+
using DynamicKDTree = KDTreeSingleIndexDynamicAdaptor<
674+
L2_Adaptor<num_t, PointCloud<num_t>>,
675+
PointCloud<num_t>,
676+
3 /* dim */
677+
>;
678+
679+
DynamicKDTree dynamic_index(3, cloud);
680+
681+
// Prepare result containers
682+
std::vector<size_t> dynamic_idx(num_results);
683+
std::vector<num_t> dynamic_dist(num_results);
684+
KNNResultSet<num_t> dynamic_knn_result(num_results);
685+
std::vector<ResultItem<size_t, num_t>> radius_results_vec;
686+
RadiusResultSet<num_t, size_t> dynamic_radius_result(10.0 * 10.0, radius_results_vec);
687+
688+
// Prepare search params to sort result
689+
const auto search_params = SearchParameters(0, true);
690+
691+
dynamic_knn_result.init(&dynamic_idx[0], &dynamic_dist[0]);
692+
dynamic_radius_result.init();
693+
694+
dynamic_index.findNeighbors(dynamic_knn_result, &query_pt[0], search_params);
695+
dynamic_index.findNeighbors(dynamic_radius_result, &query_pt[0], search_params);
696+
697+
// Check size
698+
const size_t expected_size = std::min(N, num_results);
699+
ASSERT_EQ(dynamic_knn_result.size(), expected_size);
700+
701+
// Ensure knn results are sorted
702+
num_t last_dist = -1;
703+
for (size_t i = 0; i < expected_size; i++)
704+
{
705+
EXPECT_GE(dynamic_dist[i], last_dist);
706+
last_dist = dynamic_dist[i];
707+
}
708+
709+
// Ensure radius results are sorted
710+
num_t last = -1;
711+
for (const auto& r : radius_results_vec)
712+
{
713+
EXPECT_GE(r.second, last);
714+
last = r.second;
715+
}
716+
}
717+
664718
TEST(kdtree, L2_vs_L2_simple)
665719
{
666720
for (int nResults = 1; nResults < 10; nResults++)
@@ -908,6 +962,15 @@ TEST(kdtree, L2_concurrent_build_vs_L2)
908962
}
909963
}
910964

965+
TEST(kdtree, L2_static_vs_dynamic)
966+
{
967+
for (int nResults = 0; nResults < 10; nResults++)
968+
{
969+
L2_dynamic_sorted_test<float>(100, nResults);
970+
L2_dynamic_sorted_test<double>(100, nResults);
971+
}
972+
}
973+
911974
TEST(kdtree, same_points)
912975
{
913976
using num_t = double;

0 commit comments

Comments
 (0)