11#ifndef SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
12#define SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
14#include <gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h>
22namespace skeleton_blocker {
32template<
typename SkeletonBlockerDS>
35 Skeleton_blocker_link_complex<Skeleton_blocker_complex> link_blocker_sigma;
36 build_link_of_blocker(*
this, *sigma, link_blocker_sigma);
43template<
typename SkeletonBlockerDS>
45 std::list<Vertex_handle> vertex_to_check;
47 vertex_to_check.push_front(v);
49 while (!vertex_to_check.empty()) {
51 vertex_to_check.pop_front();
53 bool blocker_popable_found =
true;
54 while (blocker_popable_found) {
55 blocker_popable_found =
false;
59 if (nv != v) vertex_to_check.push_back(nv);
61 blocker_popable_found =
true;
72template<
typename SkeletonBlockerDS>
74 bool blocker_popable_found =
true;
75 while (blocker_popable_found) {
76 blocker_popable_found =
false;
80 blocker_popable_found =
true;
91template<
typename SkeletonBlockerDS>
93 std::list<Vertex_handle> vertex_to_check;
94 vertex_to_check.push_front(v);
96 while (!vertex_to_check.empty()) {
98 vertex_to_check.pop_front();
100 bool blocker_popable_found =
true;
101 while (blocker_popable_found) {
102 blocker_popable_found =
false;
106 if (nv != v) vertex_to_check.push_back(nv);
108 blocker_popable_found =
true;
119template<
typename SkeletonBlockerDS>
122 update_blockers_after_remove_star_of_vertex_or_edge(
Simplex(v));
123 while (this->
degree(v) > 0) {
124 Vertex_handle w(* (adjacent_vertices(v.vertex, this->skeleton).first));
135template<
typename SkeletonBlockerDS>
136void Skeleton_blocker_complex<SkeletonBlockerDS>::update_blockers_after_remove_star_of_vertex_or_edge(
const Simplex& simplex_to_be_removed) {
137 std::list <Blocker_handle> blockers_to_update;
138 if (simplex_to_be_removed.empty())
return;
141 for (
auto blocker : this->blocker_range(v0)) {
142 if (blocker->contains(simplex_to_be_removed))
143 blockers_to_update.push_back(blocker);
146 for (
auto blocker_to_update : blockers_to_update) {
147 Simplex sub_blocker_to_be_added;
148 bool sub_blocker_need_to_be_added =
149 (blocker_to_update->dimension() - simplex_to_be_removed.
dimension()) >= 2;
150 if (sub_blocker_need_to_be_added) {
151 sub_blocker_to_be_added = *blocker_to_update;
152 sub_blocker_to_be_added.
difference(simplex_to_be_removed);
154 this->delete_blocker(blocker_to_update);
155 if (sub_blocker_need_to_be_added)
156 this->add_blocker(sub_blocker_to_be_added);
163template<
typename SkeletonBlockerDS>
165 update_blockers_after_remove_star_of_vertex_or_edge(
Simplex(a, b));
173template<
typename SkeletonBlockerDS>
181template<
typename SkeletonBlockerDS>
189 remove_blocker_containing_simplex(sigma);
194template<
typename SkeletonBlockerDS>
201 std::cerr <<
"add_simplex: Some vertices were not present in the complex, adding them" << std::endl;
202 size_t num_vertices_to_add = sigma.
last_vertex() - this->num_vertices() + 1;
203 for (
size_t i = 0; i < num_vertices_to_add; ++i)
209 remove_blocker_include_in_simplex(sigma);
210 add_blockers_after_simplex_insertion(sigma);
213template<
typename SkeletonBlockerDS>
214void Skeleton_blocker_complex<SkeletonBlockerDS>::add_blockers_after_simplex_insertion(Simplex sigma) {
217 for (
auto s : coboundary_range(sigma)) {
218 this->add_blocker(s);
225template<
typename SkeletonBlockerDS>
226void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_containing_simplex(
const Simplex& sigma) {
227 std::vector <Blocker_handle> blockers_to_remove;
228 for (
auto blocker : this->blocker_range(sigma.
first_vertex())) {
229 if (blocker->contains(sigma))
230 blockers_to_remove.push_back(blocker);
232 for (
auto blocker_to_update : blockers_to_remove)
233 this->delete_blocker(blocker_to_update);
239template<
typename SkeletonBlockerDS>
240void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_include_in_simplex(
const Simplex& sigma) {
243 std::set <Blocker_handle> blockers_to_remove;
244 for (
auto s : sigma) {
245 for (
auto blocker : this->blocker_range(s)) {
246 if (sigma.contains(*blocker))
247 blockers_to_remove.insert(blocker);
250 for (
auto blocker_to_update : blockers_to_remove) {
251 auto s = *blocker_to_update;
252 this->delete_blocker(blocker_to_update);
256 for (
const auto& b : coboundary_range(s))
257 if (!sigma.contains(b))
258 this->add_blocker(b);
267template<
typename SkeletonBlockerDS>
268void Skeleton_blocker_complex<SkeletonBlockerDS>::tip_blockers(Vertex_handle a, Vertex_handle b,
269 std::vector<Simplex> & buffer)
const {
270 for (
auto const blocker : this->const_blocker_range(a)) {
271 Simplex beta = (*blocker);
273 buffer.push_back(beta);
277 this->add_neighbours(b, n);
278 this->remove_neighbours(a, n);
282 for (Vertex_handle y : n) {
285 buffer.push_back(beta);
297template<
typename SkeletonBlockerDS>
299Skeleton_blocker_complex<SkeletonBlockerDS>::swap_edge(Vertex_handle a, Vertex_handle b, Vertex_handle x) {
300 this->add_edge_without_blockers(a, x);
301 if (this->visitor) this->visitor->on_swaped_edge(a, b, x);
302 this->remove_edge(b, x);
305template<
typename SkeletonBlockerDS>
307Skeleton_blocker_complex<SkeletonBlockerDS>::delete_blockers_around_vertex(Vertex_handle v) {
308 std::list <Blocker_handle> blockers_to_delete;
309 for (
auto blocker : this->blocker_range(v)) {
310 blockers_to_delete.push_back(blocker);
312 while (!blockers_to_delete.empty()) {
313 this->remove_blocker(blockers_to_delete.back());
314 blockers_to_delete.pop_back();
321template<
typename SkeletonBlockerDS>
323Skeleton_blocker_complex<SkeletonBlockerDS>::delete_blockers_around_edge(Vertex_handle a, Vertex_handle b) {
324 std::list<Blocker_handle> blocker_to_delete;
325 for (
auto blocker : this->blocker_range(a))
326 if (blocker->contains(b)) blocker_to_delete.push_back(blocker);
327 while (!blocker_to_delete.empty()) {
328 this->delete_blocker(blocker_to_delete.back());
329 blocker_to_delete.pop_back();
338template<
typename SkeletonBlockerDS>
341 assert(this->contains_vertex(a));
342 assert(this->contains_vertex(b));
349 delete_blockers_around_edge(a, b);
351 std::set<Simplex> blockers_to_add;
353 get_blockers_to_be_added_after_contraction(a, b, blockers_to_add);
355 delete_blockers_around_vertices(a, b);
357 update_edges_after_contraction(a, b);
361 notify_changed_edges(a);
363 for (
auto block : blockers_to_add)
366 assert(this->contains_vertex(a));
367 assert(!this->contains_vertex(b));
370template<
typename SkeletonBlockerDS>
371void Skeleton_blocker_complex<SkeletonBlockerDS>::get_blockers_to_be_added_after_contraction(Vertex_handle a,
373 std::set<Simplex>& blockers_to_add) {
374 blockers_to_add.clear();
378 LinkComplexType link_a(*
this, a);
379 LinkComplexType link_b(*
this, b);
381 std::vector<Simplex> vector_alpha, vector_beta;
383 tip_blockers(a, b, vector_alpha);
384 tip_blockers(b, a, vector_beta);
386 for (
auto alpha = vector_alpha.begin(); alpha != vector_alpha.end(); ++alpha) {
387 for (
auto beta = vector_beta.begin(); beta != vector_beta.end(); ++beta) {
388 Simplex sigma = *alpha;
390 Root_simplex_handle sigma_id = this->get_id(sigma);
391 if (this->contains(sigma) &&
392 proper_faces_in_union<Skeleton_blocker_complex < SkeletonBlockerDS >> (sigma_id, link_a, link_b)) {
395 blockers_to_add.insert(sigma);
404template<
typename SkeletonBlockerDS>
406Skeleton_blocker_complex<SkeletonBlockerDS>::delete_blockers_around_vertices(Vertex_handle a, Vertex_handle b) {
407 std::vector<Blocker_handle> blocker_to_delete;
408 for (
auto bl : this->blocker_range(a))
409 blocker_to_delete.push_back(bl);
410 for (
auto bl : this->blocker_range(b))
411 blocker_to_delete.push_back(bl);
412 while (!blocker_to_delete.empty()) {
413 this->delete_blocker(blocker_to_delete.back());
414 blocker_to_delete.pop_back();
418template<
typename SkeletonBlockerDS>
420Skeleton_blocker_complex<SkeletonBlockerDS>::update_edges_after_contraction(Vertex_handle a, Vertex_handle b) {
422 this->remove_edge(a, b);
426 while (this->degree(b) > 0) {
427 Vertex_handle x(*(adjacent_vertices(b.vertex, this->skeleton).first));
428 if (!this->contains_edge(a, x))
430 this->swap_edge(a, b, x);
432 this->remove_edge(b, x);
436template<
typename SkeletonBlockerDS>
438Skeleton_blocker_complex<SkeletonBlockerDS>::notify_changed_edges(Vertex_handle a) {
440 boost_adjacency_iterator v, v_end;
442 for (tie(v, v_end) = adjacent_vertices(a.vertex, this->skeleton); v != v_end; ++v)
443 if (this->visitor) this->visitor->on_changed_edge(a, Vertex_handle(*v));
449namespace skbl = skeleton_blocker;
virtual contractible_status is_contractible() const
Test if the complex is reducible using a strategy defined in the class (by default it tests if the co...
Definition Skeleton_blocker_complex.h:1162
Complex_blocker_around_vertex_range blocker_range(Vertex_handle v)
Returns a range of the blockers of the complex passing through a vertex.
Definition Skeleton_blocker_complex.h:1469
bool contains_vertices(const Simplex &sigma) const
Definition Skeleton_blocker_complex.h:421
Edge_handle add_edge_without_blockers(Vertex_handle a, Vertex_handle b)
Adds an edge between vertices a and b without blockers.
Definition Skeleton_blocker_complex.h:566
Vertex_handle first_vertex(Edge_handle edge_handle) const
returns the first vertex of an edge
Definition Skeleton_blocker_complex.h:512
virtual Edge_handle remove_edge(Vertex_handle a, Vertex_handle b)
Removes an edge from the simplicial complex and all its cofaces.
Definition Skeleton_blocker_complex.h:596
void contract_edge(Edge_handle edge)
Definition Skeleton_blocker_complex.h:1244
int degree(Vertex_handle local) const
return the graph degree of a vertex.
Definition Skeleton_blocker_complex.h:468
bool link_condition(Vertex_handle a, Vertex_handle b, bool ignore_popable_blockers=false) const
Definition Skeleton_blocker_complex.h:1182
Vertex_handle second_vertex(Edge_handle edge_handle) const
returns the first vertex of an edge
Definition Skeleton_blocker_complex.h:520
void add_simplex(const Simplex &sigma)
add a simplex and all its faces.
Definition Skeleton_blocker_simplifiable_complex.h:195
void remove_all_popable_blockers(Vertex_handle v)
Removes all the popable blockers of the complex passing through v and delete them....
Definition Skeleton_blocker_simplifiable_complex.h:92
virtual bool contains(const Simplex &s) const
returns true iff the simplex s belongs to the simplicial complex.
Definition Skeleton_blocker_complex.h:952
void remove_popable_blockers()
Definition Skeleton_blocker_simplifiable_complex.h:44
Blocker_handle add_blocker(const Simplex &blocker)
Adds the simplex to the set of blockers and returns a Blocker_handle toward it if was not present bef...
Definition Skeleton_blocker_complex.h:669
bool contains_edges(const Simplex &sigma) const
Definition Skeleton_blocker_complex.h:647
Skeleton_blocker_simplex< Vertex_handle > Simplex
A ordered set of integers that represents a simplex.
Definition Skeleton_blocker_complex.h:83
Vertex_handle add_vertex()
Adds a vertex to the simplicial complex and returns its Vertex_handle.
Definition Skeleton_blocker_complex.h:372
Simplex * Blocker_handle
Handle to a blocker of the complex.
Definition Skeleton_blocker_complex.h:89
void remove_star(Vertex_handle v)
Definition Skeleton_blocker_simplifiable_complex.h:120
void delete_blocker(Blocker_handle sigma)
Definition Skeleton_blocker_complex.h:770
bool is_popable_blocker(Blocker_handle sigma) const
Definition Skeleton_blocker_simplifiable_complex.h:33
void remove_vertex(Vertex_handle address)
Remove a vertex from the simplicial complex.
Definition Skeleton_blocker_complex.h:390
Complex_vertex_range vertex_range() const
Returns a Complex_vertex_range over all vertices of the complex.
Definition Skeleton_blocker_complex.h:1282
Edge_handle add_edge(Vertex_handle a, Vertex_handle b)
Adds an edge between vertices a and b.
Definition Skeleton_blocker_complex.h:541
SkeletonBlockerDS::Vertex_handle Vertex_handle
The type of an handle to a vertex of the complex.
Definition Skeleton_blocker_complex.h:77
bool contains_edge(Vertex_handle a, Vertex_handle b) const
Definition Skeleton_blocker_complex.h:638
bool contains_blocker(const Blocker_handle s) const
Definition Skeleton_blocker_complex.h:780
boost::graph_traits< Graph >::edge_descriptor Edge_handle
Handle to an edge of the complex.
Definition Skeleton_blocker_complex.h:114
Class representing the link of a simplicial complex encoded by a skeleton/blockers pair....
Definition Skeleton_blocker_link_complex.h:31
T first_vertex() const
Definition Skeleton_blocker_simplex.h:210
void union_vertices(const Skeleton_blocker_simplex &a)
Definition Skeleton_blocker_simplex.h:155
T last_vertex() const
Definition Skeleton_blocker_simplex.h:220
void remove_vertex(T v)
Definition Skeleton_blocker_simplex.h:117
void difference(const Skeleton_blocker_simplex &a)
Definition Skeleton_blocker_simplex.h:139
int dimension() const
Definition Skeleton_blocker_simplex.h:197
void add_vertex(T v)
Definition Skeleton_blocker_simplex.h:110
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14