summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeGUDHIVersion.txt4
-rw-r--r--biblio/how_to_cite_gudhi.bib15
-rw-r--r--data/persistence_diagram/PD1.pers (renamed from data/persistence_diagram/PD1)0
-rw-r--r--data/persistence_diagram/PD2.pers (renamed from data/persistence_diagram/PD2)0
-rw-r--r--data/persistence_diagram/simple_diagram.txt4
-rw-r--r--[-rwxr-xr-x]data/points/KleinBottle5D.off0
-rw-r--r--[-rwxr-xr-x]data/points/human.off0
-rw-r--r--data/points/iso_cuboid_3_in_0_10.txt1
-rw-r--r--data/points/shifted_sphere.off1002
-rw-r--r--data/points/shifted_sphere.weights1000
-rw-r--r--src/Alpha_complex/doc/Intro_alpha_complex.h4
-rw-r--r--src/Alpha_complex/include/gudhi/Alpha_complex.h2
-rw-r--r--src/Alpha_complex/test/Alpha_complex_unit_test.cpp19
-rw-r--r--src/Alpha_complex/utilities/CMakeLists.txt2
-rw-r--r--src/Alpha_complex/utilities/alpha_complex_3d_helper.h8
-rw-r--r--src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp59
-rw-r--r--src/Alpha_complex/utilities/alphacomplex.md (renamed from src/Alpha_complex/utilities/README)173
-rw-r--r--src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp43
-rw-r--r--src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp54
-rw-r--r--src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp51
-rw-r--r--src/Alpha_complex/utilities/weighted_periodic_alpha_complex_3d_persistence.cpp95
-rw-r--r--src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h1
-rw-r--r--src/Bitmap_cubical_complex/utilities/README18
-rw-r--r--src/Bitmap_cubical_complex/utilities/cubicalcomplex.md29
-rw-r--r--src/Bottleneck_distance/include/gudhi/Bottleneck.h4
-rw-r--r--src/Bottleneck_distance/include/gudhi/Neighbors_finder.h3
-rw-r--r--src/Bottleneck_distance/utilities/README10
-rw-r--r--src/Bottleneck_distance/utilities/bottleneckdistance.md18
-rw-r--r--src/Contraction/include/gudhi/Edge_contraction.h4
-rw-r--r--src/Doxyfile4
-rw-r--r--src/GudhUI/CMakeLists.txt66
-rw-r--r--src/Kernels/example/kernel_basic_example.cpp18
-rw-r--r--src/Kernels/include/gudhi/kernel.h480
-rw-r--r--src/Nerve_GIC/doc/Intro_graph_induced_complex.h44
-rw-r--r--src/Nerve_GIC/doc/funcGICvisu.jpgbin71647 -> 68388 bytes
-rw-r--r--src/Nerve_GIC/doc/funcGICvisu.pdfbin0 -> 11347 bytes
-rw-r--r--src/Nerve_GIC/example/CMakeLists.txt40
-rw-r--r--src/Nerve_GIC/example/CoordGIC.cpp4
-rw-r--r--src/Nerve_GIC/example/FuncGIC.cpp4
-rw-r--r--src/Nerve_GIC/example/GIC.cpp95
-rwxr-xr-xsrc/Nerve_GIC/example/KeplerMapperVisuFromTxtFile.py72
-rw-r--r--src/Nerve_GIC/example/Nerve.txt43
-rw-r--r--src/Nerve_GIC/include/gudhi/GIC.h768
-rw-r--r--src/Nerve_GIC/test/CMakeLists.txt19
-rw-r--r--src/Nerve_GIC/test/test_GIC.cpp4
-rw-r--r--src/Nerve_GIC/utilities/CMakeLists.txt28
-rwxr-xr-xsrc/Nerve_GIC/utilities/KeplerMapperVisuFromTxtFile.py89
-rw-r--r--src/Nerve_GIC/utilities/Nerve.cpp (renamed from src/Nerve_GIC/example/Nerve.cpp)5
-rw-r--r--src/Nerve_GIC/utilities/Nerve.txt63
-rw-r--r--src/Nerve_GIC/utilities/VoronoiGIC.cpp (renamed from src/Nerve_GIC/example/VoronoiGIC.cpp)4
-rw-r--r--src/Nerve_GIC/utilities/covercomplex.md62
-rwxr-xr-xsrc/Nerve_GIC/utilities/km.py (renamed from src/Nerve_GIC/example/km.py)0
-rw-r--r--src/Nerve_GIC/utilities/km.py.COPYRIGHT (renamed from src/Nerve_GIC/example/km.py.COPYRIGHT)0
-rw-r--r--src/Persistence_representations/doc/Persistence_representations_doc.h10
-rw-r--r--src/Persistence_representations/example/CMakeLists.txt17
-rw-r--r--src/Persistence_representations/example/persistence_vectors.cpp2
-rw-r--r--src/Persistence_representations/example/persistence_weighted_gaussian.cpp96
-rw-r--r--src/Persistence_representations/example/sliced_wasserstein.cpp55
-rw-r--r--src/Persistence_representations/include/gudhi/PSSK.h8
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_heat_maps.h21
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_intervals.h17
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h3
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_landscape.h130
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h12
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_vectors.h7
-rw-r--r--src/Persistence_representations/include/gudhi/Persistence_weighted_gaussian.h143
-rw-r--r--src/Persistence_representations/include/gudhi/Sliced_Wasserstein.h285
-rw-r--r--src/Persistence_representations/include/gudhi/read_persistence_from_file.h125
-rw-r--r--src/Persistence_representations/test/CMakeLists.txt14
-rw-r--r--src/Persistence_representations/test/persistence_heat_maps_test.cpp72
-rw-r--r--src/Persistence_representations/test/persistence_intervals_test.cpp231
-rw-r--r--src/Persistence_representations/test/persistence_intervals_with_distances_test.cpp19
-rw-r--r--src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp64
-rw-r--r--src/Persistence_representations/test/persistence_lanscapes_test.cpp170
-rw-r--r--src/Persistence_representations/test/read_persistence_from_file_test.cpp12
-rw-r--r--src/Persistence_representations/test/vector_representation_test.cpp8
-rw-r--r--src/Persistence_representations/utilities/CMakeLists.txt55
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt72
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/average_persistence_heat_maps.cpp16
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp13
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp14
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp35
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp37
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp38
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp34
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp34
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp8
-rw-r--r--src/Persistence_representations/utilities/persistence_heat_maps/simple_diagram.txt.mps11
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt44
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp22
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp20
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp1
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp39
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp30
-rw-r--r--src/Persistence_representations/utilities/persistence_intervals/plot_persistence_intervals.cpp13
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt40
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/average_landscapes.cpp15
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp14
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/compute_scalar_product_of_landscapes.cpp15
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/create_landscapes.cpp24
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp16
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes/simple_diagram.txt.land13
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt39
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp16
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp13
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp15
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp26
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp17
-rw-r--r--src/Persistence_representations/utilities/persistence_landscapes_on_grid/simple_diagram.txt.g_land104
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt38
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/average_persistence_vectors.cpp16
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp6
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp18
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp26
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/plot_persistence_vectors.cpp3
-rw-r--r--src/Persistence_representations/utilities/persistence_vectors/simple_diagram.txt.vect1
-rw-r--r--src/Persistent_cohomology/doc/Intro_persistent_cohomology.h32
-rw-r--r--src/Rips_complex/doc/Intro_rips_complex.h2
-rw-r--r--src/Rips_complex/test/test_rips_complex.cpp25
-rw-r--r--src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp61
-rw-r--r--src/Rips_complex/utilities/rips_persistence.cpp60
-rw-r--r--src/Rips_complex/utilities/ripscomplex.md (renamed from src/Rips_complex/utilities/README)55
-rw-r--r--src/Simplex_tree/doc/Intro_simplex_tree.h1
-rw-r--r--src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp85
-rw-r--r--src/Simplex_tree/example/graph_expansion_with_blocker.cpp40
-rw-r--r--src/Simplex_tree/example/simple_simplex_tree.cpp84
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree.h179
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h32
-rw-r--r--src/Simplex_tree/test/simplex_tree_unit_test.cpp32
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h3
-rw-r--r--src/Spatial_searching/doc/Intro_spatial_searching.h2
-rw-r--r--src/Spatial_searching/include/gudhi/Kd_tree_search.h3
-rw-r--r--src/Subsampling/doc/Intro_subsampling.h2
-rw-r--r--src/Subsampling/include/gudhi/choose_n_farthest_points.h4
-rw-r--r--src/Tangential_complex/doc/Intro_tangential_complex.h2
-rw-r--r--src/Witness_complex/doc/Witness_complex_doc.h3
-rw-r--r--src/Witness_complex/example/example_strong_witness_complex_off.cpp22
-rw-r--r--src/Witness_complex/example/example_witness_complex_sphere.cpp24
-rw-r--r--src/Witness_complex/utilities/strong_witness_persistence.cpp69
-rw-r--r--src/Witness_complex/utilities/weak_witness_persistence.cpp69
-rw-r--r--src/Witness_complex/utilities/witnesscomplex.md (renamed from src/Witness_complex/utilities/README)62
-rw-r--r--src/cmake/modules/GUDHI_test_coverage.cmake14
-rw-r--r--src/cmake/modules/GUDHI_third_party_libraries.cmake7
-rw-r--r--src/common/doc/examples.h99
-rw-r--r--src/common/doc/file_formats.h2
-rw-r--r--src/common/doc/footer.html10
-rw-r--r--src/common/doc/header.html4
-rw-r--r--src/common/doc/installation.h263
-rw-r--r--src/common/doc/main_page.h307
-rw-r--r--src/common/include/gudhi/Debug_utils.h4
-rw-r--r--src/common/include/gudhi/Unitary_tests_utils.h40
-rw-r--r--src/common/include/gudhi/distance_functions.h31
-rw-r--r--src/common/utilities/README19
-rw-r--r--src/common/utilities/pointsetgenerator.md33
-rw-r--r--src/cython/cython/simplex_tree.pyx11
-rw-r--r--src/cython/doc/_templates/layout.html6
-rwxr-xr-xsrc/cython/doc/conf.py4
-rw-r--r--src/cython/doc/cubical_complex_user.rst45
-rw-r--r--src/cython/doc/fileformats.rst55
-rw-r--r--src/cython/doc/witness_complex_user.rst2
-rw-r--r--src/cython/include/Tangential_complex_interface.h2
-rw-r--r--src/cython/setup.py.in4
162 files changed, 5688 insertions, 3294 deletions
diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt
index bfef1590..5e71f7eb 100644
--- a/CMakeGUDHIVersion.txt
+++ b/CMakeGUDHIVersion.txt
@@ -1,6 +1,6 @@
set (GUDHI_MAJOR_VERSION 2)
-set (GUDHI_MINOR_VERSION 0)
-set (GUDHI_PATCH_VERSION 1)
+set (GUDHI_MINOR_VERSION 1)
+set (GUDHI_PATCH_VERSION 0)
set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION})
message(STATUS "GUDHI version : ${GUDHI_VERSION}")
diff --git a/biblio/how_to_cite_gudhi.bib b/biblio/how_to_cite_gudhi.bib
index b8c29109..5994124a 100644
--- a/biblio/how_to_cite_gudhi.bib
+++ b/biblio/how_to_cite_gudhi.bib
@@ -123,11 +123,20 @@
, year = 2016
}
-@incollection{gudhi:Kernels
+@incollection{gudhi:CoverComplex
, author = "Mathieu Carri\`ere"
-, title = "Kernels for PDs"
+, title = "Cover complex"
, publisher = "{GUDHI Editorial Board}"
, booktitle = "{GUDHI} User and Reference Manual"
-, url = "http://gudhi.gforge.inria.fr/python/latest/"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group__cover__complex.html"
+, year = 2017
+}
+
+@incollection{gudhi:PersistenceRepresentations
+, author = "Pawel Dlotko"
+, title = "Persistence representations"
+, publisher = "{GUDHI Editorial Board}"
+, booktitle = "{GUDHI} User and Reference Manual"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group___persistence__representations.html"
, year = 2017
}
diff --git a/data/persistence_diagram/PD1 b/data/persistence_diagram/PD1.pers
index 404199b4..404199b4 100644
--- a/data/persistence_diagram/PD1
+++ b/data/persistence_diagram/PD1.pers
diff --git a/data/persistence_diagram/PD2 b/data/persistence_diagram/PD2.pers
index 125d8e4b..125d8e4b 100644
--- a/data/persistence_diagram/PD2
+++ b/data/persistence_diagram/PD2.pers
diff --git a/data/persistence_diagram/simple_diagram.txt b/data/persistence_diagram/simple_diagram.txt
deleted file mode 100644
index 2f199fd4..00000000
--- a/data/persistence_diagram/simple_diagram.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-1 2
-3 4
-5 6
-7 8 \ No newline at end of file
diff --git a/data/points/KleinBottle5D.off b/data/points/KleinBottle5D.off
index b578593c..b578593c 100755..100644
--- a/data/points/KleinBottle5D.off
+++ b/data/points/KleinBottle5D.off
diff --git a/data/points/human.off b/data/points/human.off
index f9f79a3f..f9f79a3f 100755..100644
--- a/data/points/human.off
+++ b/data/points/human.off
diff --git a/data/points/iso_cuboid_3_in_0_10.txt b/data/points/iso_cuboid_3_in_0_10.txt
new file mode 100644
index 00000000..d4bd2233
--- /dev/null
+++ b/data/points/iso_cuboid_3_in_0_10.txt
@@ -0,0 +1 @@
+0.0 0.0 0.0 10.0 10.0 10.0
diff --git a/data/points/shifted_sphere.off b/data/points/shifted_sphere.off
new file mode 100644
index 00000000..54051bb1
--- /dev/null
+++ b/data/points/shifted_sphere.off
@@ -0,0 +1,1002 @@
+OFF
+1000 0 0
+9.30846 0.674959 0.354663
+0.319662 1.44971 1.83394
+9.65204 0.108855 0.71069
+0.436642 0.138375 0.741799
+0.0632498 0.127158 1.4832
+9.82265 1.72038 0.329397
+9.68531 1.67209 1.6711
+9.1011 1.35914 0.751961
+9.65025 0.282699 1.60289
+0.595828 0.729081 1.75592
+9.80149 0.757514 0.050331
+9.10316 1.37502 0.766079
+0.206286 1.28181 0.062618
+9.86287 0.599391 1.90637
+0.752303 0.959047 1.65779
+0.408715 0.370051 0.339071
+0.763951 0.35776 0.96287
+0.787187 1.58585 1.19409
+9.19533 1.56634 0.817889
+0.389083 1.48987 1.77932
+9.29707 1.50344 1.5013
+9.52194 1.25374 1.84083
+9.11152 1.14569 1.43541
+9.13003 0.676105 1.36907
+9.26591 0.33078 1.11691
+0.225878 1.68793 0.309819
+9.17648 1.48207 1.29953
+9.06088 0.770958 1.26066
+0.40229 1.67195 1.62168
+0.36113 0.210086 0.505648
+0.513719 0.606886 0.237303
+0.465305 1.00616 0.11343
+9.79064 0.531028 1.85772
+0.402296 1.68593 0.392899
+9.39871 0.785732 1.76864
+9.50963 0.769971 1.84125
+0.574711 0.232991 1.28278
+9.46029 1.74245 1.39506
+9.70859 1.728 0.381063
+9.40135 1.6228 0.497349
+9.80349 0.350047 0.265554
+0.5205 0.315442 0.489697
+9.66743 1.59533 0.268522
+0.63638 0.459809 1.55151
+9.32128 1.69746 1.22987
+0.579606 1.62531 0.477566
+9.46979 1.05065 0.153742
+0.497503 0.295609 0.494444
+9.5305 0.311525 0.448818
+0.201698 0.559269 1.87594
+9.40197 0.242174 0.739812
+9.80384 0.436469 0.196842
+0.917472 1.3961 1.03098
+0.430443 1.70418 1.56464
+0.734443 1.0951 0.327576
+0.128518 1.23079 0.036416
+0.512276 0.354876 1.5682
+0.335417 1.94211 0.96602
+9.41638 1.61148 0.466857
+9.66932 0.48881 1.79411
+0.693771 1.19897 1.69116
+0.500594 1.0148 0.134668
+9.1287 1.41163 0.734505
+0.512771 0.175531 0.757848
+0.688494 0.28064 0.912601
+9.81907 1.45648 1.87221
+9.59914 0.361106 1.65511
+9.6906 0.729731 1.9109
+0.38137 0.228081 1.50909
+9.89254 0.171539 0.451542
+9.3757 0.669098 1.70762
+0.567413 0.506158 0.341853
+9.41361 0.356943 0.504933
+0.693218 1.33146 0.359005
+9.33618 1.02829 0.25267
+0.33001 0.889273 1.93754
+0.634114 1.7631 1.11676
+9.20523 0.969888 1.6064
+9.49207 1.43389 1.74365
+9.48723 1.3551 1.78098
+0.353267 0.171761 0.566745
+0.00281403 1.95322 0.694855
+9.81863 0.133865 1.466
+9.18333 0.606508 1.42101
+0.809911 0.481932 1.27582
+0.618363 0.306112 1.36657
+0.57338 0.861296 1.80684
+9.52152 0.375778 1.61674
+9.22189 0.377518 0.927135
+0.0672128 0.104379 1.44149
+0.747095 0.927229 0.338673
+0.608156 0.704862 0.264126
+0.363804 0.074293 1.10006
+0.0122474 1.98089 1.19565
+9.56964 0.781257 0.124396
+9.75726 1.35396 1.90289
+0.580618 0.348216 0.51222
+0.90293 1.25833 0.655364
+0.707832 0.496896 1.49614
+9.91197 1.44047 0.106621
+0.62221 0.633297 0.308156
+0.738081 0.545317 1.49771
+9.26368 0.870001 0.336853
+9.41656 0.303368 1.41853
+0.660177 1.55316 0.492621
+9.29193 1.11476 0.302828
+0.753703 0.922288 1.65315
+9.90122 1.57401 0.186427
+9.89515 0.81988 0.022722
+0.943642 0.669905 1.03831
+0.35494 0.121196 1.3186
+0.113821 0.725036 0.044863
+0.78621 0.525938 0.602937
+0.9436 0.711032 1.164
+0.693706 0.996992 1.71948
+9.55737 0.66744 1.832
+0.033109 1.90074 0.567379
+0.0303382 1.59115 1.80647
+0.510765 0.383863 1.59787
+0.504748 1.62916 0.408589
+0.599172 0.347881 1.4643
+0.770621 1.4112 0.513994
+9.89523 1.04275 0.007174
+0.918102 1.39349 1.05751
+0.289995 0.2713 0.378792
+0.635603 0.346144 1.41236
+9.27103 0.366076 0.746158
+0.744256 1.58078 0.671541
+9.82547 1.69795 0.305921
+0.475202 1.79287 1.3805
+9.23064 1.61766 1.16769
+0.839446 0.471308 1.12654
+9.64484 1.06402 1.93287
+0.869122 1.31313 0.619081
+9.37852 0.613046 0.317987
+9.12666 1.01357 1.48593
+0.61551 0.509337 0.383014
+9.49447 0.289841 1.49055
+9.33656 1.65404 0.637152
+9.2815 1.21595 0.338471
+0.175223 1.66642 0.275799
+9.91146 1.81366 0.425203
+9.5727 0.096868 0.968795
+0.675554 0.341694 1.33051
+9.47093 0.373629 0.427866
+0.424603 0.384317 1.66227
+0.742433 1.66671 0.919566
+9.36778 0.442545 0.462367
+9.73883 1.78075 1.5683
+0.726513 0.323835 1.1158
+0.302755 1.38553 1.87211
+0.535727 1.42295 1.7306
+9.58514 0.244869 1.50895
+9.52125 0.246166 1.44982
+9.31431 1.62892 1.36503
+9.98779 0.257898 0.329823
+0.0579226 1.5191 1.85295
+0.0992393 1.41632 1.90423
+9.31551 1.62831 1.37069
+0.405234 1.88855 1.21584
+0.625832 1.50754 1.59278
+0.540334 1.01342 1.84151
+0.6496 0.542131 1.60709
+9.1196 1.26202 1.39519
+9.86104 0.212888 0.399129
+9.06495 1.24027 0.737926
+0.344454 0.185716 0.532575
+9.75547 1.66099 0.291572
+9.63087 1.87689 0.690648
+9.49262 1.54726 1.66683
+9.6166 0.390168 0.305417
+0.137617 1.74887 0.351788
+0.510714 0.156618 0.831459
+0.910054 1.31334 0.726199
+0.306053 0.148671 1.42861
+9.30128 0.760904 1.67389
+9.77787 1.97485 1.02163
+9.36039 0.274654 1.2556
+0.650794 0.707288 1.70052
+9.28551 0.89261 0.308749
+9.6073 0.750516 1.88548
+0.139642 0.374535 0.233686
+0.169241 1.00351 1.98452
+0.17452 1.73298 0.342129
+9.81048 1.29468 0.064031
+0.613694 0.491945 1.6058
+0.86926 0.511672 0.928761
+9.37715 0.254352 1.23831
+0.529366 0.500958 1.68549
+0.707169 0.370226 1.32004
+0.583783 0.810561 0.211606
+0.817859 0.614869 1.42783
+0.273889 1.8313 0.517321
+9.65951 0.109985 1.30326
+0.534185 1.66958 1.51599
+9.40421 1.79876 1.08529
+0.401013 1.44468 1.79996
+0.734147 0.681305 0.40045
+0.267486 1.65773 1.7031
+0.207956 1.58052 0.213657
+9.50709 1.75553 1.4317
+9.6408 1.91814 1.1672
+0.603943 1.79704 0.968268
+9.29105 0.675764 1.62584
+9.45715 0.724906 0.207524
+0.896406 1.44072 1.0199
+0.452172 1.56373 1.6909
+9.18298 0.426014 1.05132
+9.58257 1.90551 1.08378
+0.241326 0.669849 0.086473
+0.69452 0.649301 1.62797
+9.31101 0.393937 1.39491
+0.606919 1.74714 1.26936
+9.01696 1.12479 0.868244
+0.699129 1.16957 0.305401
+9.78814 1.9726 0.901019
+0.110775 1.21621 1.97039
+9.87457 0.228483 0.377592
+0.244342 0.245656 0.390684
+0.209537 0.523986 0.145469
+0.0681799 1.90388 1.42101
+9.19912 1.10591 0.411084
+9.39365 0.622151 1.69953
+0.585521 1.47394 1.65807
+9.59435 1.03292 1.91382
+9.58259 0.12136 1.23316
+9.32166 0.278287 1.13967
+9.92846 0.598427 0.087388
+9.58126 0.739163 0.131286
+9.49655 1.79467 0.65822
+9.33657 1.7484 1.016
+9.12701 1.46677 1.14482
+0.561281 1.431 0.294166
+9.78693 1.67653 0.294285
+9.34118 1.65731 0.633753
+0.710196 1.64238 0.709801
+0.886622 1.20789 1.41162
+0.0677664 1.88706 1.45798
+0.698576 1.64678 0.693225
+0.448705 1.4017 0.200863
+9.07985 1.18138 1.34817
+0.336259 0.075346 0.820857
+9.20408 1.60515 0.946053
+0.287467 0.837373 0.056324
+0.749378 1.41774 0.486959
+9.26923 1.37711 0.430709
+0.14936 1.42609 0.107197
+0.0714009 0.385934 0.213925
+9.8277 1.53049 1.82976
+0.708935 1.65578 0.738062
+0.0948228 1.02128 1.99598
+9.46121 1.82926 0.851863
+0.351601 0.320042 1.64413
+9.14855 1.5226 0.95391
+9.66048 1.89872 0.723401
+0.731093 1.54757 1.4081
+0.568092 1.55204 0.390022
+9.50103 1.02343 1.86631
+0.900843 1.06925 0.572554
+0.924983 0.750278 0.71105
+9.5152 1.53088 1.69393
+0.526094 0.382679 1.58711
+9.27225 0.58499 0.451932
+9.8952 0.339988 1.7439
+0.539653 0.16291 0.908454
+0.764392 0.718045 0.420146
+0.212162 1.58316 0.215563
+0.586207 0.190524 0.98709
+0.762071 1.35318 0.457938
+0.667942 1.58796 0.543524
+0.919602 0.817803 1.34976
+0.979513 1.19215 1.04643
+0.604525 0.415454 0.457791
+9.31338 1.18312 0.295843
+0.826517 1.56001 0.957552
+0.960202 1.00363 0.71871
+9.88889 0.593648 0.092558
+9.26776 1.42434 1.53417
+9.72683 0.212705 0.446213
+0.0892455 0.428248 1.81447
+9.1279 0.803382 1.44952
+0.567967 0.233242 0.700016
+0.713055 1.30645 1.63019
+9.39379 0.533988 1.64534
+9.79079 0.392974 1.76697
+0.189703 1.7765 0.399243
+0.452701 0.330663 1.59137
+9.90818 1.98953 1.11297
+0.791462 0.396492 1.10484
+0.365535 1.62772 1.68677
+9.32953 0.284113 0.810467
+9.40158 0.427932 0.437794
+9.391 1.1379 1.78265
+0.18534 1.63937 0.252221
+9.2501 1.64904 0.877825
+0.555286 0.945554 1.8299
+9.06892 0.733273 1.24644
+9.56004 1.88069 0.82576
+0.536902 1.59437 1.59971
+0.719609 1.53732 1.44135
+0.815317 1.48107 0.679938
+9.09161 1.07216 0.587408
+0.38704 0.393483 0.305542
+0.58356 0.931129 1.80986
+9.76549 0.315478 1.69017
+9.41161 1.49959 1.63564
+0.857946 1.14196 1.49573
+9.1062 0.55662 1.06206
+0.655278 0.37006 1.41593
+0.43935 1.77927 0.553587
+0.498884 0.633188 0.215244
+0.0413873 0.052232 0.68187
+9.21432 1.21157 1.58165
+9.3669 0.288726 1.30683
+9.21879 0.732198 1.56605
+0.137692 0.009768 0.98158
+0.534583 1.82836 0.832465
+9.49295 1.73478 0.550143
+9.91646 0.353096 0.242656
+0.589176 0.86984 0.202279
+0.362188 0.280249 0.408181
+0.274268 0.578879 1.86326
+0.604039 0.646069 1.71282
+0.223247 0.248073 1.6204
+9.80604 0.039333 0.800413
+9.34856 0.519354 0.413036
+0.575657 0.363191 0.487241
+9.77876 0.111893 0.59577
+9.35382 0.371739 0.566805
+0.390854 1.63041 0.329802
+0.326032 0.299066 1.63321
+0.276027 1.93536 0.780336
+9.5341 0.308619 0.448063
+9.69074 1.65329 1.69065
+0.80983 1.41519 0.583414
+0.214206 1.97686 1.01529
+9.30424 0.422441 1.4283
+9.03621 0.932833 1.25919
+0.0162511 1.47352 0.119265
+0.634681 1.62576 1.45132
+9.62458 0.421022 0.276348
+9.59186 0.094231 1.1144
+0.235683 0.039578 1.14882
+0.679211 0.561997 0.409886
+9.27834 1.23643 1.64976
+9.98396 1.1683 0.01445
+0.89075 0.574707 0.841959
+0.599068 1.71862 0.645656
+0.735763 0.802774 0.351296
+0.221189 1.63699 0.261565
+0.491243 1.76319 1.42035
+9.52118 1.65738 0.419019
+0.585694 0.375541 0.483415
+0.396747 1.018 1.91799
+0.272033 0.049254 0.849099
+9.69974 1.88908 0.65217
+9.68837 0.238558 1.56671
+0.00255645 1.10273 0.005041
+9.55682 1.89631 1.00269
+9.55587 0.301162 0.439312
+9.53807 1.4991 0.268301
+9.89207 0.216586 0.389146
+9.1795 0.588829 1.39745
+9.31832 1.72452 1.09325
+9.13622 1.06525 0.499373
+9.52185 1.36872 1.79725
+9.22658 1.61069 1.16485
+9.94276 1.24572 1.96796
+9.02696 1.0582 1.22697
+0.80752 0.708452 0.487053
+9.10573 1.4299 1.1269
+0.98495 0.860354 1.10283
+9.38055 1.15878 1.76855
+9.45367 0.19399 0.77129
+0.875921 0.781193 0.568202
+9.87074 0.769623 0.034773
+0.224263 0.295292 0.32622
+0.731827 0.618023 0.434908
+9.99886 1.69083 1.72367
+0.623328 0.634997 1.6922
+9.3372 0.587922 1.62543
+9.3572 1.59656 1.48079
+9.27659 1.1581 0.327505
+0.39176 1.74876 0.466292
+0.143229 0.295076 1.69381
+9.88444 1.35346 0.07155
+0.596156 0.885592 1.79536
+0.632835 1.35451 0.312432
+9.91148 1.91254 0.601527
+9.70675 0.132142 1.40151
+0.0379983 1.96093 0.727646
+0.0695625 1.67084 1.73697
+0.0497337 0.069458 1.36443
+0.467864 1.64334 0.39398
+9.88243 0.325653 0.271916
+9.25849 0.352779 0.826798
+9.41786 0.615693 0.283297
+9.77252 0.06521 0.730099
+9.07278 0.724821 0.745202
+0.541446 0.554969 1.71349
+9.07219 1.36188 0.910299
+9.96347 1.31989 0.053531
+9.94233 0.057785 0.672203
+0.851371 0.633945 1.37547
+9.41634 1.75703 1.29234
+0.432735 0.89891 1.89562
+9.42798 1.77295 0.723062
+0.718712 0.939884 0.307506
+9.39573 0.349571 1.46192
+9.8909 0.057458 0.681189
+0.587289 0.65288 1.73061
+9.49098 0.527971 0.278984
+0.531355 0.407789 1.60662
+0.44577 1.61302 0.34676
+9.4039 0.875696 1.79229
+9.30052 0.300747 0.857446
+9.97632 1.36358 0.068381
+0.977321 0.981502 1.21586
+0.18791 1.7447 1.64068
+9.77844 1.69616 1.68323
+9.45987 1.02334 1.84107
+9.62908 0.371649 0.315032
+0.837233 0.791406 0.495623
+0.186518 1.57329 1.79823
+9.2765 1.54891 0.58079
+0.551206 0.643942 0.247098
+9.23363 0.46334 1.35321
+0.334144 1.80084 0.502846
+9.16145 1.5192 0.831298
+0.762642 0.358565 0.927552
+9.1761 1.26594 0.497657
+0.820286 1.10485 1.56154
+0.815722 1.5629 0.876298
+9.04692 1.21477 0.785943
+0.185109 1.97267 0.863569
+0.203111 0.42647 1.79413
+9.26044 0.45224 0.608183
+9.36708 0.422611 1.51615
+0.0531105 1.89548 1.44169
+9.57875 1.02138 0.093198
+9.43244 1.32488 0.243539
+9.31694 1.70926 0.829119
+9.62104 1.67553 1.63247
+9.83744 0.189483 0.435472
+0.550179 0.167419 1.06353
+0.00502337 1.72837 0.316535
+0.932246 1.35071 1.08601
+9.55128 0.16624 0.678766
+0.503754 1.13797 0.146266
+9.45202 1.46465 1.69603
+0.10128 0.400598 1.79456
+0.918924 0.803505 0.655406
+0.103326 1.81527 1.57046
+0.747962 0.946862 1.66143
+0.0327211 1.70282 0.28861
+0.218882 1.64983 0.272482
+0.199276 0.065998 0.706647
+0.504895 0.394994 0.384649
+9.94351 0.357309 1.76518
+0.694589 1.71921 0.969525
+9.67198 1.59351 1.73384
+0.421343 0.663674 1.8436
+0.551235 0.229307 1.32017
+0.758943 0.642131 0.456827
+9.4442 0.171738 0.924593
+9.28092 1.67664 1.1585
+0.659912 0.592402 0.369168
+0.114891 0.580276 0.098807
+9.91435 0.769098 0.029944
+9.04828 1.11313 0.715219
+0.968707 0.853522 0.798368
+9.94126 0.206713 1.60462
+0.65562 1.08526 1.7506
+9.11825 1.32529 0.656674
+0.246314 0.848914 0.04193
+0.731244 1.2672 0.372555
+9.87693 1.66967 1.73409
+9.9703 0.503362 1.86819
+0.667704 1.44317 1.59887
+9.53734 1.39847 0.207196
+9.97053 1.79371 0.393694
+9.37297 1.1686 0.23899
+9.45256 1.61958 0.43834
+9.76375 1.71549 0.340859
+9.3734 0.346872 1.42407
+0.5125 1.84211 0.832575
+0.932041 0.67555 0.845347
+9.49733 1.24542 0.171411
+9.83022 0.218933 0.398263
+9.3321 0.476499 1.53112
+0.550712 1.35084 0.243683
+9.6505 1.77285 1.53145
+0.11957 0.947519 0.007769
+9.75615 0.596159 1.88234
+0.809122 0.438308 1.17405
+9.95713 0.981126 1.99948
+0.591199 1.60434 1.53349
+0.487668 1.85321 1.18495
+0.956176 1.26081 0.862054
+9.46859 0.629161 1.76147
+0.547885 0.544311 0.29811
+0.536275 0.220812 1.32556
+0.398207 1.91061 1.11507
+0.0402346 0.316766 0.270353
+0.270426 1.61264 1.74224
+9.71078 0.358589 1.71085
+9.24733 1.50792 0.578291
+0.613955 1.19862 1.76316
+0.392413 1.74782 1.53531
+9.24869 1.06357 0.344695
+9.53261 1.5516 0.309929
+0.935946 0.813894 1.30057
+0.527774 0.162478 0.850937
+0.830806 1.53354 1.16061
+9.02502 0.812013 0.878552
+0.519587 1.78326 1.34115
+0.567002 1.21986 1.79448
+9.13955 0.850995 1.4861
+0.74967 1.64198 0.843855
+0.175846 0.700507 1.93899
+9.73844 0.22365 1.57498
+9.26819 1.66752 0.861099
+9.71894 0.404593 0.247375
+9.53267 0.214904 0.595629
+0.693719 0.917312 0.284077
+0.547917 0.402839 0.413438
+0.0844952 0.885454 1.99056
+0.202379 0.278 1.66239
+0.265358 1.08061 0.03905
+0.775521 1.24402 0.417377
+9.91364 1.99236 0.908648
+0.388763 1.55501 1.73574
+9.122 1.4585 1.14199
+0.856257 0.504886 1.147
+9.63301 1.91146 0.809757
+9.18053 1.46788 1.33201
+0.868119 1.49438 0.97842
+0.891772 1.17963 0.585111
+0.850286 0.863415 1.50974
+9.63805 1.8232 0.565249
+0.690344 0.877511 1.71198
+0.747495 1.20652 1.63033
+9.03804 1.1497 0.772564
+0.802784 1.39586 0.552522
+0.589376 1.57708 1.56531
+0.418664 1.67319 1.61064
+0.209528 1.85472 1.47302
+9.76727 1.54659 1.80444
+0.33653 1.63502 0.304715
+0.171426 0.258308 1.64949
+0.907411 0.666978 1.2608
+9.1637 1.07816 1.54336
+0.683719 0.303247 1.21306
+9.60125 0.247266 1.52338
+0.670147 0.446458 0.50591
+0.495214 0.186146 1.30503
+0.340572 0.770593 1.91229
+0.294228 1.9449 0.862692
+0.876347 1.18335 0.556539
+9.4379 0.336691 0.505474
+9.80748 0.375332 1.75574
+9.30654 0.782442 0.312649
+0.782074 1.29819 1.54777
+0.0583806 1.94132 1.33345
+9.38461 1.61502 1.49326
+9.45506 1.71879 0.568663
+9.69553 0.42906 1.7633
+9.44246 1.39375 1.73089
+9.27668 1.54311 1.42565
+0.244979 0.425879 1.78104
+0.0508857 1.35719 1.93165
+0.508441 0.568761 1.74461
+0.22771 1.12088 0.032771
+0.331629 1.7584 1.56037
+9.23481 1.57289 0.70378
+0.512795 1.3176 0.203395
+0.0350435 1.5893 0.193235
+9.20153 1.55324 0.762203
+0.164685 0.836704 0.027783
+0.0300097 0.303271 1.71596
+9.3172 1.71852 1.13144
+9.66242 0.280481 1.60535
+0.321784 0.157059 1.43201
+9.22851 0.822415 1.60948
+0.58427 1.07427 1.80832
+0.654863 0.87903 1.74468
+0.706336 0.531863 1.53079
+0.0169793 1.76133 0.352015
+9.66444 0.172158 1.44895
+0.67235 1.42259 0.391911
+0.829522 0.97393 1.55827
+9.81542 1.61738 1.76373
+0.756196 1.44959 0.523201
+0.65706 1.11249 1.74695
+9.37241 1.57875 0.479702
+9.33588 0.777786 1.71413
+0.375155 1.75113 1.54265
+0.0229391 0.531802 1.88295
+0.213719 1.48186 1.84872
+9.52401 1.24875 0.15692
+9.94211 0.006862 1.09663
+9.33013 0.519479 0.432186
+9.54022 1.37595 0.195345
+9.53769 0.137537 0.794878
+0.343332 1.93923 1.04129
+0.470026 1.46991 1.74635
+9.08859 1.15981 0.6218
+0.525781 0.441913 1.64174
+0.0525363 1.35865 0.069011
+0.110072 0.005576 1.01205
+9.2731 0.66746 1.6017
+0.689674 1.45809 0.438933
+0.847185 0.500752 1.18657
+9.54366 0.310179 0.437616
+9.80241 1.9473 0.745297
+0.352206 1.48317 1.80133
+0.994063 1.02097 1.11557
+0.363083 1.65831 1.65808
+0.0946325 0.915427 0.008875
+9.47179 1.66937 1.52266
+9.25627 1.64231 1.1838
+9.20909 1.31761 1.52317
+9.89843 0.192177 1.58247
+0.33303 0.81999 1.92628
+0.0657317 1.16105 0.015248
+0.755704 1.39947 0.483116
+0.275053 1.79415 1.54376
+0.0361209 0.384035 1.78787
+9.52975 1.6904 0.448524
+9.54536 1.30554 1.83667
+0.0349238 1.70847 0.295379
+9.22441 0.540634 0.567442
+0.386726 1.68692 0.383914
+0.934901 0.651698 1.04749
+0.0287155 1.8789 1.47413
+9.56574 1.90024 1.03899
+9.5682 1.6132 0.339015
+0.747524 1.48544 0.546733
+9.29441 0.8844 1.69898
+9.92357 0.95486 1.9963
+0.883612 1.46008 0.929191
+9.22409 0.513342 1.40356
+9.92647 0.405598 1.79989
+0.818444 1.4833 0.689723
+0.455696 0.897039 0.11702
+0.513092 0.214776 1.34538
+9.73375 1.76073 0.406789
+9.88884 0.328377 0.268188
+9.70471 0.561806 1.84959
+9.16429 1.412 1.36097
+0.274298 0.565471 0.142986
+9.86262 0.990513 1.99072
+0.592856 1.60034 0.464052
+0.937727 1.23643 1.2515
+9.92874 0.031265 0.761554
+9.88665 1.7512 1.65097
+0.7284 1.37457 1.57405
+0.924492 1.3548 1.13326
+9.52508 1.7702 0.571209
+9.28926 0.660586 0.383994
+0.739071 1.25631 0.377355
+0.86006 0.634698 1.35433
+9.59589 1.25798 1.87764
+0.906153 1.39396 0.844199
+9.26927 0.731891 1.62699
+9.53049 1.83076 0.701588
+0.444221 0.224474 1.4505
+9.99488 1.87759 0.519899
+0.66516 0.298101 0.744515
+0.49939 0.933317 0.135503
+9.72602 1.89041 1.36586
+0.9979 0.966813 1.03886
+9.72708 0.297366 1.65811
+0.895043 0.553516 0.973516
+9.87917 0.007656 0.948227
+9.61016 1.68094 0.381168
+0.769795 1.37345 1.51768
+0.267673 0.870071 1.95429
+9.41811 0.253617 1.32238
+9.69078 0.28435 1.62643
+9.88903 0.378559 0.225044
+0.738473 1.63003 0.758483
+0.676777 0.750002 1.69234
+0.324284 1.81755 0.523296
+0.198011 1.56812 1.80002
+0.846835 0.505819 1.19449
+0.964422 1.07372 0.742479
+9.8486 1.76812 1.62083
+0.325947 1.76194 1.55871
+0.0928117 1.79537 1.59902
+0.540065 1.82114 0.811507
+9.38792 1.67465 0.586693
+0.250774 0.403275 0.237141
+9.335 0.879029 0.264208
+0.34599 1.84448 1.40829
+9.81458 0.599094 1.89721
+0.716022 0.311804 0.877223
+9.33174 0.675852 0.329869
+0.628637 0.687032 1.71095
+9.96661 1.87236 0.510967
+0.42254 0.657619 1.84023
+9.59113 1.58078 1.70241
+9.58299 0.383387 1.66821
+9.3978 0.824698 1.77784
+9.97121 1.84906 0.473275
+0.274797 0.049728 0.853491
+0.0742825 0.128504 0.51645
+0.592091 0.741113 1.76144
+0.647568 1.63463 0.580052
+9.42798 0.649392 1.74144
+0.928172 1.25702 0.731125
+9.1111 1.40986 0.797008
+0.533476 0.982859 0.153788
+0.429166 0.290022 1.55578
+0.0600464 0.652227 0.063992
+0.0108808 0.001029 0.964279
+9.56753 0.315251 0.412289
+0.62443 0.279972 0.695399
+0.752 0.897714 1.64952
+0.906618 1.12086 1.40599
+9.61025 1.37057 1.84233
+0.328613 0.302526 0.363258
+0.678302 0.322806 0.716225
+0.390688 0.784454 1.89558
+0.947788 1.1148 1.29747
+0.662258 1.73855 0.873339
+9.79132 0.085265 0.653096
+9.89027 1.99426 0.971032
+9.82892 1.96772 1.18453
+9.21357 1.60729 0.879168
+0.379845 0.285926 0.410559
+0.604001 1.45742 0.347111
+9.61169 0.193379 0.556756
+0.760119 0.348519 0.999573
+9.47079 0.309741 0.507132
+9.49792 1.86474 0.965852
+9.58379 0.401567 1.68369
+9.16082 0.979655 0.455847
+9.65454 1.74968 1.56512
+9.68794 1.76119 1.56854
+9.27859 1.05479 1.68848
+9.95593 1.801 1.59887
+0.0838551 1.99355 1.06997
+9.64751 0.39576 1.7144
+0.509192 0.435253 1.64844
+9.2327 1.26592 1.58499
+9.83622 1.98537 0.98628
+9.1709 1.54751 0.885197
+9.17178 0.461224 0.844773
+0.848394 1.52499 0.939547
+0.0938825 0.14265 1.50551
+0.611498 0.486773 0.398772
+9.04195 1.21577 1.18978
+0.338911 0.443473 1.7597
+9.78861 0.930578 0.025412
+0.684417 1.64386 1.34436
+9.59616 0.90914 1.90959
+9.43427 1.82386 1.02924
+9.61441 0.266579 1.55917
+0.45135 1.22824 0.137735
+0.455622 1.16878 0.126224
+0.750743 1.12841 1.64856
+0.172786 0.075024 1.33716
+0.572666 0.294857 1.4187
+9.27381 1.21164 0.345058
+9.46202 1.64717 1.54077
+0.0366763 0.391544 0.206898
+9.40837 0.206739 0.857619
+0.611193 1.68799 1.39347
+0.862774 0.623728 0.66434
+9.42747 1.53546 1.6204
+0.0182886 3.2e-05 1.00195
+0.469988 1.28221 1.83664
+9.34452 1.75611 0.965025
+9.13378 1.26897 1.42142
+0.626128 0.813556 0.242849
+9.54174 1.23235 1.85908
+0.765526 0.35703 1.03416
+9.16656 0.738462 1.48587
+0.944991 1.22701 0.763345
+9.63657 0.623108 1.85221
+0.116017 0.007572 1.00673
+0.477945 1.72195 1.5003
+0.680767 1.61792 0.606739
+9.70777 1.79969 1.52572
+9.70878 1.76773 0.429594
+9.32819 0.263616 0.921956
+9.85216 1.60872 1.78044
+0.888413 0.788841 1.40964
+9.35123 0.243199 1.07959
+9.73072 1.71735 0.356638
+0.539146 1.66073 1.52119
+9.58888 1.71186 0.428579
+9.7705 1.96015 1.15494
+9.3271 0.271531 1.12971
+0.38882 0.177281 1.41333
+0.578109 1.80902 0.889951
+9.29671 1.27844 0.345163
+0.333766 0.377278 1.70815
+0.194681 0.02759 0.876214
+0.492794 0.515888 0.277186
+9.73075 0.522755 1.83764
+0.73811 1.01636 1.67471
+0.440905 1.64308 0.372436
+0.885936 0.697894 1.35044
+0.248017 0.483918 1.81979
+0.0595597 0.140828 0.490657
+0.744763 1.64309 0.821368
+0.628699 0.819193 0.242528
+0.806474 0.413315 1.05853
+9.86282 1.10855 1.98463
+9.5142 0.673339 0.188719
+0.609208 0.59979 1.6855
+9.46112 0.482508 1.66487
+0.29424 1.93157 0.788847
+0.887888 0.764671 1.39441
+9.36527 1.59945 0.512936
+0.670515 0.567908 1.60186
+0.387324 1.62551 1.67801
+9.69403 1.92717 1.21881
+0.855285 1.01646 1.51826
+0.874648 0.54619 1.16988
+0.401297 0.162778 1.37027
+0.699869 0.521882 0.468438
+9.04117 0.808129 1.20545
+9.79343 1.17177 0.036894
+0.629572 0.563369 1.64294
+0.237979 1.85532 0.539296
+9.61041 1.90074 1.19242
+0.0117479 1.46748 1.88395
+0.717363 1.02219 1.69744
+0.417465 1.65124 0.36796
+9.15203 1.45403 1.27388
+0.862344 0.676412 1.38781
+0.802817 0.442809 0.787517
+9.87139 1.07787 0.011176
+0.869561 1.39444 1.29918
+9.93289 0.37935 1.78029
+9.50474 0.578651 1.76021
+9.157 0.5742 1.32967
+0.974 1.1133 1.19294
+9.3209 0.358139 1.35532
+9.79115 1.8987 1.38553
+0.782911 0.424774 1.23823
+9.20991 0.653463 0.496746
+0.46777 1.75999 1.45042
+0.715743 0.892531 0.308989
+0.0960513 0.636225 0.0725
+9.40396 1.58373 0.451449
+9.95865 1.41271 0.089521
+9.76324 0.907231 0.033297
+9.73945 0.068106 1.25414
+0.536417 0.407007 0.398644
+0.839362 0.731562 0.527637
+0.294591 1.83059 1.4729
+9.83072 1.52465 0.164401
+9.04946 1.26663 1.15474
+0.205957 1.19858 1.95889
+9.36019 0.427652 1.51431
+9.47393 1.13945 0.160051
+0.686785 0.480854 1.50877
+9.74079 1.58783 0.234956
+9.79752 1.49862 0.156777
+9.61756 0.263588 1.55903
+9.39137 0.659291 1.71736
+0.580255 0.443237 1.59434
+9.34656 0.310227 1.31239
+0.0268579 0.554747 1.89521
+0.696521 0.689563 1.64594
+0.651964 1.72023 1.23989
+9.04386 0.753458 0.841026
+0.619664 1.53723 0.427654
+0.596641 0.497144 1.62423
+0.128775 1.73451 0.33271
+0.406038 1.70259 1.58592
+9.26017 1.2072 1.64047
+9.50083 0.472742 1.68693
+9.77601 0.608544 1.89236
+0.132479 0.93583 0.010117
+0.546506 1.40821 0.268103
+9.54142 0.342728 0.400954
+0.627297 1.73608 0.742049
+9.60283 1.36315 1.84372
+9.38232 0.92598 0.21726
+0.360034 1.92928 0.918004
+9.66062 0.260257 0.417215
+0.799573 0.959625 1.59881
+9.45903 0.839588 0.1733
+0.568969 0.219001 0.744878
+0.63884 0.428299 1.51465
+9.25013 1.32073 1.57945
+0.468303 0.123466 0.885497
+0.415226 0.324968 0.388973
+9.24282 0.833462 1.63171
+0.466496 1.56766 1.67818
+0.262187 0.143814 0.556028
+9.14692 0.936489 1.51721
+0.143808 0.16235 0.471895
+9.07604 0.635357 0.880006
+0.602601 0.642722 1.71231
+9.10192 0.959485 1.43947
+9.49288 1.84763 0.840536
+0.259475 0.836268 1.95074
+9.5931 0.169714 0.621414
+9.34152 0.54576 1.59995
+0.385993 0.077814 1.00309
+9.7543 0.392957 1.7549
+0.703594 1.59957 0.618014
+0.28396 1.38516 1.87763
+9.47216 1.49187 0.308427
+9.75064 0.847619 1.95524
+0.794438 0.533126 1.38927
+0.458255 0.447104 1.69467
+0.374261 1.40599 0.165617
+0.508332 1.45369 0.266876
+0.260436 0.04725 0.848098
+0.523546 1.46304 1.71365
+9.85853 1.07995 1.9863
+9.42973 1.81578 1.09982
+0.388103 1.05943 1.91992
+0.476978 1.70117 0.470762
+0.136105 0.778474 0.035417
+0.184601 1.54026 1.8208
+9.6957 0.689279 0.098452
+0.571886 1.46763 1.67421
+9.78389 0.721641 1.93675
+9.64603 1.50351 0.212504
+9.33479 1.43862 1.60356
+0.397572 1.58421 0.292223
+9.31721 0.443609 0.525264
+0.328354 0.357877 0.309063
+9.70621 1.71928 1.63125
+9.94985 1.74847 1.66185
+0.40709 0.384888 1.67494
+9.34601 1.20088 0.270165
+9.26684 1.04359 1.67861
+9.98278 0.071776 0.631486
+0.0335023 1.7533 0.343581
+0.126878 0.488354 0.150417
+9.42928 0.770031 0.212005
+9.86227 1.34485 1.92808
+9.69736 1.95041 0.943469
+9.45709 0.876758 0.168502
+0.151555 1.64388 0.249811
+9.81167 0.308096 1.69777
+9.29211 1.40989 1.57533
+0.943288 1.32913 1.0384
+9.51399 1.08536 0.129898
+0.862593 0.510705 0.869305
+0.402814 0.580634 1.81308
+0.560986 1.46185 1.68895
+0.597669 1.61114 1.517
+0.870172 0.746315 0.57874
+0.166247 1.62624 1.76249
+0.403377 0.646714 0.155771
+9.2505 1.10616 1.65508
+9.31197 1.63978 1.3402
+0.117564 1.83425 1.53848
+9.1859 1.5101 1.27657
+0.89193 1.16174 1.42446
+0.928389 1.35924 1.0886
+9.71862 1.43147 1.85746
+9.32164 1.73306 1.03569
+9.57868 0.207621 0.560166
+9.17069 0.465718 1.16609
+0.0749666 0.508784 0.131655
+9.00509 0.910826 0.982497
+9.18708 0.845121 1.55964
+0.230179 1.55547 0.201774
+0.963875 1.2047 0.829545
+0.639822 0.245481 1.14715
+0.330198 1.93655 0.876378
+0.415056 1.62304 1.66408
+9.5512 0.126185 1.1867
+0.919378 0.780583 1.32691
+0.211055 1.97731 1.0452
+9.63332 0.457348 0.245116
+9.11293 0.57283 0.824045
+9.2941 1.25297 1.66244
+9.24923 0.342548 1.06118
+0.512464 0.144511 1.06912
+9.20904 0.394573 0.920849
+9.75283 0.065458 1.25925
+0.0658611 1.9907 0.877273
+9.96161 0.012968 1.15098
+9.36225 1.28415 0.283022
+0.296386 1.04104 0.04487
+9.34276 1.75367 1.00771
+0.988566 0.930967 1.14033
+0.508411 0.803566 1.83833
+9.2627 1.08535 0.32846
+9.61688 1.50743 1.77102
+0.894891 0.787156 1.39054
+9.7692 1.77447 0.409455
+0.43942 0.105031 0.920975
+0.86666 0.528692 1.16637
+0.432977 1.30289 0.150308
+0.878035 1.34008 1.33693
+9.32994 1.62778 1.39603
+9.78551 0.265972 0.35543
diff --git a/data/points/shifted_sphere.weights b/data/points/shifted_sphere.weights
new file mode 100644
index 00000000..bb5602eb
--- /dev/null
+++ b/data/points/shifted_sphere.weights
@@ -0,0 +1,1000 @@
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
+0.0001
diff --git a/src/Alpha_complex/doc/Intro_alpha_complex.h b/src/Alpha_complex/doc/Intro_alpha_complex.h
index cf1a946a..a08663ca 100644
--- a/src/Alpha_complex/doc/Intro_alpha_complex.h
+++ b/src/Alpha_complex/doc/Intro_alpha_complex.h
@@ -31,7 +31,7 @@ namespace alpha_complex {
/** \defgroup alpha_complex Alpha complex
*
* \author Vincent Rouvreau
- *
+ *
* @{
*
* \section definition Definition
@@ -195,8 +195,6 @@ namespace alpha_complex {
*
* \include Alpha_complex/alphaoffreader_for_doc_32.txt
*
- * \copyright GNU General Public License v3.
- * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup alpha_complex
diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h
index 5f7d7622..63c6675c 100644
--- a/src/Alpha_complex/include/gudhi/Alpha_complex.h
+++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h
@@ -175,7 +175,7 @@ class Alpha_complex {
*
* @return The number of vertices.
*/
- const std::size_t number_of_vertices() const {
+ std::size_t number_of_vertices() const {
return vertex_handle_to_iterator_.size();
}
diff --git a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp
index 166373fe..c3ad1a9c 100644
--- a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp
+++ b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp
@@ -23,6 +23,7 @@
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "alpha_complex"
#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
#include <CGAL/Delaunay_triangulation.h>
#include <CGAL/Epick_d.h>
@@ -36,7 +37,7 @@
// to construct a simplex_tree from Delaunay_triangulation
#include <gudhi/graph_simplicial_complex.h>
#include <gudhi/Simplex_tree.h>
-#include <boost/mpl/list.hpp>
+#include <gudhi/Unitary_tests_utils.h>
// Use dynamic_dimension_tag for the user to be able to set dimension
typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel_d;
@@ -96,10 +97,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_from_OFF_file, TestedKernel, list_of
BOOST_CHECK(simplex_tree_59.num_simplices() == 23);
}
-bool are_almost_the_same(float a, float b) {
- return std::fabs(a - b) < std::numeric_limits<float>::epsilon();
-}
-
// Use static dimension_tag for the user not to be able to set dimension
typedef CGAL::Epick_d< CGAL::Dimension_tag<4> > Kernel_4;
typedef Kernel_4::Point_d Point_4;
@@ -166,16 +163,16 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) {
for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
switch (simplex_tree.dimension(f_simplex)) {
case 0:
- BOOST_CHECK(are_almost_the_same(simplex_tree.filtration(f_simplex), 0.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(simplex_tree.filtration(f_simplex), 0.0);
break;
case 1:
- BOOST_CHECK(are_almost_the_same(simplex_tree.filtration(f_simplex), 1.0/2.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(simplex_tree.filtration(f_simplex), 1.0/2.0);
break;
case 2:
- BOOST_CHECK(are_almost_the_same(simplex_tree.filtration(f_simplex), 2.0/3.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(simplex_tree.filtration(f_simplex), 2.0/3.0);
break;
case 3:
- BOOST_CHECK(are_almost_the_same(simplex_tree.filtration(f_simplex), 3.0/4.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(simplex_tree.filtration(f_simplex), 3.0/4.0);
break;
default:
BOOST_CHECK(false); // Shall not happen
@@ -239,10 +236,10 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) {
for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
switch (simplex_tree.dimension(f_simplex)) {
case 0:
- BOOST_CHECK(are_almost_the_same(simplex_tree.filtration(f_simplex), 0.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(simplex_tree.filtration(f_simplex), 0.0);
break;
case 1:
- BOOST_CHECK(are_almost_the_same(simplex_tree.filtration(f_simplex), 1.0/2.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(simplex_tree.filtration(f_simplex), 1.0/2.0);
break;
default:
BOOST_CHECK(false); // Shall not happen
diff --git a/src/Alpha_complex/utilities/CMakeLists.txt b/src/Alpha_complex/utilities/CMakeLists.txt
index 79d9e7dd..a2dfac20 100644
--- a/src/Alpha_complex/utilities/CMakeLists.txt
+++ b/src/Alpha_complex/utilities/CMakeLists.txt
@@ -54,7 +54,7 @@ if(CGAL_FOUND)
target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES})
endif(TBB_FOUND)
- add_test(NAME Persistent_cohomology_example_weigted_periodic_alpha_complex_3d COMMAND $<TARGET_FILE:weighted_periodic_alpha_complex_3d_persistence>
+ add_test(NAME Alpha_complex_utilities_weigted_periodic_alpha_complex_3d COMMAND $<TARGET_FILE:weighted_periodic_alpha_complex_3d_persistence>
"${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off" "${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.weights"
"${CMAKE_SOURCE_DIR}/data/points/iso_cuboid_3_in_0_1.txt" "3" "1.0")
diff --git a/src/Alpha_complex/utilities/alpha_complex_3d_helper.h b/src/Alpha_complex/utilities/alpha_complex_3d_helper.h
index 6b3b7d5d..a59f0654 100644
--- a/src/Alpha_complex/utilities/alpha_complex_3d_helper.h
+++ b/src/Alpha_complex/utilities/alpha_complex_3d_helper.h
@@ -52,13 +52,11 @@ Vertex_list from_facet(const Facet& fct) {
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)) {
+ for (auto i : {edg.second, edg.third}) {
#ifdef DEBUG_TRACES
- std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
+ std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
#endif // DEBUG_TRACES
- the_list.push_back(edg.first->vertex(i));
- }
+ the_list.push_back(edg.first->vertex(i));
}
return the_list;
}
diff --git a/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp
index 0a021a0f..8ef5ffb2 100644
--- a/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/alpha_complex_3d_persistence.cpp
@@ -20,9 +20,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <boost/version.hpp>
#include <boost/program_options.hpp>
#include <boost/variant.hpp>
+#if BOOST_VERSION >= 105400
+#include <boost/container/static_vector.hpp>
+#endif
+
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
#include <gudhi/Points_3D_off_io.h>
@@ -38,7 +43,6 @@
#include <tuple>
#include <map>
#include <utility>
-#include <list>
#include <vector>
#include <cstdlib>
@@ -66,14 +70,18 @@ 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>;
+
+#if BOOST_VERSION >= 105400
+using Vertex_list = boost::container::static_vector<Alpha_shape_3::Vertex_handle, 4>;
+#else
+using Vertex_list = std::vector<Alpha_shape_3::Vertex_handle>;
+#endif
// 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>;
@@ -97,7 +105,7 @@ int main(int argc, char **argv) {
exit(-1);
}
- // Retrieve the triangulation
+ // Retrieve the points
std::vector<Point_3> lp = off_reader.get_point_cloud();
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
@@ -128,37 +136,23 @@ int main(int argc, char **argv) {
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)) {
+ 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)) {
+ } 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)) {
+ } 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)) {
+ } 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;
+ Simplex_tree_vector_vertex the_simplex;
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()) {
@@ -167,30 +161,25 @@ int main(int argc, char **argv) {
#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));
+ the_simplex.push_back(vertex);
+ map_cgal_simplex_tree.emplace(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);
+ the_simplex.push_back(vertex);
}
}
// Construction of the simplex_tree
- Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator);
+ 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.insert_simplex(the_simplex, filtr);
+ GUDHI_CHECK(the_alpha_value_iterator != the_alpha_values.end(), "CGAL provided more simplices than values");
+ ++the_alpha_value_iterator;
}
#ifdef DEBUG_TRACES
diff --git a/src/Alpha_complex/utilities/README b/src/Alpha_complex/utilities/alphacomplex.md
index 1cd2ca95..aace85d3 100644
--- a/src/Alpha_complex/utilities/README
+++ b/src/Alpha_complex/utilities/alphacomplex.md
@@ -1,14 +1,26 @@
-# Alpha_complex #
-## `alpha_complex_3d_persistence` ##
-This program computes the persistent homology with coefficient field Z/pZ of the 3D alpha complex built from a 3D point cloud. The output diagram contains one bar per line, written with the convention:
-`p dim birth death`
+# Alpha complex #
-where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature, and `p` is the characteristic of the field *Z/pZ* used for homology coefficients (`p` must be a prime number).
+
+## alpha_complex_persistence ##
+
+This program computes the persistent homology with coefficient field Z/pZ of the dD alpha complex built from a dD point cloud.
+The output diagram contains one bar per line, written with the convention:
+
+```
+ p dim birth death
+```
+
+where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature,
+and `p` is the characteristic of the field *Z/pZ* used for homology coefficients (`p` must be a prime number).
**Usage**
-`alpha_complex_3d_persistence [options] <input OFF file>`
+
+```
+ alpha_complex_persistence [options] <input OFF file>
+```
+
where
`<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
@@ -16,47 +28,37 @@ where
* `-h [ --help ]` Produce help message
* `-o [ --output-file ]` Name of file in which the persistence diagram is written. Default print in standard output.
-* `-p [ --field-charac ]` (default=11) Characteristic p of the coefficient field Z/pZ for computing homology.
+* `-r [ --max-alpha-square-value ]` (default = inf) Maximal alpha square value for the Alpha complex construction.
+* `-p [ --field-charac ]` (default = 11) Characteristic p of the coefficient field Z/pZ for computing homology.
* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals.
**Example**
-`alpha_complex_3d_persistence ../../data/points/tore3D_300.off -p 2 -m 0.45`
-outputs:
```
-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
+ alpha_complex_persistence -r 32 -p 2 -m 0.45 ../../data/points/tore3D_300.off
```
-Here we retrieve expected Betti numbers on a tore 3D:
-```
-Betti numbers[0] = 1
-Betti numbers[1] = 2
-Betti numbers[2] = 1
-```
+N.B.:
-N.B.:
-* `alpha_complex_3d_persistence` only accepts OFF files in dimension 3.
* Filtration values are alpha square values.
+## alpha_complex_3d_persistence ##
+This program computes the persistent homology with coefficient field Z/pZ of the 3D alpha complex built from a 3D point cloud. The output diagram contains one bar per line, written with the convention:
-## `exact_alpha_complex_3d_persistence` ##
-Same as `alpha_complex_3d_persistence`, but using exact computation. It is slower, but it is necessary when points are on a grid for instance.
+```
+p dim birth death
+```
+where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature, and `p` is the characteristic of the field *Z/pZ* used for homology coefficients (`p` must be a prime number).
+**Usage**
-## `weighted_alpha_complex_3d_persistence` ##
-Same as `alpha_complex_3d_persistence`, but using weighted points.
+```
+ alpha_complex_3d_persistence [options] <input OFF file>
+```
-**Usage**
-`weighted_alpha_complex_3d_persistence [options] <input OFF file> <weights input file>`
-where
-`<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
-`<input weights file>` is the path to the file containing the weights of the points (one value per line).
+where `<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
**Allowed options**
@@ -66,112 +68,91 @@ where
* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals.
**Example**
-`weighted_alpha_complex_3d_persistence ../../data/points/tore3D_300.off ../../data/points/tore3D_300.weights -p 2 -m 0.45`
-outputs:
```
-Simplex_tree dim: 3
-2 0 -1 inf
-2 1 -0.931784 0.000103311
-2 1 -0.906588 2.60165e-05
-2 2 -0.43556 0.0393798
+alpha_complex_3d_persistence ../../data/points/tore3D_300.off -p 2 -m 0.45
```
N.B.:
-* Weights values are explained on CGAL [Alpha shape](https://doc.cgal.org/latest/Alpha_shapes_3/index.html#title0)
-and [Regular triangulation](https://doc.cgal.org/latest/Triangulation_3/index.html#Triangulation3secclassRegulartriangulation) documentation.
+
+* `alpha_complex_3d_persistence` only accepts OFF files in dimension 3.
* Filtration values are alpha square values.
-## `periodic_alpha_complex_3d_persistence` ##
-Same as `alpha_complex_3d_persistence`, but using periodic alpha shape 3d.
-Refer to the [CGAL's 3D Periodic Triangulations User Manual](https://doc.cgal.org/latest/Periodic_3_triangulation_3/index.html) for more details.
+## exact_alpha_complex_3d_persistence ##
+
+Same as `alpha_complex_3d_persistence`, but using exact computation.
+It is slower, but it is necessary when points are on a grid for instance.
+
+
+
+## weighted_alpha_complex_3d_persistence ##
+
+Same as `alpha_complex_3d_persistence`, but using weighted points.
**Usage**
-`periodic_alpha_complex_3d_persistence [options] <input OFF file> <cuboid file>`
+
+```
+ weighted_alpha_complex_3d_persistence [options] <input OFF file> <weights input file>
+```
+
where
-`<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
-`<cuboid file>` is the path to the file describing the periodic domain. It must be in the format described [here](http://gudhi.gforge.inria.fr/doc/latest/fileformats.html#FileFormatsIsoCuboid).
+
+* `<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
+* `<input weights file>` is the path to the file containing the weights of the points (one value per line).
**Allowed options**
* `-h [ --help ]` Produce help message
* `-o [ --output-file ]` Name of file in which the persistence diagram is written. Default print in standard output.
* `-p [ --field-charac ]` (default=11) Characteristic p of the coefficient field Z/pZ for computing homology.
-* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals
-
+* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals.
**Example**
-`periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off ../../data/points/iso_cuboid_3_in_0_1.txt -p 3 -m 1.0`
-
-outputs:
-```
-Periodic Delaunay computed.
-Simplex_tree dim: 3
-3 0 0 inf
-3 1 0.0025 inf
-3 1 0.0025 inf
-3 1 0.0025 inf
-3 2 0.005 inf
-3 2 0.005 inf
-3 2 0.005 inf
-3 3 0.0075 inf
-```
-Here we retrieve expected Betti numbers on an 3D iso-oriented cuboids:
```
-Betti numbers[0] = 1
-Betti numbers[1] = 3
-Betti numbers[2] = 3
-Betti numbers[3] = 1
+ weighted_alpha_complex_3d_persistence ../../data/points/tore3D_300.off ../../data/points/tore3D_300.weights -p 2 -m 0.45
```
-N.B.:
-* Cuboid file must be in the format described [here](http://gudhi.gforge.inria.fr/doc/latest/fileformats.html#FileFormatsIsoCuboid).
-* Filtration values are alpha square values.
+N.B.:
+* Weights values are explained on CGAL [Alpha shape](https://doc.cgal.org/latest/Alpha_shapes_3/index.html#title0)
+and [Regular triangulation](https://doc.cgal.org/latest/Triangulation_3/index.html#Triangulation3secclassRegulartriangulation) documentation.
+* Filtration values are alpha square values.
-## `alpha_complex_persistence` ##
-This program computes the persistent homology with coefficient field Z/pZ of the dD alpha complex built from a dD point cloud. The output diagram contains one bar per line, written with the convention:
+## periodic_alpha_complex_3d_persistence ##
+Same as `alpha_complex_3d_persistence`, but using periodic alpha shape 3d.
+Refer to the [CGAL's 3D Periodic Triangulations User Manual](https://doc.cgal.org/latest/Periodic_3_triangulation_3/index.html) for more details.
-`p dim birth death`
+**Usage**
-where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature, and `p` is the characteristic of the field *Z/pZ* used for homology coefficients (`p` must be a prime number).
+```
+ periodic_alpha_complex_3d_persistence [options] <input OFF file> <cuboid file>
+```
-**Usage**
-`alpha_complex_persistence [options] <input OFF file>`
where
-`<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
+
+* `<input OFF file>` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html).
+* `<cuboid file>` is the path to the file describing the periodic domain. It must be in the format described
+[here](/doc/latest/fileformats.html#FileFormatsIsoCuboid).
**Allowed options**
* `-h [ --help ]` Produce help message
* `-o [ --output-file ]` Name of file in which the persistence diagram is written. Default print in standard output.
-* `-r [ --max-alpha-square-value ]` (default = inf) Maximal alpha square value for the Alpha complex construction.
-* `-p [ --field-charac ]` (default = 11) Characteristic p of the coefficient field Z/pZ for computing homology.
-* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals.
+* `-p [ --field-charac ]` (default=11) Characteristic p of the coefficient field Z/pZ for computing homology.
+* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals
-**Example**
-`alpha_complex_persistence -r 32 -p 2 -m 0.45 ../../data/points/tore3D_300.off`
-outputs:
-```
-Alpha complex is of dimension 3 - 9273 simplices - 300 vertices.
-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
-```
+**Example**
-Here we retrieve expected Betti numbers on a tore 3D:
```
-Betti numbers[0] = 1
-Betti numbers[1] = 2
-Betti numbers[2] = 1
+periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off ../../data/points/iso_cuboid_3_in_0_1.txt -p 3 -m 1.0
```
N.B.:
+
+* Cuboid file must be in the format described [here](/doc/latest/fileformats.html#FileFormatsIsoCuboid).
* Filtration values are alpha square values.
diff --git a/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp
index 9a266418..cceac46e 100644
--- a/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/exact_alpha_complex_3d_persistence.cpp
@@ -38,7 +38,6 @@
#include <tuple>
#include <map>
#include <utility>
-#include <list>
#include <vector>
#include <cstdlib>
@@ -67,14 +66,13 @@ 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>;
+using Vertex_list = std::vector<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>;
@@ -98,7 +96,7 @@ int main(int argc, char **argv) {
exit(-1);
}
- // Retrieve the triangulation
+ // Retrieve the points
std::vector<Point_3> lp = off_reader.get_point_cloud();
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
@@ -129,37 +127,23 @@ int main(int argc, char **argv) {
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)) {
+ 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)) {
+ } 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)) {
+ } 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)) {
+ } 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;
+ Simplex_tree_vector_vertex the_simplex;
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()) {
@@ -168,27 +152,24 @@ int main(int argc, char **argv) {
#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));
+ the_simplex.push_back(vertex);
+ map_cgal_simplex_tree.emplace(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);
+ the_simplex.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());
+ 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);
+ simplex_tree.insert_simplex(the_simplex, filtr);
if (the_alpha_value_iterator != the_alpha_values.end())
++the_alpha_value_iterator;
else
diff --git a/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp
index 186a58f8..188cf604 100644
--- a/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/periodic_alpha_complex_3d_persistence.cpp
@@ -3,6 +3,7 @@
* library for computational topology.
*
* Author(s): Vincent Rouvreau
+ * Pawel Dlotko - 2017 - Swansea University, UK
*
* Copyright (C) 2014 INRIA
*
@@ -39,7 +40,6 @@
#include <tuple>
#include <map>
#include <utility>
-#include <list>
#include <vector>
#include <cstdlib>
@@ -72,14 +72,13 @@ 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>;
+using Vertex_list = std::vector<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>;
@@ -114,8 +113,13 @@ int main(int argc, char **argv) {
std::cerr << "Unable to read file " << cuboid_file << std::endl;
exit(-1);
}
+ // Checking if the cuboid is the same in x,y and z direction. If not, CGAL will not process it.
+ if ((x_max - x_min != y_max - y_min) || (x_max - x_min != z_max - z_min) || (z_max - z_min != y_max - y_min)) {
+ std::cerr << "The size of the cuboid in every directions is not the same." << std::endl;
+ exit(-1);
+ }
- // Retrieve the triangulation
+ // Retrieve the points
std::vector<Point_3> lp = off_reader.get_point_cloud();
// Define the periodic cube
@@ -123,7 +127,12 @@ int main(int argc, char **argv) {
// Heuristic for inserting large point sets (if pts is reasonably large)
pdt.insert(lp.begin(), lp.end(), true);
// As pdt won't be modified anymore switch to 1-sheeted cover if possible
- if (pdt.is_triangulation_in_1_sheet()) pdt.convert_to_1_sheeted_covering();
+ if (pdt.is_triangulation_in_1_sheet()) {
+ pdt.convert_to_1_sheeted_covering();
+ } else {
+ std::cerr << "ERROR: we were not able to construct a triangulation within a single periodic domain." << std::endl;
+ exit(-1);
+ }
std::cout << "Periodic Delaunay computed." << std::endl;
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. This is the default mode
@@ -152,37 +161,23 @@ int main(int argc, char **argv) {
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)) {
+ 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)) {
+ } 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)) {
+ } 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)) {
+ } 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;
+ Simplex_tree_vector_vertex the_simplex;
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()) {
@@ -191,15 +186,15 @@ int main(int argc, char **argv) {
#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));
+ the_simplex.push_back(vertex);
+ map_cgal_simplex_tree.emplace(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);
+ the_simplex.push_back(vertex);
}
}
// Construction of the simplex_tree
@@ -207,10 +202,7 @@ int main(int argc, char **argv) {
#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);
+ simplex_tree.insert_simplex(the_simplex, filtr);
if (the_alpha_value_iterator != the_alpha_values.end())
++the_alpha_value_iterator;
else
diff --git a/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp
index 0e73a99b..93be8a05 100644
--- a/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/weighted_alpha_complex_3d_persistence.cpp
@@ -44,7 +44,6 @@
#include <tuple>
#include <map>
#include <utility>
-#include <list>
#include <vector>
#include <cstdlib>
@@ -66,13 +65,13 @@ using Point_3 = Gt::Bare_point;
using Weighted_point_3 = Gt::Weighted_point;
// For CGAL >= 4.11
-#else // CGAL_VERSION_NR < 1041100000
+#else // CGAL_VERSION_NR < 1041100000
using Rvb = CGAL::Regular_triangulation_vertex_base_3<Kernel>;
-using Vb = CGAL::Alpha_shape_vertex_base_3<Kernel,Rvb>;
+using Vb = CGAL::Alpha_shape_vertex_base_3<Kernel, Rvb>;
using Rcb = CGAL::Regular_triangulation_cell_base_3<Kernel>;
-using Cb = CGAL::Alpha_shape_cell_base_3<Kernel,Rcb>;
-using Tds = CGAL::Triangulation_data_structure_3<Vb,Cb>;
-using Triangulation_3 = CGAL::Regular_triangulation_3<Kernel,Tds>;
+using Cb = CGAL::Alpha_shape_cell_base_3<Kernel, Rcb>;
+using Tds = CGAL::Triangulation_data_structure_3<Vb, Cb>;
+using Triangulation_3 = CGAL::Regular_triangulation_3<Kernel, Tds>;
// From file type definition
using Point_3 = Triangulation_3::Bare_point;
@@ -92,14 +91,13 @@ 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>;
+using Vertex_list = std::vector<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>;
@@ -125,7 +123,7 @@ int main(int argc, char **argv) {
exit(-1);
}
- // Retrieve the triangulation
+ // Retrieve the points
std::vector<Point_3> lp = off_reader.get_point_cloud();
// Read weights information from file
@@ -177,37 +175,23 @@ int main(int argc, char **argv) {
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)) {
+ 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)) {
+ } 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)) {
+ } 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)) {
+ } 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;
+ Simplex_tree_vector_vertex the_simplex;
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()) {
@@ -216,15 +200,15 @@ int main(int argc, char **argv) {
#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));
+ the_simplex.push_back(vertex);
+ map_cgal_simplex_tree.emplace(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);
+ the_simplex.push_back(vertex);
}
}
// Construction of the simplex_tree
@@ -232,10 +216,7 @@ int main(int argc, char **argv) {
#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);
+ simplex_tree.insert_simplex(the_simplex, filtr);
if (the_alpha_value_iterator != the_alpha_values.end())
++the_alpha_value_iterator;
else
diff --git a/src/Alpha_complex/utilities/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Alpha_complex/utilities/weighted_periodic_alpha_complex_3d_persistence.cpp
index 13634ff7..5321bb0a 100644
--- a/src/Alpha_complex/utilities/weighted_periodic_alpha_complex_3d_persistence.cpp
+++ b/src/Alpha_complex/utilities/weighted_periodic_alpha_complex_3d_persistence.cpp
@@ -3,6 +3,7 @@
* library for computational topology.
*
* Author(s): Vincent Rouvreau
+ * Pawel Dlotko - 2017 - Swansea University, UK
*
* Copyright (C) 2014 INRIA
*
@@ -38,7 +39,6 @@
#include <tuple>
#include <map>
#include <utility>
-#include <list>
#include <vector>
#include <cstdlib>
@@ -50,14 +50,14 @@ using PK = CGAL::Periodic_3_regular_triangulation_traits_3<Kernel>;
// Vertex type
using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>;
-using Vb = CGAL::Regular_triangulation_vertex_base_3<PK,DsVb>;
-using AsVb = CGAL::Alpha_shape_vertex_base_3<PK,Vb>;
+using Vb = CGAL::Regular_triangulation_vertex_base_3<PK, DsVb>;
+using AsVb = CGAL::Alpha_shape_vertex_base_3<PK, Vb>;
// Cell type
using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>;
-using Cb = CGAL::Regular_triangulation_cell_base_3<PK,DsCb>;
-using AsCb = CGAL::Alpha_shape_cell_base_3<PK,Cb>;
-using Tds = CGAL::Triangulation_data_structure_3<AsVb,AsCb>;
-using P3RT3 = CGAL::Periodic_3_regular_triangulation_3<PK,Tds>;
+using Cb = CGAL::Regular_triangulation_cell_base_3<PK, DsCb>;
+using AsCb = CGAL::Alpha_shape_cell_base_3<PK, Cb>;
+using Tds = CGAL::Triangulation_data_structure_3<AsVb, AsCb>;
+using P3RT3 = CGAL::Periodic_3_regular_triangulation_3<PK, Tds>;
using Alpha_shape_3 = CGAL::Alpha_shape_3<P3RT3>;
using Point_3 = P3RT3::Bare_point;
@@ -74,14 +74,13 @@ 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>;
+using Vertex_list = std::vector<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>;
@@ -112,18 +111,46 @@ int main(int argc, char* const argv[]) {
usage(argv[0]);
}
- // Retrieve the triangulation
+ // Retrieve the points
std::vector<Point_3> lp = off_reader.get_point_cloud();
+ // Read iso_cuboid_3 information from file
+ std::ifstream iso_cuboid_str(argv[3]);
+ double x_min, y_min, z_min, x_max, y_max, z_max;
+ if (iso_cuboid_str.is_open()) {
+ if (!(iso_cuboid_str >> x_min >> y_min >> z_min >> x_max >> y_max >> z_max)) {
+ std::cerr << argv[3] << " - Bad file format." << std::endl;
+ usage(argv[0]);
+ }
+
+ } else {
+ std::cerr << "Unable to read file " << argv[3] << std::endl;
+ usage(argv[0]);
+ }
+ // Checking if the cuboid is the same in x,y and z direction. If not, CGAL will not process it.
+ if ((x_max - x_min != y_max - y_min) || (x_max - x_min != z_max - z_min) || (z_max - z_min != y_max - y_min)) {
+ std::cerr << "The size of the cuboid in every directions is not the same." << std::endl;
+ exit(-1);
+ }
+
+ double maximal_possible_weight = 0.015625 * (x_max - x_min) * (x_max - x_min);
+
// Read weights information from file
std::ifstream weights_ifstr(argv[2]);
std::vector<Weighted_point_3> wp;
- if (weights_ifstr.good()) {
+ if (weights_ifstr.is_open()) {
double weight = 0.0;
std::size_t index = 0;
wp.reserve(lp.size());
// Attempt read the weight in a double format, return false if it fails
while ((weights_ifstr >> weight) && (index < lp.size())) {
+ if ((weight >= maximal_possible_weight) || (weight < 0)) {
+ std::cerr << "At line " << (index + 1) << ", the weight (" << weight
+ << ") is negative or more than or equal to maximal possible weight (" << maximal_possible_weight
+ << ") = 1/64*cuboid length squared, which is not an acceptable input." << std::endl;
+ exit(-1);
+ }
+
wp.push_back(Weighted_point_3(lp[index], weight));
index++;
}
@@ -136,23 +163,18 @@ int main(int argc, char* const argv[]) {
usage(argv[0]);
}
- // Read iso_cuboid_3 information from file
- std::ifstream iso_cuboid_str(argv[3]);
- double x_min, y_min, z_min, x_max, y_max, z_max;
- if (iso_cuboid_str.good()) {
- iso_cuboid_str >> x_min >> y_min >> z_min >> x_max >> y_max >> z_max;
- } else {
- std::cerr << "Unable to read file " << argv[3] << std::endl;
- usage(argv[0]);
- }
-
// Define the periodic cube
P3RT3 prt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max));
// Heuristic for inserting large point sets (if pts is reasonably large)
prt.insert(wp.begin(), wp.end(), true);
// As prt won't be modified anymore switch to 1-sheeted cover if possible
- if (prt.is_triangulation_in_1_sheet()) prt.convert_to_1_sheeted_covering();
- std::cout << "Periodic Delaunay computed." << std::endl;
+ if (prt.is_triangulation_in_1_sheet()) {
+ prt.convert_to_1_sheeted_covering();
+ } else {
+ std::cerr << "ERROR: we were not able to construct a triangulation within a single periodic domain." << std::endl;
+ exit(-1);
+ }
+ std::cout << "Weighted Periodic Delaunay computed." << std::endl;
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. This is the default mode
// Maybe need to set it to GENERAL mode
@@ -180,37 +202,23 @@ int main(int argc, char* const argv[]) {
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;
+ Simplex_tree_vector_vertex the_simplex;
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()) {
@@ -219,15 +227,15 @@ int main(int argc, char* const argv[]) {
#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));
+ the_simplex.push_back(vertex);
+ map_cgal_simplex_tree.emplace(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);
+ the_simplex.push_back(vertex);
}
}
// Construction of the simplex_tree
@@ -235,10 +243,7 @@ int main(int argc, char* const argv[]) {
#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);
+ simplex_tree.insert_simplex(the_simplex, filtr);
if (the_alpha_value_iterator != the_alpha_values.end())
++the_alpha_value_iterator;
else
diff --git a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h
index ee84e201..a5d7b60f 100644
--- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h
+++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h
@@ -105,7 +105,6 @@ namespace cubical_complex {
* \section BitmapExamples Examples
* End user programs are available in example/Bitmap_cubical_complex and utilities/Bitmap_cubical_complex folders.
*
- * \copyright GNU General Public License v3.
*/
/** @} */ // end defgroup cubical_complex
diff --git a/src/Bitmap_cubical_complex/utilities/README b/src/Bitmap_cubical_complex/utilities/README
deleted file mode 100644
index ddff7034..00000000
--- a/src/Bitmap_cubical_complex/utilities/README
+++ /dev/null
@@ -1,18 +0,0 @@
-# Bitmap_cubical_complex #
-
-## `cubical_complex_persistence` ##
-This program computes persistent homology, by using the Bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style. See [here](http://gudhi.gforge.inria.fr/doc/latest/fileformats.html#FileFormatsPerseus) for a description of the file format.
-
-Example:
-
-* Create a Cubical Complex from the Perseus style file `CubicalTwoSphere.txt`, computes Persistence cohomology from it and writes the results in a persistence file `CubicalTwoSphere.txt_persistence`:
-`cubical_complex_persistence data/bitmap/CubicalTwoSphere.txt`
-
-## `periodic_cubical_complex_persistence` ##
-
-Same as above, but with periodic boundary conditions.
-
-Example:
-
-* Create a Periodical Cubical Complex from the Perseus style file `3d_torus.txt`, computes Persistence cohomology from it and writes the results in a persistence file `3d_torus.txt_persistence`:
-`periodic_cubical_complex_persistence data/bitmap/3d_torus.txt`
diff --git a/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md b/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md
new file mode 100644
index 00000000..6e1b2578
--- /dev/null
+++ b/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md
@@ -0,0 +1,29 @@
+
+
+# Cubical complex#
+
+## cubical_complex_persistence ##
+This program computes persistent homology, by using the Bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style.
+See [here](/doc/latest/fileformats.html#FileFormatsPerseus) for a description of the file format.
+
+**Example**
+
+```
+ cubical_complex_persistence data/bitmap/CubicalTwoSphere.txt
+```
+
+* Creates a Cubical Complex from the Perseus style file `CubicalTwoSphere.txt`,
+computes Persistence cohomology from it and writes the results in a persistence file `CubicalTwoSphere.txt_persistence`.
+
+## periodic_cubical_complex_persistence ##
+
+Same as above, but with periodic boundary conditions.
+
+**Example**
+
+```
+ periodic_cubical_complex_persistence data/bitmap/3d_torus.txt
+```
+
+* Creates a Periodical Cubical Complex from the Perseus style file `3d_torus.txt`,
+computes Persistence cohomology from it and writes the results in a persistence file `3d_torus.txt_persistence`.
diff --git a/src/Bottleneck_distance/include/gudhi/Bottleneck.h b/src/Bottleneck_distance/include/gudhi/Bottleneck.h
index 8c97dce9..7aee07bb 100644
--- a/src/Bottleneck_distance/include/gudhi/Bottleneck.h
+++ b/src/Bottleneck_distance/include/gudhi/Bottleneck.h
@@ -46,7 +46,7 @@ double bottleneck_distance_approx(Persistence_graph& g, double e) {
if (step <= b_lower_bound || step >= b_upper_bound) // Avoid precision problem
break;
m.set_r(step);
- while (m.multi_augment()) {}; // compute a maximum matching (in the graph corresponding to the current r)
+ while (m.multi_augment()) {} // compute a maximum matching (in the graph corresponding to the current r)
if (m.perfect()) {
m = biggest_unperfect;
b_upper_bound = step;
@@ -68,7 +68,7 @@ double bottleneck_distance_exact(Persistence_graph& g) {
while (lower_bound_i != upper_bound_i) {
long step = lower_bound_i + static_cast<long> ((upper_bound_i - lower_bound_i - 1) / alpha);
m.set_r(sd.at(step));
- while (m.multi_augment()) {}; // compute a maximum matching (in the graph corresponding to the current r)
+ while (m.multi_augment()) {} // compute a maximum matching (in the graph corresponding to the current r)
if (m.perfect()) {
m = biggest_unperfect;
upper_bound_i = step;
diff --git a/src/Bottleneck_distance/include/gudhi/Neighbors_finder.h b/src/Bottleneck_distance/include/gudhi/Neighbors_finder.h
index a6b9b021..87c7cee5 100644
--- a/src/Bottleneck_distance/include/gudhi/Neighbors_finder.h
+++ b/src/Bottleneck_distance/include/gudhi/Neighbors_finder.h
@@ -32,6 +32,7 @@
#include <unordered_set>
#include <vector>
+#include <algorithm> // for std::max
namespace Gudhi {
@@ -44,7 +45,7 @@ struct Square_query {
typedef Internal_point Point_d;
typedef double FT;
bool contains(Point_d p) const {
- return std::abs(p.x()-c.x()) <= size && std::abs(p.y()-c.y()) <= size;
+ return std::max(std::abs(p.x()-c.x()), std::abs(p.y()-c.y())) <= size;
}
bool inner_range_intersects(CGAL::Kd_tree_rectangle<FT, D> const&r) const {
return
diff --git a/src/Bottleneck_distance/utilities/README b/src/Bottleneck_distance/utilities/README
deleted file mode 100644
index d9fdd252..00000000
--- a/src/Bottleneck_distance/utilities/README
+++ /dev/null
@@ -1,10 +0,0 @@
-# Bottleneck_distance #
-
-## `bottleneck_read_file_example` ##
-This program computes the Bottleneck distance between two persistence diagram files.
-
-Usage:
-`bottleneck_read_file_example <file_1.pers> <file_2.pers> [<tolerance>]`
-where
-`<file_1.pers>` and `<file_2.pers>` must be in the format described [here](http://gudhi.gforge.inria.fr/doc/latest/fileformats.html#FileFormatsPers).
-`<tolerance>` is an error bound on the bottleneck distance (set by default to the smallest positive double value).
diff --git a/src/Bottleneck_distance/utilities/bottleneckdistance.md b/src/Bottleneck_distance/utilities/bottleneckdistance.md
new file mode 100644
index 00000000..526f5822
--- /dev/null
+++ b/src/Bottleneck_distance/utilities/bottleneckdistance.md
@@ -0,0 +1,18 @@
+
+
+# Bottleneck distance #
+
+## bottleneck_read_file_example ##
+
+This program computes the Bottleneck distance between two persistence diagram files.
+
+**Usage**
+
+```
+ bottleneck_read_file_example <file_1.pers> <file_2.pers> [<tolerance>]
+```
+
+where
+
+* `<file_1.pers>` and `<file_2.pers>` must be in the format described [here](/doc/latest/fileformats.html#FileFormatsPers).
+* `<tolerance>` is an error bound on the bottleneck distance (set by default to the smallest positive double value).
diff --git a/src/Contraction/include/gudhi/Edge_contraction.h b/src/Contraction/include/gudhi/Edge_contraction.h
index 61f2d945..cf9a2c27 100644
--- a/src/Contraction/include/gudhi/Edge_contraction.h
+++ b/src/Contraction/include/gudhi/Edge_contraction.h
@@ -210,7 +210,6 @@ int main (int argc, char *argv[])
}
\endcode
-
\verbatim
./example/Contraction/RipsContraction ../../data/SO3_10000.off 0.3
[ 50%] [100%] Built target SkeletonBlockerIteration
@@ -223,9 +222,6 @@ Time to simplify and enumerate simplices:
3.166621s wall, 3.150000s user + 0.010000s system = 3.160000s CPU (99.8%)
\endverbatim
-
-
-\copyright GNU General Public License v3.
*/
/** @} */ // end defgroup
} // namespace contraction
diff --git a/src/Doxyfile b/src/Doxyfile
index bda6f03d..2348b290 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = "GUDHI"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = "2.0.1"
+PROJECT_NUMBER = "2.1.0"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -801,7 +801,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
-EXCLUDE_PATTERNS =
+EXCLUDE_PATTERNS = */utilities/*/*.md
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt
index 374195d0..2503a03e 100644
--- a/src/GudhUI/CMakeLists.txt
+++ b/src/GudhUI/CMakeLists.txt
@@ -1,37 +1,41 @@
cmake_minimum_required(VERSION 2.8)
project(GudhUI)
-find_package(Qt5 COMPONENTS Widgets Xml OpenGL)
-find_package(QGLViewer)
+# Need to find OpenGL first as find_package(Qt5) tries to #include"GL/gl.h" on some platforms
find_package(OpenGL)
-if ( CGAL_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND NOT CGAL_VERSION VERSION_EQUAL 4.8.0)
-
- set(CMAKE_AUTOMOC ON)
- set(CMAKE_AUTOUIC ON)
- set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
- SET(Boost_USE_STATIC_LIBS ON)
- SET(Boost_USE_MULTITHREAD OFF)
- include_directories (${QGLVIEWER_INCLUDE_DIR})
-
- add_executable ( GudhUI
- gui/gudhui.cpp
- gui/MainWindow.cpp
- gui/Menu_k_nearest_neighbors.cpp
- gui/Menu_uniform_neighbors.cpp
- gui/Menu_edge_contraction.cpp
- gui/Menu_persistence.cpp
- view/Viewer_instructor.cpp
- view/Viewer.cpp
- )
- target_link_libraries( GudhUI Qt5::Widgets Qt5::Xml Qt5::OpenGL )
- target_link_libraries( GudhUI ${QGLVIEWER_LIBRARIES} )
- target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
- if (TBB_FOUND)
- target_link_libraries( GudhUI ${TBB_LIBRARIES})
+if (OPENGL_FOUND)
+ find_package(Qt5 COMPONENTS Widgets Xml OpenGL)
+ find_package(QGLViewer)
+
+ if ( CGAL_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND NOT CGAL_VERSION VERSION_EQUAL 4.8.0)
+
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_AUTOUIC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+ SET(Boost_USE_STATIC_LIBS ON)
+ SET(Boost_USE_MULTITHREAD OFF)
+ include_directories (${QGLVIEWER_INCLUDE_DIR})
+
+ add_executable ( GudhUI
+ gui/gudhui.cpp
+ gui/MainWindow.cpp
+ gui/Menu_k_nearest_neighbors.cpp
+ gui/Menu_uniform_neighbors.cpp
+ gui/Menu_edge_contraction.cpp
+ gui/Menu_persistence.cpp
+ view/Viewer_instructor.cpp
+ view/Viewer.cpp
+ )
+ target_link_libraries( GudhUI Qt5::Widgets Qt5::Xml Qt5::OpenGL )
+ target_link_libraries( GudhUI ${QGLVIEWER_LIBRARIES} )
+ target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
+ if (TBB_FOUND)
+ target_link_libraries( GudhUI ${TBB_LIBRARIES})
+ endif()
+
+ install(TARGETS GudhUI DESTINATION bin)
+
endif()
-
- install(TARGETS GudhUI DESTINATION bin)
-
-endif()
+endif(OPENGL_FOUND) \ No newline at end of file
diff --git a/src/Kernels/example/kernel_basic_example.cpp b/src/Kernels/example/kernel_basic_example.cpp
index 85ce36d4..7ecbe401 100644
--- a/src/Kernels/example/kernel_basic_example.cpp
+++ b/src/Kernels/example/kernel_basic_example.cpp
@@ -30,7 +30,7 @@
void usage(int nbArgs, char *const progName) {
std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
std::cerr << "Usage: " << progName << " PD1 PD2 \n";
- std::cerr << " i.e.: " << progName << " ../../../../data/persistence_diagram/PD1 ../../../../data/persistence_diagram/PD2 \n";
+ std::cerr << " i.e.: " << progName << " ../../../../data/persistence_diagram/PD1.pers ../../../../data/persistence_diagram/PD2.pers \n";
exit(-1); // ----- >>
}
@@ -53,13 +53,13 @@ int main(int argc, char **argv) {
std::stringstream stream(line); stream >> b; stream >> d; v2.push_back(std::pair<double,double>(b,d));
}
- std::cout << "SWK exact = " << Gudhi::kernel::swk (v1,v2,sigma) << std::endl;
- std::cout << "SWK approx = " << Gudhi::kernel::approx_swk (v1,v2,sigma) << std::endl;
- std::cout << "PSSK exact = " << Gudhi::kernel::pssk (v1,v2,sigma) << std::endl;
- std::cout << "PSSK approx = " << Gudhi::kernel::approx_pssk (v1,v2,sigma) << std::endl;
- std::cout << "LPWGK exact = " << Gudhi::kernel::lpwgk (v1,v2,sigma) << std::endl;
- std::cout << "LPWGK approx = " << Gudhi::kernel::approx_lpwgk (v1,v2,sigma) << std::endl;
- std::cout << "GPWGK exact = " << Gudhi::kernel::gpwgk (v1,v2,sigma,tau) << std::endl;
- std::cout << "GPWGK approx = " << Gudhi::kernel::approx_gpwgk (v1,v2,sigma,tau) << std::endl;
+ std::cout << "SWK exact = " << Gudhi::kernel::sliced_wasserstein_kernel (v1,v2,sigma,-1) << std::endl;
+ std::cout << "SWK approx = " << Gudhi::kernel::sliced_wasserstein_kernel (v1,v2,sigma) << std::endl;
+ std::cout << "PSSK exact = " << Gudhi::kernel::persistence_scale_space_kernel (v1,v2,sigma,-1) << std::endl;
+ std::cout << "PSSK approx = " << Gudhi::kernel::persistence_scale_space_kernel (v1,v2,sigma) << std::endl;
+ std::cout << "LPWGK exact = " << Gudhi::kernel::linear_persistence_weighted_gaussian_kernel (v1,v2,sigma,Gudhi::kernel::arctan_weight,-1) << std::endl;
+ std::cout << "LPWGK approx = " << Gudhi::kernel::linear_persistence_weighted_gaussian_kernel (v1,v2,sigma,Gudhi::kernel::arctan_weight) << std::endl;
+ std::cout << "GPWGK exact = " << Gudhi::kernel::gaussian_persistence_weighted_gaussian_kernel (v1,v2,sigma,tau,Gudhi::kernel::arctan_weight,-1) << std::endl;
+ std::cout << "GPWGK approx = " << Gudhi::kernel::gaussian_persistence_weighted_gaussian_kernel (v1,v2,sigma,tau,Gudhi::kernel::arctan_weight) << std::endl;
}
diff --git a/src/Kernels/include/gudhi/kernel.h b/src/Kernels/include/gudhi/kernel.h
index 900db092..3293cc62 100644
--- a/src/Kernels/include/gudhi/kernel.h
+++ b/src/Kernels/include/gudhi/kernel.h
@@ -28,6 +28,9 @@
#include <algorithm>
#include <cmath>
#include <random>
+#include <limits> //for numeric_limits<>
+#include <utility> //for pair<>
+
#include <boost/math/constants/constants.hpp>
@@ -37,6 +40,13 @@ namespace kernel {
using PD = std::vector<std::pair<double,double> >;
double pi = boost::math::constants::pi<double>();
+
+
+
+// ********************************************************************
+// Utils.
+// ********************************************************************
+
bool sortAngle(const std::pair<double, std::pair<int,int> >& p1, const std::pair<double, std::pair<int,int> >& p2){return (p1.first < p2.first);}
bool myComp(const std::pair<int,double> & P1, const std::pair<int,double> & P2){return P1.second < P2.second;}
@@ -49,80 +59,6 @@ double arctan_weight(std::pair<double,double> P){
return atan(P.second - P.first);
}
-
-
-
-// ********************************************************************
-// Exact computation.
-// ********************************************************************
-
-/** \brief Computes the Linear Persistence Weighted Gaussian Kernel between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- * @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
- * @param[in] weight weight function for the points in the diagrams.
- *
- */
-template<class Weight = double(*)(std::pair<double,double>) >
-double lpwgk(const PD & PD1, const PD & PD2, double sigma, Weight weight = arctan_weight){
- int num_pts1 = PD1.size(); int num_pts2 = PD2.size(); double k = 0;
- for(int i = 0; i < num_pts1; i++)
- for(int j = 0; j < num_pts2; j++)
- k += (*weight)(PD1[i])*(*weight)(PD2[j])*exp(-(pow(PD1[i].first-PD2[j].first,2) + pow(PD1[i].second-PD2[j].second,2))/(2*pow(sigma,2)));
- return k;
-}
-
-/** \brief Computes the Persistence Scale Space Kernel between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- * @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
- *
- */
-double pssk(const PD & PD1, const PD & PD2, double sigma){
- PD pd1 = PD1; int numpts = PD1.size(); for(int i = 0; i < numpts; i++) pd1.push_back(std::pair<double,double>(PD1[i].second,PD1[i].first));
- PD pd2 = PD2; numpts = PD2.size(); for(int i = 0; i < numpts; i++) pd2.push_back(std::pair<double,double>(PD2[i].second,PD2[i].first));
- return lpwgk(pd1, pd2, 2*sqrt(sigma), &pss_weight) / (2*8*pi*sigma);
-}
-
-/** \brief Computes the Gaussian Persistence Weighted Gaussian Kernel between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- * @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
- * @param[in] tau bandwidth parameter of the Gaussian Kernel used between the embeddings.
- * @param[in] weight weight function for the points in the diagrams.
- *
- */
-template<class Weight = double(*)(std::pair<double,double>) >
-double gpwgk(const PD & PD1, const PD & PD2, double sigma, double tau, Weight weight = arctan_weight){
- double k1 = lpwgk(PD1,PD1,sigma,weight);
- double k2 = lpwgk(PD2,PD2,sigma,weight);
- double k3 = lpwgk(PD1,PD2,sigma,weight);
- return exp( - (k1+k2-2*k3) / (2*pow(tau,2)) );
-}
-
-/** \brief Computes the RKHS distance induced by the Gaussian Kernel Embedding between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- * @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
- * @param[in] weight weight function for the points in the diagrams.
- *
- */
-template<class Weight = double(*)(std::pair<double,double>) >
-double dpwg(const PD & PD1, const PD & PD2, double sigma, Weight weight = arctan_weight){
- double k1 = lpwgk(PD1,PD1,sigma,weight);
- double k2 = lpwgk(PD2,PD2,sigma,weight);
- double k3 = lpwgk(PD1,PD2,sigma,weight);
- return std::sqrt(k1+k2-2*k3);
-}
-
// Compute the angle formed by two points of a PD
double compute_angle(const PD & PersDiag, const int & i, const int & j){
std::pair<double,double> vect; double x1,y1, x2,y2;
@@ -140,15 +76,13 @@ double compute_angle(const PD & PersDiag, const int & i, const int & j){
vect.first = 0;
vect.second = abs(x1 - x2);}
}
- double norm = std::sqrt(pow(vect.first,2) + pow(vect.second,2));
+ double norm = std::sqrt(vect.first*vect.first + vect.second*vect.second);
return asin(vect.second/norm);
}
-// Compute the integral of |cos()| between alpha and beta
-// Valid only if alpha is in [-pi,pi] and beta-alpha is in [0,pi]
+// Compute the integral of |cos()| between alpha and beta, valid only if alpha is in [-pi,pi] and beta-alpha is in [0,pi]
double compute_int_cos(const double & alpha, const double & beta){
double res = 0;
- //assert((alpha >= 0 && alpha <= pi) || (alpha >= -pi && alpha <= 0));
if (alpha >= 0 && alpha <= pi){
if (cos(alpha) >= 0){
if(pi/2 <= beta){res = 2-sin(alpha)-sin(beta);}
@@ -173,7 +107,7 @@ double compute_int_cos(const double & alpha, const double & beta){
}
double compute_int(const double & theta1, const double & theta2, const int & p, const int & q, const PD & PD1, const PD & PD2){
- double norm = std::sqrt(pow(PD1[p].first-PD2[q].first,2) + pow(PD1[p].second-PD2[q].second,2));
+ double norm = std::sqrt( (PD1[p].first-PD2[q].first)*(PD1[p].first-PD2[q].first) + (PD1[p].second-PD2[q].second)*(PD1[p].second-PD2[q].second) );
double angle1;
if (PD1[p].first > PD2[q].first)
angle1 = theta1 - asin( (PD1[p].second-PD2[q].second)/norm );
@@ -184,122 +118,32 @@ double compute_int(const double & theta1, const double & theta2, const int & p,
return norm*integral;
}
-
-
-double compute_sw(const std::vector<std::vector<std::pair<int,double> > > & V1, const std::vector<std::vector<std::pair<int,double> > > & V2, const PD & PD1, const PD & PD2){
- int N = V1.size(); double sw = 0;
- for (int i = 0; i < N; i++){
- std::vector<std::pair<int,double> > U,V; U = V1[i]; V = V2[i];
- double theta1, theta2; theta1 = -pi/2;
- unsigned int ku, kv; ku = 0; kv = 0; theta2 = std::min(U[ku].second,V[kv].second);
- while(theta1 != pi/2){
- if(PD1[U[ku].first].first != PD2[V[kv].first].first || PD1[U[ku].first].second != PD2[V[kv].first].second)
- if(theta1 != theta2)
- sw += compute_int(theta1, theta2, U[ku].first, V[kv].first, PD1, PD2);
- theta1 = theta2;
- if ( (theta2 == U[ku].second) && ku < U.size()-1 ) ku++;
- if ( (theta2 == V[kv].second) && kv < V.size()-1 ) kv++;
- theta2 = std::min(U[ku].second, V[kv].second);
+template<class Weight = std::function<double (std::pair<double,double>) > >
+std::vector<std::pair<double,double> > Fourier_feat(PD D, std::vector<std::pair<double,double> > Z, Weight weight = arctan_weight){
+ int m = D.size(); std::vector<std::pair<double,double> > B; int M = Z.size();
+ for(int i = 0; i < M; i++){
+ double d1 = 0; double d2 = 0; double zx = Z[i].first; double zy = Z[i].second;
+ for(int j = 0; j < m; j++){
+ double x = D[j].first; double y = D[j].second;
+ d1 += weight(D[j])*cos(x*zx + y*zy);
+ d2 += weight(D[j])*sin(x*zx + y*zy);
}
+ B.emplace_back(d1,d2);
}
- return sw/pi;
+ return B;
}
-/** \brief Computes the Sliced Wasserstein distance between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- *
- */
- double sw(PD PD1, PD PD2){
-
- // Add projections onto diagonal.
- int n1, n2; n1 = PD1.size(); n2 = PD2.size(); double max_ordinate = std::numeric_limits<double>::lowest();
- for (int i = 0; i < n2; i++){
- max_ordinate = std::max(max_ordinate, PD2[i].second);
- PD1.push_back( std::pair<double,double>( ((PD2[i].first+PD2[i].second)/2), ((PD2[i].first+PD2[i].second)/2) ) );
- }
- for (int i = 0; i < n1; i++){
- max_ordinate = std::max(max_ordinate, PD1[i].second);
- PD2.push_back( std::pair<double,double>( ((PD1[i].first+PD1[i].second)/2), ((PD1[i].first+PD1[i].second)/2) ) );
- }
- int N = PD1.size();
-
- // Slightly perturb the points so that the PDs are in generic positions.
- int mag = 0; while(max_ordinate > 10){mag++; max_ordinate/=10;}
- double thresh = pow(10,-5+mag);
- srand(time(NULL));
- for (int i = 0; i < N; i++){
- PD1[i].first += thresh*(1.0-2.0*rand()/RAND_MAX); PD1[i].second += thresh*(1.0-2.0*rand()/RAND_MAX);
- PD2[i].first += thresh*(1.0-2.0*rand()/RAND_MAX); PD2[i].second += thresh*(1.0-2.0*rand()/RAND_MAX);
- }
-
- // Compute all angles in both PDs.
- std::vector<std::pair<double, std::pair<int,int> > > angles1, angles2;
- for (int i = 0; i < N; i++){
- for (int j = i+1; j < N; j++){
- double theta1 = compute_angle(PD1,i,j); double theta2 = compute_angle(PD2,i,j);
- angles1.push_back(std::pair<double, std::pair<int,int> >(theta1, std::pair<int,int>(i,j)));
- angles2.push_back(std::pair<double, std::pair<int,int> >(theta2, std::pair<int,int>(i,j)));
- }
- }
-
- // Sort angles.
- std::sort(angles1.begin(), angles1.end(), sortAngle); std::sort(angles2.begin(), angles2.end(), sortAngle);
-
- // Initialize orders of the points of both PDs (given by ordinates when theta = -pi/2).
- std::vector<int> orderp1, orderp2;
- for (int i = 0; i < N; i++){ orderp1.push_back(i); orderp2.push_back(i); }
- std::sort( orderp1.begin(), orderp1.end(), [=](int i, int j){ if(PD1[i].second != PD1[j].second) return (PD1[i].second < PD1[j].second); else return (PD1[i].first > PD1[j].first); } );
- std::sort( orderp2.begin(), orderp2.end(), [=](int i, int j){ if(PD2[i].second != PD2[j].second) return (PD2[i].second < PD2[j].second); else return (PD2[i].first > PD2[j].first); } );
-
- // Find the inverses of the orders.
- std::vector<int> order1(N); std::vector<int> order2(N);
- for(int i = 0; i < N; i++) for (int j = 0; j < N; j++) if(orderp1[j] == i){ order1[i] = j; break; }
- for(int i = 0; i < N; i++) for (int j = 0; j < N; j++) if(orderp2[j] == i){ order2[i] = j; break; }
-
- // Record all inversions of points in the orders as theta varies along the positive half-disk.
- std::vector<std::vector<std::pair<int,double> > > anglePerm1(N);
- std::vector<std::vector<std::pair<int,double> > > anglePerm2(N);
-
- int M1 = angles1.size();
- for (int i = 0; i < M1; i++){
- double theta = angles1[i].first; int p = angles1[i].second.first; int q = angles1[i].second.second;
- anglePerm1[order1[p]].push_back(std::pair<int, double>(p,theta));
- anglePerm1[order1[q]].push_back(std::pair<int, double>(q,theta));
- int a = order1[p]; int b = order1[q]; order1[p] = b; order1[q] = a;
- }
-
- int M2 = angles2.size();
- for (int i = 0; i < M2; i++){
- double theta = angles2[i].first; int p = angles2[i].second.first; int q = angles2[i].second.second;
- anglePerm2[order2[p]].push_back(std::pair<int, double>(p,theta));
- anglePerm2[order2[q]].push_back(std::pair<int, double>(q,theta));
- int a = order2[p]; int b = order2[q]; order2[p] = b; order2[q] = a;
- }
-
- for (int i = 0; i < N; i++){
- anglePerm1[order1[i]].push_back(std::pair<int, double>(i,pi/2));
- anglePerm2[order2[i]].push_back(std::pair<int, double>(i,pi/2));
+std::vector<std::pair<double,double> > random_Fourier(double sigma, int M = 1000){
+ std::normal_distribution<double> distrib(0,1); std::vector<std::pair<double,double> > Z; std::random_device rd;
+ for(int i = 0; i < M; i++){
+ std::mt19937 e1(rd()); std::mt19937 e2(rd());
+ double zx = distrib(e1); double zy = distrib(e2);
+ Z.emplace_back(zx/sigma,zy/sigma);
}
-
- // Compute the SW distance with the list of inversions.
- return compute_sw(anglePerm1, anglePerm2, PD1, PD2);
-
+ return Z;
}
- /** \brief Computes the Sliced Wasserstein Kernel between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- * @param[in] sigma bandwidth parameter.
- *
- */
- double swk(PD PD1, PD PD2, double sigma){
- return exp( - sw(PD1,PD2) / (2*pow(sigma, 2)) );
- }
+
@@ -309,92 +153,59 @@ double compute_sw(const std::vector<std::vector<std::pair<int,double> > > & V1,
// ********************************************************************
-// Approximate computation.
+// Kernel computation.
// ********************************************************************
-double approx_lpwg_Fourier(const std::vector<std::pair<double,double> >& B1, const std::vector<std::pair<double,double> >& B2){
- double d = 0; int M = B1.size();
- for(int i = 0; i < M; i++) d += B1[i].first*B2[i].first + B1[i].second*B2[i].second;
- return (1.0/M)*d;
-}
-
-double approx_gpwg_Fourier(const std::vector<std::pair<double,double> >& B1, const std::vector<std::pair<double,double> >& B2, double tau){
- int M = B1.size();
- double d3 = approx_lpwg_Fourier(B1, B2);
- double d1 = 0; double d2 = 0;
- for(int i = 0; i < M; i++){d1 += pow(B1[i].first,2) + pow(B1[i].second,2); d2 += pow(B2[i].first,2) + pow(B2[i].second,2);}
- return exp( -((1.0/M)*(d1+d2)-2*d3) / (2*pow(tau,2)) );
-}
-
-double approx_dpwg_Fourier(const std::vector<std::pair<double,double> >& B1, const std::vector<std::pair<double,double> >& B2){
- int M = B1.size();
- double d3 = approx_lpwg_Fourier(B1, B2);
- double d1 = 0; double d2 = 0;
- for(int i = 0; i < M; i++){d1 += pow(B1[i].first,2) + pow(B1[i].second,2); d2 += pow(B2[i].first,2) + pow(B2[i].second,2);}
- return std::sqrt((1.0/M)*(d1+d2)-2*d3);
-}
-template<class Weight = double(*)(std::pair<double,double>) >
-std::vector<std::pair<double,double> > Fourier_feat(PD D, std::vector<std::pair<double,double> > Z, Weight weight = arctan_weight){
- int m = D.size(); std::vector<std::pair<double,double> > B; int M = Z.size();
- for(int i = 0; i < M; i++){
- double d1 = 0; double d2 = 0; double zx = Z[i].first; double zy = Z[i].second;
- for(int j = 0; j < m; j++){
- double x = D[j].first; double y = D[j].second;
- d1 += (*weight)(D[j])*cos(x*zx + y*zy);
- d2 += (*weight)(D[j])*sin(x*zx + y*zy);
- }
- B.push_back(std::pair<double,double>(d1,d2));
- }
- return B;
-}
-std::vector<std::pair<double,double> > random_Fourier(double sigma, int M = 1000){
- std::normal_distribution<double> distrib(0,1); std::vector<std::pair<double,double> > Z; std::random_device rd;
- for(int i = 0; i < M; i++){
- std::mt19937 e1(rd()); std::mt19937 e2(rd());
- double zx = distrib(e1); double zy = distrib(e2);
- Z.push_back(std::pair<double,double>((1.0/sigma)*zx,(1.0/sigma)*zy));
- }
- return Z;
-}
-/** \brief Computes an approximation of the Linear Persistence Weighted Gaussian Kernel between two persistence diagrams with random Fourier features.
+/** \brief Computes the Linear Persistence Weighted Gaussian Kernel between two persistence diagrams with random Fourier features.
* \ingroup kernel
*
* @param[in] PD1 first persistence diagram.
* @param[in] PD2 second persistence diagram.
* @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
* @param[in] weight weight function for the points in the diagrams.
- * @param[in] M number of Fourier features.
+ * @param[in] M number of Fourier features (set -1 for exact computation).
*
*/
-template<class Weight = double(*)(std::pair<double,double>) >
-double approx_lpwgk(const PD & PD1, const PD & PD2, double sigma, Weight weight = arctan_weight, int M = 1000){
- std::vector<std::pair<double,double> > Z = random_Fourier(sigma, M);
- std::vector<std::pair<double,double> > B1 = Fourier_feat(PD1,Z,weight);
- std::vector<std::pair<double,double> > B2 = Fourier_feat(PD2,Z,weight);
- return approx_lpwg_Fourier(B1,B2);
+template<class Weight = std::function<double (std::pair<double,double>) > >
+double linear_persistence_weighted_gaussian_kernel(const PD & PD1, const PD & PD2, double sigma, Weight weight = arctan_weight, int M = 1000){
+
+ if(M == -1){
+ int num_pts1 = PD1.size(); int num_pts2 = PD2.size(); double k = 0;
+ for(int i = 0; i < num_pts1; i++)
+ for(int j = 0; j < num_pts2; j++)
+ k += weight(PD1[i])*weight(PD2[j])*exp(-((PD1[i].first-PD2[j].first)*(PD1[i].first-PD2[j].first) + (PD1[i].second-PD2[j].second)*(PD1[i].second-PD2[j].second))/(2*sigma*sigma));
+ return k;
+ }
+ else{
+ std::vector<std::pair<double,double> > Z = random_Fourier(sigma, M);
+ std::vector<std::pair<double,double> > B1 = Fourier_feat(PD1,Z,weight);
+ std::vector<std::pair<double,double> > B2 = Fourier_feat(PD2,Z,weight);
+ double d = 0; for(int i = 0; i < M; i++) d += B1[i].first*B2[i].first + B1[i].second*B2[i].second;
+ return d/M;
+ }
}
-/** \brief Computes an approximation of the Persistence Scale Space Kernel between two persistence diagrams with random Fourier features.
+/** \brief Computes the Persistence Scale Space Kernel between two persistence diagrams with random Fourier features.
* \ingroup kernel
*
* @param[in] PD1 first persistence diagram.
* @param[in] PD2 second persistence diagram.
* @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
- * @param[in] M number of Fourier features.
+ * @param[in] M number of Fourier features (set -1 for exact computation).
*
*/
-double approx_pssk(const PD & PD1, const PD & PD2, double sigma, int M = 1000){
- PD pd1 = PD1; int numpts = PD1.size(); for(int i = 0; i < numpts; i++) pd1.push_back(std::pair<double,double>(PD1[i].second,PD1[i].first));
- PD pd2 = PD2; numpts = PD2.size(); for(int i = 0; i < numpts; i++) pd2.push_back(std::pair<double,double>(PD2[i].second,PD2[i].first));
- return approx_lpwgk(pd1, pd2, 2*sqrt(sigma), &pss_weight, M) / (2*8*pi*sigma);
+double persistence_scale_space_kernel(const PD & PD1, const PD & PD2, double sigma, int M = 1000){
+ PD pd1 = PD1; int numpts = PD1.size(); for(int i = 0; i < numpts; i++) pd1.emplace_back(PD1[i].second,PD1[i].first);
+ PD pd2 = PD2; numpts = PD2.size(); for(int i = 0; i < numpts; i++) pd2.emplace_back(PD2[i].second,PD2[i].first);
+ return linear_persistence_weighted_gaussian_kernel(pd1, pd2, 2*sqrt(sigma), pss_weight, M) / (2*8*pi*sigma);
}
-/** \brief Computes an approximation of the Gaussian Persistence Weighted Gaussian Kernel between two persistence diagrams with random Fourier features.
+/** \brief Computes the Gaussian Persistence Weighted Gaussian Kernel between two persistence diagrams with random Fourier features.
* \ingroup kernel
*
* @param[in] PD1 first persistence diagram.
@@ -402,66 +213,149 @@ double approx_pssk(const PD & PD1, const PD & PD2, double sigma, int M = 1000){
* @param[in] sigma bandwidth parameter of the Gaussian Kernel used for the Kernel Mean Embedding of the diagrams.
* @param[in] tau bandwidth parameter of the Gaussian Kernel used between the embeddings.
* @param[in] weight weight function for the points in the diagrams.
- * @param[in] M number of Fourier features.
+ * @param[in] M number of Fourier features (set -1 for exact computation).
*
*/
-template<class Weight = double(*)(std::pair<double,double>) >
-double approx_gpwgk(const PD & PD1, const PD & PD2, double sigma, double tau, Weight weight = arctan_weight, int M = 1000){
- std::vector<std::pair<double,double> > Z = random_Fourier(sigma, M);
- std::vector<std::pair<double,double> > B1 = Fourier_feat(PD1,Z,weight);
- std::vector<std::pair<double,double> > B2 = Fourier_feat(PD2,Z,weight);
- return approx_gpwg_Fourier(B1,B2,tau);
+template<class Weight = std::function<double (std::pair<double,double>) > >
+double gaussian_persistence_weighted_gaussian_kernel(const PD & PD1, const PD & PD2, double sigma, double tau, Weight weight = arctan_weight, int M = 1000){
+ double k1 = linear_persistence_weighted_gaussian_kernel(PD1,PD1,sigma,weight,M);
+ double k2 = linear_persistence_weighted_gaussian_kernel(PD2,PD2,sigma,weight,M);
+ double k3 = linear_persistence_weighted_gaussian_kernel(PD1,PD2,sigma,weight,M);
+ return exp( - (k1+k2-2*k3) / (2*tau*tau) );
}
-/** \brief Computes an approximation of the Sliced Wasserstein distance between two persistence diagrams.
+/** \brief Computes the Sliced Wasserstein Kernel between two persistence diagrams with sampled directions.
* \ingroup kernel
*
* @param[in] PD1 first persistence diagram.
* @param[in] PD2 second persistence diagram.
- * @param[in] N number of points sampled on the circle.
+ * @param[in] sigma bandwidth parameter.
+ * @param[in] N number of points sampled on the circle (set -1 for exact computation).
*
*/
-double approx_sw(PD PD1, PD PD2, int N = 100){
-
- double step = pi/N; double sw = 0;
-
- // Add projections onto diagonal.
- int n1, n2; n1 = PD1.size(); n2 = PD2.size();
- for (int i = 0; i < n2; i++)
- PD1.push_back(std::pair<double,double>( (PD2[i].first + PD2[i].second)/2, (PD2[i].first + PD2[i].second)/2) );
- for (int i = 0; i < n1; i++)
- PD2.push_back(std::pair<double,double>( (PD1[i].first + PD1[i].second)/2, (PD1[i].first + PD1[i].second)/2) );
- int n = PD1.size();
-
- // Sort and compare all projections.
- //#pragma omp parallel for
- for (int i = 0; i < N; i++){
- std::vector<std::pair<int,double> > L1, L2;
- for (int j = 0; j < n; j++){
- L1.push_back( std::pair<int,double>(j, PD1[j].first*cos(-pi/2+i*step) + PD1[j].second*sin(-pi/2+i*step)) );
- L2.push_back( std::pair<int,double>(j, PD2[j].first*cos(-pi/2+i*step) + PD2[j].second*sin(-pi/2+i*step)) );
+double sliced_wasserstein_kernel(PD PD1, PD PD2, double sigma, int N = 100){
+
+ if(N == -1){
+
+ // Add projections onto diagonal.
+ int n1, n2; n1 = PD1.size(); n2 = PD2.size(); double max_ordinate = std::numeric_limits<double>::lowest();
+ for (int i = 0; i < n2; i++){
+ max_ordinate = std::max(max_ordinate, PD2[i].second);
+ PD1.emplace_back( (PD2[i].first+PD2[i].second)/2, (PD2[i].first+PD2[i].second)/2 );
+ }
+ for (int i = 0; i < n1; i++){
+ max_ordinate = std::max(max_ordinate, PD1[i].second);
+ PD2.emplace_back( (PD1[i].first+PD1[i].second)/2, (PD1[i].first+PD1[i].second)/2 );
+ }
+ int num_pts_dgm = PD1.size();
+
+ // Slightly perturb the points so that the PDs are in generic positions.
+ int mag = 0; while(max_ordinate > 10){mag++; max_ordinate/=10;}
+ double thresh = pow(10,-5+mag);
+ srand(time(NULL));
+ for (int i = 0; i < num_pts_dgm; i++){
+ PD1[i].first += thresh*(1.0-2.0*rand()/RAND_MAX); PD1[i].second += thresh*(1.0-2.0*rand()/RAND_MAX);
+ PD2[i].first += thresh*(1.0-2.0*rand()/RAND_MAX); PD2[i].second += thresh*(1.0-2.0*rand()/RAND_MAX);
+ }
+
+ // Compute all angles in both PDs.
+ std::vector<std::pair<double, std::pair<int,int> > > angles1, angles2;
+ for (int i = 0; i < num_pts_dgm; i++){
+ for (int j = i+1; j < num_pts_dgm; j++){
+ double theta1 = compute_angle(PD1,i,j); double theta2 = compute_angle(PD2,i,j);
+ angles1.emplace_back(theta1, std::pair<int,int>(i,j));
+ angles2.emplace_back(theta2, std::pair<int,int>(i,j));
+ }
+ }
+
+ // Sort angles.
+ std::sort(angles1.begin(), angles1.end(), sortAngle); std::sort(angles2.begin(), angles2.end(), sortAngle);
+
+ // Initialize orders of the points of both PDs (given by ordinates when theta = -pi/2).
+ std::vector<int> orderp1, orderp2;
+ for (int i = 0; i < num_pts_dgm; i++){ orderp1.push_back(i); orderp2.push_back(i); }
+ std::sort( orderp1.begin(), orderp1.end(), [=](int i, int j){ if(PD1[i].second != PD1[j].second) return (PD1[i].second < PD1[j].second); else return (PD1[i].first > PD1[j].first); } );
+ std::sort( orderp2.begin(), orderp2.end(), [=](int i, int j){ if(PD2[i].second != PD2[j].second) return (PD2[i].second < PD2[j].second); else return (PD2[i].first > PD2[j].first); } );
+
+ // Find the inverses of the orders.
+ std::vector<int> order1(num_pts_dgm); std::vector<int> order2(num_pts_dgm);
+ for(int i = 0; i < num_pts_dgm; i++) for (int j = 0; j < num_pts_dgm; j++) if(orderp1[j] == i){ order1[i] = j; break; }
+ for(int i = 0; i < num_pts_dgm; i++) for (int j = 0; j < num_pts_dgm; j++) if(orderp2[j] == i){ order2[i] = j; break; }
+
+ // Record all inversions of points in the orders as theta varies along the positive half-disk.
+ std::vector<std::vector<std::pair<int,double> > > anglePerm1(num_pts_dgm);
+ std::vector<std::vector<std::pair<int,double> > > anglePerm2(num_pts_dgm);
+
+ int M1 = angles1.size();
+ for (int i = 0; i < M1; i++){
+ double theta = angles1[i].first; int p = angles1[i].second.first; int q = angles1[i].second.second;
+ anglePerm1[order1[p]].emplace_back(p,theta);
+ anglePerm1[order1[q]].emplace_back(q,theta);
+ int a = order1[p]; int b = order1[q]; order1[p] = b; order1[q] = a;
+ }
+
+ int M2 = angles2.size();
+ for (int i = 0; i < M2; i++){
+ double theta = angles2[i].first; int p = angles2[i].second.first; int q = angles2[i].second.second;
+ anglePerm2[order2[p]].emplace_back(p,theta);
+ anglePerm2[order2[q]].emplace_back(q,theta);
+ int a = order2[p]; int b = order2[q]; order2[p] = b; order2[q] = a;
+ }
+
+ for (int i = 0; i < num_pts_dgm; i++){
+ anglePerm1[order1[i]].emplace_back(i,pi/2);
+ anglePerm2[order2[i]].emplace_back(i,pi/2);
+ }
+
+ // Compute the SW distance with the list of inversions.
+ double sw = 0;
+ for (int i = 0; i < num_pts_dgm; i++){
+ std::vector<std::pair<int,double> > U,V; U = anglePerm1[i]; V = anglePerm2[i];
+ double theta1, theta2; theta1 = -pi/2;
+ unsigned int ku, kv; ku = 0; kv = 0; theta2 = std::min(U[ku].second,V[kv].second);
+ while(theta1 != pi/2){
+ if(PD1[U[ku].first].first != PD2[V[kv].first].first || PD1[U[ku].first].second != PD2[V[kv].first].second)
+ if(theta1 != theta2)
+ sw += compute_int(theta1, theta2, U[ku].first, V[kv].first, PD1, PD2);
+ theta1 = theta2;
+ if ( (theta2 == U[ku].second) && ku < U.size()-1 ) ku++;
+ if ( (theta2 == V[kv].second) && kv < V.size()-1 ) kv++;
+ theta2 = std::min(U[ku].second, V[kv].second);
+ }
}
- std::sort(L1.begin(),L1.end(), myComp); std::sort(L2.begin(),L2.end(), myComp);
- double f = 0; for (int j = 0; j < n; j++) f += std::abs(L1[j].second - L2[j].second);
- sw += f*step;
+
+ return exp( -(sw/pi)/(2*sigma*sigma) );
+
}
- return sw/pi;
-}
-/** \brief Computes an approximation of the Sliced Wasserstein Kernel between two persistence diagrams.
- * \ingroup kernel
- *
- * @param[in] PD1 first persistence diagram.
- * @param[in] PD2 second persistence diagram.
- * @param[in] sigma bandwidth parameter.
- * @param[in] N number of points sampled on the circle.
- *
- */
-double approx_swk(PD PD1, PD PD2, double sigma, int N = 100){
- return exp( - approx_sw(PD1,PD2,N) / (2*pow(sigma,2)));
-}
+ else{
+ double step = pi/N; double sw = 0;
+
+ // Add projections onto diagonal.
+ int n1, n2; n1 = PD1.size(); n2 = PD2.size();
+ for (int i = 0; i < n2; i++)
+ PD1.emplace_back( (PD2[i].first + PD2[i].second)/2, (PD2[i].first + PD2[i].second)/2 );
+ for (int i = 0; i < n1; i++)
+ PD2.emplace_back( (PD1[i].first + PD1[i].second)/2, (PD1[i].first + PD1[i].second)/2 );
+ int n = PD1.size();
+
+ // Sort and compare all projections.
+ //#pragma omp parallel for
+ for (int i = 0; i < N; i++){
+ std::vector<std::pair<int,double> > L1, L2;
+ for (int j = 0; j < n; j++){
+ L1.emplace_back( j, PD1[j].first*cos(-pi/2+i*step) + PD1[j].second*sin(-pi/2+i*step) );
+ L2.emplace_back( j, PD2[j].first*cos(-pi/2+i*step) + PD2[j].second*sin(-pi/2+i*step) );
+ }
+ std::sort(L1.begin(),L1.end(), myComp); std::sort(L2.begin(),L2.end(), myComp);
+ double f = 0; for (int j = 0; j < n; j++) f += std::abs(L1[j].second - L2[j].second);
+ sw += f*step;
+ }
+ return exp( -(sw/pi)/(2*sigma*sigma) );
+ }
+}
} // namespace kernel
diff --git a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h
index 3a0d8154..2b648425 100644
--- a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h
+++ b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h
@@ -70,15 +70,15 @@ namespace cover_complex {
*
* When launching:
*
- * \code $> ./Nerve ../../../../data/points/human.off 2 10 0.3 --v
+ * \code $> ./Nerve ../../data/points/human.off 2 10 0.3 -v
* \endcode
*
* the program output is:
*
* \include Nerve_GIC/Nerve.txt
*
- * The program also writes a file SC.txt. The first three lines in this file are the location of the input point cloud
- * and the function used to compute the cover.
+ * The program also writes a file ../../data/points/human_sc.txt. The first three lines in this file are the location
+ * of the input point cloud and the function used to compute the cover.
* The fourth line contains the number of vertices nv and edges ne of the Nerve.
* The next nv lines represent the vertices. Each line contains the vertex ID,
* the number of data points it contains, and their average color function value.
@@ -113,12 +113,12 @@ namespace cover_complex {
*
* When launching:
*
- * \code $> ./VoronoiGIC ../../../../data/points/human.off 700 --v
+ * \code $> ./VoronoiGIC ../../data/points/human.off 700 -v
* \endcode
*
* the program outputs SC.off. Using e.g.
*
- * \code $> geomview SC.off
+ * \code $> geomview ../../data/points/human_sc.off
* \endcode
*
* one can obtain the following visualization:
@@ -146,7 +146,7 @@ namespace cover_complex {
*
* When launching:
*
- * \code $> ./CoordGIC ../../../../data/points/KleinBottle5D.off 0 --v
+ * \code $> ./CoordGIC ../../data/points/KleinBottle5D.off 0 -v
* \endcode
*
* the program outputs SC.dot. Using e.g.
@@ -169,15 +169,13 @@ namespace cover_complex {
*
* When launching:
*
- * \code $> ./FuncGIC ../../data/points/COIL_database/lucky_cat.off ../../data/points/COIL_database/lucky_cat_PCA1 --v
+ * \code $> ./FuncGIC ../../data/points/COIL_database/lucky_cat.off ../../data/points/COIL_database/lucky_cat_PCA1 -v
* \endcode
*
* the program outputs again SC.dot which gives the following visualization after using neato:
*
* \image html "funcGICvisu.jpg" "Visualization with neato"
*
- * \copyright GNU General Public License v3.
- * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup cover_complex
@@ -186,31 +184,3 @@ namespace cover_complex {
} // namespace Gudhi
#endif // DOC_COVER_COMPLEX_INTRO_COVER_COMPLEX_H_
-
-
-/* * \subsection gicexample Example with cover from function
- *
- * This example builds the GIC of a point cloud sampled on a 3D human shape (human.off).
- * The cover C comes from the preimages of intervals (with length 0.075 and gain 0)
- * covering the height function (coordinate 2),
- * and the graph G comes from a Rips complex built with threshold 0.075.
- * Note that if the gain is too big, the number of cliques increases a lot,
- * which make the computation time much larger.
- *
- * \include Nerve_GIC/GIC.cpp
- *
- * When launching:
- *
- * \code $> ./GIC ../../../../data/points/human.off 0.075 2 0.075 0 --v
- * \endcode
- *
- * the program outputs SC.txt, which can be visualized with python and firefox as before:
- *
- * \image html "gicvisu.jpg" "Visualization with KeplerMapper"
- * */
-
-
-/* * Using e.g.
- *
- * \code $> python KeplerMapperVisuFromTxtFile.py && firefox SC.html
- * \endcode */
diff --git a/src/Nerve_GIC/doc/funcGICvisu.jpg b/src/Nerve_GIC/doc/funcGICvisu.jpg
index f3da45ac..36b64dde 100644
--- a/src/Nerve_GIC/doc/funcGICvisu.jpg
+++ b/src/Nerve_GIC/doc/funcGICvisu.jpg
Binary files differ
diff --git a/src/Nerve_GIC/doc/funcGICvisu.pdf b/src/Nerve_GIC/doc/funcGICvisu.pdf
new file mode 100644
index 00000000..d7456cd3
--- /dev/null
+++ b/src/Nerve_GIC/doc/funcGICvisu.pdf
Binary files differ
diff --git a/src/Nerve_GIC/example/CMakeLists.txt b/src/Nerve_GIC/example/CMakeLists.txt
index 461b6db2..542c6af4 100644
--- a/src/Nerve_GIC/example/CMakeLists.txt
+++ b/src/Nerve_GIC/example/CMakeLists.txt
@@ -1,29 +1,29 @@
cmake_minimum_required(VERSION 2.6)
project(Nerve_GIC_examples)
-add_executable ( Nerve Nerve.cpp )
-add_executable ( CoordGIC CoordGIC.cpp )
-add_executable ( FuncGIC FuncGIC.cpp )
-add_executable ( VoronoiGIC VoronoiGIC.cpp )
+if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
-if (TBB_FOUND)
- target_link_libraries(Nerve ${TBB_LIBRARIES})
- target_link_libraries(CoordGIC ${TBB_LIBRARIES})
- target_link_libraries(FuncGIC ${TBB_LIBRARIES})
- target_link_libraries(VoronoiGIC ${TBB_LIBRARIES})
-endif()
+ add_executable ( CoordGIC CoordGIC.cpp )
+ add_executable ( FuncGIC FuncGIC.cpp )
-file(COPY KeplerMapperVisuFromTxtFile.py km.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ if (TBB_FOUND)
+ target_link_libraries(CoordGIC ${TBB_LIBRARIES})
+ target_link_libraries(FuncGIC ${TBB_LIBRARIES})
+ endif()
-add_test(NAME Nerve_GIC_example_nerve COMMAND $<TARGET_FILE:Nerve>
- "${CMAKE_SOURCE_DIR}/data/points/human.off" "2" "10" "0.3")
+ # Copy files for not to pollute sources when testing
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
-add_test(NAME Nerve_GIC_example_VoronoiGIC COMMAND $<TARGET_FILE:VoronoiGIC>
- "${CMAKE_SOURCE_DIR}/data/points/human.off" "100")
+ add_test(NAME Nerve_GIC_example_CoordGIC COMMAND $<TARGET_FILE:CoordGIC>
+ "tore3D_1307.off" "0")
-add_test(NAME Nerve_GIC_example_CoordGIC COMMAND $<TARGET_FILE:CoordGIC>
- "${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off" "0")
+ add_test(NAME Nerve_GIC_example_FuncGIC COMMAND $<TARGET_FILE:FuncGIC>
+ "lucky_cat.off"
+ "lucky_cat_PCA1")
-add_test(NAME Nerve_GIC_example_FuncGIC COMMAND $<TARGET_FILE:FuncGIC>
- "${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat.off"
- "${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1")
+ install(TARGETS CoordGIC DESTINATION bin)
+ install(TARGETS FuncGIC DESTINATION bin)
+
+endif (NOT CGAL_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Nerve_GIC/example/CoordGIC.cpp b/src/Nerve_GIC/example/CoordGIC.cpp
index c03fcbb3..c92cf235 100644
--- a/src/Nerve_GIC/example/CoordGIC.cpp
+++ b/src/Nerve_GIC/example/CoordGIC.cpp
@@ -27,8 +27,8 @@
void usage(int nbArgs, char *const progName) {
std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
- std::cerr << "Usage: " << progName << " filename.off coordinate [--v] \n";
- std::cerr << " i.e.: " << progName << " ../../data/points/human.off 2 --v \n";
+ std::cerr << "Usage: " << progName << " filename.off coordinate [-v] \n";
+ std::cerr << " i.e.: " << progName << " ../../data/points/human.off 2 -v \n";
exit(-1); // ----- >>
}
diff --git a/src/Nerve_GIC/example/FuncGIC.cpp b/src/Nerve_GIC/example/FuncGIC.cpp
index 3762db4e..cb0f0d63 100644
--- a/src/Nerve_GIC/example/FuncGIC.cpp
+++ b/src/Nerve_GIC/example/FuncGIC.cpp
@@ -27,9 +27,9 @@
void usage(int nbArgs, char *const progName) {
std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
- std::cerr << "Usage: " << progName << " filename.off function [--v] \n";
+ std::cerr << "Usage: " << progName << " filename.off function [-v] \n";
std::cerr << " i.e.: " << progName << " ../../data/points/COIL_database/lucky_cat.off "
- "../../data/points/COIL_database/lucky_cat_PCA1 --v \n";
+ "../../data/points/COIL_database/lucky_cat_PCA1 -v \n";
exit(-1); // ----- >>
}
diff --git a/src/Nerve_GIC/example/GIC.cpp b/src/Nerve_GIC/example/GIC.cpp
deleted file mode 100644
index 2bc24a4d..00000000
--- a/src/Nerve_GIC/example/GIC.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* 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): Mathieu Carrière
- *
- * Copyright (C) 2017 INRIA
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gudhi/GIC.h>
-
-#include <string>
-#include <vector>
-
-void usage(int nbArgs, char *const progName) {
- std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
- std::cerr << "Usage: " << progName << " filename.off threshold coordinate resolution gain [--v] \n";
- std::cerr << " i.e.: " << progName << " ../../data/points/human.off 0.075 2 0.075 0 --v \n";
- exit(-1); // ----- >>
-}
-
-int main(int argc, char **argv) {
- if ((argc != 6) && (argc != 7)) usage(argc, argv[0]);
-
- using Point = std::vector<float>;
-
- std::string off_file_name(argv[1]);
- double threshold = atof(argv[2]);
- int coord = atoi(argv[3]);
- double resolution = atof(argv[4]);
- double gain = atof(argv[5]);
- bool verb = 0;
- if (argc == 7) verb = 1;
-
- // ----------------------------------------------------------------------------
- // Init of a graph induced complex from an OFF file
- // ----------------------------------------------------------------------------
-
- Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
- GIC.set_verbose(verb);
-
- bool check = GIC.read_point_cloud(off_file_name);
-
- if (!check) {
- std::cout << "Incorrect OFF file." << std::endl;
- } else {
- GIC.set_color_from_coordinate(coord);
- GIC.set_function_from_coordinate(coord);
-
- GIC.set_graph_from_rips(threshold, Gudhi::Euclidean_distance());
-
- GIC.set_resolution_with_interval_length(resolution);
- GIC.set_gain(gain);
- GIC.set_cover_from_function();
-
- GIC.find_GIC_simplices();
-
- GIC.plot_TXT_for_KeplerMapper();
-
- Gudhi::Simplex_tree<> stree;
- GIC.create_complex(stree);
-
- // ----------------------------------------------------------------------------
- // Display information about the graph induced complex
- // ----------------------------------------------------------------------------
-
- if (verb) {
- std::cout << "Graph induced complex is of dimension " << stree.dimension() << " - " << stree.num_simplices()
- << " simplices - " << stree.num_vertices() << " vertices." << std::endl;
-
- std::cout << "Iterator on graph induced complex simplices" << std::endl;
- for (auto f_simplex : stree.filtration_simplex_range()) {
- for (auto vertex : stree.simplex_vertex_range(f_simplex)) {
- std::cout << vertex << " ";
- }
- std::cout << std::endl;
- }
- }
- }
-
- return 0;
-}
diff --git a/src/Nerve_GIC/example/KeplerMapperVisuFromTxtFile.py b/src/Nerve_GIC/example/KeplerMapperVisuFromTxtFile.py
deleted file mode 100755
index d2897774..00000000
--- a/src/Nerve_GIC/example/KeplerMapperVisuFromTxtFile.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-
-import km
-import numpy as np
-from collections import defaultdict
-
-"""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): Mathieu Carriere
-
- Copyright (C) 2017 INRIA
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-__author__ = "Mathieu Carriere"
-__copyright__ = "Copyright (C) 2017 INRIA"
-__license__ = "GPL v3"
-
-network = {}
-mapper = km.KeplerMapper(verbose=0)
-data = np.zeros((3,3))
-projected_data = mapper.fit_transform( data, projection="sum", scaler=None )
-
-f = open('SC.txt','r')
-nodes = defaultdict(list)
-links = defaultdict(list)
-custom = defaultdict(list)
-
-dat = f.readline()
-lens = f.readline()
-color = f.readline();
-param = [float(i) for i in f.readline().split(" ")]
-
-nums = [int(i) for i in f.readline().split(" ")]
-num_nodes = nums[0]
-num_edges = nums[1]
-
-for i in range(0,num_nodes):
- point = [float(j) for j in f.readline().split(" ")]
- nodes[ str(int(point[0])) ] = [ int(point[0]), point[1], int(point[2]) ]
- links[ str(int(point[0])) ] = []
- custom[ int(point[0]) ] = point[1]
-
-m = min([custom[i] for i in range(0,num_nodes)])
-M = max([custom[i] for i in range(0,num_nodes)])
-
-for i in range(0,num_edges):
- edge = [int(j) for j in f.readline().split(" ")]
- links[ str(edge[0]) ].append( str(edge[1]) )
- links[ str(edge[1]) ].append( str(edge[0]) )
-
-network["nodes"] = nodes
-network["links"] = links
-network["meta"] = lens
-
-mapper.visualize(network, color_function = color, path_html="SC.html", title=dat,
-graph_link_distance=30, graph_gravity=0.1, graph_charge=-120, custom_tooltips=custom, width_html=0,
-height_html=0, show_tooltips=True, show_title=True, show_meta=True, res=param[0],gain=param[1], minimum=m,maximum=M)
diff --git a/src/Nerve_GIC/example/Nerve.txt b/src/Nerve_GIC/example/Nerve.txt
deleted file mode 100644
index 2a861c5f..00000000
--- a/src/Nerve_GIC/example/Nerve.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Nerve is of dimension 1 - 41 simplices - 21 vertices.
-Iterator on Nerve simplices
-0
-1
-2
-2 0
-3
-3 1
-4
-4 3
-5
-5 2
-6
-6 4
-7
-7 5
-8
-9
-9 6
-10
-10 7
-11
-12
-12 8
-13
-13 9
-13 10
-14
-14 11
-15
-15 13
-16
-16 12
-17
-17 14
-18
-18 15
-18 16
-18 17
-19
-19 18
-20
-20 19
diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h
index 9f107a7e..40ff7a4a 100644
--- a/src/Nerve_GIC/include/gudhi/GIC.h
+++ b/src/Nerve_GIC/include/gudhi/GIC.h
@@ -30,16 +30,27 @@
#include <gudhi/Rips_complex.h>
#include <gudhi/Points_off_io.h>
#include <gudhi/distance_functions.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Bottleneck.h>
+
+#include <boost/config.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/connected_components.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/subgraph.hpp>
+#include <boost/graph/graph_utility.hpp>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <limits> // for numeric_limits
-#include <utility> // for pair<>
+#include <utility> // for std::pair<>
#include <algorithm> // for std::max
#include <random>
#include <cassert>
+#include <cmath>
namespace Gudhi {
@@ -48,6 +59,13 @@ namespace cover_complex {
using Simplex_tree = Gudhi::Simplex_tree<>;
using Filtration_value = Simplex_tree::Filtration_value;
using Rips_complex = Gudhi::rips_complex::Rips_complex<Filtration_value>;
+using Persistence_diagram = std::vector<std::pair<double, double> >;
+using Graph = boost::subgraph<
+ boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS, boost::no_property,
+ boost::property<boost::edge_index_t, int, boost::property<boost::edge_weight_t, double> > > >;
+using Vertex_t = boost::graph_traits<Graph>::vertex_descriptor;
+using Index_map = boost::property_map<Graph, boost::vertex_index_t>::type;
+using Weight_map = boost::property_map<Graph, boost::edge_weight_t>::type;
/**
* \class Cover_complex
@@ -72,25 +90,40 @@ using Rips_complex = Gudhi::rips_complex::Rips_complex<Filtration_value>;
template <typename Point>
class Cover_complex {
private:
- // Graph_induced_complex(std::map<int, double> fun){func = fun;}
bool verbose = false; // whether to display information.
- std::vector<Point> point_cloud;
- std::vector<std::vector<int> > one_skeleton;
- typedef int Cover_t; // elements of cover C are indexed by integers.
- std::vector<std::vector<Cover_t> > simplices;
- std::map<int, std::vector<Cover_t> > cover;
- std::map<Cover_t, std::vector<int> > cover_back;
- int maximal_dim; // maximal dimension of output simplicial complex.
- int data_dimension; // dimension of input data.
- int n; // number of points.
- std::map<Cover_t, int>
+ std::string type; // Nerve or GIC
+
+ std::vector<Point> point_cloud; // input point cloud.
+ std::vector<std::vector<double> > distances; // all pairwise distances.
+ int maximal_dim; // maximal dimension of output simplicial complex.
+ int data_dimension; // dimension of input data.
+ int n; // number of points.
+
+ std::map<int, double> func; // function used to compute the output simplicial complex.
+ std::map<int, double>
+ func_color; // function used to compute the colors of the nodes of the output simplicial complex.
+ bool functional_cover = false; // whether we use a cover with preimages of a function or not.
+
+ Graph one_skeleton_OFF; // one-skeleton given by the input OFF file (if it exists).
+ Graph one_skeleton; // one-skeleton used to compute the connected components.
+ std::vector<Vertex_t> vertices; // vertices of one_skeleton.
+
+ std::vector<std::vector<int> > simplices; // simplices of output simplicial complex.
+ std::vector<int> voronoi_subsamples; // Voronoi germs (in case of Voronoi cover).
+
+ Persistence_diagram PD;
+ std::vector<double> distribution;
+
+ std::map<int, std::vector<int> >
+ cover; // function associating to each data point its vectors of cover elements to which it belongs.
+ std::map<int, std::vector<int> >
+ cover_back; // inverse of cover, in order to get the data points associated to a specific cover element.
+ std::map<int, double> cover_std; // standard function (induced by func) used to compute the extended persistence
+ // diagram of the output simplicial complex.
+ std::map<int, int>
cover_fct; // integer-valued function that allows to state if two elements of the cover are consecutive or not.
- std::map<Cover_t, std::pair<int, double> >
- cover_color; // size and coloring of the vertices of the output simplicial complex.
- Simplex_tree st;
-
- std::map<int, std::vector<int> > adjacency_matrix;
- std::vector<std::vector<double> > distances;
+ std::map<int, std::pair<int, double> >
+ cover_color; // size and coloring (induced by func_color) of the vertices of the output simplicial complex.
int resolution_int = -1;
double resolution_double = -1;
@@ -99,14 +132,11 @@ class Cover_complex {
double rate_power = 0.001; // Power in the subsampling.
int mask = 0; // Ignore nodes containing less than mask points.
- std::map<int, double> func;
- std::map<int, double> func_color;
- std::vector<int> voronoi_subsamples;
+ std::map<int, int> name2id, name2idinv;
+
std::string cover_name;
std::string point_cloud_name;
std::string color_name;
- std::string type; // Nerve or GIC
- bool functional_cover = false; // whether we use a cover with preimages of a function or not
// Point comparator
struct Less {
@@ -120,21 +150,16 @@ class Cover_complex {
}
};
- // DFS
- private:
- void dfs(std::map<int, std::vector<int> >& G, int p, std::vector<int>& cc, std::map<int, bool>& visit) {
- cc.push_back(p);
- visit[p] = true;
- int neighb = G[p].size();
- for (int i = 0; i < neighb; i++)
- if (visit.find(G[p][i]) != visit.end())
- if (!(visit[G[p][i]])) dfs(G, G[p][i], cc, visit);
+ // Remove all edges of a graph.
+ void remove_edges(Graph& G) {
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = boost::edges(G); ei != ei_end; ++ei) boost::remove_edge(*ei, G);
}
// Find random number in [0,1].
double GetUniform() {
- static std::default_random_engine re;
- static std::uniform_real_distribution<double> Dist(0, 1);
+ thread_local std::default_random_engine re;
+ thread_local std::uniform_real_distribution<double> Dist(0, 1);
return Dist(re);
}
@@ -155,24 +180,14 @@ class Cover_complex {
}
}
- private:
- void fill_adjacency_matrix_from_st() {
- std::vector<int> empty;
- for (int i = 0; i < n; i++) adjacency_matrix[i] = empty;
- for (auto simplex : st.complex_simplex_range()) {
- if (st.dimension(simplex) == 1) {
- std::vector<int> vertices;
- for (auto vertex : st.simplex_vertex_range(simplex)) vertices.push_back(vertex);
- adjacency_matrix[vertices[0]].push_back(vertices[1]);
- adjacency_matrix[vertices[1]].push_back(vertices[0]);
- }
- }
- }
+ // *******************************************************************************************************************
+ // Utils.
+ // *******************************************************************************************************************
public:
/** \brief Specifies whether the type of the output simplicial complex.
*
- * @param[in] t string (either "GIC" or "Nerve").
+ * @param[in] t std::string (either "GIC" or "Nerve").
*
*/
void set_type(const std::string& t) { type = t; }
@@ -221,14 +236,15 @@ class Cover_complex {
char comment = '#';
while (comment == '#') {
- getline(input, line);
- if (!line.empty() && !std::all_of(line.begin(), line.end(), isspace)) comment = line[line.find_first_not_of(' ')];
+ std::getline(input, line);
+ if (!line.empty() && !all_of(line.begin(), line.end(), (int (*)(int))isspace))
+ comment = line[line.find_first_not_of(' ')];
}
- if (std::strcmp((char*)line.c_str(), "nOFF") == 0) {
+ if (strcmp((char*)line.c_str(), "nOFF") == 0) {
comment = '#';
while (comment == '#') {
- getline(input, line);
- if (!line.empty() && !std::all_of(line.begin(), line.end(), isspace))
+ std::getline(input, line);
+ if (!line.empty() && !all_of(line.begin(), line.end(), (int (*)(int))isspace))
comment = line[line.find_first_not_of(' ')];
}
std::stringstream stream(line);
@@ -238,10 +254,11 @@ class Cover_complex {
}
comment = '#';
- int numedges, numfaces, i, num;
+ int numedges, numfaces, i, dim;
while (comment == '#') {
- getline(input, line);
- if (!line.empty() && !std::all_of(line.begin(), line.end(), isspace)) comment = line[line.find_first_not_of(' ')];
+ std::getline(input, line);
+ if (!line.empty() && !all_of(line.begin(), line.end(), (int (*)(int))isspace))
+ comment = line[line.find_first_not_of(' ')];
}
std::stringstream stream(line);
stream >> n;
@@ -250,34 +267,31 @@ class Cover_complex {
i = 0;
while (i < n) {
- getline(input, line);
+ std::getline(input, line);
if (!line.empty() && line[line.find_first_not_of(' ')] != '#' &&
- !std::all_of(line.begin(), line.end(), isspace)) {
+ !all_of(line.begin(), line.end(), (int (*)(int))isspace)) {
+ std::stringstream iss(line);
std::vector<double> point;
- std::istringstream iss(line);
point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
point_cloud.emplace_back(point.begin(), point.begin() + data_dimension);
+ boost::add_vertex(one_skeleton_OFF);
+ vertices.push_back(boost::add_vertex(one_skeleton));
i++;
}
}
i = 0;
while (i < numfaces) {
- getline(input, line);
+ std::getline(input, line);
if (!line.empty() && line[line.find_first_not_of(' ')] != '#' &&
- !std::all_of(line.begin(), line.end(), isspace)) {
+ !all_of(line.begin(), line.end(), (int (*)(int))isspace)) {
std::vector<int> simplex;
- std::istringstream iss(line);
+ std::stringstream iss(line);
simplex.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>());
- num = simplex[0];
- std::vector<int> edge(2);
- for (int j = 1; j <= num; j++) {
- for (int k = j + 1; k <= num; k++) {
- edge[0] = simplex[j];
- edge[1] = simplex[k];
- one_skeleton.push_back(edge);
- }
- }
+ dim = simplex[0];
+ for (int j = 1; j <= dim; j++)
+ for (int k = j + 1; k <= dim; k++)
+ boost::add_edge(vertices[simplex[j]], vertices[simplex[k]], one_skeleton_OFF);
i++;
}
}
@@ -298,22 +312,16 @@ class Cover_complex {
*
*/
void set_graph_from_file(const std::string& graph_file_name) {
+ remove_edges(one_skeleton);
int neighb;
std::ifstream input(graph_file_name);
std::string line;
- int edge[2];
- int n = 0;
+ int source;
while (std::getline(input, line)) {
std::stringstream stream(line);
- stream >> edge[0];
- while (stream >> neighb) {
- edge[1] = neighb;
- st.insert_simplex_and_subfaces(edge);
- }
- n++;
+ stream >> source;
+ while (stream >> neighb) boost::add_edge(vertices[source], vertices[neighb], one_skeleton);
}
-
- fill_adjacency_matrix_from_st();
}
public: // Set graph from OFF file.
@@ -321,13 +329,11 @@ class Cover_complex {
*
*/
void set_graph_from_OFF() {
- int num_edges = one_skeleton.size();
- if (num_edges > 0) {
- for (int i = 0; i < num_edges; i++) st.insert_simplex_and_subfaces(one_skeleton[i]);
- fill_adjacency_matrix_from_st();
- } else {
+ remove_edges(one_skeleton);
+ if (num_edges(one_skeleton_OFF))
+ one_skeleton = one_skeleton_OFF;
+ else
std::cout << "No triangulation read in OFF file!" << std::endl;
- }
}
public: // Set graph from Rips complex.
@@ -339,9 +345,27 @@ class Cover_complex {
*/
template <typename Distance>
void set_graph_from_rips(double threshold, Distance distance) {
- Rips_complex rips_complex_from_points(point_cloud, threshold, distance);
- rips_complex_from_points.create_complex(st, 1);
- fill_adjacency_matrix_from_st();
+ remove_edges(one_skeleton);
+ if (distances.size() == 0) compute_pairwise_distances(distance);
+ for (int i = 0; i < n; i++) {
+ for (int j = i + 1; j < n; j++) {
+ if (distances[i][j] <= threshold) {
+ boost::add_edge(vertices[i], vertices[j], one_skeleton);
+ boost::put(boost::edge_weight, one_skeleton, boost::edge(vertices[i], vertices[j], one_skeleton).first,
+ distances[i][j]);
+ }
+ }
+ }
+ }
+
+ public:
+ void set_graph_weights() {
+ Index_map index = boost::get(boost::vertex_index, one_skeleton);
+ Weight_map weight = boost::get(boost::edge_weight, one_skeleton);
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = boost::edges(one_skeleton); ei != ei_end; ++ei)
+ boost::put(weight, *ei,
+ distances[index[boost::source(*ei, one_skeleton)]][index[boost::target(*ei, one_skeleton)]]);
}
public: // Pairwise distances.
@@ -352,9 +376,8 @@ class Cover_complex {
double d;
std::vector<double> zeros(n);
for (int i = 0; i < n; i++) distances.push_back(zeros);
- std::string distance = point_cloud_name;
- distance.append("_dist");
- std::ifstream input(distance.c_str(), std::ios::out | std::ios::binary);
+ std::string distance = point_cloud_name + "_dist";
+ std::ifstream input(distance, std::ios::out | std::ios::binary);
if (input.good()) {
if (verbose) std::cout << "Reading distances..." << std::endl;
@@ -420,10 +443,7 @@ class Cover_complex {
}
if (verbose) std::cout << "delta = " << delta << std::endl;
- Rips_complex rips_complex_from_points(point_cloud, delta, distance);
- rips_complex_from_points.create_complex(st, 1);
- fill_adjacency_matrix_from_st();
-
+ set_graph_from_rips(delta, distance);
return delta;
}
@@ -438,15 +458,15 @@ class Cover_complex {
*
*/
void set_function_from_file(const std::string& func_file_name) {
- int vertex_id = 0;
+ int i = 0;
std::ifstream input(func_file_name);
std::string line;
double f;
while (std::getline(input, line)) {
std::stringstream stream(line);
stream >> f;
- func.emplace(vertex_id, f);
- vertex_id++;
+ func.emplace(i, f);
+ i++;
}
functional_cover = true;
cover_name = func_file_name;
@@ -460,10 +480,8 @@ class Cover_complex {
*/
void set_function_from_coordinate(int k) {
for (int i = 0; i < n; i++) func.emplace(i, point_cloud[i][k]);
- char coordinate[100];
- sprintf(coordinate, "coordinate %d", k);
functional_cover = true;
- cover_name = coordinate;
+ cover_name = "coordinate " + std::to_string(k);
}
public: // Set function from vector.
@@ -474,12 +492,8 @@ class Cover_complex {
*/
template <class InputRange>
void set_function_from_range(InputRange const& function) {
+ for (int i = 0; i < n; i++) func.emplace(i, function[i]);
functional_cover = true;
- int index = 0;
- for (auto v : function) {
- func.emplace(index, v);
- index++;
- }
}
// *******************************************************************************************************************
@@ -505,27 +519,23 @@ class Cover_complex {
}
double reso = 0;
+ Index_map index = boost::get(boost::vertex_index, one_skeleton);
if (type == "GIC") {
- for (auto simplex : st.complex_simplex_range()) {
- if (st.dimension(simplex) == 1) {
- std::vector<int> vertices;
- for (auto vertex : st.simplex_vertex_range(simplex)) vertices.push_back(vertex);
- reso = std::max(reso, std::abs(func[vertices[0]] - func[vertices[1]]));
- }
- }
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = boost::edges(one_skeleton); ei != ei_end; ++ei)
+ reso = std::max(reso, std::abs(func[index[boost::source(*ei, one_skeleton)]] -
+ func[index[boost::target(*ei, one_skeleton)]]));
if (verbose) std::cout << "resolution = " << reso << std::endl;
resolution_double = reso;
}
if (type == "Nerve") {
- for (auto simplex : st.complex_simplex_range()) {
- if (st.dimension(simplex) == 1) {
- std::vector<int> vertices;
- for (auto vertex : st.simplex_vertex_range(simplex)) vertices.push_back(vertex);
- reso = std::max(reso, (std::abs(func[vertices[0]] - func[vertices[1]])) / gain);
- }
- }
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = boost::edges(one_skeleton); ei != ei_end; ++ei)
+ reso = std::max(reso, std::abs(func[index[boost::source(*ei, one_skeleton)]] -
+ func[index[boost::target(*ei, one_skeleton)]]) /
+ gain);
if (verbose) std::cout << "resolution = " << reso << std::endl;
resolution_double = reso;
}
@@ -568,15 +578,12 @@ class Cover_complex {
}
// Read function values and compute min and max
- std::map<int, double>::iterator it;
- double maxf, minf;
- minf = std::numeric_limits<float>::max();
- maxf = std::numeric_limits<float>::min();
- for (it = func.begin(); it != func.end(); it++) {
- minf = std::min(minf, it->second);
- maxf = std::max(maxf, it->second);
+ double minf = std::numeric_limits<float>::max();
+ double maxf = std::numeric_limits<float>::lowest();
+ for (int i = 0; i < n; i++) {
+ minf = std::min(minf, func[i]);
+ maxf = std::max(maxf, func[i]);
}
- int n = func.size();
if (verbose) std::cout << "Min function value = " << minf << " and Max function value = " << maxf << std::endl;
// Compute cover of im(f)
@@ -648,78 +655,96 @@ class Cover_complex {
std::vector<int> points(n);
for (int i = 0; i < n; i++) points[i] = i;
std::sort(points.begin(), points.end(), Less(this->func));
+
int id = 0;
int pos = 0;
+ Index_map index = boost::get(boost::vertex_index, one_skeleton); // int maxc = -1;
+ std::map<int, std::vector<int> > preimages;
+ std::map<int, double> funcstd;
+ if (verbose) std::cout << "Computing preimages..." << std::endl;
for (int i = 0; i < res; i++) {
// Find points in the preimage
- std::map<int, std::vector<int> > prop;
std::pair<double, double> inter1 = intervals[i];
int tmp = pos;
+ double u, v;
if (i != res - 1) {
if (i != 0) {
std::pair<double, double> inter3 = intervals[i - 1];
while (func[points[tmp]] < inter3.second && tmp != n) {
- prop[points[tmp]] = adjacency_matrix[points[tmp]];
+ preimages[i].push_back(points[tmp]);
tmp++;
}
+ u = inter3.second;
+ } else {
+ u = inter1.first;
}
std::pair<double, double> inter2 = intervals[i + 1];
while (func[points[tmp]] < inter2.first && tmp != n) {
- prop[points[tmp]] = adjacency_matrix[points[tmp]];
+ preimages[i].push_back(points[tmp]);
tmp++;
}
-
+ v = inter2.first;
pos = tmp;
while (func[points[tmp]] < inter1.second && tmp != n) {
- prop[points[tmp]] = adjacency_matrix[points[tmp]];
+ preimages[i].push_back(points[tmp]);
tmp++;
}
} else {
std::pair<double, double> inter3 = intervals[i - 1];
while (func[points[tmp]] < inter3.second && tmp != n) {
- prop[points[tmp]] = adjacency_matrix[points[tmp]];
+ preimages[i].push_back(points[tmp]);
tmp++;
}
-
while (tmp != n) {
- prop[points[tmp]] = adjacency_matrix[points[tmp]];
+ preimages[i].push_back(points[tmp]);
tmp++;
}
+ u = inter3.second;
+ v = inter1.second;
}
- // Compute the connected components with DFS
- std::map<int, bool> visit;
- if (verbose) std::cout << "Preimage of interval " << i << std::endl;
- for (std::map<int, std::vector<int> >::iterator it = prop.begin(); it != prop.end(); it++)
- visit[it->first] = false;
- if (!(prop.empty())) {
- for (std::map<int, std::vector<int> >::iterator it = prop.begin(); it != prop.end(); it++) {
- if (!(visit[it->first])) {
- std::vector<int> cc;
- cc.clear();
- dfs(prop, it->first, cc, visit);
- int cci = cc.size();
- if (verbose) std::cout << "one CC with " << cci << " points, ";
- double average_col = 0;
- for (int j = 0; j < cci; j++) {
- cover[cc[j]].push_back(id);
- cover_back[id].push_back(cc[j]);
- average_col += func_color[cc[j]] / cci;
- }
- cover_fct[id] = i;
- cover_color[id] = std::pair<int, double>(cci, average_col);
- id++;
- }
- }
+ funcstd[i] = 0.5 * (u + v);
+ }
+
+ if (verbose) std::cout << "Computing connected components..." << std::endl;
+ // #pragma omp parallel for
+ for (int i = 0; i < res; i++) {
+ // Compute connected components
+ Graph G = one_skeleton.create_subgraph();
+ int num = preimages[i].size();
+ std::vector<int> component(num);
+ for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G);
+ boost::connected_components(G, &component[0]);
+ int max = 0;
+
+ // For each point in preimage
+ for (int j = 0; j < num; j++) {
+ // Update number of components in preimage
+ if (component[j] > max) max = component[j];
+
+ // Identify component with Cantor polynomial N^2 -> N
+ int identifier = (std::pow(i + component[j], 2) + 3 * i + component[j]) / 2;
+
+ // Update covers
+ cover[preimages[i][j]].push_back(identifier);
+ cover_back[identifier].push_back(preimages[i][j]);
+ cover_fct[identifier] = i;
+ cover_std[identifier] = funcstd[i];
+ cover_color[identifier].second += func_color[preimages[i][j]];
+ cover_color[identifier].first += 1;
}
- if (verbose) std::cout << std::endl;
+
+ // Maximal dimension is total number of connected components
+ id += max + 1;
}
maximal_dim = id - 1;
+ for (std::map<int, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++)
+ iit->second.second /= iit->second.first;
}
public: // Set cover from file.
@@ -730,9 +755,9 @@ class Cover_complex {
*
*/
void set_cover_from_file(const std::string& cover_file_name) {
- int vertex_id = 0;
- Cover_t cov;
- std::vector<Cover_t> cov_elts, cov_number;
+ int i = 0;
+ int cov;
+ std::vector<int> cov_elts, cov_number;
std::ifstream input(cover_file_name);
std::string line;
while (std::getline(input, line)) {
@@ -742,17 +767,18 @@ class Cover_complex {
cov_elts.push_back(cov);
cov_number.push_back(cov);
cover_fct[cov] = cov;
- cover_color[cov].second += func_color[vertex_id];
+ cover_color[cov].second += func_color[i];
cover_color[cov].first++;
- cover_back[cov].push_back(vertex_id);
+ cover_back[cov].push_back(i);
}
- cover[vertex_id] = cov_elts;
- vertex_id++;
+ cover[i] = cov_elts;
+ i++;
}
- std::vector<Cover_t>::iterator it;
+
std::sort(cov_number.begin(), cov_number.end());
- it = std::unique(cov_number.begin(), cov_number.end());
+ std::vector<int>::iterator it = std::unique(cov_number.begin(), cov_number.end());
cov_number.resize(std::distance(cov_number.begin(), it));
+
maximal_dim = cov_number.size() - 1;
for (int i = 0; i <= maximal_dim; i++) cover_color[i].second /= cover_color[i].first;
cover_name = cover_file_name;
@@ -770,52 +796,25 @@ class Cover_complex {
voronoi_subsamples.resize(m);
SampleWithoutReplacement(n, m, voronoi_subsamples);
if (distances.size() == 0) compute_pairwise_distances(distance);
+ set_graph_weights();
+ Weight_map weight = boost::get(boost::edge_weight, one_skeleton);
+ Index_map index = boost::get(boost::vertex_index, one_skeleton);
std::vector<double> mindist(n);
for (int j = 0; j < n; j++) mindist[j] = std::numeric_limits<double>::max();
// Compute the geodesic distances to subsamples with Dijkstra
+ // #pragma omp parallel for
for (int i = 0; i < m; i++) {
if (verbose) std::cout << "Computing geodesic distances to seed " << i << "..." << std::endl;
int seed = voronoi_subsamples[i];
- std::vector<double> dist(n);
- std::vector<int> process(n);
- for (int j = 0; j < n; j++) {
- dist[j] = std::numeric_limits<double>::max();
- process[j] = j;
- }
- dist[seed] = 0;
- int curr_size = process.size();
- int min_point, min_index;
- double min_dist;
- std::vector<int> neighbors;
- int num_neighbors;
-
- while (curr_size > 0) {
- min_dist = std::numeric_limits<double>::max();
- min_index = -1;
- min_point = -1;
- for (int j = 0; j < curr_size; j++) {
- if (dist[process[j]] < min_dist) {
- min_point = process[j];
- min_dist = dist[process[j]];
- min_index = j;
- }
- }
- assert(min_index != -1);
- process.erase(process.begin() + min_index);
- assert(min_point != -1);
- neighbors = adjacency_matrix[min_point];
- num_neighbors = neighbors.size();
- for (int j = 0; j < num_neighbors; j++) {
- double d = dist[min_point] + distances[min_point][neighbors[j]];
- dist[neighbors[j]] = std::min(dist[neighbors[j]], d);
- }
- curr_size = process.size();
- }
+ std::vector<double> dmap(n);
+ boost::dijkstra_shortest_paths(
+ one_skeleton, vertices[seed],
+ boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index)));
for (int j = 0; j < n; j++)
- if (mindist[j] > dist[j]) {
- mindist[j] = dist[j];
+ if (mindist[j] > dmap[j]) {
+ mindist[j] = dmap[j];
if (cover[j].size() == 0)
cover[j].push_back(i);
else
@@ -840,7 +839,7 @@ class Cover_complex {
* @result cover_back(c) vector of IDs of data points.
*
*/
- const std::vector<int>& subpopulation(Cover_t c) { return cover_back[c]; }
+ const std::vector<int>& subpopulation(int c) { return cover_back[name2idinv[c]]; }
// *******************************************************************************************************************
// Visualization.
@@ -854,15 +853,15 @@ class Cover_complex {
*
*/
void set_color_from_file(const std::string& color_file_name) {
- int vertex_id = 0;
+ int i = 0;
std::ifstream input(color_file_name);
std::string line;
double f;
while (std::getline(input, line)) {
std::stringstream stream(line);
stream >> f;
- func_color.emplace(vertex_id, f);
- vertex_id++;
+ func_color.emplace(i, f);
+ i++;
}
color_name = color_file_name;
}
@@ -874,7 +873,7 @@ class Cover_complex {
*
*/
void set_color_from_coordinate(int k = 0) {
- for (int i = 0; i < n; i++) func_color.emplace(i, point_cloud[i][k]);
+ for (int i = 0; i < n; i++) func_color[i] = point_cloud[i][k];
color_name = "coordinate ";
color_name.append(std::to_string(k));
}
@@ -886,7 +885,7 @@ class Cover_complex {
*
*/
void set_color_from_vector(std::vector<double> color) {
- for (unsigned int i = 0; i < color.size(); i++) func_color.emplace(i, color[i]);
+ for (unsigned int i = 0; i < color.size(); i++) func_color[i] = color[i];
}
public: // Create a .dot file that can be compiled with neato to produce a .pdf file.
@@ -895,26 +894,30 @@ class Cover_complex {
* of its 1-skeleton in a .pdf file.
*/
void plot_DOT() {
- char mapp[11] = "SC.dot";
+ std::string mapp = point_cloud_name + "_sc.dot";
std::ofstream graphic(mapp);
- graphic << "graph GIC {" << std::endl;
- double maxv, minv;
- maxv = std::numeric_limits<double>::min();
- minv = std::numeric_limits<double>::max();
- for (std::map<Cover_t, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end();
- iit++) {
+
+ double maxv = std::numeric_limits<double>::lowest();
+ double minv = std::numeric_limits<double>::max();
+ for (std::map<int, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++) {
maxv = std::max(maxv, iit->second.second);
minv = std::min(minv, iit->second.second);
}
+
int k = 0;
std::vector<int> nodes;
nodes.clear();
- for (std::map<Cover_t, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end();
- iit++) {
+
+ graphic << "graph GIC {" << std::endl;
+ int id = 0;
+ for (std::map<int, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++) {
if (iit->second.first > mask) {
nodes.push_back(iit->first);
- graphic << iit->first << "[shape=circle fontcolor=black color=black label=\"" << iit->first << ":"
- << iit->second.first << "\" style=filled fillcolor=\""
+ name2id[iit->first] = id;
+ name2idinv[id] = iit->first;
+ id++;
+ graphic << name2id[iit->first] << "[shape=circle fontcolor=black color=black label=\"" << name2id[iit->first]
+ << ":" << iit->second.first << "\" style=filled fillcolor=\""
<< (1 - (maxv - iit->second.second) / (maxv - minv)) * 0.6 << ", 1, 1\"]" << std::endl;
k++;
}
@@ -924,13 +927,14 @@ class Cover_complex {
for (int i = 0; i < num_simplices; i++)
if (simplices[i].size() == 2) {
if (cover_color[simplices[i][0]].first > mask && cover_color[simplices[i][1]].first > mask) {
- graphic << " " << simplices[i][0] << " -- " << simplices[i][1] << " [weight=15];" << std::endl;
+ graphic << " " << name2id[simplices[i][0]] << " -- " << name2id[simplices[i][1]] << " [weight=15];"
+ << std::endl;
ke++;
}
}
graphic << "}";
graphic.close();
- std::cout << "SC.dot generated. It can be visualized with e.g. neato." << std::endl;
+ std::cout << mapp << " file generated. It can be visualized with e.g. neato." << std::endl;
}
public: // Create a .txt file that can be compiled with KeplerMapper.
@@ -940,8 +944,9 @@ class Cover_complex {
void write_info() {
int num_simplices = simplices.size();
int num_edges = 0;
- char mapp[11] = "SC.txt";
+ std::string mapp = point_cloud_name + "_sc.txt";
std::ofstream graphic(mapp);
+
for (int i = 0; i < num_simplices; i++)
if (simplices[i].size() == 2)
if (cover_color[simplices[i][0]].first > mask && cover_color[simplices[i][1]].first > mask) num_edges++;
@@ -952,16 +957,21 @@ class Cover_complex {
graphic << resolution_double << " " << gain << std::endl;
graphic << cover_color.size() << " " << num_edges << std::endl;
- for (std::map<Cover_t, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end();
- iit++)
- graphic << iit->first << " " << iit->second.second << " " << iit->second.first << std::endl;
+ int id = 0;
+ for (std::map<int, std::pair<int, double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++) {
+ graphic << id << " " << iit->second.second << " " << iit->second.first << std::endl;
+ name2id[iit->first] = id;
+ name2idinv[id] = iit->first;
+ id++;
+ }
for (int i = 0; i < num_simplices; i++)
if (simplices[i].size() == 2)
if (cover_color[simplices[i][0]].first > mask && cover_color[simplices[i][1]].first > mask)
- graphic << simplices[i][0] << " " << simplices[i][1] << std::endl;
+ graphic << name2id[simplices[i][0]] << " " << name2id[simplices[i][1]] << std::endl;
graphic.close();
- std::cout << "SC.txt generated. It can be visualized with e.g. python KeplerMapperVisuFromTxtFile.py and firefox."
+ std::cout << mapp
+ << " generated. It can be visualized with e.g. python KeplerMapperVisuFromTxtFile.py and firefox."
<< std::endl;
}
@@ -972,14 +982,17 @@ class Cover_complex {
*/
void plot_OFF() {
assert(cover_name == "Voronoi");
- char gic[11] = "SC.off";
- std::ofstream graphic(gic);
- graphic << "OFF" << std::endl;
+
int m = voronoi_subsamples.size();
int numedges = 0;
int numfaces = 0;
std::vector<std::vector<int> > edges, faces;
int numsimplices = simplices.size();
+
+ std::string mapp = point_cloud_name + "_sc.off";
+ std::ofstream graphic(mapp);
+
+ graphic << "OFF" << std::endl;
for (int i = 0; i < numsimplices; i++) {
if (simplices[i].size() == 2) {
numedges++;
@@ -1004,26 +1017,183 @@ class Cover_complex {
for (int i = 0; i < numfaces; i++)
graphic << 3 << " " << faces[i][0] << " " << faces[i][1] << " " << faces[i][2] << std::endl;
graphic.close();
- std::cout << "SC.off generated. It can be visualized with e.g. geomview." << std::endl;
+ std::cout << mapp << " generated. It can be visualized with e.g. geomview." << std::endl;
}
// *******************************************************************************************************************
+ // Extended Persistence Diagrams.
+ // *******************************************************************************************************************
+
+ public:
+ /** \brief Computes the extended persistence diagram of the complex.
+ *
+ */
+ void compute_PD() {
+ Simplex_tree st;
+
+ // Compute max and min
+ double maxf = std::numeric_limits<double>::lowest();
+ double minf = std::numeric_limits<double>::max();
+ for (std::map<int, double>::iterator it = cover_std.begin(); it != cover_std.end(); it++) {
+ maxf = std::max(maxf, it->second);
+ minf = std::min(minf, it->second);
+ }
+
+ for (auto const& simplex : simplices) {
+ // Add a simplex and a cone on it
+ std::vector<int> splx = simplex;
+ splx.push_back(-2);
+ st.insert_simplex_and_subfaces(splx);
+ }
+
+ // Build filtration
+ for (auto simplex : st.complex_simplex_range()) {
+ double filta = std::numeric_limits<double>::lowest();
+ double filts = filta;
+ bool ascending = true;
+ for (auto vertex : st.simplex_vertex_range(simplex)) {
+ if (vertex == -2) {
+ ascending = false;
+ continue;
+ }
+ filta = std::max(-2 + (cover_std[vertex] - minf) / (maxf - minf), filta);
+ filts = std::max(2 - (cover_std[vertex] - minf) / (maxf - minf), filts);
+ }
+ if (ascending)
+ st.assign_filtration(simplex, filta);
+ else
+ st.assign_filtration(simplex, filts);
+ }
+ int magic[] = {-2};
+ st.assign_filtration(st.find(magic), -3);
+
+ // Compute PD
+ st.initialize_filtration();
+ Gudhi::persistent_cohomology::Persistent_cohomology<Simplex_tree, Gudhi::persistent_cohomology::Field_Zp> pcoh(st);
+ pcoh.init_coefficients(2);
+ pcoh.compute_persistent_cohomology();
+
+ // Output PD
+ int max_dim = st.dimension();
+ for (int i = 0; i < max_dim; i++) {
+ std::vector<std::pair<double, double> > bars = pcoh.intervals_in_dimension(i);
+ int num_bars = bars.size();
+ if(verbose) std::cout << num_bars << " interval(s) in dimension " << i << ":" << std::endl;
+ for (int j = 0; j < num_bars; j++) {
+ double birth = bars[j].first;
+ double death = bars[j].second;
+ if (i == 0 && std::isinf(death)) continue;
+ if (birth < 0)
+ birth = minf + (birth + 2) * (maxf - minf);
+ else
+ birth = minf + (2 - birth) * (maxf - minf);
+ if (death < 0)
+ death = minf + (death + 2) * (maxf - minf);
+ else
+ death = minf + (2 - death) * (maxf - minf);
+ PD.push_back(std::pair<double, double>(birth, death));
+ if (verbose) std::cout << " [" << birth << ", " << death << "]" << std::endl;
+ }
+ }
+ }
+
+ public:
+ /** \brief Computes bootstrapped distances distribution.
+ *
+ * @param[in] N number of bootstrap iterations.
+ *
+ */
+ template <typename SimplicialComplex>
+ void compute_distribution(int N = 100) {
+ if (distribution.size() >= N) {
+ std::cout << "Already done!" << std::endl;
+ } else {
+ for (int i = 0; i < N - distribution.size(); i++) {
+ Cover_complex Cboot;
+ Cboot.n = this->n;
+ std::vector<int> boot(this->n);
+ for (int j = 0; j < this->n; j++) {
+ double u = GetUniform();
+ int id = std::floor(u * (this->n));
+ boot[j] = id;
+ Cboot.point_cloud[j] = this->point_cloud[id];
+ Cboot.func.emplace(j, this->func[id]);
+ }
+ for (int j = 0; j < n; j++) {
+ std::vector<double> dist(n);
+ for (int k = 0; k < n; k++) dist[k] = distances[boot[j]][boot[k]];
+ Cboot.distances.push_back(dist);
+ }
+
+ Cboot.set_graph_from_automatic_rips(Gudhi::Euclidean_distance());
+ Cboot.set_automatic_resolution();
+ Cboot.set_gain();
+ Cboot.set_cover_from_function();
+ Cboot.find_simplices();
+ Cboot.compute_PD();
+
+ distribution.push_back(Gudhi::persistence_diagram::bottleneck_distance(this->PD, Cboot.PD));
+ }
+
+ std::sort(distribution.begin(), distribution.end());
+ }
+ }
+
+ public:
+ /** \brief Computes the bottleneck distance threshold corresponding to a specific confidence level.
+ *
+ * @param[in] alpha Confidence level.
+ *
+ */
+ double compute_distance_from_confidence_level(double alpha) {
+ int N = distribution.size();
+ return distribution[std::floor(alpha * N)];
+ }
+
+ public:
+ /** \brief Computes the confidence level of a specific bottleneck distance threshold.
+ *
+ * @param[in] d Bottleneck distance.
+ *
+ */
+ double compute_confidence_level_from_distance(double d) {
+ int N = distribution.size();
+ for (int i = 0; i < N; i++)
+ if (distribution[i] > d) return i * 1.0 / N;
+ }
+
+ public:
+ /** \brief Computes the p-value, i.e. the opposite of the confidence level of the largest bottleneck
+ * distance preserving the points in the persistence diagram of the output simplicial complex.
+ *
+ */
+ double compute_p_value() {
+ double distancemin = -std::numeric_limits<double>::lowest();
+ int N = PD.size();
+ for (int i = 0; i < N; i++) distancemin = std::min(distancemin, 0.5 * (PD[i].second - PD[i].first));
+ return 1 - compute_confidence_level_from_distance(distancemin);
+ }
+
+ // *******************************************************************************************************************
+ // Computation of simplices.
// *******************************************************************************************************************
public:
/** \brief Creates the simplicial complex.
*
- * @param[in] complex SimplicialComplexForRips to be created.
+ * @param[in] complex SimplicialComplex to be created.
*
*/
- template <typename SimplicialComplexForRips>
- void create_complex(SimplicialComplexForRips& complex) {
+ template <typename SimplicialComplex>
+ void create_complex(SimplicialComplex& complex) {
unsigned int dimension = 0;
for (auto const& simplex : simplices) {
- complex.insert_simplex_and_subfaces(simplex);
+ int numvert = simplex.size();
+ double filt = std::numeric_limits<double>::lowest();
+ for (int i = 0; i < numvert; i++) filt = std::max(cover_color[simplex[i]].second, filt);
+ complex.insert_simplex_and_subfaces(simplex, filt);
if (dimension < simplex.size() - 1) dimension = simplex.size() - 1;
}
- complex.set_dimension(dimension);
}
public:
@@ -1036,15 +1206,16 @@ class Cover_complex {
}
if (type == "Nerve") {
- for (std::map<int, std::vector<Cover_t> >::iterator it = cover.begin(); it != cover.end(); it++)
- simplices.push_back(it->second);
- std::vector<std::vector<Cover_t> >::iterator it;
+ for(auto& simplex : cover)
+ simplices.push_back(simplex.second);
std::sort(simplices.begin(), simplices.end());
- it = std::unique(simplices.begin(), simplices.end());
+ std::vector<std::vector<int> >::iterator it = std::unique(simplices.begin(), simplices.end());
simplices.resize(std::distance(simplices.begin(), it));
}
if (type == "GIC") {
+ Index_map index = boost::get(boost::vertex_index, one_skeleton);
+
if (functional_cover) {
// Computes the simplices in the GIC by looking at all the edges of the graph and adding the
// corresponding edges in the GIC if the images of the endpoints belong to consecutive intervals.
@@ -1053,81 +1224,44 @@ class Cover_complex {
throw std::invalid_argument(
"the output of this function is correct ONLY if the cover is minimal, i.e. the gain is less than 0.5.");
- int v1, v2;
-
- // Loop on all points.
- for (std::map<int, std::vector<Cover_t> >::iterator it = cover.begin(); it != cover.end(); it++) {
- int vid = it->first;
- std::vector<int> neighbors = adjacency_matrix[vid];
- int num_neighb = neighbors.size();
-
- // Find cover of current point (vid).
- if (cover[vid].size() == 2)
- v1 = std::min(cover[vid][0], cover[vid][1]);
- else
- v1 = cover[vid][0];
- std::vector<int> node(1);
- node[0] = v1;
- simplices.push_back(node);
-
- // Loop on neighbors.
- for (int i = 0; i < num_neighb; i++) {
- int neighb = neighbors[i];
-
- // Find cover of neighbor (neighb).
- if (cover[neighb].size() == 2)
- v2 = std::max(cover[neighb][0], cover[neighb][1]);
- else
- v2 = cover[neighb][0];
-
- // If neighbor is in next interval, add edge.
- if (cover_fct[v2] == cover_fct[v1] + 1) {
- std::vector<int> edge(2);
- edge[0] = v1;
- edge[1] = v2;
- simplices.push_back(edge);
+ // Loop on all edges.
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = boost::edges(one_skeleton); ei != ei_end; ++ei) {
+ int nums = cover[index[boost::source(*ei, one_skeleton)]].size();
+ for (int i = 0; i < nums; i++) {
+ int vs = cover[index[boost::source(*ei, one_skeleton)]][i];
+ int numt = cover[index[boost::target(*ei, one_skeleton)]].size();
+ for (int j = 0; j < numt; j++) {
+ int vt = cover[index[boost::target(*ei, one_skeleton)]][j];
+ if (cover_fct[vs] == cover_fct[vt] + 1 || cover_fct[vt] == cover_fct[vs] + 1) {
+ std::vector<int> edge(2);
+ edge[0] = std::min(vs, vt);
+ edge[1] = std::max(vs, vt);
+ simplices.push_back(edge);
+ goto afterLoop;
+ }
}
}
+ afterLoop:;
}
- std::vector<std::vector<Cover_t> >::iterator it;
std::sort(simplices.begin(), simplices.end());
- it = std::unique(simplices.begin(), simplices.end());
+ std::vector<std::vector<int> >::iterator it = std::unique(simplices.begin(), simplices.end());
simplices.resize(std::distance(simplices.begin(), it));
} else {
- // Find IDs of edges to remove
- std::vector<int> simplex_to_remove;
- int simplex_id = 0;
- for (auto simplex : st.complex_simplex_range()) {
- if (st.dimension(simplex) == 1) {
- std::vector<std::vector<Cover_t> > comp;
- for (auto vertex : st.simplex_vertex_range(simplex)) comp.push_back(cover[vertex]);
- if (comp[0].size() == 1 && comp[0] == comp[1]) simplex_to_remove.push_back(simplex_id);
+ // Find edges to keep
+ Simplex_tree st;
+ boost::graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = boost::edges(one_skeleton); ei != ei_end; ++ei)
+ if (!(cover[index[boost::target(*ei, one_skeleton)]].size() == 1 &&
+ cover[index[boost::target(*ei, one_skeleton)]] == cover[index[boost::source(*ei, one_skeleton)]])) {
+ std::vector<int> edge(2);
+ edge[0] = index[boost::source(*ei, one_skeleton)];
+ edge[1] = index[boost::target(*ei, one_skeleton)];
+ st.insert_simplex_and_subfaces(edge);
}
- simplex_id++;
- }
- // Remove edges
- if (simplex_to_remove.size() > 1) {
- int current_id = 1;
- auto simplex = st.complex_simplex_range().begin();
- int num_rem = 0;
- for (int i = 0; i < simplex_id - 1; i++) {
- int j = i + 1;
- auto simplex_tmp = simplex;
- simplex_tmp++;
- if (j == simplex_to_remove[current_id]) {
- st.remove_maximal_simplex(*simplex_tmp);
- current_id++;
- num_rem++;
- } else {
- simplex++;
- }
- }
- simplex = st.complex_simplex_range().begin();
- for (int i = 0; i < simplex_to_remove[0]; i++) simplex++;
- st.remove_maximal_simplex(*simplex);
- }
+ // st.insert_graph(one_skeleton);
// Build the Simplex Tree corresponding to the graph
st.expansion(maximal_dim);
@@ -1136,23 +1270,21 @@ class Cover_complex {
simplices.clear();
for (auto simplex : st.complex_simplex_range()) {
if (!st.has_children(simplex)) {
- std::vector<Cover_t> simplx;
+ std::vector<int> simplx;
for (auto vertex : st.simplex_vertex_range(simplex)) {
unsigned int sz = cover[vertex].size();
for (unsigned int i = 0; i < sz; i++) {
simplx.push_back(cover[vertex][i]);
}
}
-
std::sort(simplx.begin(), simplx.end());
- std::vector<Cover_t>::iterator it = std::unique(simplx.begin(), simplx.end());
+ std::vector<int>::iterator it = std::unique(simplx.begin(), simplx.end());
simplx.resize(std::distance(simplx.begin(), it));
simplices.push_back(simplx);
}
}
- std::vector<std::vector<Cover_t> >::iterator it;
std::sort(simplices.begin(), simplices.end());
- it = std::unique(simplices.begin(), simplices.end());
+ std::vector<std::vector<int> >::iterator it = std::unique(simplices.begin(), simplices.end());
simplices.resize(std::distance(simplices.begin(), it));
}
}
diff --git a/src/Nerve_GIC/test/CMakeLists.txt b/src/Nerve_GIC/test/CMakeLists.txt
index 03fe47ca..c35cdff7 100644
--- a/src/Nerve_GIC/test/CMakeLists.txt
+++ b/src/Nerve_GIC/test/CMakeLists.txt
@@ -1,14 +1,17 @@
cmake_minimum_required(VERSION 2.6)
project(Graph_induced_complex_tests)
-include(GUDHI_test_coverage)
+if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
+ include(GUDHI_test_coverage)
-add_executable ( Nerve_GIC_test_unit test_GIC.cpp )
-target_link_libraries(Nerve_GIC_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
-if (TBB_FOUND)
- target_link_libraries(Nerve_GIC_test_unit ${TBB_LIBRARIES})
-endif()
+ add_executable ( Nerve_GIC_test_unit test_GIC.cpp )
+ target_link_libraries(Nerve_GIC_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ if (TBB_FOUND)
+ target_link_libraries(Nerve_GIC_test_unit ${TBB_LIBRARIES})
+ endif()
-file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
-gudhi_add_coverage_test(Nerve_GIC_test_unit)
+ gudhi_add_coverage_test(Nerve_GIC_test_unit)
+
+endif (NOT CGAL_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Nerve_GIC/test/test_GIC.cpp b/src/Nerve_GIC/test/test_GIC.cpp
index a8b1e7f7..d633753c 100644
--- a/src/Nerve_GIC/test/test_GIC.cpp
+++ b/src/Nerve_GIC/test/test_GIC.cpp
@@ -24,11 +24,11 @@
#define BOOST_TEST_MODULE "graph_induced_complex"
#include <boost/test/unit_test.hpp>
-#include <cmath> // float comparison
+
#include <limits>
#include <string>
#include <vector>
-#include <algorithm> // std::max
+
#include <gudhi/GIC.h>
#include <gudhi/distance_functions.h>
#include <gudhi/reader_utils.h>
diff --git a/src/Nerve_GIC/utilities/CMakeLists.txt b/src/Nerve_GIC/utilities/CMakeLists.txt
new file mode 100644
index 00000000..7a838a8c
--- /dev/null
+++ b/src/Nerve_GIC/utilities/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 2.6)
+project(Nerve_GIC_examples)
+
+if (NOT CGAL_VERSION VERSION_LESS 4.8.1)
+
+ add_executable ( Nerve Nerve.cpp )
+ add_executable ( VoronoiGIC VoronoiGIC.cpp )
+
+ if (TBB_FOUND)
+ target_link_libraries(Nerve ${TBB_LIBRARIES})
+ target_link_libraries(VoronoiGIC ${TBB_LIBRARIES})
+ endif()
+
+ file(COPY KeplerMapperVisuFromTxtFile.py km.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ # Copy files for not to pollute sources when testing
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/human.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+ add_test(NAME Nerve_GIC_utilities_nerve COMMAND $<TARGET_FILE:Nerve>
+ "human.off" "2" "10" "0.3")
+
+ add_test(NAME Nerve_GIC_utilities_VoronoiGIC COMMAND $<TARGET_FILE:VoronoiGIC>
+ "human.off" "100")
+
+ install(TARGETS Nerve DESTINATION bin)
+ install(TARGETS VoronoiGIC DESTINATION bin)
+ install(FILES KeplerMapperVisuFromTxtFile.py km.py km.py.COPYRIGHT DESTINATION bin)
+
+endif (NOT CGAL_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Nerve_GIC/utilities/KeplerMapperVisuFromTxtFile.py b/src/Nerve_GIC/utilities/KeplerMapperVisuFromTxtFile.py
new file mode 100755
index 00000000..c811f610
--- /dev/null
+++ b/src/Nerve_GIC/utilities/KeplerMapperVisuFromTxtFile.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+import km
+import numpy as np
+from collections import defaultdict
+import argparse
+
+"""This file is part of the Gudhi Library. The Gudhi library
+ (Geometric Understanding in Higher Dimensions) is a generic C++
+ library for computational topology.
+
+ Author(s): Mathieu Carriere
+
+ Copyright (C) 2017 INRIA
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+__author__ = "Mathieu Carriere"
+__copyright__ = "Copyright (C) 2017 INRIA"
+__license__ = "GPL v3"
+
+parser = argparse.ArgumentParser(description='Creates an html Keppler Mapper '
+ 'file to visualize a SC.txt file.',
+ epilog='Example: '
+ './KeplerMapperVisuFromTxtFile.py '
+ '-f ../../data/points/human.off_sc.txt'
+ '- Constructs an human.off_sc.html file.')
+parser.add_argument("-f", "--file", type=str, required=True)
+
+args = parser.parse_args()
+
+with open(args.file, 'r') as f:
+ network = {}
+ mapper = km.KeplerMapper(verbose=0)
+ data = np.zeros((3,3))
+ projected_data = mapper.fit_transform( data, projection="sum", scaler=None )
+
+ nodes = defaultdict(list)
+ links = defaultdict(list)
+ custom = defaultdict(list)
+
+ dat = f.readline()
+ lens = f.readline()
+ color = f.readline();
+ param = [float(i) for i in f.readline().split(" ")]
+
+ nums = [int(i) for i in f.readline().split(" ")]
+ num_nodes = nums[0]
+ num_edges = nums[1]
+
+ for i in range(0,num_nodes):
+ point = [float(j) for j in f.readline().split(" ")]
+ nodes[ str(int(point[0])) ] = [ int(point[0]), point[1], int(point[2]) ]
+ links[ str(int(point[0])) ] = []
+ custom[ int(point[0]) ] = point[1]
+
+ m = min([custom[i] for i in range(0,num_nodes)])
+ M = max([custom[i] for i in range(0,num_nodes)])
+
+ for i in range(0,num_edges):
+ edge = [int(j) for j in f.readline().split(" ")]
+ links[ str(edge[0]) ].append( str(edge[1]) )
+ links[ str(edge[1]) ].append( str(edge[0]) )
+
+ network["nodes"] = nodes
+ network["links"] = links
+ network["meta"] = lens
+
+ html_output_filename = args.file.rsplit('.', 1)[0] + '.html'
+ mapper.visualize(network, color_function = color, path_html=html_output_filename, title=dat,
+ graph_link_distance=30, graph_gravity=0.1, graph_charge=-120, custom_tooltips=custom, width_html=0,
+ height_html=0, show_tooltips=True, show_title=True, show_meta=True, res=param[0],gain=param[1], minimum=m,maximum=M)
+ message = repr(html_output_filename) + " is generated. You can now use your favorite web browser to visualize it."
+ print(message)
+
+
+ f.close()
diff --git a/src/Nerve_GIC/example/Nerve.cpp b/src/Nerve_GIC/utilities/Nerve.cpp
index 4d5b009b..aefc3874 100644
--- a/src/Nerve_GIC/example/Nerve.cpp
+++ b/src/Nerve_GIC/utilities/Nerve.cpp
@@ -27,8 +27,8 @@
void usage(int nbArgs, char *const progName) {
std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
- std::cerr << "Usage: " << progName << " filename.off coordinate resolution gain [--v] \n";
- std::cerr << " i.e.: " << progName << " ../../data/points/human.off 2 10 0.3 --v \n";
+ std::cerr << "Usage: " << progName << " filename.off coordinate resolution gain [-v] \n";
+ std::cerr << " i.e.: " << progName << " ../../data/points/human.off 2 10 0.3 -v \n";
exit(-1); // ----- >>
}
@@ -72,6 +72,7 @@ int main(int argc, char **argv) {
Gudhi::Simplex_tree<> stree;
SC.create_complex(stree);
+ SC.compute_PD();
// ----------------------------------------------------------------------------
// Display information about the graph induced complex
diff --git a/src/Nerve_GIC/utilities/Nerve.txt b/src/Nerve_GIC/utilities/Nerve.txt
new file mode 100644
index 00000000..839ff45e
--- /dev/null
+++ b/src/Nerve_GIC/utilities/Nerve.txt
@@ -0,0 +1,63 @@
+Min function value = -0.979672 and Max function value = 0.816414
+Interval 0 = [-0.979672, -0.761576]
+Interval 1 = [-0.838551, -0.581967]
+Interval 2 = [-0.658942, -0.402359]
+Interval 3 = [-0.479334, -0.22275]
+Interval 4 = [-0.299725, -0.0431415]
+Interval 5 = [-0.120117, 0.136467]
+Interval 6 = [0.059492, 0.316076]
+Interval 7 = [0.239101, 0.495684]
+Interval 8 = [0.418709, 0.675293]
+Interval 9 = [0.598318, 0.816414]
+Computing preimages...
+Computing connected components...
+.txt generated. It can be visualized with e.g. python KeplerMapperVisuFromTxtFile.py and firefox.
+5 interval(s) in dimension 0:
+ [-0.909111, 0.00817529]
+ [-0.171433, 0.367392]
+ [-0.171433, 0.367392]
+ [-0.909111, 0.745853]
+0 interval(s) in dimension 1:
+Nerve is of dimension 1 - 41 simplices - 21 vertices.
+Iterator on Nerve simplices
+1
+0
+4
+4 0
+2
+2 1
+8
+8 2
+5
+5 4
+9
+9 8
+13
+13 5
+14
+14 9
+19
+19 13
+25
+32
+20
+32 20
+33
+33 25
+26
+26 14
+26 19
+42
+42 26
+34
+34 33
+27
+27 20
+35
+35 27
+35 34
+42 35
+44
+44 35
+54
+54 44 \ No newline at end of file
diff --git a/src/Nerve_GIC/example/VoronoiGIC.cpp b/src/Nerve_GIC/utilities/VoronoiGIC.cpp
index 32431cc2..54bb871e 100644
--- a/src/Nerve_GIC/example/VoronoiGIC.cpp
+++ b/src/Nerve_GIC/utilities/VoronoiGIC.cpp
@@ -27,8 +27,8 @@
void usage(int nbArgs, char *const progName) {
std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
- std::cerr << "Usage: " << progName << " filename.off N [--v] \n";
- std::cerr << " i.e.: " << progName << " ../../data/points/human.off 100 --v \n";
+ std::cerr << "Usage: " << progName << " filename.off N [-v] \n";
+ std::cerr << " i.e.: " << progName << " ../../data/points/human.off 100 -v \n";
exit(-1); // ----- >>
}
diff --git a/src/Nerve_GIC/utilities/covercomplex.md b/src/Nerve_GIC/utilities/covercomplex.md
new file mode 100644
index 00000000..f33cb2e0
--- /dev/null
+++ b/src/Nerve_GIC/utilities/covercomplex.md
@@ -0,0 +1,62 @@
+
+
+# Cover complex #
+
+
+## Nerve ##
+This program builds the Nerve of a point cloud sampled on an OFF file.
+The cover C comes from the preimages of intervals covering a coordinate function,
+which are then refined into their connected components using the triangulation of the .OFF file.
+
+The program also writes a file SC.txt.
+The first three lines in this file are the location of the input point cloud and the function used to compute the cover.
+The fourth line contains the number of vertices nv and edges ne of the Nerve. The next nv lines represent the vertices.
+Each line contains the vertex ID, the number of data points it contains, and their average color function value.
+Finally, the next ne lines represent the edges, characterized by the ID of their vertices.
+
+**Usage**
+
+`Nerve <OFF input file> coordinate resolution gain [-v]`
+
+where
+
+* `coordinate` is the coordinate function to cover
+* `resolution` is the number of the intervals
+* `gain` is the gain for each interval
+* `-v` is optional, it activates verbose mode.
+
+**Example**
+
+`Nerve ../../data/points/human.off 2 10 0.3`
+
+* Builds the Nerve of a point cloud sampled on a 3D human shape (human.off).
+The cover C comes from the preimages of intervals (10 intervals with gain 0.3) covering the height function (coordinate 2).
+
+`python KeplerMapperVisuFromTxtFile.py -f ../../data/points/human.off_sc.txt`
+
+* Constructs `human.off_sc.html` file. You can now use your favorite web browser to visualize it.
+
+## VoronoiGIC ##
+
+This util builds the Graph Induced Complex (GIC) of a point cloud.
+It subsamples *N* points in the point cloud, which act as seeds of a geodesic Voronoï diagram.
+Each cell of the diagram is then an element of C.
+
+The program also writes a file `*_sc.off`, that is an OFF file that can be visualized with GeomView.
+
+**Usage**
+
+`VoroniGIC <OFF input file> samples_number [-v]`
+
+where
+
+* `samples_number` is the number of samples to take from the point cloud
+* `-v` is optional, it activates verbose mode.
+
+**Example**
+
+`VoroniGIC ../../data/points/human.off 700`
+
+* Builds the Voronoi Graph Induced Complex with 700 subsamples from `human.off` file.
+`../../data/points/human_sc.off` can be visualized with GeomView.
+
diff --git a/src/Nerve_GIC/example/km.py b/src/Nerve_GIC/utilities/km.py
index 53024aab..53024aab 100755
--- a/src/Nerve_GIC/example/km.py
+++ b/src/Nerve_GIC/utilities/km.py
diff --git a/src/Nerve_GIC/example/km.py.COPYRIGHT b/src/Nerve_GIC/utilities/km.py.COPYRIGHT
index bef7b121..bef7b121 100644
--- a/src/Nerve_GIC/example/km.py.COPYRIGHT
+++ b/src/Nerve_GIC/utilities/km.py.COPYRIGHT
diff --git a/src/Persistence_representations/doc/Persistence_representations_doc.h b/src/Persistence_representations/doc/Persistence_representations_doc.h
index c77e75e2..38bd3a21 100644
--- a/src/Persistence_representations/doc/Persistence_representations_doc.h
+++ b/src/Persistence_representations/doc/Persistence_representations_doc.h
@@ -67,7 +67,7 @@ namespace Persistence_representations {
\li Concept of representation of persistence that allows computations of distances.
\li Concept of representation of persistence that allows computations of scalar products.
\li Concept of representation of persistence that allows vectorization.
- \li Concept of representation of persistence that allows computations of real--valued characteristics of objects.
+ \li Concept of representation of persistence that allows computations of real-valued characteristics of objects.
At the moment an implementation of the following representations of persistence are available (further details of
@@ -83,8 +83,8 @@ namespace Persistence_representations {
\li Persistence vectors (allow averaging, computation of distances, scalar products, vectorizations and real value
characteristics).
\li Persistence diagrams / barcodes (allow computation of distances, vectorizations and real value characteristics).
-
-
+
+
Note that at the while functionalities like averaging, distances and scalar products are fixed, there is no canonical
way of vectorizing and computing real valued characteristics of objects. Therefore the
vectorizations and computation of real value characteristics procedures are quite likely to evolve in the furthering
@@ -139,7 +139,8 @@ namespace Persistence_representations {
possible ways to proceed:
\li Use non exact representation on a grid described in the Section \ref sec_landscapes_on_grid.
- \li Compute just a number of initial nonzero landscapes. This option is available from C++ level as a last parameter of the constructor of persistence landscape (set by default to std::numeric_limits<size_t>::max()).
+ \li Compute just a number of initial nonzero landscapes. This option is available from C++ level as a last parameter of
+ the constructor of persistence landscape (set by default to std::numeric_limits<size_t>::max()).
@@ -249,7 +250,6 @@ namespace Persistence_representations {
absolute value of differences between coordinates. A scalar product is a sum of products of
values at the corresponding positions of two vectors.
- \copyright GNU General Public License v3.
*/
/** @} */ // end defgroup Persistence_representations
diff --git a/src/Persistence_representations/example/CMakeLists.txt b/src/Persistence_representations/example/CMakeLists.txt
index 7788b603..54d719ac 100644
--- a/src/Persistence_representations/example/CMakeLists.txt
+++ b/src/Persistence_representations/example/CMakeLists.txt
@@ -1,34 +1,29 @@
cmake_minimum_required(VERSION 2.6)
project(Persistence_representations_example)
-file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/simple_diagram.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
-
add_executable ( Persistence_representations_example_landscape_on_grid persistence_landscape_on_grid.cpp )
-target_link_libraries(Persistence_representations_example_landscape_on_grid ${Boost_SYSTEM_LIBRARY})
add_test(NAME Persistence_representations_example_landscape_on_grid
COMMAND $<TARGET_FILE:Persistence_representations_example_landscape_on_grid>)
+install(TARGETS Persistence_representations_example_landscape_on_grid DESTINATION bin)
add_executable ( Persistence_representations_example_landscape persistence_landscape.cpp )
-target_link_libraries(Persistence_representations_example_landscape ${Boost_SYSTEM_LIBRARY})
add_test(NAME Persistence_representations_example_landscape
COMMAND $<TARGET_FILE:Persistence_representations_example_landscape>)
+install(TARGETS Persistence_representations_example_landscape DESTINATION bin)
add_executable ( Persistence_representations_example_intervals persistence_intervals.cpp )
-target_link_libraries(Persistence_representations_example_intervals ${Boost_SYSTEM_LIBRARY})
add_test(NAME Persistence_representations_example_intervals
COMMAND $<TARGET_FILE:Persistence_representations_example_intervals>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
+ "${CMAKE_SOURCE_DIR}/data/persistence_diagram/first.pers")
+install(TARGETS Persistence_representations_example_intervals DESTINATION bin)
add_executable ( Persistence_representations_example_vectors persistence_vectors.cpp )
-target_link_libraries(Persistence_representations_example_vectors ${Boost_SYSTEM_LIBRARY})
add_test(NAME Persistence_representations_example_vectors
COMMAND $<TARGET_FILE:Persistence_representations_example_vectors>)
+install(TARGETS Persistence_representations_example_vectors DESTINATION bin)
add_executable ( Persistence_representations_example_heat_maps persistence_heat_maps.cpp )
-target_link_libraries(Persistence_representations_example_heat_maps ${Boost_SYSTEM_LIBRARY})
add_test(NAME Persistence_representations_example_heat_maps
COMMAND $<TARGET_FILE:Persistence_representations_example_heat_maps>)
-
-
-
+install(TARGETS Persistence_representations_example_heat_maps DESTINATION bin)
diff --git a/src/Persistence_representations/example/persistence_vectors.cpp b/src/Persistence_representations/example/persistence_vectors.cpp
index 59eca152..834ae644 100644
--- a/src/Persistence_representations/example/persistence_vectors.cpp
+++ b/src/Persistence_representations/example/persistence_vectors.cpp
@@ -30,7 +30,7 @@
#include <utility>
using Vector_distances_in_diagram =
- Gudhi::Persistence_representations::Vector_distances_in_diagram<Gudhi::Euclidean_distance>;
+ Gudhi::Persistence_representations::Vector_distances_in_diagram<Gudhi::Euclidean_distance>;
int main(int argc, char** argv) {
// create two simple vectors with birth--death pairs:
diff --git a/src/Persistence_representations/example/persistence_weighted_gaussian.cpp b/src/Persistence_representations/example/persistence_weighted_gaussian.cpp
new file mode 100644
index 00000000..e95b9445
--- /dev/null
+++ b/src/Persistence_representations/example/persistence_weighted_gaussian.cpp
@@ -0,0 +1,96 @@
+/* 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): Mathieu Carriere
+ *
+ * Copyright (C) 2018 INRIA (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/Persistence_weighted_gaussian.h>
+
+#include <iostream>
+#include <vector>
+#include <utility>
+
+using PD = std::vector<std::pair<double,double> >;
+using PWG = Gudhi::Persistence_representations::Persistence_weighted_gaussian;
+
+int main(int argc, char** argv) {
+
+ std::vector<std::pair<double, double> > persistence1;
+ std::vector<std::pair<double, double> > persistence2;
+
+ persistence1.push_back(std::make_pair(1, 2));
+ persistence1.push_back(std::make_pair(6, 8));
+ persistence1.push_back(std::make_pair(0, 4));
+ persistence1.push_back(std::make_pair(3, 8));
+
+ persistence2.push_back(std::make_pair(2, 9));
+ persistence2.push_back(std::make_pair(1, 6));
+ persistence2.push_back(std::make_pair(3, 5));
+ persistence2.push_back(std::make_pair(6, 10));
+
+ PWG PWG1(persistence1);
+ PWG PWG2(persistence2);
+ double sigma = 1;
+ double tau = 1;
+ int m = 1000;
+
+
+
+ // Linear PWG
+
+ std::cout << PWG1.compute_scalar_product (PWG2, sigma, PWG::arctan_weight, m) << std::endl;
+ std::cout << PWG1.compute_scalar_product (PWG2, sigma, PWG::arctan_weight, -1) << std::endl;
+
+ std::cout << PWG1.distance (PWG2, sigma, PWG::arctan_weight, m) << std::endl;
+ std::cout << PWG1.distance (PWG2, sigma, PWG::arctan_weight, -1) << std::endl;
+
+
+
+
+
+
+
+ // Gaussian PWG
+
+ std::cout << std::exp( -PWG1.distance (PWG2, sigma, PWG::arctan_weight, m, 2) ) / (2*tau*tau) << std::endl;
+ std::cout << std::exp( -PWG1.distance (PWG2, sigma, PWG::arctan_weight, -1, 2) ) / (2*tau*tau) << std::endl;
+
+
+
+
+
+
+
+ // PSS
+
+ PD pd1 = persistence1; int numpts = persistence1.size(); for(int i = 0; i < numpts; i++) pd1.emplace_back(persistence1[i].second,persistence1[i].first);
+ PD pd2 = persistence2; numpts = persistence2.size(); for(int i = 0; i < numpts; i++) pd2.emplace_back(persistence2[i].second,persistence2[i].first);
+
+ PWG pwg1(pd1);
+ PWG pwg2(pd2);
+
+ std::cout << pwg1.compute_scalar_product (pwg2, 2*std::sqrt(sigma), PWG::pss_weight, m) / (16*pi*sigma) << std::endl;
+ std::cout << pwg1.compute_scalar_product (pwg2, 2*std::sqrt(sigma), PWG::pss_weight, -1) / (16*pi*sigma) << std::endl;
+
+ std::cout << pwg1.distance (pwg2, 2*std::sqrt(sigma), PWG::pss_weight, m) / (16*pi*sigma) << std::endl;
+ std::cout << pwg1.distance (pwg2, 2*std::sqrt(sigma), PWG::pss_weight, -1) / (16*pi*sigma) << std::endl;
+
+
+ return 0;
+}
diff --git a/src/Persistence_representations/example/sliced_wasserstein.cpp b/src/Persistence_representations/example/sliced_wasserstein.cpp
new file mode 100644
index 00000000..673d8474
--- /dev/null
+++ b/src/Persistence_representations/example/sliced_wasserstein.cpp
@@ -0,0 +1,55 @@
+/* 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): Mathieu Carriere
+ *
+ * Copyright (C) 2018 INRIA (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/Sliced_Wasserstein.h>
+
+#include <iostream>
+#include <vector>
+#include <utility>
+
+using SW = Gudhi::Persistence_representations::Sliced_Wasserstein;
+
+int main(int argc, char** argv) {
+
+ std::vector<std::pair<double, double> > persistence1;
+ std::vector<std::pair<double, double> > persistence2;
+
+ persistence1.push_back(std::make_pair(1, 2));
+ persistence1.push_back(std::make_pair(6, 8));
+ persistence1.push_back(std::make_pair(0, 4));
+ persistence1.push_back(std::make_pair(3, 8));
+
+ persistence2.push_back(std::make_pair(2, 9));
+ persistence2.push_back(std::make_pair(1, 6));
+ persistence2.push_back(std::make_pair(3, 5));
+ persistence2.push_back(std::make_pair(6, 10));
+
+ SW SW1(persistence1);
+ SW SW2(persistence2);
+
+ std::cout << SW1.compute_sliced_wasserstein_distance(SW2,100) << std::endl;
+ std::cout << SW1.compute_sliced_wasserstein_distance(SW2,-1) << std::endl;
+ std::cout << SW1.compute_scalar_product(SW2,1,100) << std::endl;
+ std::cout << SW1.distance(SW2,1,100,1) << std::endl;
+
+ return 0;
+}
diff --git a/src/Persistence_representations/include/gudhi/PSSK.h b/src/Persistence_representations/include/gudhi/PSSK.h
index e2d4225e..630f5623 100644
--- a/src/Persistence_representations/include/gudhi/PSSK.h
+++ b/src/Persistence_representations/include/gudhi/PSSK.h
@@ -121,10 +121,10 @@ void PSSK::construct(const std::vector<std::pair<double, double> >& intervals_,
for (size_t pt_nr = 0; pt_nr != intervals_.size(); ++pt_nr) {
// compute the value of intervals_[pt_nr] in the grid:
- int x_grid = static_cast<int>((intervals_[pt_nr].first - this->min_) /
- (this->max_ - this->min_) * number_of_pixels);
- int y_grid = static_cast<int>((intervals_[pt_nr].second - this->min_) /
- (this->max_ - this->min_) * number_of_pixels);
+ int x_grid =
+ static_cast<int>((intervals_[pt_nr].first - this->min_) / (this->max_ - this->min_) * number_of_pixels);
+ int y_grid =
+ static_cast<int>((intervals_[pt_nr].second - this->min_) / (this->max_ - this->min_) * number_of_pixels);
if (dbg) {
std::cerr << "point : " << intervals_[pt_nr].first << " , " << intervals_[pt_nr].second << std::endl;
diff --git a/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h b/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h
index 04dd78ad..a80c3c40 100644
--- a/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h
+++ b/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h
@@ -582,10 +582,10 @@ void Persistence_heat_maps<Scalling_of_kernels>::construct(const std::vector<std
for (size_t pt_nr = 0; pt_nr != intervals_.size(); ++pt_nr) {
// compute the value of intervals_[pt_nr] in the grid:
- int x_grid = static_cast<int>((intervals_[pt_nr].first - this->min_) /
- (this->max_ - this->min_) * number_of_pixels);
- int y_grid = static_cast<int>((intervals_[pt_nr].second - this->min_) /
- (this->max_ - this->min_) * number_of_pixels);
+ int x_grid =
+ static_cast<int>((intervals_[pt_nr].first - this->min_) / (this->max_ - this->min_) * number_of_pixels);
+ int y_grid =
+ static_cast<int>((intervals_[pt_nr].second - this->min_) / (this->max_ - this->min_) * number_of_pixels);
if (dbg) {
std::cerr << "point : " << intervals_[pt_nr].first << " , " << intervals_[pt_nr].second << std::endl;
@@ -743,10 +743,10 @@ void Persistence_heat_maps<Scalling_of_kernels>::compute_percentage_of_active(
template <typename Scalling_of_kernels>
void Persistence_heat_maps<Scalling_of_kernels>::plot(const char* filename) const {
std::ofstream out;
- std::stringstream ss;
- ss << filename << "_GnuplotScript";
+ std::stringstream gnuplot_script;
+ gnuplot_script << filename << "_GnuplotScript";
- out.open(ss.str().c_str());
+ out.open(gnuplot_script.str().c_str());
out << "plot '-' matrix with image" << std::endl;
for (size_t i = 0; i != this->heat_map.size(); ++i) {
for (size_t j = 0; j != this->heat_map[i].size(); ++j) {
@@ -755,8 +755,8 @@ void Persistence_heat_maps<Scalling_of_kernels>::plot(const char* filename) cons
out << std::endl;
}
out.close();
- std::cout << "Gnuplot script have been created. Open gnuplot and type load \'" << ss.str().c_str()
- << "\' to see the picture." << std::endl;
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
}
template <typename Scalling_of_kernels>
@@ -797,8 +797,7 @@ void Persistence_heat_maps<Scalling_of_kernels>::load_from_file(const char* file
std::string temp;
std::getline(in, temp);
-
- while (!in.eof()) {
+ while (in.good()) {
std::getline(in, temp);
std::stringstream lineSS;
lineSS << temp;
diff --git a/src/Persistence_representations/include/gudhi/Persistence_intervals.h b/src/Persistence_representations/include/gudhi/Persistence_intervals.h
index 525d58a3..3d04d8b7 100644
--- a/src/Persistence_representations/include/gudhi/Persistence_intervals.h
+++ b/src/Persistence_representations/include/gudhi/Persistence_intervals.h
@@ -167,10 +167,10 @@ class Persistence_intervals {
// this program create a gnuplot script file that allows to plot persistence diagram.
std::ofstream out;
- std::ostringstream nameSS;
- nameSS << filename << "_GnuplotScript";
- std::string nameStr = nameSS.str();
- out.open(nameStr);
+ std::stringstream gnuplot_script;
+ gnuplot_script << filename << "_GnuplotScript";
+
+ out.open(gnuplot_script.str().c_str());
std::pair<double, double> min_max_values = this->get_x_range();
if (min_x == max_x) {
@@ -195,8 +195,8 @@ class Persistence_intervals {
out.close();
- std::cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '"
- << nameStr << "' in gnuplot to visualize." << std::endl;
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
}
/**
@@ -402,9 +402,8 @@ std::vector<double> Persistence_intervals::characteristic_function_of_diagram(do
}
for (size_t pos = beginIt; pos != endIt; ++pos) {
- result[pos] +=
- ((x_max - x_min) / static_cast<double>(number_of_bins)) *
- (this->intervals[i].second - this->intervals[i].first);
+ result[pos] += ((x_max - x_min) / static_cast<double>(number_of_bins)) *
+ (this->intervals[i].second - this->intervals[i].first);
}
if (dbg) {
std::cerr << "Result at this stage \n";
diff --git a/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h b/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h
index d5ab04b4..79908883 100644
--- a/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h
+++ b/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h
@@ -26,7 +26,6 @@
#include <gudhi/Persistence_intervals.h>
#include <gudhi/Bottleneck.h>
-
#include <limits>
namespace Gudhi {
@@ -47,7 +46,7 @@ class Persistence_intervals_with_distances : public Persistence_intervals {
* The last parameter, tolerance, it is an additiv error of the approimation, set by default to zero.
**/
double distance(const Persistence_intervals_with_distances& second, double power = std::numeric_limits<double>::max(),
- double tolerance = 0) const {
+ double tolerance = (std::numeric_limits<double>::min)()) const {
if (power >= std::numeric_limits<double>::max()) {
return Gudhi::persistence_diagram::bottleneck_distance(this->intervals, second.intervals, tolerance);
} else {
diff --git a/src/Persistence_representations/include/gudhi/Persistence_landscape.h b/src/Persistence_representations/include/gudhi/Persistence_landscape.h
index 5c300112..c5aa7867 100644
--- a/src/Persistence_representations/include/gudhi/Persistence_landscape.h
+++ b/src/Persistence_representations/include/gudhi/Persistence_landscape.h
@@ -79,14 +79,16 @@ class Persistence_landscape {
/**
* Constructor that takes as an input a vector of birth-death pairs.
**/
- Persistence_landscape(const std::vector<std::pair<double, double> >& p, size_t number_of_levels = std::numeric_limits<size_t>::max() );
+ Persistence_landscape(const std::vector<std::pair<double, double> >& p,
+ size_t number_of_levels = std::numeric_limits<size_t>::max());
/**
* Constructor that reads persistence intervals from file and creates persistence landscape. The format of the
*input file is the following: in each line we put birth-death pair. Last line is assumed
* to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read.
**/
- Persistence_landscape(const char* filename, size_t dimension = std::numeric_limits<unsigned>::max() , size_t number_of_levels = std::numeric_limits<size_t>::max() );
+ Persistence_landscape(const char* filename, size_t dimension = std::numeric_limits<unsigned>::max(),
+ size_t number_of_levels = std::numeric_limits<size_t>::max());
/**
* This procedure loads a landscape from file. It erase all the data that was previously stored in this landscape.
@@ -285,7 +287,7 @@ class Persistence_landscape {
*distance, we need to take its absolute value. This is the purpose of this procedure.
**/
Persistence_landscape abs();
-
+
Persistence_landscape* new_abs();
/**
@@ -453,7 +455,8 @@ class Persistence_landscape {
size_t number_of_functions_for_vectorization;
size_t number_of_functions_for_projections_to_reals;
- void construct_persistence_landscape_from_barcode(const std::vector<std::pair<double, double> >& p , size_t number_of_levels = std::numeric_limits<size_t>::max());
+ void construct_persistence_landscape_from_barcode(const std::vector<std::pair<double, double> >& p,
+ size_t number_of_levels = std::numeric_limits<size_t>::max());
Persistence_landscape multiply_lanscape_by_real_number_not_overwrite(double x) const;
void multiply_lanscape_by_real_number_overwrite(double x);
friend double compute_maximal_distance_non_symmetric(const Persistence_landscape& pl1,
@@ -473,7 +476,7 @@ Persistence_landscape::Persistence_landscape(const char* filename, size_t dimens
} else {
barcode = read_persistence_intervals_in_one_dimension_from_file(filename);
}
- this->construct_persistence_landscape_from_barcode(barcode,number_of_levels);
+ this->construct_persistence_landscape_from_barcode(barcode, number_of_levels);
this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
}
@@ -506,14 +509,14 @@ bool Persistence_landscape::operator==(const Persistence_landscape& rhs) const {
return true;
}
-Persistence_landscape::Persistence_landscape(const std::vector<std::pair<double, double> >& p,size_t number_of_levels) {
- this->construct_persistence_landscape_from_barcode(p,number_of_levels);
+Persistence_landscape::Persistence_landscape(const std::vector<std::pair<double, double> >& p,
+ size_t number_of_levels) {
+ this->construct_persistence_landscape_from_barcode(p, number_of_levels);
this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
}
void Persistence_landscape::construct_persistence_landscape_from_barcode(
- const std::vector<std::pair<double, double> >& p, size_t number_of_levels)
- {
+ const std::vector<std::pair<double, double> >& p, size_t number_of_levels) {
bool dbg = false;
if (dbg) {
std::cerr << "Persistence_landscape::Persistence_landscape( const std::vector< std::pair< double , double > >& p )"
@@ -648,12 +651,11 @@ void Persistence_landscape::construct_persistence_landscape_from_barcode(
lambda_n.erase(std::unique(lambda_n.begin(), lambda_n.end()), lambda_n.end());
this->land.push_back(lambda_n);
-
+
++number_of_levels_in_the_landscape;
- if ( number_of_levels == number_of_levels_in_the_landscape )
- {
- break;
- }
+ if (number_of_levels == number_of_levels_in_the_landscape) {
+ break;
+ }
}
}
@@ -857,58 +859,47 @@ Persistence_landscape Persistence_landscape::abs() {
return result;
}
+Persistence_landscape* Persistence_landscape::new_abs() {
+ Persistence_landscape* result = new Persistence_landscape(*this);
+ for (size_t level = 0; level != this->land.size(); ++level) {
+ if (AbsDbg) {
+ std::cout << "level: " << level << std::endl;
+ }
+ std::vector<std::pair<double, double> > lambda_n;
+ lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
+ for (size_t i = 1; i != this->land[level].size(); ++i) {
+ if (AbsDbg) {
+ std::cout << "this->land[" << level << "][" << i << "] : " << this->land[level][i].first << " "
+ << this->land[level][i].second << std::endl;
+ }
+ // if a line segment between this->land[level][i-1] and this->land[level][i] crosses the x-axis, then we have to
+ // add one landscape point t o result
+ if ((this->land[level][i - 1].second) * (this->land[level][i].second) < 0) {
+ double zero =
+ find_zero_of_a_line_segment_between_those_two_points(this->land[level][i - 1], this->land[level][i]);
-Persistence_landscape* Persistence_landscape::new_abs()
-{
- Persistence_landscape* result = new Persistence_landscape(*this);
- for (size_t level = 0; level != this->land.size(); ++level)
- {
- if (AbsDbg)
- {
- std::cout << "level: " << level << std::endl;
- }
- std::vector<std::pair<double, double> > lambda_n;
- lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
- for (size_t i = 1; i != this->land[level].size(); ++i)
- {
- if (AbsDbg)
- {
- std::cout << "this->land[" << level << "][" << i << "] : " << this->land[level][i].first << " "
- << this->land[level][i].second << std::endl;
- }
- // if a line segment between this->land[level][i-1] and this->land[level][i] crosses the x-axis, then we have to
- // add one landscape point t o result
- if ((this->land[level][i - 1].second) * (this->land[level][i].second) < 0) {
- double zero =
- find_zero_of_a_line_segment_between_those_two_points(this->land[level][i - 1], this->land[level][i]);
-
- lambda_n.push_back(std::make_pair(zero, 0));
- lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
- if (AbsDbg)
- {
- std::cout << "Adding pair : (" << zero << ",0)" << std::endl;
- std::cout << "In the same step adding pair : (" << this->land[level][i].first << ","
- << fabs(this->land[level][i].second) << ") " << std::endl;
- std::cin.ignore();
- }
- }
- else
- {
- lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
- if (AbsDbg)
- {
- std::cout << "Adding pair : (" << this->land[level][i].first << "," << fabs(this->land[level][i].second)
- << ") " << std::endl;
- std::cin.ignore();
- }
- }
- }
- result->land.push_back(lambda_n);
- }
- return result;
+ lambda_n.push_back(std::make_pair(zero, 0));
+ lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
+ if (AbsDbg) {
+ std::cout << "Adding pair : (" << zero << ",0)" << std::endl;
+ std::cout << "In the same step adding pair : (" << this->land[level][i].first << ","
+ << fabs(this->land[level][i].second) << ") " << std::endl;
+ std::cin.ignore();
+ }
+ } else {
+ lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
+ if (AbsDbg) {
+ std::cout << "Adding pair : (" << this->land[level][i].first << "," << fabs(this->land[level][i].second)
+ << ") " << std::endl;
+ std::cin.ignore();
+ }
+ }
+ }
+ result->land.push_back(lambda_n);
+ }
+ return result;
}
-
Persistence_landscape Persistence_landscape::multiply_lanscape_by_real_number_not_overwrite(double x) const {
std::vector<std::vector<std::pair<double, double> > > result(this->land.size());
for (size_t dim = 0; dim != this->land.size(); ++dim) {
@@ -954,7 +945,7 @@ void Persistence_landscape::load_landscape_from_file(const char* filename) {
std::vector<std::pair<double, double> > landscapeAtThisLevel;
bool isThisAFirsLine = true;
- while (!in.eof()) {
+ while (in.good()) {
getline(in, line);
if (!(line.length() == 0 || line[0] == '#')) {
std::stringstream lineSS;
@@ -1340,10 +1331,9 @@ void Persistence_landscape::plot(const char* filename, double xRangeBegin, doubl
// this program create a gnuplot script file that allows to plot persistence diagram.
std::ofstream out;
- std::ostringstream nameSS;
- nameSS << filename << "_GnuplotScript";
- std::string nameStr = nameSS.str();
- out.open(nameStr);
+ std::ostringstream gnuplot_script;
+ gnuplot_script << filename << "_GnuplotScript";
+ out.open(gnuplot_script.str().c_str());
if ((xRangeBegin != std::numeric_limits<double>::max()) || (xRangeEnd != std::numeric_limits<double>::max()) ||
(yRangeBegin != std::numeric_limits<double>::max()) || (yRangeEnd != std::numeric_limits<double>::max())) {
@@ -1376,8 +1366,8 @@ void Persistence_landscape::plot(const char* filename, double xRangeBegin, doubl
}
out << "EOF" << std::endl;
}
- std::cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '"
- << nameStr << "' in gnuplot to visualize." << std::endl;
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
}
} // namespace Persistence_representations
diff --git a/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h b/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h
index 4ceb9bf6..84fd22ed 100644
--- a/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h
+++ b/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h
@@ -1207,10 +1207,9 @@ void Persistence_landscape_on_grid::plot(const char* filename, double min_x, dou
// this program create a gnuplot script file that allows to plot persistence diagram.
std::ofstream out;
- std::ostringstream nameSS;
- nameSS << filename << "_GnuplotScript";
- std::string nameStr = nameSS.str();
- out.open(nameStr);
+ std::ostringstream gnuplot_script;
+ gnuplot_script << filename << "_GnuplotScript";
+ out.open(gnuplot_script.str().c_str());
if (min_x == max_x) {
std::pair<double, double> min_max = compute_minimum_maximum();
@@ -1241,7 +1240,6 @@ void Persistence_landscape_on_grid::plot(const char* filename, double min_x, dou
out << "plot ";
for (size_t lambda = from; lambda != to; ++lambda) {
- // out << " '-' using 1:2 title 'l" << lambda << "' with lp";
out << " '-' using 1:2 notitle with lp";
if (lambda + 1 != to) {
out << ", \\";
@@ -1261,8 +1259,8 @@ void Persistence_landscape_on_grid::plot(const char* filename, double min_x, dou
}
out << "EOF" << std::endl;
}
- std::cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '"
- << nameStr << "' in gnuplot to visualize." << std::endl;
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
}
template <typename T>
diff --git a/src/Persistence_representations/include/gudhi/Persistence_vectors.h b/src/Persistence_representations/include/gudhi/Persistence_vectors.h
index 0fb49eee..63577e46 100644
--- a/src/Persistence_representations/include/gudhi/Persistence_vectors.h
+++ b/src/Persistence_representations/include/gudhi/Persistence_vectors.h
@@ -201,7 +201,8 @@ class Vector_distances_in_diagram {
}
out << std::endl;
out.close();
- std::cout << "To visualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl;
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
}
/**
@@ -617,9 +618,7 @@ void Vector_distances_in_diagram<F>::load_from_file(const char* filename) {
}
double number;
- while (true) {
- in >> number;
- if (in.eof()) break;
+ while (in >> number) {
this->sorted_vector_of_distances.push_back(number);
}
in.close();
diff --git a/src/Persistence_representations/include/gudhi/Persistence_weighted_gaussian.h b/src/Persistence_representations/include/gudhi/Persistence_weighted_gaussian.h
new file mode 100644
index 00000000..2884885c
--- /dev/null
+++ b/src/Persistence_representations/include/gudhi/Persistence_weighted_gaussian.h
@@ -0,0 +1,143 @@
+/* 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): Mathieu Carriere
+ *
+ * Copyright (C) 2018 INRIA (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 PERSISTENCE_WEIGHTED_GAUSSIAN_H_
+#define PERSISTENCE_WEIGHTED_GAUSSIAN_H_
+
+#ifdef GUDHI_USE_TBB
+#include <tbb/parallel_for.h>
+#endif
+
+// gudhi include
+#include <gudhi/read_persistence_from_file.h>
+
+// standard include
+#include <cmath>
+#include <iostream>
+#include <vector>
+#include <limits>
+#include <fstream>
+#include <sstream>
+#include <algorithm>
+#include <string>
+#include <utility>
+#include <functional>
+#include <boost/math/constants/constants.hpp>
+
+double pi = boost::math::constants::pi<double>();
+using PD = std::vector<std::pair<double,double> >;
+
+namespace Gudhi {
+namespace Persistence_representations {
+
+class Persistence_weighted_gaussian{
+
+ protected:
+ PD diagram;
+
+ public:
+
+ Persistence_weighted_gaussian(PD _diagram){diagram = _diagram;}
+ PD get_diagram(){return this->diagram;}
+
+
+ // **********************************
+ // Utils.
+ // **********************************
+
+
+ static double pss_weight(std::pair<double,double> P){
+ if(P.second > P.first) return 1;
+ else return -1;
+ }
+
+ static double arctan_weight(std::pair<double,double> P){
+ return atan(P.second - P.first);
+ }
+
+ template<class Weight = std::function<double (std::pair<double,double>) > >
+ std::vector<std::pair<double,double> > Fourier_feat(PD D, std::vector<std::pair<double,double> > Z, Weight weight = arctan_weight){
+ int m = D.size(); std::vector<std::pair<double,double> > B; int M = Z.size();
+ for(int i = 0; i < M; i++){
+ double d1 = 0; double d2 = 0; double zx = Z[i].first; double zy = Z[i].second;
+ for(int j = 0; j < m; j++){
+ double x = D[j].first; double y = D[j].second;
+ d1 += weight(D[j])*cos(x*zx + y*zy);
+ d2 += weight(D[j])*sin(x*zx + y*zy);
+ }
+ B.emplace_back(d1,d2);
+ }
+ return B;
+ }
+
+ std::vector<std::pair<double,double> > random_Fourier(double sigma, int M = 1000){
+ std::normal_distribution<double> distrib(0,1); std::vector<std::pair<double,double> > Z; std::random_device rd;
+ for(int i = 0; i < M; i++){
+ std::mt19937 e1(rd()); std::mt19937 e2(rd());
+ double zx = distrib(e1); double zy = distrib(e2);
+ Z.emplace_back(zx/sigma,zy/sigma);
+ }
+ return Z;
+ }
+
+
+
+ // **********************************
+ // Scalar product + distance.
+ // **********************************
+
+
+ template<class Weight = std::function<double (std::pair<double,double>) > >
+ double compute_scalar_product(Persistence_weighted_gaussian second, double sigma, Weight weight = arctan_weight, int m = 1000){
+
+ PD diagram1 = this->diagram; PD diagram2 = second.diagram;
+
+ if(m == -1){
+ int num_pts1 = diagram1.size(); int num_pts2 = diagram2.size(); double k = 0;
+ for(int i = 0; i < num_pts1; i++)
+ for(int j = 0; j < num_pts2; j++)
+ k += weight(diagram1[i])*weight(diagram2[j])*exp(-((diagram1[i].first - diagram2[j].first) * (diagram1[i].first - diagram2[j].first) +
+ (diagram1[i].second - diagram2[j].second) * (diagram1[i].second - diagram2[j].second))
+ /(2*sigma*sigma));
+ return k;
+ }
+ else{
+ std::vector<std::pair<double,double> > z = random_Fourier(sigma, m);
+ std::vector<std::pair<double,double> > b1 = Fourier_feat(diagram1,z,weight);
+ std::vector<std::pair<double,double> > b2 = Fourier_feat(diagram2,z,weight);
+ double d = 0; for(int i = 0; i < m; i++) d += b1[i].first*b2[i].first + b1[i].second*b2[i].second;
+ return d/m;
+ }
+ }
+
+ template<class Weight = std::function<double (std::pair<double,double>) > >
+ double distance(Persistence_weighted_gaussian second, double sigma, Weight weight = arctan_weight, int m = 1000, double power = 1) {
+ return std::pow(this->compute_scalar_product(*this, sigma, weight, m) + second.compute_scalar_product(second, sigma, weight, m)-2*this->compute_scalar_product(second, sigma, weight, m), power/2.0);
+ }
+
+
+};
+
+} // namespace Persistence_weighted_gaussian
+} // namespace Gudhi
+
+#endif // PERSISTENCE_WEIGHTED_GAUSSIAN_H_
diff --git a/src/Persistence_representations/include/gudhi/Sliced_Wasserstein.h b/src/Persistence_representations/include/gudhi/Sliced_Wasserstein.h
new file mode 100644
index 00000000..4fa6151f
--- /dev/null
+++ b/src/Persistence_representations/include/gudhi/Sliced_Wasserstein.h
@@ -0,0 +1,285 @@
+/* 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): Mathieu Carriere
+ *
+ * Copyright (C) 2018 INRIA (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 SLICED_WASSERSTEIN_H_
+#define SLICED_WASSERSTEIN_H_
+
+#ifdef GUDHI_USE_TBB
+#include <tbb/parallel_for.h>
+#endif
+
+// gudhi include
+#include <gudhi/read_persistence_from_file.h>
+
+// standard include
+#include <cmath>
+#include <iostream>
+#include <vector>
+#include <limits>
+#include <fstream>
+#include <sstream>
+#include <algorithm>
+#include <string>
+#include <utility>
+#include <functional>
+#include <boost/math/constants/constants.hpp>
+
+double pi = boost::math::constants::pi<double>();
+using PD = std::vector<std::pair<double,double> >;
+
+namespace Gudhi {
+namespace Persistence_representations {
+
+class Sliced_Wasserstein {
+
+ protected:
+ PD diagram;
+
+ public:
+
+ Sliced_Wasserstein(PD _diagram){diagram = _diagram;}
+ PD get_diagram(){return this->diagram;}
+
+
+ // **********************************
+ // Utils.
+ // **********************************
+
+ // Compute the angle formed by two points of a PD
+ double compute_angle(PD diag, int i, int j){
+ std::pair<double,double> vect; double x1,y1, x2,y2;
+ x1 = diag[i].first; y1 = diag[i].second;
+ x2 = diag[j].first; y2 = diag[j].second;
+ if (y1 - y2 > 0){
+ vect.first = y1 - y2;
+ vect.second = x2 - x1;}
+ else{
+ if(y1 - y2 < 0){
+ vect.first = y2 - y1;
+ vect.second = x1 - x2;
+ }
+ else{
+ vect.first = 0;
+ vect.second = abs(x1 - x2);}
+ }
+ double norm = std::sqrt(vect.first*vect.first + vect.second*vect.second);
+ return asin(vect.second/norm);
+ }
+
+ // Compute the integral of |cos()| between alpha and beta, valid only if alpha is in [-pi,pi] and beta-alpha is in [0,pi]
+ double compute_int_cos(const double & alpha, const double & beta){
+ double res = 0;
+ if (alpha >= 0 && alpha <= pi){
+ if (cos(alpha) >= 0){
+ if(pi/2 <= beta){res = 2-sin(alpha)-sin(beta);}
+ else{res = sin(beta)-sin(alpha);}
+ }
+ else{
+ if(1.5*pi <= beta){res = 2+sin(alpha)+sin(beta);}
+ else{res = sin(alpha)-sin(beta);}
+ }
+ }
+ if (alpha >= -pi && alpha <= 0){
+ if (cos(alpha) <= 0){
+ if(-pi/2 <= beta){res = 2+sin(alpha)+sin(beta);}
+ else{res = sin(alpha)-sin(beta);}
+ }
+ else{
+ if(pi/2 <= beta){res = 2-sin(alpha)-sin(beta);}
+ else{res = sin(beta)-sin(alpha);}
+ }
+ }
+ return res;
+ }
+
+ double compute_int(const double & theta1, const double & theta2, const int & p, const int & q, const PD & PD1, const PD & PD2){
+ double norm = std::sqrt( (PD1[p].first-PD2[q].first)*(PD1[p].first-PD2[q].first) + (PD1[p].second-PD2[q].second)*(PD1[p].second-PD2[q].second) );
+ double angle1;
+ if (PD1[p].first > PD2[q].first)
+ angle1 = theta1 - asin( (PD1[p].second-PD2[q].second)/norm );
+ else
+ angle1 = theta1 - asin( (PD2[q].second-PD1[p].second)/norm );
+ double angle2 = angle1 + theta2 - theta1;
+ double integral = compute_int_cos(angle1,angle2);
+ return norm*integral;
+ }
+
+
+
+
+ // **********************************
+ // Scalar product + distance.
+ // **********************************
+
+ double compute_sliced_wasserstein_distance(Sliced_Wasserstein second, int approx) {
+
+ PD diagram1 = this->diagram; PD diagram2 = second.diagram; double sw = 0;
+
+ if(approx == -1){
+
+ // Add projections onto diagonal.
+ int n1, n2; n1 = diagram1.size(); n2 = diagram2.size(); double max_ordinate = std::numeric_limits<double>::lowest();
+ for (int i = 0; i < n2; i++){
+ max_ordinate = std::max(max_ordinate, diagram2[i].second);
+ diagram1.emplace_back( (diagram2[i].first+diagram2[i].second)/2, (diagram2[i].first+diagram2[i].second)/2 );
+ }
+ for (int i = 0; i < n1; i++){
+ max_ordinate = std::max(max_ordinate, diagram1[i].second);
+ diagram2.emplace_back( (diagram1[i].first+diagram1[i].second)/2, (diagram1[i].first+diagram1[i].second)/2 );
+ }
+ int num_pts_dgm = diagram1.size();
+
+ // Slightly perturb the points so that the PDs are in generic positions.
+ int mag = 0; while(max_ordinate > 10){mag++; max_ordinate/=10;}
+ double thresh = pow(10,-5+mag);
+ srand(time(NULL));
+ for (int i = 0; i < num_pts_dgm; i++){
+ diagram1[i].first += thresh*(1.0-2.0*rand()/RAND_MAX); diagram1[i].second += thresh*(1.0-2.0*rand()/RAND_MAX);
+ diagram2[i].first += thresh*(1.0-2.0*rand()/RAND_MAX); diagram2[i].second += thresh*(1.0-2.0*rand()/RAND_MAX);
+ }
+
+ // Compute all angles in both PDs.
+ std::vector<std::pair<double, std::pair<int,int> > > angles1, angles2;
+ for (int i = 0; i < num_pts_dgm; i++){
+ for (int j = i+1; j < num_pts_dgm; j++){
+ double theta1 = compute_angle(diagram1,i,j); double theta2 = compute_angle(diagram2,i,j);
+ angles1.emplace_back(theta1, std::pair<int,int>(i,j));
+ angles2.emplace_back(theta2, std::pair<int,int>(i,j));
+ }
+ }
+
+ // Sort angles.
+ std::sort(angles1.begin(), angles1.end(), [=](std::pair<double, std::pair<int,int> >& p1, const std::pair<double, std::pair<int,int> >& p2){return (p1.first < p2.first);});
+ std::sort(angles2.begin(), angles2.end(), [=](std::pair<double, std::pair<int,int> >& p1, const std::pair<double, std::pair<int,int> >& p2){return (p1.first < p2.first);});
+
+ // Initialize orders of the points of both PDs (given by ordinates when theta = -pi/2).
+ std::vector<int> orderp1, orderp2;
+ for (int i = 0; i < num_pts_dgm; i++){ orderp1.push_back(i); orderp2.push_back(i); }
+ std::sort( orderp1.begin(), orderp1.end(), [=](int i, int j){ if(diagram1[i].second != diagram1[j].second) return (diagram1[i].second < diagram1[j].second); else return (diagram1[i].first > diagram1[j].first); } );
+ std::sort( orderp2.begin(), orderp2.end(), [=](int i, int j){ if(diagram2[i].second != diagram2[j].second) return (diagram2[i].second < diagram2[j].second); else return (diagram2[i].first > diagram2[j].first); } );
+
+ // Find the inverses of the orders.
+ std::vector<int> order1(num_pts_dgm); std::vector<int> order2(num_pts_dgm);
+ for(int i = 0; i < num_pts_dgm; i++) for (int j = 0; j < num_pts_dgm; j++) if(orderp1[j] == i){ order1[i] = j; break; }
+ for(int i = 0; i < num_pts_dgm; i++) for (int j = 0; j < num_pts_dgm; j++) if(orderp2[j] == i){ order2[i] = j; break; }
+
+ // Record all inversions of points in the orders as theta varies along the positive half-disk.
+ std::vector<std::vector<std::pair<int,double> > > anglePerm1(num_pts_dgm);
+ std::vector<std::vector<std::pair<int,double> > > anglePerm2(num_pts_dgm);
+
+ int m1 = angles1.size();
+ for (int i = 0; i < m1; i++){
+ double theta = angles1[i].first; int p = angles1[i].second.first; int q = angles1[i].second.second;
+ anglePerm1[order1[p]].emplace_back(p,theta);
+ anglePerm1[order1[q]].emplace_back(q,theta);
+ int a = order1[p]; int b = order1[q]; order1[p] = b; order1[q] = a;
+ }
+
+ int m2 = angles2.size();
+ for (int i = 0; i < m2; i++){
+ double theta = angles2[i].first; int p = angles2[i].second.first; int q = angles2[i].second.second;
+ anglePerm2[order2[p]].emplace_back(p,theta);
+ anglePerm2[order2[q]].emplace_back(q,theta);
+ int a = order2[p]; int b = order2[q]; order2[p] = b; order2[q] = a;
+ }
+
+ for (int i = 0; i < num_pts_dgm; i++){
+ anglePerm1[order1[i]].emplace_back(i,pi/2);
+ anglePerm2[order2[i]].emplace_back(i,pi/2);
+ }
+
+ // Compute the SW distance with the list of inversions.
+ for (int i = 0; i < num_pts_dgm; i++){
+ std::vector<std::pair<int,double> > u,v; u = anglePerm1[i]; v = anglePerm2[i];
+ double theta1, theta2; theta1 = -pi/2;
+ unsigned int ku, kv; ku = 0; kv = 0; theta2 = std::min(u[ku].second,v[kv].second);
+ while(theta1 != pi/2){
+ if(diagram1[u[ku].first].first != diagram2[v[kv].first].first || diagram1[u[ku].first].second != diagram2[v[kv].first].second)
+ if(theta1 != theta2)
+ sw += compute_int(theta1, theta2, u[ku].first, v[kv].first, diagram1, diagram2);
+ theta1 = theta2;
+ if ( (theta2 == u[ku].second) && ku < u.size()-1 ) ku++;
+ if ( (theta2 == v[kv].second) && kv < v.size()-1 ) kv++;
+ theta2 = std::min(u[ku].second, v[kv].second);
+ }
+ }
+ }
+
+
+ else{
+ double step = pi/approx;
+
+ // Add projections onto diagonal.
+ int n1, n2; n1 = diagram1.size(); n2 = diagram2.size();
+ for (int i = 0; i < n2; i++)
+ diagram1.emplace_back( (diagram2[i].first + diagram2[i].second)/2, (diagram2[i].first + diagram2[i].second)/2 );
+ for (int i = 0; i < n1; i++)
+ diagram2.emplace_back( (diagram1[i].first + diagram1[i].second)/2, (diagram1[i].first + diagram1[i].second)/2 );
+ int n = diagram1.size();
+
+ // Sort and compare all projections.
+ #ifdef GUDHI_USE_TBB
+ tbb::parallel_for(0, approx, [&](int i){
+ std::vector<std::pair<int,double> > l1, l2;
+ for (int j = 0; j < n; j++){
+ l1.emplace_back( j, diagram1[j].first*cos(-pi/2+i*step) + diagram1[j].second*sin(-pi/2+i*step) );
+ l2.emplace_back( j, diagram2[j].first*cos(-pi/2+i*step) + diagram2[j].second*sin(-pi/2+i*step) );
+ }
+ std::sort(l1.begin(),l1.end(), [=](const std::pair<int,double> & p1, const std::pair<int,double> & p2){return p1.second < p2.second;});
+ std::sort(l2.begin(),l2.end(), [=](const std::pair<int,double> & p1, const std::pair<int,double> & p2){return p1.second < p2.second;});
+ double f = 0; for (int j = 0; j < n; j++) f += std::abs(l1[j].second - l2[j].second);
+ sw += f*step;
+ });
+ #else
+ for (int i = 0; i < approx; i++){
+ std::vector<std::pair<int,double> > l1, l2;
+ for (int j = 0; j < n; j++){
+ l1.emplace_back( j, diagram1[j].first*cos(-pi/2+i*step) + diagram1[j].second*sin(-pi/2+i*step) );
+ l2.emplace_back( j, diagram2[j].first*cos(-pi/2+i*step) + diagram2[j].second*sin(-pi/2+i*step) );
+ }
+ std::sort(l1.begin(),l1.end(), [=](const std::pair<int,double> & p1, const std::pair<int,double> & p2){return p1.second < p2.second;});
+ std::sort(l2.begin(),l2.end(), [=](const std::pair<int,double> & p1, const std::pair<int,double> & p2){return p1.second < p2.second;});
+ double f = 0; for (int j = 0; j < n; j++) f += std::abs(l1[j].second - l2[j].second);
+ sw += f*step;
+ }
+ #endif
+ }
+
+ return sw/pi;
+ }
+
+
+ double compute_scalar_product(Sliced_Wasserstein second, double sigma, int approx = 100) {
+ return std::exp(-compute_sliced_wasserstein_distance(second, approx)/(2*sigma*sigma));
+ }
+
+ double distance(Sliced_Wasserstein second, double sigma, int approx = 100, double power = 1) {
+ return std::pow(this->compute_scalar_product(*this, sigma, approx) + second.compute_scalar_product(second, sigma, approx)-2*this->compute_scalar_product(second, sigma, approx), power/2.0);
+ }
+
+
+};
+
+} // namespace Sliced_Wasserstein
+} // namespace Gudhi
+
+#endif // SLICED_WASSERSTEIN_H_
diff --git a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h
index 770da15b..83b89d0e 100644
--- a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h
+++ b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h
@@ -23,6 +23,8 @@
#ifndef READ_PERSISTENCE_FROM_FILE_H_
#define READ_PERSISTENCE_FROM_FILE_H_
+#include <gudhi/reader_utils.h>
+
#include <iostream>
#include <fstream>
#include <sstream>
@@ -30,7 +32,7 @@
#include <algorithm>
#include <string>
#include <utility>
-#include <gudhi/reader_utils.h>
+#include <limits> // for std::numeric_limits<>
namespace Gudhi {
namespace Persistence_representations {
@@ -50,81 +52,66 @@ namespace Persistence_representations {
* The procedure returns vector of persistence pairs.
**/
std::vector<std::pair<double, double> > read_persistence_intervals_in_one_dimension_from_file(
- std::string const& filename, int dimension = -1, double what_to_substitute_for_infinite_bar = -1) {
+ std::string const& filename, int dimension = -1, double what_to_substitute_for_infinite_bar = -1) {
bool dbg = false;
std::string line;
- std::vector<std::pair<double, double> > barcode_initial = read_persistence_intervals_in_dimension(filename,(int)dimension);
+ std::vector<std::pair<double, double> > barcode_initial =
+ read_persistence_intervals_in_dimension(filename, (int)dimension);
std::vector<std::pair<double, double> > final_barcode;
- final_barcode.reserve( barcode_initial.size() );
-
- if ( dbg )
- {
- std::cerr << "Here are the intervals that we read from the file : \n";
- for ( size_t i = 0 ; i != barcode_initial.size() ; ++i )
- {
- std::cout << barcode_initial[i].first << " " << barcode_initial[i].second << std::endl;
- }
- getchar();
+ final_barcode.reserve(barcode_initial.size());
+
+ if (dbg) {
+ std::cerr << "Here are the intervals that we read from the file : \n";
+ for (size_t i = 0; i != barcode_initial.size(); ++i) {
+ std::cout << barcode_initial[i].first << " " << barcode_initial[i].second << std::endl;
+ }
+ getchar();
}
-
- for ( size_t i = 0 ; i != barcode_initial.size() ; ++i )
- {
- if ( dbg )
- {
- std::cout << "COnsidering interval : " << barcode_initial[i].first << " " << barcode_initial[i].second << std::endl;
- }
- // if ( barcode_initial[i].first == barcode_initial[i].second )
- //{
- // if ( dbg )std::cout << "It has zero length \n";
- // continue;//zero length intervals are not relevant, so we skip all of them.
- //}
-
- if ( barcode_initial[i].first > barcode_initial[i].second )//note that in this case barcode_initial[i].second != std::numeric_limits<double>::infinity()
- {
- if ( dbg )std::cout << "Swap and enter \n";
- //swap them to make sure that birth < death
- final_barcode.push_back( std::pair<double,double>( barcode_initial[i].second , barcode_initial[i].first ) );
- continue;
- }
- else
- {
- if ( barcode_initial[i].second != std::numeric_limits<double>::infinity() )
- {
- if ( dbg )std::cout << "Simply enters\n";
- //in this case, due to the previous conditions we know that barcode_initial[i].first < barcode_initial[i].second, so we put them as they are
- final_barcode.push_back( std::pair<double,double>( barcode_initial[i].first , barcode_initial[i].second ) );
- }
- }
-
- if ( (barcode_initial[i].second == std::numeric_limits<double>::infinity() ) && ( what_to_substitute_for_infinite_bar != -1 ) )
- {
- if ( barcode_initial[i].first < what_to_substitute_for_infinite_bar )//if only birth < death.
- {
- final_barcode.push_back( std::pair<double,double>( barcode_initial[i].first , what_to_substitute_for_infinite_bar ) );
- }
- }
- else
- {
- //if the variable what_to_substitute_for_infinite_bar is not set, then we ignore all the infinite bars.
- }
+
+ for (size_t i = 0; i != barcode_initial.size(); ++i) {
+ if (dbg) {
+ std::cout << "COnsidering interval : " << barcode_initial[i].first << " " << barcode_initial[i].second
+ << std::endl;
+ }
+
+ if (barcode_initial[i].first > barcode_initial[i].second) {
+ // note that in this case barcode_initial[i].second != std::numeric_limits<double>::infinity()
+ if (dbg) std::cout << "Swap and enter \n";
+ // swap them to make sure that birth < death
+ final_barcode.push_back(std::pair<double, double>(barcode_initial[i].second, barcode_initial[i].first));
+ continue;
+ } else {
+ if (barcode_initial[i].second != std::numeric_limits<double>::infinity()) {
+ if (dbg) std::cout << "Simply enters\n";
+ // in this case, due to the previous conditions we know that barcode_initial[i].first <
+ // barcode_initial[i].second, so we put them as they are
+ final_barcode.push_back(std::pair<double, double>(barcode_initial[i].first, barcode_initial[i].second));
+ }
+ }
+
+ if ((barcode_initial[i].second == std::numeric_limits<double>::infinity()) &&
+ (what_to_substitute_for_infinite_bar != -1)) {
+ if (barcode_initial[i].first < what_to_substitute_for_infinite_bar) // if only birth < death.
+ {
+ final_barcode.push_back(
+ std::pair<double, double>(barcode_initial[i].first, what_to_substitute_for_infinite_bar));
+ }
+ } else {
+ // if the variable what_to_substitute_for_infinite_bar is not set, then we ignore all the infinite bars.
+ }
}
-
-
- if ( dbg )
- {
- std::cerr << "Here are the final bars that we are sending further : \n";
- for ( size_t i = 0 ; i != final_barcode.size() ; ++i )
- {
- std::cout << final_barcode[i].first << " " << final_barcode[i].second << std::endl;
- }
- std::cerr << "final_barcode.size() : " << final_barcode.size() << std::endl;
- getchar();
+
+ if (dbg) {
+ std::cerr << "Here are the final bars that we are sending further : \n";
+ for (size_t i = 0; i != final_barcode.size(); ++i) {
+ std::cout << final_barcode[i].first << " " << final_barcode[i].second << std::endl;
+ }
+ std::cerr << "final_barcode.size() : " << final_barcode.size() << std::endl;
+ getchar();
}
-
-
-
- return final_barcode;
+
+ return final_barcode;
} // read_persistence_intervals_in_one_dimension_from_file
} // namespace Persistence_representations
diff --git a/src/Persistence_representations/test/CMakeLists.txt b/src/Persistence_representations/test/CMakeLists.txt
index 4483de07..335a71ef 100644
--- a/src/Persistence_representations/test/CMakeLists.txt
+++ b/src/Persistence_representations/test/CMakeLists.txt
@@ -6,38 +6,38 @@ include(GUDHI_test_coverage)
# copy data directory for tests purpose.
file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
add_executable ( Persistence_intervals_test_unit persistence_intervals_test.cpp )
-target_link_libraries(Persistence_intervals_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+target_link_libraries(Persistence_intervals_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
gudhi_add_coverage_test(Persistence_intervals_test_unit)
add_executable (Vector_representation_test_unit vector_representation_test.cpp )
-target_link_libraries(Vector_representation_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+target_link_libraries(Vector_representation_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
gudhi_add_coverage_test(Vector_representation_test_unit)
add_executable (Persistence_lanscapes_test_unit persistence_lanscapes_test.cpp )
-target_link_libraries(Persistence_lanscapes_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+target_link_libraries(Persistence_lanscapes_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
gudhi_add_coverage_test(Persistence_lanscapes_test_unit)
add_executable ( Persistence_lanscapes_on_grid_test_unit persistence_lanscapes_on_grid_test.cpp )
-target_link_libraries(Persistence_lanscapes_on_grid_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+target_link_libraries(Persistence_lanscapes_on_grid_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
gudhi_add_coverage_test(Persistence_lanscapes_on_grid_test_unit)
add_executable (Persistence_heat_maps_test_unit persistence_heat_maps_test.cpp )
-target_link_libraries(Persistence_heat_maps_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+target_link_libraries(Persistence_heat_maps_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
gudhi_add_coverage_test(Persistence_heat_maps_test_unit)
add_executable ( Read_persistence_from_file_test_unit read_persistence_from_file_test.cpp )
-target_link_libraries(Read_persistence_from_file_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+target_link_libraries(Read_persistence_from_file_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
gudhi_add_coverage_test(Read_persistence_from_file_test_unit)
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
add_executable (Persistence_intervals_with_distances_test_unit persistence_intervals_with_distances_test.cpp )
- target_link_libraries(Persistence_intervals_with_distances_test_unit ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ target_link_libraries(Persistence_intervals_with_distances_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
if (TBB_FOUND)
target_link_libraries(Persistence_intervals_with_distances_test_unit ${TBB_LIBRARIES})
endif(TBB_FOUND)
diff --git a/src/Persistence_representations/test/persistence_heat_maps_test.cpp b/src/Persistence_representations/test/persistence_heat_maps_test.cpp
index 1f1502f5..e36108b7 100644
--- a/src/Persistence_representations/test/persistence_heat_maps_test.cpp
+++ b/src/Persistence_representations/test/persistence_heat_maps_test.cpp
@@ -25,12 +25,15 @@
#include <boost/test/unit_test.hpp>
#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_heat_maps.h>
+#include <gudhi/Unitary_tests_utils.h>
#include <iostream>
using namespace Gudhi;
using namespace Gudhi::Persistence_representations;
+double epsilon = 0.0005;
+
BOOST_AUTO_TEST_CASE(check_construction_of_heat_maps) {
std::vector<std::vector<double> > filter = create_Gaussian_filter(100, 1);
Persistence_heat_maps<constant_scaling_function> p("data/file_with_diagram", filter, false, 1000, 0, 1);
@@ -139,28 +142,15 @@ BOOST_AUTO_TEST_CASE(check_distance_for_heat_maps) {
Persistence_heat_maps<constant_scaling_function> q("data/file_with_diagram_1", filter, false, 1000, 0, 1);
Persistence_heat_maps<constant_scaling_function> r("data/file_with_diagram_2", filter, false, 1000, 0, 1);
- // cerr << p.distance( p ) << endl;
- // cerr << p.distance( q ) << endl;
- // cerr << p.distance( r ) << endl;
- // cerr << q.distance( p ) << endl;
- // cerr << q.distance( q ) << endl;
- // cerr << q.distance( r ) << endl;
- // cerr << r.distance( p ) << endl;
- // cerr << r.distance( q ) << endl;
- // cerr << r.distance( r ) << endl;
- // 0 624.183 415.815
- // 624.183 0 528.06Z
- // 415.815 528.066 0
-
- BOOST_CHECK(fabs(p.distance(p) - 0) < 0.0005);
- BOOST_CHECK(fabs(p.distance(q) - 624.183) < 0.0005);
- BOOST_CHECK(fabs(p.distance(r) - 415.815) < 0.0005);
- BOOST_CHECK(fabs(q.distance(p) - 624.183) < 0.0005);
- BOOST_CHECK(fabs(q.distance(q) - 0) < 0.0005);
- BOOST_CHECK(fabs(q.distance(r) - 528.066) < 0.0005);
- BOOST_CHECK(fabs(r.distance(p) - 415.815) < 0.0005);
- BOOST_CHECK(fabs(r.distance(q) - 528.066) < 0.0005);
- BOOST_CHECK(fabs(r.distance(r) - 0) < 0.0005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(p), 0., epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q), 624.183, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(r), 415.815, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.distance(p), 624.183, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.distance(q), 0., epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.distance(r), 528.066, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.distance(p), 415.815, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.distance(q), 528.066, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.distance(r), 0., epsilon);
}
BOOST_AUTO_TEST_CASE(check_projections_to_R_for_heat_maps) {
@@ -169,13 +159,9 @@ BOOST_AUTO_TEST_CASE(check_projections_to_R_for_heat_maps) {
Persistence_heat_maps<constant_scaling_function> q("data/file_with_diagram_1", filter, false, 1000, 0, 1);
Persistence_heat_maps<constant_scaling_function> r("data/file_with_diagram_2", filter, false, 1000, 0, 1);
- // cerr << p.project_to_R(0) << endl;
- // cerr << q.project_to_R(0) << endl;
- // cerr << r.project_to_R(0) << endl;
-
- BOOST_CHECK(fabs(p.project_to_R(0) - 44.3308) < 0.0005);
- BOOST_CHECK(fabs(q.project_to_R(0) - 650.568) < 0.0005);
- BOOST_CHECK(fabs(r.project_to_R(0) - 429.287) < 0.0005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.project_to_R(0), 44.3308, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.project_to_R(0), 650.568, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.project_to_R(0), 429.287, epsilon);
}
BOOST_AUTO_TEST_CASE(check_scalar_products_for_heat_maps) {
@@ -184,25 +170,15 @@ BOOST_AUTO_TEST_CASE(check_scalar_products_for_heat_maps) {
Persistence_heat_maps<constant_scaling_function> q("data/file_with_diagram_1", filter, false, 1000, 0, 1);
Persistence_heat_maps<constant_scaling_function> r("data/file_with_diagram_2", filter, false, 1000, 0, 1);
- // cerr << p.compute_scalar_product( p ) << endl;
- // cerr << p.compute_scalar_product( q ) << endl;
- // cerr << p.compute_scalar_product( r ) << endl;
- // cerr << q.compute_scalar_product( p ) << endl;
- // cerr << q.compute_scalar_product( q ) << endl;
- // cerr << q.compute_scalar_product( r ) << endl;
- // cerr << r.compute_scalar_product( p ) << endl;
- // cerr << r.compute_scalar_product( q ) << endl;
- // cerr << r.compute_scalar_product( r ) << endl;
-
- BOOST_CHECK(fabs(p.compute_scalar_product(p) - 0.0345687) < 0.0005);
- BOOST_CHECK(fabs(p.compute_scalar_product(q) - 0.0509357) < 0.0005);
- BOOST_CHECK(fabs(p.compute_scalar_product(r) - 0.0375608) < 0.0005);
- BOOST_CHECK(fabs(q.compute_scalar_product(p) - 0.0509357) < 0.0005);
- BOOST_CHECK(fabs(q.compute_scalar_product(q) - 1.31293) < 0.0005);
- BOOST_CHECK(fabs(q.compute_scalar_product(r) - 0.536799) < 0.0005);
- BOOST_CHECK(fabs(r.compute_scalar_product(p) - 0.0375608) < 0.0005);
- BOOST_CHECK(fabs(r.compute_scalar_product(q) - 0.536799) < 0.0005);
- BOOST_CHECK(fabs(r.compute_scalar_product(r) - 0.672907) < 0.0005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_scalar_product(p), 0.0345687, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_scalar_product(q), 0.0509357, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_scalar_product(r), 0.0375608, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.compute_scalar_product(p), 0.0509357, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.compute_scalar_product(q), 1.31293, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(q.compute_scalar_product(r), 0.536799, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.compute_scalar_product(p), 0.0375608, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.compute_scalar_product(q), 0.536799, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(r.compute_scalar_product(r), 0.672907, epsilon);
}
BOOST_AUTO_TEST_CASE(check_arythmetic_operations_for_heat_maps) {
diff --git a/src/Persistence_representations/test/persistence_intervals_test.cpp b/src/Persistence_representations/test/persistence_intervals_test.cpp
index 545330c4..f555e243 100644
--- a/src/Persistence_representations/test/persistence_intervals_test.cpp
+++ b/src/Persistence_representations/test/persistence_intervals_test.cpp
@@ -25,25 +25,20 @@
#include <boost/test/unit_test.hpp>
#include <gudhi/reader_utils.h>
#include "gudhi/Persistence_intervals.h"
+#include <gudhi/common_persistence_representations.h>
+#include <gudhi/Unitary_tests_utils.h>
#include <iostream>
using namespace Gudhi;
using namespace Gudhi::Persistence_representations;
-double epsilon = 0.0000005;
-
-// cout << "Left most end of the interval : " << min_max_.first << std::endl;
-// cout << "Right most end of the interval : " << min_max_.second << std::endl;
BOOST_AUTO_TEST_CASE(check_min_max_function) {
- std::cerr << "First test \n";
Persistence_intervals p("data/file_with_diagram");
std::pair<double, double> min_max_ = p.get_x_range();
- // cout << min_max_.first << " " << min_max_.second << std::endl;getchar();
-
- BOOST_CHECK(fabs(min_max_.first - 0.0290362) <= epsilon);
- BOOST_CHECK(fabs(min_max_.second - 0.994537) <= epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(min_max_.first, 0.0290362, Gudhi::Persistence_representations::epsi);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(min_max_.second, 0.994537, Gudhi::Persistence_representations::epsi);
}
BOOST_AUTO_TEST_CASE(check_length_of_dominant_intervals) {
@@ -61,7 +56,8 @@ BOOST_AUTO_TEST_CASE(check_length_of_dominant_intervals) {
dominant_intervals_length.push_back(0.700468);
dominant_intervals_length.push_back(0.622177);
for (size_t i = 0; i != dominant_ten_intervals_length.size(); ++i) {
- BOOST_CHECK(fabs(dominant_ten_intervals_length[i] - dominant_intervals_length[i]) <= epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(dominant_ten_intervals_length[i], dominant_intervals_length[i],
+ Gudhi::Persistence_representations::epsi);
}
}
BOOST_AUTO_TEST_CASE(check_dominant_intervals) {
@@ -81,8 +77,10 @@ BOOST_AUTO_TEST_CASE(check_dominant_intervals) {
templ.push_back(std::pair<double, double>(0.267421, 0.889597));
for (size_t i = 0; i != ten_dominant_intervals.size(); ++i) {
- BOOST_CHECK(fabs(ten_dominant_intervals[i].first - templ[i].first) <= epsilon);
- BOOST_CHECK(fabs(ten_dominant_intervals[i].second - templ[i].second) <= epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(ten_dominant_intervals[i].first, templ[i].first,
+ Gudhi::Persistence_representations::epsi);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(ten_dominant_intervals[i].second, templ[i].second,
+ Gudhi::Persistence_representations::epsi);
}
}
@@ -102,7 +100,7 @@ BOOST_AUTO_TEST_CASE(check_histogram_of_lengths) {
template_histogram.push_back(1);
template_histogram.push_back(1);
for (size_t i = 0; i != histogram.size(); ++i) {
- BOOST_CHECK(fabs(histogram[i] - template_histogram[i]) <= epsilon);
+ BOOST_CHECK(histogram[i] == template_histogram[i]);
}
}
@@ -123,7 +121,7 @@ BOOST_AUTO_TEST_CASE(check_cumulative_histograms_of_lengths) {
template_cumulative_histogram.push_back(45);
for (size_t i = 0; i != cumulative_histogram.size(); ++i) {
- BOOST_CHECK(fabs(cumulative_histogram[i] - template_cumulative_histogram[i]) <= epsilon);
+ BOOST_CHECK(cumulative_histogram[i] == template_cumulative_histogram[i]);
}
}
BOOST_AUTO_TEST_CASE(check_characteristic_function_of_diagram) {
@@ -143,15 +141,8 @@ BOOST_AUTO_TEST_CASE(check_characteristic_function_of_diagram) {
template_char_funct_diag.push_back(0.0676303);
for (size_t i = 0; i != char_funct_diag.size(); ++i) {
- // cout << char_funct_diag[i] << std::endl;
- if (fabs(char_funct_diag[i] - template_char_funct_diag[i]) >= 0.0001) {
- std::cout << "Boost test fail check_characteristic_function_of_diagram : " << std::endl;
- std::cerr << char_funct_diag[i] << " " << template_char_funct_diag[i] << std::endl;
- std::cerr << fabs(char_funct_diag[i] - template_char_funct_diag[i]) << std::endl;
- std::cerr << 0.0001 << std::endl;
- //getchar();
- }
- BOOST_CHECK(fabs(char_funct_diag[i] - template_char_funct_diag[i]) <= 0.0001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(char_funct_diag[i], template_char_funct_diag[i],
+ Gudhi::Persistence_representations::epsi);
}
}
@@ -174,110 +165,109 @@ BOOST_AUTO_TEST_CASE(check_cumulative_characteristic_function_of_diagram) {
template_char_funct_diag_cumul.push_back(9.48386);
for (size_t i = 0; i != cumul_char_funct_diag.size(); ++i) {
- // cout << cumul_char_funct_diag[i] << std::endl;
- BOOST_CHECK(fabs(cumul_char_funct_diag[i] - template_char_funct_diag_cumul[i]) <= 0.0001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(cumul_char_funct_diag[i], template_char_funct_diag_cumul[i],
+ Gudhi::Persistence_representations::epsi);
}
}
BOOST_AUTO_TEST_CASE(check_compute_persistent_betti_numbers) {
Persistence_intervals p("data/file_with_diagram");
- std::vector<std::pair<double, double> > pbns;
- pbns.push_back(std::pair<double, double>(0.0290362, 1));
- pbns.push_back(std::pair<double, double>(0.0307676, 2));
- pbns.push_back(std::pair<double, double>(0.0366312, 3));
- pbns.push_back(std::pair<double, double>(0.0544614, 4));
- pbns.push_back(std::pair<double, double>(0.0920033, 5));
- pbns.push_back(std::pair<double, double>(0.104599, 6));
- pbns.push_back(std::pair<double, double>(0.114718, 7));
- pbns.push_back(std::pair<double, double>(0.117379, 8));
- pbns.push_back(std::pair<double, double>(0.123493, 9));
- pbns.push_back(std::pair<double, double>(0.133638, 10));
- pbns.push_back(std::pair<double, double>(0.137798, 9));
- pbns.push_back(std::pair<double, double>(0.149798, 10));
- pbns.push_back(std::pair<double, double>(0.155421, 11));
- pbns.push_back(std::pair<double, double>(0.158443, 12));
- pbns.push_back(std::pair<double, double>(0.176956, 13));
- pbns.push_back(std::pair<double, double>(0.183234, 12));
- pbns.push_back(std::pair<double, double>(0.191069, 13));
- pbns.push_back(std::pair<double, double>(0.191333, 14));
- pbns.push_back(std::pair<double, double>(0.191836, 15));
- pbns.push_back(std::pair<double, double>(0.192675, 16));
- pbns.push_back(std::pair<double, double>(0.208564, 17));
- pbns.push_back(std::pair<double, double>(0.218425, 18));
- pbns.push_back(std::pair<double, double>(0.219902, 17));
- pbns.push_back(std::pair<double, double>(0.23233, 16));
- pbns.push_back(std::pair<double, double>(0.234558, 17));
- pbns.push_back(std::pair<double, double>(0.237166, 16));
- pbns.push_back(std::pair<double, double>(0.247352, 17));
- pbns.push_back(std::pair<double, double>(0.267421, 18));
- pbns.push_back(std::pair<double, double>(0.268093, 19));
- pbns.push_back(std::pair<double, double>(0.278734, 18));
- pbns.push_back(std::pair<double, double>(0.284722, 19));
- pbns.push_back(std::pair<double, double>(0.284998, 20));
- pbns.push_back(std::pair<double, double>(0.294069, 21));
- pbns.push_back(std::pair<double, double>(0.306293, 22));
- pbns.push_back(std::pair<double, double>(0.322361, 21));
- pbns.push_back(std::pair<double, double>(0.323152, 22));
- pbns.push_back(std::pair<double, double>(0.371021, 23));
- pbns.push_back(std::pair<double, double>(0.372395, 24));
- pbns.push_back(std::pair<double, double>(0.387744, 25));
- pbns.push_back(std::pair<double, double>(0.435537, 26));
- pbns.push_back(std::pair<double, double>(0.462911, 25));
- pbns.push_back(std::pair<double, double>(0.483569, 26));
- pbns.push_back(std::pair<double, double>(0.489209, 25));
- pbns.push_back(std::pair<double, double>(0.517115, 24));
- pbns.push_back(std::pair<double, double>(0.522197, 23));
- pbns.push_back(std::pair<double, double>(0.532665, 22));
- pbns.push_back(std::pair<double, double>(0.545262, 23));
- pbns.push_back(std::pair<double, double>(0.587227, 22));
- pbns.push_back(std::pair<double, double>(0.593036, 23));
- pbns.push_back(std::pair<double, double>(0.602647, 24));
- pbns.push_back(std::pair<double, double>(0.605044, 25));
- pbns.push_back(std::pair<double, double>(0.621962, 24));
- pbns.push_back(std::pair<double, double>(0.629449, 23));
- pbns.push_back(std::pair<double, double>(0.636719, 22));
- pbns.push_back(std::pair<double, double>(0.64957, 21));
- pbns.push_back(std::pair<double, double>(0.650781, 22));
- pbns.push_back(std::pair<double, double>(0.654951, 23));
- pbns.push_back(std::pair<double, double>(0.683489, 24));
- pbns.push_back(std::pair<double, double>(0.687172, 23));
- pbns.push_back(std::pair<double, double>(0.69703, 22));
- pbns.push_back(std::pair<double, double>(0.701174, 21));
- pbns.push_back(std::pair<double, double>(0.717623, 22));
- pbns.push_back(std::pair<double, double>(0.722023, 21));
- pbns.push_back(std::pair<double, double>(0.722298, 20));
- pbns.push_back(std::pair<double, double>(0.725347, 19));
- pbns.push_back(std::pair<double, double>(0.73071, 18));
- pbns.push_back(std::pair<double, double>(0.758355, 17));
- pbns.push_back(std::pair<double, double>(0.770913, 18));
- pbns.push_back(std::pair<double, double>(0.790833, 17));
- pbns.push_back(std::pair<double, double>(0.821211, 16));
- pbns.push_back(std::pair<double, double>(0.849305, 17));
- pbns.push_back(std::pair<double, double>(0.853669, 16));
- pbns.push_back(std::pair<double, double>(0.866659, 15));
- pbns.push_back(std::pair<double, double>(0.872896, 16));
- pbns.push_back(std::pair<double, double>(0.889597, 15));
- pbns.push_back(std::pair<double, double>(0.900231, 14));
- pbns.push_back(std::pair<double, double>(0.903847, 13));
- pbns.push_back(std::pair<double, double>(0.906299, 12));
- pbns.push_back(std::pair<double, double>(0.910852, 11));
- pbns.push_back(std::pair<double, double>(0.93453, 10));
- pbns.push_back(std::pair<double, double>(0.944757, 9));
- pbns.push_back(std::pair<double, double>(0.947812, 8));
- pbns.push_back(std::pair<double, double>(0.959154, 7));
- pbns.push_back(std::pair<double, double>(0.975654, 6));
- pbns.push_back(std::pair<double, double>(0.976719, 5));
- pbns.push_back(std::pair<double, double>(0.977343, 4));
- pbns.push_back(std::pair<double, double>(0.980129, 3));
- pbns.push_back(std::pair<double, double>(0.987842, 2));
- pbns.push_back(std::pair<double, double>(0.990127, 1));
- pbns.push_back(std::pair<double, double>(0.994537, 0));
+ std::vector<std::pair<double, size_t> > pbns;
+ pbns.push_back(std::pair<double, size_t>(0.0290362, 1));
+ pbns.push_back(std::pair<double, size_t>(0.0307676, 2));
+ pbns.push_back(std::pair<double, size_t>(0.0366312, 3));
+ pbns.push_back(std::pair<double, size_t>(0.0544614, 4));
+ pbns.push_back(std::pair<double, size_t>(0.0920033, 5));
+ pbns.push_back(std::pair<double, size_t>(0.104599, 6));
+ pbns.push_back(std::pair<double, size_t>(0.114718, 7));
+ pbns.push_back(std::pair<double, size_t>(0.117379, 8));
+ pbns.push_back(std::pair<double, size_t>(0.123493, 9));
+ pbns.push_back(std::pair<double, size_t>(0.133638, 10));
+ pbns.push_back(std::pair<double, size_t>(0.137798, 9));
+ pbns.push_back(std::pair<double, size_t>(0.149798, 10));
+ pbns.push_back(std::pair<double, size_t>(0.155421, 11));
+ pbns.push_back(std::pair<double, size_t>(0.158443, 12));
+ pbns.push_back(std::pair<double, size_t>(0.176956, 13));
+ pbns.push_back(std::pair<double, size_t>(0.183234, 12));
+ pbns.push_back(std::pair<double, size_t>(0.191069, 13));
+ pbns.push_back(std::pair<double, size_t>(0.191333, 14));
+ pbns.push_back(std::pair<double, size_t>(0.191836, 15));
+ pbns.push_back(std::pair<double, size_t>(0.192675, 16));
+ pbns.push_back(std::pair<double, size_t>(0.208564, 17));
+ pbns.push_back(std::pair<double, size_t>(0.218425, 18));
+ pbns.push_back(std::pair<double, size_t>(0.219902, 17));
+ pbns.push_back(std::pair<double, size_t>(0.23233, 16));
+ pbns.push_back(std::pair<double, size_t>(0.234558, 17));
+ pbns.push_back(std::pair<double, size_t>(0.237166, 16));
+ pbns.push_back(std::pair<double, size_t>(0.247352, 17));
+ pbns.push_back(std::pair<double, size_t>(0.267421, 18));
+ pbns.push_back(std::pair<double, size_t>(0.268093, 19));
+ pbns.push_back(std::pair<double, size_t>(0.278734, 18));
+ pbns.push_back(std::pair<double, size_t>(0.284722, 19));
+ pbns.push_back(std::pair<double, size_t>(0.284998, 20));
+ pbns.push_back(std::pair<double, size_t>(0.294069, 21));
+ pbns.push_back(std::pair<double, size_t>(0.306293, 22));
+ pbns.push_back(std::pair<double, size_t>(0.322361, 21));
+ pbns.push_back(std::pair<double, size_t>(0.323152, 22));
+ pbns.push_back(std::pair<double, size_t>(0.371021, 23));
+ pbns.push_back(std::pair<double, size_t>(0.372395, 24));
+ pbns.push_back(std::pair<double, size_t>(0.387744, 25));
+ pbns.push_back(std::pair<double, size_t>(0.435537, 26));
+ pbns.push_back(std::pair<double, size_t>(0.462911, 25));
+ pbns.push_back(std::pair<double, size_t>(0.483569, 26));
+ pbns.push_back(std::pair<double, size_t>(0.489209, 25));
+ pbns.push_back(std::pair<double, size_t>(0.517115, 24));
+ pbns.push_back(std::pair<double, size_t>(0.522197, 23));
+ pbns.push_back(std::pair<double, size_t>(0.532665, 22));
+ pbns.push_back(std::pair<double, size_t>(0.545262, 23));
+ pbns.push_back(std::pair<double, size_t>(0.587227, 22));
+ pbns.push_back(std::pair<double, size_t>(0.593036, 23));
+ pbns.push_back(std::pair<double, size_t>(0.602647, 24));
+ pbns.push_back(std::pair<double, size_t>(0.605044, 25));
+ pbns.push_back(std::pair<double, size_t>(0.621962, 24));
+ pbns.push_back(std::pair<double, size_t>(0.629449, 23));
+ pbns.push_back(std::pair<double, size_t>(0.636719, 22));
+ pbns.push_back(std::pair<double, size_t>(0.64957, 21));
+ pbns.push_back(std::pair<double, size_t>(0.650781, 22));
+ pbns.push_back(std::pair<double, size_t>(0.654951, 23));
+ pbns.push_back(std::pair<double, size_t>(0.683489, 24));
+ pbns.push_back(std::pair<double, size_t>(0.687172, 23));
+ pbns.push_back(std::pair<double, size_t>(0.69703, 22));
+ pbns.push_back(std::pair<double, size_t>(0.701174, 21));
+ pbns.push_back(std::pair<double, size_t>(0.717623, 22));
+ pbns.push_back(std::pair<double, size_t>(0.722023, 21));
+ pbns.push_back(std::pair<double, size_t>(0.722298, 20));
+ pbns.push_back(std::pair<double, size_t>(0.725347, 19));
+ pbns.push_back(std::pair<double, size_t>(0.73071, 18));
+ pbns.push_back(std::pair<double, size_t>(0.758355, 17));
+ pbns.push_back(std::pair<double, size_t>(0.770913, 18));
+ pbns.push_back(std::pair<double, size_t>(0.790833, 17));
+ pbns.push_back(std::pair<double, size_t>(0.821211, 16));
+ pbns.push_back(std::pair<double, size_t>(0.849305, 17));
+ pbns.push_back(std::pair<double, size_t>(0.853669, 16));
+ pbns.push_back(std::pair<double, size_t>(0.866659, 15));
+ pbns.push_back(std::pair<double, size_t>(0.872896, 16));
+ pbns.push_back(std::pair<double, size_t>(0.889597, 15));
+ pbns.push_back(std::pair<double, size_t>(0.900231, 14));
+ pbns.push_back(std::pair<double, size_t>(0.903847, 13));
+ pbns.push_back(std::pair<double, size_t>(0.906299, 12));
+ pbns.push_back(std::pair<double, size_t>(0.910852, 11));
+ pbns.push_back(std::pair<double, size_t>(0.93453, 10));
+ pbns.push_back(std::pair<double, size_t>(0.944757, 9));
+ pbns.push_back(std::pair<double, size_t>(0.947812, 8));
+ pbns.push_back(std::pair<double, size_t>(0.959154, 7));
+ pbns.push_back(std::pair<double, size_t>(0.975654, 6));
+ pbns.push_back(std::pair<double, size_t>(0.976719, 5));
+ pbns.push_back(std::pair<double, size_t>(0.977343, 4));
+ pbns.push_back(std::pair<double, size_t>(0.980129, 3));
+ pbns.push_back(std::pair<double, size_t>(0.987842, 2));
+ pbns.push_back(std::pair<double, size_t>(0.990127, 1));
+ pbns.push_back(std::pair<double, size_t>(0.994537, 0));
std::vector<std::pair<double, size_t> > pbns_new = p.compute_persistent_betti_numbers();
for (size_t i = 0; i != pbns.size(); ++i) {
- // cout << pbns_new[i].first << "," << pbns_new[i].second << std::endl;
- BOOST_CHECK(fabs(pbns[i].first - pbns_new[i].first) <= epsilon);
- BOOST_CHECK(fabs(pbns[i].second - pbns_new[i].second) <= epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(pbns[i].first, pbns_new[i].first, Gudhi::Persistence_representations::epsi);
+ BOOST_CHECK(pbns[i].second == pbns_new[i].second);
}
}
@@ -297,7 +287,6 @@ BOOST_AUTO_TEST_CASE(check_k_n_n) {
knn_template.push_back(0.786945);
for (size_t i = 0; i != knn.size(); ++i) {
- // cout << knn[i] << std::endl;
- BOOST_CHECK(fabs(knn[i] - knn_template[i]) <= 0.000005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(knn[i], knn_template[i], Gudhi::Persistence_representations::epsi);
}
}
diff --git a/src/Persistence_representations/test/persistence_intervals_with_distances_test.cpp b/src/Persistence_representations/test/persistence_intervals_with_distances_test.cpp
index 7b70eee3..631e4d70 100644
--- a/src/Persistence_representations/test/persistence_intervals_with_distances_test.cpp
+++ b/src/Persistence_representations/test/persistence_intervals_with_distances_test.cpp
@@ -24,8 +24,9 @@
#define BOOST_TEST_MODULE "Persistence_intervals_with_distances_test"
#include <boost/test/unit_test.hpp>
#include <gudhi/reader_utils.h>
-#include "gudhi/Persistence_intervals_with_distances.h"
-#include "gudhi/common_persistence_representations.h"
+#include <gudhi/Persistence_intervals_with_distances.h>
+#include <gudhi/common_persistence_representations.h>
+#include <gudhi/Unitary_tests_utils.h>
#include <iostream>
@@ -38,9 +39,7 @@ BOOST_AUTO_TEST_CASE(check_bottleneck_distances_computation) {
double dist = p.distance(q);
- // std::cout << "dist : " << dist << std::endl;
-
- BOOST_CHECK(almost_equal(dist, 0.389043));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(dist, 0.389043, Gudhi::Persistence_representations::epsi);
}
BOOST_AUTO_TEST_CASE(check_default_parameters_in_distance) {
@@ -51,11 +50,7 @@ BOOST_AUTO_TEST_CASE(check_default_parameters_in_distance) {
double max_parameter_distance = p.distance(q, std::numeric_limits<double>::max());
double inf_parameter_distance = p.distance(q, std::numeric_limits<double>::infinity());
- // std::cout << "default_parameter_distance : " << default_parameter_distance << std::endl;
- // std::cout << "max_parameter_distance : " << max_parameter_distance << std::endl;
- // std::cout << "inf_parameter_distance : " << inf_parameter_distance << std::endl;
-
- BOOST_CHECK(default_parameter_distance == max_parameter_distance);
- BOOST_CHECK(inf_parameter_distance == max_parameter_distance);
- BOOST_CHECK(inf_parameter_distance == max_parameter_distance);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(default_parameter_distance, max_parameter_distance);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(inf_parameter_distance, max_parameter_distance);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(inf_parameter_distance, max_parameter_distance);
}
diff --git a/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp b/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp
index 6b1608fe..130ac8cc 100644
--- a/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp
+++ b/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp
@@ -25,12 +25,15 @@
#include <boost/test/unit_test.hpp>
#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_landscape_on_grid.h>
+#include <gudhi/Unitary_tests_utils.h>
#include <iostream>
using namespace Gudhi;
using namespace Gudhi::Persistence_representations;
+double epsilon = 0.0005;
+
BOOST_AUTO_TEST_CASE(check_construction_of_landscape) {
Persistence_landscape_on_grid l("data/file_with_diagram_1", 100, std::numeric_limits<unsigned short>::max());
l.print_to_file("landscape_from_file_with_diagram_1");
@@ -53,16 +56,14 @@ BOOST_AUTO_TEST_CASE(check_construction_of_landscape_using_only_ten_levels) {
std::vector<double> v2 = g.vectorize(level);
BOOST_CHECK(v1.size() == v2.size());
for (size_t i = 0; i != v1.size(); ++i) {
- BOOST_CHECK(v1[i] == v2[i]);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(v1[i], v2[i]);
}
}
}
BOOST_AUTO_TEST_CASE(check_computations_of_integrals) {
Persistence_landscape_on_grid p("data/file_with_diagram_1", 100, std::numeric_limits<unsigned short>::max());
- double integral = p.compute_integral_of_landscape();
- // cerr << "integral : " << integral << endl;getchar();
- BOOST_CHECK(fabs(integral - 27.343) <= 0.00005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_integral_of_landscape(), 27.343, epsilon);
}
BOOST_AUTO_TEST_CASE(check_computations_of_integrals_for_each_level_separatelly) {
@@ -92,9 +93,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals_for_each_level_separatelly)
integrals_fir_different_levels.push_back(0.202633);
for (size_t level = 0; level != integrals_fir_different_levels.size(); ++level) {
- double integral = p.compute_integral_of_landscape(level);
- // cerr << integral << endl;
- BOOST_CHECK(fabs(integral - integrals_fir_different_levels[level]) <= 0.00005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_integral_of_landscape(level), integrals_fir_different_levels[level],
+ epsilon);
}
}
@@ -109,9 +109,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals_of_powers_of_landscape) {
integrals_fir_different_powers.push_back(0.23011);
for (size_t power = 0; power != 5; ++power) {
- double integral = p.compute_integral_of_landscape(power);
- // cerr << integral << endl;
- BOOST_CHECK(fabs(integral - integrals_fir_different_powers[power]) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_integral_of_landscape(power), integrals_fir_different_powers[power],
+ epsilon);
}
}
@@ -145,8 +144,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_values_on_different_points) {
double x = 0.0012321;
double dx = 0.05212;
for (size_t i = 0; i != 10; ++i) {
- BOOST_CHECK(almost_equal(p.compute_value_at_a_given_point(0, x), results_level_0[i]));
- BOOST_CHECK(almost_equal(p.compute_value_at_a_given_point(10, x), results_level_10[i]));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(0, x), results_level_0[i], epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(10, x), results_level_10[i], epsilon);
x += dx;
}
}
@@ -179,37 +178,27 @@ BOOST_AUTO_TEST_CASE(check_computations_of_maxima_and_norms) {
Persistence_landscape_on_grid second("data/file_with_diagram_2", 0., 1., 100);
Persistence_landscape_on_grid sum = p + second;
- // cerr << p.compute_maximum() << endl;
- // cerr << p.compute_norm_of_landscape(1) << endl;
- // cerr << p.compute_norm_of_landscape(2) << endl;
- // cerr << p.compute_norm_of_landscape(3) << endl;
- // cerr << compute_distance_of_landscapes_on_grid(p,sum,1) << endl;
- // cerr << compute_distance_of_landscapes_on_grid(p,sum,2) << endl;
- // cerr << compute_distance_of_landscapes_on_grid(p,sum,std::numeric_limits<double>::max()) << endl;
-
- BOOST_CHECK(fabs(p.compute_maximum() - 0.46) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_norm_of_landscape(1) - 27.3373) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_norm_of_landscape(2) - 1.84143) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_norm_of_landscape(3) - 0.927067) <= 0.00001);
- BOOST_CHECK(fabs(compute_distance_of_landscapes_on_grid(p, sum, 1) - 16.8519) <= 0.00005);
- BOOST_CHECK(fabs(compute_distance_of_landscapes_on_grid(p, sum, 2) - 1.44542) <= 0.00001);
- BOOST_CHECK(fabs(compute_distance_of_landscapes_on_grid(p, sum, std::numeric_limits<double>::max()) - 0.45) <=
- 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_maximum(), 0.46, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_norm_of_landscape(1), 27.3373, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_norm_of_landscape(2), 1.84143, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_norm_of_landscape(3), 0.927067, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(compute_distance_of_landscapes_on_grid(p, sum, 1), 16.8519, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(compute_distance_of_landscapes_on_grid(p, sum, 2), 1.44542, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(compute_distance_of_landscapes_on_grid(p, sum, std::numeric_limits<double>::max()),
+ 0.45, epsilon);
}
BOOST_AUTO_TEST_CASE(check_default_parameters_of_distances) {
- std::vector<std::pair<double, double> > diag =
- read_persistence_intervals_in_dimension("data/file_with_diagram");
+ std::vector<std::pair<double, double> > diag = read_persistence_intervals_in_dimension("data/file_with_diagram");
Persistence_landscape_on_grid p(diag, 0., 1., 100);
- std::vector<std::pair<double, double> > diag1 =
- read_persistence_intervals_in_dimension("data/file_with_diagram_1");
+ std::vector<std::pair<double, double> > diag1 = read_persistence_intervals_in_dimension("data/file_with_diagram_1");
Persistence_landscape_on_grid q(diag1, 0., 1., 100);
double dist_numeric_limit_max = p.distance(q, std::numeric_limits<double>::max());
double dist_infinity = p.distance(q, std::numeric_limits<double>::infinity());
- BOOST_CHECK(dist_numeric_limit_max == dist_infinity);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(dist_numeric_limit_max, dist_infinity);
}
BOOST_AUTO_TEST_CASE(check_computations_of_averages) {
@@ -226,16 +215,15 @@ BOOST_AUTO_TEST_CASE(check_computations_of_averages) {
BOOST_AUTO_TEST_CASE(check_computations_of_distances) {
Persistence_landscape_on_grid p("data/file_with_diagram", 0., 1., 10000);
Persistence_landscape_on_grid q("data/file_with_diagram_1", 0., 1., 10000);
- BOOST_CHECK(fabs(p.distance(q) - 25.5779) <= 0.00005);
- BOOST_CHECK(fabs(p.distance(q, 2) - 2.04891) <= 0.00001);
- BOOST_CHECK(fabs(p.distance(q, std::numeric_limits<double>::max()) - 0.359) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q), 25.5779, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q, 2), 2.04891, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q, std::numeric_limits<double>::max()), 0.359, epsilon);
}
BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) {
Persistence_landscape_on_grid p("data/file_with_diagram", 0., 1., 10000);
Persistence_landscape_on_grid q("data/file_with_diagram_1", 0., 1., 10000);
- // std::cerr << p.compute_scalar_product( q ) << std::endl;
- BOOST_CHECK(almost_equal(p.compute_scalar_product(q), 0.754367));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_scalar_product(q), 0.754367, epsilon);
}
// Below I am storing the code used to generate tests for that functionality.
diff --git a/src/Persistence_representations/test/persistence_lanscapes_test.cpp b/src/Persistence_representations/test/persistence_lanscapes_test.cpp
index 81adb6fa..e98ef894 100644
--- a/src/Persistence_representations/test/persistence_lanscapes_test.cpp
+++ b/src/Persistence_representations/test/persistence_lanscapes_test.cpp
@@ -25,6 +25,7 @@
#include <boost/test/unit_test.hpp>
#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_landscape.h>
+#include <gudhi/Unitary_tests_utils.h>
#include <iostream>
#include <limits>
@@ -32,14 +33,14 @@
using namespace Gudhi;
using namespace Gudhi::Persistence_representations;
-double epsilon = 0.0000005;
+double epsilon = 0.0005;
-BOOST_AUTO_TEST_CASE(check_construction_of_landscape) {
+BOOST_AUTO_TEST_CASE(check_construction_of_landscape) {
std::vector<std::pair<double, double> > diag =
- read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram");
+ read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram");
Persistence_landscape p(diag);
- Persistence_landscape q;
- q.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram");
+ Persistence_landscape q;
+ q.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram");
BOOST_CHECK(p == q);
}
@@ -47,19 +48,15 @@ BOOST_AUTO_TEST_CASE(check_construction_of_landscape_form_gudhi_style_file) {
Persistence_landscape p("data/persistence_file_with_four_entries_per_line", 1);
// p.print_to_file("persistence_file_with_four_entries_per_line_landscape");
Persistence_landscape q;
- q.load_landscape_from_file("data/persistence_file_with_four_entries_per_line_landscape");
+ q.load_landscape_from_file("data/persistence_file_with_four_entries_per_line_landscape");
BOOST_CHECK(p == q);
}
-
-
BOOST_AUTO_TEST_CASE(check_computations_of_integrals) {
std::vector<std::pair<double, double> > diag =
read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram");
Persistence_landscape p(diag);
- double integral = p.compute_integral_of_landscape();
- // cerr << integral << " " << 2.34992 << endl;
- BOOST_CHECK(fabs(integral - 2.34992) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_integral_of_landscape(), 2.34992, epsilon);
}
BOOST_AUTO_TEST_CASE(check_computations_of_integrals_for_each_level_separatelly) {
@@ -67,37 +64,37 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals_for_each_level_separatelly)
read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram");
Persistence_landscape p(diag);
- std::vector<double> integrals_fir_different_levels;
- integrals_fir_different_levels.push_back(0.216432);
- integrals_fir_different_levels.push_back(0.204763);
- integrals_fir_different_levels.push_back(0.188793);
- integrals_fir_different_levels.push_back(0.178856);
- integrals_fir_different_levels.push_back(0.163142);
- integrals_fir_different_levels.push_back(0.155015);
- integrals_fir_different_levels.push_back(0.143046);
- integrals_fir_different_levels.push_back(0.133765);
- integrals_fir_different_levels.push_back(0.123531);
- integrals_fir_different_levels.push_back(0.117393);
- integrals_fir_different_levels.push_back(0.111269);
- integrals_fir_different_levels.push_back(0.104283);
- integrals_fir_different_levels.push_back(0.0941308);
- integrals_fir_different_levels.push_back(0.0811208);
- integrals_fir_different_levels.push_back(0.0679001);
- integrals_fir_different_levels.push_back(0.0580801);
- integrals_fir_different_levels.push_back(0.0489647);
- integrals_fir_different_levels.push_back(0.0407936);
- integrals_fir_different_levels.push_back(0.0342599);
- integrals_fir_different_levels.push_back(0.02896);
- integrals_fir_different_levels.push_back(0.0239881);
- integrals_fir_different_levels.push_back(0.0171792);
- integrals_fir_different_levels.push_back(0.0071511);
- integrals_fir_different_levels.push_back(0.00462067);
- integrals_fir_different_levels.push_back(0.00229033);
- integrals_fir_different_levels.push_back(0.000195296);
+ std::vector<double> integrals_for_different_levels;
+ integrals_for_different_levels.push_back(0.216432);
+ integrals_for_different_levels.push_back(0.204763);
+ integrals_for_different_levels.push_back(0.188793);
+ integrals_for_different_levels.push_back(0.178856);
+ integrals_for_different_levels.push_back(0.163142);
+ integrals_for_different_levels.push_back(0.155015);
+ integrals_for_different_levels.push_back(0.143046);
+ integrals_for_different_levels.push_back(0.133765);
+ integrals_for_different_levels.push_back(0.123531);
+ integrals_for_different_levels.push_back(0.117393);
+ integrals_for_different_levels.push_back(0.111269);
+ integrals_for_different_levels.push_back(0.104283);
+ integrals_for_different_levels.push_back(0.0941308);
+ integrals_for_different_levels.push_back(0.0811208);
+ integrals_for_different_levels.push_back(0.0679001);
+ integrals_for_different_levels.push_back(0.0580801);
+ integrals_for_different_levels.push_back(0.0489647);
+ integrals_for_different_levels.push_back(0.0407936);
+ integrals_for_different_levels.push_back(0.0342599);
+ integrals_for_different_levels.push_back(0.02896);
+ integrals_for_different_levels.push_back(0.0239881);
+ integrals_for_different_levels.push_back(0.0171792);
+ integrals_for_different_levels.push_back(0.0071511);
+ integrals_for_different_levels.push_back(0.00462067);
+ integrals_for_different_levels.push_back(0.00229033);
+ integrals_for_different_levels.push_back(0.000195296);
for (size_t level = 0; level != p.size(); ++level) {
- double integral = p.compute_integral_of_a_level_of_a_landscape(level);
- BOOST_CHECK(fabs(integral - integrals_fir_different_levels[level]) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_integral_of_a_level_of_a_landscape(level),
+ integrals_for_different_levels[level], epsilon);
}
}
@@ -106,16 +103,16 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals_of_powers_of_landscape) {
read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram");
Persistence_landscape p(diag);
- std::vector<double> integrals_fir_different_powers;
- integrals_fir_different_powers.push_back(17.1692);
- integrals_fir_different_powers.push_back(2.34992);
- integrals_fir_different_powers.push_back(0.49857);
- integrals_fir_different_powers.push_back(0.126405);
- integrals_fir_different_powers.push_back(0.0355235);
+ std::vector<double> integrals_for_different_powers;
+ integrals_for_different_powers.push_back(17.1692);
+ integrals_for_different_powers.push_back(2.34992);
+ integrals_for_different_powers.push_back(0.49857);
+ integrals_for_different_powers.push_back(0.126405);
+ integrals_for_different_powers.push_back(0.0355235);
for (size_t power = 0; power != 5; ++power) {
- double integral = p.compute_integral_of_landscape((double)power);
- BOOST_CHECK(fabs(integral - integrals_fir_different_powers[power]) <= 0.00005);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_integral_of_landscape((double)power),
+ integrals_for_different_powers[power], epsilon);
}
}
@@ -124,18 +121,18 @@ BOOST_AUTO_TEST_CASE(check_computations_of_values_on_different_points) {
read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram");
Persistence_landscape p(diag);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(1, 0.0)) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(1, 0.1) - 0.0692324) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(1, 0.2) - 0.163369) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(1, 0.3) - 0.217115) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(2, 0.0)) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(2, 0.1) - 0.0633688) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(2, 0.2) - 0.122361) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(2, 0.3) - 0.195401) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(3, 0.0)) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(3, 0.1) - 0.0455386) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(3, 0.2) - 0.0954012) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_value_at_a_given_point(3, 0.3) - 0.185282) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(1, 0.0), 0., epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(1, 0.1), 0.0692324, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(1, 0.2), 0.163369, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(1, 0.3), 0.217115, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(2, 0.0), 0., epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(2, 0.1), 0.0633688, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(2, 0.2), 0.122361, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(2, 0.3), 0.195401, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(3, 0.0), 0., epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(3, 0.1), 0.0455386, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(3, 0.2), 0.0954012, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_value_at_a_given_point(3, 0.3), 0.185282, epsilon);
}
BOOST_AUTO_TEST_CASE(check_computations_sum_differences_and_multiplications) {
@@ -171,13 +168,14 @@ BOOST_AUTO_TEST_CASE(check_computations_of_maxima_and_norms) {
second.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram_1");
Persistence_landscape sum = p + second;
- BOOST_CHECK(fabs(p.compute_maximum() - 0.431313) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_norm_of_landscape(1) - 2.34992) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_norm_of_landscape(2) - 0.706095) <= 0.00001);
- BOOST_CHECK(fabs(p.compute_norm_of_landscape(3) - 0.501867) <= 0.00001);
- BOOST_CHECK(fabs(compute_distance_of_landscapes(p, sum, 1) - 27.9323) <= 0.00005);
- BOOST_CHECK(fabs(compute_distance_of_landscapes(p, sum, 2) - 2.35199) <= 0.00001);
- BOOST_CHECK(fabs(compute_distance_of_landscapes(p, sum, std::numeric_limits<double>::max()) - 0.464478) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_maximum(), 0.431313, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_norm_of_landscape(1), 2.34992, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_norm_of_landscape(2), 0.706095, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_norm_of_landscape(3), 0.501867, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(compute_distance_of_landscapes(p, sum, 1), 27.9323, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(compute_distance_of_landscapes(p, sum, 2), 2.35199, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(compute_distance_of_landscapes(p, sum, std::numeric_limits<double>::max()), 0.464478,
+ epsilon);
}
BOOST_AUTO_TEST_CASE(check_default_parameters_of_distances) {
@@ -192,7 +190,7 @@ BOOST_AUTO_TEST_CASE(check_default_parameters_of_distances) {
double dist_numeric_limit_max = p.distance(q, std::numeric_limits<double>::max());
double dist_infinity = p.distance(q, std::numeric_limits<double>::infinity());
- BOOST_CHECK(dist_numeric_limit_max == dist_infinity);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(dist_numeric_limit_max, dist_infinity);
}
BOOST_AUTO_TEST_CASE(check_computations_of_averages) {
@@ -217,13 +215,9 @@ BOOST_AUTO_TEST_CASE(check_computations_of_distances) {
std::vector<std::pair<double, double> > diag2 =
read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1");
Persistence_landscape q(diag2);
- std::cout << "p.distance(q) = " << p.distance(q) << std::endl;
- BOOST_CHECK(fabs(p.distance(q) - 25.5824) <= 0.00005);
- std::cout << "p.distance(q, 2) = " << p.distance(q, 2) << std::endl;
- BOOST_CHECK(fabs(p.distance(q, 2) - 2.1264) <= 0.0001);
- std::cout << "p.distance(q, std::numeric_limits<double>::max()) = " <<
- p.distance(q, std::numeric_limits<double>::max()) << std::endl;
- BOOST_CHECK(fabs(p.distance(q, std::numeric_limits<double>::max()) - 0.359068) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q), 25.5824, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q, 2), 2.1264, epsilon);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.distance(q, std::numeric_limits<double>::max()), 0.359068, epsilon);
}
BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) {
@@ -233,33 +227,9 @@ BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) {
std::vector<std::pair<double, double> > diag2 =
read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1");
Persistence_landscape q(diag2);
- BOOST_CHECK(fabs(p.compute_scalar_product(q) - 0.754498) <= 0.00001);
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(p.compute_scalar_product(q), 0.754498, epsilon);
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
// Below I am storing the code used to generate tests for that functionality.
/*
if ( argc != 2 )
diff --git a/src/Persistence_representations/test/read_persistence_from_file_test.cpp b/src/Persistence_representations/test/read_persistence_from_file_test.cpp
index 76d7cdb0..276b92ab 100644
--- a/src/Persistence_representations/test/read_persistence_from_file_test.cpp
+++ b/src/Persistence_representations/test/read_persistence_from_file_test.cpp
@@ -21,7 +21,7 @@
*/
#define BOOST_TEST_DYN_LINK
-#define BOOST_TEST_MODULE "Persistence_representations"
+#define BOOST_TEST_MODULE "read_persistence_from_file_test"
#include <boost/test/unit_test.hpp>
#include <gudhi/read_persistence_from_file.h>
@@ -30,8 +30,6 @@
using namespace Gudhi;
using namespace Gudhi::Persistence_representations;
-
-
BOOST_AUTO_TEST_CASE(test_read_file_with_four_elements_per_line) {
std::vector<std::pair<double, double> > what_we_should_get;
what_we_should_get.push_back(std::make_pair(0, 2));
@@ -39,7 +37,7 @@ BOOST_AUTO_TEST_CASE(test_read_file_with_four_elements_per_line) {
what_we_should_get.push_back(std::make_pair(10, 90));
what_we_should_get.push_back(std::make_pair(4, 4));
std::vector<std::pair<double, double> > what_we_get = read_persistence_intervals_in_one_dimension_from_file(
- "data/persistence_file_with_four_entries_per_line", 1, 1000);
+ "data/persistence_file_with_four_entries_per_line", 1, 1000);
// for ( size_t i = 0 ; i != what_we_get.size() ; ++i )
//{
@@ -76,7 +74,6 @@ BOOST_AUTO_TEST_CASE(test_read_file_with_three_elements_per_line) {
}
}
-
BOOST_AUTO_TEST_CASE(test_read_file_with_two_elements_per_line) {
std::vector<std::pair<double, double> > what_we_should_get;
what_we_should_get.push_back(std::make_pair(4, 10));
@@ -84,12 +81,11 @@ BOOST_AUTO_TEST_CASE(test_read_file_with_two_elements_per_line) {
what_we_should_get.push_back(std::make_pair(0, 1));
what_we_should_get.push_back(std::make_pair(1, 4));
- std::vector<std::pair<double, double> > what_we_get =
- read_persistence_intervals_in_one_dimension_from_file("data/persistence_file_with_two_entries_per_line", -1, 9999);
+ std::vector<std::pair<double, double> > what_we_get = read_persistence_intervals_in_one_dimension_from_file(
+ "data/persistence_file_with_two_entries_per_line", -1, 9999);
BOOST_CHECK(what_we_should_get.size() == what_we_get.size());
for (size_t i = 0; i != what_we_get.size(); ++i) {
BOOST_CHECK(what_we_should_get[i] == what_we_get[i]);
}
}
-
diff --git a/src/Persistence_representations/test/vector_representation_test.cpp b/src/Persistence_representations/test/vector_representation_test.cpp
index 3f3e2abe..c545dce7 100644
--- a/src/Persistence_representations/test/vector_representation_test.cpp
+++ b/src/Persistence_representations/test/vector_representation_test.cpp
@@ -26,7 +26,7 @@
#include <iostream>
#define BOOST_TEST_DYN_LINK
-#define BOOST_TEST_MODULE "Persistence_representations"
+#define BOOST_TEST_MODULE "vector_representation_test"
#include <boost/test/unit_test.hpp>
#include <gudhi/reader_utils.h>
#include <vector>
@@ -295,12 +295,10 @@ BOOST_AUTO_TEST_CASE(check_distance_computations) {
}
BOOST_AUTO_TEST_CASE(check_default_parameters_of_distances) {
- std::vector<std::pair<double, double> > diag =
- read_persistence_intervals_in_dimension("data/file_with_diagram");
+ std::vector<std::pair<double, double> > diag = read_persistence_intervals_in_dimension("data/file_with_diagram");
Vector_distances_in_diagram<Euclidean_distance> p(diag, 100);
- std::vector<std::pair<double, double> > diag1 =
- read_persistence_intervals_in_dimension("data/file_with_diagram_1");
+ std::vector<std::pair<double, double> > diag1 = read_persistence_intervals_in_dimension("data/file_with_diagram_1");
Vector_distances_in_diagram<Euclidean_distance> q(diag1, 100);
double dist_numeric_limit_max = p.distance(q, std::numeric_limits<double>::max());
diff --git a/src/Persistence_representations/utilities/CMakeLists.txt b/src/Persistence_representations/utilities/CMakeLists.txt
index 66524666..fc51b1d6 100644
--- a/src/Persistence_representations/utilities/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/CMakeLists.txt
@@ -1,6 +1,59 @@
+# Copy files, otherwise result files are created in sources
+file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/first.pers" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
+file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/second.pers" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
+
+function(add_persistence_representation_creation_utility creation_utility)
+ add_executable ( ${creation_utility} ${creation_utility}.cpp )
+
+ # as the function is called in a subdirectory level, need to '../' to find persistence files
+ # ARGN will add all the other arguments (except creation_utility) sent to the CMake functions
+ add_test(NAME Persistence_representation_utilities_${creation_utility} COMMAND $<TARGET_FILE:${creation_utility}>
+ ${ARGN} "${CMAKE_CURRENT_BINARY_DIR}/../first.pers"
+ "${CMAKE_CURRENT_BINARY_DIR}/../second.pers")
+
+ install(TARGETS ${creation_utility} DESTINATION bin)
+endfunction(add_persistence_representation_creation_utility)
+
+function(add_persistence_representation_plot_utility plot_utility tool_extension)
+ add_executable ( ${plot_utility} ${plot_utility}.cpp )
+
+ # as the function is called in a subdirectory level, need to '../' to find persistence heat maps files
+ add_test(NAME Persistence_representation_utilities_${plot_utility}_first COMMAND $<TARGET_FILE:${plot_utility}>
+ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}")
+ #add_test(NAME Persistence_representation_utilities_${plot_utility}_second COMMAND $<TARGET_FILE:${plot_utility}>
+ # "${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}")
+ if(GNUPLOT_PATH)
+ add_test(NAME Persistence_representation_utilities_${plot_utility}_first_gnuplot COMMAND ${GNUPLOT_PATH}
+ "-e" "load '${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}_GnuplotScript'")
+ #add_test(NAME Persistence_representation_utilities_${plot_utility}_second_gnuplot COMMAND ${GNUPLOT_PATH}
+ # "-e" "load '${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}_GnuplotScript'")
+ endif()
+
+ install(TARGETS ${plot_utility} DESTINATION bin)
+endfunction(add_persistence_representation_plot_utility)
+
+function(add_persistence_representation_function_utility function_utility tool_extension)
+ add_executable ( ${function_utility} ${function_utility}.cpp )
+
+ # ARGV2 is an optional argument
+ if (${ARGV2})
+ # as the function is called in a subdirectory level, need to '../' to find persistence heat maps files
+ add_test(NAME Persistence_representation_utilities_${function_utility} COMMAND $<TARGET_FILE:${function_utility}>
+ "${ARGV2}"
+ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}"
+ "${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}")
+ else()
+ # as the function is called in a subdirectory level, need to '../' to find persistence heat maps files
+ add_test(NAME Persistence_representation_utilities_${function_utility} COMMAND $<TARGET_FILE:${function_utility}>
+ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers${tool_extension}"
+ "${CMAKE_CURRENT_BINARY_DIR}/../second.pers${tool_extension}")
+ endif()
+
+ install(TARGETS ${function_utility} DESTINATION bin)
+endfunction(add_persistence_representation_function_utility)
+
add_subdirectory(persistence_heat_maps)
add_subdirectory(persistence_intervals)
add_subdirectory(persistence_landscapes)
add_subdirectory(persistence_landscapes_on_grid)
add_subdirectory(persistence_vectors)
-
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt
index 0dd63852..386e9fa5 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt
@@ -1,63 +1,15 @@
cmake_minimum_required(VERSION 2.6)
project(Persistence_representations_heat_maps_utilities)
-file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/simple_diagram.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
-
-add_executable ( create_persistence_heat_maps create_persistence_heat_maps.cpp )
-target_link_libraries(create_persistence_heat_maps ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME create_persistence_heat_maps COMMAND $<TARGET_FILE:create_persistence_heat_maps>
- "10" "-1" "-1" "4" "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-
-add_executable ( create_pssk create_pssk.cpp )
-target_link_libraries(create_pssk ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME create_pssk COMMAND $<TARGET_FILE:create_pssk>
- "10" "-1" "-1" "4" "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( create_p_h_m_weighted_by_distance_from_diagonal create_p_h_m_weighted_by_distance_from_diagonal.cpp )
-target_link_libraries(create_p_h_m_weighted_by_distance_from_diagonal ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME create_p_h_m_weighted_by_distance_from_diagonal COMMAND $<TARGET_FILE:create_p_h_m_weighted_by_distance_from_diagonal>
- "10" "-1" "-1" "4" "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( create_p_h_m_weighted_by_squared_diag_distance create_p_h_m_weighted_by_squared_diag_distance.cpp )
-target_link_libraries(create_p_h_m_weighted_by_squared_diag_distance ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME create_p_h_m_weighted_by_squared_diag_distance COMMAND $<TARGET_FILE:create_p_h_m_weighted_by_squared_diag_distance>
- "10" "-1" "-1" "4" "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( create_p_h_m_weighted_by_arctan_of_their_persistence create_p_h_m_weighted_by_arctan_of_their_persistence.cpp )
-target_link_libraries(create_p_h_m_weighted_by_arctan_of_their_persistence ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME create_p_h_m_weighted_by_arctan_of_their_persistence COMMAND $<TARGET_FILE:create_p_h_m_weighted_by_arctan_of_their_persistence>
- "10" "-1" "-1" "4" "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( average_persistence_heat_maps average_persistence_heat_maps.cpp )
-target_link_libraries(average_persistence_heat_maps ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME average_persistence_heat_maps COMMAND $<TARGET_FILE:average_persistence_heat_maps>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( plot_persistence_heat_map plot_persistence_heat_map.cpp )
-target_link_libraries(plot_persistence_heat_map ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME plot_persistence_heat_map COMMAND $<TARGET_FILE:plot_persistence_heat_map>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( compute_distance_of_persistence_heat_maps compute_distance_of_persistence_heat_maps.cpp )
-target_link_libraries(compute_distance_of_persistence_heat_maps ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_distance_of_persistence_heat_maps COMMAND $<TARGET_FILE:compute_distance_of_persistence_heat_maps>
- "1"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( compute_scalar_product_of_persistence_heat_maps compute_scalar_product_of_persistence_heat_maps.cpp )
-target_link_libraries(compute_scalar_product_of_persistence_heat_maps ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_scalar_product_of_persistence_heat_maps COMMAND $<TARGET_FILE:compute_scalar_product_of_persistence_heat_maps>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
+add_persistence_representation_creation_utility(create_pssk "10" "-1" "-1" "4" "-1")
+add_persistence_representation_creation_utility(create_p_h_m_weighted_by_arctan_of_their_persistence "10" "-1" "-1" "4" "-1")
+add_persistence_representation_creation_utility(create_p_h_m_weighted_by_distance_from_diagonal "10" "-1" "-1" "4" "-1")
+add_persistence_representation_creation_utility(create_p_h_m_weighted_by_squared_diag_distance "10" "-1" "-1" "4" "-1")
+# Need to set grid min and max for further average, distance and scalar_product
+add_persistence_representation_creation_utility(create_persistence_heat_maps "10" "0" "35" "10" "-1")
+
+add_persistence_representation_plot_utility(plot_persistence_heat_map ".mps")
+
+add_persistence_representation_function_utility(average_persistence_heat_maps ".mps")
+add_persistence_representation_function_utility(compute_distance_of_persistence_heat_maps ".mps" "1")
+add_persistence_representation_function_utility(compute_scalar_product_of_persistence_heat_maps ".mps")
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/average_persistence_heat_maps.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/average_persistence_heat_maps.cpp
index 4e81375a..6739e0b6 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/average_persistence_heat_maps.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/average_persistence_heat_maps.cpp
@@ -29,21 +29,20 @@ using constant_scaling_function = Gudhi::Persistence_representations::constant_s
using Persistence_heat_maps = Gudhi::Persistence_representations::Persistence_heat_maps<constant_scaling_function>;
int main(int argc, char** argv) {
- std::cout << "This program computes average persistence landscape of persistence landscapes created based on "
- "persistence diagrams provided as an input. Please call this program with the names of files with "
- "persistence diagrams \n";
- std::vector<const char*> filenames;
+ std::cout << "This program computes average of persistence heat maps stored in files (the files needs to be "
+ << "created beforehand).\n"
+ << "The parameters of this programs are names of files with persistence heat maps.\n";
- if (argc == 1) {
- std::cout << "No input files given, the program will now terminate \n";
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
return 1;
}
+ std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence landscapes...\n";
std::vector<Persistence_heat_maps*> maps;
for (size_t i = 0; i != filenames.size(); ++i) {
Persistence_heat_maps* l = new Persistence_heat_maps;
@@ -53,13 +52,12 @@ int main(int argc, char** argv) {
Persistence_heat_maps av;
av.compute_average(maps);
-
av.print_to_file("average.mps");
for (size_t i = 0; i != filenames.size(); ++i) {
delete maps[i];
}
- std::cout << "Done \n";
+ std::cout << "Average can be found in 'average.mps' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp
index befb0837..ed8278a2 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp
@@ -31,11 +31,11 @@ using constant_scaling_function = Gudhi::Persistence_representations::constant_s
using Persistence_heat_maps = Gudhi::Persistence_representations::Persistence_heat_maps<constant_scaling_function>;
int main(int argc, char** argv) {
- std::cout << "This program computes distance of persistence heat maps stored in a file (the file needs to be created "
- "beforehand). \n";
- std::cout << "The first parameter of a program is an integer p. The program compute L^p distance of the two heat "
- "maps. For L^infty distance choose p = -1. \n";
- std::cout << "The remaining parameters of this program are names of files with persistence heat maps.\n";
+ std::cout << "This program computes distance of persistence heat maps stored in files (the files needs to be "
+ << "created beforehand).\n"
+ << "The first parameter of a program is an integer p. The program compute L^p distance of the two heat "
+ << "maps. For L^infty distance choose p = -1. \n"
+ << "The remaining parameters of this program are names of files with persistence heat maps.\n";
if (argc < 3) {
std::cout << "Wrong number of parameters, the program will now terminate \n";
@@ -78,7 +78,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("distance");
+ out.open("distance.mps");
for (size_t i = 0; i != distance.size(); ++i) {
for (size_t j = 0; j != distance.size(); ++j) {
std::cout << distance[i][j] << " ";
@@ -89,5 +89,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'distance.mps' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp
index c684a336..63626853 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp
@@ -30,9 +30,14 @@ using constant_scaling_function = Gudhi::Persistence_representations::constant_s
using Persistence_heat_maps = Gudhi::Persistence_representations::Persistence_heat_maps<constant_scaling_function>;
int main(int argc, char** argv) {
- std::cout << "This program computes scalar product of persistence landscapes stored in a file (the file needs to be "
- "created beforehand). \n";
- std::cout << "The parameters of this programs are names of files with persistence landscapes.\n";
+ std::cout << "This program computes scalar product of persistence heat maps stored in a file (the file needs to be "
+ << "created beforehand). \n"
+ << "The parameters of this programs are names of files with persistence heat maps.\n";
+
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
+ return 1;
+ }
std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
@@ -64,7 +69,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("scalar_product");
+ out.open("scalar_product.mps");
for (size_t i = 0; i != scalar_product.size(); ++i) {
for (size_t j = 0; j != scalar_product.size(); ++j) {
std::cout << scalar_product[i][j] << " ";
@@ -75,5 +80,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'scalar_product.mps' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp
index 2bf185a3..b4a1daa5 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp
@@ -29,25 +29,25 @@
using arc_tan_of_persistence_of_point = Gudhi::Persistence_representations::arc_tan_of_persistence_of_point;
using Persistence_heat_maps =
- Gudhi::Persistence_representations::Persistence_heat_maps<arc_tan_of_persistence_of_point>;
+ Gudhi::Persistence_representations::Persistence_heat_maps<arc_tan_of_persistence_of_point>;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are "
- "weighted by the arc tangential of their persistence.\n";
- std::cout << "The first parameter of a program is an integer, a size of a grid.\n";
- std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
- "based on the data, set them both to -1 \n";
- std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
- "of pixels \n";
- std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the "
- "persistence heat maps.";
- std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the "
- "procedure please provide the dimension of persistence you want to use.";
- std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1."
- << std::endl;
- std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
+ std::cout << "This program creates persistence heat map files (*.mps) of persistence diagrams files (*.pers) "
+ << "provided as an input.The Gaussian kernels are weighted by the arc tangential of their persistence.\n"
+ << "The first parameter of a program is an integer, a size of a grid.\n"
+ << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
+ << "based on the data, set them both to -1 \n"
+ << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
+ << "of pixels.\n"
+ << "The fifth parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a fifth parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the fifth parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
- if (argc < 5) {
+ if (argc < 7) {
std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
@@ -68,9 +68,7 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence heat maps...\n";
std::vector<std::vector<double> > filter = Gudhi::Persistence_representations::create_Gaussian_filter(stdiv, 1);
-
for (size_t i = 0; i != filenames.size(); ++i) {
std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl;
Persistence_heat_maps l(filenames[i], filter, false, size_of_grid, min_, max_, dimension);
@@ -79,6 +77,5 @@ int main(int argc, char** argv) {
ss << filenames[i] << ".mps";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp
index ec9477f1..c50f9ddb 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp
@@ -28,26 +28,26 @@
#include <vector>
using distance_from_diagonal_scaling = Gudhi::Persistence_representations::distance_from_diagonal_scaling;
-using Persistence_heat_maps =
- Gudhi::Persistence_representations::Persistence_heat_maps<distance_from_diagonal_scaling>;
+using Persistence_heat_maps = Gudhi::Persistence_representations::Persistence_heat_maps<distance_from_diagonal_scaling>;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are "
- "weighted by the distance of a center from the diagonal.\n";
- std::cout << "The first parameter of a program is an integer, a size of a grid.\n";
- std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
- "based on the data, set them both to -1 \n";
- std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
- "of pixels \n";
- std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the "
- "persistence heat maps.";
- std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the "
- "procedure please provide the dimension of persistence you want to use.";
- std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1."
- << std::endl;
- std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
+ std::cout << "This program creates persistence heat map files (*.mps) of persistence diagrams files (*.pers) "
+ << "provided as an input.The Gaussian kernels are weighted by the distance of a center from the "
+ << "diagonal.\n"
+ << "The first parameter of a program is an integer, a size of a grid.\n"
+ << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
+ << "based on the data, set them both to -1 \n"
+ << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
+ << "of pixels.\n"
+ << "The fifth parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a fifth parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the fifth parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
- if (argc < 5) {
+ if (argc < 7) {
std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
@@ -68,9 +68,7 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence heat maps...\n";
std::vector<std::vector<double> > filter = Gudhi::Persistence_representations::create_Gaussian_filter(stdiv, 1);
-
for (size_t i = 0; i != filenames.size(); ++i) {
std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl;
Persistence_heat_maps l(filenames[i], filter, false, size_of_grid, min_, max_, dimension);
@@ -79,6 +77,5 @@ int main(int argc, char** argv) {
ss << filenames[i] << ".mps";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp
index ffec8b3d..59ff3c24 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp
@@ -28,27 +28,28 @@
#include <vector>
using squared_distance_from_diagonal_scaling =
- Gudhi::Persistence_representations::squared_distance_from_diagonal_scaling;
+ Gudhi::Persistence_representations::squared_distance_from_diagonal_scaling;
using Persistence_heat_maps =
- Gudhi::Persistence_representations::Persistence_heat_maps<squared_distance_from_diagonal_scaling>;
+ Gudhi::Persistence_representations::Persistence_heat_maps<squared_distance_from_diagonal_scaling>;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are "
- "weighted by the square of distance of a center from the diagonal.\n";
- std::cout << "The first parameter of a program is an integer, a size of a grid.\n";
- std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
- "based on the data, set them both to -1 \n";
- std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
- "of pixels \n";
- std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the "
- "persistence heat maps.";
- std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the "
- "procedure please provide the dimension of persistence you want to use.";
- std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1."
- << std::endl;
- std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
+ std::cout << "This program creates persistence heat map files (*.mps) of persistence diagrams files (*.pers) "
+ << "provided as an input.The Gaussian kernels are weighted by the square of distance of a center from the "
+ << "diagonal.\n"
+ << "The first parameter of a program is an integer, a size of a grid.\n"
+ << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
+ << "based on the data, set them both to -1 \n"
+ << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
+ << "of pixels.\n"
+ << "The fifth parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a fifth parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the fifth parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
- if (argc < 5) {
+ if (argc < 7) {
std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
@@ -69,9 +70,7 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence heat maps...\n";
std::vector<std::vector<double> > filter = Gudhi::Persistence_representations::create_Gaussian_filter(stdiv, 1);
-
for (size_t i = 0; i != filenames.size(); ++i) {
std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl;
Persistence_heat_maps l(filenames[i], filter, false, size_of_grid, min_, max_, dimension);
@@ -80,6 +79,5 @@ int main(int argc, char** argv) {
ss << filenames[i] << ".mps";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp
index db2f0008..25cd1067 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp
@@ -31,21 +31,22 @@ using constant_scaling_function = Gudhi::Persistence_representations::constant_s
using Persistence_heat_maps = Gudhi::Persistence_representations::Persistence_heat_maps<constant_scaling_function>;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence heat map of diagrams provided as an input.\n";
- std::cout << "The first parameter of a program is an integer, a size of a grid.\n";
- std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
- "based on the data, set them both to -1 \n";
- std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
- "of pixels \n";
+ std::cout << "This program creates persistence heat map files (*.mps) of persistence diagrams files (*.pers) "
+ << "provided as an input.\n"
+ << "The first parameter of a program is an integer, a size of a grid.\n"
+ << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
+ << "based on the data, set them both to -1 \n"
+ << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
+ << "of pixels.\n"
+ << "The fifth parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a fifth parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the fifth parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
- std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the "
- "persistence heat maps.";
- std::cout << "If your input file contains persistence pairs of various dimension, as a fifth parameter of the "
- "procedure please provide the dimension of persistence you want to use.";
- std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1."
- << std::endl;
- std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
- if (argc < 5) {
+ if (argc < 7) {
std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
@@ -64,17 +65,14 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence heat maps...\n";
std::vector<std::vector<double> > filter = Gudhi::Persistence_representations::create_Gaussian_filter(stdiv, 1);
-
for (size_t i = 0; i != filenames.size(); ++i) {
- std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl;
+ std::cout << "Creating a heat map based on file : " << filenames[i] << std::endl;
Persistence_heat_maps l(filenames[i], filter, false, size_of_grid, min_, max_, dimension);
std::stringstream ss;
ss << filenames[i] << ".mps";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp
index 6aefbb00..97ddb8f0 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp
@@ -30,21 +30,22 @@
using PSSK = Gudhi::Persistence_representations::PSSK;
int main(int argc, char** argv) {
- std::cout << "This program creates PSSK of diagrams provided as an input.\n";
- std::cout << "The first parameter of a program is an integer, a size of a grid.\n";
- std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
- "based on the data, set them both to -1 \n";
- std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
- "of pixels \n";
- std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the "
- "persistence heat maps.";
- std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the "
- "procedure please provide the dimension of persistence you want to use.";
- std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1."
- << std::endl;
- std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
+ std::cout << "This program creates PSSK files (*.pssk) of persistence diagrams files (*.pers) "
+ << "provided as an input.\n"
+ << "The first parameter of a program is an integer, a size of a grid.\n"
+ << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
+ << "based on the data, set them both to -1 \n"
+ << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number "
+ << "of pixels.\n"
+ << "The fifth parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the PSSK."
+ << "If your input files contains persistence pairs of various dimension, as a fifth parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the first parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
- if (argc < 5) {
+ if (argc < 7) {
std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
@@ -65,17 +66,14 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence heat maps...\n";
std::vector<std::vector<double> > filter = Gudhi::Persistence_representations::create_Gaussian_filter(stdiv, 1);
-
for (size_t i = 0; i != filenames.size(); ++i) {
- std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl;
+ std::cout << "Creating a PSSK based on a file : " << filenames[i] << std::endl;
PSSK l(filenames[i], filter, size_of_grid, min_, max_, dimension);
std::stringstream ss;
ss << filenames[i] << ".pssk";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp
index a7c9f2d8..63711d83 100644
--- a/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp
+++ b/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp
@@ -29,8 +29,12 @@ using constant_scaling_function = Gudhi::Persistence_representations::constant_s
using Persistence_heat_maps = Gudhi::Persistence_representations::Persistence_heat_maps<constant_scaling_function>;
int main(int argc, char** argv) {
- std::cout << "This program plot persistence landscape stored in a file (the file needs to be created beforehand). "
- "Please call the code with the name of a landscape file \n";
+ std::cout << "This program creates a gnuplot script from a persistence heat maps stored in a file (the file needs "
+ << "to be created beforehand). Please call the code with the name of a single heat maps file \n";
+ if (argc != 2) {
+ std::cout << "Wrong parameter list, the program will now terminate \n";
+ return 1;
+ }
Persistence_heat_maps l;
l.load_from_file(argv[1]);
l.plot(argv[1]);
diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/simple_diagram.txt.mps b/src/Persistence_representations/utilities/persistence_heat_maps/simple_diagram.txt.mps
deleted file mode 100644
index b7643887..00000000
--- a/src/Persistence_representations/utilities/persistence_heat_maps/simple_diagram.txt.mps
+++ /dev/null
@@ -1,11 +0,0 @@
-0.93 8.0707
-0.0492104 0.03889 0.0190956 0.00603584 0.00131569 0.000120934 2.10152e-05 0 0 0
-0.0650745 0.0539306 0.0296488 0.011745 0.00357642 0.000695928 0.000120934 0 0 0
-0.0572665 0.0559446 0.0409942 0.0230905 0.00937173 0.00242903 0.000422102 0 0 0
-0.0409942 0.0559656 0.0573874 0.0408475 0.0192639 0.00628964 0.00178718 0.000422102 0.000120934 2.10152e-05
-0.0296488 0.0540515 0.0657704 0.0519133 0.0283092 0.0132056 0.00628964 0.00242903 0.000695928 0.000120934
-0.0190956 0.0393121 0.0516395 0.0465955 0.0359385 0.0283092 0.0192639 0.00937173 0.00357642 0.00131569
-0.00847814 0.0188418 0.0281882 0.0358964 0.0465955 0.0519133 0.0408475 0.0230905 0.011745 0.00603584
-0.00242903 0.00628964 0.0132056 0.0281882 0.0516395 0.0657704 0.0573874 0.0409942 0.0296488 0.0190956
-0.000422102 0.00178718 0.00628964 0.0188418 0.0393121 0.0540515 0.0559656 0.0559446 0.0539306 0.03889
-0 0.000422102 0.00242903 0.00847814 0.0190956 0.0296488 0.0409942 0.0572665 0.0650745 0.0492104
diff --git a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt
index 105b7efb..875ff45e 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt
@@ -1,46 +1,38 @@
cmake_minimum_required(VERSION 2.6)
project(Persistence_representations_intervals_utilities)
-file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/simple_diagram.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
-add_executable ( plot_persistence_intervals plot_persistence_intervals.cpp )
-target_link_libraries( plot_persistence_intervals ${Boost_SYSTEM_LIBRARY})
+add_executable ( plot_histogram_of_intervals_lengths plot_histogram_of_intervals_lengths.cpp )
-add_test(NAME plot_persistence_intervals COMMAND $<TARGET_FILE:plot_persistence_intervals>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
+add_test(NAME plot_histogram_of_intervals_lengths COMMAND $<TARGET_FILE:plot_histogram_of_intervals_lengths>
+ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers" "-1")
-add_executable ( compute_birth_death_range_in_persistence_diagram compute_birth_death_range_in_persistence_diagram.cpp )
-target_link_libraries( compute_birth_death_range_in_persistence_diagram ${Boost_SYSTEM_LIBRARY})
+install(TARGETS plot_histogram_of_intervals_lengths DESTINATION bin)
-add_test(NAME compute_birth_death_range_in_persistence_diagram COMMAND $<TARGET_FILE:compute_birth_death_range_in_persistence_diagram>
- "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
+add_persistence_representation_plot_utility(plot_persistence_intervals "")
+add_persistence_representation_plot_utility(plot_persistence_Betti_numbers "")
-add_executable ( compute_number_of_dominant_intervals compute_number_of_dominant_intervals.cpp )
-target_link_libraries( compute_number_of_dominant_intervals ${Boost_SYSTEM_LIBRARY})
+add_persistence_representation_creation_utility(compute_birth_death_range_in_persistence_diagram "-1")
-add_test(NAME compute_number_of_dominant_intervals COMMAND $<TARGET_FILE:compute_number_of_dominant_intervals>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt" "-1" "2")
-add_executable ( plot_histogram_of_intervals_lengths plot_histogram_of_intervals_lengths.cpp )
-target_link_libraries( plot_histogram_of_intervals_lengths ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME plot_histogram_of_intervals_lengths COMMAND $<TARGET_FILE:plot_histogram_of_intervals_lengths>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt" "2")
+add_executable ( compute_number_of_dominant_intervals compute_number_of_dominant_intervals.cpp )
+add_test(NAME Persistence_representation_utilities_compute_number_of_dominant_intervals
+ COMMAND $<TARGET_FILE:compute_number_of_dominant_intervals>
+ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers" "-1" "2")
-add_executable ( plot_persistence_Betti_numbers plot_persistence_Betti_numbers.cpp )
-target_link_libraries( plot_persistence_Betti_numbers ${Boost_SYSTEM_LIBRARY})
+install(TARGETS compute_number_of_dominant_intervals DESTINATION bin)
-add_test(NAME plot_persistence_Betti_numbers COMMAND $<TARGET_FILE:plot_persistence_Betti_numbers>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
add_executable ( compute_bottleneck_distance compute_bottleneck_distance.cpp )
- target_link_libraries( compute_bottleneck_distance ${Boost_SYSTEM_LIBRARY})
if (TBB_FOUND)
target_link_libraries(compute_bottleneck_distance ${TBB_LIBRARIES})
endif(TBB_FOUND)
+ add_test(NAME Persistence_representation_utilities_compute_bottleneck_distance
+ COMMAND $<TARGET_FILE:compute_bottleneck_distance>
+ "-1"
+ "${CMAKE_CURRENT_BINARY_DIR}/../first.pers"
+ "${CMAKE_CURRENT_BINARY_DIR}/../second.pers")
- add_test(NAME compute_bottleneck_distance COMMAND $<TARGET_FILE:compute_bottleneck_distance>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
+ install(TARGETS compute_bottleneck_distance DESTINATION bin)
endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1)
diff --git a/src/Persistence_representations/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp b/src/Persistence_representations/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp
index 66fa31ca..9102da79 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp
+++ b/src/Persistence_representations/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp
@@ -20,7 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_intervals.h>
#include <iostream>
@@ -31,16 +30,21 @@
using Persistence_intervals = Gudhi::Persistence_representations::Persistence_intervals;
int main(int argc, char** argv) {
- std::cout << "This program compute the range of birth and death times of persistence pairs in diagrams provided as "
- "an input. \n";
- std::cout << "The first parameter of the program is the dimension of persistence to be used. If your file contains ";
- std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence "
- "pairs you want to use. If your input files consist only ";
- std::cout << "of birth-death pairs, please set this first parameter to -1 \n";
- std::cout << "The remaining parameters of the program are the names of files with persistence diagrams. \n";
+ std::cout << "This program computes the range of birth and death times of persistence pairs in diagrams provided as "
+ << "an input.\n"
+ << "The first parameter is the dimension of persistence to be used to create persistence intervals. "
+ << "If your file contains the information about dimension of persistence pairs, please provide here the "
+ << "dimension of persistence pairs you want to use. "
+ << "If your input files consist only of birth-death pairs, please set this first parameter to -1.\n"
+ << "The remaining parameters of the program are the names of files with persistence diagrams.\n";
+
+ if (argc < 3) {
+ std::cout << "Wrong parameter list, the program will now terminate \n";
+ return 1;
+ }
- int dim = atoi(argv[1]);
unsigned dimension = std::numeric_limits<unsigned>::max();
+ int dim = atoi(argv[1]);
if (dim >= 0) {
dimension = (unsigned)dim;
}
diff --git a/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp b/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp
index 0b1b526d..c8290845 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp
+++ b/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp
@@ -21,7 +21,6 @@
*/
#include <gudhi/Persistence_intervals_with_distances.h>
-#include <gudhi/read_persistence_from_file.h>
#include <iostream>
#include <sstream>
@@ -31,21 +30,21 @@
using Persistence_intervals_with_distances = Gudhi::Persistence_representations::Persistence_intervals_with_distances;
int main(int argc, char** argv) {
- std::cout << "This program compute the bottleneck distance of persistence diagrams stored in a files. \n";
- std::cout << "The first parameter of the program is the dimension of persistence to be used to construct persistence "
- "landscapes. If your file contains ";
- std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence "
- "pairs you want to use. If your input files consist only ";
- std::cout << "of birth-death pairs, please set this first parameter to -1 \n";
- std::cout << "The remaining parameters of this programs are names of files with persistence diagrams.\n";
+ std::cout << "This program computes the bottleneck distance of persistence pairs in diagrams provided as "
+ << "an input.\n"
+ << "The first parameter is the dimension of persistence to be used to create persistence intervals. "
+ << "If your file contains the information about dimension of persistence pairs, please provide here the "
+ << "dimension of persistence pairs you want to use. "
+ << "If your input files consist only of birth-death pairs, please set this first parameter to -1.\n"
+ << "The remaining parameters of the program are the names of files with persistence diagrams.\n";
if (argc < 3) {
std::cout << "Wrong number of parameters, the program will now terminate \n";
return 1;
}
- int dim = atoi(argv[1]);
unsigned dimension = std::numeric_limits<unsigned>::max();
+ int dim = atoi(argv[1]);
if (dim >= 0) {
dimension = (unsigned)dim;
}
@@ -80,7 +79,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("distance");
+ out.open("distance.itv");
for (size_t i = 0; i != distance.size(); ++i) {
for (size_t j = 0; j != distance.size(); ++j) {
std::cout << distance[i][j] << " ";
@@ -91,5 +90,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'distance.itv' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp b/src/Persistence_representations/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp
index 1286ca57..b3d126f0 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp
+++ b/src/Persistence_representations/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp
@@ -20,7 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_intervals.h>
#include <iostream>
diff --git a/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp b/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp
index d68f4584..ccb5b645 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp
+++ b/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp
@@ -20,7 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_intervals.h>
#include <iostream>
@@ -31,30 +30,34 @@
using Persistence_intervals = Gudhi::Persistence_representations::Persistence_intervals;
int main(int argc, char** argv) {
- std::cout << "This program compute a histogram of barcode's length. A number of bins in the histogram is a parameter "
- "of this program. \n";
- if (argc != 3) {
+ std::cout << "This program computes a histogram of barcode's length. A number of bins in the histogram is a "
+ << "parameter of this program. \n";
+ if ((argc != 3) && (argc != 4)) {
std::cout << "To run this program, please provide the name of a file with persistence diagram and number of "
- "dominant intervals you would like to get \n";
- std::cout << "The third parameter of a program is the dimension of the persistence that is to be used. If your "
- "file contains only birth-death pairs, you can skip this parameter\n";
+ << "dominant intervals you would like to get. Set a negative number dominant intervals value "
+ << "If your file contains only birth-death pairs.\n"
+ << "The third parameter is the dimension of the persistence that is to be used. If your "
+ << "file contains only birth-death pairs, you can skip this parameter\n";
return 1;
}
- unsigned dimension = std::numeric_limits<unsigned>::max();
- int dim = -1;
- if (argc > 2) {
- dim = atoi(argv[2]);
+
+ unsigned dominant_interval_number = std::numeric_limits<unsigned>::max();
+ int nbr = atoi(argv[2]);
+ if (nbr >= 0) {
+ dominant_interval_number = static_cast<unsigned>(nbr);
}
- if (dim >= 0) {
- dimension = (unsigned)dim;
+
+ int persistence_dimension = -1;
+ if (argc == 4) {
+ persistence_dimension = atoi(argv[3]);
}
- Persistence_intervals p(argv[1], dimension);
- std::vector<std::pair<double, double> > dominant_intervals = p.dominant_intervals(atoi(argv[2]));
+ Persistence_intervals p(argv[1], dominant_interval_number);
+ std::vector<std::pair<double, double> > dominant_intervals = p.dominant_intervals(persistence_dimension);
std::vector<size_t> histogram = p.histogram_of_lengths(10);
std::stringstream gnuplot_script;
- gnuplot_script << argv[1] << "_Gnuplot_script";
+ gnuplot_script << argv[1] << "_GnuplotScript";
std::ofstream out;
out.open(gnuplot_script.str().c_str());
@@ -66,7 +69,9 @@ int main(int argc, char** argv) {
out << histogram[i] << std::endl;
}
out << std::endl;
- std::cout << "To visualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl;
out.close();
+
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp b/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp
index da2b9319..b433c2b3 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp
+++ b/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp
@@ -20,7 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_intervals.h>
#include <iostream>
@@ -31,29 +30,24 @@
using Persistence_intervals = Gudhi::Persistence_representations::Persistence_intervals;
int main(int argc, char** argv) {
- std::cout << "This program compute a plot of persistence Betti numbers. The input parameter is a file with "
- "persistence intervals. \n";
- std::cout << "The second optional parameter of a program is the dimension of the persistence that is to be used. If "
- "your file contains only birth-death pairs, you can skip this parameter\n";
- if (argc < 2) {
- std::cout << "To run this program, please provide the name of a file with persistence diagram and number of "
- "dominant intervals you would like to get \n";
+ if ((argc != 3) && (argc != 2)) {
+ std::cout << "This program creates a gnuplot script of Betti numbers from a single persistence diagram file"
+ << "(*.pers).\n"
+ << "To run this program, please provide the name of a file with persistence diagram.\n"
+ << "The second optional parameter of a program is the dimension of the persistence that is to be used. "
+ << "If your file contains only birth-death pairs, you can skip this parameter.\n";
return 1;
}
+
unsigned dimension = std::numeric_limits<unsigned>::max();
int dim = -1;
- if (argc > 2) {
+ if (argc == 3) {
dim = atoi(argv[2]);
}
if (dim >= 0) {
dimension = (unsigned)dim;
}
- std::stringstream gnuplot_script;
- gnuplot_script << argv[1] << "_Gnuplot_script";
- std::ofstream out;
- out.open(gnuplot_script.str().c_str());
-
Persistence_intervals p(argv[1], dimension);
std::vector<std::pair<double, size_t> > pbns = p.compute_persistent_betti_numbers();
@@ -69,6 +63,11 @@ int main(int argc, char** argv) {
xRangeEnd += (xRangeEnd - xRangeBegin) / 100.0;
yRangeEnd += yRangeEnd / 100;
+ std::stringstream gnuplot_script;
+ gnuplot_script << argv[1] << "_GnuplotScript";
+ std::ofstream out;
+ out.open(gnuplot_script.str().c_str());
+
out << "set xrange [" << xRangeBegin << " : " << xRangeEnd << "]" << std::endl;
out << "set yrange [" << yRangeBegin << " : " << yRangeEnd << "]" << std::endl;
out << "plot '-' using 1:2 notitle with lp " << std::endl;
@@ -81,7 +80,8 @@ int main(int argc, char** argv) {
out << std::endl;
out.close();
- std::cout << "To visualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl;
+ std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
+ << gnuplot_script.str().c_str() << "\'\"" << std::endl;
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_intervals.cpp b/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_intervals.cpp
index e7d29e84..33387802 100644
--- a/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_intervals.cpp
+++ b/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_intervals.cpp
@@ -20,9 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/reader_utils.h>
#include <gudhi/Persistence_intervals.h>
-#include <gudhi/read_persistence_from_file.h>
#include <iostream>
#include <limits>
@@ -32,15 +30,16 @@
using Persistence_intervals = Gudhi::Persistence_representations::Persistence_intervals;
int main(int argc, char** argv) {
- if (argc < 2) {
- std::cout << "To run this program, please provide the name of a file with persistence diagram \n";
- std::cout << "The second optional parameter of a program is the dimension of the persistence that is to be used. "
- "If your file contains only birth-death pairs, you can skip this parameter\n";
+ if ((argc != 3) && (argc != 2)) {
+ std::cout << "This program creates a gnuplot script from a single persistence diagram file (*.pers).\n"
+ << "To run this program, please provide the name of a file with persistence diagram.\n"
+ << "The second optional parameter of a program is the dimension of the persistence that is to be used. "
+ << "If your file contains only birth-death pairs, you can skip this parameter.\n";
return 1;
}
unsigned dimension = std::numeric_limits<unsigned>::max();
int dim = -1;
- if (argc > 2) {
+ if (argc == 3) {
dim = atoi(argv[2]);
}
if (dim >= 0) {
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt
index baf8de3c..d7087ed8 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt
@@ -1,38 +1,10 @@
cmake_minimum_required(VERSION 2.6)
-project(Persistence_representations_lanscapes_utilities)
+project(Persistence_representations_landscapes_utilities)
-file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/simple_diagram.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
+add_persistence_representation_creation_utility(create_landscapes "-1")
-add_executable ( create_landscapes create_landscapes.cpp )
-target_link_libraries(create_landscapes ${Boost_SYSTEM_LIBRARY})
+add_persistence_representation_plot_utility(plot_landscapes ".land")
-# Will create simple_diagram.txt.land
-add_test(NAME create_landscapes COMMAND $<TARGET_FILE:create_landscapes>
- "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( average_landscapes average_landscapes.cpp )
-target_link_libraries(average_landscapes ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME average_landscapes COMMAND $<TARGET_FILE:average_landscapes>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( plot_landscapes plot_landscapes.cpp )
-target_link_libraries(plot_landscapes ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME plot_landscapes COMMAND $<TARGET_FILE:plot_landscapes>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( compute_distance_of_landscapes compute_distance_of_landscapes.cpp )
-target_link_libraries(compute_distance_of_landscapes ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_distance_of_landscapes COMMAND $<TARGET_FILE:compute_distance_of_landscapes>
- "1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.land"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.land")
-
-add_executable ( compute_scalar_product_of_landscapes compute_scalar_product_of_landscapes.cpp )
-target_link_libraries(compute_scalar_product_of_landscapes ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_scalar_product_of_landscapes COMMAND $<TARGET_FILE:compute_scalar_product_of_landscapes>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.land"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.land")
+add_persistence_representation_function_utility(average_landscapes ".land")
+add_persistence_representation_function_utility(compute_distance_of_landscapes ".land" "1")
+add_persistence_representation_function_utility(compute_scalar_product_of_landscapes ".land")
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/average_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/average_landscapes.cpp
index 526130e9..1a59be8c 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes/average_landscapes.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes/average_landscapes.cpp
@@ -28,14 +28,13 @@
using Persistence_landscape = Gudhi::Persistence_representations::Persistence_landscape;
int main(int argc, char** argv) {
- std::cout << "This program computes average persistence landscape of persistence landscapes created based on "
- "persistence diagrams provided as an input (you must create them first).\n";
- std::cout << "Please call this program with the names of files with persistence landscapes. The program will create "
- "a persistence landscape which will be their average \n";
+ std::cout << "This program computes average of persistence landscapes stored in files (the files needs to be "
+ << "created beforehand).\n"
+ << "The parameters of this programs are names of files with persistence landscapes.\n";
std::vector<const char*> filenames;
- if (argc == 1) {
- std::cout << "No input files given, the program will now terminate \n";
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
return 1;
}
@@ -43,7 +42,6 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence landscapes...\n";
std::vector<Persistence_landscape*> lands;
for (size_t i = 0; i != filenames.size(); ++i) {
Persistence_landscape* l = new Persistence_landscape;
@@ -60,7 +58,6 @@ int main(int argc, char** argv) {
delete lands[i];
}
- std::cout << "Done \n";
-
+ std::cout << "Average can be found in 'average.land' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp
index b3881d6a..5062f521 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp
@@ -30,11 +30,11 @@
using Persistence_landscape = Gudhi::Persistence_representations::Persistence_landscape;
int main(int argc, char** argv) {
- std::cout << "This program compute distance of persistence landscapes stored in a file (the file needs to be created "
- "beforehand). \n";
- std::cout << "The first parameter of a program is an integer p. The program compute L^p distance of the given "
- "landscapes. For L^infty distance choose p = -1. \n";
- std::cout << "The remaining parameters of this programs are names of files with persistence landscapes.";
+ std::cout << "This program computes distance of persistence landscapes stored in files (the files needs to be "
+ << "created beforehand).\n"
+ << "The first parameter of a program is an integer p. The program compute L^p distance of the two heat "
+ << "maps. For L^infty distance choose p = -1. \n"
+ << "The remaining parameters of this program are names of files with persistence landscapes.\n";
if (argc < 3) {
std::cout << "Wrong number of parameters, the program will now terminate \n";
@@ -54,7 +54,6 @@ int main(int argc, char** argv) {
std::vector<Persistence_landscape> landscaspes;
landscaspes.reserve(filenames.size());
for (size_t file_no = 0; file_no != filenames.size(); ++file_no) {
- std::cout << "Loading persistence landscape from a file : " << filenames[file_no] << std::endl;
Persistence_landscape l;
l.load_landscape_from_file(filenames[file_no]);
landscaspes.push_back(l);
@@ -78,7 +77,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("distance");
+ out.open("distance.land");
for (size_t i = 0; i != distance.size(); ++i) {
for (size_t j = 0; j != distance.size(); ++j) {
std::cout << distance[i][j] << " ";
@@ -89,5 +88,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'distance.land' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/compute_scalar_product_of_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/compute_scalar_product_of_landscapes.cpp
index 8dad7b4d..5b5e9fa3 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes/compute_scalar_product_of_landscapes.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes/compute_scalar_product_of_landscapes.cpp
@@ -29,9 +29,14 @@
using Persistence_landscape = Gudhi::Persistence_representations::Persistence_landscape;
int main(int argc, char** argv) {
- std::cout << "This program compute scalar product of persistence landscapes stored in a file (the file needs to be "
- "created beforehand). \n";
- std::cout << "The parameters of this programs are names of files with persistence landscapes.\n";
+ std::cout << "This program computes scalar product of persistence landscapes stored in a file (the file needs to be "
+ << "created beforehand). \n"
+ << "The parameters of this programs are names of files with persistence landscapes.\n";
+
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
+ return 1;
+ }
std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
@@ -40,7 +45,6 @@ int main(int argc, char** argv) {
std::vector<Persistence_landscape> landscaspes;
landscaspes.reserve(filenames.size());
for (size_t file_no = 0; file_no != filenames.size(); ++file_no) {
- std::cout << "Reading persistence landscape from a file : " << filenames[file_no] << std::endl;
Persistence_landscape l;
l.load_landscape_from_file(filenames[file_no]);
landscaspes.push_back(l);
@@ -64,7 +68,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("scalar_product");
+ out.open("scalar_product.land");
for (size_t i = 0; i != scalar_product.size(); ++i) {
for (size_t j = 0; j != scalar_product.size(); ++j) {
std::cout << scalar_product[i][j] << " ";
@@ -75,5 +79,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'scalar_product.land' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/create_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/create_landscapes.cpp
index 325081d1..6030e994 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes/create_landscapes.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes/create_landscapes.cpp
@@ -30,13 +30,20 @@
using Persistence_landscape = Gudhi::Persistence_representations::Persistence_landscape;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence landscapes of diagrams provided as an input. \n";
- std::cout << "The first parameter of the program is the dimension of persistence to be used to construct persistence "
- "landscapes. If your file contains ";
- std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence "
- "pairs you want to use. If your input files consist only ";
- std::cout << "of birth-death pairs, please set this first parameter to -1 \n";
- std::cout << "The remaining parameters of the program are the names of files with persistence diagrams. \n";
+ std::cout << "This program creates persistence landscapes files (*.land) of persistence diagrams files (*.pers) "
+ << "provided as an input.\n"
+ << "The first parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a first parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the first parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
+
+ if (argc < 3) {
+ std::cout << "Wrong parameter list, the program will now terminate \n";
+ return 1;
+ }
std::vector<const char*> filenames;
int dim = atoi(argv[1]);
unsigned dimension = std::numeric_limits<unsigned>::max();
@@ -47,13 +54,12 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence landscapes...\n";
for (size_t i = 0; i != filenames.size(); ++i) {
+ std::cout << "Creating a landscape based on file : " << filenames[i] << std::endl;
Persistence_landscape l(filenames[i], dimension);
std::stringstream ss;
ss << filenames[i] << ".land";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp
index ebdb20a1..c797a7a8 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp
@@ -28,16 +28,16 @@
using Persistence_landscape = Gudhi::Persistence_representations::Persistence_landscape;
int main(int argc, char** argv) {
- std::cout << "This program plot persistence landscape stored in a file (the file needs to be created beforehand). "
- "Please call the code with the name of a landscape file \n";
+ std::cout << "This program creates a gnuplot script from a persistence landscape stored in a file (the file needs "
+ << "to be created beforehand). Please call the code with the name of a single landscape file.\n";
+ if (argc != 2) {
+ std::cout << "Wrong parameter list, the program will now terminate \n";
+ return 1;
+ }
+
Persistence_landscape l;
l.load_landscape_from_file(argv[1]);
-
- std::stringstream ss;
- ss << argv[1] << "_gnuplot_script";
- l.plot(ss.str().c_str());
-
- std::cout << "Done \n";
+ l.plot(argv[1]);
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes/simple_diagram.txt.land b/src/Persistence_representations/utilities/persistence_landscapes/simple_diagram.txt.land
deleted file mode 100644
index b99d2f62..00000000
--- a/src/Persistence_representations/utilities/persistence_landscapes/simple_diagram.txt.land
+++ /dev/null
@@ -1,13 +0,0 @@
-#lambda_0
-1 0
-1.5 0.5
-2 0
-3 0
-3.5 0.5
-4 0
-5 0
-5.5 0.5
-6 0
-7 0
-7.5 0.5
-8 0
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt
index 55a4fd50..c5ea4bbf 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt
@@ -1,38 +1,11 @@
cmake_minimum_required(VERSION 2.6)
project(Persistence_representations_lanscapes_on_grid_utilities)
-file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/simple_diagram.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
+# Need to set grid min and max for further average, distance and scalar_product
+add_persistence_representation_creation_utility(create_landscapes_on_grid "100" "0" "35" "-1")
-add_executable ( create_landscapes_on_grid create_landscapes_on_grid.cpp )
-target_link_libraries(create_landscapes_on_grid ${Boost_SYSTEM_LIBRARY})
+add_persistence_representation_plot_utility(plot_landscapes_on_grid ".g_land")
-# Will create simple_diagram.txt.land
-add_test(NAME create_landscapes_on_grid COMMAND $<TARGET_FILE:create_landscapes_on_grid>
- "100" "-1" "-1" "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( average_landscapes_on_grid average_landscapes_on_grid.cpp )
-target_link_libraries(average_landscapes_on_grid ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME average_landscapes_on_grid COMMAND $<TARGET_FILE:average_landscapes_on_grid>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land")
-
-add_executable ( plot_landscapes_on_grid plot_landscapes_on_grid.cpp )
-target_link_libraries(plot_landscapes_on_grid ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME plot_landscapes_on_grid COMMAND $<TARGET_FILE:plot_landscapes_on_grid>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land")
-
-add_executable ( compute_distance_of_landscapes_on_grid compute_distance_of_landscapes_on_grid.cpp )
-target_link_libraries(compute_distance_of_landscapes_on_grid ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_distance_of_landscapes_on_grid COMMAND $<TARGET_FILE:compute_distance_of_landscapes_on_grid>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land")
-
-add_executable ( compute_scalar_product_of_landscapes_on_grid compute_scalar_product_of_landscapes_on_grid.cpp )
-target_link_libraries(compute_scalar_product_of_landscapes_on_grid ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_scalar_product_of_landscapes_on_grid COMMAND $<TARGET_FILE:compute_scalar_product_of_landscapes_on_grid>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.g_land")
+add_persistence_representation_function_utility(average_landscapes_on_grid ".g_land")
+add_persistence_representation_function_utility(compute_distance_of_landscapes_on_grid ".g_land" "1")
+add_persistence_representation_function_utility(compute_scalar_product_of_landscapes_on_grid ".g_land")
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp
index d50118a0..0b098d1a 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp
@@ -28,21 +28,20 @@
using Persistence_landscape_on_grid = Gudhi::Persistence_representations::Persistence_landscape_on_grid;
int main(int argc, char** argv) {
- std::cout << "This program computes average persistence landscape on grid of persistence landscapes on grid created "
- "based on persistence diagrams provided as an input. Please call this program with the names of files "
- "with persistence diagrams \n";
- std::vector<const char*> filenames;
+ std::cout << "This program computes average of persistence landscapes on grid stored in files (the files needs to "
+ << "be created beforehand).\n"
+ << "The parameters of this programs are names of files with persistence landscapes on grid.\n";
- if (argc == 1) {
- std::cout << "No input files given, the program will now terminate \n";
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
return 1;
}
+ std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence landscapes...\n";
std::vector<Persistence_landscape_on_grid*> lands;
for (size_t i = 0; i != filenames.size(); ++i) {
Persistence_landscape_on_grid* l = new Persistence_landscape_on_grid;
@@ -59,7 +58,6 @@ int main(int argc, char** argv) {
delete lands[i];
}
- std::cout << "Done \n";
-
+ std::cout << "Average can be found in 'average.g_land' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp
index 859c6991..fd0fcd15 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp
@@ -30,11 +30,11 @@
using Persistence_landscape_on_grid = Gudhi::Persistence_representations::Persistence_landscape_on_grid;
int main(int argc, char** argv) {
- std::cout << "This program compute distance of persistence landscapes on grid stored in a file (the file needs to be "
- "created beforehand). \n";
- std::cout << "The first parameter of a program is an integer p. The program compute L^p distance of the landscapes "
- "on grid. For L^infty distance choose p = -1. \n";
- std::cout << "The remaining parameters of this programs are names of files with persistence landscapes on grid.\n";
+ std::cout << "This program computes distance of persistence landscapes on grid stored in files (the files needs to "
+ << "be created beforehand).\n"
+ << "The first parameter of a program is an integer p. The program compute L^p distance of the two heat "
+ << "maps. For L^infty distance choose p = -1. \n"
+ << "The remaining parameters of this program are names of files with persistence landscapes on grid.\n";
if (argc < 3) {
std::cout << "Wrong number of parameters, the program will now terminate \n";
@@ -77,7 +77,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("distance");
+ out.open("distance.g_land");
for (size_t i = 0; i != distance.size(); ++i) {
for (size_t j = 0; j != distance.size(); ++j) {
std::cout << distance[i][j] << " ";
@@ -88,5 +88,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'distance.g_land' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp
index e95bf8ad..01de3dee 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp
@@ -29,9 +29,15 @@
using Persistence_landscape_on_grid = Gudhi::Persistence_representations::Persistence_landscape_on_grid;
int main(int argc, char** argv) {
- std::cout << "This program compute scalar product of persistence landscapes on grid stored in a file (the file needs "
- "to be created beforehand). \n";
- std::cout << "The parameters of this programs are names of files with persistence landscapes on grid.\n";
+ std::cout
+ << "This program computes scalar product of persistence landscapes on grid stored in a file (the file needs to "
+ << "be created beforehand). \n"
+ << "The parameters of this programs are names of files with persistence landscapes on grid.\n";
+
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
+ return 1;
+ }
std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
@@ -63,7 +69,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("scalar_product");
+ out.open("scalar_product.g_land");
for (size_t i = 0; i != scalar_product.size(); ++i) {
for (size_t j = 0; j != scalar_product.size(); ++j) {
std::cout << scalar_product[i][j] << " ";
@@ -74,5 +80,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'scalar_product.g_land' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp
index 8d747c14..78e8ef57 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp
@@ -30,18 +30,20 @@
using Persistence_landscape_on_grid = Gudhi::Persistence_representations::Persistence_landscape_on_grid;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence landscape on grid of diagrams provided as an input.\n";
- std::cout << "The first parameter of a program is an integer, a size of a grid.\n";
- std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
- "based on the data, set them both to -1 \n";
- std::cout << "The fourth parameter of the program is the dimension of persistence to be used to construct "
- "persistence landscape on a grid. If your file contains ";
- std::cout << "the information about dimension of birth-death pairs, please provide here the dimension of intervals "
- "you want to use. If your input files consist only ";
- std::cout << "of birth-death pairs, please set the fourth parameter to -1 \n";
- std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
+ std::cout << "This program creates persistence landscapes on grid files (*.g_land) of persistence diagrams files "
+ << "(*.pers) provided as an input.\n"
+ << "The first parameter of a program is an integer, a size of a grid.\n"
+ << "The second and third parameters are min and max of the grid. If you want those numbers to be computed "
+ << "based on the data, set them both to -1 \n"
+ << "The fourth parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a fourth parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the fourth parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
- if (argc < 5) {
+ if (argc < 6) {
std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
@@ -60,7 +62,6 @@ int main(int argc, char** argv) {
filenames.push_back(argv[i]);
}
- std::cout << "Creating persistence landscapes...\n";
for (size_t i = 0; i != filenames.size(); ++i) {
std::cout << "Creating persistence landscape on a grid based on a file : " << filenames[i] << std::endl;
Persistence_landscape_on_grid l;
@@ -74,6 +75,5 @@ int main(int argc, char** argv) {
ss << filenames[i] << ".g_land";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp
index 42822a01..dddb3615 100644
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp
+++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp
@@ -28,20 +28,17 @@
using Persistence_landscape_on_grid = Gudhi::Persistence_representations::Persistence_landscape_on_grid;
int main(int argc, char** argv) {
- std::cout << "This program plot persistence landscape on grid stored in a file (the file needs to be created "
- "beforehand). Please call the code with the name of a landscape on grid file \n";
- if (argc == 1) {
- std::cout << "Wrong parameters of a program call, the program will now terminate \n";
+ std::cout << "This program creates a gnuplot script from a persistence landscape on grid stored in a file (the file "
+ << "needs to be created beforehand). Please call the code with the name of a single landscape on grid file"
+ << ".\n";
+ if (argc != 2) {
+ std::cout << "Wrong parameter list, the program will now terminate \n";
return 1;
}
+
Persistence_landscape_on_grid l;
l.load_landscape_from_file(argv[1]);
-
- std::stringstream ss;
- ss << argv[1] << "_gnuplot_script";
- l.plot(ss.str().c_str());
-
- std::cout << "Done \n";
+ l.plot(argv[1]);
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/simple_diagram.txt.g_land b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/simple_diagram.txt.g_land
deleted file mode 100644
index dc53b932..00000000
--- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/simple_diagram.txt.g_land
+++ /dev/null
@@ -1,104 +0,0 @@
-1
-8
-101
-
-0.07
-0.14
-0.21
-0.28
-0.35
-0.42
-0.49
-0.42
-0.35
-0.28
-0.21
-0.14
-0.07
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0.07
-0.14
-0.21
-0.28
-0.35
-0.42
-0.49
-0.42
-0.35
-0.28
-0.21
-0.14
-0.07
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0.07
-0.14
-0.21
-0.28
-0.35
-0.42
-0.49
-0.42
-0.35
-0.28
-0.21
-0.14
-0.07
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-0.07
-0.14
-0.21
-0.28
-0.35
-0.42
-0.49
-0.42
-0.35
-0.28
-0.21
-0.14
-0.07
-
-
diff --git a/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt
index e3d1013b..a401c955 100644
--- a/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt
+++ b/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt
@@ -1,38 +1,10 @@
cmake_minimum_required(VERSION 2.6)
project(Persistence_vectors_utilities)
-file(COPY "${CMAKE_SOURCE_DIR}/data/persistence_diagram/simple_diagram.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
+add_persistence_representation_creation_utility(create_persistence_vectors "-1")
-add_executable ( create_persistence_vectors create_persistence_vectors.cpp )
-target_link_libraries(create_persistence_vectors ${Boost_SYSTEM_LIBRARY})
+add_persistence_representation_plot_utility(plot_persistence_vectors ".vect")
-# Will create simple_diagram.txt.vect
-add_test(NAME create_persistence_vectors COMMAND $<TARGET_FILE:create_persistence_vectors>
- "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt")
-
-add_executable ( average_persistence_vectors average_persistence_vectors.cpp )
-target_link_libraries(average_persistence_vectors ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME average_persistence_vectors COMMAND $<TARGET_FILE:average_persistence_vectors>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect")
-
-add_executable ( compute_distance_of_persistence_vectors compute_distance_of_persistence_vectors.cpp )
-target_link_libraries(compute_distance_of_persistence_vectors ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_distance_of_persistence_vectors COMMAND $<TARGET_FILE:compute_distance_of_persistence_vectors>
- "-1" "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect")
-
-add_executable ( compute_scalar_product_of_persistence_vectors compute_scalar_product_of_persistence_vectors.cpp )
-target_link_libraries(compute_scalar_product_of_persistence_vectors ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME compute_scalar_product_of_persistence_vectors COMMAND $<TARGET_FILE:compute_scalar_product_of_persistence_vectors>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect"
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect")
-
-add_executable ( plot_persistence_vectors plot_persistence_vectors.cpp )
-target_link_libraries(plot_persistence_vectors ${Boost_SYSTEM_LIBRARY})
-
-add_test(NAME plot_persistence_vectors COMMAND $<TARGET_FILE:plot_persistence_vectors>
- "${CMAKE_CURRENT_BINARY_DIR}/simple_diagram.txt.vect")
+add_persistence_representation_function_utility(average_persistence_vectors ".vect")
+add_persistence_representation_function_utility(compute_distance_of_persistence_vectors ".vect" "1")
+add_persistence_representation_function_utility(compute_scalar_product_of_persistence_vectors ".vect")
diff --git a/src/Persistence_representations/utilities/persistence_vectors/average_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/average_persistence_vectors.cpp
index 366ee2bc..0144e76f 100644
--- a/src/Persistence_representations/utilities/persistence_vectors/average_persistence_vectors.cpp
+++ b/src/Persistence_representations/utilities/persistence_vectors/average_persistence_vectors.cpp
@@ -26,25 +26,23 @@
#include <vector>
using Euclidean_distance = Gudhi::Euclidean_distance;
-using Vector_distances_in_diagram =
- Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
+using Vector_distances_in_diagram = Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
int main(int argc, char** argv) {
- std::cout << "This program computes average persistence vector of persistence vectors created based on persistence "
- "diagrams provided as an input. \n";
- std::cout << "Please call this program with the names of files with persistence diagrams \n";
- std::vector<const char*> filenames;
+ std::cout << "This program computes average of persistence vectors stored in files (the files needs to "
+ << "be created beforehand).\n"
+ << "The parameters of this programs are names of files with persistence vectors.\n";
- if (argc == 1) {
- std::cout << "No input files given, the program will now terminate \n";
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
return 1;
}
+ std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
filenames.push_back(argv[i]);
}
- std::cout << "Reading persistence vectors...\n";
std::vector<Vector_distances_in_diagram*> lands;
for (size_t i = 0; i != filenames.size(); ++i) {
Vector_distances_in_diagram* l = new Vector_distances_in_diagram;
diff --git a/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp
index 3aed297e..7e66d25e 100644
--- a/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp
+++ b/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp
@@ -28,8 +28,7 @@
#include <vector>
using Euclidean_distance = Gudhi::Euclidean_distance;
-using Vector_distances_in_diagram =
- Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
+using Vector_distances_in_diagram = Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
int main(int argc, char** argv) {
std::cout << "This program compute distance of persistence vectors stored in a file (the file needs to be created "
@@ -79,7 +78,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("distance");
+ out.open("distance.vect");
for (size_t i = 0; i != distance.size(); ++i) {
for (size_t j = 0; j != distance.size(); ++j) {
std::cout << distance[i][j] << " ";
@@ -90,5 +89,6 @@ int main(int argc, char** argv) {
}
out.close();
+ std::cout << "Distance can be found in 'distance.vect' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp
index d9ad4360..303c6e3e 100644
--- a/src/Persistence_representations/utilities/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp
+++ b/src/Persistence_representations/utilities/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp
@@ -28,13 +28,17 @@
#include <vector>
using Euclidean_distance = Gudhi::Euclidean_distance;
-using Vector_distances_in_diagram =
- Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
+using Vector_distances_in_diagram = Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
int main(int argc, char** argv) {
- std::cout << "This program compute scalar product of persistence vectors stored in a file (the file needs to be "
- "created beforehand). \n";
- std::cout << "The parameters of this programs are names of files with persistence vectors.\n";
+ std::cout << "This program computes scalar product of persistence vectors stored in a file (the file needs to "
+ << "be created beforehand). \n"
+ << "The parameters of this programs are names of files with persistence vectors.\n";
+
+ if (argc < 3) {
+ std::cout << "Wrong number of parameters, the program will now terminate \n";
+ return 1;
+ }
std::vector<const char*> filenames;
for (int i = 1; i < argc; ++i) {
@@ -66,7 +70,7 @@ int main(int argc, char** argv) {
// and now output the result to the screen and a file:
std::ofstream out;
- out.open("scalar_product");
+ out.open("scalar_product.vect");
for (size_t i = 0; i != scalar_product.size(); ++i) {
for (size_t j = 0; j != scalar_product.size(); ++j) {
std::cout << scalar_product[i][j] << " ";
@@ -76,5 +80,7 @@ int main(int argc, char** argv) {
out << std::endl;
}
out.close();
+
+ std::cout << "Distance can be found in 'scalar_product.vect' file\n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp
index b618ca67..cc5e5393 100644
--- a/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp
+++ b/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp
@@ -28,17 +28,24 @@
#include <vector>
using Euclidean_distance = Gudhi::Euclidean_distance;
-using Vector_distances_in_diagram =
- Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
+using Vector_distances_in_diagram = Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
int main(int argc, char** argv) {
- std::cout << "This program creates persistence vectors of diagrams provided as an input. The first parameter of this "
- "program is a dimension of persistence ";
- std::cout << " that will be used in creation of the persistence vectors. If our input files contain persistence "
- "pairs of various dimension, as a second parameter of the ";
- std::cout << " procedure please provide the dimension of persistence you want to use. If in your file there are only "
- "birth-death pairs of the same dimension, set the first parameter to -1."
- << std::endl;
+ std::cout << "This program creates persistence vectors files (*.vect) of persistence diagrams files (*.pers) "
+ << "provided as an input.\n"
+ << "The first parameter of this program is a dimension of persistence that will be used in creation of "
+ << "the persistence heat maps."
+ << "If your input files contains persistence pairs of various dimension, as a first parameter of the "
+ << "procedure please provide the dimension of persistence you want to use."
+ << "If in your files there are only birth-death pairs of the same dimension, set the first parameter to "
+ << "-1.\n"
+ << "The remaining parameters are the names of files with persistence diagrams. \n";
+
+ if (argc < 3) {
+ std::cout << "Wrong parameter list, the program will now terminate \n";
+ return 1;
+ }
+
std::cout << "The remaining parameters are the names of files with persistence diagrams. \n";
int dim = atoi(argv[1]);
unsigned dimension = std::numeric_limits<unsigned>::max();
@@ -58,6 +65,5 @@ int main(int argc, char** argv) {
ss << filenames[i] << ".vect";
l.print_to_file(ss.str().c_str());
}
- std::cout << "Done \n";
return 0;
}
diff --git a/src/Persistence_representations/utilities/persistence_vectors/plot_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/plot_persistence_vectors.cpp
index e52b8f7d..aa33107d 100644
--- a/src/Persistence_representations/utilities/persistence_vectors/plot_persistence_vectors.cpp
+++ b/src/Persistence_representations/utilities/persistence_vectors/plot_persistence_vectors.cpp
@@ -26,8 +26,7 @@
#include <sstream>
using Euclidean_distance = Gudhi::Euclidean_distance;
-using Vector_distances_in_diagram =
- Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
+using Vector_distances_in_diagram = Gudhi::Persistence_representations::Vector_distances_in_diagram<Euclidean_distance>;
int main(int argc, char** argv) {
std::cout << "This program create a Gnuplot script to plot persistence vector. Please call this program with the "
diff --git a/src/Persistence_representations/utilities/persistence_vectors/simple_diagram.txt.vect b/src/Persistence_representations/utilities/persistence_vectors/simple_diagram.txt.vect
deleted file mode 100644
index 1d4eeaaf..00000000
--- a/src/Persistence_representations/utilities/persistence_vectors/simple_diagram.txt.vect
+++ /dev/null
@@ -1 +0,0 @@
-0.707107 0.707107 0.707107 0.707107 0.707107 0.707107 0.707107 0.707107 0.707107 0.707107 \ No newline at end of file
diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
index 62bbbfc5..4dbe82c7 100644
--- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
+++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
@@ -165,7 +165,7 @@ outputs its persistence diagram.
\li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
Alpha_complex/alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
-\code $> ./alpha_complex_3d_persistence ../../data/points/tore3D_300.off 2 0.45 \endcode
+\code $> ./alpha_complex_3d_persistence ../../data/points/tore3D_300.off -p 2 -m 0.45 \endcode
\code Simplex_tree dim: 3
2 0 0 inf
2 1 0.0682162 1.0001
@@ -177,7 +177,7 @@ Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a> computes the persistent
\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 $> ./exact_alpha_complex_3d_persistence ../../data/points/sphere3D_pts_on_grid.off -p 2 -m 0.1 \endcode
\code Simplex_tree dim: 3
2 0 0 inf
2 2 0.0002 0.2028 \endcode
@@ -187,7 +187,7 @@ Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a> computes the persist
\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
+../../data/points/tore3D_300.weights -p 2 -m 0.45 \endcode
\code Simplex_tree dim: 3
2 0 -1 inf
2 1 -0.931784 0.000103311
@@ -208,8 +208,10 @@ Simplex_tree dim: 3
\li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the periodic alpha complex on points sampling from an OFF file.
+The second parameter is a \ref FileFormatsIsoCuboid file with coordinates of the periodic cuboid.
+Note that the lengths of the sides of the periodic cuboid have to be the same.
\code $> ./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off
-../../data/points/iso_cuboid_3_in_0_1.txt 3 1.0 \endcode
+../../data/points/iso_cuboid_3_in_0_1.txt -p 3 -m 1.0 \endcode
\code Periodic Delaunay computed.
Simplex_tree dim: 3
3 0 0 inf
@@ -221,11 +223,31 @@ Simplex_tree dim: 3
3 2 0.005 inf
3 3 0.0075 inf \endcode
+\li <a href="_persistent_cohomology_2weighted_periodic_alpha_complex_3d_persistence_8cpp-example.html">
+Persistent_cohomology/weighted_periodic_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
+\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the periodic alpha complex on weighted points from an OFF file. The
+additional parameters of this program are:<br>
+(a) The file with the weights of points. The file consist of a sequence of numbers (as many as points).
+Note that the weight of each single point have to be bounded by 1/64 times the square of the cuboid edge length.<br>
+(b) A \ref FileFormatsIsoCuboid file with coordinates of the periodic cuboid.
+Note that the lengths of the sides of the periodic cuboid have to be the same.<br>
+\code $> ./weighted_periodic_alpha_complex_3d_persistence ../../data/points/shifted_sphere.off
+../../data/points/shifted_sphere.weights ../../data/points/iso_cuboid_3_in_0_10.txt 3 1.0 \endcode
+\code Weighted Periodic Delaunay computed.
+Simplex_tree dim: 3
+3 0 -0.0001 inf
+3 1 16.0264 inf
+3 1 16.0273 inf
+3 1 16.0303 inf
+3 2 36.8635 inf
+3 2 36.8704 inf
+3 2 36.8838 inf
+3 3 58.6783 inf \endcode
+
\li <a href="_persistent_cohomology_2plain_homology_8cpp-example.html">
Persistent_cohomology/plain_homology.cpp</a> computes the plain homology of a simple simplicial complex without
filtration values.
- \copyright GNU General Public License v3.
*/
} // namespace persistent_cohomology
diff --git a/src/Rips_complex/doc/Intro_rips_complex.h b/src/Rips_complex/doc/Intro_rips_complex.h
index 124dfec9..8c517516 100644
--- a/src/Rips_complex/doc/Intro_rips_complex.h
+++ b/src/Rips_complex/doc/Intro_rips_complex.h
@@ -146,8 +146,6 @@ namespace rips_complex {
*
* \include Rips_complex/full_skeleton_rips_for_doc.txt
*
- * \copyright GNU General Public License v3.
- * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup rips_complex
diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp
index fc83f5f7..89afbc25 100644
--- a/src/Rips_complex/test/test_rips_complex.cpp
+++ b/src/Rips_complex/test/test_rips_complex.cpp
@@ -36,6 +36,7 @@
#include <gudhi/Simplex_tree.h>
#include <gudhi/distance_functions.h>
#include <gudhi/reader_utils.h>
+#include <gudhi/Unitary_tests_utils.h>
// Type definitions
using Point = std::vector<double>;
@@ -44,10 +45,6 @@ using Filtration_value = Simplex_tree::Filtration_value;
using Rips_complex = Gudhi::rips_complex::Rips_complex<Simplex_tree::Filtration_value>;
using Distance_matrix = std::vector<std::vector<Filtration_value>>;
-bool are_almost_the_same(float a, float b) {
- return std::fabs(a - b) < std::numeric_limits<float>::epsilon();
-}
-
BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) {
// ----------------------------------------------------------------------------
//
@@ -92,7 +89,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) {
std::cout << ") - distance =" << Gudhi::Euclidean_distance()(vp.at(0), vp.at(1)) <<
" - filtration =" << st.filtration(f_simplex) << std::endl;
BOOST_CHECK(vp.size() == 2);
- BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), Gudhi::Euclidean_distance()(vp.at(0), vp.at(1))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(st.filtration(f_simplex), Gudhi::Euclidean_distance()(vp.at(0), vp.at(1)));
}
}
@@ -113,14 +110,14 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) {
Simplex_tree::Filtration_value f12 = st2.filtration(st2.find({1, 2}));
Simplex_tree::Filtration_value f012 = st2.filtration(st2.find({0, 1, 2}));
std::cout << "f012= " << f012 << " | f01= " << f01 << " - f02= " << f02 << " - f12= " << f12 << std::endl;
- BOOST_CHECK(are_almost_the_same(f012, std::max(f01, std::max(f02,f12))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(f012, std::max(f01, std::max(f02,f12)));
Simplex_tree::Filtration_value f45 = st2.filtration(st2.find({4, 5}));
Simplex_tree::Filtration_value f56 = st2.filtration(st2.find({5, 6}));
Simplex_tree::Filtration_value f46 = st2.filtration(st2.find({4, 6}));
Simplex_tree::Filtration_value f456 = st2.filtration(st2.find({4, 5, 6}));
std::cout << "f456= " << f456 << " | f45= " << f45 << " - f56= " << f56 << " - f46= " << f46 << std::endl;
- BOOST_CHECK(are_almost_the_same(f456, std::max(f45, std::max(f56,f46))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(f456, std::max(f45, std::max(f56,f46)));
const int DIMENSION_3 = 3;
Simplex_tree st3;
@@ -140,7 +137,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) {
Simplex_tree::Filtration_value f0123 = st3.filtration(st3.find({0, 1, 2, 3}));
std::cout << "f0123= " << f0123 << " | f012= " << f012 << " - f123= " << f123 << " - f013= " << f013 <<
" - f023= " << f023 << std::endl;
- BOOST_CHECK(are_almost_the_same(f0123, std::max(f012, std::max(f123, std::max(f013, f023)))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(f0123, std::max(f012, std::max(f123, std::max(f013, f023))));
}
@@ -219,12 +216,12 @@ BOOST_AUTO_TEST_CASE(Rips_complex_from_points) {
std::cout << "dimension(" << st.dimension(f_simplex) << ") - f = " << st.filtration(f_simplex) << std::endl;
switch (st.dimension(f_simplex)) {
case 0:
- BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), 0.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(st.filtration(f_simplex), 0.0);
break;
case 1:
case 2:
case 3:
- BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), 2.0));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(st.filtration(f_simplex), 2.0);
break;
default:
BOOST_CHECK(false); // Shall not happen
@@ -276,7 +273,7 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) {
}
std::cout << ") - filtration =" << st.filtration(f_simplex) << std::endl;
BOOST_CHECK(vvh.size() == 2);
- BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), distances[vvh.at(0)][vvh.at(1)]));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(st.filtration(f_simplex), distances[vvh.at(0)][vvh.at(1)]);
}
}
@@ -297,14 +294,14 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) {
Simplex_tree::Filtration_value f12 = st2.filtration(st2.find({1, 2}));
Simplex_tree::Filtration_value f012 = st2.filtration(st2.find({0, 1, 2}));
std::cout << "f012= " << f012 << " | f01= " << f01 << " - f02= " << f02 << " - f12= " << f12 << std::endl;
- BOOST_CHECK(are_almost_the_same(f012, std::max(f01, std::max(f02,f12))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(f012, std::max(f01, std::max(f02,f12)));
Simplex_tree::Filtration_value f45 = st2.filtration(st2.find({4, 5}));
Simplex_tree::Filtration_value f56 = st2.filtration(st2.find({5, 6}));
Simplex_tree::Filtration_value f46 = st2.filtration(st2.find({4, 6}));
Simplex_tree::Filtration_value f456 = st2.filtration(st2.find({4, 5, 6}));
std::cout << "f456= " << f456 << " | f45= " << f45 << " - f56= " << f56 << " - f46= " << f46 << std::endl;
- BOOST_CHECK(are_almost_the_same(f456, std::max(f45, std::max(f56,f46))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(f456, std::max(f45, std::max(f56,f46)));
const int DIMENSION_3 = 3;
Simplex_tree st3;
@@ -324,7 +321,7 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) {
Simplex_tree::Filtration_value f0123 = st3.filtration(st3.find({0, 1, 2, 3}));
std::cout << "f0123= " << f0123 << " | f012= " << f012 << " - f123= " << f123 << " - f013= " << f013 <<
" - f023= " << f023 << std::endl;
- BOOST_CHECK(are_almost_the_same(f0123, std::max(f012, std::max(f123, std::max(f013, f023)))));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(f0123, std::max(f012, std::max(f123, std::max(f013, f023))));
}
diff --git a/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp b/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp
index d38808c7..ca3c0327 100644
--- a/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp
+++ b/src/Rips_complex/utilities/rips_distance_matrix_persistence.cpp
@@ -1,5 +1,5 @@
-/* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
+/* 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
@@ -36,18 +36,13 @@ using Simplex_tree = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persis
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 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);
+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[]) {
+int main(int argc, char* argv[]) {
std::string csv_matrix_file;
std::string filediag;
Filtration_value threshold;
@@ -88,33 +83,28 @@ int main(int argc, char * argv[]) {
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) {
+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 ';'.");
+ 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");
+ 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);
@@ -123,8 +113,7 @@ void program_options(int argc, char * argv[]
all.add(visible).add(hidden);
po::variables_map vm;
- po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), 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")) {
diff --git a/src/Rips_complex/utilities/rips_persistence.cpp b/src/Rips_complex/utilities/rips_persistence.cpp
index d504798b..8405c014 100644
--- a/src/Rips_complex/utilities/rips_persistence.cpp
+++ b/src/Rips_complex/utilities/rips_persistence.cpp
@@ -1,5 +1,5 @@
-/* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
+/* 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
@@ -37,19 +37,14 @@ using Simplex_tree = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persis
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 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);
+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[]) {
+int main(int argc, char* argv[]) {
std::string off_file_points;
std::string filediag;
Filtration_value threshold;
@@ -91,33 +86,27 @@ int main(int argc, char * argv[]) {
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) {
+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");
+ 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");
+ 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);
@@ -126,8 +115,7 @@ void program_options(int argc, char * argv[]
all.add(visible).add(hidden);
po::variables_map vm;
- po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), 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")) {
diff --git a/src/Rips_complex/utilities/README b/src/Rips_complex/utilities/ripscomplex.md
index 4d20c806..4291fae7 100644
--- a/src/Rips_complex/utilities/README
+++ b/src/Rips_complex/utilities/ripscomplex.md
@@ -1,13 +1,16 @@
-# Rips_complex #
-## `rips_persistence` ##
-This program computes the persistent homology with coefficient field *Z/pZ* of a Rips complex defined on a set of input points. The output diagram contains one bar per line, written with the convention:
+
+# Rips complex #
+
+## rips_persistence ##
+This program computes the persistent homology with coefficient field *Z/pZ* of a Rips complex defined on a set of input points, using Euclidean distance. The output diagram contains one bar per line, written with the convention:
`p dim birth death`
where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature, and `p` is the characteristic of the field *Z/pZ* used for homology coefficients (`p` must be a prime number).
**Usage**
+
`rips_persistence [options] <OFF input file>`
**Allowed options**
@@ -22,53 +25,25 @@ where `dim` is the dimension of the homological feature, `birth` and `death` are
Beware: this program may use a lot of RAM and take a lot of time if `max-edge-length` is set to a large value.
**Example 1 with Z/2Z coefficients**
-`rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 2`
-outputs:
-```
-2 0 0 inf
-2 1 0.0983494 inf
-2 1 0.104347 inf
-2 2 0.138335 inf
-```
+`rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 2`
**Example 2 with Z/3Z coefficients**
-rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3
+`rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3`
-outputs:
-```
-3 0 0 inf
-3 1 0.0983494 inf
-3 1 0.104347 inf
-3 2 0.138335 inf
-```
+## rips_distance_matrix_persistence ##
+Same as `rips_persistence` but taking a distance matrix as input.
-
-## `rips_distance_matrix_persistence` ##
-Same as `rips_persistence` but taking a distance matrix as input.
-
**Usage**
-`rips_persistence [options] <CSV input file>`
-where
+
+`rips_persistence [options] <CSV input file>`
+
+where
`<CSV input file>` is the path to the file containing a distance matrix. Can be square or lower triangular matrix. Separator is ';'.
**Example**
-`rips_distance_matrix_persistence data/distance_matrix/full_square_distance_matrix.csv -r 15 -d 3 -p 3 -m 0`
-outputs:
-```
-The complex contains 46 simplices
- and has dimension 3
-3 0 0 inf
-3 0 0 8.94427
-3 0 0 7.28011
-3 0 0 6.08276
-3 0 0 5.83095
-3 0 0 5.38516
-3 0 0 5
-3 1 11 12.0416
-3 1 6.32456 6.7082
-```
+`rips_distance_matrix_persistence data/distance_matrix/full_square_distance_matrix.csv -r 15 -d 3 -p 3 -m 0`
diff --git a/src/Simplex_tree/doc/Intro_simplex_tree.h b/src/Simplex_tree/doc/Intro_simplex_tree.h
index 769491d9..6b80d1c9 100644
--- a/src/Simplex_tree/doc/Intro_simplex_tree.h
+++ b/src/Simplex_tree/doc/Intro_simplex_tree.h
@@ -79,7 +79,6 @@ Number of vertices = 10 Number of simplices = 98 \endcode
* 1 incidence relations in a complex. It is consequently faster when accessing the boundary of a simplex, but is less
* compact and harder to construct from scratch.
*
- * \copyright GNU General Public License v3.
* @}
*/
diff --git a/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp b/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp
index 217e251f..9bd51106 100644
--- a/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp
+++ b/src/Simplex_tree/example/cech_complex_cgal_mini_sphere_3d.cpp
@@ -1,5 +1,5 @@
-/* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
+/* 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
@@ -33,7 +33,7 @@
#include <string>
#include <vector>
-#include <limits> // infinity
+#include <limits> // infinity
#include <utility> // for pair
#include <map>
@@ -50,15 +50,14 @@ using Vertex_handle = Simplex_tree::Vertex_handle;
using Simplex_handle = Simplex_tree::Simplex_handle;
using Filtration_value = Simplex_tree::Filtration_value;
using Siblings = Simplex_tree::Siblings;
-using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS
-, boost::property < Gudhi::vertex_filtration_t, Filtration_value >
-, boost::property < Gudhi::edge_filtration_t, Filtration_value >
->;
-using Edge_t = std::pair< Vertex_handle, Vertex_handle >;
+using Graph_t = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
+ boost::property<Gudhi::vertex_filtration_t, Filtration_value>,
+ boost::property<Gudhi::edge_filtration_t, Filtration_value> >;
+using Edge_t = std::pair<Vertex_handle, Vertex_handle>;
-using Kernel = CGAL::Epick_d< CGAL::Dimension_tag<3> >;
+using Kernel = CGAL::Epick_d<CGAL::Dimension_tag<3> >;
using Point = Kernel::Point_d;
-using Traits = CGAL::Min_sphere_of_points_d_traits_d<Kernel,Filtration_value,3>;
+using Traits = CGAL::Min_sphere_of_points_d_traits_d<Kernel, Filtration_value, 3>;
using Min_sphere = CGAL::Min_sphere_of_spheres_d<Traits>;
using Points_off_reader = Gudhi::Points_off_reader<Point>;
@@ -76,7 +75,7 @@ class Cech_blocker {
std::cout << vertex << ", ";
#endif // DEBUG_TRACES
}
- Min_sphere ms(points.begin(),points.end());
+ Min_sphere ms(points.begin(), points.end());
Filtration_value radius = ms.radius();
#if DEBUG_TRACES
std::cout << "] - radius = " << radius << " - returns " << (radius > threshold_) << std::endl;
@@ -85,24 +84,20 @@ class Cech_blocker {
return (radius > threshold_);
}
Cech_blocker(Simplex_tree& simplex_tree, Filtration_value threshold, const std::vector<Point>& point_cloud)
- : simplex_tree_(simplex_tree),
- threshold_(threshold),
- point_cloud_(point_cloud) { }
+ : simplex_tree_(simplex_tree), threshold_(threshold), point_cloud_(point_cloud) {}
+
private:
Simplex_tree simplex_tree_;
Filtration_value threshold_;
std::vector<Point> point_cloud_;
};
-template< typename InputPointRange>
-Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold);
+template <typename InputPointRange>
+Graph_t compute_proximity_graph(InputPointRange& points, Filtration_value threshold);
-void program_options(int argc, char * argv[]
- , std::string & off_file_points
- , Filtration_value & threshold
- , int & dim_max);
+void program_options(int argc, char* argv[], std::string& off_file_points, Filtration_value& threshold, int& dim_max);
-int main(int argc, char * argv[]) {
+int main(int argc, char* argv[]) {
std::string off_file_points;
Filtration_value threshold;
int dim_max;
@@ -115,7 +110,7 @@ int main(int argc, char * argv[]) {
// Compute the proximity graph of the points
Graph_t prox_graph = compute_proximity_graph(off_reader.get_point_cloud(), threshold);
- //Min_sphere sph1(off_reader.get_point_cloud()[0], off_reader.get_point_cloud()[1], off_reader.get_point_cloud()[2]);
+ // Min_sphere sph1(off_reader.get_point_cloud()[0], off_reader.get_point_cloud()[1], off_reader.get_point_cloud()[2]);
// Construct the Rips complex in a Simplex Tree
Simplex_tree st;
// insert the proximity graph in the simplex tree
@@ -135,7 +130,8 @@ int main(int argc, char * argv[]) {
std::cout << "* The complex contains " << st.num_simplices() << " simplices - dimension=" << st.dimension() << "\n";
std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
for (auto f_simplex : st.filtration_simplex_range()) {
- std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ std::cout << " "
+ << "[" << st.filtration(f_simplex) << "] ";
for (auto vertex : st.simplex_vertex_range(f_simplex)) {
std::cout << static_cast<int>(vertex) << " ";
}
@@ -145,24 +141,19 @@ int main(int argc, char * argv[]) {
return 0;
}
-void program_options(int argc, char * argv[]
- , std::string & off_file_points
- , Filtration_value & threshold
- , int & dim_max) {
+void program_options(int argc, char* argv[], std::string& off_file_points, Filtration_value& threshold, int& dim_max) {
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 3d point set.\n");
+ hidden.add_options()("input-file", po::value<std::string>(&off_file_points),
+ "Name of an OFF file containing a 3d point set.\n");
po::options_description visible("Allowed options", 100);
- visible.add_options()
- ("help,h", "produce help message")
- ("max-edge-length,r",
- po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
- "Maximal length of an edge for the Cech complex construction.")
- ("cpx-dimension,d", po::value<int>(&dim_max)->default_value(1),
- "Maximal dimension of the Cech complex we want to compute.");
+ visible.add_options()("help,h", "produce help message")(
+ "max-edge-length,r",
+ po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
+ "Maximal length of an edge for the Cech complex construction.")(
+ "cpx-dimension,d", po::value<int>(&dim_max)->default_value(1),
+ "Maximal dimension of the Cech complex we want to compute.");
po::positional_options_description pos;
pos.add("input-file", 1);
@@ -171,8 +162,7 @@ void program_options(int argc, char * argv[]
all.add(visible).add(hidden);
po::variables_map vm;
- po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), 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")) {
@@ -194,10 +184,10 @@ void program_options(int argc, char * argv[]
* The type PointCloud furnishes .begin() and .end() methods, that return
* iterators with value_type Point.
*/
-template< typename InputPointRange>
-Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold) {
- std::vector< Edge_t > edges;
- std::vector< Filtration_value > edges_fil;
+template <typename InputPointRange>
+Graph_t compute_proximity_graph(InputPointRange& points, Filtration_value threshold) {
+ std::vector<Edge_t> edges;
+ std::vector<Filtration_value> edges_fil;
Kernel k;
Vertex_handle idx_u, idx_v;
@@ -217,16 +207,13 @@ Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value thresh
++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
+ 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(Gudhi::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) {
+ for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) {
boost::put(vertex_prop, *vi, 0.);
}
diff --git a/src/Simplex_tree/example/graph_expansion_with_blocker.cpp b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp
index 86bfb8cb..0d458cbd 100644
--- a/src/Simplex_tree/example/graph_expansion_with_blocker.cpp
+++ b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp
@@ -27,8 +27,7 @@
using Simplex_tree = Gudhi::Simplex_tree<>;
using Simplex_handle = Simplex_tree::Simplex_handle;
-int main(int argc, char * const argv[]) {
-
+int main(int argc, char* const argv[]) {
// Construct the Simplex Tree with a 1-skeleton graph example
Simplex_tree simplexTree;
@@ -45,33 +44,32 @@ int main(int argc, char * const argv[]) {
simplexTree.insert_simplex({5, 6}, 10.);
simplexTree.insert_simplex({6}, 10.);
- simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){
- bool result = false;
- std::cout << "Blocker on [";
- // User can loop on the vertices from the given simplex_handle i.e.
- for (auto vertex : simplexTree.simplex_vertex_range(sh)) {
- // We block the expansion, if the vertex '6' is in the given list of vertices
- if (vertex == 6)
- result = true;
- std::cout << vertex << ", ";
- }
- std::cout << "] ( " << simplexTree.filtration(sh);
- // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries)
- simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.);
+ simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh) {
+ bool result = false;
+ std::cout << "Blocker on [";
+ // User can loop on the vertices from the given simplex_handle i.e.
+ for (auto vertex : simplexTree.simplex_vertex_range(sh)) {
+ // We block the expansion, if the vertex '6' is in the given list of vertices
+ if (vertex == 6) result = true;
+ std::cout << vertex << ", ";
+ }
+ std::cout << "] ( " << simplexTree.filtration(sh);
+ // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries)
+ simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.);
- std::cout << " + 1. ) = " << result << std::endl;
+ std::cout << " + 1. ) = " << result << std::endl;
- return result;
- });
+ return result;
+ });
std::cout << "********************************************************************\n";
std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices";
std::cout << " - dimension " << simplexTree.dimension() << "\n";
std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
for (auto f_simplex : simplexTree.filtration_simplex_range()) {
- std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] ";
- for (auto vertex : simplexTree.simplex_vertex_range(f_simplex))
- std::cout << "(" << vertex << ")";
+ std::cout << " "
+ << "[" << simplexTree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) std::cout << "(" << vertex << ")";
std::cout << std::endl;
}
diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp
index b6b65b88..828977c2 100644
--- a/src/Simplex_tree/example/simple_simplex_tree.cpp
+++ b/src/Simplex_tree/example/simple_simplex_tree.cpp
@@ -30,10 +30,10 @@
using Simplex_tree = Gudhi::Simplex_tree<>;
using Vertex_handle = Simplex_tree::Vertex_handle;
using Filtration_value = Simplex_tree::Filtration_value;
-using typeVectorVertex = std::vector< Vertex_handle >;
-using typePairSimplexBool = std::pair< Simplex_tree::Simplex_handle, bool >;
+using typeVectorVertex = std::vector<Vertex_handle>;
+using typePairSimplexBool = std::pair<Simplex_tree::Simplex_handle, bool>;
-int main(int argc, char * const argv[]) {
+int main(int argc, char* const argv[]) {
const Filtration_value FIRST_FILTRATION_VALUE = 0.1;
const Filtration_value SECOND_FILTRATION_VALUE = 0.2;
const Filtration_value THIRD_FILTRATION_VALUE = 0.3;
@@ -54,7 +54,7 @@ int main(int argc, char * const argv[]) {
// ++ FIRST
std::cout << " * INSERT 0" << std::endl;
- typeVectorVertex firstSimplexVector = { 0 };
+ typeVectorVertex firstSimplexVector = {0};
typePairSimplexBool returnValue =
simplexTree.insert_simplex(firstSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
@@ -66,9 +66,8 @@ int main(int argc, char * const argv[]) {
// ++ SECOND
std::cout << " * INSERT 1" << std::endl;
- typeVectorVertex secondSimplexVector = { 1 };
- returnValue =
- simplexTree.insert_simplex(secondSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ typeVectorVertex secondSimplexVector = {1};
+ returnValue = simplexTree.insert_simplex(secondSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 1 INSERTED" << std::endl;
@@ -78,9 +77,8 @@ int main(int argc, char * const argv[]) {
// ++ THIRD
std::cout << " * INSERT (0,1)" << std::endl;
- typeVectorVertex thirdSimplexVector = { 0, 1 };
- returnValue =
- simplexTree.insert_simplex(thirdSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ typeVectorVertex thirdSimplexVector = {0, 1};
+ returnValue = simplexTree.insert_simplex(thirdSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + (0,1) INSERTED" << std::endl;
@@ -90,9 +88,8 @@ int main(int argc, char * const argv[]) {
// ++ FOURTH
std::cout << " * INSERT 2" << std::endl;
- typeVectorVertex fourthSimplexVector = { 2 };
- returnValue =
- simplexTree.insert_simplex(fourthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ typeVectorVertex fourthSimplexVector = {2};
+ returnValue = simplexTree.insert_simplex(fourthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 2 INSERTED" << std::endl;
@@ -102,9 +99,8 @@ int main(int argc, char * const argv[]) {
// ++ FIFTH
std::cout << " * INSERT (2,0)" << std::endl;
- typeVectorVertex fifthSimplexVector = { 2, 0 };
- returnValue =
- simplexTree.insert_simplex(fifthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ typeVectorVertex fifthSimplexVector = {2, 0};
+ returnValue = simplexTree.insert_simplex(fifthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + (2,0) INSERTED" << std::endl;
@@ -114,9 +110,8 @@ int main(int argc, char * const argv[]) {
// ++ SIXTH
std::cout << " * INSERT (2,1)" << std::endl;
- typeVectorVertex sixthSimplexVector = { 2, 1 };
- returnValue =
- simplexTree.insert_simplex(sixthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ typeVectorVertex sixthSimplexVector = {2, 1};
+ returnValue = simplexTree.insert_simplex(sixthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + (2,1) INSERTED" << std::endl;
@@ -126,9 +121,8 @@ int main(int argc, char * const argv[]) {
// ++ SEVENTH
std::cout << " * INSERT (2,1,0)" << std::endl;
- typeVectorVertex seventhSimplexVector = { 2, 1, 0 };
- returnValue =
- simplexTree.insert_simplex(seventhSimplexVector, Filtration_value(THIRD_FILTRATION_VALUE));
+ typeVectorVertex seventhSimplexVector = {2, 1, 0};
+ returnValue = simplexTree.insert_simplex(seventhSimplexVector, Filtration_value(THIRD_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + (2,1,0) INSERTED" << std::endl;
@@ -138,9 +132,8 @@ int main(int argc, char * const argv[]) {
// ++ EIGHTH
std::cout << " * INSERT 3" << std::endl;
- typeVectorVertex eighthSimplexVector = { 3 };
- returnValue =
- simplexTree.insert_simplex(eighthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ typeVectorVertex eighthSimplexVector = {3};
+ returnValue = simplexTree.insert_simplex(eighthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 3 INSERTED" << std::endl;
@@ -150,9 +143,8 @@ int main(int argc, char * const argv[]) {
// ++ NINETH
std::cout << " * INSERT (3,0)" << std::endl;
- typeVectorVertex ninethSimplexVector = { 3, 0 };
- returnValue =
- simplexTree.insert_simplex(ninethSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ typeVectorVertex ninethSimplexVector = {3, 0};
+ returnValue = simplexTree.insert_simplex(ninethSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + (3,0) INSERTED" << std::endl;
@@ -162,7 +154,7 @@ int main(int argc, char * const argv[]) {
// ++ TENTH
std::cout << " * INSERT 0 (already inserted)" << std::endl;
- typeVectorVertex tenthSimplexVector = { 0 };
+ typeVectorVertex tenthSimplexVector = {0};
// With a different filtration value
returnValue = simplexTree.insert_simplex(tenthSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
@@ -174,9 +166,8 @@ int main(int argc, char * const argv[]) {
// ++ ELEVENTH
std::cout << " * INSERT (2,1,0) (already inserted)" << std::endl;
- typeVectorVertex eleventhSimplexVector = { 2, 1, 0 };
- returnValue =
- simplexTree.insert_simplex(eleventhSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
+ typeVectorVertex eleventhSimplexVector = {2, 1, 0};
+ returnValue = simplexTree.insert_simplex(eleventhSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + (2,1,0) INSERTED" << std::endl;
@@ -192,9 +183,9 @@ int main(int argc, char * const argv[]) {
std::cout << " - dimension " << simplexTree.dimension() << "\n";
std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
for (auto f_simplex : simplexTree.filtration_simplex_range()) {
- std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] ";
- for (auto vertex : simplexTree.simplex_vertex_range(f_simplex))
- std::cout << "(" << vertex << ")";
+ std::cout << " "
+ << "[" << simplexTree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) std::cout << "(" << vertex << ")";
std::cout << std::endl;
}
// [0.1] 0
@@ -217,7 +208,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- typeVectorVertex unknownSimplexVector = { 15 };
+ typeVectorVertex unknownSimplexVector = {15};
simplexFound = simplexTree.find(unknownSimplexVector);
std::cout << "**************IS THE SIMPLEX {15} IN THE SIMPLEX TREE ?\n";
if (simplexFound != simplexTree.null_simplex())
@@ -232,7 +223,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- typeVectorVertex otherSimplexVector = { 1, 15 };
+ typeVectorVertex otherSimplexVector = {1, 15};
simplexFound = simplexTree.find(otherSimplexVector);
std::cout << "**************IS THE SIMPLEX {15,1} IN THE SIMPLEX TREE ?\n";
if (simplexFound != simplexTree.null_simplex())
@@ -240,7 +231,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- typeVectorVertex invSimplexVector = { 1, 2, 0 };
+ typeVectorVertex invSimplexVector = {1, 2, 0};
simplexFound = simplexTree.find(invSimplexVector);
std::cout << "**************IS THE SIMPLEX {1,2,0} IN THE SIMPLEX TREE ?\n";
if (simplexFound != simplexTree.null_simplex())
@@ -248,7 +239,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- simplexFound = simplexTree.find({ 0, 1 });
+ simplexFound = simplexTree.find({0, 1});
std::cout << "**************IS THE SIMPLEX {0,1} IN THE SIMPLEX TREE ?\n";
if (simplexFound != simplexTree.null_simplex())
std::cout << "***+ YES IT IS!\n";
@@ -256,23 +247,20 @@ int main(int argc, char * const argv[]) {
std::cout << "***- NO IT ISN'T\n";
std::cout << "**************COFACES OF {0,1} IN CODIMENSION 1 ARE\n";
- for (auto& simplex : simplexTree.cofaces_simplex_range(simplexTree.find({0,1}), 1)) {
- for (auto vertex : simplexTree.simplex_vertex_range(simplex))
- std::cout << "(" << vertex << ")";
+ for (auto& simplex : simplexTree.cofaces_simplex_range(simplexTree.find({0, 1}), 1)) {
+ for (auto vertex : simplexTree.simplex_vertex_range(simplex)) std::cout << "(" << vertex << ")";
std::cout << std::endl;
}
std::cout << "**************STARS OF {0,1} ARE\n";
- for (auto& simplex : simplexTree.star_simplex_range(simplexTree.find({0,1}))) {
- for (auto vertex : simplexTree.simplex_vertex_range(simplex))
- std::cout << "(" << vertex << ")";
+ for (auto& simplex : simplexTree.star_simplex_range(simplexTree.find({0, 1}))) {
+ for (auto vertex : simplexTree.simplex_vertex_range(simplex)) std::cout << "(" << vertex << ")";
std::cout << std::endl;
}
std::cout << "**************BOUNDARIES OF {0,1,2} ARE\n";
- for (auto& simplex : simplexTree.boundary_simplex_range(simplexTree.find({0,1,2}))) {
- for (auto vertex : simplexTree.simplex_vertex_range(simplex))
- std::cout << "(" << vertex << ")";
+ for (auto& simplex : simplexTree.boundary_simplex_range(simplexTree.find({0, 1, 2}))) {
+ for (auto vertex : simplexTree.simplex_vertex_range(simplex)) std::cout << "(" << vertex << ")";
std::cout << std::endl;
}
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h
index cb6ab309..7456cb1f 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h
@@ -49,6 +49,7 @@
#include <initializer_list>
#include <algorithm> // for std::max
#include <cstdint> // for std::uint32_t
+#include <iterator> // for std::distance
namespace Gudhi {
@@ -106,8 +107,9 @@ class Simplex_tree {
};
struct Key_simplex_base_dummy {
Key_simplex_base_dummy() {}
- void assign_key(Simplex_key) { }
- Simplex_key key() const { assert(false); return -1; }
+ // Undefined so it will not link
+ void assign_key(Simplex_key);
+ Simplex_key key() const;
};
typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type
Key_simplex_base;
@@ -121,7 +123,7 @@ class Simplex_tree {
};
struct Filtration_simplex_base_dummy {
Filtration_simplex_base_dummy() {}
- void assign_filtration(Filtration_value f) { assert(f == 0); }
+ void assign_filtration(Filtration_value GUDHI_CHECK_code(f)) { GUDHI_CHECK(f == 0, "filtration value specified for a complex that does not store them"); }
Filtration_value filtration() const { return 0; }
};
typedef typename std::conditional<Options::store_filtration, Filtration_simplex_base_real,
@@ -500,6 +502,7 @@ class Simplex_tree {
* sh has children.*/
template<class SimplexHandle>
bool has_children(SimplexHandle sh) const {
+ // Here we rely on the root using null_vertex(), which cannot match any real vertex.
return (sh->second.children()->parent() == sh->first);
}
@@ -529,18 +532,30 @@ class Simplex_tree {
Simplex_handle find_simplex(const std::vector<Vertex_handle> & simplex) {
Siblings * tmp_sib = &root_;
Dictionary_it tmp_dit;
- Vertex_handle last = simplex.back();
- for (auto v : simplex) {
- tmp_dit = tmp_sib->members_.find(v);
- if (tmp_dit == tmp_sib->members_.end()) {
+ auto vi = simplex.begin();
+ if (Options::contiguous_vertices) {
+ // Equivalent to the first iteration of the normal loop
+ GUDHI_CHECK(contiguous_vertices(), "non-contiguous vertices");
+ Vertex_handle v = *vi++;
+ if(v < 0 || v >= static_cast<Vertex_handle>(root_.members_.size()))
return null_simplex();
- }
- if (!has_children(tmp_dit) && v != last) {
+ tmp_dit = root_.members_.begin() + v;
+ if (vi == simplex.end())
+ return tmp_dit;
+ if (!has_children(tmp_dit))
+ return null_simplex();
+ tmp_sib = tmp_dit->second.children();
+ }
+ for (;;) {
+ tmp_dit = tmp_sib->members_.find(*vi++);
+ if (tmp_dit == tmp_sib->members_.end())
+ return null_simplex();
+ if (vi == simplex.end())
+ return tmp_dit;
+ if (!has_children(tmp_dit))
return null_simplex();
- }
tmp_sib = tmp_dit->second.children();
}
- return tmp_dit;
}
/** \brief Returns the Simplex_handle corresponding to the 0-simplex
@@ -584,12 +599,14 @@ class Simplex_tree {
std::pair<Simplex_handle, bool> res_insert;
auto vi = simplex.begin();
for (; vi != simplex.end() - 1; ++vi) {
+ GUDHI_CHECK(*vi != null_vertex(), "cannot use the dummy null_vertex() as a real vertex");
res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
if (!(has_children(res_insert.first))) {
res_insert.first->second.assign_children(new Siblings(curr_sib, *vi));
}
curr_sib = res_insert.first->second.children();
}
+ GUDHI_CHECK(*vi != null_vertex(), "cannot use the dummy null_vertex() as a real vertex");
res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
if (!res_insert.second) {
// if already in the complex
@@ -664,71 +681,67 @@ class Simplex_tree {
*/
template<class InputVertexRange = std::initializer_list<Vertex_handle>>
std::pair<Simplex_handle, bool> insert_simplex_and_subfaces(const InputVertexRange& Nsimplex,
- Filtration_value filtration = 0) {
+ Filtration_value filtration = 0) {
auto first = std::begin(Nsimplex);
auto last = std::end(Nsimplex);
if (first == last)
- return std::pair<Simplex_handle, bool>(null_simplex(), true); // ----->>
+ return { null_simplex(), true }; // ----->>
// Copy before sorting
- std::vector<Vertex_handle> copy(first, last);
+ thread_local std::vector<Vertex_handle> copy;
+ copy.clear();
+ copy.insert(copy.end(), first, last);
std::sort(std::begin(copy), std::end(copy));
+ GUDHI_CHECK_code(
+ for (Vertex_handle v : copy)
+ GUDHI_CHECK(v != null_vertex(), "cannot use the dummy null_vertex() as a real vertex");
+ )
- std::vector<std::vector<Vertex_handle>> to_be_inserted;
- std::vector<std::vector<Vertex_handle>> to_be_propagated;
- return rec_insert_simplex_and_subfaces(copy, to_be_inserted, to_be_propagated, filtration);
+ return insert_simplex_and_subfaces_sorted(copy, filtration);
}
private:
- std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces(std::vector<Vertex_handle>& the_simplex,
- std::vector<std::vector<Vertex_handle>>& to_be_inserted,
- std::vector<std::vector<Vertex_handle>>& to_be_propagated,
- Filtration_value filtration = 0.0) {
- std::pair<Simplex_handle, bool> insert_result;
- if (the_simplex.size() > 1) {
- // Get and remove last vertex
- Vertex_handle last_vertex = the_simplex.back();
- the_simplex.pop_back();
- // Recursive call after last vertex removal
- insert_result = rec_insert_simplex_and_subfaces(the_simplex, to_be_inserted, to_be_propagated, filtration);
-
- // Concatenation of to_be_inserted and to_be_propagated
- to_be_inserted.insert(to_be_inserted.begin(), to_be_propagated.begin(), to_be_propagated.end());
- to_be_propagated = to_be_inserted;
-
- // to_be_inserted treatment
- for (auto& simplex_tbi : to_be_inserted) {
- simplex_tbi.push_back(last_vertex);
- }
- std::vector<Vertex_handle> last_simplex(1, last_vertex);
- to_be_inserted.insert(to_be_inserted.begin(), last_simplex);
- // i.e. (0,1,2) =>
- // [to_be_inserted | to_be_propagated] = [(1) (0,1) | (0)]
- // [to_be_inserted | to_be_propagated] = [(2) (0,2) (1,2) (0,1,2) | (0) (1) (0,1)]
- // N.B. : it is important the last inserted to be the highest in dimension
- // in order to return the "last" insert_simplex result
-
- // insert all to_be_inserted
- for (auto& simplex_tbi : to_be_inserted) {
- insert_result = insert_vertex_vector(simplex_tbi, filtration);
- }
- } else if (the_simplex.size() == 1) {
- // When reaching the end of recursivity, vector of simplices shall be empty and filled on back recursive
- if ((to_be_inserted.size() != 0) || (to_be_propagated.size() != 0)) {
- std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Error vector not empty\n";
- exit(-1);
+ /// Same as insert_simplex_and_subfaces but assumes that the range of vertices is sorted
+ template<class ForwardVertexRange = std::initializer_list<Vertex_handle>>
+ std::pair<Simplex_handle, bool> insert_simplex_and_subfaces_sorted(const ForwardVertexRange& Nsimplex, Filtration_value filt = 0) {
+ auto first = std::begin(Nsimplex);
+ auto last = std::end(Nsimplex);
+ if (first == last)
+ return { null_simplex(), true }; // FIXME: false would make more sense to me.
+ GUDHI_CHECK(std::is_sorted(first, last), "simplex vertices listed in unsorted order");
+ // Update dimension if needed. We could wait to see if the insertion succeeds, but I doubt there is much to gain.
+ dimension_ = (std::max)(dimension_, static_cast<int>(std::distance(first, last)) - 1);
+ return rec_insert_simplex_and_subfaces_sorted(root(), first, last, filt);
+ }
+ // To insert {1,2,3,4}, we insert {2,3,4} twice, once at the root, and once below 1.
+ template<class ForwardVertexIterator>
+ std::pair<Simplex_handle, bool> rec_insert_simplex_and_subfaces_sorted(Siblings* sib, ForwardVertexIterator first, ForwardVertexIterator last, Filtration_value filt) {
+ // An alternative strategy would be:
+ // - try to find the complete simplex, if found (and low filtration) exit
+ // - insert all the vertices at once in sib
+ // - loop over those (new or not) simplices, with a recursive call(++first, last)
+ Vertex_handle vertex_one = *first;
+ auto&& dict = sib->members();
+ auto insertion_result = dict.emplace(vertex_one, Node(sib, filt));
+ Simplex_handle simplex_one = insertion_result.first;
+ bool one_is_new = insertion_result.second;
+ if (!one_is_new) {
+ if (filtration(simplex_one) > filt) {
+ assign_filtration(simplex_one, filt);
+ } else {
+ // FIXME: this interface makes no sense, and it doesn't seem to be tested.
+ insertion_result.first = null_simplex();
}
- std::vector<Vertex_handle> first_simplex(1, the_simplex.back());
- // i.e. (0,1,2) => [to_be_inserted | to_be_propagated] = [(0) | ]
- to_be_inserted.push_back(first_simplex);
-
- insert_result = insert_vertex_vector(first_simplex, filtration);
- } else {
- std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Recursivity error\n";
- exit(-1);
}
- return insert_result;
+ if (++first == last) return insertion_result;
+ if (!has_children(simplex_one))
+ // TODO: have special code here, we know we are building the whole subtree from scratch.
+ simplex_one->second.assign_children(new Siblings(sib, vertex_one));
+ auto res = rec_insert_simplex_and_subfaces_sorted(simplex_one->second.children(), first, last, filt);
+ // No need to continue if the full simplex was already there with a low enough filtration value.
+ if (res.first != null_simplex()) rec_insert_simplex_and_subfaces_sorted(sib, first, last, filt);
+ return res;
}
public:
@@ -941,8 +954,9 @@ class Simplex_tree {
* called.
*
* Inserts all vertices and edges given by a OneSkeletonGraph.
- * OneSkeletonGraph must be a model of boost::AdjacencyGraph,
- * boost::EdgeListGraph and boost::PropertyGraph.
+ * OneSkeletonGraph must be a model of
+ * <a href="http://www.boost.org/doc/libs/1_65_1/libs/graph/doc/EdgeListGraph.html">boost::EdgeListGraph</a>
+ * and <a href="http://www.boost.org/doc/libs/1_65_1/libs/graph/doc/PropertyGraph.html">boost::PropertyGraph</a>.
*
* The vertex filtration value is accessible through the property tag
* vertex_filtration_t.
@@ -952,7 +966,10 @@ class Simplex_tree {
* boost::graph_traits<OneSkeletonGraph>::vertex_descriptor
* must be Vertex_handle.
* boost::graph_traits<OneSkeletonGraph>::directed_category
- * must be undirected_tag. */
+ * must be undirected_tag.
+ *
+ * If an edge appears with multiplicity, the function will arbitrarily pick
+ * one representative to read the filtration value. */
template<class OneSkeletonGraph>
void insert_graph(const OneSkeletonGraph& skel_graph) {
// the simplex tree must be empty
@@ -983,18 +1000,22 @@ class Simplex_tree {
++e_it) {
auto u = source(*e_it, skel_graph);
auto v = target(*e_it, skel_graph);
- if (u < v) {
- // count edges only once { std::swap(u,v); } // u < v
- auto sh = find_vertex(u);
- if (!has_children(sh)) {
- sh->second.assign_children(new Siblings(&root_, sh->first));
- }
-
- sh->second.children()->members().emplace(
- v,
- Node(sh->second.children(),
- boost::get(edge_filtration_t(), skel_graph, *e_it)));
+ if (u == v) throw "Self-loops are not simplicial";
+ // We cannot skip edges with the wrong orientation and expect them to
+ // come a second time with the right orientation, that does not always
+ // happen in practice. emplace() should be a NOP when an element with the
+ // same key is already there, so seeing the same edge multiple times is
+ // ok.
+ // Should we actually forbid multiple edges? That would be consistent
+ // with rejecting self-loops.
+ if (v < u) std::swap(u, v);
+ auto sh = find_vertex(u);
+ if (!has_children(sh)) {
+ sh->second.assign_children(new Siblings(&root_, sh->first));
}
+
+ sh->second.children()->members().emplace(v,
+ Node(sh->second.children(), boost::get(edge_filtration_t(), skel_graph, *e_it)));
}
}
@@ -1138,7 +1159,7 @@ class Simplex_tree {
to_be_inserted=false;
break;
}
- filt = std::max(filt, filtration(border_child));
+ filt = (std::max)(filt, filtration(border_child));
}
if (to_be_inserted) {
intersection.emplace_back(next->first, Node(nullptr, filt));
@@ -1334,7 +1355,7 @@ class Simplex_tree {
if (sh_dimension >= dimension_)
// Stop browsing as soon as the dimension is reached, no need to go furter
return false;
- new_dimension = std::max(new_dimension, sh_dimension);
+ new_dimension = (std::max)(new_dimension, sh_dimension);
}
dimension_ = new_dimension;
return true;
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h
index 7e0a454d..ab7346d4 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h
@@ -23,6 +23,8 @@
#ifndef SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
#define SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
+#include <gudhi/Debug_utils.h>
+
#include <boost/iterator/iterator_facade.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION >= 105600
@@ -109,11 +111,18 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
: last_(sh->first),
sib_(nullptr),
st_(st) {
+ // Only check once at the beginning instead of for every increment, as this is expensive.
+ if (SimplexTree::Options::contiguous_vertices)
+ GUDHI_CHECK(st_->contiguous_vertices(), "The set of vertices is not { 0, ..., n } without holes");
Siblings * sib = st->self_siblings(sh);
next_ = sib->parent();
sib_ = sib->oncles();
if (sib_ != nullptr) {
- sh_ = sib_->find(next_);
+ if (SimplexTree::Options::contiguous_vertices && sib_->oncles() == nullptr)
+ // Only relevant for edges
+ sh_ = sib_->members_.begin()+next_;
+ else
+ sh_ = sib_->find(next_);
} else {
sh_ = st->null_simplex();
} // vertex: == end()
@@ -140,14 +149,19 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
Siblings * for_sib = sib_;
Siblings * new_sib = sib_->oncles();
auto rit = suffix_.rbegin();
- if (SimplexTree::Options::contiguous_vertices && new_sib == nullptr && rit != suffix_.rend()) {
- // We reached the root, use a short-cut to find a vertex. We could also
- // optimize finding the second vertex of a segment, but people are
- // expected to call endpoints().
- assert(st_->contiguous_vertices());
- sh_ = for_sib->members_.begin()+*rit;
- for_sib = sh_->second.children();
- ++rit;
+ if (SimplexTree::Options::contiguous_vertices && new_sib == nullptr) {
+ // We reached the root, use a short-cut to find a vertex.
+ if (rit == suffix_.rend()) {
+ // Segment, this vertex is the last boundary simplex
+ sh_ = for_sib->members_.begin()+last_;
+ sib_ = nullptr;
+ return;
+ } else {
+ // Dim >= 2, initial step of the descent
+ sh_ = for_sib->members_.begin()+*rit;
+ for_sib = sh_->second.children();
+ ++rit;
+ }
}
for (; rit != suffix_.rend(); ++rit) {
sh_ = for_sib->find(*rit);
diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
index 580d610a..f63ea080 100644
--- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp
+++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
@@ -863,3 +863,35 @@ BOOST_AUTO_TEST_CASE(make_filtration_non_decreasing) {
BOOST_CHECK(st == st_other_copy);
}
+
+BOOST_AUTO_TEST_CASE(insert_graph) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "INSERT GRAPH" << std::endl;
+ typedef typename boost::adjacency_list<boost::vecS, boost::vecS,
+ boost::undirectedS,
+ boost::property<vertex_filtration_t, double>,
+ boost::property<edge_filtration_t, double>> Graph;
+ Graph g(3);
+ // filtration value 0 everywhere
+ put(Gudhi::vertex_filtration_t(), g, 0, 0);
+ put(Gudhi::vertex_filtration_t(), g, 1, 0);
+ put(Gudhi::vertex_filtration_t(), g, 2, 0);
+ // vertices don't always occur in sorted order
+ add_edge(0, 1, 0, g);
+ add_edge(2, 1, 0, g);
+ add_edge(2, 0, 0, g);
+
+ typedef Simplex_tree<> typeST;
+ typeST st1;
+ st1.insert_graph(g);
+ BOOST_CHECK(st1.num_simplices() == 6);
+
+ // edges can have multiplicity in the graph unless we replace the first vecS with (hash_)setS
+ add_edge(1, 0, 0, g);
+ add_edge(1, 2, 0, g);
+ add_edge(0, 2, 0, g);
+ add_edge(0, 2, 0, g);
+ typeST st2;
+ st2.insert_graph(g);
+ BOOST_CHECK(st2.num_simplices() == 6);
+}
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
index 32fe411c..aca2aa57 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
@@ -239,9 +239,6 @@ their collaboration to write the two initial papers
about this data-structure
and also Dominique for leaving him use a prototype.
-
-\copyright GNU General Public License v3.
-
@} */
} // namespace skeleton_blocker
diff --git a/src/Spatial_searching/doc/Intro_spatial_searching.h b/src/Spatial_searching/doc/Intro_spatial_searching.h
index 1ee5e92e..52ed65e4 100644
--- a/src/Spatial_searching/doc/Intro_spatial_searching.h
+++ b/src/Spatial_searching/doc/Intro_spatial_searching.h
@@ -50,8 +50,6 @@ namespace spatial_searching {
*
* \include Spatial_searching/example_spatial_searching.cpp
*
- * \copyright GNU General Public License v3.
- * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup spatial_searching
diff --git a/src/Spatial_searching/include/gudhi/Kd_tree_search.h b/src/Spatial_searching/include/gudhi/Kd_tree_search.h
index ef428002..96bbeb36 100644
--- a/src/Spatial_searching/include/gudhi/Kd_tree_search.h
+++ b/src/Spatial_searching/include/gudhi/Kd_tree_search.h
@@ -271,8 +271,7 @@ class Kd_tree_search {
m_tree.search(it, Fuzzy_sphere(p, radius, eps, m_tree.traits()));
}
- int tree_depth() const
- {
+ int tree_depth() const {
return m_tree.root()->depth();
}
diff --git a/src/Subsampling/doc/Intro_subsampling.h b/src/Subsampling/doc/Intro_subsampling.h
index c84616dd..ab9cdc37 100644
--- a/src/Subsampling/doc/Intro_subsampling.h
+++ b/src/Subsampling/doc/Intro_subsampling.h
@@ -58,8 +58,6 @@ namespace subsampling {
* This example outputs a subset of 100 points picked randomly.
*
* \include Subsampling/example_pick_n_random_points.cpp
- * \copyright GNU General Public License v3.
- * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup subsampling
diff --git a/src/Subsampling/include/gudhi/choose_n_farthest_points.h b/src/Subsampling/include/gudhi/choose_n_farthest_points.h
index 86500b28..8390b4c9 100644
--- a/src/Subsampling/include/gudhi/choose_n_farthest_points.h
+++ b/src/Subsampling/include/gudhi/choose_n_farthest_points.h
@@ -93,7 +93,7 @@ void choose_n_farthest_points(Kernel const &k,
// Choose randomly the first landmark
std::random_device rd;
std::mt19937 gen(rd());
- std::uniform_int_distribution<std::size_t> dis(0, (input_pts.size() - 1));
+ std::uniform_int_distribution<std::size_t> dis(0, nb_points - 1);
starting_point = dis(gen);
}
@@ -110,7 +110,7 @@ void choose_n_farthest_points(Kernel const &k,
*output_it++ = input_pts[curr_max_w];
*dist_it++ = dist_to_L[curr_max_w];
std::size_t i = 0;
- for (auto& p : input_pts) {
+ for (auto&& p : input_pts) {
double curr_dist = sqdist(p, *(std::begin(input_pts) + curr_max_w));
if (curr_dist < dist_to_L[i])
dist_to_L[i] = curr_dist;
diff --git a/src/Tangential_complex/doc/Intro_tangential_complex.h b/src/Tangential_complex/doc/Intro_tangential_complex.h
index 3d687c1d..00e00c52 100644
--- a/src/Tangential_complex/doc/Intro_tangential_complex.h
+++ b/src/Tangential_complex/doc/Intro_tangential_complex.h
@@ -107,8 +107,6 @@ dimensions are known at compile-time.
\include Tangential_complex/example_with_perturb.cpp
-\copyright GNU General Public License v3.
-\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup tangential_complex
diff --git a/src/Witness_complex/doc/Witness_complex_doc.h b/src/Witness_complex/doc/Witness_complex_doc.h
index 5d5c0735..62203054 100644
--- a/src/Witness_complex/doc/Witness_complex_doc.h
+++ b/src/Witness_complex/doc/Witness_complex_doc.h
@@ -117,9 +117,6 @@ int main(int argc, char * const argv[]) {
\include Witness_complex/example_nearest_landmark_table.cpp
- \copyright GNU General Public License v3.
-
-
*/
#endif // WITNESS_COMPLEX_DOC_H_
diff --git a/src/Witness_complex/example/example_strong_witness_complex_off.cpp b/src/Witness_complex/example/example_strong_witness_complex_off.cpp
index bc069654..346bef6d 100644
--- a/src/Witness_complex/example/example_strong_witness_complex_off.cpp
+++ b/src/Witness_complex/example/example_strong_witness_complex_off.cpp
@@ -39,10 +39,9 @@ using Point_d = typename K::Point_d;
using Witness_complex = Gudhi::witness_complex::Euclidean_strong_witness_complex<K>;
using Point_vector = std::vector<Point_d>;
-int main(int argc, char * const argv[]) {
+int main(int argc, char* const argv[]) {
if (argc != 5) {
- std::cerr << "Usage: " << argv[0]
- << " path_to_point_file number_of_landmarks max_squared_alpha limit_dimension\n";
+ std::cerr << "Usage: " << argv[0] << " path_to_point_file number_of_landmarks max_squared_alpha limit_dimension\n";
return 0;
}
@@ -56,9 +55,9 @@ int main(int argc, char * const argv[]) {
Point_vector point_vector, landmarks;
Gudhi::Points_off_reader<Point_d> off_reader(file_name);
if (!off_reader.is_valid()) {
- std::cerr << "Strong witness complex - Unable to read file " << file_name << "\n";
- exit(-1); // ----- >>
- }
+ std::cerr << "Strong witness complex - Unable to read file " << file_name << "\n";
+ exit(-1); // ----- >>
+ }
point_vector = Point_vector(off_reader.get_point_cloud());
std::cout << "Successfully read " << point_vector.size() << " points.\n";
@@ -66,16 +65,15 @@ int main(int argc, char * const argv[]) {
// Choose landmarks (decomment one of the following two lines)
// Gudhi::subsampling::pick_n_random_points(point_vector, nbL, std::back_inserter(landmarks));
- Gudhi::subsampling::choose_n_farthest_points(K(), point_vector, nbL, Gudhi::subsampling::random_starting_point, std::back_inserter(landmarks));
-
+ Gudhi::subsampling::choose_n_farthest_points(K(), point_vector, nbL, Gudhi::subsampling::random_starting_point,
+ std::back_inserter(landmarks));
+
// Compute witness complex
start = clock();
- Witness_complex witness_complex(landmarks,
- point_vector);
+ Witness_complex witness_complex(landmarks, point_vector);
witness_complex.create_complex(simplex_tree, alpha2, lim_dim);
end = clock();
- std::cout << "Strong witness complex took "
- << static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n";
+ std::cout << "Strong witness complex took " << static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n";
std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << "\n";
}
diff --git a/src/Witness_complex/example/example_witness_complex_sphere.cpp b/src/Witness_complex/example/example_witness_complex_sphere.cpp
index a66da3f9..a6e9b11a 100644
--- a/src/Witness_complex/example/example_witness_complex_sphere.cpp
+++ b/src/Witness_complex/example/example_witness_complex_sphere.cpp
@@ -42,27 +42,25 @@
/** Write a gnuplot readable file.
* Data range is a random access range of pairs (arg, value)
*/
-template < typename Data_range >
-void write_data(Data_range & data, std::string filename) {
+template <typename Data_range>
+void write_data(Data_range& data, std::string filename) {
std::ofstream ofs(filename, std::ofstream::out);
- for (auto entry : data)
- ofs << entry.first << ", " << entry.second << "\n";
+ for (auto entry : data) ofs << entry.first << ", " << entry.second << "\n";
ofs.close();
}
-int main(int argc, char * const argv[]) {
+int main(int argc, char* const argv[]) {
using Kernel = CGAL::Epick_d<CGAL::Dynamic_dimension_tag>;
using Witness_complex = Gudhi::witness_complex::Euclidean_witness_complex<Kernel>;
if (argc != 2) {
- std::cerr << "Usage: " << argv[0]
- << " number_of_landmarks \n";
+ std::cerr << "Usage: " << argv[0] << " number_of_landmarks \n";
return 0;
}
int number_of_landmarks = atoi(argv[1]);
- std::vector< std::pair<int, double> > l_time;
+ std::vector<std::pair<int, double> > l_time;
// Generate points
for (int nbP = 500; nbP < 10000; nbP += 500) {
@@ -77,16 +75,16 @@ int main(int argc, char * const argv[]) {
// Choose landmarks
start = clock();
// Gudhi::subsampling::pick_n_random_points(point_vector, number_of_landmarks, std::back_inserter(landmarks));
- Gudhi::subsampling::choose_n_farthest_points(K(), point_vector, number_of_landmarks, Gudhi::subsampling::random_starting_point, std::back_inserter(landmarks));
+ Gudhi::subsampling::choose_n_farthest_points(K(), point_vector, number_of_landmarks,
+ Gudhi::subsampling::random_starting_point,
+ std::back_inserter(landmarks));
// Compute witness complex
- Witness_complex witness_complex(landmarks,
- point_vector);
+ Witness_complex witness_complex(landmarks, point_vector);
witness_complex.create_complex(simplex_tree, 0);
end = clock();
double time = static_cast<double>(end - start) / CLOCKS_PER_SEC;
- std::cout << "Witness complex for " << number_of_landmarks << " landmarks took "
- << time << " s. \n";
+ std::cout << "Witness complex for " << number_of_landmarks << " landmarks took " << time << " s. \n";
std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << "\n";
l_time.push_back(std::make_pair(nbP, time));
}
diff --git a/src/Witness_complex/utilities/strong_witness_persistence.cpp b/src/Witness_complex/utilities/strong_witness_persistence.cpp
index e3e0c1ee..2fba631b 100644
--- a/src/Witness_complex/utilities/strong_witness_persistence.cpp
+++ b/src/Witness_complex/utilities/strong_witness_persistence.cpp
@@ -47,16 +47,10 @@ using Filtration_value = SimplexTree::Filtration_value;
using Field_Zp = Gudhi::persistent_cohomology::Field_Zp;
using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<SimplexTree, Field_Zp>;
-void program_options(int argc, char * argv[]
- , int & nbL
- , std::string & file_name
- , std::string & filediag
- , Filtration_value & max_squared_alpha
- , int & p
- , int & dim_max
- , Filtration_value & min_persistence);
-
-int main(int argc, char * argv[]) {
+void program_options(int argc, char* argv[], int& nbL, std::string& file_name, std::string& filediag,
+ Filtration_value& max_squared_alpha, int& p, int& dim_max, Filtration_value& min_persistence);
+
+int main(int argc, char* argv[]) {
std::string file_name;
std::string filediag;
Filtration_value max_squared_alpha;
@@ -70,8 +64,8 @@ int main(int argc, char * argv[]) {
Point_vector witnesses, landmarks;
Gudhi::Points_off_reader<Point_d> off_reader(file_name);
if (!off_reader.is_valid()) {
- std::cerr << "Witness complex - Unable to read file " << file_name << "\n";
- exit(-1); // ----- >>
+ std::cerr << "Witness complex - Unable to read file " << file_name << "\n";
+ exit(-1); // ----- >>
}
witnesses = Point_vector(off_reader.get_point_cloud());
std::cout << "Successfully read " << witnesses.size() << " points.\n";
@@ -79,11 +73,11 @@ int main(int argc, char * argv[]) {
// Choose landmarks (decomment one of the following two lines)
// Gudhi::subsampling::pick_n_random_points(point_vector, nbL, std::back_inserter(landmarks));
- Gudhi::subsampling::choose_n_farthest_points(K(), witnesses, nbL, Gudhi::subsampling::random_starting_point, std::back_inserter(landmarks));
+ Gudhi::subsampling::choose_n_farthest_points(K(), witnesses, nbL, Gudhi::subsampling::random_starting_point,
+ std::back_inserter(landmarks));
// Compute witness complex
- Strong_witness_complex strong_witness_complex(landmarks,
- witnesses);
+ Strong_witness_complex strong_witness_complex(landmarks, witnesses);
strong_witness_complex.create_complex(simplex_tree, max_squared_alpha, lim_d);
@@ -112,37 +106,28 @@ int main(int argc, char * argv[]) {
return 0;
}
-void program_options(int argc, char * argv[]
- , int & nbL
- , std::string & file_name
- , std::string & filediag
- , Filtration_value & max_squared_alpha
- , int & p
- , int & dim_max
- , Filtration_value & min_persistence) {
+void program_options(int argc, char* argv[], int& nbL, std::string& file_name, std::string& filediag,
+ Filtration_value& max_squared_alpha, int& p, int& dim_max, Filtration_value& min_persistence) {
namespace po = boost::program_options;
po::options_description hidden("Hidden options");
- hidden.add_options()
- ("input-file", po::value<std::string>(&file_name),
- "Name of file containing a point set in off format.");
+ hidden.add_options()("input-file", po::value<std::string>(&file_name),
+ "Name of file containing a point set in off format.");
po::options_description visible("Allowed options", 100);
Filtration_value default_alpha = std::numeric_limits<Filtration_value>::infinity();
- visible.add_options()
- ("help,h", "produce help message")
- ("landmarks,l", po::value<int>(&nbL),
- "Number of landmarks to choose from the point cloud.")
- ("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-sq-alpha,a", po::value<Filtration_value>(&max_squared_alpha)->default_value(default_alpha),
- "Maximal squared relaxation parameter.")
- ("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)->default_value(0),
- "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals")
- ("cpx-dimension,d", po::value<int>(&dim_max)->default_value(std::numeric_limits<int>::max()),
- "Maximal dimension of the strong witness complex we want to compute.");
+ visible.add_options()("help,h", "produce help message")("landmarks,l", po::value<int>(&nbL),
+ "Number of landmarks to choose from the point cloud.")(
+ "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-sq-alpha,a", po::value<Filtration_value>(&max_squared_alpha)->default_value(default_alpha),
+ "Maximal squared relaxation parameter.")(
+ "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)->default_value(0),
+ "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length "
+ "intervals")("cpx-dimension,d", po::value<int>(&dim_max)->default_value(std::numeric_limits<int>::max()),
+ "Maximal dimension of the strong witness complex we want to compute.");
po::positional_options_description pos;
pos.add("input-file", 1);
@@ -151,8 +136,7 @@ void program_options(int argc, char * argv[]
all.add(visible).add(hidden);
po::variables_map vm;
- po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), 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")) {
@@ -170,4 +154,3 @@ void program_options(int argc, char * argv[]
std::abort();
}
}
-
diff --git a/src/Witness_complex/utilities/weak_witness_persistence.cpp b/src/Witness_complex/utilities/weak_witness_persistence.cpp
index a63b0837..23fa93aa 100644
--- a/src/Witness_complex/utilities/weak_witness_persistence.cpp
+++ b/src/Witness_complex/utilities/weak_witness_persistence.cpp
@@ -47,16 +47,10 @@ using Filtration_value = SimplexTree::Filtration_value;
using Field_Zp = Gudhi::persistent_cohomology::Field_Zp;
using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<SimplexTree, Field_Zp>;
-void program_options(int argc, char * argv[]
- , int & nbL
- , std::string & file_name
- , std::string & filediag
- , Filtration_value & max_squared_alpha
- , int & p
- , int & dim_max
- , Filtration_value & min_persistence);
-
-int main(int argc, char * argv[]) {
+void program_options(int argc, char* argv[], int& nbL, std::string& file_name, std::string& filediag,
+ Filtration_value& max_squared_alpha, int& p, int& dim_max, Filtration_value& min_persistence);
+
+int main(int argc, char* argv[]) {
std::string file_name;
std::string filediag;
Filtration_value max_squared_alpha;
@@ -70,8 +64,8 @@ int main(int argc, char * argv[]) {
Point_vector witnesses, landmarks;
Gudhi::Points_off_reader<Point_d> off_reader(file_name);
if (!off_reader.is_valid()) {
- std::cerr << "Witness complex - Unable to read file " << file_name << "\n";
- exit(-1); // ----- >>
+ std::cerr << "Witness complex - Unable to read file " << file_name << "\n";
+ exit(-1); // ----- >>
}
witnesses = Point_vector(off_reader.get_point_cloud());
std::cout << "Successfully read " << witnesses.size() << " points.\n";
@@ -79,11 +73,11 @@ int main(int argc, char * argv[]) {
// Choose landmarks (decomment one of the following two lines)
// Gudhi::subsampling::pick_n_random_points(point_vector, nbL, std::back_inserter(landmarks));
- Gudhi::subsampling::choose_n_farthest_points(K(), witnesses, nbL, Gudhi::subsampling::random_starting_point, std::back_inserter(landmarks));
+ Gudhi::subsampling::choose_n_farthest_points(K(), witnesses, nbL, Gudhi::subsampling::random_starting_point,
+ std::back_inserter(landmarks));
// Compute witness complex
- Witness_complex witness_complex(landmarks,
- witnesses);
+ Witness_complex witness_complex(landmarks, witnesses);
witness_complex.create_complex(simplex_tree, max_squared_alpha, lim_d);
@@ -112,38 +106,28 @@ int main(int argc, char * argv[]) {
return 0;
}
-
-void program_options(int argc, char * argv[]
- , int & nbL
- , std::string & file_name
- , std::string & filediag
- , Filtration_value & max_squared_alpha
- , int & p
- , int & dim_max
- , Filtration_value & min_persistence) {
+void program_options(int argc, char* argv[], int& nbL, std::string& file_name, std::string& filediag,
+ Filtration_value& max_squared_alpha, int& p, int& dim_max, Filtration_value& min_persistence) {
namespace po = boost::program_options;
po::options_description hidden("Hidden options");
- hidden.add_options()
- ("input-file", po::value<std::string>(&file_name),
- "Name of file containing a point set in off format.");
+ hidden.add_options()("input-file", po::value<std::string>(&file_name),
+ "Name of file containing a point set in off format.");
Filtration_value default_alpha = std::numeric_limits<Filtration_value>::infinity();
po::options_description visible("Allowed options", 100);
- visible.add_options()
- ("help,h", "produce help message")
- ("landmarks,l", po::value<int>(&nbL),
- "Number of landmarks to choose from the point cloud.")
- ("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-sq-alpha,a", po::value<Filtration_value>(&max_squared_alpha)->default_value(default_alpha),
- "Maximal squared relaxation parameter.")
- ("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)->default_value(0),
- "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals")
- ("cpx-dimension,d", po::value<int>(&dim_max)->default_value(std::numeric_limits<int>::max()),
- "Maximal dimension of the weak witness complex we want to compute.");
+ visible.add_options()("help,h", "produce help message")("landmarks,l", po::value<int>(&nbL),
+ "Number of landmarks to choose from the point cloud.")(
+ "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-sq-alpha,a", po::value<Filtration_value>(&max_squared_alpha)->default_value(default_alpha),
+ "Maximal squared relaxation parameter.")(
+ "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)->default_value(0),
+ "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length "
+ "intervals")("cpx-dimension,d", po::value<int>(&dim_max)->default_value(std::numeric_limits<int>::max()),
+ "Maximal dimension of the weak witness complex we want to compute.");
po::positional_options_description pos;
pos.add("input-file", 1);
@@ -152,8 +136,7 @@ void program_options(int argc, char * argv[]
all.add(visible).add(hidden);
po::variables_map vm;
- po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), 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")) {
diff --git a/src/Witness_complex/utilities/README b/src/Witness_complex/utilities/witnesscomplex.md
index 1141033e..2341759b 100644
--- a/src/Witness_complex/utilities/README
+++ b/src/Witness_complex/utilities/witnesscomplex.md
@@ -1,18 +1,24 @@
-# Witness_complex #
-For more details about the witness complex, please read the [user manual of the package](http://gudhi.gforge.inria.fr/doc/latest/group__witness__complex.html).
-## `weak_witness_persistence` ##
-This program computes the persistent homology with coefficient field *Z/pZ* of a Weak witness complex defined on a set of input points. The output diagram contains one bar per line, written with the convention:
+# Witness complex #
+
+
+For more details about the witness complex, please read the [user manual of the package](/doc/latest/group__witness__complex.html).
+
+## weak_witness_persistence ##
+This program computes the persistent homology with coefficient field *Z/pZ* of a Weak witness complex defined on a set of input points.
+The output diagram contains one bar per line, written with the convention:
`p dim birth death`
-where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature, and `p` is the characteristic of the field *Z/pZ* used for homology coefficients.
+where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature,
+and `p` is the characteristic of the field *Z/pZ* used for homology coefficients.
+
+**Usage**
-*Usage*
`weak_witness_persistence [options] <OFF input file>`
-*Allowed options*
+**Allowed options**
* `-h [ --help ]` Produce help message
* `-l [ --landmarks ]` Number of landmarks to choose from the point cloud.
@@ -22,33 +28,28 @@ where `dim` is the dimension of the homological feature, `birth` and `death` are
* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals.
* `-d [ --cpx-dimension ]` (default = 2147483647) Maximal dimension of the weak witness complex we want to compute.
-*Example*
-`weak_witness_persistence data/points/tore3D_1307.off -l 20 -a 0.5 -m 0.006`
+**Example**
-outputs:
-```
-Successfully read 1307 points.
-Ambient dimension is 3.
-The complex contains 732 simplices and has dimension 8
-11 0 0 inf
-11 1 0 inf
-11 2 0.0275251 0.0534586
-11 1 0 0.0239952
-```
+`weak_witness_persistence data/points/tore3D_1307.off -l 20 -a 0.5 -m 0.006`
N.B.: output is random as the 20 landmarks are chosen randomly.
-## `strong_witness_persistence` ##
-This program computes the persistent homology with coefficient field *Z/pZ* of a Strong witness complex defined on a set of input points. The output diagram contains one bar per line, written with the convention:
+
+## strong_witness_persistence ##
+
+This program computes the persistent homology with coefficient field *Z/pZ* of a Strong witness complex defined on a set of input points.
+The output diagram contains one bar per line, written with the convention:
`p dim birth death`
-where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature, and `p` is the characteristic of the field *Z/pZ* used for homology coefficients.
+where `dim` is the dimension of the homological feature, `birth` and `death` are respectively the birth and death of the feature,
+and `p` is the characteristic of the field *Z/pZ* used for homology coefficients.
+
+**Usage**
-*Usage*
`strong_witness_persistence [options] <OFF input file>`
-*Allowed options*
+**Allowed options**
* `-h [ --help ]` Produce help message
* `-l [ --landmarks ]` Number of landmarks to choose from the point cloud.
@@ -58,17 +59,8 @@ where `dim` is the dimension of the homological feature, `birth` and `death` are
* `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals.
* `-d [ --cpx-dimension ]` (default = 2147483647) Maximal dimension of the weak witness complex we want to compute.
-*Example*
-`strong_witness_persistence data/points/tore3D_1307.off -l 20 -a 0.5 -m 0.06`
+**Example**
-outputs:
-```
-Successfully read 1307 points.
-Ambient dimension is 3.
-The complex contains 1836 simplices and has dimension 8
-11 0 0 inf
-11 1 0.00674748 inf
-11 2 0.0937751 0.235354
-```
+`strong_witness_persistence data/points/tore3D_1307.off -l 20 -a 0.5 -m 0.06`
N.B.: output is random as the 20 landmarks are chosen randomly.
diff --git a/src/cmake/modules/GUDHI_test_coverage.cmake b/src/cmake/modules/GUDHI_test_coverage.cmake
index ce171a0e..bea5b2d6 100644
--- a/src/cmake/modules/GUDHI_test_coverage.cmake
+++ b/src/cmake/modules/GUDHI_test_coverage.cmake
@@ -8,7 +8,19 @@ if (GPROF_PATH)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
endif()
+if (DEBUG_TRACES)
+ # Make CTest more verbose with DEBUG_TRACES - no XML output
+ set(GUDHI_UT_LOG_LEVEL "--log_level=all")
+ set(GUDHI_UT_REPORT_LEVEL "--report_level=detailed")
+else()
+ set(GUDHI_UT_LOG_FORMAT "--log_format=XML")
+ set(GUDHI_UT_LOG_SINK "--log_sink=${CMAKE_BINARY_DIR}/${unitary_test}_UT.xml")
+ set(GUDHI_UT_LOG_LEVEL "--log_level=test_suite")
+ set(GUDHI_UT_REPORT_LEVEL "--report_level=no")
+endif()
+
function(gudhi_add_coverage_test unitary_test)
add_test(NAME ${unitary_test} COMMAND $<TARGET_FILE:${unitary_test}>
- "--log_format=XML" "--log_sink=${CMAKE_BINARY_DIR}/${unitary_test}_UT.xml" "--log_level=test_suite" "--report_level=no")
+ ${GUDHI_UT_LOG_FORMAT} ${GUDHI_UT_LOG_SINK}
+ ${GUDHI_UT_LOG_LEVEL} ${GUDHI_UT_REPORT_LEVEL})
endfunction()
diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake
index 8269c3bf..419c2581 100644
--- a/src/cmake/modules/GUDHI_third_party_libraries.cmake
+++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake
@@ -1,6 +1,6 @@
# This files manage third party libraries required by GUDHI
-find_package(Boost REQUIRED COMPONENTS system filesystem unit_test_framework program_options thread)
+find_package(Boost 1.48.0 REQUIRED COMPONENTS system filesystem unit_test_framework program_options thread)
if(NOT Boost_FOUND)
message(FATAL_ERROR "NOTICE: This program requires Boost and will not be compiled.")
@@ -85,7 +85,6 @@ FIND_PROGRAM( GCOVR_PATH gcovr )
if (GCOVR_PATH)
message("gcovr found in ${GCOVR_PATH}")
endif()
-# Required programs for unitary tests purpose
FIND_PROGRAM( GPROF_PATH gprof )
if (GPROF_PATH)
message("gprof found in ${GPROF_PATH}")
@@ -94,6 +93,10 @@ FIND_PROGRAM( DIFF_PATH diff )
if (DIFF_PATH)
message("diff found in ${DIFF_PATH}")
endif()
+FIND_PROGRAM( GNUPLOT_PATH gnuplot )
+if (GNUPLOT_PATH)
+ message("gnuplot found in ${GNUPLOT_PATH}")
+endif()
# BOOST ISSUE result_of vs C++11
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
diff --git a/src/common/doc/examples.h b/src/common/doc/examples.h
new file mode 100644
index 00000000..40f202c7
--- /dev/null
+++ b/src/common/doc/examples.h
@@ -0,0 +1,99 @@
+// List of GUDHI examples - Doxygen needs at least a file tag to analyse comments
+// In user_version, `find . -name "*.cpp"` in example and utilities folders
+/*! @file Examples
+ * @example Alpha_complex/Alpha_complex_from_off.cpp
+ * @example Alpha_complex/Alpha_complex_from_points.cpp
+ * @example Bottleneck_distance/bottleneck_basic_example.cpp
+ * @example Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp
+ * @example Witness_complex/example_nearest_landmark_table.cpp
+ * @example Witness_complex/example_witness_complex_off.cpp
+ * @example Witness_complex/example_witness_complex_sphere.cpp
+ * @example Witness_complex/example_strong_witness_complex_off.cpp
+ * @example Simplex_tree/mini_simplex_tree.cpp
+ * @example Simplex_tree/graph_expansion_with_blocker.cpp
+ * @example Simplex_tree/simple_simplex_tree.cpp
+ * @example Simplex_tree/simplex_tree_from_cliques_of_graph.cpp
+ * @example Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp
+ * @example Simplex_tree/cech_complex_cgal_mini_sphere_3d.cpp
+ * @example Persistent_cohomology/plain_homology.cpp
+ * @example Persistent_cohomology/persistence_from_file.cpp
+ * @example Persistent_cohomology/rips_persistence_step_by_step.cpp
+ * @example Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp
+ * @example Persistent_cohomology/custom_persistence_sort.cpp
+ * @example Persistent_cohomology/persistence_from_simple_simplex_tree.cpp
+ * @example Persistent_cohomology/rips_multifield_persistence.cpp
+ * @example Skeleton_blocker/Skeleton_blocker_from_simplices.cpp
+ * @example Skeleton_blocker/Skeleton_blocker_iteration.cpp
+ * @example Skeleton_blocker/Skeleton_blocker_link.cpp
+ * @example Contraction/Garland_heckbert.cpp
+ * @example Contraction/Rips_contraction.cpp
+ * @example Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp
+ * @example common/example_CGAL_3D_points_off_reader.cpp
+ * @example common/example_vector_double_points_off_reader.cpp
+ * @example common/example_CGAL_points_off_reader.cpp
+ * @example Rips_complex/example_one_skeleton_rips_from_distance_matrix.cpp
+ * @example Rips_complex/example_one_skeleton_rips_from_points.cpp
+ * @example Rips_complex/example_rips_complex_from_csv_distance_matrix_file.cpp
+ * @example Rips_complex/example_rips_complex_from_off_file.cpp
+ * @example Persistence_representations/persistence_intervals.cpp
+ * @example Persistence_representations/persistence_vectors.cpp
+ * @example Persistence_representations/persistence_heat_maps.cpp
+ * @example Persistence_representations/persistence_landscape_on_grid.cpp
+ * @example Persistence_representations/persistence_landscape.cpp
+ * @example Tangential_complex/example_basic.cpp
+ * @example Tangential_complex/example_with_perturb.cpp
+ * @example Subsampling/example_custom_kernel.cpp
+ * @example Subsampling/example_choose_n_farthest_points.cpp
+ * @example Subsampling/example_sparsify_point_set.cpp
+ * @example Subsampling/example_pick_n_random_points.cpp
+ * @example Nerve_GIC/CoordGIC.cpp
+ * @example Nerve_GIC/Nerve.cpp
+ * @example Nerve_GIC/FuncGIC.cpp
+ * @example Nerve_GIC/VoronoiGIC.cpp
+ * @example Spatial_searching/example_spatial_searching.cpp
+ * @example Alpha_complex/alpha_complex_3d_persistence.cpp
+ * @example Alpha_complex/alpha_complex_persistence.cpp
+ * @example Alpha_complex/weighted_periodic_alpha_complex_3d_persistence.cpp
+ * @example Alpha_complex/weighted_alpha_complex_3d_persistence.cpp
+ * @example Alpha_complex/periodic_alpha_complex_3d_persistence.cpp
+ * @example Alpha_complex/exact_alpha_complex_3d_persistence.cpp
+ * @example Bottleneck_distance/bottleneck_distance.cpp
+ * @example Witness_complex/weak_witness_persistence.cpp
+ * @example Witness_complex/strong_witness_persistence.cpp
+ * @example Bitmap_cubical_complex/cubical_complex_persistence.cpp
+ * @example Bitmap_cubical_complex/periodic_cubical_complex_persistence.cpp
+ * @example common/off_file_from_shape_generator.cpp
+ * @example Rips_complex/rips_distance_matrix_persistence.cpp
+ * @example Rips_complex/rips_persistence.cpp
+ * @example Persistence_representations/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp
+ * @example Persistence_representations/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp
+ * @example Persistence_representations/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp
+ * @example Persistence_representations/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp
+ * @example Persistence_representations/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp
+ * @example Persistence_representations/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp
+ * @example Persistence_representations/persistence_intervals/compute_number_of_dominant_intervals.cpp
+ * @example Persistence_representations/persistence_intervals/plot_persistence_Betti_numbers.cpp
+ * @example Persistence_representations/persistence_intervals/plot_persistence_intervals.cpp
+ * @example Persistence_representations/persistence_intervals/plot_histogram_of_intervals_lengths.cpp
+ * @example Persistence_representations/persistence_intervals/compute_bottleneck_distance.cpp
+ * @example Persistence_representations/persistence_heat_maps/create_pssk.cpp
+ * @example Persistence_representations/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp
+ * @example Persistence_representations/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp
+ * @example Persistence_representations/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp
+ * @example Persistence_representations/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp
+ * @example Persistence_representations/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp
+ * @example Persistence_representations/persistence_heat_maps/average_persistence_heat_maps.cpp
+ * @example Persistence_representations/persistence_heat_maps/plot_persistence_heat_map.cpp
+ * @example Persistence_representations/persistence_heat_maps/create_persistence_heat_maps.cpp
+ * @example Persistence_representations/persistence_vectors/plot_persistence_vectors.cpp
+ * @example Persistence_representations/persistence_vectors/compute_distance_of_persistence_vectors.cpp
+ * @example Persistence_representations/persistence_vectors/average_persistence_vectors.cpp
+ * @example Persistence_representations/persistence_vectors/create_persistence_vectors.cpp
+ * @example Persistence_representations/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp
+ * @example Persistence_representations/persistence_landscapes/average_landscapes.cpp
+ * @example Persistence_representations/persistence_landscapes/compute_scalar_product_of_landscapes.cpp
+ * @example Persistence_representations/persistence_landscapes/create_landscapes.cpp
+ * @example Persistence_representations/persistence_landscapes/compute_distance_of_landscapes.cpp
+ * @example Persistence_representations/persistence_landscapes/plot_landscapes.cpp
+ */
+
diff --git a/src/common/doc/file_formats.h b/src/common/doc/file_formats.h
index d06b81f5..c60ed15a 100644
--- a/src/common/doc/file_formats.h
+++ b/src/common/doc/file_formats.h
@@ -117,6 +117,8 @@ namespace Gudhi {
Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y.
+ Other sample files can be found in the `data/bitmap` folder.
+
*/
} // namespace Gudhi
diff --git a/src/common/doc/footer.html b/src/common/doc/footer.html
index 7b4cdc5c..a557922b 100644
--- a/src/common/doc/footer.html
+++ b/src/common/doc/footer.html
@@ -6,24 +6,18 @@
<!--BEGIN PROJECT_NAME--> $projectname
<!--BEGIN PROJECT_NUMBER-->&#160;Version $projectnumber<!--END PROJECT_NUMBER-->
<!--BEGIN PROJECT_BRIEF-->&#160;-&#160;$projectbrief<!--END PROJECT_BRIEF-->
+<!--BEGIN PROJECT_BRIEF-->&#160;-&#160;Copyright : GPL v3<!--END PROJECT_BRIEF-->
<!--END PROJECT_NAME-->
</td>
<td class="network-entypo">
<!--BEGIN GENERATE_TREEVIEW-->
$generatedby
<a href="http://www.doxygen.org/index.html">
- <img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion
+ Doxygen</a> $doxygenversion
<!--END GENERATE_TREEVIEW-->
</td>
</tr>
</table>
-<!--BEGIN !GENERATE_TREEVIEW-->
-<hr class="footer"/><address class="footer"><small> tralala
-$generatedby &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
-</a> $doxygenversion
-</small></address>
-<!--END !GENERATE_TREEVIEW-->
</body>
</html>
diff --git a/src/common/doc/header.html b/src/common/doc/header.html
index 53b5c0a2..d69b28fa 100644
--- a/src/common/doc/header.html
+++ b/src/common/doc/header.html
@@ -56,6 +56,8 @@ $extrastylesheet
<ul class="dropdown">
<li><a href="http://gudhi.gforge.inria.fr/licensing/">Licensing</a></li>
<li><a href="https://gforge.inria.fr/frs/?group_id=3865" target="_blank">Get the sources</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37365/2018-02-01-16-59-31_GUDHI_2.1.0_OSX_UTILS.tar.gz" target="_blank">Utils for Mac OSx</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37366/2018-01-31-09-25-53_GUDHI_2.1.0_WIN64_UTILS.zip" target="_blank">Utils for Win x64</a></li>
</ul>
</li>
<li class="divider"></li>
@@ -66,6 +68,8 @@ $extrastylesheet
<li><a href="http://gudhi.gforge.inria.fr/doc/latest/installation.html">C++ installation manual</a></li>
<li><a href="http://gudhi.gforge.inria.fr/python/latest/">Python documentation</a></li>
<li><a href="http://gudhi.gforge.inria.fr/python/latest/installation.html">Python installation manual</a></li>
+ <li><a href="http://gudhi.gforge.inria.fr/utils/">Utilities</a></li>
+ <li><a href="http://bertrand.michel.perso.math.cnrs.fr/Enseignements/TDA-Gudhi-Python.html" target="_blank">Tutorial</a></li>
</ul>
</li>
<li class="divider"></li>
diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h
new file mode 100644
index 00000000..25675cc5
--- /dev/null
+++ b/src/common/doc/installation.h
@@ -0,0 +1,263 @@
+/*! \page installation GUDHI installation
+ * \tableofcontents
+ * As GUDHI is a header only library, there is no need to install the library.
+ *
+ * Examples of GUDHI headers inclusion can be found in \ref demos.
+ *
+ * \section compiling Compiling
+ * The library uses c++11 and requires <a target="_blank" href="http://www.boost.org/">Boost</a> with version 1.48.0 or
+ * more recent. It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2015.
+ *
+ * \subsection demos Demos and examples
+ * To build the demos and examples, run the following commands in a terminal:
+\verbatim cd /path-to-gudhi/
+mkdir build
+cd build/
+cmake ..
+make \endverbatim
+ * A list of examples is available <a href="examples.html">here</a>.
+ *
+ * \subsection testsuites Test suites
+ * To test your build, run the following command in a terminal:
+ * \verbatim make test \endverbatim
+ *
+ * \subsection documentationgeneration Documentation
+ * To generate the documentation, <a target="_blank" href="http://www.doxygen.org/">Doxygen</a> is required.
+ * Run the following command in a terminal:
+\verbatim
+make doxygen
+# Documentation will be generated in the folder YYYY-MM-DD-hh-mm-ss_GUDHI_X.Y.Z/doc/html/
+# You can customize the directory name by calling `cmake -DUSER_VERSION_DIR=/my/custom/folder`
+\endverbatim
+ *
+ * \section optionallibrary Optional third-party library
+ * \subsection gmp GMP
+ * The multi-field persistent homology algorithm requires GMP which is a free library for arbitrary-precision
+ * arithmetic, operating on signed integers, rational numbers, and floating point numbers.
+ *
+ * The following example requires the <a target="_blank" href="http://gmplib.org/">GNU Multiple Precision Arithmetic
+ * Library</a> (GMP) and will not be built if GMP is not installed:
+ * \li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
+ * Persistent_cohomology/rips_multifield_persistence.cpp</a>
+ *
+ * Having GMP version 4.2 or higher installed is recommended.
+ *
+ * \subsection cgal CGAL
+ * The \ref alpha_complex data structure, \ref bottleneck_distance, and few examples requires CGAL, which is a C++
+ * library which provides easy access to efficient and reliable geometric algorithms.
+ *
+ * \note There is no need to install CGAL, you can just <CODE>cmake . && make</CODE> CGAL (or even
+ * <CODE>cmake -DCGAL_HEADER_ONLY=ON .</CODE> for CGAL version &ge; 4.8.0), thereafter you will be able to compile
+ * GUDHI by calling <CODE>cmake -DCGAL_DIR=/your/path/to/CGAL-X.Y .. && make</CODE>
+ *
+ * Having CGAL version 4.4.0 or higher installed is recommended. The procedure to install this library according to
+ * your operating system is detailed here http://doc.cgal.org/latest/Manual/installation.html
+ *
+ * The following examples/utilities require the <a target="_blank" href="http://www.cgal.org/">Computational Geometry Algorithms
+ * Library</a> (CGAL \cite cgal:eb-15b) and will not be built if CGAL is not installed:
+ * \li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html">
+ * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a>
+ *
+ * The following examples/utilities require CGAL version &ge; 4.6.0:
+ * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html">
+ * Witness_complex/strong_witness_persistence.cpp</a>
+ * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html">
+ * Witness_complex/weak_witness_persistence.cpp</a>
+ * \li <a href="_witness_complex_2example_strong_witness_complex_off_8cpp-example.html">
+ * Witness_complex/example_strong_witness_complex_off.cpp</a>
+ * \li <a href="_witness_complex_2example_witness_complex_off_8cpp-example.html">
+ * Witness_complex/example_witness_complex_off.cpp</a>
+ * \li <a href="_witness_complex_2example_witness_complex_sphere_8cpp-example.html">
+ * Witness_complex/example_witness_complex_sphere.cpp</a>
+ *
+ * The following example requires CGAL version &ge; 4.7.0:
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a>
+ * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
+ * Alpha_complex/alpha_complex_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2custom_persistence_sort_8cpp-example.html">
+ * Persistent_cohomology/custom_persistence_sort.cpp</a>
+ *
+ * The following example requires CGAL version &ge; 4.8.1:
+ * \li <a href="_bottleneck_distance_2alpha_rips_persistence_bottleneck_distance_8cpp-example.html">
+ * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp</a>
+ * \li <a href="_bottleneck_distance_2bottleneck_basic_example_8cpp-example.html">
+ * Bottleneck_distance/bottleneck_basic_example.cpp</a>
+ * \li <a href="_bottleneck_distance_2bottleneck_read_file_8cpp-example.html">
+ * Bottleneck_distance/bottleneck_distance.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_coord_g_i_c_8cpp-example.html">
+ * Nerve_GIC/CoordGIC.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_func_g_i_c_8cpp-example.html">
+ * Nerve_GIC/FuncGIC.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_nerve_8cpp-example.html">
+ * Nerve_GIC/Nerve.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_voronoi_g_i_c_8cpp-example.html">
+ * Nerve_GIC/VoronoiGIC.cpp</a>
+ * \li <a href="_spatial_searching_2example_spatial_searching_8cpp-example.html">
+ * Spatial_searching/example_spatial_searching.cpp</a>
+ * \li <a href="_subsampling_2example_choose_n_farthest_points_8cpp-example.html">
+ * Subsampling/example_choose_n_farthest_points.cpp</a>
+ * \li <a href="_subsampling_2example_custom_kernel_8cpp-example.html">
+ * Subsampling/example_custom_kernel.cpp</a>
+ * \li <a href="_subsampling_2example_pick_n_random_points_8cpp-example.html">
+ * Subsampling/example_pick_n_random_points.cpp</a>
+ * \li <a href="_subsampling_2example_sparsify_point_set_8cpp-example.html">
+ * Subsampling/example_sparsify_point_set.cpp</a>
+ * \li <a href="_tangential_complex_2example_basic_8cpp-example.html">
+ * Tangential_complex/example_basic.cpp</a>
+ * \li <a href="_tangential_complex_2example_with_perturb_8cpp-example.html">
+ * Tangential_complex/example_with_perturb.cpp</a>
+ *
+ * \subsection eigen3 Eigen3
+ * The \ref alpha_complex data structure and few examples requires
+ * <a target="_blank" href="http://eigen.tuxfamily.org/">Eigen3</a> is a C++ template library for linear algebra:
+ * matrices, vectors, numerical solvers, and related algorithms.
+ *
+ * The following examples/utilities require the <a target="_blank" href="http://eigen.tuxfamily.org/">Eigen3</a> and will not be
+ * built if Eigen3 is not installed:
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a>
+ * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
+ * Alpha_complex/alpha_complex_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_bottleneck_distance_2alpha_rips_persistence_bottleneck_distance_8cpp-example.html">
+ * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp</a>
+ * \li <a href="_persistent_cohomology_2custom_persistence_sort_8cpp-example.html">
+ * Persistent_cohomology/custom_persistence_sort.cpp</a>
+ * \li <a href="_spatial_searching_2example_spatial_searching_8cpp-example.html">
+ * Spatial_searching/example_spatial_searching.cpp</a>
+ * \li <a href="_subsampling_2example_choose_n_farthest_points_8cpp-example.html">
+ * Subsampling/example_choose_n_farthest_points.cpp</a>
+ * \li <a href="_subsampling_2example_custom_kernel_8cpp-example.html">
+ * Subsampling/example_custom_kernel.cpp</a>
+ * \li <a href="_subsampling_2example_pick_n_random_points_8cpp-example.html">
+ * Subsampling/example_pick_n_random_points.cpp</a>
+ * \li <a href="_subsampling_2example_sparsify_point_set_8cpp-example.html">
+ * Subsampling/example_sparsify_point_set.cpp</a>
+ * \li <a href="_tangential_complex_2example_basic_8cpp-example.html">
+ * Tangential_complex/example_basic.cpp</a>
+ * \li <a href="_tangential_complex_2example_with_perturb_8cpp-example.html">
+ * Tangential_complex/example_with_perturb.cpp</a>
+ * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html">
+ * Witness_complex/strong_witness_persistence.cpp</a>
+ * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html">
+ * Witness_complex/weak_witness_persistence.cpp</a>
+ * \li <a href="_witness_complex_2example_strong_witness_complex_off_8cpp-example.html">
+ * Witness_complex/example_strong_witness_complex_off.cpp</a>
+ * \li <a href="_witness_complex_2example_witness_complex_off_8cpp-example.html">
+ * Witness_complex/example_witness_complex_off.cpp</a>
+ * \li <a href="_witness_complex_2example_witness_complex_sphere_8cpp-example.html">
+ * Witness_complex/example_witness_complex_sphere.cpp</a>
+ *
+ * \subsection tbb Threading Building Blocks
+ * <a target="_blank" href="https://www.threadingbuildingblocks.org/">Intel&reg; TBB</a> lets you easily write parallel
+ * C++ programs that take full advantage of multicore performance, that are portable and composable, and that have
+ * future-proof scalability.
+ *
+ * Having Intel&reg; TBB installed is recommended to parallelize and accelerate some GUDHI computations.
+ *
+ * The following examples/utilities are using Intel&reg; TBB if installed:
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a>
+ * \li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
+ * Alpha_complex/alpha_complex_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
+ * Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_8cpp-example.html">
+ * Bitmap_cubical_complex/cubical_complex_persistence.cpp</a>
+ * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_periodic_boundary_conditions_8cpp-example.html">
+ * Bitmap_cubical_complex/periodic_cubical_complex_persistence.cpp</a>
+ * \li <a href="_bitmap_cubical_complex_2_random_bitmap_cubical_complex_8cpp-example.html">
+ * Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_coord_g_i_c_8cpp-example.html">
+ * Nerve_GIC/CoordGIC.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_func_g_i_c_8cpp-example.html">
+ * Nerve_GIC/FuncGIC.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_nerve_8cpp-example.html">
+ * Nerve_GIC/Nerve.cpp</a>
+ * \li <a href="_nerve__g_i_c_2_voronoi_g_i_c_8cpp-example.html">
+ * Nerve_GIC/VoronoiGIC.cpp</a>
+ * \li <a href="_simplex_tree_2simple_simplex_tree_8cpp-example.html">
+ * Simplex_tree/simple_simplex_tree.cpp</a>
+ * \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html">
+ * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a>
+ * \li <a href="_simplex_tree_2simplex_tree_from_cliques_of_graph_8cpp-example.html">
+ * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp</a>
+ * \li <a href="_simplex_tree_2graph_expansion_with_blocker_8cpp-example.html">
+ * Simplex_tree/graph_expansion_with_blocker.cpp</a>
+ * \li <a href="_persistent_cohomology_2alpha_complex_3d_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2rips_persistence_via_boundary_matrix_8cpp-example.html">
+ * Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp</a>
+ * \li <a href="_persistent_cohomology_2persistence_from_file_8cpp-example.html">
+ * Persistent_cohomology/persistence_from_file.cpp</a>
+ * \li <a href="_persistent_cohomology_2persistence_from_simple_simplex_tree_8cpp-example.html">
+ * Persistent_cohomology/persistence_from_simple_simplex_tree.cpp</a>
+ * \li <a href="_persistent_cohomology_2plain_homology_8cpp-example.html">
+ * Persistent_cohomology/plain_homology.cpp</a>
+ * \li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
+ * Persistent_cohomology/rips_multifield_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2rips_persistence_step_by_step_8cpp-example.html">
+ * Persistent_cohomology/rips_persistence_step_by_step.cpp</a>
+ * \li <a href="_persistent_cohomology_2exact_alpha_complex_3d_persistence_8cpp-example.html">
+ * Persistent_cohomology/exact_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
+ * Persistent_cohomology/weighted_alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2custom_persistence_sort_8cpp-example.html">
+ * Persistent_cohomology/custom_persistence_sort.cpp</a>
+ * \li <a href="_rips_complex_2example_one_skeleton_rips_from_points_8cpp-example.html">
+ * Rips_complex/example_one_skeleton_rips_from_points.cpp</a>
+ * \li <a href="_rips_complex_2example_rips_complex_from_off_file_8cpp-example.html">
+ * Rips_complex/example_rips_complex_from_off_file.cpp</a>
+ * \li <a href="_rips_complex_2rips_distance_matrix_persistence_8cpp-example.html">
+ * Rips_complex/rips_distance_matrix_persistence.cpp</a>
+ * \li <a href="_rips_complex_2rips_persistence_8cpp-example.html">
+ * Rips_complex/rips_persistence.cpp</a>
+ * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html">
+ * Witness_complex/strong_witness_persistence.cpp</a>
+ * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html">
+ * Witness_complex/weak_witness_persistence.cpp</a>
+ * \li <a href="_witness_complex_2example_nearest_landmark_table_8cpp-example.html">
+ * Witness_complex/example_nearest_landmark_table.cpp</a>
+ *
+ * \section Contributions Bug reports and contributions
+ * Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to:
+ * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
+ *
+ * GUDHI is open to external contributions. If you want to join our development team, please contact us.
+ *
+*/
+
+/*! \page Citation Acknowledging the GUDHI library
+ * We kindly ask users to cite the GUDHI library as appropriately as possible in their papers, and to mention the use
+ * of the GUDHI library on the web pages of their projects using GUDHI and provide us with links to these web pages.
+ * Feel free to contact us in case you have any question or remark on this topic.
+ *
+ * We provide \ref GudhiBibtex entries for the modules of the User and Reference Manual, as well as for publications
+ * directly related to the GUDHI library.
+ * \section GudhiBibtex GUDHI bibtex
+ * \verbinclude biblio/how_to_cite_gudhi.bib
+*/
diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h
index 108cf6e3..b3e9ea03 100644
--- a/src/common/doc/main_page.h
+++ b/src/common/doc/main_page.h
@@ -93,14 +93,15 @@
</td>
</tr>
</table>
- \subsection CoverComplexDataStructure Cover Complexes: Nerves and Graph Induced Complexes
+ \subsection CoverComplexDataStructure Cover Complexes
\image html "gicvisu.jpg" "Graph Induced Complex of a point cloud."
<table border="0">
<tr>
<td width="25%">
<b>Author:</b> Mathieu Carri&egrave;re<br>
- <b>Introduced in:</b> GUDHI 2.0.1<br>
+ <b>Introduced in:</b> GUDHI 2.1.0<br>
<b>Copyright:</b> GPL v3<br>
+ <b>Requires:</b> \ref cgal &ge; 4.8.1
</td>
<td width="75%">
Nerves and Graph Induced Complexes are cover complexes, i.e. simplicial complexes that provably contain
@@ -250,305 +251,3 @@
</table>
*/
-
-/*! \page installation GUDHI installation
- * \tableofcontents
- * As GUDHI is a header only library, there is no need to install the library.
- *
- * Examples of GUDHI headers inclusion can be found in \ref demos.
- *
- * \section compiling Compiling
- * The library uses c++11 and requires <a target="_blank" href="http://www.boost.org/">Boost</a> with version 1.48.0 or
- * more recent. It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2015.
- *
- * \subsection demos Demos and examples
- * To build the demos and examples, run the following commands in a terminal:
-\verbatim cd /path-to-gudhi/
-mkdir build
-cd build/
-cmake ..
-make \endverbatim
- * A list of examples is available <a href="examples.html">here</a>.
- *
- * \subsection testsuites Test suites
- * To test your build, run the following command in a terminal:
- * \verbatim make test \endverbatim
- *
- * \subsection documentationgeneration Documentation
- * To generate the documentation, <a target="_blank" href="http://www.doxygen.org/">Doxygen</a> is required.
- * Run the following command in a terminal:
-\verbatim
-make doxygen
-# Documentation will be generated in the folder YYYY-MM-DD-hh-mm-ss_GUDHI_X.Y.Z/doc/html/
-# You can customize the directory name by calling `cmake -DUSER_VERSION_DIR=/my/custom/folder`
-\endverbatim
- *
- * \section optionallibrary Optional third-party library
- * \subsection gmp GMP
- * The multi-field persistent homology algorithm requires GMP which is a free library for arbitrary-precision
- * arithmetic, operating on signed integers, rational numbers, and floating point numbers.
- *
- * The following example requires the <a target="_blank" href="http://gmplib.org/">GNU Multiple Precision Arithmetic
- * Library</a> (GMP) and will not be built if GMP is not installed:
- * \li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
- * Persistent_cohomology/rips_multifield_persistence.cpp</a>
- *
- * Having GMP version 4.2 or higher installed is recommended.
- *
- * \subsection cgal CGAL
- * The \ref alpha_complex data structure, \ref bottleneck_distance, and few examples requires CGAL, which is a C++
- * library which provides easy access to efficient and reliable geometric algorithms.
- *
- * \note There is no need to install CGAL, you can just <CODE>cmake . && make</CODE> CGAL (or even
- * <CODE>cmake -DCGAL_HEADER_ONLY=ON .</CODE> for CGAL version &ge; 4.8.0), thereafter you will be able to compile
- * GUDHI by calling <CODE>cmake -DCGAL_DIR=/your/path/to/CGAL-X.Y .. && make</CODE>
- *
- * Having CGAL version 4.4.0 or higher installed is recommended. The procedure to install this library according to
- * your operating system is detailed here http://doc.cgal.org/latest/Manual/installation.html
- *
- * The following examples/utilities require the <a target="_blank" href="http://www.cgal.org/">Computational Geometry Algorithms
- * Library</a> (CGAL \cite cgal:eb-15b) and will not be built if CGAL is not installed:
- * \li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html">
- * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a>
- *
- * The following examples/utilities require CGAL version &ge; 4.6.0:
- * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html">
- * Witness_complex/strong_witness_persistence.cpp</a>
- * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html">
- * Witness_complex/weak_witness_persistence.cpp</a>
- * \li <a href="_witness_complex_2example_strong_witness_complex_off_8cpp-example.html">
- * Witness_complex/example_strong_witness_complex_off.cpp</a>
- * \li <a href="_witness_complex_2example_witness_complex_off_8cpp-example.html">
- * Witness_complex/example_witness_complex_off.cpp</a>
- * \li <a href="_witness_complex_2example_witness_complex_sphere_8cpp-example.html">
- * Witness_complex/example_witness_complex_sphere.cpp</a>
- *
- * The following example requires CGAL version &ge; 4.7.0:
- * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
- * Alpha_complex/Alpha_complex_from_off.cpp</a>
- * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
- * Alpha_complex/Alpha_complex_from_points.cpp</a>
- * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
- * Alpha_complex/alpha_complex_persistence.cpp</a>
- * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_persistent_cohomology_2custom_persistence_sort_8cpp-example.html">
- * Persistent_cohomology/custom_persistence_sort.cpp</a>
- *
- * The following example requires CGAL version &ge; 4.8.1:
- * \li <a href="_bottleneck_distance_2alpha_rips_persistence_bottleneck_distance_8cpp-example.html">
- * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp</a>
- * \li <a href="_bottleneck_distance_2bottleneck_basic_example_8cpp-example.html">
- * Bottleneck_distance/bottleneck_basic_example.cpp</a>
- * \li <a href="_bottleneck_distance_2bottleneck_read_file_8cpp-example.html">
- * Bottleneck_distance/bottleneck_distance.cpp</a>
- * \li <a href="_spatial_searching_2example_spatial_searching_8cpp-example.html">
- * Spatial_searching/example_spatial_searching.cpp</a>
- * \li <a href="_subsampling_2example_choose_n_farthest_points_8cpp-example.html">
- * Subsampling/example_choose_n_farthest_points.cpp</a>
- * \li <a href="_subsampling_2example_custom_kernel_8cpp-example.html">
- * Subsampling/example_custom_kernel.cpp</a>
- * \li <a href="_subsampling_2example_pick_n_random_points_8cpp-example.html">
- * Subsampling/example_pick_n_random_points.cpp</a>
- * \li <a href="_subsampling_2example_sparsify_point_set_8cpp-example.html">
- * Subsampling/example_sparsify_point_set.cpp</a>
- * \li <a href="_tangential_complex_2example_basic_8cpp-example.html">
- * Tangential_complex/example_basic.cpp</a>
- * \li <a href="_tangential_complex_2example_with_perturb_8cpp-example.html">
- * Tangential_complex/example_with_perturb.cpp</a>
- *
- * \subsection eigen3 Eigen3
- * The \ref alpha_complex data structure and few examples requires
- * <a target="_blank" href="http://eigen.tuxfamily.org/">Eigen3</a> is a C++ template library for linear algebra:
- * matrices, vectors, numerical solvers, and related algorithms.
- *
- * The following examples/utilities require the <a target="_blank" href="http://eigen.tuxfamily.org/">Eigen3</a> and will not be
- * built if Eigen3 is not installed:
- * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
- * Alpha_complex/Alpha_complex_from_off.cpp</a>
- * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
- * Alpha_complex/Alpha_complex_from_points.cpp</a>
- * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
- * Alpha_complex/alpha_complex_persistence.cpp</a>
- * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_bottleneck_distance_2alpha_rips_persistence_bottleneck_distance_8cpp-example.html">
- * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp</a>
- * \li <a href="_persistent_cohomology_2custom_persistence_sort_8cpp-example.html">
- * Persistent_cohomology/custom_persistence_sort.cpp</a>
- * \li <a href="_spatial_searching_2example_spatial_searching_8cpp-example.html">
- * Spatial_searching/example_spatial_searching.cpp</a>
- * \li <a href="_subsampling_2example_choose_n_farthest_points_8cpp-example.html">
- * Subsampling/example_choose_n_farthest_points.cpp</a>
- * \li <a href="_subsampling_2example_custom_kernel_8cpp-example.html">
- * Subsampling/example_custom_kernel.cpp</a>
- * \li <a href="_subsampling_2example_pick_n_random_points_8cpp-example.html">
- * Subsampling/example_pick_n_random_points.cpp</a>
- * \li <a href="_subsampling_2example_sparsify_point_set_8cpp-example.html">
- * Subsampling/example_sparsify_point_set.cpp</a>
- * \li <a href="_tangential_complex_2example_basic_8cpp-example.html">
- * Tangential_complex/example_basic.cpp</a>
- * \li <a href="_tangential_complex_2example_with_perturb_8cpp-example.html">
- * Tangential_complex/example_with_perturb.cpp</a>
- * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html">
- * Witness_complex/strong_witness_persistence.cpp</a>
- * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html">
- * Witness_complex/weak_witness_persistence.cpp</a>
- * \li <a href="_witness_complex_2example_strong_witness_complex_off_8cpp-example.html">
- * Witness_complex/example_strong_witness_complex_off.cpp</a>
- * \li <a href="_witness_complex_2example_witness_complex_off_8cpp-example.html">
- * Witness_complex/example_witness_complex_off.cpp</a>
- * \li <a href="_witness_complex_2example_witness_complex_sphere_8cpp-example.html">
- * Witness_complex/example_witness_complex_sphere.cpp</a>
- *
- * \subsection tbb Threading Building Blocks
- * <a target="_blank" href="https://www.threadingbuildingblocks.org/">Intel&reg; TBB</a> lets you easily write parallel
- * C++ programs that take full advantage of multicore performance, that are portable and composable, and that have
- * future-proof scalability.
- *
- * Having Intel&reg; TBB installed is recommended to parallelize and accelerate some GUDHI computations.
- *
- * The following examples/utilities are using Intel&reg; TBB if installed:
- * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
- * Alpha_complex/Alpha_complex_from_off.cpp</a>
- * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
- * Alpha_complex/Alpha_complex_from_points.cpp</a>
- * \li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
- * Alpha_complex/alpha_complex_persistence.cpp</a>
- * \li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
- * Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_8cpp-example.html">
- * Bitmap_cubical_complex/cubical_complex_persistence.cpp</a>
- * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_periodic_boundary_conditions_8cpp-example.html">
- * Bitmap_cubical_complex/periodic_cubical_complex_persistence.cpp</a>
- * \li <a href="_bitmap_cubical_complex_2_random_bitmap_cubical_complex_8cpp-example.html">
- * Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp</a>
- * \li <a href="_simplex_tree_2simple_simplex_tree_8cpp-example.html">
- * Simplex_tree/simple_simplex_tree.cpp</a>
- * \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html">
- * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a>
- * \li <a href="_simplex_tree_2simplex_tree_from_cliques_of_graph_8cpp-example.html">
- * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp</a>
- * \li <a href="_simplex_tree_2graph_expansion_with_blocker_8cpp-example.html">
- * Simplex_tree/graph_expansion_with_blocker.cpp</a>
- * \li <a href="_persistent_cohomology_2alpha_complex_3d_persistence_8cpp-example.html">
- * Persistent_cohomology/alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html">
- * Persistent_cohomology/alpha_complex_persistence.cpp</a>
- * \li <a href="_persistent_cohomology_2rips_persistence_via_boundary_matrix_8cpp-example.html">
- * Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp</a>
- * \li <a href="_persistent_cohomology_2persistence_from_file_8cpp-example.html">
- * Persistent_cohomology/persistence_from_file.cpp</a>
- * \li <a href="_persistent_cohomology_2persistence_from_simple_simplex_tree_8cpp-example.html">
- * Persistent_cohomology/persistence_from_simple_simplex_tree.cpp</a>
- * \li <a href="_persistent_cohomology_2plain_homology_8cpp-example.html">
- * Persistent_cohomology/plain_homology.cpp</a>
- * \li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
- * Persistent_cohomology/rips_multifield_persistence.cpp</a>
- * \li <a href="_persistent_cohomology_2rips_persistence_step_by_step_8cpp-example.html">
- * Persistent_cohomology/rips_persistence_step_by_step.cpp</a>
- * \li <a href="_persistent_cohomology_2exact_alpha_complex_3d_persistence_8cpp-example.html">
- * Persistent_cohomology/exact_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_persistent_cohomology_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
- * Persistent_cohomology/weighted_alpha_complex_3d_persistence.cpp</a>
- * \li <a href="_persistent_cohomology_2custom_persistence_sort_8cpp-example.html">
- * Persistent_cohomology/custom_persistence_sort.cpp</a>
- * \li <a href="_rips_complex_2example_one_skeleton_rips_from_points_8cpp-example.html">
- * Rips_complex/example_one_skeleton_rips_from_points.cpp</a>
- * \li <a href="_rips_complex_2example_rips_complex_from_off_file_8cpp-example.html">
- * Rips_complex/example_rips_complex_from_off_file.cpp</a>
- * \li <a href="_rips_complex_2rips_distance_matrix_persistence_8cpp-example.html">
- * Rips_complex/rips_distance_matrix_persistence.cpp</a>
- * \li <a href="_rips_complex_2rips_persistence_8cpp-example.html">
- * Rips_complex/rips_persistence.cpp</a>
- * \li <a href="_witness_complex_2strong_witness_persistence_8cpp-example.html">
- * Witness_complex/strong_witness_persistence.cpp</a>
- * \li <a href="_witness_complex_2weak_witness_persistence_8cpp-example.html">
- * Witness_complex/weak_witness_persistence.cpp</a>
- * \li <a href="_witness_complex_2example_nearest_landmark_table_8cpp-example.html">
- * Witness_complex/example_nearest_landmark_table.cpp</a>
- *
- * \section Contributions Bug reports and contributions
- * Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to:
- * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
- *
- * GUDHI is open to external contributions. If you want to join our development team, please contact us.
- *
-*/
-
-/*! \page Citation Acknowledging the GUDHI library
- * We kindly ask users to cite the GUDHI library as appropriately as possible in their papers, and to mention the use
- * of the GUDHI library on the web pages of their projects using GUDHI and provide us with links to these web pages.
- * Feel free to contact us in case you have any question or remark on this topic.
- *
- * We provide \ref GudhiBibtex entries for the modules of the User and Reference Manual, as well as for publications
- * directly related to the GUDHI library.
- * \section GudhiBibtex GUDHI bibtex
- * \verbinclude biblio/how_to_cite_gudhi.bib
-*/
-
-// List of GUDHI examples - Doxygen needs at least a file tag to analyse comments
-/*! @file Examples
- * @example Alpha_complex/Alpha_complex_from_off.cpp
- * @example Alpha_complex/Alpha_complex_from_points.cpp
- * @example Alpha_complex/alpha_complex_3d_persistence.cpp
- * @example Alpha_complex/alpha_complex_persistence.cpp
- * @example Alpha_complex/exact_alpha_complex_3d_persistence.cpp
- * @example Alpha_complex/periodic_alpha_complex_3d_persistence.cpp
- * @example Alpha_complex/weighted_alpha_complex_3d_persistence.cpp
- * @example Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp
- * @example Bottleneck_distance/bottleneck_basic_example.cpp
- * @example Bottleneck_distance/bottleneck_distance.cpp
- * @example Bitmap_cubical_complex/cubical_complex_persistence.cpp
- * @example Bitmap_cubical_complex/periodic_cubical_complex_persistence.cpp
- * @example Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp
- * @example common/example_CGAL_3D_points_off_reader.cpp
- * @example common/example_CGAL_points_off_reader.cpp
- * @example Contraction/Garland_heckbert.cpp
- * @example Contraction/Rips_contraction.cpp
- * @example Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp
- * @example Persistent_cohomology/persistence_from_file.cpp
- * @example Persistent_cohomology/persistence_from_simple_simplex_tree.cpp
- * @example Persistent_cohomology/plain_homology.cpp
- * @example Persistent_cohomology/rips_multifield_persistence.cpp
- * @example Persistent_cohomology/custom_persistence_sort.cpp
- * @example Persistent_cohomology/rips_persistence_step_by_step.cpp
- * @example Rips_complex/example_one_skeleton_rips_from_points.cpp
- * @example Rips_complex/example_rips_complex_from_off_file.cpp
- * @example Rips_complex/rips_persistence.cpp
- * @example Rips_complex/rips_distance_matrix_persistence.cpp
- * @example Simplex_tree/mini_simplex_tree.cpp
- * @example Simplex_tree/simple_simplex_tree.cpp
- * @example Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp
- * @example Simplex_tree/simplex_tree_from_cliques_of_graph.cpp
- * @example Simplex_tree/graph_expansion_with_blocker.cpp
- * @example Skeleton_blocker/Skeleton_blocker_from_simplices.cpp
- * @example Skeleton_blocker/Skeleton_blocker_iteration.cpp
- * @example Skeleton_blocker/Skeleton_blocker_link.cpp
- * @example Spatial_searching/example_spatial_searching.cpp
- * @example Subsampling/example_choose_n_farthest_points.cpp
- * @example Subsampling/example_custom_kernel.cpp
- * @example Subsampling/example_pick_n_random_points.cpp
- * @example Subsampling/example_sparsify_point_set.cpp
- * @example Tangential_complex/example_basic.cpp
- * @example Tangential_complex/example_with_perturb.cpp
- * @example Witness_complex/example_nearest_landmark_table.cpp
- * @example Witness_complex/example_strong_witness_complex_off.cpp
- * @example Witness_complex/example_witness_complex_off.cpp
- * @example Witness_complex/example_witness_complex_sphere.cpp
- * @example Witness_complex/weak_witness_persistence.cpp
- * @example Witness_complex/strong_witness_persistence.cpp
- */
- \ No newline at end of file
diff --git a/src/common/include/gudhi/Debug_utils.h b/src/common/include/gudhi/Debug_utils.h
index 8ed3b7b3..90d3cf47 100644
--- a/src/common/include/gudhi/Debug_utils.h
+++ b/src/common/include/gudhi/Debug_utils.h
@@ -4,7 +4,7 @@
*
* Author(s): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -32,7 +32,7 @@
// GUDHI_CHECK throw an exception if expression is false in debug mode, but does nothing in release mode
// Could assert in release mode, but cmake sets NDEBUG (for "NO DEBUG") in this mode, means assert does nothing.
#ifdef GUDHI_DEBUG
- #define GUDHI_CHECK(expression, excpt) if ((expression) == 0) throw excpt
+ #define GUDHI_CHECK(expression, excpt) ((expression) ? (void) 0 : (throw excpt))
#define GUDHI_CHECK_code(CODE) CODE
#else
#define GUDHI_CHECK(expression, excpt) (void) 0
diff --git a/src/common/include/gudhi/Unitary_tests_utils.h b/src/common/include/gudhi/Unitary_tests_utils.h
new file mode 100644
index 00000000..8394a062
--- /dev/null
+++ b/src/common/include/gudhi/Unitary_tests_utils.h
@@ -0,0 +1,40 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2017 INRIA
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef UNITARY_TESTS_UTILS_H_
+#define UNITARY_TESTS_UTILS_H_
+
+#include <boost/test/unit_test.hpp>
+
+#include <iostream>
+#include <limits> // for std::numeric_limits<>
+
+template<typename FloatingType >
+void GUDHI_TEST_FLOAT_EQUALITY_CHECK(FloatingType a, FloatingType b,
+ FloatingType epsilon = std::numeric_limits<FloatingType>::epsilon()) {
+#ifdef DEBUG_TRACES
+ std::cout << "GUDHI_TEST_FLOAT_EQUALITY_CHECK - " << a << " versus " << b
+ << " | diff = " << std::fabs(a - b) << " - epsilon = " << epsilon << std::endl;
+#endif
+ BOOST_CHECK(std::fabs(a - b) < epsilon);
+}
+
+#endif // UNITARY_TESTS_UTILS_H_
diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h
index c556155e..3a5d1fd5 100644
--- a/src/common/include/gudhi/distance_functions.h
+++ b/src/common/include/gudhi/distance_functions.h
@@ -23,6 +23,10 @@
#ifndef DISTANCE_FUNCTIONS_H_
#define DISTANCE_FUNCTIONS_H_
+#include <gudhi/Debug_utils.h>
+
+#include <boost/range/metafunctions.hpp>
+
#include <cmath> // for std::sqrt
#include <type_traits> // for std::decay
#include <iterator> // for std::begin, std::end
@@ -38,20 +42,29 @@ namespace Gudhi {
* have the same dimension. */
class Euclidean_distance {
public:
+ // boost::range_value is not SFINAE-friendly so we cannot use it in the return type
template< typename Point >
- auto operator()(const Point& p1, const Point& p2) const -> typename std::decay<decltype(*std::begin(p1))>::type {
- auto it1 = p1.begin();
- auto it2 = p2.begin();
- typename Point::value_type dist = 0.;
- for (; it1 != p1.end(); ++it1, ++it2) {
- typename Point::value_type tmp = (*it1) - (*it2);
+ typename std::iterator_traits<typename boost::range_iterator<Point>::type>::value_type
+ operator()(const Point& p1, const Point& p2) const {
+ auto it1 = std::begin(p1);
+ auto it2 = std::begin(p2);
+ typedef typename boost::range_value<Point>::type NT;
+ NT dist = 0;
+ for (; it1 != std::end(p1); ++it1, ++it2) {
+ GUDHI_CHECK(it2 != std::end(p2), "inconsistent point dimensions");
+ NT tmp = *it1 - *it2;
dist += tmp*tmp;
}
- return std::sqrt(dist);
+ GUDHI_CHECK(it2 == std::end(p2), "inconsistent point dimensions");
+ using std::sqrt;
+ return sqrt(dist);
}
template< typename T >
- T operator() (const std::pair< T, T >& f, const std::pair< T, T >& s) {
- return sqrt((f.first-s.first)*(f.first-s.first) + (f.second-s.second)*(f.second-s.second));
+ T operator() (const std::pair< T, T >& f, const std::pair< T, T >& s) const {
+ T dx = f.first - s.first;
+ T dy = f.second - s.second;
+ using std::sqrt;
+ return sqrt(dx*dx + dy*dy);
}
};
diff --git a/src/common/utilities/README b/src/common/utilities/README
deleted file mode 100644
index 18fa8cc4..00000000
--- a/src/common/utilities/README
+++ /dev/null
@@ -1,19 +0,0 @@
-# Pointset generator #
-
-## `off_file_from_shape_generator` ##
-
-Generates a pointset and save it in an OFF file. Command-line is:
-`off_file_from_shape_generator on|in sphere|cube|curve|torus|klein <filename> <num_points> <dimension> <parameter1> <parameter2>...`
-
-Warning: "on cube" generator is not available!
-
-Examples:
-
-* Generate an onSphere.off file with 1000 points randomized on a sphere of dimension 3 and radius 15.2:
-`off_file_from_shape_generator on sphere onSphere.off 1000 3 15.2`
-
-* Generate an inSphere.off file with 100 points randomized in a sphere of dimension 2 (circle) and radius 1.0 (default):
-`off_file_from_shape_generator in sphere inSphere.off 100 2`
-
-* Generates a inCube.off file with 10000 points randomized in a cube of dimension 3 and side 5.8:
-`off_file_from_shape_generator in cube inCube.off 10000 3 5.8`
diff --git a/src/common/utilities/pointsetgenerator.md b/src/common/utilities/pointsetgenerator.md
new file mode 100644
index 00000000..284715d4
--- /dev/null
+++ b/src/common/utilities/pointsetgenerator.md
@@ -0,0 +1,33 @@
+
+
+# common #
+
+## off_file_from_shape_generator ##
+
+Generates a pointset and save it in an OFF file. Command-line is:
+
+```
+off_file_from_shape_generator on|in sphere|cube|curve|torus|klein <filename> <num_points> <dimension> <parameter1> <parameter2>...
+```
+
+Warning: "on cube" generator is not available!
+
+**Examples**
+
+```
+off_file_from_shape_generator on sphere onSphere.off 1000 3 15.2
+```
+
+* Generates an onSphere.off file with 1000 points randomized on a sphere of dimension 3 and radius 15.2.
+
+```
+off_file_from_shape_generator in sphere inSphere.off 100 2
+```
+
+* Generates an inSphere.off file with 100 points randomized in a sphere of dimension 2 (circle) and radius 1.0 (default).
+
+```
+off_file_from_shape_generator in cube inCube.off 10000 3 5.8
+```
+
+* Generates a inCube.off file with 10000 points randomized in a cube of dimension 3 and side 5.8.
diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx
index 8a436619..0cb575d2 100644
--- a/src/cython/cython/simplex_tree.pyx
+++ b/src/cython/cython/simplex_tree.pyx
@@ -106,8 +106,8 @@ cdef class SimplexTree:
return self.pcohptr != NULL
def filtration(self, simplex):
- """This function returns the simplicial complex filtration value for a
- given N-simplex.
+ """This function returns the filtration value for a given N-simplex in
+ this simplicial complex, or +infinity if it is not in the complex.
:param simplex: The N-simplex, represented by a list of vertex.
:type simplex: list of int.
@@ -222,14 +222,17 @@ cdef class SimplexTree:
def insert(self, simplex, filtration=0.0):
"""This function inserts the given N-simplex and its subfaces with the
- given filtration value (default value is '0.0').
+ given filtration value (default value is '0.0'). If some of those
+ simplices are already present with a higher filtration value, their
+ filtration value is lowered.
:param simplex: The N-simplex to insert, represented by a list of
vertex.
:type simplex: list of int.
:param filtration: The filtration value of the simplex.
:type filtration: float.
- :returns: true if the simplex was found, false otherwise.
+ :returns: true if the simplex was not yet in the complex, false
+ otherwise (whatever its original filtration value).
:rtype: bool
"""
cdef vector[int] csimplex
diff --git a/src/cython/doc/_templates/layout.html b/src/cython/doc/_templates/layout.html
index 243f33c6..c9356116 100644
--- a/src/cython/doc/_templates/layout.html
+++ b/src/cython/doc/_templates/layout.html
@@ -198,6 +198,8 @@
<ul class="dropdown">
<li><a href="http://gudhi.gforge.inria.fr/licensing/">Licensing</a></li>
<li><a href="https://gforge.inria.fr/frs/?group_id=3865" target="_blank">Get the sources</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37365/2018-02-01-16-59-31_GUDHI_2.1.0_OSX_UTILS.tar.gz" target="_blank">Utils for Mac OSx</a></li>
+ <li><a href="https://gforge.inria.fr/frs/download.php/file/37366/2018-01-31-09-25-53_GUDHI_2.1.0_WIN64_UTILS.zip" target="_blank">Utils for Win x64</a></li>
</ul>
</li>
<li class="divider"></li>
@@ -208,6 +210,8 @@
<li><a href="http://gudhi.gforge.inria.fr/doc/latest/installation.html">C++ installation manual</a></li>
<li><a href="http://gudhi.gforge.inria.fr/python/latest/">Python documentation</a></li>
<li><a href="http://gudhi.gforge.inria.fr/python/latest/installation.html">Python installation manual</a></li>
+ <li><a href="http://gudhi.gforge.inria.fr/utils/">Utilities</a></li>
+ <li><a href="http://bertrand.michel.perso.math.cnrs.fr/Enseignements/TDA-Gudhi-Python.html" target="_blank">Tutorial</a></li>
</ul>
</li>
<li class="divider"></li>
@@ -255,7 +259,7 @@
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
- {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+ {% trans copyright=copyright|e %} {{ copyright }}.{% endtrans %}
{%- endif %}
{%- endif %}
{%- if last_updated %}
diff --git a/src/cython/doc/conf.py b/src/cython/doc/conf.py
index 19a880d4..a13c9751 100755
--- a/src/cython/doc/conf.py
+++ b/src/cython/doc/conf.py
@@ -62,7 +62,7 @@ import gudhi
# General information about the project.
project = gudhi.__name__
-copyright = gudhi.__copyright__
+copyright = gudhi.__copyright__ + ' - ' + gudhi.__license__
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -158,7 +158,7 @@ html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
diff --git a/src/cython/doc/cubical_complex_user.rst b/src/cython/doc/cubical_complex_user.rst
index 2bfac62a..34598f02 100644
--- a/src/cython/doc/cubical_complex_user.rst
+++ b/src/cython/doc/cubical_complex_user.rst
@@ -81,23 +81,7 @@ filtration to all cubes. There are a number of constructors that can be used to
who want to use the code directly. They can be found in the :doc:`cubical_complex_ref`.
Currently one input from a text file is used. It uses a format used already in
`Perseus software <http://www.sas.upenn.edu/~vnanda/perseus/>`_ by Vidit Nanda.
-Below we are providing a description of the format. The first line contains a number d begin the dimension of the
-bitmap (2 in the example below). Next d lines are the numbers of top dimensional cubes in each dimensions (3 and 3
-in the example below). Next, in lexicographical order, the filtration of top dimensional cubes is given (1 4 6 8
-20 4 7 6 5 in the example below).
-
-.. figure::
- ../../doc/Bitmap_cubical_complex/exampleBitmap.png
- :alt: Example of a input data.
- :figclass: align-center
-
- Example of a input data.
-
-The input file for the following complex is:
-
-.. literalinclude:: ../../data/bitmap/cubicalcomplexdoc.txt
-
-.. centered:: ../../data/bitmap/cubicalcomplexdoc.txt
+The file format is described here: :doc:`Perseus <fileformats>`.
.. testcode::
@@ -124,15 +108,9 @@ Imposing periodic boundary conditions in the direction i, means that the left an
:math:`\mathcal{K}` are considered the same. In particular, if for a bitmap :math:`\mathcal{K}` periodic boundary
conditions are imposed in all directions, then complex :math:`\mathcal{K}` became n-dimensional torus. One can use
various constructors from the file Bitmap_cubical_complex_periodic_boundary_conditions_base.h to construct cubical
-complex with periodic boundary conditions. One can also use Perseus style input files. To indicate periodic boundary
-conditions in a given direction, then number of top dimensional cells in this direction have to be multiplied by -1.
-For instance:
-
-.. literalinclude:: ../../data/bitmap/periodiccubicalcomplexdoc.txt
-
-.. centered:: ../../data/bitmap/periodiccubicalcomplexdoc.txt
+complex with periodic boundary conditions.
-Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y.
+One can also use Perseus style input files (see :doc:`Perseus <fileformats>`) for the specific periodic case:
.. testcode::
@@ -149,6 +127,23 @@ the program output is:
Periodic cubical complex is of dimension 2 - 42 simplices.
+Or it can be defined as follows:
+
+.. testcode::
+
+ from gudhi import PeriodicCubicalComplex as pcc
+ periodic_cc = pcc(dimensions=[3,3],
+ top_dimensional_cells= [0, 0, 0, 0, 1, 0, 0, 0, 0],
+ periodic_dimensions=[True, False])
+ result_str = 'Periodic cubical complex is of dimension ' + repr(periodic_cc.dimension()) + ' - ' + \
+ repr(periodic_cc.num_simplices()) + ' simplices.'
+ print(result_str)
+
+the program output is:
+
+.. testoutput::
+
+ Periodic cubical complex is of dimension 2 - 42 simplices.
Examples.
---------
diff --git a/src/cython/doc/fileformats.rst b/src/cython/doc/fileformats.rst
index 156ef4e4..4f0b6f6d 100644
--- a/src/cython/doc/fileformats.rst
+++ b/src/cython/doc/fileformats.rst
@@ -23,7 +23,7 @@ Here is a simple sample file::
3 34.2 34.974
4 3. inf
-Other sample files can be found in the data/persistence_diagram folder.
+Other sample files can be found in the `data/persistence_diagram` folder.
Such files can be generated with
:meth:`gudhi.SimplexTree.write_persistence_diagram`, read with
@@ -31,3 +31,56 @@ Such files can be generated with
:meth:`gudhi.read_persistence_intervals_in_dimension` and displayed with
:meth:`gudhi.plot_persistence_barcode` or
:meth:`gudhi.plot_persistence_diagram`.
+
+Iso-cuboid
+**********
+
+Such a file describes an iso-oriented cuboid with diagonal opposite vertices
+(min_x, min_y, min_z,...) and (max_x, max_y, max_z, ...). The format is::
+
+ min_x min_y [min_z ...]
+ max_x max_y [max_z ...]
+
+Here is a simple sample file in the 3D case::
+
+ -1. -1. -1.
+ 1. 1. 1.
+
+
+Perseus
+*******
+
+This file format is the format used by the
+`Perseus software <http://www.sas.upenn.edu/~vnanda/perseus/>`_ by Vidit Nanda.
+The first line contains a number d begin the dimension of the bitmap (2 in the
+example below). Next d lines are the numbers of top dimensional cubes in each
+dimensions (3 and 3 in the example below). Next, in lexicographical order, the
+filtration of top dimensional cubes is given (1 4 6 8 20 4 7 6 5 in the example
+below).
+
+.. figure::
+ ../../doc/Bitmap_cubical_complex/exampleBitmap.png
+ :alt: Example of a input data.
+ :figclass: align-center
+
+ Example of a input data.
+
+The input file for the following complex is:
+
+.. literalinclude:: ../../data/bitmap/cubicalcomplexdoc.txt
+
+.. centered:: ../../data/bitmap/cubicalcomplexdoc.txt
+
+To indicate periodic boundary conditions in a given direction, then number of
+top dimensional cells in this direction have to be multiplied by -1. For
+instance:
+
+.. literalinclude:: ../../data/bitmap/periodiccubicalcomplexdoc.txt
+
+.. centered:: ../../data/bitmap/periodiccubicalcomplexdoc.txt
+
+
+Indicate that we have imposed periodic boundary conditions in the direction x,
+but not in the direction y.
+
+Other sample files can be found in the `data/bitmap` folder.
diff --git a/src/cython/doc/witness_complex_user.rst b/src/cython/doc/witness_complex_user.rst
index 29413269..99be5185 100644
--- a/src/cython/doc/witness_complex_user.rst
+++ b/src/cython/doc/witness_complex_user.rst
@@ -121,7 +121,7 @@ Example2: Computing persistence using strong relaxed witness complex
Here is an example of constructing a strong witness complex filtration and computing persistence on it:
-* :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>`
+* :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>`
Bibliography
============
diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h
index ecf014b3..0c3a510e 100644
--- a/src/cython/include/Tangential_complex_interface.h
+++ b/src/cython/include/Tangential_complex_interface.h
@@ -105,7 +105,7 @@ class Tangential_complex_interface {
}
void create_simplex_tree(Simplex_tree<>* simplex_tree) {
- int max_dim = tangential_complex_->create_complex<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>(*simplex_tree);
+ tangential_complex_->create_complex<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>(*simplex_tree);
simplex_tree->initialize_filtration();
}
diff --git a/src/cython/setup.py.in b/src/cython/setup.py.in
index fefa36bb..c767e93d 100644
--- a/src/cython/setup.py.in
+++ b/src/cython/setup.py.in
@@ -23,7 +23,7 @@ from Cython.Build import cythonize
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
-__author__ = "Vincent Rouvreau"
+__author__ = "GUDHI Editorial Board"
__copyright__ = "Copyright (C) 2016 INRIA"
__license__ = "GPL v3"
@@ -41,7 +41,7 @@ gudhi = Extension(
setup(
name = 'gudhi',
- author='Vincent Rouvreau',
+ author='GUDHI Editorial Board',
author_email='gudhi-contact@lists.gforge.inria.fr',
version='@GUDHI_VERSION@',
url='http://gudhi.gforge.inria.fr/',