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>
34 assert(this->contains_blocker(*sigma));
36 build_link_of_blocker(*
this, *sigma, link_blocker_sigma);
44template<
typename SkeletonBlockerDS>
46 std::list<Vertex_handle> vertex_to_check;
47 for (
auto v : this->vertex_range())
48 vertex_to_check.push_front(v);
50 while (!vertex_to_check.empty()) {
52 vertex_to_check.pop_front();
54 bool blocker_popable_found =
true;
55 while (blocker_popable_found) {
56 blocker_popable_found =
false;
57 for (
auto block : this->blocker_range(v)) {
58 if (this->is_popable_blocker(block)) {
60 if (nv != v) vertex_to_check.push_back(nv);
61 this->delete_blocker(block);
62 blocker_popable_found =
true;
73template<
typename SkeletonBlockerDS>
75 bool blocker_popable_found =
true;
76 while (blocker_popable_found) {
77 blocker_popable_found =
false;
78 for (
auto block : this->blocker_range(v)) {
79 if (is_popable_blocker(block)) {
80 this->delete_blocker(block);
81 blocker_popable_found =
true;
92template<
typename SkeletonBlockerDS>
94 std::list<Vertex_handle> vertex_to_check;
95 vertex_to_check.push_front(v);
97 while (!vertex_to_check.empty()) {
99 vertex_to_check.pop_front();
101 bool blocker_popable_found =
true;
102 while (blocker_popable_found) {
103 blocker_popable_found =
false;
104 for (
auto block : this->blocker_range(v)) {
105 if (this->is_popable_blocker(block)) {
107 if (nv != v) vertex_to_check.push_back(nv);
108 this->delete_blocker(block);
109 blocker_popable_found =
true;
120template<
typename SkeletonBlockerDS>
123 update_blockers_after_remove_star_of_vertex_or_edge(
Simplex(v));
124 while (this->degree(v) > 0) {
125 Vertex_handle w(* (adjacent_vertices(v.vertex, this->skeleton).first));
126 this->remove_edge(v, w);
128 this->remove_vertex(v);
136template<
typename SkeletonBlockerDS>
138 std::list <Blocker_handle> blockers_to_update;
139 if (simplex_to_be_removed.empty())
return;
142 for (
auto blocker : this->blocker_range(v0)) {
143 if (blocker->contains(simplex_to_be_removed))
144 blockers_to_update.push_back(blocker);
147 for (
auto blocker_to_update : blockers_to_update) {
148 Simplex sub_blocker_to_be_added;
149 bool sub_blocker_need_to_be_added =
150 (blocker_to_update->dimension() - simplex_to_be_removed.dimension()) >= 2;
151 if (sub_blocker_need_to_be_added) {
152 sub_blocker_to_be_added = *blocker_to_update;
153 sub_blocker_to_be_added.difference(simplex_to_be_removed);
155 this->delete_blocker(blocker_to_update);
156 if (sub_blocker_need_to_be_added)
157 this->add_blocker(sub_blocker_to_be_added);
165template<
typename SkeletonBlockerDS>
167 update_blockers_after_remove_star_of_vertex_or_edge(
Simplex(a, b));
169 this->remove_edge(a, b);
175template<
typename SkeletonBlockerDS>
177 return remove_star(this->first_vertex(e), this->second_vertex(e));
183template<
typename SkeletonBlockerDS>
185 assert(this->contains(sigma));
191 remove_blocker_containing_simplex(sigma);
192 this->add_blocker(sigma);
196template<
typename SkeletonBlockerDS>
200 assert(!this->contains(sigma));
202 if (!contains_vertices(sigma)) {
203 std::cerr <<
"add_simplex: Some vertices were not present in the complex, adding them" << std::endl;
204 size_t num_vertices_to_add = sigma.
last_vertex() - this->num_vertices() + 1;
205 for (
size_t i = 0; i < num_vertices_to_add; ++i)
208 assert(contains_vertices(sigma));
209 if (!contains_edges(sigma))
211 remove_blocker_include_in_simplex(sigma);
212 add_blockers_after_simplex_insertion(sigma);
215template<
typename SkeletonBlockerDS>
217 if (sigma.dimension() < 1)
return;
219 for (
auto s : coboundary_range(sigma)) {
220 this->add_blocker(s);
227template<
typename SkeletonBlockerDS>
228void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_containing_simplex(
const Simplex& sigma) {
229 std::vector <Blocker_handle> blockers_to_remove;
230 for (
auto blocker : this->blocker_range(sigma.first_vertex())) {
231 if (blocker->contains(sigma))
232 blockers_to_remove.push_back(blocker);
234 for (
auto blocker_to_update : blockers_to_remove)
235 this->delete_blocker(blocker_to_update);
241template<
typename SkeletonBlockerDS>
242void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_include_in_simplex(
const Simplex& sigma) {
245 std::set <Blocker_handle> blockers_to_remove;
246 for (
auto s : sigma) {
247 for (
auto blocker : this->blocker_range(s)) {
248 if (sigma.contains(*blocker))
249 blockers_to_remove.insert(blocker);
252 for (
auto blocker_to_update : blockers_to_remove) {
253 auto s = *blocker_to_update;
254 this->delete_blocker(blocker_to_update);
258 for (
const auto& b : coboundary_range(s))
259 if (!sigma.contains(b))
260 this->add_blocker(b);
269template<
typename SkeletonBlockerDS>
270void Skeleton_blocker_complex<SkeletonBlockerDS>::tip_blockers(Vertex_handle a, Vertex_handle b,
271 std::vector<Simplex> & buffer)
const {
272 for (
auto const & blocker : this->const_blocker_range(a)) {
273 Simplex beta = (*blocker);
274 beta.remove_vertex(a);
275 buffer.push_back(beta);
279 this->add_neighbours(b, n);
280 this->remove_neighbours(a, n);
284 for (Vertex_handle y : n) {
287 buffer.push_back(beta);
299template<
typename SkeletonBlockerDS>
301Skeleton_blocker_complex<SkeletonBlockerDS>::swap_edge(Vertex_handle a, Vertex_handle b, Vertex_handle x) {
302 this->add_edge_without_blockers(a, x);
303 if (this->visitor) this->visitor->on_swaped_edge(a, b, x);
304 this->remove_edge(b, x);
307template<
typename SkeletonBlockerDS>
309Skeleton_blocker_complex<SkeletonBlockerDS>::delete_blockers_around_vertex(Vertex_handle v) {
310 std::list <Blocker_handle> blockers_to_delete;
311 for (
auto blocker : this->blocker_range(v)) {
312 blockers_to_delete.push_back(blocker);
314 while (!blockers_to_delete.empty()) {
315 this->remove_blocker(blockers_to_delete.back());
316 blockers_to_delete.pop_back();
323template<
typename SkeletonBlockerDS>
325Skeleton_blocker_complex<SkeletonBlockerDS>::delete_blockers_around_edge(Vertex_handle a, Vertex_handle b) {
326 std::list<Blocker_handle> blocker_to_delete;
327 for (
auto blocker : this->blocker_range(a))
328 if (blocker->contains(b)) blocker_to_delete.push_back(blocker);
329 while (!blocker_to_delete.empty()) {
330 this->delete_blocker(blocker_to_delete.back());
331 blocker_to_delete.pop_back();
340template<
typename SkeletonBlockerDS>
343 assert(this->contains_vertex(a));
344 assert(this->contains_vertex(b));
346 if (this->contains_edge(a, b))
347 this->add_edge_without_blockers(a, b);
350 if (!link_condition(a, b))
351 delete_blockers_around_edge(a, b);
353 std::set<Simplex> blockers_to_add;
355 get_blockers_to_be_added_after_contraction(a, b, blockers_to_add);
357 delete_blockers_around_vertices(a, b);
359 update_edges_after_contraction(a, b);
361 this->remove_vertex(b);
363 notify_changed_edges(a);
365 for (
auto block : blockers_to_add)
366 this->add_blocker(block);
368 assert(this->contains_vertex(a));
369 assert(!this->contains_vertex(b));
372template<
typename SkeletonBlockerDS>
375 std::set<Simplex>& blockers_to_add) {
376 blockers_to_add.
clear();
380 LinkComplexType link_a(*
this, a);
381 LinkComplexType link_b(*
this, b);
383 std::vector<Simplex> vector_alpha, vector_beta;
385 tip_blockers(a, b, vector_alpha);
386 tip_blockers(b, a, vector_beta);
388 for (
auto alpha = vector_alpha.begin(); alpha != vector_alpha.end(); ++alpha) {
389 for (
auto beta = vector_beta.begin(); beta != vector_beta.end(); ++beta) {
390 Simplex sigma = *alpha;
391 sigma.union_vertices(*beta);
392 Root_simplex_handle sigma_id = this->get_id(sigma);
393 if (this->contains(sigma) &&
397 blockers_to_add.insert(sigma);
406template<
typename SkeletonBlockerDS>
408Skeleton_blocker_complex<SkeletonBlockerDS>::delete_blockers_around_vertices(Vertex_handle a, Vertex_handle b) {
409 std::vector<Blocker_handle> blocker_to_delete;
410 for (
auto bl : this->blocker_range(a))
411 blocker_to_delete.push_back(bl);
412 for (
auto bl : this->blocker_range(b))
413 blocker_to_delete.push_back(bl);
414 while (!blocker_to_delete.empty()) {
415 this->delete_blocker(blocker_to_delete.back());
416 blocker_to_delete.pop_back();
420template<
typename SkeletonBlockerDS>
422Skeleton_blocker_complex<SkeletonBlockerDS>::update_edges_after_contraction(Vertex_handle a, Vertex_handle b) {
424 this->remove_edge(a, b);
428 while (this->degree(b) > 0) {
429 Vertex_handle x(*(adjacent_vertices(b.vertex, this->skeleton).first));
430 if (!this->contains_edge(a, x))
432 this->swap_edge(a, b, x);
434 this->remove_edge(b, x);
438template<
typename SkeletonBlockerDS>
440Skeleton_blocker_complex<SkeletonBlockerDS>::notify_changed_edges(Vertex_handle a) {
442 boost_adjacency_iterator v, v_end;
444 for (tie(v, v_end) = adjacent_vertices(a.vertex, this->skeleton); v != v_end; ++v)
445 if (this->visitor) this->visitor->on_changed_edge(a, Vertex_handle(*v));
451namespace skbl = skeleton_blocker;
Abstract Simplicial Complex represented with a skeleton/blockers pair.
Definition: Skeleton_blocker_complex.h:51
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:1164
Vertex_handle first_vertex(Edge_handle edge_handle) const
returns the first vertex of an edge
Definition: Skeleton_blocker_complex.h:512
void contract_edge(Edge_handle edge)
Definition: Skeleton_blocker_complex.h:1246
void add_simplex(const Simplex &sigma)
add a simplex and all its faces.
Definition: Skeleton_blocker_simplifiable_complex.h:197
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:93
void remove_popable_blockers()
Definition: Skeleton_blocker_simplifiable_complex.h:45
virtual void clear()
Definition: Skeleton_blocker_complex.h:311
void remove_star(Vertex_handle v)
Definition: Skeleton_blocker_simplifiable_complex.h:121
bool is_popable_blocker(Blocker_handle sigma) const
Definition: Skeleton_blocker_simplifiable_complex.h:33
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
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:38
T first_vertex() const
Definition: Skeleton_blocker_simplex.h:210
T last_vertex() const
Definition: Skeleton_blocker_simplex.h:220
int dimension() const
Definition: Skeleton_blocker_simplex.h:197
Definition: SkeletonBlockerDS.h:56