11#ifndef SIMPLEX_TREE_H_ 
   12#define SIMPLEX_TREE_H_ 
   14#include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h> 
   15#include <gudhi/Simplex_tree/Simplex_tree_siblings.h> 
   16#include <gudhi/Simplex_tree/Simplex_tree_iterators.h> 
   17#include <gudhi/Simplex_tree/indexing_tag.h> 
   21#include <gudhi/Debug_utils.h> 
   23#include <boost/container/flat_map.hpp> 
   24#include <boost/iterator/transform_iterator.hpp> 
   25#include <boost/graph/adjacency_list.hpp> 
   26#include <boost/range/adaptor/reversed.hpp> 
   27#include <boost/range/adaptor/transformed.hpp> 
   28#include <boost/range/size.hpp> 
   29#include <boost/container/static_vector.hpp> 
   32#include <tbb/parallel_sort.h> 
   40#include <initializer_list> 
   65struct Simplex_tree_options_full_featured;
 
   80template<
typename SimplexTreeOptions = Simplex_tree_options_full_featured>
 
  104  typedef typename boost::container::flat_map<Vertex_handle, Node> Dictionary;
 
  111  struct Key_simplex_base_real {
 
  112    Key_simplex_base_real() : key_(-1) {}
 
  118  struct Key_simplex_base_dummy {
 
  119    Key_simplex_base_dummy() {}
 
  121    void assign_key(Simplex_key);
 
  122    Simplex_key key() 
const;
 
  124  struct Extended_filtration_data {
 
  127    Extended_filtration_data(){}
 
  130  typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type
 
  133  struct Filtration_simplex_base_real {
 
  134    Filtration_simplex_base_real() : filt_(0) {}
 
  140  struct Filtration_simplex_base_dummy {
 
  141    Filtration_simplex_base_dummy() {}
 
  142    void assign_filtration(
Filtration_value GUDHI_CHECK_code(f)) { GUDHI_CHECK(f == 0, 
"filtration value specified for a complex that does not store them"); }
 
  146    Filtration_simplex_base_dummy>::type Filtration_simplex_base;
 
  157  typedef typename Dictionary::iterator Dictionary_it;
 
  158  typedef typename Dictionary_it::value_type Dit_value_t;
 
  160  struct return_first {
 
  230                                boost::make_transform_iterator(root_.members_.begin(), return_first()),
 
  231                                boost::make_transform_iterator(root_.members_.end(), return_first()));
 
  275    return filtration_vect_;
 
  304  template<
class SimplexHandle>
 
  321  template<
class SimplexHandle>
 
  334      root_(nullptr, null_vertex_),
 
  341    std::clog << 
"Simplex_tree copy constructor" << std::endl;
 
  343    copy_from(complex_source);
 
  351    std::clog << 
"Simplex_tree move constructor" << std::endl;
 
  353    move_from(complex_source);
 
  357    complex_source.dimension_ = -1;
 
  362    root_members_recursive_deletion();
 
  368    std::clog << 
"Simplex_tree copy assignment" << std::endl;
 
  371    if (&complex_source != 
this) {
 
  373      root_members_recursive_deletion();
 
  375      copy_from(complex_source);
 
  385    std::clog << 
"Simplex_tree move assignment" << std::endl;
 
  388    if (&complex_source != 
this) {
 
  390      root_members_recursive_deletion();
 
  392      move_from(complex_source);
 
  401    null_vertex_ = complex_source.null_vertex_;
 
  402    filtration_vect_.clear();
 
  403    dimension_ = complex_source.dimension_;
 
  404    auto root_source = complex_source.root_;
 
  407    root_.members() = Dictionary(boost::container::ordered_unique_range, root_source.members().begin(), root_source.members().end());
 
  409    for (
auto& map_el : root_.members()) {
 
  410      map_el.second.assign_children(&root_);
 
  412    rec_copy(&root_, &root_source);
 
  417    for (
auto sh = sib->members().begin(), sh_source = sib_source->members().begin();
 
  418         sh != sib->members().end(); ++sh, ++sh_source) {
 
  421        newsib->members_.reserve(sh_source->second.children()->members().size());
 
  422        for (
auto & child : sh_source->second.children()->members())
 
  423          newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(newsib, child.second.filtration()));
 
  424        rec_copy(newsib, sh_source->second.children());
 
  425        sh->second.assign_children(newsib);
 
  432    null_vertex_ = std::move(complex_source.null_vertex_);
 
  433    root_ = std::move(complex_source.root_);
 
  434    filtration_vect_ = std::move(complex_source.filtration_vect_);
 
  435    dimension_ = std::move(complex_source.dimension_);
 
  438    for (
auto& map_el : root_.members()) {
 
  439      if (map_el.second.children() != &(complex_source.root_)) {
 
  441        map_el.second.children()->oncles_ = &root_;
 
  444        GUDHI_CHECK(map_el.second.children()->oncles_ == 
nullptr,
 
  445                    std::invalid_argument(
"Simplex_tree move constructor from an invalid Simplex_tree"));
 
  447        map_el.second.assign_children(&root_);
 
  453  void root_members_recursive_deletion() {
 
  454    for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
 
  456        rec_delete(sh->second.children());
 
  459    root_.members().clear();
 
  464    for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
 
  466        rec_delete(sh->second.children());
 
  475    if ((null_vertex_ != st2.null_vertex_) ||
 
  476        (dimension_ != st2.dimension_))
 
  478    return rec_equal(&root_, &st2.root_);
 
  483    return (!(*
this == st2));
 
  489    if (s1->members().size() != s2->members().size())
 
  491    for (
auto sh1 = s1->members().begin(), sh2 = s2->members().begin();
 
  492         (sh1 != s1->members().end() && sh2 != s2->members().end()); ++sh1, ++sh2) {
 
  493      if (sh1->first != sh2->first || sh1->second.filtration() != sh2->second.filtration())
 
  499        if (!rec_equal(sh1->second.children(), sh2->second.children()))
 
  511    return sh->second.filtration();
 
  521    return sh->second.key();
 
  529    return filtration_vect_[idx];
 
  539      return sh->second.filtration();
 
  541      return std::numeric_limits<Filtration_value>::infinity();
 
  550                std::invalid_argument(
"Simplex_tree::assign_filtration - cannot assign filtration on null_simplex"));
 
  551    sh->second.assign_filtration(fv);
 
  559    return Dictionary_it(
nullptr);
 
  575    return root_.members_.size();
 
  587    auto sib_begin = sib->members().begin();
 
  588    auto sib_end = sib->members().end();
 
  589    size_t simplices_number = sib_end - sib_begin;
 
  590    for (
auto sh = sib_begin; sh != sib_end; ++sh) {
 
  595    return simplices_number;
 
  605    while (curr_sib != 
nullptr) {
 
  607      curr_sib = curr_sib->oncles();
 
  622    if (dimension_to_be_lowered_)
 
  623      lower_upper_bound_dimension();
 
  629  template<
class SimplexHandle>
 
  632    return (sh->second.children()->parent() == sh->first);
 
  642  template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
 
  644    auto first = std::begin(s);
 
  645    auto last = std::end(s);
 
  651    std::vector<Vertex_handle> copy(first, last);
 
  652    std::sort(std::begin(copy), std::end(copy));
 
  653    return find_simplex(copy);
 
  658  Simplex_handle find_simplex(
const std::vector<Vertex_handle> & 
simplex) {
 
  660    Dictionary_it tmp_dit;
 
  664      GUDHI_CHECK(contiguous_vertices(), 
"non-contiguous vertices");
 
  666      if(v < 0 || v >= 
static_cast<Vertex_handle>(root_.members_.size()))
 
  668      tmp_dit = root_.members_.begin() + v;
 
  673      tmp_sib = tmp_dit->second.children();
 
  676      tmp_dit = tmp_sib->members_.find(*vi++);
 
  677      if (tmp_dit == tmp_sib->members_.end())
 
  683      tmp_sib = tmp_dit->second.children();
 
  691      assert(contiguous_vertices());
 
  692      return root_.members_.begin() + v;
 
  694      return root_.members_.find(v);
 
  700  bool contiguous_vertices()
 const {
 
  701    if (root_.members_.empty()) 
return true;
 
  702    if (root_.members_.begin()->first != 0) 
return false;
 
  703    if (std::prev(root_.members_.end())->first != 
static_cast<Vertex_handle>(root_.members_.size() - 1)) 
return false;
 
  722  template <
class RandomVertexHandleRange = std::initializer_list<Vertex_handle>>
 
  723  std::pair<Simplex_handle, bool> insert_simplex_raw(
const RandomVertexHandleRange& 
simplex,
 
  726    std::pair<Simplex_handle, bool> res_insert;
 
  728    for (; vi != std::prev(
simplex.end()); ++vi) {
 
  729      GUDHI_CHECK(*vi != 
null_vertex(), 
"cannot use the dummy null_vertex() as a real vertex");
 
  730      res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, 
filtration));
 
  732        res_insert.first->second.assign_children(
new Siblings(curr_sib, *vi));
 
  734      curr_sib = res_insert.first->second.children();
 
  736    GUDHI_CHECK(*vi != 
null_vertex(), 
"cannot use the dummy null_vertex() as a real vertex");
 
  737    res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, 
filtration));
 
  738    if (!res_insert.second) {
 
  740      if (res_insert.first->second.filtration() > 
filtration) {
 
  742        res_insert.first->second.assign_filtration(
filtration);
 
  746      return std::pair<Simplex_handle, bool>(
null_simplex(), 
false);
 
  749    int dim = 
static_cast<int>(boost::size(
simplex)) - 1;
 
  750    if (dim > dimension_) {
 
  781  template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
 
  784    auto first = std::begin(
simplex);
 
  788      return std::pair<Simplex_handle, bool>(
null_simplex(), 
true);  
 
  791    std::vector<Vertex_handle> copy(first, last);
 
  792    std::sort(std::begin(copy), std::end(copy));
 
  810  template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
 
  813    auto first = std::begin(Nsimplex);
 
  814    auto last = std::end(Nsimplex);
 
  819    thread_local std::vector<Vertex_handle> copy;
 
  821    copy.insert(copy.end(), first, last);
 
  822    std::sort(copy.begin(), copy.end());
 
  823    auto last_unique = std::unique(copy.begin(), copy.end());
 
  824    copy.erase(last_unique, copy.end());
 
  827        GUDHI_CHECK(v != 
null_vertex(), 
"cannot use the dummy null_vertex() as a real vertex");
 
  830    dimension_ = (std::max)(dimension_, 
static_cast<int>(std::distance(copy.begin(), copy.end())) - 1);
 
  832    return rec_insert_simplex_and_subfaces_sorted(
root(), copy.begin(), copy.end(), 
filtration);
 
  837  template<
class ForwardVertexIterator>
 
  838  std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces_sorted(
Siblings* sib,
 
  839                                                                         ForwardVertexIterator first,
 
  840                                                                         ForwardVertexIterator last,
 
  847    auto&& dict = sib->members();
 
  848    auto insertion_result = dict.emplace(vertex_one, Node(sib, filt));
 
  849    Simplex_handle simplex_one = insertion_result.first;
 
  850    bool one_is_new = insertion_result.second;
 
  859    if (++first == last) 
return insertion_result;
 
  862      simplex_one->second.assign_children(
new Siblings(sib, vertex_one));
 
  863    auto res = rec_insert_simplex_and_subfaces_sorted(simplex_one->second.children(), first, last, filt);
 
  865    if (res.first != 
null_simplex()) rec_insert_simplex_and_subfaces_sorted(sib, first, last, filt);
 
  873    sh->second.assign_key(
key);
 
  881    return { find_vertex(sh->first), find_vertex(
self_siblings(sh)->parent()) };
 
  885  template<
class SimplexHandle>
 
  887    if (sh->second.children()->parent() == sh->first)
 
  888      return sh->second.children()->oncles();
 
  890      return sh->second.children();
 
  904    dimension_to_be_lowered_ = 
false;
 
  917    filtration_vect_.clear();
 
  920      filtration_vect_.push_back(sh);
 
  932    tbb::parallel_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
 
  934    std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
 
  941    if (filtration_vect_.empty()) {
 
  950    filtration_vect_.clear();
 
  966  void rec_coface(std::vector<Vertex_handle> &vertices, 
Siblings *curr_sib, 
int curr_nbVertices,
 
  967                  std::vector<Simplex_handle>& cofaces, 
bool star, 
int nbVertices) {
 
  968    if (!(star || curr_nbVertices <= nbVertices))  
 
  970    for (Simplex_handle 
simplex = curr_sib->members().begin(); 
simplex != curr_sib->members().end(); ++
simplex) {
 
  971      if (vertices.empty()) {
 
  976        bool addCoface = (star || curr_nbVertices == nbVertices);
 
  980          rec_coface(vertices, 
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
 
  982        if (
simplex->first == vertices.back()) {
 
  984          bool equalDim = (star || curr_nbVertices == nbVertices);  
 
  985          bool addCoface = vertices.size() == 1 && equalDim;
 
  992            rec_coface(vertices, 
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
 
  993            vertices.push_back(tmp);
 
  995        } 
else if (
simplex->first > vertices.back()) {
 
 1000            rec_coface(vertices, 
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
 
 1026    assert(codimension >= 0);
 
 1028    std::vector<Vertex_handle> copy(rg.begin(), rg.end());
 
 1029    if (codimension + 
static_cast<int>(copy.size()) > dimension_ + 1 ||
 
 1030        (codimension == 0 && 
static_cast<int>(copy.size()) > dimension_))  
 
 1033    assert(std::is_sorted(copy.begin(), copy.end(), std::greater<Vertex_handle>()));
 
 1034    bool star = codimension == 0;
 
 1035    rec_coface(copy, &root_, 1, cofaces, star, codimension + 
static_cast<int>(copy.size()));
 
 1047  bool reverse_lexicographic_order(Simplex_handle sh1, Simplex_handle sh2) {
 
 1052    while (it1 != rg1.end() && it2 != rg2.end()) {
 
 1060    return ((it1 == rg1.end()) && (it2 != rg2.end()));
 
 1069  struct is_before_in_filtration {
 
 1073    bool operator()(
const Simplex_handle sh1, 
const Simplex_handle sh2)
 const {
 
 1075      if (sh1->second.filtration() != sh2->second.filtration()) {
 
 1076        return sh1->second.filtration() < sh2->second.filtration();
 
 1079      return st_->reverse_lexicographic_order(sh1, sh2);
 
 1109  template<
class OneSkeletonGraph>
 
 1115    using boost::num_vertices;
 
 1120    if (num_edges(skel_graph) == 0) {
 
 1127    auto verts = vertices(skel_graph) | boost::adaptors::transformed([&](
auto v){
 
 1128        return Dit_value_t(v, 
Node(&root_, get(vertex_filtration_t(), skel_graph, v))); });
 
 1129    root_.members_.insert(boost::begin(verts), boost::end(verts));
 
 1132    std::pair<typename boost::graph_traits<OneSkeletonGraph>::edge_iterator,
 
 1133              typename boost::graph_traits<OneSkeletonGraph>::edge_iterator> boost_edges = edges(skel_graph);
 
 1136    for (; boost_edges.first != boost_edges.second; boost_edges.first++) {
 
 1137      auto edge = *(boost_edges.first);
 
 1138      auto u = source(edge, skel_graph);
 
 1139      auto v = target(edge, skel_graph);
 
 1140      if (u == v) 
throw std::invalid_argument(
"Self-loops are not simplicial");
 
 1148      if (v < u) std::swap(u, v);
 
 1149      auto sh = find_vertex(u);
 
 1151        sh->second.assign_children(
new Siblings(&root_, sh->first));
 
 1154      sh->second.children()->members().emplace(v,
 
 1155          Node(sh->second.children(), get(edge_filtration_t(), skel_graph, edge)));
 
 1166  template <
class VertexRange>
 
 1168    auto verts = vertices | boost::adaptors::transformed([&](
auto v){
 
 1169        return Dit_value_t(v, 
Node(&root_, filt)); });
 
 1170    root_.members_.insert(boost::begin(verts), boost::end(verts));
 
 1171    if (dimension_ < 0 && !root_.members_.empty()) dimension_ = 0;
 
 1186    if (max_dim <= 1) 
return;
 
 1188    dimension_ = max_dim;
 
 1189    for (Dictionary_it root_it = root_.members_.begin();
 
 1190         root_it != root_.members_.end(); ++root_it) {
 
 1192        siblings_expansion(root_it->second.children(), max_dim - 1);
 
 1195    dimension_ = max_dim - dimension_;
 
 1200  void siblings_expansion(
Siblings * siblings,  
 
 1202    if (dimension_ > k) {
 
 1207    Dictionary_it next = siblings->members().begin();
 
 1210    thread_local std::vector<std::pair<Vertex_handle, Node> > inter;
 
 1211    for (Dictionary_it s_h = siblings->members().begin();
 
 1212         s_h != siblings->members().end(); ++s_h, ++next) {
 
 1213      Simplex_handle root_sh = find_vertex(s_h->first);
 
 1218                     siblings->members().end(),  
 
 1219                     root_sh->second.children()->members().begin(),
 
 1220                     root_sh->second.children()->members().end(),
 
 1221                     s_h->second.filtration());
 
 1222        if (inter.size() != 0) {
 
 1227          s_h->second.assign_children(new_sib);
 
 1228          siblings_expansion(new_sib, k - 1);
 
 1231          s_h->second.assign_children(siblings);
 
 1240  static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
 
 1241                           Dictionary_it begin1, Dictionary_it end1,
 
 1242                           Dictionary_it begin2, Dictionary_it end2,
 
 1244    if (begin1 == end1 || begin2 == end2)
 
 1247      if (begin1->first == begin2->first) {
 
 1248        Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
 
 1249        intersection.emplace_back(begin1->first, Node(
nullptr, filt));
 
 1250        if (++begin1 == end1 || ++begin2 == end2)
 
 1252      } 
else if (begin1->first < begin2->first) {
 
 1253        if (++begin1 == end1)
 
 1256        if (++begin2 == end2)
 
 1281  template< 
typename Blocker >
 
 1284    for (
auto& 
simplex : boost::adaptors::reverse(root_.members())) {
 
 1286        siblings_expansion_with_blockers(
simplex.second.children(), max_dim, max_dim - 1, block_simplex);
 
 1293  template< 
typename Blocker >
 
 1294  void siblings_expansion_with_blockers(
Siblings* siblings, 
int max_dim, 
int k, Blocker block_simplex) {
 
 1295    if (dimension_ < max_dim - k) {
 
 1296      dimension_ = max_dim - k;
 
 1301    if (siblings->members().size() < 2)
 
 1304    for (
auto simplex = siblings->members().rbegin() + 1; 
simplex != siblings->members().rend(); 
simplex++) {
 
 1305      std::vector<std::pair<Vertex_handle, Node> > intersection;
 
 1306      for(
auto next = siblings->members().rbegin(); next != 
simplex; next++) {
 
 1307        bool to_be_inserted = 
true;
 
 1311          Simplex_handle border_child = find_child(border, next->first);
 
 1313            to_be_inserted=
false;
 
 1316          filt = (std::max)(filt, 
filtration(border_child));
 
 1318        if (to_be_inserted) {
 
 1319          intersection.emplace_back(next->first, Node(
nullptr, filt));
 
 1322      if (intersection.size() != 0) {
 
 1326                                          boost::adaptors::reverse(intersection));  
 
 1327        simplex->second.assign_children(new_sib);
 
 1328        std::vector<Vertex_handle> blocked_new_sib_vertex_list;
 
 1330        for (
auto new_sib_member = new_sib->members().begin();
 
 1331             new_sib_member != new_sib->members().end();
 
 1333           bool blocker_result = block_simplex(new_sib_member);
 
 1336           if (blocker_result) {
 
 1337             blocked_new_sib_vertex_list.push_back(new_sib_member->first);
 
 1340        if (blocked_new_sib_vertex_list.size() == new_sib->members().size()) {
 
 1344          simplex->second.assign_children(siblings);
 
 1346          for (
auto& blocked_new_sib_member : blocked_new_sib_vertex_list) {
 
 1347            new_sib->members().erase(blocked_new_sib_member);
 
 1350          siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex);
 
 1354        simplex->second.assign_children(siblings);
 
 1363  Simplex_handle find_child(Simplex_handle sh, 
Vertex_handle vh)
 const {
 
 1367    Simplex_handle child = sh->second.children()->find(vh);
 
 1370    if (child == sh->second.children()->members().end())
 
 1388        os << 
key(b_sh) << 
" ";
 
 1402    bool modified = 
false;
 
 1404    for (
auto& 
simplex : boost::adaptors::reverse(root_.members())) {
 
 1406        modified |= rec_make_filtration_non_decreasing(
simplex.second.children());
 
 1419  bool rec_make_filtration_non_decreasing(
Siblings * sib) {
 
 1420    bool modified = 
false;
 
 1423    for (
auto& 
simplex : boost::adaptors::reverse(sib->members())) {
 
 1427                                                              [](Simplex_handle sh1, Simplex_handle sh2) {
 
 1434      if (!(
simplex.second.filtration() >= max_filt_border_value)) {
 
 1437        simplex.second.assign_filtration(max_filt_border_value);
 
 1440        modified |= rec_make_filtration_non_decreasing(
simplex.second.children());
 
 1464    auto&& list = sib->members();
 
 1465    auto last = std::remove_if(list.begin(), list.end(), [
this,filt](Dit_value_t& 
simplex) {
 
 1466        if (simplex.second.filtration() <= filt) return false;
 
 1467        if (has_children(&simplex)) rec_delete(simplex.second.children());
 
 1469        dimension_to_be_lowered_ = true;
 
 1473    bool modified = (last != list.end());
 
 1474    if (last == list.begin() && sib != 
root()) {
 
 1476      sib->oncles()->members()[sib->parent()].assign_children(sib->oncles());
 
 1479      dimension_to_be_lowered_ = 
true;
 
 1483      list.erase(last, list.end());
 
 1486          modified |= rec_prune_above_filtration(
simplex.second.children(), filt);
 
 1497  bool lower_upper_bound_dimension() {
 
 1499    dimension_to_be_lowered_ = 
false;
 
 1500    int new_dimension = -1;
 
 1505        std::clog << 
" " << vertex;
 
 1507      std::clog << std::endl;
 
 1511      if (sh_dimension >= dimension_)
 
 1514      new_dimension = (std::max)(new_dimension, sh_dimension);
 
 1516    dimension_ = new_dimension;
 
 1533                std::invalid_argument(
"Simplex_tree::remove_maximal_simplex - argument has children"));
 
 1536    Siblings* child = sh->second.children();
 
 1538    if ((child->size() > 1) || (child == 
root())) {
 
 1544      child->oncles()->members().at(child->parent()).assign_children(child->oncles());
 
 1547      dimension_to_be_lowered_ = 
true;
 
 1568    std::pair<Filtration_value, Extended_simplex_type> p;
 
 1571    if (f >= -2 && f <= -1){
 
 1572      p.first = minval + (maxval-minval)*(f + 2); p.second = Extended_simplex_type::UP;
 
 1574    else if (f >= 1 && f <= 2){
 
 1575      p.first = minval - (maxval-minval)*(f - 2); p.second = Extended_simplex_type::DOWN;
 
 1578      p.first = std::numeric_limits<Filtration_value>::quiet_NaN(); p.second = Extended_simplex_type::EXTRA;
 
 1600    Vertex_handle maxvert = std::numeric_limits<Vertex_handle>::min();
 
 1601    Filtration_value minval = std::numeric_limits<Filtration_value>::infinity();
 
 1602    Filtration_value maxval = -std::numeric_limits<Filtration_value>::infinity();
 
 1603    for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh){
 
 1605      minval = std::min(minval, f);
 
 1606      maxval = std::max(maxval, f);
 
 1607      maxvert = std::max(sh->first, maxvert);
 
 1610    GUDHI_CHECK(maxvert < std::numeric_limits<Vertex_handle>::max(), std::invalid_argument(
"Simplex_tree contains a vertex with the largest Vertex_handle"));
 
 1616    this->insert_simplex_raw({maxvert}, -3);
 
 1619    std::vector<Vertex_handle> vr;
 
 1627      auto sh = this->
find(vr);
 
 1630      vr.push_back(maxvert);
 
 1650    Extended_filtration_data efd(minval, maxval);
 
 1659    auto filt = filtration_(sh);
 
 1661      if(filtration_(find_vertex(v)) == filt)
 
 1675    auto end = std::end(vertices);
 
 1676    auto vi = std::begin(vertices);
 
 1677    GUDHI_CHECK(vi != end, 
"empty simplex");
 
 1680    GUDHI_CHECK(vi != end, 
"simplex of dimension 0");
 
 1681    if(std::next(vi) == end) 
return sh; 
 
 1682    boost::container::static_vector<Vertex_handle, 40> suffix;
 
 1683    suffix.push_back(v0);
 
 1684    auto filt = filtration_(sh);
 
 1688      auto&& children1 = find_vertex(v)->second.children()->members_;
 
 1689      for(
auto w : suffix){
 
 1692        if(filtration_(s) == filt)
 
 1695      suffix.push_back(v);
 
 1706    auto filt = filtration_(sh);
 
 1709      if(filtration_(b) == filt)
 
 1724    rec_reset_filtration(&root_, filt_value, min_dim);
 
 1735    for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
 
 1736      if (min_depth <= 0) {
 
 1737        sh->second.assign_filtration(filt_value);
 
 1740        rec_reset_filtration(sh->second.children(), filt_value, min_depth - 1);
 
 1751  std::vector<Simplex_handle> filtration_vect_;
 
 1754  bool dimension_to_be_lowered_ = 
false;
 
 1758template<
typename...T>
 
 1770template<
typename...T>
 
 1773  std::vector<typename ST::Vertex_handle> simplex;
 
 1779    int dim = 
static_cast<int> (simplex.size() - 1);
 
 1780    if (max_dim < dim) {
 
 1798  typedef int Vertex_handle;
 
 1799  typedef double Filtration_value;
 
 1800  typedef std::uint32_t Simplex_key;
 
 1801  static const bool store_key = 
true;
 
 1802  static const bool store_filtration = 
true;
 
 1803  static const bool contiguous_vertices = 
false;
 
 1814  typedef int Vertex_handle;
 
 1815  typedef float Filtration_value;
 
 1816  typedef std::uint32_t Simplex_key;
 
 1817  static const bool store_key = 
true;
 
 1818  static const bool store_filtration = 
true;
 
 1819  static const bool contiguous_vertices = 
true;
 
Extended simplex type data structure for representing the type of simplices in an extended filtration...
Iterator over the simplices of the boundary of a simplex and their opposite vertices.
Definition: Simplex_tree_iterators.h:190
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree_iterators.h:83
Iterator over the simplices of a simplicial complex.
Definition: Simplex_tree_iterators.h:300
Data structure to store a set of nodes in a SimplexTree sharing the same parent node.
Definition: Simplex_tree_siblings.h:31
Iterator over the vertices of a simplex in a SimplexTree.
Definition: Simplex_tree_iterators.h:38
Iterator over the simplices of the skeleton of a given dimension of the simplicial complex.
Definition: Simplex_tree_iterators.h:374
Simplex Tree data structure for representing simplicial complexes.
Definition: Simplex_tree.h:81
static Siblings * self_siblings(SimplexHandle sh)
Definition: Simplex_tree.h:886
Simplex_tree(Simplex_tree &&complex_source)
User-defined move constructor relocates the whole tree structure.
Definition: Simplex_tree.h:349
bool operator==(Simplex_tree &st2)
Checks if two simplex trees are equal.
Definition: Simplex_tree.h:474
Options::Filtration_value Filtration_value
Type for the value of the filtration function.
Definition: Simplex_tree.h:88
Cofaces_simplex_range cofaces_simplex_range(const Simplex_handle simplex, int codimension)
Compute the cofaces of a n simplex.
Definition: Simplex_tree.h:1023
Simplex_tree_boundary_opposite_vertex_simplex_iterator< Simplex_tree > Boundary_opposite_vertex_simplex_iterator
Iterator over the simplices of the boundary of a simplex and their opposite vertices.
Definition: Simplex_tree.h:198
void reset_filtration(Filtration_value filt_value, int min_dim=0)
This function resets the filtration value of all the simplices of dimension at least min_dim....
Definition: Simplex_tree.h:1723
void assign_filtration(Simplex_handle sh, Filtration_value fv)
Sets the filtration value of a simplex.
Definition: Simplex_tree.h:548
bool make_filtration_non_decreasing()
This function ensures that each simplex has a higher filtration value than its faces by increasing th...
Definition: Simplex_tree.h:1401
Dictionary::iterator Simplex_handle
Handle type to a simplex contained in the simplicial complex represented by the simplex tree.
Definition: Simplex_tree.h:154
Vertex_handle vertex_with_same_filtration(Simplex_handle sh)
Returns a vertex of sh that has the same filtration value as sh if it exists, and null_vertex() other...
Definition: Simplex_tree.h:1658
Filtration_simplex_range const & filtration_simplex_range(Indexing_tag=Indexing_tag())
Returns a range over the simplices of the simplicial complex, in the order of the filtration.
Definition: Simplex_tree.h:273
std::pair< Simplex_handle, bool > insert_simplex(const InputVertexRange &simplex, Filtration_value filtration=0)
Insert a simplex, represented by a range of Vertex_handles, in the simplicial complex.
Definition: Simplex_tree.h:782
Vertex_handle null_vertex() const
Returns a Vertex_handle different from all Vertex_handles associated to the vertices of the simplicia...
Definition: Simplex_tree.h:569
boost::iterator_range< Boundary_simplex_iterator > Boundary_simplex_range
Range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:194
Simplex_vertex_range simplex_vertex_range(Simplex_handle sh) const
Returns a range over the vertices of a simplex.
Definition: Simplex_tree.h:284
void clear_filtration()
Clears the filtration cache produced by initialize_filtration().
Definition: Simplex_tree.h:949
Simplex_tree_simplex_vertex_iterator< Simplex_tree > Simplex_vertex_iterator
Iterator over the vertices of a simplex.
Definition: Simplex_tree.h:184
static Simplex_key key(Simplex_handle sh)
Returns the key associated to a simplex.
Definition: Simplex_tree.h:520
static Filtration_value filtration(Simplex_handle sh)
Returns the filtration value of a simplex.
Definition: Simplex_tree.h:537
bool operator!=(Simplex_tree &st2)
Checks if two simplex trees are different.
Definition: Simplex_tree.h:482
bool has_children(SimplexHandle sh) const
Returns true if the node in the simplex tree pointed by sh has children.
Definition: Simplex_tree.h:630
Cofaces_simplex_range star_simplex_range(const Simplex_handle simplex)
Compute the star of a n simplex.
Definition: Simplex_tree.h:1012
void expansion_with_blockers(int max_dim, Blocker block_simplex)
Expands a simplex tree containing only a graph. Simplices corresponding to cliques in the graph are a...
Definition: Simplex_tree.h:1282
boost::iterator_range< Simplex_vertex_iterator > Simplex_vertex_range
Range over the vertices of a simplex.
Definition: Simplex_tree.h:186
void remove_maximal_simplex(Simplex_handle sh)
Remove a maximal simplex.
Definition: Simplex_tree.h:1530
std::pair< Simplex_handle, Simplex_handle > endpoints(Simplex_handle sh)
Definition: Simplex_tree.h:879
void assign_key(Simplex_handle sh, Simplex_key key)
Assign a value 'key' to the key of the simplex represented by the Simplex_handle 'sh'.
Definition: Simplex_tree.h:872
Options::Simplex_key Simplex_key
Key associated to each simplex.
Definition: Simplex_tree.h:92
Simplex_tree()
Constructs an empty simplex tree.
Definition: Simplex_tree.h:332
void maybe_initialize_filtration()
Initializes the filtration cache if it isn't initialized yet.
Definition: Simplex_tree.h:940
boost::iterator_range< Complex_simplex_iterator > Complex_simplex_range
Range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:206
Simplex_tree_boundary_simplex_iterator< Simplex_tree > Boundary_simplex_iterator
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:192
Simplex_tree_siblings< Simplex_tree, Dictionary > Siblings
Set of nodes sharing a same parent in the simplex tree.
Definition: Simplex_tree.h:107
Simplex_handle find(const InputVertexRange &s)
Given a range of Vertex_handles, returns the Simplex_handle of the simplex in the simplicial complex ...
Definition: Simplex_tree.h:643
std::vector< Simplex_handle > Cofaces_simplex_range
Range over the cofaces of a simplex.
Definition: Simplex_tree.h:188
Boundary_opposite_vertex_simplex_range boundary_opposite_vertex_simplex_range(SimplexHandle sh)
Given a simplex, returns a range over the simplices of its boundary and their opposite vertices.
Definition: Simplex_tree.h:322
Simplex_handle edge_with_same_filtration(Simplex_handle sh)
Returns an edge of sh that has the same filtration value as sh if it exists, and null_simplex() other...
Definition: Simplex_tree.h:1672
Simplex_tree_complex_simplex_iterator< Simplex_tree > Complex_simplex_iterator
Iterator over the simplices of the simplicial complex.
Definition: Simplex_tree.h:204
Simplex_handle simplex(Simplex_key idx) const
Returns the simplex that has index idx in the filtration.
Definition: Simplex_tree.h:528
void initialize_filtration()
Initializes the filtration cache, i.e. sorts the simplices according to their order in the filtration...
Definition: Simplex_tree.h:916
Skeleton_simplex_range skeleton_simplex_range(int dim)
Returns a range over the simplices of the dim-skeleton of the simplicial complex.
Definition: Simplex_tree.h:253
boost::transform_iterator< return_first, Dictionary_it > Complex_vertex_iterator
Iterator over the vertices of the simplicial complex.
Definition: Simplex_tree.h:178
void insert_batch_vertices(VertexRange const &vertices, Filtration_value filt=0)
Inserts several vertices.
Definition: Simplex_tree.h:1167
std::vector< Simplex_handle > Filtration_simplex_range
Range over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:216
Filtration_simplex_range::const_iterator Filtration_simplex_iterator
Iterator over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:220
Extended_filtration_data extend_filtration()
Extend filtration for computing extended persistence. This function only uses the filtration values a...
Definition: Simplex_tree.h:1596
Simplex_handle minimal_simplex_with_same_filtration(Simplex_handle sh)
Returns a minimal face of sh that has the same filtration value as sh.
Definition: Simplex_tree.h:1705
Options::Vertex_handle Vertex_handle
Type for the vertex handle.
Definition: Simplex_tree.h:96
std::pair< Filtration_value, Extended_simplex_type > decode_extended_filtration(Filtration_value f, const Extended_filtration_data &efd)
Retrieve the original filtration value for a given simplex in the Simplex_tree. Since the computation...
Definition: Simplex_tree.h:1567
size_t num_vertices() const
Returns the number of vertices in the complex.
Definition: Simplex_tree.h:574
void expansion(int max_dim)
Expands the Simplex_tree containing only its one skeleton until dimension max_dim.
Definition: Simplex_tree.h:1185
Simplex_tree(const Simplex_tree &complex_source)
User-defined copy constructor reproduces the whole tree structure.
Definition: Simplex_tree.h:339
boost::iterator_range< Complex_vertex_iterator > Complex_vertex_range
Range over the vertices of the simplicial complex.
Definition: Simplex_tree.h:180
static Simplex_key null_key()
Returns a fixed number not in the interval [0, num_simplices()).
Definition: Simplex_tree.h:563
Boundary_simplex_range boundary_simplex_range(SimplexHandle sh)
Returns a range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:305
int dimension(Simplex_handle sh)
Returns the dimension of a simplex.
Definition: Simplex_tree.h:602
bool prune_above_filtration(Filtration_value filtration)
Prune above filtration value given as parameter.
Definition: Simplex_tree.h:1455
int upper_bound_dimension() const
Returns an upper bound on the dimension of the simplicial complex.
Definition: Simplex_tree.h:613
Siblings * root()
Definition: Simplex_tree.h:895
int dimension()
Returns the dimension of the simplicial complex.
Definition: Simplex_tree.h:621
std::pair< Simplex_handle, bool > insert_simplex_and_subfaces(const InputVertexRange &Nsimplex, Filtration_value filtration=0)
Insert a N-simplex and all his subfaces, from a N-simplex represented by a range of Vertex_handles,...
Definition: Simplex_tree.h:811
size_t num_simplices()
returns the number of simplices in the simplex_tree.
Definition: Simplex_tree.h:580
Simplex_tree_skeleton_simplex_iterator< Simplex_tree > Skeleton_simplex_iterator
Iterator over the simplices of the skeleton of the simplicial complex, for a given dimension.
Definition: Simplex_tree.h:211
Simplex_tree & operator=(Simplex_tree &&complex_source)
User-defined move assignment relocates the whole tree structure.
Definition: Simplex_tree.h:383
boost::iterator_range< Boundary_opposite_vertex_simplex_iterator > Boundary_opposite_vertex_simplex_range
Range over the simplices of the boundary of a simplex and their opposite vertices.
Definition: Simplex_tree.h:200
Simplex_tree & operator=(const Simplex_tree &complex_source)
User-defined copy assignment reproduces the whole tree structure.
Definition: Simplex_tree.h:366
void insert_graph(const OneSkeletonGraph &skel_graph)
Inserts a 1-skeleton in an empty Simplex_tree.
Definition: Simplex_tree.h:1110
void set_dimension(int dimension)
Set a dimension for the simplicial complex.
Definition: Simplex_tree.h:903
boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range
Range over the simplices of the skeleton of the simplicial complex, for a given dimension.
Definition: Simplex_tree.h:214
void print_hasse(std::ostream &os)
Write the hasse diagram of the simplicial complex in os.
Definition: Simplex_tree.h:1383
~Simplex_tree()
Destructor; deallocates the whole tree structure.
Definition: Simplex_tree.h:361
static Simplex_handle null_simplex()
Returns a Simplex_handle different from all Simplex_handles associated to the simplices in the simpli...
Definition: Simplex_tree.h:558
Complex_simplex_range complex_simplex_range()
Returns a range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:239
Complex_vertex_range complex_vertex_range()
Returns a range over the vertices of the simplicial complex. The order is increasing according to < o...
Definition: Simplex_tree.h:228
Graph simplicial complex methods.
This file includes common file reader for GUDHI.
bool read_simplex(std::istream &in_, std::vector< Vertex_handle > &simplex, Filtration_value &fil)
Read a face from a file.
Definition: reader_utils.h:158
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20
Node of a simplex tree with filtration value and simplex key.
Definition: Simplex_tree_node_explicit_storage.h:29
Definition: Simplex_tree.h:1812
Definition: Simplex_tree.h:1796
Tag for a linear ordering of simplices.
Definition: indexing_tag.h:20
Concept describing an indexing scheme (see FilteredComplex) for applying continuous maps to a cell co...
Definition: IndexingTag.h:18
Key type used as simplex identifier.
Definition: SimplexKey.h:15
Concept of the template parameter for the class Gudhi::Simplex_tree<SimplexTreeOptions>.
Definition: SimplexTreeOptions.h:15
static const bool store_filtration
If true, each simplex has extra storage for one Filtration_value, and this value is propagated by ope...
Definition: SimplexTreeOptions.h:27
static constexpr bool contiguous_vertices
If true, the list of vertices present in the complex must always be 0, ..., num_vertices-1,...
Definition: SimplexTreeOptions.h:29
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15