23 #ifndef SKELETON_BLOCKER_LINK_COMPLEX_H_ 24 #define SKELETON_BLOCKER_LINK_COMPLEX_H_ 26 #include <gudhi/Skeleton_blocker_complex.h> 27 #include <gudhi/Debug_utils.h> 31 namespace skeleton_blocker {
33 template<
class ComplexType>
class Skeleton_blocker_sub_complex;
41 template<
typename ComplexType>
45 typedef typename ComplexType::Edge_handle Edge_handle;
47 typedef typename ComplexType::boost_vertex_handle boost_vertex_handle;
50 bool only_superior_vertices_;
53 typedef typename ComplexType::Vertex_handle Vertex_handle;
54 typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
56 typedef typename ComplexType::Simplex Simplex;
57 typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
61 typedef typename ComplexType::Root_simplex_handle::Simplex_vertex_const_iterator Root_simplex_handle_iterator;
64 : only_superior_vertices_(only_superior_vertices) { }
72 const Simplex& alpha_parent_adress,
73 bool only_superior_vertices =
false,
74 bool only_vertices =
false)
75 : only_superior_vertices_(only_superior_vertices) {
76 if (!alpha_parent_adress.empty())
77 build_link(parent_complex, alpha_parent_adress, only_vertices);
85 Vertex_handle a_parent_adress,
86 bool only_superior_vertices =
false)
87 : only_superior_vertices_(only_superior_vertices) {
88 Simplex alpha_simplex(a_parent_adress);
97 Edge_handle edge,
bool only_superior_vertices =
99 : only_superior_vertices_(only_superior_vertices) {
100 Simplex alpha_simplex(parent_complex.first_vertex(edge),
101 parent_complex.second_vertex(edge));
111 void compute_link_vertices(
const ComplexType & parent_complex,
112 const Simplex& alpha_parent_adress,
113 bool only_superior_vertices,
114 bool is_alpha_blocker =
false) {
115 if (alpha_parent_adress.dimension() == 0) {
118 this->compute_link_vertices(parent_complex,
119 alpha_parent_adress.first_vertex(),
120 only_superior_vertices_);
123 Simplex link_vertices_parent;
124 parent_complex.add_neighbours(alpha_parent_adress, link_vertices_parent,
125 only_superior_vertices);
128 for (
auto v_parent : link_vertices_parent) {
129 bool new_vertex =
true;
130 for (
auto beta : parent_complex.const_blocker_range(v_parent)) {
131 if (!is_alpha_blocker || *beta != alpha_parent_adress) {
132 new_vertex = !(alpha_parent_adress.contains_difference(*beta,
139 this->
add_vertex(parent_complex.get_id(v_parent));
149 void compute_link_vertices(
const ComplexType & parent_complex,
150 Vertex_handle alpha_parent_adress,
151 bool only_superior_vertices) {
153 this->skeleton.m_vertices.reserve(
154 parent_complex.degree(alpha_parent_adress));
158 for (
auto v_parent : parent_complex.vertex_range(alpha_parent_adress)) {
159 if (!only_superior_vertices
160 || v_parent.vertex > alpha_parent_adress.vertex)
161 this->
add_vertex(parent_complex.get_id(v_parent));
165 void compute_link_edges(
const ComplexType & parent_complex,
166 const Simplex& alpha_parent_adress,
167 bool is_alpha_blocker =
false) {
168 if (this->num_vertices() <= 1)
173 for (
auto y_link = x_link; ++y_link != this->
vertex_range().end();) {
174 Vertex_handle x_parent = *parent_complex.get_address(
176 Vertex_handle y_parent = *parent_complex.get_address(
178 if (parent_complex.contains_edge(x_parent, y_parent)) {
180 bool new_edge =
true;
181 for (
auto blocker_parent : parent_complex.const_blocker_range(
183 if (!is_alpha_blocker || *blocker_parent != alpha_parent_adress) {
184 if (blocker_parent->contains(y_parent)) {
185 new_edge = !(alpha_parent_adress.contains_difference(
186 *blocker_parent, x_parent, y_parent));
204 boost::optional<Vertex_handle> give_equivalent_vertex(
const ComplexType & other_complex,
205 Vertex_handle address)
const {
206 Root_vertex_handle id((*
this)[address].
get_id());
207 return other_complex.get_address(
id);
215 void compute_link_blockers(
const ComplexType & parent_complex,
216 const Simplex& alpha_parent,
217 bool is_alpha_blocker =
false) {
219 Vertex_handle x_parent = *this->give_equivalent_vertex(parent_complex,
222 for (
auto blocker_parent : parent_complex.const_blocker_range(x_parent)) {
223 if (!is_alpha_blocker || *blocker_parent != alpha_parent) {
224 Simplex sigma_parent(*blocker_parent);
226 sigma_parent.difference(alpha_parent);
228 if (sigma_parent.dimension() >= 2
229 && sigma_parent.first_vertex() == x_parent) {
230 Root_simplex_handle sigma_id(parent_complex.get_id(sigma_parent));
234 bool is_new_blocker =
true;
235 for (
auto a : alpha_parent) {
236 for (
auto eta_parent : parent_complex.const_blocker_range(a)) {
237 if (!is_alpha_blocker || *eta_parent != alpha_parent) {
238 Simplex eta_minus_alpha(*eta_parent);
239 eta_minus_alpha.difference(alpha_parent);
240 if (eta_minus_alpha != sigma_parent
241 && sigma_parent.contains_difference(*eta_parent,
243 is_new_blocker =
false;
267 const Simplex& alpha_parent_adress,
268 bool is_alpha_blocker =
false,
269 bool only_vertices =
false) {
270 assert(is_alpha_blocker || parent_complex.contains(alpha_parent_adress));
271 compute_link_vertices(parent_complex, alpha_parent_adress, only_superior_vertices_);
272 if (!only_vertices) {
273 compute_link_edges(parent_complex, alpha_parent_adress, is_alpha_blocker);
274 compute_link_blockers(parent_complex, alpha_parent_adress, is_alpha_blocker);
286 assert(blocker.dimension() >= 2);
287 assert(parent_complex.contains_blocker(blocker));
289 result.
build_link(parent_complex, blocker,
true);
295 namespace skbl = skeleton_blocker;
299 #endif // SKELETON_BLOCKER_LINK_COMPLEX_H_ Simplicial subcomplex of a complex represented by a skeleton/blockers pair.
Definition: Skeleton_blocker_link_superior.h:32
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:50
void add_blocker(const Root_simplex_handle &blocker_root)
Definition: Skeleton_blocker_sub_complex.h:124
Skeleton_blocker_link_complex(const ComplexType &parent_complex, const Simplex &alpha_parent_adress, bool only_superior_vertices=false, bool only_vertices=false)
Definition: Skeleton_blocker_link_complex.h:71
Skeleton_blocker_link_complex(const ComplexType &parent_complex, Vertex_handle a_parent_adress, bool only_superior_vertices=false)
Definition: Skeleton_blocker_link_complex.h:84
Class representing the link of a simplicial complex encoded by a skeleton/blockers pair...
Definition: Skeleton_blocker_link_complex.h:42
Definition: SimplicialComplexForAlpha.h:26
Class representing the link of a simplicial complex encoded by a skeleton/blockers pair...
Definition: Skeleton_blocker_link_superior.h:39
Root_vertex_handle get_id(Vertex_handle local) const
Definition: Skeleton_blocker_complex.h:455
Skeleton_blocker_link_complex(const ComplexType &parent_complex, Edge_handle edge, bool only_superior_vertices=false)
Definition: Skeleton_blocker_link_complex.h:96
void build_link(const ComplexType &parent_complex, const Simplex &alpha_parent_adress, bool is_alpha_blocker=false, bool only_vertices=false)
compute vertices, edges and blockers of the link.
Definition: Skeleton_blocker_link_complex.h:266
friend void build_link_of_blocker(const ComplexType &parent_complex, Simplex &blocker, Skeleton_blocker_link_complex &result)
build the link of a blocker which is the link of the blocker's simplex if this simplex had been remov...
Definition: Skeleton_blocker_link_complex.h:283
void add_edge_without_blockers(Root_vertex_handle v1_root, Root_vertex_handle v2_root)
Definition: Skeleton_blocker_sub_complex.h:112
boost::optional< Simplex > get_simplex_address(const Root_simplex_handle &s) const
Compute the local vertices of 's' in the current complex If one of them is not present in the complex...
Definition: Skeleton_blocker_complex.h:931
Vertex_handle add_vertex()
Adds a vertex to the simplicial complex and returns its Vertex_handle.
Definition: Skeleton_blocker_complex.h:384
Complex_vertex_range vertex_range() const
Returns a Complex_vertex_range over all vertices of the complex.
Definition: Skeleton_blocker_complex.h:1296
void clear()
Definition: Skeleton_blocker_sub_complex.h:168