57#include <unordered_set>
61#define NANOFLANN_VERSION 0x150
64#if !defined(NOMINMAX) && (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
82template <
typename T> T
pi_const() {
return static_cast<T
>(3.14159265358979323846); }
88template <
typename T,
typename =
int>
struct has_resize : std::false_type
92template <
typename T>
struct has_resize<T, decltype((void)std::declval<T>().
resize(1), 0)> : std::true_type
96template <
typename T,
typename =
int>
struct has_assign : std::false_type
100template <
typename T>
struct has_assign<T, decltype((void)std::declval<T>().
assign(1, 0), 0)> : std::true_type
107template <
typename Container>
108inline typename std::enable_if<has_resize<Container>::value,
void>::type
resize(Container& c,
const size_t nElements)
117template <
typename Container>
118inline typename std::enable_if<!has_resize<Container>::value,
void>::type
resize(Container& c,
const size_t nElements)
120 if (nElements != c.size())
121 throw std::logic_error(
"Try to change the size of a std::array.");
127template <
typename Container,
typename T>
128inline typename std::enable_if<has_assign<Container>::value,
void>::type
assign(Container& c,
const size_t nElements,
131 c.assign(nElements, value);
137template <
typename Container,
typename T>
138inline typename std::enable_if<!has_assign<Container>::value,
void>::type
assign(Container& c,
const size_t nElements,
141 for (
size_t i = 0; i < nElements; i++)
147template <
typename _DistanceType,
typename _IndexType =
size_t,
typename _CountType =
size_t>
class KNNResultSet
169 dists[
capacity - 1] = (std::numeric_limits<DistanceType>::max)();
184 for (i =
count; i > 0; --i)
188#ifdef NANOFLANN_FIRST_MATCH
189 if ((
dists[i - 1] > dist) || ((dist ==
dists[i - 1]) && (
indices[i - 1] > index)))
192 if (
dists[i - 1] > dist)
223 template <
typename PairType>
bool operator()(
const PairType& p1,
const PairType& p2)
const
225 return p1.second < p2.second;
237template <
typename IndexType =
size_t,
typename DistanceType =
double>
struct ResultItem
240 ResultItem(
const IndexType index,
const DistanceType distance) : first(index), second(distance) {}
261 : radius(radius_), m_indices_dists(indices_dists)
267 void clear() { m_indices_dists.clear(); }
269 size_t size()
const {
return m_indices_dists.size(); }
270 size_t empty()
const {
return m_indices_dists.empty(); }
272 bool full()
const {
return true; }
282 m_indices_dists.emplace_back(index, dist);
294 if (m_indices_dists.empty())
295 throw std::runtime_error(
"Cannot invoke RadiusResultSet::worst_item() on "
296 "an empty list of results.");
297 auto it = std::max_element(m_indices_dists.begin(), m_indices_dists.end(),
IndexDist_Sorter());
306template <
typename T>
void save_value(std::ostream& stream,
const T& value)
308 stream.write(
reinterpret_cast<const char*
>(&value),
sizeof(T));
311template <
typename T>
void save_value(std::ostream& stream,
const std::vector<T>& value)
313 size_t size = value.size();
314 stream.write(
reinterpret_cast<const char*
>(&
size),
sizeof(
size_t));
315 stream.write(
reinterpret_cast<const char*
>(value.data()),
sizeof(T) *
size);
318template <
typename T>
void load_value(std::istream& stream, T& value)
320 stream.read(
reinterpret_cast<char*
>(&value),
sizeof(T));
323template <
typename T>
void load_value(std::istream& stream, std::vector<T>& value)
326 stream.read(
reinterpret_cast<char*
>(&
size),
sizeof(
size_t));
328 stream.read(
reinterpret_cast<char*
>(value.data()),
sizeof(T) *
size);
349template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
struct L1_Adaptor
356 L1_Adaptor(
const DataSource& _data_source) : data_source(_data_source) {}
361 const T* last = a + size;
362 const T* lastgroup = last - 3;
366 while (a < lastgroup)
368 const DistanceType diff0 = std::abs(a[0] - data_source.kdtree_get_pt(b_idx, d++));
369 const DistanceType diff1 = std::abs(a[1] - data_source.kdtree_get_pt(b_idx, d++));
370 const DistanceType diff2 = std::abs(a[2] - data_source.kdtree_get_pt(b_idx, d++));
371 const DistanceType diff3 = std::abs(a[3] - data_source.kdtree_get_pt(b_idx, d++));
372 result += diff0 + diff1 + diff2 + diff3;
374 if ((worst_dist > 0) && (result > worst_dist))
383 result += std::abs(*a++ - data_source.kdtree_get_pt(b_idx, d++));
390 return std::abs(a - b);
404template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
struct L2_Adaptor
411 L2_Adaptor(
const DataSource& _data_source) : data_source(_data_source) {}
416 const T* last = a + size;
417 const T* lastgroup = last - 3;
421 while (a < lastgroup)
423 const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx, d++);
424 const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx, d++);
425 const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx, d++);
426 const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx, d++);
427 result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
429 if ((worst_dist > 0) && (result > worst_dist))
438 const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx, d++);
439 result += diff0 * diff0;
446 return (a - b) * (a - b);
460template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
struct L2_Simple_Adaptor
472 for (
size_t i = 0; i < size; ++i)
474 const DistanceType diff = a[i] - data_source.kdtree_get_pt(b_idx, i);
475 result += diff * diff;
482 return (a - b) * (a - b);
496template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
struct SO2_Adaptor
503 SO2_Adaptor(
const DataSource& _data_source) : data_source(_data_source) {}
507 return accum_dist(a[size - 1], data_source.kdtree_get_pt(b_idx, size - 1), size - 1);
519 else if (result < -PI)
535template <
class T,
class DataSource,
typename _DistanceType = T,
typename IndexType = u
int32_t>
struct SO3_Adaptor
542 SO3_Adaptor(
const DataSource& _data_source) : distance_L2_Simple(_data_source) {}
546 return distance_L2_Simple.
evalMetric(a, b_idx, size);
551 return distance_L2_Simple.
accum_dist(a, b, idx);
558 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
struct traits
567 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
struct traits
576 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
struct traits
584 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
struct traits
592 template <
class T,
class DataSource,
typename IndexType = u
int32_t>
struct traits
612 using underlying =
typename std::underlying_type<KDTreeSingleIndexAdaptorFlags>::type;
613 return static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs);
621 : leaf_max_size(_leaf_max_size), flags(_flags)
659 static constexpr size_t WORDSIZE = 16;
660 static constexpr size_t BLOCKSIZE = 8192;
673 void* base_ =
nullptr;
674 void* loc_ =
nullptr;
701 while (base_ !=
nullptr)
704 void* prev = *(
static_cast<void**
>(base_));
721 const Size size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
726 if (size > remaining_)
728 wastedMemory += remaining_;
731 const Size blocksize = (size +
sizeof(
void*) + (WORDSIZE - 1) > BLOCKSIZE)
732 ? size +
sizeof(
void*) + (WORDSIZE - 1)
736 void* m = ::malloc(blocksize);
739 fprintf(stderr,
"Failed to allocate memory.\n");
740 throw std::bad_alloc();
744 static_cast<void**
>(m)[0] = base_;
751 remaining_ = blocksize -
sizeof(
void*) - shift;
752 loc_ = (
static_cast<char*
>(m) +
sizeof(
void*) + shift);
755 loc_ =
static_cast<char*
>(loc_) + size;
770 template <
typename T> T*
allocate(
const size_t count = 1)
772 T* mem =
static_cast<T*
>(this->malloc(
sizeof(T) * count));
786 using type = std::array<T, DIM>;
810template <
class Derived,
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
818 obj.pool_.free_all();
819 obj.root_node_ =
nullptr;
820 obj.size_at_index_build_ = 0;
831 using Offset =
typename decltype(vAcc_)::size_type;
832 using Size =
typename decltype(vAcc_)::size_type;
856 Node *child1 =
nullptr, *child2 =
nullptr;
898 Size size(
const Derived& obj)
const {
return obj.size_; }
901 Size veclen(
const Derived& obj) {
return DIM > 0 ? DIM : obj.dim; }
906 return obj.dataset_.kdtree_get_pt(element, component);
915 return obj.pool_.usedMemory + obj.pool_.wastedMemory +
916 obj.dataset_.kdtree_get_point_count() *
sizeof(IndexType);
922 min_elem = dataset_get(obj, vAcc_[ind], element);
924 for (
Offset i = 1; i < count; ++i)
926 ElementType val = dataset_get(obj, vAcc_[ind + i], element);
943 NodePtr node = obj.pool_.template allocate<Node>();
944 const auto dims = (DIM > 0 ? DIM : obj.dim_);
947 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)
963 const auto val = dataset_get(obj, obj.vAcc_[k], i);
964 if (bbox[i].low > val)
966 if (bbox[i].high < val)
976 middleSplit_(obj, left, right - left, idx, cutfeat, cutval, bbox);
981 left_bbox[cutfeat].high = cutval;
982 node->
child1 = this->divideTree(obj, left, left + idx, left_bbox);
985 right_bbox[cutfeat].low = cutval;
986 node->
child2 = this->divideTree(obj, left + idx, right, right_bbox);
993 bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
994 bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1004 const auto dims = (DIM > 0 ? DIM : obj.dim_);
1006 ElementType max_span = bbox[0].high - bbox[0].low;
1010 if (span > max_span)
1020 if (span > (1 - EPS) * max_span)
1023 computeMinMax(obj, ind, count, i, min_elem, max_elem);
1025 if (spread > max_spread)
1028 max_spread = spread;
1033 DistanceType split_val = (bbox[cutfeat].low + bbox[cutfeat].high) / 2;
1035 computeMinMax(obj, ind, count, cutfeat, min_elem, max_elem);
1037 if (split_val < min_elem)
1039 else if (split_val > max_elem)
1045 planeSplit(obj, ind, count, cutfeat, cutval, lim1, lim2);
1047 if (lim1 > count / 2)
1049 else if (lim2 < count / 2)
1069 Offset right = count - 1;
1072 while (left <= right && dataset_get(obj, vAcc_[ind + left], cutfeat) < cutval)
1074 while (right && left <= right && dataset_get(obj, vAcc_[ind + right], cutfeat) >= cutval)
1076 if (left > right || !right)
1078 std::swap(vAcc_[ind + left], vAcc_[ind + right]);
1089 while (left <= right && dataset_get(obj, vAcc_[ind + left], cutfeat) <= cutval)
1091 while (right && left <= right && dataset_get(obj, vAcc_[ind + right], cutfeat) > cutval)
1093 if (left > right || !right)
1095 std::swap(vAcc_[ind + left], vAcc_[ind + right]);
1107 for (
Dimension i = 0; i < (DIM > 0 ? DIM : obj.dim_); ++i)
1109 if (vec[i] < obj.root_bbox_[i].low)
1111 dists[i] = obj.distance_.accum_dist(vec[i], obj.root_bbox_[i].low, i);
1114 if (vec[i] > obj.root_bbox_[i].high)
1116 dists[i] = obj.distance_.accum_dist(vec[i], obj.root_bbox_[i].high, i);
1126 if (tree->
child1 !=
nullptr)
1128 save_tree(obj, stream, tree->
child1);
1130 if (tree->
child2 !=
nullptr)
1132 save_tree(obj, stream, tree->
child2);
1138 tree = obj.pool_.template allocate<Node>();
1140 if (tree->
child1 !=
nullptr)
1142 load_tree(obj, stream, tree->
child1);
1144 if (tree->
child2 !=
nullptr)
1146 load_tree(obj, stream, tree->
child2);
1155 void saveIndex(
const Derived& obj, std::ostream& stream)
const
1162 save_tree(obj, stream, obj.root_node_);
1177 load_tree(obj, stream, obj.root_node_);
1222template <
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
1224 :
public KDTreeBaseClass<KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, IndexType>, Distance,
1225 DatasetAdaptor, DIM, IndexType>
1283 template <
class... Args>
1286 : dataset_(inputData), indexParams(params), distance_(inputData, std::forward<Args>(args)...)
1288 init(dimensionality, params);
1293 : dataset_(inputData), indexParams(params), distance_(inputData)
1295 init(dimensionality, params);
1301 Base::size_ = dataset_.kdtree_get_point_count();
1302 Base::size_at_index_build_ = Base::size_;
1303 Base::dim_ = dimensionality;
1308 if (!(params.
flags & KDTreeSingleIndexAdaptorFlags::SkipInitialBuildIndex))
1321 Base::size_ = dataset_.kdtree_get_point_count();
1322 Base::size_at_index_build_ = Base::size_;
1324 this->freeIndex(*
this);
1325 Base::size_at_index_build_ = Base::size_;
1326 if (Base::size_ == 0)
1328 computeBoundingBox(Base::root_bbox_);
1330 Base::root_node_ = this->divideTree(*
this, 0, Base::size_, Base::root_bbox_);
1352 template <
typename RESULTSET>
1356 if (this->size(*
this) == 0)
1358 if (!Base::root_node_)
1359 throw std::runtime_error(
"[nanoflann] findNeighbors() called before building the "
1361 float epsError = 1 + searchParams.eps;
1364 distance_vector_t dists;
1366 auto zero =
static_cast<decltype(result.worstDist())
>(0);
1367 assign(dists, (DIM > 0 ? DIM : Base::dim_), zero);
1368 DistanceType dist = this->computeInitialDistances(*
this, vec, dists);
1369 searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
1370 return result.full();
1392 resultSet.
init(out_indices, out_distances);
1393 findNeighbors(resultSet, query_point);
1394 return resultSet.
size();
1421 const Size nFound = radiusSearchCustomCallback(query_point, resultSet, searchParams);
1422 if (searchParams.sorted)
1432 template <
class SEARCH_CALLBACK>
1436 findNeighbors(resultSet, query_point, searchParams);
1437 return resultSet.size();
1448 Base::size_ = dataset_.kdtree_get_point_count();
1449 if (Base::vAcc_.size() != Base::size_)
1450 Base::vAcc_.resize(Base::size_);
1451 for (
Size i = 0; i < Base::size_; i++)
1457 const auto dims = (DIM > 0 ? DIM : Base::dim_);
1459 if (dataset_.kdtree_get_bbox(bbox))
1465 const Size N = dataset_.kdtree_get_point_count();
1467 throw std::runtime_error(
"[nanoflann] computeBoundingBox() called but "
1468 "no data points found.");
1471 bbox[i].low = bbox[i].high = this->dataset_get(*
this, Base::vAcc_[0], i);
1473 for (
Offset k = 1; k < N; ++k)
1477 const auto val = this->dataset_get(*
this, Base::vAcc_[k], i);
1478 if (val < bbox[i].low)
1480 if (val > bbox[i].high)
1493 template <
class RESULTSET>
1498 if ((node->child1 ==
nullptr) && (node->child2 ==
nullptr))
1501 for (
Offset i = node->node_type.lr.left; i < node->node_type.lr.right; ++i)
1503 const IndexType accessor = Base::vAcc_[i];
1504 DistanceType dist = distance_.evalMetric(vec, accessor, (DIM > 0 ? DIM : Base::dim_));
1505 if (dist < worst_dist)
1507 if (!result_set.addPoint(dist, Base::vAcc_[i]))
1519 Dimension idx = node->node_type.sub.divfeat;
1522 DistanceType diff2 = val - node->node_type.sub.divhigh;
1527 if ((diff1 + diff2) < 0)
1529 bestChild = node->child1;
1530 otherChild = node->child2;
1531 cut_dist = distance_.accum_dist(val, node->node_type.sub.divhigh, idx);
1535 bestChild = node->child2;
1536 otherChild = node->child1;
1537 cut_dist = distance_.accum_dist(val, node->node_type.sub.divlow, idx);
1541 if (!searchLevel(result_set, vec, bestChild, mindist, dists, epsError))
1549 mindist = mindist + cut_dist - dst;
1550 dists[idx] = cut_dist;
1551 if (mindist * epsError <= result_set.worstDist())
1553 if (!searchLevel(result_set, vec, otherChild, mindist, dists, epsError))
1570 void saveIndex(std::ostream& stream)
const { Base::saveIndex(*
this, stream); }
1577 void loadIndex(std::istream& stream) { Base::loadIndex(*
this, stream); }
1618template <
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
1620 :
public KDTreeBaseClass<KDTreeSingleIndexDynamicAdaptor_<Distance, DatasetAdaptor, DIM, IndexType>, Distance,
1621 DatasetAdaptor, DIM, IndexType>
1637 DatasetAdaptor, DIM, IndexType>;
1674 std::vector<int>& treeIndex,
1676 : dataset_(inputData), index_params_(params), treeIndex_(treeIndex), distance_(inputData)
1679 Base::size_at_index_build_ = 0;
1680 for (
auto& v : Base::root_bbox_)
1682 Base::dim_ = dimensionality;
1685 Base::leaf_max_size_ = params.leaf_max_size;
1695 std::swap(Base::vAcc_, tmp.Base::vAcc_);
1696 std::swap(Base::leaf_max_size_, tmp.Base::leaf_max_size_);
1699 std::swap(Base::size_, tmp.Base::size_);
1700 std::swap(Base::size_at_index_build_, tmp.Base::size_at_index_build_);
1701 std::swap(Base::root_node_, tmp.Base::root_node_);
1702 std::swap(Base::root_bbox_, tmp.Base::root_bbox_);
1703 std::swap(Base::pool_, tmp.Base::pool_);
1712 Base::size_ = Base::vAcc_.size();
1713 this->freeIndex(*
this);
1714 Base::size_at_index_build_ = Base::size_;
1715 if (Base::size_ == 0)
1717 computeBoundingBox(Base::root_bbox_);
1719 Base::root_node_ = this->divideTree(*
this, 0, Base::size_, Base::root_bbox_);
1745 template <
typename RESULTSET>
1749 if (this->size(*
this) == 0)
1751 if (!Base::root_node_)
1753 float epsError = 1 + searchParams.eps;
1756 distance_vector_t dists;
1758 assign(dists, (DIM > 0 ? DIM : Base::dim_),
static_cast<typename distance_vector_t::value_type
>(0));
1759 DistanceType dist = this->computeInitialDistances(*
this, vec, dists);
1760 searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
1761 return result.full();
1782 resultSet.
init(out_indices, out_distances);
1783 findNeighbors(resultSet, query_point);
1784 return resultSet.
size();
1811 const size_t nFound = radiusSearchCustomCallback(query_point, resultSet, searchParams);
1812 if (searchParams.sorted)
1822 template <
class SEARCH_CALLBACK>
1826 findNeighbors(resultSet, query_point, searchParams);
1827 return resultSet.size();
1835 const auto dims = (DIM > 0 ? DIM : Base::dim_);
1838 if (dataset_.kdtree_get_bbox(bbox))
1844 const Size N = Base::size_;
1846 throw std::runtime_error(
"[nanoflann] computeBoundingBox() called but "
1847 "no data points found.");
1850 bbox[i].low = bbox[i].high = this->dataset_get(*
this, Base::vAcc_[0], i);
1852 for (
Offset k = 1; k < N; ++k)
1856 const auto val = this->dataset_get(*
this, Base::vAcc_[k], i);
1857 if (val < bbox[i].low)
1859 if (val > bbox[i].high)
1870 template <
class RESULTSET>
1875 if ((node->child1 ==
nullptr) && (node->child2 ==
nullptr))
1878 for (
Offset i = node->node_type.lr.left; i < node->node_type.lr.right; ++i)
1880 const IndexType index = Base::vAcc_[i];
1881 if (treeIndex_[index] == -1)
1883 DistanceType dist = distance_.evalMetric(vec, index, (DIM > 0 ? DIM : Base::dim_));
1884 if (dist < worst_dist)
1886 if (!result_set.addPoint(
static_cast<typename RESULTSET::DistanceType
>(dist),
1887 static_cast<typename RESULTSET::IndexType
>(Base::vAcc_[i])))
1899 Dimension idx = node->node_type.sub.divfeat;
1902 DistanceType diff2 = val - node->node_type.sub.divhigh;
1907 if ((diff1 + diff2) < 0)
1909 bestChild = node->child1;
1910 otherChild = node->child2;
1911 cut_dist = distance_.accum_dist(val, node->node_type.sub.divhigh, idx);
1915 bestChild = node->child2;
1916 otherChild = node->child1;
1917 cut_dist = distance_.accum_dist(val, node->node_type.sub.divlow, idx);
1921 searchLevel(result_set, vec, bestChild, mindist, dists, epsError);
1924 mindist = mindist + cut_dist - dst;
1925 dists[idx] = cut_dist;
1926 if (mindist * epsError <= result_set.worstDist())
1928 searchLevel(result_set, vec, otherChild, mindist, dists, epsError);
1963template <
typename Distance,
class DatasetAdaptor, int32_t DIM = -1,
typename IndexType = uint32_t>
2018 std::vector<my_kd_tree_t> index(treeCount_, my_kd_tree_t(dim_ , dataset_, treeIndex_, index_params_));
2041 const int dimensionality,
const DatasetAdaptor& inputData,
2043 const size_t maximumPointCount = 1000000000U)
2044 : dataset_(inputData), index_params_(params), distance_(inputData)
2046 treeCount_ =
static_cast<size_t>(std::log2(maximumPointCount)) + 1;
2048 dim_ = dimensionality;
2054 const size_t num_initial_points = dataset_.kdtree_get_point_count();
2055 if (num_initial_points > 0)
2057 addPoints(0, num_initial_points - 1);
2068 const Size count = end - start + 1;
2070 treeIndex_.resize(treeIndex_.size() + count);
2071 for (IndexType idx = start; idx <= end; idx++)
2073 const int pos = First0Bit(pointCount_);
2074 maxIndex = std::max(pos, maxIndex);
2075 treeIndex_[pointCount_] = pos;
2077 const auto it = removedPoints_.find(idx);
2078 if (it != removedPoints_.end())
2080 removedPoints_.erase(it);
2081 treeIndex_[idx] = pos;
2084 for (
int i = 0; i < pos; i++)
2086 for (
int j = 0; j < static_cast<int>(index_[i].vAcc_.size()); j++)
2088 index_[pos].vAcc_.push_back(index_[i].vAcc_[j]);
2089 if (treeIndex_[index_[i].vAcc_[j]] != -1)
2090 treeIndex_[index_[i].vAcc_[j]] = pos;
2092 index_[i].vAcc_.clear();
2094 index_[pos].vAcc_.push_back(idx);
2098 for (
int i = 0; i <= maxIndex; ++i)
2100 index_[i].freeIndex(index_[i]);
2101 if (!index_[i].vAcc_.empty())
2102 index_[i].buildIndex();
2109 if (idx >= pointCount_)
2111 removedPoints_.insert(idx);
2112 treeIndex_[idx] = -1;
2131 template <
typename RESULTSET>
2134 for (
size_t i = 0; i < treeCount_; i++)
2136 index_[i].findNeighbors(result, &vec[0], searchParams);
2138 return result.full();
2167template <
class MatrixType, int32_t DIM = -1,
class Distance =
nanoflann::metric_L2,
bool row_major =
true>
2171 using num_t =
typename MatrixType::Scalar;
2173 using metric_t =
typename Distance::template traits<num_t, self_t, IndexType>::distance_t;
2187 const std::reference_wrapper<const MatrixType>& mat,
const int leaf_max_size = 10)
2188 : m_data_matrix(mat)
2190 const auto dims = row_major ? mat.get().cols() : mat.get().rows();
2191 if (
static_cast<Dimension>(dims) != dimensionality)
2192 throw std::runtime_error(
"Error: 'dimensionality' must match column count in data "
2194 if (DIM > 0 &&
static_cast<int32_t
>(dims) != DIM)
2195 throw std::runtime_error(
"Data set dimensionality does not match the 'DIM' template "
2219 resultSet.
init(out_indices, out_distances);
2233 return m_data_matrix.get().rows();
2235 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);
Definition nanoflann.hpp:812
Size usedMemory(Derived &obj)
Definition nanoflann.hpp:913
DistanceType computeInitialDistances(const Derived &obj, const ElementType *vec, distance_vector_t &dists) const
Definition nanoflann.hpp:1102
void planeSplit(const Derived &obj, const Offset ind, const Size count, const Dimension cutfeat, const DistanceType &cutval, Offset &lim1, Offset &lim2)
Definition nanoflann.hpp:1064
typename array_or_vector< DIM, DistanceType >::type distance_vector_t
Definition nanoflann.hpp:883
std::vector< IndexType > vAcc_
Definition nanoflann.hpp:829
void computeMinMax(const Derived &obj, Offset ind, Size count, Dimension element, ElementType &min_elem, ElementType &max_elem)
Definition nanoflann.hpp:919
static void load_tree(Derived &obj, std::istream &stream, NodePtr &tree)
Definition nanoflann.hpp:1136
Size size(const Derived &obj) const
Definition nanoflann.hpp:898
void freeIndex(Derived &obj)
Definition nanoflann.hpp:816
void loadIndex(Derived &obj, std::istream &stream)
Definition nanoflann.hpp:1170
typename array_or_vector< DIM, Interval >::type BoundingBox
Definition nanoflann.hpp:879
BoundingBox root_bbox_
Definition nanoflann.hpp:886
typename decltype(vAcc_)::size_type Size
Definition nanoflann.hpp:832
void saveIndex(const Derived &obj, std::ostream &stream) const
Definition nanoflann.hpp:1155
void middleSplit_(const Derived &obj, const Offset ind, const Size count, Offset &index, Dimension &cutfeat, DistanceType &cutval, const BoundingBox &bbox)
Definition nanoflann.hpp:1001
typename Distance::ElementType ElementType
Definition nanoflann.hpp:823
PooledAllocator pool_
Definition nanoflann.hpp:895
NodePtr divideTree(Derived &obj, const Offset left, const Offset right, BoundingBox &bbox)
Definition nanoflann.hpp:941
typename Distance::DistanceType DistanceType
Definition nanoflann.hpp:824
ElementType dataset_get(const Derived &obj, IndexType element, Dimension component) const
Helper accessor to the dataset points:
Definition nanoflann.hpp:904
Size veclen(const Derived &obj)
Definition nanoflann.hpp:901
static void save_tree(const Derived &obj, std::ostream &stream, const NodeConstPtr tree)
Definition nanoflann.hpp:1123
int32_t Dimension
Definition nanoflann.hpp:833
typename decltype(vAcc_)::size_type Offset
Definition nanoflann.hpp:831
Definition nanoflann.hpp:1226
const KDTreeSingleIndexAdaptorParams indexParams
Definition nanoflann.hpp:1235
Size radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1433
KDTreeSingleIndexAdaptor(const KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, IndexType > &)=delete
KDTreeSingleIndexAdaptor(const Dimension dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms, Args &&... args)
Definition nanoflann.hpp:1284
Distance distance_
Definition nanoflann.hpp:1237
typename Base::Size Size
Definition nanoflann.hpp:1244
typename Base::ElementType ElementType
Definition nanoflann.hpp:1247
typename nanoflann::KDTreeBaseClass< nanoflann::KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, IndexType >, Distance, DatasetAdaptor, DIM, IndexType > Base
Definition nanoflann.hpp:1239
Size radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< ResultItem< IndexType, DistanceType > > &IndicesDists, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1416
typename Base::distance_vector_t distance_vector_t
Definition nanoflann.hpp:1261
void loadIndex(std::istream &stream)
Definition nanoflann.hpp:1577
typename Base::Node Node
Definition nanoflann.hpp:1250
typename Base::BoundingBox BoundingBox
Definition nanoflann.hpp:1257
typename Base::DistanceType DistanceType
Definition nanoflann.hpp:1248
KDTreeSingleIndexAdaptor(const Dimension dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms={})
Definition nanoflann.hpp:1291
typename Base::Interval Interval
Definition nanoflann.hpp:1253
Size knnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances) const
Definition nanoflann.hpp:1388
typename Base::Dimension Dimension
Definition nanoflann.hpp:1245
void init(const Dimension dimensionality, const KDTreeSingleIndexAdaptorParams ¶ms)
Definition nanoflann.hpp:1299
void init_vind()
Definition nanoflann.hpp:1445
const DatasetAdaptor & dataset_
Definition nanoflann.hpp:1233
void saveIndex(std::ostream &stream) const
Definition nanoflann.hpp:1570
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1353
Node * NodePtr
Definition nanoflann.hpp:1251
typename Base::Offset Offset
Definition nanoflann.hpp:1243
void buildIndex()
Definition nanoflann.hpp:1319
bool searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindist, distance_vector_t &dists, const float epsError) const
Definition nanoflann.hpp:1494
void computeBoundingBox(BoundingBox &bbox)
Definition nanoflann.hpp:1455
Definition nanoflann.hpp:1622
Size radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< ResultItem< IndexType, DistanceType > > &IndicesDists, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1806
KDTreeSingleIndexDynamicAdaptor_(const Dimension dimensionality, const DatasetAdaptor &inputData, std::vector< int > &treeIndex, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams())
Definition nanoflann.hpp:1673
std::vector< int > & treeIndex_
Definition nanoflann.hpp:1631
typename Base::Dimension Dimension
Definition nanoflann.hpp:1644
typename Base::BoundingBox BoundingBox
Definition nanoflann.hpp:1652
const DatasetAdaptor & dataset_
The source of our data.
Definition nanoflann.hpp:1627
Size radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1823
typename Base::DistanceType DistanceType
Definition nanoflann.hpp:1640
KDTreeSingleIndexAdaptorParams index_params_
Definition nanoflann.hpp:1629
KDTreeSingleIndexDynamicAdaptor_(const KDTreeSingleIndexDynamicAdaptor_ &rhs)=default
typename Base::Offset Offset
Definition nanoflann.hpp:1642
void buildIndex()
Definition nanoflann.hpp:1710
typename Base::ElementType ElementType
Definition nanoflann.hpp:1639
void saveIndex(std::ostream &stream)
Definition nanoflann.hpp:1939
void computeBoundingBox(BoundingBox &bbox)
Definition nanoflann.hpp:1833
typename Base::Node Node
Definition nanoflann.hpp:1646
typename Base::Size Size
Definition nanoflann.hpp:1643
Node * NodePtr
Definition nanoflann.hpp:1647
typename Base::distance_vector_t distance_vector_t
Definition nanoflann.hpp:1656
void loadIndex(std::istream &stream)
Definition nanoflann.hpp:1946
typename Base::Interval Interval
Definition nanoflann.hpp:1649
typename nanoflann::KDTreeBaseClass< nanoflann::KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM, IndexType >, Distance, DatasetAdaptor, DIM, IndexType > Base
Definition nanoflann.hpp:1635
Size knnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances) const
Definition nanoflann.hpp:1778
void searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindist, distance_vector_t &dists, const float epsError) const
Definition nanoflann.hpp:1871
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:1746
Distance distance_
Definition nanoflann.hpp:1633
KDTreeSingleIndexDynamicAdaptor_ operator=(const KDTreeSingleIndexDynamicAdaptor_ &rhs)
Definition nanoflann.hpp:1692
Definition nanoflann.hpp:1965
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Dimension Dimension
Definition nanoflann.hpp:1972
void init()
Definition nanoflann.hpp:2015
int First0Bit(IndexType num)
Definition nanoflann.hpp:2003
typename Distance::ElementType ElementType
Definition nanoflann.hpp:1967
Size treeCount_
Definition nanoflann.hpp:1976
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Definition nanoflann.hpp:2132
typename Distance::DistanceType DistanceType
Definition nanoflann.hpp:1968
Size leaf_max_size_
Definition nanoflann.hpp:1975
Distance distance_
Definition nanoflann.hpp:2023
const DatasetAdaptor & dataset_
The source of our data.
Definition nanoflann.hpp:1982
void removePoint(size_t idx)
Definition nanoflann.hpp:2107
std::unordered_set< int > removedPoints_
Definition nanoflann.hpp:1987
Size pointCount_
Definition nanoflann.hpp:1977
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Offset Offset
Definition nanoflann.hpp:1970
void addPoints(IndexType start, IndexType end)
Definition nanoflann.hpp:2066
std::vector< index_container_t > index_
Definition nanoflann.hpp:1994
KDTreeSingleIndexDynamicAdaptor(const int dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams(), const size_t maximumPointCount=1000000000U)
Definition nanoflann.hpp:2040
std::vector< int > treeIndex_
Definition nanoflann.hpp:1986
const std::vector< index_container_t > & getAllIndices() const
Definition nanoflann.hpp:1999
KDTreeSingleIndexAdaptorParams index_params_
Definition nanoflann.hpp:1989
Dimension dim_
Dimensionality of each data point.
Definition nanoflann.hpp:1991
KDTreeSingleIndexDynamicAdaptor(const KDTreeSingleIndexDynamicAdaptor< Distance, DatasetAdaptor, DIM, IndexType > &)=delete
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Size Size
Definition nanoflann.hpp:1971
Definition nanoflann.hpp:148
_CountType CountType
Definition nanoflann.hpp:152
CountType capacity
Definition nanoflann.hpp:157
void init(IndexType *indices_, DistanceType *dists_)
Definition nanoflann.hpp:163
_DistanceType DistanceType
Definition nanoflann.hpp:150
bool addPoint(DistanceType dist, IndexType index)
Definition nanoflann.hpp:181
CountType size() const
Definition nanoflann.hpp:172
DistanceType * dists
Definition nanoflann.hpp:156
KNNResultSet(CountType capacity_)
Definition nanoflann.hpp:161
_IndexType IndexType
Definition nanoflann.hpp:151
DistanceType worstDist() const
Definition nanoflann.hpp:216
IndexType * indices
Definition nanoflann.hpp:155
bool full() const
Definition nanoflann.hpp:174
CountType count
Definition nanoflann.hpp:158
Definition nanoflann.hpp:658
~PooledAllocator()
Definition nanoflann.hpp:696
void free_all()
Definition nanoflann.hpp:699
void internal_init()
Definition nanoflann.hpp:676
uint32_t Offset
Definition nanoflann.hpp:668
void * malloc(const size_t req_size)
Definition nanoflann.hpp:715
int32_t Dimension
Definition nanoflann.hpp:670
T * allocate(const size_t count=1)
Definition nanoflann.hpp:770
uint32_t Size
Definition nanoflann.hpp:669
PooledAllocator()
Definition nanoflann.hpp:691
Definition nanoflann.hpp:250
void init()
Definition nanoflann.hpp:266
const DistanceType radius
Definition nanoflann.hpp:256
RadiusResultSet(DistanceType radius_, std::vector< ResultItem< IndexType, DistanceType > > &indices_dists)
Definition nanoflann.hpp:260
size_t empty() const
Definition nanoflann.hpp:270
DistanceType worstDist() const
Definition nanoflann.hpp:286
ResultItem< IndexType, DistanceType > worst_item() const
Definition nanoflann.hpp:292
_DistanceType DistanceType
Definition nanoflann.hpp:252
bool full() const
Definition nanoflann.hpp:272
size_t size() const
Definition nanoflann.hpp:269
std::vector< ResultItem< IndexType, DistanceType > > & m_indices_dists
Definition nanoflann.hpp:258
void clear()
Definition nanoflann.hpp:267
_IndexType IndexType
Definition nanoflann.hpp:253
bool addPoint(DistanceType dist, IndexType index)
Definition nanoflann.hpp:279
void load_value(std::istream &stream, T &value)
Definition nanoflann.hpp:318
void save_value(std::ostream &stream, const T &value)
Definition nanoflann.hpp:306
std::enable_if< has_assign< Container >::value, void >::type assign(Container &c, const size_t nElements, const T &value)
Definition nanoflann.hpp:128
T pi_const()
Definition nanoflann.hpp:82
std::enable_if< has_resize< Container >::value, void >::type resize(Container &c, const size_t nElements)
Definition nanoflann.hpp:108
std::underlying_type< KDTreeSingleIndexAdaptorFlags >::type operator&(KDTreeSingleIndexAdaptorFlags lhs, KDTreeSingleIndexAdaptorFlags rhs)
Definition nanoflann.hpp:609
KDTreeSingleIndexAdaptorFlags
Definition nanoflann.hpp:604
Definition nanoflann.hpp:77
Definition nanoflann.hpp:221
bool operator()(const PairType &p1, const PairType &p2) const
Definition nanoflann.hpp:223
Definition nanoflann.hpp:863
ElementType high
Definition nanoflann.hpp:864
Definition nanoflann.hpp:839
DistanceType divhigh
Definition nanoflann.hpp:851
Offset left
Definition nanoflann.hpp:845
struct nanoflann::KDTreeBaseClass::Node::@0::nonleaf sub
Node * child1
Definition nanoflann.hpp:856
Dimension divfeat
Definition nanoflann.hpp:849
Node * child2
Definition nanoflann.hpp:856
struct nanoflann::KDTreeBaseClass::Node::@0::leaf lr
union nanoflann::KDTreeBaseClass::Node::@0 node_type
Definition nanoflann.hpp:2169
void query(const num_t *query_point, const Size num_closest, IndexType *out_indices, num_t *out_distances) const
Definition nanoflann.hpp:2216
typename MatrixType::Scalar num_t
Definition nanoflann.hpp:2171
num_t kdtree_get_pt(const IndexType idx, size_t dim) const
Definition nanoflann.hpp:2239
Size kdtree_get_point_count() const
Definition nanoflann.hpp:2230
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:2186
typename index_t::Size Size
Definition nanoflann.hpp:2182
bool kdtree_get_bbox(BBOX &) const
Definition nanoflann.hpp:2252
const std::reference_wrapper< const MatrixType > m_data_matrix
Definition nanoflann.hpp:2206
KDTreeEigenMatrixAdaptor(const self_t &)=delete
const self_t & derived() const
Definition nanoflann.hpp:2226
index_t * index_
Definition nanoflann.hpp:2178
typename Distance::template traits< num_t, self_t, IndexType >::distance_t metric_t
Definition nanoflann.hpp:2173
self_t & derived()
Definition nanoflann.hpp:2227
typename MatrixType::Index IndexType
Definition nanoflann.hpp:2172
typename index_t::Dimension Dimension
Definition nanoflann.hpp:2183
typename index_t::Offset Offset
Definition nanoflann.hpp:2181
~KDTreeEigenMatrixAdaptor()
Definition nanoflann.hpp:2204
Definition nanoflann.hpp:618
KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size=10, KDTreeSingleIndexAdaptorFlags _flags=KDTreeSingleIndexAdaptorFlags::None)
Definition nanoflann.hpp:619
size_t leaf_max_size
Definition nanoflann.hpp:625
KDTreeSingleIndexAdaptorFlags flags
Definition nanoflann.hpp:626
Definition nanoflann.hpp:350
T ElementType
Definition nanoflann.hpp:351
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size, DistanceType worst_dist=-1) const
Definition nanoflann.hpp:358
const DataSource & data_source
Definition nanoflann.hpp:354
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:388
_DistanceType DistanceType
Definition nanoflann.hpp:352
L1_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:356
Definition nanoflann.hpp:405
_DistanceType DistanceType
Definition nanoflann.hpp:407
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:444
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size, DistanceType worst_dist=-1) const
Definition nanoflann.hpp:413
T ElementType
Definition nanoflann.hpp:406
L2_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:411
const DataSource & data_source
Definition nanoflann.hpp:409
Definition nanoflann.hpp:461
const DataSource & data_source
Definition nanoflann.hpp:465
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
Definition nanoflann.hpp:469
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:480
L2_Simple_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:467
_DistanceType DistanceType
Definition nanoflann.hpp:463
T ElementType
Definition nanoflann.hpp:462
Definition nanoflann.hpp:336
Definition nanoflann.hpp:238
DistanceType second
Distance from sample to query point.
Definition nanoflann.hpp:243
ResultItem(const IndexType index, const DistanceType distance)
Definition nanoflann.hpp:240
IndexType first
Index of the sample in the dataset.
Definition nanoflann.hpp:242
Definition nanoflann.hpp:497
const DataSource & data_source
Definition nanoflann.hpp:501
_DistanceType DistanceType
Definition nanoflann.hpp:499
T ElementType
Definition nanoflann.hpp:498
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
Definition nanoflann.hpp:505
SO2_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:503
DistanceType accum_dist(const U a, const V b, const size_t) const
Definition nanoflann.hpp:512
Definition nanoflann.hpp:536
_DistanceType DistanceType
Definition nanoflann.hpp:538
L2_Simple_Adaptor< T, DataSource, DistanceType, IndexType > distance_L2_Simple
Definition nanoflann.hpp:540
T ElementType
Definition nanoflann.hpp:537
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
Definition nanoflann.hpp:544
SO3_Adaptor(const DataSource &_data_source)
Definition nanoflann.hpp:542
DistanceType accum_dist(const U a, const V b, const size_t idx) const
Definition nanoflann.hpp:549
Definition nanoflann.hpp:631
SearchParameters(float eps_=0, bool sorted_=true)
Definition nanoflann.hpp:632
bool sorted
Definition nanoflann.hpp:635
float eps
search for eps-approximate neighbours (default: 0)
Definition nanoflann.hpp:634
std::vector< T > type
Definition nanoflann.hpp:791
Definition nanoflann.hpp:785
std::array< T, DIM > type
Definition nanoflann.hpp:786
Definition nanoflann.hpp:97
Definition nanoflann.hpp:89
Definition nanoflann.hpp:559
Definition nanoflann.hpp:557
Definition nanoflann.hpp:568
Definition nanoflann.hpp:577
Definition nanoflann.hpp:575
Definition nanoflann.hpp:566
Definition nanoflann.hpp:585
Definition nanoflann.hpp:583
Definition nanoflann.hpp:593
Definition nanoflann.hpp:591