summaryrefslogtreecommitdiff
path: root/src/Simplex_tree/include/gudhi/Simplex_tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Simplex_tree/include/gudhi/Simplex_tree.h')
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree.h137
1 files changed, 59 insertions, 78 deletions
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h
index 95a6d090..247630cc 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h
@@ -38,7 +38,6 @@
#include <functional> // for greater<>
namespace Gudhi {
-
/** \defgroup simplex_tree Filtered Complexes
*
* A simplicial complex \f$\mathbf{K}\f$
@@ -73,7 +72,6 @@ namespace Gudhi {
* \copyright GNU General Public License v3.
* @{
*/
-
/**
* \brief Simplex Tree data structure for representing simplicial complexes.
*
@@ -190,12 +188,12 @@ class Simplex_tree {
/** \name Range and iterator methods
* @{ */
- /** \brief Returns a range over the vertices of the simplicial complex.
+ /** \brief Returns a range over the vertices of the simplicial complex.
* The order is increasing according to < on Vertex_handles.*/
Complex_vertex_range complex_vertex_range() {
return Complex_vertex_range(
- boost::make_transform_iterator(root_.members_.begin(), return_first()),
- boost::make_transform_iterator(root_.members_.end(), return_first()));
+ boost::make_transform_iterator(root_.members_.begin(), return_first()),
+ boost::make_transform_iterator(root_.members_.end(), return_first()));
}
/** \brief Returns a range over the simplices of the simplicial complex.
@@ -286,11 +284,12 @@ class Simplex_tree {
/** \brief Constructs an empty simplex tree. */
Simplex_tree()
: null_vertex_(-1),
- threshold_(0),
- num_simplices_(0),
- root_(NULL, null_vertex_),
- filtration_vect_(),
- dimension_(-1) { }
+ threshold_(0),
+ num_simplices_(0),
+ root_(NULL, null_vertex_),
+ filtration_vect_(),
+ dimension_(-1) {
+ }
/** \brief Destructor; deallocates the whole tree structure. */
~Simplex_tree() {
@@ -316,21 +315,21 @@ class Simplex_tree {
/** \brief Returns the key associated to a simplex.
*
* The filtration must be initialized. */
- Simplex_key key(Simplex_handle sh) {
+ static Simplex_key key(Simplex_handle sh) {
return sh->second.key();
}
/** \brief Returns the simplex associated to a key.
*
* The filtration must be initialized. */
- Simplex_handle simplex(Simplex_key key) {
+ Simplex_handle simplex(Simplex_key key) const {
return filtration_vect_[key];
}
/** \brief Returns the filtration value of a simplex.
*
* Called on the null_simplex, returns INFINITY. */
- Filtration_value filtration(Simplex_handle sh) const {
+ static Filtration_value filtration(Simplex_handle sh) {
if (sh != null_simplex()) {
return sh->second.filtration();
} else {
@@ -338,6 +337,15 @@ class Simplex_tree {
}
}
+ /** \brief Sets the filtration value of a simplex.
+ *
+ * No action if called on the null_simplex*/
+ void assign_filtration(Simplex_handle sh, Filtration_value fv) {
+ if (sh != null_simplex()) {
+ sh->second.assign_filtration(fv);
+ }
+ }
+
/** \brief Returns an upper bound of the filtration values of the simplices. */
Filtration_value filtration() const {
return threshold_;
@@ -347,13 +355,13 @@ class Simplex_tree {
* associated to the simplices in the simplicial complex.
*
* One can call filtration(null_simplex()). */
- Simplex_handle null_simplex() const {
+ static Simplex_handle null_simplex() {
return Dictionary_it(NULL);
}
/** \brief Returns a key different for all keys associated to the
* simplices of the simplicial complex. */
- Simplex_key null_key() const {
+ static Simplex_key null_key() {
return -1;
}
@@ -399,7 +407,6 @@ class Simplex_tree {
return (sh->second.children()->parent() == sh->first);
}
- public:
/** \brief Given a range of Vertex_handles, returns the Simplex_handle
* of the simplex in the simplicial complex containing the corresponding
* vertices. Return null_simplex() if the simplex is not in the complex.
@@ -436,7 +443,6 @@ class Simplex_tree {
Simplex_handle find_vertex(Vertex_handle v) {
return root_.members_.begin() + v;
}
- //{ return root_.members_.find(v); }
/** \brief Insert a simplex, represented by a range of Vertex_handles, in the simplicial complex.
*
@@ -463,7 +469,7 @@ class Simplex_tree {
* .end() return random access iterators, with 'value_type' Vertex_handle. */
template<class RandomAccessVertexRange>
std::pair<Simplex_handle, bool> insert_simplex(RandomAccessVertexRange & simplex,
- Filtration_value filtration) {
+ Filtration_value filtration) {
if (simplex.empty()) {
return std::pair<Simplex_handle, bool>(null_simplex(), true);
}
@@ -500,10 +506,11 @@ class Simplex_tree {
*
* @param[in] Nsimplex range of Vertex_handles, representing the vertices of the new N-simplex
* @param[in] filtration the filtration value assigned to the new N-simplex.
- */
+ */
template<class RandomAccessVertexRange>
- void insert_simplex_and_subfaces(RandomAccessVertexRange& Nsimplex,
- Filtration_value filtration = 0.0) {
+ std::pair<Simplex_handle, bool> insert_simplex_and_subfaces(RandomAccessVertexRange& Nsimplex,
+ Filtration_value filtration = 0.0) {
+ std::pair<Simplex_handle, bool> returned;
if (Nsimplex.size() > 1) {
for (unsigned int NIndex = 0; NIndex < Nsimplex.size(); NIndex++) {
// insert N (N-1)-Simplex
@@ -513,22 +520,23 @@ class Simplex_tree {
NsimplexMinusOne.push_back(Nsimplex[(NIndex + NListIter) % Nsimplex.size()]);
}
// (N-1)-Simplex recursive call
- insert_simplex_and_subfaces(NsimplexMinusOne, filtration);
+ returned = insert_simplex_and_subfaces(NsimplexMinusOne, filtration);
}
// N-Simplex insert
- std::pair<Simplex_handle, bool> returned = insert_simplex(Nsimplex, filtration);
+ returned = insert_simplex(Nsimplex, filtration);
if (returned.second == true) {
num_simplices_++;
}
} else if (Nsimplex.size() == 1) {
// 1-Simplex insert - End of recursivity
- std::pair<Simplex_handle, bool> returned = insert_simplex(Nsimplex, filtration);
+ returned = insert_simplex(Nsimplex, filtration);
if (returned.second == true) {
num_simplices_++;
}
} else {
// Nothing to insert - empty vector
}
+ return returned;
}
/** \brief Assign a value 'key' to the key of the simplex
@@ -543,8 +551,8 @@ class Simplex_tree {
* optimized version of the boundary computation. */
std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
return std::pair<Simplex_handle, Simplex_handle>(
- root_.members_.find(sh->first),
- root_.members_.find(self_siblings(sh)->parent()));
+ root_.members_.find(sh->first),
+ root_.members_.find(self_siblings(sh)->parent()));
}
/** Returns the Siblings containing a simplex.*/
@@ -555,23 +563,13 @@ class Simplex_tree {
return sh->second.children();
}
- // void display_simplex(Simplex_handle sh)
- // {
- // std::cout << " " << "[" << filtration(sh) << "] ";
- // for( auto vertex : simplex_vertex_range(sh) )
- // { std::cout << vertex << " "; }
- // }
-
- // void print(Simplex_handle sh, std::ostream& os = std::cout)
- // { for(auto v : simplex_vertex_range(sh)) {os << v << " ";}
- // os << std::endl; }
-
public:
/** Returns a pointer to the root nodes of the simplex tree. */
Siblings * root() {
return &root_;
}
+ public:
/** Set an upper bound for the filtration values. */
void set_filtration(Filtration_value fil) {
threshold_ = fil;
@@ -606,10 +604,8 @@ class Simplex_tree {
void initialize_filtration() {
filtration_vect_.clear();
filtration_vect_.reserve(num_simplices());
- for (auto cpx_it = complex_simplex_range().begin();
- cpx_it != complex_simplex_range().end(); ++cpx_it) {
- filtration_vect_.push_back(*cpx_it);
- }
+ for (Simplex_handle sh : complex_simplex_range())
+ filtration_vect_.push_back(sh);
// the stable sort ensures the ordering heuristic
std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(),
@@ -787,15 +783,15 @@ class Simplex_tree {
typename boost::graph_traits<OneSkeletonGraph>::vertex_iterator v_it,
v_it_end;
for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end;
- ++v_it) {
+ ++v_it) {
root_.members_.emplace_hint(
- root_.members_.end(), *v_it,
- Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it)));
+ root_.members_.end(), *v_it,
+ Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it)));
}
typename boost::graph_traits<OneSkeletonGraph>::edge_iterator e_it,
e_it_end;
for (std::tie(e_it, e_it_end) = boost::edges(skel_graph); e_it != e_it_end;
- ++e_it) {
+ ++e_it) {
auto u = source(*e_it, skel_graph);
auto v = target(*e_it, skel_graph);
if (u < v) {
@@ -806,9 +802,9 @@ class Simplex_tree {
}
sh->second.children()->members().emplace(
- v,
- Node(sh->second.children(),
- boost::get(edge_filtration_t(), skel_graph, *e_it)));
+ v,
+ Node(sh->second.children(),
+ boost::get(edge_filtration_t(), skel_graph, *e_it)));
}
}
}
@@ -827,7 +823,7 @@ class Simplex_tree {
void expansion(int max_dim) {
dimension_ = max_dim;
for (Dictionary_it root_it = root_.members_.begin();
- root_it != root_.members_.end(); ++root_it) {
+ root_it != root_.members_.end(); ++root_it) {
if (has_children(root_it)) {
siblings_expansion(root_it->second.children(), max_dim - 1);
}
@@ -836,9 +832,10 @@ class Simplex_tree {
}
private:
+
/** \brief Recursive expansion of the simplex tree.*/
void siblings_expansion(Siblings * siblings, // must contain elements
- int k) {
+ int k) {
if (dimension_ > k) {
dimension_ = k;
}
@@ -862,8 +859,8 @@ class Simplex_tree {
if (inter.size() != 0) {
this->num_simplices_ += inter.size();
Siblings * new_sib = new Siblings(siblings, // oncles
- s_h->first, // parent
- inter); // boost::container::ordered_unique_range_t
+ s_h->first, // parent
+ inter); // boost::container::ordered_unique_range_t
inter.clear();
s_h->second.assign_children(new_sib);
siblings_expansion(new_sib, k - 1);
@@ -881,40 +878,25 @@ class Simplex_tree {
static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
Dictionary_it begin1, Dictionary_it end1,
Dictionary_it begin2, Dictionary_it end2,
- Filtration_value filtration) {
+ Filtration_value filtration_) {
if (begin1 == end1 || begin2 == end2)
return; // ----->>
while (true) {
if (begin1->first == begin2->first) {
- intersection.push_back(std::pair<Vertex_handle, Node>(begin1->first,
- Node(NULL,
- maximum(begin1->second.filtration(),
- begin2->second.filtration(), filtration))));
- ++begin1;
- ++begin2;
- if (begin1 == end1 || begin2 == end2)
+ Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
+ intersection.emplace_back(begin1->first, Node(NULL, filt));
+ if (++begin1 == end1 || ++begin2 == end2)
+ return; // ----->>
+ } else if (begin1->first < begin2->first) {
+ if (++begin1 == end1)
+ return;
+ } else /* begin1->first > begin2->first */ {
+ if (++begin2 == end2)
return; // ----->>
- } else {
- if (begin1->first < begin2->first) {
- ++begin1;
- if (begin1 == end1)
- return;
- } else {
- ++begin2;
- if (begin2 == end2)
- return; // ----->>
- }
}
}
}
- /** Maximum over 3 values.*/
- static Filtration_value maximum(Filtration_value a, Filtration_value b,
- Filtration_value c) {
- Filtration_value max = (a < b) ? b : a;
- return ((max < c) ? c : max);
- }
-
public:
/** \brief Write the hasse diagram of the simplicial complex in os.
*
@@ -948,7 +930,6 @@ class Simplex_tree {
};
// Print a Simplex_tree in os.
-
template<typename T1, typename T2, typename T3>
std::ostream& operator<<(std::ostream & os, Simplex_tree<T1, T2, T3> & st) {
for (auto sh : st.filtration_simplex_range()) {