11#ifndef NEIGHBORS_FINDER_H_
12#define NEIGHBORS_FINDER_H_
15#include <CGAL/Kd_tree.h>
16#include <CGAL/Search_traits.h>
18#include <gudhi/Persistence_graph.h>
19#include <gudhi/Internal_point.h>
21#include <unordered_set>
28namespace persistence_diagram {
33 typedef CGAL::Dimension_tag<2> D;
34 typedef Internal_point Point_d;
36 bool contains(Point_d p)
const {
37 return (std::max)(std::abs(p.x()-c.x()), std::abs(p.y()-c.y())) <= size;
39 bool inner_range_intersects(CGAL::Kd_tree_rectangle<FT, D>
const&r)
const {
41 r.max_coord(0) >= c.x() - size &&
42 r.min_coord(0) <= c.x() + size &&
43 r.max_coord(1) >= c.y() - size &&
44 r.min_coord(1) <= c.y() + size;
46 bool outer_range_contains(CGAL::Kd_tree_rectangle<FT, D>
const&r)
const {
48 r.min_coord(0) >= c.x() - size &&
49 r.max_coord(0) <= c.x() + size &&
50 r.min_coord(1) >= c.y() - size &&
51 r.max_coord(1) <= c.y() + size;
65class Neighbors_finder {
66 typedef CGAL::Dimension_tag<2> D;
67 typedef CGAL::Search_traits<double, Internal_point, const double*, Construct_coord_iterator, D> Traits;
68 typedef CGAL::Kd_tree<Traits> Kd_tree;
72 Neighbors_finder(
const Persistence_graph& g,
double r);
74 void add(
int v_point_index);
77 int pull_near(
int u_point_index);
79 std::vector<int> pull_all_near(
int u_point_index);
82 const Persistence_graph& g;
85 std::unordered_set<int> projections_f;
96class Layered_neighbors_finder {
99 Layered_neighbors_finder(
const Persistence_graph& g,
double r);
101 void add(
int v_point_index,
int vlayer);
104 int pull_near(
int u_point_index,
int vlayer);
106 int vlayers_number()
const;
109 const Persistence_graph& g;
111 std::vector<std::unique_ptr<Neighbors_finder>> neighbors_finder;
114inline Neighbors_finder::Neighbors_finder(
const Persistence_graph& g,
double r) :
115 g(g), r(r), kd_t(), projections_f() { }
117inline void Neighbors_finder::add(
int v_point_index) {
118 if (g.on_the_v_diagonal(v_point_index))
119 projections_f.emplace(v_point_index);
121 kd_t.insert(g.get_v_point(v_point_index));
124inline int Neighbors_finder::pull_near(
int u_point_index) {
126 int c = g.corresponding_point_in_v(u_point_index);
127 if (g.on_the_u_diagonal(u_point_index) && !projections_f.empty()) {
129 tmp = *projections_f.cbegin();
130 projections_f.erase(tmp);
131 }
else if (projections_f.count(c) && (g.distance(u_point_index, c) <= r)) {
134 projections_f.erase(tmp);
137 Internal_point u_point = g.get_u_point(u_point_index);
138 auto neighbor = kd_t.search_any_point(Square_query{u_point, r});
140 return null_point_index();
141 tmp = neighbor->point_index;
142 auto point = g.get_v_point(tmp);
143 int idx = point.point_index;
144 kd_t.remove(point, [idx](Internal_point
const&p){
return p.point_index == idx;});
149inline std::vector<int> Neighbors_finder::pull_all_near(
int u_point_index) {
150 std::vector<int> all_pull;
151 int last_pull = pull_near(u_point_index);
152 while (last_pull != null_point_index()) {
153 all_pull.emplace_back(last_pull);
154 last_pull = pull_near(u_point_index);
159inline Layered_neighbors_finder::Layered_neighbors_finder(
const Persistence_graph& g,
double r) :
160 g(g), r(r), neighbors_finder() { }
162inline void Layered_neighbors_finder::add(
int v_point_index,
int vlayer) {
163 for (
int l = neighbors_finder.size(); l <= vlayer; l++)
164 neighbors_finder.emplace_back(std::unique_ptr<Neighbors_finder>(
new Neighbors_finder(g, r)));
165 neighbors_finder.at(vlayer)->add(v_point_index);
168inline int Layered_neighbors_finder::pull_near(
int u_point_index,
int vlayer) {
169 if (
static_cast<int> (neighbors_finder.size()) <= vlayer)
170 return null_point_index();
171 return neighbors_finder.at(vlayer)->pull_near(u_point_index);
174inline int Layered_neighbors_finder::vlayers_number()
const {
175 return static_cast<int> (neighbors_finder.size());