19#ifndef SIMPLEX_TREE_H_
20#define SIMPLEX_TREE_H_
22#include <gudhi/Simplex_tree/simplex_tree_options.h>
23#include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h>
24#include <gudhi/Simplex_tree/Simplex_tree_siblings.h>
25#include <gudhi/Simplex_tree/Simplex_tree_iterators.h>
26#include <gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h>
27#include <gudhi/Simplex_tree/serialization_utils.h>
28#include <gudhi/Simplex_tree/hooks_simplex_base.h>
32#include <gudhi/Debug_utils.h>
34#include <boost/container/map.hpp>
35#include <boost/container/flat_map.hpp>
36#include <boost/iterator/transform_iterator.hpp>
37#include <boost/graph/adjacency_list.hpp>
38#include <boost/range/adaptor/reversed.hpp>
39#include <boost/range/adaptor/transformed.hpp>
40#include <boost/range/size.hpp>
41#include <boost/container/static_vector.hpp>
42#include <boost/range/adaptors.hpp>
44#include <boost/intrusive/list.hpp>
45#include <boost/intrusive/parent_from_member.hpp>
49#include <tbb/parallel_sort.h>
57#include <initializer_list>
61#include <unordered_map>
97template<
typename SimplexTreeOptions = Simplex_tree_options_default>
127 typedef typename boost::container::flat_map<Vertex_handle, Node> flat_map;
130 typedef typename boost::container::map<Vertex_handle, Node> map;
131 typedef typename std::conditional<Options::stable_simplex_handles,
133 flat_map>::type Dictionary;
140 struct Key_simplex_base_real {
141 Key_simplex_base_real() : key_(-1) {}
148 struct Key_simplex_base_dummy {
149 Key_simplex_base_dummy() {}
155 struct Extended_filtration_data {
158 Extended_filtration_data(){}
161 typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type
164 struct Filtration_simplex_base_real {
165 Filtration_simplex_base_real() : filt_(0) {}
172 struct Filtration_simplex_base_dummy {
173 Filtration_simplex_base_dummy() {}
175 GUDHI_CHECK(f == 0,
"filtration value specified for a complex that does not store them");
178 GUDHI_CHECK(f == 0,
"filtration value specified for a complex that does not store them");
182 typedef typename std::conditional<Options::store_filtration, Filtration_simplex_base_real,
183 Filtration_simplex_base_dummy>::type Filtration_simplex_base;
195 typedef typename Dictionary::iterator Dictionary_it;
196 typedef typename Dictionary::const_iterator Dictionary_const_it;
197 typedef typename Dictionary_it::value_type Dit_value_t;
199 struct return_first {
214 using Optimized_star_simplex_range = boost::iterator_range<Optimized_star_simplex_iterator>;
216 class Fast_cofaces_predicate {
221 Fast_cofaces_predicate(
Simplex_tree const* st,
int codim,
int dim)
222 : st_(st), codim_(codim), dim_(codim + dim) {}
223 bool operator()(
const Simplex_handle iter )
const {
228 return dim_ == st_->dimension(iter);
234 using Optimized_cofaces_simplex_filtered_range = boost::filtered_range<Fast_cofaces_predicate,
235 Optimized_star_simplex_range>;
240 static constexpr int max_dimension() {
return 40; }
263 typedef typename std::conditional<Options::link_nodes_by_label,
264 Optimized_cofaces_simplex_filtered_range,
270 using Static_vertex_vector = boost::container::static_vector<
Vertex_handle, max_dimension()>;
312 return Complex_vertex_range(boost::make_transform_iterator(root_.members_.begin(), return_first()),
313 boost::make_transform_iterator(root_.members_.end(), return_first()));
360 return filtration_vect_;
389 template<
class SimplexHandle>
406 template<
class SimplexHandle>
419 root_(nullptr, null_vertex_),
438 template<
typename OtherSimplexTreeOptions,
typename F>
441 std::clog <<
"Simplex_tree custom copy constructor" << std::endl;
443 copy_from(complex_source, translate_filtration_value);
451 std::clog <<
"Simplex_tree copy constructor" << std::endl;
453 copy_from(complex_source);
462 std::clog <<
"Simplex_tree move constructor" << std::endl;
464 move_from(complex_source);
468 complex_source.dimension_ = -1;
473 root_members_recursive_deletion();
481 std::clog <<
"Simplex_tree copy assignment" << std::endl;
484 if (&complex_source !=
this) {
486 root_members_recursive_deletion();
488 copy_from(complex_source);
499 std::clog <<
"Simplex_tree move assignment" << std::endl;
502 if (&complex_source !=
this) {
504 root_members_recursive_deletion();
506 move_from(complex_source);
515 null_vertex_ = complex_source.null_vertex_;
516 filtration_vect_.clear();
517 dimension_ = complex_source.dimension_;
518 auto root_source = complex_source.root_;
522 Dictionary(boost::container::ordered_unique_range, root_source.members().begin(), root_source.members().end());
524 for (
auto& map_el : root_.members()) {
525 map_el.second.assign_children(&root_);
528 if constexpr (!std::is_same_v<Simplex_data, No_simplex_data>) {
529 auto dst_iter = root_.members().begin();
530 auto src_iter = root_source.members().begin();
532 while(dst_iter != root_.members().end() || src_iter != root_source.members().end()) {
533 dst_iter->second.data() = src_iter->second.data();
538 assert(dst_iter == root_.members().end());
539 assert(src_iter == root_source.members().end());
541 rec_copy<Options::store_key, true>(
546 template<
typename OtherSimplexTreeOptions,
typename F>
548 null_vertex_ = complex_source.null_vertex_;
549 filtration_vect_.clear();
550 dimension_ = complex_source.dimension_;
551 auto root_source = complex_source.root_;
554 if constexpr (!Options::stable_simplex_handles) root_.members().reserve(root_source.size());
555 for (
auto& p : root_source.members()){
556 if constexpr (Options::store_key && OtherSimplexTreeOptions::store_key) {
557 auto it = root_.members().try_emplace(
558 root_.members().end(), p.first, &root_, translate_filtration_value(p.second.filtration()), p.second.key());
560 auto it = root_.members().try_emplace(
561 root_.members().end(), p.first, &root_, translate_filtration_value(p.second.filtration()));
565 rec_copy<OtherSimplexTreeOptions::store_key, false>(&root_, &root_source, translate_filtration_value);
569 template<
bool store_key,
bool copy_simplex_data,
typename OtherSiblings,
typename F>
570 void rec_copy(
Siblings *sib, OtherSiblings *sib_source, F&& translate_filtration_value) {
571 auto sh_source = sib_source->members().begin();
572 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh, ++sh_source) {
573 update_simplex_tree_after_node_insertion(sh);
576 if constexpr (!Options::stable_simplex_handles) {
577 newsib->members_.reserve(sh_source->second.children()->members().size());
579 for (
auto & child : sh_source->second.children()->members()){
580 Dictionary_it new_it{};
581 if constexpr (store_key && Options::store_key) {
582 new_it = newsib->members_.emplace_hint(
583 newsib->members_.end(),
585 Node(newsib, translate_filtration_value(child.second.filtration()), child.second.key()));
587 new_it = newsib->members_.emplace_hint(newsib->members_.end(),
589 Node(newsib, translate_filtration_value(child.second.filtration())));
592 if constexpr (copy_simplex_data && !std::is_same_v<Simplex_data, No_simplex_data>) {
593 new_it->second.data() = child.second.data();
596 rec_copy<store_key, copy_simplex_data>(newsib, sh_source->second.children(), translate_filtration_value);
597 sh->second.assign_children(newsib);
604 null_vertex_ = std::move(complex_source.null_vertex_);
605 root_ = std::move(complex_source.root_);
606 filtration_vect_ = std::move(complex_source.filtration_vect_);
607 dimension_ = complex_source.dimension_;
608 if constexpr (Options::link_nodes_by_label) {
609 nodes_label_to_list_.swap(complex_source.nodes_label_to_list_);
612 for (
auto& map_el : root_.members()) {
613 if (map_el.second.children() != &(complex_source.root_)) {
615 map_el.second.children()->oncles_ = &root_;
618 GUDHI_CHECK(map_el.second.children()->oncles_ ==
nullptr,
619 std::invalid_argument(
"Simplex_tree move constructor from an invalid Simplex_tree"));
621 map_el.second.assign_children(&root_);
627 void root_members_recursive_deletion() {
628 for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
630 rec_delete(sh->second.children());
633 root_.members().clear();
638 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
640 rec_delete(sh->second.children());
652 template<
class OtherSimplexTreeOptions>
654 if ((null_vertex_ != st2.null_vertex_) ||
655 (dimension_ != st2.dimension_ && !dimension_to_be_lowered_ && !st2.dimension_to_be_lowered_))
657 return rec_equal(&root_, &st2.root_);
661 template<
class OtherSimplexTreeOptions>
663 return (!(*
this == st2));
668 template<
class OtherSiblings>
669 bool rec_equal(
Siblings const* s1, OtherSiblings
const* s2)
const {
670 if (s1->members().size() != s2->members().size())
672 auto sh2 = s2->members().begin();
673 for (
auto sh1 = s1->members().begin();
674 (sh1 != s1->members().end() && sh2 != s2->members().end());
676 if (sh1->first != sh2->first || sh1->second.filtration() != sh2->second.filtration())
682 if (!rec_equal(sh1->second.children(), sh2->second.children()))
694 return sh->second.filtration();
698 Dictionary_it _to_node_it(Simplex_handle sh) {
709 return sh->second.key();
719 return filtration_vect_[idx];
729 return sh->second.filtration();
731 return std::numeric_limits<Filtration_value>::infinity();
740 std::invalid_argument(
"Simplex_tree::assign_filtration - cannot assign filtration on null_simplex"));
741 _to_node_it(sh)->second.assign_filtration(fv);
749 return Dictionary_const_it();
760 std::invalid_argument(
"Simplex_tree::simplex_data - no data associated to null_simplex"));
761 return _to_node_it(sh)->second.data();
767 std::invalid_argument(
"Simplex_tree::simplex_data - no data associated to null_simplex"));
768 return sh->second.data();
779 return root_.members_.size();
784 return root_.members_.empty();
798 auto sib_begin = sib->members().begin();
799 auto sib_end = sib->members().end();
800 size_t simplices_number = sib->members().size();
801 for (
auto sh = sib_begin; sh != sib_end; ++sh) {
806 return simplices_number;
817 while (curr_sib !=
nullptr) {
819 curr_sib = curr_sib->oncles();
830 auto fun = [&res](
Simplex_handle,
int dim) ->
void { ++res[dim]; };
832 if (dimension_to_be_lowered_) {
833 GUDHI_CHECK(res.front() != 0, std::logic_error(
"Bug in Gudhi: non-empty complex has no vertex"));
834 while (res.back() == 0) res.pop_back();
835 dimension_ =
static_cast<int>(res.size()) - 1;
836 dimension_to_be_lowered_ =
false;
838 GUDHI_CHECK(res.back() != 0,
839 std::logic_error(
"Bug in Gudhi: there is no simplex of dimension the dimension of the complex"));
866 if (dimension_to_be_lowered_)
867 lower_upper_bound_dimension();
873 template<
class SimplexHandle>
876 return (sh->second.children()->parent() == sh->first);
885 Siblings const* children(Simplex_handle sh)
const {
886 GUDHI_CHECK(
has_children(sh), std::invalid_argument(
"Simplex_tree::children - argument has no child"));
887 return sh->second.children();
898 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
900 auto first = std::begin(s);
901 auto last = std::end(s);
907 std::vector<Vertex_handle> copy(first, last);
908 std::sort(std::begin(copy), std::end(copy));
909 return find_simplex(copy);
914 Simplex_handle find_simplex(
const std::vector<Vertex_handle> &
simplex)
const {
916 Dictionary_const_it tmp_dit;
918 if constexpr (Options::contiguous_vertices && !Options::stable_simplex_handles) {
920 GUDHI_CHECK(contiguous_vertices(),
"non-contiguous vertices");
922 if(v < 0 || v >=
static_cast<Vertex_handle>(root_.members_.size()))
924 tmp_dit = root_.members_.begin() + v;
929 tmp_sib = tmp_dit->second.children();
932 tmp_dit = tmp_sib->members_.find(*vi++);
933 if (tmp_dit == tmp_sib->members_.end())
939 tmp_sib = tmp_dit->second.children();
946 if constexpr (Options::contiguous_vertices && !Options::stable_simplex_handles) {
947 assert(contiguous_vertices());
948 return root_.members_.begin() + v;
950 return root_.members_.find(v);
956 bool contiguous_vertices()
const {
957 if (root_.members_.empty())
return true;
958 if (root_.members_.begin()->first != 0)
return false;
959 if (std::prev(root_.members_.end())->first !=
static_cast<Vertex_handle>(root_.members_.size() - 1))
return false;
978 template <
class RandomVertexHandleRange = std::initializer_list<Vertex_handle>>
979 std::pair<Simplex_handle, bool> insert_simplex_raw(
const RandomVertexHandleRange&
simplex,
982 std::pair<Dictionary_it, bool> res_insert;
984 for (; vi != std::prev(
simplex.end()); ++vi) {
985 GUDHI_CHECK(*vi !=
null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
986 res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib,
filtration));
987 if (res_insert.second) {
989 update_simplex_tree_after_node_insertion(res_insert.first);
992 res_insert.first->second.assign_children(
new Siblings(curr_sib, *vi));
994 curr_sib = res_insert.first->second.children();
996 GUDHI_CHECK(*vi !=
null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
997 res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib,
filtration));
998 if (!res_insert.second) {
1000 if (res_insert.first->second.filtration() >
filtration) {
1002 res_insert.first->second.assign_filtration(
filtration);
1006 return std::pair<Simplex_handle, bool>(
null_simplex(),
false);
1009 update_simplex_tree_after_node_insertion(res_insert.first);
1012 int dim =
static_cast<int>(boost::size(
simplex)) - 1;
1013 if (dim > dimension_) {
1044 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
1047 auto first = std::begin(
simplex);
1048 auto last = std::end(
simplex);
1051 return std::pair<Simplex_handle, bool>(
null_simplex(),
true);
1054 std::vector<Vertex_handle> copy(first, last);
1055 std::sort(std::begin(copy), std::end(copy));
1073 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
1076 auto first = std::begin(Nsimplex);
1077 auto last = std::end(Nsimplex);
1082 thread_local std::vector<Vertex_handle> copy;
1084 copy.insert(copy.end(), first, last);
1085 std::sort(copy.begin(), copy.end());
1086 auto last_unique = std::unique(copy.begin(), copy.end());
1087 copy.erase(last_unique, copy.end());
1090 GUDHI_CHECK(v !=
null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
1093 dimension_ = (std::max)(dimension_,
static_cast<int>(std::distance(copy.begin(), copy.end())) - 1);
1095 return rec_insert_simplex_and_subfaces_sorted(
root(), copy.begin(), copy.end(),
filtration);
1100 template<
class ForwardVertexIterator>
1101 std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces_sorted(
Siblings* sib,
1102 ForwardVertexIterator first,
1103 ForwardVertexIterator last,
1110 auto&& dict = sib->members();
1111 auto insertion_result = dict.emplace(vertex_one, Node(sib, filt));
1112 std::pair<Simplex_handle, bool> result(insertion_result);
1114 auto simplex_one = insertion_result.first;
1115 bool one_is_new = insertion_result.second;
1118 update_simplex_tree_after_node_insertion(insertion_result.first);
1127 if (++first == last)
return result;
1130 simplex_one->second.assign_children(
new Siblings(sib, vertex_one));
1131 auto res = rec_insert_simplex_and_subfaces_sorted(simplex_one->second.children(), first, last, filt);
1133 if (res.first !=
null_simplex()) rec_insert_simplex_and_subfaces_sorted(sib, first, last, filt);
1141 _to_node_it(sh)->second.assign_key(
key);
1149 return { find_vertex(sh->first), find_vertex(
self_siblings(sh)->parent()) };
1153 template<
class SimplexHandle>
1155 if (sh->second.children()->parent() == sh->first)
1156 return sh->second.children()->oncles();
1158 return sh->second.children();
1162 template<
class SimplexHandle>
1166 return const_cast<Siblings*
>(std::as_const(*this).self_siblings(sh));
1185 dimension_to_be_lowered_ = !exact;
1201 filtration_vect_.clear();
1204 if (ignore_infinite_values &&
1205 std::numeric_limits<Filtration_value>::has_infinity &&
1206 filtration(sh) == std::numeric_limits<Filtration_value>::infinity())
continue;
1207 filtration_vect_.push_back(sh);
1220 tbb::parallel_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
1222 std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
1232 if (filtration_vect_.empty()) {
1244 filtration_vect_.clear();
1261 void rec_coface(std::vector<Vertex_handle> &vertices,
Siblings const*curr_sib,
int curr_nbVertices,
1262 std::vector<Simplex_handle>& cofaces,
bool star,
int nbVertices)
const {
1263 if (!(star || curr_nbVertices <= nbVertices))
1265 for (Simplex_handle
simplex = curr_sib->members().begin();
simplex != curr_sib->members().end(); ++
simplex) {
1266 if (vertices.empty()) {
1271 bool addCoface = (star || curr_nbVertices == nbVertices);
1275 rec_coface(vertices,
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
1277 if (
simplex->first == vertices.back()) {
1279 bool equalDim = (star || curr_nbVertices == nbVertices);
1280 bool addCoface = vertices.size() == 1 && equalDim;
1286 vertices.pop_back();
1287 rec_coface(vertices,
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
1288 vertices.push_back(tmp);
1290 }
else if (
simplex->first > vertices.back()) {
1295 rec_coface(vertices,
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
1326 assert(codimension >= 0);
1328 if constexpr (Options::link_nodes_by_label) {
1330 Static_vertex_vector simp(rg.begin(), rg.end());
1332 assert(std::is_sorted(simp.begin(), simp.end(), std::greater<Vertex_handle>()));
1336 Fast_cofaces_predicate select(
this, codimension, this->
dimension(simplex));
1337 return boost::adaptors::filter(range, select);
1341 std::vector<Vertex_handle> copy(rg.begin(), rg.end());
1342 if (codimension +
static_cast<int>(copy.size()) > dimension_ + 1 ||
1343 (codimension == 0 &&
static_cast<int>(copy.size()) > dimension_))
1346 assert(std::is_sorted(copy.begin(), copy.end(), std::greater<Vertex_handle>()));
1347 bool star = codimension == 0;
1348 rec_coface(copy, &root_, 1, cofaces, star, codimension +
static_cast<int>(copy.size()));
1361 bool reverse_lexicographic_order(Simplex_handle sh1, Simplex_handle sh2)
const {
1366 while (it1 != rg1.end() && it2 != rg2.end()) {
1374 return ((it1 == rg1.end()) && (it2 != rg2.end()));
1383 struct is_before_in_filtration {
1384 explicit is_before_in_filtration(
Simplex_tree const* st)
1387 bool operator()(
const Simplex_handle sh1,
const Simplex_handle sh2)
const {
1389 if (sh1->second.filtration() != sh2->second.filtration()) {
1390 return sh1->second.
filtration() < sh2->second.filtration();
1393 return st_->reverse_lexicographic_order(sh1, sh2);
1423 template<
class OneSkeletonGraph>
1429 using boost::num_vertices;
1434 if (num_edges(skel_graph) == 0) {
1440 if constexpr (!Options::stable_simplex_handles)
1442 auto verts = vertices(skel_graph) | boost::adaptors::transformed([&](
auto v){
1443 return Dit_value_t(v,
Node(&root_,
get(vertex_filtration_t(), skel_graph, v))); });
1444 root_.members_.insert(boost::begin(verts), boost::end(verts));
1447 for (Dictionary_it it = boost::begin(root_.members_); it != boost::end(root_.members_); it++) {
1448 update_simplex_tree_after_node_insertion(it);
1451 std::pair<typename boost::graph_traits<OneSkeletonGraph>::edge_iterator,
1452 typename boost::graph_traits<OneSkeletonGraph>::edge_iterator> boost_edges = edges(skel_graph);
1455 for (; boost_edges.first != boost_edges.second; boost_edges.first++) {
1456 auto edge = *(boost_edges.first);
1457 auto u = source(edge, skel_graph);
1458 auto v = target(edge, skel_graph);
1459 if (u == v)
throw std::invalid_argument(
"Self-loops are not simplicial");
1467 if (v < u) std::swap(u, v);
1468 auto sh = _to_node_it(find_vertex(u));
1470 sh->second.assign_children(
new Siblings(&root_, sh->first));
1473 auto insertion_res = sh->second.children()->members().emplace(
1474 v,
Node(sh->second.children(),
get(edge_filtration_t(), skel_graph, edge)));
1475 if (insertion_res.second) update_simplex_tree_after_node_insertion(insertion_res.first);
1486 template <
class VertexRange>
1488 auto verts = vertices | boost::adaptors::transformed([&](
auto v){
1489 return Dit_value_t(v,
Node(&root_, filt)); });
1490 root_.members_.insert(boost::begin(verts), boost::end(verts));
1491 if (dimension_ < 0 && !root_.members_.empty()) dimension_ = 0;
1492 if constexpr (Options::link_nodes_by_label) {
1493 for (
auto sh = root_.members().begin(); sh != root_.members().end(); sh++) {
1495 if (!sh->second.list_max_vertex_hook_.is_linked())
1496 update_simplex_tree_after_node_insertion(sh);
1513 if (max_dim <= 1)
return;
1515 dimension_ = max_dim;
1516 for (Dictionary_it root_it = root_.members_.begin();
1517 root_it != root_.members_.end(); ++root_it) {
1519 siblings_expansion(root_it->second.children(), max_dim - 1);
1522 dimension_ = max_dim - dimension_;
1563 , std::vector<Simplex_handle>& added_simplices)
1584 static_assert(Options::link_nodes_by_label,
"Options::link_nodes_by_label must be true");
1587 auto res_ins = root_.members().emplace(u,
Node(&root_,fil));
1588 if (res_ins.second) {
1589 added_simplices.push_back(res_ins.first);
1590 update_simplex_tree_after_node_insertion(res_ins.first);
1591 if (dimension_ == -1) dimension_ = 0;
1596 if (v < u) { std::swap(u,v); }
1605 auto sh_u = root_.members().find(u);
1606 GUDHI_CHECK(sh_u != root_.members().end() &&
1607 root_.members().find(v) != root_.members().end(),
1608 std::invalid_argument(
1609 "Simplex_tree::insert_edge_as_flag - inserts an edge whose vertices are not in the complex")
1612 sh_u->second.children()->members().find(v) == sh_u->second.children()->members().end(),
1613 std::invalid_argument(
1614 "Simplex_tree::insert_edge_as_flag - inserts an already existing edge")
1619 const auto tmp_dim = dimension_;
1620 auto tmp_max_dim = dimension_;
1625 List_max_vertex* nodes_with_label_u = nodes_by_label(u);
1627 GUDHI_CHECK(nodes_with_label_u !=
nullptr,
1628 "Simplex_tree::insert_edge_as_flag - cannot find the list of Nodes with label u");
1630 for (
auto&& node_as_hook : *nodes_with_label_u)
1632 Node& node_u =
static_cast<Node&
>(node_as_hook);
1635 if (sib_u->members().find(v) != sib_u->members().end()) {
1637 if (dim_max == -1 || curr_dim < dim_max){
1641 node_u.assign_children(
new Siblings(sib_u, u));
1643 dimension_ = dim_max - curr_dim - 1;
1644 compute_punctual_expansion(
1648 dim_max - curr_dim - 1,
1650 dimension_ = dim_max - dimension_;
1651 if (dimension_ > tmp_max_dim) tmp_max_dim = dimension_;
1655 if (tmp_dim <= tmp_max_dim){
1656 dimension_ = tmp_max_dim;
1657 dimension_to_be_lowered_ =
false;
1659 dimension_ = tmp_dim;
1677 , std::vector<Simplex_handle>& added_simplices )
1679 auto res_ins_v = sib->members().emplace(v, Node(sib,fil));
1680 added_simplices.push_back(res_ins_v.first);
1681 update_simplex_tree_after_node_insertion(res_ins_v.first);
1689 create_local_expansion( res_ins_v.first
1693 , added_simplices );
1696 for (
auto sh = sib->members().begin(); sh != res_ins_v.first; ++sh)
1698 Simplex_handle root_sh = find_vertex(sh->first);
1700 root_sh->second.children()->members().find(v) != root_sh->second.children()->members().end())
1703 sh->second.assign_children(
new Siblings(sib, sh->first));
1706 compute_punctual_expansion( v
1707 , sh->second.children()
1710 , added_simplices );
1721 void create_local_expansion(
1726 , std::vector<Simplex_handle> &added_simplices)
1729 Dictionary_it next_it = sh_v;
1732 if (dimension_ > k) {
1736 create_expansion<true>(curr_sib, sh_v, next_it, fil_uv, k, &added_simplices);
1748 void siblings_expansion(
1752 , std::vector<Simplex_handle> & added_simplices )
1754 if (dimension_ > k) {
1757 if (k == 0) {
return; }
1758 Dictionary_it next = ++(siblings->members().begin());
1760 for (Dictionary_it s_h = siblings->members().begin();
1761 next != siblings->members().end(); ++s_h, ++next)
1763 create_expansion<true>(siblings, s_h, next, fil, k, &added_simplices);
1769 void siblings_expansion(
Siblings * siblings,
1771 if (k >= 0 && dimension_ > k) {
1776 Dictionary_it next = siblings->members().begin();
1779 for (Dictionary_it s_h = siblings->members().begin();
1780 s_h != siblings->members().end(); ++s_h, ++next)
1782 create_expansion<false>(siblings, s_h, next, s_h->second.filtration(), k);
1790 template<
bool force_filtration_value>
1791 void create_expansion(
Siblings * siblings,
1793 Dictionary_it& next,
1796 std::vector<Simplex_handle>* added_simplices =
nullptr)
1798 Simplex_handle root_sh = find_vertex(s_h->first);
1799 thread_local std::vector<std::pair<Vertex_handle, Node> > inter;
1803 intersection<force_filtration_value>(
1806 siblings->members().end(),
1807 root_sh->second.children()->members().begin(),
1808 root_sh->second.children()->members().end(),
1810 if (inter.size() != 0) {
1814 for (
auto it = new_sib->members().begin(); it != new_sib->members().end(); ++it) {
1815 update_simplex_tree_after_node_insertion(it);
1816 if constexpr (force_filtration_value){
1818 added_simplices->push_back(it);
1822 s_h->second.assign_children(new_sib);
1823 if constexpr (force_filtration_value){
1824 siblings_expansion(new_sib, fil, k - 1, *added_simplices);
1826 siblings_expansion(new_sib, k - 1);
1830 s_h->second.assign_children(siblings);
1837 template<
bool force_filtration_value = false>
1838 static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
1839 Dictionary_const_it begin1, Dictionary_const_it end1,
1840 Dictionary_const_it begin2, Dictionary_const_it end2,
1842 if (begin1 == end1 || begin2 == end2)
1845 if (begin1->first == begin2->first) {
1846 if constexpr (force_filtration_value){
1847 intersection.emplace_back(begin1->first, Node(
nullptr, filtration_));
1849 Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
1850 intersection.emplace_back(begin1->first, Node(
nullptr, filt));
1852 if (++begin1 == end1 || ++begin2 == end2)
1854 }
else if (begin1->first < begin2->first) {
1855 if (++begin1 == end1)
1858 if (++begin2 == end2)
1883 template<
typename Blocker >
1886 for (
auto&
simplex : boost::adaptors::reverse(root_.members())) {
1888 siblings_expansion_with_blockers(
simplex.second.children(), max_dim, max_dim - 1, block_simplex);
1895 template<
typename Blocker >
1896 void siblings_expansion_with_blockers(
Siblings* siblings,
int max_dim,
int k, Blocker block_simplex) {
1897 if (dimension_ < max_dim - k) {
1898 dimension_ = max_dim - k;
1903 if (siblings->members().size() < 2)
1906 for (
auto simplex = std::next(siblings->members().rbegin());
simplex != siblings->members().rend();
simplex++) {
1907 std::vector<std::pair<Vertex_handle, Node> > intersection;
1908 for(
auto next = siblings->members().rbegin(); next !=
simplex; next++) {
1909 bool to_be_inserted =
true;
1913 Simplex_handle border_child = find_child(border, next->first);
1915 to_be_inserted=
false;
1918 filt = (std::max)(filt,
filtration(border_child));
1920 if (to_be_inserted) {
1921 intersection.emplace_back(next->first, Node(
nullptr, filt));
1924 if (intersection.size() != 0) {
1929 boost::adaptors::reverse(intersection));
1930 simplex->second.assign_children(new_sib);
1931 std::vector<Vertex_handle> blocked_new_sib_vertex_list;
1933 for (
auto new_sib_member = new_sib->members().begin();
1934 new_sib_member != new_sib->members().end();
1936 update_simplex_tree_after_node_insertion(new_sib_member);
1937 bool blocker_result = block_simplex(new_sib_member);
1940 if (blocker_result) {
1941 blocked_new_sib_vertex_list.push_back(new_sib_member->first);
1944 update_simplex_tree_before_node_removal(new_sib_member);
1947 if (blocked_new_sib_vertex_list.size() == new_sib->members().size()) {
1951 simplex->second.assign_children(siblings);
1953 for (
auto& blocked_new_sib_member : blocked_new_sib_vertex_list) {
1954 new_sib->members().erase(blocked_new_sib_member);
1957 siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex);
1961 simplex->second.assign_children(siblings);
1970 Simplex_handle find_child(Simplex_handle sh,
Vertex_handle vh)
const {
1974 Simplex_handle child = sh->second.children()->find(vh);
1977 if (child == sh->second.children()->members().end())
1999 os <<
key(b_sh) <<
" ";
2018 if constexpr (std::is_same_v<void,
decltype(fun(sh, dim))>) {
2022 return fun(sh, dim);
2026 rec_for_each_simplex(
root(), 0, f);
2031 void rec_for_each_simplex(
const Siblings* sib,
int dim, Fun&& fun)
const {
2032 Simplex_handle sh = sib->members().end();
2033 GUDHI_CHECK(sh != sib->members().begin(),
"Bug in Gudhi: only the root siblings may be empty");
2037 rec_for_each_simplex(sh->second.children(), dim+1, fun);
2041 while(sh != sib->members().begin());
2052 bool modified =
false;
2053 auto fun = [&modified,
this](
Simplex_handle sh,
int dim) ->
void {
2054 if (dim == 0)
return;
2065 if (!(sh->second.filtration() >= max_filt_border_value)) {
2082 root_members_recursive_deletion();
2085 dimension_to_be_lowered_ =
false;
2086 if constexpr (Options::link_nodes_by_label)
2087 nodes_label_to_list_.clear();
2098 if (std::numeric_limits<Filtration_value>::has_infinity &&
filtration == std::numeric_limits<Filtration_value>::infinity())
2108 auto&& list = sib->members();
2109 bool modified =
false;
2110 bool emptied =
false;
2111 Simplex_handle last;
2113 auto to_remove = [
this, filt](Dit_value_t&
simplex) {
2114 if (
simplex.second.filtration() <= filt)
return false;
2117 dimension_to_be_lowered_ =
true;
2123 if constexpr (Options::stable_simplex_handles) {
2125 for (
auto sh = list.begin(); sh != list.end();) {
2126 if (to_remove(*sh)) {
2127 sh = list.erase(sh);
2133 emptied = (list.empty() && sib !=
root());
2135 last = std::remove_if(list.begin(), list.end(), to_remove);
2136 modified = (last != list.end());
2137 emptied = (last == list.begin() && sib !=
root());
2142 sib->oncles()->members()[sib->parent()].assign_children(sib->oncles());
2145 dimension_to_be_lowered_ =
true;
2149 if constexpr (!Options::stable_simplex_handles) list.erase(last, list.end());
2166 bool modified =
false;
2169 root_members_recursive_deletion();
2186 bool rec_prune_above_dimension(
Siblings* sib,
int dim,
int actual_dim) {
2187 bool modified =
false;
2188 auto&& list = sib->members();
2192 if (actual_dim >= dim) {
2193 rec_delete(
simplex.second.children());
2194 simplex.second.assign_children(sib);
2197 modified |= rec_prune_above_dimension(
simplex.second.children(), dim, actual_dim + 1);
2210 bool lower_upper_bound_dimension()
const {
2212 dimension_to_be_lowered_ =
false;
2213 int new_dimension = -1;
2218 std::clog <<
" " << vertex;
2220 std::clog << std::endl;
2224 if (sh_dimension >= dimension_)
2227 new_dimension = (std::max)(new_dimension, sh_dimension);
2229 dimension_ = new_dimension;
2246 std::invalid_argument(
"Simplex_tree::remove_maximal_simplex - argument has children"));
2248 update_simplex_tree_before_node_removal(sh);
2251 Dictionary_it nodeIt = _to_node_it(sh);
2252 Siblings* child = nodeIt->second.children();
2254 if ((child->size() > 1) || (child ==
root())) {
2257 child->erase(nodeIt);
2260 child->oncles()->members().at(child->parent()).assign_children(child->oncles());
2263 dimension_to_be_lowered_ =
true;
2284 std::pair<Filtration_value, Extended_simplex_type> p;
2287 if (f >= -2 && f <= -1) {
2288 p.first = minval + (maxval-minval)*(f + 2); p.second = Extended_simplex_type::UP;
2289 }
else if (f >= 1 && f <= 2) {
2290 p.first = minval - (maxval-minval)*(f - 2); p.second = Extended_simplex_type::DOWN;
2292 p.first = std::numeric_limits<Filtration_value>::quiet_NaN(); p.second = Extended_simplex_type::EXTRA;
2314 Vertex_handle maxvert = std::numeric_limits<Vertex_handle>::min();
2315 Filtration_value minval = std::numeric_limits<Filtration_value>::infinity();
2316 Filtration_value maxval = -std::numeric_limits<Filtration_value>::infinity();
2317 for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
2319 minval = std::min(minval, f);
2320 maxval = std::max(maxval, f);
2321 maxvert = std::max(sh->first, maxvert);
2324 GUDHI_CHECK(maxvert < std::numeric_limits<Vertex_handle>::max(), std::invalid_argument(
"Simplex_tree contains a vertex with the largest Vertex_handle"));
2330 this->insert_simplex_raw({maxvert}, -3);
2337 std::vector<Vertex_handle> vr;
2340 vr.assign(simplex_range.begin(), simplex_range.end());
2341 auto sh = this->
find(vr);
2344 vr.push_back(maxvert);
2363 return Extended_filtration_data(minval, maxval);
2371 auto filt = filtration_(sh);
2373 if(filtration_(find_vertex(v)) == filt)
2387 auto end = std::end(vertices);
2388 auto vi = std::begin(vertices);
2389 GUDHI_CHECK(vi != end,
"empty simplex");
2392 GUDHI_CHECK(vi != end,
"simplex of dimension 0");
2393 if(std::next(vi) == end)
return sh;
2394 Static_vertex_vector suffix;
2395 suffix.push_back(v0);
2396 auto filt = filtration_(sh);
2400 auto&& children1 = find_vertex(v)->second.children()->members_;
2401 for(
auto w : suffix){
2404 if(filtration_(s) == filt)
2407 suffix.push_back(v);
2418 auto filt = filtration_(sh);
2421 if(filtration_(b) == filt)
2429 &Hooks_simplex_base_link_nodes::list_max_vertex_hook_>
2433 boost::intrusive::constant_time_size<false>> List_max_vertex;
2443 std::unordered_map<Vertex_handle, List_max_vertex> nodes_label_to_list_;
2448 return const_cast<List_max_vertex*
>(std::as_const(*this).nodes_by_label(v));
2451 List_max_vertex
const* nodes_by_label(
Vertex_handle v)
const {
2452 if constexpr (Options::link_nodes_by_label) {
2453 auto it_v = nodes_label_to_list_.find(v);
2454 if (it_v != nodes_label_to_list_.end()) {
2455 return &(it_v->second);
2465 static Simplex_handle simplex_handle_from_node(
const Node& node) {
2466 if constexpr (Options::stable_simplex_handles){
2477 Dictionary_const_it testIt = node.children()->members().begin();
2478 const Node* testNode = &testIt->second;
2479 auto testIIt = testIt.get();
2480 auto testPtr = testIIt.pointed_node();
2482 auto shift = (
const char*)(testNode) - (
const char*)(testPtr);
2485 decltype(testPtr) sh_ptr =
decltype(testPtr)((
const char*)(&node) - shift);
2497 decltype(testIIt) sh_ii;
2499 Dictionary_const_it sh(sh_ii);
2504 return (Simplex_handle)(boost::intrusive::get_parent_from_member<Dit_value_t>(
const_cast<Node*
>(&node),
2505 &Dit_value_t::second));
2511 friend class Simplex_tree_optimized_cofaces_rooted_subtrees_simplex_iterator<
Simplex_tree>;
2516 void update_simplex_tree_after_node_insertion(Simplex_handle sh) {
2518 std::clog <<
"update_simplex_tree_after_node_insertion" << std::endl;
2520 if constexpr (Options::link_nodes_by_label) {
2522 nodes_label_to_list_[sh->first].push_back(_to_node_it(sh)->second);
2528 void update_simplex_tree_before_node_removal(Simplex_handle sh) {
2530 std::clog <<
"update_simplex_tree_before_node_removal" << std::endl;
2532 if constexpr (Options::link_nodes_by_label) {
2533 _to_node_it(sh)->second.unlink_hooks();
2534 if (nodes_label_to_list_[sh->first].empty())
2535 nodes_label_to_list_.erase(sh->first);
2549 rec_reset_filtration(&root_, filt_value, min_dim);
2560 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
2561 if (min_depth <= 0) {
2562 sh->second.assign_filtration(filt_value);
2565 rec_reset_filtration(sh->second.children(), filt_value, min_depth - 1);
2578 std::size_t get_serialization_size()
const {
2581 const std::size_t buffer_byte_size = vh_byte_size +
num_simplices() * (fv_byte_size + 2 * vh_byte_size);
2583 std::clog <<
"Gudhi::simplex_tree::get_serialization_size - buffer size = " << buffer_byte_size << std::endl;
2585 return buffer_byte_size;
2619 void serialize(
char* buffer,
const std::size_t buffer_size)
const {
2620 char* buffer_end = rec_serialize(&root_, buffer);
2621 if (
static_cast<std::size_t
>(buffer_end - buffer) != buffer_size)
2622 throw std::invalid_argument(
"Serialization does not match end of buffer");
2627 char* rec_serialize(
Siblings const *sib,
char* buffer)
const {
2629 ptr = Gudhi::simplex_tree::serialize_trivial(
static_cast<Vertex_handle>(sib->members().size()), ptr);
2631 std::clog <<
"\n" << sib->members().size() <<
" : ";
2633 for (
auto& map_el : sib->members()) {
2634 ptr = Gudhi::simplex_tree::serialize_trivial(map_el.first, ptr);
2635 if (Options::store_filtration)
2636 ptr = Gudhi::simplex_tree::serialize_trivial(map_el.second.filtration(), ptr);
2638 std::clog <<
" [ " << map_el.first <<
" | " << map_el.second.filtration() <<
" ] ";
2641 for (
auto& map_el : sib->members()) {
2643 ptr = rec_serialize(map_el.second.children(), ptr);
2645 ptr = Gudhi::simplex_tree::serialize_trivial(
static_cast<Vertex_handle>(0), ptr);
2647 std::cout <<
"\n0 : ";
2669 void deserialize(
const char* buffer,
const std::size_t buffer_size) {
2670 GUDHI_CHECK(
num_vertices() == 0, std::logic_error(
"Simplex_tree::deserialize - Simplex_tree must be empty"));
2671 const char* ptr = buffer;
2674 ptr = Gudhi::simplex_tree::deserialize_trivial(members_size, ptr);
2675 ptr = rec_deserialize(&root_, members_size, ptr, 0);
2676 if (
static_cast<std::size_t
>(ptr - buffer) != buffer_size) {
2677 throw std::invalid_argument(
"Deserialization does not match end of buffer");
2685 if (members_size > 0) {
2686 if constexpr (!Options::stable_simplex_handles) sib->members_.reserve(members_size);
2690 ptr = Gudhi::simplex_tree::deserialize_trivial(vertex, ptr);
2691 if (Options::store_filtration) {
2692 ptr = Gudhi::simplex_tree::deserialize_trivial(
filtration, ptr);
2694 sib->members_.emplace_hint(sib->members_.end(), vertex, Node(sib,
filtration));
2697 sib->members_.emplace_hint(sib->members_.end(), vertex, Node(sib));
2701 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
2702 update_simplex_tree_after_node_insertion(sh);
2703 ptr = Gudhi::simplex_tree::deserialize_trivial(child_size, ptr);
2704 if (child_size > 0) {
2706 sh->second.assign_children(child);
2707 ptr = rec_deserialize(child, child_size, ptr, dim + 1);
2710 if (dim > dimension_) {
2727 mutable std::vector<Simplex_handle> filtration_vect_;
2729 mutable int dimension_;
2730 mutable bool dimension_to_be_lowered_ =
false;
2734template<
typename...T>
2737 os << st.dimension(sh) <<
" ";
2746template<
typename...T>
2749 std::vector<typename ST::Vertex_handle> simplex;
2755 int dim =
static_cast<int> (simplex.size() - 1);
2756 if (max_dim < dim) {
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:193
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree_iterators.h:81
Iterator over the simplices of a simplicial complex.
Definition: Simplex_tree_iterators.h:308
Iterator over the simplices of the star of a simplex.
Definition: Simplex_tree_star_simplex_iterators.h:162
Iterator over the vertices of a simplex in a SimplexTree.
Definition: Simplex_tree_iterators.h:36
Iterator over the simplices of the skeleton of a given dimension of the simplicial complex.
Definition: Simplex_tree_iterators.h:382
Simplex Tree data structure for representing simplicial complexes.
Definition: Simplex_tree.h:98
Simplex_tree(Simplex_tree &&complex_source)
User-defined move constructor relocates the whole tree structure including extra data (Simplex_data) ...
Definition: Simplex_tree.h:460
std::vector< size_t > num_simplices_by_dimension() const
Returns the number of simplices of each dimension in the simplex tree.
Definition: Simplex_tree.h:826
void for_each_simplex(Fun &&fun) const
Definition: Simplex_tree.h:2015
void insert_edge_as_flag(Vertex_handle u, Vertex_handle v, Filtration_value fil, int dim_max, std::vector< Simplex_handle > &added_simplices)
Adds a new vertex or a new edge in a flag complex, as well as all simplices of its star,...
Definition: Simplex_tree.h:1559
Options::Filtration_value Filtration_value
Type for the value of the filtration function.
Definition: Simplex_tree.h:105
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:281
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:2548
int dimension(Simplex_handle sh) const
Returns the dimension of a simplex.
Definition: Simplex_tree.h:847
void assign_filtration(Simplex_handle sh, Filtration_value fv)
Sets the filtration value of a simplex.
Definition: Simplex_tree.h:738
Siblings const * self_siblings(SimplexHandle sh) const
Definition: Simplex_tree.h:1154
std::conditional< Options::link_nodes_by_label, Optimized_cofaces_simplex_filtered_range, std::vector< Simplex_handle > >::type Cofaces_simplex_range
Range over the cofaces of a simplex.
Definition: Simplex_tree.h:265
void initialize_filtration(bool ignore_infinite_values=false) const
Initializes the filtration cache, i.e. sorts the simplices according to their order in the filtration...
Definition: Simplex_tree.h:1200
Complex_simplex_range complex_simplex_range() const
Returns a range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:321
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:2051
bool operator==(const Simplex_tree< OtherSimplexTreeOptions > &st2) const
Checks if two simplex trees are equal. Any extra data (Simplex_data) stored in the simplices are igno...
Definition: Simplex_tree.h:653
Vertex_handle vertex_with_same_filtration(Simplex_handle sh) const
Returns a vertex of sh that has the same filtration value as sh if it exists, and null_vertex() other...
Definition: Simplex_tree.h:2370
bool operator!=(const Simplex_tree< OtherSimplexTreeOptions > &st2) const
Checks if two simplex trees are different.
Definition: Simplex_tree.h:662
bool prune_above_dimension(int dimension)
Remove all simplices of dimension greater than a given value.
Definition: Simplex_tree.h:2162
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:1045
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:773
Simplex_handle edge_with_same_filtration(Simplex_handle sh) const
Returns an edge of sh that has the same filtration value as sh if it exists, and null_simplex() other...
Definition: Simplex_tree.h:2384
boost::iterator_range< Boundary_simplex_iterator > Boundary_simplex_range
Range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:277
Simplex_vertex_range simplex_vertex_range(Simplex_handle sh) const
Returns a range over the vertices of a simplex.
Definition: Simplex_tree.h:369
Boundary_opposite_vertex_simplex_range boundary_opposite_vertex_simplex_range(SimplexHandle sh) const
Given a simplex, returns a range over the simplices of its boundary and their opposite vertices.
Definition: Simplex_tree.h:407
Simplex_tree_simplex_vertex_iterator< Simplex_tree > Simplex_vertex_iterator
Iterator over the vertices of a simplex.
Definition: Simplex_tree.h:259
void clear()
Remove all the simplices, leaving an empty complex.
Definition: Simplex_tree.h:2081
static Simplex_key key(Simplex_handle sh)
Returns the key associated to a simplex.
Definition: Simplex_tree.h:708
static Filtration_value filtration(Simplex_handle sh)
Returns the filtration value of a simplex.
Definition: Simplex_tree.h:727
Simplex_tree(const Simplex_tree< OtherSimplexTreeOptions > &complex_source, F &&translate_filtration_value)
Construct the simplex tree as the copy of a given simplex tree with eventually different template par...
Definition: Simplex_tree.h:439
Cofaces_simplex_range star_simplex_range(const Simplex_handle simplex) const
Compute the star of a n simplex.
Definition: Simplex_tree.h:1310
boost::transform_iterator< return_first, Dictionary_const_it > Complex_vertex_iterator
Iterator over the vertices of the simplicial complex.
Definition: Simplex_tree.h:253
bool has_children(SimplexHandle sh) const
Returns true if the node in the simplex tree pointed by the given simplex handle has children.
Definition: Simplex_tree.h:874
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:1884
boost::iterator_range< Simplex_vertex_iterator > Simplex_vertex_range
Range over the vertices of a simplex.
Definition: Simplex_tree.h:261
void remove_maximal_simplex(Simplex_handle sh)
Remove a maximal simplex.
Definition: Simplex_tree.h:2243
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:1140
Options::Simplex_key Simplex_key
Key associated to each simplex.
Definition: Simplex_tree.h:109
Simplex_tree()
Constructs an empty simplex tree.
Definition: Simplex_tree.h:417
boost::iterator_range< Complex_simplex_iterator > Complex_simplex_range
Range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:289
Dictionary::const_iterator Simplex_handle
Handle type to a simplex contained in the simplicial complex represented by the simplex tree.
Definition: Simplex_tree.h:192
Simplex_tree_boundary_simplex_iterator< Simplex_tree > Boundary_simplex_iterator
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:275
const Simplex_data & simplex_data(Simplex_handle sh) const
Returns the extra data stored in a simplex.
Definition: Simplex_tree.h:765
Simplex_tree_siblings< Simplex_tree, Dictionary > Siblings
Set of nodes sharing a same parent in the simplex tree.
Definition: Simplex_tree.h:136
Siblings * self_siblings(SimplexHandle sh)
Definition: Simplex_tree.h:1163
std::pair< Simplex_handle, Simplex_handle > endpoints(Simplex_handle sh) const
Definition: Simplex_tree.h:1147
bool is_empty() const
Returns whether the complex is empty.
Definition: Simplex_tree.h:783
Simplex_tree_complex_simplex_iterator< Simplex_tree > Complex_simplex_iterator
Iterator over the simplices of the simplicial complex.
Definition: Simplex_tree.h:287
Simplex_handle simplex(Simplex_key idx) const
Returns the simplex that has index idx in the filtration.
Definition: Simplex_tree.h:718
void print_hasse(std::ostream &os) const
Write the hasse diagram of the simplicial complex in os.
Definition: Simplex_tree.h:1993
Simplex_data & simplex_data(Simplex_handle sh)
Returns the extra data stored in a simplex.
Definition: Simplex_tree.h:758
void insert_batch_vertices(VertexRange const &vertices, Filtration_value filt=0)
Inserts several vertices.
Definition: Simplex_tree.h:1487
std::vector< Simplex_handle > Filtration_simplex_range
Range over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:299
Filtration_simplex_range::const_iterator Filtration_simplex_iterator
Iterator over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:303
int dimension() const
Returns the dimension of the simplicial complex.
Definition: Simplex_tree.h:865
Extended_filtration_data extend_filtration()
Extend filtration for computing extended persistence. This function only uses the filtration values a...
Definition: Simplex_tree.h:2310
std::pair< Filtration_value, Extended_simplex_type > decode_extended_filtration(Filtration_value f, const Extended_filtration_data &efd) const
Retrieve the original filtration value for a given simplex in the Simplex_tree. Since the computation...
Definition: Simplex_tree.h:2283
void maybe_initialize_filtration() const
Initializes the filtration cache if it isn't initialized yet.
Definition: Simplex_tree.h:1231
Options::Vertex_handle Vertex_handle
Type for the vertex handle.
Definition: Simplex_tree.h:119
Skeleton_simplex_range skeleton_simplex_range(int dim) const
Returns a range over the simplices of the dim-skeleton of the simplicial complex.
Definition: Simplex_tree.h:335
Filtration_simplex_range const & filtration_simplex_range(Indexing_tag=Indexing_tag()) const
Returns a range over the simplices of the simplicial complex, in the order of the filtration.
Definition: Simplex_tree.h:358
size_t num_vertices() const
Returns the number of vertices in the complex.
Definition: Simplex_tree.h:778
Cofaces_simplex_range cofaces_simplex_range(const Simplex_handle simplex, int codimension) const
Compute the cofaces of a n simplex.
Definition: Simplex_tree.h:1324
void clear_filtration() const
Clears the filtration cache produced by initialize_filtration().
Definition: Simplex_tree.h:1243
void expansion(int max_dim)
Expands the Simplex_tree containing only its one skeleton until dimension max_dim.
Definition: Simplex_tree.h:1512
Simplex_tree(const Simplex_tree &complex_source)
User-defined copy constructor reproduces the whole tree structure including extra data (Simplex_data)...
Definition: Simplex_tree.h:449
size_t num_simplices() const
Returns the number of simplices in the simplex_tree.
Definition: Simplex_tree.h:791
boost::iterator_range< Complex_vertex_iterator > Complex_vertex_range
Range over the vertices of the simplicial complex.
Definition: Simplex_tree.h:255
static Simplex_key null_key()
Returns a fixed number not in the interval [0, num_simplices()).
Definition: Simplex_tree.h:753
Simplex_handle minimal_simplex_with_same_filtration(Simplex_handle sh) const
Returns a minimal face of sh that has the same filtration value as sh.
Definition: Simplex_tree.h:2417
bool prune_above_filtration(Filtration_value filtration)
Prune above filtration value given as parameter.
Definition: Simplex_tree.h:2097
int upper_bound_dimension() const
Returns an upper bound on the dimension of the simplicial complex.
Definition: Simplex_tree.h:855
Siblings * root()
Definition: Simplex_tree.h:1171
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:1074
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:294
Simplex_tree & operator=(Simplex_tree &&complex_source)
User-defined move assignment relocates the whole tree structure including extra data (Simplex_data) s...
Definition: Simplex_tree.h:497
const Siblings * root() const
Definition: Simplex_tree.h:1174
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:283
Simplex_tree & operator=(const Simplex_tree &complex_source)
User-defined copy assignment reproduces the whole tree structure including extra data (Simplex_data) ...
Definition: Simplex_tree.h:479
Complex_vertex_range complex_vertex_range() const
Returns a range over the vertices of the simplicial complex. The order is increasing according to < o...
Definition: Simplex_tree.h:311
void insert_graph(const OneSkeletonGraph &skel_graph)
Inserts a 1-skeleton in an empty Simplex_tree.
Definition: Simplex_tree.h:1424
Get_simplex_data_type< Options >::type Simplex_data
Extra data stored in each simplex.
Definition: Simplex_tree.h:115
Simplex_handle find(const InputVertexRange &s) const
Given a range of Vertex_handles, returns the Simplex_handle of the simplex in the simplicial complex ...
Definition: Simplex_tree.h:899
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:297
~Simplex_tree()
Destructor; deallocates the whole tree structure.
Definition: Simplex_tree.h:472
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:748
Boundary_simplex_range boundary_simplex_range(SimplexHandle sh) const
Returns a range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:390
void set_dimension(int dimension, bool exact=true)
Set a dimension for the simplicial complex.
Definition: Simplex_tree.h:1184
Graph simplicial complex methods.
std::ostream & operator<<(std::ostream &os, const Permutahedral_representation< Vertex, OrderedSetPartition > &simplex)
Print a permutahedral representation to a stream.
Definition: Permutahedral_representation.h:173
constexpr auto & get(Gudhi::persistence_matrix::Persistence_interval< Dimension, Event_value > &i) noexcept
Partial specialization of get for Gudhi::persistence_matrix::Persistence_interval.
Definition: persistence_interval.h:199
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
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
This file includes common file reader for GUDHI.
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20
No hook when SimplexTreeOptions::link_nodes_by_label is false.
Definition: hooks_simplex_base.h:20
Data structure to put all simplex tree nodes with same label into a list.
Definition: hooks_simplex_base.h:29
Node of a simplex tree with filtration value and simplex key.
Definition: Simplex_tree_node_explicit_storage.h:40
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:17
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:34
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15