60#include <unordered_set>
64#define NANOFLANN_VERSION 0x171
67#if !defined(NOMINMAX) && \
68 (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
89 return static_cast<T
>(3.14159265358979323846);
96template <
typename T,
typename =
int>
107template <
typename T,
typename =
int>
121template <
typename Container>
122inline typename std::enable_if<has_resize<Container>::value,
void>::type
resize(
123 Container& c,
const size_t nElements)
132template <
typename Container>
133inline typename std::enable_if<!has_resize<Container>::value,
void>::type
134 resize(Container& c,
const size_t nElements)
136 if (nElements != c.size())
137 throw std::logic_error(
"Try to change the size of a std::array.");
143template <
typename Container,
typename T>
144inline typename std::enable_if<has_assign<Container>::value,
void>::type
assign(
145 Container& c,
const size_t nElements,
const T& value)
147 c.assign(nElements, value);
153template <
typename Container,
typename T>
154inline typename std::enable_if<!has_assign<Container>::value,
void>::type
155 assign(Container& c,
const size_t nElements,
const T& value)
157 for (
size_t i = 0; i < nElements; i++) c[i] = value;
164 template <
typename PairType>
165 bool operator()(
const PairType& p1,
const PairType& p2)
const
167 return p1.second < p2.second;
179template <
typename IndexType =
size_t,
typename DistanceType =
double>
183 ResultItem(
const IndexType index,
const DistanceType distance)
197 typename _DistanceType,
typename _IndexType = size_t,
198 typename _CountType =
size_t>
237 for (i =
count; i > 0; --i)
241#ifdef NANOFLANN_FIRST_MATCH
242 if ((
dists[i - 1] > dist) ||
246 if (
dists[i - 1] > dist)
274 ? std::numeric_limits<DistanceType>::max()
286 typename _DistanceType,
typename _IndexType = size_t,
287 typename _CountType =
size_t>
333 for (i =
count; i > 0; --i)
337#ifdef NANOFLANN_FIRST_MATCH
338 if ((
dists[i - 1] > dist) ||
342 if (
dists[i - 1] > dist)
382template <
typename _DistanceType,
typename _IndexType =
size_t>
408 bool full()
const {
return true; }
430 throw std::runtime_error(
431 "Cannot invoke RadiusResultSet::worst_item() on "
432 "an empty list of results.");
433 auto it = std::max_element(
452 stream.write(
reinterpret_cast<const char*
>(&value),
sizeof(T));
456void save_value(std::ostream& stream,
const std::vector<T>& value)
458 size_t size = value.size();
459 stream.write(
reinterpret_cast<const char*
>(&size),
sizeof(
size_t));
460 stream.write(
reinterpret_cast<const char*
>(value.data()),
sizeof(T) * size);
466 stream.read(
reinterpret_cast<char*
>(&value),
sizeof(T));
473 stream.read(
reinterpret_cast<char*
>(&size),
sizeof(
size_t));
475 stream.read(
reinterpret_cast<char*
>(value.data()),
sizeof(T) * size);
497 class T,
class DataSource,
typename _DistanceType = T,
498 typename IndexType =
size_t>
509 const T* a,
const IndexType b_idx,
size_t size,
513 const T* last = a + size;
514 const T* lastgroup = last - 3;
518 while (a < lastgroup)
521 std::abs(a[0] -
data_source.kdtree_get_pt(b_idx, d++));
523 std::abs(a[1] -
data_source.kdtree_get_pt(b_idx, d++));
525 std::abs(a[2] -
data_source.kdtree_get_pt(b_idx, d++));
527 std::abs(a[3] -
data_source.kdtree_get_pt(b_idx, d++));
528 result += diff0 + diff1 + diff2 + diff3;
530 if ((worst_dist > 0) && (result > worst_dist)) {
return result; }
536 result += std::abs(*a++ -
data_source.kdtree_get_pt(b_idx, d++));
541 template <
typename U,
typename V>
544 return std::abs(a - b);
559 class T,
class DataSource,
typename _DistanceType = T,
560 typename IndexType =
size_t>
571 const T* a,
const IndexType b_idx,
size_t size,
575 const T* last = a + size;
576 const T* lastgroup = last - 3;
580 while (a < lastgroup)
591 diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
593 if ((worst_dist > 0) && (result > worst_dist)) {
return result; }
601 result += diff0 * diff0;
606 template <
typename U,
typename V>
609 return (a - b) * (a - b);
624 class T,
class DataSource,
typename _DistanceType = T,
625 typename IndexType =
size_t>
639 const T* a,
const IndexType b_idx,
size_t size)
const
642 for (
size_t i = 0; i < size; ++i)
646 result += diff * diff;
651 template <
typename U,
typename V>
654 return (a - b) * (a - b);
669 class T,
class DataSource,
typename _DistanceType = T,
670 typename IndexType =
size_t>
681 const T* a,
const IndexType b_idx,
size_t size)
const
684 a[size - 1],
data_source.kdtree_get_pt(b_idx, size - 1), size - 1);
689 template <
typename U,
typename V>
697 else if (result < -
PI)
714 class T,
class DataSource,
typename _DistanceType = T,
715 typename IndexType =
size_t>
730 const T* a,
const IndexType b_idx,
size_t size)
const
735 template <
typename U,
typename V>
745 template <
class T,
class DataSource,
typename IndexType =
size_t>
755 template <
class T,
class DataSource,
typename IndexType =
size_t>
765 template <
class T,
class DataSource,
typename IndexType =
size_t>
774 template <
class T,
class DataSource,
typename IndexType =
size_t>
783 template <
class T,
class DataSource,
typename IndexType =
size_t>
801inline std::underlying_type<KDTreeSingleIndexAdaptorFlags>::type
operator&(
805 typename std::underlying_type<KDTreeSingleIndexAdaptorFlags>::type;
806 return static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs);
813 size_t _leaf_max_size = 10,
816 unsigned int _n_thread_build = 1)
901 while (
base_ !=
nullptr)
904 void* prev = *(
static_cast<void**
>(
base_));
931 const Size blocksize =
938 throw std::bad_alloc();
942 static_cast<void**
>(m)[0] =
base_;
949 loc_ =
static_cast<char*
>(
loc_) + size;
964 template <
typename T>
967 T* mem =
static_cast<T*
>(this->
malloc(
sizeof(T) * count));
979template <
int32_t DIM,
typename T>
982 using type = std::array<T, DIM>;
1008 class Derived,
typename Distance,
class DatasetAdaptor,
int32_t DIM = -1,
1009 typename index_t = uint32_t>
1017 obj.pool_.free_all();
1018 obj.root_node_ =
nullptr;
1019 obj.size_at_index_build_ = 0;
1101 Size size(
const Derived& obj)
const {
return obj.size_; }
1104 Size veclen(
const Derived& obj)
const {
return DIM > 0 ? DIM : obj.dim_; }
1110 return obj.dataset_.kdtree_get_pt(element, component);
1119 return obj.pool_.usedMemory + obj.pool_.wastedMemory +
1120 obj.dataset_.kdtree_get_point_count() *
1132 max_elem = min_elem;
1133 for (
Offset i = 1; i < count; ++i)
1136 if (val < min_elem) min_elem = val;
1137 if (val > max_elem) max_elem = val;
1152 assert(left < obj.dataset_.kdtree_get_point_count());
1154 NodePtr node = obj.pool_.template allocate<Node>();
1155 const auto dims = (DIM > 0 ? DIM : obj.dim_);
1158 if ((right - left) <=
static_cast<Offset>(obj.leaf_max_size_))
1167 bbox[i].low =
dataset_get(obj, obj.vAcc_[left], i);
1168 bbox[i].high =
dataset_get(obj, obj.vAcc_[left], i);
1170 for (
Offset k = left + 1; k < right; ++k)
1174 const auto val =
dataset_get(obj, obj.vAcc_[k], i);
1175 if (bbox[i].low > val) bbox[i].low = val;
1176 if (bbox[i].high < val) bbox[i].high = val;
1186 middleSplit_(obj, left, right - left, idx, cutfeat, cutval, bbox);
1192 left_bbox[cutfeat].high = cutval;
1197 right_bbox[cutfeat].low = cutval;
1205 bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
1206 bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1226 std::atomic<unsigned int>& thread_count, std::mutex& mutex)
1228 std::unique_lock<std::mutex> lock(mutex);
1229 NodePtr node = obj.pool_.template allocate<Node>();
1232 const auto dims = (DIM > 0 ? DIM : obj.dim_);
1235 if ((right - left) <=
static_cast<Offset>(obj.leaf_max_size_))
1244 bbox[i].low =
dataset_get(obj, obj.vAcc_[left], i);
1245 bbox[i].high =
dataset_get(obj, obj.vAcc_[left], i);
1247 for (
Offset k = left + 1; k < right; ++k)
1251 const auto val =
dataset_get(obj, obj.vAcc_[k], i);
1252 if (bbox[i].low > val) bbox[i].low = val;
1253 if (bbox[i].high < val) bbox[i].high = val;
1263 middleSplit_(obj, left, right - left, idx, cutfeat, cutval, bbox);
1267 std::future<NodePtr> right_future;
1272 right_bbox[cutfeat].low = cutval;
1277 right_future = std::async(
1279 this, std::ref(obj), left + idx, right,
1280 std::ref(right_bbox), std::ref(thread_count),
1283 else { --thread_count; }
1288 left_bbox[cutfeat].high = cutval;
1290 obj, left, left + idx, left_bbox, thread_count, mutex);
1292 if (right_future.valid())
1296 node->
child2 = right_future.get();
1304 obj, left + idx, right, right_bbox, thread_count, mutex);
1312 bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
1313 bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1324 const auto dims = (DIM > 0 ? DIM : obj.dim_);
1326 ElementType max_span = bbox[0].high - bbox[0].low;
1330 if (span > max_span) { max_span = span; }
1338 if (span >= (1 - EPS) * max_span)
1343 if (spread > max_spread)
1346 max_spread = spread;
1347 min_elem = min_elem_;
1348 max_elem = max_elem_;
1353 DistanceType split_val = (bbox[cutfeat].low + bbox[cutfeat].high) / 2;
1355 if (split_val < min_elem)
1357 else if (split_val > max_elem)
1363 planeSplit(obj, ind, count, cutfeat, cutval, lim1, lim2);
1365 if (lim1 > count / 2)
1367 else if (lim2 < count / 2)
1383 const Derived& obj,
const Offset ind,
const Size count,
1391 Offset right = count - 1;
1394 while (left <= right &&
1397 while (right && left <= right &&
1400 if (left > right || !right)
1402 std::swap(
vAcc_[ind + left],
vAcc_[ind + right]);
1414 while (left <= right &&
1417 while (right && left <= right &&
1420 if (left > right || !right)
1422 std::swap(
vAcc_[ind + left],
vAcc_[ind + right]);
1436 for (
Dimension i = 0; i < (DIM > 0 ? DIM : obj.dim_); ++i)
1438 if (vec[i] < obj.root_bbox_[i].low)
1441 obj.distance_.accum_dist(vec[i], obj.root_bbox_[i].low, i);
1444 if (vec[i] > obj.root_bbox_[i].high)
1447 obj.distance_.accum_dist(vec[i], obj.root_bbox_[i].high, i);
1455 const Derived& obj, std::ostream& stream,
const NodeConstPtr tree)
1464 tree = obj.pool_.template allocate<Node>();
1475 void saveIndex(
const Derived& obj, std::ostream& stream)
const
1482 if (obj.root_node_)
save_tree(obj, stream, obj.root_node_);
1543 typename Distance,
class DatasetAdaptor,
int32_t DIM = -1,
1544 typename index_t = uint32_t>
1547 KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, index_t>,
1548 Distance, DatasetAdaptor, DIM, index_t>
1554 Distance, DatasetAdaptor, DIM, index_t>&) =
delete;
1565 Distance, DatasetAdaptor, DIM, index_t>,
1566 Distance, DatasetAdaptor, DIM, index_t>;
1609 template <
class... Args>
1611 const Dimension dimensionality,
const DatasetAdaptor& inputData,
1615 distance_(inputData, std::forward<Args>(args)...)
1617 init(dimensionality, params);
1621 const Dimension dimensionality,
const DatasetAdaptor& inputData,
1623 : dataset_(inputData), indexParams(params), distance_(inputData)
1625 init(dimensionality, params);
1633 Base::size_ =
dataset_.kdtree_get_point_count();
1634 Base::size_at_index_build_ = Base::size_;
1635 Base::dim_ = dimensionality;
1636 if (DIM > 0) Base::dim_ = DIM;
1644 Base::n_thread_build_ =
1645 std::max(std::thread::hardware_concurrency(), 1u);
1648 if (!(params.
flags &
1662 Base::size_ =
dataset_.kdtree_get_point_count();
1663 Base::size_at_index_build_ = Base::size_;
1666 Base::size_at_index_build_ = Base::size_;
1667 if (Base::size_ == 0)
return;
1670 if (Base::n_thread_build_ == 1)
1673 this->
divideTree(*
this, 0, Base::size_, Base::root_bbox_);
1677#ifndef NANOFLANN_NO_THREADS
1678 std::atomic<unsigned int> thread_count(0u);
1681 *
this, 0, Base::size_, Base::root_bbox_, thread_count, mutex);
1683 throw std::runtime_error(
"Multithreading is disabled");
1707 template <
typename RESULTSET>
1713 if (this->size(*
this) == 0)
return false;
1714 if (!Base::root_node_)
1715 throw std::runtime_error(
1716 "[nanoflann] findNeighbors() called before building the "
1718 float epsError = 1 + searchParams.eps;
1721 distance_vector_t dists;
1723 auto zero =
static_cast<typename RESULTSET::DistanceType
>(0);
1724 assign(dists, (DIM > 0 ? DIM : Base::dim_), zero);
1725 DistanceType dist = this->computeInitialDistances(*
this, vec, dists);
1726 searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
1728 if (searchParams.sorted) result.sort();
1730 return result.full();
1753 resultSet.
init(out_indices, out_distances);
1755 return resultSet.
size();
1783 radius, IndicesDists);
1785 radiusSearchCustomCallback(query_point, resultSet, searchParams);
1794 template <
class SEARCH_CALLBACK>
1796 const ElementType* query_point, SEARCH_CALLBACK& resultSet,
1799 findNeighbors(resultSet, query_point, searchParams);
1800 return resultSet.size();
1825 num_closest, radius);
1826 resultSet.
init(out_indices, out_distances);
1828 return resultSet.
size();
1839 Base::size_ =
dataset_.kdtree_get_point_count();
1840 if (Base::vAcc_.
size() != Base::size_) Base::vAcc_.resize(Base::size_);
1841 for (
IndexType i = 0; i < static_cast<IndexType>(Base::size_); i++)
1847 const auto dims = (DIM > 0 ? DIM : Base::dim_);
1849 if (
dataset_.kdtree_get_bbox(bbox))
1857 throw std::runtime_error(
1858 "[nanoflann] computeBoundingBox() called but "
1859 "no data points found.");
1862 bbox[i].low = bbox[i].high =
1865 for (
Offset k = 1; k < N; ++k)
1871 if (val < bbox[i].low) bbox[i].low = val;
1872 if (val > bbox[i].high) bbox[i].high = val;
1884 template <
class RESULTSET>
1888 const float epsError)
const
1891 if ((node->child1 ==
nullptr) && (node->child2 ==
nullptr))
1894 for (
Offset i = node->node_type.lr.left;
1895 i < node->node_type.lr.right; ++i)
1897 const IndexType accessor = Base::vAcc_[i];
1899 vec, accessor, (DIM > 0 ? DIM : Base::dim_));
1900 if (dist < worst_dist)
1902 if (!result_set.addPoint(dist, Base::vAcc_[i]))
1914 Dimension idx = node->node_type.sub.divfeat;
1917 DistanceType diff2 = val - node->node_type.sub.divhigh;
1922 if ((diff1 + diff2) < 0)
1924 bestChild = node->child1;
1925 otherChild = node->child2;
1927 distance_.accum_dist(val, node->node_type.sub.divhigh, idx);
1931 bestChild = node->child2;
1932 otherChild = node->child1;
1934 distance_.accum_dist(val, node->node_type.sub.divlow, idx);
1938 if (!
searchLevel(result_set, vec, bestChild, mindist, dists, epsError))
1946 mindist = mindist + cut_dist - dst;
1947 dists[idx] = cut_dist;
1948 if (mindist * epsError <= result_set.worstDist())
1951 result_set, vec, otherChild, mindist, dists, epsError))
1970 Base::saveIndex(*
this, stream);
1978 void loadIndex(std::istream& stream) { Base::loadIndex(*
this, stream); }
2020 typename Distance,
class DatasetAdaptor,
int32_t DIM = -1,
2021 typename IndexType = uint32_t>
2024 KDTreeSingleIndexDynamicAdaptor_<
2025 Distance, DatasetAdaptor, DIM, IndexType>,
2026 Distance, DatasetAdaptor, DIM, IndexType>
2042 Distance, DatasetAdaptor, DIM,
IndexType>,
2043 Distance, DatasetAdaptor, DIM,
IndexType>;
2080 const Dimension dimensionality,
const DatasetAdaptor& inputData,
2081 std::vector<int>& treeIndex,
2090 Base::size_at_index_build_ = 0;
2091 for (
auto& v : Base::root_bbox_) v = {};
2092 Base::dim_ = dimensionality;
2093 if (DIM > 0) Base::dim_ = DIM;
2094 Base::leaf_max_size_ = params.leaf_max_size;
2095 if (params.n_thread_build > 0)
2097 Base::n_thread_build_ = params.n_thread_build;
2101 Base::n_thread_build_ =
2102 std::max(std::thread::hardware_concurrency(), 1u);
2115 std::swap(Base::vAcc_, tmp.Base::vAcc_);
2116 std::swap(Base::leaf_max_size_, tmp.Base::leaf_max_size_);
2119 std::swap(Base::size_, tmp.Base::size_);
2120 std::swap(Base::size_at_index_build_, tmp.Base::size_at_index_build_);
2121 std::swap(Base::root_node_, tmp.Base::root_node_);
2122 std::swap(Base::root_bbox_, tmp.Base::root_bbox_);
2123 std::swap(Base::pool_, tmp.Base::pool_);
2132 Base::size_ = Base::vAcc_.size();
2134 Base::size_at_index_build_ = Base::size_;
2135 if (Base::size_ == 0)
return;
2138 if (Base::n_thread_build_ == 1)
2141 this->
divideTree(*
this, 0, Base::size_, Base::root_bbox_);
2145#ifndef NANOFLANN_NO_THREADS
2146 std::atomic<unsigned int> thread_count(0u);
2149 *
this, 0, Base::size_, Base::root_bbox_, thread_count, mutex);
2151 throw std::runtime_error(
"Multithreading is disabled");
2179 template <
typename RESULTSET>
2185 if (this->size(*
this) == 0)
return false;
2186 if (!Base::root_node_)
return false;
2187 float epsError = 1 + searchParams.eps;
2190 distance_vector_t dists;
2193 dists, (DIM > 0 ? DIM : Base::dim_),
2194 static_cast<typename distance_vector_t::value_type
>(0));
2195 DistanceType dist = this->computeInitialDistances(*
this, vec, dists);
2196 searchLevel(result, vec, Base::root_node_, dist, dists, epsError);
2197 return result.full();
2220 resultSet.init(out_indices, out_distances);
2221 findNeighbors(resultSet, query_point, searchParams);
2222 return resultSet.size();
2250 radius, IndicesDists);
2251 const size_t nFound =
2252 radiusSearchCustomCallback(query_point, resultSet, searchParams);
2261 template <
class SEARCH_CALLBACK>
2263 const ElementType* query_point, SEARCH_CALLBACK& resultSet,
2266 findNeighbors(resultSet, query_point, searchParams);
2267 return resultSet.size();
2275 const auto dims = (DIM > 0 ? DIM : Base::dim_);
2278 if (
dataset_.kdtree_get_bbox(bbox))
2284 const Size N = Base::size_;
2286 throw std::runtime_error(
2287 "[nanoflann] computeBoundingBox() called but "
2288 "no data points found.");
2291 bbox[i].low = bbox[i].high =
2294 for (
Offset k = 1; k < N; ++k)
2300 if (val < bbox[i].low) bbox[i].low = val;
2301 if (val > bbox[i].high) bbox[i].high = val;
2311 template <
class RESULTSET>
2315 const float epsError)
const
2318 if ((node->child1 ==
nullptr) && (node->child2 ==
nullptr))
2321 for (
Offset i = node->node_type.lr.left;
2322 i < node->node_type.lr.right; ++i)
2327 vec, index, (DIM > 0 ? DIM : Base::dim_));
2328 if (dist < worst_dist)
2330 if (!result_set.addPoint(
2331 static_cast<typename RESULTSET::DistanceType
>(dist),
2332 static_cast<typename RESULTSET::IndexType
>(
2345 Dimension idx = node->node_type.sub.divfeat;
2348 DistanceType diff2 = val - node->node_type.sub.divhigh;
2353 if ((diff1 + diff2) < 0)
2355 bestChild = node->child1;
2356 otherChild = node->child2;
2358 distance_.accum_dist(val, node->node_type.sub.divhigh, idx);
2362 bestChild = node->child2;
2363 otherChild = node->child1;
2365 distance_.accum_dist(val, node->node_type.sub.divlow, idx);
2369 searchLevel(result_set, vec, bestChild, mindist, dists, epsError);
2372 mindist = mindist + cut_dist - dst;
2373 dists[idx] = cut_dist;
2374 if (mindist * epsError <= result_set.worstDist())
2376 searchLevel(result_set, vec, otherChild, mindist, dists, epsError);
2412 typename Distance,
class DatasetAdaptor,
int32_t DIM = -1,
2413 typename IndexType = uint32_t>
2421 Distance, DatasetAdaptor, DIM>
::Offset;
2423 Distance, DatasetAdaptor, DIM>
::Size;
2447 Distance, DatasetAdaptor, DIM, IndexType>;
2475 Distance, DatasetAdaptor, DIM, IndexType>;
2476 std::vector<my_kd_tree_t> index(
2501 const int dimensionality,
const DatasetAdaptor& inputData,
2504 const size_t maximumPointCount = 1000000000U)
2507 treeCount_ =
static_cast<size_t>(std::log2(maximumPointCount)) + 1;
2509 dim_ = dimensionality;
2511 if (DIM > 0)
dim_ = DIM;
2514 const size_t num_initial_points =
dataset_.kdtree_get_point_count();
2515 if (num_initial_points > 0) {
addPoints(0, num_initial_points - 1); }
2521 Distance, DatasetAdaptor, DIM, IndexType>&) =
delete;
2526 const Size count = end - start + 1;
2529 for (IndexType idx = start; idx <= end; idx++)
2532 maxIndex = std::max(pos, maxIndex);
2542 for (
int i = 0; i < pos; i++)
2544 for (
int j = 0; j < static_cast<int>(
index_[i].vAcc_.size());
2553 index_[pos].vAcc_.push_back(idx);
2557 for (
int i = 0; i <= maxIndex; ++i)
2588 template <
typename RESULTSET>
2593 for (
size_t i = 0; i < treeCount_; i++)
2595 index_[i].findNeighbors(result, &vec[0], searchParams);
2597 return result.full();
2627 class MatrixType, int32_t DIM = -1,
class Distance = nanoflann::metric_L2,
2628 bool row_major =
true>
2633 using num_t =
typename MatrixType::Scalar;
2640 row_major ? MatrixType::ColsAtCompileTime
2641 : MatrixType::RowsAtCompileTime,
2654 const std::reference_wrapper<const MatrixType>& mat,
2655 const int leaf_max_size = 10,
const unsigned int n_thread_build = 1)
2658 const auto dims = row_major ? mat.get().cols() : mat.get().rows();
2659 if (
static_cast<Dimension>(dims) != dimensionality)
2660 throw std::runtime_error(
2661 "Error: 'dimensionality' must match column count in data "
2663 if (DIM > 0 &&
static_cast<int32_t>(dims) != DIM)
2664 throw std::runtime_error(
2665 "Data set dimensionality does not match the 'DIM' template "
2691 const num_t* query_point,
const Size num_closest,
2695 resultSet.
init(out_indices, out_distances);
2696 index_->findNeighbors(resultSet, query_point);
2728 template <
class BBOX>
void freeIndex(Derived &obj)
void middleSplit_(const Derived &obj, const Offset ind, const Size count, Offset &index, Dimension &cutfeat, DistanceType &cutval, const BoundingBox &bbox)
Size veclen(const Derived &obj) const
DistanceType computeInitialDistances(const Derived &obj, const ElementType *vec, distance_vector_t &dists) const
void computeMinMax(const Derived &obj, Offset ind, Size count, Dimension element, ElementType &min_elem, ElementType &max_elem) const
void saveIndex(const Derived &obj, std::ostream &stream) const
typename decltype(vAcc_)::size_type Size
Dimension dim_
Dimensionality of each data point.
typename Distance::ElementType ElementType
typename array_or_vector< DIM, DistanceType >::type distance_vector_t
void planeSplit(const Derived &obj, const Offset ind, const Size count, const Dimension cutfeat, const DistanceType &cutval, Offset &lim1, Offset &lim2)
Size n_thread_build_
Number of thread for concurrent tree build.
static void load_tree(Derived &obj, std::istream &stream, NodePtr &tree)
NodePtr divideTree(Derived &obj, const Offset left, const Offset right, BoundingBox &bbox)
static void save_tree(const Derived &obj, std::ostream &stream, const NodeConstPtr tree)
std::vector< IndexType > vAcc_
Size size(const Derived &obj) const
Size size_at_index_build_
Number of points in the dataset when the index was built.
NodePtr divideTreeConcurrent(Derived &obj, const Offset left, const Offset right, BoundingBox &bbox, std::atomic< unsigned int > &thread_count, std::mutex &mutex)
const Node * NodeConstPtr
typename Distance::DistanceType DistanceType
Size size_
Number of current points in the dataset.
typename decltype(vAcc_)::size_type Offset
Size usedMemory(const Derived &obj) const
void loadIndex(Derived &obj, std::istream &stream)
ElementType dataset_get(const Derived &obj, IndexType element, Dimension component) const
Helper accessor to the dataset points:
typename array_or_vector< DIM, Interval >::type BoundingBox
typename Base::DistanceType DistanceType
bool searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindist, distance_vector_t &dists, const float epsError) const
const KDTreeSingleIndexAdaptorParams indexParams
void init(const Dimension dimensionality, const KDTreeSingleIndexAdaptorParams ¶ms)
typename Base::IndexType IndexType
typename Base::ElementType ElementType
void saveIndex(std::ostream &stream) const
Size radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< ResultItem< IndexType, DistanceType > > &IndicesDists, const SearchParameters &searchParams={}) const
typename Base::Dimension Dimension
typename nanoflann::KDTreeBaseClass< nanoflann::KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, index_t >, Distance, DatasetAdaptor, DIM, index_t > Base
typename Base::Offset Offset
KDTreeSingleIndexAdaptor(const KDTreeSingleIndexAdaptor< Distance, DatasetAdaptor, DIM, index_t > &)=delete
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
Size rknnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances, const DistanceType &radius) const
typename Base::Interval Interval
Size radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParameters &searchParams={}) const
typename Base::distance_vector_t distance_vector_t
void loadIndex(std::istream &stream)
void computeBoundingBox(BoundingBox &bbox)
KDTreeSingleIndexAdaptor(const Dimension dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms={})
typename Base::BoundingBox BoundingBox
KDTreeSingleIndexAdaptor(const Dimension dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms, Args &&... args)
Size knnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances) const
Size radiusSearch(const ElementType *query_point, const DistanceType &radius, std::vector< ResultItem< IndexType, DistanceType > > &IndicesDists, const SearchParameters &searchParams={}) const
KDTreeSingleIndexDynamicAdaptor_(const Dimension dimensionality, const DatasetAdaptor &inputData, std::vector< int > &treeIndex, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams())
std::vector< int > & treeIndex_
typename Base::Dimension Dimension
typename Base::BoundingBox BoundingBox
const DatasetAdaptor & dataset_
Size radiusSearchCustomCallback(const ElementType *query_point, SEARCH_CALLBACK &resultSet, const SearchParameters &searchParams={}) const
typename Base::DistanceType DistanceType
typename nanoflann::KDTreeBaseClass< nanoflann::KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM, IndexType >, Distance, DatasetAdaptor, DIM, IndexType > Base
KDTreeSingleIndexAdaptorParams index_params_
KDTreeSingleIndexDynamicAdaptor_(const KDTreeSingleIndexDynamicAdaptor_ &rhs)=default
typename Base::Offset Offset
typename Base::ElementType ElementType
void saveIndex(std::ostream &stream)
void computeBoundingBox(BoundingBox &bbox)
typename Base::distance_vector_t distance_vector_t
void loadIndex(std::istream &stream)
typename Base::Interval Interval
Size knnSearch(const ElementType *query_point, const Size num_closest, IndexType *out_indices, DistanceType *out_distances, const SearchParameters &searchParams={}) const
void searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindist, distance_vector_t &dists, const float epsError) const
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
KDTreeSingleIndexDynamicAdaptor_ operator=(const KDTreeSingleIndexDynamicAdaptor_ &rhs)
int First0Bit(IndexType num)
typename Distance::ElementType ElementType
bool findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParameters &searchParams={}) const
typename Distance::DistanceType DistanceType
const DatasetAdaptor & dataset_
The source of our data.
void removePoint(size_t idx)
std::unordered_set< int > removedPoints_
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Offset Offset
KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM, IndexType > index_container_t
void addPoints(IndexType start, IndexType end)
std::vector< index_container_t > index_
KDTreeSingleIndexDynamicAdaptor(const int dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams(), const size_t maximumPointCount=1000000000U)
std::vector< int > treeIndex_
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Dimension Dimension
const std::vector< index_container_t > & getAllIndices() const
typename KDTreeSingleIndexDynamicAdaptor_< Distance, DatasetAdaptor, DIM >::Size Size
KDTreeSingleIndexAdaptorParams index_params_
Dimension dim_
Dimensionality of each data point.
KDTreeSingleIndexDynamicAdaptor(const KDTreeSingleIndexDynamicAdaptor< Distance, DatasetAdaptor, DIM, IndexType > &)=delete
void init(IndexType *indices_, DistanceType *dists_)
_DistanceType DistanceType
bool addPoint(DistanceType dist, IndexType index)
KNNResultSet(CountType capacity_)
DistanceType worstDist() const
static constexpr size_t BLOCKSIZE
void * malloc(const size_t req_size)
Size remaining_
Number of bytes left in current block of storage.
static constexpr size_t WORDSIZE
T * allocate(const size_t count=1)
void * loc_
Current location in block to next allocate.
void * base_
Pointer to base of current block of storage.
bool addPoint(DistanceType dist, IndexType index)
void init(IndexType *indices_, DistanceType *dists_)
RKNNResultSet(CountType capacity_, DistanceType maximumSearchDistanceSquared_)
DistanceType maximumSearchDistanceSquared
_DistanceType DistanceType
DistanceType worstDist() const
const DistanceType radius
RadiusResultSet(DistanceType radius_, std::vector< ResultItem< IndexType, DistanceType > > &indices_dists)
DistanceType worstDist() const
ResultItem< IndexType, DistanceType > worst_item() const
_DistanceType DistanceType
std::vector< ResultItem< IndexType, DistanceType > > & m_indices_dists
bool addPoint(DistanceType dist, IndexType index)
void load_value(std::istream &stream, T &value)
void save_value(std::ostream &stream, const T &value)
std::enable_if< has_assign< Container >::value, void >::type assign(Container &c, const size_t nElements, const T &value)
std::enable_if< has_resize< Container >::value, void >::type resize(Container &c, const size_t nElements)
std::underlying_type< KDTreeSingleIndexAdaptorFlags >::type operator&(KDTreeSingleIndexAdaptorFlags lhs, KDTreeSingleIndexAdaptorFlags rhs)
KDTreeSingleIndexAdaptorFlags
bool operator()(const PairType &p1, const PairType &p2) const
DistanceType divlow
The values used for subdivision.
Offset right
Indices of points in leaf node.
struct nanoflann::KDTreeBaseClass::Node::@364321301303311376260063053066165110326243214105::leaf lr
struct nanoflann::KDTreeBaseClass::Node::@364321301303311376260063053066165110326243214105::nonleaf sub
union nanoflann::KDTreeBaseClass::Node::@364321301303311376260063053066165110326243214105 node_type
typename Distance::template traits< num_t, self_t, IndexType >::distance_t metric_t
void query(const num_t *query_point, const Size num_closest, IndexType *out_indices, num_t *out_distances) const
KDTreeEigenMatrixAdaptor< MatrixType, DIM, Distance, row_major > self_t
typename MatrixType::Scalar num_t
num_t kdtree_get_pt(const IndexType idx, size_t dim) const
Size kdtree_get_point_count() const
typename index_t::Size Size
bool kdtree_get_bbox(BBOX &) const
KDTreeSingleIndexAdaptor< metric_t, self_t, row_major ? MatrixType::ColsAtCompileTime :MatrixType::RowsAtCompileTime, IndexType > index_t
const std::reference_wrapper< const MatrixType > m_data_matrix
KDTreeEigenMatrixAdaptor(const self_t &)=delete
const self_t & derived() const
typename MatrixType::Index IndexType
typename index_t::Dimension Dimension
typename index_t::Offset Offset
~KDTreeEigenMatrixAdaptor()
KDTreeEigenMatrixAdaptor(const Dimension dimensionality, const std::reference_wrapper< const MatrixType > &mat, const int leaf_max_size=10, const unsigned int n_thread_build=1)
Constructor: takes a const ref to the matrix object with the data points.
KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size=10, KDTreeSingleIndexAdaptorFlags _flags=KDTreeSingleIndexAdaptorFlags::None, unsigned int _n_thread_build=1)
unsigned int n_thread_build
KDTreeSingleIndexAdaptorFlags flags
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size, DistanceType worst_dist=-1) const
const DataSource & data_source
DistanceType accum_dist(const U a, const V b, const size_t) const
_DistanceType DistanceType
L1_Adaptor(const DataSource &_data_source)
_DistanceType DistanceType
DistanceType accum_dist(const U a, const V b, const size_t) const
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size, DistanceType worst_dist=-1) const
L2_Adaptor(const DataSource &_data_source)
const DataSource & data_source
const DataSource & data_source
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
DistanceType accum_dist(const U a, const V b, const size_t) const
L2_Simple_Adaptor(const DataSource &_data_source)
_DistanceType DistanceType
DistanceType second
Distance from sample to query point.
ResultItem(const IndexType index, const DistanceType distance)
IndexType first
Index of the sample in the dataset.
const DataSource & data_source
_DistanceType DistanceType
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
SO2_Adaptor(const DataSource &_data_source)
DistanceType accum_dist(const U a, const V b, const size_t) const
_DistanceType DistanceType
L2_Simple_Adaptor< T, DataSource, DistanceType, IndexType > distance_L2_Simple
DistanceType evalMetric(const T *a, const IndexType b_idx, size_t size) const
SO3_Adaptor(const DataSource &_data_source)
DistanceType accum_dist(const U a, const V b, const size_t idx) const
SearchParameters(float eps_=0, bool sorted_=true)
bool sorted
distance (default: true)
float eps
search for eps-approximate neighbours (default: 0)
std::array< T, DIM > type
L1_Adaptor< T, DataSource, T, IndexType > distance_t
L2_Adaptor< T, DataSource, T, IndexType > distance_t
L2_Simple_Adaptor< T, DataSource, T, IndexType > distance_t
SO2_Adaptor< T, DataSource, T, IndexType > distance_t
SO3_Adaptor< T, DataSource, T, IndexType > distance_t