1 /***********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
5 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
6 * Copyright 2011-2016  Jose Luis Blanco (joseluisblancoc@gmail.com).
7 *   All rights reserved.
8 *
9 * THE BSD LICENSE
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *************************************************************************/
32 
33 /** \mainpage nanoflann C++ API documentation
34 *  nanoflann is a C++ header-only library for building KD-Trees, mostly
35 *  optimized for 2D or 3D point clouds.
36 *
37 *  nanoflann does not require compiling or installing, just an
38 *  #include <nanoflann.hpp> in your code.
39 *
40 *  See:
41 *   - <a href="modules.html" >C++ API organized by modules</a>
42 *   - <a href="https://github.com/jlblancoc/nanoflann" >Online README</a>
43 *   - <a href="http://jlblancoc.github.io/nanoflann/" >Doxygen
44 * documentation</a>
45 */
46 
47 #ifndef NANOFLANN_HPP_
48 #define NANOFLANN_HPP_
49 
50 #include <algorithm>
51 #include <array>
52 #include <cassert>
53 #include <cmath>   // for abs()
54 #include <cstdio>  // for fwrite()
55 #include <cstdlib> // for abs()
56 #include <functional>
57 #include <limits> // std::reference_wrapper
58 #include <stdexcept>
59 #include <vector>
60 
61 /** Library version: 0xMmP (M=Major,m=minor,P=patch) */
62 #define NANOFLANN_VERSION 0x130
63 
64 // Avoid conflicting declaration of min/max macros in windows headers
65 #if !defined(NOMINMAX) &&                                                      \
66     (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
67 #define NOMINMAX
68 #ifdef max
69 #undef max
70 #undef min
71 #endif
72 #endif
73 
74 namespace nanoflann {
75 	/** @addtogroup nanoflann_grp nanoflann C++ library for ANN
76 	*  @{ */
77 
78 	/** the PI constant (required to avoid MSVC missing symbols) */
pi_const()79 	template <typename T> T pi_const() {
80 		return static_cast<T>(3.14159265358979323846);
81 	}
82 
83 	/**
84 	* Traits if object is resizable and assignable (typically has a resize | assign
85 	* method)
86 	*/
87 	template <typename T, typename = int> struct has_resize : std::false_type {};
88 
89 	template <typename T>
90 	struct has_resize<T, decltype((void)std::declval<T>().resize(1), 0)>
91 		: std::true_type {};
92 
93 	template <typename T, typename = int> struct has_assign : std::false_type {};
94 
95 	template <typename T>
96 	struct has_assign<T, decltype((void)std::declval<T>().assign(1, 0), 0)>
97 		: std::true_type {};
98 
99 	/**
100 	* Free function to resize a resizable object
101 	*/
102 	template <typename Container>
103 	inline typename std::enable_if<has_resize<Container>::value, void>::type
resize(Container & c,const size_t nElements)104 		resize(Container &c, const size_t nElements) {
105 		c.resize(nElements);
106 	}
107 
108 	/**
109 	* Free function that has no effects on non resizable containers (e.g.
110 	* std::array) It raises an exception if the expected size does not match
111 	*/
112 	template <typename Container>
113 	inline typename std::enable_if<!has_resize<Container>::value, void>::type
resize(Container & c,const size_t nElements)114 		resize(Container &c, const size_t nElements) {
115 		if (nElements != c.size())
116 			throw std::logic_error("Try to change the size of a std::array.");
117 	}
118 
119 	/**
120 	* Free function to assign to a container
121 	*/
122 	template <typename Container, typename T>
123 	inline typename std::enable_if<has_assign<Container>::value, void>::type
assign(Container & c,const size_t nElements,const T & value)124 		assign(Container &c, const size_t nElements, const T &value) {
125 		c.assign(nElements, value);
126 	}
127 
128 	/**
129 	* Free function to assign to a std::array
130 	*/
131 	template <typename Container, typename T>
132 	inline typename std::enable_if<!has_assign<Container>::value, void>::type
assign(Container & c,const size_t nElements,const T & value)133 		assign(Container &c, const size_t nElements, const T &value) {
134 		for (size_t i = 0; i < nElements; i++)
135 			c[i] = value;
136 	}
137 
138 	/** @addtogroup result_sets_grp Result set classes
139 	*  @{ */
140 	template <typename _DistanceType, typename _IndexType = size_t,
141 		typename _CountType = size_t>
142 		class KNNResultSet {
143 		public:
144 			typedef _DistanceType DistanceType;
145 			typedef _IndexType IndexType;
146 			typedef _CountType CountType;
147 
148 		private:
149 			IndexType *indices;
150 			DistanceType *dists;
151 			CountType capacity;
152 			CountType count;
153 
154 		public:
KNNResultSet(CountType capacity_)155 			inline KNNResultSet(CountType capacity_)
156 				: indices(0), dists(0), capacity(capacity_), count(0) {}
157 
init(IndexType * indices_,DistanceType * dists_)158 			inline void init(IndexType *indices_, DistanceType *dists_) {
159 				indices = indices_;
160 				dists = dists_;
161 				count = 0;
162 				if (capacity)
163 					dists[capacity - 1] = (std::numeric_limits<DistanceType>::max)();
164 			}
165 
size() const166 			inline CountType size() const { return count; }
167 
full() const168 			inline bool full() const { return count == capacity; }
169 
170 			/**
171 			* Called during search to add an element matching the criteria.
172 			* @return true if the search should be continued, false if the results are
173 			* sufficient
174 			*/
addPoint(DistanceType dist,IndexType index)175 			inline bool addPoint(DistanceType dist, IndexType index) {
176 				CountType i;
177 				for (i = count; i > 0; --i) {
178 					#ifdef NANOFLANN_FIRST_MATCH // If defined and two points have the same
179 					// distance, the one with the lowest-index will be
180 					// returned first.
181 					if ((dists[i - 1] > dist) ||
182 						((dist == dists[i - 1]) && (indices[i - 1] > index))) {
183 						#else
184 					if (dists[i - 1] > dist) {
185 						#endif
186 						if (i < capacity) {
187 							dists[i] = dists[i - 1];
188 							indices[i] = indices[i - 1];
189 						}
190 					} else
191 						break;
192 					}
193 				if (i < capacity) {
194 					dists[i] = dist;
195 					indices[i] = index;
196 				}
197 				if (count < capacity)
198 					count++;
199 
200 				// tell caller that the search shall continue
201 				return true;
202 				}
203 
204 			inline DistanceType worstDist() const { return dists[capacity - 1]; }
205 			};
206 
207 	/** operator "<" for std::sort() */
208 	struct IndexDist_Sorter {
209 		/** PairType will be typically: std::pair<IndexType,DistanceType> */
210 		template <typename PairType>
operator ()nanoflann::IndexDist_Sorter211 		inline bool operator()(const PairType &p1, const PairType &p2) const {
212 			return p1.second < p2.second;
213 		}
214 	};
215 
216 	/**
217 	* A result-set class used when performing a radius based search.
218 	*/
219 	template <typename _DistanceType, typename _IndexType = size_t>
220 	class RadiusResultSet {
221 	public:
222 		typedef _DistanceType DistanceType;
223 		typedef _IndexType IndexType;
224 
225 	public:
226 		const DistanceType radius;
227 
228 		std::vector<std::pair<IndexType, DistanceType>> &m_indices_dists;
229 
RadiusResultSet(DistanceType radius_,std::vector<std::pair<IndexType,DistanceType>> & indices_dists)230 		inline RadiusResultSet(
231 			DistanceType radius_,
232 			std::vector<std::pair<IndexType, DistanceType>> &indices_dists)
233 			: radius(radius_), m_indices_dists(indices_dists) {
234 			init();
235 		}
236 
init()237 		inline void init() { clear(); }
clear()238 		inline void clear() { m_indices_dists.clear(); }
239 
size() const240 		inline size_t size() const { return m_indices_dists.size(); }
241 
full() const242 		inline bool full() const { return true; }
243 
244 		/**
245 		* Called during search to add an element matching the criteria.
246 		* @return true if the search should be continued, false if the results are
247 		* sufficient
248 		*/
addPoint(DistanceType dist,IndexType index)249 		inline bool addPoint(DistanceType dist, IndexType index) {
250 			if (dist < radius)
251 				m_indices_dists.push_back(std::make_pair(index, dist));
252 			return true;
253 		}
254 
worstDist() const255 		inline DistanceType worstDist() const { return radius; }
256 
257 		/**
258 		* Find the worst result (furtherest neighbor) without copying or sorting
259 		* Pre-conditions: size() > 0
260 		*/
worst_item() const261 		std::pair<IndexType, DistanceType> worst_item() const {
262 			if (m_indices_dists.empty())
263 				throw std::runtime_error("Cannot invoke RadiusResultSet::worst_item() on "
264 					"an empty list of results.");
265 			typedef
266 				typename std::vector<std::pair<IndexType, DistanceType>>::const_iterator
267 				DistIt;
268 			DistIt it = std::max_element(m_indices_dists.begin(), m_indices_dists.end(),
269 				IndexDist_Sorter());
270 			return *it;
271 		}
272 	};
273 
274 	/** @} */
275 
276 	/** @addtogroup loadsave_grp Load/save auxiliary functions
277 	* @{ */
278 	template <typename T>
save_value(FILE * stream,const T & value,size_t count=1)279 	void save_value(FILE *stream, const T &value, size_t count = 1) {
280 		fwrite(&value, sizeof(value), count, stream);
281 	}
282 
283 	template <typename T>
save_value(FILE * stream,const std::vector<T> & value)284 	void save_value(FILE *stream, const std::vector<T> &value) {
285 		size_t size = value.size();
286 		fwrite(&size, sizeof(size_t), 1, stream);
287 		fwrite(&value[0], sizeof(T), size, stream);
288 	}
289 
290 	template <typename T>
load_value(FILE * stream,T & value,size_t count=1)291 	void load_value(FILE *stream, T &value, size_t count = 1) {
292 		size_t read_cnt = fread(&value, sizeof(value), count, stream);
293 		if (read_cnt != count) {
294 			throw std::runtime_error("Cannot read from file");
295 		}
296 	}
297 
load_value(FILE * stream,std::vector<T> & value)298 	template <typename T> void load_value(FILE *stream, std::vector<T> &value) {
299 		size_t size;
300 		size_t read_cnt = fread(&size, sizeof(size_t), 1, stream);
301 		if (read_cnt != 1) {
302 			throw std::runtime_error("Cannot read from file");
303 		}
304 		value.resize(size);
305 		read_cnt = fread(&value[0], sizeof(T), size, stream);
306 		if (read_cnt != size) {
307 			throw std::runtime_error("Cannot read from file");
308 		}
309 	}
310 	/** @} */
311 
312 	/** @addtogroup metric_grp Metric (distance) classes
313 	* @{ */
314 
315 	struct Metric {};
316 
317 	/** Manhattan distance functor (generic version, optimized for
318 	* high-dimensionality data sets). Corresponding distance traits:
319 	* nanoflann::metric_L1 \tparam T Type of the elements (e.g. double, float,
320 	* uint8_t) \tparam _DistanceType Type of distance variables (must be signed)
321 	* (e.g. float, double, int64_t)
322 	*/
323 	template <class T, class DataSource, typename _DistanceType = T>
324 	struct L1_Adaptor {
325 		typedef T ElementType;
326 		typedef _DistanceType DistanceType;
327 
328 		const DataSource &data_source;
329 
L1_Adaptornanoflann::L1_Adaptor330 		L1_Adaptor(const DataSource &_data_source) : data_source(_data_source) {}
331 
evalMetricnanoflann::L1_Adaptor332 		inline DistanceType evalMetric(const T *a, const size_t b_idx, size_t size,
333 			DistanceType worst_dist = -1) const {
334 			DistanceType result = DistanceType();
335 			const T *last = a + size;
336 			const T *lastgroup = last - 3;
337 			size_t d = 0;
338 
339 			/* Process 4 items with each loop for efficiency. */
340 			while (a < lastgroup) {
341 				const DistanceType diff0 =
342 					std::abs(a[0] - data_source.kdtree_get_pt(b_idx, d++));
343 				const DistanceType diff1 =
344 					std::abs(a[1] - data_source.kdtree_get_pt(b_idx, d++));
345 				const DistanceType diff2 =
346 					std::abs(a[2] - data_source.kdtree_get_pt(b_idx, d++));
347 				const DistanceType diff3 =
348 					std::abs(a[3] - data_source.kdtree_get_pt(b_idx, d++));
349 				result += diff0 + diff1 + diff2 + diff3;
350 				a += 4;
351 				if ((worst_dist > 0) && (result > worst_dist)) {
352 					return result;
353 				}
354 			}
355 			/* Process last 0-3 components.  Not needed for standard vector lengths. */
356 			while (a < last) {
357 				result += std::abs(*a++ - data_source.kdtree_get_pt(b_idx, d++));
358 			}
359 			return result;
360 		}
361 
362 		template <typename U, typename V>
accum_distnanoflann::L1_Adaptor363 		inline DistanceType accum_dist(const U a, const V b, const size_t) const {
364 			return std::abs(a - b);
365 		}
366 	};
367 
368 	/** Squared Euclidean distance functor (generic version, optimized for
369 	* high-dimensionality data sets). Corresponding distance traits:
370 	* nanoflann::metric_L2 \tparam T Type of the elements (e.g. double, float,
371 	* uint8_t) \tparam _DistanceType Type of distance variables (must be signed)
372 	* (e.g. float, double, int64_t)
373 	*/
374 	template <class T, class DataSource, typename _DistanceType = T>
375 	struct L2_Adaptor {
376 		typedef T ElementType;
377 		typedef _DistanceType DistanceType;
378 
379 		const DataSource &data_source;
380 
L2_Adaptornanoflann::L2_Adaptor381 		L2_Adaptor(const DataSource &_data_source) : data_source(_data_source) {}
382 
evalMetricnanoflann::L2_Adaptor383 		inline DistanceType evalMetric(const T *a, const size_t b_idx, size_t size,
384 			DistanceType worst_dist = -1) const {
385 			DistanceType result = DistanceType();
386 			const T *last = a + size;
387 			const T *lastgroup = last - 3;
388 			size_t d = 0;
389 
390 			/* Process 4 items with each loop for efficiency. */
391 			while (a < lastgroup) {
392 				const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx, d++);
393 				const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx, d++);
394 				const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx, d++);
395 				const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx, d++);
396 				result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
397 				a += 4;
398 				if ((worst_dist > 0) && (result > worst_dist)) {
399 					return result;
400 				}
401 			}
402 			/* Process last 0-3 components.  Not needed for standard vector lengths. */
403 			while (a < last) {
404 				const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx, d++);
405 				result += diff0 * diff0;
406 			}
407 			return result;
408 		}
409 
410 		template <typename U, typename V>
accum_distnanoflann::L2_Adaptor411 		inline DistanceType accum_dist(const U a, const V b, const size_t) const {
412 			return (a - b) * (a - b);
413 		}
414 	};
415 
416 	/** Squared Euclidean (L2) distance functor (suitable for low-dimensionality
417 	* datasets, like 2D or 3D point clouds) Corresponding distance traits:
418 	* nanoflann::metric_L2_Simple \tparam T Type of the elements (e.g. double,
419 	* float, uint8_t) \tparam _DistanceType Type of distance variables (must be
420 	* signed) (e.g. float, double, int64_t)
421 	*/
422 	template <class T, class DataSource, typename _DistanceType = T>
423 	struct L2_Simple_Adaptor {
424 		typedef T ElementType;
425 		typedef _DistanceType DistanceType;
426 
427 		const DataSource &data_source;
428 
L2_Simple_Adaptornanoflann::L2_Simple_Adaptor429 		L2_Simple_Adaptor(const DataSource &_data_source)
430 			: data_source(_data_source) {}
431 
evalMetricnanoflann::L2_Simple_Adaptor432 		inline DistanceType evalMetric(const T *a, const size_t b_idx,
433 			size_t size) const {
434 			DistanceType result = DistanceType();
435 			for (size_t i = 0; i < size; ++i) {
436 				const DistanceType diff = a[i] - data_source.kdtree_get_pt(b_idx, i);
437 				result += diff * diff;
438 			}
439 			return result;
440 		}
441 
442 		template <typename U, typename V>
accum_distnanoflann::L2_Simple_Adaptor443 		inline DistanceType accum_dist(const U a, const V b, const size_t) const {
444 			return (a - b) * (a - b);
445 		}
446 	};
447 
448 	/** SO2 distance functor
449 	*  Corresponding distance traits: nanoflann::metric_SO2
450 	* \tparam T Type of the elements (e.g. double, float)
451 	* \tparam _DistanceType Type of distance variables (must be signed) (e.g.
452 	* float, double) orientation is constrained to be in [-pi, pi]
453 	*/
454 	template <class T, class DataSource, typename _DistanceType = T>
455 	struct SO2_Adaptor {
456 		typedef T ElementType;
457 		typedef _DistanceType DistanceType;
458 
459 		const DataSource &data_source;
460 
SO2_Adaptornanoflann::SO2_Adaptor461 		SO2_Adaptor(const DataSource &_data_source) : data_source(_data_source) {}
462 
evalMetricnanoflann::SO2_Adaptor463 		inline DistanceType evalMetric(const T *a, const size_t b_idx,
464 			size_t size) const {
465 			return accum_dist(a[size - 1], data_source.kdtree_get_pt(b_idx, size - 1),
466 				size - 1);
467 		}
468 
469 		/** Note: this assumes that input angles are already in the range [-pi,pi] */
470 		template <typename U, typename V>
accum_distnanoflann::SO2_Adaptor471 		inline DistanceType accum_dist(const U a, const V b, const size_t) const {
472 			DistanceType result = DistanceType(), PI = pi_const<DistanceType>();
473 			result = b - a;
474 			if (result > PI)
475 				result -= 2 * PI;
476 			else if (result < -PI)
477 				result += 2 * PI;
478 			return result;
479 		}
480 	};
481 
482 	/** SO3 distance functor (Uses L2_Simple)
483 	*  Corresponding distance traits: nanoflann::metric_SO3
484 	* \tparam T Type of the elements (e.g. double, float)
485 	* \tparam _DistanceType Type of distance variables (must be signed) (e.g.
486 	* float, double)
487 	*/
488 	template <class T, class DataSource, typename _DistanceType = T>
489 	struct SO3_Adaptor {
490 		typedef T ElementType;
491 		typedef _DistanceType DistanceType;
492 
493 		L2_Simple_Adaptor<T, DataSource> distance_L2_Simple;
494 
SO3_Adaptornanoflann::SO3_Adaptor495 		SO3_Adaptor(const DataSource &_data_source)
496 			: distance_L2_Simple(_data_source) {}
497 
evalMetricnanoflann::SO3_Adaptor498 		inline DistanceType evalMetric(const T *a, const size_t b_idx,
499 			size_t size) const {
500 			return distance_L2_Simple.evalMetric(a, b_idx, size);
501 		}
502 
503 		template <typename U, typename V>
accum_distnanoflann::SO3_Adaptor504 		inline DistanceType accum_dist(const U a, const V b, const size_t idx) const {
505 			return distance_L2_Simple.accum_dist(a, b, idx);
506 		}
507 	};
508 
509 	/** Metaprogramming helper traits class for the L1 (Manhattan) metric */
510 	struct metric_L1 : public Metric {
511 		template <class T, class DataSource> struct traits {
512 			typedef L1_Adaptor<T, DataSource> distance_t;
513 		};
514 	};
515 	/** Metaprogramming helper traits class for the L2 (Euclidean) metric */
516 	struct metric_L2 : public Metric {
517 		template <class T, class DataSource> struct traits {
518 			typedef L2_Adaptor<T, DataSource> distance_t;
519 		};
520 	};
521 	/** Metaprogramming helper traits class for the L2_simple (Euclidean) metric */
522 	struct metric_L2_Simple : public Metric {
523 		template <class T, class DataSource> struct traits {
524 			typedef L2_Simple_Adaptor<T, DataSource> distance_t;
525 		};
526 	};
527 	/** Metaprogramming helper traits class for the SO3_InnerProdQuat metric */
528 	struct metric_SO2 : public Metric {
529 		template <class T, class DataSource> struct traits {
530 			typedef SO2_Adaptor<T, DataSource> distance_t;
531 		};
532 	};
533 	/** Metaprogramming helper traits class for the SO3_InnerProdQuat metric */
534 	struct metric_SO3 : public Metric {
535 		template <class T, class DataSource> struct traits {
536 			typedef SO3_Adaptor<T, DataSource> distance_t;
537 		};
538 	};
539 
540 	/** @} */
541 
542 	/** @addtogroup param_grp Parameter structs
543 	* @{ */
544 
545 	/**  Parameters (see README.md) */
546 	struct KDTreeSingleIndexAdaptorParams {
KDTreeSingleIndexAdaptorParamsnanoflann::KDTreeSingleIndexAdaptorParams547 		KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size = 10)
548 			: leaf_max_size(_leaf_max_size) {}
549 
550 		size_t leaf_max_size;
551 	};
552 
553 	/** Search options for KDTreeSingleIndexAdaptor::findNeighbors() */
554 	struct SearchParams {
555 		/** Note: The first argument (checks_IGNORED_) is ignored, but kept for
556 		* compatibility with the FLANN interface */
SearchParamsnanoflann::SearchParams557 		SearchParams(int checks_IGNORED_ = 32, float eps_ = 0, bool sorted_ = true)
558 			: checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {}
559 
560 		int checks;  //!< Ignored parameter (Kept for compatibility with the FLANN
561 					 //!< interface).
562 		float eps;   //!< search for eps-approximate neighbours (default: 0)
563 		bool sorted; //!< only for radius search, require neighbours sorted by
564 					 //!< distance (default: true)
565 	};
566 	/** @} */
567 
568 	/** @addtogroup memalloc_grp Memory allocation
569 	* @{ */
570 
571 	/**
572 	* Allocates (using C's malloc) a generic type T.
573 	*
574 	* Params:
575 	*     count = number of instances to allocate.
576 	* Returns: pointer (of type T*) to memory buffer
577 	*/
allocate(size_t count=1)578 	template <typename T> inline T *allocate(size_t count = 1) {
579 		T *mem = static_cast<T *>(::malloc(sizeof(T) * count));
580 		return mem;
581 	}
582 
583 	/**
584 	* Pooled storage allocator
585 	*
586 	* The following routines allow for the efficient allocation of storage in
587 	* small chunks from a specified pool.  Rather than allowing each structure
588 	* to be freed individually, an entire pool of storage is freed at once.
589 	* This method has two advantages over just using malloc() and free().  First,
590 	* it is far more efficient for allocating small objects, as there is
591 	* no overhead for remembering all the information needed to free each
592 	* object or consolidating fragmented memory.  Second, the decision about
593 	* how long to keep an object is made at the time of allocation, and there
594 	* is no need to track down all the objects to free them.
595 	*
596 	*/
597 
598 	const size_t WORDSIZE = 16;
599 	const size_t BLOCKSIZE = 8192;
600 
601 	class PooledAllocator {
602 		/* We maintain memory alignment to word boundaries by requiring that all
603 		allocations be in multiples of the machine wordsize.  */
604 		/* Size of machine word in bytes.  Must be power of 2. */
605 		/* Minimum number of bytes requested at a time from	the system.  Must be
606 		* multiple of WORDSIZE. */
607 
608 		size_t remaining; /* Number of bytes left in current block of storage. */
609 		void *base;       /* Pointer to base of current block of storage. */
610 		void *loc;        /* Current location in block to next allocate memory. */
611 
internal_init()612 		void internal_init() {
613 			remaining = 0;
614 			base = NULL;
615 			usedMemory = 0;
616 			wastedMemory = 0;
617 		}
618 
619 	public:
620 		size_t usedMemory;
621 		size_t wastedMemory;
622 
623 		/**
624 		Default constructor. Initializes a new pool.
625 		*/
PooledAllocator()626 		PooledAllocator() { internal_init(); }
627 
628 		/**
629 		* Destructor. Frees all the memory allocated in this pool.
630 		*/
~PooledAllocator()631 		~PooledAllocator() { free_all(); }
632 
633 		/** Frees all allocated memory chunks */
free_all()634 		void free_all() {
635 			while (base != NULL) {
636 				void *prev =
637 					*(static_cast<void **>(base)); /* Get pointer to prev block. */
638 				::free(base);
639 				base = prev;
640 			}
641 			internal_init();
642 		}
643 
644 		/**
645 		* Returns a pointer to a piece of new memory of the given size in bytes
646 		* allocated from the pool.
647 		*/
malloc(const size_t req_size)648 		void *malloc(const size_t req_size) {
649 			/* Round size up to a multiple of wordsize.  The following expression
650 			only works for WORDSIZE that is a power of 2, by masking last bits of
651 			incremented size to zero.
652 			*/
653 			const size_t size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
654 
655 			/* Check whether a new block must be allocated.  Note that the first word
656 			of a block is reserved for a pointer to the previous block.
657 			*/
658 			if (size > remaining) {
659 
660 				wastedMemory += remaining;
661 
662 				/* Allocate new storage. */
663 				const size_t blocksize =
664 					(size + sizeof(void *) + (WORDSIZE - 1) > BLOCKSIZE)
665 					? size + sizeof(void *) + (WORDSIZE - 1)
666 					: BLOCKSIZE;
667 
668 				// use the standard C malloc to allocate memory
669 				void *m = ::malloc(blocksize);
670 				if (!m) {
671 					fprintf(stderr, "Failed to allocate memory.\n");
672 					return NULL;
673 				}
674 
675 				/* Fill first word of new block with pointer to previous block. */
676 				static_cast<void **>(m)[0] = base;
677 				base = m;
678 
679 				size_t shift = 0;
680 				// int size_t = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) &
681 				// (WORDSIZE-1))) & (WORDSIZE-1);
682 
683 				remaining = blocksize - sizeof(void *) - shift;
684 				loc = (static_cast<char *>(m) + sizeof(void *) + shift);
685 			}
686 			void *rloc = loc;
687 			loc = static_cast<char *>(loc) + size;
688 			remaining -= size;
689 
690 			usedMemory += size;
691 
692 			return rloc;
693 		}
694 
695 		/**
696 		* Allocates (using this pool) a generic type T.
697 		*
698 		* Params:
699 		*     count = number of instances to allocate.
700 		* Returns: pointer (of type T*) to memory buffer
701 		*/
allocate(const size_t count=1)702 		template <typename T> T *allocate(const size_t count = 1) {
703 			T *mem = static_cast<T *>(this->malloc(sizeof(T) * count));
704 			return mem;
705 		}
706 	};
707 	/** @} */
708 
709 	/** @addtogroup nanoflann_metaprog_grp Auxiliary metaprogramming stuff
710 	* @{ */
711 
712 	/** Used to declare fixed-size arrays when DIM>0, dynamically-allocated vectors
713 	* when DIM=-1. Fixed size version for a generic DIM:
714 	*/
715 	template <int DIM, typename T> struct array_or_vector_selector {
716 		typedef std::array<T, DIM> container_t;
717 	};
718 	/** Dynamic size version */
719 	template <typename T> struct array_or_vector_selector<-1, T> {
720 		typedef std::vector<T> container_t;
721 	};
722 
723 	/** @} */
724 
725 	/** kd-tree base-class
726 	*
727 	* Contains the member functions common to the classes KDTreeSingleIndexAdaptor
728 	* and KDTreeSingleIndexDynamicAdaptor_.
729 	*
730 	* \tparam Derived The name of the class which inherits this class.
731 	* \tparam DatasetAdaptor The user-provided adaptor (see comments above).
732 	* \tparam Distance The distance metric to use, these are all classes derived
733 	* from nanoflann::Metric \tparam DIM Dimensionality of data points (e.g. 3 for
734 	* 3D points) \tparam IndexType Will be typically size_t or int
735 	*/
736 
737 	template <class Derived, typename Distance, class DatasetAdaptor, int DIM = -1,
738 		typename IndexType = size_t>
739 		class KDTreeBaseClass {
740 
741 		public:
742 			/** Frees the previously-built index. Automatically called within
743 			* buildIndex(). */
freeIndex(Derived & obj)744 			void freeIndex(Derived &obj) {
745 				obj.pool.free_all();
746 				obj.root_node = NULL;
747 				obj.m_size_at_index_build = 0;
748 			}
749 
750 			typedef typename Distance::ElementType ElementType;
751 			typedef typename Distance::DistanceType DistanceType;
752 
753 			/*--------------------- Internal Data Structures --------------------------*/
754 			struct Node {
755 				/** Union used because a node can be either a LEAF node or a non-leaf node,
756 				* so both data fields are never used simultaneously */
757 				union {
758 					struct leaf {
759 						IndexType left, right; //!< Indices of points in leaf node
760 					} lr;
761 					struct nonleaf {
762 						int divfeat;                  //!< Dimension used for subdivision.
763 						DistanceType divlow, divhigh; //!< The values used for subdivision.
764 					} sub;
765 				} node_type;
766 				Node *child1, *child2; //!< Child nodes (both=NULL mean its a leaf node)
767 			};
768 
769 			typedef Node *NodePtr;
770 
771 			struct Interval {
772 				ElementType low, high;
773 			};
774 
775 			/**
776 			*  Array of indices to vectors in the dataset.
777 			*/
778 			std::vector<IndexType> vind;
779 
780 			NodePtr root_node;
781 
782 			size_t m_leaf_max_size;
783 
784 			size_t m_size;                //!< Number of current points in the dataset
785 			size_t m_size_at_index_build; //!< Number of points in the dataset when the
786 										  //!< index was built
787 			int dim;                      //!< Dimensionality of each data point
788 
789 										  /** Define "BoundingBox" as a fixed-size or variable-size container depending
790 										  * on "DIM" */
791 			typedef
792 				typename array_or_vector_selector<DIM, Interval>::container_t BoundingBox;
793 
794 			/** Define "distance_vector_t" as a fixed-size or variable-size container
795 			* depending on "DIM" */
796 			typedef typename array_or_vector_selector<DIM, DistanceType>::container_t
797 				distance_vector_t;
798 
799 			/** The KD-tree used to find neighbours */
800 
801 			BoundingBox root_bbox;
802 
803 			/**
804 			* Pooled memory allocator.
805 			*
806 			* Using a pooled memory allocator is more efficient
807 			* than allocating memory directly when there is a large
808 			* number small of memory allocations.
809 			*/
810 			PooledAllocator pool;
811 
812 			/** Returns number of points in dataset  */
size(const Derived & obj) const813 			size_t size(const Derived &obj) const { return obj.m_size; }
814 
815 			/** Returns the length of each point in the dataset */
veclen(const Derived & obj)816 			size_t veclen(const Derived &obj) {
817 				return static_cast<size_t>(DIM > 0 ? DIM : obj.dim);
818 			}
819 
820 			/// Helper accessor to the dataset points:
dataset_get(const Derived & obj,size_t idx,int component) const821 			inline ElementType dataset_get(const Derived &obj, size_t idx,
822 				int component) const {
823 				return obj.dataset.kdtree_get_pt(idx, component);
824 			}
825 
826 			/**
827 			* Computes the inde memory usage
828 			* Returns: memory used by the index
829 			*/
usedMemory(Derived & obj)830 			size_t usedMemory(Derived &obj) {
831 				return obj.pool.usedMemory + obj.pool.wastedMemory +
832 					obj.dataset.kdtree_get_point_count() *
833 					sizeof(IndexType); // pool memory and vind array memory
834 			}
835 
computeMinMax(const Derived & obj,IndexType * ind,IndexType count,int element,ElementType & min_elem,ElementType & max_elem)836 			void computeMinMax(const Derived &obj, IndexType *ind, IndexType count,
837 				int element, ElementType &min_elem,
838 				ElementType &max_elem) {
839 				min_elem = dataset_get(obj, ind[0], element);
840 				max_elem = dataset_get(obj, ind[0], element);
841 				for (IndexType i = 1; i < count; ++i) {
842 					ElementType val = dataset_get(obj, ind[i], element);
843 					if (val < min_elem)
844 						min_elem = val;
845 					if (val > max_elem)
846 						max_elem = val;
847 				}
848 			}
849 
850 			/**
851 			* Create a tree node that subdivides the list of vecs from vind[first]
852 			* to vind[last].  The routine is called recursively on each sublist.
853 			*
854 			* @param left index of the first vector
855 			* @param right index of the last vector
856 			*/
divideTree(Derived & obj,const IndexType left,const IndexType right,BoundingBox & bbox)857 			NodePtr divideTree(Derived &obj, const IndexType left, const IndexType right,
858 				BoundingBox &bbox) {
859 				NodePtr node = obj.pool.template allocate<Node>(); // allocate memory
860 
861 																   /* If too few exemplars remain, then make this a leaf node. */
862 				if ((right - left) <= static_cast<IndexType>(obj.m_leaf_max_size)) {
863 					node->child1 = node->child2 = NULL; /* Mark as leaf node. */
864 					node->node_type.lr.left = left;
865 					node->node_type.lr.right = right;
866 
867 					// compute bounding-box of leaf points
868 					for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
869 						bbox[i].low = dataset_get(obj, obj.vind[left], i);
870 						bbox[i].high = dataset_get(obj, obj.vind[left], i);
871 					}
872 					for (IndexType k = left + 1; k < right; ++k) {
873 						for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
874 							if (bbox[i].low > dataset_get(obj, obj.vind[k], i))
875 								bbox[i].low = dataset_get(obj, obj.vind[k], i);
876 							if (bbox[i].high < dataset_get(obj, obj.vind[k], i))
877 								bbox[i].high = dataset_get(obj, obj.vind[k], i);
878 						}
879 					}
880 				} else {
881 					IndexType idx;
882 					int cutfeat;
883 					DistanceType cutval;
884 					middleSplit_(obj, &obj.vind[0] + left, right - left, idx, cutfeat, cutval,
885 						bbox);
886 
887 					node->node_type.sub.divfeat = cutfeat;
888 
889 					BoundingBox left_bbox(bbox);
890 					left_bbox[cutfeat].high = cutval;
891 					node->child1 = divideTree(obj, left, left + idx, left_bbox);
892 
893 					BoundingBox right_bbox(bbox);
894 					right_bbox[cutfeat].low = cutval;
895 					node->child2 = divideTree(obj, left + idx, right, right_bbox);
896 
897 					node->node_type.sub.divlow = left_bbox[cutfeat].high;
898 					node->node_type.sub.divhigh = right_bbox[cutfeat].low;
899 
900 					for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
901 						bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
902 						bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
903 					}
904 				}
905 
906 				return node;
907 			}
908 
middleSplit_(Derived & obj,IndexType * ind,IndexType count,IndexType & index,int & cutfeat,DistanceType & cutval,const BoundingBox & bbox)909 			void middleSplit_(Derived &obj, IndexType *ind, IndexType count,
910 				IndexType &index, int &cutfeat, DistanceType &cutval,
911 				const BoundingBox &bbox) {
912 				const DistanceType EPS = static_cast<DistanceType>(0.00001);
913 				ElementType max_span = bbox[0].high - bbox[0].low;
914 				for (int i = 1; i < (DIM > 0 ? DIM : obj.dim); ++i) {
915 					ElementType span = bbox[i].high - bbox[i].low;
916 					if (span > max_span) {
917 						max_span = span;
918 					}
919 				}
920 				ElementType max_spread = -1;
921 				cutfeat = 0;
922 				for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
923 					ElementType span = bbox[i].high - bbox[i].low;
924 					if (span > (1 - EPS) * max_span) {
925 						ElementType min_elem, max_elem;
926 						computeMinMax(obj, ind, count, i, min_elem, max_elem);
927 						ElementType spread = max_elem - min_elem;
928 						;
929 						if (spread > max_spread) {
930 							cutfeat = i;
931 							max_spread = spread;
932 						}
933 					}
934 				}
935 				// split in the middle
936 				DistanceType split_val = (bbox[cutfeat].low + bbox[cutfeat].high) / 2;
937 				ElementType min_elem, max_elem;
938 				computeMinMax(obj, ind, count, cutfeat, min_elem, max_elem);
939 
940 				if (split_val < min_elem)
941 					cutval = min_elem;
942 				else if (split_val > max_elem)
943 					cutval = max_elem;
944 				else
945 					cutval = split_val;
946 
947 				IndexType lim1, lim2;
948 				planeSplit(obj, ind, count, cutfeat, cutval, lim1, lim2);
949 
950 				if (lim1 > count / 2)
951 					index = lim1;
952 				else if (lim2 < count / 2)
953 					index = lim2;
954 				else
955 					index = count / 2;
956 			}
957 
958 			/**
959 			*  Subdivide the list of points by a plane perpendicular on axe corresponding
960 			*  to the 'cutfeat' dimension at 'cutval' position.
961 			*
962 			*  On return:
963 			*  dataset[ind[0..lim1-1]][cutfeat]<cutval
964 			*  dataset[ind[lim1..lim2-1]][cutfeat]==cutval
965 			*  dataset[ind[lim2..count]][cutfeat]>cutval
966 			*/
planeSplit(Derived & obj,IndexType * ind,const IndexType count,int cutfeat,DistanceType & cutval,IndexType & lim1,IndexType & lim2)967 			void planeSplit(Derived &obj, IndexType *ind, const IndexType count,
968 				int cutfeat, DistanceType &cutval, IndexType &lim1,
969 				IndexType &lim2) {
970 				/* Move vector indices for left subtree to front of list. */
971 				IndexType left = 0;
972 				IndexType right = count - 1;
973 				for (;;) {
974 					while (left <= right && dataset_get(obj, ind[left], cutfeat) < cutval)
975 						++left;
976 					while (right && left <= right &&
977 						dataset_get(obj, ind[right], cutfeat) >= cutval)
978 						--right;
979 					if (left > right || !right)
980 						break; // "!right" was added to support unsigned Index types
981 					std::swap(ind[left], ind[right]);
982 					++left;
983 					--right;
984 				}
985 				/* If either list is empty, it means that all remaining features
986 				* are identical. Split in the middle to maintain a balanced tree.
987 				*/
988 				lim1 = left;
989 				right = count - 1;
990 				for (;;) {
991 					while (left <= right && dataset_get(obj, ind[left], cutfeat) <= cutval)
992 						++left;
993 					while (right && left <= right &&
994 						dataset_get(obj, ind[right], cutfeat) > cutval)
995 						--right;
996 					if (left > right || !right)
997 						break; // "!right" was added to support unsigned Index types
998 					std::swap(ind[left], ind[right]);
999 					++left;
1000 					--right;
1001 				}
1002 				lim2 = left;
1003 			}
1004 
computeInitialDistances(const Derived & obj,const ElementType * vec,distance_vector_t & dists) const1005 			DistanceType computeInitialDistances(const Derived &obj,
1006 				const ElementType *vec,
1007 				distance_vector_t &dists) const {
1008 				assert(vec);
1009 				DistanceType distsq = DistanceType();
1010 
1011 				for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
1012 					if (vec[i] < obj.root_bbox[i].low) {
1013 						dists[i] = obj.distance.accum_dist(vec[i], obj.root_bbox[i].low, i);
1014 						distsq += dists[i];
1015 					}
1016 					if (vec[i] > obj.root_bbox[i].high) {
1017 						dists[i] = obj.distance.accum_dist(vec[i], obj.root_bbox[i].high, i);
1018 						distsq += dists[i];
1019 					}
1020 				}
1021 				return distsq;
1022 			}
1023 
save_tree(Derived & obj,FILE * stream,NodePtr tree)1024 			void save_tree(Derived &obj, FILE *stream, NodePtr tree) {
1025 				save_value(stream, *tree);
1026 				if (tree->child1 != NULL) {
1027 					save_tree(obj, stream, tree->child1);
1028 				}
1029 				if (tree->child2 != NULL) {
1030 					save_tree(obj, stream, tree->child2);
1031 				}
1032 			}
1033 
load_tree(Derived & obj,FILE * stream,NodePtr & tree)1034 			void load_tree(Derived &obj, FILE *stream, NodePtr &tree) {
1035 				tree = obj.pool.template allocate<Node>();
1036 				load_value(stream, *tree);
1037 				if (tree->child1 != NULL) {
1038 					load_tree(obj, stream, tree->child1);
1039 				}
1040 				if (tree->child2 != NULL) {
1041 					load_tree(obj, stream, tree->child2);
1042 				}
1043 			}
1044 
1045 			/**  Stores the index in a binary file.
1046 			*   IMPORTANT NOTE: The set of data points is NOT stored in the file, so when
1047 			* loading the index object it must be constructed associated to the same
1048 			* source of data points used while building it. See the example:
1049 			* examples/saveload_example.cpp \sa loadIndex  */
saveIndex_(Derived & obj,FILE * stream)1050 			void saveIndex_(Derived &obj, FILE *stream) {
1051 				save_value(stream, obj.m_size);
1052 				save_value(stream, obj.dim);
1053 				save_value(stream, obj.root_bbox);
1054 				save_value(stream, obj.m_leaf_max_size);
1055 				save_value(stream, obj.vind);
1056 				save_tree(obj, stream, obj.root_node);
1057 			}
1058 
1059 			/**  Loads a previous index from a binary file.
1060 			*   IMPORTANT NOTE: The set of data points is NOT stored in the file, so the
1061 			* index object must be constructed associated to the same source of data
1062 			* points used while building the index. See the example:
1063 			* examples/saveload_example.cpp \sa loadIndex  */
loadIndex_(Derived & obj,FILE * stream)1064 			void loadIndex_(Derived &obj, FILE *stream) {
1065 				load_value(stream, obj.m_size);
1066 				load_value(stream, obj.dim);
1067 				load_value(stream, obj.root_bbox);
1068 				load_value(stream, obj.m_leaf_max_size);
1069 				load_value(stream, obj.vind);
1070 				load_tree(obj, stream, obj.root_node);
1071 			}
1072 	};
1073 
1074 	/** @addtogroup kdtrees_grp KD-tree classes and adaptors
1075 	* @{ */
1076 
1077 	/** kd-tree static index
1078 	*
1079 	* Contains the k-d trees and other information for indexing a set of points
1080 	* for nearest-neighbor matching.
1081 	*
1082 	*  The class "DatasetAdaptor" must provide the following interface (can be
1083 	* non-virtual, inlined methods):
1084 	*
1085 	*  \code
1086 	*   // Must return the number of data poins
1087 	*   inline size_t kdtree_get_point_count() const { ... }
1088 	*
1089 	*
1090 	*   // Must return the dim'th component of the idx'th point in the class:
1091 	*   inline T kdtree_get_pt(const size_t idx, const size_t dim) const { ... }
1092 	*
1093 	*   // Optional bounding-box computation: return false to default to a standard
1094 	* bbox computation loop.
1095 	*   //   Return true if the BBOX was already computed by the class and returned
1096 	* in "bb" so it can be avoided to redo it again.
1097 	*   //   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3
1098 	* for point clouds) template <class BBOX> bool kdtree_get_bbox(BBOX &bb) const
1099 	*   {
1100 	*      bb[0].low = ...; bb[0].high = ...;  // 0th dimension limits
1101 	*      bb[1].low = ...; bb[1].high = ...;  // 1st dimension limits
1102 	*      ...
1103 	*      return true;
1104 	*   }
1105 	*
1106 	*  \endcode
1107 	*
1108 	* \tparam DatasetAdaptor The user-provided adaptor (see comments above).
1109 	* \tparam Distance The distance metric to use: nanoflann::metric_L1,
1110 	* nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam DIM
1111 	* Dimensionality of data points (e.g. 3 for 3D points) \tparam IndexType Will
1112 	* be typically size_t or int
1113 	*/
1114 	template <typename Distance, class DatasetAdaptor, int DIM = -1,
1115 		typename IndexType = size_t>
1116 		class KDTreeSingleIndexAdaptor
1117 		: public KDTreeBaseClass<
1118 		KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, IndexType>,
1119 		Distance, DatasetAdaptor, DIM, IndexType> {
1120 		public:
1121 			/** Deleted copy constructor*/
1122 			KDTreeSingleIndexAdaptor(
1123 				const KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM, IndexType>
1124 				&) = delete;
1125 
1126 			/**
1127 			* The dataset used by this index
1128 			*/
1129 			const DatasetAdaptor &dataset; //!< The source of our data
1130 
1131 			const KDTreeSingleIndexAdaptorParams index_params;
1132 
1133 			Distance distance;
1134 
1135 			typedef typename nanoflann::KDTreeBaseClass<
1136 				nanoflann::KDTreeSingleIndexAdaptor<Distance, DatasetAdaptor, DIM,
1137 				IndexType>,
1138 				Distance, DatasetAdaptor, DIM, IndexType>
1139 				BaseClassRef;
1140 
1141 			typedef typename BaseClassRef::ElementType ElementType;
1142 			typedef typename BaseClassRef::DistanceType DistanceType;
1143 
1144 			typedef typename BaseClassRef::Node Node;
1145 			typedef Node *NodePtr;
1146 
1147 			typedef typename BaseClassRef::Interval Interval;
1148 			/** Define "BoundingBox" as a fixed-size or variable-size container depending
1149 			* on "DIM" */
1150 			typedef typename BaseClassRef::BoundingBox BoundingBox;
1151 
1152 			/** Define "distance_vector_t" as a fixed-size or variable-size container
1153 			* depending on "DIM" */
1154 			typedef typename BaseClassRef::distance_vector_t distance_vector_t;
1155 
1156 			/**
1157 			* KDTree constructor
1158 			*
1159 			* Refer to docs in README.md or online in
1160 			* https://github.com/jlblancoc/nanoflann
1161 			*
1162 			* The KD-Tree point dimension (the length of each point in the datase, e.g. 3
1163 			* for 3D points) is determined by means of:
1164 			*  - The \a DIM template parameter if >0 (highest priority)
1165 			*  - Otherwise, the \a dimensionality parameter of this constructor.
1166 			*
1167 			* @param inputData Dataset with the input features
1168 			* @param params Basically, the maximum leaf node size
1169 			*/
KDTreeSingleIndexAdaptor(const int dimensionality,const DatasetAdaptor & inputData,const KDTreeSingleIndexAdaptorParams & params=KDTreeSingleIndexAdaptorParams ())1170 			KDTreeSingleIndexAdaptor(const int dimensionality,
1171 				const DatasetAdaptor &inputData,
1172 				const KDTreeSingleIndexAdaptorParams &params =
1173 				KDTreeSingleIndexAdaptorParams())
1174 				: dataset(inputData), index_params(params), distance(inputData) {
1175 				BaseClassRef::root_node = NULL;
1176 				BaseClassRef::m_size = dataset.kdtree_get_point_count();
1177 				BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1178 				BaseClassRef::dim = dimensionality;
1179 				if (DIM > 0)
1180 					BaseClassRef::dim = DIM;
1181 				BaseClassRef::m_leaf_max_size = params.leaf_max_size;
1182 
1183 				// Create a permutable array of indices to the input vectors.
1184 				init_vind();
1185 			}
1186 
1187 			/**
1188 			* Builds the index
1189 			*/
buildIndex()1190 			void buildIndex() {
1191 				BaseClassRef::m_size = dataset.kdtree_get_point_count();
1192 				BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1193 				init_vind();
1194 				this->freeIndex(*this);
1195 				BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1196 				if (BaseClassRef::m_size == 0)
1197 					return;
1198 				computeBoundingBox(BaseClassRef::root_bbox);
1199 				BaseClassRef::root_node =
1200 					this->divideTree(*this, 0, BaseClassRef::m_size,
1201 						BaseClassRef::root_bbox); // construct the tree
1202 			}
1203 
1204 			/** \name Query methods
1205 			* @{ */
1206 
1207 			/**
1208 			* Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored
1209 			* inside the result object.
1210 			*
1211 			* Params:
1212 			*     result = the result object in which the indices of the
1213 			* nearest-neighbors are stored vec = the vector for which to search the
1214 			* nearest neighbors
1215 			*
1216 			* \tparam RESULTSET Should be any ResultSet<DistanceType>
1217 			* \return  True if the requested neighbors could be found.
1218 			* \sa knnSearch, radiusSearch
1219 			*/
1220 			template <typename RESULTSET>
findNeighbors(RESULTSET & result,const ElementType * vec,const SearchParams & searchParams) const1221 			bool findNeighbors(RESULTSET &result, const ElementType *vec,
1222 				const SearchParams &searchParams) const {
1223 				assert(vec);
1224 				if (this->size(*this) == 0)
1225 					return false;
1226 				if (!BaseClassRef::root_node)
1227 					throw std::runtime_error(
1228 						"[nanoflann] findNeighbors() called before building the index.");
1229 				float epsError = 1 + searchParams.eps;
1230 
1231 				distance_vector_t
1232 					dists; // fixed or variable-sized container (depending on DIM)
1233 				auto zero = static_cast<decltype(result.worstDist())>(0);
1234 				assign(dists, (DIM > 0 ? DIM : BaseClassRef::dim),
1235 					zero); // Fill it with zeros.
1236 				DistanceType distsq = this->computeInitialDistances(*this, vec, dists);
1237 				searchLevel(result, vec, BaseClassRef::root_node, distsq, dists,
1238 					epsError); // "count_leaf" parameter removed since was neither
1239 							   // used nor returned to the user.
1240 				return result.full();
1241 			}
1242 
1243 			/**
1244 			* Find the "num_closest" nearest neighbors to the \a query_point[0:dim-1].
1245 			* Their indices are stored inside the result object. \sa radiusSearch,
1246 			* findNeighbors \note nChecks_IGNORED is ignored but kept for compatibility
1247 			* with the original FLANN interface. \return Number `N` of valid points in
1248 			* the result set. Only the first `N` entries in `out_indices` and
1249 			* `out_distances_sq` will be valid. Return may be less than `num_closest`
1250 			* only if the number of elements in the tree is less than `num_closest`.
1251 			*/
knnSearch(const ElementType * query_point,const size_t num_closest,IndexType * out_indices,DistanceType * out_distances_sq,const int=10) const1252 			size_t knnSearch(const ElementType *query_point, const size_t num_closest,
1253 				IndexType *out_indices, DistanceType *out_distances_sq,
1254 				const int /* nChecks_IGNORED */ = 10) const {
1255 				nanoflann::KNNResultSet<DistanceType, IndexType> resultSet(num_closest);
1256 				resultSet.init(out_indices, out_distances_sq);
1257 				this->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
1258 				return resultSet.size();
1259 			}
1260 
1261 			/**
1262 			* Find all the neighbors to \a query_point[0:dim-1] within a maximum radius.
1263 			*  The output is given as a vector of pairs, of which the first element is a
1264 			* point index and the second the corresponding distance. Previous contents of
1265 			* \a IndicesDists are cleared.
1266 			*
1267 			*  If searchParams.sorted==true, the output list is sorted by ascending
1268 			* distances.
1269 			*
1270 			*  For a better performance, it is advisable to do a .reserve() on the vector
1271 			* if you have any wild guess about the number of expected matches.
1272 			*
1273 			*  \sa knnSearch, findNeighbors, radiusSearchCustomCallback
1274 			* \return The number of points within the given radius (i.e. indices.size()
1275 			* or dists.size() )
1276 			*/
1277 			size_t
radiusSearch(const ElementType * query_point,const DistanceType & radius,std::vector<std::pair<IndexType,DistanceType>> & IndicesDists,const SearchParams & searchParams) const1278 				radiusSearch(const ElementType *query_point, const DistanceType &radius,
1279 					std::vector<std::pair<IndexType, DistanceType>> &IndicesDists,
1280 					const SearchParams &searchParams) const {
1281 				RadiusResultSet<DistanceType, IndexType> resultSet(radius, IndicesDists);
1282 				const size_t nFound =
1283 					radiusSearchCustomCallback(query_point, resultSet, searchParams);
1284 				if (searchParams.sorted)
1285 					std::sort(IndicesDists.begin(), IndicesDists.end(), IndexDist_Sorter());
1286 				return nFound;
1287 			}
1288 
1289 			/**
1290 			* Just like radiusSearch() but with a custom callback class for each point
1291 			* found in the radius of the query. See the source of RadiusResultSet<> as a
1292 			* start point for your own classes. \sa radiusSearch
1293 			*/
1294 			template <class SEARCH_CALLBACK>
radiusSearchCustomCallback(const ElementType * query_point,SEARCH_CALLBACK & resultSet,const SearchParams & searchParams=SearchParams ()) const1295 			size_t radiusSearchCustomCallback(
1296 				const ElementType *query_point, SEARCH_CALLBACK &resultSet,
1297 				const SearchParams &searchParams = SearchParams()) const {
1298 				this->findNeighbors(resultSet, query_point, searchParams);
1299 				return resultSet.size();
1300 			}
1301 
1302 			/** @} */
1303 
1304 		public:
1305 			/** Make sure the auxiliary list \a vind has the same size than the current
1306 			* dataset, and re-generate if size has changed. */
init_vind()1307 			void init_vind() {
1308 				// Create a permutable array of indices to the input vectors.
1309 				BaseClassRef::m_size = dataset.kdtree_get_point_count();
1310 				if (BaseClassRef::vind.size() != BaseClassRef::m_size)
1311 					BaseClassRef::vind.resize(BaseClassRef::m_size);
1312 				for (size_t i = 0; i < BaseClassRef::m_size; i++)
1313 					BaseClassRef::vind[i] = i;
1314 			}
1315 
computeBoundingBox(BoundingBox & bbox)1316 			void computeBoundingBox(BoundingBox &bbox) {
1317 				resize(bbox, (DIM > 0 ? DIM : BaseClassRef::dim));
1318 				if (dataset.kdtree_get_bbox(bbox)) {
1319 					// Done! It was implemented in derived class
1320 				} else {
1321 					const size_t N = dataset.kdtree_get_point_count();
1322 					if (!N)
1323 						throw std::runtime_error("[nanoflann] computeBoundingBox() called but "
1324 							"no data points found.");
1325 					for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1326 						bbox[i].low = bbox[i].high = this->dataset_get(*this, 0, i);
1327 					}
1328 					for (size_t k = 1; k < N; ++k) {
1329 						for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1330 							if (this->dataset_get(*this, k, i) < bbox[i].low)
1331 								bbox[i].low = this->dataset_get(*this, k, i);
1332 							if (this->dataset_get(*this, k, i) > bbox[i].high)
1333 								bbox[i].high = this->dataset_get(*this, k, i);
1334 						}
1335 					}
1336 				}
1337 			}
1338 
1339 			/**
1340 			* Performs an exact search in the tree starting from a node.
1341 			* \tparam RESULTSET Should be any ResultSet<DistanceType>
1342 			* \return true if the search should be continued, false if the results are
1343 			* sufficient
1344 			*/
1345 			template <class RESULTSET>
searchLevel(RESULTSET & result_set,const ElementType * vec,const NodePtr node,DistanceType mindistsq,distance_vector_t & dists,const float epsError) const1346 			bool searchLevel(RESULTSET &result_set, const ElementType *vec,
1347 				const NodePtr node, DistanceType mindistsq,
1348 				distance_vector_t &dists, const float epsError) const {
1349 				/* If this is a leaf node, then do check and return. */
1350 				if ((node->child1 == NULL) && (node->child2 == NULL)) {
1351 					// count_leaf += (node->lr.right-node->lr.left);  // Removed since was
1352 					// neither used nor returned to the user.
1353 					DistanceType worst_dist = result_set.worstDist();
1354 					for (IndexType i = node->node_type.lr.left; i < node->node_type.lr.right;
1355 						++i) {
1356 						const IndexType index = BaseClassRef::vind[i]; // reorder... : i;
1357 						DistanceType dist = distance.evalMetric(
1358 							vec, index, (DIM > 0 ? DIM : BaseClassRef::dim));
1359 						if (dist < worst_dist) {
1360 							if (!result_set.addPoint(dist, BaseClassRef::vind[i])) {
1361 								// the resultset doesn't want to receive any more points, we're done
1362 								// searching!
1363 								return false;
1364 							}
1365 						}
1366 					}
1367 					return true;
1368 				}
1369 
1370 				/* Which child branch should be taken first? */
1371 				int idx = node->node_type.sub.divfeat;
1372 				ElementType val = vec[idx];
1373 				DistanceType diff1 = val - node->node_type.sub.divlow;
1374 				DistanceType diff2 = val - node->node_type.sub.divhigh;
1375 
1376 				NodePtr bestChild;
1377 				NodePtr otherChild;
1378 				DistanceType cut_dist;
1379 				if ((diff1 + diff2) < 0) {
1380 					bestChild = node->child1;
1381 					otherChild = node->child2;
1382 					cut_dist = distance.accum_dist(val, node->node_type.sub.divhigh, idx);
1383 				} else {
1384 					bestChild = node->child2;
1385 					otherChild = node->child1;
1386 					cut_dist = distance.accum_dist(val, node->node_type.sub.divlow, idx);
1387 				}
1388 
1389 				/* Call recursively to search next level down. */
1390 				if (!searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError)) {
1391 					// the resultset doesn't want to receive any more points, we're done
1392 					// searching!
1393 					return false;
1394 				}
1395 
1396 				DistanceType dst = dists[idx];
1397 				mindistsq = mindistsq + cut_dist - dst;
1398 				dists[idx] = cut_dist;
1399 				if (mindistsq * epsError <= result_set.worstDist()) {
1400 					if (!searchLevel(result_set, vec, otherChild, mindistsq, dists,
1401 						epsError)) {
1402 						// the resultset doesn't want to receive any more points, we're done
1403 						// searching!
1404 						return false;
1405 					}
1406 				}
1407 				dists[idx] = dst;
1408 				return true;
1409 			}
1410 
1411 		public:
1412 			/**  Stores the index in a binary file.
1413 			*   IMPORTANT NOTE: The set of data points is NOT stored in the file, so when
1414 			* loading the index object it must be constructed associated to the same
1415 			* source of data points used while building it. See the example:
1416 			* examples/saveload_example.cpp \sa loadIndex  */
saveIndex(FILE * stream)1417 			void saveIndex(FILE *stream) { this->saveIndex_(*this, stream); }
1418 
1419 			/**  Loads a previous index from a binary file.
1420 			*   IMPORTANT NOTE: The set of data points is NOT stored in the file, so the
1421 			* index object must be constructed associated to the same source of data
1422 			* points used while building the index. See the example:
1423 			* examples/saveload_example.cpp \sa loadIndex  */
loadIndex(FILE * stream)1424 			void loadIndex(FILE *stream) { this->loadIndex_(*this, stream); }
1425 
1426 	}; // class KDTree
1427 
1428 	   /** kd-tree dynamic index
1429 	   *
1430 	   * Contains the k-d trees and other information for indexing a set of points
1431 	   * for nearest-neighbor matching.
1432 	   *
1433 	   *  The class "DatasetAdaptor" must provide the following interface (can be
1434 	   * non-virtual, inlined methods):
1435 	   *
1436 	   *  \code
1437 	   *   // Must return the number of data poins
1438 	   *   inline size_t kdtree_get_point_count() const { ... }
1439 	   *
1440 	   *   // Must return the dim'th component of the idx'th point in the class:
1441 	   *   inline T kdtree_get_pt(const size_t idx, const size_t dim) const { ... }
1442 	   *
1443 	   *   // Optional bounding-box computation: return false to default to a standard
1444 	   * bbox computation loop.
1445 	   *   //   Return true if the BBOX was already computed by the class and returned
1446 	   * in "bb" so it can be avoided to redo it again.
1447 	   *   //   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3
1448 	   * for point clouds) template <class BBOX> bool kdtree_get_bbox(BBOX &bb) const
1449 	   *   {
1450 	   *      bb[0].low = ...; bb[0].high = ...;  // 0th dimension limits
1451 	   *      bb[1].low = ...; bb[1].high = ...;  // 1st dimension limits
1452 	   *      ...
1453 	   *      return true;
1454 	   *   }
1455 	   *
1456 	   *  \endcode
1457 	   *
1458 	   * \tparam DatasetAdaptor The user-provided adaptor (see comments above).
1459 	   * \tparam Distance The distance metric to use: nanoflann::metric_L1,
1460 	   * nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam DIM
1461 	   * Dimensionality of data points (e.g. 3 for 3D points) \tparam IndexType Will
1462 	   * be typically size_t or int
1463 	   */
1464 	template <typename Distance, class DatasetAdaptor, int DIM = -1,
1465 		typename IndexType = size_t>
1466 		class KDTreeSingleIndexDynamicAdaptor_
1467 		: public KDTreeBaseClass<KDTreeSingleIndexDynamicAdaptor_<
1468 		Distance, DatasetAdaptor, DIM, IndexType>,
1469 		Distance, DatasetAdaptor, DIM, IndexType> {
1470 		public:
1471 			/**
1472 			* The dataset used by this index
1473 			*/
1474 			const DatasetAdaptor &dataset; //!< The source of our data
1475 
1476 			KDTreeSingleIndexAdaptorParams index_params;
1477 
1478 			std::vector<int> &treeIndex;
1479 
1480 			Distance distance;
1481 
1482 			typedef typename nanoflann::KDTreeBaseClass<
1483 				nanoflann::KDTreeSingleIndexDynamicAdaptor_<Distance, DatasetAdaptor, DIM,
1484 				IndexType>,
1485 				Distance, DatasetAdaptor, DIM, IndexType>
1486 				BaseClassRef;
1487 
1488 			typedef typename BaseClassRef::ElementType ElementType;
1489 			typedef typename BaseClassRef::DistanceType DistanceType;
1490 
1491 			typedef typename BaseClassRef::Node Node;
1492 			typedef Node *NodePtr;
1493 
1494 			typedef typename BaseClassRef::Interval Interval;
1495 			/** Define "BoundingBox" as a fixed-size or variable-size container depending
1496 			* on "DIM" */
1497 			typedef typename BaseClassRef::BoundingBox BoundingBox;
1498 
1499 			/** Define "distance_vector_t" as a fixed-size or variable-size container
1500 			* depending on "DIM" */
1501 			typedef typename BaseClassRef::distance_vector_t distance_vector_t;
1502 
1503 			/**
1504 			* KDTree constructor
1505 			*
1506 			* Refer to docs in README.md or online in
1507 			* https://github.com/jlblancoc/nanoflann
1508 			*
1509 			* The KD-Tree point dimension (the length of each point in the datase, e.g. 3
1510 			* for 3D points) is determined by means of:
1511 			*  - The \a DIM template parameter if >0 (highest priority)
1512 			*  - Otherwise, the \a dimensionality parameter of this constructor.
1513 			*
1514 			* @param inputData Dataset with the input features
1515 			* @param params Basically, the maximum leaf node size
1516 			*/
KDTreeSingleIndexDynamicAdaptor_(const int dimensionality,const DatasetAdaptor & inputData,std::vector<int> & treeIndex_,const KDTreeSingleIndexAdaptorParams & params=KDTreeSingleIndexAdaptorParams ())1517 			KDTreeSingleIndexDynamicAdaptor_(
1518 				const int dimensionality, const DatasetAdaptor &inputData,
1519 				std::vector<int> &treeIndex_,
1520 				const KDTreeSingleIndexAdaptorParams &params =
1521 				KDTreeSingleIndexAdaptorParams())
1522 				: dataset(inputData), index_params(params), treeIndex(treeIndex_),
1523 				distance(inputData) {
1524 				BaseClassRef::root_node = NULL;
1525 				BaseClassRef::m_size = 0;
1526 				BaseClassRef::m_size_at_index_build = 0;
1527 				BaseClassRef::dim = dimensionality;
1528 				if (DIM > 0)
1529 					BaseClassRef::dim = DIM;
1530 				BaseClassRef::m_leaf_max_size = params.leaf_max_size;
1531 			}
1532 
1533 			/** Assignment operator definiton */
1534 			KDTreeSingleIndexDynamicAdaptor_
operator =(const KDTreeSingleIndexDynamicAdaptor_ & rhs)1535 				operator=(const KDTreeSingleIndexDynamicAdaptor_ &rhs) {
1536 				KDTreeSingleIndexDynamicAdaptor_ tmp(rhs);
1537 				std::swap(BaseClassRef::vind, tmp.BaseClassRef::vind);
1538 				std::swap(BaseClassRef::m_leaf_max_size, tmp.BaseClassRef::m_leaf_max_size);
1539 				std::swap(index_params, tmp.index_params);
1540 				std::swap(treeIndex, tmp.treeIndex);
1541 				std::swap(BaseClassRef::m_size, tmp.BaseClassRef::m_size);
1542 				std::swap(BaseClassRef::m_size_at_index_build,
1543 					tmp.BaseClassRef::m_size_at_index_build);
1544 				std::swap(BaseClassRef::root_node, tmp.BaseClassRef::root_node);
1545 				std::swap(BaseClassRef::root_bbox, tmp.BaseClassRef::root_bbox);
1546 				std::swap(BaseClassRef::pool, tmp.BaseClassRef::pool);
1547 				return *this;
1548 			}
1549 
1550 			/**
1551 			* Builds the index
1552 			*/
buildIndex()1553 			void buildIndex() {
1554 				BaseClassRef::m_size = BaseClassRef::vind.size();
1555 				this->freeIndex(*this);
1556 				BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1557 				if (BaseClassRef::m_size == 0)
1558 					return;
1559 				computeBoundingBox(BaseClassRef::root_bbox);
1560 				BaseClassRef::root_node =
1561 					this->divideTree(*this, 0, BaseClassRef::m_size,
1562 						BaseClassRef::root_bbox); // construct the tree
1563 			}
1564 
1565 			/** \name Query methods
1566 			* @{ */
1567 
1568 			/**
1569 			* Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored
1570 			* inside the result object.
1571 			*
1572 			* Params:
1573 			*     result = the result object in which the indices of the
1574 			* nearest-neighbors are stored vec = the vector for which to search the
1575 			* nearest neighbors
1576 			*
1577 			* \tparam RESULTSET Should be any ResultSet<DistanceType>
1578 			* \return  True if the requested neighbors could be found.
1579 			* \sa knnSearch, radiusSearch
1580 			*/
1581 			template <typename RESULTSET>
findNeighbors(RESULTSET & result,const ElementType * vec,const SearchParams & searchParams) const1582 			bool findNeighbors(RESULTSET &result, const ElementType *vec,
1583 				const SearchParams &searchParams) const {
1584 				assert(vec);
1585 				if (this->size(*this) == 0)
1586 					return false;
1587 				if (!BaseClassRef::root_node)
1588 					return false;
1589 				float epsError = 1 + searchParams.eps;
1590 
1591 				// fixed or variable-sized container (depending on DIM)
1592 				distance_vector_t dists;
1593 				// Fill it with zeros.
1594 				assign(dists, (DIM > 0 ? DIM : BaseClassRef::dim),
1595 					static_cast<typename distance_vector_t::value_type>(0));
1596 				DistanceType distsq = this->computeInitialDistances(*this, vec, dists);
1597 				searchLevel(result, vec, BaseClassRef::root_node, distsq, dists,
1598 					epsError); // "count_leaf" parameter removed since was neither
1599 							   // used nor returned to the user.
1600 				return result.full();
1601 			}
1602 
1603 			/**
1604 			* Find the "num_closest" nearest neighbors to the \a query_point[0:dim-1].
1605 			* Their indices are stored inside the result object. \sa radiusSearch,
1606 			* findNeighbors \note nChecks_IGNORED is ignored but kept for compatibility
1607 			* with the original FLANN interface. \return Number `N` of valid points in
1608 			* the result set. Only the first `N` entries in `out_indices` and
1609 			* `out_distances_sq` will be valid. Return may be less than `num_closest`
1610 			* only if the number of elements in the tree is less than `num_closest`.
1611 			*/
knnSearch(const ElementType * query_point,const size_t num_closest,IndexType * out_indices,DistanceType * out_distances_sq,const int=10) const1612 			size_t knnSearch(const ElementType *query_point, const size_t num_closest,
1613 				IndexType *out_indices, DistanceType *out_distances_sq,
1614 				const int /* nChecks_IGNORED */ = 10) const {
1615 				nanoflann::KNNResultSet<DistanceType, IndexType> resultSet(num_closest);
1616 				resultSet.init(out_indices, out_distances_sq);
1617 				this->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
1618 				return resultSet.size();
1619 			}
1620 
1621 			/**
1622 			* Find all the neighbors to \a query_point[0:dim-1] within a maximum radius.
1623 			*  The output is given as a vector of pairs, of which the first element is a
1624 			* point index and the second the corresponding distance. Previous contents of
1625 			* \a IndicesDists are cleared.
1626 			*
1627 			*  If searchParams.sorted==true, the output list is sorted by ascending
1628 			* distances.
1629 			*
1630 			*  For a better performance, it is advisable to do a .reserve() on the vector
1631 			* if you have any wild guess about the number of expected matches.
1632 			*
1633 			*  \sa knnSearch, findNeighbors, radiusSearchCustomCallback
1634 			* \return The number of points within the given radius (i.e. indices.size()
1635 			* or dists.size() )
1636 			*/
1637 			size_t
radiusSearch(const ElementType * query_point,const DistanceType & radius,std::vector<std::pair<IndexType,DistanceType>> & IndicesDists,const SearchParams & searchParams) const1638 				radiusSearch(const ElementType *query_point, const DistanceType &radius,
1639 					std::vector<std::pair<IndexType, DistanceType>> &IndicesDists,
1640 					const SearchParams &searchParams) const {
1641 				RadiusResultSet<DistanceType, IndexType> resultSet(radius, IndicesDists);
1642 				const size_t nFound =
1643 					radiusSearchCustomCallback(query_point, resultSet, searchParams);
1644 				if (searchParams.sorted)
1645 					std::sort(IndicesDists.begin(), IndicesDists.end(), IndexDist_Sorter());
1646 				return nFound;
1647 			}
1648 
1649 			/**
1650 			* Just like radiusSearch() but with a custom callback class for each point
1651 			* found in the radius of the query. See the source of RadiusResultSet<> as a
1652 			* start point for your own classes. \sa radiusSearch
1653 			*/
1654 			template <class SEARCH_CALLBACK>
radiusSearchCustomCallback(const ElementType * query_point,SEARCH_CALLBACK & resultSet,const SearchParams & searchParams=SearchParams ()) const1655 			size_t radiusSearchCustomCallback(
1656 				const ElementType *query_point, SEARCH_CALLBACK &resultSet,
1657 				const SearchParams &searchParams = SearchParams()) const {
1658 				this->findNeighbors(resultSet, query_point, searchParams);
1659 				return resultSet.size();
1660 			}
1661 
1662 			/** @} */
1663 
1664 		public:
computeBoundingBox(BoundingBox & bbox)1665 			void computeBoundingBox(BoundingBox &bbox) {
1666 				resize(bbox, (DIM > 0 ? DIM : BaseClassRef::dim));
1667 
1668 				if (dataset.kdtree_get_bbox(bbox)) {
1669 					// Done! It was implemented in derived class
1670 				} else {
1671 					const size_t N = BaseClassRef::m_size;
1672 					if (!N)
1673 						throw std::runtime_error("[nanoflann] computeBoundingBox() called but "
1674 							"no data points found.");
1675 					for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1676 						bbox[i].low = bbox[i].high =
1677 							this->dataset_get(*this, BaseClassRef::vind[0], i);
1678 					}
1679 					for (size_t k = 1; k < N; ++k) {
1680 						for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1681 							if (this->dataset_get(*this, BaseClassRef::vind[k], i) < bbox[i].low)
1682 								bbox[i].low = this->dataset_get(*this, BaseClassRef::vind[k], i);
1683 							if (this->dataset_get(*this, BaseClassRef::vind[k], i) > bbox[i].high)
1684 								bbox[i].high = this->dataset_get(*this, BaseClassRef::vind[k], i);
1685 						}
1686 					}
1687 				}
1688 			}
1689 
1690 			/**
1691 			* Performs an exact search in the tree starting from a node.
1692 			* \tparam RESULTSET Should be any ResultSet<DistanceType>
1693 			*/
1694 			template <class RESULTSET>
searchLevel(RESULTSET & result_set,const ElementType * vec,const NodePtr node,DistanceType mindistsq,distance_vector_t & dists,const float epsError) const1695 			void searchLevel(RESULTSET &result_set, const ElementType *vec,
1696 				const NodePtr node, DistanceType mindistsq,
1697 				distance_vector_t &dists, const float epsError) const {
1698 				/* If this is a leaf node, then do check and return. */
1699 				if ((node->child1 == NULL) && (node->child2 == NULL)) {
1700 					// count_leaf += (node->lr.right-node->lr.left);  // Removed since was
1701 					// neither used nor returned to the user.
1702 					DistanceType worst_dist = result_set.worstDist();
1703 					for (IndexType i = node->node_type.lr.left; i < node->node_type.lr.right;
1704 						++i) {
1705 						const IndexType index = BaseClassRef::vind[i]; // reorder... : i;
1706 						if (treeIndex[index] == -1)
1707 							continue;
1708 						DistanceType dist = distance.evalMetric(
1709 							vec, index, (DIM > 0 ? DIM : BaseClassRef::dim));
1710 						if (dist < worst_dist) {
1711 							if (!result_set.addPoint(
1712 								static_cast<typename RESULTSET::DistanceType>(dist),
1713 								static_cast<typename RESULTSET::IndexType>(
1714 									BaseClassRef::vind[i]))) {
1715 								// the resultset doesn't want to receive any more points, we're done
1716 								// searching!
1717 								return; // false;
1718 							}
1719 						}
1720 					}
1721 					return;
1722 				}
1723 
1724 				/* Which child branch should be taken first? */
1725 				int idx = node->node_type.sub.divfeat;
1726 				ElementType val = vec[idx];
1727 				DistanceType diff1 = val - node->node_type.sub.divlow;
1728 				DistanceType diff2 = val - node->node_type.sub.divhigh;
1729 
1730 				NodePtr bestChild;
1731 				NodePtr otherChild;
1732 				DistanceType cut_dist;
1733 				if ((diff1 + diff2) < 0) {
1734 					bestChild = node->child1;
1735 					otherChild = node->child2;
1736 					cut_dist = distance.accum_dist(val, node->node_type.sub.divhigh, idx);
1737 				} else {
1738 					bestChild = node->child2;
1739 					otherChild = node->child1;
1740 					cut_dist = distance.accum_dist(val, node->node_type.sub.divlow, idx);
1741 				}
1742 
1743 				/* Call recursively to search next level down. */
1744 				searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError);
1745 
1746 				DistanceType dst = dists[idx];
1747 				mindistsq = mindistsq + cut_dist - dst;
1748 				dists[idx] = cut_dist;
1749 				if (mindistsq * epsError <= result_set.worstDist()) {
1750 					searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError);
1751 				}
1752 				dists[idx] = dst;
1753 			}
1754 
1755 		public:
1756 			/**  Stores the index in a binary file.
1757 			*   IMPORTANT NOTE: The set of data points is NOT stored in the file, so when
1758 			* loading the index object it must be constructed associated to the same
1759 			* source of data points used while building it. See the example:
1760 			* examples/saveload_example.cpp \sa loadIndex  */
saveIndex(FILE * stream)1761 			void saveIndex(FILE *stream) { this->saveIndex_(*this, stream); }
1762 
1763 			/**  Loads a previous index from a binary file.
1764 			*   IMPORTANT NOTE: The set of data points is NOT stored in the file, so the
1765 			* index object must be constructed associated to the same source of data
1766 			* points used while building the index. See the example:
1767 			* examples/saveload_example.cpp \sa loadIndex  */
loadIndex(FILE * stream)1768 			void loadIndex(FILE *stream) { this->loadIndex_(*this, stream); }
1769 	};
1770 
1771 	/** kd-tree dynaimic index
1772 	*
1773 	* class to create multiple static index and merge their results to behave as
1774 	* single dynamic index as proposed in Logarithmic Approach.
1775 	*
1776 	*  Example of usage:
1777 	*  examples/dynamic_pointcloud_example.cpp
1778 	*
1779 	* \tparam DatasetAdaptor The user-provided adaptor (see comments above).
1780 	* \tparam Distance The distance metric to use: nanoflann::metric_L1,
1781 	* nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam DIM
1782 	* Dimensionality of data points (e.g. 3 for 3D points) \tparam IndexType Will
1783 	* be typically size_t or int
1784 	*/
1785 	template <typename Distance, class DatasetAdaptor, int DIM = -1,
1786 		typename IndexType = size_t>
1787 		class KDTreeSingleIndexDynamicAdaptor {
1788 		public:
1789 			typedef typename Distance::ElementType ElementType;
1790 			typedef typename Distance::DistanceType DistanceType;
1791 
1792 		protected:
1793 			size_t m_leaf_max_size;
1794 			size_t treeCount;
1795 			size_t pointCount;
1796 
1797 			/**
1798 			* The dataset used by this index
1799 			*/
1800 			const DatasetAdaptor &dataset; //!< The source of our data
1801 
1802 			std::vector<int> treeIndex; //!< treeIndex[idx] is the index of tree in which
1803 										//!< point at idx is stored. treeIndex[idx]=-1
1804 										//!< means that point has been removed.
1805 
1806 			KDTreeSingleIndexAdaptorParams index_params;
1807 
1808 			int dim; //!< Dimensionality of each data point
1809 
1810 			typedef KDTreeSingleIndexDynamicAdaptor_<Distance, DatasetAdaptor, DIM>
1811 				index_container_t;
1812 			std::vector<index_container_t> index;
1813 
1814 		public:
1815 			/** Get a const ref to the internal list of indices; the number of indices is
1816 			* adapted dynamically as the dataset grows in size. */
getAllIndices() const1817 			const std::vector<index_container_t> &getAllIndices() const { return index; }
1818 
1819 		private:
1820 			/** finds position of least significant unset bit */
First0Bit(IndexType num)1821 			int First0Bit(IndexType num) {
1822 				int pos = 0;
1823 				while (num & 1) {
1824 					num = num >> 1;
1825 					pos++;
1826 				}
1827 				return pos;
1828 			}
1829 
1830 			/** Creates multiple empty trees to handle dynamic support */
init()1831 			void init() {
1832 				typedef KDTreeSingleIndexDynamicAdaptor_<Distance, DatasetAdaptor, DIM>
1833 					my_kd_tree_t;
1834 				std::vector<my_kd_tree_t> index_(
1835 					treeCount, my_kd_tree_t(dim /*dim*/, dataset, treeIndex, index_params));
1836 				index = index_;
1837 			}
1838 
1839 		public:
1840 			Distance distance;
1841 
1842 			/**
1843 			* KDTree constructor
1844 			*
1845 			* Refer to docs in README.md or online in
1846 			* https://github.com/jlblancoc/nanoflann
1847 			*
1848 			* The KD-Tree point dimension (the length of each point in the datase, e.g. 3
1849 			* for 3D points) is determined by means of:
1850 			*  - The \a DIM template parameter if >0 (highest priority)
1851 			*  - Otherwise, the \a dimensionality parameter of this constructor.
1852 			*
1853 			* @param inputData Dataset with the input features
1854 			* @param params Basically, the maximum leaf node size
1855 			*/
KDTreeSingleIndexDynamicAdaptor(const int dimensionality,const DatasetAdaptor & inputData,const KDTreeSingleIndexAdaptorParams & params=KDTreeSingleIndexAdaptorParams (),const size_t maximumPointCount=1000000000U)1856 			KDTreeSingleIndexDynamicAdaptor(const int dimensionality,
1857 				const DatasetAdaptor &inputData,
1858 				const KDTreeSingleIndexAdaptorParams &params =
1859 				KDTreeSingleIndexAdaptorParams(),
1860 				const size_t maximumPointCount = 1000000000U)
1861 				: dataset(inputData), index_params(params), distance(inputData) {
1862 				treeCount = static_cast<size_t>(std::log2(maximumPointCount));
1863 				pointCount = 0U;
1864 				dim = dimensionality;
1865 				treeIndex.clear();
1866 				if (DIM > 0)
1867 					dim = DIM;
1868 				m_leaf_max_size = params.leaf_max_size;
1869 				init();
1870 				const size_t num_initial_points = dataset.kdtree_get_point_count();
1871 				if (num_initial_points > 0) {
1872 					addPoints(0, num_initial_points - 1);
1873 				}
1874 			}
1875 
1876 			/** Deleted copy constructor*/
1877 			KDTreeSingleIndexDynamicAdaptor(
1878 				const KDTreeSingleIndexDynamicAdaptor<Distance, DatasetAdaptor, DIM,
1879 				IndexType> &) = delete;
1880 
1881 			/** Add points to the set, Inserts all points from [start, end] */
addPoints(IndexType start,IndexType end)1882 			void addPoints(IndexType start, IndexType end) {
1883 				size_t count = end - start + 1;
1884 				treeIndex.resize(treeIndex.size() + count);
1885 				for (IndexType idx = start; idx <= end; idx++) {
1886 					int pos = First0Bit(pointCount);
1887 					index[pos].vind.clear();
1888 					treeIndex[pointCount] = pos;
1889 					for (int i = 0; i < pos; i++) {
1890 						for (int j = 0; j < static_cast<int>(index[i].vind.size()); j++) {
1891 							index[pos].vind.push_back(index[i].vind[j]);
1892 							if (treeIndex[index[i].vind[j]] != -1)
1893 								treeIndex[index[i].vind[j]] = pos;
1894 						}
1895 						index[i].vind.clear();
1896 						index[i].freeIndex(index[i]);
1897 					}
1898 					index[pos].vind.push_back(idx);
1899 					index[pos].buildIndex();
1900 					pointCount++;
1901 				}
1902 			}
1903 
1904 			/** Remove a point from the set (Lazy Deletion) */
removePoint(size_t idx)1905 			void removePoint(size_t idx) {
1906 				if (idx >= pointCount)
1907 					return;
1908 				treeIndex[idx] = -1;
1909 			}
1910 
1911 			/**
1912 			* Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored
1913 			* inside the result object.
1914 			*
1915 			* Params:
1916 			*     result = the result object in which the indices of the
1917 			* nearest-neighbors are stored vec = the vector for which to search the
1918 			* nearest neighbors
1919 			*
1920 			* \tparam RESULTSET Should be any ResultSet<DistanceType>
1921 			* \return  True if the requested neighbors could be found.
1922 			* \sa knnSearch, radiusSearch
1923 			*/
1924 			template <typename RESULTSET>
findNeighbors(RESULTSET & result,const ElementType * vec,const SearchParams & searchParams) const1925 			bool findNeighbors(RESULTSET &result, const ElementType *vec,
1926 				const SearchParams &searchParams) const {
1927 				for (size_t i = 0; i < treeCount; i++) {
1928 					index[i].findNeighbors(result, &vec[0], searchParams);
1929 				}
1930 				return result.full();
1931 			}
1932 	};
1933 
1934 	/** An L2-metric KD-tree adaptor for working with data directly stored in an
1935 	* Eigen Matrix, without duplicating the data storage. Each row in the matrix
1936 	* represents a point in the state space.
1937 	*
1938 	*  Example of usage:
1939 	* \code
1940 	* 	Eigen::Matrix<num_t,Dynamic,Dynamic>  mat;
1941 	* 	// Fill out "mat"...
1942 	*
1943 	* 	typedef KDTreeEigenMatrixAdaptor< Eigen::Matrix<num_t,Dynamic,Dynamic> >
1944 	* my_kd_tree_t; const int max_leaf = 10; my_kd_tree_t   mat_index(mat, max_leaf
1945 	* ); mat_index.index->buildIndex(); mat_index.index->... \endcode
1946 	*
1947 	*  \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality
1948 	* for the points in the data set, allowing more compiler optimizations. \tparam
1949 	* Distance The distance metric to use: nanoflann::metric_L1,
1950 	* nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc.
1951 	*/
1952 	template <class MatrixType, int DIM = -1, class Distance = nanoflann::metric_L2>
1953 	struct KDTreeEigenMatrixAdaptor {
1954 		typedef KDTreeEigenMatrixAdaptor<MatrixType, DIM, Distance> self_t;
1955 		typedef typename MatrixType::Scalar num_t;
1956 		typedef typename MatrixType::Index IndexType;
1957 		typedef
1958 			typename Distance::template traits<num_t, self_t>::distance_t metric_t;
1959 		typedef KDTreeSingleIndexAdaptor<metric_t, self_t,
1960 			MatrixType::ColsAtCompileTime, IndexType>
1961 			index_t;
1962 
1963 		index_t *index; //! The kd-tree index for the user to call its methods as
1964 						//! usual with any other FLANN index.
1965 
1966 						/// Constructor: takes a const ref to the matrix object with the data points
KDTreeEigenMatrixAdaptornanoflann::KDTreeEigenMatrixAdaptor1967 		KDTreeEigenMatrixAdaptor(const size_t dimensionality,
1968 			const std::reference_wrapper<const MatrixType> &mat,
1969 			const int leaf_max_size = 10)
1970 			: m_data_matrix(mat) {
1971 			const auto dims = mat.get().cols();
1972 			if (size_t(dims) != dimensionality)
1973 				throw std::runtime_error(
1974 					"Error: 'dimensionality' must match column count in data matrix");
1975 			if (DIM > 0 && int(dims) != DIM)
1976 				throw std::runtime_error(
1977 					"Data set dimensionality does not match the 'DIM' template argument");
1978 			index =
1979 				new index_t(static_cast<int>(dims), *this /* adaptor */,
1980 					nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size));
1981 			index->buildIndex();
1982 		}
1983 
1984 	public:
1985 		/** Deleted copy constructor */
1986 		KDTreeEigenMatrixAdaptor(const self_t &) = delete;
1987 
~KDTreeEigenMatrixAdaptornanoflann::KDTreeEigenMatrixAdaptor1988 		~KDTreeEigenMatrixAdaptor() { delete index; }
1989 
1990 		const std::reference_wrapper<const MatrixType> m_data_matrix;
1991 
1992 		/** Query for the \a num_closest closest points to a given point (entered as
1993 		* query_point[0:dim-1]). Note that this is a short-cut method for
1994 		* index->findNeighbors(). The user can also call index->... methods as
1995 		* desired. \note nChecks_IGNORED is ignored but kept for compatibility with
1996 		* the original FLANN interface.
1997 		*/
querynanoflann::KDTreeEigenMatrixAdaptor1998 		inline void query(const num_t *query_point, const size_t num_closest,
1999 			IndexType *out_indices, num_t *out_distances_sq,
2000 			const int /* nChecks_IGNORED */ = 10) const {
2001 			nanoflann::KNNResultSet<num_t, IndexType> resultSet(num_closest);
2002 			resultSet.init(out_indices, out_distances_sq);
2003 			index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
2004 		}
2005 
2006 		/** @name Interface expected by KDTreeSingleIndexAdaptor
2007 		* @{ */
2008 
derivednanoflann::KDTreeEigenMatrixAdaptor2009 		const self_t &derived() const { return *this; }
derivednanoflann::KDTreeEigenMatrixAdaptor2010 		self_t &derived() { return *this; }
2011 
2012 		// Must return the number of data points
kdtree_get_point_countnanoflann::KDTreeEigenMatrixAdaptor2013 		inline size_t kdtree_get_point_count() const {
2014 			return m_data_matrix.get().rows();
2015 		}
2016 
2017 		// Returns the dim'th component of the idx'th point in the class:
kdtree_get_ptnanoflann::KDTreeEigenMatrixAdaptor2018 		inline num_t kdtree_get_pt(const IndexType idx, size_t dim) const {
2019 			return m_data_matrix.get().coeff(idx, IndexType(dim));
2020 		}
2021 
2022 		// Optional bounding-box computation: return false to default to a standard
2023 		// bbox computation loop.
2024 		//   Return true if the BBOX was already computed by the class and returned in
2025 		//   "bb" so it can be avoided to redo it again. Look at bb.size() to find out
2026 		//   the expected dimensionality (e.g. 2 or 3 for point clouds)
kdtree_get_bboxnanoflann::KDTreeEigenMatrixAdaptor2027 		template <class BBOX> bool kdtree_get_bbox(BBOX & /*bb*/) const {
2028 			return false;
2029 		}
2030 
2031 		/** @} */
2032 
2033 	}; // end of KDTreeEigenMatrixAdaptor
2034 	   /** @} */
2035 
2036 	   /** @} */ // end of grouping
2037 	} // namespace nanoflann
2038 
2039 #endif /* NANOFLANN_HPP_ */
2040