33 #ifndef NANOFLANN_HPP_
34 #define NANOFLANN_HPP_
45 #if !defined(NOMINMAX) && (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
59 #define NANOFLANN_VERSION 0x118
63 template <
typename DistanceType,
typename IndexType =
size_t,
typename CountType =
size_t>
72 inline KNNResultSet(CountType capacity_) : capacity(capacity_), count(0)
76 inline void init(IndexType* indices_, DistanceType* dists_)
81 dists[capacity-1] = (std::numeric_limits<DistanceType>::max)();
84 inline CountType
size()
const
95 inline void addPoint(DistanceType dist, IndexType index)
98 for (i=count; i>0; --i) {
99 #ifdef NANOFLANN_FIRST_MATCH // If defined and two poins have the same distance, the one with the lowest-index will be returned first.
100 if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) ) {
102 if (dists[i-1]>dist) {
105 dists[i] = dists[i-1];
106 indices[i] = indices[i-1];
115 if (count<capacity) count++;
120 return dists[capacity-1];
128 template <
typename DistanceType,
typename IndexType =
size_t>
136 inline RadiusResultSet(DistanceType radius_, std::vector<std::pair<IndexType,DistanceType> >& indices_dists) : radius(radius_), m_indices_dists(indices_dists)
143 inline void init() { clear(); }
144 inline void clear() { m_indices_dists.clear(); }
146 inline size_t size()
const {
return m_indices_dists.size(); }
148 inline bool full()
const {
return true; }
150 inline void addPoint(DistanceType dist, IndexType index)
153 m_indices_dists.push_back(std::make_pair(index,dist));
156 inline DistanceType
worstDist()
const {
return radius; }
171 if (m_indices_dists.empty())
throw std::runtime_error(
"Cannot invoke RadiusResultSet::worst_item() on an empty list of results.");
172 typedef typename std::vector<std::pair<IndexType,DistanceType> >
::const_iterator DistIt;
173 DistIt it = std::max_element(m_indices_dists.begin(), m_indices_dists.end());
182 template <
typename PairType>
183 inline bool operator()(
const PairType &p1,
const PairType &p2)
const {
184 return p1.second < p2.second;
194 void save_value(FILE* stream,
const T& value,
size_t count = 1)
196 fwrite(&value,
sizeof(value),count, stream);
202 size_t size = value.size();
203 fwrite(&size,
sizeof(
size_t), 1, stream);
204 fwrite(&value[0],
sizeof(T), size, stream);
210 size_t read_cnt = fread(&value,
sizeof(value), count, stream);
211 if (read_cnt != count) {
212 throw std::runtime_error(
"Cannot read from file");
221 size_t read_cnt = fread(&size,
sizeof(
size_t), 1, stream);
223 throw std::runtime_error(
"Cannot read from file");
226 read_cnt = fread(&value[0],
sizeof(T), size, stream);
227 if (read_cnt!=size) {
228 throw std::runtime_error(
"Cannot read from file");
237 template<
typename T>
inline T
abs(T x) {
return (x<0) ? -x : x; }
239 template<>
inline float abs<float>(
float x) {
return fabsf(x); }
240 template<>
inline double abs<double>(
double x) {
return fabs(x); }
248 template<
class T,
class DataSource,
typename _DistanceType = T>
256 L1_Adaptor(
const DataSource &_data_source) : data_source(_data_source) { }
258 inline DistanceType
operator()(
const T* a,
const size_t b_idx,
size_t size, DistanceType worst_dist = -1)
const
260 DistanceType result = DistanceType();
261 const T* last = a +
size;
262 const T* lastgroup = last - 3;
266 while (a < lastgroup) {
267 const DistanceType diff0 =
nanoflann::abs(a[0] - data_source.kdtree_get_pt(b_idx,d++));
268 const DistanceType diff1 =
nanoflann::abs(a[1] - data_source.kdtree_get_pt(b_idx,d++));
269 const DistanceType diff2 =
nanoflann::abs(a[2] - data_source.kdtree_get_pt(b_idx,d++));
270 const DistanceType diff3 =
nanoflann::abs(a[3] - data_source.kdtree_get_pt(b_idx,d++));
271 result += diff0 + diff1 + diff2 + diff3;
273 if ((worst_dist>0)&&(result>worst_dist)) {
279 result +=
nanoflann::abs( *a++ - data_source.kdtree_get_pt(b_idx,d++) );
284 template <
typename U,
typename V>
285 inline DistanceType
accum_dist(
const U a,
const V b,
int )
const
296 template<
class T,
class DataSource,
typename _DistanceType = T>
304 L2_Adaptor(
const DataSource &_data_source) : data_source(_data_source) { }
306 inline DistanceType
operator()(
const T* a,
const size_t b_idx,
size_t size, DistanceType worst_dist = -1)
const
308 DistanceType result = DistanceType();
309 const T* last = a +
size;
310 const T* lastgroup = last - 3;
314 while (a < lastgroup) {
315 const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx,d++);
316 const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx,d++);
317 const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx,d++);
318 const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx,d++);
319 result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
321 if ((worst_dist>0)&&(result>worst_dist)) {
327 const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx,d++);
328 result += diff0 * diff0;
333 template <
typename U,
typename V>
334 inline DistanceType
accum_dist(
const U a,
const V b,
int )
const
345 template<
class T,
class DataSource,
typename _DistanceType = T>
355 inline DistanceType
operator()(
const T* a,
const size_t b_idx,
size_t size)
const {
356 return data_source.kdtree_distance(a,b_idx,size);
359 template <
typename U,
typename V>
360 inline DistanceType
accum_dist(
const U a,
const V b,
int )
const
368 template<
class T,
class DataSource>
375 template<
class T,
class DataSource>
382 template<
class T,
class DataSource>
400 leaf_max_size(_leaf_max_size), dim(dim_)
411 SearchParams(
int checks_IGNORED_ = 32,
float eps_ = 0,
bool sorted_ =
true ) :
412 checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {}
431 template <
typename T>
434 T* mem = (T*) ::malloc(
sizeof(T)*
count);
502 while (base != NULL) {
503 void *prev = *((
void**) base);
520 const size_t size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
525 if (size > remaining) {
527 wastedMemory += remaining;
530 const size_t blocksize = (size +
sizeof(
void*) + (WORDSIZE-1) >
BLOCKSIZE) ?
531 size +
sizeof(
void*) + (WORDSIZE-1) : BLOCKSIZE;
534 void* m = ::malloc(blocksize);
536 fprintf(stderr,
"Failed to allocate memory.\n");
541 ((
void**) m)[0] = base;
547 remaining = blocksize -
sizeof(
void*) - shift;
548 loc = ((
char*)m +
sizeof(
void*) + shift);
551 loc = (
char*)loc + size;
566 template <
typename T>
569 T* mem = (T*) this->malloc(
sizeof(T)*
count);
605 template <
typename T, std::
size_t N>
621 inline iterator
begin() {
return elems; }
622 inline const_iterator
begin()
const {
return elems; }
623 inline iterator
end() {
return elems+N; }
624 inline const_iterator
end()
const {
return elems+N; }
627 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
630 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
632 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type,
iterator,
633 reference,
iterator, reference> > reverse_iterator;
634 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type,
const_iterator,
635 const_reference,
iterator, reference> > const_reverse_iterator;
638 typedef std::reverse_iterator<iterator,T> reverse_iterator;
639 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
642 reverse_iterator
rbegin() {
return reverse_iterator(
end()); }
643 const_reverse_iterator
rbegin()
const {
return const_reverse_iterator(
end()); }
644 reverse_iterator
rend() {
return reverse_iterator(
begin()); }
645 const_reverse_iterator
rend()
const {
return const_reverse_iterator(
begin()); }
647 inline reference
operator[](size_type i) {
return elems[i]; }
648 inline const_reference
operator[](size_type i)
const {
return elems[i]; }
650 reference
at(size_type i) { rangecheck(i);
return elems[i]; }
651 const_reference
at(size_type i)
const { rangecheck(i);
return elems[i]; }
653 reference
front() {
return elems[0]; }
654 const_reference
front()
const {
return elems[0]; }
655 reference
back() {
return elems[N-1]; }
656 const_reference
back()
const {
return elems[N-1]; }
658 static inline size_type
size() {
return N; }
659 static bool empty() {
return false; }
663 inline void resize(
const size_t nElements) {
if (nElements!=N)
throw std::logic_error(
"Try to change the size of a CArray."); }
667 const T*
data()
const {
return elems; }
676 inline void assign (
const T& value) {
for (
size_t i=0;i<N;i++) elems[i]=value; }
678 void assign (
const size_t n,
const T& value) {
680 for (
size_t i=0;i<n;i++) elems[i]=value;
684 static void rangecheck (size_type i) {
if (i >=
size()) {
throw std::out_of_range(
"CArray<>: index out of range"); } }
690 template <
int DIM,
typename T>
696 template <
typename T>
738 template <
typename Distance,
class DatasetAdaptor,
int DIM = -1,
typename IndexType =
size_t>
816 template <
typename T,
typename DistanceType>
823 BranchStruct(
const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
825 inline bool operator<(const BranchStruct<T, DistanceType>& rhs)
const
827 return mindist<rhs.mindist;
861 dataset(inputData), index_params(params), root_node(NULL), distance(inputData)
863 m_size = dataset.kdtree_get_point_count();
864 dim = dimensionality;
867 if (params.dim>0) dim = params.dim;
869 m_leaf_max_size = params.leaf_max_size;
896 if(m_size == 0)
return;
897 computeBoundingBox(root_bbox);
898 root_node = divideTree(0, m_size, root_bbox );
914 return static_cast<size_t>(DIM>0 ? DIM : dim);
940 template <
typename RESULTSET>
944 if (!root_node)
throw std::runtime_error(
"[nanoflann] findNeighbors() called before building the index or no data points.");
945 float epsError = 1+searchParams.
eps;
947 distance_vector_t
dists;
948 dists.
assign((DIM>0 ? DIM : dim) ,0);
949 DistanceType distsq = computeInitialDistances(vec, dists);
950 searchLevel(result, vec, root_node, distsq, dists, epsError);
959 inline void knnSearch(
const ElementType *query_point,
const size_t num_closest, IndexType *out_indices, DistanceType *out_distances_sq,
const int nChecks_IGNORED = 10)
const
963 resultSet.
init(out_indices, out_distances_sq);
979 size_t radiusSearch(
const ElementType *query_point,
const DistanceType radius, std::vector<std::pair<IndexType,DistanceType> >& IndicesDists,
const SearchParams& searchParams)
const
982 this->findNeighbors(resultSet, query_point, searchParams);
987 return resultSet.
size();
997 m_size = dataset.kdtree_get_point_count();
998 if (vind.size()!=m_size) vind.resize(m_size);
999 for (
size_t i = 0; i < m_size; i++) vind[i] = i;
1004 return dataset.kdtree_get_pt(idx,component);
1011 if (tree->
child1!=NULL) {
1012 save_tree(stream, tree->
child1);
1014 if (tree->
child2!=NULL) {
1015 save_tree(stream, tree->
child2);
1024 if (tree->
child1!=NULL) {
1025 load_tree(stream, tree->
child1);
1027 if (tree->
child2!=NULL) {
1028 load_tree(stream, tree->
child2);
1035 bbox.resize((DIM>0 ? DIM : dim));
1036 if (dataset.kdtree_get_bbox(bbox))
1042 const size_t N = dataset.kdtree_get_point_count();
1043 if (!N)
throw std::runtime_error(
"[nanoflann] computeBoundingBox() called but no data points found.");
1044 for (
int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1046 bbox[i].high = dataset_get(0,i);
1048 for (
size_t k=1; k<N; ++k) {
1049 for (
int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1050 if (dataset_get(k,i)<bbox[i].low) bbox[i].low = dataset_get(k,i);
1051 if (dataset_get(k,i)>bbox[i].high) bbox[i].high = dataset_get(k,i);
1067 NodePtr
divideTree(
const IndexType left,
const IndexType right, BoundingBox& bbox)
1072 if ( (right-left) <= m_leaf_max_size) {
1078 for (
int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1079 bbox[i].low = dataset_get(vind[left],i);
1080 bbox[i].high = dataset_get(vind[left],i);
1082 for (IndexType k=left+1; k<right; ++k) {
1083 for (
int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1084 if (bbox[i].low>dataset_get(vind[k],i)) bbox[i].low=dataset_get(vind[k],i);
1085 if (bbox[i].high<dataset_get(vind[k],i)) bbox[i].high=dataset_get(vind[k],i);
1092 DistanceType cutval;
1093 middleSplit_(&vind[0]+left, right-left, idx, cutfeat, cutval, bbox);
1097 BoundingBox left_bbox(bbox);
1098 left_bbox[cutfeat].high = cutval;
1099 node->
child1 = divideTree(left, left+idx, left_bbox);
1101 BoundingBox right_bbox(bbox);
1102 right_bbox[cutfeat].low = cutval;
1103 node->
child2 = divideTree(left+idx, right, right_bbox);
1105 node->
sub.
divlow = left_bbox[cutfeat].high;
1108 for (
int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1109 bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
1110 bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
1117 void computeMinMax(IndexType* ind, IndexType count,
int element, ElementType& min_elem, ElementType& max_elem)
1119 min_elem = dataset_get(ind[0],element);
1120 max_elem = dataset_get(ind[0],element);
1121 for (IndexType i=1; i<
count; ++i) {
1122 ElementType val = dataset_get(ind[i],element);
1123 if (val<min_elem) min_elem = val;
1124 if (val>max_elem) max_elem = val;
1128 void middleSplit(IndexType* ind, IndexType count, IndexType& index,
int& cutfeat, DistanceType& cutval,
const BoundingBox& bbox)
1131 ElementType max_span = bbox[0].high-bbox[0].low;
1133 cutval = (bbox[0].high+bbox[0].low)/2;
1134 for (
int i=1; i<(DIM>0 ? DIM : dim); ++i) {
1135 ElementType span = bbox[i].low-bbox[i].low;
1136 if (span>max_span) {
1139 cutval = (bbox[i].high+bbox[i].low)/2;
1144 ElementType min_elem, max_elem;
1145 computeMinMax(ind, count, cutfeat, min_elem, max_elem);
1146 cutval = (min_elem+max_elem)/2;
1147 max_span = max_elem - min_elem;
1151 for (
size_t i=0; i<(DIM>0 ? DIM : dim); ++i) {
1153 ElementType span = bbox[i].high-bbox[i].low;
1154 if (span>max_span) {
1155 computeMinMax(ind, count, i, min_elem, max_elem);
1156 span = max_elem - min_elem;
1157 if (span>max_span) {
1160 cutval = (min_elem+max_elem)/2;
1164 IndexType lim1, lim2;
1165 planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
1167 if (lim1>count/2) index = lim1;
1168 else if (lim2<count/2) index = lim2;
1169 else index = count/2;
1173 void middleSplit_(IndexType* ind, IndexType count, IndexType& index,
int& cutfeat, DistanceType& cutval,
const BoundingBox& bbox)
1175 const DistanceType EPS=
static_cast<DistanceType
>(0.00001);
1176 ElementType max_span = bbox[0].high-bbox[0].low;
1177 for (
int i=1; i<(DIM>0 ? DIM : dim); ++i) {
1178 ElementType span = bbox[i].high-bbox[i].low;
1179 if (span>max_span) {
1183 ElementType max_spread = -1;
1185 for (
int i=0; i<(DIM>0 ? DIM : dim); ++i) {
1186 ElementType span = bbox[i].high-bbox[i].low;
1187 if (span>(1-EPS)*max_span) {
1188 ElementType min_elem, max_elem;
1189 computeMinMax(ind, count, cutfeat, min_elem, max_elem);
1190 ElementType spread = max_elem-min_elem;;
1191 if (spread>max_spread) {
1193 max_spread = spread;
1198 DistanceType split_val = (bbox[cutfeat].low+bbox[cutfeat].high)/2;
1199 ElementType min_elem, max_elem;
1200 computeMinMax(ind, count, cutfeat, min_elem, max_elem);
1202 if (split_val<min_elem) cutval = min_elem;
1203 else if (split_val>max_elem) cutval = max_elem;
1204 else cutval = split_val;
1206 IndexType lim1, lim2;
1207 planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
1209 if (lim1>count/2) index = lim1;
1210 else if (lim2<count/2) index = lim2;
1211 else index = count/2;
1224 void planeSplit(IndexType* ind,
const IndexType count,
int cutfeat, DistanceType cutval, IndexType& lim1, IndexType& lim2)
1228 IndexType right = count-1;
1230 while (left<=right && dataset_get(ind[left],cutfeat)<cutval) ++left;
1231 while (right && left<=right && dataset_get(ind[right],cutfeat)>=cutval) --right;
1232 if (left>right || !right)
break;
1233 std::swap(ind[left], ind[right]);
1243 while (left<=right && dataset_get(ind[left],cutfeat)<=cutval) ++left;
1244 while (right && left<=right && dataset_get(ind[right],cutfeat)>cutval) --right;
1245 if (left>right || !right)
break;
1246 std::swap(ind[left], ind[right]);
1256 DistanceType distsq = 0.0;
1258 for (
int i = 0; i < (DIM>0 ? DIM : dim); ++i) {
1259 if (vec[i] < root_bbox[i].low) {
1260 dists[i] = distance.accum_dist(vec[i], root_bbox[i].low, i);
1263 if (vec[i] > root_bbox[i].high) {
1264 dists[i] = distance.accum_dist(vec[i], root_bbox[i].high, i);
1276 template <
class RESULTSET>
1277 void searchLevel(RESULTSET& result_set,
const ElementType* vec,
const NodePtr node, DistanceType mindistsq,
1278 distance_vector_t& dists,
const float epsError)
const
1283 DistanceType worst_dist = result_set.worstDist();
1284 for (IndexType i=node->
lr.
left; i<node->lr.right; ++i) {
1285 const IndexType index = vind[i];
1286 DistanceType dist =
distance(vec, index, (DIM>0 ? DIM : dim));
1287 if (dist<worst_dist) {
1288 result_set.addPoint(dist,vind[i]);
1296 ElementType val = vec[idx];
1297 DistanceType diff1 = val - node->
sub.
divlow;
1298 DistanceType diff2 = val - node->
sub.
divhigh;
1302 DistanceType cut_dist;
1303 if ((diff1+diff2)<0) {
1304 bestChild = node->
child1;
1305 otherChild = node->
child2;
1306 cut_dist = distance.accum_dist(val, node->
sub.
divhigh, idx);
1309 bestChild = node->
child2;
1310 otherChild = node->
child1;
1311 cut_dist = distance.accum_dist( val, node->
sub.
divlow, idx);
1315 searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError);
1317 DistanceType dst = dists[idx];
1318 mindistsq = mindistsq + cut_dist - dst;
1319 dists[idx] = cut_dist;
1320 if (mindistsq*epsError<=result_set.worstDist()) {
1321 searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError);
1338 save_tree(stream, root_node);
1352 load_tree(stream, root_node);
1377 template <
class MatrixType,
int DIM = -1,
class Distance =
nanoflann::metric_L2,
typename IndexType =
size_t>
1381 typedef typename MatrixType::Scalar
num_t;
1382 typedef typename Distance::template traits<num_t,self_t>::distance_t
metric_t;
1391 const size_t dims = mat.cols();
1392 if (DIM>0 && static_cast<int>(dims)!=DIM)
1393 throw std::runtime_error(
"Data set dimensionality does not match the 'DIM' template argument");
1413 inline void query(
const num_t *query_point,
const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq,
const int nChecks_IGNORED = 10)
const
1417 resultSet.
init(out_indices, out_distances_sq);
1433 return m_data_matrix.rows();
1440 for (
size_t i=0; i<
size; i++) {
1441 const num_t d= p1[i]-m_data_matrix.coeff(idx_p2,i);
1449 return m_data_matrix.coeff(idx,dim);
1455 template <
class BBOX>
A simple KD-tree adaptor for working with data directly stored in an Eigen Matrix, without duplicating the data storage.
long double abs< long double >(long double x)
std::reverse_iterator< iterator > reverse_iterator
DistanceType accum_dist(const U a, const V b, int) const
num_t kdtree_get_pt(const size_t idx, int dim) const
PooledAllocator(const size_t blocksize_=BLOCKSIZE)
Default constructor.
KDTreeEigenMatrixAdaptor(const int dimensionality, const MatrixType &mat, const int leaf_max_size=10)
The kd-tree index for the user to call its methods as usual with any other FLANN index.
size_t kdtree_get_point_count() const
size_t size() const
Returns size of index.
void freeIndex()
Frees the previously-built index.
EIGEN_STRONG_INLINE iterator end()
void swap(CArray< T, N > &y)
const DataSource & data_source
Metaprogramming helper traits class for the L2 (Euclidean) metric.
std::vector< IndexType > vind
Array of indices to vectors in the dataset.
Manhattan distance functor (generic version, optimized for high-dimensionality data sets)...
void loadIndex(FILE *stream)
Loads a previous index from a binary file.
Squared Euclidean distance functor (suitable for low-dimensionality datasets, like 2D or 3D point clo...
BranchStruct(const T &aNode, DistanceType dist)
void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int nChecks_IGNORED=10) const
Query for the num_closest closest points to a given point (entered as query_point[0:dim-1]).
void searchLevel(RESULTSET &result_set, const ElementType *vec, const NodePtr node, DistanceType mindistsq, distance_vector_t &dists, const float epsError) const
Performs an exact search in the tree starting from a node.
const DistanceType radius
~PooledAllocator()
Destructor.
double abs< double >(double x)
DistanceType worstDist() const
std::ptrdiff_t difference_type
RadiusResultSet(DistanceType radius_, std::vector< std::pair< IndexType, DistanceType > > &indices_dists)
size_t usedMemory() const
Computes the inde memory usage Returns: memory used by the index.
~KDTreeSingleIndexAdaptor()
Standard destructor.
const KDTreeSingleIndexAdaptorParams index_params
static void rangecheck(size_type i)
reverse_iterator rbegin()
std::pair< IndexType, DistanceType > worst_item() const
Find the worst result (furtherest neighbor) without copying or sorting Pre-conditions: size() > 0...
void init(IndexType *indices_, DistanceType *dists_)
EIGEN_STRONG_INLINE iterator begin()
const Scalar * const_iterator
L2_Simple_Adaptor< T, DataSource > distance_t
float eps
search for eps-approximate neighbours (default: 0)
bool kdtree_get_bbox(BBOX &bb) const
DistanceType accum_dist(const U a, const V b, int) const
void resize(const size_t nElements)
This method has no effects in this class, but raises an exception if the expected size does not match...
L2_Adaptor< T, DataSource > distance_t
L1_Adaptor< T, DataSource > distance_t
void load_value(FILE *stream, T &value, size_t count=1)
Used to declare fixed-size arrays when DIM>0, dynamically-allocated vectors when DIM=-1.
const DataSource & data_source
DistanceType operator()(const T *a, const size_t b_idx, size_t size, DistanceType worst_dist=-1) const
void init_vind()
Make sure the auxiliary list vind has the same size than the current dataset, and re-generate if size...
L2_Adaptor(const DataSource &_data_source)
void addPoint(DistanceType dist, IndexType index)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
array_or_vector_selector< DIM, DistanceType >::container_t distance_vector_t
Define "distance_vector_t" as a fixed-size or variable-size container depending on "DIM"...
int divfeat
Dimension used for subdivision.
const_reference operator[](size_type i) const
static size_type max_size()
std::vector< T > container_t
bool sorted
only for radius search, require neighbours sorted by distance (default: true)
const DatasetAdaptor & dataset
The dataset used by this index.
operator "<" for std::sort()
void middleSplit(IndexType *ind, IndexType count, IndexType &index, int &cutfeat, DistanceType &cutval, const BoundingBox &bbox)
void knnSearch(const ElementType *query_point, const size_t num_closest, IndexType *out_indices, DistanceType *out_distances_sq, const int nChecks_IGNORED=10) const
Find the "num_closest" nearest neighbors to the query_point[0:dim-1].
reference operator[](size_type i)
Distance::DistanceType DistanceType
void middleSplit_(IndexType *ind, IndexType count, IndexType &index, int &cutfeat, DistanceType &cutval, const BoundingBox &bbox)
~KDTreeEigenMatrixAdaptor()
DistanceType accum_dist(const U a, const V b, int) const
bool operator()(const PairType &p1, const PairType &p2) const
PairType will be typically: std::pair
DistanceType worstDist() const
KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size=10, int dim_=-1)
DistanceType operator()(const T *a, const size_t b_idx, size_t size) const
std::vector< std::pair< IndexType, DistanceType > > & m_indices_dists
T * allocate(size_t count=1)
Allocates (using C's malloc) a generic type T.
Distance::ElementType ElementType
reference at(size_type i)
KNNResultSet(CountType capacity_)
void saveIndex(FILE *stream)
Stores the index in a binary file.
A result-set class used when performing a radius based search.
KDTreeSingleIndexAdaptor(const int dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams())
KDTree constructor.
T * allocate(const size_t count=1)
Allocates (using this pool) a generic type T.
A STL container (as wrapper) for arrays of constant size defined at compile time (class imported from...
int checks
Ignored parameter (Kept for compatibility with the FLANN interface).
L1_Adaptor(const DataSource &_data_source)
const_reference front() const
ElementType dataset_get(size_t idx, int component) const
Helper accessor to the dataset points:
void addPoint(DistanceType dist, IndexType index)
IndexType left
Indices of points in leaf node.
void free_all()
Frees all allocated memory chunks.
const self_t & derived() const
KDTreeEigenMatrixAdaptor< MatrixType, DIM, Distance, IndexType > self_t
void planeSplit(IndexType *ind, const IndexType count, int cutfeat, DistanceType cutval, IndexType &lim1, IndexType &lim2)
Subdivide the list of points by a plane perpendicular on axe corresponding to the 'cutfeat' dimension...
This record represents a branch point when finding neighbors in the tree.
_DistanceType DistanceType
array_or_vector_selector< DIM, Interval >::container_t BoundingBox
Define "BoundingBox" as a fixed-size or variable-size container depending on "DIM".
Squared Euclidean distance functor (generic version, optimized for high-dimensionality data sets)...
NodePtr root_node
Array of k-d trees used to find neighbours.
const DataSource & data_source
void assign(const T &value)
Parameters (see http://code.google.com/p/nanoflann/ for help choosing the parameters) ...
const MatrixType & m_data_matrix
_DistanceType DistanceType
void computeMinMax(IndexType *ind, IndexType count, int element, ElementType &min_elem, ElementType &max_elem)
NodePtr divideTree(const IndexType left, const IndexType right, BoundingBox &bbox)
Create a tree node that subdivides the list of vecs from vind[first] to vind[last].
L2_Simple_Adaptor(const DataSource &_data_source)
const_reverse_iterator rend() const
void assign(const size_t n, const T &value)
Distance::template traits< num_t, self_t >::distance_t metric_t
void save_tree(FILE *stream, NodePtr tree)
DistanceType computeInitialDistances(const ElementType *vec, distance_vector_t &dists) const
int dim
Dimensionality of each data point.
const_iterator begin() const
BranchStruct< NodePtr, DistanceType > BranchSt
Search options for KDTreeSingleIndexAdaptor::findNeighbors()
std::reverse_iterator< const_iterator > const_reverse_iterator
const size_t WORDSIZE
Pooled storage allocator.
const_reference back() const
void computeBoundingBox(BoundingBox &bbox)
void save_value(FILE *stream, const T &value, size_t count=1)
void load_tree(FILE *stream, NodePtr &tree)
Node * child1
The child nodes.
PooledAllocator pool
Pooled memory allocator.
void findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParams &searchParams) const
Find set of nearest neighbors to vec[0:dim-1].
size_t veclen() const
Returns the length of an index feature.
Metaprogramming helper traits class for the L1 (Manhattan) metric.
const_reference at(size_type i) const
int BASE_IMPEXP fprintf(FILE *fil, const char *format,...) MRPT_NO_THROWS MRPT_printf_format_check(2
An OS-independent version of fprintf.
void * malloc(const size_t req_size)
Returns a pointer to a piece of new memory of the given size in bytes allocated from the pool...
num_t kdtree_distance(const num_t *p1, const size_t idx_p2, size_t size) const
SearchParams(int checks_IGNORED_=32, float eps_=0, bool sorted_=true)
Note: The first argument (checks_IGNORED_) is ignored, but kept for compatibility with the FLANN inte...
Metaprogramming helper traits class for the L2_simple (Euclidean) metric.
float abs< float >(float x)
_DistanceType DistanceType
void set_radius_and_clear(const DistanceType r)
Clears the result set and adjusts the search radius.
KDTreeSingleIndexAdaptor< metric_t, self_t, DIM, IndexType > index_t
size_t radiusSearch(const ElementType *query_point, const DistanceType radius, std::vector< std::pair< IndexType, DistanceType > > &IndicesDists, const SearchParams &searchParams) const
Find all the neighbors to query_point[0:dim-1] within a maximum radius.
CArray< T, DIM > container_t
const_reverse_iterator rbegin() const
DistanceType divlow
The values used for subdivision.
double BASE_IMPEXP distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
const_iterator end() const
void buildIndex()
Builds the index.
const T & const_reference
DistanceType operator()(const T *a, const size_t b_idx, size_t size, DistanceType worst_dist=-1) const