summaryrefslogtreecommitdiff
path: root/src/Persistent_cohomology
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2017-04-01 08:59:44 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2017-04-01 08:59:44 +0000
commit39cd1e8ab33bd069236649edc10459925cea83f4 (patch)
tree23c2138114ebcdfa6c75daf0a0268a1eaa0049ad /src/Persistent_cohomology
parent5084fc612a5f8ed47a80771785e5c26ee4e42d94 (diff)
parentdd108b5a6c620b10675b7ebaf8d1561c2c165bf2 (diff)
Merge last trunk modifications and fix new rips interface
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/gudhi_stat@2299 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1e836cba1a372f609e94b66b6db512817a3d875e
Diffstat (limited to 'src/Persistent_cohomology')
-rw-r--r--src/Persistent_cohomology/benchmark/CMakeLists.txt14
-rw-r--r--src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp (renamed from src/Persistent_cohomology/example/performance_rips_persistence.cpp)36
-rw-r--r--src/Persistent_cohomology/doc/COPYRIGHT19
-rw-r--r--src/Persistent_cohomology/doc/Intro_persistent_cohomology.h42
-rw-r--r--src/Persistent_cohomology/example/CMakeLists.txt98
-rw-r--r--src/Persistent_cohomology/example/README50
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_3d_helper.h76
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp140
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_persistence.cpp66
-rw-r--r--src/Persistent_cohomology/example/custom_persistence_sort.cpp89
-rw-r--r--src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp245
-rw-r--r--src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp79
-rw-r--r--src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp19
-rw-r--r--src/Persistent_cohomology/example/plain_homology.cpp11
-rw-r--r--src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp144
-rw-r--r--src/Persistent_cohomology/example/rips_multifield_persistence.cpp58
-rw-r--r--src/Persistent_cohomology/example/rips_persistence.cpp60
-rw-r--r--src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp217
-rw-r--r--src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp52
-rw-r--r--src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp263
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h26
-rw-r--r--src/Persistent_cohomology/test/betti_numbers_unit_test.cpp57
-rw-r--r--src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp4
23 files changed, 1452 insertions, 413 deletions
diff --git a/src/Persistent_cohomology/benchmark/CMakeLists.txt b/src/Persistent_cohomology/benchmark/CMakeLists.txt
new file mode 100644
index 00000000..ea792c89
--- /dev/null
+++ b/src/Persistent_cohomology/benchmark/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.6)
+project(Persistent_cohomology_benchmark)
+
+
+if(GMP_FOUND)
+ if(GMPXX_FOUND)
+ add_executable ( performance_rips_persistence EXCLUDE_FROM_ALL performance_rips_persistence.cpp )
+ target_link_libraries(performance_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+ if (TBB_FOUND)
+ target_link_libraries(performance_rips_persistence ${TBB_LIBRARIES})
+ endif(TBB_FOUND)
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/Kl.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ endif(GMPXX_FOUND)
+endif(GMP_FOUND)
diff --git a/src/Persistent_cohomology/example/performance_rips_persistence.cpp b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp
index b4d282ac..ba752999 100644
--- a/src/Persistent_cohomology/example/performance_rips_persistence.cpp
+++ b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp
@@ -20,20 +20,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
-#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Rips_complex.h>
#include <gudhi/distance_functions.h>
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
#include <gudhi/Persistent_cohomology/Multi_field.h>
#include <gudhi/Hasse_complex.h>
+#include <gudhi/Points_off_io.h>
#include <chrono>
#include <string>
#include <vector>
-using namespace Gudhi;
-using namespace Gudhi::persistent_cohomology;
+// 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 Multi_field = Gudhi::persistent_cohomology::Multi_field;
+using Point = std::vector<double>;
+using Points_off_reader = Gudhi::Points_off_reader<Point>;
/* Compute the persistent homology of the complex cpx with coefficients in Z/pZ. */
template< typename FilteredComplex>
@@ -66,33 +72,29 @@ int main(int argc, char * argv[]) {
int elapsed_sec;
{
- std::string filepoints = "../../../data/points/Kl.txt";
+ std::string off_file_points = "Kl.off";
Filtration_value threshold = 0.27;
int dim_max = 3;
int p = 2;
int q = 1223;
- // Extract the points from the file filepoints
- typedef std::vector<double> Point_t;
- std::vector< Point_t > points;
- read_points(filepoints, points);
+ // Extract the points from the file off_file_points
+ Points_off_reader off_reader(off_file_points);
// Compute the proximity graph of the points
start = std::chrono::system_clock::now();
- Graph_t prox_graph = compute_proximity_graph(points, threshold
- , euclidean_distance<Point_t>);
+ Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance());
end = std::chrono::system_clock::now();
elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "Compute Rips graph in " << elapsed_sec << " ms.\n";
// Construct the Rips complex in a Simplex Tree
- Simplex_tree<Simplex_tree_options_fast_persistence> st;
+ Simplex_tree st;
start = std::chrono::system_clock::now();
// insert the proximity graph in the simplex tree
- st.insert_graph(prox_graph);
// expand the graph until dimension dim_max
- st.expansion(dim_max);
+ rips_complex_from_file.create_complex(st, dim_max);
end = std::chrono::system_clock::now();
elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
@@ -120,7 +122,7 @@ int main(int argc, char * argv[]) {
// Convert the simplex tree into a hasse diagram
start = std::chrono::system_clock::now();
- Hasse_complex<> hcpx(st);
+ Gudhi::Hasse_complex<> hcpx(st);
end = std::chrono::system_clock::now();
elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "Convert the simplex tree into a Hasse diagram in " << elapsed_sec << " ms.\n";
@@ -152,7 +154,7 @@ timing_persistence(FilteredComplex & cpx
int elapsed_sec;
{
start = std::chrono::system_clock::now();
- Persistent_cohomology< FilteredComplex, Field_Zp > pcoh(cpx);
+ Gudhi::persistent_cohomology::Persistent_cohomology< FilteredComplex, Field_Zp > pcoh(cpx);
end = std::chrono::system_clock::now();
elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << " Initialize pcoh in " << elapsed_sec << " ms.\n";
@@ -186,7 +188,7 @@ timing_persistence(FilteredComplex & cpx
int elapsed_sec;
{
start = std::chrono::system_clock::now();
- Persistent_cohomology< FilteredComplex, Multi_field > pcoh(cpx);
+ Gudhi::persistent_cohomology::Persistent_cohomology< FilteredComplex, Multi_field > pcoh(cpx);
end = std::chrono::system_clock::now();
elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << " Initialize pcoh in " << elapsed_sec << " ms.\n";
diff --git a/src/Persistent_cohomology/doc/COPYRIGHT b/src/Persistent_cohomology/doc/COPYRIGHT
new file mode 100644
index 00000000..34345bef
--- /dev/null
+++ b/src/Persistent_cohomology/doc/COPYRIGHT
@@ -0,0 +1,19 @@
+The files of this directory are part of the Gudhi Library. The Gudhi library
+(Geometric Understanding in Higher Dimensions) is a generic C++ library for
+computational topology.
+
+Author(s): Clément Maria
+
+Copyright (C) 2015 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/>.
diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
index 433cfd3e..e17e5926 100644
--- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
+++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
@@ -144,17 +144,23 @@ namespace persistent_cohomology {
We provide several example files: run these examples with -h for details on their use, and read the README file.
\li <a href="_persistent_cohomology_2rips_persistence_8cpp-example.html">
-Persistent_cohomology/rips_persistence.cpp</a> computes the Rips complex of a point cloud and its persistence diagram.
+Persistent_cohomology/rips_persistence.cpp</a> computes the Rips complex of a point cloud and outputs its persistence
+diagram.
+\code $> ./rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3 \endcode
+\code The complex contains 177838 simplices
+ and has dimension 3
+3 0 0 inf
+3 1 0.0983494 inf
+3 1 0.104347 inf
+3 2 0.138335 inf \endcode
\li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
-Persistent_cohomology/rips_multifield_persistence.cpp</a> computes the Rips complex of a point cloud and its
+Persistent_cohomology/rips_multifield_persistence.cpp</a> computes the Rips complex of a point cloud and outputs its
persistence diagram with a family of field coefficients.
-\li <a href="_persistent_cohomology_2performance_rips_persistence_8cpp-example.html">
-Persistent_cohomology/performance_rips_persistence.cpp</a> provides timings for the construction of the Rips complex
-on a set of points sampling a Klein bottle in \f$\mathbb{R}^5\f$ with a simplex tree, its conversion to a
-Hasse diagram and the computation of persistent homology and multi-field persistent homology for the
-different representations.
+\li <a href="_persistent_cohomology_2rips_distance_matrix_persistence_8cpp-example.html">
+Persistent_cohomology/rips_distance_matrix_persistence.cpp</a> computes the Rips complex of a distance matrix and
+outputs its persistence diagram.
\li <a href="_persistent_cohomology_2alpha_complex_3d_persistence_8cpp-example.html">
Persistent_cohomology/alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
@@ -166,6 +172,28 @@ Persistent_cohomology/alpha_complex_3d_persistence.cpp</a> computes the persiste
2 1 0.0934117 1.00003
2 2 0.56444 1.03938 \endcode
+\li <a href="_persistent_cohomology_2exact_alpha_complex_3d_persistence_8cpp-example.html">
+Persistent_cohomology/exact_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.
+Here, as CGAL computes the exact values, it is slower, but it is necessary when points are on a grid
+for instance.
+\code $> ./exact_alpha_complex_3d_persistence ../../data/points/sphere3D_pts_on_grid.off 2 0.1 \endcode
+\code Simplex_tree dim: 3
+2 0 0 inf
+2 2 0.0002 0.2028 \endcode
+
+\li <a href="_persistent_cohomology_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
+Persistent_cohomology/weighted_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
+\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the weighted alpha complex on points sampling from an OFF file
+and a weights file.
+\code $> ./weighted_alpha_complex_3d_persistence ../../data/points/tore3D_300.off
+../../data/points/tore3D_300.weights 2 0.45 \endcode
+\code Simplex_tree dim: 3
+2 -0 0 inf
+2 1 0.0682162 1.0001
+2 1 0.0934117 1.00003
+2 2 0.56444 1.03938 \endcode
+
\li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html">
Persistent_cohomology/alpha_complex_persistence.cpp</a> computes the persistent homology with
\f$\mathbb{Z}/p\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt
index d97d1b63..a6b698c3 100644
--- a/src/Persistent_cohomology/example/CMakeLists.txt
+++ b/src/Persistent_cohomology/example/CMakeLists.txt
@@ -1,19 +1,21 @@
cmake_minimum_required(VERSION 2.6)
project(Persistent_cohomology_examples)
-# problem with Visual Studio link on Boost program_options
-add_definitions( -DBOOST_ALL_NO_LIB )
-add_definitions( -DBOOST_ALL_DYN_LINK )
-
add_executable(plain_homology plain_homology.cpp)
target_link_libraries(plain_homology ${Boost_SYSTEM_LIBRARY})
add_executable(persistence_from_simple_simplex_tree persistence_from_simple_simplex_tree.cpp)
target_link_libraries(persistence_from_simple_simplex_tree ${Boost_SYSTEM_LIBRARY})
+add_executable(rips_distance_matrix_persistence rips_distance_matrix_persistence.cpp)
+target_link_libraries(rips_distance_matrix_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+
add_executable(rips_persistence rips_persistence.cpp)
target_link_libraries(rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+add_executable(rips_persistence_step_by_step rips_persistence_step_by_step.cpp)
+target_link_libraries(rips_persistence_step_by_step ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+
add_executable(rips_persistence_via_boundary_matrix rips_persistence_via_boundary_matrix.cpp)
target_link_libraries(rips_persistence_via_boundary_matrix ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
@@ -23,62 +25,82 @@ target_link_libraries(persistence_from_file ${Boost_SYSTEM_LIBRARY} ${Boost_PROG
if (TBB_FOUND)
target_link_libraries(plain_homology ${TBB_LIBRARIES})
target_link_libraries(persistence_from_simple_simplex_tree ${TBB_LIBRARIES})
+ target_link_libraries(rips_distance_matrix_persistence ${TBB_LIBRARIES})
target_link_libraries(rips_persistence ${TBB_LIBRARIES})
+ target_link_libraries(rips_persistence_step_by_step ${TBB_LIBRARIES})
target_link_libraries(rips_persistence_via_boundary_matrix ${TBB_LIBRARIES})
target_link_libraries(persistence_from_file ${TBB_LIBRARIES})
endif()
add_test(plain_homology ${CMAKE_CURRENT_BINARY_DIR}/plain_homology)
add_test(persistence_from_simple_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_simple_simplex_tree 1 0)
-add_test(rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.2 -d 3 -p 3 -m 100)
-add_test(rips_persistence_via_boundary_matrix_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence_via_boundary_matrix ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.txt -r 0.3 -d 3 -p 3 -m 100)
-add_test(persistence_from_file_3_2_0 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 2 -m 0)
-add_test(persistence_from_file_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
+add_test(rips_distance_matrix ${CMAKE_CURRENT_BINARY_DIR}/rips_distance_matrix_persistence
+ ${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv -r 1.0 -d 3 -p 3 -m 0)
+add_test(rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3)
+add_test(rips_persistence_step_by_step_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence_step_by_step
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3)
+add_test(rips_persistence_via_boundary_matrix_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence_via_boundary_matrix
+ ${CMAKE_SOURCE_DIR}/data/points/Kl.off -r 0.16 -d 3 -p 3 -m 100)
+add_test(persistence_from_file_3_2_0 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file
+ ${CMAKE_SOURCE_DIR}/data/filtered_simplicial_complex/bunny_5000_complex.fsc -p 2 -m 0)
+add_test(persistence_from_file_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file
+ ${CMAKE_SOURCE_DIR}/data/filtered_simplicial_complex/bunny_5000_complex.fsc -p 3 -m 100)
if(GMP_FOUND)
if(GMPXX_FOUND)
add_executable(rips_multifield_persistence rips_multifield_persistence.cpp )
- target_link_libraries(rips_multifield_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
- add_executable ( performance_rips_persistence performance_rips_persistence.cpp )
- target_link_libraries(performance_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+ target_link_libraries(rips_multifield_persistence
+ ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
if (TBB_FOUND)
target_link_libraries(rips_multifield_persistence ${TBB_LIBRARIES})
- target_link_libraries(performance_rips_persistence ${TBB_LIBRARIES})
endif(TBB_FOUND)
-
- add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.2 -d 3 -p 2 -q 71 -m 100)
+ add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 2 -q 71)
endif(GMPXX_FOUND)
endif(GMP_FOUND)
if(CGAL_FOUND)
add_executable(alpha_complex_3d_persistence alpha_complex_3d_persistence.cpp)
target_link_libraries(alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ add_executable(exact_alpha_complex_3d_persistence exact_alpha_complex_3d_persistence.cpp)
+ target_link_libraries(exact_alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp)
+ target_link_libraries(weighted_alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
if (TBB_FOUND)
target_link_libraries(alpha_complex_3d_persistence ${TBB_LIBRARIES})
+ target_link_libraries(exact_alpha_complex_3d_persistence ${TBB_LIBRARIES})
+ target_link_libraries(weighted_alpha_complex_3d_persistence ${TBB_LIBRARIES})
endif(TBB_FOUND)
- add_test(alpha_complex_3d_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_complex_3d_persistence ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off 2 0.45)
-
-
- if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
- if (EIGEN3_FOUND)
- add_executable (alpha_complex_persistence alpha_complex_persistence.cpp)
- target_link_libraries(alpha_complex_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
-
- add_executable(periodic_alpha_complex_3d_persistence periodic_alpha_complex_3d_persistence.cpp)
- target_link_libraries(periodic_alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
-
- add_executable(custom_persistence_sort custom_persistence_sort.cpp)
- target_link_libraries(custom_persistence_sort ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
-
- if (TBB_FOUND)
- target_link_libraries(alpha_complex_persistence ${TBB_LIBRARIES})
- target_link_libraries(periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES})
- target_link_libraries(custom_persistence_sort ${TBB_LIBRARIES})
- endif(TBB_FOUND)
- add_test(alpha_complex_persistence_2_0_45 ${CMAKE_CURRENT_BINARY_DIR}/alpha_complex_persistence ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -m 0.45 -p 2)
- add_test(periodic_alpha_complex_3d_persistence_2_0 ${CMAKE_CURRENT_BINARY_DIR}/periodic_alpha_complex_3d_persistence ${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off ${CMAKE_SOURCE_DIR}/data/points/iso_cuboid_3_in_0_1.txt 2 0)
- add_test(custom_persistence_sort ${CMAKE_CURRENT_BINARY_DIR}/custom_persistence_sort)
- endif(EIGEN3_FOUND)
- endif (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ add_test(alpha_complex_3d_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_complex_3d_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off 2 0.45)
+ add_test(exact_alpha_complex_3d_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/exact_alpha_complex_3d_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off 2 0.45)
+ add_test(weighted_alpha_complex_3d_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/weighted_alpha_complex_3d_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.weights 2 0.45)
+
+
+ if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0)
+ add_executable (alpha_complex_persistence alpha_complex_persistence.cpp)
+ target_link_libraries(alpha_complex_persistence
+ ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+
+ add_executable(periodic_alpha_complex_3d_persistence periodic_alpha_complex_3d_persistence.cpp)
+ target_link_libraries(periodic_alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+
+ add_executable(custom_persistence_sort custom_persistence_sort.cpp)
+ target_link_libraries(custom_persistence_sort ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+
+ if (TBB_FOUND)
+ target_link_libraries(alpha_complex_persistence ${TBB_LIBRARIES})
+ target_link_libraries(periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES})
+ target_link_libraries(custom_persistence_sort ${TBB_LIBRARIES})
+ endif(TBB_FOUND)
+ add_test(alpha_complex_persistence_2_0_45 ${CMAKE_CURRENT_BINARY_DIR}/alpha_complex_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -m 0.45 -p 2)
+ add_test(periodic_alpha_complex_3d_persistence_2_0 ${CMAKE_CURRENT_BINARY_DIR}/periodic_alpha_complex_3d_persistence
+ ${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off ${CMAKE_SOURCE_DIR}/data/points/iso_cuboid_3_in_0_1.txt 2 0)
+ add_test(custom_persistence_sort ${CMAKE_CURRENT_BINARY_DIR}/custom_persistence_sort)
+ endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0)
endif(CGAL_FOUND)
diff --git a/src/Persistent_cohomology/example/README b/src/Persistent_cohomology/example/README
index 7803e5ab..2ac79398 100644
--- a/src/Persistent_cohomology/example/README
+++ b/src/Persistent_cohomology/example/README
@@ -10,13 +10,13 @@ Example of use of RIPS:
Computation of the persistent homology with Z/2Z coefficients of the Rips complex on points
sampling a Klein bottle:
-./rips_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -m 100
+./rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 2
output:
-210 0 0 inf
-210 1 0.0702103 inf
-2 1 0.0702103 inf
-2 2 0.159992 inf
+2 0 0 inf
+2 1 0.0983494 inf
+2 1 0.104347 inf
+2 2 0.138335 inf
Every line is of this format: p1*...*pr dim b d
@@ -29,31 +29,45 @@ where
with Z/3Z coefficients:
-./rips_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 3 -m 100
+./rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3
output:
-3 0 0 inf
-3 1 0.0702103 inf
+3 0 0 inf
+3 1 0.0983494 inf
+3 1 0.104347 inf
+3 2 0.138335 inf
and the computation with Z/2Z and Z/3Z coefficients simultaneously:
-./rips_multifield_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 3 -m 100
+./rips_multifield_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.12 -d 3 -p 2 -q 3
output:
-6 0 0 inf
-6 1 0.0702103 inf
-2 1 0.0702103 inf
-2 2 0.159992 inf
+6 0 0 inf
+6 1 0.0983494 inf
+6 1 0.104347 inf
+6 2 0.138335 inf
+6 0 0 0.122545
+6 0 0 0.121171
+6 0 0 0.120964
+6 0 0 0.12057
+6 0 0 0.12047
+6 0 0 0.120414
and finally the computation with all Z/pZ for 2 <= p <= 71 (20 first prime numbers):
- ./rips_multifield_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100
+ ./rips_multifield_persistence ../../data/points/Kl.off -r 0.25 -m 0.5 -d 3 -p 2 -q 71
output:
-557940830126698960967415390 0 0 inf
-557940830126698960967415390 1 0.0702103 inf
-2 1 0.0702103 inf
-2 2 0.159992 inf
+557940830126698960967415390 0 0 inf
+557940830126698960967415390 1 0.0983494 inf
+557940830126698960967415390 1 0.104347 inf
+557940830126698960967415390 2 0.138335 inf
+557940830126698960967415390 0 0 0.122545
+557940830126698960967415390 0 0 0.121171
+557940830126698960967415390 0 0 0.120964
+557940830126698960967415390 0 0 0.12057
+557940830126698960967415390 0 0 0.12047
+557940830126698960967415390 0 0 0.120414
***********************************************************************************************************************
Example of use of ALPHA:
diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_helper.h b/src/Persistent_cohomology/example/alpha_complex_3d_helper.h
new file mode 100644
index 00000000..7865e4ec
--- /dev/null
+++ b/src/Persistent_cohomology/example/alpha_complex_3d_helper.h
@@ -0,0 +1,76 @@
+/* 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) 2014 INRIA Saclay (France)
+ *
+ * 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 ALPHA_COMPLEX_3D_HELPER_H_
+#define ALPHA_COMPLEX_3D_HELPER_H_
+
+template<class Vertex_list, class Cell_handle>
+Vertex_list from_cell(const Cell_handle& ch) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+#ifdef DEBUG_TRACES
+ std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(ch->vertex(i));
+ }
+ return the_list;
+}
+
+template<class Vertex_list, class Facet>
+Vertex_list from_facet(const Facet& fct) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+ if (fct.second != i) {
+#ifdef DEBUG_TRACES
+ std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(fct.first->vertex(i));
+ }
+ }
+ return the_list;
+}
+
+template<class Vertex_list, class Edge_3>
+Vertex_list from_edge(const Edge_3& edg) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+ if ((edg.second == i) || (edg.third == i)) {
+#ifdef DEBUG_TRACES
+ std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(edg.first->vertex(i));
+ }
+ }
+ return the_list;
+}
+
+template<class Vertex_list, class Vertex_handle>
+Vertex_list from_vertex(const Vertex_handle& vh) {
+ Vertex_list the_list;
+#ifdef DEBUG_TRACES
+ std::cout << "from vertex=" << vh->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(vh);
+ return the_list;
+}
+
+#endif // ALPHA_COMPLEX_3D_HELPER_H_
diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
index 20142ab2..fd227b82 100644
--- a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
@@ -4,7 +4,7 @@
*
* Author(s): Vincent Rouvreau
*
- * Copyright (C) 2014 INRIA Saclay (France)
+ * Copyright (C) 2014 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
@@ -20,13 +20,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <boost/variant.hpp>
+
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
-#include <boost/variant.hpp>
+#include <gudhi/Points_3D_off_io.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-#include <CGAL/Regular_triangulation_3.h>
-#include <CGAL/Regular_triangulation_euclidean_traits_3.h>
+#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/Alpha_shape_3.h>
#include <CGAL/iterator.h>
@@ -39,85 +40,42 @@
#include <list>
#include <vector>
+#include "alpha_complex_3d_helper.h"
+
// Alpha_shape_3 templates type definitions
-typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
-typedef CGAL::Regular_triangulation_euclidean_traits_3<Kernel> Gt;
-typedef CGAL::Alpha_shape_vertex_base_3<Gt> Vb;
-typedef CGAL::Alpha_shape_cell_base_3<Gt> Fb;
-typedef CGAL::Triangulation_data_structure_3<Vb, Fb> Tds;
-typedef CGAL::Regular_triangulation_3<Gt, Tds> Triangulation_3;
-typedef CGAL::Alpha_shape_3<Triangulation_3> Alpha_shape_3;
+using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
+using Vb = CGAL::Alpha_shape_vertex_base_3<Kernel>;
+using Fb = CGAL::Alpha_shape_cell_base_3<Kernel>;
+using Tds = CGAL::Triangulation_data_structure_3<Vb, Fb>;
+using Triangulation_3 = CGAL::Delaunay_triangulation_3<Kernel, Tds>;
+using Alpha_shape_3 = CGAL::Alpha_shape_3<Triangulation_3>;
// From file type definition
-typedef Kernel::Point_3 Point_3;
+using Point_3 = Kernel::Point_3;
// filtration with alpha values needed type definition
-typedef Alpha_shape_3::FT Alpha_value_type;
-typedef CGAL::Object Object;
-typedef CGAL::Dispatch_output_iterator<
-CGAL::cpp11::tuple<Object, Alpha_value_type>,
-CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
- std::back_insert_iterator< std::vector<Alpha_value_type> > > > Dispatch;
-typedef Alpha_shape_3::Cell_handle Cell_handle;
-typedef Alpha_shape_3::Facet Facet;
-typedef Alpha_shape_3::Edge Edge_3;
-typedef std::list<Alpha_shape_3::Vertex_handle> Vertex_list;
+using Alpha_value_type = Alpha_shape_3::FT;
+using Object = CGAL::Object;
+using Dispatch = CGAL::Dispatch_output_iterator<
+ CGAL::cpp11::tuple<Object, Alpha_value_type>,
+ CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
+ std::back_insert_iterator< std::vector<Alpha_value_type> > > >;
+using Cell_handle = Alpha_shape_3::Cell_handle;
+using Facet = Alpha_shape_3::Facet;
+using Edge_3 = Alpha_shape_3::Edge;
+using Vertex_handle = Alpha_shape_3::Vertex_handle;
+using Vertex_list = std::list<Alpha_shape_3::Vertex_handle>;
// gudhi type definition
-typedef Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence> ST;
-typedef ST::Vertex_handle Simplex_tree_vertex;
-typedef std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex > Alpha_shape_simplex_tree_map;
-typedef std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex> Alpha_shape_simplex_tree_pair;
-typedef std::vector< Simplex_tree_vertex > Simplex_tree_vector_vertex;
-typedef Gudhi::persistent_cohomology::Persistent_cohomology< ST, Gudhi::persistent_cohomology::Field_Zp > PCOH;
-
-Vertex_list from(const Cell_handle& ch) {
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++) {
-#ifdef DEBUG_TRACES
- std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(ch->vertex(i));
- }
- return the_list;
-}
-
-Vertex_list from(const Facet& fct) {
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++) {
- if (fct.second != i) {
-#ifdef DEBUG_TRACES
- std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(fct.first->vertex(i));
- }
- }
- return the_list;
-}
-
-Vertex_list from(const Edge_3& edg) {
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++) {
- if ((edg.second == i) || (edg.third == i)) {
-#ifdef DEBUG_TRACES
- std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(edg.first->vertex(i));
- }
- }
- return the_list;
-}
-
-Vertex_list from(const Alpha_shape_3::Vertex_handle& vh) {
- Vertex_list the_list;
-#ifdef DEBUG_TRACES
- std::cout << "from vertex=" << vh->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(vh);
- return the_list;
-}
-
-void usage(char * const progName) {
+using ST = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Filtration_value = ST::Filtration_value;
+using Simplex_tree_vertex = ST::Vertex_handle;
+using Alpha_shape_simplex_tree_map = std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex >;
+using Alpha_shape_simplex_tree_pair = std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>;
+using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >;
+using PCOH = Gudhi::persistent_cohomology::Persistent_cohomology< ST, Gudhi::persistent_cohomology::Field_Zp >;
+
+void usage(const std::string& progName) {
std::cerr << "Usage: " << progName <<
" path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
exit(-1);
@@ -133,17 +91,24 @@ int main(int argc, char * const argv[]) {
int coeff_field_characteristic = atoi(argv[2]);
Filtration_value min_persistence = 0.0;
- int returnedScanValue = sscanf(argv[3], "%lf", &min_persistence);
+ int returnedScanValue = sscanf(argv[3], "%f", &min_persistence);
if ((returnedScanValue == EOF) || (min_persistence < -1.0)) {
std::cerr << "Error: " << argv[3] << " is not correct\n";
usage(argv[0]);
}
- std::vector<Gt::Weighted_point> lp;
- lp.emplace_back(Point_3(0,0,0),0);
- lp.emplace_back(Point_3(0,0,1),0);
- lp.emplace_back(Point_3(0,1,0),.2);
- lp.emplace_back(Point_3(1,0,0),0);
+ // Read points from file
+ std::string offInputFile(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);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ usage(argv[0]);
+ }
+
+ // Retrieve the triangulation
+ std::vector<Point_3> lp = off_reader.get_point_cloud();
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
Alpha_shape_3 as(lp.begin(), lp.end(), 0, Alpha_shape_3::GENERAL);
@@ -178,30 +143,29 @@ int main(int argc, char * const argv[]) {
for (auto object_iterator : the_objects) {
// Retrieve Alpha shape vertex list from object
if (const Cell_handle * cell = CGAL::object_cast<Cell_handle>(&object_iterator)) {
- vertex_list = from(*cell);
+ vertex_list = from_cell<Vertex_list, Cell_handle>(*cell);
count_cells++;
if (dim_max < 3) {
// Cell is of dim 3
dim_max = 3;
}
} else if (const Facet * facet = CGAL::object_cast<Facet>(&object_iterator)) {
- vertex_list = from(*facet);
+ vertex_list = from_facet<Vertex_list, Facet>(*facet);
count_facets++;
if (dim_max < 2) {
// Facet is of dim 2
dim_max = 2;
}
} else if (const Edge_3 * edge = CGAL::object_cast<Edge_3>(&object_iterator)) {
- vertex_list = from(*edge);
+ vertex_list = from_edge<Vertex_list, Edge_3>(*edge);
count_edges++;
if (dim_max < 1) {
// Edge_3 is of dim 1
dim_max = 1;
}
- } else if (const Alpha_shape_3::Vertex_handle * vertex =
- CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator)) {
+ } else if (const Vertex_handle * vertex = CGAL::object_cast<Vertex_handle>(&object_iterator)) {
count_vertices++;
- vertex_list = from(*vertex);
+ vertex_list = from_vertex<Vertex_list, Vertex_handle>(*vertex);
}
// Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
Simplex_tree_vector_vertex the_simplex_tree;
diff --git a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
index cb181936..9e84e91f 100644
--- a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
@@ -4,11 +4,16 @@
#include <gudhi/Alpha_complex.h>
#include <gudhi/Persistent_cohomology.h>
+// to construct a simplex_tree from alpha complex
+#include <gudhi/Simplex_tree.h>
#include <iostream>
#include <string>
#include <limits> // for numeric_limits
+using Simplex_tree = Gudhi::Simplex_tree<>;
+using Filtration_value = Simplex_tree::Filtration_value;
+
void program_options(int argc, char * argv[]
, std::string & off_file_points
, std::string & output_file_diag
@@ -30,35 +35,38 @@ int main(int argc, char **argv) {
// Init of an alpha complex from an OFF file
// ----------------------------------------------------------------------------
using Kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >;
- Gudhi::alpha_complex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_points, alpha_square_max_value);
-
- // ----------------------------------------------------------------------------
- // Display information about the alpha complex
- // ----------------------------------------------------------------------------
- std::cout << "Alpha complex is of dimension " << alpha_complex_from_file.dimension() <<
- " - " << alpha_complex_from_file.num_simplices() << " simplices - " <<
- alpha_complex_from_file.num_vertices() << " vertices." << std::endl;
-
- // Sort the simplices in the order of the filtration
- alpha_complex_from_file.initialize_filtration();
-
- std::cout << "Simplex_tree dim: " << alpha_complex_from_file.dimension() << std::endl;
- // Compute the persistence diagram of the complex
- Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::alpha_complex::Alpha_complex<Kernel>,
- Gudhi::persistent_cohomology::Field_Zp > pcoh(alpha_complex_from_file);
- // initializes the coefficient field for homology
- pcoh.init_coefficients(coeff_field_characteristic);
-
- pcoh.compute_persistent_cohomology(min_persistence);
-
- // Output the diagram in filediag
- if (output_file_diag.empty()) {
- pcoh.output_diagram();
- } else {
- std::cout << "Result in file: " << output_file_diag << std::endl;
- std::ofstream out(output_file_diag);
- pcoh.output_diagram(out);
- out.close();
+ Gudhi::alpha_complex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_points);
+
+ Simplex_tree simplex;
+ if (alpha_complex_from_file.create_complex(simplex, alpha_square_max_value)) {
+ // ----------------------------------------------------------------------------
+ // Display information about the alpha complex
+ // ----------------------------------------------------------------------------
+ std::cout << "Simplicial complex is of dimension " << simplex.dimension() <<
+ " - " << simplex.num_simplices() << " simplices - " <<
+ simplex.num_vertices() << " vertices." << std::endl;
+
+ // Sort the simplices in the order of the filtration
+ simplex.initialize_filtration();
+
+ std::cout << "Simplex_tree dim: " << simplex.dimension() << std::endl;
+ // Compute the persistence diagram of the complex
+ Gudhi::persistent_cohomology::Persistent_cohomology< Simplex_tree,
+ Gudhi::persistent_cohomology::Field_Zp > pcoh(simplex);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in filediag
+ if (output_file_diag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::cout << "Result in file: " << output_file_diag << std::endl;
+ std::ofstream out(output_file_diag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
}
return 0;
diff --git a/src/Persistent_cohomology/example/custom_persistence_sort.cpp b/src/Persistent_cohomology/example/custom_persistence_sort.cpp
index 9af38611..64f2a4dc 100644
--- a/src/Persistent_cohomology/example/custom_persistence_sort.cpp
+++ b/src/Persistent_cohomology/example/custom_persistence_sort.cpp
@@ -27,6 +27,8 @@
#include <gudhi/Alpha_complex.h>
#include <gudhi/Persistent_cohomology.h>
+// to construct a simplex_tree from alpha complex
+#include <gudhi/Simplex_tree.h>
#include <iostream>
#include <iterator>
@@ -38,6 +40,9 @@
using Kernel = CGAL::Epick_d< CGAL::Dimension_tag<3> >;
using Point = Kernel::Point_d;
using Alpha_complex = Gudhi::alpha_complex::Alpha_complex<Kernel>;
+using Simplex_tree = Gudhi::Simplex_tree<>;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< Simplex_tree,
+ Gudhi::persistent_cohomology::Field_Zp >;
std::vector<Point> random_points() {
// Instanciate a random point generator
@@ -60,7 +65,7 @@ std::vector<Point> random_points() {
* Compare two intervals by dimension, then by length.
*/
struct cmp_intervals_by_dim_then_length {
- explicit cmp_intervals_by_dim_then_length(Alpha_complex * sc)
+ explicit cmp_intervals_by_dim_then_length(Simplex_tree * sc)
: sc_(sc) { }
template<typename Persistent_interval>
@@ -71,46 +76,62 @@ struct cmp_intervals_by_dim_then_length {
else
return (sc_->dimension(get < 0 > (p1)) > sc_->dimension(get < 0 > (p2)));
}
- Alpha_complex* sc_;
+ Simplex_tree* sc_;
};
int main(int argc, char **argv) {
std::vector<Point> points = random_points();
+ std::cout << "Points size=" << points.size() << std::endl;
// Alpha complex persistence computation from generated points
- Alpha_complex alpha_complex_from_points(points, 0.6);
-
- using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< Alpha_complex,
- Gudhi::persistent_cohomology::Field_Zp >;
- Persistent_cohomology pcoh(alpha_complex_from_points);
-
- // initializes the coefficient field for homology - Z/3Z
- pcoh.init_coefficients(3);
- pcoh.compute_persistent_cohomology(0.2);
-
- // Custom sort and output persistence
- cmp_intervals_by_dim_then_length cmp(&alpha_complex_from_points);
- 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 << alpha_complex_from_points.dimension(get<0>(pair)) << " "
- << alpha_complex_from_points.filtration(get<0>(pair)) << " "
- << alpha_complex_from_points.filtration(get<1>(pair)) << std::endl;
+ Alpha_complex alpha_complex_from_points(points);
+ std::cout << "alpha_complex_from_points" << std::endl;
+
+ Simplex_tree simplex;
+ std::cout << "simplex" << std::endl;
+ if (alpha_complex_from_points.create_complex(simplex, 0.6)) {
+ std::cout << "simplex" << std::endl;
+ // ----------------------------------------------------------------------------
+ // Display information about the alpha complex
+ // ----------------------------------------------------------------------------
+ std::cout << "Simplicial complex is of dimension " << simplex.dimension() <<
+ " - " << simplex.num_simplices() << " simplices - " <<
+ simplex.num_vertices() << " vertices." << std::endl;
+
+ // Sort the simplices in the order of the filtration
+ simplex.initialize_filtration();
+
+ std::cout << "Simplex_tree dim: " << simplex.dimension() << std::endl;
+
+ Persistent_cohomology pcoh(simplex);
+
+ // initializes the coefficient field for homology - Z/3Z
+ pcoh.init_coefficients(3);
+ pcoh.compute_persistent_cohomology(0.2);
+
+ // Custom sort and output persistence
+ cmp_intervals_by_dim_then_length cmp(&simplex);
+ 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 << simplex.dimension(get<0>(pair)) << " "
+ << simplex.filtration(get<0>(pair)) << " "
+ << simplex.filtration(get<1>(pair)) << std::endl;
+ }
+
+ // Persistent Betti numbers
+ std::cout << "The persistent Betti numbers in interval [0.40, 0.41] are : ";
+ for (int dim = 0; dim < simplex.dimension(); dim++)
+ std::cout << "b" << dim << " = " << pcoh.persistent_betti_number(dim, 0.40, 0.41) << " ; ";
+ std::cout << std::endl;
+
+ // Betti numbers
+ 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;
}
-
- // Persistent Betti numbers
- std::cout << "The persistent Betti numbers in interval [0.40, 0.41] are : ";
- for (int dim = 0; dim < alpha_complex_from_points.dimension(); dim++)
- std::cout << "b" << dim << " = " << pcoh.persistent_betti_number(dim, 0.40, 0.41) << " ; ";
- std::cout << std::endl;
-
- // Betti numbers
- 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;
-
return 0;
}
diff --git a/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp
new file mode 100644
index 00000000..8a335075
--- /dev/null
+++ b/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp
@@ -0,0 +1,245 @@
+/* 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) 2014 INRIA Saclay (France)
+ *
+ * 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 <boost/variant.hpp>
+
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Points_3D_off_io.h>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Delaunay_triangulation_3.h>
+#include <CGAL/Alpha_shape_3.h>
+#include <CGAL/iterator.h>
+
+#include <fstream>
+#include <cmath>
+#include <string>
+#include <tuple>
+#include <map>
+#include <utility>
+#include <list>
+#include <vector>
+
+#include "alpha_complex_3d_helper.h"
+
+// Alpha_shape_3 templates type definitions
+using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
+using Exact_tag = CGAL::Tag_true;
+using Vb = CGAL::Alpha_shape_vertex_base_3<Kernel, CGAL::Default, Exact_tag>;
+using Fb = CGAL::Alpha_shape_cell_base_3<Kernel, CGAL::Default, Exact_tag>;
+using Tds = CGAL::Triangulation_data_structure_3<Vb, Fb>;
+using Triangulation_3 = CGAL::Delaunay_triangulation_3<Kernel, Tds>;
+using Alpha_shape_3 = CGAL::Alpha_shape_3<Triangulation_3, Exact_tag>;
+
+// From file type definition
+using Point_3 = Kernel::Point_3;
+
+// filtration with alpha values needed type definition
+using Alpha_value_type = Alpha_shape_3::FT;
+using Object = CGAL::Object;
+using Dispatch = CGAL::Dispatch_output_iterator<
+ CGAL::cpp11::tuple<Object, Alpha_value_type>,
+ CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
+ std::back_insert_iterator< std::vector<Alpha_value_type> > > >;
+using Cell_handle = Alpha_shape_3::Cell_handle;
+using Facet = Alpha_shape_3::Facet;
+using Edge_3 = Alpha_shape_3::Edge;
+using Vertex_handle = Alpha_shape_3::Vertex_handle;
+using Vertex_list = std::list<Vertex_handle>;
+
+// gudhi type definition
+using ST = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Filtration_value = ST::Filtration_value;
+using Simplex_tree_vertex = ST::Vertex_handle;
+using Alpha_shape_simplex_tree_map = std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex >;
+using Alpha_shape_simplex_tree_pair = std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>;
+using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >;
+using PCOH = Gudhi::persistent_cohomology::Persistent_cohomology< ST, Gudhi::persistent_cohomology::Field_Zp >;
+
+void usage(char * const progName) {
+ std::cerr << "Usage: " << progName <<
+ " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
+ exit(-1);
+}
+
+int main(int argc, char * const argv[]) {
+ // program args management
+ if (argc != 4) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
+ usage(argv[0]);
+ }
+
+ int coeff_field_characteristic = atoi(argv[2]);
+
+ Filtration_value min_persistence = 0.0;
+ int returnedScanValue = sscanf(argv[3], "%f", &min_persistence);
+ if ((returnedScanValue == EOF) || (min_persistence < -1.0)) {
+ std::cerr << "Error: " << argv[3] << " is not correct\n";
+ usage(argv[0]);
+ }
+
+ // Read points from file
+ std::string offInputFile(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);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ usage(argv[0]);
+ }
+
+ // Retrieve the triangulation
+ std::vector<Point_3> lp = off_reader.get_point_cloud();
+
+ // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
+ Alpha_shape_3 as(lp.begin(), lp.end(), 0, Alpha_shape_3::GENERAL);
+#ifdef DEBUG_TRACES
+ std::cout << "Alpha shape computed in GENERAL mode" << std::endl;
+#endif // DEBUG_TRACES
+
+ // filtration with alpha values from alpha shape
+ std::vector<Object> the_objects;
+ std::vector<Alpha_value_type> the_alpha_values;
+
+ Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>(std::back_inserter(the_objects),
+ std::back_inserter(the_alpha_values));
+
+ as.filtration_with_alpha_values(disp);
+#ifdef DEBUG_TRACES
+ std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl;
+#endif // DEBUG_TRACES
+
+ Alpha_shape_3::size_type count_vertices = 0;
+ Alpha_shape_3::size_type count_edges = 0;
+ Alpha_shape_3::size_type count_facets = 0;
+ Alpha_shape_3::size_type count_cells = 0;
+
+ // Loop on objects vector
+ Vertex_list vertex_list;
+ ST simplex_tree;
+ Alpha_shape_simplex_tree_map map_cgal_simplex_tree;
+ std::vector<Alpha_value_type>::iterator the_alpha_value_iterator = the_alpha_values.begin();
+ int dim_max = 0;
+ Filtration_value filtration_max = 0.0;
+ for (auto object_iterator : the_objects) {
+ // Retrieve Alpha shape vertex list from object
+ if (const Cell_handle * cell = CGAL::object_cast<Cell_handle>(&object_iterator)) {
+ vertex_list = from_cell<Vertex_list, Cell_handle>(*cell);
+ count_cells++;
+ if (dim_max < 3) {
+ // Cell is of dim 3
+ dim_max = 3;
+ }
+ } else if (const Facet * facet = CGAL::object_cast<Facet>(&object_iterator)) {
+ vertex_list = from_facet<Vertex_list, Facet>(*facet);
+ count_facets++;
+ if (dim_max < 2) {
+ // Facet is of dim 2
+ dim_max = 2;
+ }
+ } else if (const Edge_3 * edge = CGAL::object_cast<Edge_3>(&object_iterator)) {
+ vertex_list = from_edge<Vertex_list, Edge_3>(*edge);
+ count_edges++;
+ if (dim_max < 1) {
+ // Edge_3 is of dim 1
+ dim_max = 1;
+ }
+ } else if (const Vertex_handle * vertex = CGAL::object_cast<Vertex_handle>(&object_iterator)) {
+ count_vertices++;
+ vertex_list = from_vertex<Vertex_list, Vertex_handle>(*vertex);
+ }
+ // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
+ Simplex_tree_vector_vertex the_simplex_tree;
+ for (auto the_alpha_shape_vertex : vertex_list) {
+ Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex);
+ if (the_map_iterator == map_cgal_simplex_tree.end()) {
+ // alpha shape not found
+ Simplex_tree_vertex vertex = map_cgal_simplex_tree.size();
+#ifdef DEBUG_TRACES
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex));
+ } else {
+ // alpha shape found
+ Simplex_tree_vertex vertex = the_map_iterator->second;
+#ifdef DEBUG_TRACES
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ }
+ }
+ // Construction of the simplex_tree
+ // you can also use the_alpha_value_iterator->exact()
+ Filtration_value filtr = /*std::sqrt*/CGAL::to_double(the_alpha_value_iterator->exact());
+#ifdef DEBUG_TRACES
+ std::cout << "filtration = " << filtr << std::endl;
+#endif // DEBUG_TRACES
+ if (filtr > filtration_max) {
+ filtration_max = filtr;
+ }
+ simplex_tree.insert_simplex(the_simplex_tree, filtr);
+ if (the_alpha_value_iterator != the_alpha_values.end())
+ ++the_alpha_value_iterator;
+ else
+ std::cout << "This shall not happen" << std::endl;
+ }
+ simplex_tree.set_filtration(filtration_max);
+ simplex_tree.set_dimension(dim_max);
+
+#ifdef DEBUG_TRACES
+ std::cout << "vertices \t\t" << count_vertices << std::endl;
+ std::cout << "edges \t\t" << count_edges << std::endl;
+ std::cout << "facets \t\t" << count_facets << std::endl;
+ std::cout << "cells \t\t" << count_cells << std::endl;
+
+
+ std::cout << "Information of the Simplex Tree: " << std::endl;
+ std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " ";
+ std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl;
+ std::cout << " Dimension = " << simplex_tree.dimension() << " ";
+ std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl;
+#endif // DEBUG_TRACES
+
+#ifdef DEBUG_TRACES
+ std::cout << "Iterator on vertices: " << std::endl;
+ for (auto vertex : simplex_tree.complex_vertex_range()) {
+ std::cout << vertex << " ";
+ }
+#endif // DEBUG_TRACES
+
+ // Sort the simplices in the order of the filtration
+ simplex_tree.initialize_filtration();
+
+ std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl;
+ // Compute the persistence diagram of the complex
+ PCOH pcoh(simplex_tree);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ pcoh.output_diagram();
+
+ return 0;
+}
diff --git a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp
index a199fea1..8928cfc2 100644
--- a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp
+++ b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp
@@ -4,7 +4,7 @@
*
* Author(s): Vincent Rouvreau
*
- * Copyright (C) 2014 INRIA Saclay (France)
+ * Copyright (C) 2014 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
@@ -20,10 +20,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <boost/variant.hpp>
+
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
#include <gudhi/Points_3D_off_io.h>
-#include <boost/variant.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Periodic_3_Delaunay_triangulation_traits_3.h>
@@ -39,6 +40,9 @@
#include <utility>
#include <list>
#include <vector>
+#include <cstdlib>
+
+#include "alpha_complex_3d_helper.h"
// Traits
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
@@ -66,10 +70,12 @@ using Dispatch = CGAL::Dispatch_output_iterator<
using Cell_handle = Alpha_shape_3::Cell_handle;
using Facet = Alpha_shape_3::Facet;
using Edge_3 = Alpha_shape_3::Edge;
+using Vertex_handle = Alpha_shape_3::Vertex_handle;
using Vertex_list = std::list<Alpha_shape_3::Vertex_handle>;
// gudhi type definition
using ST = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Filtration_value = ST::Filtration_value;
using Simplex_tree_vertex = ST::Vertex_handle;
using Alpha_shape_simplex_tree_map = std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex >;
using Alpha_shape_simplex_tree_pair = std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>;
@@ -77,52 +83,6 @@ using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >;
using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<
ST, Gudhi::persistent_cohomology::Field_Zp >;
-Vertex_list from(const Cell_handle& ch) {
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++) {
-#ifdef DEBUG_TRACES
- std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(ch->vertex(i));
- }
- return the_list;
-}
-
-Vertex_list from(const Facet& fct) {
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++) {
- if (fct.second != i) {
-#ifdef DEBUG_TRACES
- std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(fct.first->vertex(i));
- }
- }
- return the_list;
-}
-
-Vertex_list from(const Edge_3& edg) {
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++) {
- if ((edg.second == i) || (edg.third == i)) {
-#ifdef DEBUG_TRACES
- std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(edg.first->vertex(i));
- }
- }
- return the_list;
-}
-
-Vertex_list from(const Alpha_shape_3::Vertex_handle& vh) {
- Vertex_list the_list;
-#ifdef DEBUG_TRACES
- std::cout << "from vertex=" << vh->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(vh);
- return the_list;
-}
-
void usage(char * const progName) {
std::cerr << "Usage: " << progName <<
" path_to_file_graph path_to_iso_cuboid_3_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
@@ -136,19 +96,8 @@ int main(int argc, char * const argv[]) {
usage(argv[0]);
}
- int coeff_field_characteristic = 0;
- int returnedScanValue = sscanf(argv[3], "%d", &coeff_field_characteristic);
- if ((returnedScanValue == EOF) || (coeff_field_characteristic <= 0)) {
- std::cerr << "Error: " << argv[3] << " is not correct\n";
- usage(argv[0]);
- }
-
- Filtration_value min_persistence = 0.0;
- returnedScanValue = sscanf(argv[4], "%lf", &min_persistence);
- if ((returnedScanValue == EOF) || (min_persistence < -1.0)) {
- std::cerr << "Error: " << argv[4] << " is not correct\n";
- usage(argv[0]);
- }
+ int coeff_field_characteristic = atoi(argv[3]);
+ Filtration_value min_persistence = strtof(argv[4], nullptr);
// Read points from file
std::string offInputFile(argv[1]);
@@ -212,21 +161,21 @@ int main(int argc, char * const argv[]) {
for (auto object_iterator : the_objects) {
// Retrieve Alpha shape vertex list from object
if (const Cell_handle * cell = CGAL::object_cast<Cell_handle>(&object_iterator)) {
- vertex_list = from(*cell);
+ vertex_list = from_cell<Vertex_list, Cell_handle>(*cell);
count_cells++;
if (dim_max < 3) {
// Cell is of dim 3
dim_max = 3;
}
} else if (const Facet * facet = CGAL::object_cast<Facet>(&object_iterator)) {
- vertex_list = from(*facet);
+ vertex_list = from_facet<Vertex_list, Facet>(*facet);
count_facets++;
if (dim_max < 2) {
// Facet is of dim 2
dim_max = 2;
}
} else if (const Edge_3 * edge = CGAL::object_cast<Edge_3>(&object_iterator)) {
- vertex_list = from(*edge);
+ vertex_list = from_edge<Vertex_list, Edge_3>(*edge);
count_edges++;
if (dim_max < 1) {
// Edge_3 is of dim 1
@@ -235,7 +184,7 @@ int main(int argc, char * const argv[]) {
} else if (const Alpha_shape_3::Vertex_handle * vertex =
CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator)) {
count_vertices++;
- vertex_list = from(*vertex);
+ vertex_list = from_vertex<Vertex_list, Vertex_handle>(*vertex);
}
// Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
Simplex_tree_vector_vertex the_simplex_tree;
diff --git a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp
index ba772f04..7ca9410a 100644
--- a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp
+++ b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp
@@ -4,7 +4,7 @@
*
* Author(s): Vincent Rouvreau
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 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
@@ -29,13 +29,12 @@
#include <utility>
#include <vector>
-using namespace Gudhi;
-using namespace Gudhi::persistent_cohomology;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-typedef Simplex_tree<> typeST;
+// Types definition
+using Simplex_tree = Gudhi::Simplex_tree<>;
+using Filtration_value = Simplex_tree::Filtration_value;
+using Field_Zp = Gudhi::persistent_cohomology::Field_Zp;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Field_Zp >;
+using typeVectorVertex = std::vector< Simplex_tree::Vertex_handle >;
void usage(char * const progName) {
std::cerr << "Usage: " << progName << " coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
@@ -66,7 +65,7 @@ int main(int argc, char * const argv[]) {
// TEST OF INSERTION
std::cout << "********************************************************************" << std::endl;
std::cout << "TEST OF INSERTION" << std::endl;
- typeST st;
+ Simplex_tree st;
// ++ FIRST
std::cout << " - INSERT (0,1,2)" << std::endl;
@@ -166,7 +165,7 @@ int main(int argc, char * const argv[]) {
std::cout << "**************************************************************" << std::endl;
// Compute the persistence diagram of the complex
- persistent_cohomology::Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(st);
+ Persistent_cohomology pcoh(st);
// initializes the coefficient field for homology
pcoh.init_coefficients(coeff_field_characteristic);
diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp
index ae82c817..50f692f2 100644
--- a/src/Persistent_cohomology/example/plain_homology.cpp
+++ b/src/Persistent_cohomology/example/plain_homology.cpp
@@ -27,13 +27,11 @@
#include <vector>
#include <cstdint> // for std::uint8_t
-using namespace Gudhi;
-
/* We could perfectly well use the default Simplex_tree<> (which uses
* Simplex_tree_options_full_featured), the following simply demonstrates
* how to save on storage by not storing a filtration value. */
-struct MyOptions : Simplex_tree_options_full_featured {
+struct MyOptions : Gudhi::Simplex_tree_options_full_featured {
// Implicitly use 0 as filtration value for all simplices
static const bool store_filtration = false;
// The persistence algorithm needs this
@@ -43,7 +41,10 @@ struct MyOptions : Simplex_tree_options_full_featured {
// Maximum number of simplices to compute persistence is 2^8 - 1 = 255. One is reserved for null_key
typedef std::uint8_t Simplex_key;
};
-typedef Simplex_tree<MyOptions> ST;
+
+using ST = Gudhi::Simplex_tree<MyOptions>;
+using Field_Zp = Gudhi::persistent_cohomology::Field_Zp;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<ST, Field_Zp>;
int main() {
ST st;
@@ -70,7 +71,7 @@ int main() {
st.initialize_filtration();
// Class for homology computation
- persistent_cohomology::Persistent_cohomology<ST, persistent_cohomology::Field_Zp> pcoh(st);
+ Persistent_cohomology pcoh(st);
// Initialize the coefficient field Z/2Z for homology
pcoh.init_coefficients(2);
diff --git a/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp b/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp
new file mode 100644
index 00000000..8517e7f6
--- /dev/null
+++ b/src/Persistent_cohomology/example/rips_distance_matrix_persistence.cpp
@@ -0,0 +1,144 @@
+/* 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 <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 Distance_matrix = std::vector<std::vector<Filtration_value>>;
+
+void program_options(int argc, char * argv[]
+ , std::string & csv_matrix_file
+ , std::string & filediag
+ , Filtration_value & threshold
+ , 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 threshold;
+ int dim_max;
+ int p;
+ Filtration_value min_persistence;
+
+ program_options(argc, argv, csv_matrix_file, filediag, threshold, dim_max, p, min_persistence);
+
+ Distance_matrix distances = read_lower_triangular_matrix_from_csv_file<Filtration_value>(csv_matrix_file);
+ Rips_complex rips_complex_from_file(distances, 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);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in filediag
+ if (filediag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::ofstream out(filediag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
+ return 0;
+}
+
+void program_options(int argc, char * argv[]
+ , std::string & csv_matrix_file
+ , std::string & filediag
+ , Filtration_value & threshold
+ , 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 distance 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")
+ ("max-edge-length,r",
+ po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
+ "Maximal length 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 set of distance 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/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
index c5cd775d..7674b5a5 100644
--- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
@@ -4,7 +4,7 @@
*
* Author(s): Clément Maria
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 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
@@ -20,26 +20,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
-#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Rips_complex.h>
#include <gudhi/distance_functions.h>
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
#include <gudhi/Persistent_cohomology/Multi_field.h>
+#include <gudhi/Points_off_io.h>
#include <boost/program_options.hpp>
#include <string>
#include <vector>
-using namespace Gudhi;
-using namespace Gudhi::persistent_cohomology;
-
-typedef int Vertex_handle;
-typedef double Filtration_value;
+// 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 Multi_field = Gudhi::persistent_cohomology::Multi_field;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Multi_field >;
+using Point = std::vector<double>;
+using Points_off_reader = Gudhi::Points_off_reader<Point>;
void program_options(int argc, char * argv[]
- , std::string & filepoints
+ , std::string & off_file_points
, std::string & filediag
, Filtration_value & threshold
, int & dim_max
@@ -48,7 +51,7 @@ void program_options(int argc, char * argv[]
, Filtration_value & min_persistence);
int main(int argc, char * argv[]) {
- std::string filepoints;
+ std::string off_file_points;
std::string filediag;
Filtration_value threshold;
int dim_max;
@@ -56,33 +59,26 @@ int main(int argc, char * argv[]) {
int max_p;
Filtration_value min_persistence;
- program_options(argc, argv, filepoints, filediag, threshold, dim_max, min_p, max_p, min_persistence);
-
- // Extract the points from the file filepoints
- typedef std::vector<double> Point_t;
- std::vector< Point_t > points;
- read_points(filepoints, points);
+ program_options(argc, argv, off_file_points, filediag, threshold, dim_max, min_p, max_p, min_persistence);
- // Compute the proximity graph of the points
- Graph_t prox_graph = compute_proximity_graph(points, threshold
- , euclidean_distance<Point_t>);
+ Points_off_reader off_reader(off_file_points);
+ Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance());
// Construct the Rips complex in a Simplex Tree
- typedef Simplex_tree<Simplex_tree_options_fast_persistence> ST;
- ST st;
- // insert the proximity graph in the simplex tree
- st.insert_graph(prox_graph);
- // expand the graph until dimension dim_max
- st.expansion(dim_max);
+ 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
- st.initialize_filtration();
+ simplex_tree.initialize_filtration();
// Compute the persistence diagram of the complex
- Persistent_cohomology<ST, Multi_field > pcoh(st);
+ Persistent_cohomology pcoh(simplex_tree);
// initializes the coefficient field for homology
pcoh.init_coefficients(min_p, max_p);
- // compute persistent homology, disgarding persistent features of life shorter than min_persistence
+
pcoh.compute_persistent_cohomology(min_persistence);
// Output the diagram in filediag
@@ -98,7 +94,7 @@ int main(int argc, char * argv[]) {
}
void program_options(int argc, char * argv[]
- , std::string & filepoints
+ , std::string & off_file_points
, std::string & filediag
, Filtration_value & threshold
, int & dim_max
@@ -108,8 +104,8 @@ void program_options(int argc, char * argv[]
namespace po = boost::program_options;
po::options_description hidden("Hidden options");
hidden.add_options()
- ("input-file", po::value<std::string>(&filepoints),
- "Name of file containing a point set. Format is one point per line: X1 ... Xd \n");
+ ("input-file", po::value<std::string>(&off_file_points),
+ "Name of an OFF file containing a point set.\n");
po::options_description visible("Allowed options");
visible.add_options()
diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp
index cab49395..c6378de7 100644
--- a/src/Persistent_cohomology/example/rips_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence.cpp
@@ -4,7 +4,7 @@
*
* Author(s): Clément Maria
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 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
@@ -20,11 +20,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
-#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Rips_complex.h>
#include <gudhi/distance_functions.h>
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Points_off_io.h>
#include <boost/program_options.hpp>
@@ -32,14 +32,17 @@
#include <vector>
#include <limits> // infinity
-using namespace Gudhi;
-using namespace Gudhi::persistent_cohomology;
-
-typedef int Vertex_handle;
-typedef double Filtration_value;
+// 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 Point = std::vector<double>;
+using Points_off_reader = Gudhi::Points_off_reader<Point>;
void program_options(int argc, char * argv[]
- , std::string & filepoints
+ , std::string & off_file_points
, std::string & filediag
, Filtration_value & threshold
, int & dim_max
@@ -47,40 +50,30 @@ void program_options(int argc, char * argv[]
, Filtration_value & min_persistence);
int main(int argc, char * argv[]) {
- std::string filepoints;
+ std::string off_file_points;
std::string filediag;
Filtration_value threshold;
int dim_max;
int p;
Filtration_value min_persistence;
- program_options(argc, argv, filepoints, filediag, threshold, dim_max, p, min_persistence);
-
- // Extract the points from the file filepoints
- typedef std::vector<double> Point_t;
- std::vector< Point_t > points;
- read_points(filepoints, points);
+ program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence);
- // Compute the proximity graph of the points
- Graph_t prox_graph = compute_proximity_graph(points, threshold
- , euclidean_distance<Point_t>);
+ Points_off_reader off_reader(off_file_points);
+ Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance());
// Construct the Rips complex in a Simplex Tree
- typedef Simplex_tree<Simplex_tree_options_fast_persistence> ST;
- ST st;
- // insert the proximity graph in the simplex tree
- st.insert_graph(prox_graph);
- // expand the graph until dimension dim_max
- st.expansion(dim_max);
+ Simplex_tree simplex_tree;
- std::cout << "The complex contains " << st.num_simplices() << " simplices \n";
- std::cout << " and has dimension " << st.dimension() << " \n";
+ 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
- st.initialize_filtration();
+ simplex_tree.initialize_filtration();
// Compute the persistence diagram of the complex
- persistent_cohomology::Persistent_cohomology<ST, Field_Zp > pcoh(st);
+ Persistent_cohomology pcoh(simplex_tree);
// initializes the coefficient field for homology
pcoh.init_coefficients(p);
@@ -99,7 +92,7 @@ int main(int argc, char * argv[]) {
}
void program_options(int argc, char * argv[]
- , std::string & filepoints
+ , std::string & off_file_points
, std::string & filediag
, Filtration_value & threshold
, int & dim_max
@@ -108,15 +101,16 @@ void program_options(int argc, char * argv[]
namespace po = boost::program_options;
po::options_description hidden("Hidden options");
hidden.add_options()
- ("input-file", po::value<std::string>(&filepoints),
- "Name of file containing a point set. Format is one point per line: X1 ... Xd ");
+ ("input-file", po::value<std::string>(&off_file_points),
+ "Name of an OFF file containing a point set.\n");
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")
- ("max-edge-length,r", po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
+ ("max-edge-length,r",
+ po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
"Maximal length 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.")
diff --git a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp
new file mode 100644
index 00000000..b159c62e
--- /dev/null
+++ b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp
@@ -0,0 +1,217 @@
+/* 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): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * 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/graph_simplicial_complex.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Points_off_io.h>
+
+#include <boost/program_options.hpp>
+
+#include <string>
+#include <vector>
+#include <limits> // infinity
+#include <utility> // for pair
+#include <map>
+
+// ----------------------------------------------------------------------------
+// rips_persistence_step_by_step is an example of each step that is required to
+// build a Rips over a Simplex_tree. Please refer to rips_persistence to see
+// how to do the same thing with the Rips_complex wrapper for less detailed
+// steps.
+// ----------------------------------------------------------------------------
+
+// Types definition
+using Simplex_tree = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Vertex_handle = Simplex_tree::Vertex_handle;
+using Filtration_value = Simplex_tree::Filtration_value;
+using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS
+, boost::property < vertex_filtration_t, Filtration_value >
+, boost::property < edge_filtration_t, Filtration_value >
+>;
+using Edge_t = std::pair< Vertex_handle, Vertex_handle >;
+
+template< typename InputPointRange, typename Distance >
+Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold, Distance distance);
+
+using Field_Zp = Gudhi::persistent_cohomology::Field_Zp;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Field_Zp >;
+using Point = std::vector<double>;
+using Points_off_reader = Gudhi::Points_off_reader<Point>;
+
+void program_options(int argc, char * argv[]
+ , std::string & off_file_points
+ , std::string & filediag
+ , Filtration_value & threshold
+ , int & dim_max
+ , int & p
+ , Filtration_value & min_persistence);
+
+int main(int argc, char * argv[]) {
+ std::string off_file_points;
+ std::string filediag;
+ Filtration_value threshold;
+ int dim_max;
+ int p;
+ Filtration_value min_persistence;
+
+ program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence);
+
+ // Extract the points from the file filepoints
+ Points_off_reader off_reader(off_file_points);
+
+ // Compute the proximity graph of the points
+ Graph_t prox_graph = compute_proximity_graph(off_reader.get_point_cloud(), threshold
+ , Euclidean_distance());
+
+ // Construct the Rips complex in a Simplex Tree
+ Simplex_tree st;
+ // insert the proximity graph in the simplex tree
+ st.insert_graph(prox_graph);
+ // expand the graph until dimension dim_max
+ st.expansion(dim_max);
+
+ std::cout << "The complex contains " << st.num_simplices() << " simplices \n";
+ std::cout << " and has dimension " << st.dimension() << " \n";
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology pcoh(st);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(p);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in filediag
+ if (filediag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::ofstream out(filediag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
+
+ return 0;
+}
+
+void program_options(int argc, char * argv[]
+ , std::string & off_file_points
+ , std::string & filediag
+ , Filtration_value & threshold
+ , 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>(&off_file_points),
+ "Name of an OFF file containing a point set.\n");
+
+ 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")
+ ("max-edge-length,r",
+ po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
+ "Maximal length 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 set of input points.\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();
+ }
+}
+
+/** Output the proximity graph of the points.
+ *
+ * If points contains n elements, the proximity graph is the graph
+ * with n vertices, and an edge [u,v] iff the distance function between
+ * points u and v is smaller than threshold.
+ *
+ * The type PointCloud furnishes .begin() and .end() methods, that return
+ * iterators with value_type Point.
+ */
+template< typename InputPointRange, typename Distance >
+Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold, Distance distance) {
+ std::vector< Edge_t > edges;
+ std::vector< Filtration_value > edges_fil;
+
+ Vertex_handle idx_u, idx_v;
+ Filtration_value fil;
+ idx_u = 0;
+ for (auto it_u = points.begin(); it_u != points.end(); ++it_u) {
+ idx_v = idx_u + 1;
+ for (auto it_v = it_u + 1; it_v != points.end(); ++it_v, ++idx_v) {
+ fil = distance(*it_u, *it_v);
+ if (fil <= threshold) {
+ edges.emplace_back(idx_u, idx_v);
+ edges_fil.push_back(fil);
+ }
+ }
+ ++idx_u;
+ }
+
+ Graph_t skel_graph(edges.begin()
+ , edges.end()
+ , edges_fil.begin()
+ , idx_u); // number of points labeled from 0 to idx_u-1
+
+ auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph);
+
+ boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
+ for (std::tie(vi, vi_end) = boost::vertices(skel_graph);
+ vi != vi_end; ++vi) {
+ boost::put(vertex_prop, *vi, 0.);
+ }
+
+ return skel_graph;
+}
diff --git a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp
index 4c6656f5..63da9847 100644
--- a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp
@@ -4,8 +4,7 @@
*
* Author(s): Clément Maria, Marc Glisse
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France),
- * 2015 INRIA Saclay Île de France)
+ * Copyright (C) 2014 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
@@ -21,12 +20,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
-#include <gudhi/graph_simplicial_complex.h>
-#include <gudhi/distance_functions.h>
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Rips_complex.h>
#include <gudhi/Hasse_complex.h>
+#include <gudhi/Points_off_io.h>
+#include <gudhi/distance_functions.h>
#include <boost/program_options.hpp>
@@ -44,14 +43,16 @@
// //
////////////////////////////////////////////////////////////////
-using namespace Gudhi;
-using namespace Gudhi::persistent_cohomology;
-
-typedef int Vertex_handle;
-typedef double Filtration_value;
+// Types definition
+using Simplex_tree = Gudhi::Simplex_tree<>;
+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 Point = std::vector<double>;
+using Points_off_reader = Gudhi::Points_off_reader<Point>;
void program_options(int argc, char * argv[]
- , std::string & filepoints
+ , std::string & off_file_points
, std::string & filediag
, Filtration_value & threshold
, int & dim_max
@@ -59,30 +60,21 @@ void program_options(int argc, char * argv[]
, Filtration_value & min_persistence);
int main(int argc, char * argv[]) {
- std::string filepoints;
+ std::string off_file_points;
std::string filediag;
Filtration_value threshold;
int dim_max;
int p;
Filtration_value min_persistence;
- program_options(argc, argv, filepoints, filediag, threshold, dim_max, p, min_persistence);
-
- // Extract the points from the file filepoints
- typedef std::vector<double> Point_t;
- std::vector< Point_t > points;
- read_points(filepoints, points);
+ program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence);
- // Compute the proximity graph of the points
- Graph_t prox_graph = compute_proximity_graph(points, threshold
- , euclidean_distance<Point_t>);
+ Points_off_reader off_reader(off_file_points);
+ Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance());
// Construct the Rips complex in a Simplex Tree
- Simplex_tree<>& st = *new Simplex_tree<>;
- // insert the proximity graph in the simplex tree
- st.insert_graph(prox_graph);
- // expand the graph until dimension dim_max
- st.expansion(dim_max);
+ Simplex_tree& st = *new Simplex_tree;
+ rips_complex_from_file.create_complex(st, dim_max);
std::cout << "The complex contains " << st.num_simplices() << " simplices \n";
std::cout << " and has dimension " << st.dimension() << " \n";
@@ -99,7 +91,7 @@ int main(int argc, char * argv[]) {
st.assign_key(sh, count++);
// Convert to a more convenient representation.
- Hasse_complex<> hcpx(st);
+ Gudhi::Hasse_complex<> hcpx(st);
#ifdef GUDHI_USE_TBB
ts.terminate();
@@ -109,7 +101,7 @@ int main(int argc, char * argv[]) {
delete &st;
// Compute the persistence diagram of the complex
- persistent_cohomology::Persistent_cohomology< Hasse_complex<>, Field_Zp > pcoh(hcpx);
+ Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::Hasse_complex<>, Field_Zp > pcoh(hcpx);
// initializes the coefficient field for homology
pcoh.init_coefficients(p);
@@ -126,7 +118,7 @@ int main(int argc, char * argv[]) {
}
void program_options(int argc, char * argv[]
- , std::string & filepoints
+ , std::string & off_file_points
, std::string & filediag
, Filtration_value & threshold
, int & dim_max
@@ -135,7 +127,7 @@ void program_options(int argc, char * argv[]
namespace po = boost::program_options;
po::options_description hidden("Hidden options");
hidden.add_options()
- ("input-file", po::value<std::string>(&filepoints),
+ ("input-file", po::value<std::string>(&off_file_points),
"Name of file containing a point set. Format is one point per line: X1 ... Xd ");
po::options_description visible("Allowed options", 100);
diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp
new file mode 100644
index 00000000..34b90933
--- /dev/null
+++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp
@@ -0,0 +1,263 @@
+/* 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) 2014 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 <boost/variant.hpp>
+
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Points_3D_off_io.h>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Regular_triangulation_euclidean_traits_3.h>
+#include <CGAL/Regular_triangulation_3.h>
+#include <CGAL/Alpha_shape_3.h>
+#include <CGAL/iterator.h>
+
+#include <fstream>
+#include <cmath>
+#include <string>
+#include <tuple>
+#include <map>
+#include <utility>
+#include <list>
+#include <vector>
+#include <cstdlib>
+
+#include "alpha_complex_3d_helper.h"
+
+// Traits
+using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
+using Gt = CGAL::Regular_triangulation_euclidean_traits_3<Kernel>;
+using Vb = CGAL::Alpha_shape_vertex_base_3<Gt>;
+using Fb = CGAL::Alpha_shape_cell_base_3<Gt>;
+using Tds = CGAL::Triangulation_data_structure_3<Vb, Fb>;
+using Triangulation_3 = CGAL::Regular_triangulation_3<Gt, Tds>;
+using Alpha_shape_3 = CGAL::Alpha_shape_3<Triangulation_3>;
+
+// From file type definition
+using Point_3 = Gt::Bare_point;
+using Weighted_point_3 = Gt::Weighted_point;
+
+// filtration with alpha values needed type definition
+using Alpha_value_type = Alpha_shape_3::FT;
+using Object = CGAL::Object;
+using Dispatch = CGAL::Dispatch_output_iterator<
+ CGAL::cpp11::tuple<Object, Alpha_value_type>,
+ CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
+ std::back_insert_iterator< std::vector<Alpha_value_type> > > >;
+using Cell_handle = Alpha_shape_3::Cell_handle;
+using Facet = Alpha_shape_3::Facet;
+using Edge_3 = Alpha_shape_3::Edge;
+using Vertex_handle = Alpha_shape_3::Vertex_handle;
+using Vertex_list = std::list<Alpha_shape_3::Vertex_handle>;
+
+// gudhi type definition
+using ST = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Filtration_value = ST::Filtration_value;
+using Simplex_tree_vertex = ST::Vertex_handle;
+using Alpha_shape_simplex_tree_map = std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex >;
+using Alpha_shape_simplex_tree_pair = std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>;
+using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<
+ ST, Gudhi::persistent_cohomology::Field_Zp >;
+
+void usage(char * const progName) {
+ std::cerr << "Usage: " << progName <<
+ " path_to_file_graph path_to_weight_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
+ exit(-1);
+}
+
+int main(int argc, char * const argv[]) {
+ // program args management
+ if (argc != 5) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
+ usage(argv[0]);
+ }
+
+ int coeff_field_characteristic = atoi(argv[3]);
+ Filtration_value min_persistence = strtof(argv[4], nullptr);
+
+ // Read points from file
+ std::string offInputFile(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);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ usage(argv[0]);
+ }
+
+ // Retrieve the triangulation
+ std::vector<Point_3> lp = off_reader.get_point_cloud();
+
+ // Read weights information from file
+ std::ifstream weights_ifstr(argv[2]);
+ std::vector<Weighted_point_3> wp;
+ if (weights_ifstr.good()) {
+ double weight = 0.0;
+ std::size_t index = 0;
+ // Attempt read the weight in a double format, return false if it fails
+ while ((weights_ifstr >> weight) && (index < lp.size())) {
+ wp.push_back(Weighted_point_3(lp[index], weight));
+ index++;
+ }
+ if (index != lp.size()) {
+ std::cerr << "Bad number of weights in file " << argv[2] << std::endl;
+ usage(argv[0]);
+ }
+ } else {
+ std::cerr << "Unable to read file " << argv[2] << std::endl;
+ usage(argv[0]);
+ }
+
+ // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
+ Alpha_shape_3 as(lp.begin(), lp.end(), 0, Alpha_shape_3::GENERAL);
+#ifdef DEBUG_TRACES
+ std::cout << "Alpha shape computed in GENERAL mode" << std::endl;
+#endif // DEBUG_TRACES
+
+ // filtration with alpha values from alpha shape
+ std::vector<Object> the_objects;
+ std::vector<Alpha_value_type> the_alpha_values;
+
+ Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>(std::back_inserter(the_objects),
+ std::back_inserter(the_alpha_values));
+
+ as.filtration_with_alpha_values(disp);
+#ifdef DEBUG_TRACES
+ std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl;
+#endif // DEBUG_TRACES
+
+ Alpha_shape_3::size_type count_vertices = 0;
+ Alpha_shape_3::size_type count_edges = 0;
+ Alpha_shape_3::size_type count_facets = 0;
+ Alpha_shape_3::size_type count_cells = 0;
+
+ // Loop on objects vector
+ Vertex_list vertex_list;
+ ST simplex_tree;
+ Alpha_shape_simplex_tree_map map_cgal_simplex_tree;
+ std::vector<Alpha_value_type>::iterator the_alpha_value_iterator = the_alpha_values.begin();
+ int dim_max = 0;
+ Filtration_value filtration_max = 0.0;
+ for (auto object_iterator : the_objects) {
+ // Retrieve Alpha shape vertex list from object
+ if (const Cell_handle * cell = CGAL::object_cast<Cell_handle>(&object_iterator)) {
+ vertex_list = from_cell<Vertex_list, Cell_handle>(*cell);
+ count_cells++;
+ if (dim_max < 3) {
+ // Cell is of dim 3
+ dim_max = 3;
+ }
+ } else if (const Facet * facet = CGAL::object_cast<Facet>(&object_iterator)) {
+ vertex_list = from_facet<Vertex_list, Facet>(*facet);
+ count_facets++;
+ if (dim_max < 2) {
+ // Facet is of dim 2
+ dim_max = 2;
+ }
+ } else if (const Edge_3 * edge = CGAL::object_cast<Edge_3>(&object_iterator)) {
+ vertex_list = from_edge<Vertex_list, Edge_3>(*edge);
+ count_edges++;
+ if (dim_max < 1) {
+ // Edge_3 is of dim 1
+ dim_max = 1;
+ }
+ } else if (const Alpha_shape_3::Vertex_handle * vertex =
+ CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator)) {
+ count_vertices++;
+ vertex_list = from_vertex<Vertex_list, Vertex_handle>(*vertex);
+ }
+ // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
+ Simplex_tree_vector_vertex the_simplex_tree;
+ for (auto the_alpha_shape_vertex : vertex_list) {
+ Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex);
+ if (the_map_iterator == map_cgal_simplex_tree.end()) {
+ // alpha shape not found
+ Simplex_tree_vertex vertex = map_cgal_simplex_tree.size();
+#ifdef DEBUG_TRACES
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex));
+ } else {
+ // alpha shape found
+ Simplex_tree_vertex vertex = the_map_iterator->second;
+#ifdef DEBUG_TRACES
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ }
+ }
+ // Construction of the simplex_tree
+ Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator);
+#ifdef DEBUG_TRACES
+ std::cout << "filtration = " << filtr << std::endl;
+#endif // DEBUG_TRACES
+ if (filtr > filtration_max) {
+ filtration_max = filtr;
+ }
+ simplex_tree.insert_simplex(the_simplex_tree, filtr);
+ if (the_alpha_value_iterator != the_alpha_values.end())
+ ++the_alpha_value_iterator;
+ else
+ std::cout << "This shall not happen" << std::endl;
+ }
+ simplex_tree.set_filtration(filtration_max);
+ simplex_tree.set_dimension(dim_max);
+
+#ifdef DEBUG_TRACES
+ std::cout << "vertices \t\t" << count_vertices << std::endl;
+ std::cout << "edges \t\t" << count_edges << std::endl;
+ std::cout << "facets \t\t" << count_facets << std::endl;
+ std::cout << "cells \t\t" << count_cells << std::endl;
+
+
+ std::cout << "Information of the Simplex Tree: " << std::endl;
+ std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " ";
+ std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl;
+ std::cout << " Dimension = " << simplex_tree.dimension() << " ";
+ std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl;
+#endif // DEBUG_TRACES
+
+#ifdef DEBUG_TRACES
+ std::cout << "Iterator on vertices: " << std::endl;
+ for (auto vertex : simplex_tree.complex_vertex_range()) {
+ std::cout << vertex << " ";
+ }
+#endif // DEBUG_TRACES
+
+ // Sort the simplices in the order of the filtration
+ simplex_tree.initialize_filtration();
+
+ std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl;
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology pcoh(simplex_tree, true);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ pcoh.output_diagram();
+
+ return 0;
+}
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
index 3568561a..6f194f57 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
@@ -110,7 +110,7 @@ class Persistent_cohomology {
cell_pool_() {
if (cpx_->num_simplices() > std::numeric_limits<Simplex_key>::max()) {
// num_simplices must be strictly lower than the limit, because a value is reserved for null_key.
- throw std::out_of_range ("The number of simplices is more than Simplex_key type numeric limit.");
+ throw std::out_of_range("The number of simplices is more than Simplex_key type numeric limit.");
}
Simplex_key idx_fil = 0;
for (auto sh : cpx_->filtration_simplex_range()) {
@@ -300,8 +300,7 @@ class Persistent_cohomology {
// with multiplicity. We used to sum the coefficients directly in
// annotations_in_boundary by using a map, we now do it later.
typedef std::pair<Column *, int> annotation_t;
- // Danger: not thread-safe!
- static std::vector<annotation_t> annotations_in_boundary;
+ thread_local std::vector<annotation_t> annotations_in_boundary;
annotations_in_boundary.clear();
int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the
// alternate sum in the boundary.
@@ -623,7 +622,7 @@ class Persistent_cohomology {
*/
std::vector<int> betti_numbers() const {
// Init Betti numbers vector with zeros until Simplicial complex dimension
- std::vector<int> betti_numbers(cpx_->dimension(), 0);
+ std::vector<int> betti_numbers(dim_max_, 0);
for (auto pair : persistent_pairs_) {
// Count never ended persistence intervals
@@ -662,8 +661,7 @@ class Persistent_cohomology {
*/
std::vector<int> persistent_betti_numbers(Filtration_value from, Filtration_value to) const {
// Init Betti numbers vector with zeros until Simplicial complex dimension
- std::vector<int> betti_numbers(cpx_->dimension(), 0);
-
+ std::vector<int> betti_numbers(dim_max_, 0);
for (auto pair : persistent_pairs_) {
// Count persistence intervals that covers the given interval
// null_simplex test : if the function is called with to=+infinity, we still get something useful. And it will
@@ -709,6 +707,22 @@ class Persistent_cohomology {
return persistent_pairs_;
}
+ /** @brief Returns persistence intervals for a given dimension.
+ * @param[in] dimension Dimension to get the birth and death pairs from.
+ * @return A vector of persistence intervals (birth and death) on a fixed dimension.
+ */
+ std::vector< std::pair< Filtration_value , Filtration_value > >
+ intervals_in_dimension(int dimension) {
+ std::vector< std::pair< Filtration_value , Filtration_value > > result;
+ // auto && pair, to avoid unnecessary copying
+ for (auto && pair : persistent_pairs_) {
+ if (cpx_->dimension(get<0>(pair)) == dimension) {
+ result.emplace_back(cpx_->filtration(get<0>(pair)), cpx_->filtration(get<1>(pair)));
+ }
+ }
+ return result;
+ }
+
private:
/*
* Structure representing a cocycle.
diff --git a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp
index 40221005..0ed3fddf 100644
--- a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp
+++ b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp
@@ -84,6 +84,8 @@ BOOST_AUTO_TEST_CASE( plain_homology_betti_numbers )
// 2 1 0 inf
// means that in Z/2Z-homology, the Betti numbers are b0=2 and b1=1.
+ std::cout << "BETTI NUMBERS" << std::endl;
+
BOOST_CHECK(pcoh.betti_number(0) == 2);
BOOST_CHECK(pcoh.betti_number(1) == 1);
BOOST_CHECK(pcoh.betti_number(2) == 0);
@@ -93,6 +95,8 @@ BOOST_AUTO_TEST_CASE( plain_homology_betti_numbers )
BOOST_CHECK(bns[0] == 2);
BOOST_CHECK(bns[1] == 1);
BOOST_CHECK(bns[2] == 0);
+
+ std::cout << "GET PERSISTENT PAIRS" << std::endl;
// Custom sort and output persistence
cmp_intervals_by_dim_then_length<Mini_simplex_tree> cmp(&st);
@@ -115,6 +119,33 @@ BOOST_AUTO_TEST_CASE( plain_homology_betti_numbers )
BOOST_CHECK(st.dimension(get<0>(persistent_pairs[2])) == 0);
BOOST_CHECK(st.filtration(get<0>(persistent_pairs[2])) == 0);
BOOST_CHECK(get<1>(persistent_pairs[2]) == st.null_simplex());
+
+ std::cout << "INTERVALS IN DIMENSION" << std::endl;
+
+ auto intervals_in_dimension_0 = pcoh.intervals_in_dimension(0);
+ std::cout << "intervals_in_dimension_0.size() = " << intervals_in_dimension_0.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_0.size(); i++)
+ std::cout << "intervals_in_dimension_0[" << i << "] = [" << intervals_in_dimension_0[i].first << "," <<
+ intervals_in_dimension_0[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_0.size() == 2);
+ BOOST_CHECK(intervals_in_dimension_0[0].first == 0);
+ BOOST_CHECK(intervals_in_dimension_0[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+ BOOST_CHECK(intervals_in_dimension_0[1].first == 0);
+ BOOST_CHECK(intervals_in_dimension_0[1].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+
+ auto intervals_in_dimension_1 = pcoh.intervals_in_dimension(1);
+ std::cout << "intervals_in_dimension_1.size() = " << intervals_in_dimension_1.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_1.size(); i++)
+ std::cout << "intervals_in_dimension_1[" << i << "] = [" << intervals_in_dimension_1[i].first << "," <<
+ intervals_in_dimension_1[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_1.size() == 1);
+ BOOST_CHECK(intervals_in_dimension_1[0].first == 0);
+ BOOST_CHECK(intervals_in_dimension_1[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+ auto intervals_in_dimension_2 = pcoh.intervals_in_dimension(2);
+ std::cout << "intervals_in_dimension_2.size() = " << intervals_in_dimension_2.size() << std::endl;
+ BOOST_CHECK(intervals_in_dimension_2.size() == 0);
}
using Simplex_tree = Gudhi::Simplex_tree<>;
@@ -231,4 +262,30 @@ BOOST_AUTO_TEST_CASE( betti_numbers )
BOOST_CHECK(st.dimension(get<0>(persistent_pairs[2])) == 0);
BOOST_CHECK(st.filtration(get<0>(persistent_pairs[2])) == 1);
BOOST_CHECK(get<1>(persistent_pairs[2]) == st.null_simplex());
+
+ std::cout << "INTERVALS IN DIMENSION" << std::endl;
+
+ auto intervals_in_dimension_0 = pcoh.intervals_in_dimension(0);
+ std::cout << "intervals_in_dimension_0.size() = " << intervals_in_dimension_0.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_0.size(); i++)
+ std::cout << "intervals_in_dimension_0[" << i << "] = [" << intervals_in_dimension_0[i].first << "," <<
+ intervals_in_dimension_0[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_0.size() == 2);
+ BOOST_CHECK(intervals_in_dimension_0[0].first == 2);
+ BOOST_CHECK(intervals_in_dimension_0[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+ BOOST_CHECK(intervals_in_dimension_0[1].first == 1);
+ BOOST_CHECK(intervals_in_dimension_0[1].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+ auto intervals_in_dimension_1 = pcoh.intervals_in_dimension(1);
+ std::cout << "intervals_in_dimension_1.size() = " << intervals_in_dimension_1.size() << std::endl;
+ for (std::size_t i = 0; i < intervals_in_dimension_1.size(); i++)
+ std::cout << "intervals_in_dimension_1[" << i << "] = [" << intervals_in_dimension_1[i].first << "," <<
+ intervals_in_dimension_1[i].second << "]" << std::endl;
+ BOOST_CHECK(intervals_in_dimension_1.size() == 1);
+ BOOST_CHECK(intervals_in_dimension_1[0].first == 4);
+ BOOST_CHECK(intervals_in_dimension_1[0].second == std::numeric_limits<Mini_simplex_tree::Filtration_value>::infinity());
+
+ auto intervals_in_dimension_2 = pcoh.intervals_in_dimension(2);
+ std::cout << "intervals_in_dimension_2.size() = " << intervals_in_dimension_2.size() << std::endl;
+ BOOST_CHECK(intervals_in_dimension_2.size() == 0);
}
diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
index 703682e1..1a6e3296 100644
--- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
+++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
@@ -21,7 +21,7 @@ using namespace boost::unit_test;
typedef Simplex_tree<> typeST;
-std::string test_rips_persistence(int min_coefficient, int max_coefficient, int min_persistence) {
+std::string test_rips_persistence(int min_coefficient, int max_coefficient, double min_persistence) {
// file name is given as parameter from CMakeLists.txt
const std::string inputFile(framework::master_test_suite().argv[1]);
@@ -74,7 +74,7 @@ void test_rips_persistence_in_dimension(int min_dimension, int max_dimension) {
std::cout << "********************************************************************" << std::endl;
std::cout << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_MULTI_FIELD MIN_DIM=" << min_dimension << " MAX_DIM=" << max_dimension << " MIN_PERS=0" << std::endl;
- std::string str_rips_persistence = test_rips_persistence(min_dimension, max_dimension, static_cast<Filtration_value> (0.0));
+ std::string str_rips_persistence = test_rips_persistence(min_dimension, max_dimension, 0.0);
std::cout << "str_rips_persistence=" << str_rips_persistence << std::endl;
BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found