summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2018-04-03 21:20:42 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2018-04-03 21:20:42 +0000
commit1e55ed3f7ce467f598c66e18e6a7337476961588 (patch)
tree28abf10fee50e222c821eecde93878571a577198
parent9a60bbaf5b0895ccc24a545aafe5190b2d108126 (diff)
parentc06596e61c92f54a01756e1ba1babaff800f0f02 (diff)
Merge last trunk modifications
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-glisse@3335 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 41b78dbadb13e3eca889479c1112814b2b58f679
-rw-r--r--data/correlation_matrix/lower_triangular_correlation_matrix.csv6
-rw-r--r--data/points/Kl.off4
-rw-r--r--src/Alpha_complex/include/gudhi/Alpha_complex.h4
-rw-r--r--src/Alpha_complex/utilities/alphacomplex.md10
-rw-r--r--src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h2
-rw-r--r--src/Bitmap_cubical_complex/utilities/cubicalcomplex.md10
-rw-r--r--src/Bottleneck_distance/utilities/bottleneckdistance.md10
-rw-r--r--src/GudhUI/model/Model.h2
-rw-r--r--src/GudhUI/utils/Critical_points.h2
-rw-r--r--src/GudhUI/utils/K_nearest_builder.h2
-rw-r--r--src/GudhUI/utils/Rips_builder.h2
-rw-r--r--src/Nerve_GIC/example/CMakeLists.txt3
-rw-r--r--src/Nerve_GIC/include/gudhi/GIC.h254
-rw-r--r--src/Nerve_GIC/test/test_GIC.cpp3
-rw-r--r--src/Nerve_GIC/utilities/CMakeLists.txt4
-rw-r--r--src/Nerve_GIC/utilities/covercomplex.md10
-rw-r--r--src/Persistence_representations/example/CMakeLists.txt8
-rw-r--r--src/Persistence_representations/utilities/CMakeLists.txt6
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt6
-rw-r--r--src/Persistent_cohomology/concept/FilteredComplex.h6
-rw-r--r--src/Persistent_cohomology/doc/Intro_persistent_cohomology.h13
-rw-r--r--src/Rips_complex/doc/Intro_rips_complex.h27
-rw-r--r--src/Rips_complex/example/CMakeLists.txt7
-rw-r--r--src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp81
-rw-r--r--src/Rips_complex/example/one_skeleton_rips_from_correlation_matrix_for_doc.txt17
-rw-r--r--src/Rips_complex/utilities/CMakeLists.txt7
-rw-r--r--src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp170
-rw-r--r--src/Rips_complex/utilities/ripscomplex.md40
-rw-r--r--src/Witness_complex/utilities/witnesscomplex.md10
-rw-r--r--src/common/doc/header.html6
-rw-r--r--src/common/doc/offline_header.html41
-rw-r--r--src/common/example/CMakeLists.txt11
-rw-r--r--src/common/example/example_CGAL_3D_points_off_reader.cpp6
-rw-r--r--src/common/example/example_CGAL_points_off_reader.cpp6
-rw-r--r--src/common/example/example_vector_double_points_off_reader.cpp14
-rw-r--r--src/common/example/vectordoubleoffreader_result.txt (renamed from src/common/example/cgaloffreader_result.txt)0
-rw-r--r--src/common/include/gudhi/Off_reader.h29
-rw-r--r--src/common/include/gudhi/Points_off_io.h4
-rw-r--r--src/common/include/gudhi/writing_persistence_to_file.h117
-rw-r--r--src/common/utilities/pointsetgenerator.md16
-rw-r--r--src/cython/cython/off_reader.pyx1
-rw-r--r--src/cython/cython/rips_complex.pyx35
-rw-r--r--src/cython/doc/_templates/layout.html4
-rw-r--r--src/cython/doc/persistence_graphical_tools_user.rst8
-rwxr-xr-xsrc/cython/doc/pyplots/diagram_persistence.py5
-rw-r--r--src/cython/doc/rips_complex_user.rst80
-rwxr-xr-xsrc/cython/example/alpha_rips_persistence_bottleneck_distance.py5
-rwxr-xr-xsrc/cython/example/bottleneck_basic_example.py2
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py84
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py7
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_off_file_example.py3
-rw-r--r--src/cython/include/Rips_complex_interface.h17
52 files changed, 1007 insertions, 220 deletions
diff --git a/data/correlation_matrix/lower_triangular_correlation_matrix.csv b/data/correlation_matrix/lower_triangular_correlation_matrix.csv
new file mode 100644
index 00000000..99ad0b5d
--- /dev/null
+++ b/data/correlation_matrix/lower_triangular_correlation_matrix.csv
@@ -0,0 +1,6 @@
+
+0.4090538938
+0.2182708406;0.5664245836
+0.9109757412;0.5234453492;0.4239008464
+0.2426856242;0.7178816327;0.4748826202;0.8254894051
+0.0908790566;0.9369574252;0.9760741671;0.5256838992;0.0653515265
diff --git a/data/points/Kl.off b/data/points/Kl.off
index 911bcd23..8930a321 100644
--- a/data/points/Kl.off
+++ b/data/points/Kl.off
@@ -1,5 +1,5 @@
-OFF
-10000 0 0
+nOFF
+5 10000 0 0
0.5 0 0 0 1
0.562791 0 0.125333 0 0.998027
0.625333 0 0.24869 0 0.992115
diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h
index 63c6675c..91305032 100644
--- a/src/Alpha_complex/include/gudhi/Alpha_complex.h
+++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h
@@ -34,6 +34,7 @@
#include <CGAL/Epick_d.h>
#include <CGAL/Spatial_sort_traits_adapter_d.h>
#include <CGAL/property_map.h> // for CGAL::Identity_property_map
+#include <CGAL/NT_converter.h>
#include <iostream>
#include <vector>
@@ -323,8 +324,9 @@ class Alpha_complex {
if (f_simplex_dim > 0) {
// squared_radius function initialization
Squared_Radius squared_radius = kernel_.compute_squared_radius_d_object();
+ CGAL::NT_converter<typename Geom_traits::FT, Filtration_value> cv;
- alpha_complex_filtration = squared_radius(pointVector.begin(), pointVector.end());
+ alpha_complex_filtration = cv(squared_radius(pointVector.begin(), pointVector.end()));
}
complex.assign_filtration(f_simplex, alpha_complex_filtration);
#ifdef DEBUG_TRACES
diff --git a/src/Alpha_complex/utilities/alphacomplex.md b/src/Alpha_complex/utilities/alphacomplex.md
index aace85d3..ede749a9 100644
--- a/src/Alpha_complex/utilities/alphacomplex.md
+++ b/src/Alpha_complex/utilities/alphacomplex.md
@@ -1,3 +1,13 @@
+---
+layout: page
+title: "Alpha complex"
+meta_title: "Alpha complex"
+teaser: ""
+permalink: /alphacomplex/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
# Alpha complex #
diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h
index 969daba6..770eb55f 100644
--- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h
+++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h
@@ -383,7 +383,7 @@ class Bitmap_cubical_complex : public T {
std::vector<std::size_t> bdry = this->get_boundary_of_a_cell(sh);
if (globalDbg) {
std::cerr << "std::pair<Simplex_handle, Simplex_handle> endpoints( Simplex_handle sh )\n";
- std::cerr << "bdry.size() : " << bdry.size() << std::endl;
+ std::cerr << "bdry.size() : " << bdry.size() << "\n";
}
// this method returns two first elements from the boundary of sh.
if (bdry.size() < 2)
diff --git a/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md b/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md
index 6e1b2578..a1bb9007 100644
--- a/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md
+++ b/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md
@@ -1,3 +1,13 @@
+---
+layout: page
+title: "Cubical complex"
+meta_title: "Cubical complex"
+teaser: ""
+permalink: /cubicalcomplex/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
# Cubical complex#
diff --git a/src/Bottleneck_distance/utilities/bottleneckdistance.md b/src/Bottleneck_distance/utilities/bottleneckdistance.md
index 526f5822..f2749acc 100644
--- a/src/Bottleneck_distance/utilities/bottleneckdistance.md
+++ b/src/Bottleneck_distance/utilities/bottleneckdistance.md
@@ -1,3 +1,13 @@
+---
+layout: page
+title: "Bottleneck distance"
+meta_title: "Bottleneck distance"
+teaser: ""
+permalink: /bottleneckdistance/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
# Bottleneck distance #
diff --git a/src/GudhUI/model/Model.h b/src/GudhUI/model/Model.h
index fc284cc6..072d1185 100644
--- a/src/GudhUI/model/Model.h
+++ b/src/GudhUI/model/Model.h
@@ -74,7 +74,7 @@ class CGAL_geometric_flag_complex_wrapper {
// std::cout << "size:" << vertices.size() << std::endl;
for (std::size_t i = 0; i < vertices.size(); ++i)
for (std::size_t j = i + 1; j < vertices.size(); ++j)
- complex_.add_edge(Vertex_handle(vertices[i]), Vertex_handle(vertices[j]));
+ complex_.add_edge_without_blockers(Vertex_handle(vertices[i]), Vertex_handle(vertices[j]));
}
}
diff --git a/src/GudhUI/utils/Critical_points.h b/src/GudhUI/utils/Critical_points.h
index 2a18e079..e7b9ef31 100644
--- a/src/GudhUI/utils/Critical_points.h
+++ b/src/GudhUI/utils/Critical_points.h
@@ -79,7 +79,7 @@ template<typename SkBlComplex> class Critical_points {
unsigned pos = 0;
for (Edge e : edges) {
std::cout << "edge " << pos++ << "/" << edges.size() << "\n";
- auto eh = filled_complex_.add_edge(e.first, e.second);
+ auto eh = filled_complex_.add_edge_without_blockers(e.first, e.second);
int is_contractible(is_link_reducible(eh));
switch (is_contractible) {
diff --git a/src/GudhUI/utils/K_nearest_builder.h b/src/GudhUI/utils/K_nearest_builder.h
index 7be0a4f4..4000a331 100644
--- a/src/GudhUI/utils/K_nearest_builder.h
+++ b/src/GudhUI/utils/K_nearest_builder.h
@@ -81,7 +81,7 @@ template<typename SkBlComplex> class K_nearest_builder {
for (auto it = ++search.begin(); it != search.end(); ++it) {
Vertex_handle q(std::get<1>(it->first));
if (p != q && complex_.contains_vertex(p) && complex_.contains_vertex(q))
- complex_.add_edge(p, q);
+ complex_.add_edge_without_blockers(p, q);
}
}
}
diff --git a/src/GudhUI/utils/Rips_builder.h b/src/GudhUI/utils/Rips_builder.h
index b22f4db6..59b4bee2 100644
--- a/src/GudhUI/utils/Rips_builder.h
+++ b/src/GudhUI/utils/Rips_builder.h
@@ -60,7 +60,7 @@ template<typename SkBlComplex> class Rips_builder {
std::cout.flush();
for (auto q = p; ++q != vertices.end(); /**/)
if (squared_eucl_distance(complex_.point(*p), complex_.point(*q)) < 4 * alpha * alpha)
- complex_.add_edge(*p, *q);
+ complex_.add_edge_without_blockers(*p, *q);
}
std::cout << std::endl;
}
diff --git a/src/Nerve_GIC/example/CMakeLists.txt b/src/Nerve_GIC/example/CMakeLists.txt
index f2626927..542c6af4 100644
--- a/src/Nerve_GIC/example/CMakeLists.txt
+++ b/src/Nerve_GIC/example/CMakeLists.txt
@@ -23,4 +23,7 @@ if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
"lucky_cat.off"
"lucky_cat_PCA1")
+ install(TARGETS CoordGIC DESTINATION bin)
+ install(TARGETS FuncGIC DESTINATION bin)
+
endif (NOT CGAL_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h
index 40ff7a4a..f5b67be6 100644
--- a/src/Nerve_GIC/include/gudhi/GIC.h
+++ b/src/Nerve_GIC/include/gudhi/GIC.h
@@ -23,6 +23,11 @@
#ifndef GIC_H_
#define GIC_H_
+#ifdef GUDHI_USE_TBB
+#include <tbb/parallel_for.h>
+#include <tbb/mutex.h>
+#endif
+
#include <gudhi/Debug_utils.h>
#include <gudhi/graph_simplicial_complex.h>
#include <gudhi/reader_utils.h>
@@ -99,9 +104,8 @@ class Cover_complex {
int data_dimension; // dimension of input data.
int n; // number of points.
- std::map<int, double> func; // function used to compute the output simplicial complex.
- std::map<int, double>
- func_color; // function used to compute the colors of the nodes of the output simplicial complex.
+ std::vector<double> func; // function used to compute the output simplicial complex.
+ std::vector<double> func_color; // function used to compute the colors of the nodes of the output simplicial complex.
bool functional_cover = false; // whether we use a cover with preimages of a function or not.
Graph one_skeleton_OFF; // one-skeleton given by the input OFF file (if it exists).
@@ -114,8 +118,8 @@ class Cover_complex {
Persistence_diagram PD;
std::vector<double> distribution;
- std::map<int, std::vector<int> >
- cover; // function associating to each data point its vectors of cover elements to which it belongs.
+ std::vector<std::vector<int> >
+ cover; // function associating to each data point the vector of cover elements to which it belongs.
std::map<int, std::vector<int> >
cover_back; // inverse of cover, in order to get the data points associated to a specific cover element.
std::map<int, double> cover_std; // standard function (induced by func) used to compute the extended persistence
@@ -140,8 +144,8 @@ class Cover_complex {
// Point comparator
struct Less {
- Less(std::map<int, double> func) { Fct = func; }
- std::map<int, double> Fct;
+ Less(std::vector<double> func) { Fct = func; }
+ std::vector<double> Fct;
bool operator()(int a, int b) {
if (Fct[a] == Fct[b])
return a < b;
@@ -276,6 +280,7 @@ class Cover_complex {
point_cloud.emplace_back(point.begin(), point.begin() + data_dimension);
boost::add_vertex(one_skeleton_OFF);
vertices.push_back(boost::add_vertex(one_skeleton));
+ std::vector<int> dummy; dummy.clear(); cover.push_back(dummy);
i++;
}
}
@@ -430,17 +435,29 @@ class Cover_complex {
if (distances.size() == 0) compute_pairwise_distances(distance);
- // #pragma omp parallel for
- for (int i = 0; i < N; i++) {
- SampleWithoutReplacement(n, m, samples);
- double hausdorff_dist = 0;
- for (int j = 0; j < n; j++) {
- double mj = distances[j][samples[0]];
- for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]);
- hausdorff_dist = std::max(hausdorff_dist, mj);
+ #ifdef GUDHI_USE_TBB
+ tbb::parallel_for(0, N, [&](int i){
+ SampleWithoutReplacement(n, m, samples);
+ double hausdorff_dist = 0;
+ for (int j = 0; j < n; j++) {
+ double mj = distances[j][samples[0]];
+ for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]);
+ hausdorff_dist = std::max(hausdorff_dist, mj);
+ }
+ delta += hausdorff_dist / N;
+ });
+ #else
+ for (int i = 0; i < N; i++) {
+ SampleWithoutReplacement(n, m, samples);
+ double hausdorff_dist = 0;
+ for (int j = 0; j < n; j++) {
+ double mj = distances[j][samples[0]];
+ for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]);
+ hausdorff_dist = std::max(hausdorff_dist, mj);
+ }
+ delta += hausdorff_dist / N;
}
- delta += hausdorff_dist / N;
- }
+ #endif
if (verbose) std::cout << "delta = " << delta << std::endl;
set_graph_from_rips(delta, distance);
@@ -465,7 +482,7 @@ class Cover_complex {
while (std::getline(input, line)) {
std::stringstream stream(line);
stream >> f;
- func.emplace(i, f);
+ func.push_back(f);
i++;
}
functional_cover = true;
@@ -479,7 +496,7 @@ class Cover_complex {
*
*/
void set_function_from_coordinate(int k) {
- for (int i = 0; i < n; i++) func.emplace(i, point_cloud[i][k]);
+ for (int i = 0; i < n; i++) func.push_back(point_cloud[i][k]);
functional_cover = true;
cover_name = "coordinate " + std::to_string(k);
}
@@ -492,7 +509,7 @@ class Cover_complex {
*/
template <class InputRange>
void set_function_from_range(InputRange const& function) {
- for (int i = 0; i < n; i++) func.emplace(i, function[i]);
+ for (int i = 0; i < n; i++) func.push_back(function[i]);
functional_cover = true;
}
@@ -710,37 +727,69 @@ class Cover_complex {
funcstd[i] = 0.5 * (u + v);
}
- if (verbose) std::cout << "Computing connected components..." << std::endl;
- // #pragma omp parallel for
- for (int i = 0; i < res; i++) {
- // Compute connected components
- Graph G = one_skeleton.create_subgraph();
- int num = preimages[i].size();
- std::vector<int> component(num);
- for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G);
- boost::connected_components(G, &component[0]);
- int max = 0;
-
- // For each point in preimage
- for (int j = 0; j < num; j++) {
- // Update number of components in preimage
- if (component[j] > max) max = component[j];
-
- // Identify component with Cantor polynomial N^2 -> N
- int identifier = (std::pow(i + component[j], 2) + 3 * i + component[j]) / 2;
-
- // Update covers
- cover[preimages[i][j]].push_back(identifier);
- cover_back[identifier].push_back(preimages[i][j]);
- cover_fct[identifier] = i;
- cover_std[identifier] = funcstd[i];
- cover_color[identifier].second += func_color[preimages[i][j]];
- cover_color[identifier].first += 1;
- }
+ #ifdef GUDHI_USE_TBB
+ if (verbose) std::cout << "Computing connected components (parallelized)..." << std::endl;
+ tbb::parallel_for(0, res, [&](int i){
+ // Compute connected components
+ Graph G = one_skeleton.create_subgraph();
+ int num = preimages[i].size();
+ std::vector<int> component(num);
+ for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G);
+ boost::connected_components(G, &component[0]);
+ int max = 0;
+
+ // For each point in preimage
+ for (int j = 0; j < num; j++) {
+ // Update number of components in preimage
+ if (component[j] > max) max = component[j];
+
+ // Identify component with Cantor polynomial N^2 -> N
+ int identifier = ((i + component[j])*(i + component[j]) + 3 * i + component[j]) / 2;
+
+ // Update covers
+ cover[preimages[i][j]].push_back(identifier);
+ cover_back[identifier].push_back(preimages[i][j]);
+ cover_fct[identifier] = i;
+ cover_std[identifier] = funcstd[i];
+ cover_color[identifier].second += func_color[preimages[i][j]];
+ cover_color[identifier].first += 1;
+ }
- // Maximal dimension is total number of connected components
- id += max + 1;
- }
+ // Maximal dimension is total number of connected components
+ id += max + 1;
+ });
+ #else
+ if (verbose) std::cout << "Computing connected components..." << std::endl;
+ for (int i = 0; i < res; i++) {
+ // Compute connected components
+ Graph G = one_skeleton.create_subgraph();
+ int num = preimages[i].size();
+ std::vector<int> component(num);
+ for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G);
+ boost::connected_components(G, &component[0]);
+ int max = 0;
+
+ // For each point in preimage
+ for (int j = 0; j < num; j++) {
+ // Update number of components in preimage
+ if (component[j] > max) max = component[j];
+
+ // Identify component with Cantor polynomial N^2 -> N
+ int identifier = (std::pow(i + component[j], 2) + 3 * i + component[j]) / 2;
+
+ // Update covers
+ cover[preimages[i][j]].push_back(identifier);
+ cover_back[identifier].push_back(preimages[i][j]);
+ cover_fct[identifier] = i;
+ cover_std[identifier] = funcstd[i];
+ cover_color[identifier].second += func_color[preimages[i][j]];
+ cover_color[identifier].first += 1;
+ }
+
+ // Maximal dimension is total number of connected components
+ id += max + 1;
+ }
+ #endif
maximal_dim = id - 1;
for (std::map<int, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++)
@@ -803,24 +852,46 @@ class Cover_complex {
for (int j = 0; j < n; j++) mindist[j] = std::numeric_limits<double>::max();
// Compute the geodesic distances to subsamples with Dijkstra
- // #pragma omp parallel for
- for (int i = 0; i < m; i++) {
- if (verbose) std::cout << "Computing geodesic distances to seed " << i << "..." << std::endl;
- int seed = voronoi_subsamples[i];
- std::vector<double> dmap(n);
- boost::dijkstra_shortest_paths(
- one_skeleton, vertices[seed],
- boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index)));
-
- for (int j = 0; j < n; j++)
- if (mindist[j] > dmap[j]) {
- mindist[j] = dmap[j];
- if (cover[j].size() == 0)
- cover[j].push_back(i);
- else
- cover[j][0] = i;
- }
- }
+ #ifdef GUDHI_USE_TBB
+ if (verbose) std::cout << "Computing geodesic distances (parallelized)..." << std::endl;
+ tbb::mutex coverMutex; tbb::mutex mindistMutex;
+ tbb::parallel_for(0, m, [&](int i){
+ int seed = voronoi_subsamples[i];
+ std::vector<double> dmap(n);
+ boost::dijkstra_shortest_paths(
+ one_skeleton, vertices[seed],
+ boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index)));
+
+ coverMutex.lock(); mindistMutex.lock();
+ for (int j = 0; j < n; j++)
+ if (mindist[j] > dmap[j]) {
+ mindist[j] = dmap[j];
+ if (cover[j].size() == 0)
+ cover[j].push_back(i);
+ else
+ cover[j][0] = i;
+ }
+ coverMutex.unlock(); mindistMutex.unlock();
+ });
+ #else
+ for (int i = 0; i < m; i++) {
+ if (verbose) std::cout << "Computing geodesic distances to seed " << i << "..." << std::endl;
+ int seed = voronoi_subsamples[i];
+ std::vector<double> dmap(n);
+ boost::dijkstra_shortest_paths(
+ one_skeleton, vertices[seed],
+ boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index)));
+
+ for (int j = 0; j < n; j++)
+ if (mindist[j] > dmap[j]) {
+ mindist[j] = dmap[j];
+ if (cover[j].size() == 0)
+ cover[j].push_back(i);
+ else
+ cover[j][0] = i;
+ }
+ }
+ #endif
for (int i = 0; i < n; i++) {
cover_back[cover[i][0]].push_back(i);
@@ -860,7 +931,7 @@ class Cover_complex {
while (std::getline(input, line)) {
std::stringstream stream(line);
stream >> f;
- func_color.emplace(i, f);
+ func_color.push_back(f);
i++;
}
color_name = color_file_name;
@@ -873,7 +944,7 @@ class Cover_complex {
*
*/
void set_color_from_coordinate(int k = 0) {
- for (int i = 0; i < n; i++) func_color[i] = point_cloud[i][k];
+ for (int i = 0; i < n; i++) func_color.push_back(point_cloud[i][k]);
color_name = "coordinate ";
color_name.append(std::to_string(k));
}
@@ -885,7 +956,7 @@ class Cover_complex {
*
*/
void set_color_from_vector(std::vector<double> color) {
- for (unsigned int i = 0; i < color.size(); i++) func_color[i] = color[i];
+ for (unsigned int i = 0; i < color.size(); i++) func_color.push_back(color[i]);
}
public: // Create a .dot file that can be compiled with neato to produce a .pdf file.
@@ -1039,45 +1110,29 @@ class Cover_complex {
minf = std::min(minf, it->second);
}
+ // Build filtration
for (auto const& simplex : simplices) {
- // Add a simplex and a cone on it
- std::vector<int> splx = simplex;
- splx.push_back(-2);
- st.insert_simplex_and_subfaces(splx);
+ std::vector<int> splx = simplex; splx.push_back(-2);
+ st.insert_simplex_and_subfaces(splx, -3);
}
- // Build filtration
- for (auto simplex : st.complex_simplex_range()) {
- double filta = std::numeric_limits<double>::lowest();
- double filts = filta;
- bool ascending = true;
- for (auto vertex : st.simplex_vertex_range(simplex)) {
- if (vertex == -2) {
- ascending = false;
- continue;
- }
- filta = std::max(-2 + (cover_std[vertex] - minf) / (maxf - minf), filta);
- filts = std::max(2 - (cover_std[vertex] - minf) / (maxf - minf), filts);
- }
- if (ascending)
- st.assign_filtration(simplex, filta);
- else
- st.assign_filtration(simplex, filts);
+ for (std::map<int, double>::iterator it = cover_std.begin(); it != cover_std.end(); it++) {
+ int vertex = it->first; float val = it->second;
+ int vert[] = {vertex}; int edge[] = {vertex, -2};
+ st.assign_filtration(st.find(vert), -2 + (val - minf)/(maxf - minf));
+ st.assign_filtration(st.find(edge), 2 - (val - minf)/(maxf - minf));
}
- int magic[] = {-2};
- st.assign_filtration(st.find(magic), -3);
+ st.make_filtration_non_decreasing();
// Compute PD
- st.initialize_filtration();
- Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Gudhi::persistent_cohomology::Field_Zp> pcoh(st);
- pcoh.init_coefficients(2);
+ Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Gudhi::persistent_cohomology::Field_Zp> pcoh(st); pcoh.init_coefficients(2);
pcoh.compute_persistent_cohomology();
// Output PD
int max_dim = st.dimension();
for (int i = 0; i < max_dim; i++) {
std::vector<std::pair<double, double> > bars = pcoh.intervals_in_dimension(i);
- int num_bars = bars.size();
+ int num_bars = bars.size(); if(i == 0) num_bars -= 1;
if(verbose) std::cout << num_bars << " interval(s) in dimension " << i << ":" << std::endl;
for (int j = 0; j < num_bars; j++) {
double birth = bars[j].first;
@@ -1206,8 +1261,7 @@ class Cover_complex {
}
if (type == "Nerve") {
- for(auto& simplex : cover)
- simplices.push_back(simplex.second);
+ for(int i = 0; i < n; i++) simplices.push_back(cover[i]);
std::sort(simplices.begin(), simplices.end());
std::vector<std::vector<int> >::iterator it = std::unique(simplices.begin(), simplices.end());
simplices.resize(std::distance(simplices.begin(), it));
diff --git a/src/Nerve_GIC/test/test_GIC.cpp b/src/Nerve_GIC/test/test_GIC.cpp
index d633753c..e3067d35 100644
--- a/src/Nerve_GIC/test/test_GIC.cpp
+++ b/src/Nerve_GIC/test/test_GIC.cpp
@@ -39,6 +39,7 @@ BOOST_AUTO_TEST_CASE(check_nerve) {
N.set_type("Nerve");
std::string cloud_file_name("data/cloud");
N.read_point_cloud(cloud_file_name);
+ N.set_color_from_coordinate();
std::string graph_file_name("data/graph");
N.set_graph_from_file(graph_file_name);
std::string cover_file_name("data/cover");
@@ -58,6 +59,7 @@ BOOST_AUTO_TEST_CASE(check_GIC) {
GIC.set_type("GIC");
std::string cloud_file_name("data/cloud");
GIC.read_point_cloud(cloud_file_name);
+ GIC.set_color_from_coordinate();
std::string graph_file_name("data/graph");
GIC.set_graph_from_file(graph_file_name);
std::string cover_file_name("data/cover");
@@ -77,6 +79,7 @@ BOOST_AUTO_TEST_CASE(check_voronoiGIC) {
GIC.set_type("GIC");
std::string cloud_file_name("data/cloud");
GIC.read_point_cloud(cloud_file_name);
+ GIC.set_color_from_coordinate();
std::string graph_file_name("data/graph");
GIC.set_graph_from_file(graph_file_name);
GIC.set_cover_from_Voronoi(Gudhi::Euclidean_distance(), 2);
diff --git a/src/Nerve_GIC/utilities/CMakeLists.txt b/src/Nerve_GIC/utilities/CMakeLists.txt
index 7762c8a0..7a838a8c 100644
--- a/src/Nerve_GIC/utilities/CMakeLists.txt
+++ b/src/Nerve_GIC/utilities/CMakeLists.txt
@@ -21,4 +21,8 @@ if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
add_test(NAME Nerve_GIC_utilities_VoronoiGIC COMMAND $<TARGET_FILE:VoronoiGIC>
"human.off" "100")
+ install(TARGETS Nerve DESTINATION bin)
+ install(TARGETS VoronoiGIC DESTINATION bin)
+ install(FILES KeplerMapperVisuFromTxtFile.py km.py km.py.COPYRIGHT DESTINATION bin)
+
endif (NOT CGAL_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Nerve_GIC/utilities/covercomplex.md b/src/Nerve_GIC/utilities/covercomplex.md
index f33cb2e0..6d16d16f 100644
--- a/src/Nerve_GIC/utilities/covercomplex.md
+++ b/src/Nerve_GIC/utilities/covercomplex.md
@@ -1,3 +1,13 @@
+---
+layout: page
+title: "Cover complex"
+meta_title: "Cover complex"
+teaser: ""
+permalink: /covercomplex/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
# Cover complex #
diff --git a/src/Persistence_representations/example/CMakeLists.txt b/src/Persistence_representations/example/CMakeLists.txt
index eb3258f8..54d719ac 100644
--- a/src/Persistence_representations/example/CMakeLists.txt
+++ b/src/Persistence_representations/example/CMakeLists.txt
@@ -4,24 +4,26 @@ project(Persistence_representations_example)
add_executable ( Persistence_representations_example_landscape_on_grid persistence_landscape_on_grid.cpp )
add_test(NAME Persistence_representations_example_landscape_on_grid
COMMAND $<TARGET_FILE:Persistence_representations_example_landscape_on_grid>)
+install(TARGETS Persistence_representations_example_landscape_on_grid DESTINATION bin)
add_executable ( Persistence_representations_example_landscape persistence_landscape.cpp )
add_test(NAME Persistence_representations_example_landscape
COMMAND $<TARGET_FILE:Persistence_representations_example_landscape>)
+install(TARGETS Persistence_representations_example_landscape DESTINATION bin)
add_executable ( Persistence_representations_example_intervals persistence_intervals.cpp )
add_test(NAME Persistence_representations_example_intervals
COMMAND $<TARGET_FILE:Persistence_representations_example_intervals>
"${CMAKE_SOURCE_DIR}/data/persistence_diagram/first.pers")
+install(TARGETS Persistence_representations_example_intervals DESTINATION bin)
add_executable ( Persistence_representations_example_vectors persistence_vectors.cpp )
add_test(NAME Persistence_representations_example_vectors
COMMAND $<TARGET_FILE:Persistence_representations_example_vectors>)
+install(TARGETS Persistence_representations_example_vectors DESTINATION bin)
add_executable ( Persistence_representations_example_heat_maps persistence_heat_maps.cpp )
add_test(NAME Persistence_representations_example_heat_maps
COMMAND $<TARGET_FILE:Persistence_representations_example_heat_maps>)
-
-
-
+install(TARGETS Persistence_representations_example_heat_maps DESTINATION bin)
diff --git a/src/Persistence_representations/utilities/CMakeLists.txt b/src/Persistence_representations/utilities/CMakeLists.txt
index 137eb0c1..fc51b1d6 100644
--- a/src/Persistence_representations/utilities/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/CMakeLists.txt
@@ -10,6 +10,8 @@ function(add_persistence_representation_creation_utility creation_utility)
add_test(NAME Persistence_representation_utilities_${creation_utility} COMMAND $<TARGET_FILE:${creation_utility}>
${ARGN} "${CMAKE_CURRENT_BINARY_DIR}/../first.pers"
"${CMAKE_CURRENT_BINARY_DIR}/../second.pers")
+
+ install(TARGETS ${creation_utility} DESTINATION bin)
endfunction(add_persistence_representation_creation_utility)
function(add_persistence_representation_plot_utility plot_utility tool_extension)
@@ -26,6 +28,8 @@ function(add_persistence_representation_plot_utility plot_utility tool_extension
#add_test(NAME Persistence_representation_utilities_${plot_utility}_second_gnuplot COMMAND ${GNUPLOT_PATH}
# "-e" "load '${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}_GnuplotScript'")
endif()
+
+ install(TARGETS ${plot_utility} DESTINATION bin)
endfunction(add_persistence_representation_plot_utility)
function(add_persistence_representation_function_utility function_utility tool_extension)
@@ -44,6 +48,8 @@ function(add_persistence_representation_function_utility function_utility tool_e
"${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}"
"${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}")
endif()
+
+ install(TARGETS ${function_utility} DESTINATION bin)
endfunction(add_persistence_representation_function_utility)
add_subdirectory(persistence_heat_maps)
diff --git a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt
index 897e12a3..875ff45e 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt
@@ -7,6 +7,8 @@ add_executable ( plot_histogram_of_intervals_lengths plot_histogram_of_intervals
add_test(NAME plot_histogram_of_intervals_lengths COMMAND $<TARGET_FILE:plot_histogram_of_intervals_lengths>
"${CMAKE_CURRENT_BINARY_DIR}/../first.pers" "-1")
+install(TARGETS plot_histogram_of_intervals_lengths DESTINATION bin)
+
add_persistence_representation_plot_utility(plot_persistence_intervals "")
add_persistence_representation_plot_utility(plot_persistence_Betti_numbers "")
@@ -18,6 +20,8 @@ add_test(NAME Persistence_representation_utilities_compute_number_of_dominant_in
COMMAND $<TARGET_FILE:compute_number_of_dominant_intervals>
"${CMAKE_CURRENT_BINARY_DIR}/../first.pers" "-1" "2")
+install(TARGETS compute_number_of_dominant_intervals DESTINATION bin)
+
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
add_executable ( compute_bottleneck_distance compute_bottleneck_distance.cpp )
@@ -29,4 +33,6 @@ if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
"-1"
"${CMAKE_CURRENT_BINARY_DIR}/../first.pers"
"${CMAKE_CURRENT_BINARY_DIR}/../second.pers")
+
+ install(TARGETS compute_bottleneck_distance DESTINATION bin)
endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Persistent_cohomology/concept/FilteredComplex.h b/src/Persistent_cohomology/concept/FilteredComplex.h
index c19698df..d6b662e9 100644
--- a/src/Persistent_cohomology/concept/FilteredComplex.h
+++ b/src/Persistent_cohomology/concept/FilteredComplex.h
@@ -31,7 +31,7 @@ struct FilteredComplex
typedef unspecified Simplex_handle;
/** \brief Key associated to each simplex.
*
- * Must be a signed integer type. */
+ * Must be an integer type. */
typedef unspecified Simplex_key;
/** \brief Type for the value of the filtration function.
*
@@ -67,8 +67,8 @@ struct FilteredComplex
Simplex_key key ( Simplex_handle sh );
/** \brief Returns the simplex that has index idx in the filtration.
*
- * This is never called on null_key(). */
- Simplex_handle simplex ( Simplex_key idx );
+ * This is only called on valid indices. */
+ Simplex_handle simplex ( size_t idx );
/** \brief Assign a key to a simplex. */
void assign_key(Simplex_handle sh, Simplex_key key);
diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
index 4dbe82c7..3113a22c 100644
--- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
+++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
@@ -162,6 +162,19 @@ persistence diagram with a family of field coefficients.
Rips_complex/rips_distance_matrix_persistence.cpp</a> computes the Rips complex of a distance matrix and
outputs its persistence diagram.
+The file should contain square or lower triangular distance matrix with semicolons as separators.
+The code do not check if it is dealing with a distance matrix. It is the user responsibility to provide a valid input.
+Please refer to data/distance_matrix/lower_triangular_distance_matrix.csv for an example of a file.
+
+\li <a href="_rips_complex_2rips_correlation_matrix_persistence_8cpp-example.html">
+Rips_complex/rips_correlation_matrix_persistence.cpp</a>
+computes the Rips complex of a correlation matrix and outputs its persistence diagram.
+
+Note that no check is performed if the matrix given as the input is a correlation matrix.
+It is the user responsibility to ensure that this is the case. The input is to be given either as a square or a lower
+triangular matrix.
+Please refer to data/correlation_matrix/lower_triangular_correlation_matrix.csv for an example of a file.
+
\li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
Alpha_complex/alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
diff --git a/src/Rips_complex/doc/Intro_rips_complex.h b/src/Rips_complex/doc/Intro_rips_complex.h
index 9cc58412..da6bd8d9 100644
--- a/src/Rips_complex/doc/Intro_rips_complex.h
+++ b/src/Rips_complex/doc/Intro_rips_complex.h
@@ -203,6 +203,33 @@ namespace rips_complex {
*
* \include Rips_complex/full_skeleton_rips_for_doc.txt
*
+ *
+ * \section ripscorrelationematrix Correlation matrix
+ *
+ * Analogously to the case of distance matrix, Rips complexes can be also constructed based on correlation matrix.
+ * Given a correlation matrix M, comportment-wise 1-M is a distance matrix.
+ * This example builds the one skeleton graph from the given corelation matrix and threshold value.
+ * Then it creates a `Simplex_tree` with it.
+ *
+ * Then, it is asked to display information about the simplicial complex.
+ *
+ * \include Rips_complex/example_one_skeleton_rips_from_correlation_matrix.cpp
+ *
+ * When launching:
+ *
+ * \code $> ./example_one_skeleton_from_correlation_matrix
+ * \endcode
+ *
+ * the program output is:
+ *
+ * \include Rips_complex/one_skeleton_rips_from_correlation_matrix_for_doc.txt
+ *
+ * All the other constructions discussed for Rips complex for distance matrix can be also performed for Rips complexes
+ * construction from correlation matrices.
+ *
+ * @warning As persistence diagrams points will be under the diagonal, bottleneck distance and persistence graphical
+ * tool will not work properly, this is a known issue.
+ *
*/
/** @} */ // end defgroup rips_complex
diff --git a/src/Rips_complex/example/CMakeLists.txt b/src/Rips_complex/example/CMakeLists.txt
index d05d3e57..90c2d9f7 100644
--- a/src/Rips_complex/example/CMakeLists.txt
+++ b/src/Rips_complex/example/CMakeLists.txt
@@ -14,11 +14,15 @@ add_executable ( Rips_complex_example_from_csv_distance_matrix example_rips_comp
# Point cloud
add_executable ( Rips_complex_example_sparse example_sparse_rips.cpp )
+# Correlation matrix
+add_executable ( Rips_complex_example_one_skeleton_rips_from_correlation_matrix example_one_skeleton_rips_from_correlation_matrix.cpp )
+
if (TBB_FOUND)
target_link_libraries(Rips_complex_example_from_off ${TBB_LIBRARIES})
target_link_libraries(Rips_complex_example_one_skeleton_from_points ${TBB_LIBRARIES})
target_link_libraries(Rips_complex_example_one_skeleton_from_distance_matrix ${TBB_LIBRARIES})
target_link_libraries(Rips_complex_example_from_csv_distance_matrix ${TBB_LIBRARIES})
+ target_link_libraries(Rips_complex_example_one_skeleton_rips_from_correlation_matrix ${TBB_LIBRARIES})
target_link_libraries(Rips_complex_example_sparse ${TBB_LIBRARIES})
endif()
@@ -26,6 +30,8 @@ add_test(NAME Rips_complex_example_one_skeleton_from_points
COMMAND $<TARGET_FILE:Rips_complex_example_one_skeleton_from_points>)
add_test(NAME Rips_complex_example_one_skeleton_from_distance_matrix
COMMAND $<TARGET_FILE:Rips_complex_example_one_skeleton_from_distance_matrix>)
+add_test(NAME Rips_complex_example_one_skeleton_rips_from_correlation_matrix
+ COMMAND $<TARGET_FILE:Rips_complex_example_one_skeleton_rips_from_correlation_matrix>)
add_test(NAME Rips_complex_example_from_off_doc_12_1 COMMAND $<TARGET_FILE:Rips_complex_example_from_off>
"${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" "12.0" "1" "${CMAKE_CURRENT_BINARY_DIR}/ripsoffreader_result_12_1.txt")
@@ -61,3 +67,4 @@ install(TARGETS Rips_complex_example_from_off DESTINATION bin)
install(TARGETS Rips_complex_example_one_skeleton_from_points DESTINATION bin)
install(TARGETS Rips_complex_example_one_skeleton_from_distance_matrix DESTINATION bin)
install(TARGETS Rips_complex_example_from_csv_distance_matrix DESTINATION bin)
+install(TARGETS Rips_complex_example_one_skeleton_rips_from_correlation_matrix DESTINATION bin)
diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp
new file mode 100644
index 00000000..1343f24d
--- /dev/null
+++ b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp
@@ -0,0 +1,81 @@
+#include <gudhi/Rips_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/distance_functions.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <limits> // for std::numeric_limits
+
+int main() {
+ // Type definitions
+ using Simplex_tree = Gudhi::Simplex_tree<>;
+ using Filtration_value = Simplex_tree::Filtration_value;
+ using Rips_complex = Gudhi::rips_complex::Rips_complex<Filtration_value>;
+ using Distance_matrix = std::vector<std::vector<Filtration_value>>;
+
+ // User defined correlation matrix is:
+ // |1 0.06 0.23 0.01 0.89|
+ // |0.06 1 0.74 0.01 0.61|
+ // |0.23 0.74 1 0.72 0.03|
+ // |0.01 0.01 0.72 1 0.7 |
+ // |0.89 0.61 0.03 0.7 1 |
+
+ Distance_matrix correlations;
+ correlations.push_back({});
+ correlations.push_back({0.06});
+ correlations.push_back({0.23, 0.74});
+ correlations.push_back({0.01, 0.01, 0.72});
+ correlations.push_back({0.89, 0.61, 0.03, 0.7});
+
+ // ----------------------------------------------------------------------------
+ // Convert correlation matrix to a distance matrix:
+ // ----------------------------------------------------------------------------
+ double threshold = 0;
+ for (size_t i = 0; i != correlations.size(); ++i) {
+ for (size_t j = 0; j != correlations[i].size(); ++j) {
+ // Here we check if our data comes from corelation matrix.
+ if ((correlations[i][j] < -1) || (correlations[i][j] > 1)) {
+ std::cerr << "The input matrix is not a correlation matrix. The program will now terminate.\n";
+ throw "The input matrix is not a correlation matrix. The program will now terminate.\n";
+ }
+ correlations[i][j] = 1 - correlations[i][j];
+ // Here we make sure that we will get the treshold value equal to maximal
+ // distance in the matrix.
+ if (correlations[i][j] > threshold) threshold = correlations[i][j];
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ // Now the correlation matrix is a distance matrix and can be processed further.
+ //-----------------------------------------------------------------------------
+ Distance_matrix distances = correlations;
+
+ Rips_complex rips_complex_from_points(distances, threshold);
+
+ Simplex_tree stree;
+ rips_complex_from_points.create_complex(stree, 1);
+ // ----------------------------------------------------------------------------
+ // Display information about the one skeleton Rips complex. Note that
+ // the filtration displayed here comes from the distance matrix computed
+ // above, which is 1 - initial correlation matrix. Only this way, we obtain
+ // a complex with filtration. If a correlation matrix is used instead, we would
+ // have a reverse filtration (i.e. filtration of boundary of each simplex S
+ // is greater or equal to the filtration of S).
+ // ----------------------------------------------------------------------------
+ std::cout << "Rips complex is of dimension " << stree.dimension() << " - " << stree.num_simplices() << " simplices - "
+ << stree.num_vertices() << " vertices." << std::endl;
+
+ std::cout << "Iterator on Rips complex simplices in the filtration order, with [filtration value]:" << std::endl;
+ for (auto f_simplex : stree.filtration_simplex_range()) {
+ std::cout << " ( ";
+ for (auto vertex : stree.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << ") -> "
+ << "[" << stree.filtration(f_simplex) << "] ";
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/Rips_complex/example/one_skeleton_rips_from_correlation_matrix_for_doc.txt b/src/Rips_complex/example/one_skeleton_rips_from_correlation_matrix_for_doc.txt
new file mode 100644
index 00000000..640d7083
--- /dev/null
+++ b/src/Rips_complex/example/one_skeleton_rips_from_correlation_matrix_for_doc.txt
@@ -0,0 +1,17 @@
+Rips complex is of dimension 1 - 15 simplices - 5 vertices.
+Iterator on Rips complex simplices in the filtration order, with [filtration value]:
+ ( 0 ) -> [0]
+ ( 1 ) -> [0]
+ ( 2 ) -> [0]
+ ( 3 ) -> [0]
+ ( 4 ) -> [0]
+ ( 4 0 ) -> [0.11]
+ ( 2 1 ) -> [0.26]
+ ( 3 2 ) -> [0.28]
+ ( 4 3 ) -> [0.3]
+ ( 4 1 ) -> [0.39]
+ ( 2 0 ) -> [0.77]
+ ( 1 0 ) -> [0.94]
+ ( 4 2 ) -> [0.97]
+ ( 3 0 ) -> [0.99]
+ ( 3 1 ) -> [0.99]
diff --git a/src/Rips_complex/utilities/CMakeLists.txt b/src/Rips_complex/utilities/CMakeLists.txt
index b245eb08..c8d389a0 100644
--- a/src/Rips_complex/utilities/CMakeLists.txt
+++ b/src/Rips_complex/utilities/CMakeLists.txt
@@ -7,12 +7,16 @@ target_link_libraries(rips_distance_matrix_persistence ${Boost_PROGRAM_OPTIONS_L
add_executable(rips_persistence rips_persistence.cpp)
target_link_libraries(rips_persistence ${Boost_PROGRAM_OPTIONS_LIBRARY})
+add_executable(rips_correlation_matrix_persistence rips_correlation_matrix_persistence.cpp)
+target_link_libraries(rips_correlation_matrix_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+
add_executable(sparse_rips_persistence sparse_rips_persistence.cpp)
target_link_libraries(sparse_rips_persistence ${Boost_PROGRAM_OPTIONS_LIBRARY})
if (TBB_FOUND)
target_link_libraries(rips_distance_matrix_persistence ${TBB_LIBRARIES})
target_link_libraries(rips_persistence ${TBB_LIBRARIES})
+ target_link_libraries(rips_correlation_matrix_persistence ${TBB_LIBRARIES})
target_link_libraries(sparse_rips_persistence ${TBB_LIBRARIES})
endif()
@@ -20,9 +24,12 @@ add_test(NAME Rips_complex_utility_from_rips_distance_matrix COMMAND $<TARGET_FI
"${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv" "-r" "1.0" "-d" "3" "-p" "3" "-m" "0")
add_test(NAME Rips_complex_utility_from_rips_on_tore_3D COMMAND $<TARGET_FILE:rips_persistence>
"${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off" "-r" "0.25" "-m" "0.5" "-d" "3" "-p" "3")
+add_test(NAME Rips_complex_utility_from_rips_correlation_matrix COMMAND $<TARGET_FILE:rips_correlation_matrix_persistence>
+ "${CMAKE_SOURCE_DIR}/data/correlation_matrix/lower_triangular_correlation_matrix.csv" "-c" "0.3" "-d" "3" "-p" "3" "-m" "0")
add_test(NAME Sparse_rips_complex_utility_on_tore_3D COMMAND $<TARGET_FILE:sparse_rips_persistence>
"${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off" "-e" "0.5" "-m" "0.2" "-d" "3" "-p" "2")
install(TARGETS rips_distance_matrix_persistence DESTINATION bin)
install(TARGETS rips_persistence DESTINATION bin)
+install(TARGETS rips_correlation_matrix_persistence DESTINATION bin)
install(TARGETS sparse_rips_persistence DESTINATION bin)
diff --git a/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp b/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp
new file mode 100644
index 00000000..c2082fae
--- /dev/null
+++ b/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp
@@ -0,0 +1,170 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko, Vincent Rouvreau
+ *
+ * Copyright (C) 2016 INRIA
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/Rips_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/reader_utils.h>
+#include <gudhi/writing_persistence_to_file.h>
+
+#include <boost/program_options.hpp>
+
+#include <string>
+#include <vector>
+#include <limits> // infinity
+
+// Types definition
+using Simplex_tree = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Filtration_value = Simplex_tree::Filtration_value;
+using Rips_complex = Gudhi::rips_complex::Rips_complex<Filtration_value>;
+using Field_Zp = Gudhi::persistent_cohomology::Field_Zp;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Field_Zp>;
+using Correlation_matrix = std::vector<std::vector<Filtration_value>>;
+using intervals_common = Gudhi::Persistence_interval_common<double, int>;
+
+void program_options(int argc, char* argv[], std::string& csv_matrix_file, std::string& filediag,
+ Filtration_value& correlation_min, int& dim_max, int& p, Filtration_value& min_persistence);
+
+int main(int argc, char* argv[]) {
+ std::string csv_matrix_file;
+ std::string filediag;
+ Filtration_value correlation_min;
+ int dim_max;
+ int p;
+ Filtration_value min_persistence;
+
+ program_options(argc, argv, csv_matrix_file, filediag, correlation_min, dim_max, p, min_persistence);
+
+ Correlation_matrix correlations =
+ Gudhi::read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_matrix_file);
+
+ Filtration_value threshold = 0;
+
+ // Given a correlation matrix M, we compute component-wise M'[i,j] = 1-M[i,j] to get a distance matrix:
+ for (size_t i = 0; i != correlations.size(); ++i) {
+ for (size_t j = 0; j != correlations[i].size(); ++j) {
+ correlations[i][j] = 1 - correlations[i][j];
+ // Here we make sure that the values of corelations lie between -1 and 1.
+ // If not, we throw an exception.
+ if ((correlations[i][j] < -1) || (correlations[i][j] > 1)) {
+ std::cerr << "The input matrix is not a correlation matrix. The program will now terminate. \n";
+ throw "The input matrix is not a correlation matrix. The program will now terminate. \n";
+ }
+ if (correlations[i][j] > threshold) threshold = correlations[i][j];
+ }
+ }
+
+ Rips_complex rips_complex_from_file(correlations, threshold);
+
+ // Construct the Rips complex in a Simplex Tree
+ Simplex_tree simplex_tree;
+
+ rips_complex_from_file.create_complex(simplex_tree, dim_max);
+ std::cout << "The complex contains " << simplex_tree.num_simplices() << " simplices \n";
+ std::cout << " and has dimension " << simplex_tree.dimension() << " \n";
+
+ // Sort the simplices in the order of the filtration
+ simplex_tree.initialize_filtration();
+
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology pcoh(simplex_tree);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(p);
+ // compute persistence
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // invert the persistence diagram. The reason for this procedure is the following:
+ // The input to the program is a corelation matrix M. When processing it, it is
+ // turned into 1-M and the obtained persistence intervals are in '1-M' units.
+ // Below we reverse every (birth,death) pair into (1-birth, 1-death) pair
+ // so that the input and the output to the program is expressed in the same
+ // units.
+ auto pairs = pcoh.get_persistent_pairs();
+ std::vector<intervals_common> processed_persistence_intervals;
+ processed_persistence_intervals.reserve(pairs.size());
+ for (auto pair : pairs) {
+ double birth = 1 - simplex_tree.filtration(get<0>(pair));
+ double death = 1 - simplex_tree.filtration(get<1>(pair));
+ unsigned dimension = (unsigned)simplex_tree.dimension(get<0>(pair));
+ int field = get<2>(pair);
+ processed_persistence_intervals.push_back(intervals_common(birth, death, dimension, field));
+ }
+
+ // sort the processed intervals:
+ std::sort(processed_persistence_intervals.begin(), processed_persistence_intervals.end());
+
+ // and write them to a file
+ if (filediag.empty()) {
+ write_persistence_intervals_to_stream(processed_persistence_intervals);
+ } else {
+ std::ofstream out(filediag);
+ write_persistence_intervals_to_stream(processed_persistence_intervals, out);
+ }
+ return 0;
+}
+
+void program_options(int argc, char* argv[], std::string& csv_matrix_file, std::string& filediag,
+ Filtration_value& correlation_min, int& dim_max, int& p, Filtration_value& min_persistence) {
+ namespace po = boost::program_options;
+ po::options_description hidden("Hidden options");
+ hidden.add_options()(
+ "input-file", po::value<std::string>(&csv_matrix_file),
+ "Name of file containing a corelation matrix. Can be square or lower triangular matrix. Separator is ';'.");
+ po::options_description visible("Allowed options", 100);
+ visible.add_options()("help,h", "produce help message")(
+ "output-file,o", po::value<std::string>(&filediag)->default_value(std::string()),
+ "Name of file in which the persistence diagram is written. Default print in std::cout")(
+ "min-edge-corelation,c", po::value<Filtration_value>(&correlation_min)->default_value(0),
+ "Minimal corelation of an edge for the Rips complex construction.")(
+ "cpx-dimension,d", po::value<int>(&dim_max)->default_value(1),
+ "Maximal dimension of the Rips complex we want to compute.")(
+ "field-charac,p", po::value<int>(&p)->default_value(11),
+ "Characteristic p of the coefficient field Z/pZ for computing homology.")(
+ "min-persistence,m", po::value<Filtration_value>(&min_persistence),
+ "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length "
+ "intervals");
+
+ po::positional_options_description pos;
+ pos.add("input-file", 1);
+
+ po::options_description all;
+ all.add(visible).add(hidden);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).options(all).positional(pos).run(), vm);
+ po::notify(vm);
+
+ if (vm.count("help") || !vm.count("input-file")) {
+ std::cout << std::endl;
+ std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
+ std::cout << "of a Rips complex defined on a corelation matrix.\n \n";
+ std::cout << "The output diagram contains one bar per line, written with the convention: \n";
+ std::cout << " p dim b d \n";
+ std::cout << "where dim is the dimension of the homological feature,\n";
+ std::cout << "b and d are respectively the birth and death of the feature and \n";
+ std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl;
+
+ std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
+ std::cout << visible << std::endl;
+ std::abort();
+ }
+}
diff --git a/src/Rips_complex/utilities/ripscomplex.md b/src/Rips_complex/utilities/ripscomplex.md
index 421caa7d..84f40cc1 100644
--- a/src/Rips_complex/utilities/ripscomplex.md
+++ b/src/Rips_complex/utilities/ripscomplex.md
@@ -1,3 +1,13 @@
+---
+layout: page
+title: "Rips complex"
+meta_title: "Rips complex"
+teaser: ""
+permalink: /ripscomplex/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
# Rips complex #
@@ -35,20 +45,46 @@ Beware: this program may use a lot of RAM and take a lot of time if `max-edge-le
## rips_distance_matrix_persistence ##
-Same as `rips_persistence` but taking a distance matrix as input.
+Same as `rips_persistence` but taking a distance matrix as input.
**Usage**
-`rips_persistence [options] <CSV input file>`
+`rips_distance_matrix_persistence [options] <CSV input file>`
where
`<CSV input file>` is the path to the file containing a distance matrix. Can be square or lower triangular matrix. Separator is ';'.
+The code do not check if it is dealing with a distance matrix. It is the user responsibility to provide a valid input.
+Please refer to data/distance_matrix/lower_triangular_distance_matrix.csv for an example of a file.
**Example**
`rips_distance_matrix_persistence data/distance_matrix/full_square_distance_matrix.csv -r 15 -d 3 -p 3 -m 0`
+## rips_correlation_matrix_persistence ##
+
+Same as `rips_distance_matrix_persistence` but taking a correlation matrix as input.
+
+**Usage**
+
+`rips_correlation_matrix_persistence [options] <CSV input file>`
+
+where
+`<CSV input file>` is the path to the file containing a correlation matrix. Can be square or lower triangular matrix. Separator is ';'.
+Note that no check is performed if the matrix given as the input is a correlation matrix.
+It is the user responsibility to ensure that this is the case.
+Please refer to data/correlation_matrix/lower_triangular_correlation_matrix.csv for an example of a file.
+
+**Example**
+
+`rips_correlation_matrix_persistence data/distance_matrix/full_square_distance_matrix.csv -r 15 -d 3 -p 3 -m 0`
+
+**Warning**
+
+As persistence diagrams points will be under the diagonal, bottleneck distance and persistence graphical tool will not work
+properly, this is a known issue.
+
+
## sparse_rips_persistence ##
This program computes the persistent homology with coefficient field *Z/pZ*
of a sparse (1+epsilon)-approximation of the Rips complex defined on a set of input Euclidean points. The output diagram contains one bar per line, written with the convention:
diff --git a/src/Witness_complex/utilities/witnesscomplex.md b/src/Witness_complex/utilities/witnesscomplex.md
index 2341759b..3be9bc55 100644
--- a/src/Witness_complex/utilities/witnesscomplex.md
+++ b/src/Witness_complex/utilities/witnesscomplex.md
@@ -1,3 +1,13 @@
+---
+layout: page
+title: "Witness complex"
+meta_title: "Witness complex"
+teaser: ""
+permalink: /witnesscomplex/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
# Witness complex #
diff --git a/src/common/doc/header.html b/src/common/doc/header.html
index 9c514381..2f54e68d 100644
--- a/src/common/doc/header.html
+++ b/src/common/doc/header.html
@@ -9,7 +9,7 @@
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<!-- GUDHI website css for header BEGIN -->
-<link rel="stylesheet" type="text/css" href="http://pages.saclay.inria.fr/vincent.rouvreau/gudhi/gudhi-doc-2.0.0/assets/css/styles_feeling_responsive.css" />
+<link rel="stylesheet" type="text/css" href="http://gudhi.gforge.inria.fr/assets/css/styles_feeling_responsive.css" />
<!-- GUDHI website css for header END -->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
@@ -56,8 +56,8 @@ $extrastylesheet
<ul class="dropdown">
<li><a href="http://gudhi.gforge.inria.fr/licensing/">Licensing</a></li>
<li><a href="https://gforge.inria.fr/frs/?group_id=3865" target="_blank">Get the sources</a></li>
- <li><a href="https://gforge.inria.fr/frs/download.php/file/37113/GUDHI_2.0.0_OSX_UTILS.beta.tar.gz" target="_blank">Utils for Mac OSx</a></li>
- <li><a href="https://gforge.inria.fr/frs/download.php/file/37112/GUDHI_2.0.0_WIN64_UTILS.beta.zip" target="_blank">Utils for Win x64</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37365/2018-02-01-16-59-31_GUDHI_2.1.0_OSX_UTILS.tar.gz" target="_blank">Utils for Mac OSx</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37366/2018-01-31-09-25-53_GUDHI_2.1.0_WIN64_UTILS.zip" target="_blank">Utils for Win x64</a></li>
</ul>
</li>
<li class="divider"></li>
diff --git a/src/common/doc/offline_header.html b/src/common/doc/offline_header.html
new file mode 100644
index 00000000..6a02a895
--- /dev/null
+++ b/src/common/doc/offline_header.html
@@ -0,0 +1,41 @@
+<!-- HTML header for doxygen 1.8.6-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- GUDHI website : class="no-js" lang="en" is necessary -->
+<html xmlns="http://www.w3.org/1999/xhtml" class="no-js" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen $doxygenversion"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<!-- GUDHI website css for header END -->
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
+$treeview
+$search
+$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+$extrastylesheet
+</head>
+<body>
+
+
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+
+<!--BEGIN TITLEAREA-->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 30px;">
+ <!--BEGIN DISABLE_INDEX-->
+ <!--BEGIN SEARCHENGINE-->
+ <td>$searchbox</td>
+ <!--END SEARCHENGINE-->
+ <!--END DISABLE_INDEX-->
+ </tr>
+ </tbody>
+</table>
+</div>
+<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/src/common/example/CMakeLists.txt b/src/common/example/CMakeLists.txt
index afe865d4..1273c699 100644
--- a/src/common/example/CMakeLists.txt
+++ b/src/common/example/CMakeLists.txt
@@ -3,11 +3,20 @@ project(Common_examples)
add_executable ( vector_double_off_reader example_vector_double_points_off_reader.cpp )
target_link_libraries(vector_double_off_reader ${CGAL_LIBRARY})
+file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
add_test(NAME Common_example_vector_double_off_reader COMMAND $<TARGET_FILE:vector_double_off_reader>
- "${CMAKE_SOURCE_DIR}/data/points/SO3_10000.off")
+ "alphacomplexdoc.off")
install(TARGETS vector_double_off_reader DESTINATION bin)
+if (DIFF_PATH)
+ # Do not forget to copy test results files in current binary dir
+ file(COPY "vectordoubleoffreader_result.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+ add_test(Common_example_vector_double_off_reader_diff_files ${DIFF_PATH}
+ ${CMAKE_CURRENT_BINARY_DIR}/vectordoubleoffreader_result.txt ${CMAKE_CURRENT_BINARY_DIR}/alphacomplexdoc.off.txt)
+endif()
+
if(CGAL_FOUND)
add_executable ( cgal_3D_off_reader example_CGAL_3D_points_off_reader.cpp )
target_link_libraries(cgal_3D_off_reader ${CGAL_LIBRARY})
diff --git a/src/common/example/example_CGAL_3D_points_off_reader.cpp b/src/common/example/example_CGAL_3D_points_off_reader.cpp
index 665b7a29..4658d8d5 100644
--- a/src/common/example/example_CGAL_3D_points_off_reader.cpp
+++ b/src/common/example/example_CGAL_3D_points_off_reader.cpp
@@ -20,12 +20,12 @@ int main(int argc, char **argv) {
usage(argv[0]);
}
- std::string offInputFile(argv[1]);
+ std::string off_input_file(argv[1]);
// Read the OFF file (input file name given as parameter) and triangulate points
- Gudhi::Points_3D_off_reader<Point_3> off_reader(offInputFile);
+ Gudhi::Points_3D_off_reader<Point_3> off_reader(off_input_file);
// Check the read operation was correct
if (!off_reader.is_valid()) {
- std::cerr << "Unable to read file " << offInputFile << std::endl;
+ std::cerr << "Unable to read file " << off_input_file << std::endl;
usage(argv[0]);
}
diff --git a/src/common/example/example_CGAL_points_off_reader.cpp b/src/common/example/example_CGAL_points_off_reader.cpp
index 8c6a6b54..f45683a5 100644
--- a/src/common/example/example_CGAL_points_off_reader.cpp
+++ b/src/common/example/example_CGAL_points_off_reader.cpp
@@ -22,12 +22,12 @@ int main(int argc, char **argv) {
usage(argv[0]);
}
- std::string offInputFile(argv[1]);
+ std::string off_input_file(argv[1]);
// Read the OFF file (input file name given as parameter) and triangulate points
- Gudhi::Points_off_reader<Point_d> off_reader(offInputFile);
+ Gudhi::Points_off_reader<Point_d> off_reader(off_input_file);
// Check the read operation was correct
if (!off_reader.is_valid()) {
- std::cerr << "Unable to read file " << offInputFile << std::endl;
+ std::cerr << "Unable to read file " << off_input_file << std::endl;
usage(argv[0]);
}
diff --git a/src/common/example/example_vector_double_points_off_reader.cpp b/src/common/example/example_vector_double_points_off_reader.cpp
index 8aecb26e..5093da85 100644
--- a/src/common/example/example_vector_double_points_off_reader.cpp
+++ b/src/common/example/example_vector_double_points_off_reader.cpp
@@ -17,25 +17,27 @@ int main(int argc, char **argv) {
usage(argv[0]);
}
- std::string offInputFile(argv[1]);
+ std::string off_input_file(argv[1]);
// Read the OFF file (input file name given as parameter) and triangulate points
- Gudhi::Points_off_reader<Point_d> off_reader(offInputFile);
+ Gudhi::Points_off_reader<Point_d> off_reader(off_input_file);
// Check the read operation was correct
if (!off_reader.is_valid()) {
- std::cerr << "Unable to read file " << offInputFile << std::endl;
+ std::cerr << "Unable to read file " << off_input_file << std::endl;
usage(argv[0]);
}
// Retrieve the triangulation
std::vector<Point_d> point_cloud = off_reader.get_point_cloud();
+ std::ofstream output_file(off_input_file + ".txt");
int n {0};
for (auto point : point_cloud) {
- std::cout << "Point[" << n << "] = ";
+ output_file << "Point[" << n << "] = ";
for (std::size_t i {0}; i < point.size(); i++)
- std::cout << point[i] << " ";
- std::cout << "\n";
+ output_file << point[i] << " ";
+ output_file << "\n";
++n;
}
+ output_file.close();
return 0;
}
diff --git a/src/common/example/cgaloffreader_result.txt b/src/common/example/vectordoubleoffreader_result.txt
index 1deb8dbd..1deb8dbd 100644
--- a/src/common/example/cgaloffreader_result.txt
+++ b/src/common/example/vectordoubleoffreader_result.txt
diff --git a/src/common/include/gudhi/Off_reader.h b/src/common/include/gudhi/Off_reader.h
index 4fcd2af2..32320e4d 100644
--- a/src/common/include/gudhi/Off_reader.h
+++ b/src/common/include/gudhi/Off_reader.h
@@ -105,25 +105,26 @@ class Off_reader {
bool is_off_file = (line.find("OFF") != std::string::npos);
bool is_noff_file = (line.find("nOFF") != std::string::npos);
+
+
if (!is_off_file && !is_noff_file) {
std::cerr << line << std::endl;
std::cerr << "missing off header\n";
return false;
}
+ if (is_noff_file) {
+ // Should be on a separate line, but we accept it on the same line as the number of vertices
+ stream_ >> off_info_.dim;
+ } else {
+ off_info_.dim = 3;
+ }
+
if (!goto_next_uncomment_line(line)) return false;
std::istringstream iss(line);
- if ((is_off_file) && (!is_noff_file)) {
- off_info_.dim = 3;
- if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
- std::cerr << "incorrect number of vertices/faces/edges\n";
- return false;
- }
- } else {
- if (!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
+ if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
std::cerr << "incorrect number of vertices/faces/edges\n";
return false;
- }
}
off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges);
@@ -131,10 +132,12 @@ class Off_reader {
}
bool goto_next_uncomment_line(std::string& uncomment_line) {
- uncomment_line.clear();
- do
- std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%');
- return (uncomment_line.size() > 0 && uncomment_line[0] != '%');
+ do {
+ // skip whitespace, including empty lines
+ if (!std::ifstream::sentry(stream_)) return false;
+ std::getline(stream_, uncomment_line);
+ } while (uncomment_line[0] == '#');
+ return (bool)stream_;
}
template<typename OffVisitor>
diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h
index 29af8a8a..08f324c6 100644
--- a/src/common/include/gudhi/Points_off_io.h
+++ b/src/common/include/gudhi/Points_off_io.h
@@ -126,9 +126,9 @@ class Points_off_visitor_reader {
* \code $> ./vector_double_off_reader ../../data/points/alphacomplexdoc.off
* \endcode
*
- * the program output is:
+ * the program outputs a file ../../data/points/alphacomplexdoc.off.txt:
*
- * \include common/cgaloffreader_result.txt
+ * \include common/vectordoubleoffreader_result.txt
*/
template<typename Point_d>
class Points_off_reader {
diff --git a/src/common/include/gudhi/writing_persistence_to_file.h b/src/common/include/gudhi/writing_persistence_to_file.h
new file mode 100644
index 00000000..0e79704b
--- /dev/null
+++ b/src/common/include/gudhi/writing_persistence_to_file.h
@@ -0,0 +1,117 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 2017 Swansea University, UK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef WRITING_PERSISTENCE_TO_FILE_H
+#define WRITING_PERSISTENCE_TO_FILE_H
+
+#include <iostream>
+#include <string>
+#include <limits>
+
+namespace Gudhi {
+
+/**
+* This is a class to store persistence intervals. Its main purpose is to
+* exchange data in between different packages and provide unified way
+* of writing a collection of persistence intervals to file.
+**/
+template <typename Filtration_type, typename Coefficient_field>
+class Persistence_interval_common {
+ public:
+ /**
+ * Constructor taking as an input birth and death of the pair.
+ **/
+ Persistence_interval_common(Filtration_type birth, Filtration_type death)
+ : birth_(birth),
+ death_(death),
+ dimension_(std::numeric_limits<unsigned>::max),
+ arith_element_(std::numeric_limits<Coefficient_field>::max()) {}
+
+ /**
+ * Constructor taking as an input birth, death and dimension of the pair.
+ **/
+ Persistence_interval_common(Filtration_type birth, Filtration_type death, unsigned dim)
+ : birth_(birth), death_(death), dimension_(dim), arith_element_(std::numeric_limits<Coefficient_field>::max()) {}
+
+ /**
+* Constructor taking as an input birth, death, dimension of the pair as well
+* as the number p such that this interval is present over Z_p field.
+**/
+ Persistence_interval_common(Filtration_type birth, Filtration_type death, unsigned dim, Coefficient_field field)
+ : birth_(birth), death_(death), dimension_(dim), arith_element_(field) {}
+
+ /**
+ * Operator to compare two persistence pairs. During the comparision all the
+ * fields: birth, death, dimensiona and arith_element_ are taken into account
+ * and they all have to be equal for two pairs to be equal.
+ **/
+ bool operator==(const Persistence_interval_common& i2) const {
+ return ((this->birth_ == i2.birth_) && (this->death_ == i2.death_) && (this->dimension_ == i2.dimension_) &&
+ (this->arith_element_ == i2.arith_element_));
+ }
+
+ /**
+ * Check if two persistence paris are not equal.
+ **/
+ bool operator!=(const Persistence_interval_common& i2) const { return (!((*this) == i2)); }
+
+ /**
+ * Operator to compare objects of a type Persistence_interval_common.
+ * One intervals is smaller than the other if it has lower persistence.
+ * Note that this operator do not take Arith_element into account when doing comparisions.
+ **/
+ bool operator<(const Persistence_interval_common& i2) const {
+ return fabs(this->death_ - this->birth_) < fabs(i2.death_ - i2.birth_);
+ }
+
+ friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) {
+ if (it.arith_element_ != std::numeric_limits<Coefficient_field>::max()) {
+ out << it.arith_element_ << " ";
+ }
+ if (it.dimension_ != std::numeric_limits<unsigned>::max()) {
+ out << it.dimension_ << " ";
+ }
+ out << it.birth_ << " " << it.death_ << " ";
+ return out;
+ }
+
+ private:
+ Filtration_type birth_;
+ Filtration_type death_;
+ unsigned dimension_;
+ Coefficient_field arith_element_;
+};
+
+/**
+ * This function write a vector<Persistence_interval_common> to a stream
+**/
+template <typename Persistence_interval_range>
+void write_persistence_intervals_to_stream(const Persistence_interval_range& intervals,
+ std::ostream& out = std::cout) {
+ for (auto interval : intervals) {
+ out << interval << "\n";
+ }
+}
+
+}
+
+#endif // WRITING_PERSISTENCE_TO_FILE_H
diff --git a/src/common/utilities/pointsetgenerator.md b/src/common/utilities/pointsetgenerator.md
index 284715d4..3b23e668 100644
--- a/src/common/utilities/pointsetgenerator.md
+++ b/src/common/utilities/pointsetgenerator.md
@@ -1,6 +1,16 @@
-
-
-# common #
+---
+layout: page
+title: "OFF point set generator"
+meta_title: "OFF point set generator"
+teaser: ""
+permalink: /pointsetgenerator/
+---
+{::comment}
+Leave the lines above as it is required by the web site generator 'Jekyll'
+{:/comment}
+
+
+# Miscellaneous #
## off_file_from_shape_generator ##
diff --git a/src/cython/cython/off_reader.pyx b/src/cython/cython/off_reader.pyx
index b6e107ef..266dae2c 100644
--- a/src/cython/cython/off_reader.pyx
+++ b/src/cython/cython/off_reader.pyx
@@ -46,4 +46,5 @@ def read_off(off_file=''):
return read_points_from_OFF_file(str.encode(off_file))
else:
print("file " + off_file + " not found.")
+ return []
diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx
index ad9b0a4d..73b154b8 100644
--- a/src/cython/cython/rips_complex.pyx
+++ b/src/cython/cython/rips_complex.pyx
@@ -34,8 +34,6 @@ __license__ = "GPL v3"
cdef extern from "Rips_complex_interface.h" namespace "Gudhi":
cdef cppclass Rips_complex_interface "Gudhi::rips_complex::Rips_complex_interface":
Rips_complex_interface(vector[vector[double]] values, double threshold, bool euclidean)
- # bool from_file is a workaround for cython to find the correct signature
- Rips_complex_interface(string file_name, double threshold, bool euclidean, bool from_file)
void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, int dim_max)
# RipsComplex python interface
@@ -49,7 +47,7 @@ cdef class RipsComplex:
cdef Rips_complex_interface * thisptr
# Fake constructor that does nothing but documenting the constructor
- def __init__(self, points=None, off_file='', distance_matrix=None, csv_file='', max_edge_length=float('inf')):
+ def __init__(self, points=None, distance_matrix=None, max_edge_length=float('inf')):
"""RipsComplex constructor.
:param max_edge_length: Rips value.
@@ -60,41 +58,14 @@ cdef class RipsComplex:
Or
- :param off_file: An OFF file style name.
- :type off_file: string
-
- Or
-
:param distance_matrix: A distance matrix (full square or lower
triangular).
:type points: list of list of double
-
- Or
-
- :param csv_file: A csv file style name containing a full square or a
- lower triangular distance matrix.
- :type csv_file: string
"""
# The real cython constructor
- def __cinit__(self, points=None, off_file='', distance_matrix=None, csv_file='', max_edge_length=float('inf')):
- if off_file is not '':
- if os.path.isfile(off_file):
- self.thisptr = new Rips_complex_interface(str.encode(off_file),
- max_edge_length,
- True,
- True)
- else:
- print("file " + off_file + " not found.")
- elif csv_file is not '':
- if os.path.isfile(csv_file):
- self.thisptr = new Rips_complex_interface(str.encode(csv_file),
- max_edge_length,
- False,
- True)
- else:
- print("file " + csv_file + " not found.")
- elif distance_matrix is not None:
+ def __cinit__(self, points=None, distance_matrix=None, max_edge_length=float('inf')):
+ if distance_matrix is not None:
self.thisptr = new Rips_complex_interface(distance_matrix, max_edge_length, False)
else:
if points is None:
diff --git a/src/cython/doc/_templates/layout.html b/src/cython/doc/_templates/layout.html
index 8e4eba40..c9356116 100644
--- a/src/cython/doc/_templates/layout.html
+++ b/src/cython/doc/_templates/layout.html
@@ -198,8 +198,8 @@
<ul class="dropdown">
<li><a href="http://gudhi.gforge.inria.fr/licensing/">Licensing</a></li>
<li><a href="https://gforge.inria.fr/frs/?group_id=3865" target="_blank">Get the sources</a></li>
- <li><a href="https://gforge.inria.fr/frs/download.php/file/37113/GUDHI_2.0.0_OSX_UTILS.beta.tar.gz" target="_blank">Utils for Mac OSx</a></li>
- <li><a href="https://gforge.inria.fr/frs/download.php/file/37112/GUDHI_2.0.0_WIN64_UTILS.beta.zip" target="_blank">Utils for Win x64</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37365/2018-02-01-16-59-31_GUDHI_2.1.0_OSX_UTILS.tar.gz" target="_blank">Utils for Mac OSx</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37366/2018-01-31-09-25-53_GUDHI_2.1.0_WIN64_UTILS.zip" target="_blank">Utils for Win x64</a></li>
</ul>
</li>
<li class="divider"></li>
diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst
index 9033331f..a5523d23 100644
--- a/src/cython/doc/persistence_graphical_tools_user.rst
+++ b/src/cython/doc/persistence_graphical_tools_user.rst
@@ -58,8 +58,8 @@ This function can display the persistence result as a diagram:
import gudhi
- rips_complex = gudhi.RipsComplex(off_file=gudhi.__root_source_dir__ + \
- '/data/points/tore3D_1307.off', max_edge_length=0.2)
+ point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + '/data/points/tore3D_1307.off')
+ rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.2)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=3)
diag = simplex_tree.persistence()
plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13)
@@ -69,8 +69,8 @@ This function can display the persistence result as a diagram:
import gudhi
- rips_complex = gudhi.RipsComplex(off_file=gudhi.__root_source_dir__ + \
- '/data/points/tore3D_1307.off', max_edge_length=0.2)
+ point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + '/data/points/tore3D_1307.off')
+ rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.2)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=3)
diag = simplex_tree.persistence()
plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13)
diff --git a/src/cython/doc/pyplots/diagram_persistence.py b/src/cython/doc/pyplots/diagram_persistence.py
index c2fbf801..ac20bf47 100755
--- a/src/cython/doc/pyplots/diagram_persistence.py
+++ b/src/cython/doc/pyplots/diagram_persistence.py
@@ -1,7 +1,8 @@
import gudhi
-rips_complex = gudhi.RipsComplex(off_file=gudhi.__root_source_dir__ + \
- '/data/points/tore3D_1307.off', max_edge_length=0.2)
+point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + \
+ '/data/points/tore3D_1307.off')
+rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.2)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=3)
diag = simplex_tree.persistence()
plt = gudhi.plot_persistence_diagram(diag, band_boot=0.13)
diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst
index 96ba9944..7738aef0 100644
--- a/src/cython/doc/rips_complex_user.rst
+++ b/src/cython/doc/rips_complex_user.rst
@@ -101,8 +101,8 @@ Finally, it is asked to display information about the Rips complex.
.. testcode::
import gudhi
- rips_complex = gudhi.RipsComplex(off_file=gudhi.__root_source_dir__ + \
- '/data/points/alphacomplexdoc.off', max_edge_length=12.0)
+ point_cloud = gudhi.read_off(off_file=gudhi.__root_source_dir__ + '/data/points/alphacomplexdoc.off')
+ rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=12.0)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=1)
result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \
repr(simplex_tree.num_simplices()) + ' simplices - ' + \
@@ -197,7 +197,7 @@ Example from csv file
^^^^^^^^^^^^^^^^^^^^^
This example builds the :doc:`Rips_complex <rips_complex_ref>` from the given
-points in an OFF file, and max_edge_length value.
+distance matrix in a csv file, and max_edge_length value.
Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
Finally, it is asked to display information about the Rips complex.
@@ -206,8 +206,9 @@ Finally, it is asked to display information about the Rips complex.
.. testcode::
import gudhi
- rips_complex = gudhi.RipsComplex(csv_file=gudhi.__root_source_dir__ + \
- '/data/distance_matrix/full_square_distance_matrix.csv', max_edge_length=12.0)
+ distance_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=gudhi.__root_source_dir__ + \
+ '/data/distance_matrix/full_square_distance_matrix.csv')
+ rips_complex = gudhi.RipsComplex(distance_matrix=distance_matrix, max_edge_length=12.0)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=1)
result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \
repr(simplex_tree.num_simplices()) + ' simplices - ' + \
@@ -240,3 +241,72 @@ the program output is:
[0, 3] -> 9.43
[4, 6] -> 9.49
[3, 6] -> 11.00
+
+Correlation matrix
+---------------
+
+Example from a correlation matrix
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Analogously to the case of distance matrix, Rips complexes can be also constructed based on correlation matrix.
+Given a correlation matrix M, comportment-wise 1-M is a distance matrix.
+This example builds the one skeleton graph from the given corelation matrix and threshold value.
+Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
+
+Finally, it is asked to display information about the simplicial complex.
+
+.. testcode::
+
+ import gudhi
+ import numpy as np
+
+ # User defined correlation matrix is:
+ # |1 0.06 0.23 0.01 0.89|
+ # |0.06 1 0.74 0.01 0.61|
+ # |0.23 0.74 1 0.72 0.03|
+ # |0.01 0.01 0.72 1 0.7 |
+ # |0.89 0.61 0.03 0.7 1 |
+ correlation_matrix=np.array([[1., 0.06, 0.23, 0.01, 0.89],
+ [0.06, 1., 0.74, 0.01, 0.61],
+ [0.23, 0.74, 1., 0.72, 0.03],
+ [0.01, 0.01, 0.72, 1., 0.7],
+ [0.89, 0.61, 0.03, 0.7, 1.]], float)
+
+ distance_matrix = np.ones((correlation_matrix.shape),float) - correlation_matrix
+ rips_complex = gudhi.RipsComplex(distance_matrix=distance_matrix, max_edge_length=1.0)
+
+ simplex_tree = rips_complex.create_simplex_tree(max_dimension=1)
+ result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \
+ repr(simplex_tree.num_simplices()) + ' simplices - ' + \
+ repr(simplex_tree.num_vertices()) + ' vertices.'
+ print(result_str)
+ fmt = '%s -> %.2f'
+ for filtered_value in simplex_tree.get_filtration():
+ print(fmt % tuple(filtered_value))
+
+When launching (Rips maximal distance between 2 points is 12.0, is expanded
+until dimension 1 - one skeleton graph in other words), the output is:
+
+.. testoutput::
+
+ Rips complex is of dimension 1 - 15 simplices - 5 vertices.
+ [0] -> 0.00
+ [1] -> 0.00
+ [2] -> 0.00
+ [3] -> 0.00
+ [4] -> 0.00
+ [0, 4] -> 0.11
+ [1, 2] -> 0.26
+ [2, 3] -> 0.28
+ [3, 4] -> 0.30
+ [1, 4] -> 0.39
+ [0, 2] -> 0.77
+ [0, 1] -> 0.94
+ [2, 4] -> 0.97
+ [0, 3] -> 0.99
+ [1, 3] -> 0.99
+
+.. note::
+ As persistence diagrams points will be under the diagonal,
+ bottleneck distance and persistence graphical tool will not work properly,
+ this is a known issue.
diff --git a/src/cython/example/alpha_rips_persistence_bottleneck_distance.py b/src/cython/example/alpha_rips_persistence_bottleneck_distance.py
index ab5fc1e9..386f8457 100755
--- a/src/cython/example/alpha_rips_persistence_bottleneck_distance.py
+++ b/src/cython/example/alpha_rips_persistence_bottleneck_distance.py
@@ -45,13 +45,14 @@ args = parser.parse_args()
with open(args.file, 'r') as f:
first_line = f.readline()
if (first_line == 'OFF\n') or (first_line == 'nOFF\n'):
+ point_cloud = gudhi.read_off(off_file=args.file)
print("#####################################################################")
print("RipsComplex creation from points read in a OFF file")
message = "RipsComplex with max_edge_length=" + repr(args.threshold)
print(message)
- rips_complex = gudhi.RipsComplex(off_file=args.file,
+ rips_complex = gudhi.RipsComplex(points=point_cloud,
max_edge_length=args.threshold)
rips_stree = rips_complex.create_simplex_tree(max_dimension=args.max_dimension)
@@ -67,7 +68,7 @@ with open(args.file, 'r') as f:
message = "AlphaComplex with max_edge_length=" + repr(args.threshold)
print(message)
- alpha_complex = gudhi.AlphaComplex(off_file=args.file)
+ alpha_complex = gudhi.AlphaComplex(points=point_cloud)
alpha_stree = alpha_complex.create_simplex_tree(max_alpha_square=(args.threshold * args.threshold))
message = "Number of simplices=" + repr(alpha_stree.num_simplices())
diff --git a/src/cython/example/bottleneck_basic_example.py b/src/cython/example/bottleneck_basic_example.py
index 31cecb29..a7fa01c1 100755
--- a/src/cython/example/bottleneck_basic_example.py
+++ b/src/cython/example/bottleneck_basic_example.py
@@ -28,8 +28,6 @@ __author__ = "Francois Godi, Vincent Rouvreau"
__copyright__ = "Copyright (C) 2016 INRIA"
__license__ = "GPL v3"
-import gudhi
-
diag1 = [[2.7, 3.7],[9.6, 14.],[34.2, 34.974], [3.,float('Inf')]]
diag2 = [[2.8, 4.45],[9.5, 14.1],[3.2,float('Inf')]]
diff --git a/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py
new file mode 100755
index 00000000..aa82ef71
--- /dev/null
+++ b/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+import gudhi
+import sys
+import argparse
+
+"""This file is part of the Gudhi Library. The Gudhi library
+ (Geometric Understanding in Higher Dimensions) is a generic C++
+ library for computational topology.
+
+ Author(s): Vincent Rouvreau
+
+ Copyright (C) 2017 INRIA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+__author__ = "Vincent Rouvreau"
+__copyright__ = "Copyright (C) 2017 INRIA"
+__license__ = "GPL v3"
+
+parser = argparse.ArgumentParser(description='RipsComplex creation from '
+ 'a correlation matrix read in a csv file.',
+ epilog='Example: '
+ 'example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py '
+ '-f ../data/correlation_matrix/lower_triangular_correlation_matrix.csv -e 12.0 -d 3'
+ '- Constructs a Rips complex with the '
+ 'correlation matrix from the given csv file.')
+parser.add_argument("-f", "--file", type=str, required=True)
+parser.add_argument("-c", "--min_edge_correlation", type=float, default=0.5)
+parser.add_argument("-d", "--max_dimension", type=int, default=1)
+parser.add_argument("-b", "--band_boot", type=float, default=0.)
+parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
+
+args = parser.parse_args()
+
+if not (-1. < args.min_edge_correlation < 1.):
+ print("Wrong value of the treshold corelation (should be between -1 and 1).")
+ sys.exit(1)
+
+print("#####################################################################")
+print("Caution: as persistence diagrams points will be under the diagonal,")
+print("bottleneck distance and persistence graphical tool will not work")
+print("properly, this is a known issue.")
+
+print("#####################################################################")
+print("RipsComplex creation from correlation matrix read in a csv file")
+
+message = "RipsComplex with min_edge_correlation=" + repr(args.min_edge_correlation)
+print(message)
+
+correlation_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=args.file)
+# Given a correlation matrix M, we compute component-wise M'[i,j] = 1-M[i,j] to get a distance matrix:
+distance_matrix = [[1.-correlation_matrix[i][j] for j in range(len(correlation_matrix[i]))] for i in range(len(correlation_matrix))]
+
+rips_complex = gudhi.RipsComplex(distance_matrix=distance_matrix,
+ max_edge_length=1.-args.min_edge_correlation)
+simplex_tree = rips_complex.create_simplex_tree(max_dimension=args.max_dimension)
+
+message = "Number of simplices=" + repr(simplex_tree.num_simplices())
+print(message)
+
+diag = simplex_tree.persistence()
+
+print("betti_numbers()=")
+print(simplex_tree.betti_numbers())
+
+# invert the persistence diagram
+invert_diag = [(diag[pers][0],(1.-diag[pers][1][0], 1.-diag[pers][1][1])) for pers in range(len(diag))]
+
+if args.no_diagram == False:
+ pplot = gudhi.plot_persistence_diagram(invert_diag, band_boot=args.band_boot)
+ pplot.show()
diff --git a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
index 3baebd17..c8aac240 100755
--- a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
+++ b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
@@ -30,12 +30,12 @@ __copyright__ = "Copyright (C) 2016 INRIA"
__license__ = "GPL v3"
parser = argparse.ArgumentParser(description='RipsComplex creation from '
- 'a distance matrix read in a OFF file.',
+ 'a distance matrix read in a csv file.',
epilog='Example: '
'example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py '
'-f ../data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3'
'- Constructs a Rips complex with the '
- 'points from the given OFF file.')
+ 'distance matrix from the given csv file.')
parser.add_argument("-f", "--file", type=str, required=True)
parser.add_argument("-e", "--max_edge_length", type=float, default=0.5)
parser.add_argument("-d", "--max_dimension", type=int, default=1)
@@ -50,7 +50,8 @@ print("RipsComplex creation from distance matrix read in a csv file")
message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length)
print(message)
-rips_complex = gudhi.RipsComplex(csv_file=args.file, max_edge_length=args.max_edge_length)
+distance_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=args.file)
+rips_complex = gudhi.RipsComplex(distance_matrix=distance_matrix, max_edge_length=args.max_edge_length)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=args.max_dimension)
message = "Number of simplices=" + repr(simplex_tree.num_simplices())
diff --git a/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
index 5951eedf..544b68c9 100755
--- a/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
+++ b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
@@ -53,7 +53,8 @@ with open(args.file, 'r') as f:
message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length)
print(message)
- rips_complex = gudhi.RipsComplex(off_file=args.file, max_edge_length=args.max_edge_length)
+ point_cloud = gudhi.read_off(off_file=args.file)
+ rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=args.max_edge_length)
simplex_tree = rips_complex.create_simplex_tree(max_dimension=args.max_dimension)
message = "Number of simplices=" + repr(simplex_tree.num_simplices())
diff --git a/src/cython/include/Rips_complex_interface.h b/src/cython/include/Rips_complex_interface.h
index 02985727..f26befbc 100644
--- a/src/cython/include/Rips_complex_interface.h
+++ b/src/cython/include/Rips_complex_interface.h
@@ -25,9 +25,7 @@
#include <gudhi/Simplex_tree.h>
#include <gudhi/Rips_complex.h>
-#include <gudhi/Points_off_io.h>
#include <gudhi/distance_functions.h>
-#include <gudhi/reader_utils.h>
#include "Simplex_tree_interface.h"
@@ -56,21 +54,6 @@ class Rips_complex_interface {
}
}
- Rips_complex_interface(const std::string& file_name, double threshold, bool euclidean, bool from_file = true) {
- if (euclidean) {
- // Rips construction where file_name is an OFF file
- Gudhi::Points_off_reader<Point_d> off_reader(file_name);
- rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(off_reader.get_point_cloud(),
- threshold,
- Gudhi::Euclidean_distance());
- } else {
- // Rips construction where values is a distance matrix
- Distance_matrix distances =
- Gudhi::read_lower_triangular_matrix_from_csv_file<Simplex_tree_interface<>::Filtration_value>(file_name);
- rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(distances, threshold);
- }
- }
-
~Rips_complex_interface() {
delete rips_complex_;
}