/* This file is part of the Gudhi Library. The Gudhi library * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * * Author(s): David Salinas * * Copyright (C) 2014 Inria * * Modification(s): * - YYYY/MM Author: Description of the modification */ #ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_ #define SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_ #include #include #include #include #include #include #include namespace Gudhi { namespace skeleton_blocker { /** *@brief Abstract simplex used in Skeleton blockers data-structure. * * An abstract simplex is represented as an ordered set of T elements, * each element representing a vertex. * * The element representing a vertex can be SkeletonBlockerDS::Vertex_handle or SkeletonBlockerDS::Root_vertex_handle. * * */ template class Skeleton_blocker_simplex { private: std::set simplex_set; public: typedef typename T::boost_vertex_handle boost_vertex_handle; typedef T Vertex_handle; typedef typename std::set::const_iterator Simplex_vertex_const_iterator; typedef typename std::set::iterator Simplex_vertex_iterator; /** @name Constructors / Destructors / Initialization */ //@{ void clear() { simplex_set.clear(); } Skeleton_blocker_simplex(std::initializer_list& list) { std::for_each(list.begin(), list.end(), [&] (T const& elt) { add_vertex(elt); }); } template explicit Skeleton_blocker_simplex(Args ... args) { add_vertices(args...); } template void add_vertices(T v, Args ... args) { add_vertex(v); add_vertices(args...); } void add_vertices(T v) { add_vertex(v); } void add_vertices() { } /** * Initialize a simplex with a string such as {0,1,2} */ explicit Skeleton_blocker_simplex(std::string token) { clear(); if ((token[0] == '{') && (token[token.size() - 1] == '}')) { token.erase(0, 1); token.erase(token.size() - 1, 1); while (token.size() != 0) { int coma_position = token.find_first_of(','); // cout << "coma_position:"< v; v.reserve((std::min)(simplex_set.size(), a.simplex_set.size())); set_intersection(simplex_set.begin(), simplex_set.end(), a.simplex_set.begin(), a.simplex_set.end(), std::back_inserter(v)); clear(); for (auto i : v) simplex_set.insert(i); } /** * Substracts a from the simplex. */ void difference(const Skeleton_blocker_simplex & a) { std::vector v; v.reserve(simplex_set.size()); set_difference(simplex_set.begin(), simplex_set.end(), a.simplex_set.begin(), a.simplex_set.end(), std::back_inserter(v)); clear(); for (auto i : v) simplex_set.insert(i); } /** * Add vertices of a to the simplex. */ void union_vertices(const Skeleton_blocker_simplex & a) { std::vector v; v.reserve(simplex_set.size() + a.simplex_set.size()); set_union(simplex_set.begin(), simplex_set.end(), a.simplex_set.begin(), a.simplex_set.end(), std::back_inserter(v)); clear(); simplex_set.insert(v.begin(), v.end()); } typename std::set::const_iterator begin() const { return simplex_set.cbegin(); } typename std::set::const_iterator end() const { return simplex_set.cend(); } typename std::set::const_reverse_iterator rbegin() const { return simplex_set.crbegin(); } typename std::set::const_reverse_iterator rend() const { return simplex_set.crend(); } typename std::set::iterator begin() { return simplex_set.begin(); } typename std::set::iterator end() { return simplex_set.end(); } //@} /** @name Queries */ //@{ /** * Returns the dimension of the simplex. */ int dimension() const { return (simplex_set.size() - 1); } bool empty() const { return simplex_set.empty(); } /** * Returns the first and smallest vertex of the simplex. * * Be careful : assumes the simplex is non-empty. */ T first_vertex() const { assert(!empty()); return *(begin()); } /** * Returns the last and greatest vertex of the simplex. * * Be careful : assumes the simplex is non-empty. */ T last_vertex() const { assert(!empty()); return *(simplex_set.rbegin()); } /** * @return true iff the simplex contains the simplex a. */ bool contains(const Skeleton_blocker_simplex & a) const { return includes(simplex_set.cbegin(), simplex_set.cend(), a.simplex_set.cbegin(), a.simplex_set.cend()); } /** * @return true iff the simplex contains the difference \f$ a \setminus b \f$. */ bool contains_difference(const Skeleton_blocker_simplex& a, const Skeleton_blocker_simplex& b) const { auto first1 = begin(); auto last1 = end(); auto first2 = a.begin(); auto last2 = a.end(); while (first2 != last2) { // we ignore vertices of b if (b.contains(*first2)) { ++first2; } else { if ((first1 == last1) || (*first2 < *first1)) return false; if (!(*first1 < *first2)) ++first2; ++first1; } } return true; } /** * @return true iff the simplex contains the difference \f$ a \setminus \{ x \} \f$. */ bool contains_difference(const Skeleton_blocker_simplex& a, T x) const { auto first1 = begin(); auto last1 = end(); auto first2 = a.begin(); auto last2 = a.end(); while (first2 != last2) { // we ignore vertices x if (x == *first2) { ++first2; } else { if ((first1 == last1) || (*first2 < *first1)) return false; if (!(*first1 < *first2)) ++first2; ++first1; } } return true; } /** * @return true iff the simplex contains the difference \f$ a \setminus \{ x,y \} \f$. */ bool contains_difference(const Skeleton_blocker_simplex& a, T x, T y) const { auto first1 = begin(); auto last1 = end(); auto first2 = a.begin(); auto last2 = a.end(); while (first2 != last2) { // we ignore vertices of x,y if (x == *first2 || y == *first2) { ++first2; } else { if ((first1 == last1) || (*first2 < *first1)) return false; if (!(*first1 < *first2)) ++first2; ++first1; } } return true; } bool contains(T v) const { return (simplex_set.find(v) != simplex_set.end()); } bool disjoint(const Skeleton_blocker_simplex& a) const { std::vector v; v.reserve(std::min(simplex_set.size(), a.simplex_set.size())); set_intersection(simplex_set.cbegin(), simplex_set.cend(), a.simplex_set.cbegin(), a.simplex_set.cend(), std::back_inserter(v)); return (v.size() == 0); } bool operator==(const Skeleton_blocker_simplex& other) const { return (this->simplex_set == other.simplex_set); } bool operator!=(const Skeleton_blocker_simplex& other) const { return (this->simplex_set != other.simplex_set); } bool operator<(const Skeleton_blocker_simplex& other) const { return (std::lexicographical_compare(this->simplex_set.begin(), this->simplex_set.end(), other.begin(), other.end())); } //@} friend std::ostream& operator<<(std::ostream& o, const Skeleton_blocker_simplex & sigma) { bool first = true; o << "{"; for (auto i : sigma) { if (first) first = false; else o << ","; o << i; } o << "}"; return o; } }; } // namespace skeleton_blocker namespace skbl = skeleton_blocker; } // namespace Gudhi #endif // SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_