Medusa  1.1
Coordinate Free Mehless Method implementation
FindClosest.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_DOMAINS_FINDCLOSEST_HPP_
2 #define MEDUSA_BITS_DOMAINS_FINDCLOSEST_HPP_
3 
9 #include "FindClosest_fwd.hpp"
12 
18 namespace mm {
19 
20 template <typename domain_t>
21 void FindClosest::operator()(domain_t& domain) const {
22  // TODO(jureslak): speed up if search among is empty
23  auto for_which = for_which_;
24  if (for_which.empty()) for_which = domain.all();
25  auto search_among = search_among_;
26  if (search_among.empty()) {
27  search_among = Range<int>::seq(domain.size()); // include potential ghost nodes
28  }
29 
30  assert_msg(!domain.positions().empty(), "Cannot find support in an empty domain.");
31  assert_msg(support_size > 0, "Support size must be greater than 0, got %d.", support_size);
32  assert_msg(support_size <= search_among.size(),
33  "Support size (%d) cannot exceed number of points that we are searching among (%d).",
34  support_size, search_among.size());
35  assert_msg(!for_which.empty(), "Set of nodes for which to find the support is empty. "
36  "There appear to be no nodes in domain discretization.");
37  assert_msg(!search_among.empty(), "Set of nodes to search among is empty. "
38  "There appear to be no nodes in domain discretization.");
39  for (int x : for_which) {
40  assert_msg(0 <= x && x < domain.size(), "Index %d out of range [%d, %d) in forNodes.",
41  x, 0, domain.size());
42  }
43  for (int x : search_among) {
44  assert_msg(0 <= x && x < domain.size(), "Index %d out of range [%d, %d) in "
45  "searchAmong.", x, 0, domain.size());
46  }
47  KDTree<typename domain_t::vector_t> tree(domain.positions()[search_among]);
48  if (force_self_) {
49  for (int i : for_which) {
50  Range<int> ss = search_among[tree.query(domain.pos(i), support_size).first];
51  if (i != ss[0]) {
52  domain.support(i) = {i};
53  domain.support(i).insert(domain.support(i).end(), ss.begin(), ss.end()-1);
54  } else {
55  domain.support(i) = ss;
56  }
57  }
58  } else {
59  for (int i : for_which) {
60  domain.support(i) = search_among[tree.query(domain.pos(i), support_size).first];
61  }
62  }
63 }
64 
65 } // namespace mm
66 
67 #endif // MEDUSA_BITS_DOMAINS_FINDCLOSEST_HPP_
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
mm::KDTree
Class representing a static k-d tree data structure.
Definition: KDTree_fwd.hpp:36
mm::FindClosest::operator()
void operator()(domain_t &domain) const
Find support for nodes in domain.
Definition: FindClosest.hpp:21
FindClosest_fwd.hpp
mm::Range::seq
static Range seq(V n)
Returns range {0, ..., n-1}.
assert_msg
#define assert_msg(cond,...)
Assert with better error reporting.
Definition: assert.hpp:75
mm::KDTree::query
std::pair< Range< int >, Range< scalar_t > > query(const vec_t &point, int k=1) const
Find k nearest neighbors to given point.
Definition: KDTree.hpp:16
mm::FindClosest::support_size
int support_size
Support size.
Definition: FindClosest_fwd.hpp:25
KDTree.hpp
assert.hpp
mm::FindClosest::search_among_
Range< int > search_among_
Search only among these nodes.
Definition: FindClosest_fwd.hpp:27
mm::FindClosest::for_which_
Range< int > for_which_
Find support only for these nodes.
Definition: FindClosest_fwd.hpp:26
mm::FindClosest::force_self_
bool force_self_
Force each node as the first element of its support.
Definition: FindClosest_fwd.hpp:28
mm::Range< int >