|
Robotics Library
0.7.0
|
Go to the documentation of this file.
27 #ifndef RL_MATH_KDTREENEARESTNEIGHBORS_H
28 #define RL_MATH_KDTREENEARESTNEIGHBORS_H
36 #include <type_traits>
39 #include <boost/optional.hpp>
54 template<
typename MetricT>
75 typedef typename MetricT::Size
Size;
77 typedef typename MetricT::Value
Value;
103 template<
typename InputIterator>
113 this->
insert(first, last);
116 template<
typename InputIterator>
126 this->
insert(first, last);
141 ::std::vector<Value>
data()
const
143 ::std::vector<Value>
data;
164 template<
typename InputIterator>
165 void insert(InputIterator first, InputIterator last)
184 for (InputIterator i = first; i != last; ++i)
191 ::std::vector<Neighbor>
nearest(
const Value& query, const ::std::size_t& k,
const bool& sorted =
true)
const
193 return this->
search(query, &k,
nullptr, sorted);
270 return *(begin(other) + this->
index) < this->
value;
282 return lhs.first < rhs.first;
312 ::std::array< ::std::unique_ptr<Node>, 2>
children;
319 void data(
const Node& node, ::std::vector<Value>&
data)
const
321 data.push_back(*node.data);
323 for (::std::size_t i = 0; i < node.children.size(); ++i)
325 this->
data(*node.children[i],
data);
329 template<
typename InputIterator>
330 void divide(Node& node, InputIterator first, InputIterator last)
332 node.cut = this->
select(first, last);
333 InputIterator split = ::std::partition(first, last, node.cut);
335 for (::std::size_t i = 0; i < 2; ++i)
337 #if __cplusplus > 201103L || _MSC_VER >= 1800
338 node.children[i] = ::std::make_unique<Node>();
340 node.children[i].reset(
new Node());
343 InputIterator begin = 0 == i ? first : split;
344 InputIterator end = 0 == i ? split : last;
348 this->
divide(*node.children[i], begin, end);
352 node.children[i]->data = *begin;
362 if (
nullptr == node.children[0] &&
nullptr == node.children[1] && !node.data)
366 else if (
nullptr == node.children[0] &&
nullptr == node.children[1])
368 ::std::size_t dim =
size(value);
371 for (::std::size_t i = 0; i < dim; ++i)
373 Distance span = ::std::abs(*(begin(value) + i) - *(begin(*node.data) + i));
382 for (::std::size_t i = 0; i < 2; ++i)
384 #if __cplusplus > 201103L || _MSC_VER >= 1800
385 node.children[i] = ::std::make_unique<Node>();
387 node.children[i].reset(
new Node());
391 bool less = *(begin(value) + node.cut.index) < *(begin(*node.data) + node.cut.index);
392 node.cut.value = (*(begin(value) + node.cut.index) + *(begin(*node.data) + node.cut.index)) / 2;
394 node.children[0]->cut.index = 0;
395 node.children[0]->data = less ? value : ::std::move(node.data);
396 node.children[1]->cut.index = 0;
397 node.children[1]->data = less ? ::std::move(node.data) : value;
403 if (*(begin(value) + node.cut.index) < node.cut.value)
405 this->
push(*node.children[0], value);
409 this->
push(*node.children[1], value);
418 ::std::vector<Neighbor> neighbors;
419 neighbors.reserve(
nullptr != k ? *k : this->
values);
423 ::std::vector<Branch> branches;
424 ::std::vector<Distance> sidedist(
size(query),
Distance());
427 while (!branches.empty() && (!this->checks || checks < this->
checks))
429 Branch branch = branches.front();
430 ::std::pop_heap(branches.begin(), branches.end(), BranchCompare());
432 this->
search(*branch.node, query, k,
radius, branches, neighbors,
checks, branch.dist, branch.sidedist);
437 ::std::sort_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
442 neighbors.shrink_to_fit();
448 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 Distance& mindist, const ::std::vector<Distance>& sidedist)
const
452 if (
nullptr == node.children[0] &&
nullptr == node.children[1])
458 if (
nullptr == k || neighbors.size() < *k ||
distance < neighbors.front().first)
462 if (
nullptr != k && *k == neighbors.size())
464 ::std::pop_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
465 neighbors.pop_back();
468 #if (defined(_MSC_VER) && _MSC_VER < 1800) || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8)
469 neighbors.push_back(::std::make_pair(
distance, *node.data));
471 neighbors.emplace_back(::std::piecewise_construct, ::std::forward_as_tuple(
distance), ::std::forward_as_tuple(*node.data));
473 ::std::push_heap(neighbors.begin(), neighbors.end(), NeighborCompare());
482 Distance value = *(begin(query) + node.cut.index);
483 Distance diff = value - node.cut.value;
485 ::std::size_t best = diff < 0 ? 0 : 1;
486 ::std::size_t worst = diff < 0 ? 1 : 0;
488 this->
search(*node.children[best], query, k,
radius, branches, neighbors,
checks, mindist, sidedist);
490 Distance cutdist = this->
metric(value, node.cut.value, node.cut.index);
491 Distance newdist = mindist - sidedist[node.cut.index] + cutdist;
493 if (
nullptr == k || neighbors.size() < *k || newdist <= neighbors.front().first)
495 ::std::vector<Distance> newsidedist(sidedist);
496 newsidedist[node.cut.index] = cutdist;
500 this->
search(*node.children[worst], query, k,
radius, branches, neighbors,
checks, newdist, newsidedist);
504 #if defined(_MSC_VER) && _MSC_VER < 1800
505 branches.push_back(Branch(newdist, newsidedist, node.children[worst].get()));
507 branches.emplace_back(newdist, newsidedist, node.children[worst].get());
509 ::std::push_heap(branches.begin(), branches.end(), BranchCompare());
515 template<
typename InputIterator>
516 Cut
select(InputIterator first, InputIterator last)
522 assert(
distance > 0 ||
"mean expects at least one element");
524 ::std::size_t dim =
size(*first);
526 this->
mean.resize(dim);
527 ::std::fill(this->
mean.begin(), this->mean.end(),
Distance());
529 this->
var.resize(dim);
530 ::std::fill(this->
var.begin(), this->var.end(),
Distance());
532 for (InputIterator i = first; i < first +
samples; ++i)
534 for (::std::size_t j = 0; j < dim; ++j)
536 this->
mean[j] += *(begin(*i) + j);
540 for (::std::size_t i = 0; i < dim; ++i)
545 for (InputIterator i = first; i < first +
samples; ++i)
547 for (::std::size_t j = 0; j < dim; ++j)
550 this->
var[j] += d * d;
554 typename ::std::vector<Distance>::iterator max = ::std::max_element(this->
var.begin(), this->var.end());
558 cut.value = this->
mean[cut.index];
562 ::boost::optional< ::std::size_t>
checks;
574 ::std::vector<Distance>
var;
579 #endif // RL_MATH_KDTREENEARESTNEIGHBORS_H
void setSamples(const ::std::size_t &samples)
Definition: KdtreeNearestNeighbors.h:212
MetricT::Value value_type
Definition: KdtreeNearestNeighbors.h:69
void setChecks(const ::boost::optional< ::std::size_t > &checks)
Definition: KdtreeNearestNeighbors.h:207
MetricT::Distance Distance
Definition: KdtreeNearestNeighbors.h:71
::std::vector< Distance > sidedist
Definition: KdtreeNearestNeighbors.h:254
friend void swap(KdtreeNearestNeighbors &lhs, KdtreeNearestNeighbors &rhs)
Definition: KdtreeNearestNeighbors.h:233
::boost::optional< ::std::size_t > checks
Definition: KdtreeNearestNeighbors.h:562
bool operator()(const Branch &lhs, const Branch &rhs) const
Definition: KdtreeNearestNeighbors.h:259
MetricT::Size Size
Definition: KdtreeNearestNeighbors.h:75
~Node()
Definition: KdtreeNearestNeighbors.h:295
::std::vector< Neighbor > nearest(const Value &query, const ::std::size_t &k, const bool &sorted=true) const
Definition: KdtreeNearestNeighbors.h:191
::boost::optional< ::std::size_t > getChecks() const
Definition: KdtreeNearestNeighbors.h:154
KdtreeNearestNeighbors(const Metric &metric)
Definition: KdtreeNearestNeighbors.h:81
::std::array< ::std::unique_ptr< Node >, 2 > children
Definition: KdtreeNearestNeighbors.h:312
::std::size_t size() const
Definition: KdtreeNearestNeighbors.h:217
Node()
Definition: KdtreeNearestNeighbors.h:288
::std::size_t values
Definition: KdtreeNearestNeighbors.h:572
::std::vector< Distance > mean
Definition: KdtreeNearestNeighbors.h:564
bool operator()(const Value &other) const
Definition: KdtreeNearestNeighbors.h:267
Branch(Distance &dist, ::std::vector< Distance > &sidedist, const Node *node)
Definition: KdtreeNearestNeighbors.h:243
MetricT::Value & reference
Definition: KdtreeNearestNeighbors.h:65
bool empty() const
Definition: KdtreeNearestNeighbors.h:149
Distance dist
Definition: KdtreeNearestNeighbors.h:250
Definition: KdtreeNearestNeighbors.h:287
k-d tree.
Definition: KdtreeNearestNeighbors.h:56
const Node * node
Definition: KdtreeNearestNeighbors.h:252
const MetricT::Value & const_reference
Definition: KdtreeNearestNeighbors.h:58
::std::pair< Distance, Value > Neighbor
Definition: KdtreeNearestNeighbors.h:79
::std::size_t samples
Definition: KdtreeNearestNeighbors.h:570
::std::vector< Neighbor > radius(const Value &query, const Distance &radius, const bool &sorted=true) const
Definition: KdtreeNearestNeighbors.h:202
MetricT Metric
Definition: KdtreeNearestNeighbors.h:73
Definition: KdtreeNearestNeighbors.h:242
KdtreeNearestNeighbors(InputIterator first, InputIterator last, Metric &&metric=Metric())
Definition: KdtreeNearestNeighbors.h:117
void swap(::rl::util::rtai::thread &x, ::rl::util::rtai::thread &y)
Definition: thread.h:492
~KdtreeNearestNeighbors()
Definition: KdtreeNearestNeighbors.h:129
Definition: KdtreeNearestNeighbors.h:266
::boost::optional< Value > data
Definition: KdtreeNearestNeighbors.h:316
void swap(Node &other)
Definition: KdtreeNearestNeighbors.h:299
bool operator()(const Neighbor &lhs, const Neighbor &rhs) const
Definition: KdtreeNearestNeighbors.h:280
void insert(InputIterator first, InputIterator last)
Definition: KdtreeNearestNeighbors.h:165
::std::size_t size_type
Definition: KdtreeNearestNeighbors.h:67
Definition: KdtreeNearestNeighbors.h:279
void push(const Value &value)
Definition: KdtreeNearestNeighbors.h:196
Node root
Definition: KdtreeNearestNeighbors.h:568
Size index
Definition: KdtreeNearestNeighbors.h:273
void divide(Node &node, InputIterator first, InputIterator last)
Definition: KdtreeNearestNeighbors.h:330
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 Distance &mindist, const ::std::vector< Distance > &sidedist) const
Definition: KdtreeNearestNeighbors.h:448
Metric metric
Definition: KdtreeNearestNeighbors.h:566
void swap(KdtreeNearestNeighbors &other)
Definition: KdtreeNearestNeighbors.h:222
Cut select(InputIterator first, InputIterator last)
Definition: KdtreeNearestNeighbors.h:516
void push(Node &node, const Value &value)
Definition: KdtreeNearestNeighbors.h:357
MetricT::Value Value
Definition: KdtreeNearestNeighbors.h:77
::std::size_t getSamples() const
Definition: KdtreeNearestNeighbors.h:159
::std::vector< Value > data() const
Definition: KdtreeNearestNeighbors.h:141
::std::ptrdiff_t difference_type
Definition: KdtreeNearestNeighbors.h:63
Distance value
Definition: KdtreeNearestNeighbors.h:275
::std::vector< Distance > var
Definition: KdtreeNearestNeighbors.h:574
KdtreeNearestNeighbors(Metric &&metric=Metric())
Definition: KdtreeNearestNeighbors.h:92
Cut cut
Definition: KdtreeNearestNeighbors.h:314
Definition: KdtreeNearestNeighbors.h:258
KdtreeNearestNeighbors(InputIterator first, InputIterator last, const Metric &metric)
Definition: KdtreeNearestNeighbors.h:104
friend void swap(Node &lhs, Node &rhs)
Definition: KdtreeNearestNeighbors.h:307
void clear()
Definition: KdtreeNearestNeighbors.h:133
::std::vector< Neighbor > search(const Value &query, const ::std::size_t *k, const Distance *radius, const bool &sorted) const
Definition: KdtreeNearestNeighbors.h:414
void data(const Node &node, ::std::vector< Value > &data) const
Definition: KdtreeNearestNeighbors.h:319
Robotics Library.
Definition: AnalogInput.cpp:30