Robotics Library  0.7.0
GnatNearestNeighbors.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2009, Markus Rickert
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 // POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 #ifndef RL_MATH_GNATNEARESTNEIGHBORS_H
28 #define RL_MATH_GNATNEARESTNEIGHBORS_H
29 
30 #include <algorithm>
31 #include <iterator>
32 #include <limits>
33 #include <random>
34 #include <type_traits>
35 #include <utility>
36 #include <vector>
37 #include <boost/optional.hpp>
38 
39 namespace rl
40 {
41  namespace math
42  {
52  template<typename MetricT>
54  {
55  private:
56  struct Node;
57 
58  public:
59  typedef const typename MetricT::Value& const_reference;
60 
61  typedef ::std::ptrdiff_t difference_type;
62 
63  typedef typename MetricT::Value& reference;
64 
65  typedef ::std::size_t size_type;
66 
67  typedef typename MetricT::Value value_type;
68 
69  typedef typename MetricT::Distance Distance;
70 
71  typedef MetricT Metric;
72 
73  typedef typename MetricT::Value Value;
74 
75  typedef ::std::pair<Distance, Value> Neighbor;
76 
77  explicit GnatNearestNeighbors(const Metric& metric) :
78  checks(),
79  generator(::std::random_device()()),
80  metric(metric),
81  nodeDataMax(50),
82  nodeDegree(8),
83  nodeDegreeMax(12),
84  nodeDegreeMin(4),
85  root(0, 0, nodeDegree, nodeDataMax, true),
86  values(0)
87  {
88  }
89 
91  checks(),
92  generator(::std::random_device()()),
93  metric(::std::move(metric)),
94  nodeDataMax(50),
95  nodeDegree(8),
96  nodeDegreeMax(12),
97  nodeDegreeMin(4),
98  root(0, 0, nodeDegree, nodeDataMax, true),
99  values(0)
100  {
101  }
102 
103  template<typename InputIterator>
104  GnatNearestNeighbors(InputIterator first, InputIterator last, const Metric& metric) :
105  checks(),
106  generator(::std::random_device()()),
107  metric(metric),
108  nodeDataMax(50),
109  nodeDegree(8),
110  nodeDegreeMax(12),
111  nodeDegreeMin(4),
112  root(first, last, 0, 0, nodeDegree, nodeDataMax, true),
113  values(::std::distance(first, last))
114  {
115  if (this->root.data.size() > this->nodeDataMax && this->root.data.size() > this->root.degree)
116  {
117  this->split(this->root);
118  }
119  }
120 
121  template<typename InputIterator>
122  GnatNearestNeighbors(InputIterator first, InputIterator last, Metric&& metric = Metric()) :
123  checks(),
124  generator(::std::random_device()()),
125  metric(::std::move(metric)),
126  nodeDataMax(50),
127  nodeDegree(8),
128  nodeDegreeMax(12),
129  nodeDegreeMin(4),
130  root(first, last, nullptr, 0, 0, nodeDegree, nodeDataMax, true),
131  values(::std::distance(first, last))
132  {
133  if (this->root.data.size() > this->nodeDataMax && this->root.data.size() > this->root.degree)
134  {
135  this->split(this->root);
136  }
137  }
138 
140  {
141  }
142 
143  void clear()
144  {
145  this->root.children.clear();
146  this->root.children.reserve(this->nodeDegree);
147  this->root.data.clear();
148  this->root.data.reserve(this->nodeDataMax + 1);
149  this->values = 0;
150  }
151 
152  ::std::vector<Value> data() const
153  {
154  ::std::vector<Value> data;
155  data.reserve(this->values);
156  this->data(this->root, data);
157  return data;
158  }
159 
160  bool empty() const
161  {
162  return this->root.removed && this->root.data.empty() && this->root.children.empty();
163  }
164 
165  ::boost::optional< ::std::size_t> getChecks() const
166  {
167  return this->checks;
168  }
169 
170  ::std::size_t getNodeDataMax() const
171  {
172  return this->nodeDataMax;
173  }
174 
175  ::std::size_t getNodeDegree() const
176  {
177  return this->nodeDegree;
178  }
179 
180  ::std::size_t getNodeDegreeMax() const
181  {
182  return this->nodeDegreeMax;
183  }
184 
185  ::std::size_t getNodeDegreeMin() const
186  {
187  return this->nodeDegreeMin;
188  }
189 
190  template<typename InputIterator>
191  void insert(InputIterator first, InputIterator last)
192  {
193  if (this->empty())
194  {
195  this->root.data.insert(this->root.data.end(), first, last);
196 
197  if (this->root.data.size() > this->nodeDataMax && this->root.data.size() > this->root.degree)
198  {
199  this->split(this->root);
200  }
201 
202  this->values += ::std::distance(first, last);
203  }
204  else
205  {
206  for (InputIterator i = first; i != last; ++i)
207  {
208  this->push(*i);
209  }
210  }
211  }
212 
213  ::std::vector<Neighbor> nearest(const Value& query, const ::std::size_t& k, const bool& sorted = true) const
214  {
215  return this->search(query, &k, nullptr, sorted);
216  }
217 
218  void push(const Value& value)
219  {
220  this->push(this->root, value);
221  ++this->values;
222  }
223 
224  ::std::vector<Neighbor> radius(const Value& query, const Distance& radius, const bool& sorted = true) const
225  {
226  return this->search(query, nullptr, &radius, sorted);
227  }
228 
229  void seed(const ::std::mt19937::result_type& value)
230  {
231  this->generator.seed(value);
232  }
233 
234  void setChecks(const ::boost::optional< ::std::size_t>& checks)
235  {
236  this->checks = checks;
237  }
238 
239  void setNodeDataMax(const ::std::size_t& nodeDataMax)
240  {
241  this->nodeDataMax = nodeDataMax;
242  }
243 
244  void setNodeDegree(const ::std::size_t& nodeDegree)
245  {
246  this->nodeDegree = nodeDegree;
247  }
248 
249  void setNodeDegreeMax(const ::std::size_t& nodeDegreeMax)
250  {
251  this->nodeDegreeMax = nodeDegreeMax;
252  }
253 
254  void setNodeDegreeMin(const ::std::size_t& nodeDegreeMin)
255  {
256  this->nodeDegreeMin = nodeDegreeMin;
257  }
258 
259  ::std::size_t size() const
260  {
261  return this->values;
262  }
263 
265  {
267  swap(this->generator, other.generator);
268  swap(this->metric, other.metric);
269  swap(this->nodeDegree, other.nodeDegree);
270  swap(this->nodeDegreeMax, other.nodeDegreeMax);
271  swap(this->nodeDegreeMin, other.nodeDegreeMin);
272  swap(this->nodeDataMax, other.nodeDataMax);
273  swap(this->root, other.root);
274  swap(this->values, other.values);
275  }
276 
278  {
279  lhs.swap(rhs);
280  }
281 
282  protected:
283 
284  private:
285  typedef ::std::pair<Distance, const Node*> Branch;
286 
288  {
289  bool operator()(const Branch& lhs, const Branch& rhs) const
290  {
291  return lhs.first - lhs.second->max[lhs.second->index] > rhs.first - rhs.second->max[rhs.second->index];
292  }
293  };
294 
296  {
297  bool operator()(const Neighbor& lhs, const Neighbor& rhs) const
298  {
299  return lhs.first < rhs.first;
300  }
301  };
302 
303  struct Node
304  {
305  Node(const ::std::size_t& index, const ::std::size_t& siblings, const ::std::size_t& degree, const ::std::size_t& capacity, const bool& removed = false) :
306  children(),
307  data(),
308  degree(degree),
309  index(index),
310  max(siblings + 1, -::std::numeric_limits<Distance>::infinity()),
311  min(siblings + 1, ::std::numeric_limits<Distance>::infinity()),
312  pivot(),
314  {
315  this->children.reserve(degree);
316  this->data.reserve(capacity + 1);
317  }
318 
319  template<typename InputIterator>
320  Node(InputIterator first, InputIterator last, const ::std::size_t& index, const ::std::size_t& siblings, const ::std::size_t& degree, const ::std::size_t& capacity, const bool& removed = false) :
321  children(),
322  data(first, last),
323  degree(degree),
324  index(index),
325  max(siblings + 1, -::std::numeric_limits<Distance>::infinity()),
326  min(siblings + 1, ::std::numeric_limits<Distance>::infinity()),
327  pivot(),
329  {
330  this->children.reserve(degree);
331  this->data.reserve(capacity + 1);
332  }
333 
335  {
336  }
337 
338  void swap(Node& other)
339  {
341  swap(this->children, other.children);
342  swap(this->data, other.data);
343  swap(this->degree, other.degree);
344  swap(this->index, other.index);
345  swap(this->max, other.max);
346  swap(this->min, other.min);
347  swap(this->pivot, other.pivot);
348  swap(this->removed, other.removed);
349  }
350 
351  friend void swap(Node& lhs, Node& rhs)
352  {
353  lhs.swap(rhs);
354  }
355 
356  ::std::vector<Node> children;
357 
358  ::std::vector<Value> data;
359 
360  ::std::size_t degree;
361 
362  ::std::size_t index;
363 
364  ::std::vector<Distance> max;
365 
366  ::std::vector<Distance> min;
367 
369 
370  bool removed;
371  };
372 
373  void choose(const Node& node, ::std::vector< ::std::size_t>& centers, ::std::vector< ::std::vector<Distance>>& distances)
374  {
375  ::std::size_t k = node.degree;
376  ::std::vector<Distance> min(node.data.size(), ::std::numeric_limits<Distance>::infinity());
377 
378  ::std::uniform_int_distribution< ::std::size_t> distribution(0, node.data.size() - 1);
379  centers[0] = distribution(this->generator);
380 
381  for (::std::size_t i = 0; i < k - 1; ++i)
382  {
383  Distance max = Distance();
384 
385  for (::std::size_t j = 0; j < node.data.size(); ++j)
386  {
387  distances[i][j] = j != centers[i] ? this->metric(node.data[j], node.data[centers[i]]) : 0;
388  min[j] = ::std::min(min[j], distances[i][j]);
389 
390  if (min[j] > max)
391  {
392  max = min[j];
393  centers[i + 1] = j;
394  }
395  }
396  }
397 
398  for (::std::size_t j = 0; j < node.data.size(); ++j)
399  {
400  distances[k - 1][j] = this->metric(node.data[j], node.data[centers[k - 1]]);
401  }
402  }
403 
404  void data(const Node& node, ::std::vector<Value>& data) const
405  {
406  data.insert(data.end(), node.data.begin(), node.data.end());
407 
408  for (::std::size_t i = 0; i < node.children.size(); ++i)
409  {
410  data.push_back(node.children[i].pivot);
411  this->data(node.children[i], data);
412  }
413  }
414 
415  void push(Node& node, const Value& value)
416  {
417  if (node.children.empty())
418  {
419  node.data.push_back(value);
420 
421  if (node.data.size() > this->nodeDataMax && node.data.size() > node.degree)
422  {
423  this->split(node);
424  }
425  }
426  else
427  {
428  ::std::vector<Distance> distances(node.children.size());
429  ::std::size_t index = 0;
430  Distance min = ::std::numeric_limits<Distance>::infinity();
431 
432  for (::std::size_t i = 0; i < node.children.size(); ++i)
433  {
434  distances[i] = this->metric(value, node.children[i].pivot);
435 
436  if (distances[i] < min)
437  {
438  index = i;
439  min = distances[i];
440  }
441  }
442 
443  for (::std::size_t i = 0; i < node.children.size(); ++i)
444  {
445  node.children[i].max[index] = ::std::max(node.children[i].max[index], distances[i]);
446  node.children[i].min[index] = ::std::min(node.children[i].min[index], distances[i]);
447  }
448 
449  this->push(node.children[index], value);
450  }
451  }
452 
453  ::std::vector<Neighbor> search(const Value& query, const ::std::size_t* k, const Distance* radius, const bool& sorted) const
454  {
455  ::std::vector<Neighbor> neighbors;
456  neighbors.reserve(nullptr != k ? *k : this->values);
457 
458  ::std::size_t checks = 0;
459 
460  ::std::vector<Branch> branches;
461  this->search(this->root, query, k, radius, branches, neighbors, checks);
462 
463  while (!branches.empty() && (!this->checks || checks < this->checks))
464  {
465  Branch branch = branches.front();
466  ::std::pop_heap(branches.begin(), branches.end(), BranchCompare());
467  branches.pop_back();
468 
469  if (nullptr == k || *k == neighbors.size())
470  {
471  Distance distance = nullptr != radius ? *radius : neighbors.front().first;
472 
473  if (branch.first - distance > branch.second->max[branch.second->index] ||
474  branch.first + distance < branch.second->min[branch.second->index])
475  {
476  continue;
477  }
478  }
479 
480  this->search(*branch.second, query, k, radius, branches, neighbors, checks);
481  }
482 
483  if (sorted)
484  {
485  ::std::sort_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
486  }
487 
488  if (nullptr == k)
489  {
490  neighbors.shrink_to_fit();
491  }
492 
493  return neighbors;
494  }
495 
496  void search(const Node& node, const Value& query, const ::std::size_t* k, const Distance* radius, ::std::vector<Branch>& branches, ::std::vector<Neighbor>& neighbors, ::std::size_t& checks) const
497  {
498  if (node.children.empty())
499  {
500  for (::std::size_t i = 0; i < node.data.size(); ++i)
501  {
502  Distance distance = this->metric(query, node.data[i]);
503 
504  if (nullptr == k || neighbors.size() < *k || distance < neighbors.front().first)
505  {
506  if (nullptr == radius || distance < *radius)
507  {
508  if (nullptr != k && *k == neighbors.size())
509  {
510  ::std::pop_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
511  neighbors.pop_back();
512  }
513 
514 #if (defined(_MSC_VER) && _MSC_VER < 1800) || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8)
515  neighbors.push_back(::std::make_pair(distance, node.data[i]));
516 #else
517  neighbors.emplace_back(::std::piecewise_construct, ::std::forward_as_tuple(distance), ::std::forward_as_tuple(node.data[i]));
518 #endif
519  ::std::push_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
520  }
521  }
522 
523  if (this->checks && ++checks > this->checks)
524  {
525  return;
526  }
527  }
528  }
529  else
530  {
531  ::std::vector<Distance> distances(node.children.size());
532  ::std::vector<bool> removed(node.children.size(), false);
533 
534  for (::std::size_t i = 0; i < node.children.size(); ++i)
535  {
536  if (!removed[i])
537  {
538  distances[i] = this->metric(query, node.children[i].pivot);
539 
540  if (!node.children[i].removed)
541  {
542  if (nullptr == k || neighbors.size() < *k || distances[i] < neighbors.front().first)
543  {
544  if (nullptr == radius || distances[i] < *radius)
545  {
546  if (nullptr != k && *k == neighbors.size())
547  {
548  ::std::pop_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
549  neighbors.pop_back();
550  }
551 
552 #if (defined(_MSC_VER) && _MSC_VER < 1800) || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8)
553  neighbors.push_back(::std::make_pair(distances[i], node.children[i].pivot));
554 #else
555  neighbors.emplace_back(::std::piecewise_construct, ::std::forward_as_tuple(distances[i]), ::std::forward_as_tuple(node.children[i].pivot));
556 #endif
557  ::std::push_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
558  }
559  }
560  }
561 
562  if (nullptr == k || *k == neighbors.size())
563  {
564  Distance distance = nullptr != radius ? *radius : neighbors.front().first;
565 
566  for (::std::size_t j = 0; j < node.children.size(); ++j)
567  {
568  if (i != j && !removed[j])
569  {
570  if (distances[i] - distance > node.children[i].max[j] ||
571  distances[i] + distance < node.children[i].min[j])
572  {
573  removed[j] = true;
574  }
575  }
576  }
577  }
578 
579  if (this->checks && ++checks > this->checks)
580  {
581  return;
582  }
583  }
584  }
585 
586  for (::std::size_t i = 0; i < node.children.size(); ++i)
587  {
588  if (!removed[i])
589  {
590  Distance distance = nullptr != radius ? *radius : neighbors.front().first;
591 
592  if (distances[i] - distance <= node.children[i].max[i] &&
593  distances[i] + distance >= node.children[i].min[i])
594  {
595 #if defined(_MSC_VER) && _MSC_VER < 1800
596  branches.push_back(::std::make_pair(distances[i], &node.children[i]));
597 #else
598  branches.emplace_back(distances[i], &node.children[i]);
599 #endif
600  ::std::push_heap(branches.begin(), branches.end(), BranchCompare());
601  }
602  }
603  }
604  }
605  }
606 
607  void split(Node& node)
608  {
609 
610  ::std::vector< ::std::vector<Distance>> distances(node.degree, ::std::vector<Distance>(node.data.size()));
611  ::std::vector< ::std::size_t> centers(node.degree);
612  this->choose(node, centers, distances);
613 
614  for (::std::size_t i = 0; i < centers.size(); ++i)
615  {
616 #if defined(_MSC_VER) && _MSC_VER < 1800
617  node.children.push_back(Node(i, node.degree - 1, this->nodeDegree, this->nodeDataMax));
618 #else
619  node.children.emplace_back(i, node.degree - 1, this->nodeDegree, this->nodeDataMax);
620 #endif
621  node.children[i].pivot = ::std::move(node.data[centers[i]]);
622  }
623 
624  for (::std::size_t i = 0; i < node.data.size(); ++i)
625  {
626  ::std::size_t index = 0;
627  Distance min = ::std::numeric_limits<Distance>::infinity();
628 
629  for (::std::size_t j = 0; j < centers.size(); ++j)
630  {
631  Distance distance = distances[j][i];
632 
633  if (distance < min)
634  {
635  index = j;
636  min = distance;
637  }
638  }
639 
640  for (::std::size_t j = 0; j < centers.size(); ++j)
641  {
642  if (i != centers[j])
643  {
644  node.children[j].max[index] = ::std::max(node.children[j].max[index], distances[j][i]);
645  node.children[j].min[index] = ::std::min(node.children[j].min[index], distances[j][i]);
646  }
647  }
648 
649  if (i != centers[index])
650  {
651  node.children[index].data.push_back(::std::move(node.data[i]));
652  }
653  }
654 
655  for (::std::size_t i = 0; i < node.children.size(); ++i)
656  {
657  node.children[i].degree = ::std::min(::std::max(this->nodeDegree * node.children[i].data.size() / node.data.size(), this->nodeDegreeMin), this->nodeDegreeMax);
658 
659  if (node.children[i].data.empty())
660  {
661  node.children[i].max[i] = Distance();
662  node.children[i].min[i] = Distance();
663  }
664  }
665 
666  ::std::size_t size = node.data.size();
667 
668  node.data.clear();
669  node.data.shrink_to_fit();
670 
671 #pragma omp parallel for if (size > 2 * this->nodeDataMax)
672 #if defined(_OPENMP) && _OPENMP < 200805
673  for (::std::ptrdiff_t i = 0; i < node.children.size(); ++i)
674 #else
675  for (::std::size_t i = 0; i < node.children.size(); ++i)
676 #endif
677  {
678  if (node.children[i].data.size() > this->nodeDataMax && node.children[i].data.size() > node.children[i].degree)
679  {
680  this->split(node.children[i]);
681  }
682  }
683  }
684 
685  ::boost::optional< ::std::size_t> checks;
686 
687  ::std::mt19937 generator;
688 
690 
691  ::std::size_t nodeDataMax;
692 
693  ::std::size_t nodeDegree;
694 
695  ::std::size_t nodeDegreeMax;
696 
697  ::std::size_t nodeDegreeMin;
698 
699  Node root;
700 
701  ::std::size_t values;
702  };
703  }
704 }
705 
706 #endif // RL_MATH_GNATNEARESTNEIGHBORS_H
rl::math::GnatNearestNeighbors::insert
void insert(InputIterator first, InputIterator last)
Definition: GnatNearestNeighbors.h:191
rl::math::GnatNearestNeighbors::clear
void clear()
Definition: GnatNearestNeighbors.h:143
rl::math::GnatNearestNeighbors::Node::children
::std::vector< Node > children
Definition: GnatNearestNeighbors.h:356
endif
dummy cpp endif() if(CMAKE_SIZEOF_VOID_P EQUAL 4) target_compile_definitions(math INTERFACE -DEIGEN_DONT_ALIGN_STATICALLY) endif() if(NOT CMAKE_VERSION VERSION_LESS 3.8) target_compile_features(math INTERFACE cxx_std_11) endif() target_include_directories(math INTERFACE $< BUILD_INTERFACE
Definition: CMakeLists.txt:66
rl::math::GnatNearestNeighbors::nodeDegreeMax
::std::size_t nodeDegreeMax
Definition: GnatNearestNeighbors.h:695
rl::math::GnatNearestNeighbors::metric
Metric metric
Definition: GnatNearestNeighbors.h:689
rl::math::GnatNearestNeighbors::Node::min
::std::vector< Distance > min
Definition: GnatNearestNeighbors.h:366
rl::math::GnatNearestNeighbors::const_reference
const MetricT::Value & const_reference
Definition: GnatNearestNeighbors.h:56
rl::math::GnatNearestNeighbors::Node
Definition: GnatNearestNeighbors.h:304
rl::math::GnatNearestNeighbors::getNodeDataMax
::std::size_t getNodeDataMax() const
Definition: GnatNearestNeighbors.h:170
rl::math::GnatNearestNeighbors::values
::std::size_t values
Definition: GnatNearestNeighbors.h:701
rl::math::GnatNearestNeighbors::Neighbor
::std::pair< Distance, Value > Neighbor
Definition: GnatNearestNeighbors.h:75
rl::math::GnatNearestNeighbors::search
::std::vector< Neighbor > search(const Value &query, const ::std::size_t *k, const Distance *radius, const bool &sorted) const
Definition: GnatNearestNeighbors.h:453
rl::math::GnatNearestNeighbors::Node::pivot
Value pivot
Definition: GnatNearestNeighbors.h:368
rl::math::GnatNearestNeighbors::GnatNearestNeighbors
GnatNearestNeighbors(InputIterator first, InputIterator last, Metric &&metric=Metric())
Definition: GnatNearestNeighbors.h:122
rl::math::GnatNearestNeighbors::Node::removed
bool removed
Definition: GnatNearestNeighbors.h:370
rl::math::GnatNearestNeighbors::root
Node root
Definition: GnatNearestNeighbors.h:699
rl::math::GnatNearestNeighbors::push
void push(const Value &value)
Definition: GnatNearestNeighbors.h:218
rl::math::GnatNearestNeighbors::Node::data
::std::vector< Value > data
Definition: GnatNearestNeighbors.h:358
rl::math::GnatNearestNeighbors::size_type
::std::size_t size_type
Definition: GnatNearestNeighbors.h:65
rl::math::GnatNearestNeighbors::~GnatNearestNeighbors
~GnatNearestNeighbors()
Definition: GnatNearestNeighbors.h:139
rl::math::GnatNearestNeighbors::checks
::boost::optional< ::std::size_t > checks
Definition: GnatNearestNeighbors.h:685
rl::math::GnatNearestNeighbors::Node::swap
friend void swap(Node &lhs, Node &rhs)
Definition: GnatNearestNeighbors.h:351
rl::math::GnatNearestNeighbors::difference_type
::std::ptrdiff_t difference_type
Definition: GnatNearestNeighbors.h:61
rl::math::GnatNearestNeighbors::Metric
MetricT Metric
Definition: GnatNearestNeighbors.h:71
rl::math::GnatNearestNeighbors::split
void split(Node &node)
Definition: GnatNearestNeighbors.h:607
rl::math::GnatNearestNeighbors::radius
::std::vector< Neighbor > radius(const Value &query, const Distance &radius, const bool &sorted=true) const
Definition: GnatNearestNeighbors.h:224
rl::math::GnatNearestNeighbors::Node::Node
Node(InputIterator first, InputIterator last, const ::std::size_t &index, const ::std::size_t &siblings, const ::std::size_t &degree, const ::std::size_t &capacity, const bool &removed=false)
Definition: GnatNearestNeighbors.h:320
rl::math::GnatNearestNeighbors::getNodeDegreeMin
::std::size_t getNodeDegreeMin() const
Definition: GnatNearestNeighbors.h:185
rl::math::GnatNearestNeighbors::Distance
MetricT::Distance Distance
Definition: GnatNearestNeighbors.h:69
rl::math::GnatNearestNeighbors::empty
bool empty() const
Definition: GnatNearestNeighbors.h:160
rl::math::GnatNearestNeighbors::size
::std::size_t size() const
Definition: GnatNearestNeighbors.h:259
rl::math::GnatNearestNeighbors::setNodeDataMax
void setNodeDataMax(const ::std::size_t &nodeDataMax)
Definition: GnatNearestNeighbors.h:239
rl::math::GnatNearestNeighbors::push
void push(Node &node, const Value &value)
Definition: GnatNearestNeighbors.h:415
rl::math::GnatNearestNeighbors::search
void search(const Node &node, const Value &query, const ::std::size_t *k, const Distance *radius, ::std::vector< Branch > &branches, ::std::vector< Neighbor > &neighbors, ::std::size_t &checks) const
Definition: GnatNearestNeighbors.h:496
rl::math::GnatNearestNeighbors::swap
friend void swap(GnatNearestNeighbors &lhs, GnatNearestNeighbors &rhs)
Definition: GnatNearestNeighbors.h:277
rl::math::GnatNearestNeighbors::seed
void seed(const ::std::mt19937::result_type &value)
Definition: GnatNearestNeighbors.h:229
rl::math::GnatNearestNeighbors::BranchCompare
Definition: GnatNearestNeighbors.h:288
rl::math::GnatNearestNeighbors::Value
MetricT::Value Value
Definition: GnatNearestNeighbors.h:73
rl::math::GnatNearestNeighbors::BranchCompare::operator()
bool operator()(const Branch &lhs, const Branch &rhs) const
Definition: GnatNearestNeighbors.h:289
rl::math::GnatNearestNeighbors::generator
::std::mt19937 generator
Definition: GnatNearestNeighbors.h:687
rl::math::GnatNearestNeighbors::nodeDataMax
::std::size_t nodeDataMax
Definition: GnatNearestNeighbors.h:691
rl::math::GnatNearestNeighbors::swap
void swap(GnatNearestNeighbors &other)
Definition: GnatNearestNeighbors.h:264
std::swap
void swap(::rl::util::rtai::thread &x, ::rl::util::rtai::thread &y)
Definition: thread.h:492
rl::math::GnatNearestNeighbors::value_type
MetricT::Value value_type
Definition: GnatNearestNeighbors.h:67
rl::math::GnatNearestNeighbors::Node::index
::std::size_t index
Definition: GnatNearestNeighbors.h:362
rl::math::GnatNearestNeighbors::nodeDegree
::std::size_t nodeDegree
Definition: GnatNearestNeighbors.h:693
rl::math::GnatNearestNeighbors
Geometric Near-Neighbor Access Tree (GNAT).
Definition: GnatNearestNeighbors.h:54
rl::math::GnatNearestNeighbors::GnatNearestNeighbors
GnatNearestNeighbors(InputIterator first, InputIterator last, const Metric &metric)
Definition: GnatNearestNeighbors.h:104
rl::math::GnatNearestNeighbors::Branch
::std::pair< Distance, const Node * > Branch
Definition: GnatNearestNeighbors.h:285
rl::math::GnatNearestNeighbors::GnatNearestNeighbors
GnatNearestNeighbors(const Metric &metric)
Definition: GnatNearestNeighbors.h:77
rl::math::GnatNearestNeighbors::data
::std::vector< Value > data() const
Definition: GnatNearestNeighbors.h:152
rl::math::GnatNearestNeighbors::data
void data(const Node &node, ::std::vector< Value > &data) const
Definition: GnatNearestNeighbors.h:404
rl::math::GnatNearestNeighbors::GnatNearestNeighbors
GnatNearestNeighbors(Metric &&metric=Metric())
Definition: GnatNearestNeighbors.h:90
rl::math::GnatNearestNeighbors::NeighborCompare::operator()
bool operator()(const Neighbor &lhs, const Neighbor &rhs) const
Definition: GnatNearestNeighbors.h:297
rl::math::GnatNearestNeighbors::Node::Node
Node(const ::std::size_t &index, const ::std::size_t &siblings, const ::std::size_t &degree, const ::std::size_t &capacity, const bool &removed=false)
Definition: GnatNearestNeighbors.h:305
rl::math::GnatNearestNeighbors::Node::degree
::std::size_t degree
Definition: GnatNearestNeighbors.h:360
rl::math::GnatNearestNeighbors::Node::max
::std::vector< Distance > max
Definition: GnatNearestNeighbors.h:364
rl::plan::WorkspaceMetric
Definition: WorkspaceMetric.h:38
std
Definition: thread.h:482
rl::math::GnatNearestNeighbors::nodeDegreeMin
::std::size_t nodeDegreeMin
Definition: GnatNearestNeighbors.h:697
rl::math::GnatNearestNeighbors::reference
MetricT::Value & reference
Definition: GnatNearestNeighbors.h:63
rl::math::GnatNearestNeighbors::setNodeDegreeMin
void setNodeDegreeMin(const ::std::size_t &nodeDegreeMin)
Definition: GnatNearestNeighbors.h:254
rl::math::GnatNearestNeighbors::setChecks
void setChecks(const ::boost::optional< ::std::size_t > &checks)
Definition: GnatNearestNeighbors.h:234
rl::math::GnatNearestNeighbors::NeighborCompare
Definition: GnatNearestNeighbors.h:296
rl::math::GnatNearestNeighbors::getNodeDegree
::std::size_t getNodeDegree() const
Definition: GnatNearestNeighbors.h:175
distance
Scalar distance(const Transform< Scalar, Dim, Mode, Options > &other, const Scalar &weight=1) const
Definition: TransformAddons.h:33
rl::math::GnatNearestNeighbors::setNodeDegreeMax
void setNodeDegreeMax(const ::std::size_t &nodeDegreeMax)
Definition: GnatNearestNeighbors.h:249
rl::math::GnatNearestNeighbors::Node::swap
void swap(Node &other)
Definition: GnatNearestNeighbors.h:338
rl::math::GnatNearestNeighbors::choose
void choose(const Node &node, ::std::vector< ::std::size_t > &centers, ::std::vector< ::std::vector< Distance >> &distances)
Definition: GnatNearestNeighbors.h:373
rl::math::GnatNearestNeighbors::Node::~Node
~Node()
Definition: GnatNearestNeighbors.h:334
rl::math::GnatNearestNeighbors::getChecks
::boost::optional< ::std::size_t > getChecks() const
Definition: GnatNearestNeighbors.h:165
rl::math::GnatNearestNeighbors::nearest
::std::vector< Neighbor > nearest(const Value &query, const ::std::size_t &k, const bool &sorted=true) const
Definition: GnatNearestNeighbors.h:213
rl::math::GnatNearestNeighbors::setNodeDegree
void setNodeDegree(const ::std::size_t &nodeDegree)
Definition: GnatNearestNeighbors.h:244
rl::math::GnatNearestNeighbors::getNodeDegreeMax
::std::size_t getNodeDegreeMax() const
Definition: GnatNearestNeighbors.h:180
rl
Robotics Library.
Definition: AnalogInput.cpp:30