Gudhi  1.2.0
 All Classes Functions Variables Typedefs Friends Groups Pages
Simplex_tree.h
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): Clément Maria
6  *
7  * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef SIMPLEX_TREE_H_
24 #define SIMPLEX_TREE_H_
25 
26 #include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h>
27 #include <gudhi/Simplex_tree/Simplex_tree_siblings.h>
28 #include <gudhi/Simplex_tree/Simplex_tree_iterators.h>
29 #include <gudhi/Simplex_tree/indexing_tag.h>
30 
31 #include <gudhi/reader_utils.h>
32 #include <gudhi/graph_simplicial_complex.h>
33 
34 #include <boost/container/flat_map.hpp>
35 #include <boost/iterator/transform_iterator.hpp>
36 #include <boost/graph/adjacency_list.hpp>
37 
38 #include <algorithm>
39 #include <utility>
40 #include <vector>
41 #include <functional> // for greater<>
42 
43 namespace Gudhi {
44 
80 struct Simplex_tree_options_full_featured {
82  typedef linear_indexing_tag Indexing_tag;
83  typedef int Vertex_handle;
84  typedef double Filtration_value;
85  typedef int Simplex_key;
86  static const bool store_key = true;
87  static const bool store_filtration = true;
88 };
89 
102 template<typename SimplexTreeOptions = Simplex_tree_options_full_featured>
104  public:
105  typedef SimplexTreeOptions Options;
106  typedef typename Options::Indexing_tag Indexing_tag;
119 
120  /* Type of node in the simplex tree. */
121  typedef Simplex_tree_node_explicit_storage<Simplex_tree> Node;
122  /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */
123  // Note: this wastes space when Vertex_handle is 32 bits and Node is aligned on 64 bits. It would be better to use a
124  // flat_set (with our own comparator) where we can control the layout of the struct (put Vertex_handle and
125  // Simplex_key next to each other).
126  typedef typename boost::container::flat_map<Vertex_handle, Node> Dictionary;
127 
128  /* \brief Set of nodes sharing a same parent in the simplex tree. */
129  /* \brief Set of nodes sharing a same parent in the simplex tree. */
130  typedef Simplex_tree_siblings<Simplex_tree, Dictionary> Siblings;
131 
132  struct Key_simplex_base_real {
133  Key_simplex_base_real() : key_(-1) {}
134  void assign_key(Simplex_key k) { key_ = k; }
135  Simplex_key key() const { return key_; }
136  private:
137  Simplex_key key_;
138  };
139  struct Key_simplex_base_dummy {
140  Key_simplex_base_dummy() {}
141  void assign_key(Simplex_key) { }
142  Simplex_key key() const { assert(false); return -1; }
143  };
144  typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type Key_simplex_base;
145 
146  struct Filtration_simplex_base_real {
147  Filtration_simplex_base_real() : filt_(0) {}
148  void assign_filtration(Filtration_value f) { filt_ = f; }
149  Filtration_value filtration() const { return filt_; }
150  private:
151  Filtration_value filt_;
152  };
153  struct Filtration_simplex_base_dummy {
154  Filtration_simplex_base_dummy() {}
155  void assign_filtration(Filtration_value f) { assert(f == 0); }
156  Filtration_value filtration() const { return 0; }
157  };
158  typedef typename std::conditional<Options::store_filtration, Filtration_simplex_base_real,
159  Filtration_simplex_base_dummy>::type Filtration_simplex_base;
160 
161  public:
164  typedef typename Dictionary::iterator Simplex_handle;
165 
166  private:
167  typedef typename Dictionary::iterator Dictionary_it;
168  typedef typename Dictionary_it::value_type Dit_value_t;
169 
170  struct return_first {
171  Vertex_handle operator()(const Dit_value_t& p_sh) const {
172  return p_sh.first;
173  }
174  };
175 
176  public:
188  typedef boost::transform_iterator<return_first, Dictionary_it> Complex_vertex_iterator;
190  typedef boost::iterator_range<Complex_vertex_iterator> Complex_vertex_range;
194  typedef Simplex_tree_simplex_vertex_iterator<Simplex_tree> Simplex_vertex_iterator;
196  typedef boost::iterator_range<Simplex_vertex_iterator> Simplex_vertex_range;
198  typedef std::vector<Simplex_handle> Cofaces_simplex_range;
202  typedef Simplex_tree_boundary_simplex_iterator<Simplex_tree> Boundary_simplex_iterator;
204  typedef boost::iterator_range<Boundary_simplex_iterator> Boundary_simplex_range;
208  typedef Simplex_tree_complex_simplex_iterator<Simplex_tree> Complex_simplex_iterator;
210  typedef boost::iterator_range<Complex_simplex_iterator> Complex_simplex_range;
215  typedef Simplex_tree_skeleton_simplex_iterator<Simplex_tree> Skeleton_simplex_iterator;
218  typedef boost::iterator_range<Skeleton_simplex_iterator> Skeleton_simplex_range;
220  typedef std::vector<Simplex_handle> Filtration_simplex_range;
224  typedef typename Filtration_simplex_range::const_iterator Filtration_simplex_iterator;
225 
226  /* @} */ // end name range and iterator types
233  return Complex_vertex_range(
234  boost::make_transform_iterator(root_.members_.begin(), return_first()),
235  boost::make_transform_iterator(root_.members_.end(), return_first()));
236  }
237 
246  }
247 
260  }
261 
278  if (filtration_vect_.empty()) {
280  }
281  return filtration_vect_;
282  }
283 
291  assert(sh != null_simplex()); // Empty simplex
294  }
295 
313  }
314  // end range and iterator methods
321  : null_vertex_(-1),
322  threshold_(0),
323  root_(nullptr, null_vertex_),
324  filtration_vect_(),
325  dimension_(-1) { }
326 
328  Simplex_tree(const Simplex_tree& simplex_source)
329  : null_vertex_(simplex_source.null_vertex_),
330  threshold_(simplex_source.threshold_),
331  filtration_vect_(),
332  dimension_(simplex_source.dimension_) {
333  auto root_source = simplex_source.root_;
334  auto memb_source = root_source.members();
335  root_ = Siblings(nullptr, null_vertex_, memb_source);
336  rec_copy(&root_, &root_source);
337  }
338 
340  void rec_copy(Siblings *sib, Siblings *sib_source) {
341  for (auto sh = sib->members().begin(), sh_source = sib_source->members().begin();
342  sh != sib->members().end(); ++sh, ++sh_source) {
343  if (has_children(sh_source)) {
344  Siblings * newsib = new Siblings(sib, sh_source->first);
345  newsib->members_.reserve(sh_source->second.children()->members().size());
346  for (auto & child : sh_source->second.children()->members())
347  newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(sib, child.second.filtration()));
348  rec_copy(newsib, sh_source->second.children());
349  sh->second.assign_children(newsib);
350  }
351  }
352  }
353 
356  : null_vertex_(std::move(old.null_vertex_)),
357  threshold_(std::move(old.threshold_)),
358  root_(std::move(old.root_)),
359  filtration_vect_(std::move(old.filtration_vect_)),
360  dimension_(std::move(old.dimension_)) {
361  old.dimension_ = -1;
362  old.threshold_ = 0;
363  old.root_ = Siblings(nullptr, null_vertex_);
364  }
365 
368  for (auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
369  if (has_children(sh)) {
370  rec_delete(sh->second.children());
371  }
372  }
373  } // end constructor/destructor
375  private:
376  // Recursive deletion
377  void rec_delete(Siblings * sib) {
378  for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
379  if (has_children(sh)) {
380  rec_delete(sh->second.children());
381  }
382  }
383  delete sib;
384  }
385 
386  public:
389  if ((null_vertex_ != st2.null_vertex_) ||
390  (threshold_ != st2.threshold_) ||
391  (dimension_ != st2.dimension_))
392  return false;
393  return rec_equal(&root_, &st2.root_);
394  }
395 
398  return (!(*this == st2));
399  }
400 
401  private:
403  bool rec_equal(Siblings* s1, Siblings* s2) {
404  if (s1->members().size() != s2->members().size())
405  return false;
406  for (auto sh1 = s1->members().begin(), sh2 = s2->members().begin();
407  (sh1 != s1->members().end() && sh2 != s2->members().end()); ++sh1, ++sh2) {
408  if (sh1->first != sh2->first || sh1->second.filtration() != sh2->second.filtration())
409  return false;
410  if (has_children(sh1) != has_children(sh2))
411  return false;
412  // Recursivity on children only if both have children
413  else if (has_children(sh1))
414  if (!rec_equal(sh1->second.children(), sh2->second.children()))
415  return false;
416  }
417  return true;
418  }
419 
420  public:
427  return sh->second.key();
428  }
429 
436  return filtration_vect_[key];
437  }
438 
445  if (sh != null_simplex()) {
446  return sh->second.filtration();
447  } else {
448  return INFINITY;
449  }
450  }
451 
454  return threshold_;
455  }
456 
462  return Dictionary_it(nullptr);
463  }
464 
468  return -1;
469  }
470 
474  return null_vertex_;
475  }
476 
478  size_t num_vertices() const {
479  return root_.members_.size();
480  }
481 
482  public:
484  size_t num_simplices() {
485  return num_simplices(&root_);
486  }
487 
488  private:
490  size_t num_simplices(Siblings * sib) {
491  auto sib_begin = sib->members().begin();
492  auto sib_end = sib->members().end();
493  size_t simplices_number = sib_end - sib_begin;
494  for (auto sh = sib_begin; sh != sib_end; ++sh) {
495  if (has_children(sh)) {
496  simplices_number += num_simplices(sh->second.children());
497  }
498  }
499  return simplices_number;
500  }
501 
502  public:
507  Siblings * curr_sib = self_siblings(sh);
508  int dim = 0;
509  while (curr_sib != nullptr) {
510  ++dim;
511  curr_sib = curr_sib->oncles();
512  }
513  return dim - 1;
514  }
515 
517  int dimension() const {
518  return dimension_;
519  }
520 
523  bool has_children(Simplex_handle sh) const {
524  return (sh->second.children()->parent() == sh->first);
525  }
526 
534  template<class InputVertexRange>
535  Simplex_handle find(const InputVertexRange & s) {
536  auto first = std::begin(s);
537  auto last = std::end(s);
538 
539  if (first == last)
540  return null_simplex(); // ----->>
541 
542  // Copy before sorting
543  std::vector<Vertex_handle> copy(first, last);
544  std::sort(std::begin(copy), std::end(copy));
545  return find_simplex(copy);
546  }
547 
548  private:
550  Simplex_handle find_simplex(const std::vector<Vertex_handle> & simplex) {
551  Siblings * tmp_sib = &root_;
552  Dictionary_it tmp_dit;
553  Vertex_handle last = simplex.back();
554  for (auto v : simplex) {
555  tmp_dit = tmp_sib->members_.find(v);
556  if (tmp_dit == tmp_sib->members_.end()) {
557  return null_simplex();
558  }
559  if (!has_children(tmp_dit) && v != last) {
560  return null_simplex();
561  }
562  tmp_sib = tmp_dit->second.children();
563  }
564  return tmp_dit;
565  }
566 
569  Simplex_handle find_vertex(Vertex_handle v) {
570  return root_.members_.begin() + v;
571  }
572  //{ return root_.members_.find(v); }
573 
574  private:
577  std::pair<Simplex_handle, bool> insert_vertex_vector(const std::vector<Vertex_handle>& simplex,
578  Filtration_value filtration) {
579  Siblings * curr_sib = &root_;
580  std::pair<Simplex_handle, bool> res_insert;
581  auto vi = simplex.begin();
582  for (; vi != simplex.end() - 1; ++vi) {
583  res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
584  if (!(has_children(res_insert.first))) {
585  res_insert.first->second.assign_children(new Siblings(curr_sib, *vi));
586  }
587  curr_sib = res_insert.first->second.children();
588  }
589  res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
590  if (!res_insert.second) {
591  // if already in the complex
592  if (res_insert.first->second.filtration() > filtration) {
593  // if filtration value modified
594  res_insert.first->second.assign_filtration(filtration);
595  return res_insert;
596  }
597  // if filtration value unchanged
598  return std::pair<Simplex_handle, bool>(null_simplex(), false);
599  }
600  // otherwise the insertion has succeeded
601  return res_insert;
602  }
603 
604  public:
628  template<class InputVertexRange>
629  std::pair<Simplex_handle, bool> insert_simplex(const InputVertexRange & simplex,
630  Filtration_value filtration = 0) {
631  auto first = std::begin(simplex);
632  auto last = std::end(simplex);
633 
634  if (first == last)
635  return std::pair<Simplex_handle, bool>(null_simplex(), true); // ----->>
636 
637  // Copy before sorting
638  std::vector<Vertex_handle> copy(first, last);
639  std::sort(std::begin(copy), std::end(copy));
640  return insert_vertex_vector(copy, filtration);
641  }
642 
657  template<class InputVertexRange>
658  std::pair<Simplex_handle, bool> insert_simplex_and_subfaces(const InputVertexRange& Nsimplex,
659  Filtration_value filtration = 0) {
660  auto first = std::begin(Nsimplex);
661  auto last = std::end(Nsimplex);
662 
663  if (first == last)
664  return std::pair<Simplex_handle, bool>(null_simplex(), true); // ----->>
665 
666  // Copy before sorting
667  std::vector<Vertex_handle> copy(first, last);
668  std::sort(std::begin(copy), std::end(copy));
669 
670  std::vector<std::vector<Vertex_handle>> to_be_inserted;
671  std::vector<std::vector<Vertex_handle>> to_be_propagated;
672  return rec_insert_simplex_and_subfaces(copy, to_be_inserted, to_be_propagated, filtration);
673  }
674 
675  private:
676  std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces(std::vector<Vertex_handle>& the_simplex,
677  std::vector<std::vector<Vertex_handle>>& to_be_inserted,
678  std::vector<std::vector<Vertex_handle>>& to_be_propagated,
679  Filtration_value filtration = 0.0) {
680  std::pair<Simplex_handle, bool> insert_result;
681  if (the_simplex.size() > 1) {
682  // Get and remove last vertex
683  Vertex_handle last_vertex = the_simplex.back();
684  the_simplex.pop_back();
685  // Recursive call after last vertex removal
686  insert_result = rec_insert_simplex_and_subfaces(the_simplex, to_be_inserted, to_be_propagated, filtration);
687 
688  // Concatenation of to_be_inserted and to_be_propagated
689  to_be_inserted.insert(to_be_inserted.begin(), to_be_propagated.begin(), to_be_propagated.end());
690  to_be_propagated = to_be_inserted;
691 
692  // to_be_inserted treatment
693  for (auto& simplex_tbi : to_be_inserted) {
694  simplex_tbi.push_back(last_vertex);
695  }
696  std::vector<Vertex_handle> last_simplex(1, last_vertex);
697  to_be_inserted.insert(to_be_inserted.begin(), last_simplex);
698  // i.e. (0,1,2) =>
699  // [to_be_inserted | to_be_propagated] = [(1) (0,1) | (0)]
700  // [to_be_inserted | to_be_propagated] = [(2) (0,2) (1,2) (0,1,2) | (0) (1) (0,1)]
701  // N.B. : it is important the last inserted to be the highest in dimension
702  // in order to return the "last" insert_simplex result
703 
704  // insert all to_be_inserted
705  for (auto& simplex_tbi : to_be_inserted) {
706  insert_result = insert_vertex_vector(simplex_tbi, filtration);
707  }
708  } else if (the_simplex.size() == 1) {
709  // When reaching the end of recursivity, vector of simplices shall be empty and filled on back recursive
710  if ((to_be_inserted.size() != 0) || (to_be_propagated.size() != 0)) {
711  std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Error vector not empty" << std::endl;
712  exit(-1);
713  }
714  std::vector<Vertex_handle> first_simplex(1, the_simplex.back());
715  // i.e. (0,1,2) => [to_be_inserted | to_be_propagated] = [(0) | ]
716  to_be_inserted.push_back(first_simplex);
717 
718  insert_result = insert_vertex_vector(first_simplex, filtration);
719  } else {
720  std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Recursivity error" << std::endl;
721  exit(-1);
722  }
723  return insert_result;
724  }
725 
726  public:
730  sh->second.assign_key(key);
731  }
732 
733  public:
737  std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
738  assert(dimension(sh) == 1);
739  return { find_vertex(sh->first), find_vertex(self_siblings(sh)->parent()) };
740  }
741 
743  Siblings * self_siblings(Simplex_handle sh) {
744  if (sh->second.children()->parent() == sh->first)
745  return sh->second.children()->oncles();
746  else
747  return sh->second.children();
748  }
749 
750  public:
752  Siblings * root() {
753  return &root_;
754  }
755 
758  threshold_ = fil;
759  }
760 
763  dimension_ = dimension;
764  }
765 
766  public:
777  filtration_vect_.clear();
778  filtration_vect_.reserve(num_simplices());
780  filtration_vect_.push_back(sh);
781 
782  /* We use stable_sort here because with libstdc++ it is faster than sort.
783  * is_before_in_filtration is now a total order, but we used to call
784  * stable_sort for the following heuristic:
785  * The use of a depth-first traversal of the simplex tree, provided by
786  * complex_simplex_range(), combined with a stable sort is meant to
787  * optimize the order of simplices with same filtration value. The
788  * heuristic consists in inserting the cofaces of a simplex as soon as
789  * possible.
790  */
791  std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(),
792  is_before_in_filtration(this));
793  }
794 
795  private:
808  void rec_coface(std::vector<Vertex_handle> &vertices, Siblings *curr_sib, int curr_nbVertices,
809  std::vector<Simplex_handle>& cofaces, bool star, int nbVertices) {
810  if (!(star || curr_nbVertices <= nbVertices)) // dimension of actual simplex <= nbVertices
811  return;
812  for (Simplex_handle simplex = curr_sib->members().begin(); simplex != curr_sib->members().end(); ++simplex) {
813  if (vertices.empty()) {
814  // If we reached the end of the vertices, and the simplex has more vertices than the given simplex
815  // => we found a coface
816 
817  // Add a coface if we wan't the star or if the number of vertices of the current simplex matches with nbVertices
818  bool addCoface = (star || curr_nbVertices == nbVertices);
819  if (addCoface)
820  cofaces.push_back(simplex);
821  if ((!addCoface || star) && has_children(simplex)) // Rec call
822  rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
823  } else {
824  if (simplex->first == vertices.back()) {
825  // If curr_sib matches with the top vertex
826  bool equalDim = (star || curr_nbVertices == nbVertices); // dimension of actual simplex == nbVertices
827  bool addCoface = vertices.size() == 1 && equalDim;
828  if (addCoface)
829  cofaces.push_back(simplex);
830  if ((!addCoface || star) && has_children(simplex)) {
831  // Rec call
832  Vertex_handle tmp = vertices.back();
833  vertices.pop_back();
834  rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
835  vertices.push_back(tmp);
836  }
837  } else if (simplex->first > vertices.back()) {
838  return;
839  } else {
840  // (simplex->first < vertices.back()
841  if (has_children(simplex))
842  rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
843  }
844  }
845  }
846  }
847 
848  public:
855  return cofaces_simplex_range(simplex, 0);
856  }
857 
866  Cofaces_simplex_range cofaces;
867  // codimension must be positive or null integer
868  assert(codimension >= 0);
870  std::vector<Vertex_handle> copy(rg.begin(), rg.end());
871  if (codimension + static_cast<int>(copy.size()) > dimension_ + 1 ||
872  (codimension == 0 && static_cast<int>(copy.size()) > dimension_)) // n+codimension greater than dimension_
873  return cofaces;
874  // must be sorted in decreasing order
875  assert(std::is_sorted(copy.begin(), copy.end(), std::greater<Vertex_handle>()));
876  bool star = codimension == 0;
877  rec_coface(copy, &root_, 1, cofaces, star, codimension + static_cast<int>(copy.size()));
878  return cofaces;
879  }
880 
881  private:
889  bool reverse_lexicographic_order(Simplex_handle sh1, Simplex_handle sh2) {
892  Simplex_vertex_iterator it1 = rg1.begin();
893  Simplex_vertex_iterator it2 = rg2.begin();
894  while (it1 != rg1.end() && it2 != rg2.end()) {
895  if (*it1 == *it2) {
896  ++it1;
897  ++it2;
898  } else {
899  return *it1 < *it2;
900  }
901  }
902  return ((it1 == rg1.end()) && (it2 != rg2.end()));
903  }
904 
911  struct is_before_in_filtration {
912  explicit is_before_in_filtration(Simplex_tree * st)
913  : st_(st) { }
914 
915  bool operator()(const Simplex_handle sh1, const Simplex_handle sh2) const {
916  // Not using st_->filtration(sh1) because it uselessly tests for null_simplex.
917  if (sh1->second.filtration() != sh2->second.filtration()) {
918  return sh1->second.filtration() < sh2->second.filtration();
919  }
920  // is sh1 a proper subface of sh2
921  return st_->reverse_lexicographic_order(sh1, sh2);
922  }
923 
924  Simplex_tree * st_;
925  };
926 
927  public:
946  template<class OneSkeletonGraph>
947  void insert_graph(const OneSkeletonGraph& skel_graph) {
948  // the simplex tree must be empty
949  assert(num_simplices() == 0);
950 
951  if (boost::num_vertices(skel_graph) == 0) {
952  return;
953  }
954  if (num_edges(skel_graph) == 0) {
955  dimension_ = 0;
956  } else {
957  dimension_ = 1;
958  }
959 
960  root_.members_.reserve(boost::num_vertices(skel_graph));
961 
962  typename boost::graph_traits<OneSkeletonGraph>::vertex_iterator v_it,
963  v_it_end;
964  for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end;
965  ++v_it) {
966  root_.members_.emplace_hint(
967  root_.members_.end(), *v_it,
968  Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it)));
969  }
970  typename boost::graph_traits<OneSkeletonGraph>::edge_iterator e_it,
971  e_it_end;
972  for (std::tie(e_it, e_it_end) = boost::edges(skel_graph); e_it != e_it_end;
973  ++e_it) {
974  auto u = source(*e_it, skel_graph);
975  auto v = target(*e_it, skel_graph);
976  if (u < v) {
977  // count edges only once { std::swap(u,v); } // u < v
978  auto sh = find_vertex(u);
979  if (!has_children(sh)) {
980  sh->second.assign_children(new Siblings(&root_, sh->first));
981  }
982 
983  sh->second.children()->members().emplace(
984  v,
985  Node(sh->second.children(),
986  boost::get(edge_filtration_t(), skel_graph, *e_it)));
987  }
988  }
989  }
990 
1002  void expansion(int max_dim) {
1003  dimension_ = max_dim;
1004  for (Dictionary_it root_it = root_.members_.begin();
1005  root_it != root_.members_.end(); ++root_it) {
1006  if (has_children(root_it)) {
1007  siblings_expansion(root_it->second.children(), max_dim - 1);
1008  }
1009  }
1010  dimension_ = max_dim - dimension_;
1011  }
1012 
1013  private:
1015  void siblings_expansion(Siblings * siblings, // must contain elements
1016  int k) {
1017  if (dimension_ > k) {
1018  dimension_ = k;
1019  }
1020  if (k == 0)
1021  return;
1022  Dictionary_it next = siblings->members().begin();
1023  ++next;
1024 
1025  static std::vector<std::pair<Vertex_handle, Node> > inter; // static, not thread-safe.
1026  for (Dictionary_it s_h = siblings->members().begin();
1027  s_h != siblings->members().end(); ++s_h, ++next) {
1028  Simplex_handle root_sh = find_vertex(s_h->first);
1029  if (has_children(root_sh)) {
1030  intersection(
1031  inter, // output intersection
1032  next, // begin
1033  siblings->members().end(), // end
1034  root_sh->second.children()->members().begin(),
1035  root_sh->second.children()->members().end(),
1036  s_h->second.filtration());
1037  if (inter.size() != 0) {
1038  Siblings * new_sib = new Siblings(siblings, // oncles
1039  s_h->first, // parent
1040  inter); // boost::container::ordered_unique_range_t
1041  inter.clear();
1042  s_h->second.assign_children(new_sib);
1043  siblings_expansion(new_sib, k - 1);
1044  } else {
1045  // ensure the children property
1046  s_h->second.assign_children(siblings);
1047  inter.clear();
1048  }
1049  }
1050  }
1051  }
1052 
1055  static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
1056  Dictionary_it begin1, Dictionary_it end1,
1057  Dictionary_it begin2, Dictionary_it end2,
1058  Filtration_value filtration_) {
1059  if (begin1 == end1 || begin2 == end2)
1060  return; // ----->>
1061  while (true) {
1062  if (begin1->first == begin2->first) {
1063  Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
1064  intersection.emplace_back(begin1->first, Node(nullptr, filt));
1065  if (++begin1 == end1 || ++begin2 == end2)
1066  return; // ----->>
1067  } else if (begin1->first < begin2->first) {
1068  if (++begin1 == end1)
1069  return;
1070  } else /* begin1->first > begin2->first */ {
1071  if (++begin2 == end2)
1072  return; // ----->>
1073  }
1074  }
1075  }
1076 
1077  public:
1084  void print_hasse(std::ostream& os) {
1085  os << num_simplices() << " " << std::endl;
1086  for (auto sh : filtration_simplex_range()) {
1087  os << dimension(sh) << " ";
1088  for (auto b_sh : boundary_simplex_range(sh)) {
1089  os << key(b_sh) << " ";
1090  }
1091  os << filtration(sh) << " \n";
1092  }
1093  }
1094 
1095  private:
1096  Vertex_handle null_vertex_;
1098  Filtration_value threshold_;
1101  Siblings root_;
1103  std::vector<Simplex_handle> filtration_vect_;
1105  int dimension_;
1106 };
1107 
1108 // Print a Simplex_tree in os.
1109 
1110 template<typename...T>
1111 std::ostream& operator<<(std::ostream & os, Simplex_tree<T...> & st) {
1112  for (auto sh : st.filtration_simplex_range()) {
1113  os << st.dimension(sh) << " ";
1114  for (auto v : st.simplex_vertex_range(sh)) {
1115  os << v << " ";
1116  }
1117  os << st.filtration(sh) << "\n"; // TODO(VR): why adding the key ?? not read ?? << " " << st.key(sh) << " \n";
1118  }
1119  return os;
1120 }
1121 
1122 template<typename...T>
1123 std::istream& operator>>(std::istream & is, Simplex_tree<T...> & st) {
1124  typedef Simplex_tree<T...> ST;
1125  std::vector<typename ST::Vertex_handle> simplex;
1126  typename ST::Filtration_value fil;
1127  typename ST::Filtration_value max_fil = 0;
1128  int max_dim = -1;
1129  while (read_simplex(is, simplex, fil)) {
1130  // read all simplices in the file as a list of vertices
1131  // Warning : simplex_size needs to be casted in int - Can be 0
1132  int dim = static_cast<int> (simplex.size() - 1);
1133  if (max_dim < dim) {
1134  max_dim = dim;
1135  }
1136  if (max_fil < fil) {
1137  max_fil = fil;
1138  }
1139  // insert every simplex in the simplex tree
1140  st.insert_simplex(simplex, fil);
1141  simplex.clear();
1142  }
1143  st.set_dimension(max_dim);
1144  st.set_filtration(max_fil);
1145 
1146  return is;
1147 } // end defgroup simplex_tree
1149 
1150 } // namespace Gudhi
1151 
1152 #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:215
unspecified Simplex_key
Key associated to each simplex.
Definition: FilteredComplex.h:35
Dictionary::iterator Simplex_handle
Handle type to a simplex contained in the simplicial complex represented by the simplex tree...
Definition: Simplex_tree.h:164
void expansion(int max_dim)
Expands the Simplex_tree containing only its one skeleton until dimension max_dim.
Definition: Simplex_tree.h:1002
Filtration_simplex_range::const_iterator Filtration_simplex_iterator
Iterator over the simplices of the simplicial complex, ordered by the filtration. ...
Definition: Simplex_tree.h:224
Simplex Tree data structure for representing simplicial complexes.
Definition: Simplex_tree.h:103
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:658
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:729
bool operator==(Simplex_tree &st2)
Checks if two simplex trees are equal.
Definition: Simplex_tree.h:388
Concept describing an indexing scheme (see FilteredComplex) for applying continuous maps to a cell co...
Definition: IndexingTag.h:30
static Simplex_key key(Simplex_handle sh)
Returns the key associated to a simplex.
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:461
boost::iterator_range< Complex_vertex_iterator > Complex_vertex_range
Range over the vertices of the simplicial complex.
Definition: Simplex_tree.h:190
Simplex_tree_simplex_vertex_iterator< Simplex_tree > Simplex_vertex_iterator
Iterator over the vertices of a simplex.
Definition: Simplex_tree.h:194
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:473
void print_hasse(std::ostream &os)
Write the hasse diagram of the simplicial complex in os.
Definition: Simplex_tree.h:1084
Key type used as simplex identifier.
Definition: SimplexKey.h:27
Siblings * root()
Definition: Simplex_tree.h:752
bool has_children(Simplex_handle sh) const
Returns true iff the node in the simplex tree pointed by sh has children.
Definition: Simplex_tree.h:523
Simplex_tree(Simplex_tree &&old)
User-defined move constructor moves the whole tree structure.
Definition: Simplex_tree.h:355
unspecified Indexing_tag
Specifies the nature of the indexing scheme.
Definition: FilteredComplex.h:44
Filtration_value filtration() const
Returns an upper bound of the filtration values of the simplices.
Definition: Simplex_tree.h:453
Options::Simplex_key Simplex_key
Key associated to each simplex.
Definition: Simplex_tree.h:114
bool operator!=(Simplex_tree &st2)
Checks if two simplex trees are different.
Definition: Simplex_tree.h:397
std::vector< Simplex_handle > Filtration_simplex_range
Range over the simplices of the simplicial complex, ordered by the filtration.
Definition: Simplex_tree.h:220
Boundary_simplex_range boundary_simplex_range(Simplex_handle sh)
Returns a range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:310
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:277
void initialize_filtration()
Initializes the filtrations, i.e. sort the simplices according to their order in the filtration and i...
Definition: Simplex_tree.h:776
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:535
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:32
unspecified Boundary_simplex_range
Range giving access to the simplices in the boundary of a simplex.
Definition: FilteredComplex.h:85
Cofaces_simplex_range cofaces_simplex_range(const Simplex_handle simplex, int codimension)
Compute the cofaces of a n simplex.
Definition: Simplex_tree.h:865
Complex_simplex_range complex_simplex_range()
Returns a range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:243
Filtration_simplex_range filtration_simplex_range()
Returns a range over the simplices of the complex in the order of the filtration. ...
Concept of the template parameter for the class Gudhi::Simplex_tree<SimplexTreeOptions>.
Definition: SimplexTreeOptions.h:27
std::pair< Simplex_handle, Simplex_handle > endpoints(Simplex_handle sh)
Definition: Simplex_tree.h:737
int dimension() const
Returns an upper bound on the dimension of the simplicial complex.
Definition: Simplex_tree.h:517
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:232
Simplex_vertex_range simplex_vertex_range(Simplex_handle sh)
Returns a range over the vertices of a simplex.
Definition: Simplex_tree.h:290
Options::Vertex_handle Vertex_handle
Type for the vertex handle.
Definition: Simplex_tree.h:118
unspecified Filtration_simplex_range
Range over the simplices of the complex in the order of the filtration.
Definition: FilteredComplex.h:110
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:257
boost::iterator_range< Boundary_simplex_iterator > Boundary_simplex_range
Range over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:204
void set_filtration(Filtration_value fil)
Definition: Simplex_tree.h:757
Cofaces_simplex_range star_simplex_range(const Simplex_handle simplex)
Compute the star of a n simplex.
Definition: Simplex_tree.h:854
void set_dimension(int dimension)
Definition: Simplex_tree.h:762
Abstract simplex used in Skeleton blockers data-structure.
Definition: Skeleton_blocker_simplex.h:50
Siblings * self_siblings(Simplex_handle sh)
Definition: Simplex_tree.h:743
Simplex_handle simplex(Simplex_key key) const
Returns the simplex associated to a key.
Definition: Simplex_tree.h:435
int dimension(Simplex_handle sh)
Returns the dimension of a simplex.
Definition: Simplex_tree.h:506
static Simplex_key null_key()
Returns a key different for all keys associated to the simplices of the simplicial complex...
Definition: Simplex_tree.h:467
static Filtration_value filtration(Simplex_handle sh)
Returns the filtration value of a simplex.
Definition: Simplex_tree.h:444
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:27
boost::transform_iterator< return_first, Dictionary_it > Complex_vertex_iterator
Iterator over the vertices of the simplicial complex.
Definition: Simplex_tree.h:188
~Simplex_tree()
Destructor; deallocates the whole tree structure.
Definition: Simplex_tree.h:367
size_t num_vertices() const
Returns the number of vertices in the complex.
Definition: Simplex_tree.h:478
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:39
size_t num_simplices()
returns the number of simplices in the simplex_tree.
Definition: Simplex_tree.h:484
boost::iterator_range< Complex_simplex_iterator > Complex_simplex_range
Range over the simplices of the simplicial complex.
Definition: Simplex_tree.h:210
Options::Filtration_value Filtration_value
Type for the value of the filtration function.
Definition: Simplex_tree.h:110
Simplex_tree()
Constructs an empty simplex tree.
Definition: Simplex_tree.h:320
Simplex_tree_boundary_simplex_iterator< Simplex_tree > Boundary_simplex_iterator
Iterator over the simplices of the boundary of a simplex.
Definition: Simplex_tree.h:202
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:218
Simplex_tree_complex_simplex_iterator< Simplex_tree > Complex_simplex_iterator
Iterator over the simplices of the simplicial complex.
Definition: Simplex_tree.h:208
void insert_graph(const OneSkeletonGraph &skel_graph)
Inserts a 1-skeleton in an empty Simplex_tree.
Definition: Simplex_tree.h:947
unspecified Filtration_value
Type for the value of the filtration function.
Definition: FilteredComplex.h:39
Simplex_tree(const Simplex_tree &simplex_source)
User-defined copy constructor reproduces the whole tree structure.
Definition: Simplex_tree.h:328
boost::iterator_range< Simplex_vertex_iterator > Simplex_vertex_range
Range over the vertices of a simplex.
Definition: Simplex_tree.h:196
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:629
void rec_copy(Siblings *sib, Siblings *sib_source)
depth first search, inserts simplices when reaching a leaf.
Definition: Simplex_tree.h:340
std::vector< Simplex_handle > Cofaces_simplex_range
Range over the cofaces of a simplex.
Definition: Simplex_tree.h:198