Loading...
Searching...
No Matches
Skeleton_blocker_sub_complex.h
/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
* See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
* Author(s): David Salinas
*
* Copyright (C) 2014 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/
#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
#define SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
#include <gudhi/Skeleton_blocker_complex.h>
#include <gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h>
#include <gudhi/Debug_utils.h>
#include <map>
#include <vector>
namespace Gudhi {
namespace skeleton_blocker {
template<typename ComplexType>
class Skeleton_blocker_sub_complex : public ComplexType {
protected:
template<class T> friend class Skeleton_blocker_link_complex;
typedef typename ComplexType::Graph Graph;
typedef typename ComplexType::Edge_handle Edge_handle;
typedef typename ComplexType::boost_vertex_handle boost_vertex_handle;
public:
using ComplexType::add_vertex;
using ComplexType::add_edge_without_blockers;
using ComplexType::add_blocker;
typedef typename ComplexType::Vertex_handle Vertex_handle;
typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
typedef typename ComplexType::Simplex Simplex;
typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
protected:
typedef std::map<Root_vertex_handle, Vertex_handle> IdAddressMap;
typedef typename IdAddressMap::value_type AddressPair;
typedef typename IdAddressMap::iterator IdAddressMapIterator;
typedef typename IdAddressMap::const_iterator IdAddressMapConstIterator;
std::map<Root_vertex_handle, Vertex_handle> addresses;
public:
Vertex_handle add_vertex(Root_vertex_handle global) {
assert(!this->contains_vertex(global));
Vertex_handle address(boost::add_vertex(this->skeleton));
this->num_vertices_++;
(*this)[address].activate();
(*this)[address].set_id(global);
addresses.insert(AddressPair(global, address));
this->degree_.push_back(0);
return address;
}
void add_edge_without_blockers(Root_vertex_handle v1_root, Root_vertex_handle v2_root) {
auto v1_sub(this->get_address(v1_root));
auto v2_sub(this->get_address(v2_root));
assert(v1_sub && v2_sub);
this->ComplexType::add_edge_without_blockers(*v1_sub, *v2_sub);
}
void add_blocker(const Root_simplex_handle& blocker_root) {
auto blocker_sub = this->get_address(blocker_root);
assert(blocker_sub);
this->add_blocker(new Simplex(*blocker_sub));
}
public:
void make_restricted_complex(const ComplexType & parent_complex,
const Simplex& simplex) {
this->clear();
// add vertices to the sub complex
for (auto x : simplex) {
assert(parent_complex.contains_vertex(x));
auto x_local = this->add_vertex(parent_complex[x].get_id());
(*this)[x_local] = parent_complex[x];
}
// add edges to the sub complex
for (auto x : simplex) {
// x_neigh is the neighbor of x intersected with vertices_simplex
Simplex x_neigh;
parent_complex.add_neighbours(x, x_neigh, true);
x_neigh.intersection(simplex);
for (auto y : x_neigh) {
this->add_edge_without_blockers(parent_complex[x].get_id(), parent_complex[y].get_id());
}
}
// add blockers to the sub complex
for (auto blocker : parent_complex.const_blocker_range()) {
// check if it is the first time we encounter the blocker
if (simplex.contains(*blocker)) {
Root_simplex_handle blocker_root(parent_complex.get_id(*(blocker)));
Simplex blocker_restr(
*(this->get_simplex_address(blocker_root)));
this->add_blocker(new Simplex(blocker_restr));
}
}
}
void clear() {
addresses.clear();
ComplexType::clear();
}
boost::optional<Vertex_handle> get_address(Root_vertex_handle global) const {
boost::optional < Vertex_handle > res;
IdAddressMapConstIterator it = addresses.find(global);
if (it == addresses.end())
res.reset();
else
res = (*it).second;
return res;
}
// /**
// * Allocates a simplex in L corresponding to the simplex s in K
// * with its local addresses and returns an AddressSimplex.
// */
// boost::optional<Simplex> get_address(const Root_simplex_handle & s) const;
// private:
// @remark should be private but problem with VS
std::vector<boost::optional<Vertex_handle> > get_addresses(
const Root_simplex_handle & s) const {
std::vector < boost::optional<Vertex_handle> > res;
for (auto i : s) {
res.push_back(get_address(i));
}
return res;
}
};
template<typename ComplexType>
bool proper_face_in_union(
Skeleton_blocker_sub_complex<ComplexType> & link,
std::vector<boost::optional<typename ComplexType::Vertex_handle> > & addresses_sigma_in_link,
std::size_t vertex_to_be_ignored) {
// we test that all vertices of 'addresses_sigma_in_link' but 'vertex_to_be_ignored'
// are in link1 if it is the case we construct the corresponding simplex
bool vertices_sigma_are_in_link = true;
typename ComplexType::Simplex sigma_in_link;
for (std::size_t i = 0; i < addresses_sigma_in_link.size(); ++i) {
if (i != vertex_to_be_ignored) {
if (!addresses_sigma_in_link[i]) {
vertices_sigma_are_in_link = false;
break;
} else {
sigma_in_link.add_vertex(*addresses_sigma_in_link[i]);
}
}
}
// If one of vertices of the simplex is not in the complex then it returns false
// Otherwise, it tests if the simplex is in the complex
return vertices_sigma_are_in_link && link.contains(sigma_in_link);
}
// Remark: this function should be friend in order to leave get_addresses private
// however doing so seems currently not possible due to a visual studio bug c2668
// "the compiler does not support partial ordering of template functions as specified in the C++ Standard"
// http://www.serkey.com/error-c2668-ambiguous-call-to-overloaded-function-bb45ft.html
template<typename ComplexType>
bool proper_faces_in_union(
Skeleton_blocker_simplex<typename ComplexType::Root_vertex_handle> & sigma,
Skeleton_blocker_sub_complex<ComplexType> & link1,
Skeleton_blocker_sub_complex<ComplexType> & link2) {
typedef typename ComplexType::Vertex_handle Vertex_handle;
std::vector < boost::optional<Vertex_handle> > addresses_sigma_in_link1 =
link1.get_addresses(sigma);
std::vector < boost::optional<Vertex_handle> > addresses_sigma_in_link2 =
link2.get_addresses(sigma);
for (std::size_t current_index = 0; current_index < addresses_sigma_in_link1.size();
++current_index) {
if (!proper_face_in_union(link1, addresses_sigma_in_link1, current_index)
&& !proper_face_in_union(link2, addresses_sigma_in_link2,
current_index)) {
return false;
}
}
return true;
}
} // namespace skeleton_blocker
namespace skbl = skeleton_blocker;
} // namespace Gudhi
#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
Gudhi::skeleton_blocker::Skeleton_blocker_complex::Simplex
Skeleton_blocker_simplex< Vertex_handle > Simplex
A ordered set of integers that represents a simplex.
Definition Skeleton_blocker_complex.h:83
Gudhi::skeleton_blocker::Skeleton_blocker_complex::add_vertex
Vertex_handle add_vertex()
Adds a vertex to the simplicial complex and returns its Vertex_handle.
Definition Skeleton_blocker_complex.h:372
Gudhi::skeleton_blocker::Skeleton_blocker_complex::get_id
Root_vertex_handle get_id(Vertex_handle local) const
Definition Skeleton_blocker_complex.h:443
Gudhi::skeleton_blocker::Skeleton_blocker_complex::get_simplex_address
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:919
Gudhi::skeleton_blocker::Skeleton_blocker_simplex
Abstract simplex used in Skeleton blockers data-structure.
Definition Skeleton_blocker_simplex.h:38
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex
Simplicial subcomplex of a complex represented by a skeleton/blockers pair.
Definition Skeleton_blocker_sub_complex.h:46
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::clear
void clear()
Definition Skeleton_blocker_sub_complex.h:156
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::make_restricted_complex
void make_restricted_complex(const ComplexType &parent_complex, const Simplex &simplex)
Definition Skeleton_blocker_sub_complex.h:123
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::get_addresses
std::vector< boost::optional< Vertex_handle > > get_addresses(const Root_simplex_handle &s) const
Definition Skeleton_blocker_sub_complex.h:188
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::add_blocker
void add_blocker(const Root_simplex_handle &blocker_root)
Definition Skeleton_blocker_sub_complex.h:112
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::add_vertex
Vertex_handle add_vertex(Root_vertex_handle global)
Definition Skeleton_blocker_sub_complex.h:84
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::add_edge_without_blockers
void add_edge_without_blockers(Root_vertex_handle v1_root, Root_vertex_handle v2_root)
Definition Skeleton_blocker_sub_complex.h:100
Gudhi::skeleton_blocker::Skeleton_blocker_sub_complex::get_address
boost::optional< Vertex_handle > get_address(Root_vertex_handle global) const
Definition Skeleton_blocker_sub_complex.h:165
Gudhi
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14