22 #ifndef GUDHI_SKELETON_BLOCKERS_LINK_COMPLEX_H_
23 #define GUDHI_SKELETON_BLOCKERS_LINK_COMPLEX_H_
25 #include "gudhi/Utils.h"
26 #include "gudhi/Skeleton_blocker_complex.h"
32 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;
52 bool only_superior_vertices_;
55 typedef typename ComplexType::Vertex_handle Vertex_handle;
56 typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
58 typedef typename ComplexType::Simplex_handle Simplex_handle;
59 typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
64 typedef typename ComplexType::Simplex_handle::Simplex_vertex_const_iterator Simplex_handle_iterator;
65 typedef typename ComplexType::Root_simplex_handle::Simplex_vertex_const_iterator Root_simplex_handle_iterator;
76 :only_superior_vertices_(only_superior_vertices) {
77 if(!alpha_parent_adress.empty())
78 build_link(parent_complex,alpha_parent_adress);
87 :only_superior_vertices_(only_superior_vertices){
88 Simplex_handle alpha_simplex(a_parent_adress);
98 :only_superior_vertices_(only_superior_vertices){
99 Simplex_handle alpha_simplex(parent_complex.first_vertex(edge),parent_complex.second_vertex(edge));
111 void compute_link_vertices(
const ComplexType & parent_complex,
const Simplex_handle& alpha_parent_adress,
bool only_superior_vertices,
bool is_alpha_blocker =
false){
112 if(alpha_parent_adress.dimension()==0)
115 this->compute_link_vertices(parent_complex,alpha_parent_adress.first_vertex(),only_superior_vertices_);
118 Simplex_handle link_vertices_parent;
119 parent_complex.add_neighbours(alpha_parent_adress,link_vertices_parent,only_superior_vertices);
122 for (
auto v_parent : link_vertices_parent){
123 bool new_vertex =
true;
124 for (
auto beta : parent_complex.const_blocker_range(v_parent))
126 if(!is_alpha_blocker || *beta!=alpha_parent_adress){
127 new_vertex = !(alpha_parent_adress.contains_difference(*beta,v_parent));
128 if(!new_vertex)
break;
132 this->
add_vertex(parent_complex.get_id(v_parent));
143 void compute_link_vertices(
const ComplexType & parent_complex, Vertex_handle alpha_parent_adress,
bool only_superior_vertices){
145 this->skeleton.m_vertices.reserve(parent_complex.degree(alpha_parent_adress));
149 for (
auto v_parent : parent_complex.vertex_range(alpha_parent_adress)){
150 if(!only_superior_vertices || v_parent.vertex> alpha_parent_adress.vertex)
151 this->
add_vertex(parent_complex.get_id(v_parent));
157 void compute_link_edges(
const ComplexType & parent_complex,
const Simplex_handle& alpha_parent_adress,
bool is_alpha_blocker =
false){
158 Simplex_handle_iterator y_link, x_parent , y_parent;
163 if(this->num_vertices()<=1)
return;
170 for (
auto y_link = x_link; ++y_link != this->
vertex_range().end(); ){
171 Vertex_handle x_parent = *parent_complex.get_address(this->
get_id(*x_link));
172 Vertex_handle y_parent = *parent_complex.get_address(this->
get_id(*y_link));
173 if (parent_complex.contains_edge(x_parent,y_parent) ){
176 for (
auto blocker_parent : parent_complex.const_blocker_range(x_parent))
178 if(!is_alpha_blocker || *blocker_parent!=alpha_parent_adress){
179 if (blocker_parent->contains(y_parent))
181 new_edge = !(alpha_parent_adress.contains_difference(*blocker_parent,x_parent,y_parent));
182 if (!new_edge)
break;
199 boost::optional<Vertex_handle> give_equivalent_vertex(
const ComplexType & other_complex,
200 Vertex_handle address)
const{
202 return other_complex.get_address(
id);
210 void compute_link_blockers(
const ComplexType & parent_complex,
const Simplex_handle& alpha_parent,
bool is_alpha_blocker =
false){
214 Vertex_handle x_parent = * this->give_equivalent_vertex(parent_complex,x_link);
216 for (
auto blocker_parent : parent_complex.const_blocker_range(x_parent)){
217 if(!is_alpha_blocker || *blocker_parent!=alpha_parent){
218 Simplex_handle sigma_parent(*blocker_parent);
220 sigma_parent.difference(alpha_parent);
222 if (sigma_parent.dimension()>=2 && sigma_parent.first_vertex() == x_parent){
223 Root_simplex_handle sigma_id(parent_complex.get_id(sigma_parent));
227 bool is_new_blocker =
true;
228 for(
auto a : alpha_parent){
229 for(
auto eta_parent : parent_complex.const_blocker_range(a)){
230 if(!is_alpha_blocker || *eta_parent!=alpha_parent){
231 Simplex_handle eta_minus_alpha(*eta_parent);
232 eta_minus_alpha.difference(alpha_parent);
233 if(eta_minus_alpha != sigma_parent &&
234 sigma_parent.contains_difference(*eta_parent,alpha_parent)){
235 is_new_blocker =
false;
240 if (!is_new_blocker)
break;
243 this->
add_blocker(
new Simplex_handle(*sigma_link));
259 void build_link(
const ComplexType & parent_complex,
const Simplex_handle& alpha_parent_adress,
bool is_alpha_blocker =
false)
261 assert(is_alpha_blocker || parent_complex.contains(alpha_parent_adress));
262 compute_link_vertices(parent_complex,alpha_parent_adress,only_superior_vertices_);
263 compute_link_edges(parent_complex,alpha_parent_adress,is_alpha_blocker);
264 compute_link_blockers(parent_complex,alpha_parent_adress,is_alpha_blocker);
274 const ComplexType & parent_complex,
275 Simplex_handle& blocker,
277 assert(blocker.dimension()>=2);
278 assert(parent_complex.contains_blocker(blocker));
280 result.
build_link(parent_complex,blocker,
true);
Class representing the link of a simplicial complex encoded by a skeleton/blockers pair...
Definition: Skeleton_blocker_link_complex.h:42
Class representing the link of a simplicial complex encoded by a skeleton/blockers pair...
Definition: Skeleton_blocker_link_superior.h:39
void clear()
Definition: Skeleton_blocker_sub_complex.h:194
void add_edge(Root_vertex_handle v1_root, Root_vertex_handle v2_root)
Definition: Skeleton_blocker_sub_complex.h:135
Skeleton_blocker_link_complex(const ComplexType &parent_complex, const Simplex_handle &alpha_parent_adress, bool only_superior_vertices=false)
Definition: Skeleton_blocker_link_complex.h:75
void add_blocker(const Root_simplex_handle &blocker_root)
Definition: Skeleton_blocker_sub_complex.h:147
void build_link(const ComplexType &parent_complex, const Simplex_handle &alpha_parent_adress, bool is_alpha_blocker=false)
compute vertices, edges and blockers of the link.
Definition: Skeleton_blocker_link_complex.h:259
Skeleton_blocker_link_complex(const ComplexType &parent_complex, Edge_handle edge, bool only_superior_vertices=false)
Definition: Skeleton_blocker_link_complex.h:97
Simplicial subcomplex of a complex represented by a skeleton/blockers pair.
Definition: Skeleton_blocker_link_superior.h:31
boost::optional< Simplex_handle > 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:957
Complex_vertex_range vertex_range() const
Returns a Complex_vertex_range over all vertices of the complex.
Definition: Skeleton_blocker_complex.h:1089
Root_vertex_handle get_id(Vertex_handle local) const
Definition: Skeleton_blocker_complex.h:511
Vertex_handle add_vertex()
Adds a vertex to the simplicial complex and returns its Vertex_handle.
Definition: Skeleton_blocker_complex.h:443
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:48
friend void build_link_of_blocker(const ComplexType &parent_complex, Simplex_handle &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:273
Skeleton_blocker_link_complex(const ComplexType &parent_complex, Vertex_handle a_parent_adress, bool only_superior_vertices=false)
Definition: Skeleton_blocker_link_complex.h:86
Root_vertex_handle and Vertex_handle are similar to global and local vertex descriptor used in boost ...
Definition: SkeletonBlockerDS.h:50