diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 8410fcfd..71795b6a 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -385,8 +385,8 @@ void L2_dynamic_vs_bruteforce_test(const size_t nSamples) } template -void L2_concurrent_build_vs_bruteforce_test(const size_t nSamples, - const size_t DIM) +void L2_concurrent_build_vs_bruteforce_test( + const size_t nSamples, const size_t DIM) { std::vector> samples; @@ -406,7 +406,8 @@ void L2_concurrent_build_vs_bruteforce_test(const size_t nSamples, typedef KDTreeVectorOfVectorsAdaptor>, NUM> my_kd_tree_t; - my_kd_tree_t mat_index(DIM /*dim*/, samples, 10 /* max leaf */, 0 /* concurrent build */); + my_kd_tree_t mat_index( + DIM /*dim*/, samples, 10 /* max leaf */, 0 /* concurrent build */); // do a knn search const size_t num_results = 1; @@ -443,8 +444,7 @@ void L2_concurrent_build_vs_bruteforce_test(const size_t nSamples, } template -void L2_concurrent_build_vs_L2_test(const size_t nSamples, - const size_t DIM) +void L2_concurrent_build_vs_L2_test(const size_t nSamples, const size_t DIM) { std::vector> samples; @@ -464,8 +464,8 @@ void L2_concurrent_build_vs_L2_test(const size_t nSamples, typedef KDTreeVectorOfVectorsAdaptor>, NUM> my_kd_tree_t; - my_kd_tree_t mat_index_concurrent_build(DIM /*dim*/, samples, - 10 /* max leaf */, 0 /* concurrent build */); + my_kd_tree_t mat_index_concurrent_build( + DIM /*dim*/, samples, 10 /* max leaf */, 0 /* concurrent build */); my_kd_tree_t mat_index(DIM /*dim*/, samples, 10 /* max leaf */); // Compare: @@ -670,3 +670,79 @@ TEST(kdtree, L2_concurrent_build_vs_L2) L2_concurrent_build_vs_L2_test(100, 7); } } + +template +void L2_rknn_vs_bruteforce_test( + const size_t nSamples, const size_t DIM, const size_t NUM_CLOSEST, + const NUM maxRadiusSqr) +{ + std::vector> samples; + + const NUM max_range = NUM(20.0); + + // Generate points: + generateRandomPointCloud(samples, nSamples, DIM, max_range); + + // Query point: + std::vector query_pt(DIM); + for (size_t d = 0; d < DIM; d++) + query_pt[d] = static_cast(max_range * (rand() % 1000) / (1000.0)); + + // construct a kd-tree index: + // Dimensionality set at run-time (default: L2) + // ------------------------------------------------------------ + typedef KDTreeVectorOfVectorsAdaptor>, NUM> + my_kd_tree_t; + + my_kd_tree_t mat_index( + DIM /*dim*/, samples, 10 /* max leaf */, 0 /* concurrent build */); + + // do a knn search + const size_t num_results = NUM_CLOSEST; + std::vector ret_indexes(num_results); + std::vector out_dists_sqr(num_results); + + const auto nFound = mat_index.index->rknnSearch( + &query_pt[0], num_results, ret_indexes.data(), out_dists_sqr.data(), + maxRadiusSqr); + + // Brute force: + double min_dist_L2 = std::numeric_limits::max(); + size_t min_idx = std::numeric_limits::max(); + std::map<> xxx; + + { + for (size_t i = 0; i < nSamples; i++) + { + double dist = 0.0; + for (size_t d = 0; d < DIM; d++) + dist += (query_pt[d] - samples[i][d]) * + (query_pt[d] - samples[i][d]); + if (dist < min_dist_L2) + { + min_dist_L2 = dist; + min_idx = i; + } + } + ASSERT_TRUE(min_idx != std::numeric_limits::max()); + } + + // Compare: + EXPECT_EQ(min_idx, ret_indexes[0]); + EXPECT_NEAR(min_dist_L2, out_dists_sqr[0], 1e-3); +} + +TEST(kdtree, L2_rknn_vs_bruteforce_test) +{ + srand(static_cast(time(nullptr))); + for (int i = 0; i < 10; i++) + { + L2_rknn_vs_bruteforce_test(100, 2); + L2_rknn_vs_bruteforce_test(100, 3); + L2_rknn_vs_bruteforce_test(100, 7); + + L2_rknn_vs_bruteforce_test(100, 2); + L2_rknn_vs_bruteforce_test(100, 3); + L2_rknn_vs_bruteforce_test(100, 7); + } +}