48#pragma GCC diagnostic ignored "-Wunused-parameter"
61#include <unordered_set>
65#define NANOFLANN_VERSION 0x151
68#if !defined(NOMINMAX) && (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
89 return static_cast<T
>(3.14159265358979323846);
96template <
typename T,
typename =
int>
102template <
typename T,
typename =
int>
106struct has_assign<T, decltype((void)std::declval<T>().
assign(1, 0), 0)> : std::true_type {};
111template <
typename Container>
112inline typename std::enable_if<has_resize<Container>::value,
void>::type
resize(Container& c,
const size_t nElements) {
120template <
typename Container>
121inline typename std::enable_if<!has_resize<Container>::value,
void>::type
resize(Container& c,
const size_t nElements) {
122 if (nElements != c.size())
throw std::logic_error(
"Try to change the size of a std::array.");
128template <
typename Container,
typename T>
129inline typename std::enable_if<has_assign<Container>::value,
void>::type
assign(Container& c,
const size_t nElements,
const T& value) {
130 c.assign(nElements, value);
136template <
typename Container,
typename T>
137inline typename std::enable_if<!has_assign<Container>::value,
void>::type
assign(Container& c,
const size_t nElements,
const T& value) {
138 for (
size_t i = 0; i < nElements; i++) c[i] = value;
145template <
typename _DistanceType,
typename _IndexType =
size_t,
typename _CountType =
size_t>
165 if (capacity) dists[capacity - 1] = (std::numeric_limits<DistanceType>::max)();
169 bool empty()
const {
return count == 0; }
170 bool full()
const {
return count == capacity; }
179 for (i = count; i > 0; --i) {
182#ifdef NANOFLANN_FIRST_MATCH
183 if ((dists[i - 1] > dist) || ((dist == dists[i - 1]) && (indices[i - 1] > index))) {
185 if (dists[i - 1] > dist) {
188 dists[i] = dists[i - 1];
189 indices[i] = indices[i - 1];
198 if (count < capacity) count++;
208template <
typename _DistanceType,
typename _IndexType =
size_t,
typename _CountType =
size_t>
224 : indices(nullptr), dists(nullptr), capacity(capacity_), count(0), maximumSearchDistanceSquared(maximumSearchDistanceSquared_) {}
230 if (capacity) dists[capacity - 1] = maximumSearchDistanceSquared;
234 bool empty()
const {
return count == 0; }
235 bool full()
const {
return count == capacity; }
244 for (i = count; i > 0; --i) {
247#ifdef NANOFLANN_FIRST_MATCH
248 if ((dists[i - 1] > dist) || ((dist == dists[i - 1]) && (indices[i - 1] > index))) {
250 if (dists[i - 1] > dist) {
253 dists[i] = dists[i - 1];
254 indices[i] = indices[i - 1];
263 if (count < capacity) count++;
275 template <
typename PairType>
276 bool operator()(
const PairType& p1,
const PairType& p2)
const {
277 return p1.second < p2.second;
289template <
typename IndexType =
size_t,
typename DistanceType =
double>
292 ResultItem(
const IndexType index,
const DistanceType distance) : first(index), second(distance) {}
301template <
typename _DistanceType,
typename _IndexType =
size_t>
313 : radius(radius_), m_indices_dists(indices_dists) {
318 void clear() { m_indices_dists.clear(); }
320 size_t size()
const {
return m_indices_dists.size(); }
321 size_t empty()
const {
return m_indices_dists.empty(); }
323 bool full()
const {
return true; }
331 if (dist < radius) m_indices_dists.emplace_back(index, dist);
342 if (m_indices_dists.empty())
343 throw std::runtime_error(
344 "Cannot invoke RadiusResultSet::worst_item() on "
345 "an empty list of results.");
346 auto it = std::max_element(m_indices_dists.begin(), m_indices_dists.end(),
IndexDist_Sorter());
357 stream.write(
reinterpret_cast<const char*
>(&value),
sizeof(T));
361void save_value(std::ostream& stream,
const std::vector<T>& value) {
362 size_t size = value.size();
363 stream.write(
reinterpret_cast<const char*
>(&size),
sizeof(
size_t));
364 stream.write(
reinterpret_cast<const char*
>(value.data()),
sizeof(T) * size);
369 stream.read(
reinterpret_cast<char*
>(&value),
sizeof(T));
373void load_value(std::istream& stream, std::vector<T>& value) {
375 stream.read(
reinterpret_cast<char*
>(&size),
sizeof(
size_t));
377 stream.read(
reinterpret_cast<char*
>(value.data()),
sizeof(T) * size);
396template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
403 L1_Adaptor(
const DataSource& _data_source) : data_source(_data_source) {}
407 const T* last = a + size;
408 const T* lastgroup = last - 3;
412 while (a < lastgroup) {
413 const DistanceType diff0 = std::abs(a[0] - data_source.kdtree_get_pt(b_idx, d++));
414 const DistanceType diff1 = std::abs(a[1] - data_source.kdtree_get_pt(b_idx, d++));
415 const DistanceType diff2 = std::abs(a[2] - data_source.kdtree_get_pt(b_idx, d++));
416 const DistanceType diff3 = std::abs(a[3] - data_source.kdtree_get_pt(b_idx, d++));
417 result += diff0 + diff1 + diff2 + diff3;
419 if ((worst_dist > 0) && (result > worst_dist)) {
426 result += std::abs(*a++ - data_source.kdtree_get_pt(b_idx, d++));
431 template <
typename U,
typename V>
433 return std::abs(a - b);
447template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
454 L2_Adaptor(
const DataSource& _data_source) : data_source(_data_source) {}
458 const T* last = a + size;
459 const T* lastgroup = last - 3;
463 while (a < lastgroup) {
464 const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx, d++);
465 const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx, d++);
466 const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx, d++);
467 const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx, d++);
468 result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
470 if ((worst_dist > 0) && (result > worst_dist)) {
477 const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx, d++);
478 result += diff0 * diff0;
483 template <
typename U,
typename V>
485 return (a - b) * (a - b);
499template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
510 for (
size_t i = 0; i < size; ++i) {
511 const DistanceType diff = a[i] - data_source.kdtree_get_pt(b_idx, i);
512 result += diff * diff;
517 template <
typename U,
typename V>
519 return (a - b) * (a - b);
533template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
540 SO2_Adaptor(
const DataSource& _data_source) : data_source(_data_source) {}
543 return accum_dist(a[size - 1], data_source.kdtree_get_pt(b_idx, size - 1), size - 1);
548 template <
typename U,
typename V>
555 else if (result < -PI)
571template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
578 SO3_Adaptor(
const DataSource& _data_source) : distance_L2_Simple(_data_source) {}
581 return distance_L2_Simple.
evalMetric(a, b_idx, size);
584 template <
typename U,
typename V>
586 return distance_L2_Simple.
accum_dist(a, b, idx);
592 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
600 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
608 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
615 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
622 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
637 using underlying =
typename std::underlying_type<KDTreeSingleIndexAdaptorFlags>::type;
638 return static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs);
645 unsigned int _n_thread_build = 1)
646 : leaf_max_size(_leaf_max_size), flags(_flags), n_thread_build(_n_thread_build) {}
681 static constexpr size_t WORDSIZE = 16;
682 static constexpr size_t BLOCKSIZE = 8192;
690 using Offset = uint32_t;
691 using Size = uint32_t;
692 using Dimension = int32_t;
695 void* base_ =
nullptr;
696 void* loc_ =
nullptr;
698 void internal_init() {
707 Size wastedMemory = 0;
721 while (base_ !=
nullptr) {
723 void* prev = *(
static_cast<void**
>(base_));
739 const Size size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
744 if (size > remaining_) {
745 wastedMemory += remaining_;
748 const Size blocksize = (size +
sizeof(
void*) + (WORDSIZE - 1) > BLOCKSIZE) ? size +
sizeof(
void*) + (WORDSIZE - 1) : BLOCKSIZE;
751 void* m = ::malloc(blocksize);
753 fprintf(stderr,
"Failed to allocate memory.\n");
754 throw std::bad_alloc();
758 static_cast<void**
>(m)[0] = base_;
765 remaining_ = blocksize -
sizeof(
void*) - shift;
766 loc_ = (
static_cast<char*
>(m) +
sizeof(
void*) + shift);
769 loc_ =
static_cast<char*
>(loc_) + size;
784 template <
typename T>
786 T* mem =
static_cast<T*
>(this->malloc(
sizeof(T) * count));
798template <
int32_t DIM,
typename T>
800 using type = std::array<T, DIM>;
824template <
class Derived,
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
830 obj.pool_.free_all();
831 obj.root_node_ =
nullptr;
832 obj.size_at_index_build_ = 0;
843 using Offset =
typename decltype(vAcc_)::size_type;
844 using Size =
typename decltype(vAcc_)::size_type;
865 Node *child1 =
nullptr, *child2 =
nullptr;
908 Size size(
const Derived& obj)
const {
return obj.size_; }
911 Size veclen(
const Derived& obj) {
return DIM > 0 ? DIM : obj.dim; }
915 return obj.dataset_.kdtree_get_pt(element, component);
923 return obj.pool_.usedMemory + obj.pool_.wastedMemory +
924 obj.dataset_.kdtree_get_point_count() *
sizeof(IndexType);
928 min_elem = dataset_get(obj, vAcc_[ind], element);
930 for (
Offset i = 1; i < count; ++i) {
931 ElementType val = dataset_get(obj, vAcc_[ind + i], element);
932 if (val < min_elem) min_elem = val;
933 if (val > max_elem) max_elem = val;
945 NodePtr node = obj.pool_.template allocate<Node>();
946 const auto dims = (DIM > 0 ? DIM : obj.dim_);
949 if ((right - left) <=
static_cast<Offset>(obj.leaf_max_size_)) {
956 bbox[i].low = dataset_get(obj, obj.vAcc_[left], i);
957 bbox[i].high = dataset_get(obj, obj.vAcc_[left], i);
959 for (
Offset k = left + 1; k < right; ++k) {
961 const auto val = dataset_get(obj, obj.vAcc_[k], i);
962 if (bbox[i].low > val) bbox[i].low = val;
963 if (bbox[i].high < val) bbox[i].high = val;
970 middleSplit_(obj, left, right - left, idx, cutfeat, cutval, bbox);
975 left_bbox[cutfeat].high = cutval;
976 node->
child1 = this->divideTree(obj, left, left + idx, left_bbox);
979 right_bbox[cutfeat].low = cutval;
980 node->
child2 = this->divideTree(obj, left + idx, right, right_bbox);
986 bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
987 bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1005 std::atomic<unsigned int>& thread_count, std::mutex& mutex) {
1006 std::unique_lock<std::mutex> lock(mutex);
1007 NodePtr node = obj.pool_.template allocate<Node>();
1010 const auto dims = (DIM > 0 ? DIM : obj.dim_);
1013 if ((right - left) <=
static_cast<Offset>(obj.leaf_max_size_)) {
1020 bbox[i].low = dataset_get(obj, obj.vAcc_[left], i);
1021 bbox[i].high = dataset_get(obj, obj.vAcc_[left], i);
1023 for (
Offset k = left + 1; k < right; ++k) {
1025 const auto val = dataset_get(obj, obj.vAcc_[k], i);
1026 if (bbox[i].low > val) bbox[i].low = val;
1027 if (bbox[i].high < val) bbox[i].high = val;
1034 middleSplit_(obj, left, right - left, idx, cutfeat, cutval, bbox);
1038 std::future<NodePtr> left_future, right_future;
1041 left_bbox[cutfeat].high = cutval;
1042 if (++thread_count < n_thread_build_) {
1043 left_future = std::async(std::launch::async, &KDTreeBaseClass::divideTreeConcurrent,
this, std::ref(obj), left, left + idx,
1044 std::ref(left_bbox), std::ref(thread_count), std::ref(mutex));
1047 node->
child1 = this->divideTreeConcurrent(obj, left, left + idx, left_bbox, thread_count, mutex);
1051 right_bbox[cutfeat].low = cutval;
1052 if (++thread_count < n_thread_build_) {
1053 right_future = std::async(std::launch::async, &KDTreeBaseClass::divideTreeConcurrent,
this, std::ref(obj), left + idx, right,
1054 std::ref(right_bbox), std::ref(thread_count), std::ref(mutex));
1057 node->
child2 = this->divideTreeConcurrent(obj, left + idx, right, right_bbox, thread_count, mutex);
1060 if (left_future.valid()) {
1061 node->
child1 = left_future.get();
1064 if (right_future.valid()) {
1065 node->
child2 = right_future.get();
1073 bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
1074 bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1083 const auto dims = (DIM > 0 ? DIM : obj.dim_);
1085 ElementType max_span = bbox[0].high - bbox[0].low;
1088 if (span > max_span) {
1097 if (span > (1 - EPS) * max_span) {
1099 computeMinMax(obj, ind, count, i, min_elem_, max_elem_);
1101 if (spread > max_spread) {
1103 max_spread = spread;
1104 min_elem = min_elem_;
1105 max_elem = max_elem_;
1110 DistanceType split_val = (bbox[cutfeat].low + bbox[cutfeat].high) / 2;
1112 if (split_val < min_elem)
1114 else if (split_val > max_elem)
1120 planeSplit(obj, ind, count, cutfeat, cutval, lim1, lim2);
1122 if (lim1 > count / 2)
1124 else if (lim2 < count / 2)
1143 Offset right = count - 1;
1145 while (left <= right && dataset_get(obj, vAcc_[ind + left], cutfeat) < cutval) ++left;
1146 while (right && left <= right && dataset_get(obj, vAcc_[ind + right], cutfeat) >= cutval) --right;
1147 if (left > right || !right)
break;
1148 std::swap(vAcc_[ind + left], vAcc_[ind + right]);
1158 while (left <= right && dataset_get(obj, vAcc_[ind + left], cutfeat) <= cutval) ++left;
1159 while (right && left <= right && dataset_get(obj, vAcc_[ind + right], cutfeat) > cutval) --right;
1160 if (left > right || !right)
break;
1161 std::swap(vAcc_[ind + left], vAcc_[ind + right]);
1172 for (
Dimension i = 0; i < (DIM > 0 ? DIM : obj.dim_); ++i) {
1173 if (vec[i] < obj.root_bbox_[i].low) {
1174 dists[i] = obj.distance_.accum_dist(vec[i], obj.root_bbox_[i].low, i);
1177 if (vec[i] > obj.root_bbox_[i].high) {
1178 dists[i] = obj.distance_.accum_dist(vec[i], obj.root_bbox_[i].high, i);
1187 if (tree->
child1 !=
nullptr) {
1188 save_tree(obj, stream, tree->
child1);
1190 if (tree->
child2 !=
nullptr) {
1191 save_tree(obj, stream, tree->
child2);
1196 tree = obj.pool_.template allocate<Node>();
1198 if (tree->
child1 !=
nullptr) {
1199 load_tree(obj, stream, tree->
child1);
1201 if (tree->
child2 !=
nullptr) {
1202 load_tree(obj, stream, tree->
child2);
1211 void saveIndex(
const Derived& obj, std::ostream& stream)
const {
1217 if (obj.root_node_) save_tree(obj, stream, obj.root_node_);
1231 load_tree(obj, stream, obj.root_node_);
1276template <
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
1278 :
public KDTreeBaseClass<KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, IndexType>, Distance, DatasetAdaptor, DIM, IndexType> {
1291 DatasetAdaptor, DIM, IndexType>;
1333 template <
class... Args>
1336 : dataset_(inputData), indexParams(params), distance_(inputData, std::forward<Args>(args)...) {
1337 init(dimensionality, params);
1342 : dataset_(inputData), indexParams(params), distance_(inputData) {
1343 init(dimensionality, params);
1347 void init(
const Dimension dimensionality,
const KDTreeSingleIndexAdaptorParams& params) {
1348 Base::size_ = dataset_.kdtree_get_point_count();
1349 Base::size_at_index_build_ = Base::size_;
1350 Base::dim_ = dimensionality;
1351 if (DIM > 0) Base::dim_ = DIM;
1352 Base::leaf_max_size_ = params.leaf_max_size;
1353 if (params.n_thread_build > 0) {
1354 Base::n_thread_build_ = params.n_thread_build;
1356 Base::n_thread_build_ = std::max(std::thread::hardware_concurrency(), 1u);
1359 if (!(params.flags & KDTreeSingleIndexAdaptorFlags::SkipInitialBuildIndex)) {
1370 Base::size_ = dataset_.kdtree_get_point_count();
1371 Base::size_at_index_build_ = Base::size_;
1373 this->freeIndex(*
this);
1374 Base::size_at_index_build_ = Base::size_;
1375 if (Base::size_ == 0)
return;
1376 computeBoundingBox(Base::root_bbox_);
1378 if (Base::n_thread_build_ == 1) {
1379 Base::root_node_ = this->divideTree(*
this, 0, Base::size_, Base::root_bbox_);
1381 std::atomic<unsigned int> thread_count(0u);
1383 Base::root_node_ = this->divideTreeConcurrent(*
this, 0, Base::size_, Base::root_bbox_, thread_count, mutex);
1406 template <
typename RESULTSET>
1409 if (this->size(*
this) == 0)
return false;
1410 if (!Base::root_node_)
1411 throw std::runtime_error(
1412 "[nanoflann] findNeighbors() called before building the "
1414 float epsError = 1 + searchParams.eps;
1417 distance_vector_t dists;
1419 auto zero =
static_cast<decltype(result.worstDist())
>(0);
1420 assign(dists, (DIM > 0 ? DIM : Base::dim_), zero);
1421 DistanceType dist = this->computeInitialDistances(*
this, vec, dists);
1422 searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
1423 return result.full();
1443 resultSet.
init(out_indices, out_distances);
1444 findNeighbors(resultSet, query_point);
1445 return resultSet.
size();
1470 const Size nFound = radiusSearchCustomCallback(query_point, resultSet, searchParams);
1471 if (searchParams.sorted) std::sort(IndicesDists.begin(), IndicesDists.end(),
IndexDist_Sorter());
1480 template <
class SEARCH_CALLBACK>
1483 findNeighbors(resultSet, query_point, searchParams);
1484 return resultSet.size();
1506 resultSet.
init(out_indices, out_distances);
1507 findNeighbors(resultSet, query_point);
1508 return resultSet.
size();
1518 Base::size_ = dataset_.kdtree_get_point_count();
1519 if (Base::vAcc_.size() != Base::size_) Base::vAcc_.resize(Base::size_);
1520 for (
Size i = 0; i < Base::size_; i++) Base::vAcc_[i] = i;
1524 const auto dims = (DIM > 0 ? DIM : Base::dim_);
1526 if (dataset_.kdtree_get_bbox(bbox)) {
1529 const Size N = dataset_.kdtree_get_point_count();
1531 throw std::runtime_error(
1532 "[nanoflann] computeBoundingBox() called but "
1533 "no data points found.");
1535 bbox[i].low = bbox[i].high = this->dataset_get(*
this, Base::vAcc_[0], i);
1537 for (
Offset k = 1; k < N; ++k) {
1539 const auto val = this->dataset_get(*
this, Base::vAcc_[k], i);
1540 if (val < bbox[i].low) bbox[i].low = val;
1541 if (val > bbox[i].high) bbox[i].high = val;
1553 template <
class RESULTSET>
1555 const float epsError)
const {
1557 if ((node->child1 ==
nullptr) && (node->child2 ==
nullptr)) {
1559 for (
Offset i = node->node_type.lr.left; i < node->node_type.lr.right; ++i) {
1560 const IndexType accessor = Base::vAcc_[i];
1561 DistanceType dist = distance_.evalMetric(vec, accessor, (DIM > 0 ? DIM : Base::dim_));
1562 if (dist < worst_dist) {
1563 if (!result_set.addPoint(dist, Base::vAcc_[i])) {
1574 Dimension idx = node->node_type.sub.divfeat;
1577 DistanceType diff2 = val - node->node_type.sub.divhigh;
1582 if ((diff1 + diff2) < 0) {
1583 bestChild = node->child1;
1584 otherChild = node->child2;
1585 cut_dist = distance_.accum_dist(val, node->node_type.sub.divhigh, idx);
1587 bestChild = node->child2;
1588 otherChild = node->child1;
1589 cut_dist = distance_.accum_dist(val, node->node_type.sub.divlow, idx);
1593 if (!searchLevel(result_set, vec, bestChild, mindist, dists, epsError)) {
1600 mindist = mindist + cut_dist - dst;
1601 dists[idx] = cut_dist;
1602 if (mindist * epsError <= result_set.worstDist()) {
1603 if (!searchLevel(result_set, vec, otherChild, mindist, dists, epsError)) {
1619 void saveIndex(std::ostream& stream)
const { Base::saveIndex(*
this, stream); }
1626 void loadIndex(std::istream& stream) { Base::loadIndex(*
this, stream); }
1667template <
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
1669 Distance, DatasetAdaptor, DIM, IndexType> {
1683 Distance, DatasetAdaptor, DIM, IndexType>;
1721 : dataset_(inputData), index_params_(params), treeIndex_(treeIndex), distance_(inputData) {
1723 Base::size_at_index_build_ = 0;
1724 for (
auto& v : Base::root_bbox_) v = {};
1725 Base::dim_ = dimensionality;
1726 if (DIM > 0) Base::dim_ = DIM;
1727 Base::leaf_max_size_ = params.leaf_max_size;
1728 if (params.n_thread_build > 0) {
1729 Base::n_thread_build_ = params.n_thread_build;
1731 Base::n_thread_build_ = std::max(std::thread::hardware_concurrency(), 1u);
1741 std::swap(Base::vAcc_, tmp.Base::vAcc_);
1742 std::swap(Base::leaf_max_size_, tmp.Base::leaf_max_size_);
1745 std::swap(Base::size_, tmp.Base::size_);
1746 std::swap(Base::size_at_index_build_, tmp.Base::size_at_index_build_);
1747 std::swap(Base::root_node_, tmp.Base::root_node_);
1748 std::swap(Base::root_bbox_, tmp.Base::root_bbox_);
1749 std::swap(Base::pool_, tmp.Base::pool_);
1757 Base::size_ = Base::vAcc_.size();
1758 this->freeIndex(*
this);
1759 Base::size_at_index_build_ = Base::size_;
1760 if (Base::size_ == 0)
return;
1761 computeBoundingBox(Base::root_bbox_);
1763 if (Base::n_thread_build_ == 1) {
1764 Base::root_node_ = this->divideTree(*
this, 0, Base::size_, Base::root_bbox_);
1766 std::atomic<unsigned int> thread_count(0u);
1768 Base::root_node_ = this->divideTreeConcurrent(*
this, 0, Base::size_, Base::root_bbox_, thread_count, mutex);
1795 template <
typename RESULTSET>
1798 if (this->size(*
this) == 0)
return false;
1799 if (!Base::root_node_)
return false;
1800 float epsError = 1 + searchParams.eps;
1803 distance_vector_t dists;
1805 assign(dists, (DIM > 0 ? DIM : Base::dim_), static_cast<typename distance_vector_t::value_type>(0));
1806 DistanceType dist = this->computeInitialDistances(*
this, vec, dists);
1807 searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
1808 return result.full();
1828 resultSet.init(out_indices, out_distances);
1829 findNeighbors(resultSet, query_point, searchParams);
1830 return resultSet.size();
1855 const size_t nFound = radiusSearchCustomCallback(query_point, resultSet, searchParams);
1856 if (searchParams.sorted) std::sort(IndicesDists.begin(), IndicesDists.end(),
IndexDist_Sorter());
1865 template <
class SEARCH_CALLBACK>
1868 findNeighbors(resultSet, query_point, searchParams);
1869 return resultSet.size();
1876 const auto dims = (DIM > 0 ? DIM : Base::dim_);
1879 if (dataset_.kdtree_get_bbox(bbox)) {
1882 const Size N = Base::size_;
1884 throw std::runtime_error(
1885 "[nanoflann] computeBoundingBox() called but "
1886 "no data points found.");
1888 bbox[i].low = bbox[i].high = this->dataset_get(*
this, Base::vAcc_[0], i);
1890 for (
Offset k = 1; k < N; ++k) {
1892 const auto val = this->dataset_get(*
this, Base::vAcc_[k], i);
1893 if (val < bbox[i].low) bbox[i].low = val;
1894 if (val > bbox[i].high) bbox[i].high = val;
1904 template <
class RESULTSET>
1906 const float epsError)
const {
1908 if ((node->child1 ==
nullptr) && (node->child2 ==
nullptr)) {
1910 for (
Offset i = node->node_type.lr.left; i < node->node_type.lr.right; ++i) {
1911 const IndexType index = Base::vAcc_[i];
1912 if (treeIndex_[index] == -1)
continue;
1913 DistanceType dist = distance_.evalMetric(vec, index, (DIM > 0 ? DIM : Base::dim_));
1914 if (dist < worst_dist) {
1915 if (!result_set.addPoint(
static_cast<typename RESULTSET::DistanceType
>(dist),
1916 static_cast<typename RESULTSET::IndexType
>(Base::vAcc_[i]))) {
1927 Dimension idx = node->node_type.sub.divfeat;
1930 DistanceType diff2 = val - node->node_type.sub.divhigh;
1935 if ((diff1 + diff2) < 0) {
1936 bestChild = node->child1;
1937 otherChild = node->child2;
1938 cut_dist = distance_.accum_dist(val, node->node_type.sub.divhigh, idx);
1940 bestChild = node->child2;
1941 otherChild = node->child1;
1942 cut_dist = distance_.accum_dist(val, node->node_type.sub.divlow, idx);
1946 searchLevel(result_set, vec, bestChild, mindist, dists, epsError);
1949 mindist = mindist + cut_dist - dst;
1950 dists[idx] = cut_dist;
1951 if (mindist * epsError <= result_set.worstDist()) {
1952 searchLevel(result_set, vec, otherChild, mindist, dists, epsError);
1987template <
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
2026 int First0Bit(IndexType num) {
2037 using my_kd_tree_t = KDTreeSingleIndexDynamicAdaptor_<Distance, DatasetAdaptor, DIM, IndexType>;
2038 std::vector<my_kd_tree_t> index(treeCount_, my_kd_tree_t(dim_ , dataset_, treeIndex_, index_params_));
2062 const size_t maximumPointCount = 1000000000U)
2063 : dataset_(inputData), index_params_(params), distance_(inputData) {
2064 treeCount_ =
static_cast<size_t>(std::log2(maximumPointCount)) + 1;
2066 dim_ = dimensionality;
2068 if (DIM > 0) dim_ = DIM;
2071 const size_t num_initial_points = dataset_.kdtree_get_point_count();
2072 if (num_initial_points > 0) {
2073 addPoints(0, num_initial_points - 1);
2082 const Size count = end - start + 1;
2084 treeIndex_.resize(treeIndex_.size() + count);
2085 for (IndexType idx = start; idx <= end; idx++) {
2086 const int pos = First0Bit(pointCount_);
2087 maxIndex = std::max(pos, maxIndex);
2088 treeIndex_[pointCount_] = pos;
2090 const auto it = removedPoints_.find(idx);
2091 if (it != removedPoints_.end()) {
2092 removedPoints_.erase(it);
2093 treeIndex_[idx] = pos;
2096 for (
int i = 0; i < pos; i++) {
2097 for (
int j = 0; j < static_cast<int>(index_[i].vAcc_.size()); j++) {
2098 index_[pos].vAcc_.push_back(index_[i].vAcc_[j]);
2099 if (treeIndex_[index_[i].vAcc_[j]] != -1) treeIndex_[index_[i].vAcc_[j]] = pos;
2101 index_[i].vAcc_.clear();
2103 index_[pos].vAcc_.push_back(idx);
2107 for (
int i = 0; i <= maxIndex; ++i) {
2108 index_[i].freeIndex(index_[i]);
2109 if (!index_[i].vAcc_.empty()) index_[i].buildIndex();
2115 if (idx >= pointCount_)
return;
2116 removedPoints_.insert(idx);
2117 treeIndex_[idx] = -1;
2136 template <
typename RESULTSET>
2138 for (
size_t i = 0; i < treeCount_; i++) {
2139 index_[i].findNeighbors(result, &vec[0], searchParams);
2141 return result.full();
2170template <
class MatrixType, int32_t DIM = -1,
class Distance =
nanoflann::metric_L2,
bool row_major =
true>
2173 using num_t =
typename MatrixType::Scalar;
2175 using metric_t =
typename Distance::template traits<num_t, self_t, IndexType>::distance_t;
2189 const int leaf_max_size = 10)
2190 : m_data_matrix(mat) {
2191 const auto dims = row_major ? mat.get().cols() : mat.get().rows();
2192 if (
static_cast<Dimension>(dims) != dimensionality)
2193 throw std::runtime_error(
2194 "Error: 'dimensionality' must match column count in data "
2196 if (DIM > 0 &&
static_cast<int32_t
>(dims) != DIM)
2197 throw std::runtime_error(
2198 "Data set dimensionality does not match the 'DIM' template "
2221 resultSet.
init(out_indices, out_distances);
2234 return m_data_matrix.get().rows();
2236 return m_data_matrix.get().cols();
2242 return m_data_matrix.get().coeff(idx,
IndexType(dim));
2244 return m_data_matrix.get().coeff(
IndexType(dim), idx);
2252 template <
class BBOX>
// end of grouping
2313template <
class VectorOfVectorsType,
typename num_t = double,
int DIM = -1,
class Distance =
nanoflann::metric_L2,
2317 using metric_t =
typename Distance::template traits<num_t, self_t>::distance_t;
2327 const unsigned int n_thread_build = 1)
2329 assert(mat.size() != 0 && mat[0].size() != 0);
2330 const size_t dims = mat[0].size();
2331 if (DIM > 0 &&
static_cast<int>(dims) != DIM)
2332 throw std::runtime_error(
2333 "Data set dimensionality does not match the 'DIM' template "
2336 static_cast<int>(dims), *
this ,
2349 inline void query(
const num_t* query_point,
const size_t num_closest, IndexType* out_indices, num_t* out_distances_sq)
const {
2351 resultSet.
init(out_indices, out_distances_sq);
2365 inline num_t
kdtree_get_pt(
const size_t idx,
const size_t dim)
const {
return m_data[idx][dim]; }
2372 template <
class BBOX>
2383template <
typename T>
2414 template <
class BBOX>
2420template <
typename T>
2424 for (
size_t i = 0; i < N; i++) {
2425 pc.
pts[i].x = max_range_x * (rand() % 1000) / T(1000);
2426 pc.
pts[i].y = max_range_y * (rand() % 1000) / T(1000);
2427 pc.
pts[i].z = max_range_z * (rand() % 1000) / T(1000);
2431template <
typename T>
2437template <
typename T>
2468 template <
class BBOX>
2474template <
typename T>
2477 point.
pts.resize(N);
2478 T theta, X, Y, Z, sinAng, cosAng, mag;
2479 for (
size_t i = 0; i < N; i++) {
2480 theta =
static_cast<T
>(nanoflann::pi_const<double>() * (((double)rand()) / RAND_MAX));
2482 X =
static_cast<T
>(2 * (((double)rand()) / RAND_MAX) - 1);
2483 Y =
static_cast<T
>(2 * (((double)rand()) / RAND_MAX) - 1);
2484 Z =
static_cast<T
>(2 * (((double)rand()) / RAND_MAX) - 1);
2485 mag = sqrt(X * X + Y * Y + Z * Z);
2489 cosAng = cos(theta / 2);
2490 sinAng = sin(theta / 2);
2491 point.
pts[i].w = cosAng;
2492 point.
pts[i].x = X * sinAng;
2493 point.
pts[i].y = Y * sinAng;
2494 point.
pts[i].z = Z * sinAng;
2499template <
typename T>
2514 inline T
kdtree_get_pt(
const size_t idx,
const size_t dim = 0)
const {
return pts[idx].theta; }
2521 template <
class BBOX>
2527template <
typename T>
2530 point.
pts.resize(N);
2531 for (
size_t i = 0; i < N; i++) {
2532 point.
pts[i].theta =
2533 static_cast<T
>((2 * nanoflann::pi_const<double>() * (((double)rand()) / RAND_MAX)) - nanoflann::pi_const<double>());
2538 FILE* f = fopen(
"/proc/self/statm",
"rt");
2541 size_t n = fread(str, 1, 200, f);
2543 printf(
"MEM: %s\n", str);
Definition nanoflann.hpp:825
Size usedMemory(Derived &obj)
Definition nanoflann.hpp:922
DistanceType computeInitialDistances(const Derived &obj, const ElementType *vec, distance_vector_t &dists) const
Definition nanoflann.hpp:1168
NodePtr divideTreeConcurrent(Derived &obj, const Offset left, const Offset right, BoundingBox &bbox, std::atomic< unsigned int > &thread_count, std::mutex &mutex)
Definition nanoflann.hpp:1004
void planeSplit(const Derived &obj, const Offset ind, const Size count, const Dimension cutfeat, const DistanceType &cutval, Offset &lim1, Offset &lim2)
Definition nanoflann.hpp:1139
typename array_or_vector< DIM, DistanceType >::type distance_vector_t
Definition nanoflann.hpp:893
std::vector< IndexType > vAcc_
Definition nanoflann.hpp:841
void computeMinMax(const Derived &obj, Offset ind, Size count, Dimension element, ElementType &min_elem, ElementType &max_elem)
Definition nanoflann.hpp:927
static void load_tree(Derived &obj, std::istream &stream, NodePtr &tree)
Definition nanoflann.hpp:1195
Size size(const Derived &obj) const
Definition nanoflann.hpp:908
void freeIndex(Derived &obj)
Definition nanoflann.hpp:829
void loadIndex(Derived &obj, std::istream &stream)
Definition nanoflann.hpp:1225
typename array_or_vector< DIM, Interval >::type BoundingBox
Definition nanoflann.hpp:889
BoundingBox root_bbox_
Definition nanoflann.hpp:896
typename decltype(vAcc_)::size_type Size
Definition nanoflann.hpp:844
void saveIndex(const Derived &obj, std::ostream &stream) const
Definition nanoflann.hpp:1211
void middleSplit_(const Derived &obj, const Offset ind, const Size count, Offset &index, Dimension &cutfeat, DistanceType &cutval, const BoundingBox &bbox)
Definition nanoflann.hpp:1081
typename Distance::ElementType ElementType
Definition nanoflann.hpp:835
PooledAllocator pool_
Definition nanoflann.hpp:905
NodePtr divideTree(Derived &obj, const Offset left, const Offset right, BoundingBox &bbox)
Definition nanoflann.hpp:944
typename Distance::DistanceType DistanceType
Definition nanoflann.hpp:836
ElementType dataset_get(const Derived &obj, IndexType element, Dimension component) const
Helper accessor to the dataset points:
Definition nanoflann.hpp:914
Size veclen(const Derived &obj)
Definition nanoflann.hpp:911
static void save_tree(const Derived &obj, std::ostream &stream, const NodeConstPtr tree)
Definition nanoflann.hpp:1185
int32_t Dimension
Definition nanoflann.hpp:845
typename decltype(vAcc_)::size_type Offset
Definition nanoflann.hpp:843
Definition nanoflann.hpp:1278
const KDTreeSingleIndexAdaptorParams indexParams
Definition nanoflann.hpp:1286
Size radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1481
Size rknnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances, const DistanceType &radius) const
Definition nanoflann.hpp:1503
KDTreeSingleIndexAdaptor(const KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, IndexType > &)=delete
KDTreeSingleIndexAdaptor(const Dimension dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms, Args &&... args)
Definition nanoflann.hpp:1334
Distance distance_
Definition nanoflann.hpp:1288
typename Base::Size Size
Definition nanoflann.hpp:1294
typename Base::ElementType ElementType
Definition nanoflann.hpp:1297
Size radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< ResultItem< IndexType, DistanceType > > &IndicesDists, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1467
typename Base::distance_vector_t distance_vector_t
Definition nanoflann.hpp:1311
typename nanoflann::KDTreeBaseClass< nanoflann::KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, IndexType >, Distance, DatasetAdaptor, DIM, IndexType > Base
Definition nanoflann.hpp:1291
void loadIndex(std::istream &stream)
Definition nanoflann.hpp:1626
typename Base::Node Node
Definition nanoflann.hpp:1300
typename Base::BoundingBox BoundingBox
Definition nanoflann.hpp:1307
typename Base::DistanceType DistanceType
Definition nanoflann.hpp:1298
KDTreeSingleIndexAdaptor(const Dimension dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms={})
Definition nanoflann.hpp:1340
typename Base::Interval Interval
Definition nanoflann.hpp:1303
Size knnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances) const
Definition nanoflann.hpp:1441
typename Base::Dimension Dimension
Definition nanoflann.hpp:1295
void init_vind()
Definition nanoflann.hpp:1516
const DatasetAdaptor & dataset_
Definition nanoflann.hpp:1284
void saveIndex(std::ostream &stream) const
Definition nanoflann.hpp:1619
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1407
Node * NodePtr
Definition nanoflann.hpp:1301
typename Base::Offset Offset
Definition nanoflann.hpp:1293
void buildIndex()
Definition nanoflann.hpp:1369
bool searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindist, distance_vector_t &dists, const float epsError) const
Definition nanoflann.hpp:1554
void computeBoundingBox(BoundingBox &bbox)
Definition nanoflann.hpp:1523
Definition nanoflann.hpp:1669
Size radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< ResultItem< IndexType, DistanceType > > &IndicesDists, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1852
KDTreeSingleIndexDynamicAdaptor_(const Dimension dimensionality, const DatasetAdaptor &inputData, std::vector< int > &treeIndex, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams())
Definition nanoflann.hpp:1719
std::vector< int > & treeIndex_
Definition nanoflann.hpp:1678
typename Base::Dimension Dimension
Definition nanoflann.hpp:1690
typename Base::BoundingBox BoundingBox
Definition nanoflann.hpp:1698
const DatasetAdaptor & dataset_
The source of our data.
Definition nanoflann.hpp:1674
Size radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1866
typename Base::DistanceType DistanceType
Definition nanoflann.hpp:1686
KDTreeSingleIndexAdaptorParams index_params_
Definition nanoflann.hpp:1676
KDTreeSingleIndexDynamicAdaptor_(const KDTreeSingleIndexDynamicAdaptor_ &rhs)=default
typename Base::Offset Offset
Definition nanoflann.hpp:1688
void buildIndex()
Definition nanoflann.hpp:1756
typename Base::ElementType ElementType
Definition nanoflann.hpp:1685
void saveIndex(std::ostream &stream)
Definition nanoflann.hpp:1963
void computeBoundingBox(BoundingBox &bbox)
Definition nanoflann.hpp:1875
typename Base::Node Node
Definition nanoflann.hpp:1692
typename Base::Size Size
Definition nanoflann.hpp:1689
Node * NodePtr
Definition nanoflann.hpp:1693
typename Base::distance_vector_t distance_vector_t
Definition nanoflann.hpp:1702
void loadIndex(std::istream &stream)
Definition nanoflann.hpp:1970
typename Base::Interval Interval
Definition nanoflann.hpp:1695
Size knnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1825
typename nanoflann::KDTreeBaseClass< nanoflann::KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM, IndexType >, Distance, DatasetAdaptor, DIM, IndexType > Base
Definition nanoflann.hpp:1683
void searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindist, distance_vector_t &dists, const float epsError) const
Definition nanoflann.hpp:1905
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1796
Distance distance_
Definition nanoflann.hpp:1680
KDTreeSingleIndexDynamicAdaptor_ operator=(const KDTreeSingleIndexDynamicAdaptor_ &rhs)
Definition nanoflann.hpp:1739
Definition nanoflann.hpp:1988
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Dimension Dimension
Definition nanoflann.hpp:1995
typename Distance::ElementType ElementType
Definition nanoflann.hpp:1990
Size treeCount_
Definition nanoflann.hpp:1999
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:2137
typename Distance::DistanceType DistanceType
Definition nanoflann.hpp:1991
Size leaf_max_size_
Definition nanoflann.hpp:1998
Distance distance_
Definition nanoflann.hpp:2043
const DatasetAdaptor & dataset_
The source of our data.
Definition nanoflann.hpp:2005
void removePoint(size_t idx)
Definition nanoflann.hpp:2114
std::unordered_set< int > removedPoints_
Definition nanoflann.hpp:2010
Size pointCount_
Definition nanoflann.hpp:2000
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Offset Offset
Definition nanoflann.hpp:1993
void addPoints(IndexType start, IndexType end)
Definition nanoflann.hpp:2081
std::vector< index_container_t > index_
Definition nanoflann.hpp:2017
KDTreeSingleIndexDynamicAdaptor(const int dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams(), const size_t maximumPointCount=1000000000U)
Definition nanoflann.hpp:2060
std::vector< int > treeIndex_
Definition nanoflann.hpp:2009
const std::vector< index_container_t > & getAllIndices() const
Definition nanoflann.hpp:2022
KDTreeSingleIndexAdaptorParams index_params_
Definition nanoflann.hpp:2012
Dimension dim_
Dimensionality of each data point.
Definition nanoflann.hpp:2014
KDTreeSingleIndexDynamicAdaptor(const KDTreeSingleIndexDynamicAdaptor< Distance, DatasetAdaptor, DIM, IndexType > &)=delete
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Size Size
Definition nanoflann.hpp:1994
Definition nanoflann.hpp:146
_CountType CountType
Definition nanoflann.hpp:150
void init(IndexType *indices_, DistanceType *dists_)
Definition nanoflann.hpp:161
_DistanceType DistanceType
Definition nanoflann.hpp:148
bool addPoint(DistanceType dist, IndexType index)
Definition nanoflann.hpp:177
CountType size() const
Definition nanoflann.hpp:168
bool empty() const
Definition nanoflann.hpp:169
KNNResultSet(CountType capacity_)
Definition nanoflann.hpp:159
_IndexType IndexType
Definition nanoflann.hpp:149
DistanceType worstDist() const
Definition nanoflann.hpp:204
bool full() const
Definition nanoflann.hpp:170
Definition nanoflann.hpp:680
~PooledAllocator()
Definition nanoflann.hpp:717
void free_all()
Definition nanoflann.hpp:720
void * malloc(const size_t req_size)
Definition nanoflann.hpp:734
T * allocate(const size_t count=1)
Definition nanoflann.hpp:785
PooledAllocator()
Definition nanoflann.hpp:712
Definition nanoflann.hpp:209
CountType size() const
Definition nanoflann.hpp:233
bool addPoint(DistanceType dist, IndexType index)
Definition nanoflann.hpp:242
void init(IndexType *indices_, DistanceType *dists_)
Definition nanoflann.hpp:226
RKNNResultSet(CountType capacity_, DistanceType maximumSearchDistanceSquared_)
Definition nanoflann.hpp:223
bool empty() const
Definition nanoflann.hpp:234
_CountType CountType
Definition nanoflann.hpp:213
_IndexType IndexType
Definition nanoflann.hpp:212
_DistanceType DistanceType
Definition nanoflann.hpp:211
bool full() const
Definition nanoflann.hpp:235
DistanceType worstDist() const
Definition nanoflann.hpp:269
Definition nanoflann.hpp:302
void init()
Definition nanoflann.hpp:317
const DistanceType radius
Definition nanoflann.hpp:308
RadiusResultSet(DistanceType radius_, std::vector< ResultItem< IndexType, DistanceType > > &indices_dists)
Definition nanoflann.hpp:312
size_t empty() const
Definition nanoflann.hpp:321
DistanceType worstDist() const
Definition nanoflann.hpp:335
ResultItem< IndexType, DistanceType > worst_item() const
Definition nanoflann.hpp:341
_DistanceType DistanceType
Definition nanoflann.hpp:304
bool full() const
Definition nanoflann.hpp:323
size_t size() const
Definition nanoflann.hpp:320
std::vector< ResultItem< IndexType, DistanceType > > & m_indices_dists
Definition nanoflann.hpp:310
void clear()
Definition nanoflann.hpp:318
_IndexType IndexType
Definition nanoflann.hpp:305
bool addPoint(DistanceType dist, IndexType index)
Definition nanoflann.hpp:330
void load_value(std::istream &stream, T &value)
Definition nanoflann.hpp:368
void save_value(std::ostream &stream, const T &value)
Definition nanoflann.hpp:356
std::enable_if< has_assign< Container >::value, void >::type assign(Container &c, const size_t nElements, const T &value)
Definition nanoflann.hpp:129
T pi_const()
Definition nanoflann.hpp:88
std::enable_if< has_resize< Container >::value, void >::type resize(Container &c, const size_t nElements)
Definition nanoflann.hpp:112
std::underlying_type< KDTreeSingleIndexAdaptorFlags >::type operator&(KDTreeSingleIndexAdaptorFlags lhs, KDTreeSingleIndexAdaptorFlags rhs)
Definition nanoflann.hpp:635
KDTreeSingleIndexAdaptorFlags
Definition nanoflann.hpp:633
Definition nanoflann.hpp:82
void generateRandomPointCloud(PointCloud< T > &pc, const size_t N, const T max_range=10)
Definition nanoflann.hpp:2432
void dump_mem_usage()
Definition nanoflann.hpp:2537
void generateRandomPointCloud_Quat(PointCloud_Quat< T > &point, const size_t N)
Definition nanoflann.hpp:2475
void generateRandomPointCloudRanges(PointCloud< T > &pc, const size_t N, const T max_range_x, const T max_range_y, const T max_range_z)
Definition nanoflann.hpp:2421
void generateRandomPointCloud_Orient(PointCloud_Orient< T > &point, const size_t N)
Definition nanoflann.hpp:2528
Definition nanoflann.hpp:2315
KDTreeVectorOfVectorsAdaptor(const size_t, const VectorOfVectorsType &mat, const int leaf_max_size=10, const unsigned int n_thread_build=1)
Definition nanoflann.hpp:2326
void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq) const
Definition nanoflann.hpp:2349
num_t kdtree_get_pt(const size_t idx, const size_t dim) const
Definition nanoflann.hpp:2365
size_t kdtree_get_point_count() const
Definition nanoflann.hpp:2362
const self_t & derived() const
Definition nanoflann.hpp:2358
const VectorOfVectorsType & m_data
Definition nanoflann.hpp:2342
typename Distance::template traits< num_t, self_t >::distance_t metric_t
Definition nanoflann.hpp:2317
self_t & derived()
Definition nanoflann.hpp:2359
bool kdtree_get_bbox(BBOX &) const
Definition nanoflann.hpp:2373
~KDTreeVectorOfVectorsAdaptor()
Definition nanoflann.hpp:2340
Definition nanoflann.hpp:2385
T x
Definition nanoflann.hpp:2386
Definition nanoflann.hpp:2501
T theta
Definition nanoflann.hpp:2502
Definition nanoflann.hpp:2500
size_t kdtree_get_point_count() const
Definition nanoflann.hpp:2508
bool kdtree_get_bbox(BBOX &) const
Definition nanoflann.hpp:2522
std::vector< Point > pts
Definition nanoflann.hpp:2505
T kdtree_get_pt(const size_t idx, const size_t dim=0) const
Definition nanoflann.hpp:2514
Definition nanoflann.hpp:2439
T w
Definition nanoflann.hpp:2440
Definition nanoflann.hpp:2438
bool kdtree_get_bbox(BBOX &) const
Definition nanoflann.hpp:2469
size_t kdtree_get_point_count() const
Definition nanoflann.hpp:2446
T kdtree_get_pt(const size_t idx, const size_t dim) const
Definition nanoflann.hpp:2452
std::vector< Point > pts
Definition nanoflann.hpp:2443
Definition nanoflann.hpp:2384
bool kdtree_get_bbox(BBOX &) const
Definition nanoflann.hpp:2415
std::vector< Point > pts
Definition nanoflann.hpp:2391
size_t kdtree_get_point_count() const
Definition nanoflann.hpp:2394
T coord_t
The type of each coordinate.
Definition nanoflann.hpp:2389
T kdtree_get_pt(const size_t idx, const size_t dim) const
Definition nanoflann.hpp:2400
Definition nanoflann.hpp:273
bool operator()(const PairType &p1, const PairType &p2) const
Definition nanoflann.hpp:276
Definition nanoflann.hpp:871
ElementType high
Definition nanoflann.hpp:872
Definition nanoflann.hpp:850
DistanceType divhigh
Definition nanoflann.hpp:860
Offset left
Definition nanoflann.hpp:855
Node * child1
Definition nanoflann.hpp:865
Dimension divfeat
Definition nanoflann.hpp:858
struct nanoflann::KDTreeBaseClass::Node::@1::leaf lr
struct nanoflann::KDTreeBaseClass::Node::@1::nonleaf sub
Node * child2
Definition nanoflann.hpp:865
union nanoflann::KDTreeBaseClass::Node::@1 node_type
Definition nanoflann.hpp:2171
void query(const num_t *query_point, const Size num_closest, IndexType *out_indices, num_t *out_distances) const
Definition nanoflann.hpp:2219
typename MatrixType::Scalar num_t
Definition nanoflann.hpp:2173
num_t kdtree_get_pt(const IndexType idx, size_t dim) const
Definition nanoflann.hpp:2240
Size kdtree_get_point_count() const
Definition nanoflann.hpp:2232
KDTreeEigenMatrixAdaptor(const Dimension dimensionality, const std::reference_wrapper< const MatrixType > &mat, const int leaf_max_size=10)
Constructor: takes a const ref to the matrix object with the data points.
Definition nanoflann.hpp:2188
typename index_t::Size Size
Definition nanoflann.hpp:2184
bool kdtree_get_bbox(BBOX &) const
Definition nanoflann.hpp:2253
const std::reference_wrapper< const MatrixType > m_data_matrix
Definition nanoflann.hpp:2209
KDTreeEigenMatrixAdaptor(const self_t &)=delete
const self_t & derived() const
Definition nanoflann.hpp:2228
index_t * index_
Definition nanoflann.hpp:2180
typename Distance::template traits< num_t, self_t, IndexType >::distance_t metric_t
Definition nanoflann.hpp:2175
self_t & derived()
Definition nanoflann.hpp:2229
typename MatrixType::Index IndexType
Definition nanoflann.hpp:2174
typename index_t::Dimension Dimension
Definition nanoflann.hpp:2185
typename index_t::Offset Offset
Definition nanoflann.hpp:2183
~KDTreeEigenMatrixAdaptor()
Definition nanoflann.hpp:2207
Definition nanoflann.hpp:642
KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size=10, KDTreeSingleIndexAdaptorFlags _flags=KDTreeSingleIndexAdaptorFlags::None, unsigned int _n_thread_build=1)
Definition nanoflann.hpp:643
size_t leaf_max_size
Definition nanoflann.hpp:648
unsigned int n_thread_build
Definition nanoflann.hpp:650
KDTreeSingleIndexAdaptorFlags flags
Definition nanoflann.hpp:649
Definition nanoflann.hpp:397
T ElementType
Definition nanoflann.hpp:398
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size, DistanceType worst_dist=-1) const
Definition nanoflann.hpp:405
const DataSource & data_source
Definition nanoflann.hpp:401
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:432
_DistanceType DistanceType
Definition nanoflann.hpp:399
L1_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:403
Definition nanoflann.hpp:448
_DistanceType DistanceType
Definition nanoflann.hpp:450
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:484
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size, DistanceType worst_dist=-1) const
Definition nanoflann.hpp:456
T ElementType
Definition nanoflann.hpp:449
L2_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:454
const DataSource & data_source
Definition nanoflann.hpp:452
Definition nanoflann.hpp:500
const DataSource & data_source
Definition nanoflann.hpp:504
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
Definition nanoflann.hpp:508
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:518
L2_Simple_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:506
_DistanceType DistanceType
Definition nanoflann.hpp:502
T ElementType
Definition nanoflann.hpp:501
Definition nanoflann.hpp:384
Definition nanoflann.hpp:290
DistanceType second
Distance from sample to query point.
Definition nanoflann.hpp:295
ResultItem(const IndexType index, const DistanceType distance)
Definition nanoflann.hpp:292
IndexType first
Index of the sample in the dataset.
Definition nanoflann.hpp:294
Definition nanoflann.hpp:534
const DataSource & data_source
Definition nanoflann.hpp:538
_DistanceType DistanceType
Definition nanoflann.hpp:536
T ElementType
Definition nanoflann.hpp:535
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
Definition nanoflann.hpp:542
SO2_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:540
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:549
Definition nanoflann.hpp:572
_DistanceType DistanceType
Definition nanoflann.hpp:574
L2_Simple_Adaptor< T, DataSource, DistanceType, IndexType > distance_L2_Simple
Definition nanoflann.hpp:576
T ElementType
Definition nanoflann.hpp:573
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
Definition nanoflann.hpp:580
SO3_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:578
DistanceType accum_dist(const U a, const V b, const size_t idx) const
Definition nanoflann.hpp:585
Definition nanoflann.hpp:654
SearchParameters(float eps_=0, bool sorted_=true)
Definition nanoflann.hpp:655
bool sorted
Definition nanoflann.hpp:658
float eps
search for eps-approximate neighbours (default: 0)
Definition nanoflann.hpp:657
std::vector< T > type
Definition nanoflann.hpp:805
Definition nanoflann.hpp:799
std::array< T, DIM > type
Definition nanoflann.hpp:800
Definition nanoflann.hpp:103
Definition nanoflann.hpp:97
Definition nanoflann.hpp:593
Definition nanoflann.hpp:591
Definition nanoflann.hpp:601
Definition nanoflann.hpp:609
Definition nanoflann.hpp:607
Definition nanoflann.hpp:599
Definition nanoflann.hpp:616
Definition nanoflann.hpp:614
Definition nanoflann.hpp:623
Definition nanoflann.hpp:621