c++ - Different return and coordinate types in nanoflann radius search -
i'm trying use nanoflann in project , looking @ vector-of-vector , radius search examples.
i can't find way perform radius search different data type coordinate type. example, coordinates vector
s of uint8_t
; trying input radius of type uint32_t
little success.
i see in source metric_l2 struct
(which using distance) uses l2_adaptor
2 template parameters. l2_adaptor
takes 3 parameters, third defaulted first, seems problem if understanding code correctly. however, trying force use of third results in 0 matches in radius search.
is there way this?
edit: in same code below, works. however, if change search_radius (and ret_matches) uint32_t, radiussearch method doesn't work.
#include <iostream> #include <eigen/dense> #include <nanoflann.hpp> typedef eigen::matrix<uint8_t, eigen::dynamic, 1> coord_t; using namespace nanoflann; struct point { coord_t address; point() {} point(uint8_t coordinates) : address(coord_t::random(coordinates)) {} }; struct container { std::vector<point> points; container(uint8_t coordinates, uint32_t l) : points(l) { for(auto& each_location: points) { each_location = point(coordinates); } } }; struct containeradaptor { typedef containeradaptor self_t; typedef nanoflann::metric_l2::traits<uint8_t, self_t>::distance_t metric_t; typedef kdtreesingleindexadaptor<metric_t, self_t, -1, size_t> index_t; index_t *index; const container &container; containeradaptor(const int dimensions, const container &container, const int leaf_max_size = 10) : container(container) { assert(container.points.size() != 0 && container.points[0].address.rows() != 0); const size_t dims = container.points[0].address.rows(); index = new index_t(dims, *this, nanoflann::kdtreesingleindexadaptorparams(leaf_max_size)); index->buildindex(); } ~containeradaptor() { delete index; } inline void query(const uint8_t *query_point, const size_t num_closest, size_t *out_indices, uint32_t *out_distances_sq, const int ignorethis = 10) const { nanoflann::knnresultset<uint32_t, size_t, size_t> resultset(num_closest); resultset.init(out_indices, out_distances_sq); index->findneighbors(resultset, query_point, nanoflann::searchparams()); } const self_t& derived() const { return *this; } self_t& derived() { return *this; } inline size_t kdtree_get_point_count() const { return container.points.size(); } inline size_t kdtree_distance(const uint8_t *p1, const size_t idx_p2, size_t size) const { size_t s = 0; (size_t = 0; < size; i++) { const uint8_t d = p1[i] - container.points[idx_p2].address[i]; s += d * d; } return s; } inline coord_t::scalar kdtree_get_pt(const size_t idx, int dim) const { return container.points[idx].address[dim]; } template <class bbox> bool kdtree_get_bbox(bbox & bb) const { for(size_t = 0; < bb.size(); i++) { bb[i].low = 0; bb[i].high = uint8_max; } return true; } }; void container_demo(const size_t points, const size_t coordinates) { container s(coordinates, points); coord_t query_pt(coord_t::random(coordinates)); typedef containeradaptor my_kd_tree_t; my_kd_tree_t mat_index(coordinates, s, 25); mat_index.index->buildindex(); const uint8_t search_radius = static_cast<uint8_t>(100); std::vector<std::pair<size_t, uint8_t>> ret_matches; nanoflann::searchparams params; const size_t nmatches = mat_index.index->radiussearch(query_pt.data(), search_radius, ret_matches, params); (size_t = 0; < nmatches; i++) { std::cout << "idx[" << << "]=" << +ret_matches[i].first << " dist[" << << "]=" << +ret_matches[i].second << std::endl; } std::cout << std::endl; std::cout << "radiussearch(): radius=" << +search_radius << " -> " << +nmatches << " matches" << std::endl; } int main() { container_demo(1e6, 32); return 0; }
more info: seems distance type, third parameter of l2_adaptor
, must signed type. changing metric_t typedef following solves problem if search_radius
, ret_matches
changed int64_t.
typedef l2_adaptor<uint8_t, self_t, int64_t> metric_t;
Comments
Post a Comment