summaryrefslogtreecommitdiff
path: root/src/Persistent_cohomology
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-05-24 15:17:14 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-05-24 15:17:14 +0000
commit6dae848dd4672fae2c9a6b5ae9059b44855e26a3 (patch)
tree3d5783eb979ef75703005c44de24e78dacbb09f9 /src/Persistent_cohomology
parentb16152118574b9f2127df3b7f4495f75f3b079c1 (diff)
get_persistence and Betti numbers
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/get_persistence@1190 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6da18e680111a9a1ad7753779a94a1e8ce49702c
Diffstat (limited to 'src/Persistent_cohomology')
-rw-r--r--src/Persistent_cohomology/example/plain_homology.cpp51
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h67
2 files changed, 104 insertions, 14 deletions
diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp
index 0a692717..9e5adb5d 100644
--- a/src/Persistent_cohomology/example/plain_homology.cpp
+++ b/src/Persistent_cohomology/example/plain_homology.cpp
@@ -24,6 +24,7 @@
#include <gudhi/Persistent_cohomology.h>
#include <iostream>
+#include <vector>
using namespace Gudhi;
@@ -41,6 +42,24 @@ struct MyOptions : Simplex_tree_options_full_featured {
};
typedef Simplex_tree<MyOptions> ST;
+ /*
+ * Compare two intervals by dimension, then by length.
+ */
+ struct cmp_intervals_by_dim_then_length {
+ explicit cmp_intervals_by_dim_then_length(ST * sc)
+ : sc_(sc) {
+ }
+ template<typename Persistent_interval>
+ bool operator()(const Persistent_interval & p1, const Persistent_interval & p2) {
+ if (sc_->dimension(get < 0 > (p1)) == sc_->dimension(get < 0 > (p2)))
+ return (sc_->filtration(get < 1 > (p1)) - sc_->filtration(get < 0 > (p1))
+ > sc_->filtration(get < 1 > (p2)) - sc_->filtration(get < 0 > (p2)));
+ else
+ return (sc_->dimension(get < 0 > (p1)) > sc_->dimension(get < 0 > (p2)));
+ }
+ ST* sc_;
+ };
+
int main() {
ST st;
@@ -81,4 +100,36 @@ int main() {
// 2 1 0 inf
// means that in Z/2Z-homology, the Betti numbers are b0=2 and b1=1.
pcoh.output_diagram();
+
+
+ // ********************************************************
+ // get_persistence
+ // ********************************************************
+ std::cout << std::endl;
+ std::cout << std::endl;
+
+ // First version
+ std::vector<int> betti_numbers = pcoh.betti_numbers();
+ std::cout << "The Betti numbers are : ";
+ for (std::size_t i = 0; i < betti_numbers.size(); i++)
+ std::cout << "b" << i << " = " << betti_numbers[i] << " ; ";
+ std::cout << std::endl;
+
+ // Second version
+ std::cout << "The Betti numbers are : ";
+ for (int i = 0; i < st.dimension(); i++)
+ std::cout << "b" << i << " = " << pcoh.betti_number(i) << " ; ";
+ std::cout << std::endl;
+
+ // Get persistence
+ cmp_intervals_by_dim_then_length cmp(&st);
+ auto persistent_pairs = pcoh.get_persistent_pairs();
+ std::sort(std::begin(persistent_pairs), std::end(persistent_pairs), cmp);
+ for (auto pair : persistent_pairs) {
+ std::cout << st.dimension(get<0>(pair)) << " "
+ << st.filtration(get<0>(pair)) << " "
+ << st.filtration(get<1>(pair)) << std::endl;
+ }
+
+
}
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
index cd1bd438..9fc3bf2e 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
@@ -83,7 +83,7 @@ class Persistent_cohomology {
// Sparse column type for the annotation of the boundary of an element.
typedef std::vector<std::pair<Simplex_key, Arith_element> > A_ds_type;
// Persistent interval type. The Arith_element field is used for the multi-field framework.
- typedef std::tuple<Simplex_handle, Simplex_handle, Arith_element> Persistent_interval;
+ typedef std::tuple<Simplex_handle, Simplex_handle/*, Arith_element*/> Persistent_interval;
/** \brief Initializes the Persistent_cohomology class.
*
@@ -199,17 +199,17 @@ class Persistent_cohomology {
if (ds_parent_[key] == key // root of its tree
&& zero_cocycles_.find(key) == zero_cocycles_.end()) {
persistent_pairs_.emplace_back(
- cpx_->simplex(key), cpx_->null_simplex(), coeff_field_.characteristic());
+ cpx_->simplex(key), cpx_->null_simplex()/*, coeff_field_.characteristic()*/);
}
}
for (auto zero_idx : zero_cocycles_) {
persistent_pairs_.emplace_back(
- cpx_->simplex(zero_idx.second), cpx_->null_simplex(), coeff_field_.characteristic());
+ cpx_->simplex(zero_idx.second), cpx_->null_simplex()/*, coeff_field_.characteristic()*/);
}
// Compute infinite interval of dimension > 0
for (auto cocycle : transverse_idx_) {
persistent_pairs_.emplace_back(
- cpx_->simplex(cocycle.first), cpx_->null_simplex(), cocycle.second.characteristics_);
+ cpx_->simplex(cocycle.first), cpx_->null_simplex()/*, cocycle.second.characteristics_*/);
}
}
@@ -250,7 +250,7 @@ class Persistent_cohomology {
< cpx_->filtration(cpx_->simplex(idx_coc_v))) { // Kill cocycle [idx_coc_v], which is younger.
if (interval_length_policy(cpx_->simplex(idx_coc_v), sigma)) {
persistent_pairs_.emplace_back(
- cpx_->simplex(idx_coc_v), sigma, coeff_field_.characteristic());
+ cpx_->simplex(idx_coc_v), sigma/*, coeff_field_.characteristic()*/);
}
// Maintain the index of the 0-cocycle alive.
if (kv != idx_coc_v) {
@@ -265,7 +265,7 @@ class Persistent_cohomology {
} else { // Kill cocycle [idx_coc_u], which is younger.
if (interval_length_policy(cpx_->simplex(idx_coc_u), sigma)) {
persistent_pairs_.emplace_back(
- cpx_->simplex(idx_coc_u), sigma, coeff_field_.characteristic());
+ cpx_->simplex(idx_coc_u), sigma/*, coeff_field_.characteristic()*/);
}
// Maintain the index of the 0-cocycle alive.
if (ku != idx_coc_u) {
@@ -308,14 +308,14 @@ class Persistent_cohomology {
// Find its annotation vector
curr_col = ds_repr_[dsets_.find_set(key)];
if (curr_col != NULL) { // and insert it in annotations_in_boundary with multyiplicative factor "sign".
- annotations_in_boundary.emplace_back(curr_col, sign);
+ annotations_in_boundary.emplace_back(curr_col, sign);
}
}
sign = -sign;
}
// Place identical annotations consecutively so we can easily sum their multiplicities.
std::sort(annotations_in_boundary.begin(), annotations_in_boundary.end(),
- [](annotation_t const& a, annotation_t const& b) { return a.first < b.first; });
+ [](annotation_t const& a, annotation_t const& b) { return a.first < b.first; });
// Sum the annotations with multiplicity, using a map<key,coeff>
// to represent a sparse vector.
@@ -325,7 +325,7 @@ class Persistent_cohomology {
Column* col = ann_it->first;
int mult = ann_it->second;
while (++ann_it != annotations_in_boundary.end() && ann_it->first == col) {
- mult += ann_it->second;
+ mult += ann_it->second;
}
// The following test is just a heuristic, it is not required, and it is fine that is misses p == 0.
if (mult != coeff_field_.additive_identity()) { // For all columns in the boundary,
@@ -427,7 +427,7 @@ class Persistent_cohomology {
if (interval_length_policy(cpx_->simplex(death_key), sigma)) {
persistent_pairs_.emplace_back(cpx_->simplex(death_key) // creator
, sigma // destructor
- , charac); // fields
+ /*, charac*/); // fields
}
auto death_key_row = transverse_idx_.find(death_key); // Find the beginning of the row.
@@ -566,17 +566,16 @@ class Persistent_cohomology {
* feature exists in homology with Z/piZ coefficients.
*/
void output_diagram(std::ostream& ostream = std::cout) {
-
cmp_intervals_by_length cmp(cpx_);
std::sort(std::begin(persistent_pairs_), std::end(persistent_pairs_), cmp);
bool has_infinity = std::numeric_limits<Filtration_value>::has_infinity;
for (auto pair : persistent_pairs_) {
// Special case on windows, inf is "1.#INF" (cf. unitary tests and R package TDA)
if (has_infinity && cpx_->filtration(get<1>(pair)) == std::numeric_limits<Filtration_value>::infinity()) {
- ostream << get<2>(pair) << " " << cpx_->dimension(get<0>(pair)) << " "
+ ostream << /*get<2>(pair) <<*/ " " << cpx_->dimension(get<0>(pair)) << " "
<< cpx_->filtration(get<0>(pair)) << " inf " << std::endl;
} else {
- ostream << get<2>(pair) << " " << cpx_->dimension(get<0>(pair)) << " "
+ ostream << /*get<2>(pair) <<*/ " " << cpx_->dimension(get<0>(pair)) << " "
<< cpx_->filtration(get<0>(pair)) << " "
<< cpx_->filtration(get<1>(pair)) << " " << std::endl;
}
@@ -594,12 +593,52 @@ class Persistent_cohomology {
}
}
+ /** @brief Returns Betti numbers.
+ *
+ */
+ const std::vector<int> betti_numbers() const {
+ // Init Betti numbers vector with zeros until Simplicial complex dimension
+ std::vector<int> betti_numbers(cpx_->dimension(), 0);
+
+ for (auto pair : persistent_pairs_) {
+ // Increment corresponding betti number
+ betti_numbers[cpx_->dimension(get<0>(pair))] += 1;
+ }
+ return betti_numbers;
+ }
+
+ /** @brief Returns the Betti number passed by parameter.
+ * @param[in] dimension The Betti number dimension to get.
+ * @return Betti number
+ *
+ */
+ const int betti_number(int dimension) const {
+ int betti_number = 0;
+
+ for (auto pair : persistent_pairs_) {
+ if (cpx_->dimension(get<0>(pair)) == dimension)
+ // Increment betti number found
+ ++betti_number;
+ }
+ return betti_number;
+ }
+
+ /** @brief Returns the persistent pairs.
+ * @return Persistent pairs
+ *
+ */
+ std::vector<Persistent_interval> get_persistent_pairs() const {
+ return persistent_pairs_;
+ }
+
private:
/*
* Structure representing a cocycle.
*/
struct cocycle {
- cocycle() {
+ cocycle()
+ : row_(nullptr),
+ characteristics_() {
}
cocycle(Arith_element characteristics, Hcell * row)
: row_(row),