16 #ifndef SIMPLEX_TREE_H_
17 #define SIMPLEX_TREE_H_
19 #include <gudhi/Simplex_tree/simplex_tree_options.h>
20 #include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h>
21 #include <gudhi/Simplex_tree/Simplex_tree_siblings.h>
22 #include <gudhi/Simplex_tree/Simplex_tree_iterators.h>
23 #include <gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h>
24 #include <gudhi/Simplex_tree/serialization_utils.h>
25 #include <gudhi/Simplex_tree/hooks_simplex_base.h>
29 #include <gudhi/Debug_utils.h>
31 #include <boost/container/map.hpp>
32 #include <boost/container/flat_map.hpp>
33 #include <boost/iterator/transform_iterator.hpp>
34 #include <boost/graph/adjacency_list.hpp>
35 #include <boost/range/adaptor/reversed.hpp>
36 #include <boost/range/adaptor/transformed.hpp>
37 #include <boost/range/size.hpp>
38 #include <boost/container/static_vector.hpp>
39 #include <boost/range/adaptors.hpp>
41 #include <boost/intrusive/list.hpp>
42 #include <boost/intrusive/parent_from_member.hpp>
46 #include <tbb/parallel_sort.h>
54 #include <initializer_list>
57 #include <type_traits>
58 #include <unordered_map>
94 template<
typename SimplexTreeOptions = Simplex_tree_options_default>
118 typedef typename boost::container::flat_map<Vertex_handle, Node> flat_map;
121 typedef typename boost::container::map<Vertex_handle, Node> map;
122 typedef typename std::conditional<Options::stable_simplex_handles,
124 flat_map>::type Dictionary;
131 struct Key_simplex_base_real {
132 Key_simplex_base_real() : key_(-1) {}
138 struct Key_simplex_base_dummy {
139 Key_simplex_base_dummy() {}
144 struct Extended_filtration_data {
147 Extended_filtration_data(){}
150 typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type
153 struct Filtration_simplex_base_real {
154 Filtration_simplex_base_real() : filt_(0) {}
160 struct Filtration_simplex_base_dummy {
161 Filtration_simplex_base_dummy() {}
165 typedef typename std::conditional<Options::store_filtration, Filtration_simplex_base_real,
166 Filtration_simplex_base_dummy>::type Filtration_simplex_base;
178 typedef typename Dictionary::iterator Dictionary_it;
179 typedef typename Dictionary_it::value_type Dit_value_t;
181 struct return_first {
196 using Optimized_star_simplex_range = boost::iterator_range<Optimized_star_simplex_iterator>;
198 class Fast_cofaces_predicate {
203 Fast_cofaces_predicate(
Simplex_tree* st,
int codim,
int dim)
204 : st_(st), codim_(codim), dim_(codim + dim) {}
205 bool operator()(
const Simplex_handle iter )
const {
210 return dim_ == st_->dimension(iter);
216 using Optimized_cofaces_simplex_filtered_range = boost::filtered_range<Fast_cofaces_predicate,
217 Optimized_star_simplex_range>;
222 static constexpr
int max_dimension() {
return 40; }
245 typedef typename std::conditional<Options::link_nodes_by_label,
246 Optimized_cofaces_simplex_filtered_range,
252 using Static_vertex_vector = boost::container::static_vector<
Vertex_handle, max_dimension()>;
295 boost::make_transform_iterator(root_.members_.begin(), return_first()),
296 boost::make_transform_iterator(root_.members_.end(), return_first()));
340 return filtration_vect_;
369 template<
class SimplexHandle>
386 template<
class SimplexHandle>
399 root_(nullptr, null_vertex_),
406 std::clog <<
"Simplex_tree copy constructor" << std::endl;
408 copy_from(complex_source);
416 std::clog <<
"Simplex_tree move constructor" << std::endl;
418 move_from(complex_source);
422 complex_source.dimension_ = -1;
427 root_members_recursive_deletion();
433 std::clog <<
"Simplex_tree copy assignment" << std::endl;
436 if (&complex_source !=
this) {
438 root_members_recursive_deletion();
440 copy_from(complex_source);
450 std::clog <<
"Simplex_tree move assignment" << std::endl;
453 if (&complex_source !=
this) {
455 root_members_recursive_deletion();
457 move_from(complex_source);
466 null_vertex_ = complex_source.null_vertex_;
467 filtration_vect_.clear();
468 dimension_ = complex_source.dimension_;
469 auto root_source = complex_source.root_;
472 root_.members() = Dictionary(boost::container::ordered_unique_range, root_source.members().begin(), root_source.members().end());
474 for (
auto& map_el : root_.members()) {
475 map_el.second.assign_children(&root_);
477 rec_copy(&root_, &root_source);
482 for (
auto sh = sib->members().begin(), sh_source = sib_source->members().begin();
483 sh != sib->members().end(); ++sh, ++sh_source) {
484 update_simplex_tree_after_node_insertion(sh);
487 if constexpr (!Options::stable_simplex_handles) {
488 newsib->members_.reserve(sh_source->second.children()->members().size());
490 for (
auto & child : sh_source->second.children()->members())
491 newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(newsib, child.second.filtration()));
492 rec_copy(newsib, sh_source->second.children());
493 sh->second.assign_children(newsib);
500 null_vertex_ = std::move(complex_source.null_vertex_);
501 root_ = std::move(complex_source.root_);
502 filtration_vect_ = std::move(complex_source.filtration_vect_);
503 dimension_ = complex_source.dimension_;
504 if constexpr (Options::link_nodes_by_label) {
505 nodes_label_to_list_.swap(complex_source.nodes_label_to_list_);
508 for (
auto& map_el : root_.members()) {
509 if (map_el.second.children() != &(complex_source.root_)) {
511 map_el.second.children()->oncles_ = &root_;
514 GUDHI_CHECK(map_el.second.children()->oncles_ ==
nullptr,
515 std::invalid_argument(
"Simplex_tree move constructor from an invalid Simplex_tree"));
517 map_el.second.assign_children(&root_);
523 void root_members_recursive_deletion() {
524 for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
526 rec_delete(sh->second.children());
529 root_.members().clear();
534 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
536 rec_delete(sh->second.children());
546 template<
class OtherSimplexTreeOptions>
548 if ((null_vertex_ != st2.null_vertex_) ||
549 (dimension_ != st2.dimension_ && !dimension_to_be_lowered_ && !st2.dimension_to_be_lowered_))
551 return rec_equal(&root_, &st2.root_);
555 template<
class OtherSimplexTreeOptions>
557 return (!(*
this == st2));
562 template<
class OtherSiblings>
563 bool rec_equal(
Siblings* s1, OtherSiblings* s2) {
564 if (s1->members().size() != s2->members().size())
566 auto sh2 = s2->members().begin();
567 for (
auto sh1 = s1->members().begin();
568 (sh1 != s1->members().end() && sh2 != s2->members().end());
570 if (sh1->first != sh2->first || sh1->second.filtration() != sh2->second.filtration())
576 if (!rec_equal(sh1->second.children(), sh2->second.children()))
588 return sh->second.filtration();
598 return sh->second.key();
606 return filtration_vect_[idx];
616 return sh->second.filtration();
618 return std::numeric_limits<Filtration_value>::infinity();
627 std::invalid_argument(
"Simplex_tree::assign_filtration - cannot assign filtration on null_simplex"));
628 sh->second.assign_filtration(fv);
636 return Dictionary_it();
652 return root_.members_.size();
657 return root_.members_.empty();
671 auto sib_begin = sib->members().begin();
672 auto sib_end = sib->members().end();
673 size_t simplices_number = sib->members().size();
674 for (
auto sh = sib_begin; sh != sib_end; ++sh) {
679 return simplices_number;
690 while (curr_sib !=
nullptr) {
692 curr_sib = curr_sib->oncles();
703 auto fun = [&res](
Simplex_handle,
int dim) ->
void { ++res[dim]; };
705 if (dimension_to_be_lowered_) {
706 GUDHI_CHECK(res.front() != 0, std::logic_error(
"Bug in Gudhi: non-empty complex has no vertex"));
707 while (res.back() == 0) res.pop_back();
708 dimension_ =
static_cast<int>(res.size()) - 1;
709 dimension_to_be_lowered_ =
false;
711 GUDHI_CHECK(res.back() != 0,
712 std::logic_error(
"Bug in Gudhi: there is no simplex of dimension the dimension of the complex"));
734 if (dimension_to_be_lowered_)
735 lower_upper_bound_dimension();
741 template<
class SimplexHandle>
744 return (sh->second.children()->parent() == sh->first);
753 Siblings* children(Simplex_handle sh)
const {
754 GUDHI_CHECK(
has_children(sh), std::invalid_argument(
"Simplex_tree::children - argument has no child"));
755 return sh->second.children();
766 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
768 auto first = std::begin(s);
769 auto last = std::end(s);
775 std::vector<Vertex_handle> copy(first, last);
776 std::sort(std::begin(copy), std::end(copy));
777 return find_simplex(copy);
782 Simplex_handle find_simplex(
const std::vector<Vertex_handle> &
simplex) {
784 Dictionary_it tmp_dit;
786 if constexpr (Options::contiguous_vertices && !Options::stable_simplex_handles) {
788 GUDHI_CHECK(contiguous_vertices(),
"non-contiguous vertices");
790 if(v < 0 || v >=
static_cast<Vertex_handle>(root_.members_.size()))
792 tmp_dit = root_.members_.begin() + v;
797 tmp_sib = tmp_dit->second.children();
800 tmp_dit = tmp_sib->members_.find(*vi++);
801 if (tmp_dit == tmp_sib->members_.end())
807 tmp_sib = tmp_dit->second.children();
814 if constexpr (Options::contiguous_vertices && !Options::stable_simplex_handles) {
815 assert(contiguous_vertices());
816 return root_.members_.begin() + v;
818 return root_.members_.find(v);
824 bool contiguous_vertices()
const {
825 if (root_.members_.empty())
return true;
826 if (root_.members_.begin()->first != 0)
return false;
827 if (std::prev(root_.members_.end())->first !=
static_cast<Vertex_handle>(root_.members_.size() - 1))
return false;
846 template <
class RandomVertexHandleRange = std::initializer_list<Vertex_handle>>
847 std::pair<Simplex_handle, bool> insert_simplex_raw(
const RandomVertexHandleRange&
simplex,
850 std::pair<Simplex_handle, bool> res_insert;
852 for (; vi != std::prev(
simplex.end()); ++vi) {
853 GUDHI_CHECK(*vi !=
null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
854 res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib,
filtration));
855 if (res_insert.second) {
857 update_simplex_tree_after_node_insertion(res_insert.first);
860 res_insert.first->second.assign_children(
new Siblings(curr_sib, *vi));
862 curr_sib = res_insert.first->second.children();
864 GUDHI_CHECK(*vi !=
null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
865 res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib,
filtration));
866 if (!res_insert.second) {
868 if (res_insert.first->second.filtration() >
filtration) {
870 res_insert.first->second.assign_filtration(
filtration);
874 return std::pair<Simplex_handle, bool>(
null_simplex(),
false);
877 update_simplex_tree_after_node_insertion(res_insert.first);
880 int dim =
static_cast<int>(boost::size(
simplex)) - 1;
881 if (dim > dimension_) {
912 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
915 auto first = std::begin(
simplex);
919 return std::pair<Simplex_handle, bool>(
null_simplex(),
true);
922 std::vector<Vertex_handle> copy(first, last);
923 std::sort(std::begin(copy), std::end(copy));
941 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
944 auto first = std::begin(Nsimplex);
945 auto last = std::end(Nsimplex);
950 thread_local std::vector<Vertex_handle> copy;
952 copy.insert(copy.end(), first, last);
953 std::sort(copy.begin(), copy.end());
954 auto last_unique = std::unique(copy.begin(), copy.end());
955 copy.erase(last_unique, copy.end());
958 GUDHI_CHECK(v !=
null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
961 dimension_ = (std::max)(dimension_,
static_cast<int>(std::distance(copy.begin(), copy.end())) - 1);
963 return rec_insert_simplex_and_subfaces_sorted(
root(), copy.begin(), copy.end(),
filtration);
968 template<
class ForwardVertexIterator>
969 std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces_sorted(
Siblings* sib,
970 ForwardVertexIterator first,
971 ForwardVertexIterator last,
978 auto&& dict = sib->members();
979 auto insertion_result = dict.emplace(vertex_one, Node(sib, filt));
981 if (insertion_result.second) {
983 update_simplex_tree_after_node_insertion(insertion_result.first);
986 Simplex_handle simplex_one = insertion_result.first;
987 bool one_is_new = insertion_result.second;
996 if (++first == last)
return insertion_result;
999 simplex_one->second.assign_children(
new Siblings(sib, vertex_one));
1000 auto res = rec_insert_simplex_and_subfaces_sorted(simplex_one->second.children(), first, last, filt);
1002 if (res.first !=
null_simplex()) rec_insert_simplex_and_subfaces_sorted(sib, first, last, filt);
1010 sh->second.assign_key(
key);
1018 return { find_vertex(sh->first), find_vertex(
self_siblings(sh)->parent()) };
1022 template<
class SimplexHandle>
1024 if (sh->second.children()->parent() == sh->first)
1025 return sh->second.children()->oncles();
1027 return sh->second.children();
1043 dimension_to_be_lowered_ = !exact;
1056 filtration_vect_.clear();
1059 if (ignore_infinite_values &&
1060 std::numeric_limits<Filtration_value>::has_infinity &&
1061 filtration(sh) == std::numeric_limits<Filtration_value>::infinity())
continue;
1062 filtration_vect_.push_back(sh);
1074 #ifdef GUDHI_USE_TBB
1075 tbb::parallel_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
1077 std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
1084 if (filtration_vect_.empty()) {
1093 filtration_vect_.clear();
1109 void rec_coface(std::vector<Vertex_handle> &vertices,
Siblings *curr_sib,
int curr_nbVertices,
1110 std::vector<Simplex_handle>& cofaces,
bool star,
int nbVertices) {
1111 if (!(star || curr_nbVertices <= nbVertices))
1113 for (Simplex_handle
simplex = curr_sib->members().begin();
simplex != curr_sib->members().end(); ++
simplex) {
1114 if (vertices.empty()) {
1119 bool addCoface = (star || curr_nbVertices == nbVertices);
1123 rec_coface(vertices,
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
1125 if (
simplex->first == vertices.back()) {
1127 bool equalDim = (star || curr_nbVertices == nbVertices);
1128 bool addCoface = vertices.size() == 1 && equalDim;
1134 vertices.pop_back();
1135 rec_coface(vertices,
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
1136 vertices.push_back(tmp);
1138 }
else if (
simplex->first > vertices.back()) {
1143 rec_coface(vertices,
simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
1174 assert(codimension >= 0);
1176 if constexpr (Options::link_nodes_by_label) {
1178 Static_vertex_vector simp(rg.begin(), rg.end());
1180 assert(std::is_sorted(simp.begin(), simp.end(), std::greater<Vertex_handle>()));
1184 Fast_cofaces_predicate select(
this, codimension, this->
dimension(simplex));
1185 return boost::adaptors::filter(range, select);
1189 std::vector<Vertex_handle> copy(rg.begin(), rg.end());
1190 if (codimension +
static_cast<int>(copy.size()) > dimension_ + 1 ||
1191 (codimension == 0 &&
static_cast<int>(copy.size()) > dimension_))
1194 assert(std::is_sorted(copy.begin(), copy.end(), std::greater<Vertex_handle>()));
1195 bool star = codimension == 0;
1196 rec_coface(copy, &root_, 1, cofaces, star, codimension +
static_cast<int>(copy.size()));
1209 bool reverse_lexicographic_order(Simplex_handle sh1, Simplex_handle sh2) {
1214 while (it1 != rg1.end() && it2 != rg2.end()) {
1222 return ((it1 == rg1.end()) && (it2 != rg2.end()));
1231 struct is_before_in_filtration {
1235 bool operator()(
const Simplex_handle sh1,
const Simplex_handle sh2)
const {
1237 if (sh1->second.filtration() != sh2->second.filtration()) {
1238 return sh1->second.
filtration() < sh2->second.filtration();
1241 return st_->reverse_lexicographic_order(sh1, sh2);
1271 template<
class OneSkeletonGraph>
1277 using boost::num_vertices;
1282 if (num_edges(skel_graph) == 0) {
1288 if constexpr (!Options::stable_simplex_handles)
1290 auto verts = vertices(skel_graph) | boost::adaptors::transformed([&](
auto v){
1291 return Dit_value_t(v,
Node(&root_, get(vertex_filtration_t(), skel_graph, v))); });
1292 root_.members_.insert(boost::begin(verts), boost::end(verts));
1295 for (Dictionary_it it = boost::begin(root_.members_); it != boost::end(root_.members_); it++) {
1296 update_simplex_tree_after_node_insertion(it);
1299 std::pair<typename boost::graph_traits<OneSkeletonGraph>::edge_iterator,
1300 typename boost::graph_traits<OneSkeletonGraph>::edge_iterator> boost_edges = edges(skel_graph);
1303 for (; boost_edges.first != boost_edges.second; boost_edges.first++) {
1304 auto edge = *(boost_edges.first);
1305 auto u = source(edge, skel_graph);
1306 auto v = target(edge, skel_graph);
1307 if (u == v)
throw std::invalid_argument(
"Self-loops are not simplicial");
1315 if (v < u) std::swap(u, v);
1316 auto sh = find_vertex(u);
1318 sh->second.assign_children(
new Siblings(&root_, sh->first));
1321 auto insertion_res = sh->second.children()->members().emplace(
1322 v,
Node(sh->second.children(), get(edge_filtration_t(), skel_graph, edge)));
1323 if (insertion_res.second) update_simplex_tree_after_node_insertion(insertion_res.first);
1334 template <
class VertexRange>
1336 auto verts = vertices | boost::adaptors::transformed([&](
auto v){
1337 return Dit_value_t(v,
Node(&root_, filt)); });
1338 root_.members_.insert(boost::begin(verts), boost::end(verts));
1339 if (dimension_ < 0 && !root_.members_.empty()) dimension_ = 0;
1340 if constexpr (Options::link_nodes_by_label) {
1341 for (
auto sh = root_.members().begin(); sh != root_.members().end(); sh++) {
1343 if (!sh->second.list_max_vertex_hook_.is_linked())
1344 update_simplex_tree_after_node_insertion(sh);
1361 if (max_dim <= 1)
return;
1363 dimension_ = max_dim;
1364 for (Dictionary_it root_it = root_.members_.begin();
1365 root_it != root_.members_.end(); ++root_it) {
1367 siblings_expansion(root_it->second.children(), max_dim - 1);
1370 dimension_ = max_dim - dimension_;
1411 , std::vector<Simplex_handle>& added_simplices)
1432 static_assert(Options::link_nodes_by_label,
"Options::link_nodes_by_label must be true");
1435 auto res_ins = root_.members().emplace(u,
Node(&root_,fil));
1436 if (res_ins.second) {
1437 added_simplices.push_back(res_ins.first);
1438 update_simplex_tree_after_node_insertion(res_ins.first);
1439 if (dimension_ == -1) dimension_ = 0;
1444 if (v < u) { std::swap(u,v); }
1453 auto sh_u = root_.members().find(u);
1454 GUDHI_CHECK(sh_u != root_.members().end() &&
1455 root_.members().find(v) != root_.members().end(),
1456 std::invalid_argument(
1457 "Simplex_tree::insert_edge_as_flag - inserts an edge whose vertices are not in the complex")
1460 sh_u->second.children()->members().find(v) == sh_u->second.children()->members().end(),
1461 std::invalid_argument(
1462 "Simplex_tree::insert_edge_as_flag - inserts an already existing edge")
1467 const auto tmp_dim = dimension_;
1468 auto tmp_max_dim = dimension_;
1473 List_max_vertex* nodes_with_label_u = nodes_by_label(u);
1475 GUDHI_CHECK(nodes_with_label_u !=
nullptr,
1476 "Simplex_tree::insert_edge_as_flag - cannot find the list of Nodes with label u");
1478 for (
auto&& node_as_hook : *nodes_with_label_u)
1480 Node& node_u =
static_cast<Node&
>(node_as_hook);
1483 if (sib_u->members().find(v) != sib_u->members().end()) {
1485 if (dim_max == -1 || curr_dim < dim_max){
1489 node_u.assign_children(
new Siblings(sib_u, u));
1491 dimension_ = dim_max - curr_dim - 1;
1492 compute_punctual_expansion(
1496 dim_max - curr_dim - 1,
1498 dimension_ = dim_max - dimension_;
1499 if (dimension_ > tmp_max_dim) tmp_max_dim = dimension_;
1503 if (tmp_dim <= tmp_max_dim){
1504 dimension_ = tmp_max_dim;
1505 dimension_to_be_lowered_ =
false;
1507 dimension_ = tmp_dim;
1525 , std::vector<Simplex_handle>& added_simplices )
1527 auto res_ins_v = sib->members().emplace(v, Node(sib,fil));
1528 added_simplices.push_back(res_ins_v.first);
1529 update_simplex_tree_after_node_insertion(res_ins_v.first);
1537 create_local_expansion( res_ins_v.first
1541 , added_simplices );
1544 for (
auto sh = sib->members().begin(); sh != res_ins_v.first; ++sh)
1546 Simplex_handle root_sh = find_vertex(sh->first);
1548 root_sh->second.children()->members().find(v) != root_sh->second.children()->members().end())
1551 sh->second.assign_children(
new Siblings(sib, sh->first));
1554 compute_punctual_expansion( v
1555 , sh->second.children()
1558 , added_simplices );
1569 void create_local_expansion(
1574 , std::vector<Simplex_handle> &added_simplices)
1577 Simplex_handle next_it = sh_v;
1580 if (dimension_ > k) {
1584 create_expansion<true>(curr_sib, sh_v, next_it, fil_uv, k, &added_simplices);
1596 void siblings_expansion(
1600 , std::vector<Simplex_handle> & added_simplices )
1602 if (dimension_ > k) {
1605 if (k == 0) {
return; }
1606 Dictionary_it next = ++(siblings->members().begin());
1608 for (Dictionary_it s_h = siblings->members().begin();
1609 next != siblings->members().end(); ++s_h, ++next)
1611 create_expansion<true>(siblings, s_h, next, fil, k, &added_simplices);
1617 void siblings_expansion(
Siblings * siblings,
1619 if (k >= 0 && dimension_ > k) {
1624 Dictionary_it next = siblings->members().begin();
1627 for (Dictionary_it s_h = siblings->members().begin();
1628 s_h != siblings->members().end(); ++s_h, ++next)
1630 create_expansion<false>(siblings, s_h, next, s_h->second.filtration(), k);
1638 template<
bool force_filtration_value>
1639 void create_expansion(
Siblings * siblings,
1641 Dictionary_it& next,
1644 std::vector<Simplex_handle>* added_simplices =
nullptr)
1646 Simplex_handle root_sh = find_vertex(s_h->first);
1647 thread_local std::vector<std::pair<Vertex_handle, Node> > inter;
1651 intersection<force_filtration_value>(
1654 siblings->members().end(),
1655 root_sh->second.children()->members().begin(),
1656 root_sh->second.children()->members().end(),
1658 if (inter.size() != 0) {
1662 for (
auto it = new_sib->members().begin(); it != new_sib->members().end(); ++it) {
1663 update_simplex_tree_after_node_insertion(it);
1664 if constexpr (force_filtration_value){
1666 added_simplices->push_back(it);
1670 s_h->second.assign_children(new_sib);
1671 if constexpr (force_filtration_value){
1672 siblings_expansion(new_sib, fil, k - 1, *added_simplices);
1674 siblings_expansion(new_sib, k - 1);
1678 s_h->second.assign_children(siblings);
1685 template<
bool force_filtration_value = false>
1686 static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
1687 Dictionary_it begin1, Dictionary_it end1,
1688 Dictionary_it begin2, Dictionary_it end2,
1690 if (begin1 == end1 || begin2 == end2)
1693 if (begin1->first == begin2->first) {
1694 if constexpr (force_filtration_value){
1695 intersection.emplace_back(begin1->first, Node(
nullptr, filtration_));
1697 Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
1698 intersection.emplace_back(begin1->first, Node(
nullptr, filt));
1700 if (++begin1 == end1 || ++begin2 == end2)
1702 }
else if (begin1->first < begin2->first) {
1703 if (++begin1 == end1)
1706 if (++begin2 == end2)
1731 template<
typename Blocker >
1734 for (
auto&
simplex : boost::adaptors::reverse(root_.members())) {
1736 siblings_expansion_with_blockers(
simplex.second.children(), max_dim, max_dim - 1, block_simplex);
1743 template<
typename Blocker >
1744 void siblings_expansion_with_blockers(
Siblings* siblings,
int max_dim,
int k, Blocker block_simplex) {
1745 if (dimension_ < max_dim - k) {
1746 dimension_ = max_dim - k;
1751 if (siblings->members().size() < 2)
1754 for (
auto simplex = std::next(siblings->members().rbegin());
simplex != siblings->members().rend();
simplex++) {
1755 std::vector<std::pair<Vertex_handle, Node> > intersection;
1756 for(
auto next = siblings->members().rbegin(); next !=
simplex; next++) {
1757 bool to_be_inserted =
true;
1761 Simplex_handle border_child = find_child(border, next->first);
1763 to_be_inserted=
false;
1766 filt = (std::max)(filt,
filtration(border_child));
1768 if (to_be_inserted) {
1769 intersection.emplace_back(next->first, Node(
nullptr, filt));
1772 if (intersection.size() != 0) {
1777 boost::adaptors::reverse(intersection));
1778 simplex->second.assign_children(new_sib);
1779 std::vector<Vertex_handle> blocked_new_sib_vertex_list;
1781 for (
auto new_sib_member = new_sib->members().begin();
1782 new_sib_member != new_sib->members().end();
1784 update_simplex_tree_after_node_insertion(new_sib_member);
1785 bool blocker_result = block_simplex(new_sib_member);
1788 if (blocker_result) {
1789 blocked_new_sib_vertex_list.push_back(new_sib_member->first);
1792 update_simplex_tree_before_node_removal(new_sib_member);
1795 if (blocked_new_sib_vertex_list.size() == new_sib->members().size()) {
1799 simplex->second.assign_children(siblings);
1801 for (
auto& blocked_new_sib_member : blocked_new_sib_vertex_list) {
1802 new_sib->members().erase(blocked_new_sib_member);
1805 siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex);
1809 simplex->second.assign_children(siblings);
1818 Simplex_handle find_child(Simplex_handle sh,
Vertex_handle vh)
const {
1822 Simplex_handle child = sh->second.children()->find(vh);
1825 if (child == sh->second.children()->members().end())
1843 os <<
key(b_sh) <<
" ";
1862 if constexpr (std::is_same_v<
void, decltype(fun(sh, dim))>) {
1866 return fun(sh, dim);
1870 rec_for_each_simplex(
root(), 0, f);
1875 void rec_for_each_simplex(
Siblings* sib,
int dim, Fun&& fun) {
1876 Simplex_handle sh = sib->members().end();
1877 GUDHI_CHECK(sh != sib->members().begin(),
"Bug in Gudhi: only the root siblings may be empty");
1881 rec_for_each_simplex(sh->second.children(), dim+1, fun);
1885 while(sh != sib->members().begin());
1896 bool modified =
false;
1897 auto fun = [&modified,
this](
Simplex_handle sh,
int dim) ->
void {
1898 if (dim == 0)
return;
1909 if (!(sh->second.filtration() >= max_filt_border_value)) {
1912 sh->second.assign_filtration(max_filt_border_value);
1926 root_members_recursive_deletion();
1929 dimension_to_be_lowered_ =
false;
1930 if constexpr (Options::link_nodes_by_label)
1931 nodes_label_to_list_.clear();
1942 if (std::numeric_limits<Filtration_value>::has_infinity &&
filtration == std::numeric_limits<Filtration_value>::infinity())
1952 auto&& list = sib->members();
1953 bool modified =
false;
1954 bool emptied =
false;
1955 Simplex_handle last;
1957 auto to_remove = [
this, filt](Dit_value_t&
simplex) {
1958 if (
simplex.second.filtration() <= filt)
return false;
1961 dimension_to_be_lowered_ =
true;
1967 if constexpr (Options::stable_simplex_handles) {
1969 for (
auto sh = list.begin(); sh != list.end();) {
1970 if (to_remove(*sh)) {
1971 sh = list.erase(sh);
1977 emptied = (list.empty() && sib !=
root());
1979 last = std::remove_if(list.begin(), list.end(), to_remove);
1980 modified = (last != list.end());
1981 emptied = (last == list.begin() && sib !=
root());
1986 sib->oncles()->members()[sib->parent()].assign_children(sib->oncles());
1989 dimension_to_be_lowered_ =
true;
1993 if constexpr (!Options::stable_simplex_handles) list.erase(last, list.end());
2010 bool modified =
false;
2013 root_members_recursive_deletion();
2030 bool rec_prune_above_dimension(
Siblings* sib,
int dim,
int actual_dim) {
2031 bool modified =
false;
2032 auto&& list = sib->members();
2036 if (actual_dim >= dim) {
2037 rec_delete(
simplex.second.children());
2038 simplex.second.assign_children(sib);
2041 modified |= rec_prune_above_dimension(
simplex.second.children(), dim, actual_dim + 1);
2054 bool lower_upper_bound_dimension() {
2056 dimension_to_be_lowered_ =
false;
2057 int new_dimension = -1;
2062 std::clog <<
" " << vertex;
2064 std::clog << std::endl;
2068 if (sh_dimension >= dimension_)
2071 new_dimension = (std::max)(new_dimension, sh_dimension);
2073 dimension_ = new_dimension;
2090 std::invalid_argument(
"Simplex_tree::remove_maximal_simplex - argument has children"));
2092 update_simplex_tree_before_node_removal(sh);
2095 Siblings* child = sh->second.children();
2097 if ((child->size() > 1) || (child ==
root())) {
2103 child->oncles()->members().at(child->parent()).assign_children(child->oncles());
2106 dimension_to_be_lowered_ =
true;
2127 std::pair<Filtration_value, Extended_simplex_type> p;
2130 if (f >= -2 && f <= -1) {
2131 p.first = minval + (maxval-minval)*(f + 2); p.second = Extended_simplex_type::UP;
2132 }
else if (f >= 1 && f <= 2) {
2133 p.first = minval - (maxval-minval)*(f - 2); p.second = Extended_simplex_type::DOWN;
2135 p.first = std::numeric_limits<Filtration_value>::quiet_NaN(); p.second = Extended_simplex_type::EXTRA;
2157 Vertex_handle maxvert = std::numeric_limits<Vertex_handle>::min();
2158 Filtration_value minval = std::numeric_limits<Filtration_value>::infinity();
2159 Filtration_value maxval = -std::numeric_limits<Filtration_value>::infinity();
2160 for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
2162 minval = std::min(minval, f);
2163 maxval = std::max(maxval, f);
2164 maxvert = std::max(sh->first, maxvert);
2167 GUDHI_CHECK(maxvert < std::numeric_limits<Vertex_handle>::max(), std::invalid_argument(
"Simplex_tree contains a vertex with the largest Vertex_handle"));
2173 this->insert_simplex_raw({maxvert}, -3);
2180 std::vector<Vertex_handle> vr;
2183 vr.assign(simplex_range.begin(), simplex_range.end());
2184 auto sh = this->
find(vr);
2187 vr.push_back(maxvert);
2206 return Extended_filtration_data(minval, maxval);
2214 auto filt = filtration_(sh);
2216 if(filtration_(find_vertex(v)) == filt)
2230 auto end = std::end(vertices);
2231 auto vi = std::begin(vertices);
2232 GUDHI_CHECK(vi != end,
"empty simplex");
2235 GUDHI_CHECK(vi != end,
"simplex of dimension 0");
2236 if(std::next(vi) == end)
return sh;
2237 Static_vertex_vector suffix;
2238 suffix.push_back(v0);
2239 auto filt = filtration_(sh);
2243 auto&& children1 = find_vertex(v)->second.children()->members_;
2244 for(
auto w : suffix){
2247 if(filtration_(s) == filt)
2250 suffix.push_back(v);
2261 auto filt = filtration_(sh);
2264 if(filtration_(b) == filt)
2272 &Hooks_simplex_base_link_nodes::list_max_vertex_hook_>
2276 boost::intrusive::constant_time_size<false>> List_max_vertex;
2286 std::unordered_map<Vertex_handle, List_max_vertex> nodes_label_to_list_;
2289 if constexpr (Options::link_nodes_by_label) {
2290 auto it_v = nodes_label_to_list_.find(v);
2291 if (it_v != nodes_label_to_list_.end()) {
2292 return &(it_v->second);
2302 static Simplex_handle simplex_handle_from_node(Node& node) {
2303 if constexpr (Options::stable_simplex_handles){
2314 Dictionary_it testIt = node.children()->members().begin();
2315 Node* testNode = &testIt->second;
2316 auto testIIt = testIt.get();
2317 auto testPtr = testIIt.pointed_node();
2319 auto shift = (
const char*)(testNode) - (
const char*)(testPtr);
2322 decltype(testPtr) sh_ptr = decltype(testPtr)((
const char*)(&node) - shift);
2334 decltype(testIIt) sh_ii;
2336 Dictionary_it sh(sh_ii);
2340 return (Simplex_handle)(boost::intrusive::get_parent_from_member<Dit_value_t>(&node, &Dit_value_t::second));
2346 friend class Simplex_tree_optimized_cofaces_rooted_subtrees_simplex_iterator<
Simplex_tree>;
2351 void update_simplex_tree_after_node_insertion(Simplex_handle sh) {
2353 std::clog <<
"update_simplex_tree_after_node_insertion" << std::endl;
2355 if constexpr (Options::link_nodes_by_label) {
2357 nodes_label_to_list_[sh->first].push_back(sh->second);
2363 void update_simplex_tree_before_node_removal(Simplex_handle sh) {
2365 std::clog <<
"update_simplex_tree_before_node_removal" << std::endl;
2367 if constexpr (Options::link_nodes_by_label) {
2368 sh->second.unlink_hooks();
2369 if (nodes_label_to_list_[sh->first].empty())
2370 nodes_label_to_list_.erase(sh->first);
2384 rec_reset_filtration(&root_, filt_value, min_dim);
2395 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
2396 if (min_depth <= 0) {
2397 sh->second.assign_filtration(filt_value);
2400 rec_reset_filtration(sh->second.children(), filt_value, min_depth - 1);
2413 std::size_t get_serialization_size() {
2416 const std::size_t buffer_byte_size = vh_byte_size +
num_simplices() * (fv_byte_size + 2 * vh_byte_size);
2418 std::clog <<
"Gudhi::simplex_tree::get_serialization_size - buffer size = " << buffer_byte_size << std::endl;
2420 return buffer_byte_size;
2452 void serialize(
char* buffer,
const std::size_t buffer_size) {
2453 char* buffer_end = rec_serialize(&root_, buffer);
2454 if (
static_cast<std::size_t
>(buffer_end - buffer) != buffer_size)
2455 throw std::invalid_argument(
"Serialization does not match end of buffer");
2460 char* rec_serialize(
Siblings *sib,
char* buffer) {
2462 ptr = Gudhi::simplex_tree::serialize_trivial(
static_cast<Vertex_handle>(sib->members().size()), ptr);
2464 std::clog <<
"\n" << sib->members().size() <<
" : ";
2466 for (
auto& map_el : sib->members()) {
2467 ptr = Gudhi::simplex_tree::serialize_trivial(map_el.first, ptr);
2468 if (Options::store_filtration)
2469 ptr = Gudhi::simplex_tree::serialize_trivial(map_el.second.filtration(), ptr);
2471 std::clog <<
" [ " << map_el.first <<
" | " << map_el.second.filtration() <<
" ] ";
2474 for (
auto& map_el : sib->members()) {
2476 ptr = rec_serialize(map_el.second.children(), ptr);
2478 ptr = Gudhi::simplex_tree::serialize_trivial(
static_cast<Vertex_handle>(0), ptr);
2480 std::cout <<
"\n0 : ";
2501 void deserialize(
const char* buffer,
const std::size_t buffer_size) {
2502 GUDHI_CHECK(
num_vertices() == 0, std::logic_error(
"Simplex_tree::deserialize - Simplex_tree must be empty"));
2503 const char* ptr = buffer;
2506 ptr = Gudhi::simplex_tree::deserialize_trivial(members_size, ptr);
2507 ptr = rec_deserialize(&root_, members_size, ptr, 0);
2508 if (
static_cast<std::size_t
>(ptr - buffer) != buffer_size) {
2509 throw std::invalid_argument(
"Deserialization does not match end of buffer");
2517 if (members_size > 0) {
2518 if constexpr (!Options::stable_simplex_handles) sib->members_.reserve(members_size);
2522 ptr = Gudhi::simplex_tree::deserialize_trivial(vertex, ptr);
2523 if (Options::store_filtration) {
2524 ptr = Gudhi::simplex_tree::deserialize_trivial(
filtration, ptr);
2526 sib->members_.emplace_hint(sib->members_.end(), vertex, Node(sib,
filtration));
2529 sib->members_.emplace_hint(sib->members_.end(), vertex, Node(sib));
2533 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
2534 update_simplex_tree_after_node_insertion(sh);
2535 ptr = Gudhi::simplex_tree::deserialize_trivial(child_size, ptr);
2536 if (child_size > 0) {
2538 sh->second.assign_children(child);
2539 ptr = rec_deserialize(child, child_size, ptr, dim + 1);
2542 if (dim > dimension_) {
2556 std::vector<Simplex_handle> filtration_vect_;
2559 bool dimension_to_be_lowered_ =
false;
2563 template<
typename...T>
2566 os << st.dimension(sh) <<
" ";
2575 template<
typename...T>
2578 std::vector<typename ST::Vertex_handle> simplex;
2584 int dim =
static_cast<int> (simplex.size() - 1);
2585 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:194
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree_iterators.h:82
Iterator over the simplices of a simplicial complex.
Definition: Simplex_tree_iterators.h:309
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:37
Iterator over the simplices of the skeleton of a given dimension of the simplicial complex.
Definition: Simplex_tree_iterators.h:383
Simplex Tree data structure for representing simplicial complexes.
Definition: Simplex_tree.h:95
Simplex_tree(Simplex_tree &&complex_source)
User-defined move constructor relocates the whole tree structure.
Definition: Simplex_tree.h:414
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:1407
Options::Filtration_value Filtration_value
Type for the value of the filtration function.
Definition: Simplex_tree.h:102
Cofaces_simplex_range cofaces_simplex_range(const Simplex_handle simplex, int codimension)
Compute the cofaces of a n simplex.
Definition: Simplex_tree.h:1172
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:263
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:2383
void assign_filtration(Simplex_handle sh, Filtration_value fv)
Sets the filtration value of a simplex.
Definition: Simplex_tree.h:625
Simplex_tree & operator=(Simplex_tree &&complex_source)
User-defined move assignment relocates the whole tree structure.
Definition: Simplex_tree.h:448
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:942
std::vector< size_t > num_simplices_by_dimension()
Returns the number of simplices of each dimension in the simplex tree.
Definition: Simplex_tree.h:699
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:1895
Dictionary::iterator Simplex_handle
Handle type to a simplex contained in the simplicial complex represented by the simplex tree.
Definition: Simplex_tree.h:175
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:2213
bool prune_above_dimension(int dimension)
Remove all simplices of dimension greater than a given value.
Definition: Simplex_tree.h:2006
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:338
bool operator!=(Simplex_tree< OtherSimplexTreeOptions > &st2)
Checks if two simplex trees are different.
Definition: Simplex_tree.h:556
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:646
boost::iterator_range< Boundary_simplex_iterator > Boundary_simplex_range
Range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:259
Simplex_vertex_range simplex_vertex_range(Simplex_handle sh) const
Returns a range over the vertices of a simplex.
Definition: Simplex_tree.h:349
void for_each_simplex(Fun &&fun)
Definition: Simplex_tree.h:1859
void clear_filtration()
Clears the filtration cache produced by initialize_filtration().
Definition: Simplex_tree.h:1092
Simplex_tree_simplex_vertex_iterator< Simplex_tree > Simplex_vertex_iterator
Iterator over the vertices of a simplex.
Definition: Simplex_tree.h:241
void clear()
Remove all the simplices, leaving an empty complex.
Definition: Simplex_tree.h:1925
static Simplex_key key(Simplex_handle sh)
Returns the key associated to a simplex.
Definition: Simplex_tree.h:597
static Filtration_value filtration(Simplex_handle sh)
Returns the filtration value of a simplex.
Definition: Simplex_tree.h:614
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:913
bool operator==(Simplex_tree< OtherSimplexTreeOptions > &st2)
Checks if two simplex trees are equal.
Definition: Simplex_tree.h:547
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:742
Cofaces_simplex_range star_simplex_range(const Simplex_handle simplex)
Compute the star of a n simplex.
Definition: Simplex_tree.h:1158
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:1732
boost::iterator_range< Simplex_vertex_iterator > Simplex_vertex_range
Range over the vertices of a simplex.
Definition: Simplex_tree.h:243
void initialize_filtration(bool ignore_infinite_values=false)
Initializes the filtration cache, i.e. sorts the simplices according to their order in the filtration...
Definition: Simplex_tree.h:1055
void remove_maximal_simplex(Simplex_handle sh)
Remove a maximal simplex.
Definition: Simplex_tree.h:2087
Siblings * root()
Definition: Simplex_tree.h:1032
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:1009
Options::Simplex_key Simplex_key
Key associated to each simplex.
Definition: Simplex_tree.h:106
Simplex_tree()
Constructs an empty simplex tree.
Definition: Simplex_tree.h:397
void maybe_initialize_filtration()
Initializes the filtration cache if it isn't initialized yet.
Definition: Simplex_tree.h:1083
boost::iterator_range< Complex_simplex_iterator > Complex_simplex_range
Range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:271
Simplex_tree_boundary_simplex_iterator< Simplex_tree > Boundary_simplex_iterator
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:257
Simplex_tree_siblings< Simplex_tree, Dictionary > Siblings
Set of nodes sharing a same parent in the simplex tree.
Definition: Simplex_tree.h:127
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:767
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:387
bool is_empty() const
Returns whether the complex is empty.
Definition: Simplex_tree.h:656
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:2227
Simplex_tree_complex_simplex_iterator< Simplex_tree > Complex_simplex_iterator
Iterator over the simplices of the simplicial complex.
Definition: Simplex_tree.h:269
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:2126
Simplex_handle simplex(Simplex_key idx) const
Returns the simplex that has index idx in the filtration.
Definition: Simplex_tree.h:605
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:318
boost::transform_iterator< return_first, Dictionary_it > Complex_vertex_iterator
Iterator over the vertices of the simplicial complex.
Definition: Simplex_tree.h:235
void insert_batch_vertices(VertexRange const &vertices, Filtration_value filt=0)
Inserts several vertices.
Definition: Simplex_tree.h:1335
std::vector< Simplex_handle > Filtration_simplex_range
Range over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:281
Filtration_simplex_range::const_iterator Filtration_simplex_iterator
Iterator over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:285
Extended_filtration_data extend_filtration()
Extend filtration for computing extended persistence. This function only uses the filtration values a...
Definition: Simplex_tree.h:2153
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:2260
Options::Vertex_handle Vertex_handle
Type for the vertex handle.
Definition: Simplex_tree.h:110
size_t num_vertices() const
Returns the number of vertices in the complex.
Definition: Simplex_tree.h:651
static Siblings * self_siblings(SimplexHandle sh)
Definition: Simplex_tree.h:1023
void expansion(int max_dim)
Expands the Simplex_tree containing only its one skeleton until dimension max_dim.
Definition: Simplex_tree.h:1360
Simplex_tree(const Simplex_tree &complex_source)
User-defined copy constructor reproduces the whole tree structure.
Definition: Simplex_tree.h:404
boost::iterator_range< Complex_vertex_iterator > Complex_vertex_range
Range over the vertices of the simplicial complex.
Definition: Simplex_tree.h:237
static Simplex_key null_key()
Returns a fixed number not in the interval [0, num_simplices()).
Definition: Simplex_tree.h:640
Boundary_simplex_range boundary_simplex_range(SimplexHandle sh)
Returns a range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:370
int dimension(Simplex_handle sh)
Returns the dimension of a simplex.
Definition: Simplex_tree.h:720
bool prune_above_filtration(Filtration_value filtration)
Prune above filtration value given as parameter.
Definition: Simplex_tree.h:1941
int upper_bound_dimension() const
Returns an upper bound on the dimension of the simplicial complex.
Definition: Simplex_tree.h:725
std::pair< Simplex_handle, Simplex_handle > endpoints(Simplex_handle sh)
Definition: Simplex_tree.h:1016
int dimension()
Returns the dimension of the simplicial complex.
Definition: Simplex_tree.h:733
size_t num_simplices()
Returns the number of simplices in the simplex_tree.
Definition: Simplex_tree.h:664
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:276
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:265
void insert_graph(const OneSkeletonGraph &skel_graph)
Inserts a 1-skeleton in an empty Simplex_tree.
Definition: Simplex_tree.h:1272
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:279
void print_hasse(std::ostream &os)
Write the hasse diagram of the simplicial complex in os.
Definition: Simplex_tree.h:1838
~Simplex_tree()
Destructor; deallocates the whole tree structure.
Definition: Simplex_tree.h:426
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:635
Simplex_tree & operator=(const Simplex_tree &complex_source)
User-defined copy assignment reproduces the whole tree structure.
Definition: Simplex_tree.h:431
Complex_simplex_range complex_simplex_range()
Returns a range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:304
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:247
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:293
void set_dimension(int dimension, bool exact=true)
Set a dimension for the simplicial complex.
Definition: Simplex_tree.h:1042
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
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:38
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:32
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15