11 #ifndef SIMPLEX_TREE_H_ 12 #define SIMPLEX_TREE_H_ 14 #include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h> 15 #include <gudhi/Simplex_tree/Simplex_tree_siblings.h> 16 #include <gudhi/Simplex_tree/Simplex_tree_iterators.h> 17 #include <gudhi/Simplex_tree/indexing_tag.h> 21 #include <gudhi/Debug_utils.h> 23 #include <boost/container/flat_map.hpp> 24 #include <boost/iterator/transform_iterator.hpp> 25 #include <boost/graph/adjacency_list.hpp> 26 #include <boost/range/adaptor/reversed.hpp> 27 #include <boost/container/static_vector.hpp> 30 #include <tbb/parallel_sort.h> 38 #include <initializer_list> 59 struct Simplex_tree_options_full_featured;
74 template<
typename SimplexTreeOptions = Simplex_tree_options_full_featured>
93 typedef Simplex_tree_node_explicit_storage<Simplex_tree> Node;
98 typedef typename boost::container::flat_map<Vertex_handle, Node> Dictionary;
102 typedef Simplex_tree_siblings<Simplex_tree, Dictionary> Siblings;
106 struct Key_simplex_base_real {
107 Key_simplex_base_real() : key_(-1) {}
108 void assign_key(Simplex_key k) { key_ = k; }
109 Simplex_key key()
const {
return key_; }
113 struct Key_simplex_base_dummy {
114 Key_simplex_base_dummy() {}
116 void assign_key(Simplex_key);
117 Simplex_key key()
const;
119 struct Extended_filtration_data {
120 Filtration_value minval;
121 Filtration_value maxval;
122 Extended_filtration_data(){}
123 Extended_filtration_data(Filtration_value vmin, Filtration_value vmax): minval(vmin), maxval(vmax) {}
125 typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type
128 struct Filtration_simplex_base_real {
129 Filtration_simplex_base_real() : filt_(0) {}
130 void assign_filtration(Filtration_value f) { filt_ = f; }
131 Filtration_value filtration()
const {
return filt_; }
133 Filtration_value filt_;
135 struct Filtration_simplex_base_dummy {
136 Filtration_simplex_base_dummy() {}
137 void assign_filtration(Filtration_value GUDHI_CHECK_code(f)) { GUDHI_CHECK(f == 0,
"filtration value specified for a complex that does not store them"); }
138 Filtration_value filtration()
const {
return 0; }
140 typedef typename std::conditional<Options::store_filtration, Filtration_simplex_base_real,
141 Filtration_simplex_base_dummy>::type Filtration_simplex_base;
152 typedef typename Dictionary::iterator Dictionary_it;
153 typedef typename Dictionary_it::value_type Dit_value_t;
155 struct return_first {
156 Vertex_handle operator()(
const Dit_value_t& p_sh)
const {
218 return Complex_vertex_range(
219 boost::make_transform_iterator(root_.members_.begin(), return_first()),
220 boost::make_transform_iterator(root_.members_.end(), return_first()));
229 return Complex_simplex_range(Complex_simplex_iterator(
this),
230 Complex_simplex_iterator());
243 return Skeleton_simplex_range(Skeleton_simplex_iterator(
this, dim),
244 Skeleton_simplex_iterator());
263 maybe_initialize_filtration();
264 return filtration_vect_;
274 GUDHI_CHECK(sh != null_simplex(),
"empty simplex");
275 return Simplex_vertex_range(Simplex_vertex_iterator(
this, sh),
276 Simplex_vertex_iterator(
this));
293 template<
class SimplexHandle>
295 return Boundary_simplex_range(Boundary_simplex_iterator(
this, sh),
296 Boundary_simplex_iterator(
this));
306 root_(nullptr, null_vertex_),
313 std::clog <<
"Simplex_tree copy constructor" << std::endl;
314 #endif // DEBUG_TRACES 315 copy_from(complex_source);
323 std::clog <<
"Simplex_tree move constructor" << std::endl;
324 #endif // DEBUG_TRACES 325 move_from(complex_source);
329 complex_source.dimension_ = -1;
334 root_members_recursive_deletion();
340 std::clog <<
"Simplex_tree copy assignment" << std::endl;
341 #endif // DEBUG_TRACES 343 if (&complex_source !=
this) {
345 root_members_recursive_deletion();
347 copy_from(complex_source);
357 std::clog <<
"Simplex_tree move assignment" << std::endl;
358 #endif // DEBUG_TRACES 360 if (&complex_source !=
this) {
362 root_members_recursive_deletion();
364 move_from(complex_source);
373 null_vertex_ = complex_source.null_vertex_;
374 filtration_vect_.clear();
375 dimension_ = complex_source.dimension_;
376 auto root_source = complex_source.root_;
379 root_.members() = Dictionary(boost::container::ordered_unique_range, root_source.members().begin(), root_source.members().end());
381 for (
auto& map_el : root_.members()) {
382 map_el.second.assign_children(&root_);
384 rec_copy(&root_, &root_source);
388 void rec_copy(Siblings *sib, Siblings *sib_source) {
389 for (
auto sh = sib->members().begin(), sh_source = sib_source->members().begin();
390 sh != sib->members().end(); ++sh, ++sh_source) {
391 if (has_children(sh_source)) {
392 Siblings * newsib =
new Siblings(sib, sh_source->first);
393 newsib->members_.reserve(sh_source->second.children()->members().size());
394 for (
auto & child : sh_source->second.children()->members())
395 newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(newsib, child.second.filtration()));
396 rec_copy(newsib, sh_source->second.children());
397 sh->second.assign_children(newsib);
404 null_vertex_ = std::move(complex_source.null_vertex_);
405 root_ = std::move(complex_source.root_);
406 filtration_vect_ = std::move(complex_source.filtration_vect_);
407 dimension_ = std::move(complex_source.dimension_);
410 for (
auto& map_el : root_.members()) {
411 if (map_el.second.children() != &(complex_source.root_)) {
413 map_el.second.children()->oncles_ = &root_;
416 GUDHI_CHECK(map_el.second.children()->oncles_ ==
nullptr,
417 std::invalid_argument(
"Simplex_tree move constructor from an invalid Simplex_tree"));
419 map_el.second.assign_children(&root_);
425 void root_members_recursive_deletion() {
426 for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
427 if (has_children(sh)) {
428 rec_delete(sh->second.children());
431 root_.members().clear();
435 void rec_delete(Siblings * sib) {
436 for (
auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
437 if (has_children(sh)) {
438 rec_delete(sh->second.children());
447 if ((null_vertex_ != st2.null_vertex_) ||
448 (dimension_ != st2.dimension_))
450 return rec_equal(&root_, &st2.root_);
455 return (!(*
this == st2));
460 bool rec_equal(Siblings* s1, Siblings* s2) {
461 if (s1->members().size() != s2->members().size())
463 for (
auto sh1 = s1->members().begin(), sh2 = s2->members().begin();
464 (sh1 != s1->members().end() && sh2 != s2->members().end()); ++sh1, ++sh2) {
465 if (sh1->first != sh2->first || sh1->second.filtration() != sh2->second.filtration())
467 if (has_children(sh1) != has_children(sh2))
470 else if (has_children(sh1))
471 if (!rec_equal(sh1->second.children(), sh2->second.children()))
481 static Filtration_value filtration_(Simplex_handle sh) {
482 GUDHI_CHECK (sh != null_simplex(),
"null simplex");
483 return sh->second.filtration();
492 static Simplex_key
key(Simplex_handle sh) {
493 return sh->second.key();
500 Simplex_handle
simplex(Simplex_key idx)
const {
501 return filtration_vect_[idx];
510 if (sh != null_simplex()) {
511 return sh->second.filtration();
513 return std::numeric_limits<Filtration_value>::infinity();
521 GUDHI_CHECK(sh != null_simplex(),
522 std::invalid_argument(
"Simplex_tree::assign_filtration - cannot assign filtration on null_simplex"));
523 sh->second.assign_filtration(fv);
531 return Dictionary_it(
nullptr);
547 return root_.members_.size();
553 return num_simplices(&root_);
558 size_t num_simplices(Siblings * sib) {
559 auto sib_begin = sib->members().begin();
560 auto sib_end = sib->members().end();
561 size_t simplices_number = sib_end - sib_begin;
562 for (
auto sh = sib_begin; sh != sib_end; ++sh) {
563 if (has_children(sh)) {
564 simplices_number += num_simplices(sh->second.children());
567 return simplices_number;
575 Siblings * curr_sib = self_siblings(sh);
577 while (curr_sib !=
nullptr) {
579 curr_sib = curr_sib->oncles();
594 if (dimension_to_be_lowered_)
595 lower_upper_bound_dimension();
601 template<
class SimplexHandle>
604 return (sh->second.children()->parent() == sh->first);
614 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
615 Simplex_handle
find(
const InputVertexRange & s) {
616 auto first = std::begin(s);
617 auto last = std::end(s);
620 return null_simplex();
623 std::vector<Vertex_handle> copy(first, last);
624 std::sort(std::begin(copy), std::end(copy));
625 return find_simplex(copy);
630 Simplex_handle find_simplex(
const std::vector<Vertex_handle> & simplex) {
631 Siblings * tmp_sib = &root_;
632 Dictionary_it tmp_dit;
633 auto vi = simplex.begin();
634 if (Options::contiguous_vertices) {
636 GUDHI_CHECK(contiguous_vertices(),
"non-contiguous vertices");
637 Vertex_handle v = *vi++;
638 if(v < 0 || v >= static_cast<Vertex_handle>(root_.members_.size()))
639 return null_simplex();
640 tmp_dit = root_.members_.begin() + v;
641 if (vi == simplex.end())
643 if (!has_children(tmp_dit))
644 return null_simplex();
645 tmp_sib = tmp_dit->second.children();
648 tmp_dit = tmp_sib->members_.find(*vi++);
649 if (tmp_dit == tmp_sib->members_.end())
650 return null_simplex();
651 if (vi == simplex.end())
653 if (!has_children(tmp_dit))
654 return null_simplex();
655 tmp_sib = tmp_dit->second.children();
661 Simplex_handle find_vertex(Vertex_handle v) {
662 if (Options::contiguous_vertices) {
663 assert(contiguous_vertices());
664 return root_.members_.begin() + v;
666 return root_.members_.find(v);
672 bool contiguous_vertices()
const {
673 if (root_.members_.empty())
return true;
674 if (root_.members_.begin()->first != 0)
return false;
675 if (std::prev(root_.members_.end())->first != static_cast<Vertex_handle>(root_.members_.size() - 1))
return false;
694 std::pair<Simplex_handle, bool> insert_vertex_vector(
const std::vector<Vertex_handle>& simplex,
695 Filtration_value filtration) {
696 Siblings * curr_sib = &root_;
697 std::pair<Simplex_handle, bool> res_insert;
698 auto vi = simplex.begin();
699 for (; vi != simplex.end() - 1; ++vi) {
700 GUDHI_CHECK(*vi != null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
701 res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
702 if (!(has_children(res_insert.first))) {
703 res_insert.first->second.assign_children(
new Siblings(curr_sib, *vi));
705 curr_sib = res_insert.first->second.children();
707 GUDHI_CHECK(*vi != null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
708 res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
709 if (!res_insert.second) {
711 if (res_insert.first->second.filtration() > filtration) {
713 res_insert.first->second.assign_filtration(filtration);
717 return std::pair<Simplex_handle, bool>(null_simplex(),
false);
720 if (static_cast<int>(simplex.size()) - 1 > dimension_) {
722 dimension_ =
static_cast<int>(simplex.size()) - 1;
751 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
753 Filtration_value filtration = 0) {
754 auto first = std::begin(simplex);
755 auto last = std::end(simplex);
758 return std::pair<Simplex_handle, bool>(null_simplex(),
true);
761 std::vector<Vertex_handle> copy(first, last);
762 std::sort(std::begin(copy), std::end(copy));
763 return insert_vertex_vector(copy, filtration);
780 template<
class InputVertexRange = std::initializer_list<Vertex_handle>>
782 Filtration_value filtration = 0) {
783 auto first = std::begin(Nsimplex);
784 auto last = std::end(Nsimplex);
787 return { null_simplex(),
true };
789 thread_local std::vector<Vertex_handle> copy;
791 copy.insert(copy.end(), first, last);
792 std::sort(copy.begin(), copy.end());
793 auto last_unique = std::unique(copy.begin(), copy.end());
794 copy.erase(last_unique, copy.end());
796 for (Vertex_handle v : copy)
797 GUDHI_CHECK(v != null_vertex(),
"cannot use the dummy null_vertex() as a real vertex");
800 dimension_ = (std::max)(dimension_,
static_cast<int>(std::distance(copy.begin(), copy.end())) - 1);
802 return rec_insert_simplex_and_subfaces_sorted(root(), copy.begin(), copy.end(), filtration);
807 template<
class ForwardVertexIterator>
808 std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces_sorted(Siblings* sib,
809 ForwardVertexIterator first,
810 ForwardVertexIterator last,
811 Filtration_value filt) {
816 Vertex_handle vertex_one = *first;
817 auto&& dict = sib->members();
818 auto insertion_result = dict.emplace(vertex_one, Node(sib, filt));
819 Simplex_handle simplex_one = insertion_result.first;
820 bool one_is_new = insertion_result.second;
822 if (filtration(simplex_one) > filt) {
823 assign_filtration(simplex_one, filt);
826 insertion_result.first = null_simplex();
829 if (++first == last)
return insertion_result;
830 if (!has_children(simplex_one))
832 simplex_one->second.assign_children(
new Siblings(sib, vertex_one));
833 auto res = rec_insert_simplex_and_subfaces_sorted(simplex_one->second.children(), first, last, filt);
835 if (res.first != null_simplex()) rec_insert_simplex_and_subfaces_sorted(sib, first, last, filt);
843 sh->second.assign_key(key);
849 std::pair<Simplex_handle, Simplex_handle>
endpoints(Simplex_handle sh) {
850 assert(dimension(sh) == 1);
851 return { find_vertex(sh->first), find_vertex(self_siblings(sh)->parent()) };
855 template<
class SimplexHandle>
857 if (sh->second.children()->parent() == sh->first)
858 return sh->second.children()->oncles();
860 return sh->second.children();
874 dimension_to_be_lowered_ =
false;
875 dimension_ = dimension;
887 filtration_vect_.clear();
888 filtration_vect_.reserve(num_simplices());
889 for (Simplex_handle sh : complex_simplex_range())
890 filtration_vect_.push_back(sh);
902 tbb::parallel_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
904 std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(
this));
911 if (filtration_vect_.empty()) {
912 initialize_filtration();
920 filtration_vect_.clear();
936 void rec_coface(std::vector<Vertex_handle> &vertices, Siblings *curr_sib,
int curr_nbVertices,
937 std::vector<Simplex_handle>& cofaces,
bool star,
int nbVertices) {
938 if (!(star || curr_nbVertices <= nbVertices))
940 for (Simplex_handle simplex = curr_sib->members().begin(); simplex != curr_sib->members().end(); ++simplex) {
941 if (vertices.empty()) {
946 bool addCoface = (star || curr_nbVertices == nbVertices);
948 cofaces.push_back(simplex);
949 if ((!addCoface || star) && has_children(simplex))
950 rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
952 if (simplex->first == vertices.back()) {
954 bool equalDim = (star || curr_nbVertices == nbVertices);
955 bool addCoface = vertices.size() == 1 && equalDim;
957 cofaces.push_back(simplex);
958 if ((!addCoface || star) && has_children(simplex)) {
960 Vertex_handle tmp = vertices.back();
962 rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
963 vertices.push_back(tmp);
965 }
else if (simplex->first > vertices.back()) {
969 if (has_children(simplex))
970 rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
983 return cofaces_simplex_range(simplex, 0);
994 Cofaces_simplex_range cofaces;
996 assert(codimension >= 0);
997 Simplex_vertex_range rg = simplex_vertex_range(simplex);
998 std::vector<Vertex_handle> copy(rg.begin(), rg.end());
999 if (codimension + static_cast<int>(copy.size()) > dimension_ + 1 ||
1000 (codimension == 0 && static_cast<int>(copy.size()) > dimension_))
1003 assert(std::is_sorted(copy.begin(), copy.end(), std::greater<Vertex_handle>()));
1004 bool star = codimension == 0;
1005 rec_coface(copy, &root_, 1, cofaces, star, codimension + static_cast<int>(copy.size()));
1017 bool reverse_lexicographic_order(Simplex_handle sh1, Simplex_handle sh2) {
1018 Simplex_vertex_range rg1 = simplex_vertex_range(sh1);
1019 Simplex_vertex_range rg2 = simplex_vertex_range(sh2);
1020 Simplex_vertex_iterator it1 = rg1.begin();
1021 Simplex_vertex_iterator it2 = rg2.begin();
1022 while (it1 != rg1.end() && it2 != rg2.end()) {
1030 return ((it1 == rg1.end()) && (it2 != rg2.end()));
1039 struct is_before_in_filtration {
1043 bool operator()(
const Simplex_handle sh1,
const Simplex_handle sh2)
const {
1045 if (sh1->second.filtration() != sh2->second.filtration()) {
1046 return sh1->second.filtration() < sh2->second.filtration();
1049 return st_->reverse_lexicographic_order(sh1, sh2);
1079 template<
class OneSkeletonGraph>
1082 assert(num_simplices() == 0);
1084 if (boost::num_vertices(skel_graph) == 0) {
1087 if (num_edges(skel_graph) == 0) {
1093 root_.members_.reserve(boost::num_vertices(skel_graph));
1095 typename boost::graph_traits<OneSkeletonGraph>::vertex_iterator v_it,
1097 for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end;
1099 root_.members_.emplace_hint(
1100 root_.members_.end(), *v_it,
1101 Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it)));
1103 std::pair<typename boost::graph_traits<OneSkeletonGraph>::edge_iterator,
1104 typename boost::graph_traits<OneSkeletonGraph>::edge_iterator> boost_edges = boost::edges(skel_graph);
1107 for (; boost_edges.first != boost_edges.second; boost_edges.first++) {
1108 auto edge = *(boost_edges.first);
1109 auto u = source(edge, skel_graph);
1110 auto v = target(edge, skel_graph);
1111 if (u == v)
throw "Self-loops are not simplicial";
1119 if (v < u) std::swap(u, v);
1120 auto sh = find_vertex(u);
1121 if (!has_children(sh)) {
1122 sh->second.assign_children(
new Siblings(&root_, sh->first));
1125 sh->second.children()->members().emplace(v,
1126 Node(sh->second.children(), boost::get(edge_filtration_t(), skel_graph, edge)));
1142 if (max_dim <= 1)
return;
1144 dimension_ = max_dim;
1145 for (Dictionary_it root_it = root_.members_.begin();
1146 root_it != root_.members_.end(); ++root_it) {
1147 if (has_children(root_it)) {
1148 siblings_expansion(root_it->second.children(), max_dim - 1);
1151 dimension_ = max_dim - dimension_;
1156 void siblings_expansion(Siblings * siblings,
1158 if (dimension_ > k) {
1163 Dictionary_it next = siblings->members().begin();
1166 thread_local std::vector<std::pair<Vertex_handle, Node> > inter;
1167 for (Dictionary_it s_h = siblings->members().begin();
1168 s_h != siblings->members().end(); ++s_h, ++next) {
1169 Simplex_handle root_sh = find_vertex(s_h->first);
1170 if (has_children(root_sh)) {
1174 siblings->members().end(),
1175 root_sh->second.children()->members().begin(),
1176 root_sh->second.children()->members().end(),
1177 s_h->second.filtration());
1178 if (inter.size() != 0) {
1179 Siblings * new_sib =
new Siblings(siblings,
1183 s_h->second.assign_children(new_sib);
1184 siblings_expansion(new_sib, k - 1);
1187 s_h->second.assign_children(siblings);
1196 static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
1197 Dictionary_it begin1, Dictionary_it end1,
1198 Dictionary_it begin2, Dictionary_it end2,
1199 Filtration_value filtration_) {
1200 if (begin1 == end1 || begin2 == end2)
1203 if (begin1->first == begin2->first) {
1204 Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
1205 intersection.emplace_back(begin1->first, Node(
nullptr, filt));
1206 if (++begin1 == end1 || ++begin2 == end2)
1208 }
else if (begin1->first < begin2->first) {
1209 if (++begin1 == end1)
1212 if (++begin2 == end2)
1237 template<
typename Blocker >
1240 for (
auto& simplex : boost::adaptors::reverse(root_.members())) {
1241 if (has_children(&simplex)) {
1242 siblings_expansion_with_blockers(simplex.second.children(), max_dim, max_dim - 1, block_simplex);
1249 template<
typename Blocker >
1250 void siblings_expansion_with_blockers(Siblings* siblings,
int max_dim,
int k, Blocker block_simplex) {
1251 if (dimension_ < max_dim - k) {
1252 dimension_ = max_dim - k;
1257 if (siblings->members().size() < 2)
1260 for (
auto simplex = siblings->members().rbegin() + 1; simplex != siblings->members().rend(); simplex++) {
1261 std::vector<std::pair<Vertex_handle, Node> > intersection;
1262 for(
auto next = siblings->members().rbegin(); next != simplex; next++) {
1263 bool to_be_inserted =
true;
1264 Filtration_value filt = simplex->second.filtration();
1266 for (Simplex_handle border : boundary_simplex_range(simplex)) {
1267 Simplex_handle border_child = find_child(border, next->first);
1268 if (border_child == null_simplex()) {
1269 to_be_inserted=
false;
1272 filt = (std::max)(filt, filtration(border_child));
1274 if (to_be_inserted) {
1275 intersection.emplace_back(next->first, Node(
nullptr, filt));
1278 if (intersection.size() != 0) {
1280 Siblings * new_sib =
new Siblings(siblings,
1282 boost::adaptors::reverse(intersection));
1283 std::vector<Vertex_handle> blocked_new_sib_vertex_list;
1285 for (
auto new_sib_member = new_sib->members().begin();
1286 new_sib_member != new_sib->members().end();
1288 bool blocker_result = block_simplex(new_sib_member);
1291 if (blocker_result) {
1292 blocked_new_sib_vertex_list.push_back(new_sib_member->first);
1295 if (blocked_new_sib_vertex_list.size() == new_sib->members().size()) {
1299 simplex->second.assign_children(siblings);
1301 for (
auto& blocked_new_sib_member : blocked_new_sib_vertex_list) {
1302 new_sib->members().erase(blocked_new_sib_member);
1305 simplex->second.assign_children(new_sib);
1306 siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex);
1310 simplex->second.assign_children(siblings);
1319 Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh)
const {
1320 if (!has_children(sh))
1321 return null_simplex();
1323 Simplex_handle child = sh->second.children()->find(vh);
1326 if (child == sh->second.children()->members().end())
1327 return null_simplex();
1340 os << num_simplices() <<
" " << std::endl;
1341 for (
auto sh : filtration_simplex_range()) {
1342 os << dimension(sh) <<
" ";
1343 for (
auto b_sh : boundary_simplex_range(sh)) {
1344 os << key(b_sh) <<
" ";
1346 os << filtration(sh) <<
" \n";
1358 bool modified =
false;
1360 for (
auto& simplex : boost::adaptors::reverse(root_.members())) {
1361 if (has_children(&simplex)) {
1362 modified |= rec_make_filtration_non_decreasing(simplex.second.children());
1375 bool rec_make_filtration_non_decreasing(Siblings * sib) {
1376 bool modified =
false;
1379 for (
auto& simplex : boost::adaptors::reverse(sib->members())) {
1381 Boundary_simplex_range boundary = boundary_simplex_range(&simplex);
1382 Boundary_simplex_iterator max_border = std::max_element(std::begin(boundary), std::end(boundary),
1383 [](Simplex_handle sh1, Simplex_handle sh2) {
1384 return filtration(sh1) < filtration(sh2);
1387 Filtration_value max_filt_border_value = filtration(*max_border);
1390 if (!(simplex.second.filtration() >= max_filt_border_value)) {
1393 simplex.second.assign_filtration(max_filt_border_value);
1395 if (has_children(&simplex)) {
1396 modified |= rec_make_filtration_non_decreasing(simplex.second.children());
1412 bool modified = rec_prune_above_filtration(root(), filtration);
1419 bool rec_prune_above_filtration(Siblings* sib, Filtration_value filt) {
1420 auto&& list = sib->members();
1421 auto last = std::remove_if(list.begin(), list.end(), [
this,filt](Dit_value_t& simplex) {
1422 if (simplex.second.filtration() <= filt)
return false;
1423 if (has_children(&simplex)) rec_delete(simplex.second.children());
1425 dimension_to_be_lowered_ =
true;
1429 bool modified = (last != list.end());
1430 if (last == list.begin() && sib != root()) {
1432 sib->oncles()->members()[sib->parent()].assign_children(sib->oncles());
1435 dimension_to_be_lowered_ =
true;
1439 list.erase(last, list.end());
1440 for (
auto&& simplex : list)
1441 if (has_children(&simplex))
1442 modified |= rec_prune_above_filtration(simplex.second.children(), filt);
1453 bool lower_upper_bound_dimension() {
1455 dimension_to_be_lowered_ =
false;
1456 int new_dimension = -1;
1458 for (Simplex_handle sh : complex_simplex_range()) {
1460 for (
auto vertex : simplex_vertex_range(sh)) {
1461 std::clog <<
" " << vertex;
1463 std::clog << std::endl;
1464 #endif // DEBUG_TRACES 1466 int sh_dimension = dimension(sh);
1467 if (sh_dimension >= dimension_)
1470 new_dimension = (std::max)(new_dimension, sh_dimension);
1472 dimension_ = new_dimension;
1488 GUDHI_CHECK(!has_children(sh),
1489 std::invalid_argument(
"Simplex_tree::remove_maximal_simplex - argument has children"));
1492 Siblings* child = sh->second.children();
1494 if ((child->size() > 1) || (child == root())) {
1500 child->oncles()->members().at(child->parent()).assign_children(child->oncles());
1503 dimension_to_be_lowered_ =
true;
1524 std::pair<Filtration_value, Extended_simplex_type> p;
1525 Filtration_value minval = efd.minval;
1526 Filtration_value maxval = efd.maxval;
1527 if (f >= -2 && f <= -1){
1528 p.first = minval + (maxval-minval)*(f + 2); p.second = Extended_simplex_type::UP;
1530 else if (f >= 1 && f <= 2){
1531 p.first = minval - (maxval-minval)*(f - 2); p.second = Extended_simplex_type::DOWN;
1534 p.first = std::numeric_limits<Filtration_value>::quiet_NaN(); p.second = Extended_simplex_type::EXTRA;
1556 Vertex_handle maxvert = std::numeric_limits<Vertex_handle>::min();
1557 Filtration_value minval = std::numeric_limits<Filtration_value>::infinity();
1558 Filtration_value maxval = -std::numeric_limits<Filtration_value>::infinity();
1559 for (
auto sh = root_.members().begin(); sh != root_.members().end(); ++sh){
1560 Filtration_value f = this->filtration(sh);
1561 minval = std::min(minval, f);
1562 maxval = std::max(maxval, f);
1563 maxvert = std::max(sh->first, maxvert);
1566 GUDHI_CHECK(maxvert < std::numeric_limits<Vertex_handle>::max(), std::invalid_argument(
"Simplex_tree contains a vertex with the largest Vertex_handle"));
1572 this->insert_simplex({maxvert}, -3);
1575 std::vector<Vertex_handle> vr;
1583 auto sh = this->find(vr);
1586 vr.push_back(maxvert);
1587 if (this->dimension(sh) == 0){
1588 Filtration_value v = this->filtration(sh);
1589 Filtration_value scaled_v = (v-minval)/(maxval-minval);
1591 this->assign_filtration(sh, -2 + scaled_v);
1593 this->insert_simplex(vr, 2 - scaled_v);
1597 this->assign_filtration(sh, -3);
1598 this->insert_simplex(vr, -3);
1603 this->make_filtration_non_decreasing();
1606 Extended_filtration_data efd(minval, maxval);
1615 auto filt = filtration_(sh);
1616 for(
auto v : simplex_vertex_range(sh))
1617 if(filtration_(find_vertex(v)) == filt)
1619 return null_vertex();
1630 auto&& vertices = simplex_vertex_range(sh);
1631 auto end = std::end(vertices);
1632 auto vi = std::begin(vertices);
1633 GUDHI_CHECK(vi != end,
"empty simplex");
1636 GUDHI_CHECK(vi != end,
"simplex of dimension 0");
1637 if(std::next(vi) == end)
return sh;
1638 boost::container::static_vector<Vertex_handle, 40> suffix;
1639 suffix.push_back(v0);
1640 auto filt = filtration_(sh);
1643 Vertex_handle v = *vi;
1644 auto&& children1 = find_vertex(v)->second.children()->members_;
1645 for(
auto w : suffix){
1647 Simplex_handle s = children1.find(w);
1648 if(filtration_(s) == filt)
1651 suffix.push_back(v);
1654 return null_simplex();
1662 auto filt = filtration_(sh);
1664 for(
auto b : boundary_simplex_range(sh))
1665 if(filtration_(b) == filt)
1666 return minimal_simplex_with_same_filtration(b);
1671 Vertex_handle null_vertex_;
1676 std::vector<Simplex_handle> filtration_vect_;
1679 bool dimension_to_be_lowered_ =
false;
1683 template<
typename...T>
1695 template<
typename...T>
1698 std::vector<typename ST::Vertex_handle> simplex;
1699 typename ST::Filtration_value fil;
1704 int dim =
static_cast<int> (simplex.size() - 1);
1705 if (max_dim < dim) {
1723 typedef int Vertex_handle;
1724 typedef double Filtration_value;
1725 typedef std::uint32_t Simplex_key;
1726 static const bool store_key =
true;
1727 static const bool store_filtration =
true;
1728 static const bool contiguous_vertices =
false;
1739 typedef int Vertex_handle;
1740 typedef float Filtration_value;
1741 typedef std::uint32_t Simplex_key;
1742 static const bool store_key =
true;
1743 static const bool store_filtration =
true;
1744 static const bool contiguous_vertices =
true;
1751 #endif // SIMPLEX_TREE_H_ 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:200
Dictionary::iterator Simplex_handle
Handle type to a simplex contained in the simplicial complex represented by the simplex tree...
Definition: Simplex_tree.h:149
bool prune_above_filtration(Filtration_value filtration)
Prune above filtration value given as parameter.
Definition: Simplex_tree.h:1411
void expansion(int max_dim)
Expands the Simplex_tree containing only its one skeleton until dimension max_dim.
Definition: Simplex_tree.h:1141
Filtration_simplex_range::const_iterator Filtration_simplex_iterator
Iterator over the simplices of the simplicial complex, ordered by the filtration. ...
Definition: Simplex_tree.h:209
Tag for a linear ordering of simplices.
Definition: indexing_tag.h:20
Simplex Tree data structure for representing simplicial complexes.
Definition: Simplex_tree.h:75
void maybe_initialize_filtration()
Initializes the filtration cache if it isn't initialized yet.
Definition: Simplex_tree.h:910
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:781
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:842
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
bool operator==(Simplex_tree &st2)
Checks if two simplex trees are equal.
Definition: Simplex_tree.h:446
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:1628
Concept describing an indexing scheme (see FilteredComplex) for applying continuous maps to a cell co...
Definition: IndexingTag.h:18
static Simplex_key key(Simplex_handle sh)
Returns the key associated to a simplex.
Definition: Simplex_tree.h:492
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:530
static Siblings * self_siblings(SimplexHandle sh)
Definition: Simplex_tree.h:856
boost::iterator_range< Complex_vertex_iterator > Complex_vertex_range
Range over the vertices of the simplicial complex.
Definition: Simplex_tree.h:175
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:541
Simplex_tree_simplex_vertex_iterator< Simplex_tree > Simplex_vertex_iterator
Iterator over the vertices of a simplex.
Definition: Simplex_tree.h:179
Extended_filtration_data extend_filtration()
Extend filtration for computing extended persistence. This function only uses the filtration values a...
Definition: Simplex_tree.h:1552
Definition: SimplicialComplexForAlpha.h:14
void print_hasse(std::ostream &os)
Write the hasse diagram of the simplicial complex in os.
Definition: Simplex_tree.h:1339
Key type used as simplex identifier.
Definition: SimplexKey.h:15
Siblings * root()
Definition: Simplex_tree.h:865
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:1523
Options::Simplex_key Simplex_key
Key associated to each simplex.
Definition: Simplex_tree.h:86
bool operator!=(Simplex_tree &st2)
Checks if two simplex trees are different.
Definition: Simplex_tree.h:454
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:1357
std::vector< Simplex_handle > Filtration_simplex_range
Range over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:205
int dimension()
Returns the dimension of the simplicial complex.
Definition: Simplex_tree.h:593
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:262
void initialize_filtration()
Initializes the filtration cache, i.e. sorts the simplices according to their order in the filtration...
Definition: Simplex_tree.h:886
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:615
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20
Cofaces_simplex_range cofaces_simplex_range(const Simplex_handle simplex, int codimension)
Compute the cofaces of a n simplex.
Definition: Simplex_tree.h:993
Complex_simplex_range complex_simplex_range()
Returns a range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:228
Simplex_vertex_range simplex_vertex_range(Simplex_handle sh) const
Returns a range over the vertices of a simplex.
Definition: Simplex_tree.h:273
Concept of the template parameter for the class Gudhi::Simplex_tree<SimplexTreeOptions>.
Definition: SimplexTreeOptions.h:15
size_t num_vertices() const
Returns the number of vertices in the complex.
Definition: Simplex_tree.h:546
void assign_filtration(Simplex_handle sh, Filtration_value fv)
Sets the filtration value of a simplex.
Definition: Simplex_tree.h:520
std::pair< Simplex_handle, Simplex_handle > endpoints(Simplex_handle sh)
Definition: Simplex_tree.h:849
Boundary_simplex_range boundary_simplex_range(SimplexHandle sh)
Returns a range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:294
void clear_filtration()
Clears the filtration cache produced by initialize_filtration().
Definition: Simplex_tree.h:919
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:217
Options::Vertex_handle Vertex_handle
Type for the vertex handle.
Definition: Simplex_tree.h:90
Simplex_tree(Simplex_tree &&complex_source)
User-defined move constructor relocates the whole tree structure.
Definition: Simplex_tree.h:321
Simplex_tree & operator=(Simplex_tree &&complex_source)
User-defined move assignment relocates the whole tree structure.
Definition: Simplex_tree.h:355
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:1614
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:242
boost::iterator_range< Boundary_simplex_iterator > Boundary_simplex_range
Range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:189
bool has_children(SimplexHandle sh) const
Returns true if the node in the simplex tree pointed by sh has children.
Definition: Simplex_tree.h:602
Cofaces_simplex_range star_simplex_range(const Simplex_handle simplex)
Compute the star of a n simplex.
Definition: Simplex_tree.h:982
void set_dimension(int dimension)
Set a dimension for the simplicial complex.
Definition: Simplex_tree.h:873
int upper_bound_dimension() const
Returns an upper bound on the dimension of the simplicial complex.
Definition: Simplex_tree.h:585
int dimension(Simplex_handle sh)
Returns the dimension of a simplex.
Definition: Simplex_tree.h:574
static Simplex_key null_key()
Returns a fixed number not in the interval [0, num_simplices()).
Definition: Simplex_tree.h:535
static Filtration_value filtration(Simplex_handle sh)
Returns the filtration value of a simplex.
Definition: Simplex_tree.h:509
Definition: Simplex_tree.h:1737
Definition: Simplex_tree.h:1721
Simplex_tree(const Simplex_tree &complex_source)
User-defined copy constructor reproduces the whole tree structure.
Definition: Simplex_tree.h:311
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15
boost::transform_iterator< return_first, Dictionary_it > Complex_vertex_iterator
Iterator over the vertices of the simplicial complex.
Definition: Simplex_tree.h:173
~Simplex_tree()
Destructor; deallocates the whole tree structure.
Definition: Simplex_tree.h:333
void remove_maximal_simplex(Simplex_handle sh)
Remove a maximal simplex.
Definition: Simplex_tree.h:1486
size_t num_simplices()
returns the number of simplices in the simplex_tree.
Definition: Simplex_tree.h:552
boost::iterator_range< Complex_simplex_iterator > Complex_simplex_range
Range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:195
Options::Filtration_value Filtration_value
Type for the value of the filtration function.
Definition: Simplex_tree.h:82
Simplex_tree()
Constructs an empty simplex tree.
Definition: Simplex_tree.h:304
Extended simplex type data structure for representing the type of simplices in an extended filtration...
Simplex_tree_boundary_simplex_iterator< Simplex_tree > Boundary_simplex_iterator
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:187
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:203
Simplex_tree_complex_simplex_iterator< Simplex_tree > Complex_simplex_iterator
Iterator over the simplices of the simplicial complex.
Definition: Simplex_tree.h:193
void insert_graph(const OneSkeletonGraph &skel_graph)
Inserts a 1-skeleton in an empty Simplex_tree.
Definition: Simplex_tree.h:1080
Simplex_handle simplex(Simplex_key idx) const
Returns the simplex that has index idx in the filtration.
Definition: Simplex_tree.h:500
Graph simplicial complex methods.
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:1661
This file includes common file reader for GUDHI.
boost::iterator_range< Simplex_vertex_iterator > Simplex_vertex_range
Range over the vertices of a simplex.
Definition: Simplex_tree.h:181
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:752
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:1238
std::vector< Simplex_handle > Cofaces_simplex_range
Range over the cofaces of a simplex.
Definition: Simplex_tree.h:183