summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskachano <skachano@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2015-12-07 14:45:43 +0000
committerskachano <skachano@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2015-12-07 14:45:43 +0000
commitc4078affdbf6fac7150c10ade96fcb72270ac013 (patch)
tree1ad197bb90078a56036a49c6ee3766a032f85e63
parentf70e386fc98f1dbd8287d1cb7cc715710a8f751b (diff)
parent061e43a2a48525bc5a69482a1ea80f20ff505e55 (diff)
Merged with trunk and removed unnecessary files
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@934 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d0ec52d222d22c102e9fe57590882cd0024c82d5
-rw-r--r--CMakeGUDHIVersion.txt6
-rw-r--r--CMakeLists.txt17
-rw-r--r--GUDHIVersion.cmake.in1
-rw-r--r--Version.txt1
-rw-r--r--biblio/how_to_cite_gudhi.bib44
-rw-r--r--data/points/generator/CMakeLists.txt17
-rw-r--r--data/points/generator/hypergenerator.cpp16
-rwxr-xr-xscripts/generate_version.sh41
-rw-r--r--src/Alpha_shapes/example/CMakeLists.txt32
-rw-r--r--src/Alpha_shapes/example/Delaunay_triangulation_off_rw.cpp105
-rw-r--r--src/Alpha_shapes/example/Simplex_tree_from_delaunay_triangulation.cpp103
-rw-r--r--src/Alpha_shapes/include/gudhi/Alpha_shapes.h200
-rw-r--r--src/Alpha_shapes/include/gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h213
-rw-r--r--src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp126
-rw-r--r--src/Alpha_shapes/test/CMakeLists.txt48
-rw-r--r--src/Alpha_shapes/test/README14
-rw-r--r--src/Alpha_shapes/test/S4_100.off102
-rw-r--r--src/Alpha_shapes/test/S8_10.off12
-rw-r--r--src/Bottleneck/test/bottleneck_unit_test.cpp6
-rw-r--r--src/CMakeLists.txt49
-rw-r--r--src/Contraction/example/Garland_heckbert.cpp47
-rw-r--r--src/Contraction/example/Garland_heckbert/Error_quadric.h324
-rw-r--r--src/Contraction/example/Rips_contraction.cpp99
-rw-r--r--src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h124
-rw-r--r--src/Contraction/include/gudhi/Contraction/Edge_profile.h200
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Contraction_visitor.h164
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h76
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h84
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Edge_length_cost.h90
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/First_vertex_placement.h81
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h96
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h87
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h76
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h80
-rw-r--r--src/Contraction/include/gudhi/Edge_contraction.h44
-rw-r--r--src/Contraction/include/gudhi/Skeleton_blocker_contractor.h1026
-rw-r--r--src/Doxyfile17
-rw-r--r--src/GUDHIConfig.cmake.in7
-rw-r--r--src/GUDHIConfigVersion.cmake.in11
-rw-r--r--src/GudhUI/CMakeLists.txt21
-rw-r--r--src/GudhUI/gui/MainWindow.cpp385
-rw-r--r--src/GudhUI/gui/MainWindow.h144
-rw-r--r--src/GudhUI/gui/Menu_edge_contraction.cpp118
-rw-r--r--src/GudhUI/gui/Menu_edge_contraction.h75
-rw-r--r--src/GudhUI/gui/Menu_k_nearest_neighbors.cpp82
-rw-r--r--src/GudhUI/gui/Menu_k_nearest_neighbors.h58
-rw-r--r--src/GudhUI/gui/Menu_persistence.cpp45
-rw-r--r--src/GudhUI/gui/Menu_persistence.h42
-rw-r--r--src/GudhUI/gui/Menu_uniform_neighbors.cpp87
-rw-r--r--src/GudhUI/gui/Menu_uniform_neighbors.h57
-rw-r--r--src/GudhUI/gui/Viewer.cpp0
-rw-r--r--src/GudhUI/gui/Viewer_instructor.cpp0
-rw-r--r--src/GudhUI/gui/gudhui.cpp35
-rw-r--r--src/GudhUI/model/Complex_typedefs.h48
-rw-r--r--src/GudhUI/model/Model.h650
-rw-r--r--src/GudhUI/utils/Critical_points.h203
-rw-r--r--src/GudhUI/utils/Edge_collapsor.h156
-rw-r--r--src/GudhUI/utils/Edge_contractor.h158
-rw-r--r--src/GudhUI/utils/Furthest_point_epsilon_net.h244
-rw-r--r--src/GudhUI/utils/Is_manifold.h117
-rw-r--r--src/GudhUI/utils/K_nearest_builder.h143
-rw-r--r--src/GudhUI/utils/Lloyd_builder.h133
-rw-r--r--src/GudhUI/utils/MClock.h109
-rw-r--r--src/GudhUI/utils/Persistence_compute.h138
-rw-r--r--src/GudhUI/utils/Rips_builder.h99
-rw-r--r--src/GudhUI/utils/UI_utils.h52
-rw-r--r--src/GudhUI/utils/Vertex_collapsor.h140
-rw-r--r--src/GudhUI/view/Color.h42
-rw-r--r--src/GudhUI/view/FirstCoordProjector.h44
-rw-r--r--src/GudhUI/view/Projector3D.h47
-rw-r--r--src/GudhUI/view/View_parameter.h264
-rw-r--r--src/GudhUI/view/Viewer.cpp303
-rw-r--r--src/GudhUI/view/Viewer.h132
-rw-r--r--src/GudhUI/view/Viewer_instructor.cpp272
-rw-r--r--src/GudhUI/view/Viewer_instructor.h151
-rw-r--r--src/Hasse_complex/example/CMakeLists.txt5
-rw-r--r--src/Hasse_complex/example/hasse_complex_from_simplex_tree.cpp124
-rw-r--r--src/Hasse_complex/include/gudhi/Hasse_complex.h332
-rw-r--r--src/Persistent_cohomology/example/CMakeLists.txt68
-rw-r--r--src/Persistent_cohomology/example/alpha_shapes_persistence.cpp231
-rw-r--r--src/Persistent_cohomology/example/performance_rips_persistence.cpp227
-rw-r--r--src/Persistent_cohomology/example/persistence_from_file.cpp239
-rw-r--r--src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp135
-rw-r--r--src/Persistent_cohomology/example/plain_homology.cpp84
-rw-r--r--src/Persistent_cohomology/example/rips_multifield_persistence.cpp234
-rw-r--r--src/Persistent_cohomology/example/rips_persistence.cpp222
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h125
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h24
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h15
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h35
-rw-r--r--src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp11
-rw-r--r--src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp11
-rw-r--r--src/Simplex_tree/concept/IndexingTag.h2
-rw-r--r--src/Simplex_tree/concept/SimplexKey.h4
-rw-r--r--src/Simplex_tree/concept/SimplexTreeOptions.h41
-rw-r--r--src/Simplex_tree/concept/VertexHandle.h3
-rw-r--r--src/Simplex_tree/example/CMakeLists.txt15
-rw-r--r--src/Simplex_tree/example/mini_simplex_tree.cpp69
-rw-r--r--src/Simplex_tree/example/simple_simplex_tree.cpp108
-rw-r--r--src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp440
-rw-r--r--src/Simplex_tree/example/simplex_tree_from_cliques_of_graph.cpp114
-rw-r--r--src/Simplex_tree/example/simplex_tree_from_file.cpp104
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree.h729
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h22
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h49
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h38
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/indexing_tag.h6
-rw-r--r--src/Simplex_tree/test/CMakeLists.txt3
-rw-r--r--src/Simplex_tree/test/simplex_tree_unit_test.cpp676
-rw-r--r--src/Skeleton_blocker/example/CMakeLists.txt6
-rw-r--r--src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp115
-rw-r--r--src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp132
-rw-r--r--src/Skeleton_blocker/example/Skeleton_blocker_link.cpp96
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h64
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h20
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h14
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h20
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h10
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h11
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h15
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h53
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Top_faces.h105
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h464
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h225
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_edges_iterators.h277
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h19
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h677
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h409
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_vertices_iterators.h318
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h260
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h58
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h63
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h117
-rw-r--r--src/Skeleton_blocker/test/CMakeLists.txt4
-rw-r--r--src/Skeleton_blocker/test/TestGeometricComplex.cpp154
-rw-r--r--src/Skeleton_blocker/test/TestSimplifiable.cpp620
-rw-r--r--src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp1652
-rw-r--r--src/Witness_complex/example/Torus_distance.h209
-rw-r--r--src/Witness_complex/example/protected_sets/output_tikz.h67
-rw-r--r--src/Witness_complex/example/protected_sets/protected_sets.h597
-rw-r--r--src/Witness_complex/example/protected_sets/protected_sets_paper.cpp610
-rw-r--r--src/Witness_complex/example/protected_sets/protected_sets_paper.h917
-rw-r--r--src/Witness_complex/example/protected_sets/protected_sets_paper2.h1384
-rw-r--r--src/Witness_complex/example/witness_complex_cube.cpp590
-rw-r--r--src/Witness_complex/example/witness_complex_cubic_systems.cpp547
-rw-r--r--src/Witness_complex/example/witness_complex_epsilon.cpp55
-rw-r--r--src/Witness_complex/example/witness_complex_flat_torus.cpp851
-rw-r--r--src/Witness_complex/example/witness_complex_from_off.cpp184
-rw-r--r--src/Witness_complex/example/witness_complex_from_wl_matrix.cpp148
-rw-r--r--src/Witness_complex/example/witness_complex_knn_landmarks.cpp210
-rw-r--r--src/Witness_complex/example/witness_complex_perturbations.cpp462
-rw-r--r--src/Witness_complex/example/witness_complex_protected_delaunay.cpp604
-rw-r--r--src/Witness_complex/example/witness_complex_sphere.cpp457
-rw-r--r--src/cmake/modules/FindEigen3.cmake86
-rw-r--r--src/cmake/modules/UseEigen3.cmake9
-rw-r--r--src/common/doc/main_page.h173
-rw-r--r--src/common/include/gudhi/Clock.h151
-rw-r--r--src/common/include/gudhi/Off_reader.h289
-rw-r--r--src/common/include/gudhi/Point.h286
-rw-r--r--src/common/include/gudhi/Simple_object_pool.h81
-rw-r--r--src/common/include/gudhi/Test.h156
-rw-r--r--src/common/include/gudhi/Utils.h74
-rw-r--r--src/common/include/gudhi/distance_functions.h64
-rw-r--r--src/common/include/gudhi/graph_simplicial_complex.h125
-rw-r--r--src/common/include/gudhi/reader_utils.h193
165 files changed, 10570 insertions, 18212 deletions
diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt
new file mode 100644
index 00000000..19d10535
--- /dev/null
+++ b/CMakeGUDHIVersion.txt
@@ -0,0 +1,6 @@
+set (GUDHI_MAJOR_VERSION 1)
+set (GUDHI_MINOR_VERSION 2)
+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/CMakeLists.txt b/CMakeLists.txt
index 57cb14d4..609b5eb7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,10 @@
cmake_minimum_required(VERSION 2.6)
project(GUDHIdev)
+include(CMakeGUDHIVersion.txt)
+# Generate GUDHI official version file
+configure_file(GUDHIVersion.cmake.in "${PROJECT_BINARY_DIR}/GUDHIVersion.cmake" @ONLY)
+
find_package(Boost REQUIRED COMPONENTS system filesystem unit_test_framework chrono timer program_options thread REQUIRED)
set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/")
@@ -23,7 +27,6 @@ set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
-find_package(Boost)
#find_package(GMP)
#if(GMP_FOUND)
#find_package(GMPXX)
@@ -67,9 +70,9 @@ else()
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
message(STATUS "boost include dirs:" ${Boost_INCLUDE_DIRS})
+ message(STATUS "boost library dirs:" ${Boost_LIBRARY_DIRS})
include_directories(src/common/include/)
- include_directories(src/Alpha_shapes/include/)
include_directories(src/Bottleneck/include/)
include_directories(src/Contraction/include/)
include_directories(src/Hasse_complex/include/)
@@ -85,17 +88,21 @@ else()
add_subdirectory(src/Skeleton_blocker/test)
add_subdirectory(src/Skeleton_blocker/example)
add_subdirectory(src/Contraction/example)
- add_subdirectory(src/Hasse_complex/example)
+ # add_subdirectory(src/Hasse_complex/example)
add_subdirectory(src/Witness_complex/test)
add_subdirectory(src/Witness_complex/example)
- add_subdirectory(src/Alpha_shapes/example)
- add_subdirectory(src/Alpha_shapes/test)
+ # add_subdirectory(src/Alpha_shapes/example)
+ # add_subdirectory(src/Alpha_shapes/test)
add_subdirectory(src/Bottleneck/example)
add_subdirectory(src/Bottleneck/test)
# data points generator
add_subdirectory(data/points/generator)
+ # Please let GudhUI in last compilation position as QT is known to modify CMAKE_CXX_FLAGS
+ # GudhUI
+ add_subdirectory(src/GudhUI)
+
endif()
diff --git a/GUDHIVersion.cmake.in b/GUDHIVersion.cmake.in
new file mode 100644
index 00000000..2f433c1c
--- /dev/null
+++ b/GUDHIVersion.cmake.in
@@ -0,0 +1 @@
+@GUDHI_VERSION@
diff --git a/Version.txt b/Version.txt
deleted file mode 100644
index 9084fa2f..00000000
--- a/Version.txt
+++ /dev/null
@@ -1 +0,0 @@
-1.1.0
diff --git a/biblio/how_to_cite_gudhi.bib b/biblio/how_to_cite_gudhi.bib
new file mode 100644
index 00000000..851dd5d9
--- /dev/null
+++ b/biblio/how_to_cite_gudhi.bib
@@ -0,0 +1,44 @@
+@book{gudhi:urm
+, title = "{GUDHI} User and Reference Manual"
+, author = "{The GUDHI Project}"
+, publisher = "{GUDHI Editorial Board}"
+, year = 2015
+, url = "http://gudhi.gforge.inria.fr/doc/latest/"
+}
+
+@incollection{gudhi:FilteredComplexes
+, author = "Cl\'ement Maria"
+, title = "Filtered Complexes"
+, publisher = "{GUDHI Editorial Board}"
+, booktitle = "{GUDHI} User and Reference Manual"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group__simplex__tree.html"
+, year = 2015
+}
+
+@incollection{gudhi:PersistentCohomology
+, author = "Cl\'ement Maria"
+, title = "Persistent Cohomology"
+, publisher = "{GUDHI Editorial Board}"
+, booktitle = "{GUDHI} User and Reference Manual"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group__persistent__cohomology.html"
+, year = 2015
+}
+
+@incollection{gudhi:Contraction
+, author = "David Salinas"
+, title = "Contraction"
+, publisher = "{GUDHI Editorial Board}"
+, booktitle = "{GUDHI} User and Reference Manual"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group__contr.html"
+, year = 2015
+}
+
+@incollection{gudhi:Skeleton-Blocker
+, author = "David Salinas"
+, title = "Skeleton-Blocker"
+, publisher = "{GUDHI Editorial Board}"
+, booktitle = "{GUDHI} User and Reference Manual"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group__skbl.html"
+, year = 2015
+}
+
diff --git a/data/points/generator/CMakeLists.txt b/data/points/generator/CMakeLists.txt
index 0f2674c4..26b44446 100644
--- a/data/points/generator/CMakeLists.txt
+++ b/data/points/generator/CMakeLists.txt
@@ -4,7 +4,22 @@ project(GUDHIPointsGenerator)
if(CGAL_FOUND)
if (NOT CGAL_VERSION VERSION_LESS 4.6.0)
message(STATUS "CGAL version: ${CGAL_VERSION}.")
+
include( ${CGAL_USE_FILE} )
+ # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten.
+ # cf. http://doc.cgal.org/latest/Manual/installation.html#title40
+ # A workaround is to add "-std=c++11" again.
+ # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
+ # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html
+ # but it implies to use cmake version 3.1 at least.
+ if(NOT MSVC)
+ include(CheckCXXCompilerFlag)
+ CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
+ if(COMPILER_SUPPORTS_CXX11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+ endif()
+ # - End of workaround
find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
@@ -21,6 +36,6 @@ if(CGAL_FOUND)
add_test(hypergenerator_in_cube_50000_2 ${CMAKE_CURRENT_BINARY_DIR}/hypergenerator in cube inCube.off 50000 3)
endif()
else()
- message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.")
+ message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile hypergenerator. Version 4.6.0 is required.")
endif ()
endif()
diff --git a/data/points/generator/hypergenerator.cpp b/data/points/generator/hypergenerator.cpp
index f4ea6b07..60890b44 100644
--- a/data/points/generator/hypergenerator.cpp
+++ b/data/points/generator/hypergenerator.cpp
@@ -35,8 +35,9 @@ typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > K;
typedef K::Point_d Point;
void usage(char * const progName) {
- std::cerr << "Usage: " << progName << " in|on sphere|cube off_file_name points_number[integer > 0] dimension[integer > 1] radius[double > 0.0 | default = 1.0]" << std::endl;
- exit(-1); // ----- >>
+ std::cerr << "Usage: " << progName << " in|on sphere|cube off_file_name points_number[integer > 0] " <<
+ "dimension[integer > 1] radius[double > 0.0 | default = 1.0]" << std::endl;
+ exit(-1);
}
int main(int argc, char **argv) {
@@ -86,8 +87,13 @@ int main(int argc, char **argv) {
}
std::ofstream diagram_out(argv[3]);
- diagram_out << "OFF" << std::endl;
- diagram_out << points_number << " 0 0" << std::endl;
+ if (dimension == 3) {
+ diagram_out << "OFF" << std::endl;
+ diagram_out << points_number << " 0 0" << std::endl;
+ } else {
+ diagram_out << "nOFF" << std::endl;
+ diagram_out << dimension << " " << points_number << " 0 0" << std::endl;
+ }
if (diagram_out.is_open()) {
// Instanciate a random point generator
@@ -114,7 +120,7 @@ int main(int argc, char **argv) {
for (auto thePoint : points) {
int i = 0;
- for (;i < dimension - 1; i++) {
+ for (; i < dimension - 1; i++) {
diagram_out << thePoint[i] << " ";
}
diagram_out << thePoint[i] << std::endl; // last point + Carriage Return
diff --git a/scripts/generate_version.sh b/scripts/generate_version.sh
index 4d28cf53..323396dc 100755
--- a/scripts/generate_version.sh
+++ b/scripts/generate_version.sh
@@ -2,19 +2,22 @@
#usage bash generate_version.sh : dont generate if svn st non empty
#usage bash generate_version.sh -f : generate even if svn is empty
#usage bash generate_version.sh -f DIR : generate even if svn is empty and save library in dir
+#
+# 23/06/2015 - Remove source, add biblio, and doc
+# 06/10/2015 - Replace static Version.txt with generated GUDHIVersion.cmake file
# VERSION CHECK
ROOT_DIR=..
-VERSION_FILE="$ROOT_DIR/Version.txt"
+VERSION_FILE="$ROOT_DIR/GUDHIVersion.cmake"
if [ ! -f $VERSION_FILE ]; then
- echo "File not found! : $VERSION_FILE"
+ echo "File not found! : $VERSION_FILE - Please launch cmake first to generate file"
exit 1
fi
# SVN STATUS CHECK OR IF FORCED BY USER
if [ "$1" != "-f" ]
then
- SVN_STATUS=`svn status $ROOT_DIR`
+ SVN_STATUS=`svn status $ROOT_DIR | grep -v $VERSION_FILE`
echo $SVN_STATUS
fi
@@ -42,22 +45,29 @@ mkdir "$VERSION_DIR"
# TOP LEVEL FILE COPY
cp $VERSION_FILE $VERSION_DIR
+cp $ROOT_DIR/CMakeGUDHIVersion.txt $VERSION_DIR
cp $ROOT_DIR/README $VERSION_DIR
cp $ROOT_DIR/Conventions.txt $VERSION_DIR
cp $ROOT_DIR/COPYING $VERSION_DIR
cp -R $ROOT_DIR/data $VERSION_DIR
cp $ROOT_DIR/src/CMakeLists.txt $VERSION_DIR
cp $ROOT_DIR/src/Doxyfile $VERSION_DIR
+cp -R $ROOT_DIR/biblio $VERSION_DIR
+cp $ROOT_DIR/src/GUDHIConfigVersion.cmake.in $VERSION_DIR
+cp $ROOT_DIR/src/GUDHIConfig.cmake.in $VERSION_DIR
+cp $ROOT_DIR/GUDHIVersion.cmake.in $VERSION_DIR
# PACKAGE LEVEL COPY
PACKAGE_INC_DIR="/include"
-PACKAGE_SRC_DIR="/source"
+#PACKAGE_SRC_DIR="/source"
PACKAGE_EX_DIR="/example"
+PACKAGE_CONCEPT_DIR="/concept"
+PACKAGE_DOC_DIR="/doc"
for package in `ls $ROOT_DIR/src/`
do
- echo $package
- if [ -d "$ROOT_DIR/src/$package" ]
+ if [ -d "$ROOT_DIR/src/$package" ] && [ $package != "Bottleneck" ]
then
+ echo $package
if [ "$package" == "cmake" ]
then
# SPECIFIC FOR CMAKE MODULES
@@ -77,20 +87,21 @@ do
fi
cp -R $ROOT_DIR/src/$package$PACKAGE_INC_DIR/* $VERSION_DIR$PACKAGE_INC_DIR/
fi
- if [ -d "$ROOT_DIR/src/$package$PACKAGE_SRC_DIR" ]
- then
- if [ ! -d "$VERSION_DIR$PACKAGE_SRC_DIR" ]
- then
- # MUST CREATE DIRECTORY ON FIRST LOOP
- mkdir $VERSION_DIR$PACKAGE_INC_DIR
- fi
- cp -R $ROOT_DIR/src/$package$PACKAGE_SRC_DIR/* $VERSION_DIR$PACKAGE_SRC_DIR/
- fi
if [ -d "$ROOT_DIR/src/$package$PACKAGE_EX_DIR" ]
then
mkdir -p $VERSION_DIR$PACKAGE_EX_DIR/$package
cp -R $ROOT_DIR/src/$package$PACKAGE_EX_DIR/* $VERSION_DIR$PACKAGE_EX_DIR/$package
fi
+ if [ -d "$ROOT_DIR/src/$package$PACKAGE_CONCEPT_DIR" ]
+ then
+ mkdir -p $VERSION_DIR$PACKAGE_CONCEPT_DIR/$package
+ cp -R $ROOT_DIR/src/$package$PACKAGE_CONCEPT_DIR/* $VERSION_DIR$PACKAGE_CONCEPT_DIR/$package
+ fi
+ if [ -d "$ROOT_DIR/src/$package$PACKAGE_DOC_DIR" ]
+ then
+ mkdir -p $VERSION_DIR$PACKAGE_DOC_DIR/$package
+ cp -R $ROOT_DIR/src/$package$PACKAGE_DOC_DIR/* $VERSION_DIR$PACKAGE_DOC_DIR/$package
+ fi
fi
fi
done
diff --git a/src/Alpha_shapes/example/CMakeLists.txt b/src/Alpha_shapes/example/CMakeLists.txt
deleted file mode 100644
index 753238a5..00000000
--- a/src/Alpha_shapes/example/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-cmake_minimum_required(VERSION 2.6)
-project(GUDHIAlphaShapesExample)
-
-# need CGAL 4.6
-# cmake -DCGAL_DIR=~/workspace/CGAL-4.6-beta1 ../../..
-if(CGAL_FOUND)
- if (NOT CGAL_VERSION VERSION_LESS 4.6.0)
- message(STATUS "CGAL version: ${CGAL_VERSION}.")
-
- include( ${CGAL_USE_FILE} )
-
- find_package(Eigen3 3.1.0)
- if (EIGEN3_FOUND)
- message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
- include( ${EIGEN3_USE_FILE} )
- include_directories (BEFORE "../../include")
-
- add_executable ( dtoffrw Delaunay_triangulation_off_rw.cpp )
- target_link_libraries(dtoffrw ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
- add_test(dtoffrw_tore3D ${CMAKE_CURRENT_BINARY_DIR}/dtoffrw ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off 3)
-
- # uncomment to display debug traces
- # add_definitions(-DDEBUG_TRACES)
- add_executable ( stfromdt Simplex_tree_from_delaunay_triangulation.cpp )
- target_link_libraries(stfromdt ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
- else()
- message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.")
- endif()
- else()
- message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.")
- endif ()
-endif()
diff --git a/src/Alpha_shapes/example/Delaunay_triangulation_off_rw.cpp b/src/Alpha_shapes/example/Delaunay_triangulation_off_rw.cpp
deleted file mode 100644
index 03f6440d..00000000
--- a/src/Alpha_shapes/example/Delaunay_triangulation_off_rw.cpp
+++ /dev/null
@@ -1,105 +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): Vincent Rouvreau
- *
- * Copyright (C) 2014 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// to construct a Delaunay_triangulation from a OFF file
-#include "gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h"
-
-#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/algorithm.h>
-#include <CGAL/assertions.h>
-
-#include <iostream>
-#include <iterator>
-#include <vector>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-
-// Use dynamic_dimension_tag for the user to be able to set dimension
-typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > K;
-typedef CGAL::Delaunay_triangulation<K> T;
-// The triangulation uses the default instanciation of the
-// TriangulationDataStructure template parameter
-
-void usage(char * const progName) {
- std::cerr << "Usage: " << progName << " filename.off dimension" << std::endl;
- exit(-1); // ----- >>
-}
-
-int main(int argc, char **argv) {
- if (argc != 3) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
- usage(argv[0]);
- }
-
- int dimension = 0;
- int returnedScanValue = sscanf(argv[2], "%d", &dimension);
- if ((returnedScanValue == EOF) || (dimension <= 0)) {
- std::cerr << "Error: " << argv[2] << " is not correct" << std::endl;
- usage(argv[0]);
- }
-
- T dt(dimension);
- std::string offFileName(argv[1]);
- Gudhi::alphashapes::Delaunay_triangulation_off_reader<T> off_reader(offFileName, dt, true, true);
- if (!off_reader.is_valid()) {
- std::cerr << "Unable to read file " << offFileName << std::endl;
- exit(-1); // ----- >>
- }
-
- std::cout << "number of vertices=" << dt.number_of_vertices() << std::endl;
- std::cout << "number of full cells=" << dt.number_of_full_cells() << std::endl;
- std::cout << "number of finite full cells=" << dt.number_of_finite_full_cells() << std::endl;
-
- // Points list
- /*for (T::Vertex_iterator vit = dt.vertices_begin(); vit != dt.vertices_end(); ++vit) {
- for (auto Coord = vit->point().cartesian_begin(); Coord != vit->point().cartesian_end(); ++Coord) {
- std::cout << *Coord << " ";
- }
- std::cout << std::endl;
- }
- std::cout << std::endl;*/
-
- int i = 0, j = 0;
- typedef T::Full_cell_iterator Full_cell_iterator;
- typedef T::Facet Facet;
-
- for (Full_cell_iterator cit = dt.full_cells_begin(); cit != dt.full_cells_end(); ++cit) {
- if (!dt.is_infinite(cit)) {
- j++;
- continue;
- }
- Facet fct(cit, cit->index(dt.infinite_vertex()));
- i++;
- }
- std::cout << "There are " << i << " facets on the convex hull." << std::endl;
- std::cout << "There are " << j << " facets not on the convex hull." << std::endl;
-
-
- std::string offOutputFile("out.off");
- Gudhi::alphashapes::Delaunay_triangulation_off_writer<T> off_writer(offOutputFile, dt);
-
- return 0;
-} \ No newline at end of file
diff --git a/src/Alpha_shapes/example/Simplex_tree_from_delaunay_triangulation.cpp b/src/Alpha_shapes/example/Simplex_tree_from_delaunay_triangulation.cpp
deleted file mode 100644
index 3a17b519..00000000
--- a/src/Alpha_shapes/example/Simplex_tree_from_delaunay_triangulation.cpp
+++ /dev/null
@@ -1,103 +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): Vincent Rouvreau
- *
- * Copyright (C) 2014 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// to construct a Delaunay_triangulation from a OFF file
-#include "gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h"
-#include "gudhi/Alpha_shapes.h"
-
-// to construct a simplex_tree from Delaunay_triangulation
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-
-#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/algorithm.h>
-#include <CGAL/assertions.h>
-
-#include <iostream>
-#include <iterator>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-
-// Use dynamic_dimension_tag for the user to be able to set dimension
-typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > K;
-typedef CGAL::Delaunay_triangulation<K> T;
-// The triangulation uses the default instanciation of the
-// TriangulationDataStructure template parameter
-
-void usage(char * const progName) {
- std::cerr << "Usage: " << progName << " filename.off dimension" << std::endl;
- exit(-1); // ----- >>
-}
-
-int main(int argc, char **argv) {
- if (argc != 3) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
- usage(argv[0]);
- }
-
- int dimension = 0;
- int returnedScanValue = sscanf(argv[2], "%d", &dimension);
- if ((returnedScanValue == EOF) || (dimension <= 0)) {
- std::cerr << "Error: " << argv[2] << " is not correct" << std::endl;
- usage(argv[0]);
- }
-
- // ----------------------------------------------------------------------------
- //
- // Init of an alpha-shape from a Delaunay triangulation
- //
- // ----------------------------------------------------------------------------
- T dt(dimension);
- std::string off_file_name(argv[1]);
-
- Gudhi::alphashapes::Delaunay_triangulation_off_reader<T> off_reader(off_file_name, dt, false, false);
- if (!off_reader.is_valid()) {
- std::cerr << "Unable to read file " << off_file_name << std::endl;
- exit(-1); // ----- >>
- }
-
- std::cout << "number of vertices=" << dt.number_of_vertices() << std::endl;
- std::cout << "number of full cells=" << dt.number_of_full_cells() << std::endl;
- std::cout << "number of finite full cells=" << dt.number_of_finite_full_cells() << std::endl;
-
- Gudhi::alphashapes::Alpha_shapes alpha_shapes_from_dt(dt);
- //std::cout << alpha_shapes_from_dt << std::endl;
-
- // ----------------------------------------------------------------------------
- //
- // Init of an alpha-shape from a OFF file
- //
- // ----------------------------------------------------------------------------
- Gudhi::alphashapes::Alpha_shapes alpha_shapes_from_file(off_file_name, dimension);
- //std::cout << alpha_shapes_from_file << std::endl;
-
- std::cout << "alpha_shapes_from_file.dimension()=" << alpha_shapes_from_file.dimension() << std::endl;
- std::cout << "alpha_shapes_from_file.filtration()=" << alpha_shapes_from_file.filtration() << std::endl;
- std::cout << "alpha_shapes_from_file.num_simplices()=" << alpha_shapes_from_file.num_simplices() << std::endl;
- std::cout << "alpha_shapes_from_file.num_vertices()=" << alpha_shapes_from_file.num_vertices() << std::endl;
-
- return 0;
-} \ No newline at end of file
diff --git a/src/Alpha_shapes/include/gudhi/Alpha_shapes.h b/src/Alpha_shapes/include/gudhi/Alpha_shapes.h
deleted file mode 100644
index b8efdb4d..00000000
--- a/src/Alpha_shapes/include/gudhi/Alpha_shapes.h
+++ /dev/null
@@ -1,200 +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): Vincent Rouvreau
- *
- * Copyright (C) 2015 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef SRC_ALPHA_SHAPES_INCLUDE_GUDHI_ALPHA_SHAPES_H_
-#define SRC_ALPHA_SHAPES_INCLUDE_GUDHI_ALPHA_SHAPES_H_
-
-// to construct a Delaunay_triangulation from a OFF file
-#include <gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h>
-
-// to construct a simplex_tree from Delaunay_triangulation
-#include <gudhi/graph_simplicial_complex.h>
-#include <gudhi/Simplex_tree.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/algorithm.h>
-#include <CGAL/assertions.h>
-
-#include <iostream>
-#include <iterator>
-#include <vector>
-#include <string>
-
-namespace Gudhi {
-
-namespace alphashapes {
-
-/** \defgroup alpha_shapes Alpha shapes in dimension N
- *
- <DT>Implementations:</DT>
- Alpha shapes in dimension N are a subset of Delaunay Triangulation in dimension N.
-
-
- * \author Vincent Rouvreau
- * \version 1.0
- * \date 2015
- * \copyright GNU General Public License v3.
- * @{
- */
-
-/**
- * \brief Alpha shapes data structure.
- *
- * \details Every simplex \f$[v_0, \cdots ,v_d]\f$ admits a canonical orientation
- * induced by the order relation on vertices \f$ v_0 < \cdots < v_d \f$.
- *
- * Details may be found in \cite boissonnatmariasimplextreealgorithmica.
- *
- * \implements FilteredComplex
- *
- */
-class Alpha_shapes {
- private:
- // From Simplex_tree
- /** \brief Type required to insert into a simplex_tree (with or without subfaces).*/
- typedef std::vector<Vertex_handle> typeVectorVertex;
-
- // From CGAL
- /** \brief Kernel for the Delaunay_triangulation.
- * Dimension can be set dynamically.
- */
- typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
- /** \brief Delaunay_triangulation type required to create an alpha-shape.
- */
- typedef CGAL::Delaunay_triangulation<Kernel> Delaunay_triangulation;
-
- private:
- /** \brief Upper bound on the simplex tree of the simplicial complex.*/
- Gudhi::Simplex_tree<> _st;
-
- public:
-
- Alpha_shapes(std::string off_file_name, int dimension) {
- Delaunay_triangulation dt(dimension);
- Gudhi::alphashapes::Delaunay_triangulation_off_reader<Delaunay_triangulation>
- off_reader(off_file_name, dt, true, true);
- if (!off_reader.is_valid()) {
- std::cerr << "Unable to read file " << off_file_name << std::endl;
- exit(-1); // ----- >>
- }
-#ifdef DEBUG_TRACES
- std::cout << "number of vertices=" << dt.number_of_vertices() << std::endl;
- std::cout << "number of full cells=" << dt.number_of_full_cells() << std::endl;
- std::cout << "number of finite full cells=" << dt.number_of_finite_full_cells() << std::endl;
-#endif // DEBUG_TRACES
- init<Delaunay_triangulation>(dt);
- }
-
- template<typename T>
- Alpha_shapes(T triangulation) {
- init<T>(triangulation);
- }
-
- ~Alpha_shapes() { }
-
- private:
-
- template<typename T>
- void init(T triangulation) {
- _st.set_dimension(triangulation.maximal_dimension());
- _st.set_filtration(0.0);
- // triangulation points list
- for (auto vit = triangulation.finite_vertices_begin();
- vit != triangulation.finite_vertices_end(); ++vit) {
- typeVectorVertex vertexVector;
- Vertex_handle vertexHdl = std::distance(triangulation.finite_vertices_begin(), vit);
- vertexVector.push_back(vertexHdl);
-
- // Insert each point in the simplex tree
- _st.insert_simplex(vertexVector, 0.0);
-
-#ifdef DEBUG_TRACES
- std::cout << "P" << vertexHdl << ":";
- for (auto Coord = vit->point().cartesian_begin(); Coord != vit->point().cartesian_end(); ++Coord) {
- std::cout << *Coord << " ";
- }
- std::cout << std::endl;
-#endif // DEBUG_TRACES
- }
- // triangulation finite full cells list
- for (auto cit = triangulation.finite_full_cells_begin();
- cit != triangulation.finite_full_cells_end(); ++cit) {
- typeVectorVertex vertexVector;
- for (auto vit = cit->vertices_begin(); vit != cit->vertices_end(); ++vit) {
- // Vertex handle is distance - 1
- Vertex_handle vertexHdl = std::distance(triangulation.vertices_begin(), *vit) - 1;
- vertexVector.push_back(vertexHdl);
- }
- // Insert each point in the simplex tree
- _st.insert_simplex_and_subfaces(vertexVector, 0.0);
-
-#ifdef DEBUG_TRACES
- std::cout << "C" << std::distance(triangulation.finite_full_cells_begin(), cit) << ":";
- for (auto value : vertexVector) {
- std::cout << value << ' ';
- }
- std::cout << std::endl;
-#endif // DEBUG_TRACES
- }
- }
-
- public:
-
- /** \brief Returns the number of vertices in the complex. */
- size_t num_vertices() {
- return _st.num_vertices();
- }
-
- /** \brief Returns the number of simplices in the complex.
- *
- * Does not count the empty simplex. */
- const unsigned int& num_simplices() const {
- return _st.num_simplices();
- }
-
- /** \brief Returns an upper bound on the dimension of the simplicial complex. */
- int dimension() {
- return _st.dimension();
- }
-
- /** \brief Returns an upper bound of the filtration values of the simplices. */
- Filtration_value filtration() {
- return _st.filtration();
- }
-
- friend std::ostream& operator<<(std::ostream& os, const Alpha_shapes& alpha_shape) {
- // TODO: Program terminated with signal SIGABRT, Aborted - Maybe because of copy constructor
- Gudhi::Simplex_tree<> st = alpha_shape._st;
- os << st << std::endl;
- return os;
- }
-};
-
-} // namespace alphashapes
-
-} // namespace Gudhi
-
-#endif // SRC_ALPHA_SHAPES_INCLUDE_GUDHI_ALPHA_SHAPES_H_
diff --git a/src/Alpha_shapes/include/gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h b/src/Alpha_shapes/include/gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h
deleted file mode 100644
index 693b393e..00000000
--- a/src/Alpha_shapes/include/gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h
+++ /dev/null
@@ -1,213 +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): Vincent Rouvreau
- *
- * Copyright (C) 2015 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef SRC_ALPHA_SHAPES_INCLUDE_GUDHI_ALPHA_SHAPES_DELAUNAY_TRIANGULATION_OFF_IO_H_
-#define SRC_ALPHA_SHAPES_INCLUDE_GUDHI_ALPHA_SHAPES_DELAUNAY_TRIANGULATION_OFF_IO_H_
-
-#include <string>
-#include <vector>
-#include <fstream>
-
-#include "gudhi/Off_reader.h"
-
-namespace Gudhi {
-
-namespace alphashapes {
-
-/**
- *@brief Off reader visitor with flag that can be passed to Off_reader to read a Delaunay_triangulation_complex.
- */
-template<typename Complex>
-class Delaunay_triangulation_off_flag_visitor_reader {
- Complex& complex_;
- typedef typename Complex::Point Point;
-
- const bool load_only_points_;
-
- public:
- explicit Delaunay_triangulation_off_flag_visitor_reader(Complex& complex, bool load_only_points = false) :
- complex_(complex),
- load_only_points_(load_only_points) { }
-
- void init(int dim, int num_vertices, int num_faces, int num_edges) {
-#ifdef DEBUG_TRACES
- std::cout << "init" << std::endl;
-#endif // DEBUG_TRACES
- }
-
- void point(const std::vector<double>& point) {
-#ifdef DEBUG_TRACES
- std::cout << "p ";
- for (auto coordinate: point) {
- std::cout << coordinate << " | ";
- }
- std::cout << std::endl;
-#endif // DEBUG_TRACES
- complex_.insert(Point(point.size(), point.begin(), point.end()));
- }
-
- void maximal_face(const std::vector<int>& face) {
- // For alpha shapes, only points are read
- }
-
- void done() {
-#ifdef DEBUG_TRACES
- std::cout << "done" << std::endl;
-#endif // DEBUG_TRACES
- }
-};
-
-/**
- *@brief Off reader visitor that can be passed to Off_reader to read a Delaunay_triangulation_complex.
- */
-template<typename Complex>
-class Delaunay_triangulation_off_visitor_reader {
- Complex& complex_;
- // typedef typename Complex::Vertex_handle Vertex_handle;
- // typedef typename Complex::Simplex_handle Simplex_handle;
- typedef typename Complex::Point Point;
-
- const bool load_only_points_;
- std::vector<Point> points_;
- // std::vector<Simplex_handle> maximal_faces_;
-
- public:
- explicit Delaunay_triangulation_off_visitor_reader(Complex& complex, bool load_only_points = false) :
- complex_(complex),
- load_only_points_(load_only_points) { }
-
- void init(int dim, int num_vertices, int num_faces, int num_edges) {
-#ifdef DEBUG_TRACES
- std::cout << "init - " << num_vertices << std::endl;
-#endif // DEBUG_TRACES
- // maximal_faces_.reserve(num_faces);
- points_.reserve(num_vertices);
- }
-
- void point(const std::vector<double>& point) {
-#ifdef DEBUG_TRACES
- std::cout << "p ";
- for (auto coordinate: point) {
- std::cout << coordinate << " | ";
- }
- std::cout << std::endl;
-#endif // DEBUG_TRACES
- points_.emplace_back(Point(point.size(), point.begin(), point.end()));
- }
-
- void maximal_face(const std::vector<int>& face) {
- // For alpha shapes, only points are read
- }
-
- void done() {
- complex_.insert(points_.begin(), points_.end());
-#ifdef DEBUG_TRACES
- std::cout << "done" << std::endl;
-#endif // DEBUG_TRACES
- }
-};
-
-/**
- *@brief Class that allows to load a Delaunay_triangulation_complex from an off file.
- */
-template<typename Complex>
-class Delaunay_triangulation_off_reader {
- public:
- /**
- * name_file : file to read
- * read_complex : complex that will receive the file content
- * read_only_points : specify true if only the points must be read
- */
- Delaunay_triangulation_off_reader(const std::string & name_file, Complex& read_complex, bool read_only_points = false,
- bool is_flag = false) : valid_(false) {
- std::ifstream stream(name_file);
- if (stream.is_open()) {
- if (is_flag) {
- // For alpha shapes, only points are read
- Delaunay_triangulation_off_flag_visitor_reader<Complex> off_visitor(read_complex, true);
- Off_reader off_reader(stream);
- valid_ = off_reader.read(off_visitor);
- } else {
- // For alpha shapes, only points are read
- Delaunay_triangulation_off_visitor_reader<Complex> off_visitor(read_complex, true);
- Off_reader off_reader(stream);
- valid_ = off_reader.read(off_visitor);
- }
- }
- }
-
- /**
- * return true if reading did not meet problems.
- */
- bool is_valid() const {
- return valid_;
- }
-
- private:
- bool valid_;
-};
-
-template<typename Complex>
-class Delaunay_triangulation_off_writer {
- public:
- /**
- * name_file : file where the off will be written
- * save_complex : complex that be outputted in the file
- * for now only save triangles.
- */
- Delaunay_triangulation_off_writer(const std::string & name_file, const Complex& save_complex) {
- std::ofstream stream(name_file);
- if (stream.is_open()) {
- // OFF header
- stream << "OFF" << std::endl;
- // no endl on next line - don't know why...
- stream << save_complex.number_of_vertices() << " " << save_complex.number_of_finite_full_cells() << " 0";
-
- // Points list
- for (auto vit = save_complex.vertices_begin(); vit != save_complex.vertices_end(); ++vit) {
- for (auto Coord = vit->point().cartesian_begin(); Coord != vit->point().cartesian_end(); ++Coord) {
- stream << *Coord << " ";
- }
- stream << std::endl;
- }
-
- // Finite cells list
- for (auto cit = save_complex.finite_full_cells_begin(); cit != save_complex.finite_full_cells_end(); ++cit) {
- stream << std::distance(cit->vertices_begin(), cit->vertices_end()) << " "; // Dimension
- for (auto vit = cit->vertices_begin(); vit != cit->vertices_end(); ++vit) {
- auto vertexHdl = *vit;
- // auto vertexHdl = std::distance(save_complex.vertices_begin(), *vit) - 1;
- // stream << std::distance(save_complex.vertices_begin(), *(vit)) - 1 << " ";
- }
- stream << std::endl;
- }
- stream.close();
- } else {
- std::cerr << "could not open file " << name_file << std::endl;
- }
- }
-};
-
-} // namespace alphashapes
-
-} // namespace Gudhi
-
-#endif // SRC_ALPHA_SHAPES_INCLUDE_GUDHI_ALPHA_SHAPES_DELAUNAY_TRIANGULATION_OFF_IO_H_
diff --git a/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp b/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp
deleted file mode 100644
index b4c32321..00000000
--- a/src/Alpha_shapes/test/Alpha_shapes_unit_test.cpp
+++ /dev/null
@@ -1,126 +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): Vincent Rouvreau
- *
- * Copyright (C) 2015 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define BOOST_TEST_MODULE alpha_shapes test
-#include <boost/test/included/unit_test.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/chrono/thread_clock.hpp>
-// to construct a Delaunay_triangulation from a OFF file
-#include "gudhi/Alpha_shapes/Delaunay_triangulation_off_io.h"
-#include "gudhi/Alpha_shapes.h"
-
-// to construct a simplex_tree from Delaunay_triangulation
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-
-#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/algorithm.h>
-#include <CGAL/assertions.h>
-
-#include <iostream>
-#include <iterator>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-
-// Use dynamic_dimension_tag for the user to be able to set dimension
-typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > K;
-typedef CGAL::Delaunay_triangulation<K> T;
-// The triangulation uses the default instanciation of the
-// TriangulationDataStructure template parameter
-
-BOOST_AUTO_TEST_CASE( OFF_file ) {
- // ----------------------------------------------------------------------------
- //
- // Init of an alpha-shape from a OFF file
- //
- // ----------------------------------------------------------------------------
- std::string off_file_name("S4_100.off");
- std::cout << "========== OFF FILE NAME = " << off_file_name << " ==========" << std::endl;
-
- Gudhi::alphashapes::Alpha_shapes alpha_shapes_from_file(off_file_name, 4);
-
- const int DIMENSION = 4;
- std::cout << "alpha_shapes_from_file.dimension()=" << alpha_shapes_from_file.dimension() << std::endl;
- BOOST_CHECK(alpha_shapes_from_file.dimension() == DIMENSION);
-
- const double FILTRATION = 0.0;
- std::cout << "alpha_shapes_from_file.filtration()=" << alpha_shapes_from_file.filtration() << std::endl;
- BOOST_CHECK(alpha_shapes_from_file.filtration() == FILTRATION);
-
- const int NUMBER_OF_VERTICES = 100;
- std::cout << "alpha_shapes_from_file.num_vertices()=" << alpha_shapes_from_file.num_vertices() << std::endl;
- BOOST_CHECK(alpha_shapes_from_file.num_vertices() == NUMBER_OF_VERTICES);
-
- const int NUMBER_OF_SIMPLICES = 6779;
- std::cout << "alpha_shapes_from_file.num_simplices()=" << alpha_shapes_from_file.num_simplices() << std::endl;
- BOOST_CHECK(alpha_shapes_from_file.num_simplices() == NUMBER_OF_SIMPLICES);
-
-}
-
-BOOST_AUTO_TEST_CASE( Delaunay_triangulation ) {
- // ----------------------------------------------------------------------------
- //
- // Init of an alpha-shape from a Delauny triangulation
- //
- // ----------------------------------------------------------------------------
- T dt(8);
- std::string off_file_name("S8_10.off");
- std::cout << "========== OFF FILE NAME = " << off_file_name << " ==========" << std::endl;
-
- Gudhi::alphashapes::Delaunay_triangulation_off_reader<T> off_reader(off_file_name, dt, true, true);
- std::cout << "off_reader.is_valid()=" << off_reader.is_valid() << std::endl;
- BOOST_CHECK(off_reader.is_valid());
-
- const int NUMBER_OF_VERTICES = 10;
- std::cout << "dt.number_of_vertices()=" << dt.number_of_vertices() << std::endl;
- BOOST_CHECK(dt.number_of_vertices() == NUMBER_OF_VERTICES);
-
- const int NUMBER_OF_FULL_CELLS = 30;
- std::cout << "dt.number_of_full_cells()=" << dt.number_of_full_cells() << std::endl;
- BOOST_CHECK(dt.number_of_full_cells() == NUMBER_OF_FULL_CELLS);
-
- const int NUMBER_OF_FINITE_FULL_CELLS = 6;
- std::cout << "dt.number_of_finite_full_cells()=" << dt.number_of_finite_full_cells() << std::endl;
- BOOST_CHECK(dt.number_of_finite_full_cells() == NUMBER_OF_FINITE_FULL_CELLS);
-
- Gudhi::alphashapes::Alpha_shapes alpha_shapes_from_dt(dt);
-
- const int DIMENSION = 8;
- std::cout << "alpha_shapes_from_dt.dimension()=" << alpha_shapes_from_dt.dimension() << std::endl;
- BOOST_CHECK(alpha_shapes_from_dt.dimension() == DIMENSION);
-
- const double FILTRATION = 0.0;
- std::cout << "alpha_shapes_from_dt.filtration()=" << alpha_shapes_from_dt.filtration() << std::endl;
- BOOST_CHECK(alpha_shapes_from_dt.filtration() == FILTRATION);
-
- std::cout << "alpha_shapes_from_dt.num_vertices()=" << alpha_shapes_from_dt.num_vertices() << std::endl;
- BOOST_CHECK(alpha_shapes_from_dt.num_vertices() == NUMBER_OF_VERTICES);
-
- const int NUMBER_OF_SIMPLICES = 997;
- std::cout << "alpha_shapes_from_dt.num_simplices()=" << alpha_shapes_from_dt.num_simplices() << std::endl;
- BOOST_CHECK(alpha_shapes_from_dt.num_simplices() == NUMBER_OF_SIMPLICES);
-}
-
diff --git a/src/Alpha_shapes/test/CMakeLists.txt b/src/Alpha_shapes/test/CMakeLists.txt
deleted file mode 100644
index e0d33827..00000000
--- a/src/Alpha_shapes/test/CMakeLists.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-cmake_minimum_required(VERSION 2.6)
-project(GUDHIAlphaShapesUT)
-
-# need CGAL 4.6
-# cmake -DCGAL_DIR=~/workspace/CGAL-4.6-beta1 ../../..
-if(CGAL_FOUND)
- if (NOT CGAL_VERSION VERSION_LESS 4.6.0)
- message(STATUS "CGAL version: ${CGAL_VERSION}.")
-
- include( ${CGAL_USE_FILE} )
-
- find_package(Eigen3 3.1.0)
- if (EIGEN3_FOUND)
- message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
- include( ${EIGEN3_USE_FILE} )
- include_directories (BEFORE "../../include")
-
- if (GCOVR_PATH)
- # for gcovr to make coverage reports - Corbera Jenkins plugin
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage")
- endif()
- if (GPROF_PATH)
- # for gprof to make coverage reports - Jenkins
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg")
- endif()
-
- # uncomment to display debug traces
- # add_definitions(-DDEBUG_TRACES)
- add_executable ( AlphaShapesUT Alpha_shapes_unit_test.cpp )
- target_link_libraries(AlphaShapesUT ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
- add_test(NAME AlphaShapesUT
- COMMAND ${CMAKE_CURRENT_BINARY_DIR}/AlphaShapesUT
- # XML format for Jenkins xUnit plugin
- --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/AlphaShapesUT.xml --log_level=test_suite --report_level=no)
-
-
- else()
- message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.")
- endif()
- else()
- message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.")
- endif ()
-endif()
-
diff --git a/src/Alpha_shapes/test/README b/src/Alpha_shapes/test/README
deleted file mode 100644
index cddd46ca..00000000
--- a/src/Alpha_shapes/test/README
+++ /dev/null
@@ -1,14 +0,0 @@
-To compile:
-***********
-
-cd /path-to-gudhi/
-cmake .
-cd /path-to-test/
-make
-
-To launch with details:
-***********************
-
-./AlphaShapesUT --report_level=detailed --log_level=all
-
- ==> echo $? returns 0 in case of success (non-zero otherwise)
diff --git a/src/Alpha_shapes/test/S4_100.off b/src/Alpha_shapes/test/S4_100.off
deleted file mode 100644
index 0a5dc58c..00000000
--- a/src/Alpha_shapes/test/S4_100.off
+++ /dev/null
@@ -1,102 +0,0 @@
-OFF
-100 0 0
-0.562921 -0.735261 -0.256472 0.277007
--0.803733 -0.0527915 -0.315125 0.501918
--0.24946 -0.354982 -0.410773 -0.801887
-0.916381 -0.0512295 0.371049 0.141223
-0.182222 0.940836 -0.171362 -0.228599
--0.787145 -0.129213 0.568102 -0.202402
-0.0187866 -0.22093 -0.832882 -0.507095
--0.4702 -0.533814 0.353776 0.607286
--0.159798 -0.504771 0.263586 0.806346
-0.295546 0.162541 0.452931 0.825279
-0.242043 -0.107437 -0.913612 -0.308521
-0.875759 -0.113035 -0.469189 -0.0114505
-0.547877 -0.762247 -0.256972 -0.229729
--0.172302 0.521057 0.412013 -0.727363
--0.724729 -0.0574074 -0.0290602 0.686023
-0.700434 -0.102636 0.687285 0.162779
--0.681386 0.0946893 0.610047 0.393178
--0.847553 -0.357132 0.383743 0.0827718
-0.72297 -0.161631 -0.608517 0.284424
-0.757394 0.141549 0.196065 -0.606528
-0.78094 0.00901997 0.434536 0.448586
-0.14166 -0.619339 0.614589 -0.467582
-0.473105 -0.537832 -0.0103746 0.697711
--0.208004 0.536218 0.818027 0.00605288
-0.743694 -0.628926 0.188072 0.126488
--0.462228 -0.278147 0.35514 -0.76345
--0.17361 0.249211 0.758567 -0.57648
-0.416958 -0.254924 -0.576373 -0.654946
--0.590751 -0.286089 -0.424896 0.623402
--0.639538 -0.739693 -0.203745 0.0482932
-0.0731787 0.132121 0.864022 0.480266
--0.149644 -0.164724 -0.249746 -0.94239
--0.348592 0.0120379 -0.928656 -0.126239
-0.395328 -0.54513 0.149976 -0.723917
--0.974164 0.14707 0.157191 0.068302
--0.166425 0.119943 -0.627304 -0.751269
-0.031947 -0.358518 -0.708301 -0.607251
-0.93781 -0.155368 -0.30951 0.0240237
-0.276094 -0.753155 -0.597088 -0.00387459
--0.642876 -0.200551 -0.263517 -0.690687
-0.178711 0.604987 -0.262989 0.729993
--0.520347 0.497922 -0.676144 0.155374
--0.703999 0.500219 -0.484381 0.139789
--0.131013 0.835735 0.506779 0.166004
--0.536116 -0.566557 0.229226 0.582279
--0.334105 0.158252 0.926091 0.0754059
--0.0362677 0.296076 0.897108 0.325915
--0.57486 0.798575 0.15324 -0.0912754
-0.498602 0.0186805 0.72824 0.469801
--0.960329 0.0473356 0.261005 -0.0860505
-0.899134 -0.381392 -0.214508 0.00921711
-0.570576 0.567224 0.393019 -0.445237
--0.761763 -0.614589 -0.0546476 -0.197513
-0.188584 0.289531 0.174031 0.922129
--0.458506 -0.583876 0.639297 -0.2004
-0.785343 -0.21571 0.0794082 -0.574804
-0.0819036 0.65961 -0.247426 0.704973
-0.573125 0.49706 0.373026 0.534145
--0.513286 -0.626226 0.208535 -0.548536
-0.460558 0.468686 0.507832 -0.55707
-0.716158 -0.488201 0.388209 -0.313164
-0.881074 0.152441 0.380128 -0.236589
-0.885793 0.0386389 0.161009 -0.433537
--0.365162 0.298384 0.292846 0.831784
-0.364934 0.632269 -0.197205 -0.654346
--0.31469 -0.429991 0.665304 -0.522923
--0.734198 0.462914 -0.135691 -0.477756
--0.422885 0.674444 -0.364143 -0.483419
-0.829218 -0.154622 -0.381147 0.378439
-0.887881 0.310479 -0.109528 0.321363
--0.354398 -0.693974 0.456019 -0.429941
--0.492045 -0.160008 0.044387 0.854587
-0.0595532 0.158421 0.412577 -0.895062
--0.211441 0.491794 -0.153521 0.83058
--0.33558 -0.504711 0.353831 -0.71236
--0.735211 -0.197714 0.525626 0.379593
-0.465818 -0.424245 0.769469 -0.104627
--0.641071 -0.286339 -0.704442 -0.103923
--0.00446569 0.0249849 -0.194417 -0.980591
--0.610081 -0.252448 0.176698 -0.729966
--0.0859217 -0.154471 0.715027 0.676382
-0.091315 0.0723382 -0.855023 -0.505337
-0.165362 0.200983 -0.428242 -0.865373
--0.587465 0.303019 -0.152442 0.734729
-0.454946 -0.319828 0.437063 -0.706902
--0.384368 0.277509 0.879225 -0.0470385
-0.523335 -0.330233 -0.208592 0.757335
-0.895086 0.0448492 0.268089 -0.353466
--0.0272491 -0.567336 -0.72254 -0.39411
--0.0745014 -0.121818 -0.882466 0.448179
-0.382304 -0.240135 0.851109 -0.267941
--0.418057 -0.852847 -0.3128 0.00606452
--0.554046 0.304237 0.272381 -0.725453
-0.155115 -0.0894732 -0.245017 -0.952838
-0.114459 -0.130722 0.953669 0.245614
-0.0913002 -0.462466 0.244433 0.847374
--0.198849 0.0785111 0.131441 -0.967997
--0.303154 -0.686484 0.639333 0.167604
-0.521455 0.256835 -0.0584503 -0.811606
--0.109787 0.870544 0.161523 0.451676
diff --git a/src/Alpha_shapes/test/S8_10.off b/src/Alpha_shapes/test/S8_10.off
deleted file mode 100644
index 1d67e10f..00000000
--- a/src/Alpha_shapes/test/S8_10.off
+++ /dev/null
@@ -1,12 +0,0 @@
-OFF
-10 0 0
-0.440036 -0.574754 -0.200485 0.216537 -0.501251 -0.0329236 -0.196529 0.313023
--0.129367 -0.184089 -0.213021 -0.415848 0.783529 -0.0438025 0.317256 0.120749
-0.132429 0.683748 -0.124536 -0.166133 -0.540695 -0.0887576 0.390234 -0.139031
-0.0137399 -0.161581 -0.609142 -0.370872 -0.320669 -0.364053 0.24127 0.41416
--0.115313 -0.36425 0.190208 0.581871 0.204605 0.112527 0.313562 0.571337
-0.168272 -0.0746917 -0.635156 -0.214488 0.629498 -0.0812499 -0.337255 -0.00823068
-0.369896 -0.514626 -0.173493 -0.1551 -0.127105 0.384377 0.303936 -0.536566
--0.49013 -0.0388242 -0.0196532 0.463953 0.515962 -0.0756047 0.506276 0.119908
--0.434258 0.060347 0.388793 0.250579 -0.653127 -0.275207 0.295714 0.0637842
-0.596172 -0.133284 -0.501793 0.234541 0.428452 0.0800735 0.110912 -0.343109
diff --git a/src/Bottleneck/test/bottleneck_unit_test.cpp b/src/Bottleneck/test/bottleneck_unit_test.cpp
index 068b8690..c60f5d8a 100644
--- a/src/Bottleneck/test/bottleneck_unit_test.cpp
+++ b/src/Bottleneck/test/bottleneck_unit_test.cpp
@@ -1,6 +1,6 @@
-#define BOOST_TEST_MODULE bottleneck test
-
-#include <boost/test/included/unit_test.hpp>
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "bottleneck"
+#include <boost/test/unit_test.hpp>
#include "gudhi/Graph_matching.h"
#include <iostream>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 70fc9a45..864ee040 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,11 +1,14 @@
cmake_minimum_required(VERSION 2.6)
project(GUDHI)
+include("CMakeGUDHIVersion.txt")
+
+enable_testing()
+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(Boost REQUIRED COMPONENTS system filesystem program_options chrono timer REQUIRED)
-
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
@@ -19,7 +22,6 @@ set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
-find_package(Boost)
find_package(GMP)
if(GMP_FOUND)
find_package(GMPXX)
@@ -36,22 +38,53 @@ else()
add_definitions(-DBOOST_ALL_NO_LIB)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
- LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
- include_directories(include/)
-
+ LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
+
+ #---------------------------------------------------------------------------------------
+ # Gudhi compilation part
+ include_directories(include)
+
add_subdirectory(example/Simplex_tree)
add_subdirectory(example/Persistent_cohomology)
add_subdirectory(example/Skeleton_blocker)
add_subdirectory(example/Contraction)
add_subdirectory(example/Hasse_complex)
add_subdirectort(example/Witness_complex)
- add_subdirectory(example/Alpha_shapes)
+ # add_subdirectory(example/Alpha_shapes)
add_subdirectory(example/Bottleneck)
+ # data points generator
+ add_subdirectory(data/points/generator)
+
+ # Please let GudhUI in last compilation position as QT is known to modify CMAKE_CXX_FLAGS
# GudhUI
add_subdirectory(GudhUI)
+ #---------------------------------------------------------------------------------------
- # data points generator
- add_subdirectory(data/points/generator)
+ #---------------------------------------------------------------------------------------
+ # GUDHIConfig.cmake
+ # Export the package for use from the build-tree
+ # (this registers the build-tree with a global CMake-registry)
+ export(PACKAGE GUDHI)
+
+ # Create the GUDHIConfig.cmake and GUDHIConfigVersion files
+ set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
+ configure_file(GUDHIConfig.cmake.in "${PROJECT_BINARY_DIR}/GUDHIConfig.cmake" @ONLY)
+ configure_file(GUDHIConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/GUDHIConfigVersion.cmake" @ONLY)
+
+ #---------------------------------------------------------------------------------------
+
+ #---------------------------------------------------------------------------------------
+ # Gudhi installation part
+
+ # Install the GUDHIConfig.cmake and GUDHIConfigVersion.cmake
+ install(FILES
+ "${PROJECT_BINARY_DIR}/GUDHIConfig.cmake"
+ "${PROJECT_BINARY_DIR}/GUDHIConfigVersion.cmake"
+ DESTINATION share/gudhi)
+
+ # install the include file on "make install"
+ install(DIRECTORY include/gudhi DESTINATION include)
+ #---------------------------------------------------------------------------------------
endif()
diff --git a/src/Contraction/example/Garland_heckbert.cpp b/src/Contraction/example/Garland_heckbert.cpp
index a41f65aa..b545a066 100644
--- a/src/Contraction/example/Garland_heckbert.cpp
+++ b/src/Contraction/example/Garland_heckbert.cpp
@@ -1,7 +1,4 @@
-/*
- * Garland_heckbert.h
- * Created on: Feb 10, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* This file is part of the Gudhi Library. The Gudhi library
* (Geometric Understanding in Higher Dimensions) is a generic C++
* library for computational topology.
*
@@ -28,12 +25,13 @@
#ifndef GARLAND_HECKBERT_H_
#define GARLAND_HECKBERT_H_
+#include <gudhi/Point.h>
+#include <gudhi/Edge_contraction.h>
+#include <gudhi/Skeleton_blocker.h>
+#include <gudhi/Off_reader.h>
+
#include <boost/timer/timer.hpp>
#include <iostream>
-#include "gudhi/Point.h"
-#include "gudhi/Edge_contraction.h"
-#include "gudhi/Skeleton_blocker.h"
-#include "gudhi/Off_reader.h"
#include "Garland_heckbert/Error_quadric.h"
@@ -51,7 +49,6 @@ struct Geometry_trait {
*/
struct Garland_heckbert_traits : public Skeleton_blocker_simple_geometric_traits<Geometry_trait> {
public:
-
struct Garland_heckbert_vertex : public Simple_geometric_vertex {
Error_quadric<Geometry_trait::Point> quadric;
};
@@ -68,6 +65,7 @@ typedef Skeleton_blocker_contractor<Complex> Complex_contractor;
*/
class GH_placement : public Gudhi::contraction::Placement_policy<EdgeProfile> {
Complex& complex_;
+
public:
typedef Gudhi::contraction::Placement_policy<EdgeProfile>::Placement_type Placement_type;
@@ -91,8 +89,8 @@ class GH_placement : public Gudhi::contraction::Placement_policy<EdgeProfile> {
*/
class GH_cost : public Gudhi::contraction::Cost_policy<EdgeProfile> {
Complex& complex_;
- public:
+ public:
typedef Gudhi::contraction::Cost_policy<EdgeProfile>::Cost_type Cost_type;
GH_cost(Complex& complex) : complex_(complex) { }
@@ -115,13 +113,13 @@ class GH_cost : public Gudhi::contraction::Cost_policy<EdgeProfile> {
*/
class GH_visitor : public Gudhi::contraction::Contraction_visitor<EdgeProfile> {
Complex& complex_;
- public:
+ public:
GH_visitor(Complex& complex) : complex_(complex) { }
- //Compute quadrics for every vertex v
- //The quadric of v consists in the sum of quadric
- //of every triangles passing through v weighted by its area
+ // Compute quadrics for every vertex v
+ // The quadric of v consists in the sum of quadric
+ // of every triangles passing through v weighted by its area
void on_started(Complex & complex) override {
for (auto v : complex.vertex_range()) {
@@ -147,11 +145,13 @@ class GH_visitor : public Gudhi::contraction::Contraction_visitor<EdgeProfile> {
int main(int argc, char *argv[]) {
if (argc != 4) {
- std::cerr << "Usage " << argv[0] << " input.off output.off N to load the file input.off, contract N edges and save the result to output.off.\n";
+ std::cerr << "Usage " << argv[0] <<
+ " input.off output.off N to load the file input.off, contract N edges and save the result to output.off.\n";
return EXIT_FAILURE;
}
Complex complex;
+ typedef Complex::Vertex_handle Vertex_handle;
// load the points
Skeleton_blocker_off_reader<Complex> off_reader(argv[1], complex);
@@ -160,8 +160,12 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- std::cout << "Load complex with " << complex.num_vertices() << " vertices" << std::endl;
+ if (!complex.empty() && !(complex.point(Vertex_handle(0)).dimension() == 3)) {
+ std::cerr << "Only points of dimension 3 are supported." << std::endl;
+ return EXIT_FAILURE;
+ }
+ std::cout << "Load complex with " << complex.num_vertices() << " vertices" << std::endl;
int num_contractions = atoi(argv[3]);
@@ -172,23 +176,24 @@ int main(int argc, char *argv[]) {
new GH_cost(complex),
new GH_placement(complex),
contraction::make_link_valid_contraction<EdgeProfile>(),
- new GH_visitor(complex)
- );
+ new GH_visitor(complex));
std::cout << "Contract " << num_contractions << " edges" << std::endl;
contractor.contract_edges(num_contractions);
std::cout << "Final complex has " <<
complex.num_vertices() << " vertices, " <<
- complex.num_edges() << " edges and" <<
+ complex.num_edges() << " edges and " <<
complex.num_triangles() << " triangles." << std::endl;
- //write simplified complex
+ // write simplified complex
Skeleton_blocker_off_writer<Complex> off_writer(argv[2], complex);
return EXIT_SUCCESS;
}
+#endif // GARLAND_HECKBERT_H_
+
+
-#endif /* GARLAND_HECKBERT_H_ */
diff --git a/src/Contraction/example/Garland_heckbert/Error_quadric.h b/src/Contraction/example/Garland_heckbert/Error_quadric.h
index 725a3a56..a033aa00 100644
--- a/src/Contraction/example/Garland_heckbert/Error_quadric.h
+++ b/src/Contraction/example/Garland_heckbert/Error_quadric.h
@@ -1,164 +1,182 @@
-/*
- * Error_quadric.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: 24 janv. 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-M�diterran�e (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
#ifndef ERROR_QUADRIC_H_
#define ERROR_QUADRIC_H_
-#include <vector>
-#include <utility>
#include <boost/optional/optional.hpp>
+#include <vector>
+#include <utility>
-template <typename Point> class Error_quadric{
-private :
- double coeff[10];
-
-public :
- Error_quadric(){
- clear();
- }
-
- /**
- * Quadric corresponding to the L2 distance to the plane.
- *
- * According to the notation of Garland Heckbert, they
- * denote a quadric symetric matrix as :
- * Q = [ q11 q12 q13 q14]
- * [ q12 q22 q23 q24]
- * [ q13 q23 q33 q34]
- * [ q14 q24 q34 q44]
- *
- * which is represented by a vector with 10 elts that
- * are denoted ci for clarity with :
- * Q = [ c0 c1 c2 c3 ]
- * [ c1 c4 c5 c6 ]
- * [ c2 c5 c7 c8 ]
- * [ c3 c6 c8 c9 ]
- *
- * The constructor return the quadrics that represents
- * the squared distance to the plane defined by triangle p0,p1,p2
- * times the area of triangle p0,p1,p2.
- */
- Error_quadric(const Point & p0,const Point & p1,const Point & p2){
-
- Point normal(unit_normal(p0,p1,p2));
- double a=normal[0];
- double b=normal[1];
- double c=normal[2];
- double d= -a*p0[0]-b*p0[1]-c*p0[2];
- coeff[0] = a*a ;
- coeff[1] = a*b ;
- coeff[2] = a*c ;
- coeff[3] = a*d ;
- coeff[4] = b*b ;
- coeff[5] = b*c ;
- coeff[6] = b*d ;
- coeff[7] = c*c ;
- coeff[8] = c*d ;
- coeff[9] = d*d ;
-
- double area_p0p1p2 = std::sqrt(squared_area(p0,p1,p2));
- for(auto& x : coeff)
- x*= area_p0p1p2;
- }
-
-
- inline double squared_area(const Point& p0,const Point& p1,const Point& p2) {
- //if (x1,x2,x3) = p1-p0 and (y1,y2,y3) = p2-p0
- //then the squared area is = (u^2+v^2+w^2)/4
- //with: u = x2 * y3 - x3 * y2;
- // v = x3 * y1 - x1 * y3;
- // w = x1 * y2 - x2 * y1;
- Point p0p1(p1-p0);
- Point p0p2(p2-p0);
- double A = p0p1[1] * p0p2[2] - p0p1[2] * p0p2[1];
- double B = p0p1[2] * p0p2[0] - p0p1[0] * p0p2[2];
- double C = p0p1[0] * p0p2[1] - p0p1[1] * p0p2[0];
- return 1./4. * (A*A+B*B+C*C);
- }
-
-
- void clear(){
- for(auto& x:coeff)
- x=0;
- }
-
- Error_quadric& operator+=(const Error_quadric& other){
- if(this!=&other)
- for(int i = 0 ; i < 10; ++i)
- coeff[i] += other.coeff[i];
- return *this;
- }
-
- /**
- * @return The quadric quost defined by the scalar product v^T Q v where Q is the quadratic form of Garland/Heckbert
- */
- inline double cost(const Point& point) const{
- double cost =
- coeff[0]*point.x()*point.x()+coeff[4]*point.y()*point.y()+coeff[7]*point.z()*point.z()
- +2*(coeff[1]*point.x()*point.y()+coeff[5]*point.y()*point.z()+coeff[2]*point.z()*point.x())
- +2*(coeff[3]*point.x()+coeff[6]*point.y()+coeff[8]*point.z())
- +coeff[9];
- if(cost<0) return 0;
- else {
- return cost;
- }
- }
-
- inline double grad_determinant() const{
- return
- coeff[0] * coeff[4] * coeff[7]
- - coeff[0] * coeff[5] * coeff[5]
- - coeff[1] * coeff[1] * coeff[7]
- +2*coeff[1] * coeff[5] * coeff[2]
- - coeff[4] * coeff[2] * coeff[2];
- }
-
- /**
- * Return the point such that it minimizes the gradient of the quadric.
- * Det must be passed with the determinant value of the gradient (should be non zero).
- */
- inline Point solve_linear_gradient(double det = grad_determinant()) const{
- return Point({
- (-coeff[1]*coeff[5]*coeff[8]+coeff[1]*coeff[7]*coeff[6]+coeff[2]*coeff[8]*coeff[4]-coeff[2]*coeff[5]*coeff[6]-coeff[3]*coeff[4]*coeff[7]+coeff[3]*coeff[5]*coeff[5])/ det,
- (coeff[0]*coeff[5]*coeff[8]-coeff[0]*coeff[7]*coeff[6]-coeff[5]*coeff[2]*coeff[3]-coeff[1]*coeff[2]*coeff[8]+coeff[6]*coeff[2]*coeff[2]+coeff[1]*coeff[3]*coeff[7])/det,
- (-coeff[8]*coeff[0]*coeff[4]+coeff[8]*coeff[1]*coeff[1]+coeff[2]*coeff[3]*coeff[4]+coeff[5]*coeff[0]*coeff[6]-coeff[5]*coeff[1]*coeff[3]-coeff[1]*coeff[2]*coeff[6])/det
- });
- }
-
-
- /**
- * returns the point that minimizes the quadric.
- * It inverses the quadric if its determinant is higher that a given threshold .
- * If the determinant is lower than this value the returned value is uninitialized.
- */
- boost::optional<Point> min_cost(double scale=1) const{
- // const double min_determinant = 1e-4 * scale*scale;
- const double min_determinant = 1e-5;
- boost::optional<Point> pt_res;
- double det = grad_determinant();
- if (std::abs(det)>min_determinant)
- pt_res = solve_linear_gradient(det);
- return pt_res;
- }
-
- friend std::ostream& operator<< (std::ostream& stream, const Error_quadric& quadric) {
- stream << "\n[ "<<quadric.coeff[0]<<","<<quadric.coeff[1]<<","<<quadric.coeff[2]<<","<<quadric.coeff[3]<<";\n";
- stream << " "<<quadric.coeff[1]<<","<<quadric.coeff[4]<<","<<quadric.coeff[5]<<","<<quadric.coeff[6]<<";\n";
- stream << " "<<quadric.coeff[2]<<","<<quadric.coeff[5]<<","<<quadric.coeff[7]<<","<<quadric.coeff[8]<<";\n";
- stream << " "<<quadric.coeff[3]<<","<<quadric.coeff[6]<<","<<quadric.coeff[8]<<","<<quadric.coeff[9]<<"]";
- return stream;
- }
-
-
+template <typename Point> class Error_quadric {
+ private:
+ double coeff[10];
+
+ public:
+ Error_quadric() {
+ clear();
+ }
+
+ /**
+ * Quadric corresponding to the L2 distance to the plane.
+ *
+ * According to the notation of Garland Heckbert, they
+ * denote a quadric symetric matrix as :
+ * Q = [ q11 q12 q13 q14]
+ * [ q12 q22 q23 q24]
+ * [ q13 q23 q33 q34]
+ * [ q14 q24 q34 q44]
+ *
+ * which is represented by a vector with 10 elts that
+ * are denoted ci for clarity with :
+ * Q = [ c0 c1 c2 c3 ]
+ * [ c1 c4 c5 c6 ]
+ * [ c2 c5 c7 c8 ]
+ * [ c3 c6 c8 c9 ]
+ *
+ * The constructor return the quadrics that represents
+ * the squared distance to the plane defined by triangle p0,p1,p2
+ * times the area of triangle p0,p1,p2.
+ */
+ Error_quadric(const Point & p0, const Point & p1, const Point & p2) {
+ Point normal(unit_normal(p0, p1, p2));
+ double a = normal[0];
+ double b = normal[1];
+ double c = normal[2];
+ double d = -a * p0[0] - b * p0[1] - c * p0[2];
+ coeff[0] = a*a;
+ coeff[1] = a*b;
+ coeff[2] = a*c;
+ coeff[3] = a*d;
+ coeff[4] = b*b;
+ coeff[5] = b*c;
+ coeff[6] = b*d;
+ coeff[7] = c*c;
+ coeff[8] = c*d;
+ coeff[9] = d*d;
+
+ double area_p0p1p2 = std::sqrt(squared_area(p0, p1, p2));
+ for (auto& x : coeff)
+ x *= area_p0p1p2;
+ }
+
+ inline double squared_area(const Point& p0, const Point& p1, const Point& p2) {
+ // if (x1,x2,x3) = p1-p0 and (y1,y2,y3) = p2-p0
+ // then the squared area is = (u^2+v^2+w^2)/4
+ // with: u = x2 * y3 - x3 * y2;
+ // v = x3 * y1 - x1 * y3;
+ // w = x1 * y2 - x2 * y1;
+ Point p0p1(p1 - p0);
+ Point p0p2(p2 - p0);
+ double A = p0p1[1] * p0p2[2] - p0p1[2] * p0p2[1];
+ double B = p0p1[2] * p0p2[0] - p0p1[0] * p0p2[2];
+ double C = p0p1[0] * p0p2[1] - p0p1[1] * p0p2[0];
+ return 1. / 4. * (A * A + B * B + C * C);
+ }
+
+ void clear() {
+ for (auto& x : coeff)
+ x = 0;
+ }
+
+ Error_quadric& operator+=(const Error_quadric& other) {
+ if (this != &other) {
+ for (int i = 0; i < 10; ++i)
+ coeff[i] += other.coeff[i];
+ }
+ return *this;
+ }
+
+ /**
+ * @return The quadric quost defined by the scalar product v^T Q v where Q is the quadratic form of Garland/Heckbert
+ */
+ inline double cost(const Point& point) const {
+ double cost =
+ coeff[0] * point.x() * point.x() + coeff[4] * point.y() * point.y() + coeff[7] * point.z() * point.z()
+ + 2 * (coeff[1] * point.x() * point.y() + coeff[5] * point.y() * point.z() + coeff[2] * point.z() * point.x())
+ + 2 * (coeff[3] * point.x() + coeff[6] * point.y() + coeff[8] * point.z())
+ + coeff[9];
+ if (cost < 0) {
+ return 0;
+ } else {
+ return cost;
+ }
+ }
+
+ inline double grad_determinant() const {
+ return
+ coeff[0] * coeff[4] * coeff[7]
+ - coeff[0] * coeff[5] * coeff[5]
+ - coeff[1] * coeff[1] * coeff[7]
+ + 2 * coeff[1] * coeff[5] * coeff[2]
+ - coeff[4] * coeff[2] * coeff[2];
+ }
+
+ /**
+ * Return the point such that it minimizes the gradient of the quadric.
+ * Det must be passed with the determinant value of the gradient (should be non zero).
+ */
+ inline Point solve_linear_gradient(double det) const {
+ return Point({
+ (-coeff[1] * coeff[5] * coeff[8] + coeff[1] * coeff[7] * coeff[6] + coeff[2] * coeff[8] * coeff[4] -
+ coeff[2] * coeff[5] * coeff[6] - coeff[3] * coeff[4] * coeff[7] + coeff[3] * coeff[5] * coeff[5])
+ / det,
+ (coeff[0] * coeff[5] * coeff[8] - coeff[0] * coeff[7] * coeff[6] - coeff[5] * coeff[2] * coeff[3] -
+ coeff[1] * coeff[2] * coeff[8] + coeff[6] * coeff[2] * coeff[2] + coeff[1] * coeff[3] * coeff[7])
+ / det,
+ (-coeff[8] * coeff[0] * coeff[4] + coeff[8] * coeff[1] * coeff[1] + coeff[2] * coeff[3] * coeff[4] +
+ coeff[5] * coeff[0] * coeff[6] - coeff[5] * coeff[1] * coeff[3] - coeff[1] * coeff[2] * coeff[6])
+ / det
+ });
+ }
+
+ /**
+ * returns the point that minimizes the quadric.
+ * It inverses the quadric if its determinant is higher that a given threshold .
+ * If the determinant is lower than this value the returned value is uninitialized.
+ */
+ boost::optional<Point> min_cost(double scale = 1) const {
+ // const double min_determinant = 1e-4 * scale*scale;
+ const double min_determinant = 1e-5;
+ boost::optional<Point> pt_res;
+ double det = grad_determinant();
+ if (std::abs(det) > min_determinant)
+ pt_res = solve_linear_gradient(det);
+ return pt_res;
+ }
+
+ friend std::ostream& operator<<(std::ostream& stream, const Error_quadric& quadric) {
+ stream << "\n[ " << quadric.coeff[0] << "," << quadric.coeff[1] << "," << quadric.coeff[2] << "," <<
+ quadric.coeff[3] << ";\n";
+ stream << " " << quadric.coeff[1] << "," << quadric.coeff[4] << "," << quadric.coeff[5] << "," <<
+ quadric.coeff[6] << ";\n";
+ stream << " " << quadric.coeff[2] << "," << quadric.coeff[5] << "," << quadric.coeff[7] << "," <<
+ quadric.coeff[8] << ";\n";
+ stream << " " << quadric.coeff[3] << "," << quadric.coeff[6] << "," << quadric.coeff[8] << "," <<
+ quadric.coeff[9] << "]";
+ return stream;
+ }
};
-
-
-
-#endif /* ERROR_QUADRIC_H_ */
-
+#endif // ERROR_QUADRIC_H_
diff --git a/src/Contraction/example/Rips_contraction.cpp b/src/Contraction/example/Rips_contraction.cpp
index bd0a8b8c..f80cc2dc 100644
--- a/src/Contraction/example/Rips_contraction.cpp
+++ b/src/Contraction/example/Rips_contraction.cpp
@@ -19,24 +19,23 @@
* 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/Edge_contraction.h>
+#include <gudhi/Skeleton_blocker.h>
+#include <gudhi/Off_reader.h>
+#include <gudhi/Point.h>
+
#include <boost/timer/timer.hpp>
#include <iostream>
-#include "gudhi/Edge_contraction.h"
-#include "gudhi/Skeleton_blocker.h"
-#include "gudhi/Off_reader.h"
-#include "gudhi/Point.h"
using namespace std;
using namespace Gudhi;
using namespace skbl;
using namespace contraction;
-
-struct Geometry_trait{
- typedef Point_d Point;
+struct Geometry_trait {
+ typedef Point_d Point;
};
-
typedef Geometry_trait::Point Point;
typedef Skeleton_blocker_simple_geometric_traits<Geometry_trait> Complex_geometric_traits;
typedef Skeleton_blocker_geometric_complex< Complex_geometric_traits > Complex;
@@ -44,62 +43,62 @@ typedef Edge_profile<Complex> Profile;
typedef Skeleton_blocker_contractor<Complex> Complex_contractor;
template<typename ComplexType>
-void build_rips(ComplexType& complex, double offset){
- if (offset<=0) return;
- auto vertices = complex.vertex_range();
- for (auto p = vertices.begin(); p != vertices.end(); ++p)
- for (auto q = p; ++q != vertices.end(); /**/){
- if ( squared_dist(complex.point(*p), complex.point(*q)) < 4 * offset * offset)
- complex.add_edge(*p,*q);
- }
+void build_rips(ComplexType& complex, double offset) {
+ if (offset <= 0) return;
+ auto vertices = complex.vertex_range();
+ for (auto p = vertices.begin(); p != vertices.end(); ++p)
+ for (auto q = p; ++q != vertices.end(); /**/) {
+ if (squared_dist(complex.point(*p), complex.point(*q)) < 4 * offset * offset)
+ complex.add_edge_without_blockers(*p, *q);
+ }
}
-int main (int argc, char *argv[])
-{
- if (argc!=3){
- std::cerr << "Usage "<<argv[0]<<" ../../../data/meshes/SO3_10000.off 0.3 to load the file ../../data/SO3_10000.off and contract the Rips complex built with paremeter 0.3.\n";
- return -1;
- }
+int main(int argc, char *argv[]) {
+ if (argc != 3) {
+ std::cerr << "Usage " << argv[0] << " ../../../data/meshes/SO3_10000.off 0.3 to load the file " <<
+ "../../data/SO3_10000.off and contract the Rips complex built with paremeter 0.3.\n";
+ return -1;
+ }
- Complex complex;
+ Complex complex;
- // load only the points
- Skeleton_blocker_off_reader<Complex> off_reader(argv[1],complex,true);
- if(!off_reader.is_valid()){
- std::cerr << "Unable to read file:"<<argv[1]<<std::endl;
- return EXIT_FAILURE;
- }
+ // load only the points
+ Skeleton_blocker_off_reader<Complex> off_reader(argv[1], complex, true);
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file:" << argv[1] << std::endl;
+ return EXIT_FAILURE;
+ }
- std::cout << "Build the Rips complex with "<<complex.num_vertices()<<" vertices"<<std::endl;
+ std::cout << "Build the Rips complex with " << complex.num_vertices() << " vertices" << std::endl;
- build_rips(complex,atof(argv[2]));
+ build_rips(complex, atof(argv[2]));
- boost::timer::auto_cpu_timer t;
+ boost::timer::auto_cpu_timer t;
- std::cout << "Initial complex has "<<
- complex.num_vertices()<<" vertices and "<<
- complex.num_edges()<<" edges"<<std::endl;
+ std::cout << "Initial complex has " <<
+ complex.num_vertices() << " vertices and " <<
+ complex.num_edges() << " edges" << std::endl;
- Complex_contractor contractor(complex,
- new Edge_length_cost<Profile>,
- contraction::make_first_vertex_placement<Profile>(),
- contraction::make_link_valid_contraction<Profile>(),
- contraction::make_remove_popable_blockers_visitor<Profile>());
- contractor.contract_edges();
+ Complex_contractor contractor(complex,
+ new Edge_length_cost<Profile>,
+ contraction::make_first_vertex_placement<Profile>(),
+ contraction::make_link_valid_contraction<Profile>(),
+ contraction::make_remove_popable_blockers_visitor<Profile>());
+ contractor.contract_edges();
- std::cout << "Counting final number of simplices \n";
- unsigned num_simplices = std::distance(complex.simplex_range().begin(),complex.simplex_range().end());
+ std::cout << "Counting final number of simplices \n";
+ unsigned num_simplices = std::distance(complex.complex_simplex_range().begin(), complex.complex_simplex_range().end());
- std::cout << "Final complex has "<<
- complex.num_vertices()<<" vertices, "<<
- complex.num_edges()<<" edges, "<<
- complex.num_blockers()<<" blockers and "<<
- num_simplices<<" simplices"<<std::endl;
+ std::cout << "Final complex has " <<
+ complex.num_vertices() << " vertices, " <<
+ complex.num_edges() << " edges, " <<
+ complex.num_blockers() << " blockers and " <<
+ num_simplices << " simplices" << std::endl;
- std::cout << "Time to simplify and enumerate simplices:\n";
+ std::cout << "Time to simplify and enumerate simplices:\n";
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
diff --git a/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h b/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h
index 10b89e13..5a55c513 100644
--- a/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h
+++ b/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h
@@ -16,76 +16,86 @@
//
// Author(s) : Fernando Cacciola <fernando.cacciola@geometryfactory.com>
//
-#ifndef CGAL_MODIFIABLE_PRIORITY_QUEUE_H
-#define CGAL_MODIFIABLE_PRIORITY_QUEUE_H
+#ifndef CONTRACTION_CGAL_QUEUE_MODIFIABLE_PRIORITY_QUEUE_H_
+#define CONTRACTION_CGAL_QUEUE_MODIFIABLE_PRIORITY_QUEUE_H_
#define CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP
-#include <climits> // Neeeded by the following Boost header for CHAR_BIT.
#include <boost/optional.hpp>
#include <boost/pending/relaxed_heap.hpp>
-namespace CGAL {
+#include <climits> // Neeeded by the following Boost header for CHAR_BIT.
+#include <functional> // for less
-template <class IndexedType_
- ,class Compare_ = std::less<IndexedType_>
- ,class ID_ = boost::identity_property_map
- >
-class Modifiable_priority_queue
-{
-public:
+namespace CGAL {
+template <class IndexedType_, class Compare_ = std::less<IndexedType_>, class ID_ = boost::identity_property_map>
+class Modifiable_priority_queue {
+ public:
typedef Modifiable_priority_queue Self;
-
- typedef IndexedType_ IndexedType ;
- typedef Compare_ Compare;
- typedef ID_ ID ;
-
- typedef boost::relaxed_heap<IndexedType,Compare,ID> Heap;
+
+ typedef IndexedType_ IndexedType;
+ typedef Compare_ Compare;
+ typedef ID_ ID;
+
+ typedef boost::relaxed_heap<IndexedType, Compare, ID> Heap;
typedef typename Heap::value_type value_type;
- typedef typename Heap::size_type size_type;
-
- typedef bool handle ;
-
-public:
-
- Modifiable_priority_queue( size_type largest_ID, Compare const& c, ID const& id ) : mHeap(largest_ID,c,id) {}
-
- handle push ( value_type const& v ) { mHeap.push(v) ; return handle(true) ; }
-
- handle update ( value_type const& v, handle h ) { mHeap.update(v); return h ; }
-
- handle erase ( value_type const& v, handle ) { mHeap.remove(v); return null_handle() ; }
-
- value_type top() const { return mHeap.top() ; }
-
- void pop() { mHeap.pop(); }
-
- bool empty() const { return mHeap.empty() ; }
-
- bool contains ( value_type const& v ) { return mHeap.contains(v) ; }
-
- boost::optional<value_type> extract_top()
- {
- boost::optional<value_type> r ;
- if ( !empty() )
- {
+ typedef typename Heap::size_type size_type;
+
+ typedef bool handle;
+
+ public:
+ Modifiable_priority_queue(size_type largest_ID, Compare const& c, ID const& id) : mHeap(largest_ID, c, id) { }
+
+ handle push(value_type const& v) {
+ mHeap.push(v);
+ return handle(true);
+ }
+
+ handle update(value_type const& v, handle h) {
+ mHeap.update(v);
+ return h;
+ }
+
+ handle erase(value_type const& v, handle) {
+ mHeap.remove(v);
+ return null_handle();
+ }
+
+ value_type top() const {
+ return mHeap.top();
+ }
+
+ void pop() {
+ mHeap.pop();
+ }
+
+ bool empty() const {
+ return mHeap.empty();
+ }
+
+ bool contains(value_type const& v) {
+ return mHeap.contains(v);
+ }
+
+ boost::optional<value_type> extract_top() {
+ boost::optional<value_type> r;
+ if (!empty()) {
value_type v = top();
pop();
- r = boost::optional<value_type>(v) ;
- }
- return r ;
+ r = boost::optional<value_type>(v);
+ }
+ return r;
+ }
+
+ static handle null_handle() {
+ return handle(false);
}
-
- static handle null_handle() { return handle(false); }
-
-private:
- Heap mHeap ;
-
-} ;
+ private:
+ Heap mHeap;
+};
-} //namespace CGAL
+} // namespace CGAL
-#endif
-
+#endif // CONTRACTION_CGAL_QUEUE_MODIFIABLE_PRIORITY_QUEUE_H_
diff --git a/src/Contraction/include/gudhi/Contraction/Edge_profile.h b/src/Contraction/include/gudhi/Contraction/Edge_profile.h
index f90bd71a..e4910b27 100644
--- a/src/Contraction/include/gudhi/Contraction/Edge_profile.h
+++ b/src/Contraction/include/gudhi/Contraction/Edge_profile.h
@@ -1,130 +1,130 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_EDGE_PROFILE_H_
-#define GUDHI_EDGE_PROFILE_H_
-//#include "combinatorics/Skeleton_blocker/Simplex.h"
-
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_EDGE_PROFILE_H_
+#define CONTRACTION_EDGE_PROFILE_H_
+
+#include <ostream>
+
+namespace Gudhi {
namespace contraction {
-template<typename GeometricSimplifiableComplex> class Edge_profile{
-public:
- typedef GeometricSimplifiableComplex Complex;
- typedef typename Complex::GT GT;
+template<typename GeometricSimplifiableComplex> class Edge_profile {
+ public:
+ typedef GeometricSimplifiableComplex Complex;
+ typedef typename Complex::GT GT;
- typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle;
- typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle;
+ typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle;
+ typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle;
- typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle;
- typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex;
- typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge;
- typedef typename GeometricSimplifiableComplex::Point Point;
+ typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle;
+ typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex;
+ typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge;
+ typedef typename GeometricSimplifiableComplex::Point Point;
+ Edge_profile(GeometricSimplifiableComplex& complex, Edge_handle edge) : complex_(complex), edge_handle_(edge),
+ v0_(complex_.first_vertex(edge_handle_)), v1_(complex_.second_vertex(edge_handle_)) {
+ assert(complex_.get_address(complex_[edge_handle_].first()));
+ assert(complex_.get_address(complex_[edge_handle_].second()));
+ assert(complex_.contains_edge(v0_handle(), v1_handle()));
+ assert(v0_handle() != v1_handle());
+ }
+ virtual ~Edge_profile() { }
+ GeometricSimplifiableComplex& complex() const {
+ return complex_;
+ }
- Edge_profile( GeometricSimplifiableComplex& complex,Edge_handle edge):complex_(complex),edge_handle_(edge),
- v0_(complex_.first_vertex(edge_handle_)),v1_(complex_.second_vertex(edge_handle_))
-{
- assert(complex_.get_address(complex_[edge_handle_].first()));
- assert(complex_.get_address(complex_[edge_handle_].second()));
- assert(complex_.contains_edge(v0_handle(),v1_handle()));
- assert(v0_handle() != v1_handle());
-}
+ Edge_handle edge_handle() const {
+ return edge_handle_;
+ }
- virtual ~Edge_profile(){ }
+ Graph_edge& edge() const {
+ return complex_[edge_handle_];
+ }
+ Graph_vertex& v0() const {
+ return complex_[v0_handle()];
+ }
- GeometricSimplifiableComplex& complex() const {
- return complex_;
- }
+ Graph_vertex& v1() const {
+ return complex_[v1_handle()];
+ }
- Edge_handle edge_handle() const{
- return edge_handle_;
- }
+ Vertex_handle v0_handle() const {
+ return v0_;
+ // Root_vertex_handle root = complex_[edge_handle_].first();
+ // assert(complex_.get_address(root));
+ // return *complex_.get_address(root);
+ }
- Graph_edge& edge() const{
- return complex_[edge_handle_];
- }
+ Vertex_handle v1_handle() const {
+ return v1_;
+ // Root_vertex_handle root = complex_[edge_handle_].second();
+ // assert(complex_.get_address(root));
+ // return *complex_.get_address(root);
+ }
+ const Point& p0() const {
+ return complex_.point(v0_handle());
+ }
- Graph_vertex& v0() const{return complex_[v0_handle()];}
- Graph_vertex& v1() const{return complex_[v1_handle()];}
+ const Point& p1() const {
+ return complex_.point(v1_handle());
+ }
+ friend std::ostream& operator<<(std::ostream& o, const Edge_profile& v) {
+ return o << "v0:" << v.v0_handle() << " v1:" << v.v1_handle();
+ }
- Vertex_handle v0_handle() const{
- return v0_;
-// Root_vertex_handle root = complex_[edge_handle_].first();
-// assert(complex_.get_address(root));
-// return *complex_.get_address(root);
- }
+ private:
+ GeometricSimplifiableComplex& complex_;
- Vertex_handle v1_handle() const{
- return v1_;
-// Root_vertex_handle root = complex_[edge_handle_].second();
-// assert(complex_.get_address(root));
-// return *complex_.get_address(root);
- }
+ Edge_handle edge_handle_;
- const Point& p0() const {return complex_.point(v0_handle());}
+ Vertex_handle v0_;
- const Point& p1() const {return complex_.point(v1_handle());}
-
- friend std::ostream& operator << (std::ostream& o, const Edge_profile & v){
- o << "v0:"<<v.v0_handle() << " v1:"<<v.v1_handle();
- return o;
- }
-private:
-
- GeometricSimplifiableComplex& complex_;
-
- Edge_handle edge_handle_;
-
- Vertex_handle v0_;
+ Vertex_handle v1_;
+};
- Vertex_handle v1_;
+template<typename EdgeProfile> class Edge_profile_factory {
+ public:
+ typedef typename EdgeProfile::Edge_handle Edge_handle_;
+ typedef typename EdgeProfile::Complex Complex_;
-};
+ virtual EdgeProfile make_profile(
+ Complex_& complex,
+ Edge_handle_ edge) const {
+ return EdgeProfile(complex, edge);
+ }
-template<typename EdgeProfile> class Edge_profile_factory{
-public:
- typedef typename EdgeProfile::Edge_handle Edge_handle_;
- typedef typename EdgeProfile::Complex Complex_;
- virtual EdgeProfile make_profile(
- Complex_& complex,
- Edge_handle_ edge) const{
- return EdgeProfile(complex,edge);
- }
-
- virtual ~Edge_profile_factory(){};
+ virtual ~Edge_profile_factory() { }
};
-
} // namespace contraction
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_EDGE_PROFILE_H_ */
+#endif // CONTRACTION_EDGE_PROFILE_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Contraction_visitor.h b/src/Contraction/include/gudhi/Contraction/policies/Contraction_visitor.h
index b8b1e87a..7ee05aad 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Contraction_visitor.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Contraction_visitor.h
@@ -1,32 +1,32 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_CONTRACTION_VISITOR_H_
-#define GUDHI_CONTRACTION_VISITOR_H_
-
-#include "gudhi/Contraction/Edge_profile.h"
-#include "boost/optional.hpp"
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_CONTRACTION_VISITOR_H_
+#define CONTRACTION_POLICIES_CONTRACTION_VISITOR_H_
+
+#include <gudhi/Contraction/Edge_profile.h>
+#include <boost/optional.hpp>
+
+namespace Gudhi {
namespace contraction {
@@ -36,66 +36,56 @@ namespace contraction {
*@ingroup contr
*/
template <typename EdgeProfile>
-class Contraction_visitor {//: public Dummy_complex_visitor<typename EdgeProfile::Vertex_handle> {
-public:
- //typedef typename ComplexType::GeometryTrait GT;
- typedef EdgeProfile Profile;
- typedef double FT;
- typedef typename Profile::Complex Complex;
- typedef Complex ComplexType;
- typedef typename ComplexType::Point Point;
-
-
- virtual ~Contraction_visitor(){};
-
- /**
- * @brief Called before the edge contraction process starts.
- */
- virtual void on_started (ComplexType & complex){}
-
- /**
- * @brief Called when the algorithm stops.
- */
- virtual void on_stop_condition_reached (){}
-
-
- /**
- * @brief Called during the collecting phase (when a cost is assigned to the edges), for each edge collected.
- */
- virtual void on_collected (const Profile &profile, boost::optional< FT > cost){}
-
- /**
- * @brief Called during the processing phase (when edges are contracted), for each edge that is selected.
- */
- virtual void on_selected (const Profile &profile, boost::optional< FT > cost, int initial_count, int current_count){}
-
-
- /**
- * @brief Called when an edge is about to be contracted and replaced by a vertex whose position is *placement.
- */
- virtual void on_contracting(const Profile &profile, boost::optional< Point > placement){
- }
-
-
-
- /**
- * @brief Called when after an edge has been contracted onto a new point placement.
- * A possibility would to remove popable blockers at this point for instance.
- */
- virtual void on_contracted(const Profile &profile, boost::optional< Point > placement){
-
- }
-
-
- /**
- * @brief Called for each selected edge which cannot be contracted because the ValidContractionPredicate is false
- */
- virtual void on_non_valid(const Profile &profile){}
-
+class Contraction_visitor { // : public Dummy_complex_visitor<typename EdgeProfile::Vertex_handle> {
+ public:
+ // typedef typename ComplexType::GeometryTrait GT;
+ typedef EdgeProfile Profile;
+ typedef double FT;
+ typedef typename Profile::Complex Complex;
+ typedef Complex ComplexType;
+ typedef typename ComplexType::Point Point;
+
+ virtual ~Contraction_visitor() { }
+
+ /**
+ * @brief Called before the edge contraction process starts.
+ */
+ virtual void on_started(ComplexType & complex) { }
+
+ /**
+ * @brief Called when the algorithm stops.
+ */
+ virtual void on_stop_condition_reached() { }
+
+ /**
+ * @brief Called during the collecting phase (when a cost is assigned to the edges), for each edge collected.
+ */
+ virtual void on_collected(const Profile &profile, boost::optional< FT > cost) { }
+
+ /**
+ * @brief Called during the processing phase (when edges are contracted), for each edge that is selected.
+ */
+ virtual void on_selected(const Profile &profile, boost::optional< FT > cost, int initial_count, int current_count) { }
+
+ /**
+ * @brief Called when an edge is about to be contracted and replaced by a vertex whose position is *placement.
+ */
+ virtual void on_contracting(const Profile &profile, boost::optional< Point > placement) { }
+
+ /**
+ * @brief Called when after an edge has been contracted onto a new point placement.
+ * A possibility would to remove popable blockers at this point for instance.
+ */
+ virtual void on_contracted(const Profile &profile, boost::optional< Point > placement) { }
+
+ /**
+ * @brief Called for each selected edge which cannot be contracted because the ValidContractionPredicate is false
+ */
+ virtual void on_non_valid(const Profile &profile) { }
};
} // namespace contraction
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_CONTRACTION_VISITOR_H_ */
+#endif // CONTRACTION_POLICIES_CONTRACTION_VISITOR_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h b/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h
index 3cb18c86..f4d343ec 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h
@@ -1,51 +1,53 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_COST_POLICY_H_
-#define GUDHI_COST_POLICY_H_
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_COST_POLICY_H_
+#define CONTRACTION_POLICIES_COST_POLICY_H_
#include <boost/optional.hpp>
-namespace Gudhi{
+namespace Gudhi {
namespace contraction {
/**
-*@brief Policy to specify the cost of contracting an edge.
+ *@brief Policy to specify the cost of contracting an edge.
*@ingroup contr
-*/
-template< typename EdgeProfile> class Cost_policy{
-public:
- typedef typename EdgeProfile::Point Point;
- typedef typename EdgeProfile::Graph_vertex Graph_vertex;
+ */
+template< typename EdgeProfile>
+class Cost_policy {
+ public:
+ typedef typename EdgeProfile::Point Point;
+ typedef typename EdgeProfile::Graph_vertex Graph_vertex;
- typedef boost::optional<double> Cost_type;
+ typedef boost::optional<double> Cost_type;
- virtual Cost_type operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const =0;
- virtual ~Cost_policy(){
- };
+ virtual Cost_type operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const = 0;
+
+ virtual ~Cost_policy() { }
};
} // namespace contraction
-} // namespace GUDHI
-#endif /* GUDHI_COST_POLICY_H_ */
+} // namespace Gudhi
+
+#endif // CONTRACTION_POLICIES_COST_POLICY_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h b/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h
index de473944..5d329496 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h
@@ -1,51 +1,49 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_DUMMY_VALID_CONTRACTION_H_
-#define GUDHI_DUMMY_VALID_CONTRACTION_H_
-
-#include "Valid_contraction_policy.h"
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_DUMMY_VALID_CONTRACTION_H_
+#define CONTRACTION_POLICIES_DUMMY_VALID_CONTRACTION_H_
+
+#include <gudhi/Contraction/policies/Valid_contraction_policy.h>
+
+namespace Gudhi {
namespace contraction {
-
-
- /**
- *@brief Policy that accept all edge contraction.
- */
-template< typename EdgeProfile> class Dummy_valid_contraction : public Valid_contraction_policy<EdgeProfile>{
-public:
- typedef typename EdgeProfile::Point Point;
- bool operator()(const EdgeProfile& profile,const boost::optional<Point>& placement){
- return true;
- }
+/**
+ *@brief Policy that accept all edge contraction.
+ */
+template< typename EdgeProfile>
+class Dummy_valid_contraction : public Valid_contraction_policy<EdgeProfile> {
+ public:
+ typedef typename EdgeProfile::Point Point;
+
+ bool operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) {
+ return true;
+ }
};
} // namespace contraction
-} // namespace GUDHI
-
-
+} // namespace Gudhi
-#endif /* GUDHI_DUMMY_VALID_CONTRACTION_H_ */
+#endif // CONTRACTION_POLICIES_DUMMY_VALID_CONTRACTION_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Edge_length_cost.h b/src/Contraction/include/gudhi/Contraction/policies/Edge_length_cost.h
index b22ada0d..dac2d448 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Edge_length_cost.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Edge_length_cost.h
@@ -1,56 +1,56 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_EDGE_LENGTH_COST_H_
-#define GUDHI_EDGE_LENGTH_COST_H_
-
-#include "Cost_policy.h"
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
+ */
-namespace contraction {
+#ifndef CONTRACTION_POLICIES_EDGE_LENGTH_COST_H_
+#define CONTRACTION_POLICIES_EDGE_LENGTH_COST_H_
+
+#include <gudhi/Contraction/policies/Cost_policy.h>
+namespace Gudhi {
+
+namespace contraction {
/**
* @brief return a cost corresponding to the squared length of the edge
*/
-template< typename EdgeProfile> class Edge_length_cost : public Cost_policy<EdgeProfile>{
-public:
- typedef typename Cost_policy<EdgeProfile>::Cost_type Cost_type;
- typedef typename EdgeProfile::Point Point;
- Cost_type operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const override{
- double res = 0;
- auto p0_coord = profile.p0().begin();
- auto p1_coord = profile.p1().begin();
- for(; p0_coord != profile.p0().end(); p0_coord++, p1_coord++){
- res += (*p0_coord - *p1_coord) * (*p0_coord - *p1_coord);
- }
- return res;
- }
-
+template< typename EdgeProfile>
+class Edge_length_cost : public Cost_policy<EdgeProfile> {
+ public:
+ typedef typename Cost_policy<EdgeProfile>::Cost_type Cost_type;
+ typedef typename EdgeProfile::Point Point;
+
+ Cost_type operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const override {
+ double res = 0;
+ auto p0_coord = profile.p0().begin();
+ auto p1_coord = profile.p1().begin();
+ for (; p0_coord != profile.p0().end(); p0_coord++, p1_coord++) {
+ res += (*p0_coord - *p1_coord) * (*p0_coord - *p1_coord);
+ }
+ return res;
+ }
};
} // namespace contraction
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_EDGE_LENGTH_COST_H_ */
+#endif // CONTRACTION_POLICIES_EDGE_LENGTH_COST_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/First_vertex_placement.h b/src/Contraction/include/gudhi/Contraction/policies/First_vertex_placement.h
index 93abac35..1f68db0d 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/First_vertex_placement.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/First_vertex_placement.h
@@ -1,53 +1,52 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_FIRST_VERTEX_PLACEMENT_H_
-#define GUDHI_FIRST_VERTEX_PLACEMENT_H_
-
-#include "Placement_policy.h"
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
+ */
-namespace contraction {
+#ifndef CONTRACTION_POLICIES_FIRST_VERTEX_PLACEMENT_H_
+#define CONTRACTION_POLICIES_FIRST_VERTEX_PLACEMENT_H_
+
+#include <gudhi/Contraction/policies/Placement_policy.h>
+
+namespace Gudhi {
+namespace contraction {
/**
* @brief Places the contracted point onto the first point of the edge
*/
-template< typename EdgeProfile> class First_vertex_placement : public Placement_policy<EdgeProfile>{
-
-public:
- typedef typename EdgeProfile::Point Point;
- typedef typename EdgeProfile::Edge_handle Edge_handle;
+template< typename EdgeProfile>
+class First_vertex_placement : public Placement_policy<EdgeProfile> {
+ public:
+ typedef typename EdgeProfile::Point Point;
+ typedef typename EdgeProfile::Edge_handle Edge_handle;
- typedef typename Placement_policy<EdgeProfile>::Placement_type Placement_type;
+ typedef typename Placement_policy<EdgeProfile>::Placement_type Placement_type;
- Placement_type operator()(const EdgeProfile& profile) const override{
- return Placement_type(profile.p0());
- }
+ Placement_type operator()(const EdgeProfile& profile) const override {
+ return Placement_type(profile.p0());
+ }
};
-} // namespace contraction
-} // namespace GUDHI
+} // namespace contraction
+} // namespace Gudhi
-#endif /* GUDHI_FIRST_VERTEX_PLACEMENT_H_ */
+#endif // CONTRACTION_POLICIES_FIRST_VERTEX_PLACEMENT_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h b/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h
index c901e629..919df243 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h
@@ -1,54 +1,56 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_LINK_CONDITION_VALID_CONTRACTION_H_
-#define GUDHI_LINK_CONDITION_VALID_CONTRACTION_H_
-
-#include "gudhi/Utils.h"
-#include "Valid_contraction_policy.h"
-
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_LINK_CONDITION_VALID_CONTRACTION_H_
+#define CONTRACTION_POLICIES_LINK_CONDITION_VALID_CONTRACTION_H_
+
+#include <gudhi/Utils.h>
+#include <gudhi/Contraction/policies/Valid_contraction_policy.h>
+
+
+namespace Gudhi {
namespace contraction {
-
- /**
- *@brief Policy that only accept edges verifying the link condition (and therefore whose contraction preserving homotopy type).
- *@ingroup contr
- */
-template< typename EdgeProfile> class Link_condition_valid_contraction : public Valid_contraction_policy<EdgeProfile>{
-public:
- typedef typename EdgeProfile::Edge_handle Edge_handle;
- typedef typename EdgeProfile::Point Point;
- //typedef typename EdgeProfile::Edge_handle Edge_handle;
- bool operator()(const EdgeProfile& profile,const boost::optional<Point>& placement) const override{
- Edge_handle edge(profile.edge_handle());
- DBGMSG("Link_condition_valid_contraction:",profile.complex().link_condition(edge));
- return profile.complex().link_condition(edge);
- }
+/**
+ *@brief Policy that only accept edges verifying the link condition (and therefore whose contraction preserving homotopy type).
+ *@ingroup contr
+ */
+template< typename EdgeProfile>
+class Link_condition_valid_contraction : public Valid_contraction_policy<EdgeProfile> {
+ public:
+ typedef typename EdgeProfile::Edge_handle Edge_handle;
+ typedef typename EdgeProfile::Point Point;
+ // typedef typename EdgeProfile::Edge_handle Edge_handle;
+
+ bool operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const override {
+ Edge_handle edge(profile.edge_handle());
+ DBGMSG("Link_condition_valid_contraction:", profile.complex().link_condition(edge));
+ return profile.complex().link_condition(edge);
+ }
};
+
} // namespace contraction
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_LINK_CONDITION_VALID_CONTRACTION_H_ */
+#endif // CONTRACTION_POLICIES_LINK_CONDITION_VALID_CONTRACTION_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h b/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h
index 30f0a570..4b59f1b5 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h
@@ -1,52 +1,51 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_MIDDLE_PLACEMENT_H_
-#define GUDHI_MIDDLE_PLACEMENT_H_
-
-#include "Placement_policy.h"
-
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_MIDDLE_PLACEMENT_H_
+#define CONTRACTION_POLICIES_MIDDLE_PLACEMENT_H_
+
+#include <gudhi/Contraction/policies/Placement_policy.h>
+
+namespace Gudhi {
namespace contraction {
+template< typename EdgeProfile>
+class Middle_placement : public Placement_policy<EdgeProfile> {
+ public:
+ typedef typename EdgeProfile::Point Point;
+ typedef typename EdgeProfile::Edge_handle Edge_handle;
+ typedef typename EdgeProfile::Graph_vertex Graph_vertex;
-
-template< typename EdgeProfile> class Middle_placement : public Placement_policy<EdgeProfile>{
+ typedef typename Placement_policy<EdgeProfile>::Placement_type Placement_type;
-public:
- typedef typename EdgeProfile::Point Point;
- typedef typename EdgeProfile::Edge_handle Edge_handle;
- typedef typename EdgeProfile::Graph_vertex Graph_vertex;
-
- typedef typename Placement_policy<EdgeProfile>::Placement_type Placement_type;
-
- Placement_type operator()(const EdgeProfile& profile) const override{
- //todo compute the middle
- return Placement_type(profile.p0());
- }
+ Placement_type operator()(const EdgeProfile& profile) const override {
+ // todo compute the middle
+ return Placement_type(profile.p0());
+ }
};
+
} // namespace contraction
-} // namespace GUDHI
-#endif /* GUDHI_MIDDLE_PLACEMENT_H_ */
+} // namespace Gudhi
+
+#endif // CONTRACTION_POLICIES_MIDDLE_PLACEMENT_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h b/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h
index 3a804cf0..34ffa49f 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h
@@ -1,49 +1,51 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_PLACEMENT_POLICY_H_
-#define GUDHI_PLACEMENT_POLICY_H_
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_PLACEMENT_POLICY_H_
+#define CONTRACTION_POLICIES_PLACEMENT_POLICY_H_
#include <boost/optional.hpp>
namespace Gudhi {
+
namespace contraction {
+/**
+ *@brief Policy to specify where the merged point had to be placed after an edge contraction.
+ *@ingroup contr
+ */
+template< typename EdgeProfile>
+class Placement_policy {
+ public:
+ typedef typename EdgeProfile::Point Point;
+ typedef boost::optional<Point> Placement_type;
- /**
- *@brief Policy to specify where the merged point had to be placed after an edge contraction.
- *@ingroup contr
- */
-template< typename EdgeProfile> class Placement_policy{
-public:
- typedef typename EdgeProfile::Point Point;
- typedef boost::optional<Point> Placement_type;
+ virtual Placement_type operator()(const EdgeProfile& profile) const = 0;
- virtual Placement_type operator()(const EdgeProfile& profile) const=0;
- virtual ~Placement_policy(){};
+ virtual ~Placement_policy() { }
};
-
} // namespace contraction
-} // namespace GUDHI
-#endif /* GUDHI_PLACEMENT_POLICY_H_ */
+} // namespace Gudhi
+
+#endif // CONTRACTION_POLICIES_PLACEMENT_POLICY_H_
diff --git a/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h b/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h
index bee2ecd7..78d61173 100644
--- a/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h
+++ b/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h
@@ -1,47 +1,51 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_VALID_CONTRACTION_POLICY_H_
-#define GUDHI_VALID_CONTRACTION_POLICY_H_
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CONTRACTION_POLICIES_VALID_CONTRACTION_POLICY_H_
+#define CONTRACTION_POLICIES_VALID_CONTRACTION_POLICY_H_
namespace Gudhi {
+
namespace contraction {
- /**
- *@brief Policy to specify if an edge contraction is valid or not.
- *@ingroup contr
- */
-template< typename EdgeProfile> class Valid_contraction_policy{
-public:
- typedef typename EdgeProfile::Point Point;
- typedef typename EdgeProfile::Edge_handle Edge_handle;
- typedef typename EdgeProfile::Graph_vertex Graph_vertex;
-
- virtual bool operator()(const EdgeProfile& profile,const boost::optional<Point>& placement) const =0;
- virtual ~Valid_contraction_policy(){};
+/**
+ *@brief Policy to specify if an edge contraction is valid or not.
+ *@ingroup contr
+ */
+template< typename EdgeProfile>
+class Valid_contraction_policy {
+ public:
+ typedef typename EdgeProfile::Point Point;
+ typedef typename EdgeProfile::Edge_handle Edge_handle;
+ typedef typename EdgeProfile::Graph_vertex Graph_vertex;
+
+ virtual bool operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const = 0;
+
+ virtual ~Valid_contraction_policy() { }
};
} // namespace contraction
-} // namespace GUDHI
+
+} // namespace Gudhi
-#endif /* GUDHI_VALID_CONTRACTION_POLICY_H_ */
+#endif // CONTRACTION_POLICIES_VALID_CONTRACTION_POLICY_H_
diff --git a/src/Contraction/include/gudhi/Edge_contraction.h b/src/Contraction/include/gudhi/Edge_contraction.h
index 2c254710..ee3e3de1 100644
--- a/src/Contraction/include/gudhi/Edge_contraction.h
+++ b/src/Contraction/include/gudhi/Edge_contraction.h
@@ -20,24 +20,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef GUDHI_EDGE_CONTRACTION_H_
-#define GUDHI_EDGE_CONTRACTION_H_
+#ifndef EDGE_CONTRACTION_H_
+#define EDGE_CONTRACTION_H_
-#include "gudhi/Skeleton_blocker_contractor.h"
-#include "gudhi/Contraction/policies/Edge_length_cost.h"
-#include "gudhi/Contraction/policies/First_vertex_placement.h"
-#include "gudhi/Contraction/policies/Valid_contraction_policy.h"
-#include "gudhi/Contraction/policies/Dummy_valid_contraction.h"
-#include "gudhi/Contraction/policies/Link_condition_valid_contraction.h"
-#include "gudhi/Utils.h"
+#include <gudhi/Skeleton_blocker_contractor.h>
+#include <gudhi/Contraction/policies/Edge_length_cost.h>
+#include <gudhi/Contraction/policies/First_vertex_placement.h>
+#include <gudhi/Contraction/policies/Valid_contraction_policy.h>
+#include <gudhi/Contraction/policies/Dummy_valid_contraction.h>
+#include <gudhi/Contraction/policies/Link_condition_valid_contraction.h>
+#include <gudhi/Utils.h>
+namespace Gudhi {
-namespace Gudhi{
-namespace contraction{
+namespace contraction {
-/** \defgroup contr Contraction
+/** \defgroup contr Edge contraction
\author David Salinas
@@ -120,9 +120,9 @@ while ensuring its homotopy type is preserved during the contraction (edge are c
\code{.cpp}
#include <boost/timer/timer.hpp>
#include <iostream>
-#include "gudhi/Edge_contraction.h"
-#include "gudhi/Skeleton_blocker.h"
-#include "gudhi/Off_reader.h"
+#include <gudhi/Edge_contraction.h>
+#include <gudhi/Skeleton_blocker.h>
+#include <gudhi/Off_reader.h>
using namespace std;
@@ -158,7 +158,7 @@ void build_rips(ComplexType& complex, double offset){
for (auto p = vertices.begin(); p != vertices.end(); ++p)
for (auto q = p; ++q != vertices.end(); )
if (eucl_distance(complex.point(*p), complex.point(*q)) < 2 * offset)
- complex.add_edge(*p,*q);
+ complex.add_edge_without_blockers(*p,*q);
}
int main (int argc, char *argv[])
@@ -194,7 +194,7 @@ int main (int argc, char *argv[])
contractor.contract_edges();
std::cout << "Counting final number of simplices \n";
- unsigned num_simplices = std::distance(complex.simplex_range().begin(),complex.simplex_range().end());
+ unsigned num_simplices = std::distance(complex.star_simplex_range().begin(),complex.star_simplex_range().end());
std::cout << "Final complex has "<<
complex.num_vertices()<<" vertices, "<<
@@ -226,11 +226,11 @@ Time to simplify and enumerate simplices:
\copyright GNU General Public License v3.
-\verbatim Contact: David Salinas, david.salinas@inria.fr \endverbatim
+\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
-/** @} */ // end defgroup
+/** @} */ // end defgroup
+} // namespace contraction
-}
-}
+} // namespace Gudhi
-#endif /* GUDHI_EDGE_CONTRACTION_H_ */
+#endif // EDGE_CONTRACTION_H_
diff --git a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h
index dcc05c22..d6350a2c 100644
--- a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h
+++ b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h
@@ -20,80 +20,69 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef GUDHI_SKELETON_BLOCKER_CONTRACTOR_H_
-#define GUDHI_SKELETON_BLOCKER_CONTRACTOR_H_
-
-#include <memory>
-#include <cassert>
+#ifndef SKELETON_BLOCKER_CONTRACTOR_H_
+#define SKELETON_BLOCKER_CONTRACTOR_H_
// todo remove the queue to be independent from cgald
-#include "gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h"
-
-
-#include <list>
-#include <boost/scoped_array.hpp>
-#include <boost/scoped_ptr.hpp>
-
+#include <gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h>
-#include "gudhi/Contraction/Edge_profile.h"
-#include "gudhi/Contraction/policies/Cost_policy.h"
-#include "gudhi/Contraction/policies/Edge_length_cost.h"
-#include "gudhi/Contraction/policies/Placement_policy.h"
-#include "gudhi/Contraction/policies/First_vertex_placement.h"
+#include <gudhi/Contraction/Edge_profile.h>
+#include <gudhi/Contraction/policies/Cost_policy.h>
+#include <gudhi/Contraction/policies/Edge_length_cost.h>
+#include <gudhi/Contraction/policies/Placement_policy.h>
+#include <gudhi/Contraction/policies/First_vertex_placement.h>
+#include <gudhi/Contraction/policies/Valid_contraction_policy.h>
+#include <gudhi/Contraction/policies/Dummy_valid_contraction.h> // xxx remove
+#include <gudhi/Contraction/policies/Link_condition_valid_contraction.h> // xxx remove
+#include <gudhi/Contraction/policies/Contraction_visitor.h>
-#include "gudhi/Contraction/policies/Valid_contraction_policy.h"
-#include "gudhi/Contraction/policies/Dummy_valid_contraction.h" //xxx remove
-#include "gudhi/Contraction/policies/Link_condition_valid_contraction.h" //xxx remove
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h>
+#include <gudhi/Utils.h>
-#include "gudhi/Contraction/policies/Contraction_visitor.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h"
+#include <boost/scoped_array.hpp>
+#include <boost/scoped_ptr.hpp>
-#include "gudhi/Utils.h"
+#include <memory>
+#include <cassert>
+#include <list>
+#include <utility> // for pair
+#include <vector>
-namespace Gudhi{
+namespace Gudhi {
namespace contraction {
-
-
-
template <class Profile>
-Placement_policy<Profile>* make_first_vertex_placement(){
- return new First_vertex_placement<Profile>();
+Placement_policy<Profile>* make_first_vertex_placement() {
+ return new First_vertex_placement<Profile>();
}
template <class Profile>
-Valid_contraction_policy<Profile>* make_link_valid_contraction(){
- return new Link_condition_valid_contraction<Profile>();
+Valid_contraction_policy<Profile>* make_link_valid_contraction() {
+ return new Link_condition_valid_contraction<Profile>();
}
-
/**
-*@brief Visitor to remove popable blockers after an edge contraction.
-*/
+ *@brief Visitor to remove popable blockers after an edge contraction.
+ */
template <class Profile>
-class Contraction_visitor_remove_popable : public Contraction_visitor<Profile>{
-public:
- typedef typename Profile::Point Point;
- typedef typename Profile::Complex Complex;
- typedef typename Complex::Vertex_handle Vertex_handle;
-
- void on_contracted(const Profile &profile, boost::optional< Point > placement) override{
- profile.complex().remove_all_popable_blockers(profile.v0_handle());
- }
+class Contraction_visitor_remove_popable : public Contraction_visitor<Profile> {
+ public:
+ typedef typename Profile::Point Point;
+ typedef typename Profile::Complex Complex;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+
+ void on_contracted(const Profile &profile, boost::optional< Point > placement) override {
+ profile.complex().remove_all_popable_blockers(profile.v0_handle());
+ }
};
template <class Profile>
-Contraction_visitor<Profile>* make_remove_popable_blockers_visitor(){
- return new Contraction_visitor_remove_popable<Profile>();
+Contraction_visitor<Profile>* make_remove_popable_blockers_visitor() {
+ return new Contraction_visitor_remove_popable<Profile>();
}
-
-
-
-
-
/**
*@class Skeleton_blocker_contractor
*@brief Class that allows to contract iteratively edges of a simplicial complex.
@@ -110,519 +99,484 @@ Contraction_visitor<Profile>* make_remove_popable_blockers_visitor(){
* a topological condition (link condition) or a geometrical condition (normals messed up).
*
*/
-template<
-class GeometricSimplifiableComplex,
-class EdgeProfile = Edge_profile<GeometricSimplifiableComplex>
->
-class Skeleton_blocker_contractor : private skbl::Dummy_complex_visitor<typename GeometricSimplifiableComplex::Vertex_handle>{
-
- GeometricSimplifiableComplex& complex_;
-
-public:
- typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex;
- typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle;
- typedef typename GeometricSimplifiableComplex::Simplex_handle Simplex_handle;
- typedef typename GeometricSimplifiableComplex::Simplex_handle_iterator Simplex_handle_iterator;
-
-
+template<class GeometricSimplifiableComplex, class EdgeProfile = Edge_profile<GeometricSimplifiableComplex>>
+class Skeleton_blocker_contractor : private skbl::Dummy_complex_visitor<
+typename GeometricSimplifiableComplex::Vertex_handle> {
+ GeometricSimplifiableComplex& complex_;
- typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle;
+ public:
+ typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex;
+ typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle;
+ typedef typename GeometricSimplifiableComplex::Simplex Simplex;
+ typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle;
+ typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge;
+ typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle;
+ typedef typename GeometricSimplifiableComplex::Point Point;
- typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge;
- typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle;
- typedef typename GeometricSimplifiableComplex::Point Point;
+ typedef EdgeProfile Profile;
- typedef EdgeProfile Profile;
+ typedef Cost_policy<Profile> Cost_policy_;
+ typedef Placement_policy<Profile> Placement_policy_;
+ typedef Valid_contraction_policy<Profile> Valid_contraction_policy_;
+ typedef Contraction_visitor<EdgeProfile> Contraction_visitor_;
+ typedef Edge_profile_factory<EdgeProfile> Edge_profile_factory_;
- typedef Cost_policy<Profile> Cost_policy_;
- typedef Placement_policy<Profile> Placement_policy_;
- typedef Valid_contraction_policy<Profile> Valid_contraction_policy_;
- typedef Contraction_visitor<EdgeProfile> Contraction_visitor_;
- typedef Edge_profile_factory<EdgeProfile> Edge_profile_factory_;
+ typedef boost::optional<double> Cost_type;
+ typedef boost::optional<Point> Placement_type;
- typedef boost::optional<double> Cost_type;
- typedef boost::optional<Point> Placement_type ;
+ typedef size_t size_type;
- typedef size_t size_type;
+ typedef Skeleton_blocker_contractor Self;
- typedef Skeleton_blocker_contractor Self ;
+ private:
+ struct Compare_id {
+ Compare_id() : algorithm_(0) { }
+ Compare_id(Self const* aAlgorithm) : algorithm_(aAlgorithm) { }
+ bool operator()(Edge_handle a, Edge_handle b) const {
+ return algorithm_->get_undirected_edge_id(a) < algorithm_->get_undirected_edge_id(b);
+ }
-private:
+ Self const* algorithm_;
+ };
- struct Compare_id
- {
- Compare_id() : algorithm_(0) {}
+ struct Compare_cost {
+ Compare_cost() : algorithm_(0) { }
- Compare_id( Self const* aAlgorithm ) : algorithm_(aAlgorithm) {}
+ Compare_cost(Self const* aAlgorithm) : algorithm_(aAlgorithm) { }
- bool operator() ( Edge_handle a, Edge_handle b ) const
- {
- return algorithm_->get_undirected_edge_id(a) < algorithm_->get_undirected_edge_id(b);
- }
+ bool operator()(Edge_handle a, Edge_handle b) const {
+ // NOTE: A cost is an optional<> value.
+ // Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none.
+ // In consequence, edges with undefined costs will be promoted to the top of the priority queue and popped out
+ // first.
+ return algorithm_->get_data(a).cost() < algorithm_->get_data(b).cost();
+ }
- Self const* algorithm_ ;
- } ;
+ Self const* algorithm_;
+ };
- struct Compare_cost
- {
- Compare_cost() : algorithm_(0) {
- }
+ struct Undirected_edge_id : boost::put_get_helper<size_type, Undirected_edge_id> {
+ typedef boost::readable_property_map_tag category;
+ typedef size_type value_type;
+ typedef size_type reference;
+ typedef Edge_handle key_type;
- Compare_cost( Self const* aAlgorithm ) : algorithm_(aAlgorithm) {
- }
+ Undirected_edge_id() : algorithm_(0) { }
- bool operator() ( Edge_handle a, Edge_handle b ) const
- {
- // NOTE: A cost is an optional<> value.
- // Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none.
- // In consequence, edges with undefined costs will be promoted to the top of the priority queue and poped out first.
- return algorithm_->get_data(a).cost() < algorithm_->get_data(b).cost();
- }
+ Undirected_edge_id(Self const* aAlgorithm) : algorithm_(aAlgorithm) { }
- Self const* algorithm_ ;
+ size_type operator[](Edge_handle e) const {
+ return algorithm_->get_undirected_edge_id(e);
+ }
- } ;
+ Self const* algorithm_;
+ };
+
+ typedef CGAL::Modifiable_priority_queue<Edge_handle, Compare_cost, Undirected_edge_id> PQ;
+ typedef typename PQ::handle pq_handle;
+
+
+ // An Edge_data is associated with EVERY edge in the complex (collapsible or not).
+ // It relates the edge with the PQ-handle needed to update the priority queue
+ // It also relates the edge with a policy-based cache
- struct Undirected_edge_id : boost::put_get_helper<size_type, Undirected_edge_id>
- {
- typedef boost::readable_property_map_tag category;
- typedef size_type value_type;
- typedef size_type reference;
- typedef Edge_handle key_type;
+ class Edge_data {
+ public:
+ Edge_data() : PQHandle_(), cost_() { }
- Undirected_edge_id() : algorithm_(0) {}
+ Cost_type const& cost() const {
+ return cost_;
+ }
+
+ Cost_type & cost() {
+ return cost_;
+ }
+
+ pq_handle PQ_handle() const {
+ return PQHandle_;
+ }
+
+ bool is_in_PQ() const {
+ return PQHandle_ != PQ::null_handle();
+ }
+
+ void set_PQ_handle(pq_handle h) {
+ PQHandle_ = h;
+ }
- Undirected_edge_id( Self const* aAlgorithm ) : algorithm_(aAlgorithm) {}
-
- size_type operator[] ( Edge_handle e ) const { return algorithm_->get_undirected_edge_id(e); }
-
- Self const* algorithm_ ;
- } ;
-
- typedef CGAL::Modifiable_priority_queue<Edge_handle,Compare_cost,Undirected_edge_id> PQ ;
- typedef typename PQ::handle pq_handle ;
-
-
- // An Edge_data is associated with EVERY edge in the complex (collapsible or not).
- // It relates the edge with the PQ-handle needed to update the priority queue
- // It also relates the edge with a policy-based cache
- class Edge_data
- {
- public :
-
- Edge_data() : PQHandle_(),cost_() {}
-
- Cost_type const& cost() const { return cost_ ; }
- Cost_type & cost() { return cost_ ; }
-
- pq_handle PQ_handle() const { return PQHandle_ ;}
-
- bool is_in_PQ() const { return PQHandle_ != PQ::null_handle() ; }
-
- void set_PQ_handle( pq_handle h ) { PQHandle_ = h ; }
-
- void reset_PQ_handle() { PQHandle_ = PQ::null_handle() ; }
-
- private:
- pq_handle PQHandle_ ;
- Cost_type cost_ ;
-
- } ;
- typedef Edge_data* Edge_data_ptr ;
- typedef boost::scoped_array<Edge_data> Edge_data_array ;
-
-
- int get_undirected_edge_id ( Edge_handle edge ) const {
- return complex_[edge].index() ;
- }
-
-
- const Edge_data& get_data ( Edge_handle edge ) const
- {
- return edge_data_array_[get_undirected_edge_id(edge)];
- }
-
-
- Edge_data& get_data ( Edge_handle edge )
- {
- return edge_data_array_[get_undirected_edge_id(edge)];
- }
-
- Cost_type get_cost(const Profile & profile) const{
- return (*cost_policy_)(profile,get_placement(profile));
- }
-
- Profile create_profile(Edge_handle edge) const{
- if(edge_profile_factory_)
- return edge_profile_factory_->make_profile(complex_,edge);
- else
- return Profile(complex_,edge);
- }
-
-
- void insert_in_PQ( Edge_handle edge, Edge_data& data )
- {
- data.set_PQ_handle(heap_PQ_->push(edge));
- ++current_num_edges_heap_;
- }
-
- void update_in_PQ( Edge_handle edge, Edge_data& data )
- {
- data.set_PQ_handle(heap_PQ_->update(edge,data.PQ_handle())) ;
- }
-
- void remove_from_PQ( Edge_handle edge, Edge_data& data )
- {
- data.set_PQ_handle(heap_PQ_->erase(edge,data.PQ_handle()));
- --current_num_edges_heap_;
- }
-
- boost::optional<Edge_handle> pop_from_PQ() {
- boost::optional<Edge_handle> edge = heap_PQ_->extract_top();
- if ( edge )
- get_data(*edge).reset_PQ_handle();
- return edge ;
- }
-
-
-
-private:
-
- /**
- * @brief Collect edges.
- *
- * Iterates over all edges of the simplicial complex and
- * 1) inserts them in the priority queue sorted according to the Cost policy.
- * 2) set the id() field of each edge
- */
- void collect_edges(){
- //
- // Loop over all the edges in the complex in the heap
- //
- size_type size = complex_.num_edges();
- DBG("Collecting edges ...");
- DBGMSG("num edges :",size);
-
- edge_data_array_.reset( new Edge_data[size] ) ;
-
- heap_PQ_.reset( new PQ (size, Compare_cost(this), Undirected_edge_id(this) ) ) ;
-
- std::size_t id = 0 ;
-
- //xxx do a parralel for
- for(auto edge : complex_.edge_range()){
- complex_[edge].index() = id++;
- Profile const& profile = create_profile(edge);
- Edge_data& data = get_data(edge);
- data.cost() = get_cost(profile) ;
- ++initial_num_edges_heap_;
- insert_in_PQ(edge,data);
- if(contraction_visitor_) contraction_visitor_->on_collected(profile,data.cost());
- }
-
- DBG("Edges collected.");
-
- }
-
- bool should_stop(double lCost,const Profile &profile) const{
- return false;
- }
-
- boost::optional<Point> get_placement(const Profile& profile) const{
- return (*placement_policy_)(profile);
- }
-
- bool is_contraction_valid( Profile const& profile, Placement_type placement ) const{
- if(!valid_contraction_policy_) return true;
- return (*valid_contraction_policy_)(profile,placement);
- }
-
-
-public:
- /**
- * \brief Contract edges.
- *
- * While the heap is not empty, it extracts the edge with the minimum
- * cost in the heap then try to contract it.
- * It stops when the Stop policy says so or when the number of contractions
- * given by 'num_max_contractions' is reached (if this number is positive).
- */
- void contract_edges(int num_max_contractions=-1){
-
- DBG("\n\nContract edges");
- int num_contraction = 0 ;
-
- bool unspecified_num_contractions = (num_max_contractions == -1);
- //
- // Pops and processes each edge from the PQ
- //
- boost::optional<Edge_handle> edge ;
- while ( (edge = pop_from_PQ())&& ((num_contraction<num_max_contractions)||(unspecified_num_contractions)))
- {
- Profile const& profile = create_profile(*edge);
- Cost_type cost(get_data(*edge).cost());
- if(contraction_visitor_) contraction_visitor_->on_selected(profile,cost,0,0);
-
- DBGMSG("\n\n---- Pop edge - num vertices :",complex_.num_vertices());
-
- if (cost){
- DBGMSG("sqrt(cost):",std::sqrt(*cost));
- if (should_stop(*cost,profile) )
- {
- if(contraction_visitor_) contraction_visitor_->on_stop_condition_reached();
- DBG("should_stop");
- break ;
- }
- Placement_type placement = get_placement(profile);
- if ( is_contraction_valid(profile,placement) && placement )
- {
- DBG("contraction_valid");
- contract_edge(profile,placement);
- ++ num_contraction;
- }
- else
- {
- DBG("contraction not valid");
- if(contraction_visitor_) contraction_visitor_->on_non_valid(profile);
- }
- }
- else
- DBG("uncomputable cost");
- }
- if(contraction_visitor_) contraction_visitor_->on_stop_condition_reached();
- }
-
-
- bool is_in_heap(Edge_handle edge) const{
- if(heap_PQ_->empty()) return false;
- else{
- return edge_data_array_[get_undirected_edge_id(edge)].is_in_PQ();
- }
- }
-
- bool is_heap_empty() const{
- return heap_PQ_->empty();
- }
-
-
- /**
- * @brief Returns an Edge_handle and a Placement_type. This pair consists in
- * the edge with the lowest cost in the heap together with its placement.
- * The returned value is initialized iff the heap is non-empty.
- */
- boost::optional<std::pair<Edge_handle,Placement_type > > top_edge(){
- boost::optional<std::pair<Edge_handle,Placement_type > > res;
-
- if(!heap_PQ_->empty()) {
- auto edge = heap_PQ_->top();
- Profile const& profile = create_profile(edge);
- Placement_type placement = get_placement(profile);
- res = make_pair(edge,placement);
- DBGMSG("top edge:",complex_[edge]);
-
- }
- return res;
- }
-
-
- /**
- * @brief Constructor with default policies.
- *
- * @details The default cost, placement, valid and visitor policies
- * are respectively : the edge length, the first point, the link condition
- */
- Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex)
- :complex_(complex),
- cost_policy_(new Edge_length_cost<Profile>),
- placement_policy_(new First_vertex_placement<Profile>),
- valid_contraction_policy_(new Link_condition_valid_contraction<Profile>),
- contraction_visitor_(new Contraction_visitor_()),
- edge_profile_factory_(0),
- initial_num_edges_heap_(0),
- current_num_edges_heap_(0)
- {
- complex_.set_visitor(this);
- if(contraction_visitor_) contraction_visitor_->on_started(complex);
- collect_edges();
- }
-
- /**
- * @brief Constructor with customed policies.
- * @remark Policies destruction is handle by the class with smart pointers.
- */
- Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex,
- Cost_policy_ *cost_policy,
- Placement_policy_ * placement_policy = new First_vertex_placement<Profile>,
- Valid_contraction_policy_ * valid_contraction_policy = new Link_condition_valid_contraction<Profile>,
- Contraction_visitor_* contraction_visitor = new Contraction_visitor_(),
- Edge_profile_factory_* edge_profile_factory = NULL
- ):
- complex_(complex),
- cost_policy_(cost_policy),
- placement_policy_(placement_policy),
- valid_contraction_policy_(valid_contraction_policy),
- contraction_visitor_(contraction_visitor),
- edge_profile_factory_(edge_profile_factory),
- initial_num_edges_heap_(0),
- current_num_edges_heap_(0)
- {
- complex_.set_visitor(this);
- if(contraction_visitor) contraction_visitor->on_started(complex);
- collect_edges();
- }
-
-
- ~Skeleton_blocker_contractor(){
- complex_.set_visitor(0);
- }
-
-private:
-
-
- void contract_edge(const Profile& profile, Placement_type placement ) {
- if(contraction_visitor_) contraction_visitor_->on_contracting(profile,placement);
-
- assert(complex_.contains_vertex(profile.v0_handle()));
- assert(complex_.contains_vertex(profile.v1_handle()));
- assert(placement);
-
- profile.complex().point(profile.v0_handle()) = *placement;
-
- // remark : this is not necessary since v1 will be deactivated
- // profile.complex().point(profile.v1_handle()) = *placement;
-
- complex_.contract_edge(profile.v0_handle(),profile.v1_handle());
-
- assert(complex_.contains_vertex(profile.v0_handle()));
- assert(!complex_.contains_vertex(profile.v1_handle()));
-
- update_changed_edges();
-
- // the visitor could do something as complex_.remove_popable_blockers();
- if(contraction_visitor_) contraction_visitor_->on_contracted(profile,placement);
- }
-
-private:
-
- // every time the visitor's method on_changed_edge is called, it adds an
- // edge to changed_edges_
- std::vector< Edge_handle > changed_edges_;
-
- /**
- * @brief we update the cost and the position in the heap of an edge that has
- * been changed
- */
- inline void on_changed_edge(Vertex_handle a,Vertex_handle b) override{
- boost::optional<Edge_handle> ab(complex_[std::make_pair(a,b)]);
- assert(ab);
- changed_edges_.push_back(*ab);
- }
-
- void update_changed_edges(){
- //xxx do a parralel for
-
- DBG("update edges");
-
- // sequential loop
- for(auto ab : changed_edges_){
- //1-get the Edge_handle corresponding to ab
- //2-change the data in mEdgeArray[ab.id()]
- //3-update the heap
- Edge_data& data = get_data(ab);
- Profile const& profile = create_profile(ab);
- data.cost() = get_cost(profile) ;
- if ( data.is_in_PQ()){
- update_in_PQ(ab,data);
- }
- else{
- insert_in_PQ(ab,data);
- }
- }
- changed_edges_.clear();
- }
-
-
-private:
- void on_remove_edge(Vertex_handle a,Vertex_handle b) override{
-
- boost::optional<Edge_handle> ab((complex_[std::make_pair(a,b)]));
- assert(ab);
- Edge_data& lData = get_data(*ab) ;
- if ( lData.is_in_PQ() )
- {
- remove_from_PQ(*ab,lData) ;
- }
- }
-private:
- /**
- * @brief Called when the edge 'ax' has been added while the edge 'bx'
- * is still there but will be removed on next instruction.
- * We assign the index of 'bx' to the edge index of 'ax'
- */
- void on_swaped_edge(Vertex_handle a,Vertex_handle b,Vertex_handle x) override{
- boost::optional<Edge_handle> ax(complex_[std::make_pair(a,x)]);
- boost::optional<Edge_handle> bx(complex_[std::make_pair(b,x)]);
- assert(ax&& bx);
- complex_[*ax].index() =complex_[*bx].index();
- }
-private:
- /**
- * @brief Called when a blocker is removed.
- * All the edges that passes through the blocker may be edge-contractible
- * again and are thus reinserted in the heap.
- */
- void on_delete_blocker(const Simplex_handle * blocker) override{
- // we go for all pairs xy that belongs to the blocker
- // note that such pairs xy are necessarily edges of the complex
- // by definition of a blocker
-
- // todo uniqument utile pour la link condition
- // laisser ŕ l'utilisateur? booleen update_heap_on_removed_blocker?
- Simplex_handle blocker_copy(*blocker);
- for (auto x = blocker_copy.begin(); x!= blocker_copy.end(); ++x){
- for(auto y=x ; ++y != blocker_copy.end(); ){
- auto edge_descr(complex_[std::make_pair(*x,*y)]);
- assert(edge_descr);
- Edge_data& data = get_data(*edge_descr);
- Profile const& profile = create_profile(*edge_descr);
- data.cost() = get_cost(profile) ;
-
- // If the edge is already in the heap
- // its priority has not changed.
- // If the edge is not present, we reinsert it
- // remark : we could also reinsert the edge
- // only if it is valid
- if ( !data.is_in_PQ() ){
- insert_in_PQ(*edge_descr,data);
- }
- }
- }
- }
-
-
-private:
- std::shared_ptr<Cost_policy_> cost_policy_;
- std::shared_ptr<Placement_policy_> placement_policy_;
- std::shared_ptr<Valid_contraction_policy_> valid_contraction_policy_;
- std::shared_ptr<Contraction_visitor_> contraction_visitor_;
-
- //in case the user wants to do something special when the edge profile
- //are created (for instance add some info)
- std::shared_ptr<Edge_profile_factory_> edge_profile_factory_;
- Edge_data_array edge_data_array_ ;
-
- boost::scoped_ptr<PQ> heap_PQ_ ;
- int initial_num_edges_heap_;
- int current_num_edges_heap_;
+ void reset_PQ_handle() {
+ PQHandle_ = PQ::null_handle();
+ }
+ private:
+ pq_handle PQHandle_;
+ Cost_type cost_;
+ };
+ typedef Edge_data* Edge_data_ptr;
+ typedef boost::scoped_array<Edge_data> Edge_data_array;
+
+ int get_undirected_edge_id(Edge_handle edge) const {
+ return complex_[edge].index();
+ }
+
+ const Edge_data& get_data(Edge_handle edge) const {
+ return edge_data_array_[get_undirected_edge_id(edge)];
+ }
+
+ Edge_data& get_data(Edge_handle edge) {
+ return edge_data_array_[get_undirected_edge_id(edge)];
+ }
+
+ Cost_type get_cost(const Profile & profile) const {
+ return (*cost_policy_)(profile, get_placement(profile));
+ }
+
+ Profile create_profile(Edge_handle edge) const {
+ if (edge_profile_factory_)
+ return edge_profile_factory_->make_profile(complex_, edge);
+ else
+ return Profile(complex_, edge);
+ }
+
+ void insert_in_PQ(Edge_handle edge, Edge_data& data) {
+ data.set_PQ_handle(heap_PQ_->push(edge));
+ ++current_num_edges_heap_;
+ }
+
+ void update_in_PQ(Edge_handle edge, Edge_data& data) {
+ data.set_PQ_handle(heap_PQ_->update(edge, data.PQ_handle()));
+ }
+
+ void remove_from_PQ(Edge_handle edge, Edge_data& data) {
+ data.set_PQ_handle(heap_PQ_->erase(edge, data.PQ_handle()));
+ --current_num_edges_heap_;
+ }
+
+ boost::optional<Edge_handle> pop_from_PQ() {
+ boost::optional<Edge_handle> edge = heap_PQ_->extract_top();
+ if (edge)
+ get_data(*edge).reset_PQ_handle();
+ return edge;
+ }
+
+ private:
+ /**
+ * @brief Collect edges.
+ *
+ * Iterates over all edges of the simplicial complex and
+ * 1) inserts them in the priority queue sorted according to the Cost policy.
+ * 2) set the id() field of each edge
+ */
+ void collect_edges() {
+ //
+ // Loop over all the edges in the complex in the heap
+ //
+ size_type size = complex_.num_edges();
+ DBG("Collecting edges ...");
+ DBGMSG("num edges :", size);
+
+ edge_data_array_.reset(new Edge_data[size]);
+
+ heap_PQ_.reset(new PQ(size, Compare_cost(this), Undirected_edge_id(this)));
+
+ std::size_t id = 0;
+
+ // xxx do a parralel for
+ for (auto edge : complex_.edge_range()) {
+ complex_[edge].index() = id++;
+ Profile const& profile = create_profile(edge);
+ Edge_data& data = get_data(edge);
+ data.cost() = get_cost(profile);
+ ++initial_num_edges_heap_;
+ insert_in_PQ(edge, data);
+ if (contraction_visitor_) contraction_visitor_->on_collected(profile, data.cost());
+ }
+
+ DBG("Edges collected.");
+ }
+
+ bool should_stop(double lCost, const Profile &profile) const {
+ return false;
+ }
+
+ boost::optional<Point> get_placement(const Profile& profile) const {
+ return (*placement_policy_)(profile);
+ }
+
+ bool is_contraction_valid(Profile const& profile, Placement_type placement) const {
+ if (!valid_contraction_policy_) return true;
+ return (*valid_contraction_policy_)(profile, placement);
+ }
+
+
+ public:
+ /**
+ * \brief Contract edges.
+ *
+ * While the heap is not empty, it extracts the edge with the minimum
+ * cost in the heap then try to contract it.
+ * It stops when the Stop policy says so or when the number of contractions
+ * given by 'num_max_contractions' is reached (if this number is positive).
+ */
+ void contract_edges(int num_max_contractions = -1) {
+ DBG("\n\nContract edges");
+ int num_contraction = 0;
+
+ bool unspecified_num_contractions = (num_max_contractions == -1);
+ //
+ // Pops and processes each edge from the PQ
+ //
+ boost::optional<Edge_handle> edge;
+ while ((edge = pop_from_PQ()) && ((num_contraction < num_max_contractions) || (unspecified_num_contractions))) {
+ Profile const& profile = create_profile(*edge);
+ Cost_type cost(get_data(*edge).cost());
+ if (contraction_visitor_) contraction_visitor_->on_selected(profile, cost, 0, 0);
+
+ DBGMSG("\n\n---- Pop edge - num vertices :", complex_.num_vertices());
+
+ if (cost) {
+ DBGMSG("sqrt(cost):", std::sqrt(*cost));
+ if (should_stop(*cost, profile)) {
+ if (contraction_visitor_) contraction_visitor_->on_stop_condition_reached();
+ DBG("should_stop");
+ break;
+ }
+ Placement_type placement = get_placement(profile);
+ if (is_contraction_valid(profile, placement) && placement) {
+ DBG("contraction_valid");
+ contract_edge(profile, placement);
+ ++num_contraction;
+ } else {
+ DBG("contraction not valid");
+ if (contraction_visitor_) contraction_visitor_->on_non_valid(profile);
+ }
+ } else {
+ DBG("uncomputable cost");
+ }
+ }
+ if (contraction_visitor_) contraction_visitor_->on_stop_condition_reached();
+ }
+
+ bool is_in_heap(Edge_handle edge) const {
+ if (heap_PQ_->empty()) {
+ return false;
+ } else {
+ return edge_data_array_[get_undirected_edge_id(edge)].is_in_PQ();
+ }
+ }
+
+ bool is_heap_empty() const {
+ return heap_PQ_->empty();
+ }
+
+ /**
+ * @brief Returns an Edge_handle and a Placement_type. This pair consists in
+ * the edge with the lowest cost in the heap together with its placement.
+ * The returned value is initialized iff the heap is non-empty.
+ */
+ boost::optional<std::pair<Edge_handle, Placement_type > > top_edge() {
+ boost::optional<std::pair<Edge_handle, Placement_type > > res;
+
+ if (!heap_PQ_->empty()) {
+ auto edge = heap_PQ_->top();
+ Profile const& profile = create_profile(edge);
+ Placement_type placement = get_placement(profile);
+ res = std::make_pair(edge, placement);
+ DBGMSG("top edge:", complex_[edge]);
+ }
+ return res;
+ }
+
+ /**
+ * @brief Constructor with default policies.
+ *
+ * @details The default cost, placement, valid and visitor policies
+ * are respectively : the edge length, the first point, the link condition
+ */
+ Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex)
+ : complex_(complex),
+ cost_policy_(new Edge_length_cost<Profile>),
+ placement_policy_(new First_vertex_placement<Profile>),
+ valid_contraction_policy_(new Link_condition_valid_contraction<Profile>),
+ contraction_visitor_(new Contraction_visitor_()),
+ edge_profile_factory_(0),
+ initial_num_edges_heap_(0),
+ current_num_edges_heap_(0) {
+ complex_.set_visitor(this);
+ if (contraction_visitor_) contraction_visitor_->on_started(complex);
+ collect_edges();
+ }
+
+ /**
+ * @brief Constructor with customed policies.
+ * @remark Policies destruction is handle by the class with smart pointers.
+ */
+ Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex,
+ Cost_policy_ *cost_policy,
+ Placement_policy_ * placement_policy = new First_vertex_placement<Profile>,
+ Valid_contraction_policy_ * valid_contraction_policy =
+ new Link_condition_valid_contraction<Profile>,
+ Contraction_visitor_* contraction_visitor = new Contraction_visitor_(),
+ Edge_profile_factory_* edge_profile_factory = NULL) :
+ complex_(complex),
+ cost_policy_(cost_policy),
+ placement_policy_(placement_policy),
+ valid_contraction_policy_(valid_contraction_policy),
+ contraction_visitor_(contraction_visitor),
+ edge_profile_factory_(edge_profile_factory),
+ initial_num_edges_heap_(0),
+ current_num_edges_heap_(0) {
+ complex_.set_visitor(this);
+ if (contraction_visitor) contraction_visitor->on_started(complex);
+ collect_edges();
+ }
+
+ ~Skeleton_blocker_contractor() {
+ complex_.set_visitor(0);
+ }
+
+ private:
+ void contract_edge(const Profile& profile, Placement_type placement) {
+ if (contraction_visitor_) contraction_visitor_->on_contracting(profile, placement);
+
+ assert(complex_.contains_vertex(profile.v0_handle()));
+ assert(complex_.contains_vertex(profile.v1_handle()));
+ assert(placement);
+
+ profile.complex().point(profile.v0_handle()) = *placement;
+
+ // remark : this is not necessary since v1 will be deactivated
+ // profile.complex().point(profile.v1_handle()) = *placement;
+
+ complex_.contract_edge(profile.v0_handle(), profile.v1_handle());
+
+ assert(complex_.contains_vertex(profile.v0_handle()));
+ assert(!complex_.contains_vertex(profile.v1_handle()));
+
+ update_changed_edges();
+
+ // the visitor could do something as complex_.remove_popable_blockers();
+ if (contraction_visitor_) contraction_visitor_->on_contracted(profile, placement);
+ }
+
+ private:
+ // every time the visitor's method on_changed_edge is called, it adds an
+ // edge to changed_edges_
+ std::vector< Edge_handle > changed_edges_;
+
+ /**
+ * @brief we update the cost and the position in the heap of an edge that has
+ * been changed
+ */
+ inline void on_changed_edge(Vertex_handle a, Vertex_handle b) override {
+ boost::optional<Edge_handle> ab(complex_[std::make_pair(a, b)]);
+ assert(ab);
+ changed_edges_.push_back(*ab);
+ }
+
+ void update_changed_edges() {
+ // xxx do a parralel for
+ DBG("update edges");
+
+ // sequential loop
+ for (auto ab : changed_edges_) {
+ // 1-get the Edge_handle corresponding to ab
+ // 2-change the data in mEdgeArray[ab.id()]
+ // 3-update the heap
+ Edge_data& data = get_data(ab);
+ Profile const& profile = create_profile(ab);
+ data.cost() = get_cost(profile);
+ if (data.is_in_PQ()) {
+ update_in_PQ(ab, data);
+ } else {
+ insert_in_PQ(ab, data);
+ }
+ }
+ changed_edges_.clear();
+ }
+
+
+ private:
+ void on_remove_edge(Vertex_handle a, Vertex_handle b) override {
+ boost::optional<Edge_handle> ab((complex_[std::make_pair(a, b)]));
+ assert(ab);
+ Edge_data& lData = get_data(*ab);
+ if (lData.is_in_PQ()) {
+ remove_from_PQ(*ab, lData);
+ }
+ }
+
+ private:
+ /**
+ * @brief Called when the edge 'ax' has been added while the edge 'bx'
+ * is still there but will be removed on next instruction.
+ * We assign the index of 'bx' to the edge index of 'ax'
+ */
+ void on_swaped_edge(Vertex_handle a, Vertex_handle b, Vertex_handle x) override {
+ boost::optional<Edge_handle> ax(complex_[std::make_pair(a, x)]);
+ boost::optional<Edge_handle> bx(complex_[std::make_pair(b, x)]);
+ assert(ax && bx);
+ complex_[*ax].index() = complex_[*bx].index();
+ }
+
+ private:
+ /**
+ * @brief Called when a blocker is removed.
+ * All the edges that passes through the blocker may be edge-contractible
+ * again and are thus reinserted in the heap.
+ */
+ void on_delete_blocker(const Simplex * blocker) override {
+ // we go for all pairs xy that belongs to the blocker
+ // note that such pairs xy are necessarily edges of the complex
+ // by definition of a blocker
+
+ // todo uniqument utile pour la link condition
+ // laisser a l'utilisateur ? booleen update_heap_on_removed_blocker?
+ Simplex blocker_copy(*blocker);
+ for (auto x = blocker_copy.begin(); x != blocker_copy.end(); ++x) {
+ for (auto y = x; ++y != blocker_copy.end();) {
+ auto edge_descr(complex_[std::make_pair(*x, *y)]);
+ assert(edge_descr);
+ Edge_data& data = get_data(*edge_descr);
+ Profile const& profile = create_profile(*edge_descr);
+ data.cost() = get_cost(profile);
+
+ // If the edge is already in the heap
+ // its priority has not changed.
+ // If the edge is not present, we reinsert it
+ // remark : we could also reinsert the edge
+ // only if it is valid
+ if (!data.is_in_PQ()) {
+ insert_in_PQ(*edge_descr, data);
+ }
+ }
+ }
+ }
+
+
+ private:
+ std::shared_ptr<Cost_policy_> cost_policy_;
+ std::shared_ptr<Placement_policy_> placement_policy_;
+ std::shared_ptr<Valid_contraction_policy_> valid_contraction_policy_;
+ std::shared_ptr<Contraction_visitor_> contraction_visitor_;
+
+ // in case the user wants to do something special when the edge profile
+ // are created (for instance add some info)
+ std::shared_ptr<Edge_profile_factory_> edge_profile_factory_;
+ Edge_data_array edge_data_array_;
+
+ boost::scoped_ptr<PQ> heap_PQ_;
+ int initial_num_edges_heap_;
+ int current_num_edges_heap_;
};
} // namespace contraction
-} // namespace GUDHI
-#endif /* GUDHI_SKELETON_BLOCKER_CONTRACTOR_H_ */
+} // namespace Gudhi
+
+#endif // SKELETON_BLOCKER_CONTRACTOR_H_
diff --git a/src/Doxyfile b/src/Doxyfile
index 62412627..faa0d3fe 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 = "1.1.0"
+PROJECT_NUMBER = "1.2.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
@@ -672,7 +672,8 @@ LAYOUT_FILE =
# search path. Do not use file names with spaces, bibtex cannot handle them. See
# also \cite for info how to create references.
-CITE_BIB_FILES = ../biblio/bibliography.bib
+CITE_BIB_FILES = biblio/bibliography.bib \
+ biblio/how_to_cite_gudhi.bib
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
@@ -811,7 +812,7 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include
# command).
-EXAMPLE_PATH =
+EXAMPLE_PATH = biblio/
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -831,9 +832,9 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
-IMAGE_PATH = Skeleton_blocker/doc/ \
- common/doc/ \
- Contraction/doc/
+IMAGE_PATH = doc/Skeleton_blocker/ \
+ doc/common/ \
+ doc/Contraction/
# The INPUT_FILTER tag can be used to specify a program that doxygen should
@@ -1338,7 +1339,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
-DISABLE_INDEX = NO
+DISABLE_INDEX = YES
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
@@ -1355,7 +1356,7 @@ DISABLE_INDEX = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
-GENERATE_TREEVIEW = NO
+GENERATE_TREEVIEW = YES
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
diff --git a/src/GUDHIConfig.cmake.in b/src/GUDHIConfig.cmake.in
new file mode 100644
index 00000000..02b540dc
--- /dev/null
+++ b/src/GUDHIConfig.cmake.in
@@ -0,0 +1,7 @@
+# - Config file for the GUDHI package
+# It defines the following variables
+# GUDHI_INCLUDE_DIRS - include directories for GUDHI
+
+# Compute paths
+set(GUDHI_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
+
diff --git a/src/GUDHIConfigVersion.cmake.in b/src/GUDHIConfigVersion.cmake.in
new file mode 100644
index 00000000..6d443ef6
--- /dev/null
+++ b/src/GUDHIConfigVersion.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@GUDHI_VERSION@")
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt
index ddbae969..71f4fd1a 100644
--- a/src/GudhUI/CMakeLists.txt
+++ b/src/GudhUI/CMakeLists.txt
@@ -5,9 +5,6 @@ find_package(CGAL COMPONENTS Qt4)
find_package(Qt4)
find_package(QGLViewer)
find_package(OpenGL)
-message("CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}")
-message("CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}")
-message("CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}")
if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )
set( QT_USE_QTXML TRUE )
@@ -21,7 +18,23 @@ if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
include(${QT_USE_FILE})
+
include(${CGAL_USE_FILE})
+ # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten.
+ # cf. http://doc.cgal.org/latest/Manual/installation.html#title40
+ # A workaround is to add "-std=c++11" again.
+ # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
+ # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html
+ # but it implies to use cmake version 3.1 at least.
+ if(NOT MSVC)
+ include(CheckCXXCompilerFlag)
+ CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
+ if(COMPILER_SUPPORTS_CXX11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+ endif()
+ # - End of workaround
+
include_directories (${QGLVIEWER_INCLUDE_DIR})
include_directories(.)
@@ -66,5 +79,5 @@ if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )
target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
else()
- message(STATUS "NOTICE: This demo requires CGAL, the QGLViewer, OpenGL and Qt4, and will not be compiled.")
+ message(STATUS "NOTICE: GudhUI requires CGAL, the QGLViewer, OpenGL and Qt4, and will not be compiled.")
endif()
diff --git a/src/GudhUI/gui/MainWindow.cpp b/src/GudhUI/gui/MainWindow.cpp
index e41b15ba..779ccd33 100644
--- a/src/GudhUI/gui/MainWindow.cpp
+++ b/src/GudhUI/gui/MainWindow.cpp
@@ -1,3 +1,25 @@
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 "MainWindow.h"
#include <QWidget>
@@ -6,292 +28,271 @@
#include <fenv.h>
-
#include "gui/Menu_k_nearest_neighbors.h"
#include "gui/Menu_uniform_neighbors.h"
#include "gui/Menu_edge_contraction.h"
#include "gui/Menu_persistence.h"
+MainWindow::MainWindow(QWidget* parent) :
+ menu_k_nearest_neighbors_(new Menu_k_nearest_neighbors(this)),
+ menu_uniform_neighbors_(new Menu_uniform_neighbors(this)),
+ menu_edge_contraction_(new Menu_edge_contraction(this, model_)),
+ menu_persistence_(new Menu_persistence(this)) {
+ // #ifndef NDEBUG // catch nan
+ // feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
+ // #endif
-MainWindow::MainWindow(QWidget* parent):
-menu_k_nearest_neighbors_(new Menu_k_nearest_neighbors(this)),
-menu_uniform_neighbors_(new Menu_uniform_neighbors(this)),
-menu_edge_contraction_(new Menu_edge_contraction(this,model_)),
-menu_persistence_(new Menu_persistence(this))
-{
-//#ifndef NDEBUG // catch nan
-//feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
-//#endif
+ setupUi(this);
- setupUi(this);
+ viewer_instructor_ = new Viewer_instructor(
+ this,
+ this->viewer,
+ model_.complex_);
- viewer_instructor_ = new Viewer_instructor(
- this,
- this->viewer,
- model_.complex_
- );
+ connectActions();
- connectActions();
-
- update_view();
+ update_view();
}
-void
-MainWindow::closeEvent(QCloseEvent *event){
- exit(0);
+void
+MainWindow::closeEvent(QCloseEvent *event) {
+ exit(0);
}
-
-void
-MainWindow::connectActions(){
- QObject::connect(this->actionLoad_complex, SIGNAL(triggered()), this,
- SLOT(off_file_open()));
- QObject::connect(this->actionLoad_points, SIGNAL(triggered()), this,
- SLOT(off_points_open()));
- QObject::connect(this->actionSave_complex, SIGNAL(triggered()), this,
- SLOT(off_file_save()));
- QObject::connect(this->actionSave_points, SIGNAL(triggered()), this,
- SLOT(off_points_save()));
-
- QObject::connect(this->actionShow_graph_stats, SIGNAL(triggered()), this,
- SLOT(show_graph_stats()));
- QObject::connect(this->actionShow_complex_stats, SIGNAL(triggered()), this,
- SLOT(show_complex_stats()));
- QObject::connect(this->actionShow_complex_dimension, SIGNAL(triggered()), this,
- SLOT(show_complex_dimension()));
-
- QObject::connect(this->actionUniform_proximity_graph, SIGNAL(triggered()), this,
- SLOT(build_rips_menu()));
- QObject::connect(this->actionK_nearest_neighbors_graph, SIGNAL(triggered()), this,
- SLOT(build_k_nearest_neighbors_menu()));
-
-
- QObject::connect(this->actionContract_edges, SIGNAL(triggered()), this,
- SLOT(contract_edge_menu()));
-
- QObject::connect(this->actionCollapse_vertices, SIGNAL(triggered()), this,
- SLOT(collapse_vertices()));
-
- QObject::connect(this->actionCollapse_edges, SIGNAL(triggered()), this,
- SLOT(collapse_edges()));
-
- QObject::connect(this->actionNoise, SIGNAL(triggered()), this,
- SLOT(uniform_noise()));
- QObject::connect(this->actionLloyd, SIGNAL(triggered()), this,
- SLOT(lloyd()));
-
-
- //view
- QObject::connect(this->actionPoints, SIGNAL(triggered()), this->viewer_instructor_,
- SLOT(change_draw_vertices()));
- QObject::connect(this->actionEdges, SIGNAL(triggered()), this->viewer_instructor_,
- SLOT(change_draw_edges()));
- QObject::connect(this->actionTriangles, SIGNAL(triggered()), this->viewer_instructor_,
- SLOT(change_draw_triangles()));
-
- //topology
- QObject::connect(this->actionShow_homology_group, SIGNAL(triggered()), this,
- SLOT(show_homology_group()));
- QObject::connect(this->actionEuler_characteristic, SIGNAL(triggered()), this,
- SLOT(show_euler_characteristic()));
- QObject::connect(this->actionPersistence, SIGNAL(triggered()), this,
- SLOT(persistence_menu()));
- QObject::connect(this->actionEstimate_topological_changes, SIGNAL(triggered()), this,
- SLOT(critical_points_menu()));
- QObject::connect(this->actionIs_manifold, SIGNAL(triggered()), this,
- SLOT(is_manifold_menu()));
-
-
- QObject::connect(this, SIGNAL(sceneChanged()), this->viewer_instructor_,
- SLOT(sceneChanged()));
-
+void
+MainWindow::connectActions() {
+ QObject::connect(this->actionLoad_complex, SIGNAL(triggered()), this,
+ SLOT(off_file_open()));
+ QObject::connect(this->actionLoad_points, SIGNAL(triggered()), this,
+ SLOT(off_points_open()));
+ QObject::connect(this->actionSave_complex, SIGNAL(triggered()), this,
+ SLOT(off_file_save()));
+ QObject::connect(this->actionSave_points, SIGNAL(triggered()), this,
+ SLOT(off_points_save()));
+
+ QObject::connect(this->actionShow_graph_stats, SIGNAL(triggered()), this,
+ SLOT(show_graph_stats()));
+ QObject::connect(this->actionShow_complex_stats, SIGNAL(triggered()), this,
+ SLOT(show_complex_stats()));
+ QObject::connect(this->actionShow_complex_dimension, SIGNAL(triggered()), this,
+ SLOT(show_complex_dimension()));
+
+ QObject::connect(this->actionUniform_proximity_graph, SIGNAL(triggered()), this,
+ SLOT(build_rips_menu()));
+ QObject::connect(this->actionK_nearest_neighbors_graph, SIGNAL(triggered()), this,
+ SLOT(build_k_nearest_neighbors_menu()));
+
+
+ QObject::connect(this->actionContract_edges, SIGNAL(triggered()), this,
+ SLOT(contract_edge_menu()));
+
+ QObject::connect(this->actionCollapse_vertices, SIGNAL(triggered()), this,
+ SLOT(collapse_vertices()));
+
+ QObject::connect(this->actionCollapse_edges, SIGNAL(triggered()), this,
+ SLOT(collapse_edges()));
+
+ QObject::connect(this->actionNoise, SIGNAL(triggered()), this,
+ SLOT(uniform_noise()));
+ QObject::connect(this->actionLloyd, SIGNAL(triggered()), this,
+ SLOT(lloyd()));
+
+
+ // view
+ QObject::connect(this->actionPoints, SIGNAL(triggered()), this->viewer_instructor_,
+ SLOT(change_draw_vertices()));
+ QObject::connect(this->actionEdges, SIGNAL(triggered()), this->viewer_instructor_,
+ SLOT(change_draw_edges()));
+ QObject::connect(this->actionTriangles, SIGNAL(triggered()), this->viewer_instructor_,
+ SLOT(change_draw_triangles()));
+
+ // topology
+ QObject::connect(this->actionShow_homology_group, SIGNAL(triggered()), this,
+ SLOT(show_homology_group()));
+ QObject::connect(this->actionEuler_characteristic, SIGNAL(triggered()), this,
+ SLOT(show_euler_characteristic()));
+ QObject::connect(this->actionPersistence, SIGNAL(triggered()), this,
+ SLOT(persistence_menu()));
+ QObject::connect(this->actionEstimate_topological_changes, SIGNAL(triggered()), this,
+ SLOT(critical_points_menu()));
+ QObject::connect(this->actionIs_manifold, SIGNAL(triggered()), this,
+ SLOT(is_manifold_menu()));
+
+
+ QObject::connect(this, SIGNAL(sceneChanged()), this->viewer_instructor_,
+ SLOT(sceneChanged()));
}
void
-MainWindow::init_view() const{
- viewer_instructor_->initialize_bounding_box();
- viewer_instructor_->show_entire_scene();
- update_view();
+MainWindow::init_view() const {
+ viewer_instructor_->initialize_bounding_box();
+ viewer_instructor_->show_entire_scene();
+ update_view();
}
-
void
-MainWindow::update_view() const{
- emit (sceneChanged());
+MainWindow::update_view() const {
+ emit(sceneChanged());
}
-
-
/**
* open a file chooser to choose an off to load
*/
-void
-MainWindow::off_file_open(){
- QString fileName = QFileDialog::getOpenFileName(this, tr("Open off File"),
- "~/", tr("off files (*.off)"));
- if (!fileName.isEmpty()){
- model_.off_file_open(fileName.toStdString());
- init_view();
- }
+void
+MainWindow::off_file_open() {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open off File"),
+ "~/", tr("off files (*.off)"));
+ if (!fileName.isEmpty()) {
+ model_.off_file_open(fileName.toStdString());
+ init_view();
+ }
}
void
-MainWindow::off_points_open(){
- QString fileName = QFileDialog::getOpenFileName(this, tr("Open points in a off file"),
- "~/", tr("off files (*.off)"));
- if (!fileName.isEmpty()){
- model_.off_points_open(fileName.toStdString());
- init_view();
- }
+MainWindow::off_points_open() {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open points in a off file"),
+ "~/", tr("off files (*.off)"));
+ if (!fileName.isEmpty()) {
+ model_.off_points_open(fileName.toStdString());
+ init_view();
+ }
}
-
/**
* open a file chooser to choose an off to save
*/
-void
-MainWindow::off_file_save(){
- QString fileName = QFileDialog::getOpenFileName(this, tr("Save to off File"),
- "~/", tr("off files (*.off)"));
- if (!fileName.isEmpty())
- {
- model_.off_file_save(fileName.toStdString());
- }
+void
+MainWindow::off_file_save() {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Save to off File"),
+ "~/", tr("off files (*.off)"));
+ if (!fileName.isEmpty()) {
+ model_.off_file_save(fileName.toStdString());
+ }
}
/**
* open a file chooser to choose an off to save
*/
void
-MainWindow::off_points_save(){
- QString fileName = QFileDialog::getOpenFileName(this, tr("Save to off File"),
- "~/", tr("off files (*.off)"));
- if (!fileName.isEmpty())
- {
- model_.off_points_save(fileName.toStdString());
- }
+MainWindow::off_points_save() {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Save to off File"),
+ "~/", tr("off files (*.off)"));
+ if (!fileName.isEmpty()) {
+ model_.off_points_save(fileName.toStdString());
+ }
}
-
void
-MainWindow::show_graph_stats(){
- model_.show_graph_stats();
+MainWindow::show_graph_stats() {
+ model_.show_graph_stats();
}
void
-MainWindow::show_complex_stats(){
- model_.show_complex_stats();
+MainWindow::show_complex_stats() {
+ model_.show_complex_stats();
}
-void
-MainWindow::show_complex_dimension(){
- model_.show_complex_dimension();
+void
+MainWindow::show_complex_dimension() {
+ model_.show_complex_dimension();
}
-
void
-MainWindow::build_rips_menu(){
- menu_uniform_neighbors_->show();
+MainWindow::build_rips_menu() {
+ menu_uniform_neighbors_->show();
}
void
-MainWindow::build_rips(double alpha){
- model_.build_rips(alpha);
- update_view();
+MainWindow::build_rips(double alpha) {
+ model_.build_rips(alpha);
+ update_view();
}
void
-MainWindow::build_k_nearest_neighbors_menu(){
- menu_k_nearest_neighbors_->show();
+MainWindow::build_k_nearest_neighbors_menu() {
+ menu_k_nearest_neighbors_->show();
}
void
-MainWindow::build_k_nearest_neighbors(unsigned k){
- model_.build_k_nearest_neighbors(k);
- update_view();
+MainWindow::build_k_nearest_neighbors(unsigned k) {
+ model_.build_k_nearest_neighbors(k);
+ update_view();
}
void
-MainWindow::contract_edge_menu(){
- menu_edge_contraction_->show();
+MainWindow::contract_edge_menu() {
+ menu_edge_contraction_->show();
}
void
-MainWindow::contract_edges(unsigned num_collapses){
- std::cerr <<"Collapse "<<num_collapses<< " vertices\n";
- model_.contract_edges(num_collapses);
- update_view();
+MainWindow::contract_edges(unsigned num_collapses) {
+ std::cerr << "Collapse " << num_collapses << " vertices\n";
+ model_.contract_edges(num_collapses);
+ update_view();
}
-
void
-MainWindow::collapse_edges(){
- model_.collapse_edges(model_.num_edges());
- update_view();
+MainWindow::collapse_edges() {
+ model_.collapse_edges(model_.num_edges());
+ update_view();
}
-
-
void
-MainWindow::collapse_vertices(){
- std::cerr <<"Collapse vertices edges\n";
- model_.collapse_vertices(0);
- update_view();
+MainWindow::collapse_vertices() {
+ std::cerr << "Collapse vertices edges\n";
+ model_.collapse_vertices(0);
+ update_view();
}
-
void
-MainWindow::uniform_noise(){
- bool ok;
- double amplitude = QInputDialog::getDouble(this, tr("Uniform noise"),
- tr("Amplitude:"), 0, 0, 10000, 3, &ok);
- srand(time(NULL));
- if (ok)
- model_.uniform_noise(amplitude);
+MainWindow::uniform_noise() {
+ bool ok;
+ double amplitude = QInputDialog::getDouble(this, tr("Uniform noise"),
+ tr("Amplitude:"), 0, 0, 10000, 3, &ok);
+ srand(time(NULL));
+ if (ok)
+ model_.uniform_noise(amplitude);
}
-
void
-MainWindow::lloyd(){
- //todo 1 ask lloyd parameters
- model_.lloyd(0,0);
- update_view();
+MainWindow::lloyd() {
+ // todo 1 ask lloyd parameters
+ model_.lloyd(0, 0);
+ update_view();
}
void
-MainWindow::show_homology_group(){
- model_.show_homology_group();
+MainWindow::show_homology_group() {
+ model_.show_homology_group();
}
void
-MainWindow::show_euler_characteristic(){
- model_.show_euler_characteristic();
+MainWindow::show_euler_characteristic() {
+ model_.show_euler_characteristic();
}
-
-
void
-MainWindow::persistence_menu(){
- menu_persistence_->show();
+MainWindow::persistence_menu() {
+ menu_persistence_->show();
}
void
-MainWindow::compute_persistence(int p,double threshold,int max_dim,double min_pers){
- model_.show_persistence(p,threshold,max_dim,min_pers);
+MainWindow::compute_persistence(int p, double threshold, int max_dim, double min_pers) {
+ model_.show_persistence(p, threshold, max_dim, min_pers);
}
void
-MainWindow::critical_points_menu(){
- bool ok;
- double max_length = QInputDialog::getDouble(this, tr("Maximal edge length for the Rips"),
- tr("Maximal edge length:"), 0, 0, 10000, 3, &ok);
- if (ok)
- model_.show_critical_points(max_length);
+MainWindow::critical_points_menu() {
+ bool ok;
+ double max_length = QInputDialog::getDouble(this, tr("Maximal edge length for the Rips"),
+ tr("Maximal edge length:"), 0, 0, 10000, 3, &ok);
+ if (ok)
+ model_.show_critical_points(max_length);
}
void
-MainWindow::is_manifold_menu(){
- model_.show_is_manifold();
+MainWindow::is_manifold_menu() {
+ model_.show_is_manifold();
}
diff --git a/src/GudhUI/gui/MainWindow.h b/src/GudhUI/gui/MainWindow.h
index 587f1c6f..c8c3fcf6 100644
--- a/src/GudhUI/gui/MainWindow.h
+++ b/src/GudhUI/gui/MainWindow.h
@@ -1,6 +1,30 @@
-#ifndef MAIN_WINDOW_H
-#define MAIN_WINDOW_H
-
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUI_MAINWINDOW_H_
+#define GUI_MAINWINDOW_H_
+
+// Workaround for moc-qt4 not parsing boost headers
+#include <CGAL/config.h>
#include <QMainWindow>
#include "ui_main_window.h"
@@ -13,86 +37,82 @@ class Menu_uniform_neighbors;
class Menu_edge_contraction;
class Menu_persistence;
-class MainWindow : public QMainWindow,public Ui::MainWindow{
- Q_OBJECT
-
-private:
- Model model_;
- Viewer_instructor* viewer_instructor_;
- Menu_k_nearest_neighbors* menu_k_nearest_neighbors_;
- Menu_uniform_neighbors* menu_uniform_neighbors_;
- Menu_edge_contraction* menu_edge_contraction_;
- Menu_persistence* menu_persistence_;
-
-public:
- MainWindow(QWidget* parent = 0);
- void connectActions();
-
- /**
- * compute the bounding box and calls update view
- */
- void init_view() const;
- void update_view() const;
+class MainWindow : public QMainWindow, public Ui::MainWindow {
+ Q_OBJECT
+ private:
+ Model model_;
+ Viewer_instructor* viewer_instructor_;
+ Menu_k_nearest_neighbors* menu_k_nearest_neighbors_;
+ Menu_uniform_neighbors* menu_uniform_neighbors_;
+ Menu_edge_contraction* menu_edge_contraction_;
+ Menu_persistence* menu_persistence_;
-protected:
- void closeEvent(QCloseEvent *event);
- void keyPressEvent(QKeyEvent *event){}
+ public:
+ MainWindow(QWidget* parent = 0);
+ void connectActions();
-public:
+ /**
+ * compute the bounding box and calls update view
+ */
+ void init_view() const;
+ void update_view() const;
- public slots:
+ protected:
+ void closeEvent(QCloseEvent *event);
- /**
- * open a file chooser to choose an off to load
- */
- void off_file_open();
+ void keyPressEvent(QKeyEvent *event) { }
- void off_points_open();
+ public:
+ public slots:
+ /**
+ * open a file chooser to choose an off to load
+ */
+ void off_file_open();
- /**
- * open a file chooser to choose an off to save
- */
- void off_file_save();
- void off_points_save();
+ void off_points_open();
- void show_graph_stats();
- void show_complex_stats();
- void show_complex_dimension();
+ /**
+ * open a file chooser to choose an off to save
+ */
+ void off_file_save();
+ void off_points_save();
+ void show_graph_stats();
+ void show_complex_stats();
+ void show_complex_dimension();
- void build_rips_menu();
- void build_rips(double alpha);
- void build_k_nearest_neighbors_menu();
- void build_k_nearest_neighbors(unsigned k);
+ void build_rips_menu();
+ void build_rips(double alpha);
+ void build_k_nearest_neighbors_menu();
+ void build_k_nearest_neighbors(unsigned k);
- void contract_edge_menu();
- void contract_edges(unsigned num_collapses);
+ void contract_edge_menu();
+ void contract_edges(unsigned num_collapses);
- void collapse_vertices();
- void collapse_edges();
+ void collapse_vertices();
+ void collapse_edges();
- void uniform_noise();
- void lloyd();
- void show_homology_group();
- void show_euler_characteristic();
- void persistence_menu();
- void compute_persistence(int p,double threshold,int max_dim,double min_pers);
- void critical_points_menu();
- void is_manifold_menu();
+ void uniform_noise();
+ void lloyd();
+ void show_homology_group();
+ void show_euler_characteristic();
+ void persistence_menu();
+ void compute_persistence(int p, double threshold, int max_dim, double min_pers);
+ void critical_points_menu();
+ void is_manifold_menu();
-public:
- signals:
- void sceneChanged() const;
-
+ public:
+ signals:
+ void sceneChanged() const;
};
-#endif
+#endif // GUI_MAINWINDOW_H_
diff --git a/src/GudhUI/gui/Menu_edge_contraction.cpp b/src/GudhUI/gui/Menu_edge_contraction.cpp
index dd2621be..a679b0bf 100644
--- a/src/GudhUI/gui/Menu_edge_contraction.cpp
+++ b/src/GudhUI/gui/Menu_edge_contraction.cpp
@@ -1,91 +1,97 @@
-/*
- * Menu_edge_contraction.cpp
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 11, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 MENU_EDGE_CONTRACTION_CPP_
-#define MENU_EDGE_CONTRACTION_CPP_
-
+#ifndef GUI_MENU_EDGE_CONTRACTION_CPP_
+#define GUI_MENU_EDGE_CONTRACTION_CPP_
#include "Menu_edge_contraction.h"
-Menu_edge_contraction::Menu_edge_contraction(MainWindow* parent,const Model& model):
-parent_(parent),model_(model)
-{
- setupUi(this);
- connectActions(parent_);
+Menu_edge_contraction::Menu_edge_contraction(MainWindow* parent, const Model& model) :
+ parent_(parent), model_(model) {
+ setupUi(this);
+ connectActions(parent_);
}
-void Menu_edge_contraction::connectActions(MainWindow* parent)
-{
- QObject::connect(
- this->horizontalSlider,
- SIGNAL(valueChanged(int)),
- this,
- SLOT(slider_value_changed(int))
- );
+void Menu_edge_contraction::connectActions(MainWindow* parent) {
+ QObject::connect(
+ this->horizontalSlider,
+ SIGNAL(valueChanged(int)),
+ this,
+ SLOT(slider_value_changed(int)));
- QObject::connect(this, SIGNAL(contract_edges(unsigned)), parent, SLOT(contract_edges(unsigned)));
-
- QObject::connect(this->pushButton_collapse, SIGNAL(clicked()), this, SLOT(send_contract_edges()));
+ QObject::connect(this, SIGNAL(contract_edges(unsigned)), parent, SLOT(contract_edges(unsigned)));
+ QObject::connect(this->pushButton_collapse, SIGNAL(clicked()), this, SLOT(send_contract_edges()));
}
-void Menu_edge_contraction::slider_value_changed(int new_slider_value){
- int num_collapses =
- (horizontalSlider->value()==1)? 1 : horizontalSlider->value() * model_.num_vertices() / 100 ;
- this->txt_nb_vertices->setNum((int)model_.num_vertices());
- this->txt_nb_collapses->setNum(num_collapses);
- this->spinBox_nb_remaining_vertices->setValue(model_.num_vertices()-num_collapses);
+void Menu_edge_contraction::slider_value_changed(int new_slider_value) {
+ int num_collapses =
+ (horizontalSlider->value() == 1) ? 1 : horizontalSlider->value() * model_.num_vertices() / 100;
+ this->txt_nb_vertices->setNum(static_cast<int>(model_.num_vertices()));
+ this->txt_nb_collapses->setNum(num_collapses);
+ this->spinBox_nb_remaining_vertices->setValue(model_.num_vertices() - num_collapses);
}
-
void
-Menu_edge_contraction::update_slider_value(){
- int num_vertices = model_.num_vertices();
- int num_collapses = (horizontalSlider->value()==1)? 1 : horizontalSlider->value() * num_vertices / 100 ;
- int horizontal_slider_position = num_vertices>0? num_collapses/(double)num_vertices * 100 : 1 ;
- horizontalSlider->setValue(horizontal_slider_position);
+Menu_edge_contraction::update_slider_value() {
+ int num_vertices = model_.num_vertices();
+ int num_collapses = (horizontalSlider->value() == 1) ? 1 : horizontalSlider->value() * num_vertices / 100;
+ int horizontal_slider_position = num_vertices > 0 ? num_collapses / static_cast<double>(num_vertices * 100) : 1;
+ horizontalSlider->setValue(horizontal_slider_position);
}
-
void
-Menu_edge_contraction::update_gui_numbers(){
- update_slider_value();
- bool ok;
- int num_collapses = this->txt_nb_collapses->text().toInt(&ok,10);
- if(!ok) return;
- this->txt_nb_vertices->setNum((int)model_.num_vertices());
- this->txt_nb_collapses->setNum(num_collapses);
- this->spinBox_nb_remaining_vertices->setValue(model_.num_vertices()-num_collapses);
+Menu_edge_contraction::update_gui_numbers() {
+ update_slider_value();
+ bool ok;
+ int num_collapses = this->txt_nb_collapses->text().toInt(&ok, 10);
+ if (!ok) return;
+ this->txt_nb_vertices->setNum(static_cast<int>(model_.num_vertices()));
+ this->txt_nb_collapses->setNum(num_collapses);
+ this->spinBox_nb_remaining_vertices->setValue(model_.num_vertices() - num_collapses);
}
void
-Menu_edge_contraction::update_gui_numbers(int new_value){
- update_gui_numbers();
+Menu_edge_contraction::update_gui_numbers(int new_value) {
+ update_gui_numbers();
}
-
void
-Menu_edge_contraction::send_contract_edges(){
- emit(contract_edges(num_collapses()));
- update_gui_numbers();
+Menu_edge_contraction::send_contract_edges() {
+ emit(contract_edges(num_collapses()));
+ update_gui_numbers();
}
unsigned
-Menu_edge_contraction::num_vertices(){
- return model_.num_vertices();
+Menu_edge_contraction::num_vertices() {
+ return model_.num_vertices();
}
unsigned
-Menu_edge_contraction::num_collapses(){
- return (horizontalSlider->value()==1)? 1 : horizontalSlider->value() * num_vertices() / 100 ;
+Menu_edge_contraction::num_collapses() {
+ return (horizontalSlider->value() == 1) ? 1 : horizontalSlider->value() * num_vertices() / 100;
}
-
#include "Menu_edge_contraction.moc"
-#endif /* MENU_EDGE_CONTRACTION_CPP_ */
+#endif // GUI_MENU_EDGE_CONTRACTION_CPP_
diff --git a/src/GudhUI/gui/Menu_edge_contraction.h b/src/GudhUI/gui/Menu_edge_contraction.h
index e497a90f..08f0bf67 100644
--- a/src/GudhUI/gui/Menu_edge_contraction.h
+++ b/src/GudhUI/gui/Menu_edge_contraction.h
@@ -1,52 +1,63 @@
-/*
- * Menu_edge_contraction.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 11, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 MENU_EDGE_CONTRACTION_H_
-#define MENU_EDGE_CONTRACTION_H_
+#ifndef GUI_MENU_EDGE_CONTRACTION_H_
+#define GUI_MENU_EDGE_CONTRACTION_H_
+// Workaround for moc-qt4 not parsing boost headers
+#include <CGAL/config.h>
#include "gui/MainWindow.h"
#include "gui/ui_MenuEdgeContraction.h"
#include "model/Model.h"
+class Menu_edge_contraction : public QDialog, public Ui::MenuEdgeContraction {
+ Q_OBJECT
-class Menu_edge_contraction : public QDialog,public Ui::MenuEdgeContraction{
- Q_OBJECT
-private:
- MainWindow* parent_;
- const Model& model_;
-
+ private:
+ MainWindow* parent_;
+ const Model& model_;
- void update_slider_value();
-public:
+ void update_slider_value();
- Menu_edge_contraction(MainWindow* parent,const Model& model);
+ public:
+ Menu_edge_contraction(MainWindow* parent, const Model& model);
- void connectActions(MainWindow* parent);
+ void connectActions(MainWindow* parent);
+ private:
+ unsigned num_vertices();
+ unsigned num_collapses();
-private:
- unsigned num_vertices();
- unsigned num_collapses();
+ public slots:
+ void slider_value_changed(int new_slider_value);
+ void update_gui_numbers();
+ void update_gui_numbers(int gui_numbers);
- public slots:
-
- void slider_value_changed(int new_slider_value);
- void update_gui_numbers();
- void update_gui_numbers(int);
-
- void send_contract_edges();
- signals:
-
- void contract_edges(unsigned num_collapses);
+ void send_contract_edges();
+ signals:
+ void contract_edges(unsigned num_collapses);
};
-
-
-#endif /* MENU_EDGE_CONTRACTION_H_ */
+#endif // GUI_MENU_EDGE_CONTRACTION_H_
diff --git a/src/GudhUI/gui/Menu_k_nearest_neighbors.cpp b/src/GudhUI/gui/Menu_k_nearest_neighbors.cpp
index 21c67b2a..e24865f2 100644
--- a/src/GudhUI/gui/Menu_k_nearest_neighbors.cpp
+++ b/src/GudhUI/gui/Menu_k_nearest_neighbors.cpp
@@ -1,55 +1,59 @@
-/*
- * Menu_k_nearest_neighbors.cpp
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 11, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 "Menu_k_nearest_neighbors.h"
-Menu_k_nearest_neighbors::Menu_k_nearest_neighbors(QMainWindow* parent_):
-parent(parent_)
-{
- setupUi(this);
- connectActions(parent_);
+Menu_k_nearest_neighbors::Menu_k_nearest_neighbors(QMainWindow* parent_)
+ : parent(parent_) {
+ setupUi(this);
+ connectActions(parent_);
}
-void Menu_k_nearest_neighbors::connectActions(QMainWindow* parent){
-
- QObject::connect(
- this->pushButtonCompute,
- SIGNAL(clicked()),
- this,
- SLOT(send_compute_k_nearest_neighbors())
- );
- QObject::connect(
- this->spinBoxK,
- SIGNAL(valueChanged(int)),
- this,
- SLOT(update_k(int))
- );
- QObject::connect(
- this,
- SIGNAL(compute_k_nearest_neighbors(unsigned)),
- parent,
- SLOT(build_k_nearest_neighbors(unsigned))
- );
-
+void Menu_k_nearest_neighbors::connectActions(QMainWindow* parent) {
+ QObject::connect(this->pushButtonCompute,
+ SIGNAL(clicked()),
+ this,
+ SLOT(send_compute_k_nearest_neighbors()));
+ QObject::connect(this->spinBoxK,
+ SIGNAL(valueChanged(int)),
+ this,
+ SLOT(update_k(int)));
+ QObject::connect(this,
+ SIGNAL(compute_k_nearest_neighbors(unsigned)),
+ parent,
+ SLOT(build_k_nearest_neighbors(unsigned)));
}
-void Menu_k_nearest_neighbors::send_compute_k_nearest_neighbors(){
- emit(compute_k_nearest_neighbors((unsigned)spinBoxK->value()));
+void Menu_k_nearest_neighbors::send_compute_k_nearest_neighbors() {
+ emit(compute_k_nearest_neighbors((unsigned) spinBoxK->value()));
}
-void Menu_k_nearest_neighbors::accept(){
- send_compute_k_nearest_neighbors();
+void Menu_k_nearest_neighbors::accept() {
+ send_compute_k_nearest_neighbors();
}
-void Menu_k_nearest_neighbors::update_k(int new_k_value){
- if(checkBoxAutoUpdate->isChecked())
- emit(compute_k_nearest_neighbors((unsigned)spinBoxK->value()));
+void Menu_k_nearest_neighbors::update_k(int new_k_value) {
+ if (checkBoxAutoUpdate->isChecked())
+ emit(compute_k_nearest_neighbors((unsigned) spinBoxK->value()));
}
-
#include "Menu_k_nearest_neighbors.moc"
diff --git a/src/GudhUI/gui/Menu_k_nearest_neighbors.h b/src/GudhUI/gui/Menu_k_nearest_neighbors.h
index d72b0074..8088b768 100644
--- a/src/GudhUI/gui/Menu_k_nearest_neighbors.h
+++ b/src/GudhUI/gui/Menu_k_nearest_neighbors.h
@@ -1,39 +1,51 @@
-/*
- * Menu_k_nearest_neighbors.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 11, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 MENU_K_NEAREST_NEIGHBORS_H_
-#define MENU_K_NEAREST_NEIGHBORS_H_
+#ifndef GUI_MENU_K_NEAREST_NEIGHBORS_H_
+#define GUI_MENU_K_NEAREST_NEIGHBORS_H_
#include <QMainWindow>
#include "gui/ui_KNearestNeighborsMenu.h"
class QWidget;
+class Menu_k_nearest_neighbors : public QDialog, public Ui::KNearestNeighborsMenu {
+ Q_OBJECT
-class Menu_k_nearest_neighbors : public QDialog,public Ui::KNearestNeighborsMenu{
- Q_OBJECT
-private:
- QMainWindow* parent;
+ private:
+ QMainWindow* parent;
-public:
+ public:
+ Menu_k_nearest_neighbors(QMainWindow* parent_);
- Menu_k_nearest_neighbors(QMainWindow* parent_);
+ void connectActions(QMainWindow* parent);
- void connectActions(QMainWindow* parent);
-
- public slots:
- void send_compute_k_nearest_neighbors();
- void update_k(int);
- void accept();
-
- signals:
- void compute_k_nearest_neighbors(unsigned k);
+ public slots:
+ void send_compute_k_nearest_neighbors();
+ void update_k(int k);
+ void accept();
+ signals:
+ void compute_k_nearest_neighbors(unsigned k);
};
-
-#endif /* MENU_K_NEAREST_NEIGHBORS_H_ */
+#endif // GUI_MENU_K_NEAREST_NEIGHBORS_H_
diff --git a/src/GudhUI/gui/Menu_persistence.cpp b/src/GudhUI/gui/Menu_persistence.cpp
index fae3a0e6..016c076b 100644
--- a/src/GudhUI/gui/Menu_persistence.cpp
+++ b/src/GudhUI/gui/Menu_persistence.cpp
@@ -1,13 +1,10 @@
-/*
- * Menu_persistence.cpp
- * Created on: Jan 27, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -27,34 +24,30 @@
#include "Menu_persistence.h"
-Menu_persistence::Menu_persistence(QMainWindow* parent_):parent(parent_)
-{
- setupUi(this);
- connectActions(parent_);
+Menu_persistence::Menu_persistence(QMainWindow* parent_) : parent(parent_) {
+ setupUi(this);
+ connectActions(parent_);
}
-void Menu_persistence::connectActions(QMainWindow* parent){
- QObject::connect(
- this,
- SIGNAL(compute_persistence(int,double,int,double)),
- parent,
- SLOT(compute_persistence(int,double,int,double))
- );
+void Menu_persistence::connectActions(QMainWindow* parent) {
+ QObject::connect(this,
+ SIGNAL(compute_persistence(int, double, int, double)),
+ parent,
+ SLOT(compute_persistence(int, double, int, double)));
}
-void Menu_persistence::send_compute_persistence(){
- emit(compute_persistence(p_spinBox->value(),threshold_doubleSpinBox->value(),
- maxdimension_spinBox->value(),minpersistence_doubleSpinBox->value()));
+void Menu_persistence::send_compute_persistence() {
+ emit(compute_persistence(p_spinBox->value(), threshold_doubleSpinBox->value(),
+ maxdimension_spinBox->value(), minpersistence_doubleSpinBox->value()));
}
-void Menu_persistence::accept(){
- send_compute_persistence();
+void Menu_persistence::accept() {
+ send_compute_persistence();
}
-//void Menu_persistence::compute_persistence(int p_fied,double threshold,int dim_max,double min_persistence){
-//// if(checkBoxAutoUpdate->isChecked())
-//// emit(compute_k_nearest_neighbors((unsigned)spinBoxK->value()));
-//}
-
+// void Menu_persistence::compute_persistence(int p_fied,double threshold,int dim_max,double min_persistence) {
+// if(checkBoxAutoUpdate->isChecked())
+// emit(compute_k_nearest_neighbors((unsigned)spinBoxK->value()));
+// }
#include "Menu_persistence.moc"
diff --git a/src/GudhUI/gui/Menu_persistence.h b/src/GudhUI/gui/Menu_persistence.h
index 67b64afa..8c4df158 100644
--- a/src/GudhUI/gui/Menu_persistence.h
+++ b/src/GudhUI/gui/Menu_persistence.h
@@ -1,13 +1,10 @@
-/*
- * Menu_persistence.h
- * Created on: Jan 27, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -24,36 +21,31 @@
*
*/
-
-#ifndef MENU_PERSISTENCE_H_
-#define MENU_PERSISTENCE_H_
-
+#ifndef GUI_MENU_PERSISTENCE_H_
+#define GUI_MENU_PERSISTENCE_H_
#include <QMainWindow>
#include "gui/ui_PersistenceMenu.h"
class QWidget;
+class Menu_persistence : public QDialog, public Ui::PersistenceMenu {
+ Q_OBJECT
-class Menu_persistence : public QDialog,public Ui::PersistenceMenu{
- Q_OBJECT
-private:
- QMainWindow* parent;
-
-public:
+ private:
+ QMainWindow* parent;
- Menu_persistence(QMainWindow* parent_);
+ public:
+ Menu_persistence(QMainWindow* parent_);
- void connectActions(QMainWindow* parent);
+ void connectActions(QMainWindow* parent);
- public slots:
- void send_compute_persistence();
- void accept();
- signals:
- void compute_persistence(int p_fied,double threshold,int dim_max,double min_persistence);
+ public slots:
+ void send_compute_persistence();
+ void accept();
+ signals:
+ void compute_persistence(int p_fied, double threshold, int dim_max, double min_persistence);
};
-
-
-#endif /* MENU_PERSISTENCE_H_ */
+#endif // GUI_MENU_PERSISTENCE_H_
diff --git a/src/GudhUI/gui/Menu_uniform_neighbors.cpp b/src/GudhUI/gui/Menu_uniform_neighbors.cpp
index 86e2593e..20e4f98f 100644
--- a/src/GudhUI/gui/Menu_uniform_neighbors.cpp
+++ b/src/GudhUI/gui/Menu_uniform_neighbors.cpp
@@ -1,59 +1,60 @@
-/*
- * Menu_uniform_neighbors.cpp
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 11, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 "Menu_uniform_neighbors.h"
-Menu_uniform_neighbors::Menu_uniform_neighbors(QMainWindow* parent_):
-parent(parent_)
-{
- setupUi(this);
- connectActions(parent_);
+Menu_uniform_neighbors::Menu_uniform_neighbors(QMainWindow* parent_) :
+ parent(parent_) {
+ setupUi(this);
+ connectActions(parent_);
}
-void Menu_uniform_neighbors::connectActions(QMainWindow* parent){
-
- QObject::connect(
- this->pushButtonCompute,
- SIGNAL(clicked()),
- this,
- SLOT(send_compute_uniform_neighbors())
- );
- QObject::connect(
- this->doubleSpinBoxAlpha,
- SIGNAL(valueChanged(double)),
- this,
- SLOT(update_alpha(double))
- );
- QObject::connect(
- this,
- SIGNAL(compute_uniform_neighbors(double)),
- parent,
- SLOT(build_rips(double))
- );
-
+void Menu_uniform_neighbors::connectActions(QMainWindow* parent) {
+ QObject::connect(this->pushButtonCompute,
+ SIGNAL(clicked()),
+ this,
+ SLOT(send_compute_uniform_neighbors()));
+ QObject::connect(this->doubleSpinBoxAlpha,
+ SIGNAL(valueChanged(double)),
+ this,
+ SLOT(update_alpha(double)));
+ QObject::connect(this,
+ SIGNAL(compute_uniform_neighbors(double)),
+ parent,
+ SLOT(build_rips(double)));
}
-void Menu_uniform_neighbors::send_compute_uniform_neighbors(){
- emit(compute_uniform_neighbors(doubleSpinBoxAlpha->value()));
+void Menu_uniform_neighbors::send_compute_uniform_neighbors() {
+ emit(compute_uniform_neighbors(doubleSpinBoxAlpha->value()));
}
-void Menu_uniform_neighbors::accept(){
- send_compute_uniform_neighbors();
+void Menu_uniform_neighbors::accept() {
+ send_compute_uniform_neighbors();
}
-void Menu_uniform_neighbors::update_alpha(double alpha){
- if(checkBoxAutoUpdate->isChecked())
- emit(compute_uniform_neighbors(doubleSpinBoxAlpha->value()));
+void Menu_uniform_neighbors::update_alpha(double alpha) {
+ if (checkBoxAutoUpdate->isChecked())
+ emit(compute_uniform_neighbors(doubleSpinBoxAlpha->value()));
}
-
-
#include "Menu_uniform_neighbors.moc"
diff --git a/src/GudhUI/gui/Menu_uniform_neighbors.h b/src/GudhUI/gui/Menu_uniform_neighbors.h
index cb90cc88..0b6f65fe 100644
--- a/src/GudhUI/gui/Menu_uniform_neighbors.h
+++ b/src/GudhUI/gui/Menu_uniform_neighbors.h
@@ -1,36 +1,51 @@
-/*
- * Menu_uniform_neighbors.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 11, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 MENU_UNIFORM_NEIGHBORS_H_
-#define MENU_UNIFORM_NEIGHBORS_H_
+#ifndef GUI_MENU_UNIFORM_NEIGHBORS_H_
+#define GUI_MENU_UNIFORM_NEIGHBORS_H_
#include <QMainWindow>
#include "gui/ui_UniformNeighborsMenu.h"
-class Menu_uniform_neighbors : public QDialog,public Ui::UniformMenu {
- Q_OBJECT
-private:
- QMainWindow* parent;
-
-public:
+class Menu_uniform_neighbors : public QDialog, public Ui::UniformMenu {
+ Q_OBJECT
- Menu_uniform_neighbors(QMainWindow* parent_);
+ private:
+ QMainWindow* parent;
- void connectActions(QMainWindow* parent);
+ public:
+ Menu_uniform_neighbors(QMainWindow* parent_);
- public slots:
- void send_compute_uniform_neighbors();
- void update_alpha(double);
- void accept();
+ void connectActions(QMainWindow* parent);
- signals:
- void compute_uniform_neighbors(double alpha);
+ public slots:
+ void send_compute_uniform_neighbors();
+ void update_alpha(double alpha);
+ void accept();
+ signals:
+ void compute_uniform_neighbors(double alpha);
};
-#endif /* MENU_UNIFORM_NEIGHBORS_H_ */
+#endif // GUI_MENU_UNIFORM_NEIGHBORS_H_
diff --git a/src/GudhUI/gui/Viewer.cpp b/src/GudhUI/gui/Viewer.cpp
deleted file mode 100644
index e69de29b..00000000
--- a/src/GudhUI/gui/Viewer.cpp
+++ /dev/null
diff --git a/src/GudhUI/gui/Viewer_instructor.cpp b/src/GudhUI/gui/Viewer_instructor.cpp
deleted file mode 100644
index e69de29b..00000000
--- a/src/GudhUI/gui/Viewer_instructor.cpp
+++ /dev/null
diff --git a/src/GudhUI/gui/gudhui.cpp b/src/GudhUI/gui/gudhui.cpp
index 8d90270f..377cd2f2 100644
--- a/src/GudhUI/gui/gudhui.cpp
+++ b/src/GudhUI/gui/gudhui.cpp
@@ -1,15 +1,36 @@
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 "MainWindow.h"
#include <QApplication>
#include <CGAL/Qt/resources.h>
+int main(int argc, char** argv) {
+ QApplication application(argc, argv);
+ application.setOrganizationDomain("inria.fr");
+ application.setOrganizationName("INRIA");
+ application.setApplicationName("GudhUI");
-int main(int argc, char** argv)
-{
- QApplication application(argc,argv);
- application.setOrganizationDomain("inria.fr");
- application.setOrganizationName("INRIA");
- application.setApplicationName("GudhUI");
-
MainWindow mw;
application.setQuitOnLastWindowClosed(false);
mw.show();
diff --git a/src/GudhUI/model/Complex_typedefs.h b/src/GudhUI/model/Complex_typedefs.h
index b6404d62..c310d4a6 100644
--- a/src/GudhUI/model/Complex_typedefs.h
+++ b/src/GudhUI/model/Complex_typedefs.h
@@ -1,39 +1,49 @@
-/*
- * Complex_typedefs.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 26, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 COMPLEX_TYPEDEFS_H_
-#define COMPLEX_TYPEDEFS_H_
-
+#ifndef MODEL_COMPLEX_TYPEDEFS_H_
+#define MODEL_COMPLEX_TYPEDEFS_H_
-
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h"
-#include "gudhi/Skeleton_blocker_geometric_complex.h"
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h>
+#include <gudhi/Skeleton_blocker_geometric_complex.h>
#include <CGAL/Kernel_d/Point_d.h>
-
#include <CGAL/Cartesian.h>
#include <CGAL/Cartesian_d.h>
-
struct Geometry_trait : public CGAL::Cartesian_d<double> {
- typedef CGAL::Cartesian<double>::Point_3 Point_3;
- typedef CGAL::Cartesian<double>::Vector_3 Vector_3;
- typedef CGAL::Point_d<Cartesian_d<double>> Point;
- typedef CGAL::Vector_d<Cartesian_d<double>> Vector;
+ typedef CGAL::Cartesian<double>::Point_3 Point_3;
+ typedef CGAL::Cartesian<double>::Vector_3 Vector_3;
+ typedef CGAL::Point_d<Cartesian_d<double>> Point;
+ typedef CGAL::Vector_d<Cartesian_d<double>> Vector;
};
typedef Geometry_trait::Point Point;
-
using namespace Gudhi;
using namespace Gudhi::skbl;
typedef Skeleton_blocker_simple_geometric_traits<Geometry_trait> Complex_geometric_traits;
typedef Skeleton_blocker_geometric_complex< Complex_geometric_traits > Complex;
-
-#endif /* COMPLEX_TYPEDEFS_H_ */
+#endif // MODEL_COMPLEX_TYPEDEFS_H_
diff --git a/src/GudhUI/model/Model.h b/src/GudhUI/model/Model.h
index 17a7d278..07a67a0c 100644
--- a/src/GudhUI/model/Model.h
+++ b/src/GudhUI/model/Model.h
@@ -1,16 +1,41 @@
-/*
- * Model.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 25, 2014
- * Author: david
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 MODEL_H_
-#define MODEL_H_
+#ifndef MODEL_MODEL_H_
+#define MODEL_MODEL_H_
+
+#include <gudhi/Clock.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h>
+#include <gudhi/Skeleton_blocker_geometric_complex.h>
+#include <gudhi/Off_reader.h>
+
+#include <CGAL/Euclidean_distance.h>
#include <fstream>
#include <limits>
-#include "gudhi/Clock.h"
+#include <string>
+#include <vector>
+
#include "utils/UI_utils.h"
#include "utils/Lloyd_builder.h"
#include "utils/Rips_builder.h"
@@ -22,328 +47,309 @@
#include "utils/Critical_points.h"
#include "utils/Is_manifold.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h"
-#include "gudhi/Skeleton_blocker_geometric_complex.h"
-
-#include "gudhi/Off_reader.h"
-
#include "Complex_typedefs.h"
-
-#include <CGAL/Euclidean_distance.h>
-
-
template<typename Complex>
-class CGAL_geometric_flag_complex_wrapper{
- Complex& complex_;
- typedef typename Complex::Vertex_handle Vertex_handle;
- typedef typename Complex::Point Point;
-
- const bool load_only_points_;
-
-public:
- CGAL_geometric_flag_complex_wrapper(Complex& complex,bool load_only_points = false):
- complex_(complex),
- load_only_points_(load_only_points){
- }
-
- void init(int dim,int num_vertices,int num_max_faces,int num_edges) const{
- }
-
- void point(const std::vector<double>& coords){
- Point p(coords.size(),coords.begin(),coords.end());
- complex_.add_vertex(p);
- }
-
- void maximal_face(std::vector<int> vertices){
- if (!load_only_points_){
- std::cout<<"size:"<<vertices.size()<<std::endl;
- for (int i = 0; i<vertices.size() ; ++i)
- for (int j = i+1; j<vertices.size() ; ++j)
- complex_.add_edge(Vertex_handle(vertices[i]),Vertex_handle(vertices[j]));
- }
- }
- void done() const{}
+class CGAL_geometric_flag_complex_wrapper {
+ Complex& complex_;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+ typedef typename Complex::Point Point;
+
+ const bool load_only_points_;
+
+ public:
+ CGAL_geometric_flag_complex_wrapper(Complex& complex, bool load_only_points = false) :
+ complex_(complex),
+ load_only_points_(load_only_points) { }
+
+ void init(int dim, int num_vertices, int num_max_faces, int num_edges) const { }
+
+ void point(const std::vector<double>& coords) {
+ Point p(coords.size(), coords.begin(), coords.end());
+ complex_.add_vertex(p);
+ }
+
+ void maximal_face(std::vector<int> vertices) {
+ if (!load_only_points_) {
+ std::cout << "size:" << vertices.size() << std::endl;
+ for (int i = 0; i < vertices.size(); ++i)
+ for (int j = i + 1; j < vertices.size(); ++j)
+ complex_.add_edge(Vertex_handle(vertices[i]), Vertex_handle(vertices[j]));
+ }
+ }
+
+ void done() const { }
};
-
-class Model{
-
-public:
- Complex complex_;
- typedef Complex::Vertex_handle Vertex_handle;
-
- Model():complex_(){
- }
-
-public:
- void off_file_open(const std::string& name_file){
- UIDBGMSG("load off file",name_file);
- complex_.clear();
- CGAL_geometric_flag_complex_wrapper<Complex> read_wraper(complex_,false);
- Gudhi::read_off(name_file,read_wraper);
- }
-
- void off_points_open(const std::string& name_file){
- UIDBGMSG("load off points",name_file);
- complex_.clear();
- CGAL_geometric_flag_complex_wrapper<Complex> read_wraper(complex_,true);
- Gudhi::read_off(name_file,read_wraper);
- }
-
- void off_file_save(const std::string& name_file){
- UIDBG("save off file");
- UIDBG("save off off_points_save");
- std::ofstream file(name_file);
- if(file.is_open()){
- file<<"OFF\n";
- file<<complex_.num_vertices()<<" "<<complex_.num_edges()<<" 0\n";
- for(auto v : complex_.vertex_range()){
- const auto& pt(complex_.point(v));
- for(auto it = pt.cartesian_begin();it!=pt.cartesian_end();++it)
- file<<*it<<" ";
- file<<std::endl;
- }
- for(auto e : complex_.edge_range())
- file<<"2 "<<complex_.first_vertex(e)<<" "<<complex_.second_vertex(e)<<"\n";
- file.close();
- }
- else std::cerr << "Could not open file "<<name_file<<std::endl;
-
- }
-
- void off_points_save(const std::string& name_file){
- UIDBG("save off off_points_save");
- std::ofstream file(name_file);
- if(file.is_open()){
- file<<"OFF\n";
- file<<complex_.num_vertices()<<" 0 0\n";
- for(auto v : complex_.vertex_range()){
- const auto& pt(complex_.point(v));
- for(auto it = pt.cartesian_begin();it!=pt.cartesian_end();++it)
- file<<*it<<" ";
- file<<std::endl;
- }
- file.close();
- }
- else std::cerr << "Could not open file "<<name_file<<std::endl;
-
- }
-
- // point sets operations
- void uniform_noise(double amplitude){
- UIDBG("unif noise");
- for (auto v : complex_.vertex_range())
- complex_.point(v) = add_uniform_noise(complex_.point(v),amplitude);
- }
-
-private:
- Point add_uniform_noise(const Point& point,double amplitude){
- std::vector<double> new_point(point.dimension());
- for(int i = 0 ; i < point.dimension();++i){
- new_point[i] = point[i] + (rand() % 2 - .5) * amplitude;
- }
- return Point(point.dimension(), new_point.begin(),new_point.end());
- }
-
-public:
-
- void lloyd(int num_iterations,int num_closest_neighbors){
- UIDBG("lloyd");
- Lloyd_builder<Complex> lloyd_builder(complex_,1);
- }
-
- double squared_eucl_distance(const Point& p1,const Point& p2) const{
- return Geometry_trait::Squared_distance_d()(p1,p2);
- }
-
- // complex operations from points
- void build_rips(double alpha){
- UIDBG("build_rips");
- Rips_builder<Complex> rips_builder(complex_,alpha);
- }
-
- void build_k_nearest_neighbors(unsigned k){
- UIDBG("build_k_nearest");
- complex_.keep_only_vertices();
- K_nearest_builder<Complex> k_nearest_builder(complex_,k);
- }
-
- void build_delaunay(){
- UIDBG("build_delaunay");
- complex_.keep_only_vertices();
- }
-
-
-
- void contract_edges(unsigned num_contractions){
- Clock c;
- Edge_contractor<Complex> contractor(complex_,num_contractions);
- std::cout<<"Time to simplify: "<<c.num_seconds()<<"s"<<std::endl;
- }
-
-
- void collapse_vertices(unsigned num_collapses){
-
- auto old_num_vertices = complex_.num_vertices();
- Vertex_collapsor<Complex> collapsor(complex_,complex_.num_vertices());
- UIDBGMSG("num vertices collapsed:",old_num_vertices - complex_.num_vertices());
- }
-
- void collapse_edges(unsigned num_collapses){
- Edge_collapsor<Complex> collapsor(complex_,num_collapses);
- }
-
-
- void show_graph_stats(){
- std::cout << "++++++ Graph stats +++++++"<< std::endl;
- std::cout << "Num vertices : " << complex_.num_vertices()<<std::endl;
- std::cout << "Num edges : " << complex_.num_edges()<<std::endl;
- std::cout << "Num connected components : " << complex_.num_connected_components()<<std::endl;
- std::cout << "Min/avg/max degree : " << min_degree()<<"/"<<avg_degree()<<"/"<<max_degree()<<std::endl;
- std::cout << "Num connected components : " << complex_.num_connected_components()<<std::endl;
- std::cout << "Num connected components : " << complex_.num_connected_components()<<std::endl;
- std::cout << "+++++++++++++++++++++++++"<< std::endl;
- }
-
-private:
- int min_degree() const{
- int res = (std::numeric_limits<int>::max)();
- for(auto v : complex_.vertex_range())
- res= (std::min)(res,complex_.degree(v));
- return res;
- }
-
- int max_degree() const{
- int res = 0;
- for(auto v : complex_.vertex_range())
- res= (std::max)(res,complex_.degree(v));
- return res;
- }
-
- int avg_degree() const{
- int res = 0;
- for(auto v : complex_.vertex_range())
- res+= complex_.degree(v);
- return res / complex_.num_vertices();
- }
-
-public:
-
-
-
- void show_complex_stats(){
- std::cout << "++++++ Mesh stats +++++++"<< std::endl;
- std::cout << "Num vertices : " << complex_.num_vertices()<<std::endl;
- std::cout << "Num edges : " << complex_.num_edges()<<std::endl;
- std::cout << "Num connected components : " << complex_.num_connected_components()<<std::endl;
- std::cout << "+++++++++++++++++++++++++"<< std::endl;
-
- }
-
- void show_complex_dimension(){
- unsigned num_simplices = 0;
- int euler = 0;
- int dimension = 0;
- Clock clock;
- for(const auto &s : complex_.simplex_range()){
- num_simplices++;
- dimension = (std::max)(s.dimension(),dimension);
- if(s.dimension()%2==0)
- euler+=1;
- else
- euler-=1;
- }
- clock.end();
- std::cout << "++++++ Mesh dimension +++++++"<< std::endl;
- std::cout << "Dimension : " << dimension<<std::endl;
- std::cout << "Euler characteristic : " << euler<<std::endl;
- std::cout << "Num simplices : " << num_simplices <<std::endl;
- std::cout << "Total time: " << clock <<std::endl;
- std::cout << "Time per simplex: " << clock.num_seconds()/num_simplices <<" s"<<std::endl;
- std::cout << "+++++++++++++++++++++++++"<< std::endl;
- }
-
-
- void show_homology_group(){
+class Model {
+ public:
+ Complex complex_;
+ typedef Complex::Vertex_handle Vertex_handle;
+
+ Model() : complex_() { }
+
+ public:
+ void off_file_open(const std::string& name_file) {
+ UIDBGMSG("load off file", name_file);
+ complex_.clear();
+ CGAL_geometric_flag_complex_wrapper<Complex> read_wraper(complex_, false);
+ Gudhi::read_off(name_file, read_wraper);
+ }
+
+ void off_points_open(const std::string& name_file) {
+ UIDBGMSG("load off points", name_file);
+ complex_.clear();
+ CGAL_geometric_flag_complex_wrapper<Complex> read_wraper(complex_, true);
+ Gudhi::read_off(name_file, read_wraper);
+ }
+
+ void off_file_save(const std::string& name_file) {
+ UIDBG("save off file");
+ UIDBG("save off off_points_save");
+ std::ofstream file(name_file);
+ if (file.is_open()) {
+ file << "OFF\n";
+ file << complex_.num_vertices() << " " << complex_.num_edges() << " 0\n";
+ for (auto v : complex_.vertex_range()) {
+ const auto& pt(complex_.point(v));
+ for (auto it = pt.cartesian_begin(); it != pt.cartesian_end(); ++it)
+ file << *it << " ";
+ file << std::endl;
+ }
+ for (auto e : complex_.edge_range())
+ file << "2 " << complex_.first_vertex(e) << " " << complex_.second_vertex(e) << "\n";
+ file.close();
+ } else {
+ std::cerr << "Could not open file " << name_file << std::endl;
+ }
+ }
+
+ void off_points_save(const std::string& name_file) {
+ UIDBG("save off off_points_save");
+ std::ofstream file(name_file);
+ if (file.is_open()) {
+ file << "OFF\n";
+ file << complex_.num_vertices() << " 0 0\n";
+ for (auto v : complex_.vertex_range()) {
+ const auto& pt(complex_.point(v));
+ for (auto it = pt.cartesian_begin(); it != pt.cartesian_end(); ++it)
+ file << *it << " ";
+ file << std::endl;
+ }
+ file.close();
+ } else {
+ std::cerr << "Could not open file " << name_file << std::endl;
+ }
+ }
+
+ // point sets operations
+ void uniform_noise(double amplitude) {
+ UIDBG("unif noise");
+ for (auto v : complex_.vertex_range())
+ complex_.point(v) = add_uniform_noise(complex_.point(v), amplitude);
+ }
+
+ private:
+ Point add_uniform_noise(const Point& point, double amplitude) {
+ std::vector<double> new_point(point.dimension());
+ for (int i = 0; i < point.dimension(); ++i) {
+ new_point[i] = point[i] + (rand() % 2 - .5) * amplitude;
+ }
+ return Point(point.dimension(), new_point.begin(), new_point.end());
+ }
+
+ public:
+ void lloyd(int num_iterations, int num_closest_neighbors) {
+ UIDBG("lloyd");
+ Lloyd_builder<Complex> lloyd_builder(complex_, 1);
+ }
+
+ double squared_eucl_distance(const Point& p1, const Point& p2) const {
+ return Geometry_trait::Squared_distance_d()(p1, p2);
+ }
+
+ // complex operations from points
+
+ void build_rips(double alpha) {
+ UIDBG("build_rips");
+ Rips_builder<Complex> rips_builder(complex_, alpha);
+ }
+
+ void build_k_nearest_neighbors(unsigned k) {
+ UIDBG("build_k_nearest");
+ complex_.keep_only_vertices();
+ K_nearest_builder<Complex> k_nearest_builder(complex_, k);
+ }
+
+ void build_delaunay() {
+ UIDBG("build_delaunay");
+ complex_.keep_only_vertices();
+ }
+
+ void contract_edges(unsigned num_contractions) {
+ Clock c;
+ Edge_contractor<Complex> contractor(complex_, num_contractions);
+ std::cout << "Time to simplify: " << c.num_seconds() << "s" << std::endl;
+ }
+
+ void collapse_vertices(unsigned num_collapses) {
+ auto old_num_vertices = complex_.num_vertices();
+ Vertex_collapsor<Complex> collapsor(complex_, complex_.num_vertices());
+ UIDBGMSG("num vertices collapsed:", old_num_vertices - complex_.num_vertices());
+ }
+
+ void collapse_edges(unsigned num_collapses) {
+ Edge_collapsor<Complex> collapsor(complex_, num_collapses);
+ }
+
+ void show_graph_stats() {
+ std::cout << "++++++ Graph stats +++++++" << std::endl;
+ std::cout << "Num vertices : " << complex_.num_vertices() << std::endl;
+ std::cout << "Num edges : " << complex_.num_edges() << std::endl;
+ std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl;
+ std::cout << "Min/avg/max degree : " << min_degree() << "/" << avg_degree() << "/" << max_degree() << std::endl;
+ std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl;
+ std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl;
+ std::cout << "+++++++++++++++++++++++++" << std::endl;
+ }
+
+ private:
+ int min_degree() const {
+ int res = (std::numeric_limits<int>::max)();
+ for (auto v : complex_.vertex_range())
+ res = (std::min)(res, complex_.degree(v));
+ return res;
+ }
+
+ int max_degree() const {
+ int res = 0;
+ for (auto v : complex_.vertex_range())
+ res = (std::max)(res, complex_.degree(v));
+ return res;
+ }
+
+ int avg_degree() const {
+ int res = 0;
+ for (auto v : complex_.vertex_range())
+ res += complex_.degree(v);
+ return res / complex_.num_vertices();
+ }
+
+ public:
+ void show_complex_stats() {
+ std::cout << "++++++ Mesh stats +++++++" << std::endl;
+ std::cout << "Num vertices : " << complex_.num_vertices() << std::endl;
+ std::cout << "Num edges : " << complex_.num_edges() << std::endl;
+ std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl;
+ std::cout << "+++++++++++++++++++++++++" << std::endl;
+ }
+
+ void show_complex_dimension() {
+ unsigned num_simplices = 0;
+ int euler = 0;
+ int dimension = 0;
+ Clock clock;
+ for (const auto &s : complex_.complex_simplex_range()) {
+ num_simplices++;
+ dimension = (std::max)(s.dimension(), dimension);
+ if (s.dimension() % 2 == 0)
+ euler += 1;
+ else
+ euler -= 1;
+ }
+ clock.end();
+ std::cout << "++++++ Mesh dimension +++++++" << std::endl;
+ std::cout << "Dimension : " << dimension << std::endl;
+ std::cout << "Euler characteristic : " << euler << std::endl;
+ std::cout << "Num simplices : " << num_simplices << std::endl;
+ std::cout << "Total time: " << clock << std::endl;
+ std::cout << "Time per simplex: " << clock.num_seconds() / num_simplices << " s" << std::endl;
+ std::cout << "+++++++++++++++++++++++++" << std::endl;
+ }
+
+ void show_homology_group() {
#ifdef _WIN32
- std::cout << "Works only on linux x64 for the moment\n";
+ std::cout << "Works only on linux x64 for the moment\n";
#else
- Clock clock;
- run_chomp();
- clock.end();
+ Clock clock;
+ run_chomp();
+ clock.end();
#endif
- }
-
- void show_euler_characteristic(){
- unsigned num_simplices = 0;
- int euler = 0;
- int dimension = 0;
- for(const auto &s : complex_.simplex_range()){
- num_simplices++;
- dimension = (std::max)(s.dimension(),dimension);
- if(s.dimension()%2==0)
- euler+=1;
- else
- euler-=1;
- }
- std::cout << "Saw "<<num_simplices<<" simplices with maximum dimension " << dimension<<std::endl;
- std::cout << "The euler characteristic is : " << euler<<std::endl;
- }
-
- void show_persistence( int p,double threshold,int max_dim,double min_pers){
- Persistence_compute<Complex> persistence(complex_,std::cout,Persistence_params(p,threshold,max_dim,min_pers));
- }
-
- void show_critical_points(double max_distance){
- Critical_points<Complex> critical_points(complex_,std::cout,max_distance);
- }
-
- void show_is_manifold(){
- unsigned dim;
- bool is_manifold;
- Is_manifold<Complex> test_manifold(complex_,dim,is_manifold);
-
- if(is_manifold) std::cout << "The complex is a "<<dim<<"-manifold\n";
- else
- if(dim<4) std::cout << "The complex has dimension greater than "<<dim<<" and is not a manifold\n";
- else std::cout << "The complex has dimension>=4 and may or may not be a manifold\n";
- }
-
-
-private:
- void run_chomp(){
- save_complex_in_file_for_chomp();
- std::cout << "Call CHOMP library\n";
- int returnValue = system("utils/homsimpl chomp.sim");
- std::cout << "CHOMP returns" << returnValue << std::endl;
- }
-
- void save_complex_in_file_for_chomp(){
- std::ofstream file;
- file.open("chomp.sim");
- for(const auto &s : complex_.simplex_range()){
- bool first = true;
- file<<"(";
- for(auto x : s){
- if(first) first = false;
- else file<<",";
- file << x;
- }
- file<<")\n";
- }
- }
-public:
-
-
- unsigned num_vertices() const{
- return complex_.num_vertices();
- }
-
- unsigned num_edges() const{
- return complex_.num_edges();
- }
-
+ }
+
+ void show_euler_characteristic() {
+ unsigned num_simplices = 0;
+ int euler = 0;
+ int dimension = 0;
+ for (const auto &s : complex_.complex_simplex_range()) {
+ num_simplices++;
+ dimension = (std::max)(s.dimension(), dimension);
+ if (s.dimension() % 2 == 0)
+ euler += 1;
+ else
+ euler -= 1;
+ }
+ std::cout << "Saw " << num_simplices << " simplices with maximum dimension " << dimension << std::endl;
+ std::cout << "The euler characteristic is : " << euler << std::endl;
+ }
+
+ void show_persistence(int p, double threshold, int max_dim, double min_pers) {
+ Persistence_compute<Complex> persistence(complex_, std::cout, Persistence_params(p, threshold, max_dim, min_pers));
+ }
+
+ void show_critical_points(double max_distance) {
+ Critical_points<Complex> critical_points(complex_, std::cout, max_distance);
+ }
+
+ void show_is_manifold() {
+ unsigned dim;
+ bool is_manifold;
+ Is_manifold<Complex> test_manifold(complex_, dim, is_manifold);
+
+ if (is_manifold) {
+ std::cout << "The complex is a " << dim << "-manifold\n";
+ } else {
+ if (dim < 4) {
+ std::cout << "The complex has dimension greater than " << dim << " and is not a manifold\n";
+ } else {
+ std::cout << "The complex has dimension>=4 and may or may not be a manifold\n";
+ }
+ }
+ }
+
+ private:
+ void run_chomp() {
+ save_complex_in_file_for_chomp();
+ std::cout << "Call CHOMP library\n";
+ int returnValue = system("utils/homsimpl chomp.sim");
+ std::cout << "CHOMP returns" << returnValue << std::endl;
+ }
+
+ void save_complex_in_file_for_chomp() {
+ std::ofstream file;
+ file.open("chomp.sim");
+ for (const auto &s : complex_.complex_simplex_range()) {
+ bool first = true;
+ file << "(";
+ for (auto x : s) {
+ if (first)
+ first = false;
+ else
+ file << ",";
+ file << x;
+ }
+ file << ")\n";
+ }
+ }
+
+ public:
+ unsigned num_vertices() const {
+ return complex_.num_vertices();
+ }
+
+ unsigned num_edges() const {
+ return complex_.num_edges();
+ }
};
-#endif /* MODEL_H_ */
+#endif // MODEL_MODEL_H_
diff --git a/src/GudhUI/utils/Critical_points.h b/src/GudhUI/utils/Critical_points.h
index 92392d4a..3021a5fe 100644
--- a/src/GudhUI/utils/Critical_points.h
+++ b/src/GudhUI/utils/Critical_points.h
@@ -1,13 +1,10 @@
-/*
- * Critical_points.h
- * Created on: Jan 27, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -24,11 +21,13 @@
*
*/
-
-#ifndef CRITICAL_POINTS_H_
-#define CRITICAL_POINTS_H_
+#ifndef UTILS_CRITICAL_POINTS_H_
+#define UTILS_CRITICAL_POINTS_H_
#include <deque>
+#include <utility> // for pair<>
+#include <algorithm> // for sort
+
#include "utils/Edge_contractor.h"
/**
@@ -37,101 +36,97 @@
*
* todo do a sparsification with some parameter eps while growing
*/
-template<typename SkBlComplex> class Critical_points{
-private:
- SkBlComplex filled_complex_;
- const SkBlComplex& input_complex_;
- double max_length_;
- std::ostream& stream_;
-public:
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- typedef typename SkBlComplex::Edge_handle Edge_handle;
- typedef typename std::pair<Vertex_handle,Vertex_handle> Edge;
-
- /**
- * @brief check all pair of points with length smaller than max_length
- */
- Critical_points(const SkBlComplex& input_complex,std::ostream& stream,double max_length):
- input_complex_(input_complex),max_length_(max_length),stream_(stream)
- {
-
- std::deque<Edge> edges;
- auto vertices = input_complex.vertex_range();
- for(auto p = vertices.begin(); p!= vertices.end(); ++p){
- filled_complex_.add_vertex(input_complex.point(*p));
- for (auto q = p; ++q != vertices.end(); /**/)
- if (squared_eucl_distance(input_complex.point(*p),input_complex.point(*q)) < max_length_*max_length_)
- edges.emplace_back(*p,*q);
- }
-
- std::sort(edges.begin(),edges.end(),
- [&](Edge e1,Edge e2){
- return squared_edge_length(e1) < squared_edge_length(e2);
- });
-
- anti_collapse_edges(edges);
-
- }
-
-private:
- double squared_eucl_distance(const Point& p1,const Point& p2) const{
- return Geometry_trait::Squared_distance_d()(p1,p2);
- }
-
-
- void anti_collapse_edges(const std::deque<Edge>& edges){
- unsigned pos = 0;
- for(Edge e : edges){
- std::cout<<"edge "<<pos++<<"/"<<edges.size()<<"\n";
- auto eh = filled_complex_.add_edge(e.first,e.second);
- int is_contractible(is_link_reducible(eh));
-
- switch (is_contractible) {
- case 0:
- stream_<<"alpha="<<std::sqrt(squared_edge_length(e))<< " topological change"<<std::endl;
- break;
- case 2:
- stream_<<"alpha="<<std::sqrt(squared_edge_length(e))<< " maybe a topological change"<<std::endl;
- break;
- default:
- break;
- }
- }
-
- }
-
-
- //0 -> not
- //1 -> yes
- //2 -> maybe
- int is_link_reducible(Edge_handle e){
- auto link = filled_complex_.link(e);
-
- if(link.empty()) return 0;
-
- Edge_contractor<Complex> contractor(link,link.num_vertices()-1);
-
- if(link.num_connected_components()>1) return 0; //one than more CC -> not contractible
-
- if (link.num_vertices()==1) return 1; //reduced to one point -> contractible
- else return 2; //we dont know
- }
-
-
- double squared_edge_length(Edge_handle e) const{
- return squared_eucl_distance(input_complex_.point(input_complex_.first_vertex(e)),input_complex_.point(input_complex_.second_vertex(e)));
- }
-
- double squared_edge_length(Edge e) const{
- return squared_eucl_distance(input_complex_.point(e.first),input_complex_.point(e.second));
- }
-
-
-
+template<typename SkBlComplex> class Critical_points {
+ private:
+ SkBlComplex filled_complex_;
+ const SkBlComplex& input_complex_;
+ double max_length_;
+ std::ostream& stream_;
+
+ public:
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ typedef typename SkBlComplex::Edge_handle Edge_handle;
+ typedef typename std::pair<Vertex_handle, Vertex_handle> Edge;
+
+ /**
+ * @brief check all pair of points with length smaller than max_length
+ */
+ Critical_points(const SkBlComplex& input_complex, std::ostream& stream, double max_length) :
+ input_complex_(input_complex), max_length_(max_length), stream_(stream) {
+ std::deque<Edge> edges;
+ auto vertices = input_complex.vertex_range();
+ for (auto p = vertices.begin(); p != vertices.end(); ++p) {
+ filled_complex_.add_vertex(input_complex.point(*p));
+ for (auto q = p; ++q != vertices.end(); /**/)
+ if (squared_eucl_distance(input_complex.point(*p), input_complex.point(*q)) < max_length_ * max_length_)
+ edges.emplace_back(*p, *q);
+ }
+
+ std::sort(edges.begin(), edges.end(),
+ [&](Edge e1, Edge e2) {
+ return squared_edge_length(e1) < squared_edge_length(e2);
+ });
+
+ anti_collapse_edges(edges);
+ }
+
+ private:
+ double squared_eucl_distance(const Point& p1, const Point& p2) const {
+ return Geometry_trait::Squared_distance_d()(p1, p2);
+ }
+
+ void anti_collapse_edges(const std::deque<Edge>& edges) {
+ unsigned pos = 0;
+ for (Edge e : edges) {
+ std::cout << "edge " << pos++ << "/" << edges.size() << "\n";
+ auto eh = filled_complex_.add_edge(e.first, e.second);
+ int is_contractible(is_link_reducible(eh));
+
+ switch (is_contractible) {
+ case 0:
+ stream_ << "alpha=" << std::sqrt(squared_edge_length(e)) << " topological change" << std::endl;
+ break;
+ case 2:
+ stream_ << "alpha=" << std::sqrt(squared_edge_length(e)) << " maybe a topological change" << std::endl;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // 0 -> not
+ // 1 -> yes
+ // 2 -> maybe
+
+ int is_link_reducible(Edge_handle e) {
+ auto link = filled_complex_.link(e);
+
+ if (link.empty())
+ return 0;
+
+ Edge_contractor<Complex> contractor(link, link.num_vertices() - 1);
+
+ if (link.num_connected_components() > 1)
+ // one than more CC -> not contractible
+ return 0;
+
+ if (link.num_vertices() == 1)
+ // reduced to one point -> contractible
+ return 1;
+ else
+ // we dont know
+ return 2;
+ }
+
+ double squared_edge_length(Edge_handle e) const {
+ return squared_eucl_distance(input_complex_.point(input_complex_.first_vertex(e)),
+ input_complex_.point(input_complex_.second_vertex(e)));
+ }
+
+ double squared_edge_length(Edge e) const {
+ return squared_eucl_distance(input_complex_.point(e.first), input_complex_.point(e.second));
+ }
};
-
-
-
-
-#endif /* CRITICAL_POINTS_H_ */
+#endif // UTILS_CRITICAL_POINTS_H_
diff --git a/src/GudhUI/utils/Edge_collapsor.h b/src/GudhUI/utils/Edge_collapsor.h
index 4dcd18ac..151e9b01 100644
--- a/src/GudhUI/utils/Edge_collapsor.h
+++ b/src/GudhUI/utils/Edge_collapsor.h
@@ -1,12 +1,28 @@
-/*
- * Collapsor.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 25, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 COLLAPSOR_H_
-#define COLLAPSOR_H_
+#ifndef UTILS_EDGE_COLLAPSOR_H_
+#define UTILS_EDGE_COLLAPSOR_H_
#include <list>
#include "utils/Edge_contractor.h"
@@ -15,71 +31,67 @@
/**
* Iteratively puts every vertex at the center of its neighbors
*/
-template<typename SkBlComplex> class Edge_collapsor{
-private:
- SkBlComplex& complex_;
- unsigned num_collapses_;
-public:
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- typedef typename SkBlComplex::Edge_handle Edge_handle;
-
- /**
- * @brief Collapse num_collapses edges. If num_collapses<0 then it collapses all possible edges.
- * Largest edges are collapsed first.
- *
- */
- Edge_collapsor(SkBlComplex& complex,unsigned num_collapses):
- complex_(complex),num_collapses_(num_collapses)
- {
- std::list<Edge_handle> edges;
- edges.insert(edges.begin(),complex_.edge_range().begin(),complex_.edge_range().end());
-
- edges.sort(
- [&](Edge_handle e1,Edge_handle e2){
- return squared_edge_length(e1) < squared_edge_length(e2);
- });
-
- collapse_edges(edges);
-
- }
-
-private:
-
- void collapse_edges(std::list<Edge_handle>& edges){
- while(!edges.empty() && num_collapses_--){
- Edge_handle current_edge = edges.front();
- edges.pop_front();
- if(is_link_reducible(current_edge))
- complex_.remove_edge(current_edge);
- }
-
- }
-
- bool is_link_reducible(Edge_handle e){
- auto link = complex_.link(e);
-
- if(link.empty()) return false;
-
- if(link.is_cone()) return true;
-
- if(link.num_connected_components()>1) return false;
-
- Edge_contractor<SkBlComplex> contractor(link,link.num_vertices()-1);
-
- return (link.num_vertices()==1);
- }
-
-
- double squared_edge_length(Edge_handle e) const{
- return squared_eucl_distance(complex_.point(complex_.first_vertex(e)),complex_.point(complex_.second_vertex(e)));
- }
-
- double squared_eucl_distance(const Point& p1,const Point& p2) const{
- return Geometry_trait::Squared_distance_d()(p1,p2);
- }
-
+template<typename SkBlComplex> class Edge_collapsor {
+ private:
+ SkBlComplex& complex_;
+ unsigned num_collapses_;
+
+ public:
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ typedef typename SkBlComplex::Edge_handle Edge_handle;
+
+ /**
+ * @brief Collapse num_collapses edges. If num_collapses<0 then it collapses all possible edges.
+ * Largest edges are collapsed first.
+ *
+ */
+ Edge_collapsor(SkBlComplex& complex, unsigned num_collapses) :
+ complex_(complex), num_collapses_(num_collapses) {
+ std::list<Edge_handle> edges;
+ edges.insert(edges.begin(), complex_.edge_range().begin(), complex_.edge_range().end());
+
+ edges.sort(
+ [&](Edge_handle e1, Edge_handle e2) {
+ return squared_edge_length(e1) < squared_edge_length(e2);
+ });
+
+ collapse_edges(edges);
+ }
+
+ private:
+ void collapse_edges(std::list<Edge_handle>& edges) {
+ while (!edges.empty() && num_collapses_--) {
+ Edge_handle current_edge = edges.front();
+ edges.pop_front();
+ if (is_link_reducible(current_edge))
+ complex_.remove_edge(current_edge);
+ }
+ }
+
+ bool is_link_reducible(Edge_handle e) {
+ auto link = complex_.link(e);
+
+ if (link.empty())
+ return false;
+
+ if (link.is_cone())
+ return true;
+
+ if (link.num_connected_components() > 1)
+ return false;
+
+ Edge_contractor<SkBlComplex> contractor(link, link.num_vertices() - 1);
+
+ return (link.num_vertices() == 1);
+ }
+
+ double squared_edge_length(Edge_handle e) const {
+ return squared_eucl_distance(complex_.point(complex_.first_vertex(e)), complex_.point(complex_.second_vertex(e)));
+ }
+
+ double squared_eucl_distance(const Point& p1, const Point& p2) const {
+ return Geometry_trait::Squared_distance_d()(p1, p2);
+ }
};
-
-
-#endif /* COLLAPSOR_H_ */
+#endif // UTILS_EDGE_COLLAPSOR_H_
diff --git a/src/GudhUI/utils/Edge_contractor.h b/src/GudhUI/utils/Edge_contractor.h
index d0a1f866..45079a40 100644
--- a/src/GudhUI/utils/Edge_contractor.h
+++ b/src/GudhUI/utils/Edge_contractor.h
@@ -1,85 +1,97 @@
-/*
- * Contractor.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 25, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 EDGE_CONTRACTOR_H_
-#define EDGE_CONTRACTOR_H_
+#ifndef UTILS_EDGE_CONTRACTOR_H_
+#define UTILS_EDGE_CONTRACTOR_H_
-#include "gudhi/Skeleton_blocker_contractor.h"
-
-#include "gudhi/Contraction/Edge_profile.h"
-#include "gudhi/Contraction/policies/Cost_policy.h"
+#include <gudhi/Skeleton_blocker_contractor.h>
+#include <gudhi/Contraction/Edge_profile.h>
+#include <gudhi/Contraction/policies/Cost_policy.h>
+#include <vector>
/**
* Iteratively puts every vertex at the center of its neighbors
*/
-template<typename SkBlComplex> class Edge_contractor{
-private:
- SkBlComplex& complex_;
- unsigned num_contractions_;
-
- /**
- * @brief return a cost corresponding to the squared length of the edge
- */
- template< typename EdgeProfile> class Length_cost : public contraction::Cost_policy<EdgeProfile>{
- public:
- typedef typename contraction::Cost_policy<EdgeProfile>::Cost_type Cost_type;
- typedef typename EdgeProfile::Point Point;
- Cost_type operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const override{
- Cost_type res;
- if(!placement) return res;
- return Geometry_trait::Squared_distance_d()(profile.p0(),profile.p1()); //not working??
- }
- };
-
-
- /**
- * @brief return a cost corresponding to the squared length of the edge
- */
- template< typename EdgeProfile> class Middle_placement : public contraction::Placement_policy<EdgeProfile>{
- public:
- typedef typename contraction::Placement_policy<EdgeProfile>::Placement_type Placement_type;
- typedef typename EdgeProfile::Point Point;
- Placement_type operator()(const EdgeProfile& profile) const override{
- std::vector<double> mid_coords(profile.p0().dimension(),0);
- for (size_t i = 0; i < profile.p0().dimension(); ++i){
- mid_coords[i] = (profile.p0()[i] + profile.p1()[i]) / 2.;
- }
- return Point(profile.p0().dimension(),mid_coords.begin(), mid_coords.end());
- }
- };
-
- public:
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- typedef typename SkBlComplex::Edge_handle Edge_handle;
-
- /**
- * @brief Modify complex to be the expansion of the k-nearest neighbor
- * symetric graph.
- */
- Edge_contractor(SkBlComplex& complex,unsigned num_contractions):
- complex_(complex),num_contractions_(num_contractions)
- {
- typedef typename contraction::Edge_profile<Complex> Profile;
- num_contractions = (std::min)((int)num_contractions,(int)(complex_.num_vertices()-1));
- contraction::Skeleton_blocker_contractor<Complex> contractor(
- complex_,
- new Length_cost<contraction::Edge_profile<Complex>>(),
- new Middle_placement<contraction::Edge_profile<Complex>>(),
- contraction::make_link_valid_contraction<Profile>(),
- contraction::make_remove_popable_blockers_visitor<Profile>()
- );
- contractor.contract_edges(num_contractions);
- }
-
-
+template<typename SkBlComplex> class Edge_contractor {
+ private:
+ SkBlComplex& complex_;
+ unsigned num_contractions_;
+
+ /**
+ * @brief return a cost corresponding to the squared length of the edge
+ */
+ template< typename EdgeProfile> class Length_cost : public contraction::Cost_policy<EdgeProfile> {
+ public:
+ typedef typename contraction::Cost_policy<EdgeProfile>::Cost_type Cost_type;
+ typedef typename EdgeProfile::Point Point;
+
+ Cost_type operator()(const EdgeProfile& profile, const boost::optional<Point>& placement) const override {
+ Cost_type res;
+ if (!placement)
+ return res;
+ return Geometry_trait::Squared_distance_d()(profile.p0(), profile.p1()); // not working??
+ }
+ };
+
+ /**
+ * @brief return a cost corresponding to the squared length of the edge
+ */
+ template< typename EdgeProfile> class Middle_placement : public contraction::Placement_policy<EdgeProfile> {
+ public:
+ typedef typename contraction::Placement_policy<EdgeProfile>::Placement_type Placement_type;
+ typedef typename EdgeProfile::Point Point;
+
+ Placement_type operator()(const EdgeProfile& profile) const override {
+ std::vector<double> mid_coords(profile.p0().dimension(), 0);
+ for (size_t i = 0; i < profile.p0().dimension(); ++i) {
+ mid_coords[i] = (profile.p0()[i] + profile.p1()[i]) / 2.;
+ }
+ return Point(profile.p0().dimension(), mid_coords.begin(), mid_coords.end());
+ }
+ };
+
+ public:
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ typedef typename SkBlComplex::Edge_handle Edge_handle;
+
+ /**
+ * @brief Modify complex to be the expansion of the k-nearest neighbor
+ * symetric graph.
+ */
+ Edge_contractor(SkBlComplex& complex, unsigned num_contractions) :
+ complex_(complex), num_contractions_(num_contractions) {
+ typedef typename contraction::Edge_profile<Complex> Profile;
+ num_contractions = (std::min)(static_cast<int>(num_contractions), static_cast<int>(complex_.num_vertices() - 1));
+ typedef typename contraction::Skeleton_blocker_contractor<Complex> Contractor;
+ Contractor contractor(complex_,
+ new Length_cost<contraction::Edge_profile < Complex >> (),
+ new Middle_placement<contraction::Edge_profile < Complex >> (),
+ contraction::make_link_valid_contraction<Profile>(),
+ contraction::make_remove_popable_blockers_visitor<Profile>());
+ contractor.contract_edges(num_contractions);
+ }
};
-
-
-#endif /* EDGE_CONTRACTOR_H_ */
+#endif // UTILS_EDGE_CONTRACTOR_H_
diff --git a/src/GudhUI/utils/Furthest_point_epsilon_net.h b/src/GudhUI/utils/Furthest_point_epsilon_net.h
index 590b65c4..f2a216f6 100644
--- a/src/GudhUI/utils/Furthest_point_epsilon_net.h
+++ b/src/GudhUI/utils/Furthest_point_epsilon_net.h
@@ -1,134 +1,132 @@
-/*
- * Furthest_point_epsilon_net.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 26, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 FURTHEST_POINT_EPSILON_NET_H_
-#define FURTHEST_POINT_EPSILON_NET_H_
+#ifndef UTILS_FURTHEST_POINT_EPSILON_NET_H_
+#define UTILS_FURTHEST_POINT_EPSILON_NET_H_
-#include "utils/UI_utils.h"
#include <vector>
+#include <algorithm> // for sort
+
+#include "utils/UI_utils.h"
/**
* Computes an epsilon net with furthest point strategy.
*/
-template<typename SkBlComplex> class Furthest_point_epsilon_net{
-private:
- SkBlComplex& complex_;
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- typedef typename SkBlComplex::Edge_handle Edge_handle;
-
- /**
- * Let V be the set of vertices.
- * Initially v0 is one arbitrarly vertex and the set V0 is {v0}.
- * Then Vk is computed as follows.
- * First we compute the vertex pk that is the furthest from Vk
- * then Vk = Vk \cup pk.
- * The radius of pk is its distance to Vk and its meeting vertex
- * is the vertex of Vk for which this distance is achieved.
- */
- struct Net_filtration_vertex{
- Vertex_handle vertex_handle;
- Vertex_handle meeting_vertex;
- double radius;
-
-
- Net_filtration_vertex(
- Vertex_handle vertex_handle_,
- Vertex_handle meeting_vertex_,
- double radius_):
- vertex_handle(vertex_handle_),meeting_vertex(meeting_vertex_),radius(radius_)
- {}
-
- bool operator<(const Net_filtration_vertex& other ) const{
- return radius < other.radius;
- }
-
- };
-
-public:
-
-
- std::vector<Net_filtration_vertex> net_filtration_;
-
- /**
- * @brief Modify complex to be the expansion of the k-nearest neighbor
- * symetric graph.
- */
- Furthest_point_epsilon_net(SkBlComplex& complex):
- complex_(complex)
- {
- if(!complex.empty()){
- init_filtration();
- for(int k = 2; k < net_filtration_.size(); ++k){
- update_radius_value(k);
- }
- }
- }
-
- //xxx does not work if complex not full
- double radius(Vertex_handle v){
- return net_filtration_[v.vertex].radius;
- }
-
-
-
-
-private:
-
- void init_filtration(){
- Vertex_handle v0 = *(complex_.vertex_range().begin());
- net_filtration_.reserve(complex_.num_vertices());
- for(auto v : complex_.vertex_range()){
- if(v != v0)
- net_filtration_.push_back(
- Net_filtration_vertex(v,
- Vertex_handle(-1),
- squared_eucl_distance(v,v0))
- );
- }
- net_filtration_.push_back(Net_filtration_vertex(v0,Vertex_handle(-1),1e10));
- auto n = net_filtration_.size();
- sort_filtration(n-1);
- }
-
- void update_radius_value(int k){
- int n = net_filtration_.size();
- int index_to_update = n-k;
- for(int i = 0; i< index_to_update; ++i){
- net_filtration_[i].radius = (std::min)(net_filtration_[i].radius ,
- squared_eucl_distance(
- net_filtration_[i].vertex_handle,
- net_filtration_[index_to_update].vertex_handle
- )
- );
- }
- sort_filtration(n-k);
- }
-
- /**
- * sort all i first elements.
- */
- void sort_filtration(int i){
- std::sort(net_filtration_.begin(),net_filtration_.begin()+ i);
- }
-
- double squared_eucl_distance(Vertex_handle v1,Vertex_handle v2) const{
- return std::sqrt(Geometry_trait::Squared_distance_d()(
- complex_.point(v1),complex_.point(v2))
- );
- }
-
- void print_filtration() const{
- for(auto v : net_filtration_){
- std::cerr <<"v="<<v.vertex_handle<<"-> d="<<v.radius<<std::endl;
- }
- }
-
+template<typename SkBlComplex> class Furthest_point_epsilon_net {
+ private:
+ SkBlComplex& complex_;
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ typedef typename SkBlComplex::Edge_handle Edge_handle;
+
+ /**
+ * Let V be the set of vertices.
+ * Initially v0 is one arbitrarly vertex and the set V0 is {v0}.
+ * Then Vk is computed as follows.
+ * First we compute the vertex pk that is the furthest from Vk
+ * then Vk = Vk \cup pk.
+ * The radius of pk is its distance to Vk and its meeting vertex
+ * is the vertex of Vk for which this distance is achieved.
+ */
+ struct Net_filtration_vertex {
+ Vertex_handle vertex_handle;
+ Vertex_handle meeting_vertex;
+ double radius;
+
+ Net_filtration_vertex(Vertex_handle vertex_handle_,
+ Vertex_handle meeting_vertex_,
+ double radius_) :
+ vertex_handle(vertex_handle_), meeting_vertex(meeting_vertex_), radius(radius_) { }
+
+ bool operator<(const Net_filtration_vertex& other) const {
+ return radius < other.radius;
+ }
+ };
+
+ public:
+ std::vector<Net_filtration_vertex> net_filtration_;
+
+ /**
+ * @brief Modify complex to be the expansion of the k-nearest neighbor
+ * symetric graph.
+ */
+ Furthest_point_epsilon_net(SkBlComplex& complex) :
+ complex_(complex) {
+ if (!complex.empty()) {
+ init_filtration();
+ for (int k = 2; k < net_filtration_.size(); ++k) {
+ update_radius_value(k);
+ }
+ }
+ }
+
+ // xxx does not work if complex not full
+
+ double radius(Vertex_handle v) {
+ return net_filtration_[v.vertex].radius;
+ }
+
+ private:
+ void init_filtration() {
+ Vertex_handle v0 = *(complex_.vertex_range().begin());
+ net_filtration_.reserve(complex_.num_vertices());
+ for (auto v : complex_.vertex_range()) {
+ if (v != v0)
+ net_filtration_.push_back(Net_filtration_vertex(v,
+ Vertex_handle(-1),
+ squared_eucl_distance(v, v0)));
+ }
+ net_filtration_.push_back(Net_filtration_vertex(v0, Vertex_handle(-1), 1e10));
+ auto n = net_filtration_.size();
+ sort_filtration(n - 1);
+ }
+
+ void update_radius_value(int k) {
+ int n = net_filtration_.size();
+ int index_to_update = n - k;
+ for (int i = 0; i < index_to_update; ++i) {
+ net_filtration_[i].radius = (std::min)(net_filtration_[i].radius,
+ squared_eucl_distance(net_filtration_[i].vertex_handle,
+ net_filtration_[index_to_update].vertex_handle));
+ }
+ sort_filtration(n - k);
+ }
+
+ /**
+ * sort all i first elements.
+ */
+ void sort_filtration(int i) {
+ std::sort(net_filtration_.begin(), net_filtration_.begin() + i);
+ }
+
+ double squared_eucl_distance(Vertex_handle v1, Vertex_handle v2) const {
+ return std::sqrt(Geometry_trait::Squared_distance_d()(complex_.point(v1), complex_.point(v2)));
+ }
+
+ void print_filtration() const {
+ for (auto v : net_filtration_) {
+ std::cerr << "v=" << v.vertex_handle << "-> d=" << v.radius << std::endl;
+ }
+ }
};
-
-
-#endif /* FURTHEST_POINT_EPSILON_NET_H_ */
+#endif // UTILS_FURTHEST_POINT_EPSILON_NET_H_
diff --git a/src/GudhUI/utils/Is_manifold.h b/src/GudhUI/utils/Is_manifold.h
index e708a6a4..0640ea47 100644
--- a/src/GudhUI/utils/Is_manifold.h
+++ b/src/GudhUI/utils/Is_manifold.h
@@ -7,7 +7,7 @@
*
* Author(s): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -25,11 +25,10 @@
*/
-#ifndef IS_MANIFOLD_H_
-#define IS_MANIFOLD_H_
+#ifndef UTILS_IS_MANIFOLD_H_
+#define UTILS_IS_MANIFOLD_H_
#include "utils/UI_utils.h"
-
#include "utils/Edge_contractor.h"
/**
@@ -38,67 +37,67 @@
*
* todo do a sparsification with some parameter eps while growing
*/
-template<typename SkBlComplex> class Is_manifold{
-private:
- const SkBlComplex& input_complex_;
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+template<typename SkBlComplex> class Is_manifold {
+ private:
+ const SkBlComplex& input_complex_;
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ public:
+ /*
+ * return dim the maximum dimension around one simplex and res which is true if the complex is a manifold.
+ * If the complex has dimension <= 3 then if res is false, the complex is not a manifold.
+ * For d-manifold with d>=4, res may be false while the complex is a manifold.
+ */
+ Is_manifold(const SkBlComplex& input_complex, unsigned& dim, bool & res) : input_complex_(input_complex) {
+ res = true;
+ dim = -1;
+ if (!input_complex_.empty()) {
+ for (auto v : input_complex_.vertex_range()) {
+ dim = local_dimension(v);
+ break;
+ }
+ // check that the link of every vertex is a dim-1 sphere
+ for (auto v : input_complex_.vertex_range()) {
+ if (!is_k_sphere(v, dim - 1)) {
+ res = false;
+ break;
+ }
+ }
+ }
+ }
-public:
- /*
- * return dim the maximum dimension around one simplex and res which is true if the complex is a manifold.
- * If the complex has dimension <= 3 then if res is false, the complex is not a manifold.
- * For d-manifold with d>=4, res may be false while the complex is a manifold.
- */
- Is_manifold(const SkBlComplex& input_complex,unsigned& dim,bool & res):input_complex_(input_complex){
- res = true;
- dim = -1;
- if(!input_complex_.empty()){
- for(auto v : input_complex_.vertex_range()){
- dim = local_dimension(v);
- break;
- }
- //check that the link of every vertex is a dim-1 sphere
- for(auto v : input_complex_.vertex_range()){
- if(!is_k_sphere(v,dim-1)) {
- res = false;
- break;
- }
- }
- }
- }
+ private:
+ unsigned local_dimension(Vertex_handle v) {
+ unsigned dim = 0;
+ for (const auto& s : input_complex_.star_simplex_range(v))
+ dim = (std::max)(dim, (unsigned) s.dimension());
+ return dim;
+ }
-private:
- unsigned local_dimension(Vertex_handle v){
- unsigned dim = 0;
- for(const auto& s: input_complex_.simplex_range(v))
- dim = (std::max)(dim,(unsigned)s.dimension());
- return dim;
- }
+ bool is_k_sphere(Vertex_handle v, int k) {
+ auto link = input_complex_.link(v);
+ Edge_contractor<Complex> contractor(link, link.num_vertices() - 1);
+ return (is_sphere_simplex(link) == k);
+ }
- bool is_k_sphere(Vertex_handle v,int k){
- auto link = input_complex_.link(v);
- Edge_contractor<Complex> contractor(link,link.num_vertices()-1);
- return (is_sphere_simplex(link)==k);
- }
+ // A minimal sphere is a complex that contains vertices v1...vn and all faces
+ // made upon this set except the face {v1,...,vn}
+ // return -2 if not a minimal sphere
+ // and d otherwise if complex is a d minimal sphere
- // A minimal sphere is a complex that contains vertices v1...vn and all faces
- // made upon this set except the face {v1,...,vn}
- // return -2 if not a minimal sphere
- // and d otherwise if complex is a d minimal sphere
- template<typename SubComplex>
- int is_sphere_simplex(const SubComplex& complex){
- if(complex.empty()) return -1;
- if(complex.num_blockers()!=1) return -2;
+ template<typename SubComplex>
+ int is_sphere_simplex(const SubComplex& complex) {
+ if (complex.empty()) return -1;
+ if (complex.num_blockers() != 1) return -2;
- //necessary and sufficient condition : there exists a unique blocker that passes through all vertices
- auto first_blocker = *(complex.const_blocker_range().begin());
+ // necessary and sufficient condition : there exists a unique blocker that passes through all vertices
+ auto first_blocker = *(complex.const_blocker_range().begin());
- if (first_blocker->dimension()+1 != complex.num_vertices())
- return -2;
- else
- return (first_blocker->dimension()-1);
- }
+ if (first_blocker->dimension() + 1 != complex.num_vertices())
+ return -2;
+ else
+ return (first_blocker->dimension() - 1);
+ }
};
-#endif /* IS_MANIFOLD_H_ */
+#endif // UTILS_IS_MANIFOLD_H_
diff --git a/src/GudhUI/utils/K_nearest_builder.h b/src/GudhUI/utils/K_nearest_builder.h
index b65a79e0..cab24b7c 100644
--- a/src/GudhUI/utils/K_nearest_builder.h
+++ b/src/GudhUI/utils/K_nearest_builder.h
@@ -1,81 +1,92 @@
-/*
- * K_nearest_builder.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 10, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 K_NEAREST_BUILDER_H_
-#define K_NEAREST_BUILDER_H_
+#ifndef UTILS_K_NEAREST_BUILDER_H_
+#define UTILS_K_NEAREST_BUILDER_H_
-#include <unordered_map>
-#include <boost/iterator/iterator_facade.hpp>
#include <CGAL/Euclidean_distance.h>
#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_d.h>
#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
+#include <CGAL/property_map.h>
+#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/zip_iterator.hpp>
+#include <unordered_map>
+#include <tuple>
+#include <list>
+
#include "utils/UI_utils.h"
#include "model/Complex_typedefs.h"
-
-
-template<typename SkBlComplex> class K_nearest_builder{
-private:
-
- typedef Geometry_trait Kernel;
- typedef Point Point_d;
- typedef boost::tuple<Point_d, unsigned> Point_d_with_id;
- typedef CGAL::Search_traits_d<Kernel> Traits_base;
- typedef CGAL::Search_traits_adapter<Point_d_with_id, CGAL::Nth_of_tuple_property_map<0, Point_d_with_id>, Traits_base> Traits;
- typedef CGAL::Orthogonal_k_neighbor_search<Traits> Neighbor_search;
- typedef Neighbor_search::Tree Tree;
- typedef Neighbor_search::Distance Distance;
-
- SkBlComplex& complex_;
-public:
-
- /**
- * @brief Modify complex to be the expansion of the k-nearest neighbor
- * symetric graph.
- */
- K_nearest_builder(SkBlComplex& complex,unsigned k):complex_(complex){
- complex.keep_only_vertices();
- compute_edges(k);
- }
-
-private:
-
-
-
- double squared_eucl_distance(const Point& p1,const Point& p2) const{
- return Geometry_trait::Squared_distance_d()(p1,p2);
- }
-
- void compute_edges(unsigned k){
-
- std::list<Point_d_with_id> points_with_id;
- for(auto v: complex_.vertex_range()){
- Point_d_with_id point_v(complex_.point(v),v.vertex);
- points_with_id.push_back(point_v);
- }
-
- Tree tree(points_with_id.begin(),points_with_id.end());
-
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- for (auto p : complex_.vertex_range()){
- Neighbor_search search(tree, complex_.point(p),k+1);
- for(auto it = ++search.begin(); it != search.end(); ++it){
- Vertex_handle q(boost::get<1>(it->first));
- if (p != q && complex_.contains_vertex(p) && complex_.contains_vertex(q))
- complex_.add_edge(p,q);
- }
- }
- }
-
-
+template<typename SkBlComplex> class K_nearest_builder {
+ private:
+ typedef Geometry_trait Kernel;
+ typedef Point Point_d;
+ typedef boost::tuple<Point_d, unsigned> Point_d_with_id;
+ typedef CGAL::Search_traits_d<Kernel> Traits_base;
+ typedef CGAL::Search_traits_adapter<Point_d_with_id, CGAL::Nth_of_tuple_property_map<0, Point_d_with_id>,
+ Traits_base> Traits;
+ typedef CGAL::Orthogonal_k_neighbor_search<Traits> Neighbor_search;
+ typedef Neighbor_search::Tree Tree;
+ typedef Neighbor_search::Distance Distance;
+
+ SkBlComplex& complex_;
+
+ public:
+ /**
+ * @brief Modify complex to be the expansion of the k-nearest neighbor
+ * symetric graph.
+ */
+ K_nearest_builder(SkBlComplex& complex, unsigned k) : complex_(complex) {
+ complex.keep_only_vertices();
+ compute_edges(k);
+ }
+
+ private:
+ double squared_eucl_distance(const Point& p1, const Point& p2) const {
+ return Geometry_trait::Squared_distance_d()(p1, p2);
+ }
+
+ void compute_edges(unsigned k) {
+ std::list<Point_d_with_id> points_with_id;
+ for (auto v : complex_.vertex_range()) {
+ Point_d_with_id point_v(complex_.point(v), v.vertex);
+ points_with_id.push_back(point_v);
+ }
+
+ Tree tree(points_with_id.begin(), points_with_id.end());
+
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ for (auto p : complex_.vertex_range()) {
+ Neighbor_search search(tree, complex_.point(p), k + 1);
+ for (auto it = ++search.begin(); it != search.end(); ++it) {
+ Vertex_handle q(boost::get<1>(it->first));
+ if (p != q && complex_.contains_vertex(p) && complex_.contains_vertex(q))
+ complex_.add_edge(p, q);
+ }
+ }
+ }
};
-#endif /* K_NEAREST_BUILDER_H_ */
+#endif // UTILS_K_NEAREST_BUILDER_H_
diff --git a/src/GudhUI/utils/Lloyd_builder.h b/src/GudhUI/utils/Lloyd_builder.h
index db2a7973..18ec9fac 100644
--- a/src/GudhUI/utils/Lloyd_builder.h
+++ b/src/GudhUI/utils/Lloyd_builder.h
@@ -1,78 +1,91 @@
-/*
- * Lloyd.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 25, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 LLOYD_H_
-#define LLOYD_H_
-
+#ifndef UTILS_LLOYD_BUILDER_H_
+#define UTILS_LLOYD_BUILDER_H_
#include <vector>
+#include <list>
/**
* Iteratively puts every vertex at the center of its neighbors
*/
-template<typename SkBlComplex> class Lloyd_builder{
-private:
- SkBlComplex& complex_;
- int dim;
-public:
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- /**
- * @brief Modify complex to be the expansion of the k-nearest neighbor
- * symetric graph.
- */
- Lloyd_builder(SkBlComplex& complex,unsigned num_iterations):complex_(complex),dim(-1){
- if(!complex_.empty()){
- dim = get_dimension();
- while(num_iterations--){
- std::list<Point> new_points;
- for(auto v : complex.vertex_range())
- new_points.push_back(barycenter_neighbors(v));
-
- auto new_points_it = new_points.begin();
- for(auto v : complex.vertex_range())
- complex_.point(v) = *(new_points_it++);
- }
- }
- }
+template<typename SkBlComplex> class Lloyd_builder {
+ private:
+ SkBlComplex& complex_;
+ int dim;
-private:
+ public:
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- int get_dimension(){
- assert(!complex_.empty());
- for(auto v : complex_.vertex_range())
- return complex_.point(v).dimension();
- return -1;
- }
+ /**
+ * @brief Modify complex to be the expansion of the k-nearest neighbor
+ * symetric graph.
+ */
+ Lloyd_builder(SkBlComplex& complex, unsigned num_iterations) : complex_(complex), dim(-1) {
+ if (!complex_.empty()) {
+ dim = get_dimension();
+ while (num_iterations--) {
+ std::list<Point> new_points;
+ for (auto v : complex.vertex_range())
+ new_points.push_back(barycenter_neighbors(v));
- Point barycenter_neighbors(Vertex_handle v) const{
- if(complex_.degree(v)==0)
- return complex_.point(v);
+ auto new_points_it = new_points.begin();
+ for (auto v : complex.vertex_range())
+ complex_.point(v) = *(new_points_it++);
+ }
+ }
+ }
- std::vector<double> res(dim,0);
- unsigned num_points = 0;
- for(auto nv : complex_.vertex_range(v)){
- ++num_points;
- const Point& point = complex_.point(nv);
- assert(point.dimension() == dim);
- for(int i = 0; i < point.dimension() ; ++i)
- res[i] += point[i];
- }
- for(auto& x : res)
- x/= num_points;
- return Point(dim,res.begin(),res.end());
- }
+ private:
+ int get_dimension() {
+ assert(!complex_.empty());
+ for (auto v : complex_.vertex_range())
+ return complex_.point(v).dimension();
+ return -1;
+ }
+ Point barycenter_neighbors(Vertex_handle v) const {
+ if (complex_.degree(v) == 0)
+ return complex_.point(v);
+ std::vector<double> res(dim, 0);
+ unsigned num_points = 0;
+ for (auto nv : complex_.vertex_range(v)) {
+ ++num_points;
+ const Point& point = complex_.point(nv);
+ assert(point.dimension() == dim);
+ for (int i = 0; i < point.dimension(); ++i)
+ res[i] += point[i];
+ }
+ for (auto& x : res)
+ x /= num_points;
+ return Point(dim, res.begin(), res.end());
+ }
- double squared_eucl_distance(const Point& p1,const Point& p2) const{
- return Geometry_trait::Squared_distance_d()(p1,p2);
- }
-
+ double squared_eucl_distance(const Point& p1, const Point& p2) const {
+ return Geometry_trait::Squared_distance_d()(p1, p2);
+ }
};
-
-#endif /* LLOYD_H_ */
+#endif // UTILS_LLOYD_BUILDER_H_
diff --git a/src/GudhUI/utils/MClock.h b/src/GudhUI/utils/MClock.h
index b5c7d191..e8d8918a 100644
--- a/src/GudhUI/utils/MClock.h
+++ b/src/GudhUI/utils/MClock.h
@@ -1,57 +1,70 @@
-/*
- * Clock.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Jun 17, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CLOCK_H_
-#define CLOCK_H_
+#ifndef UTILS_MCLOCK_H_
+#define UTILS_MCLOCK_H_
#include <sys/time.h>
+class MClock {
+ public:
+ MClock() {
+ end_called = false;
+ begin();
+ }
-class MClock{
-
-public:
- MClock(){
- end_called = false;
- begin();
- }
-
- void begin() const{
- end_called = false;
- gettimeofday(&startTime, NULL);
- }
-
- void end() const{
- end_called = true;
- gettimeofday(&endTime, NULL);
- }
-
- friend std::ostream& operator<< (std::ostream& stream,const MClock& clock){
- // if(!clock.end_called) clock.end();
- if(!clock.end_called) stream << "end not called";
- else{
- long totalTime = (clock.endTime.tv_sec - clock.startTime.tv_sec) * 1000000L;
- totalTime += (clock.endTime.tv_usec - clock.startTime.tv_usec);
- stream << clock.num_seconds() <<"s";
- }
- return stream;
-
- }
-
- double num_seconds() const{
- if(!end_called) end();
- long totalTime = (endTime.tv_sec - startTime.tv_sec) * 1000000L;
- totalTime += (endTime.tv_usec - startTime.tv_usec);
- return (totalTime / 1000L)/(double) 1000;
- }
-
-private:
- mutable struct timeval startTime, endTime;
- mutable bool end_called;
-};
+ void begin() const {
+ end_called = false;
+ gettimeofday(&startTime, NULL);
+ }
+ void end() const {
+ end_called = true;
+ gettimeofday(&endTime, NULL);
+ }
+
+ friend std::ostream& operator<<(std::ostream& stream, const MClock& clock) {
+ // if(!clock.end_called) clock.end();
+ if (!clock.end_called) {
+ stream << "end not called";
+ } else {
+ long totalTime = (clock.endTime.tv_sec - clock.startTime.tv_sec) * 1000000L;
+ totalTime += (clock.endTime.tv_usec - clock.startTime.tv_usec);
+ stream << clock.num_seconds() << "s";
+ }
+ return stream;
+ }
+
+ double num_seconds() const {
+ if (!end_called) end();
+ long totalTime = (endTime.tv_sec - startTime.tv_sec) * 1000000L;
+ totalTime += (endTime.tv_usec - startTime.tv_usec);
+ return (totalTime / 1000L) / static_cast<double>(1000);
+ }
+
+ private:
+ mutable struct timeval startTime, endTime;
+ mutable bool end_called;
+};
-#endif /* CLOCK_H_ */
+#endif // UTILS_MCLOCK_H_
diff --git a/src/GudhUI/utils/Persistence_compute.h b/src/GudhUI/utils/Persistence_compute.h
index 50d340b8..0b9961d3 100644
--- a/src/GudhUI/utils/Persistence_compute.h
+++ b/src/GudhUI/utils/Persistence_compute.h
@@ -1,13 +1,10 @@
-/*
- * Persistence_compute.h
- * Created on: Jan 26, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -25,83 +22,76 @@
*/
-#ifndef PERSISTENCE_COMPUTE_H_
-#define PERSISTENCE_COMPUTE_H_
+#ifndef UTILS_PERSISTENCE_COMPUTE_H_
+#define UTILS_PERSISTENCE_COMPUTE_H_
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Persistent_cohomology.h>
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/distance_functions.h"
-#include "gudhi/Persistent_cohomology.h"
+#include <vector>
+struct Persistence_params {
+ int p;
+ double threshold;
+ int max_dim;
+ double min_pers;
-struct Persistence_params{
- int p;
- double threshold;
- int max_dim;
- double min_pers;
-
- Persistence_params(int p_,double th_,int max_dim_=10,double min_pers_=0)
- :p(p_),threshold(th_),max_dim(max_dim_),min_pers(min_pers_){}
+ Persistence_params(int p_, double th_, int max_dim_ = 10, double min_pers_ = 0)
+ : p(p_), threshold(th_), max_dim(max_dim_), min_pers(min_pers_) { }
};
-
/**
* Show persistence into output stream
*/
-template<typename SkBlComplex> class Persistence_compute{
-private:
- SkBlComplex& complex_;
- std::ostream& stream_;
-public:
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- typedef typename SkBlComplex::Edge_handle Edge_handle;
-
- /**
- * @brief Compute persistence
- * parameters :
- * unsigned dim_max
- * double threshold
- * int p for coefficient Z_p
- */
- Persistence_compute(SkBlComplex& complex,std::ostream& stream,const Persistence_params& params):
-//
-// double threshold = 0.5,unsigned dim_max = 8):
- complex_(complex),stream_(stream){
-
- //for now everything is copied, todo boost adapt iterators to points of SkBlComplex instead of copying to an intial vector
- typedef std::vector<double> Point_t;
- std::vector< Point_t > points;
- points.reserve(complex.num_vertices());
- for(auto v : complex.vertex_range()){
- const auto & pt = complex.point(v);
- Point_t pt_to_add(pt.cartesian_begin(),pt.cartesian_end());
- points.emplace_back(std::move(pt_to_add));
- }
-
-
- Graph_t prox_graph = compute_proximity_graph( points, params.threshold, euclidean_distance<Point_t> );
- Gudhi::Simplex_tree<> st;
- st.insert_graph(prox_graph);
- st.expansion( params.max_dim );
-
- Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::Simplex_tree<>,Gudhi::persistent_cohomology::Field_Zp > pcoh (st);
- pcoh.init_coefficients( params.p ); //initilizes the coefficient field for homology
- pcoh.compute_persistent_cohomology( params.min_pers ); //put params.min_pers
- stream_<<"persistence: \n";
- stream_<<"p dimension birth death: \n";
-
- pcoh.output_diagram(stream_);
- }
-
-private:
-
-
+template<typename SkBlComplex> class Persistence_compute {
+ private:
+ SkBlComplex& complex_;
+ std::ostream& stream_;
+
+ public:
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ typedef typename SkBlComplex::Edge_handle Edge_handle;
+
+ /**
+ * @brief Compute persistence
+ * parameters :
+ * unsigned dim_max
+ * double threshold
+ * int p for coefficient Z_p
+ */
+ Persistence_compute(SkBlComplex& complex, std::ostream& stream, const Persistence_params& params) :
+ // double threshold = 0.5,unsigned dim_max = 8):
+ complex_(complex), stream_(stream) {
+ // for now everything is copied, todo boost adapt iterators to points of SkBlComplex instead of copying to an
+ // initial vector
+ typedef std::vector<double> Point_t;
+ std::vector< Point_t > points;
+ points.reserve(complex.num_vertices());
+ for (auto v : complex.vertex_range()) {
+ const auto & pt = complex.point(v);
+ Point_t pt_to_add(pt.cartesian_begin(), pt.cartesian_end());
+ points.emplace_back(std::move(pt_to_add));
+ }
+
+
+ Graph_t prox_graph = compute_proximity_graph(points, params.threshold, euclidean_distance<Point_t>);
+ Gudhi::Simplex_tree<> st;
+ st.insert_graph(prox_graph);
+ st.expansion(params.max_dim);
+
+ Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::Simplex_tree<>,
+ Gudhi::persistent_cohomology::Field_Zp > pcoh(st);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(params.p);
+ // put params.min_pers
+ pcoh.compute_persistent_cohomology(params.min_pers);
+ stream_ << "persistence: \n";
+ stream_ << "p dimension birth death: \n";
+
+ pcoh.output_diagram(stream_);
+ }
};
-
-
-
-
-
-#endif /* PERSISTENCE_COMPUTE_H_ */
+#endif // UTILS_PERSISTENCE_COMPUTE_H_
diff --git a/src/GudhUI/utils/Rips_builder.h b/src/GudhUI/utils/Rips_builder.h
index 9484f9ab..b22f4db6 100644
--- a/src/GudhUI/utils/Rips_builder.h
+++ b/src/GudhUI/utils/Rips_builder.h
@@ -1,56 +1,69 @@
-/*
- * Rips_builder.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 10, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 RIPS_BUILDER_H_
-#define RIPS_BUILDER_H_
+#ifndef UTILS_RIPS_BUILDER_H_
+#define UTILS_RIPS_BUILDER_H_
#include <boost/iterator/iterator_facade.hpp>
-#include "utils/UI_utils.h"
-#include "model/Complex_typedefs.h"
#include <CGAL/Euclidean_distance.h>
-
#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_d.h>
-template<typename SkBlComplex> class Rips_builder{
-private:
- SkBlComplex& complex_;
-public:
-
- /**
- * @brief Modify complex to be the Rips complex
- * of its points with offset alpha.
- */
- Rips_builder(SkBlComplex& complex,double alpha):complex_(complex){
- complex.keep_only_vertices();
- if (alpha<=0) return;
- compute_edges(alpha);
- }
-
-private:
-
-
- double squared_eucl_distance(const Point& p1,const Point& p2) const{
- return Geometry_trait::Squared_distance_d()(p1,p2);
- }
-
- void compute_edges(double alpha){
- auto vertices = complex_.vertex_range();
- for(auto p = vertices.begin(); p!= vertices.end(); ++p){
- std::cout << *p << " "; std::cout.flush();
- for (auto q = p; ++q != vertices.end(); /**/)
- if (squared_eucl_distance(complex_.point(*p),complex_.point(*q)) < 4*alpha*alpha)
- complex_.add_edge(*p,*q);
- }
- std::cout << std::endl;
- }
+#include "utils/UI_utils.h"
+#include "model/Complex_typedefs.h"
-};
+template<typename SkBlComplex> class Rips_builder {
+ private:
+ SkBlComplex& complex_;
+ public:
+ /**
+ * @brief Modify complex to be the Rips complex
+ * of its points with offset alpha.
+ */
+ Rips_builder(SkBlComplex& complex, double alpha) : complex_(complex) {
+ complex.keep_only_vertices();
+ if (alpha <= 0) return;
+ compute_edges(alpha);
+ }
+
+ private:
+ double squared_eucl_distance(const Point& p1, const Point& p2) const {
+ return Geometry_trait::Squared_distance_d()(p1, p2);
+ }
+
+ void compute_edges(double alpha) {
+ auto vertices = complex_.vertex_range();
+ for (auto p = vertices.begin(); p != vertices.end(); ++p) {
+ std::cout << *p << " ";
+ std::cout.flush();
+ for (auto q = p; ++q != vertices.end(); /**/)
+ if (squared_eucl_distance(complex_.point(*p), complex_.point(*q)) < 4 * alpha * alpha)
+ complex_.add_edge(*p, *q);
+ }
+ std::cout << std::endl;
+ }
+};
-#endif /* RIPS_BUILDER_H_ */
+#endif // UTILS_RIPS_BUILDER_H_
diff --git a/src/GudhUI/utils/UI_utils.h b/src/GudhUI/utils/UI_utils.h
index a7c0689f..9cc209d3 100644
--- a/src/GudhUI/utils/UI_utils.h
+++ b/src/GudhUI/utils/UI_utils.h
@@ -1,33 +1,45 @@
-/*
- * UI_utils.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 25, 2014
- * Author: david
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 UI_UTILS_H_
-#define UI_UTILS_H_
-
-#define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)"<<std::endl
+#ifndef UTILS_UI_UTILS_H_
+#define UTILS_UI_UTILS_H_
#define UIDBG_VERBOSE
-
#ifdef UIDBG_VERBOSE
-#define UIDBG(a) std::cerr << "UIDBG: " << (a)<<std::endl
-#define UIDBGMSG(a,b) std::cerr << "UIDBG: " << a<<b<<std::endl
-#define UIDBGVALUE(a) std::cerr << "UIDBG: " << #a << ": " << a<<std::endl
-#define UIDBGCONT(a) std::cerr << "UIDBG: container "<< #a<<" -> "; for(auto x:a) std::cerr<< x << ","; std::cerr<<std::endl
+#define UIDBG(a) std::cerr << "UIDBG: " << (a) << std::endl
+#define UIDBGMSG(a, b) std::cerr << "UIDBG: " << a << b << std::endl
+#define UIDBGVALUE(a) std::cerr << "UIDBG: " << #a << ": " << a << std::endl
+#define UIDBGCONT(a) std::cerr << "UIDBG: container " << #a << " -> "; for (auto x : a) std::cerr << x << ","; std::cerr << std::endl }
#else
-//#define DBG(a) a
-//#define DBGMSG(a,b) b
-//#define DBGVALUE(a) a
-//#define DBGCONT(a) a
+// #define DBG(a) a
+// #define DBGMSG(a, b) b
+// #define DBGVALUE(a) a
+// #define DBGCONT(a) a
#define UIDBG(a)
-#define UIDBGMSG(a,b)
+#define UIDBGMSG(a, b)
#define UIDBGVALUE(a)
#define UIDBGCONT(a)
#endif
-
-#endif /* UI_UTILS_H_ */
+#endif // UTILS_UI_UTILS_H_
diff --git a/src/GudhUI/utils/Vertex_collapsor.h b/src/GudhUI/utils/Vertex_collapsor.h
index d4911a35..2b36cb3a 100644
--- a/src/GudhUI/utils/Vertex_collapsor.h
+++ b/src/GudhUI/utils/Vertex_collapsor.h
@@ -1,76 +1,88 @@
-/*
- * Vertex_collapsor.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Sep 25, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 VERTEX_COLLAPSOR_H_
-#define VERTEX_COLLAPSOR_H_
+#ifndef UTILS_VERTEX_COLLAPSOR_H_
+#define UTILS_VERTEX_COLLAPSOR_H_
+
+#include <list>
#include "utils/Edge_contractor.h"
#include "utils/Furthest_point_epsilon_net.h"
#include "utils/UI_utils.h"
+
/**
* Iteratively puts every vertex at the center of its neighbors
*/
-template<typename SkBlComplex> class Vertex_collapsor{
-private:
- SkBlComplex& complex_;
- size_t num_collapses_;
-public:
- typedef typename SkBlComplex::Vertex_handle Vertex_handle;
- typedef typename SkBlComplex::Edge_handle Edge_handle;
-
- /**
- * @brief Modify complex to be the expansion of the k-nearest neighbor
- * symetric graph.
- */
- Vertex_collapsor(SkBlComplex& complex, size_t num_collapses) :
- complex_(complex),num_collapses_(num_collapses)
- {
-// std::list<Vertex_handle> vertices;
-// vertices.insert(vertices.begin(),complex_.vertex_range().begin(),complex_.vertex_range().end());
-// UIDBG("Collapse vertices");
-// collapse_vertices(vertices);
-
- std::list<Vertex_handle> vertices;
-
- UIDBG("Compute eps net");
- Furthest_point_epsilon_net<Complex> eps_net(complex_);
-
- for(auto vh : eps_net.net_filtration_)
- vertices.push_back(vh.vertex_handle);
-
- UIDBG("Collapse vertices");
- collapse_vertices(vertices);
-
-
-
- }
-
-private:
-
-
- void collapse_vertices(std::list<Vertex_handle>& vertices){
- while(!vertices.empty() && num_collapses_--){
- Vertex_handle current_vertex = vertices.front();
- vertices.pop_front();
- if(is_link_reducible(current_vertex))
- complex_.remove_vertex(current_vertex);
- }
- }
-
- bool is_link_reducible(Vertex_handle v){
- auto link = complex_.link(v);
- if(link.empty()) return false;
- if(link.is_cone()) return true;
- if(link.num_connected_components()>1) return false;
- Edge_contractor<Complex> contractor(link,link.num_vertices()-1);
- return (link.num_vertices()==1);
- }
-
+template<typename SkBlComplex> class Vertex_collapsor {
+ private:
+ SkBlComplex& complex_;
+ size_t num_collapses_;
+
+ public:
+ typedef typename SkBlComplex::Vertex_handle Vertex_handle;
+ typedef typename SkBlComplex::Edge_handle Edge_handle;
+
+ /**
+ * @brief Modify complex to be the expansion of the k-nearest neighbor
+ * symetric graph.
+ */
+ Vertex_collapsor(SkBlComplex& complex, size_t num_collapses) :
+ complex_(complex), num_collapses_(num_collapses) {
+ // std::list<Vertex_handle> vertices;
+ // vertices.insert(vertices.begin(),complex_.vertex_range().begin(),complex_.vertex_range().end());
+ // UIDBG("Collapse vertices");
+ // collapse_vertices(vertices);
+
+ std::list<Vertex_handle> vertices;
+
+ UIDBG("Compute eps net");
+ Furthest_point_epsilon_net<Complex> eps_net(complex_);
+
+ for (auto vh : eps_net.net_filtration_)
+ vertices.push_back(vh.vertex_handle);
+
+ UIDBG("Collapse vertices");
+ collapse_vertices(vertices);
+ }
+
+ private:
+ void collapse_vertices(std::list<Vertex_handle>& vertices) {
+ while (!vertices.empty() && num_collapses_--) {
+ Vertex_handle current_vertex = vertices.front();
+ vertices.pop_front();
+ if (is_link_reducible(current_vertex))
+ complex_.remove_vertex(current_vertex);
+ }
+ }
+
+ bool is_link_reducible(Vertex_handle v) {
+ auto link = complex_.link(v);
+ if (link.empty()) return false;
+ if (link.is_cone()) return true;
+ if (link.num_connected_components() > 1) return false;
+ Edge_contractor<Complex> contractor(link, link.num_vertices() - 1);
+ return (link.num_vertices() == 1);
+ }
};
-
-#endif /* VERTEX_COLLAPSOR_H_ */
+#endif // UTILS_VERTEX_COLLAPSOR_H_
diff --git a/src/GudhUI/view/Color.h b/src/GudhUI/view/Color.h
index a63456cb..ba0592e1 100644
--- a/src/GudhUI/view/Color.h
+++ b/src/GudhUI/view/Color.h
@@ -1,21 +1,35 @@
-/*
- * Color.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 26, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 COLOR_H_
-#define COLOR_H_
-
+#ifndef VIEW_COLOR_H_
+#define VIEW_COLOR_H_
+struct Color {
+ double r;
+ double g;
+ double b;
-struct Color{
- double r;
- double g;
- double b;
- Color(double r_,double g_,double b_):r(r_),g(g_),b(b_){}
+ Color(double r_, double g_, double b_) : r(r_), g(g_), b(b_) { }
};
-
-#endif /* COLOR_H_ */
+#endif // VIEW_COLOR_H_
diff --git a/src/GudhUI/view/FirstCoordProjector.h b/src/GudhUI/view/FirstCoordProjector.h
index 2659eef1..529d2d42 100644
--- a/src/GudhUI/view/FirstCoordProjector.h
+++ b/src/GudhUI/view/FirstCoordProjector.h
@@ -1,24 +1,40 @@
-/*
- * FirstCoordProjector.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 27, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 FIRSTCOORDPROJECTOR_H_
-#define FIRSTCOORDPROJECTOR_H_
+#ifndef VIEW_FIRSTCOORDPROJECTOR_H_
+#define VIEW_FIRSTCOORDPROJECTOR_H_
#include "utils/UI_utils.h"
#include "Projector3D.h"
-class FirstCoordProjector3D : public Projector3D{
- typedef Projector3D::Point Point;
- typedef Projector3D::Point_3 Point_3;
+class FirstCoordProjector3D : public Projector3D {
+ typedef Projector3D::Point Point;
+ typedef Projector3D::Point_3 Point_3;
- Point_3 operator()(const Point& p) const{
- assert(p.dimension()>=3);
- return Point_3(p.x(),p.y(),p.z());
- }
+ Point_3 operator()(const Point& p) const {
+ assert(p.dimension() >= 3);
+ return Point_3(p.x(), p.y(), p.z());
+ }
};
-#endif /* FIRSTCOORDPROJECTOR_H_ */
+#endif // VIEW_FIRSTCOORDPROJECTOR_H_
diff --git a/src/GudhUI/view/Projector3D.h b/src/GudhUI/view/Projector3D.h
index 503b35c5..2a756541 100644
--- a/src/GudhUI/view/Projector3D.h
+++ b/src/GudhUI/view/Projector3D.h
@@ -1,28 +1,39 @@
-/*
- * Projector.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 27, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 PROJECTOR3D_H_
-#define PROJECTOR3D_H_
+#ifndef VIEW_PROJECTOR3D_H_
+#define VIEW_PROJECTOR3D_H_
#include "model/Complex_typedefs.h"
+class Projector3D {
+ public:
+ typedef Geometry_trait::Point Point;
+ typedef Geometry_trait::Point_3 Point_3;
-class Projector3D{
-public:
- typedef Geometry_trait::Point Point;
- typedef Geometry_trait::Point_3 Point_3;
-
- virtual Point_3 operator()(const Point&) const = 0;
-
- virtual ~Projector3D(){
- }
+ virtual Point_3 operator()(const Point&) const = 0;
+ virtual ~Projector3D() { }
};
-
-
-#endif /* PROJECTOR3D_H_ */
+#endif // VIEW_PROJECTOR3D_H_
diff --git a/src/GudhUI/view/View_parameter.h b/src/GudhUI/view/View_parameter.h
index 39c5d7dd..9805abc2 100644
--- a/src/GudhUI/view/View_parameter.h
+++ b/src/GudhUI/view/View_parameter.h
@@ -1,13 +1,28 @@
-/*
- * View_parameter.h
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Mar 10, 2014
- * Author: David Salinas
- * Copyright 2013 INRIA. All rights reserved
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 VIEW_PARAMETER_H_
-#define VIEW_PARAMETER_H_
+#ifndef VIEW_VIEW_PARAMETER_H_
+#define VIEW_VIEW_PARAMETER_H_
#include <iostream>
@@ -15,123 +30,122 @@
* Different parameters for the view such as the camera angle,
* the light, options for vertices/edges/triangles.
*/
-class View_parameter{
-public:
- bool light;
- bool relative_light;
-
- double size_vertices;
- double size_edges;
- double light_edges; // in 0-1
- double light_triangles;// in 0-1
-
- /**
- * light angle
- */
- double theta;
- double phi;
-
- enum VERTEX_MODE{ V_NONE,V_SIMPLE,V_COUNT};
- enum EDGE_MODE{ E_NONE,E_SIMPLE,E_COUNT};
- enum TRIANGLE_MODE{ T_NONE,T_SIMPLE,T_COUNT};
-
-
-
-
- VERTEX_MODE vertex_mode;
- EDGE_MODE edge_mode;
- TRIANGLE_MODE triangle_mode;
-
- void change_vertex_mode(){
- int current_value = vertex_mode;
- vertex_mode = static_cast<VERTEX_MODE>(++current_value % V_COUNT);
- std::cout<<"Vertex mode : ";
- switch (vertex_mode) {
- case V_NONE:
- std::cout<<"empty\n";
- break;
- case V_SIMPLE:
- std::cout<<"simple\n";
- break;
- default:
- break;
- }
- }
-
- void change_vertex_mode(int new_mode){
- vertex_mode = static_cast<VERTEX_MODE>(new_mode % V_COUNT);
- }
-
- void change_edge_mode(){
- int current_value = edge_mode;
- edge_mode = static_cast<EDGE_MODE>(++current_value % E_COUNT);
- }
-
- void change_edge_mode(int new_mode){
- edge_mode = static_cast<EDGE_MODE>(new_mode % E_COUNT);
- }
-
-
- void change_triangle_mode(){
- int current_value = triangle_mode;
- triangle_mode = static_cast<TRIANGLE_MODE>(++current_value % T_COUNT);
- }
-
-
-
-
-
- View_parameter(){
- light = true;
- relative_light = true;
- vertex_mode = V_SIMPLE;
- edge_mode = E_SIMPLE;
- triangle_mode = T_NONE;
-
- size_vertices = 3;
- size_edges = 2;
-
- light_edges = 0.3;
- light_triangles = 0.85;
- theta = 0;
- phi = 0;
- }
-
- friend std::ostream& operator<<(std::ostream& stream, const View_parameter& param){
- stream << param.light<< " ";
- stream << param.relative_light<< " ";
- stream << param.vertex_mode<< " ";
- stream << param.edge_mode<< " ";
- stream << param.triangle_mode<< " ";
- stream << param.size_vertices<< " ";
- stream << param.size_edges<< " ";
- stream << param.light_edges<< " ";
- stream << param.light_triangles<< " ";
- stream << param.theta<< " ";
- stream << param.phi<< " ";
- return stream;
- }
-
- friend std::istream& operator>>(std::istream& stream, View_parameter& param){
- stream >> param.light;
- stream >> param.relative_light;
- int a;
- stream>>a;
- param.vertex_mode = static_cast<VERTEX_MODE>(a % V_COUNT);
- stream>>a;
- param.edge_mode = static_cast<EDGE_MODE>(a % E_COUNT);
- stream>>a;
- param.triangle_mode = static_cast<TRIANGLE_MODE>(a % T_COUNT);
- stream>>a;
- stream >> param.size_vertices;
- stream >> param.size_edges;
- stream >> param.light_edges;
- stream >> param.light_triangles;
- stream >> param.theta;
- stream >> param.phi;
- return stream;
- }
-
+class View_parameter {
+ public:
+ bool light;
+ bool relative_light;
+
+ double size_vertices;
+ double size_edges;
+ double light_edges; // in 0-1
+ double light_triangles; // in 0-1
+
+ /**
+ * light angle
+ */
+ double theta;
+ double phi;
+
+ enum VERTEX_MODE {
+ V_NONE, V_SIMPLE, V_COUNT
+ };
+
+ enum EDGE_MODE {
+ E_NONE, E_SIMPLE, E_COUNT
+ };
+
+ enum TRIANGLE_MODE {
+ T_NONE, T_SIMPLE, T_COUNT
+ };
+
+ VERTEX_MODE vertex_mode;
+ EDGE_MODE edge_mode;
+ TRIANGLE_MODE triangle_mode;
+
+ void change_vertex_mode() {
+ int current_value = vertex_mode;
+ vertex_mode = static_cast<VERTEX_MODE> (++current_value % V_COUNT);
+ std::cout << "Vertex mode : ";
+ switch (vertex_mode) {
+ case V_NONE:
+ std::cout << "empty\n";
+ break;
+ case V_SIMPLE:
+ std::cout << "simple\n";
+ break;
+ default:
+ break;
+ }
+ }
+
+ void change_vertex_mode(int new_mode) {
+ vertex_mode = static_cast<VERTEX_MODE> (new_mode % V_COUNT);
+ }
+
+ void change_edge_mode() {
+ int current_value = edge_mode;
+ edge_mode = static_cast<EDGE_MODE> (++current_value % E_COUNT);
+ }
+
+ void change_edge_mode(int new_mode) {
+ edge_mode = static_cast<EDGE_MODE> (new_mode % E_COUNT);
+ }
+
+ void change_triangle_mode() {
+ int current_value = triangle_mode;
+ triangle_mode = static_cast<TRIANGLE_MODE> (++current_value % T_COUNT);
+ }
+
+ View_parameter() {
+ light = true;
+ relative_light = true;
+ vertex_mode = V_SIMPLE;
+ edge_mode = E_SIMPLE;
+ triangle_mode = T_NONE;
+
+ size_vertices = 3;
+ size_edges = 2;
+
+ light_edges = 0.3;
+ light_triangles = 0.85;
+ theta = 0;
+ phi = 0;
+ }
+
+ friend std::ostream& operator<<(std::ostream& stream, const View_parameter& param) {
+ stream << param.light << " ";
+ stream << param.relative_light << " ";
+ stream << param.vertex_mode << " ";
+ stream << param.edge_mode << " ";
+ stream << param.triangle_mode << " ";
+ stream << param.size_vertices << " ";
+ stream << param.size_edges << " ";
+ stream << param.light_edges << " ";
+ stream << param.light_triangles << " ";
+ stream << param.theta << " ";
+ stream << param.phi << " ";
+ return stream;
+ }
+
+ friend std::istream& operator>>(std::istream& stream, View_parameter& param) {
+ stream >> param.light;
+ stream >> param.relative_light;
+ int a;
+ stream >> a;
+ param.vertex_mode = static_cast<VERTEX_MODE> (a % V_COUNT);
+ stream >> a;
+ param.edge_mode = static_cast<EDGE_MODE> (a % E_COUNT);
+ stream >> a;
+ param.triangle_mode = static_cast<TRIANGLE_MODE> (a % T_COUNT);
+ stream >> a;
+ stream >> param.size_vertices;
+ stream >> param.size_edges;
+ stream >> param.light_edges;
+ stream >> param.light_triangles;
+ stream >> param.theta;
+ stream >> param.phi;
+ return stream;
+ }
};
-#endif /* VIEW_PARAMETER_H_ */
+#endif // VIEW_VIEW_PARAMETER_H_
diff --git a/src/GudhUI/view/Viewer.cpp b/src/GudhUI/view/Viewer.cpp
index d8a35faf..c6c2b345 100644
--- a/src/GudhUI/view/Viewer.cpp
+++ b/src/GudhUI/view/Viewer.cpp
@@ -1,197 +1,186 @@
-/*
- * Viewer.cpp
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 26, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 "Viewer.h"
#include "utils/UI_utils.h"
-Viewer::Viewer(QWidget* parent): QGLViewer(QGLFormat(QGL::SampleBuffers),parent),instructor(0),theta(0),phi(0){
-}
+Viewer::Viewer(QWidget* parent) : QGLViewer(QGLFormat(QGL::SampleBuffers), parent), instructor(0), theta(0), phi(0) { }
-void
-Viewer::set_instructor(Viewer_instructor* instructor_){
- instructor = instructor_;
+void Viewer::set_instructor(Viewer_instructor* instructor_) {
+ instructor = instructor_;
}
-void
-Viewer::show_entire_scene(){
- this->showEntireScene();
+void Viewer::show_entire_scene() {
+ this->showEntireScene();
}
-void
-Viewer::draw(){
- instructor->give_instructions();
+void Viewer::draw() {
+ instructor->give_instructions();
}
-
-void
-Viewer::set_bounding_box(const Point_3 & lower_left,const Point_3 & upper_right){
- this->camera()->setSceneBoundingBox(
- qglviewer::Vec(lower_left[0], lower_left[1], lower_left[2]),
- qglviewer::Vec(upper_right[0], upper_right[1], upper_right[2])
- );
+void Viewer::set_bounding_box(const Point_3 & lower_left, const Point_3 & upper_right) {
+ this->camera()->setSceneBoundingBox(qglviewer::Vec(lower_left[0], lower_left[1], lower_left[2]),
+ qglviewer::Vec(upper_right[0], upper_right[1], upper_right[2]));
}
-void
-Viewer::update_GL(){
- this->updateGL();
-
+void Viewer::update_GL() {
+ this->updateGL();
}
-void
-Viewer::init_scene(){
- this->setBackgroundColor(Qt::white);
- ::glEnable(GL_LINE_SMOOTH);
- init_light();
+void Viewer::init_scene() {
+ this->setBackgroundColor(Qt::white);
+ ::glEnable(GL_LINE_SMOOTH);
+ init_light();
}
-void
-Viewer::init_light(){
- ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+void Viewer::init_light() {
+ ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}
-void
-Viewer::set_light(){
- if(theta>=0 && phi >=0){
- const GLfloat pos[4] = {(float)(sin(phi)*cos(theta)),(float)(sin(phi)*sin(theta)),(float)(cos(phi)),0.};
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- }
+void Viewer::set_light() {
+ if (theta >= 0 && phi >= 0) {
+ const GLfloat pos[4] = {static_cast<float> (sin(phi) * cos(theta)),
+ static_cast<float> (sin(phi) * sin(theta)),
+ static_cast<float> (cos(phi)), 0.};
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ }
}
-void
-Viewer::set_light_direction(double theta_,double phi_){
- theta = theta_;
- phi = phi_;
+void Viewer::set_light_direction(double theta_, double phi_) {
+ theta = theta_;
+ phi = phi_;
}
/**
* set the light in the direction of the observer
*/
-void
-Viewer::set_light_direction(){
- theta = -1;
- phi = -1;
+void Viewer::set_light_direction() {
+ theta = -1;
+ phi = -1;
}
+void Viewer::postSelection(const QPoint& point) {
+ bool found;
-void
-Viewer::postSelection(const QPoint& point){
- bool found;
+ auto vec = this->camera()->pointUnderPixel(point, found);
- auto vec = this->camera()->pointUnderPixel(point,found);
-
- if(found){
- Point_3 position(vec[0],vec[1],vec[2]);
- emit(click(position));
- }
+ if (found) {
+ Point_3 position(vec[0], vec[1], vec[2]);
+ emit(click(position));
+ }
}
////////////////////////
// draw
////////////////////////
-void
-Viewer::set_size_point(double size_points){
- ::glPointSize(size_points);
-}
-
-void
-Viewer::draw_point(const Point_3& p,const Color& color,double size_points){
- ::glColor3f(color.r,color.g,color.b);
- ::glDisable(GL_LIGHTING);
- ::glEnable(GL_POINT_SMOOTH);
- ::glPointSize(size_points);
- ::glBegin(GL_POINTS);
- ::glVertex3d(p.x(), p.y(), p.z());
- ::glEnd();
- ::glDisable(GL_POINT_SMOOTH);
-}
-
-void
-Viewer::begin_draw_points(double size,bool light){
- light?glEnable(GL_LIGHTING):glDisable(GL_LIGHTING);
- ::glEnable(GL_POINT_SMOOTH);
- ::glPointSize(size);
- ::glBegin(GL_POINTS);
-}
-
-void
-Viewer::set_color(const Color& color){
- ::glColor3f(color.r,color.g,color.b);
-}
-
-void
-Viewer::draw_points(const Point_3 & point){
- ::glVertex3d(point.x(),point.y(),point.z());
-}
-
-void
-Viewer::end_draw_points(){
- ::glEnd();
- ::glDisable(GL_POINT_SMOOTH);
-}
-
-void
-Viewer::draw_edge(const Point_3 &a,const Point_3 &b,const Color& color,double size){
- ::glColor3f(color.r,color.g,color.b);
- ::glPointSize(3.0);
- ::glLineWidth(size);
- ::glBegin(GL_LINES);
- ::glVertex3f(a.x(),a.y(),a.z());
- ::glVertex3f(b.x(),b.y(),b.z());
- ::glEnd();
-}
-
-void
-Viewer::begin_draw_edges(double size,bool light){
- ::glLineWidth(size);
- ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- ::glEnable(GL_POLYGON_OFFSET_LINE);
- ::glPolygonOffset(3.0f,-3.0f);
- light?glEnable(GL_LIGHTING):glDisable(GL_LIGHTING);
- ::glBegin(GL_LINES);
-}
-
-void
-Viewer::draw_edges(const Point_3 &a,const Point_3 &b){
- ::glVertex3f(a.x(),a.y(),a.z());
- ::glVertex3f(b.x(),b.y(),b.z());
-}
-
-void
-Viewer::end_draw_edges(){
- ::glEnd();
-}
-
-void
-Viewer::begin_draw_triangles(double size,bool light,bool transparent){
- if(transparent){
- ::glEnable (GL_BLEND);
- ::glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
- ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- ::glEnable(GL_POLYGON_OFFSET_FILL);
- ::glPolygonOffset(3.0f,-3.0f);
- light?glEnable(GL_LIGHTING):glDisable(GL_LIGHTING);
- ::glBegin(GL_TRIANGLES);
-}
-
-void
-Viewer::draw_triangles(const Point_3& p1,const Point_3& p2,const Point_3& p3){
- if(!CGAL::collinear(p1,p2,p3)){
- auto triangle_normal = CGAL::unit_normal(p1,p2,p3);
- ::glNormal3d(triangle_normal.x(),triangle_normal.y(),triangle_normal.z());
- ::glVertex3d(p1.x(),p1.y(),p1.z());
- ::glVertex3d(p2.x(),p2.y(),p2.z());
- ::glVertex3d(p3.x(),p3.y(),p3.z());
- }
-}
-
-void
-Viewer::end_draw_triangles(){
- ::glEnd();
+
+void Viewer::set_size_point(double size_points) {
+ ::glPointSize(size_points);
+}
+
+void Viewer::draw_point(const Point_3& p, const Color& color, double size_points) {
+ ::glColor3f(color.r, color.g, color.b);
+ ::glDisable(GL_LIGHTING);
+ ::glEnable(GL_POINT_SMOOTH);
+ ::glPointSize(size_points);
+ ::glBegin(GL_POINTS);
+ ::glVertex3d(p.x(), p.y(), p.z());
+ ::glEnd();
+ ::glDisable(GL_POINT_SMOOTH);
+}
+
+void Viewer::begin_draw_points(double size, bool light) {
+ light ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
+ ::glEnable(GL_POINT_SMOOTH);
+ ::glPointSize(size);
+ ::glBegin(GL_POINTS);
+}
+
+void Viewer::set_color(const Color& color) {
+ ::glColor3f(color.r, color.g, color.b);
+}
+
+void Viewer::draw_points(const Point_3 & point) {
+ ::glVertex3d(point.x(), point.y(), point.z());
+}
+
+void Viewer::end_draw_points() {
+ ::glEnd();
+ ::glDisable(GL_POINT_SMOOTH);
+}
+
+void Viewer::draw_edge(const Point_3 &a, const Point_3 &b, const Color& color, double size) {
+ ::glColor3f(color.r, color.g, color.b);
+ ::glPointSize(3.0);
+ ::glLineWidth(size);
+ ::glBegin(GL_LINES);
+ ::glVertex3f(a.x(), a.y(), a.z());
+ ::glVertex3f(b.x(), b.y(), b.z());
+ ::glEnd();
+}
+
+void Viewer::begin_draw_edges(double size, bool light) {
+ ::glLineWidth(size);
+ ::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ ::glEnable(GL_POLYGON_OFFSET_LINE);
+ ::glPolygonOffset(3.0f, -3.0f);
+ light ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
+ ::glBegin(GL_LINES);
+}
+
+void Viewer::draw_edges(const Point_3 &a, const Point_3 &b) {
+ ::glVertex3f(a.x(), a.y(), a.z());
+ ::glVertex3f(b.x(), b.y(), b.z());
+}
+
+void Viewer::end_draw_edges() {
+ ::glEnd();
+}
+
+void Viewer::begin_draw_triangles(double size, bool light, bool transparent) {
+ if (transparent) {
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ ::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ ::glEnable(GL_POLYGON_OFFSET_FILL);
+ ::glPolygonOffset(3.0f, -3.0f);
+ light ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
+ ::glBegin(GL_TRIANGLES);
+}
+
+void Viewer::draw_triangles(const Point_3& p1, const Point_3& p2, const Point_3& p3) {
+ if (!CGAL::collinear(p1, p2, p3)) {
+ auto triangle_normal = CGAL::unit_normal(p1, p2, p3);
+ ::glNormal3d(triangle_normal.x(), triangle_normal.y(), triangle_normal.z());
+ ::glVertex3d(p1.x(), p1.y(), p1.z());
+ ::glVertex3d(p2.x(), p2.y(), p2.z());
+ ::glVertex3d(p3.x(), p3.y(), p3.z());
+ }
+}
+
+void Viewer::end_draw_triangles() {
+ ::glEnd();
}
#include "Viewer.moc"
diff --git a/src/GudhUI/view/Viewer.h b/src/GudhUI/view/Viewer.h
index 5639aa56..276ccd3c 100644
--- a/src/GudhUI/view/Viewer.h
+++ b/src/GudhUI/view/Viewer.h
@@ -1,7 +1,36 @@
-#ifndef VIEWER_H
-#define VIEWER_H
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 VIEW_VIEWER_H_
+#define VIEW_VIEWER_H_
+
+// Workaround for moc-qt4 not parsing boost headers
+#include <CGAL/config.h>
#include <QGLViewer/qglviewer.h>
+
+#include <vector>
+
#include "View_parameter.h"
#include "model/Complex_typedefs.h"
#include "Color.h"
@@ -10,87 +39,82 @@
class Viewer_instructor;
class Viewer : public QGLViewer {
- Q_OBJECT
-
- Viewer_instructor * instructor;
-
- /**
- * light angles
- */
- double theta,phi;
- typedef Complex::GT Gudhi_kernel;
- typedef Gudhi_kernel::Point_3 Point_3;
-public:
- Viewer(QWidget* parent);
+ Q_OBJECT
- void set_instructor(Viewer_instructor* instructor_);
+ Viewer_instructor * instructor;
- void show_entire_scene();
+ /**
+ * light angles
+ */
+ double theta, phi;
+ typedef Complex::GT Gudhi_kernel;
+ typedef Gudhi_kernel::Point_3 Point_3;
- void draw();
+ public:
+ Viewer(QWidget* parent);
+ void set_instructor(Viewer_instructor* instructor_);
- void set_bounding_box(const Point_3 & lower_left,const Point_3 & upper_right);
+ void show_entire_scene();
- void update_GL();
+ void draw();
- void init_scene();
+ void set_bounding_box(const Point_3 & lower_left, const Point_3 & upper_right);
- void init_light();
+ void update_GL();
- void set_light();
+ void init_scene();
- void set_light_direction(double theta,double phi);
+ void init_light();
- /**
- * set the light in the direction of the observer
- */
- void set_light_direction();
+ void set_light();
+ void set_light_direction(double theta, double phi);
-protected:
- virtual void postSelection(const QPoint& point);
+ /**
+ * set the light in the direction of the observer
+ */
+ void set_light_direction();
+ protected:
+ virtual void postSelection(const QPoint& point);
-public:
+ public:
+ ////////////////////////
+ // draw
+ ////////////////////////
+ void set_size_point(double size_points);
- ////////////////////////
- // draw
- ////////////////////////
- void set_size_point(double size_points);
+ void set_color(const Color& color);
- void set_color(const Color& color);
+ void draw_point(const Point_3& p, const Color& color, double size_points);
- void draw_point(const Point_3& p,const Color& color,double size_points);
+ void begin_draw_points(double size, bool light = false);
- void begin_draw_points(double size,bool light=false);
+ void draw_points(const Point_3 & point);
- void draw_points(const Point_3 & point);
+ void end_draw_points();
- void end_draw_points();
+ void draw_edge(const Point_3 &a, const Point_3 &b, const Color& color, double size);
- void draw_edge(const Point_3 &a,const Point_3 &b,const Color& color,double size);
+ void begin_draw_edges(double size, bool light = false);
- void begin_draw_edges(double size,bool light=false);
+ void draw_edges(const Point_3 &a, const Point_3 &b);
- void draw_edges(const Point_3 &a,const Point_3 &b);
+ void end_draw_edges();
- void end_draw_edges();
+ void begin_draw_triangles(double size, bool light, bool transparent = false);
- void begin_draw_triangles(double size,bool light,bool transparent = false);
+ void draw_triangles(const Point_3& p1, const Point_3& p2, const Point_3& p3);
- void draw_triangles(const Point_3& p1,const Point_3& p2,const Point_3& p3);
+ // todo remove
+ void draw_triangles(const std::vector<Point_3*>& points);
- //todo remove
- void draw_triangles(const std::vector<Point_3*>& points);
+ void end_draw_triangles();
- void end_draw_triangles();
-
- signals:
- void click(const Point_3& position);
+ signals:
+ void click(const Point_3& position);
};
-
-
-#endif
+#endif // VIEW_VIEWER_H_
diff --git a/src/GudhUI/view/Viewer_instructor.cpp b/src/GudhUI/view/Viewer_instructor.cpp
index 3cb8f152..1ddd4d8b 100644
--- a/src/GudhUI/view/Viewer_instructor.cpp
+++ b/src/GudhUI/view/Viewer_instructor.cpp
@@ -1,206 +1,192 @@
-/*
- * Viewer_instructor.cpp
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
*
- * Created on: Aug 26, 2014
- * Author: dsalinas
+ * Author(s): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 <utility>
+
#include "Viewer_instructor.h"
#include "utils/UI_utils.h"
#include "FirstCoordProjector.h"
-
Viewer_instructor::Viewer_instructor(QWidget* parent,
- Viewer* viewer,
- const Complex& mesh
-):viewer_(viewer),mesh_(mesh),projector_(new FirstCoordProjector3D()){
- viewer_->set_instructor(this);
+ Viewer* viewer,
+ const Complex& mesh
+ )
+ : viewer_(viewer), mesh_(mesh), projector_(new FirstCoordProjector3D()) {
+ viewer_->set_instructor(this);
+}
+
+void Viewer_instructor::initialize_bounding_box() {
+ auto pair_bounding_box = compute_bounding_box_corners();
+ viewer_->set_bounding_box(proj(pair_bounding_box.first), proj(pair_bounding_box.second));
+ viewer_->init_scene();
}
+std::pair<Complex::Point, Complex::Point> Viewer_instructor::compute_bounding_box_corners() {
+ if (mesh_.empty()) {
+ return std::make_pair(Point(-1, -1, -1, 1), Point(1, 1, 1, 1));
+ } else {
+ double x_min = 1e10;
+ double y_min = 1e10;
+ double z_min = 1e10;
+ double x_max = -1e10;
+ double y_max = -1e10;
+ double z_max = -1e10;
+ for (auto vi : mesh_.vertex_range()) {
+ auto pt = proj(mesh_.point(vi));
+ x_min = (std::min)(x_min, pt.x());
+ y_min = (std::min)(y_min, pt.y());
+ z_min = (std::min)(z_min, pt.z());
-void
-Viewer_instructor::initialize_bounding_box(){
- auto pair_bounding_box = compute_bounding_box_corners();
- viewer_->set_bounding_box(proj(pair_bounding_box.first),proj(pair_bounding_box.second));
- viewer_->init_scene();
-}
-
-std::pair<Complex::Point,Complex::Point>
-Viewer_instructor::compute_bounding_box_corners(){
- if(mesh_.empty()){
- return std::make_pair(Point(-1,-1,-1,1),Point(1,1,1,1));
- }
- else{
- double x_min = 1e10;
- double y_min = 1e10;
- double z_min = 1e10;
- double x_max = -1e10;
- double y_max = -1e10;
- double z_max = -1e10;
- for( auto vi : mesh_.vertex_range())
- {
- auto pt = proj(mesh_.point(vi));
- x_min = (std::min)(x_min,pt.x());
- y_min = (std::min)(y_min,pt.y());
- z_min = (std::min)(z_min,pt.z());
-
- x_max = (std::max)(x_max,pt.x());
- y_max = (std::max)(y_max,pt.y());
- z_max = (std::max)(z_max,pt.z());
-
- }
- return std::make_pair(
- Point(x_min,y_min,z_min,1.),
- Point(x_max,y_max,z_max,1.)
- );
- }
+ x_max = (std::max)(x_max, pt.x());
+ y_max = (std::max)(y_max, pt.y());
+ z_max = (std::max)(z_max, pt.z());
+ }
+ return std::make_pair(Point(x_min, y_min, z_min, 1.),
+ Point(x_max, y_max, z_max, 1.));
+ }
}
-void
-Viewer_instructor::show_entire_scene(){
- viewer_->show_entire_scene();
+void Viewer_instructor::show_entire_scene() {
+ viewer_->show_entire_scene();
}
-const qglviewer::Camera*
-Viewer_instructor::camera() const{
- return viewer_->camera();
+const qglviewer::Camera* Viewer_instructor::camera() const {
+ return viewer_->camera();
}
int
-Viewer_instructor::width() const{
- return viewer_->width();
+Viewer_instructor::width() const {
+ return viewer_->width();
}
+
int
-Viewer_instructor::height() const{
- return viewer_->height();
+Viewer_instructor::height() const {
+ return viewer_->height();
}
/**
* to change display parameters
*/
-View_parameter&
-Viewer_instructor::view_params(){
- return view_params_;
+View_parameter& Viewer_instructor::view_params() {
+ return view_params_;
}
-
void
-Viewer_instructor::give_instructions(){
- if(view_params_.relative_light)
- viewer_->set_light_direction();
- else
- viewer_->set_light_direction(view_params_.theta,view_params_.phi);
- viewer_->set_light();
-
- if (view_params_.edge_mode) draw_edges();
- if (view_params_.triangle_mode) draw_triangles();
- if (view_params_.vertex_mode) draw_points();
+Viewer_instructor::give_instructions() {
+ if (view_params_.relative_light)
+ viewer_->set_light_direction();
+ else
+ viewer_->set_light_direction(view_params_.theta, view_params_.phi);
+ viewer_->set_light();
+ if (view_params_.edge_mode) draw_edges();
+ if (view_params_.triangle_mode) draw_triangles();
+ if (view_params_.vertex_mode) draw_points();
}
-void
-Viewer_instructor::draw_edges(){
- viewer_->begin_draw_edges(view_params_.size_edges,false);
+void Viewer_instructor::draw_edges() {
+ viewer_->begin_draw_edges(view_params_.size_edges, false);
- for(auto edge : mesh_.edge_range()){
- set_color_edge(edge);
- const Point& a = mesh_.point(mesh_.first_vertex(edge));
- const Point& b = mesh_.point(mesh_.second_vertex(edge)) ;
- viewer_->draw_edges(proj(a),proj(b));
- }
+ for (auto edge : mesh_.edge_range()) {
+ set_color_edge(edge);
+ const Point& a = mesh_.point(mesh_.first_vertex(edge));
+ const Point& b = mesh_.point(mesh_.second_vertex(edge));
+ viewer_->draw_edges(proj(a), proj(b));
+ }
- viewer_->end_draw_edges();
+ viewer_->end_draw_edges();
}
-void
-Viewer_instructor::draw_triangles(){
- const double size_triangles = 1.0;
- viewer_->begin_draw_triangles(size_triangles,view_params_.light);
-
- for(const auto& fit : mesh_.triangle_range()) {
- set_color_triangle(fit);
- if(view_params_.triangle_mode){
- auto fit_it = fit.begin();
- const Point& p1 = mesh_.point(*fit_it);
- const Point& p2 = mesh_.point(*(++fit_it));
- const Point& p3 = mesh_.point(*(++fit_it));
- viewer_->draw_triangles(proj(p1),proj(p2),proj(p3));
- }
- }
- viewer_->end_draw_triangles();
-}
+void Viewer_instructor::draw_triangles() {
+ const double size_triangles = 1.0;
+ viewer_->begin_draw_triangles(size_triangles, view_params_.light);
-void
-Viewer_instructor::draw_points(){
- viewer_->begin_draw_points( view_params_.size_vertices);
- for( auto vi : mesh_.vertex_range())
- {
- viewer_->set_size_point(view_params_.size_vertices);
- set_color_vertex(vi);
- viewer_->draw_points(proj(mesh_.point(vi)));
- }
- viewer_->end_draw_points();
+ for (const auto& fit : mesh_.triangle_range()) {
+ set_color_triangle(fit);
+ if (view_params_.triangle_mode) {
+ auto fit_it = fit.begin();
+ const Point& p1 = mesh_.point(*fit_it);
+ const Point& p2 = mesh_.point(*(++fit_it));
+ const Point& p3 = mesh_.point(*(++fit_it));
+ viewer_->draw_triangles(proj(p1), proj(p2), proj(p3));
+ }
+ }
+ viewer_->end_draw_triangles();
}
-
-void
-Viewer_instructor::draw_edge(const Point&,const Point&){
-
+void Viewer_instructor::draw_points() {
+ viewer_->begin_draw_points(view_params_.size_vertices);
+ for (auto vi : mesh_.vertex_range()) {
+ viewer_->set_size_point(view_params_.size_vertices);
+ set_color_vertex(vi);
+ viewer_->draw_points(proj(mesh_.point(vi)));
+ }
+ viewer_->end_draw_points();
}
-void
-Viewer_instructor::draw_point(const Point&){
-
-}
+void Viewer_instructor::draw_edge(const Point&, const Point&) { }
+void Viewer_instructor::draw_point(const Point&) { }
/**
* set the right color of vertex/edge/triangle considering the view_params choice
*/
-void
-Viewer_instructor::set_color_vertex(Vertex_handle vh){
- viewer_->set_color(Color(view_params_.light_edges,view_params_.light_edges,view_params_.light_edges));
+void Viewer_instructor::set_color_vertex(Vertex_handle vh) {
+ viewer_->set_color(Color(view_params_.light_edges, view_params_.light_edges, view_params_.light_edges));
}
-void
-Viewer_instructor::set_color_edge(Edge_handle eh) {
- viewer_->set_color(Color(view_params_.light_edges,view_params_.light_edges,view_params_.light_edges));
+void Viewer_instructor::set_color_edge(Edge_handle eh) {
+ viewer_->set_color(Color(view_params_.light_edges, view_params_.light_edges, view_params_.light_edges));
}
-void
-Viewer_instructor::set_color_triangle(const Simplex_handle& triangle){
- viewer_->set_color(Color(view_params_.light_triangles,view_params_.light_triangles,view_params_.light_triangles));
+void Viewer_instructor::set_color_triangle(const Simplex& triangle) {
+ viewer_->set_color(Color(view_params_.light_triangles, view_params_.light_triangles, view_params_.light_triangles));
}
-
Viewer_instructor::Point_3
-Viewer_instructor::proj(const Point& p) const{
- return (*projector_)(p);
+Viewer_instructor::proj(const Point& p) const {
+ return (*projector_)(p);
}
-
-void
-Viewer_instructor::sceneChanged(){
- UIDBG("sceneChanged");
- viewer_->update_GL();
+void Viewer_instructor::sceneChanged() {
+ UIDBG("sceneChanged");
+ viewer_->update_GL();
}
-void
-Viewer_instructor::change_draw_vertices(){
- view_params_.change_vertex_mode();
+void Viewer_instructor::change_draw_vertices() {
+ view_params_.change_vertex_mode();
}
-void
-Viewer_instructor::change_draw_edges(){
- view_params_.change_edge_mode();
+
+void Viewer_instructor::change_draw_edges() {
+ view_params_.change_edge_mode();
}
-void
-Viewer_instructor::change_draw_triangles(){
- view_params_.change_triangle_mode();
+
+void Viewer_instructor::change_draw_triangles() {
+ view_params_.change_triangle_mode();
}
-void
-Viewer_instructor::change_light(){
- view_params_.light =! view_params_.light ;
+
+void Viewer_instructor::change_light() {
+ view_params_.light = !view_params_.light;
}
#include "Viewer_instructor.moc"
diff --git a/src/GudhUI/view/Viewer_instructor.h b/src/GudhUI/view/Viewer_instructor.h
index 9a2a236b..82c8e346 100644
--- a/src/GudhUI/view/Viewer_instructor.h
+++ b/src/GudhUI/view/Viewer_instructor.h
@@ -1,15 +1,40 @@
-#ifndef VIEWER_INSTRUCTOR_H
-#define VIEWER_INSTRUCTOR_H
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 VIEW_VIEWER_INSTRUCTOR_H_
+#define VIEW_VIEWER_INSTRUCTOR_H_
// todo do a viewer instructor that have directely a pointer to a QGLviewer and buffer ot not triangles
-
-#include <memory>
+// Workaround for moc-qt4 not parsing boost headers
+#include <CGAL/config.h>
#include <QFileDialog>
#include <QKeyEvent>
#include <QGLViewer/camera.h>
+#include <memory>
+#include <utility> // for pair<>
#include "model/Complex_typedefs.h"
@@ -20,89 +45,73 @@
class Viewer;
class Viewer_parameter;
-class Viewer_instructor : public QWidget{
- Q_OBJECT
-
- typedef Geometry_trait::Point_3 Point_3;
- typedef Complex::Point Point;
- typedef Complex::Vertex_handle Vertex_handle;
- typedef Complex::Edge_handle Edge_handle;
- typedef Complex::Simplex_handle Simplex_handle;
-
-
- Viewer* viewer_;
- View_parameter view_params_;
- const Complex& mesh_;
- std::unique_ptr<Projector3D> projector_;
-
-
-public:
-
- Viewer_instructor(QWidget* parent,
- Viewer* viewer,
- const Complex& mesh
- );
-
-
- void initialize_bounding_box();
-
- std::pair<Point,Point> compute_bounding_box_corners();
-
- void show_entire_scene();
-
- const qglviewer::Camera* camera() const;
-
- int width() const;
- int height() const;
-
- /**
- * to change display parameters
- */
- View_parameter& view_params();
+class Viewer_instructor : public QWidget {
+ Q_OBJECT
+ typedef Geometry_trait::Point_3 Point_3;
+ typedef Complex::Point Point;
+ typedef Complex::Vertex_handle Vertex_handle;
+ typedef Complex::Edge_handle Edge_handle;
+ typedef Complex::Simplex Simplex;
-public:
+ Viewer* viewer_;
+ View_parameter view_params_;
+ const Complex& mesh_;
+ std::unique_ptr<Projector3D> projector_;
- /**
- * gives instructions to the viewer
- */
- void give_instructions();
+ public:
+ Viewer_instructor(QWidget* parent, Viewer* viewer, const Complex& mesh);
- void draw_edges();
- void draw_triangles();
- void draw_points();
+ void initialize_bounding_box();
+ std::pair<Point, Point> compute_bounding_box_corners();
- void draw_edge(const Point&,const Point&);
+ void show_entire_scene();
- void draw_point(const Point&);
+ const qglviewer::Camera* camera() const;
+ int width() const;
+ int height() const;
- /**
- * set the right color of vertex/edge/triangle considering the view_params choice
- */
- void set_color_vertex(Vertex_handle vh);
- void set_color_edge(Edge_handle eh);
+ /**
+ * to change display parameters
+ */
+ View_parameter& view_params();
- void set_color_triangle(const Simplex_handle& triangle);
+ public:
+ /**
+ * gives instructions to the viewer
+ */
+ void give_instructions();
-private:
- /**
- * Projection to 3D needed for the viewer.
- */
- Point_3 proj(const Point& p) const;
+ void draw_edges();
+ void draw_triangles();
+ void draw_points();
- public slots :
+ void draw_edge(const Point&, const Point&);
- void sceneChanged();
+ void draw_point(const Point&);
- void change_draw_vertices();
- void change_draw_edges();
- void change_draw_triangles();
- void change_light();
+ /**
+ * set the right color of vertex/edge/triangle considering the view_params choice
+ */
+ void set_color_vertex(Vertex_handle vh);
+ void set_color_edge(Edge_handle eh);
+ void set_color_triangle(const Simplex& triangle);
+ private:
+ /**
+ * Projection to 3D needed for the viewer.
+ */
+ Point_3 proj(const Point& p) const;
+ public slots:
+ void sceneChanged();
+ void change_draw_vertices();
+ void change_draw_edges();
+ void change_draw_triangles();
+ void change_light();
};
-#endif //VIEWER_INSTRUCTOR_H
+#endif // VIEW_VIEWER_INSTRUCTOR_H_
diff --git a/src/Hasse_complex/example/CMakeLists.txt b/src/Hasse_complex/example/CMakeLists.txt
deleted file mode 100644
index 564df49d..00000000
--- a/src/Hasse_complex/example/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-cmake_minimum_required(VERSION 2.6)
-project(GUDHIHasseComplexExample)
-
-add_executable ( hasse_complex_from_simplex_tree hasse_complex_from_simplex_tree.cpp )
-add_test(hasse_complex_from_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/hasse_complex_from_simplex_tree)
diff --git a/src/Hasse_complex/example/hasse_complex_from_simplex_tree.cpp b/src/Hasse_complex/example/hasse_complex_from_simplex_tree.cpp
deleted file mode 100644
index 1de43ab7..00000000
--- a/src/Hasse_complex/example/hasse_complex_from_simplex_tree.cpp
+++ /dev/null
@@ -1,124 +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): Vincent Rouvreau
- *
- * Copyright (C) 2014 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <ctime>
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-
-using namespace Gudhi;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-typedef Simplex_tree<> typeST;
-
-int main(int argc, char * const argv[]) {
- // TEST OF INSERTION
- std::cout << "********************************************************************" << std::endl;
- std::cout << "TEST OF INSERTION" << std::endl;
- typeST st;
-
- // ++ FIRST
- std::cout << " - INSERT (2,1,0)" << std::endl;
- typeVectorVertex SimplexVector1;
- SimplexVector1.push_back(2);
- SimplexVector1.push_back(1);
- SimplexVector1.push_back(0);
- st.insert_simplex_and_subfaces(SimplexVector1, 0.3);
-
- // ++ SECOND
- std::cout << " - INSERT 3" << std::endl;
- typeVectorVertex SimplexVector2;
- SimplexVector2.push_back(3);
- st.insert_simplex_and_subfaces(SimplexVector2, 0.1);
-
- // ++ THIRD
- std::cout << " - INSERT (0,3)" << std::endl;
- typeVectorVertex SimplexVector3;
- SimplexVector3.push_back(3);
- SimplexVector3.push_back(0);
- st.insert_simplex_and_subfaces(SimplexVector3, 0.2);
-
- // ++ FOURTH
- std::cout << " - INSERT (1,0) (already inserted)" << std::endl;
- typeVectorVertex SimplexVector4;
- SimplexVector4.push_back(1);
- SimplexVector4.push_back(0);
- st.insert_simplex_and_subfaces(SimplexVector4, 0.2);
-
- // ++ FIFTH
- std::cout << " - INSERT (3,4,5)" << std::endl;
- typeVectorVertex SimplexVector5;
- SimplexVector5.push_back(3);
- SimplexVector5.push_back(4);
- SimplexVector5.push_back(5);
- st.insert_simplex_and_subfaces(SimplexVector5, 0.3);
-
- // ++ SIXTH
- std::cout << " - INSERT (0,1,6,7)" << std::endl;
- typeVectorVertex SimplexVector6;
- SimplexVector6.push_back(0);
- SimplexVector6.push_back(1);
- SimplexVector6.push_back(6);
- SimplexVector6.push_back(7);
- st.insert_simplex_and_subfaces(SimplexVector6, 0.4);
-
- /* Inserted simplex: */
- /* 1 6 */
- /* o---o */
- /* /X\7/ 4 */
- /* o---o---o---o */
- /* 2 0 3\X/ */
- /* o */
- /* 5 */
-
- /* In other words: */
- /* A facet [2,1,0] */
- /* An edge [0,3] */
- /* A facet [3,4,5] */
- /* A cell [0,1,6,7] */
- /* A cell [4,5,8,9] */
- /* A facet [9,10,11] */
- /* An edge [11,6] */
- /* An edge [10,12,2] */
-
- // ++ GENERAL VARIABLE SET
- st.set_filtration(0.4); // Max filtration value
- st.set_dimension(3); // Max dimension = 3 -> (0,1,6,7)
-
- std::cout << "The complex contains " << st.num_simplices() << " simplices - " << st.num_vertices() << " vertices " << std::endl;
- std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- std::cout << "**************************************************************" << std::endl;
-
- for( auto f_simplex : st.filtration_simplex_range() )
- {
- std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- {
- std::cout << (int)vertex;
- }
- }
-
- return 0;
-}
diff --git a/src/Hasse_complex/include/gudhi/Hasse_complex.h b/src/Hasse_complex/include/gudhi/Hasse_complex.h
index 427d9916..67079687 100644
--- a/src/Hasse_complex/include/gudhi/Hasse_complex.h
+++ b/src/Hasse_complex/include/gudhi/Hasse_complex.h
@@ -1,208 +1,234 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GUDHI_HASSE_DIAGRAM_H
-#define GUDHI_HASSE_DIAGRAM_H
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HASSE_COMPLEX_H_
+#define HASSE_COMPLEX_H_
-#include <algorithm>
#include <boost/iterator/counting_iterator.hpp>
-namespace Gudhi{
+#include <algorithm>
+#include <utility> // for pair
+#include <vector>
+
+namespace Gudhi {
template < class HasseCpx >
-struct Hasse_simplex
-{
-//Complex_ds must verify that cpx->key(sh) is the order of sh in the filtration
+struct Hasse_simplex {
+ // Complex_ds must verify that cpx->key(sh) is the order of sh in the filtration
+
template< class Complex_ds >
- Hasse_simplex ( Complex_ds & cpx
- , typename Complex_ds::Simplex_handle sh )
- : key_(cpx.key(sh))
- , filtration_(cpx.filtration(sh))
- , boundary_()
- {
- boundary_.reserve(cpx.dimension(sh)+1);
- for( auto b_sh : cpx.boundary_simplex_range(sh) )
- { boundary_.push_back( cpx.key(b_sh) ); }
- }
-
- Hasse_simplex ( typename HasseCpx::Simplex_key key
+ Hasse_simplex(Complex_ds & cpx
+ , typename Complex_ds::Simplex_handle sh)
+ : key_(cpx.key(sh))
+ , filtration_(cpx.filtration(sh))
+ , boundary_() {
+ boundary_.reserve(cpx.dimension(sh) + 1);
+ for (auto b_sh : cpx.boundary_simplex_range(sh)) {
+ boundary_.push_back(cpx.key(b_sh));
+ }
+ }
+
+ Hasse_simplex(typename HasseCpx::Simplex_key key
, typename HasseCpx::Filtration_value fil
, std::vector<typename HasseCpx::Simplex_handle> boundary)
- : key_(key)
- , filtration_(fil)
- , boundary_(boundary) {}
+ : key_(key)
+ , filtration_(fil)
+ , boundary_(boundary) { }
- typename HasseCpx::Simplex_key key_;
- typename HasseCpx::Filtration_value filtration_;
+ typename HasseCpx::Simplex_key key_;
+ typename HasseCpx::Filtration_value filtration_;
std::vector<typename HasseCpx::Simplex_handle> boundary_;
};
-
-
-/** \brief Data structure representing a Hasse diagram, i.e.
- * a complex where all codimension 1 incidence
- * relations are explicitly encoded.
- *
- * \implements FilteredComplex
- * \ingroup simplex_tree
- */
-template < typename FiltrationValue = double
- , typename SimplexKey = int
- , typename VertexHandle = int
- >
-class Hasse_complex
-{
-public:
-
- typedef Hasse_simplex<Hasse_complex> Hasse_simp;
- typedef FiltrationValue Filtration_value;
- typedef SimplexKey Simplex_key;
- typedef int Simplex_handle; //index in vector complex_
-
- typedef boost::counting_iterator< Simplex_handle > Filtration_simplex_iterator;
- typedef boost::iterator_range<Filtration_simplex_iterator> Filtration_simplex_range;
-
- typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator;
- typedef boost::iterator_range<Boundary_simplex_iterator> Boundary_simplex_range;
-
- typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator;
- typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range;
-
-
-/* only dimension 0 skeleton_simplex_range(...) */
- Skeleton_simplex_range skeleton_simplex_range( int dim = 0 ) {
- if(dim != 0) { std::cerr << "Dimension must be 0 \n"; }
- return Skeleton_simplex_range(vertices_.begin(),vertices_.end());
+/** \private
+ * \brief Data structure representing a Hasse diagram, i.e.
+ * a complex where all codimension 1 incidence
+ * relations are explicitly encoded.
+ *
+ * \implements FilteredComplex
+ * \ingroup simplex_tree
+ */
+template < typename FiltrationValue = double
+, typename SimplexKey = int
+, typename VertexHandle = int
+>
+class Hasse_complex {
+ public:
+ typedef Hasse_simplex<Hasse_complex> Hasse_simp;
+ typedef FiltrationValue Filtration_value;
+ typedef SimplexKey Simplex_key;
+ typedef int Simplex_handle; // index in vector complex_
+
+ typedef boost::counting_iterator< Simplex_handle > Filtration_simplex_iterator;
+ typedef boost::iterator_range<Filtration_simplex_iterator> Filtration_simplex_range;
+
+ typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator;
+ typedef boost::iterator_range<Boundary_simplex_iterator> Boundary_simplex_range;
+
+ typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator;
+ typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range;
+
+ /* only dimension 0 skeleton_simplex_range(...) */
+ Skeleton_simplex_range skeleton_simplex_range(int dim = 0) {
+ if (dim != 0) {
+ std::cerr << "Dimension must be 0 \n";
+ }
+ return Skeleton_simplex_range(vertices_.begin(), vertices_.end());
}
template < class Complex_ds >
Hasse_complex(Complex_ds & cpx)
- : complex_()
- , vertices_()
- , threshold_(cpx.filtration())
- , num_vertices_()
- , dim_max_(cpx.dimension())
- {
+ : complex_()
+ , vertices_()
+ , threshold_(cpx.filtration())
+ , num_vertices_()
+ , dim_max_(cpx.dimension()) {
complex_.reserve(cpx.num_simplices());
int idx = 0;
- for(auto cpx_sh : cpx.filtration_simplex_range())
- {
- complex_.push_back(Hasse_simp(cpx,cpx_sh));
- if(dimension(idx) == 0) { vertices_.push_back(idx); }
- ++idx;
+ for (auto cpx_sh : cpx.filtration_simplex_range()) {
+ complex_.push_back(Hasse_simp(cpx, cpx_sh));
+ if (dimension(idx) == 0) {
+ vertices_.push_back(idx);
+ }
+ ++idx;
}
}
Hasse_complex()
- : complex_()
- , vertices_()
- , threshold_(0)
- , num_vertices_(0)
- , dim_max_(-1) {}
-
- size_t num_simplices() { return complex_.size(); }
+ : complex_()
+ , vertices_()
+ , threshold_(0)
+ , num_vertices_(0)
+ , dim_max_(-1) { }
+
+ size_t num_simplices() {
+ return complex_.size();
+ }
- Filtration_simplex_range filtration_simplex_range()
- { return Filtration_simplex_range( Filtration_simplex_iterator(0)
- , Filtration_simplex_iterator(complex_.size()) ); }
+ Filtration_simplex_range filtration_simplex_range() {
+ return Filtration_simplex_range(Filtration_simplex_iterator(0)
+ , Filtration_simplex_iterator(complex_.size()));
+ }
- Simplex_key key( Simplex_handle sh ) { return complex_[sh].key_; }
+ Simplex_key key(Simplex_handle sh) {
+ return complex_[sh].key_;
+ }
- Simplex_key null_key() { return -1; }
+ Simplex_key null_key() {
+ return -1;
+ }
- Simplex_handle simplex( Simplex_key key )
- {
- if(key == null_key()) return null_simplex();
+ Simplex_handle simplex(Simplex_key key) {
+ if (key == null_key()) return null_simplex();
return key;
}
- Simplex_handle null_simplex() { return -1; }
+ Simplex_handle null_simplex() {
+ return -1;
+ }
- Filtration_value filtration( Simplex_handle sh ) {
- if( sh == null_simplex() ) { return filtration(); }
+ Filtration_value filtration(Simplex_handle sh) {
+ if (sh == null_simplex()) {
+ return filtration();
+ }
return complex_[sh].filtration_;
}
- Filtration_value filtration() { return threshold_; }
+ Filtration_value filtration() {
+ return threshold_;
+ }
+
+ int dimension(Simplex_handle sh) {
+ if (complex_[sh].boundary_.empty()) return 0;
+ return complex_[sh].boundary_.size() - 1;
+ }
- int dimension ( Simplex_handle sh ) {
- if(complex_[sh].boundary_.empty()) return 0;
- return complex_[sh].boundary_.size()-1;
+ int dimension() {
+ return dim_max_;
}
- int dimension () { return dim_max_; }
- std::pair<Simplex_handle,Simplex_handle> endpoints( Simplex_handle sh )
- { return std::pair<Simplex_handle,Simplex_handle>( complex_[sh].boundary_[0]
- , complex_[sh].boundary_[1] ) ;}
+ std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
+ return std::pair<Simplex_handle, Simplex_handle>(complex_[sh].boundary_[0]
+ , complex_[sh].boundary_[1]);
+ }
- void assign_key( Simplex_handle sh, Simplex_key key) { complex_[sh].key_ = key; }
+ void assign_key(Simplex_handle sh, Simplex_key key) {
+ complex_[sh].key_ = key;
+ }
- Boundary_simplex_range boundary_simplex_range ( Simplex_handle sh )
- { return Boundary_simplex_range( complex_[sh].boundary_.begin()
- , complex_[sh].boundary_.end() ); }
+ Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) {
+ return Boundary_simplex_range(complex_[sh].boundary_.begin()
+ , complex_[sh].boundary_.end());
+ }
- void display_simplex(Simplex_handle sh)
- {
+ void display_simplex(Simplex_handle sh) {
std::cout << dimension(sh) << " ";
- for(auto sh_b : boundary_simplex_range(sh)) std::cout << sh_b << " ";
+ for (auto sh_b : boundary_simplex_range(sh)) std::cout << sh_b << " ";
std::cout << " " << filtration(sh) << " key=" << key(sh);
}
- void initialize_filtration()
- {
+ void initialize_filtration() {
Simplex_key key = 0;
- for(auto & h_simp : complex_) { h_simp.key_ = key; ++key; }
+ for (auto & h_simp : complex_) {
+ h_simp.key_ = key;
+ ++key;
+ }
}
- std::vector< Hasse_simp > complex_;
+ std::vector< Hasse_simp > complex_;
std::vector<Simplex_handle> vertices_;
- Filtration_value threshold_;
- size_t num_vertices_;
- int dim_max_;
+ Filtration_value threshold_;
+ size_t num_vertices_;
+ int dim_max_;
};
template< typename T1, typename T2, typename T3 >
-std::istream& operator>> ( std::istream & is
- , Hasse_complex< T1, T2, T3 > & hcpx )
-{
+std::istream& operator>>(std::istream & is
+ , Hasse_complex< T1, T2, T3 > & hcpx) {
assert(hcpx.num_simplices() == 0);
size_t num_simp;
is >> num_simp;
- hcpx.complex_.reserve(num_simp);
-
- std::vector< typename Hasse_complex<T1,T2,T3>::Simplex_key > boundary;
- typename Hasse_complex<T1,T2,T3>::Filtration_value fil;
- typename Hasse_complex<T1,T2,T3>::Filtration_value max_fil = 0 ;
- int max_dim = -1;
- int key = 0 ;
- while(read_hasse_simplex( is, boundary, fil )) //read all simplices in the file as a list of vertices
- {
- //insert every simplex in the simplex tree
- hcpx.complex_.push_back( Hasse_simplex< Hasse_complex<T1,T2,T3> >(key,fil,boundary));
-
- if(max_dim < hcpx.dimension(key)) { max_dim = hcpx.dimension(key); }
- if(hcpx.dimension(key) == 0) { hcpx.vertices_.push_back(key); }
- if(max_fil < fil) { max_fil = fil; }
+ hcpx.complex_.reserve(num_simp);
+
+ std::vector< typename Hasse_complex<T1, T2, T3>::Simplex_key > boundary;
+ typename Hasse_complex<T1, T2, T3>::Filtration_value fil;
+ typename Hasse_complex<T1, T2, T3>::Filtration_value max_fil = 0;
+ int max_dim = -1;
+ int key = 0;
+ // read all simplices in the file as a list of vertices
+ while (read_hasse_simplex(is, boundary, fil)) {
+ // insert every simplex in the simplex tree
+ hcpx.complex_.push_back(Hasse_simplex< Hasse_complex<T1, T2, T3> >(key, fil, boundary));
+
+ if (max_dim < hcpx.dimension(key)) {
+ max_dim = hcpx.dimension(key);
+ }
+ if (hcpx.dimension(key) == 0) {
+ hcpx.vertices_.push_back(key);
+ }
+ if (max_fil < fil) {
+ max_fil = fil;
+ }
++key;
boundary.clear();
@@ -214,6 +240,6 @@ std::istream& operator>> ( std::istream & is
return is;
}
-} // namespace GUDHI
+} // namespace Gudhi
-#endif // GUDHI_HASSE_DIAGRAM_H
+#endif // HASSE_COMPLEX_H_
diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt
index 9487cce6..50d10025 100644
--- a/src/Persistent_cohomology/example/CMakeLists.txt
+++ b/src/Persistent_cohomology/example/CMakeLists.txt
@@ -2,39 +2,47 @@ cmake_minimum_required(VERSION 2.6)
project(GUDHIExPersCohom)
# problem with Visual Studio link on Boost program_options
-if (NOT MSVC)
- add_executable(persistence_from_simple_simplex_tree persistence_from_simple_simplex_tree.cpp)
- target_link_libraries(persistence_from_simple_simplex_tree ${Boost_SYSTEM_LIBRARY})
+add_definitions( -DBOOST_ALL_NO_LIB )
+add_definitions( -DBOOST_ALL_DYN_LINK )
- add_executable(rips_persistence rips_persistence.cpp)
- target_link_libraries(rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
-
- add_test(rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.25 -d 3 -p 3 -m 100)
-
- add_executable(persistence_from_file persistence_from_file.cpp)
- target_link_libraries(persistence_from_file ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
- add_test(persistence_from_file_3_2_0 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 2 -m 0)
- add_test(persistence_from_file_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
-
- if(GMPXX_FOUND AND GMP_FOUND)
- message("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}")
- message("GMP_LIBRARIES = ${GMP_LIBRARIES}")
-
- add_executable(rips_multifield_persistence rips_multifield_persistence.cpp )
- target_link_libraries(rips_multifield_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
- add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100)
+add_executable(plain_homology plain_homology.cpp)
+target_link_libraries(plain_homology ${Boost_SYSTEM_LIBRARY})
+add_test(plain_homology ${CMAKE_CURRENT_BINARY_DIR}/plain_homology)
+
+add_executable(persistence_from_simple_simplex_tree persistence_from_simple_simplex_tree.cpp)
+target_link_libraries(persistence_from_simple_simplex_tree ${Boost_SYSTEM_LIBRARY})
+add_test(persistence_from_simple_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_simple_simplex_tree 1 0)
+
+add_executable(rips_persistence rips_persistence.cpp)
+target_link_libraries(rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
- add_executable ( performance_rips_persistence performance_rips_persistence.cpp )
- target_link_libraries(performance_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+add_test(rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.25 -d 3 -p 3 -m 100)
- if(CGAL_FOUND)
- # uncomment to display debug traces
- # add_definitions(-DDEBUG_TRACES)
- add_executable(alpha_shapes_persistence alpha_shapes_persistence.cpp)
- target_link_libraries(alpha_shapes_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
- add_test(alpha_shapes_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 2 0.5)
- #add_test(alpha_shapes_persistence_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
- endif()
+add_executable(persistence_from_file persistence_from_file.cpp)
+target_link_libraries(persistence_from_file ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+add_test(persistence_from_file_3_2_0 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 2 -m 0)
+add_test(persistence_from_file_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
+if(GMPXX_FOUND AND GMP_FOUND)
+ message("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}")
+ message("GMP_LIBRARIES = ${GMP_LIBRARIES}")
+
+ add_executable(rips_multifield_persistence rips_multifield_persistence.cpp )
+ target_link_libraries(rips_multifield_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+ add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100)
+
+ add_executable ( performance_rips_persistence performance_rips_persistence.cpp )
+ target_link_libraries(performance_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+
+ if(CGAL_FOUND)
+ if (CMAKE_BUILD_TYPE MATCHES Debug)
+ # For programs to be more verbose
+ add_definitions(-DDEBUG_TRACES)
+ endif()
+ add_executable(alpha_shapes_persistence alpha_shapes_persistence.cpp)
+ target_link_libraries(alpha_shapes_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
+ add_test(alpha_shapes_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 2 0.5)
+ #add_test(alpha_shapes_persistence_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
endif()
+
endif()
diff --git a/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp b/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp
index 3a50c84c..6d5eebcf 100644
--- a/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp
@@ -1,24 +1,29 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Vincent Rouvreau
- *
- * Copyright (C) 2014 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2014 INRIA Saclay (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <boost/variant.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
@@ -27,36 +32,37 @@
#include <fstream>
#include <cmath>
-
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/Persistent_cohomology.h"
-#include <boost/variant.hpp>
+#include <string>
+#include <tuple>
+#include <map>
+#include <utility>
+#include <list>
+#include <vector>
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
// Alpha_shape_3 templates type definitions
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
-typedef CGAL::Alpha_shape_vertex_base_3<Kernel> Vb;
-typedef CGAL::Alpha_shape_cell_base_3<Kernel> Fb;
-typedef CGAL::Triangulation_data_structure_3<Vb,Fb> Tds;
-typedef CGAL::Delaunay_triangulation_3<Kernel,Tds> Triangulation_3;
-typedef CGAL::Alpha_shape_3<Triangulation_3> Alpha_shape_3;
+typedef CGAL::Alpha_shape_vertex_base_3<Kernel> Vb;
+typedef CGAL::Alpha_shape_cell_base_3<Kernel> Fb;
+typedef CGAL::Triangulation_data_structure_3<Vb, Fb> Tds;
+typedef CGAL::Delaunay_triangulation_3<Kernel, Tds> Triangulation_3;
+typedef CGAL::Alpha_shape_3<Triangulation_3> Alpha_shape_3;
// From file type definition
-typedef Kernel::Point_3 Point_3;
+typedef Kernel::Point_3 Point_3;
// filtration with alpha values needed type definition
typedef Alpha_shape_3::FT Alpha_value_type;
-typedef CGAL::Object Object;
+typedef CGAL::Object Object;
typedef CGAL::Dispatch_output_iterator<
- CGAL::cpp11::tuple<Object, Alpha_value_type>,
- CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >, std::back_insert_iterator< std::vector<Alpha_value_type> >
- > > Dispatch;
-typedef Alpha_shape_3::Cell_handle Cell_handle;
-typedef Alpha_shape_3::Facet Facet;
-typedef Alpha_shape_3::Edge Edge_3;
+CGAL::cpp11::tuple<Object, Alpha_value_type>,
+CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
+ std::back_insert_iterator< std::vector<Alpha_value_type> > > > Dispatch;
+typedef Alpha_shape_3::Cell_handle Cell_handle;
+typedef Alpha_shape_3::Facet Facet;
+typedef Alpha_shape_3::Edge Edge_3;
typedef std::list<Alpha_shape_3::Vertex_handle> Vertex_list;
// gudhi type definition
@@ -65,70 +71,60 @@ typedef std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex > Alpha_shape
typedef std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex> Alpha_shape_simplex_tree_pair;
typedef std::vector< Simplex_tree_vertex > Simplex_tree_vector_vertex;
-//#define DEBUG_TRACES
-
-Vertex_list from (const Cell_handle& ch)
-{
+Vertex_list from(const Cell_handle& ch) {
Vertex_list the_list;
- for (auto i = 0; i < 4; i++)
- {
+ for (auto i = 0; i < 4; i++) {
#ifdef DEBUG_TRACES
std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
the_list.push_back(ch->vertex(i));
}
return the_list;
}
-Vertex_list from (const Facet& fct)
-{
+
+Vertex_list from(const Facet& fct) {
Vertex_list the_list;
- for (auto i = 0; i < 4; i++)
- {
- if (fct.second != i)
- {
+ for (auto i = 0; i < 4; i++) {
+ if (fct.second != i) {
#ifdef DEBUG_TRACES
std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
the_list.push_back(fct.first->vertex(i));
}
}
return the_list;
}
-Vertex_list from (const Edge_3& edg)
-{
+
+Vertex_list from(const Edge_3& edg) {
Vertex_list the_list;
- for (auto i = 0; i < 4; i++)
- {
- if ((edg.second == i) ||(edg.third == i))
- {
+ for (auto i = 0; i < 4; i++) {
+ if ((edg.second == i) || (edg.third == i)) {
#ifdef DEBUG_TRACES
std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
the_list.push_back(edg.first->vertex(i));
}
}
return the_list;
}
-Vertex_list from (const Alpha_shape_3::Vertex_handle& vh)
-{
+
+Vertex_list from(const Alpha_shape_3::Vertex_handle& vh) {
Vertex_list the_list;
#ifdef DEBUG_TRACES
std::cout << "from vertex=" << vh->point() << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
the_list.push_back(vh);
return the_list;
}
-void usage(char * const progName)
-{
- std::cerr << "Usage: " << progName << " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
- exit(-1); // ----- >>
+void usage(char * const progName) {
+ std::cerr << "Usage: " << progName <<
+ " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
+ exit(-1);
}
-int main (int argc, char * const argv[])
-{
-
- int coeff_field_characteristic=0;
+int main(int argc, char * const argv[]) {
+ int coeff_field_characteristic = 0;
int returnedScanValue = sscanf(argv[2], "%d", &coeff_field_characteristic);
if ((returnedScanValue == EOF) || (coeff_field_characteristic <= 0)) {
std::cerr << "Error: " << argv[2] << " is not correct\n";
@@ -149,102 +145,96 @@ int main (int argc, char * const argv[])
}
// Read points from file
- std::string filegraph = argv[1];
+ std::string filegraph = argv[1];
std::list<Point_3> lp;
std::ifstream is(filegraph.c_str());
int n;
is >> n;
#ifdef DEBUG_TRACES
std::cout << "Reading " << n << " points " << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
Point_3 p;
- for( ; n>0 ; n--) {
+ for (; n > 0; n--) {
is >> p;
lp.push_back(p);
}
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
- Alpha_shape_3 as(lp.begin(),lp.end(),0,Alpha_shape_3::GENERAL);
+ Alpha_shape_3 as(lp.begin(), lp.end(), 0, Alpha_shape_3::GENERAL);
#ifdef DEBUG_TRACES
std::cout << "Alpha shape computed in GENERAL mode" << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
// filtration with alpha values from alpha shape
std::vector<Object> the_objects;
std::vector<Alpha_value_type> the_alpha_values;
- Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>( std::back_inserter(the_objects), std::back_inserter(the_alpha_values));
+ Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>(std::back_inserter(the_objects),
+ std::back_inserter(the_alpha_values));
as.filtration_with_alpha_values(disp);
#ifdef DEBUG_TRACES
std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
Alpha_shape_3::size_type count_vertices = 0;
- Alpha_shape_3::size_type count_edges = 0;
- Alpha_shape_3::size_type count_facets = 0;
- Alpha_shape_3::size_type count_cells = 0;
+ Alpha_shape_3::size_type count_edges = 0;
+ Alpha_shape_3::size_type count_facets = 0;
+ Alpha_shape_3::size_type count_cells = 0;
// Loop on objects vector
Vertex_list vertex_list;
Simplex_tree<> 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)
- {
+ 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);
count_cells++;
if (dim_max < 3) {
- dim_max=3; // Cell is of dim 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);
count_facets++;
if (dim_max < 2) {
- dim_max=2; // Facet is of dim 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);
count_edges++;
if (dim_max < 1) {
- dim_max=1; // Edge_3 is of dim 1
+ // Edge_3 is of dim 1
+ dim_max = 1;
}
- }
- else if (const Alpha_shape_3::Vertex_handle* vertex = CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator))
- {
+ } else if (const Alpha_shape_3::Vertex_handle * vertex =
+ CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator)) {
count_vertices++;
vertex_list = from(*vertex);
}
// Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
Simplex_tree_vector_vertex the_simplex_tree;
- for (auto the_alpha_shape_vertex:vertex_list)
- {
+ 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())
- {
+ if (the_map_iterator == map_cgal_simplex_tree.end()) {
// alpha shape not found
Simplex_tree_vertex vertex = map_cgal_simplex_tree.size();
#ifdef DEBUG_TRACES
std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
the_simplex_tree.push_back(vertex);
- map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex,vertex));
- } else
- {
+ map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex));
+ } else {
// alpha shape found
Simplex_tree_vertex vertex = the_map_iterator->second;
#ifdef DEBUG_TRACES
std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
the_simplex_tree.push_back(vertex);
}
}
@@ -252,7 +242,7 @@ int main (int argc, char * const argv[])
Filtration_value filtr = std::sqrt(*the_alpha_value_iterator);
#ifdef DEBUG_TRACES
std::cout << "filtration = " << filtr << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
if (filtr > filtration_max) {
filtration_max = filtr;
}
@@ -263,14 +253,13 @@ int main (int argc, char * const argv[])
std::cout << "This shall not happen" << std::endl;
}
simplex_tree.set_filtration(filtration_max);
- simplex_tree.set_num_simplices(count_vertices + count_edges + count_facets + count_cells);
simplex_tree.set_dimension(dim_max);
#ifdef DEBUG_TRACES
std::cout << "vertices \t\t" << count_vertices << std::endl;
- std::cout << "edges \t\t" << count_edges << std::endl;
- std::cout << "facets \t\t" << count_facets << std::endl;
- std::cout << "cells \t\t" << count_cells << std::endl;
+ std::cout << "edges \t\t" << count_edges << std::endl;
+ std::cout << "facets \t\t" << count_facets << std::endl;
+ std::cout << "cells \t\t" << count_cells << std::endl;
std::cout << "Information of the Simplex Tree: " << std::endl;
@@ -278,23 +267,25 @@ int main (int argc, char * const argv[])
std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl;
std::cout << " Dimension = " << simplex_tree.dimension() << " ";
std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl;
-#endif // DEBUG_TRACES
+#endif // DEBUG_TRACES
#ifdef DEBUG_TRACES
std::cout << "Iterator on vertices: " << std::endl;
- for( auto vertex : simplex_tree.complex_vertex_range() )
- { std::cout << vertex << " "; }
-#endif // DEBUG_TRACES
+ for (auto vertex : simplex_tree.complex_vertex_range()) {
+ std::cout << vertex << " ";
+ }
+#endif // DEBUG_TRACES
// Sort the simplices in the order of the filtration
simplex_tree.initialize_filtration();
std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl;
// Compute the persistence diagram of the complex
- Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh( simplex_tree );
- pcoh.init_coefficients( coeff_field_characteristic ); //initializes the coefficient field for homology
+ Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(simplex_tree);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
- pcoh.compute_persistent_cohomology( min_persistence );
+ pcoh.compute_persistent_cohomology(min_persistence);
pcoh.output_diagram();
diff --git a/src/Persistent_cohomology/example/performance_rips_persistence.cpp b/src/Persistent_cohomology/example/performance_rips_persistence.cpp
index 077c2b07..fc48d6b1 100644
--- a/src/Persistent_cohomology/example/performance_rips_persistence.cpp
+++ b/src/Persistent_cohomology/example/performance_rips_persistence.cpp
@@ -1,49 +1,51 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "gudhi/reader_utils.h"
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/distance_functions.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/Persistent_cohomology.h"
-#include "gudhi/Persistent_cohomology/Multi_field.h"
-#include "gudhi/Hasse_complex.h"
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Persistent_cohomology/Multi_field.h>
+#include <gudhi/Hasse_complex.h>
#include <chrono>
+#include <string>
+#include <vector>
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
/* Compute the persistent homology of the complex cpx with coefficients in Z/pZ. */
template< typename FilteredComplex>
-void timing_persistence( FilteredComplex & cpx
- , int p );
+void timing_persistence(FilteredComplex & cpx
+ , int p);
/* Compute multi-field persistent homology of the complex cpx with coefficients in
* Z/rZ for all prime number r in [p;q].*/
template< typename FilteredComplex>
-void timing_persistence( FilteredComplex & cpx
- , int p
- , int q );
+void timing_persistence(FilteredComplex & cpx
+ , int p
+ , int q);
/* Timings for the computation of persistent homology with different
* representations of a Rips complex and different coefficient fields. The
@@ -59,111 +61,154 @@ void timing_persistence( FilteredComplex & cpx
* We present also timings for the computation of multi-field persistent
* homology in all fields Z/rZ for r prime between 2 and 1223.
*/
-int main (int argc, char * argv[])
-{
+int main(int argc, char * argv[]) {
std::chrono::time_point<std::chrono::system_clock> start, end;
- int enlapsed_sec;
+ int elapsed_sec;
+ {
- std::string filepoints = "../examples/Kl.txt";
- Filtration_value threshold = 0.3;
- int dim_max = 3;
- int p = 2;
- int q = 1223;
+ std::string filepoints = "../../../data/points/Kl.txt";
+ Filtration_value threshold = 0.27;
+ int dim_max = 3;
+ int p = 2;
+ int q = 1223;
-// Extract the points from the file filepoints
+ // Extract the points from the file filepoints
typedef std::vector<double> Point_t;
std::vector< Point_t > points;
- read_points( filepoints, points );
+ read_points(filepoints, points);
-// Compute the proximity graph of the points
+ // Compute the proximity graph of the points
start = std::chrono::system_clock::now();
- Graph_t prox_graph = compute_proximity_graph( points, threshold
- , euclidean_distance<Point_t> );
+ Graph_t prox_graph = compute_proximity_graph(points, threshold
+ , euclidean_distance<Point_t>);
end = std::chrono::system_clock::now();
- enlapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(end-start).count();
- std::cout << "Compute Rips graph in " << enlapsed_sec << " sec.\n";
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << "Compute Rips graph in " << elapsed_sec << " ms.\n";
-// Construct the Rips complex in a Simplex Tree
- Simplex_tree<> st;
+ // Construct the Rips complex in a Simplex Tree
+ Simplex_tree<> st;
start = std::chrono::system_clock::now();
- st.insert_graph(prox_graph); // insert the proximity graph in the simplex tree
- st.expansion( dim_max ); // expand the graph until dimension dim_max
+ // insert the proximity graph in the simplex tree
+ st.insert_graph(prox_graph);
+ // expand the graph until dimension dim_max
+ st.expansion(dim_max);
end = std::chrono::system_clock::now();
- enlapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(end-start).count();
- std::cout << "Compute Rips complex in " << enlapsed_sec << " sec.\n";
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << "Compute Rips complex in " << elapsed_sec << " ms.\n";
std::cout << " - dimension = " << st.dimension() << std::endl;
std::cout << " - number of simplices = " << st.num_simplices() << std::endl;
-// Sort the simplices in the order of the filtration
+ // Sort the simplices in the order of the filtration
start = std::chrono::system_clock::now();
st.initialize_filtration();
end = std::chrono::system_clock::now();
- enlapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(end-start).count();
- std::cout << "Order the simplices of the filtration in " << enlapsed_sec << " sec.\n";
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << "Order the simplices of the filtration in " << elapsed_sec << " ms.\n";
+
+ // Copy the keys inside the simplices
+ start = std::chrono::system_clock::now();
+ {
+ int count = 0;
+ for (auto sh : st.filtration_simplex_range())
+ st.assign_key(sh, count++);
+ }
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << "Copied the keys inside the simplices in " << elapsed_sec << " ms.\n";
-// Convert the simplex tree into a hasse diagram
+ // Convert the simplex tree into a hasse diagram
start = std::chrono::system_clock::now();
Hasse_complex<> hcpx(st);
end = std::chrono::system_clock::now();
- enlapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(end-start).count();
- std::cout << "Convert the simplex tree into a Hasse diagram in " << enlapsed_sec << " sec.\n";
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << "Convert the simplex tree into a Hasse diagram in " << elapsed_sec << " ms.\n";
std::cout << "Timings when using a simplex tree: \n";
- timing_persistence(st,p);
- timing_persistence(st,q);
- timing_persistence(st,p,q);
+ timing_persistence(st, p);
+ timing_persistence(st, q);
+ timing_persistence(st, p, q);
std::cout << "Timings when using a Hasse complex: \n";
- timing_persistence(hcpx,p);
- timing_persistence(hcpx,q);
- timing_persistence(hcpx,p,q);
+ timing_persistence(hcpx, p);
+ timing_persistence(hcpx, q);
+ timing_persistence(hcpx, p, q);
+ start = std::chrono::system_clock::now();
+ }
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << "Running the complex destructors in " << elapsed_sec << " ms.\n";
return 0;
}
-
template< typename FilteredComplex>
void
-timing_persistence( FilteredComplex & cpx
- , int p )
-{
+timing_persistence(FilteredComplex & cpx
+ , int p) {
std::chrono::time_point<std::chrono::system_clock> start, end;
- int enlapsed_sec;
+ int elapsed_sec;
+ {
+ start = std::chrono::system_clock::now();
+ Persistent_cohomology< FilteredComplex, Field_Zp > pcoh(cpx);
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Initialize pcoh in " << elapsed_sec << " ms.\n";
+ // initializes the coefficient field for homology
+ start = std::chrono::system_clock::now();
+ pcoh.init_coefficients(p);
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Initialize the coefficient field in " << elapsed_sec << " ms.\n";
- Persistent_cohomology< FilteredComplex, Field_Zp > pcoh (cpx);
- pcoh.init_coefficients( p ); //initilizes the coefficient field for homology
-
start = std::chrono::system_clock::now();
-
- pcoh.compute_persistent_cohomology( INFINITY );
-
+
+ pcoh.compute_persistent_cohomology(INFINITY);
+
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Compute persistent homology in Z/" << p << "Z in " << elapsed_sec << " ms.\n";
+ start = std::chrono::system_clock::now();
+ }
end = std::chrono::system_clock::now();
- enlapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(end-start).count();
- std::cout << " Compute persistent homology in Z/"<<p<<"Z in " << enlapsed_sec << " sec.\n";
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Run the persistence destructors in " << elapsed_sec << " ms.\n";
}
template< typename FilteredComplex>
void
-timing_persistence( FilteredComplex & cpx
- , int p
- , int q )
-{
+timing_persistence(FilteredComplex & cpx
+ , int p
+ , int q) {
std::chrono::time_point<std::chrono::system_clock> start, end;
- int enlapsed_sec;
-
- Persistent_cohomology< FilteredComplex, Multi_field > pcoh (cpx);
- pcoh.init_coefficients( p, q ); //initilizes the coefficient field for homology
+ int elapsed_sec;
+ {
+ start = std::chrono::system_clock::now();
+ Persistent_cohomology< FilteredComplex, Multi_field > pcoh(cpx);
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Initialize pcoh in " << elapsed_sec << " ms.\n";
+ // initializes the coefficient field for homology
+ start = std::chrono::system_clock::now();
+ pcoh.init_coefficients(p, q);
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Initialize the coefficient field in " << elapsed_sec << " ms.\n";
// compute persistent homology, disgarding persistent features of life shorter than min_persistence
start = std::chrono::system_clock::now();
- pcoh.compute_persistent_cohomology( INFINITY );
+ pcoh.compute_persistent_cohomology(INFINITY);
end = std::chrono::system_clock::now();
- enlapsed_sec = std::chrono::duration_cast<std::chrono::seconds>(end-start).count();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << " Compute multi-field persistent homology in all coefficient fields Z/pZ "
- << "with p in ["<<p<<";"<<q<<"] in " << enlapsed_sec << " sec.\n";
+ << "with p in [" << p << ";" << q << "] in " << elapsed_sec << " ms.\n";
+ start = std::chrono::system_clock::now();
+ }
+ end = std::chrono::system_clock::now();
+ elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+ std::cout << " Run the persistence destructors in " << elapsed_sec << " ms.\n";
}
diff --git a/src/Persistent_cohomology/example/persistence_from_file.cpp b/src/Persistent_cohomology/example/persistence_from_file.cpp
index e886aea7..8eb8d0f3 100644
--- a/src/Persistent_cohomology/example/persistence_from_file.cpp
+++ b/src/Persistent_cohomology/example/persistence_from_file.cpp
@@ -1,141 +1,144 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Vincent Rouvreau
- *
- * Copyright (C) 2014 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "gudhi/reader_utils.h"
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/distance_functions.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/Persistent_cohomology.h"
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2014 INRIA Saclay (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
#include <boost/program_options.hpp>
+#include <string>
+
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
-typedef int Vertex_handle;
-typedef double Filtration_value;
-
-void program_options( int argc, char * argv[]
- , std::string & simplex_tree_file
- , std::string & output_file
- , int & p
- , Filtration_value & min_persistence );
-
-int main (int argc, char * argv[])
-{
- std::string simplex_tree_file;
- std::string output_file ;
- int p ;
- Filtration_value min_persistence;
-
- program_options(argc,argv,simplex_tree_file,output_file,p,min_persistence);
-
- std::cout << "Simplex_tree from file=" << simplex_tree_file.c_str() << " - output_file=" << output_file.c_str() << std::endl;
- std::cout << " - p=" << p << " - min_persistence=" << min_persistence << std::endl;
-
- // Construct the Rips complex in a Simplex Tree
- Simplex_tree<> simplex_tree;
-
- std::ifstream simplex_tree_stream(simplex_tree_file);
- simplex_tree_stream >> simplex_tree;
-
- std::cout << "The complex contains " << simplex_tree.num_simplices() << " simplices" << std::endl;
- std::cout << " - dimension " << simplex_tree.dimension() << " - filtration " << simplex_tree.filtration() << std::endl;
-
- /*
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- for( auto f_simplex : simplex_tree.filtration_simplex_range() )
- { std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
- for( auto vertex : simplex_tree.simplex_vertex_range(f_simplex) )
- { std::cout << vertex << " "; }
- std::cout << std::endl;
- }*/
-
- // Sort the simplices in the order of the filtration
- simplex_tree.initialize_filtration();
-
- // Compute the persistence diagram of the complex
- Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh( simplex_tree );
- pcoh.init_coefficients( p ); //initilizes the coefficient field for homology
-
- pcoh.compute_persistent_cohomology( min_persistence );
-
- // Output the diagram in output_file
- if(output_file.empty()) { pcoh.output_diagram(); }
- else {
- std::ofstream out(output_file);
- pcoh.output_diagram(out);
- out.close(); }
+typedef int Vertex_handle;
+typedef double Filtration_value;
+
+void program_options(int argc, char * argv[]
+ , std::string & simplex_tree_file
+ , std::string & output_file
+ , int & p
+ , Filtration_value & min_persistence);
+
+int main(int argc, char * argv[]) {
+ std::string simplex_tree_file;
+ std::string output_file;
+ int p;
+ Filtration_value min_persistence;
+
+ program_options(argc, argv, simplex_tree_file, output_file, p, min_persistence);
+
+ std::cout << "Simplex_tree from file=" << simplex_tree_file.c_str() << " - output_file=" << output_file.c_str()
+ << std::endl;
+ std::cout << " - p=" << p << " - min_persistence=" << min_persistence << std::endl;
+
+ // Construct the Rips complex in a Simplex Tree
+ Simplex_tree<> simplex_tree;
+
+ std::ifstream simplex_tree_stream(simplex_tree_file);
+ simplex_tree_stream >> simplex_tree;
+
+ std::cout << "The complex contains " << simplex_tree.num_simplices() << " simplices" << std::endl;
+ std::cout << " - dimension " << simplex_tree.dimension() << " - filtration " << simplex_tree.filtration()
+ << std::endl;
+
+ /*
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for( auto f_simplex : simplex_tree.filtration_simplex_range() )
+ { std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for( auto vertex : simplex_tree.simplex_vertex_range(f_simplex) )
+ { std::cout << vertex << " "; }
+ std::cout << std::endl;
+ }*/
+
+ // Sort the simplices in the order of the filtration
+ simplex_tree.initialize_filtration();
+
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(simplex_tree);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(p);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in output_file
+ if (output_file.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::ofstream out(output_file);
+ pcoh.output_diagram(out);
+ out.close();
+ }
- return 0;
+ return 0;
}
-
-
-void program_options( int argc, char * argv[]
- , std::string & simplex_tree_file
- , std::string & output_file
- , int & p
- , Filtration_value & min_persistence )
-{
+void program_options(int argc, char * argv[]
+ , std::string & simplex_tree_file
+ , std::string & output_file
+ , int & p
+ , Filtration_value & min_persistence) {
namespace po = boost::program_options;
- po::options_description hidden("Hidden options");
+ po::options_description hidden("Hidden options");
hidden.add_options()
- ("input-file", po::value<std::string>(&simplex_tree_file),
- "Name of file containing a simplex set. Format is one simplex per line (cf. reader_utils.h - read_simplex): Dim1 X11 X12 ... X1d Fil1 ");
-
+ ("input-file", po::value<std::string>(&simplex_tree_file),
+ "Name of file containing a simplex set. Format is one simplex per line (cf. reader_utils.h - read_simplex): Dim1 X11 X12 ... X1d Fil1 ");
+
po::options_description visible("Allowed options", 100);
visible.add_options()
- ("help,h", "produce help message")
- ("output-file,o", po::value<std::string>(&output_file)->default_value(std::string()),
- "Name of file in which the persistence diagram is written. Default print in std::cout")
- ("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");
+ ("help,h", "produce help message")
+ ("output-file,o", po::value<std::string>(&output_file)->default_value(std::string()),
+ "Name of file in which the persistence diagram is written. Default print in std::cout")
+ ("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");
po::positional_options_description pos;
pos.add("input-file", 1);
-
- po::options_description all; all.add(visible).add(hidden);
+
+ po::options_description all;
+ all.add(visible).add(hidden);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), vm);
+ options(all).positional(pos).run(), vm);
po::notify(vm);
- if (vm.count("help") || !vm.count("input-file"))
- {
- std::cout << std::endl;
- std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
- std::cout << "of a Rips complex defined on a set of input points.\n \n";
- std::cout << "The output diagram contains one bar per line, written with the convention: \n";
- std::cout << " p dim b d \n";
- std::cout << "where dim is the dimension of the homological feature,\n";
- std::cout << "b and d are respectively the birth and death of the feature and \n";
- std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl;
-
- std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
- std::cout << visible << std::endl;
- std::abort();
+ if (vm.count("help") || !vm.count("input-file")) {
+ std::cout << std::endl;
+ std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
+ std::cout << "of a Rips complex defined on a set of input points.\n \n";
+ std::cout << "The output diagram contains one bar per line, written with the convention: \n";
+ std::cout << " p dim b d \n";
+ std::cout << "where dim is the dimension of the homological feature,\n";
+ std::cout << "b and d are respectively the birth and death of the feature and \n";
+ std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl;
+
+ std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
+ std::cout << visible << std::endl;
+ std::abort();
}
}
diff --git a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp
index ba82e4e6..ba772f04 100644
--- a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp
+++ b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp
@@ -20,11 +20,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+
#include <iostream>
#include <ctime>
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/Persistent_cohomology.h"
+#include <utility>
+#include <vector>
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
@@ -34,15 +37,19 @@ typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
typedef Simplex_tree<> typeST;
-void usage(char * const progName)
-{
+void usage(char * const progName) {
std::cerr << "Usage: " << progName << " coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
- exit(-1); // ----- >>
+ exit(-1);
}
-int main (int argc, char * const argv[])
-{
- int coeff_field_characteristic=0;
+int main(int argc, char * const argv[]) {
+ // program args management
+ if (argc != 3) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
+ usage(argv[0]);
+ }
+
+ int coeff_field_characteristic = 0;
int returnedScanValue = sscanf(argv[1], "%d", &coeff_field_characteristic);
if ((returnedScanValue == EOF) || (coeff_field_characteristic <= 0)) {
std::cerr << "Error: " << argv[1] << " is not correct\n";
@@ -56,101 +63,65 @@ int main (int argc, char * const argv[])
usage(argv[0]);
}
- // program args management
- if (argc != 3) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
- usage(argv[0]);
- }
-
// TEST OF INSERTION
std::cout << "********************************************************************" << std::endl;
std::cout << "TEST OF INSERTION" << std::endl;
typeST st;
// ++ FIRST
- std::cout << " - INSERT (2,1,0)" << std::endl;
- typeVectorVertex SimplexVector1;
- SimplexVector1.push_back(2);
- SimplexVector1.push_back(1);
- SimplexVector1.push_back(0);
- st.insert_simplex_and_subfaces ( SimplexVector1, 0.3);
+ std::cout << " - INSERT (0,1,2)" << std::endl;
+ typeVectorVertex SimplexVector = {0, 1, 2};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.3);
// ++ SECOND
std::cout << " - INSERT 3" << std::endl;
- typeVectorVertex SimplexVector2;
- SimplexVector2.push_back(3);
- st.insert_simplex_and_subfaces ( SimplexVector2, 0.1);
+ SimplexVector = {3};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.1);
// ++ THIRD
std::cout << " - INSERT (0,3)" << std::endl;
- typeVectorVertex SimplexVector3;
- SimplexVector3.push_back(3);
- SimplexVector3.push_back(0);
- st.insert_simplex_and_subfaces ( SimplexVector3, 0.2);
+ SimplexVector = {0, 3};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.2);
// ++ FOURTH
- std::cout << " - INSERT (1,0) (already inserted)" << std::endl;
- typeVectorVertex SimplexVector4;
- SimplexVector4.push_back(1);
- SimplexVector4.push_back(0);
- st.insert_simplex_and_subfaces ( SimplexVector4, 0.2);
+ std::cout << " - INSERT (0,1) (already inserted)" << std::endl;
+ SimplexVector = {0, 1};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.2);
// ++ FIFTH
std::cout << " - INSERT (3,4,5)" << std::endl;
- typeVectorVertex SimplexVector5;
- SimplexVector5.push_back(3);
- SimplexVector5.push_back(4);
- SimplexVector5.push_back(5);
- st.insert_simplex_and_subfaces ( SimplexVector5, 0.3);
+ SimplexVector = {3, 4, 5};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.3);
// ++ SIXTH
std::cout << " - INSERT (0,1,6,7)" << std::endl;
- typeVectorVertex SimplexVector6;
- SimplexVector6.push_back(0);
- SimplexVector6.push_back(1);
- SimplexVector6.push_back(6);
- SimplexVector6.push_back(7);
- st.insert_simplex_and_subfaces ( SimplexVector6, 0.4);
+ SimplexVector = {0, 1, 6, 7};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.4);
// ++ SEVENTH
std::cout << " - INSERT (4,5,8,9)" << std::endl;
- typeVectorVertex SimplexVector7;
- SimplexVector7.push_back(4);
- SimplexVector7.push_back(5);
- SimplexVector7.push_back(8);
- SimplexVector7.push_back(9);
- st.insert_simplex_and_subfaces ( SimplexVector7, 0.4);
+ SimplexVector = {4, 5, 8, 9};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.4);
// ++ EIGHTH
std::cout << " - INSERT (9,10,11)" << std::endl;
- typeVectorVertex SimplexVector8;
- SimplexVector8.push_back(9);
- SimplexVector8.push_back(10);
- SimplexVector8.push_back(11);
- st.insert_simplex_and_subfaces ( SimplexVector8, 0.3);
-
+ SimplexVector = {9, 10, 11};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.3);
+
// ++ NINETH
std::cout << " - INSERT (2,10,12)" << std::endl;
- typeVectorVertex SimplexVector9;
- SimplexVector9.push_back(2);
- SimplexVector9.push_back(10);
- SimplexVector9.push_back(12);
- st.insert_simplex_and_subfaces ( SimplexVector9, 0.3);
-
+ SimplexVector = {2, 10, 12};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.3);
+
// ++ TENTH
std::cout << " - INSERT (11,6)" << std::endl;
- typeVectorVertex SimplexVector10;
- SimplexVector10.push_back(11);
- SimplexVector10.push_back(6);
- st.insert_simplex_and_subfaces ( SimplexVector10, 0.2);
+ SimplexVector = {6, 11};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.2);
// ++ ELEVENTH
std::cout << " - INSERT (13,14,15)" << std::endl;
- typeVectorVertex SimplexVector11;
- SimplexVector11.push_back(13);
- SimplexVector11.push_back(14);
- SimplexVector11.push_back(15);
- st.insert_simplex_and_subfaces ( SimplexVector11, 0.25);
+ SimplexVector = {13, 14, 15};
+ st.insert_simplex_and_subfaces(SimplexVector, 0.25);
/* Inserted simplex: */
/* 1 6 */
@@ -175,33 +146,31 @@ int main (int argc, char * const argv[])
st.set_dimension(2);
st.set_filtration(0.4);
- std::cout << "The complex contains " << st.num_simplices() << " simplices - " << st.num_vertices() << " vertices " << std::endl;
+ std::cout << "The complex contains " << st.num_simplices() << " simplices - " << st.num_vertices() << " vertices "
+ << std::endl;
std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:"
+ << std::endl;
std::cout << "**************************************************************" << std::endl;
std::cout << "strict graph G { " << std::endl;
- for( auto f_simplex : st.filtration_simplex_range() )
- {
+ for (auto f_simplex : st.filtration_simplex_range()) {
std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- {
- std::cout << (int)vertex << " -- ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << static_cast<int>(vertex) << " -- ";
}
std::cout << ";" << std::endl;
}
std::cout << "}" << std::endl;
- //std::cout << "**************************************************************" << std::endl;
- //st.print_hasse(std::cout);
std::cout << "**************************************************************" << std::endl;
-
// Compute the persistence diagram of the complex
persistent_cohomology::Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(st);
- pcoh.init_coefficients( coeff_field_characteristic ); //initiliazes the coefficient field for homology
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
- pcoh.compute_persistent_cohomology( min_persistence );
+ pcoh.compute_persistent_cohomology(min_persistence);
// Output the diagram in filediag
pcoh.output_diagram();
diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp
new file mode 100644
index 00000000..0a692717
--- /dev/null
+++ b/src/Persistent_cohomology/example/plain_homology.cpp
@@ -0,0 +1,84 @@
+/* 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): Marc Glisse
+ *
+ * Copyright (C) 2015 INRIA Saclay - Ile-de-France (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/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+
+#include <iostream>
+
+using namespace Gudhi;
+
+/* We could perfectly well use the default Simplex_tree<> (which uses
+ * Simplex_tree_options_full_featured), the following simply demonstrates
+ * how to save on storage by not storing a filtration value. */
+
+struct MyOptions : Simplex_tree_options_full_featured {
+ // Implicitly use 0 as filtration value for all simplices
+ static const bool store_filtration = false;
+ // The persistence algorithm needs this
+ static const bool store_key = true;
+ // I have few vertices
+ typedef short Vertex_handle;
+};
+typedef Simplex_tree<MyOptions> ST;
+
+int main() {
+ ST st;
+
+ /* Complex to build. */
+ /* 1 3 */
+ /* o---o */
+ /* /X\ / */
+ /* o---o o */
+ /* 2 0 4 */
+
+ const short triangle012[] = {0, 1, 2};
+ const short edge03[] = {0, 3};
+ const short edge13[] = {1, 3};
+ const short vertex4[] = {4};
+ st.insert_simplex_and_subfaces(triangle012);
+ st.insert_simplex_and_subfaces(edge03);
+ st.insert_simplex(edge13);
+ st.insert_simplex(vertex4);
+ // FIXME: Remove this line
+ st.set_dimension(2);
+
+ // Sort the simplices in the order of the filtration
+ st.initialize_filtration();
+
+ // Class for homology computation
+ persistent_cohomology::Persistent_cohomology<ST, persistent_cohomology::Field_Zp> pcoh(st);
+
+ // Initialize the coefficient field Z/2Z for homology
+ pcoh.init_coefficients(2);
+
+ // Compute the persistence diagram of the complex
+ pcoh.compute_persistent_cohomology();
+
+ // Print the result. The format is, on each line: 2 dim 0 inf
+ // where 2 represents the field, dim the dimension of the feature.
+ // 2 0 0 inf
+ // 2 0 0 inf
+ // 2 1 0 inf
+ // means that in Z/2Z-homology, the Betti numbers are b0=2 and b1=1.
+ pcoh.output_diagram();
+}
diff --git a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
index 297a8f98..5277bf7a 100644
--- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp
@@ -1,153 +1,157 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "gudhi/reader_utils.h"
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/distance_functions.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/Persistent_cohomology.h"
-#include "gudhi/Persistent_cohomology/Multi_field.h"
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Persistent_cohomology/Multi_field.h>
#include <boost/program_options.hpp>
+#include <string>
+#include <vector>
+
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
-typedef int Vertex_handle;
+typedef int Vertex_handle;
typedef double Filtration_value;
-void program_options( int argc, char * argv[]
- , std::string & filepoints
- , std::string & filediag
- , Filtration_value & threshold
- , int & dim_max
- , int & min_p
- , int & max_p
- , Filtration_value & min_persistence );
-
-int main (int argc, char * argv[])
-{
- std::string filepoints;
- std::string filediag;
+void program_options(int argc, char * argv[]
+ , std::string & filepoints
+ , std::string & filediag
+ , Filtration_value & threshold
+ , int & dim_max
+ , int & min_p
+ , int & max_p
+ , Filtration_value & min_persistence);
+
+int main(int argc, char * argv[]) {
+ std::string filepoints;
+ std::string filediag;
Filtration_value threshold;
- int dim_max;
- int min_p;
- int max_p;
+ int dim_max;
+ int min_p;
+ int max_p;
Filtration_value min_persistence;
- program_options(argc,argv,filepoints,filediag,threshold,dim_max,min_p,max_p,min_persistence);
+ program_options(argc, argv, filepoints, filediag, threshold, dim_max, min_p, max_p, min_persistence);
-// Extract the points from the file filepoints
+ // Extract the points from the file filepoints
typedef std::vector<double> Point_t;
std::vector< Point_t > points;
- read_points( filepoints, points );
+ read_points(filepoints, points);
-// Compute the proximity graph of the points
- Graph_t prox_graph = compute_proximity_graph( points, threshold
- , euclidean_distance<Point_t> );
+ // Compute the proximity graph of the points
+ Graph_t prox_graph = compute_proximity_graph(points, threshold
+ , euclidean_distance<Point_t>);
-// Construct the Rips complex in a Simplex Tree
- Simplex_tree<> st;
- st.insert_graph(prox_graph); // insert the proximity graph in the simplex tree
- st.expansion( dim_max ); // expand the graph until dimension dim_max
+ // Construct the Rips complex in a Simplex Tree
+ Simplex_tree<> st;
+ // insert the proximity graph in the simplex tree
+ st.insert_graph(prox_graph);
+ // expand the graph until dimension dim_max
+ st.expansion(dim_max);
-// Sort the simplices in the order of the filtration
+ // Sort the simplices in the order of the filtration
st.initialize_filtration();
-// Compute the persistence diagram of the complex
- Persistent_cohomology< Simplex_tree<>, Multi_field > pcoh( st );
- pcoh.init_coefficients( min_p, max_p ); //initilizes the coefficient field for homology
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology< Simplex_tree<>, Multi_field > pcoh(st);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(min_p, max_p);
// compute persistent homology, disgarding persistent features of life shorter than min_persistence
- pcoh.compute_persistent_cohomology( min_persistence );
-
-// Output the diagram in filediag
- if(filediag.empty()) { pcoh.output_diagram(); }
- else {
- std::ofstream out(filediag);
- pcoh.output_diagram(out);
- out.close(); }
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in filediag
+ if (filediag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::ofstream out(filediag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
return 0;
}
-
-
-void program_options( int argc, char * argv[]
- , std::string & filepoints
- , std::string & filediag
- , Filtration_value & threshold
- , int & dim_max
- , int & min_p
- , int & max_p
- , Filtration_value & min_persistence )
-{
+void program_options(int argc, char * argv[]
+ , std::string & filepoints
+ , std::string & filediag
+ , Filtration_value & threshold
+ , int & dim_max
+ , int & min_p
+ , int & max_p
+ , Filtration_value & min_persistence) {
namespace po = boost::program_options;
- po::options_description hidden("Hidden options");
+ po::options_description hidden("Hidden options");
hidden.add_options()
- ("input-file", po::value<std::string>(&filepoints),
- "Name of file containing a point set. Format is one point per line: X1 ... Xd \n");
-
+ ("input-file", po::value<std::string>(&filepoints),
+ "Name of file containing a point set. Format is one point per line: X1 ... Xd \n");
+
po::options_description visible("Allowed options");
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(0),
- "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.")
- ("min-field-charac,p", po::value<int>(&min_p)->default_value(2),
- "Minimal characteristic p of the coefficient field Z/pZ.")
- ("max-field-charac,q", po::value<int>(&max_p)->default_value(1223),
- "Minimial characteristic q of the coefficient field Z/pZ.")
- ("min-persistence,m", po::value<Filtration_value>(&min_persistence),
- "Minimal lifetime of homology feature to be recorded. Default is 0");
+ ("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(0),
+ "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.")
+ ("min-field-charac,p", po::value<int>(&min_p)->default_value(2),
+ "Minimal characteristic p of the coefficient field Z/pZ.")
+ ("max-field-charac,q", po::value<int>(&max_p)->default_value(1223),
+ "Minimial characteristic q of the coefficient field Z/pZ.")
+ ("min-persistence,m", po::value<Filtration_value>(&min_persistence),
+ "Minimal lifetime of homology feature to be recorded. Default is 0");
po::positional_options_description pos;
pos.add("input-file", 1);
-
- po::options_description all; all.add(visible).add(hidden);
+
+ po::options_description all;
+ all.add(visible).add(hidden);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), vm);
+ options(all).positional(pos).run(), vm);
po::notify(vm);
- if (vm.count("help") || !vm.count("input-file"))
- {
- std::cout << std::endl;
- std::cout << "Compute the persistent homology with various coefficient fields \n";
- std::cout << "of a Rips complex defined on a set of input points. The coefficient \n";
- std::cout << "fields are all the Z/rZ for a prime number r contained in the \n";
- std::cout << "specified range [p,q]\n \n";
- std::cout << "The output diagram contains one bar per line, written with the convention: \n";
- std::cout << " p1*...*pr dim b d \n";
- std::cout << "where dim is the dimension of the homological feature,\n";
- std::cout << "b and d are respectively the birth and death of the feature and \n";
- std::cout << "p1*...*pr is the product of prime numbers pi such that the homology \n";
- std::cout << "feature exists in homology with Z/piZ coefficients."<< std::endl << std::endl;
-
- std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
- std::cout << visible << std::endl;
- std::abort();
+ if (vm.count("help") || !vm.count("input-file")) {
+ std::cout << std::endl;
+ std::cout << "Compute the persistent homology with various coefficient fields \n";
+ std::cout << "of a Rips complex defined on a set of input points. The coefficient \n";
+ std::cout << "fields are all the Z/rZ for a prime number r contained in the \n";
+ std::cout << "specified range [p,q]\n \n";
+ std::cout << "The output diagram contains one bar per line, written with the convention: \n";
+ std::cout << " p1*...*pr dim b d \n";
+ std::cout << "where dim is the dimension of the homological feature,\n";
+ std::cout << "b and d are respectively the birth and death of the feature and \n";
+ std::cout << "p1*...*pr is the product of prime numbers pi such that the homology \n";
+ std::cout << "feature exists in homology with Z/piZ coefficients." << std::endl << std::endl;
+
+ std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
+ std::cout << visible << std::endl;
+ std::abort();
}
}
diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp
index 4253def9..9b1ef42f 100644
--- a/src/Persistent_cohomology/example/rips_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence.cpp
@@ -1,147 +1,151 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "gudhi/reader_utils.h"
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/distance_functions.h"
-#include "gudhi/Simplex_tree.h"
-#include "gudhi/Persistent_cohomology.h"
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
#include <boost/program_options.hpp>
+#include <string>
+#include <vector>
+
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
-typedef int Vertex_handle;
-typedef double Filtration_value;
-
-void program_options( int argc, char * argv[]
- , std::string & filepoints
- , std::string & filediag
- , Filtration_value & threshold
- , int & dim_max
- , int & p
- , Filtration_value & min_persistence );
-
-int main (int argc, char * argv[])
-{
- std::string filepoints;
- std::string filediag ;
- Filtration_value threshold ;
- int dim_max ;
- int p ;
+typedef int Vertex_handle;
+typedef double Filtration_value;
+
+void program_options(int argc, char * argv[]
+ , std::string & filepoints
+ , std::string & filediag
+ , Filtration_value & threshold
+ , int & dim_max
+ , int & p
+ , Filtration_value & min_persistence);
+
+int main(int argc, char * argv[]) {
+ std::string filepoints;
+ std::string filediag;
+ Filtration_value threshold;
+ int dim_max;
+ int p;
Filtration_value min_persistence;
- program_options(argc,argv,filepoints,filediag,threshold,dim_max,p,min_persistence);
+ program_options(argc, argv, filepoints, filediag, threshold, dim_max, p, min_persistence);
-// Extract the points from the file filepoints
+ // Extract the points from the file filepoints
typedef std::vector<double> Point_t;
std::vector< Point_t > points;
- read_points( filepoints, points );
+ read_points(filepoints, points);
-// Compute the proximity graph of the points
- Graph_t prox_graph = compute_proximity_graph( points, threshold
- , euclidean_distance<Point_t> );
+ // Compute the proximity graph of the points
+ Graph_t prox_graph = compute_proximity_graph(points, threshold
+ , euclidean_distance<Point_t>);
-// Construct the Rips complex in a Simplex Tree
- Simplex_tree<> st;
- st.insert_graph(prox_graph); // insert the proximity graph in the simplex tree
- st.expansion( dim_max ); // expand the graph until dimension dim_max
+ // Construct the Rips complex in a Simplex Tree
+ Simplex_tree<> st;
+ // insert the proximity graph in the simplex tree
+ st.insert_graph(prox_graph);
+ // expand the graph until dimension dim_max
+ st.expansion(dim_max);
std::cout << "The complex contains " << st.num_simplices() << " simplices \n";
std::cout << " and has dimension " << st.dimension() << " \n";
-// Sort the simplices in the order of the filtration
+ // Sort the simplices in the order of the filtration
st.initialize_filtration();
-// Compute the persistence diagram of the complex
+ // Compute the persistence diagram of the complex
persistent_cohomology::Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(st);
- pcoh.init_coefficients( p ); //initilizes the coefficient field for homology
-
- pcoh.compute_persistent_cohomology( min_persistence );
-
-// Output the diagram in filediag
- if(filediag.empty()) { pcoh.output_diagram(); }
- else {
- std::ofstream out(filediag);
- pcoh.output_diagram(out);
- out.close(); }
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(p);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in filediag
+ if (filediag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::ofstream out(filediag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
return 0;
}
-
-
-void program_options( int argc, char * argv[]
- , std::string & filepoints
- , std::string & filediag
- , Filtration_value & threshold
- , int & dim_max
- , int & p
- , Filtration_value & min_persistence )
-{
+void program_options(int argc, char * argv[]
+ , std::string & filepoints
+ , 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");
+ po::options_description hidden("Hidden options");
hidden.add_options()
- ("input-file", po::value<std::string>(&filepoints),
- "Name of file containing a point set. Format is one point per line: X1 ... Xd ");
-
+ ("input-file", po::value<std::string>(&filepoints),
+ "Name of file containing a point set. Format is one point per line: X1 ... Xd ");
+
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(0),
- "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");
+ ("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(0),
+ "Maximal length of an edge for the Rips complex construction.")
+ ("cpx-dimension,d", po::value<int>(&dim_max)->default_value(1),
+ "Maximal dimension of the Rips complex we want to compute.")
+ ("field-charac,p", po::value<int>(&p)->default_value(11),
+ "Characteristic p of the coefficient field Z/pZ for computing homology.")
+ ("min-persistence,m", po::value<Filtration_value>(&min_persistence),
+ "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals");
po::positional_options_description pos;
pos.add("input-file", 1);
-
- po::options_description all; all.add(visible).add(hidden);
+
+ po::options_description all;
+ all.add(visible).add(hidden);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).
- options(all).positional(pos).run(), vm);
+ options(all).positional(pos).run(), vm);
po::notify(vm);
- if (vm.count("help") || !vm.count("input-file"))
- {
- std::cout << std::endl;
- std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
- std::cout << "of a Rips complex defined on a set of input points.\n \n";
- std::cout << "The output diagram contains one bar per line, written with the convention: \n";
- std::cout << " p dim b d \n";
- std::cout << "where dim is the dimension of the homological feature,\n";
- std::cout << "b and d are respectively the birth and death of the feature and \n";
- std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl;
-
- std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
- std::cout << visible << std::endl;
- std::abort();
+ if (vm.count("help") || !vm.count("input-file")) {
+ std::cout << std::endl;
+ std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
+ std::cout << "of a Rips complex defined on a set of input points.\n \n";
+ std::cout << "The output diagram contains one bar per line, written with the convention: \n";
+ std::cout << " p dim b d \n";
+ std::cout << "where dim is the dimension of the homological feature,\n";
+ std::cout << "b and d are respectively the birth and death of the feature and \n";
+ std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl;
+
+ std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
+ std::cout << visible << std::endl;
+ std::abort();
}
}
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
index b0d68f09..2a405830 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
@@ -20,23 +20,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_H_
-#define SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_H_
+#ifndef PERSISTENT_COHOMOLOGY_H_
+#define PERSISTENT_COHOMOLOGY_H_
#include <gudhi/Persistent_cohomology/Persistent_cohomology_column.h>
#include <gudhi/Persistent_cohomology/Field_Zp.h>
+#include <gudhi/Simple_object_pool.h>
#include <boost/tuple/tuple.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/pending/disjoint_sets.hpp>
#include <boost/intrusive/list.hpp>
-#include <boost/pool/object_pool.hpp>
#include <map>
#include <utility>
#include <list>
#include <vector>
#include <set>
+#include <fstream> // std::ofstream
+#include <limits> // for numeric_limits<>
+#include <tuple>
+#include <algorithm>
+#include <string>
namespace Gudhi {
@@ -229,9 +234,10 @@ class Persistent_cohomology {
: cpx_(&cpx),
dim_max_(cpx.dimension()), // upper bound on the dimension of the simplices
coeff_field_(), // initialize the field coefficient structure.
- ds_rank_(cpx_->num_simplices()), // union-find
- ds_parent_(cpx_->num_simplices()), // union-find
- ds_repr_(cpx_->num_simplices(), NULL), // union-find -> annotation vectors
+ num_simplices_(cpx_->num_simplices()), // num_simplices save to avoid to call thrice the function
+ ds_rank_(num_simplices_), // union-find
+ ds_parent_(num_simplices_), // union-find
+ ds_repr_(num_simplices_, NULL), // union-find -> annotation vectors
dsets_(&ds_rank_[0], &ds_parent_[0]), // union-find
cam_(), // collection of annotation vectors
zero_cocycles_(), // union-find -> Simplex_key of creator for 0-homology
@@ -241,7 +247,7 @@ class Persistent_cohomology {
column_pool_(), // memory pools for the CAM
cell_pool_() {
Simplex_key idx_fil = 0;
- for (auto & sh : cpx_->filtration_simplex_range()) {
+ for (auto sh : cpx_->filtration_simplex_range()) {
cpx_->assign_key(sh, idx_fil);
++idx_fil;
dsets_.make_set(cpx_->key(sh));
@@ -264,13 +270,10 @@ class Persistent_cohomology {
}
~Persistent_cohomology() {
-// Clean the remaining columns in the matrix.
- for (auto & cam_ref : cam_) {
- cam_ref.col_.clear();
- }
-// Clean the transversal lists
+ // Clean the transversal lists
for (auto & transverse_ref : transverse_idx_) {
- transverse_ref.second.row_->clear();
+ // Destruct all the cells
+ transverse_ref.second.row_->clear_and_dispose([&](Cell*p){p->~Cell();});
delete transverse_ref.second.row_;
}
}
@@ -335,18 +338,18 @@ class Persistent_cohomology {
if (ds_parent_[key] == key // root of its tree
&& zero_cocycles_.find(key) == zero_cocycles_.end()) {
- persistent_pairs_.push_back(
- Persistent_interval(cpx_->simplex(key), cpx_->null_simplex(), coeff_field_.characteristic()));
+ persistent_pairs_.emplace_back(
+ cpx_->simplex(key), cpx_->null_simplex(), coeff_field_.characteristic());
}
}
for (auto zero_idx : zero_cocycles_) {
- persistent_pairs_.push_back(
- Persistent_interval(cpx_->simplex(zero_idx.second), cpx_->null_simplex(), coeff_field_.characteristic()));
+ persistent_pairs_.emplace_back(
+ cpx_->simplex(zero_idx.second), cpx_->null_simplex(), coeff_field_.characteristic());
}
// Compute infinite interval of dimension > 0
for (auto cocycle : transverse_idx_) {
- persistent_pairs_.push_back(
- Persistent_interval(cpx_->simplex(cocycle.first), cpx_->null_simplex(), cocycle.second.characteristics_));
+ persistent_pairs_.emplace_back(
+ cpx_->simplex(cocycle.first), cpx_->null_simplex(), cocycle.second.characteristics_);
}
}
@@ -386,8 +389,8 @@ class Persistent_cohomology {
if (cpx_->filtration(cpx_->simplex(idx_coc_u))
< cpx_->filtration(cpx_->simplex(idx_coc_v))) { // Kill cocycle [idx_coc_v], which is younger.
if (interval_length_policy(cpx_->simplex(idx_coc_v), sigma)) {
- persistent_pairs_.push_back(
- Persistent_interval(cpx_->simplex(idx_coc_v), sigma, coeff_field_.characteristic()));
+ persistent_pairs_.emplace_back(
+ cpx_->simplex(idx_coc_v), sigma, coeff_field_.characteristic());
}
// Maintain the index of the 0-cocycle alive.
if (kv != idx_coc_v) {
@@ -401,8 +404,8 @@ class Persistent_cohomology {
}
} else { // Kill cocycle [idx_coc_u], which is younger.
if (interval_length_policy(cpx_->simplex(idx_coc_u), sigma)) {
- persistent_pairs_.push_back(
- Persistent_interval(cpx_->simplex(idx_coc_u), sigma, coeff_field_.characteristic()));
+ persistent_pairs_.emplace_back(
+ cpx_->simplex(idx_coc_u), sigma, coeff_field_.characteristic());
}
// Maintain the index of the 0-cocycle alive.
if (ku != idx_coc_u) {
@@ -428,9 +431,12 @@ class Persistent_cohomology {
std::map<Simplex_key, Arith_element> & map_a_ds, Simplex_handle sigma,
int dim_sigma) {
// traverses the boundary of sigma, keeps track of the annotation vectors,
- // with multiplicity, in a map.
- std::map<Column *, int> annotations_in_boundary;
- std::pair<typename std::map<Column *, int>::iterator, bool> result_insert_bound;
+ // with multiplicity. We used to sum the coefficients directly in
+ // annotations_in_boundary by using a map, we now do it later.
+ typedef std::pair<Column *, int> annotation_t;
+ // Danger: not thread-safe!
+ static std::vector<annotation_t> annotations_in_boundary;
+ annotations_in_boundary.clear();
int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the
// alternate sum in the boundary.
Simplex_key key;
@@ -442,22 +448,29 @@ class Persistent_cohomology {
// Find its annotation vector
curr_col = ds_repr_[dsets_.find_set(key)];
if (curr_col != NULL) { // and insert it in annotations_in_boundary with multyiplicative factor "sign".
- result_insert_bound = annotations_in_boundary.insert(std::pair<Column *, int>(curr_col, sign));
- if (!(result_insert_bound.second)) {
- result_insert_bound.first->second += sign;
- }
+ annotations_in_boundary.emplace_back(curr_col, sign);
}
}
sign = -sign;
}
+ // Place identical annotations consecutively so we can easily sum their multiplicities.
+ std::sort(annotations_in_boundary.begin(), annotations_in_boundary.end(),
+ [](annotation_t const& a, annotation_t const& b) { return a.first < b.first; });
+
// Sum the annotations with multiplicity, using a map<key,coeff>
// to represent a sparse vector.
std::pair<typename std::map<Simplex_key, Arith_element>::iterator, bool> result_insert_a_ds;
- for (auto ann_ref : annotations_in_boundary) {
- if (ann_ref.second != coeff_field_.additive_identity()) { // For all columns in the boundary,
- for (auto cell_ref : ann_ref.first->col_) { // insert every cell in map_a_ds with multiplicity
- Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, ann_ref.second); // coefficient * multiplicity
+ for (auto ann_it = annotations_in_boundary.begin(); ann_it != annotations_in_boundary.end(); /**/) {
+ Column* col = ann_it->first;
+ int mult = ann_it->second;
+ while (++ann_it != annotations_in_boundary.end() && ann_it->first == col) {
+ mult += ann_it->second;
+ }
+ // The following test is just a heuristic, it is not required, and it is fine that is misses p == 0.
+ if (mult != coeff_field_.additive_identity()) { // For all columns in the boundary,
+ for (auto cell_ref : col->col_) { // insert every cell in map_a_ds with multiplicity
+ Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, mult); // coefficient * multiplicity
if (w_y != coeff_field_.additive_identity()) { // if != 0
result_insert_a_ds = map_a_ds.insert(std::pair<Simplex_key, Arith_element>(cell_ref.key_, w_y));
@@ -525,8 +538,8 @@ class Persistent_cohomology {
Arith_element charac) {
Simplex_key key = cpx_->key(sigma);
// Create a column containing only one cell,
- Column * new_col = column_pool_.construct(Column(key));
- Cell * new_cell = cell_pool_.construct(Cell(key, x, new_col));
+ Column * new_col = column_pool_.construct(key);
+ Cell * new_cell = cell_pool_.construct(key, x, new_col);
new_col->col_.push_back(*new_cell);
// and insert it in the matrix, in constant time thanks to the hint cam_.end().
// Indeed *new_col has the biggest lexicographic value because key is the
@@ -552,9 +565,9 @@ class Persistent_cohomology {
Arith_element charac) {
// Create a finite persistent interval for which the interval exists
if (interval_length_policy(cpx_->simplex(death_key), sigma)) {
- persistent_pairs_.push_back(Persistent_interval(cpx_->simplex(death_key) // creator
- , sigma // destructor
- , charac)); // fields
+ persistent_pairs_.emplace_back(cpx_->simplex(death_key) // creator
+ , sigma // destructor
+ , charac); // fields
}
auto death_key_row = transverse_idx_.find(death_key); // Find the beginning of the row.
@@ -570,9 +583,8 @@ class Persistent_cohomology {
Column * curr_col = row_cell_it->self_col_;
++row_cell_it;
// Disconnect the column from the rows in the CAM.
- for (auto col_cell_it = curr_col->col_.begin();
- col_cell_it != curr_col->col_.end(); ++col_cell_it) {
- col_cell_it->base_hook_cam_h::unlink();
+ for (auto& col_cell : curr_col->col_) {
+ col_cell.base_hook_cam_h::unlink();
}
// Remove the column from the CAM before modifying its value
@@ -587,9 +599,9 @@ class Persistent_cohomology {
// Find whether the column obtained is already in the CAM
result_insert_cam = cam_.insert(*curr_col);
if (result_insert_cam.second) { // If it was not in the CAM before: insertion has succeeded
- for (auto col_cell_it = curr_col->col_.begin(); col_cell_it != curr_col->col_.end(); ++col_cell_it) {
+ for (auto& col_cell : curr_col->col_) {
// re-establish the row links
- transverse_idx_[col_cell_it->key_].row_->push_front(*col_cell_it);
+ transverse_idx_[col_cell.key_].row_->push_front(col_cell);
}
} else { // There is already an identical column in the CAM:
// merge two disjoint sets.
@@ -599,6 +611,8 @@ class Persistent_cohomology {
Simplex_key key_tmp = dsets_.find_set(curr_col->class_key_);
ds_repr_[key_tmp] = &(*(result_insert_cam.first));
result_insert_cam.first->class_key_ = key_tmp;
+ // intrusive containers don't own their elements, we have to release them manually
+ curr_col->col_.clear_and_dispose([&](Cell*p){cell_pool_.destroy(p);});
column_pool_.destroy(curr_col); // delete curr_col;
}
}
@@ -694,7 +708,7 @@ class Persistent_cohomology {
void output_diagram(std::ostream& ostream = std::cout) {
cmp_intervals_by_length cmp(cpx_);
- persistent_pairs_.sort(cmp);
+ std::sort(std::begin(persistent_pairs_), std::end(persistent_pairs_), cmp);
bool has_infinity = std::numeric_limits<Filtration_value>::has_infinity;
for (auto pair : persistent_pairs_) {
// Special case on windows, inf is "1.#INF" (cf. unitary tests and R package TDA)
@@ -709,13 +723,11 @@ class Persistent_cohomology {
}
}
- void write_output_diagram(std::string diagram_name)
- {
- std::ofstream diagram_out(diagram_name.c_str());
- cmp_intervals_by_length cmp( cpx_ );
- persistent_pairs_.sort( cmp );
- for(auto pair : persistent_pairs_)
- {
+ void write_output_diagram(std::string diagram_name) {
+ std::ofstream diagram_out(diagram_name.c_str());
+ cmp_intervals_by_length cmp(cpx_);
+ std::sort(std::begin(persistent_pairs_), std::end(persistent_pairs_), cmp);
+ for (auto pair : persistent_pairs_) {
diagram_out << cpx_->dimension(get<0>(pair)) << " "
<< cpx_->filtration(get<0>(pair)) << " "
<< cpx_->filtration(get<1>(pair)) << std::endl;
@@ -742,6 +754,7 @@ class Persistent_cohomology {
Complex_ds * cpx_;
int dim_max_;
CoefficientField coeff_field_;
+ size_t num_simplices_;
/* Disjoint sets data structure to link the model of FilteredComplex
* with the compressed annotation matrix.
@@ -760,11 +773,11 @@ class Persistent_cohomology {
/* Key -> row. */
std::map<Simplex_key, cocycle> transverse_idx_;
/* Persistent intervals. */
- std::list<Persistent_interval> persistent_pairs_;
+ std::vector<Persistent_interval> persistent_pairs_;
length_interval interval_length_policy;
- boost::object_pool<Column> column_pool_;
- boost::object_pool<Cell> cell_pool_;
+ Simple_object_pool<Column> column_pool_;
+ Simple_object_pool<Cell> cell_pool_;
};
/** @} */ // end defgroup persistent_cohomology
@@ -773,4 +786,4 @@ class Persistent_cohomology {
} // namespace Gudhi
-#endif // SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_H_
+#endif // PERSISTENT_COHOMOLOGY_H_
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h
index 2a4c8692..6db16e69 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h
@@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_FIELD_ZP_H_
-#define SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_FIELD_ZP_H_
+#ifndef PERSISTENT_COHOMOLOGY_FIELD_ZP_H_
+#define PERSISTENT_COHOMOLOGY_FIELD_ZP_H_
#include <utility>
#include <vector>
@@ -41,9 +41,7 @@ class Field_Zp {
Field_Zp()
: Prime(0),
- inverse_(),
- mult_id_all(1),
- add_id_all(0) {
+ inverse_() {
}
void init(int charac) {
@@ -81,14 +79,14 @@ class Field_Zp {
}
/** \brief Returns the additive idendity \f$0_{\Bbbk}\f$ of the field.*/
- const Element& additive_identity() const {
- return add_id_all;
+ Element additive_identity() const {
+ return 0;
}
/** \brief Returns the multiplicative identity \f$1_{\Bbbk}\f$ of the field.*/
- const Element& multiplicative_identity(Element = 0) const {
- return mult_id_all;
+ Element multiplicative_identity(Element = 0) const {
+ return 1;
}
- /** Returns the inverse in the field. Modifies P.*/
+ /** Returns the inverse in the field. Modifies P. ??? */
std::pair<Element, Element> inverse(Element x, Element P) {
return std::pair<Element, Element>(inverse_[x], P);
} // <------ return the product of field characteristic for which x is invertible
@@ -101,7 +99,7 @@ class Field_Zp {
}
/** \brief Returns the characteristic \f$p\f$ of the field.*/
- const int& characteristic() const {
+ int characteristic() const {
return Prime;
}
@@ -109,12 +107,10 @@ class Field_Zp {
int Prime;
/** Property map Element -> Element, which associate to an element its inverse in the field.*/
std::vector<Element> inverse_;
- const Element mult_id_all;
- const Element add_id_all;
};
} // namespace persistent_cohomology
} // namespace Gudhi
-#endif // SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_FIELD_ZP_H_
+#endif // PERSISTENT_COHOMOLOGY_FIELD_ZP_H_
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h
index c6fd5282..38bc08d1 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h
@@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_MULTI_FIELD_H_
-#define SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_MULTI_FIELD_H_
+#ifndef PERSISTENT_COHOMOLOGY_MULTI_FIELD_H_
+#define PERSISTENT_COHOMOLOGY_MULTI_FIELD_H_
#include <gmpxx.h>
@@ -81,8 +81,7 @@ class Multi_field {
// set m to primorial(bound_prime)
prod_characteristics_ = 1;
for (auto p : primes_) {
- mpz_mul_ui(prod_characteristics_.get_mpz_t(),
- prod_characteristics_.get_mpz_t(), p);
+ prod_characteristics_ *= p;
}
// Uvect_
@@ -142,7 +141,7 @@ class Multi_field {
return prod_characteristics_;
}
- /** Returns the inverse in the field. Modifies P.*/
+ /** Returns the inverse in the field. Modifies P. ??? */
std::pair<Element, Element> inverse(Element x, Element QS) {
Element QR;
mpz_gcd(QR.get_mpz_t(), x.get_mpz_t(), QS.get_mpz_t()); // QR <- gcd(x,QS)
@@ -153,12 +152,12 @@ class Multi_field {
mpz_invert(inv_qt.get_mpz_t(), x.get_mpz_t(), QT.get_mpz_t());
assert(prod_characteristics_ > 0); // division by zero + non negative values
- return std::pair<Element, Element>(
- (inv_qt * multiplicative_identity(QT)) % prod_characteristics_, QT);
+ return { (inv_qt * multiplicative_identity(QT)) % prod_characteristics_, QT };
}
/** Returns -x * y.*/
Element times_minus(const Element& x, const Element& y) {
assert(prod_characteristics_ > 0); // division by zero + non negative values
+ /* This assumes that (x*y)%pc cannot be zero, but Field_Zp has specific code for the 0 case ??? */
return prod_characteristics_ - ((x * y) % prod_characteristics_);
}
@@ -183,4 +182,4 @@ class Multi_field {
} // namespace Gudhi
-#endif // SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_MULTI_FIELD_H_
+#endif // PERSISTENT_COHOMOLOGY_MULTI_FIELD_H_
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h
index fcec819a..612658e6 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h
@@ -20,14 +20,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_
-#define SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_
+#ifndef PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_
+#define PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_
-#include <list>
+#include <boost/tuple/tuple.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/list.hpp>
-#include "boost/tuple/tuple.hpp"
-#include "boost/intrusive/set.hpp"
-#include "boost/intrusive/list.hpp"
+#include <list>
namespace Gudhi {
@@ -80,40 +80,33 @@ class Persistent_cohomology_cell : public base_hook_cam_h,
* The non-zero coefficients of the column are stored in a
* boost::intrusive::list. Contains a hook to be stored in a
* boost::intrusive::set.
+ *
+ * Movable but not Copyable.
*/
template<typename SimplexKey, typename ArithmeticElement>
class Persistent_cohomology_column : public boost::intrusive::set_base_hook<
boost::intrusive::link_mode<boost::intrusive::normal_link> > {
- private:
template<class T1, class T2> friend class Persistent_cohomology;
+ public:
typedef Persistent_cohomology_cell<SimplexKey, ArithmeticElement> Cell;
typedef boost::intrusive::list<Cell,
boost::intrusive::constant_time_size<false>,
boost::intrusive::base_hook<base_hook_cam_v> > Col_type;
/** \brief Creates an empty column.*/
- explicit Persistent_cohomology_column(SimplexKey key) {
- class_key_ = key;
- col_ = Col_type();
- }
- public:
- /** Copy constructor.*/
- Persistent_cohomology_column(Persistent_cohomology_column const &other)
+ explicit Persistent_cohomology_column(SimplexKey key)
: col_(),
- class_key_(other.class_key_) {
- if (!other.col_.empty())
- std::cerr << "Copying a non-empty column.\n";
- }
+ class_key_(key) {}
/** \brief Returns true iff the column is null.*/
- bool is_null() {
+ bool is_null() const {
return col_.empty();
}
/** \brief Returns the key of the representative simplex of
* the set of simplices having this column as annotation vector
* in the compressed annotation matrix.*/
- SimplexKey class_key() {
+ SimplexKey class_key() const {
return class_key_;
}
@@ -145,4 +138,4 @@ class Persistent_cohomology_column : public boost::intrusive::set_base_hook<
} // namespace Gudhi
-#endif // SRC_PERSISTENT_COHOMOLOGY_INCLUDE_GUDHI_PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_
+#endif // PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_
diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp
index 55bc7066..194b3e74 100644
--- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp
+++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp
@@ -1,15 +1,14 @@
-#define BOOST_TEST_MODULE persistent_cohomology test
-#include <boost/test/included/unit_test.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/chrono/thread_clock.hpp>
#include <iostream>
#include <string>
-
+#include <algorithm>
#include <utility> // std::pair, std::make_pair
-
#include <cmath> // float comparison
#include <limits>
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "persistent_cohomology"
+#include <boost/test/unit_test.hpp>
+
#include "gudhi/graph_simplicial_complex.h"
#include "gudhi/reader_utils.h"
#include "gudhi/Simplex_tree.h"
diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
index 18a4725e..703682e1 100644
--- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
+++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp
@@ -1,15 +1,14 @@
-#define BOOST_TEST_MODULE persistent_cohomology_multi_field test
-#include <boost/test/included/unit_test.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/chrono/thread_clock.hpp>
#include <iostream>
#include <string>
-
+#include <algorithm>
#include <utility> // std::pair, std::make_pair
-
#include <cmath> // float comparison
#include <limits>
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "persistent_cohomology_multi_field"
+#include <boost/test/unit_test.hpp>
+
#include "gudhi/graph_simplicial_complex.h"
#include "gudhi/reader_utils.h"
#include "gudhi/Simplex_tree.h"
diff --git a/src/Simplex_tree/concept/IndexingTag.h b/src/Simplex_tree/concept/IndexingTag.h
index d690da11..1dcdd756 100644
--- a/src/Simplex_tree/concept/IndexingTag.h
+++ b/src/Simplex_tree/concept/IndexingTag.h
@@ -25,6 +25,6 @@
* continuous maps to a cell complex, and compute its persistent
* homology.
*
- * Must be linear_indexing_tag.
+ * Must be `Gudhi::linear_indexing_tag`.
*/
struct IndexingTag {};
diff --git a/src/Simplex_tree/concept/SimplexKey.h b/src/Simplex_tree/concept/SimplexKey.h
index ce5b2382..7fdbdd84 100644
--- a/src/Simplex_tree/concept/SimplexKey.h
+++ b/src/Simplex_tree/concept/SimplexKey.h
@@ -22,7 +22,7 @@
/** \brief Key type used as simplex identifier.
*
- * Must be <CODE>int</CODE>
+ * Must be a signed integer type.
*/
struct SimplexKey {};
- \ No newline at end of file
+
diff --git a/src/Simplex_tree/concept/SimplexTreeOptions.h b/src/Simplex_tree/concept/SimplexTreeOptions.h
new file mode 100644
index 00000000..add3ebdd
--- /dev/null
+++ b/src/Simplex_tree/concept/SimplexTreeOptions.h
@@ -0,0 +1,41 @@
+ /* 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): Marc Glisse
+ *
+ * Copyright (C) 2015 INRIA Saclay - Ile-de-France (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/>.
+ */
+
+/** \brief Concept of the template parameter for the class `Gudhi::Simplex_tree<SimplexTreeOptions>`.
+ *
+ * One model for this is `Gudhi::Simplex_tree_options_full_featured`. If you want to provide your own, it is recommended that you derive from it and override some parts instead of writing a class from scratch.
+ */
+struct SimplexTreeOptions {
+ /// Forced for now.
+ typedef IndexingTag Indexing_tag;
+ /// Must be a signed integer type. It admits a total order <.
+ typedef VertexHandle Vertex_handle;
+ /// Must be comparable with operator<.
+ typedef FiltrationValue Filtration_value;
+ /// Must be a signed integer type.
+ typedef SimplexKey Simplex_key;
+ /// If true, each simplex has extra storage for one `Simplex_key`. Necessary for `Persistent_cohomology`.
+ static const bool store_key;
+ /// If true, each simplex has extra storage for one `Filtration_value`, and this value is propagated by operations like `Gudhi::Simplex_tree::expansion`. Without it, `Persistent_cohomology` degenerates to computing usual (non-persistent) cohomology.
+ static const bool store_filtration;
+};
+
diff --git a/src/Simplex_tree/concept/VertexHandle.h b/src/Simplex_tree/concept/VertexHandle.h
index 491f0f56..3efbba61 100644
--- a/src/Simplex_tree/concept/VertexHandle.h
+++ b/src/Simplex_tree/concept/VertexHandle.h
@@ -22,5 +22,6 @@
/** \brief Handle type for the vertices of a cell complex.
*
- * Must be int.*/
+ * Must be a signed integer type. <code>operator&lt;</code> defines a total order on it.
+ */
struct VertexHandle {};
diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt
index 1a3cdfbf..c70cfe35 100644
--- a/src/Simplex_tree/example/CMakeLists.txt
+++ b/src/Simplex_tree/example/CMakeLists.txt
@@ -1,21 +1,24 @@
cmake_minimum_required(VERSION 2.6)
project(GUDHISimplexTreeFromFile)
-add_executable ( simplex_tree_from_file simplex_tree_from_file.cpp )
-add_test(simplex_tree_from_file_2 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_file ${CMAKE_SOURCE_DIR}/data/points/Klein_bottle_complex.txt 2)
-add_test(simplex_tree_from_file_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_file ${CMAKE_SOURCE_DIR}/data/points/Klein_bottle_complex.txt 3)
+add_executable ( simplex_tree_from_cliques_of_graph simplex_tree_from_cliques_of_graph.cpp )
+add_test(simplex_tree_from_cliques_of_graph_2 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_cliques_of_graph ${CMAKE_SOURCE_DIR}/data/points/Klein_bottle_complex.txt 2)
+add_test(simplex_tree_from_cliques_of_graph_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_cliques_of_graph ${CMAKE_SOURCE_DIR}/data/points/Klein_bottle_complex.txt 3)
add_executable ( simple_simplex_tree simple_simplex_tree.cpp )
add_test(simple_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/simple_simplex_tree)
-
+
+add_executable ( mini_simplex_tree mini_simplex_tree.cpp )
+add_test(mini_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/mini_simplex_tree)
+
# An example with Simplex-tree using CGAL alpha_shapes_3
if(GMP_FOUND AND CGAL_FOUND)
message("CGAL_lib = ${CGAL_LIBRARIES_DIR}")
- message("GMP_LIBRARIES = ${GMP_LIBRARIES}")
+ message("GMP_LIBRARIES = ${GMP_LIBRARIES}")
INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS})
add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp )
target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY})
add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000)
-endif()
+endif()
diff --git a/src/Simplex_tree/example/mini_simplex_tree.cpp b/src/Simplex_tree/example/mini_simplex_tree.cpp
new file mode 100644
index 00000000..7e48aaaf
--- /dev/null
+++ b/src/Simplex_tree/example/mini_simplex_tree.cpp
@@ -0,0 +1,69 @@
+/* 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): Marc Glisse
+ *
+ * Copyright (C) 2015 INRIA Saclay - Ile-de-France (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/Simplex_tree.h>
+#include <iostream>
+#include <initializer_list>
+
+using namespace Gudhi;
+
+struct MyOptions : Simplex_tree_options_full_featured {
+ // Not doing persistence, so we don't need those
+ static const bool store_key = false;
+ static const bool store_filtration = false;
+ // I have few vertices
+ typedef short Vertex_handle;
+};
+typedef Simplex_tree<MyOptions> ST;
+
+// Dictionary should be private, but for now this is the easiest way.
+static_assert(sizeof(ST::Dictionary::value_type) < sizeof(Simplex_tree<>::Dictionary::value_type),
+ "Not storing the filtration and key should save some space");
+
+int main() {
+ ST st;
+
+ /* Complex to build. */
+ /* 1 */
+ /* o */
+ /* /X\ */
+ /* o---o---o */
+ /* 2 0 3 */
+
+ auto triangle012 = {0, 1, 2};
+ auto edge03 = {0, 3};
+ st.insert_simplex_and_subfaces(triangle012);
+ st.insert_simplex_and_subfaces(edge03);
+ // FIXME: Remove this line
+ st.set_dimension(2);
+
+ auto edge02 = {0, 2};
+ ST::Simplex_handle e = st.find(edge02);
+ // We are not using filtrations so everything has value 0
+ assert(st.filtration(e) == 0);
+ for (ST::Simplex_handle t : st.cofaces_simplex_range(e, 1)) {
+ // Only coface is 012
+ for (ST::Vertex_handle v : st.simplex_vertex_range(t)) // v in { 0, 1, 2 }
+ std::cout << v;
+ std::cout << '\n';
+ }
+}
diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp
index 6d20e43e..5146b906 100644
--- a/src/Simplex_tree/example/simple_simplex_tree.cpp
+++ b/src/Simplex_tree/example/simple_simplex_tree.cpp
@@ -20,10 +20,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+
#include <iostream>
-#include <ctime>
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
+#include <utility> // for pair
+#include <vector>
using namespace Gudhi;
@@ -35,15 +37,11 @@ int main(int argc, char * const argv[]) {
const Filtration_value SECOND_FILTRATION_VALUE = 0.2;
const Filtration_value THIRD_FILTRATION_VALUE = 0.3;
const Filtration_value FOURTH_FILTRATION_VALUE = 0.4;
- Vertex_handle FIRST_VERTEX_HANDLE = (Vertex_handle) 0;
- Vertex_handle SECOND_VERTEX_HANDLE = (Vertex_handle) 1;
- Vertex_handle THIRD_VERTEX_HANDLE = (Vertex_handle) 2;
- Vertex_handle FOURTH_VERTEX_HANDLE = (Vertex_handle) 3;
// TEST OF INSERTION
std::cout << "********************************************************************" << std::endl;
std::cout << "EXAMPLE OF SIMPLE INSERTION" << std::endl;
- //Construct the Simplex Tree
+ // Construct the Simplex Tree
Simplex_tree<> simplexTree;
/* Simplex to be inserted: */
@@ -55,190 +53,149 @@ int main(int argc, char * const argv[]) {
// ++ FIRST
std::cout << " * INSERT 0" << std::endl;
- typeVectorVertex firstSimplexVector;
- firstSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ typeVectorVertex firstSimplexVector = { 0 };
typePairSimplexBool returnValue =
simplexTree.insert_simplex(firstSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 0 INSERTED" << std::endl;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - 0 NOT INSERTED" << std::endl;
}
// ++ SECOND
std::cout << " * INSERT 1" << std::endl;
- typeVectorVertex secondSimplexVector;
- secondSimplexVector.push_back(SECOND_VERTEX_HANDLE);
+ typeVectorVertex secondSimplexVector = { 1 };
returnValue =
simplexTree.insert_simplex(secondSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 1 INSERTED" << std::endl;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - 1 NOT INSERTED" << std::endl;
}
// ++ THIRD
std::cout << " * INSERT (0,1)" << std::endl;
- typeVectorVertex thirdSimplexVector;
- thirdSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- thirdSimplexVector.push_back(SECOND_VERTEX_HANDLE);
+ 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;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - (0,1) NOT INSERTED" << std::endl;
}
// ++ FOURTH
std::cout << " * INSERT 2" << std::endl;
- typeVectorVertex fourthSimplexVector;
- fourthSimplexVector.push_back(THIRD_VERTEX_HANDLE);
+ typeVectorVertex fourthSimplexVector = { 2 };
returnValue =
simplexTree.insert_simplex(fourthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 2 INSERTED" << std::endl;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - 2 NOT INSERTED" << std::endl;
}
// ++ FIFTH
std::cout << " * INSERT (2,0)" << std::endl;
- typeVectorVertex fifthSimplexVector;
- fifthSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- fifthSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ 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;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - (2,0) NOT INSERTED" << std::endl;
}
// ++ SIXTH
std::cout << " * INSERT (2,1)" << std::endl;
- typeVectorVertex sixthSimplexVector;
- sixthSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- sixthSimplexVector.push_back(SECOND_VERTEX_HANDLE);
+ 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;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - (2,1) NOT INSERTED" << std::endl;
}
// ++ SEVENTH
std::cout << " * INSERT (2,1,0)" << std::endl;
- typeVectorVertex seventhSimplexVector;
- seventhSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- seventhSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- seventhSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ 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;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - (2,1,0) NOT INSERTED" << std::endl;
}
// ++ EIGHTH
std::cout << " * INSERT 3" << std::endl;
- typeVectorVertex eighthSimplexVector;
- eighthSimplexVector.push_back(FOURTH_VERTEX_HANDLE);
+ typeVectorVertex eighthSimplexVector = { 3 };
returnValue =
simplexTree.insert_simplex(eighthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 3 INSERTED" << std::endl;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - 3 NOT INSERTED" << std::endl;
}
// ++ NINETH
std::cout << " * INSERT (3,0)" << std::endl;
- typeVectorVertex ninethSimplexVector;
- ninethSimplexVector.push_back(FOURTH_VERTEX_HANDLE);
- ninethSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ 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;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - (3,0) NOT INSERTED" << std::endl;
}
// ++ TENTH
std::cout << " * INSERT 0 (already inserted)" << std::endl;
- typeVectorVertex tenthSimplexVector;
- tenthSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- returnValue =
- simplexTree.insert_simplex(tenthSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE)); // With a different filtration value
+ typeVectorVertex tenthSimplexVector = { 0 };
+ // With a different filtration value
+ returnValue = simplexTree.insert_simplex(tenthSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
if (returnValue.second == true) {
std::cout << " + 0 INSERTED" << std::endl;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - 0 NOT INSERTED" << std::endl;
}
// ++ ELEVENTH
std::cout << " * INSERT (2,1,0) (already inserted)" << std::endl;
- typeVectorVertex eleventhSimplexVector;
- eleventhSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- eleventhSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- eleventhSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ 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;
- int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
} else {
std::cout << " - (2,1,0) NOT INSERTED" << std::endl;
}
// ++ GENERAL VARIABLE SET
- simplexTree.set_filtration(FOURTH_FILTRATION_VALUE); // Max filtration value
- simplexTree.set_dimension(2); // Max dimension = 2 -> (2,1,0)
+ simplexTree.set_filtration(FOURTH_FILTRATION_VALUE); // Max filtration value
+ simplexTree.set_dimension(2); // Max dimension = 2 -> (2,1,0)
- std::cout << "********************************************************************" << std::endl;
+ std::cout << "********************************************************************\n";
// Display the Simplex_tree - Can not be done in the middle of 2 inserts
- std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices" << std::endl;
- std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << std::endl;
- std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n";
+ std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\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 << (int) vertex << " ";
+ std::cout << static_cast<int>(vertex) << " ";
}
std::cout << std::endl;
}
@@ -262,9 +219,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- Vertex_handle UNKNOWN_VERTEX_HANDLE = (Vertex_handle) 15;
- typeVectorVertex unknownSimplexVector;
- unknownSimplexVector.push_back(UNKNOWN_VERTEX_HANDLE);
+ typeVectorVertex unknownSimplexVector = { 15 };
simplexFound = simplexTree.find(unknownSimplexVector);
std::cout << "**************IS THE SIMPLEX {15} IN THE SIMPLEX TREE ?\n";
if (simplexFound != simplexTree.null_simplex())
@@ -279,9 +234,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- typeVectorVertex otherSimplexVector;
- otherSimplexVector.push_back(UNKNOWN_VERTEX_HANDLE);
- otherSimplexVector.push_back(SECOND_VERTEX_HANDLE);
+ 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())
@@ -289,10 +242,7 @@ int main(int argc, char * const argv[]) {
else
std::cout << "***- NO IT ISN'T\n";
- typeVectorVertex invSimplexVector;
- invSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- invSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- invSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ 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())
diff --git a/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp b/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp
index 5f797e93..45efe3ed 100644
--- a/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp
+++ b/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp
@@ -1,24 +1,28 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Vincent Rouvreau
- *
- * Copyright (C) 2014 INRIA Saclay (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2014 INRIA Saclay (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <boost/variant.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
@@ -27,32 +31,34 @@
#include <fstream>
#include <cmath>
-
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Simplex_tree.h"
-#include <boost/variant.hpp>
+#include <string>
+#include <tuple> // for tuple<>
+#include <map>
+#include <utility> // for pair<>
+#include <list>
+#include <vector>
// Alpha_shape_3 templates type definitions
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
-typedef CGAL::Alpha_shape_vertex_base_3<Kernel> Vb;
-typedef CGAL::Alpha_shape_cell_base_3<Kernel> Fb;
-typedef CGAL::Triangulation_data_structure_3<Vb,Fb> Tds;
-typedef CGAL::Delaunay_triangulation_3<Kernel,Tds> Triangulation_3;
-typedef CGAL::Alpha_shape_3<Triangulation_3> Alpha_shape_3;
+typedef CGAL::Alpha_shape_vertex_base_3<Kernel> Vb;
+typedef CGAL::Alpha_shape_cell_base_3<Kernel> Fb;
+typedef CGAL::Triangulation_data_structure_3<Vb, Fb> Tds;
+typedef CGAL::Delaunay_triangulation_3<Kernel, Tds> Triangulation_3;
+typedef CGAL::Alpha_shape_3<Triangulation_3> Alpha_shape_3;
// From file type definition
-typedef Kernel::Point_3 Point;
+typedef Kernel::Point_3 Point;
// filtration with alpha values needed type definition
typedef Alpha_shape_3::FT Alpha_value_type;
-typedef CGAL::Object Object;
+typedef CGAL::Object Object;
typedef CGAL::Dispatch_output_iterator<
- CGAL::cpp11::tuple<Object, Alpha_value_type>,
- CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >, std::back_insert_iterator< std::vector<Alpha_value_type> >
- > > Dispatch;
-typedef Alpha_shape_3::Cell_handle Cell_handle;
-typedef Alpha_shape_3::Facet Facet;
-typedef Alpha_shape_3::Edge Edge;
+CGAL::cpp11::tuple<Object, Alpha_value_type>,
+CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
+ std::back_insert_iterator< std::vector<Alpha_value_type> > > > Dispatch;
+typedef Alpha_shape_3::Cell_handle Cell_handle;
+typedef Alpha_shape_3::Facet Facet;
+typedef Alpha_shape_3::Edge Edge;
typedef std::list<Alpha_shape_3::Vertex_handle> Vertex_list;
// gudhi type definition
@@ -61,225 +67,209 @@ typedef std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex > Alpha_shape
typedef std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex> Alpha_shape_simplex_tree_pair;
typedef std::vector< Simplex_tree_vertex > Simplex_tree_vector_vertex;
-//#define DEBUG_TRACES
-
-Vertex_list from (const Cell_handle& ch)
-{
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++)
- {
+Vertex_list from(const Cell_handle& ch) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
#ifdef DEBUG_TRACES
- std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(ch->vertex(i));
- }
- return the_list;
+ std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(ch->vertex(i));
+ }
+ return the_list;
}
-Vertex_list from (const Facet& fct)
-{
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++)
- {
- if (fct.second != i)
- {
+
+Vertex_list from(const Facet& fct) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+ if (fct.second != i) {
#ifdef DEBUG_TRACES
- std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(fct.first->vertex(i));
- }
- }
- return the_list;
+ std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(fct.first->vertex(i));
+ }
+ }
+ return the_list;
}
-Vertex_list from (const Edge& edg)
-{
- Vertex_list the_list;
- for (auto i = 0; i < 4; i++)
- {
- if ((edg.second == i) ||(edg.third == i))
- {
+
+Vertex_list from(const Edge& edg) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+ if ((edg.second == i) || (edg.third == i)) {
#ifdef DEBUG_TRACES
- std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(edg.first->vertex(i));
- }
- }
- return the_list;
+ std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(edg.first->vertex(i));
+ }
+ }
+ return the_list;
}
-Vertex_list from (const Alpha_shape_3::Vertex_handle& vh)
-{
- Vertex_list the_list;
+
+Vertex_list from(const Alpha_shape_3::Vertex_handle& vh) {
+ Vertex_list the_list;
#ifdef DEBUG_TRACES
- std::cout << "from vertex=" << vh->point() << std::endl;
-#endif // DEBUG_TRACES
- the_list.push_back(vh);
- return the_list;
+ std::cout << "from vertex=" << vh->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(vh);
+ return the_list;
}
+int main(int argc, char * const argv[]) {
+ // program args management
+ if (argc != 2) {
+ std::cerr << "Usage: " << argv[0]
+ << " path_to_file_graph \n";
+ return 0;
+ }
-int main (int argc, char * const argv[])
-{
- // program args management
- if (argc != 2) {
- std::cerr << "Usage: " << argv[0]
- << " path_to_file_graph \n";
- return 0; // ----- >>
- }
-
- // Read points from file
- std::string filegraph = argv[1];
- std::list<Point> lp;
- std::ifstream is(filegraph.c_str());
- int n;
- is >> n;
+ // Read points from file
+ std::string filegraph = argv[1];
+ std::list<Point> lp;
+ std::ifstream is(filegraph.c_str());
+ int n;
+ is >> n;
#ifdef DEBUG_TRACES
- std::cout << "Reading " << n << " points " << std::endl;
-#endif // DEBUG_TRACES
- Point p;
- for( ; n>0 ; n--) {
- is >> p;
- lp.push_back(p);
- }
+ std::cout << "Reading " << n << " points " << std::endl;
+#endif // DEBUG_TRACES
+ Point p;
+ for (; n > 0; n--) {
+ is >> p;
+ lp.push_back(p);
+ }
- // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
- Alpha_shape_3 as(lp.begin(),lp.end(),0,Alpha_shape_3::GENERAL);
+ // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
+ Alpha_shape_3 as(lp.begin(), lp.end(), 0, Alpha_shape_3::GENERAL);
#ifdef DEBUG_TRACES
- std::cout << "Alpha shape computed in GENERAL mode" << std::endl;
-#endif // DEBUG_TRACES
+ std::cout << "Alpha shape computed in GENERAL mode" << std::endl;
+#endif // DEBUG_TRACES
- // filtration with alpha values from alpha shape
- std::vector<Object> the_objects;
- std::vector<Alpha_value_type> the_alpha_values;
+ // filtration with alpha values from alpha shape
+ std::vector<Object> the_objects;
+ std::vector<Alpha_value_type> the_alpha_values;
- Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>( std::back_inserter(the_objects), std::back_inserter(the_alpha_values));
+ Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>(std::back_inserter(the_objects),
+ std::back_inserter(the_alpha_values));
- as.filtration_with_alpha_values(disp);
+ as.filtration_with_alpha_values(disp);
#ifdef DEBUG_TRACES
- std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl;
-#endif // DEBUG_TRACES
+ std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl;
+#endif // DEBUG_TRACES
- Alpha_shape_3::size_type count_vertices = 0;
- Alpha_shape_3::size_type count_edges = 0;
- Alpha_shape_3::size_type count_facets = 0;
- Alpha_shape_3::size_type count_cells = 0;
+ Alpha_shape_3::size_type count_vertices = 0;
+ Alpha_shape_3::size_type count_edges = 0;
+ Alpha_shape_3::size_type count_facets = 0;
+ Alpha_shape_3::size_type count_cells = 0;
- // Loop on objects vector
- Vertex_list vertex_list;
- Gudhi::Simplex_tree<> 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();
- 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);
- count_cells++;
- }
- else if (const Facet* facet = CGAL::object_cast<Facet>(&object_iterator))
- {
- vertex_list = from(*facet);
- count_facets++;
- }
- else if (const Edge* edge = CGAL::object_cast<Edge>(&object_iterator))
- {
- vertex_list = from(*edge);
- count_edges++;
- }
- else if (const Alpha_shape_3::Vertex_handle* vertex = CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator))
- {
- count_vertices++;
- vertex_list = from(*vertex);
- }
- // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
- Simplex_tree_vector_vertex the_simplex_tree;
- for (auto the_alpha_shape_vertex:vertex_list)
- {
- Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex);
- if (the_map_iterator == map_cgal_simplex_tree.end())
- {
- // alpha shape not found
- Simplex_tree_vertex vertex = map_cgal_simplex_tree.size();
+ // Loop on objects vector
+ Vertex_list vertex_list;
+ Gudhi::Simplex_tree<> 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();
+ 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);
+ count_cells++;
+ } else if (const Facet * facet = CGAL::object_cast<Facet>(&object_iterator)) {
+ vertex_list = from(*facet);
+ count_facets++;
+ } else if (const Edge * edge = CGAL::object_cast<Edge>(&object_iterator)) {
+ vertex_list = from(*edge);
+ count_edges++;
+ } else if (const Alpha_shape_3::Vertex_handle * vertex =
+ CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator)) {
+ count_vertices++;
+ vertex_list = from(*vertex);
+ }
+ // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
+ Simplex_tree_vector_vertex the_simplex_tree;
+ for (auto the_alpha_shape_vertex : vertex_list) {
+ Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex);
+ if (the_map_iterator == map_cgal_simplex_tree.end()) {
+ // alpha shape not found
+ Simplex_tree_vertex vertex = map_cgal_simplex_tree.size();
#ifdef DEBUG_TRACES
- std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert_simplex " << vertex << std::endl;
-#endif // DEBUG_TRACES
- the_simplex_tree.push_back(vertex);
- map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex,vertex));
- } else
- {
- // alpha shape found
- Simplex_tree_vertex vertex = the_map_iterator->second;
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert_simplex " << vertex << "\n";
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex));
+ } else {
+ // alpha shape found
+ Simplex_tree_vertex vertex = the_map_iterator->second;
#ifdef DEBUG_TRACES
- std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl;
-#endif // DEBUG_TRACES
- the_simplex_tree.push_back(vertex);
- }
- }
- // Construction of the simplex_tree
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ }
+ }
+ // Construction of the simplex_tree
#ifdef DEBUG_TRACES
- std::cout << "filtration = " << *the_alpha_value_iterator << std::endl;
-#endif // DEBUG_TRACES
- simplex_tree.insert_simplex(the_simplex_tree, std::sqrt(*the_alpha_value_iterator));
- if (the_alpha_value_iterator != the_alpha_values.end())
- ++the_alpha_value_iterator;
- else
- std::cout << "This shall not happen" << std::endl;
- }
+ std::cout << "filtration = " << *the_alpha_value_iterator << std::endl;
+#endif // DEBUG_TRACES
+ simplex_tree.insert_simplex(the_simplex_tree, std::sqrt(*the_alpha_value_iterator));
+ if (the_alpha_value_iterator != the_alpha_values.end())
+ ++the_alpha_value_iterator;
+ else
+ std::cerr << "This shall not happen" << std::endl;
+ }
#ifdef DEBUG_TRACES
- std::cout << "vertices \t\t" << count_vertices << std::endl;
- std::cout << "edges \t\t" << count_edges << std::endl;
- std::cout << "facets \t\t" << count_facets << std::endl;
- std::cout << "cells \t\t" << count_cells << std::endl;
+ std::cout << "vertices \t\t" << count_vertices << std::endl;
+ std::cout << "edges \t\t" << count_edges << std::endl;
+ std::cout << "facets \t\t" << count_facets << std::endl;
+ std::cout << "cells \t\t" << count_cells << std::endl;
- std::cout << "Information of the Simplex Tree: " << std::endl;
- std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " ";
- std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl;
-#endif // DEBUG_TRACES
+ std::cout << "Information of the Simplex Tree:\n";
+ std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " ";
+ std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl;
+#endif // DEBUG_TRACES
#ifdef DEBUG_TRACES
- std::cout << "Iterator on vertices: " << std::endl;
- for( auto vertex : simplex_tree.complex_vertex_range() )
- { std::cout << vertex << " "; }
-#endif // DEBUG_TRACES
+ std::cout << "Iterator on vertices: \n";
+ for (auto vertex : simplex_tree.complex_vertex_range()) {
+ std::cout << vertex << " ";
+ }
+#endif // DEBUG_TRACES
- std::cout << simplex_tree << std::endl;
+ std::cout << simplex_tree << std::endl;
#ifdef DEBUG_TRACES
- std::cout << std::endl << std::endl << "Iterator on simplices: " << std::endl;
- for( auto simplex : simplex_tree.complex_simplex_range() )
- {
- std::cout << " ";
- for( auto vertex : simplex_tree.simplex_vertex_range(simplex) ) { std::cout << vertex << " "; }
- std::cout << std::endl;
- }
-#endif // DEBUG_TRACES
+ std::cout << std::endl << std::endl << "Iterator on simplices:\n";
+ for (auto simplex : simplex_tree.complex_simplex_range()) {
+ std::cout << " ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+#endif // DEBUG_TRACES
#ifdef DEBUG_TRACES
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- for( auto f_simplex : simplex_tree.filtration_simplex_range() )
- { std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
- for( auto vertex : simplex_tree.simplex_vertex_range(f_simplex) )
- { std::cout << vertex << " "; }
- std::cout << std::endl;
- }
-#endif // DEBUG_TRACES
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:\n";
+ for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+#endif // DEBUG_TRACES
#ifdef DEBUG_TRACES
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, and their boundary simplices:" << std::endl;
- for( auto f_simplex : simplex_tree.filtration_simplex_range() )
- {
- std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
- for( auto vertex : simplex_tree.simplex_vertex_range(f_simplex) )
- { std::cout << vertex << " "; }
- std::cout << std::endl;
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, and their boundary simplices:\n";
+ for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
- for( auto b_simplex : simplex_tree.boundary_simplex_range(f_simplex) )
- {
- std::cout << " " << "[" << simplex_tree.filtration(b_simplex) << "] ";
- for( auto vertex : simplex_tree.simplex_vertex_range(b_simplex) )
- { std::cout << vertex << " "; }
- std::cout << std::endl;
- }
- }
-#endif // DEBUG_TRACES
+ for (auto b_simplex : simplex_tree.boundary_simplex_range(f_simplex)) {
+ std::cout << " " << "[" << simplex_tree.filtration(b_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(b_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+ }
+#endif // DEBUG_TRACES
- return 0;
+ return 0;
}
diff --git a/src/Simplex_tree/example/simplex_tree_from_cliques_of_graph.cpp b/src/Simplex_tree/example/simplex_tree_from_cliques_of_graph.cpp
new file mode 100644
index 00000000..58085014
--- /dev/null
+++ b/src/Simplex_tree/example/simplex_tree_from_cliques_of_graph.cpp
@@ -0,0 +1,114 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/Simplex_tree.h>
+
+#include <iostream>
+#include <ctime>
+#include <string>
+
+using namespace Gudhi;
+
+int main(int argc, char * const argv[]) {
+ if (argc != 3) {
+ std::cerr << "Usage: " << argv[0]
+ << " path_to_file_graph max_dim \n";
+ return 0;
+ }
+ std::string filegraph = argv[1];
+ int max_dim = atoi(argv[2]);
+
+ clock_t start, end;
+ // Construct the Simplex Tree
+ Simplex_tree<> st;
+
+ start = clock();
+ auto g = read_graph(filegraph);
+ // insert the graph in the simplex tree as 1-skeleton
+ st.insert_graph(g);
+ end = clock();
+ std::cout << "Insert the 1-skeleton in the simplex tree in "
+ << static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n";
+
+ start = clock();
+ // expand the 1-skeleton until dimension max_dim
+ st.expansion(max_dim);
+ end = clock();
+ std::cout << "max_dim = " << max_dim << "\n";
+ std::cout << "Expand the simplex tree in "
+ << static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n";
+
+ std::cout << "Information of the Simplex Tree: " << std::endl;
+ std::cout << " Number of vertices = " << st.num_vertices() << " ";
+ std::cout << " Number of simplices = " << st.num_simplices() << std::endl;
+ std::cout << std::endl << std::endl;
+
+ std::cout << "Iterator on vertices: ";
+ for (auto vertex : st.complex_vertex_range()) {
+ std::cout << vertex << " ";
+ }
+
+ std::cout << std::endl;
+
+ std::cout << std::endl << std::endl;
+
+ std::cout << "Iterator on simplices: " << std::endl;
+ for (auto simplex : st.complex_simplex_range()) {
+ std::cout << " ";
+ for (auto vertex : st.simplex_vertex_range(simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ std::cout << std::endl << std::endl;
+
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ std::cout << std::endl << std::endl;
+
+ std::cout << "Iterator on Simplices in the filtration, and their boundary simplices:" << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+
+ for (auto b_simplex : st.boundary_simplex_range(f_simplex)) {
+ std::cout << " " << "[" << st.filtration(b_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(b_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+ }
+ return 0;
+}
diff --git a/src/Simplex_tree/example/simplex_tree_from_file.cpp b/src/Simplex_tree/example/simplex_tree_from_file.cpp
deleted file mode 100644
index 20e8f067..00000000
--- a/src/Simplex_tree/example/simplex_tree_from_file.cpp
+++ /dev/null
@@ -1,104 +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): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <ctime>
-#include "gudhi/reader_utils.h"
-#include "gudhi/Simplex_tree.h"
-
-using namespace Gudhi;
-
-int main (int argc, char * const argv[])
-{
- if (argc != 3) {
- std::cerr << "Usage: " << argv[0]
- << " path_to_file_graph max_dim \n";
- return 0;
- }
- std::string filegraph = argv[1];
- int max_dim = atoi(argv[2]);
-
- clock_t start, end;
- //Construct the Simplex Tree
- Simplex_tree<> st;
-
- start = clock();
- auto g = read_graph(filegraph);
- st.insert_graph (g); //insert the graph in the simplex tree as 1-skeleton
- end = clock();
- std::cout << "Insert the 1-skeleton in the simplex tree in "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
-
- start = clock();
- st.expansion ( max_dim ); //expand the 1-skeleton until dimension max_dim
- end = clock();
- std::cout << "max_dim = " << max_dim << "\n";
- std::cout << "Expand the simplex tree in "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
-
- std::cout << "Information of the Simplex Tree: " << std::endl;
- std::cout << " Number of vertices = " << st.num_vertices() << " ";
- std::cout << " Number of simplices = " << st.num_simplices() << std::endl;
- std::cout << std::endl << std::endl;
-
- std::cout << "Iterator on vertices: ";
- for( auto vertex : st.complex_vertex_range() ) { std::cout << vertex << " "; }
-
- std::cout << std::endl;
-
- std::cout << std::endl << std::endl;
-
- std::cout << "Iterator on simplices: " << std::endl;
- for( auto simplex : st.complex_simplex_range() )
- {
- std::cout << " ";
- for( auto vertex : st.simplex_vertex_range(simplex) ) { std::cout << vertex << " "; }
- std::cout << std::endl;
- }
-
- std::cout << std::endl << std::endl;
-
- std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- for( auto f_simplex : st.filtration_simplex_range() )
- { std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- { std::cout << vertex << " "; } std::cout << std::endl;
- }
-
- std::cout << std::endl << std::endl;
-
- std::cout << "Iterator on Simplices in the filtration, and their boundary simplices:" << std::endl;
- for( auto f_simplex : st.filtration_simplex_range() )
- {
- std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- { std::cout << vertex << " "; } std::cout << std::endl;
-
- for( auto b_simplex : st.boundary_simplex_range(f_simplex) )
- {
- std::cout << " " << "[" << st.filtration(b_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(b_simplex) )
- { std::cout << vertex << " "; } std::cout << std::endl;
- }
- }
- return 0;
-}
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h
index 5d3753ca..ea61fa2e 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h
@@ -20,14 +20,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_H_
-#define SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_H_
+#ifndef SIMPLEX_TREE_H_
+#define SIMPLEX_TREE_H_
#include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h>
#include <gudhi/Simplex_tree/Simplex_tree_siblings.h>
#include <gudhi/Simplex_tree/Simplex_tree_iterators.h>
#include <gudhi/Simplex_tree/indexing_tag.h>
+#include <gudhi/reader_utils.h>
+#include <gudhi/graph_simplicial_complex.h>
+
#include <boost/container/flat_map.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
@@ -35,10 +38,11 @@
#include <algorithm>
#include <utility>
#include <vector>
-#include <iostream>
+#include <functional> // for greater<>
+#include <initializer_list>
namespace Gudhi {
-
+
/** \defgroup simplex_tree Filtered Complexes
*
* A simplicial complex \f$\mathbf{K}\f$
@@ -73,6 +77,17 @@ namespace Gudhi {
* \copyright GNU General Public License v3.
* @{
*/
+
+/// Model of SimplexTreeOptions.
+struct Simplex_tree_options_full_featured {
+ typedef linear_indexing_tag Indexing_tag;
+ typedef int Vertex_handle;
+ typedef double Filtration_value;
+ typedef int Simplex_key;
+ static const bool store_key = true;
+ static const bool store_filtration = true;
+};
+
/**
* \brief Simplex Tree data structure for representing simplicial complexes.
*
@@ -84,46 +99,69 @@ namespace Gudhi {
* \implements FilteredComplex
*
*/
-template<typename IndexingTag = linear_indexing_tag,
- typename FiltrationValue = double, typename SimplexKey = int // must be a signed integer type
- , typename VertexHandle = int // must be a signed integer type, int convertible to it
-// , bool ContiguousVertexHandles = true //true is Vertex_handles are exactly the set [0;n)
->
+
+template<typename SimplexTreeOptions = Simplex_tree_options_full_featured>
class Simplex_tree {
public:
- typedef IndexingTag Indexing_tag;
+ typedef SimplexTreeOptions Options;
+ typedef typename Options::Indexing_tag Indexing_tag;
/** \brief Type for the value of the filtration function.
*
* Must be comparable with <. */
- typedef FiltrationValue Filtration_value;
+ typedef typename Options::Filtration_value Filtration_value;
/** \brief Key associated to each simplex.
*
* Must be a signed integer type. */
- typedef SimplexKey Simplex_key;
+ typedef typename Options::Simplex_key Simplex_key;
/** \brief Type for the vertex handle.
*
* Must be a signed integer type. It admits a total order <. */
- typedef VertexHandle Vertex_handle;
+ typedef typename Options::Vertex_handle Vertex_handle;
/* Type of node in the simplex tree. */
typedef Simplex_tree_node_explicit_storage<Simplex_tree> Node;
/* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */
+ // Note: this wastes space when Vertex_handle is 32 bits and Node is aligned on 64 bits. It would be better to use a
+ // flat_set (with our own comparator) where we can control the layout of the struct (put Vertex_handle and
+ // Simplex_key next to each other).
typedef typename boost::container::flat_map<Vertex_handle, Node> Dictionary;
- friend class Simplex_tree_node_explicit_storage< Simplex_tree<FiltrationValue, SimplexKey, VertexHandle> >;
- friend class Simplex_tree_siblings< Simplex_tree<FiltrationValue, SimplexKey, VertexHandle>, Dictionary>;
- friend class Simplex_tree_simplex_vertex_iterator< Simplex_tree<FiltrationValue, SimplexKey, VertexHandle> >;
- friend class Simplex_tree_boundary_simplex_iterator< Simplex_tree<FiltrationValue, SimplexKey, VertexHandle> >;
- friend class Simplex_tree_complex_simplex_iterator< Simplex_tree<FiltrationValue, SimplexKey, VertexHandle> >;
- friend class Simplex_tree_skeleton_simplex_iterator< Simplex_tree<FiltrationValue, SimplexKey, VertexHandle> >;
-
/* \brief Set of nodes sharing a same parent in the simplex tree. */
/* \brief Set of nodes sharing a same parent in the simplex tree. */
typedef Simplex_tree_siblings<Simplex_tree, Dictionary> Siblings;
+ struct Key_simplex_base_real {
+ Key_simplex_base_real() : key_(-1) {}
+ void assign_key(Simplex_key k) { key_ = k; }
+ Simplex_key key() const { return key_; }
+ private:
+ Simplex_key key_;
+ };
+ struct Key_simplex_base_dummy {
+ Key_simplex_base_dummy() {}
+ void assign_key(Simplex_key) { }
+ Simplex_key key() const { assert(false); return -1; }
+ };
+ typedef typename std::conditional<Options::store_key, Key_simplex_base_real, Key_simplex_base_dummy>::type Key_simplex_base;
+
+ struct Filtration_simplex_base_real {
+ Filtration_simplex_base_real() : filt_(0) {}
+ void assign_filtration(Filtration_value f) { filt_ = f; }
+ Filtration_value filtration() const { return filt_; }
+ private:
+ Filtration_value filt_;
+ };
+ struct Filtration_simplex_base_dummy {
+ Filtration_simplex_base_dummy() {}
+ void assign_filtration(Filtration_value f) { assert(f == 0); }
+ Filtration_value filtration() const { return 0; }
+ };
+ typedef typename std::conditional<Options::store_filtration, Filtration_simplex_base_real,
+ Filtration_simplex_base_dummy>::type Filtration_simplex_base;
+
public:
/** \brief Handle type to a simplex contained in the simplicial complex represented
- * byt he simplex tree. */
+ * by the simplex tree. */
typedef typename Dictionary::iterator Simplex_handle;
private:
@@ -157,6 +195,8 @@ class Simplex_tree {
typedef Simplex_tree_simplex_vertex_iterator<Simplex_tree> Simplex_vertex_iterator;
/** \brief Range over the vertices of a simplex. */
typedef boost::iterator_range<Simplex_vertex_iterator> Simplex_vertex_range;
+ /** \brief Range over the cofaces of a simplex. */
+ typedef std::vector<Simplex_handle> Cofaces_simplex_range;
/** \brief Iterator over the simplices of the boundary of a simplex.
*
* 'value_type' is Simplex_handle. */
@@ -177,24 +217,23 @@ class Simplex_tree {
/** \brief Range over the simplices of the skeleton of the simplicial complex, for a given
* dimension. */
typedef boost::iterator_range<Skeleton_simplex_iterator> Skeleton_simplex_range;
+ /** \brief Range over the simplices of the simplicial complex, ordered by the filtration. */
+ typedef std::vector<Simplex_handle> Filtration_simplex_range;
/** \brief Iterator over the simplices of the simplicial complex, ordered by the filtration.
*
* 'value_type' is Simplex_handle. */
- typedef typename std::vector<Simplex_handle>::iterator Filtration_simplex_iterator;
- /** \brief Range over the simplices of the simplicial complex, ordered by the filtration. */
- typedef boost::iterator_range<Filtration_simplex_iterator> Filtration_simplex_range;
+ typedef typename Filtration_simplex_range::const_iterator Filtration_simplex_iterator;
/* @} */ // end name range and iterator types
/** \name Range and iterator methods
* @{ */
- /** \brief Returns a range over the vertices of the simplicial complex.
- *
+ /** \brief Returns a range over the vertices of the simplicial complex.
* The order is increasing according to < on Vertex_handles.*/
Complex_vertex_range complex_vertex_range() {
return Complex_vertex_range(
- boost::make_transform_iterator(root_.members_.begin(), return_first()),
- boost::make_transform_iterator(root_.members_.end(), return_first()));
+ boost::make_transform_iterator(root_.members_.begin(), return_first()),
+ boost::make_transform_iterator(root_.members_.end(), return_first()));
}
/** \brief Returns a range over the simplices of the simplicial complex.
@@ -234,18 +273,15 @@ class Simplex_tree {
* order is used.
*
* The filtration must be valid. If the filtration has not been initialized yet, the
- * method initializes it (i.e. order the simplices). */
- Filtration_simplex_range filtration_simplex_range(Indexing_tag) {
+ * method initializes it (i.e. order the simplices). If the complex has changed since the last time the filtration
+ * was initialized, please call `initialize_filtration()` to recompute it. */
+ Filtration_simplex_range const& filtration_simplex_range(Indexing_tag = Indexing_tag()) {
if (filtration_vect_.empty()) {
initialize_filtration();
}
- return Filtration_simplex_range(filtration_vect_.begin(),
- filtration_vect_.end());
+ return filtration_vect_;
}
- Filtration_simplex_range filtration_simplex_range() {
- return filtration_simplex_range(Indexing_tag());
- }
/** \brief Returns a range over the vertices of a simplex.
*
* The order in which the vertices are visited is the decreasing order for < on Vertex_handles,
@@ -253,6 +289,7 @@ class Simplex_tree {
* equal to \f$(-1)^{\text{dim} \sigma}\f$ the canonical orientation on the simplex.
*/
Simplex_vertex_range simplex_vertex_range(Simplex_handle sh) {
+ assert(sh != null_simplex()); // Empty simplex
return Simplex_vertex_range(Simplex_vertex_iterator(this, sh),
Simplex_vertex_iterator(this));
}
@@ -283,11 +320,48 @@ class Simplex_tree {
/** \brief Constructs an empty simplex tree. */
Simplex_tree()
: null_vertex_(-1),
- threshold_(0),
- num_simplices_(0),
- root_(NULL, null_vertex_),
- filtration_vect_(),
- dimension_(-1) {
+ threshold_(0),
+ root_(nullptr, null_vertex_),
+ filtration_vect_(),
+ dimension_(-1) { }
+
+ /** \brief User-defined copy constructor reproduces the whole tree structure. */
+ Simplex_tree(const Simplex_tree& simplex_source)
+ : null_vertex_(simplex_source.null_vertex_),
+ threshold_(simplex_source.threshold_),
+ filtration_vect_(),
+ dimension_(simplex_source.dimension_) {
+ auto root_source = simplex_source.root_;
+ auto memb_source = root_source.members();
+ root_ = Siblings(nullptr, null_vertex_, memb_source);
+ rec_copy(&root_, &root_source);
+ }
+
+ /** \brief depth first search, inserts simplices when reaching a leaf. */
+ void rec_copy(Siblings *sib, Siblings *sib_source) {
+ for (auto sh = sib->members().begin(), sh_source = sib_source->members().begin();
+ sh != sib->members().end(); ++sh, ++sh_source) {
+ if (has_children(sh_source)) {
+ Siblings * newsib = new Siblings(sib, sh_source->first);
+ newsib->members_.reserve(sh_source->second.children()->members().size());
+ for (auto & child : sh_source->second.children()->members())
+ newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(sib, child.second.filtration()));
+ rec_copy(newsib, sh_source->second.children());
+ sh->second.assign_children(newsib);
+ }
+ }
+ }
+
+ /** \brief User-defined move constructor moves the whole tree structure. */
+ Simplex_tree(Simplex_tree && old)
+ : null_vertex_(std::move(old.null_vertex_)),
+ threshold_(std::move(old.threshold_)),
+ root_(std::move(old.root_)),
+ filtration_vect_(std::move(old.filtration_vect_)),
+ dimension_(std::move(old.dimension_)) {
+ old.dimension_ = -1;
+ old.threshold_ = 0;
+ old.root_ = Siblings(nullptr, null_vertex_);
}
/** \brief Destructor; deallocates the whole tree structure. */
@@ -300,7 +374,7 @@ class Simplex_tree {
}
/** @} */ // end constructor/destructor
private:
- /** Recursive deletion. */
+ // Recursive deletion
void rec_delete(Siblings * sib) {
for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
if (has_children(sh)) {
@@ -311,72 +385,135 @@ class Simplex_tree {
}
public:
+ /** \brief Checks if two simplex trees are equal. */
+ bool operator==(Simplex_tree& st2) {
+ if ((null_vertex_ != st2.null_vertex_) ||
+ (threshold_ != st2.threshold_) ||
+ (dimension_ != st2.dimension_))
+ return false;
+ return rec_equal(&root_, &st2.root_);
+ }
+
+ /** \brief Checks if two simplex trees are different. */
+ bool operator!=(Simplex_tree& st2) {
+ return (!(*this == st2));
+ }
+
+ private:
+ /** rec_equal: Checks recursively whether or not two simplex trees are equal, using depth first search. */
+ bool rec_equal(Siblings* s1, Siblings* s2) {
+ if (s1->members().size() != s2->members().size())
+ return false;
+ for (auto sh1 = s1->members().begin(), sh2 = s2->members().begin();
+ (sh1 != s1->members().end() && sh2 != s2->members().end()); ++sh1, ++sh2) {
+ if (sh1->first != sh2->first || sh1->second.filtration() != sh2->second.filtration())
+ return false;
+ if (has_children(sh1) != has_children(sh2))
+ return false;
+ // Recursivity on children only if both have children
+ else if (has_children(sh1))
+ if (!rec_equal(sh1->second.children(), sh2->second.children()))
+ return false;
+ }
+ return true;
+ }
+
+ public:
/** \brief Returns the key associated to a simplex.
*
- * The filtration must be initialized. */
- Simplex_key key(Simplex_handle sh) {
+ * The filtration must be initialized.
+ * \pre SimplexTreeOptions::store_key
+ */
+ static Simplex_key key(Simplex_handle sh) {
return sh->second.key();
}
+
/** \brief Returns the simplex associated to a key.
*
- * The filtration must be initialized. */
- Simplex_handle simplex(Simplex_key key) {
+ * The filtration must be initialized.
+ * \pre SimplexTreeOptions::store_key
+ */
+ Simplex_handle simplex(Simplex_key key) const {
return filtration_vect_[key];
}
+
/** \brief Returns the filtration value of a simplex.
*
- * Called on the null_simplex, returns INFINITY. */
- Filtration_value filtration(Simplex_handle sh) const {
+ * Called on the null_simplex, returns INFINITY.
+ * If SimplexTreeOptions::store_filtration is false, returns 0.
+ */
+ static Filtration_value filtration(Simplex_handle sh) {
if (sh != null_simplex()) {
return sh->second.filtration();
} else {
return INFINITY;
- } // filtration(); }
+ }
}
+
/** \brief Returns an upper bound of the filtration values of the simplices. */
Filtration_value filtration() const {
return threshold_;
}
+
/** \brief Returns a Simplex_handle different from all Simplex_handles
* associated to the simplices in the simplicial complex.
*
* One can call filtration(null_simplex()). */
- Simplex_handle null_simplex() const {
- return Dictionary_it(NULL);
+ static Simplex_handle null_simplex() {
+ return Dictionary_it(nullptr);
}
+
/** \brief Returns a key different for all keys associated to the
* simplices of the simplicial complex. */
- Simplex_key null_key() const {
+ static Simplex_key null_key() {
return -1;
}
+
/** \brief Returns a Vertex_handle different from all Vertex_handles associated
* to the vertices of the simplicial complex. */
Vertex_handle null_vertex() const {
return null_vertex_;
}
+
/** \brief Returns the number of vertices in the complex. */
size_t num_vertices() const {
return root_.members_.size();
}
- /** \brief Returns the number of simplices in the complex.
- *
- * Does not count the empty simplex. */
- unsigned int num_simplices() const {
- return num_simplices_;
+
+ public:
+ /** \brief returns the number of simplices in the simplex_tree. */
+ size_t num_simplices() {
+ return num_simplices(&root_);
}
+ private:
+ /** \brief returns the number of simplices in the simplex_tree. */
+ size_t num_simplices(Siblings * sib) {
+ auto sib_begin = sib->members().begin();
+ auto sib_end = sib->members().end();
+ size_t simplices_number = sib_end - sib_begin;
+ for (auto sh = sib_begin; sh != sib_end; ++sh) {
+ if (has_children(sh)) {
+ simplices_number += num_simplices(sh->second.children());
+ }
+ }
+ return simplices_number;
+ }
+
+ public:
/** \brief Returns the dimension of a simplex.
*
* Must be different from null_simplex().*/
int dimension(Simplex_handle sh) {
Siblings * curr_sib = self_siblings(sh);
int dim = 0;
- while (curr_sib != NULL) {
+ while (curr_sib != nullptr) {
++dim;
curr_sib = curr_sib->oncles();
}
return dim - 1;
}
+
/** \brief Returns an upper bound on the dimension of the simplicial complex. */
int dimension() const {
return dimension_;
@@ -388,25 +525,34 @@ class Simplex_tree {
return (sh->second.children()->parent() == sh->first);
}
- /** \brief Given a range of Vertex_handles, returns the Simplex_handle
+ /** \brief Given a range of Vertex_handles, returns the Simplex_handle
* of the simplex in the simplicial complex containing the corresponding
* vertices. Return null_simplex() if the simplex is not in the complex.
*
- * The type RandomAccessVertexRange must be a range for which .begin() and
- * .end() return random access iterators, with <CODE>value_type</CODE>
- * <CODE>Vertex_handle</CODE>.
+ * The type InputVertexRange must be a range of <CODE>Vertex_handle</CODE>
+ * on which we can call std::begin() function
*/
- template<class RandomAccessVertexRange>
- Simplex_handle find(RandomAccessVertexRange & s) {
- if (s.begin() == s.end())
- std::cerr << "Empty simplex \n";
-
- sort(s.begin(), s.end());
+ template<class InputVertexRange=std::initializer_list<Vertex_handle>>
+ Simplex_handle find(const InputVertexRange & s) {
+ auto first = std::begin(s);
+ auto last = std::end(s);
+
+ if (first == last)
+ return null_simplex(); // ----->>
+
+ // Copy before sorting
+ std::vector<Vertex_handle> copy(first, last);
+ std::sort(std::begin(copy), std::end(copy));
+ return find_simplex(copy);
+ }
+ private:
+ /** Find function, with a sorted range of vertices. */
+ Simplex_handle find_simplex(const std::vector<Vertex_handle> & simplex) {
Siblings * tmp_sib = &root_;
Dictionary_it tmp_dit;
- Vertex_handle last = s[s.size() - 1];
- for (auto v : s) {
+ Vertex_handle last = simplex.back();
+ for (auto v : simplex) {
tmp_dit = tmp_sib->members_.find(v);
if (tmp_dit == tmp_sib->members_.end()) {
return null_simplex();
@@ -424,8 +570,39 @@ class Simplex_tree {
Simplex_handle find_vertex(Vertex_handle v) {
return root_.members_.begin() + v;
}
-//{ return root_.members_.find(v); }
+ //{ return root_.members_.find(v); }
+
+ private:
+ /** \brief Inserts a simplex represented by a vector of vertex.
+ \warning the vector must be sorted by increasing vertex handle order */
+ std::pair<Simplex_handle, bool> insert_vertex_vector(const std::vector<Vertex_handle>& simplex,
+ Filtration_value filtration) {
+ Siblings * curr_sib = &root_;
+ std::pair<Simplex_handle, bool> res_insert;
+ auto vi = simplex.begin();
+ for (; vi != simplex.end() - 1; ++vi) {
+ 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();
+ }
+ res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
+ if (!res_insert.second) {
+ // if already in the complex
+ if (res_insert.first->second.filtration() > filtration) {
+ // if filtration value modified
+ res_insert.first->second.assign_filtration(filtration);
+ return res_insert;
+ }
+ // if filtration value unchanged
+ return std::pair<Simplex_handle, bool>(null_simplex(), false);
+ }
+ // otherwise the insertion has succeeded
+ return res_insert;
+ }
+ public:
/** \brief Insert a simplex, represented by a range of Vertex_handles, in the simplicial complex.
*
* @param[in] simplex range of Vertex_handles, representing the vertices of the new simplex
@@ -435,7 +612,7 @@ class Simplex_tree {
* to the new simplex.
* If the insertion fails (the simplex is already there), the bool is set to false. If the insertion
* fails and the simplex already in the complex has a filtration value strictly bigger than 'filtration',
- * we assign this simplex with the new value 'filtration', and set the Simplex_handle filed of the
+ * we assign this simplex with the new value 'filtration', and set the Simplex_handle field of the
* output pair to the Simplex_handle of the simplex. Otherwise, we set the Simplex_handle part to
* null_simplex.
*
@@ -447,76 +624,107 @@ class Simplex_tree {
* The filtration value
* assigned to the new simplex must preserve the monotonicity of the filtration.
*
- * The type RandomAccessVertexRange must be a range for which .begin() and
- * .end() return random access iterators, with 'value_type' Vertex_handle. */
- template<class RandomAccessVertexRange>
- std::pair<Simplex_handle, bool> insert_simplex(RandomAccessVertexRange & simplex,
- Filtration_value filtration) {
- if (simplex.empty()) {
- return std::pair<Simplex_handle, bool>(null_simplex(), true);
- }
-
- sort(simplex.begin(), simplex.end()); // must be sorted in increasing order
-
- Siblings * curr_sib = &root_;
- std::pair<Simplex_handle, bool> res_insert;
- typename RandomAccessVertexRange::iterator vi;
- for (vi = simplex.begin(); vi != simplex.end() - 1; ++vi) {
- 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();
- }
- res_insert = curr_sib->members_.emplace(*vi, Node(curr_sib, filtration));
- if (!res_insert.second) { // if already in the complex
- if (res_insert.first->second.filtration() > filtration) { // if filtration value modified
- res_insert.first->second.assign_filtration(filtration);
- return res_insert;
- }
- return std::pair<Simplex_handle, bool>(null_simplex(), false); // if filtration value unchanged
- }
- // otherwise the insertion has succeeded
- return res_insert;
+ * The type InputVertexRange must be a range for which .begin() and
+ * .end() return input iterators, with 'value_type' Vertex_handle. */
+ template<class InputVertexRange=std::initializer_list<Vertex_handle>>
+ std::pair<Simplex_handle, bool> insert_simplex(const InputVertexRange & simplex,
+ Filtration_value filtration = 0) {
+ auto first = std::begin(simplex);
+ auto last = std::end(simplex);
+
+ if (first == last)
+ return std::pair<Simplex_handle, bool>(null_simplex(), true); // ----->>
+
+ // Copy before sorting
+ std::vector<Vertex_handle> copy(first, last);
+ std::sort(std::begin(copy), std::end(copy));
+ return insert_vertex_vector(copy, filtration);
}
-
- /** \brief Insert a N-simplex and all his subfaces, from a N-simplex represented by a range of
+ /** \brief Insert a N-simplex and all his subfaces, from a N-simplex represented by a range of
* Vertex_handles, in the simplicial complex.
*
* @param[in] Nsimplex range of Vertex_handles, representing the vertices of the new N-simplex
* @param[in] filtration the filtration value assigned to the new N-simplex.
- */
- template<class RandomAccessVertexRange>
- void insert_simplex_and_subfaces(RandomAccessVertexRange& Nsimplex,
- Filtration_value filtration = 0.0) {
- if (Nsimplex.size() > 1) {
- for (unsigned int NIndex = 0; NIndex < Nsimplex.size(); NIndex++) {
- // insert N (N-1)-Simplex
- RandomAccessVertexRange NsimplexMinusOne;
- for (unsigned int NListIter = 0; NListIter < Nsimplex.size() - 1; NListIter++) {
- // (N-1)-Simplex creation
- NsimplexMinusOne.push_back( Nsimplex[(NIndex + NListIter) % Nsimplex.size()]);
- }
- // (N-1)-Simplex recursive call
- insert_simplex_and_subfaces(NsimplexMinusOne, filtration);
+ * The return type is a pair. If the new simplex is inserted successfully (i.e. it was not in the
+ * simplicial complex yet) the bool is set to true and the Simplex_handle is the handle assigned
+ * to the new simplex.
+ * If the insertion fails (the simplex is already there), the bool is set to false. If the insertion
+ * fails and the simplex already in the complex has a filtration value strictly bigger than 'filtration',
+ * we assign this simplex with the new value 'filtration', and set the Simplex_handle field of the
+ * output pair to the Simplex_handle of the simplex. Otherwise, we set the Simplex_handle part to
+ * null_simplex.
+ */
+ template<class InputVertexRange=std::initializer_list<Vertex_handle>>
+ std::pair<Simplex_handle, bool> insert_simplex_and_subfaces(const InputVertexRange& Nsimplex,
+ 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); // ----->>
+
+ // Copy before sorting
+ std::vector<Vertex_handle> copy(first, last);
+ std::sort(std::begin(copy), std::end(copy));
+
+ 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);
+ }
+
+ 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);
}
- // N-Simplex insert
- std::pair<Simplex_handle, bool> returned = insert_simplex(Nsimplex, filtration);
- if (returned.second == true) {
- num_simplices_++;
+ 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 (Nsimplex.size() == 1) {
- // 1-Simplex insert - End of recursivity
- std::pair<Simplex_handle, bool> returned = insert_simplex(Nsimplex, filtration);
- if (returned.second == true) {
- num_simplices_++;
+ } 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" << std::endl;
+ exit(-1);
}
+ 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 {
- // Nothing to insert - empty vector
+ std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Recursivity error" << std::endl;
+ exit(-1);
}
+ return insert_result;
}
+ public:
/** \brief Assign a value 'key' to the key of the simplex
* represented by the Simplex_handle 'sh'. */
void assign_key(Simplex_handle sh, Simplex_key key) {
@@ -528,9 +736,8 @@ class Simplex_tree {
* and edge. sh must point to a 1-dimensional simplex. This is an
* optimized version of the boundary computation. */
std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
- return std::pair<Simplex_handle, Simplex_handle>(
- root_.members_.find(sh->first),
- root_.members_.find(self_siblings(sh)->parent()));
+ assert(dimension(sh) == 1);
+ return { find_vertex(sh->first), find_vertex(self_siblings(sh)->parent()) };
}
/** Returns the Siblings containing a simplex.*/
@@ -541,32 +748,17 @@ class Simplex_tree {
return sh->second.children();
}
-// void display_simplex(Simplex_handle sh)
-// {
-// std::cout << " " << "[" << filtration(sh) << "] ";
-// for( auto vertex : simplex_vertex_range(sh) )
-// { std::cout << vertex << " "; }
-// }
-
- // void print(Simplex_handle sh, std::ostream& os = std::cout)
- // { for(auto v : simplex_vertex_range(sh)) {os << v << " ";}
- // os << std::endl; }
-
public:
/** Returns a pointer to the root nodes of the simplex tree. */
Siblings * root() {
return &root_;
}
- public:
/** Set an upper bound for the filtration values. */
void set_filtration(Filtration_value fil) {
threshold_ = fil;
}
- /** Set a number of simplices for the simplicial complex. */
- void set_num_simplices(unsigned int num_simplices) {
- num_simplices_ = num_simplices;
- }
+
/** Set a dimension for the simplicial complex. */
void set_dimension(int dimension) {
dimension_ = dimension;
@@ -580,28 +772,114 @@ class Simplex_tree {
* assigned a Simplex_key corresponding to its order in the filtration (from 0 to m-1 for a
* simplicial complex with m simplices).
*
- * The use of a depth-first traversal of the simplex tree, provided by
- * complex_simplex_range(), combined with
- * a stable sort is meant to optimize the order of simplices with same
- * filtration value. The heuristic consists in inserting the cofaces of a
- * simplex as soon as possible.
- *
* Will be automatically called when calling filtration_simplex_range()
* if the filtration has never been initialized yet. */
void initialize_filtration() {
filtration_vect_.clear();
filtration_vect_.reserve(num_simplices());
- for (auto cpx_it = complex_simplex_range().begin();
- cpx_it != complex_simplex_range().end(); ++cpx_it) {
- filtration_vect_.push_back(*cpx_it);
- }
-
- // the stable sort ensures the ordering heuristic
+ for (Simplex_handle sh : complex_simplex_range())
+ filtration_vect_.push_back(sh);
+
+ /* We use stable_sort here because with libstdc++ it is faster than sort.
+ * is_before_in_filtration is now a total order, but we used to call
+ * stable_sort for the following heuristic:
+ * The use of a depth-first traversal of the simplex tree, provided by
+ * complex_simplex_range(), combined with a stable sort is meant to
+ * optimize the order of simplices with same filtration value. The
+ * heuristic consists in inserting the cofaces of a simplex as soon as
+ * possible.
+ */
std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(),
is_before_in_filtration(this));
}
private:
+ /** Recursive search of cofaces
+ * This function uses DFS
+ *\param vertices contains a list of vertices, which represent the vertices of the simplex not found yet.
+ *\param curr_nbVertices represents the number of vertices of the simplex we reached by going through the tree.
+ *\param cofaces contains a list of Simplex_handle, representing all the cofaces asked.
+ *\param star true if we need the star of the simplex
+ *\param nbVertices number of vertices of the cofaces we search
+ * Prefix actions : When the bottom vertex matches with the current vertex in the tree, we remove the bottom vertex from vertices.
+ * Infix actions : Then we call or not the recursion.
+ * Postfix actions : Finally, we add back the removed vertex into vertices, and remove this vertex from curr_nbVertices so that we didn't change the parameters.
+ * If the vertices list is empty, we need to check if curr_nbVertices matches with the dimension of the cofaces asked.
+ */
+ void rec_coface(std::vector<Vertex_handle> &vertices, Siblings *curr_sib, int curr_nbVertices,
+ std::vector<Simplex_handle>& cofaces, bool star, int nbVertices) {
+ if (!(star || curr_nbVertices <= nbVertices)) // dimension of actual simplex <= nbVertices
+ return;
+ for (Simplex_handle simplex = curr_sib->members().begin(); simplex != curr_sib->members().end(); ++simplex) {
+ if (vertices.empty()) {
+ // If we reached the end of the vertices, and the simplex has more vertices than the given simplex
+ // => we found a coface
+
+ // Add a coface if we wan't the star or if the number of vertices of the current simplex matches with nbVertices
+ bool addCoface = (star || curr_nbVertices == nbVertices);
+ if (addCoface)
+ cofaces.push_back(simplex);
+ if ((!addCoface || star) && has_children(simplex)) // Rec call
+ rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
+ } else {
+ if (simplex->first == vertices.back()) {
+ // If curr_sib matches with the top vertex
+ bool equalDim = (star || curr_nbVertices == nbVertices); // dimension of actual simplex == nbVertices
+ bool addCoface = vertices.size() == 1 && equalDim;
+ if (addCoface)
+ cofaces.push_back(simplex);
+ if ((!addCoface || star) && has_children(simplex)) {
+ // Rec call
+ Vertex_handle tmp = vertices.back();
+ vertices.pop_back();
+ rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
+ vertices.push_back(tmp);
+ }
+ } else if (simplex->first > vertices.back()) {
+ return;
+ } else {
+ // (simplex->first < vertices.back()
+ if (has_children(simplex))
+ rec_coface(vertices, simplex->second.children(), curr_nbVertices + 1, cofaces, star, nbVertices);
+ }
+ }
+ }
+ }
+
+ public:
+ /** \brief Compute the star of a n simplex
+ * \param simplex represent the simplex of which we search the star
+ * \return Vector of Simplex_handle, empty vector if no cofaces found.
+ */
+
+ Cofaces_simplex_range star_simplex_range(const Simplex_handle simplex) {
+ return cofaces_simplex_range(simplex, 0);
+ }
+
+ /** \brief Compute the cofaces of a n simplex
+ * \param simplex represent the n-simplex of which we search the n+codimension cofaces
+ * \param codimension The function returns the n+codimension-cofaces of the n-simplex. If codimension = 0,
+ * return all cofaces (equivalent of star function)
+ * \return Vector of Simplex_handle, empty vector if no cofaces found.
+ */
+
+ Cofaces_simplex_range cofaces_simplex_range(const Simplex_handle simplex, int codimension) {
+ Cofaces_simplex_range cofaces;
+ // codimension must be positive or null integer
+ assert(codimension >= 0);
+ Simplex_vertex_range rg = simplex_vertex_range(simplex);
+ std::vector<Vertex_handle> copy(rg.begin(), rg.end());
+ if (codimension + static_cast<int>(copy.size()) > dimension_ + 1 ||
+ (codimension == 0 && static_cast<int>(copy.size()) > dimension_)) // n+codimension greater than dimension_
+ return cofaces;
+ // must be sorted in decreasing order
+ assert(std::is_sorted(copy.begin(), copy.end(), std::greater<Vertex_handle>()));
+ bool star = codimension == 0;
+ rec_coface(copy, &root_, 1, cofaces, star, codimension + static_cast<int>(copy.size()));
+ return cofaces;
+ }
+
+ private:
/** \brief Returns true iff the list of vertices of sh1
* is smaller than the list of vertices of sh2 w.r.t.
* lexicographic order on the lists read in reverse.
@@ -624,6 +902,7 @@ class Simplex_tree {
}
return ((it1 == rg1.end()) && (it2 != rg2.end()));
}
+
/** \brief StrictWeakOrdering, for the simplices, defined by the filtration.
*
* It corresponds to the partial order
@@ -632,15 +911,15 @@ class Simplex_tree {
* to be smaller. The filtration function must be monotonic. */
struct is_before_in_filtration {
explicit is_before_in_filtration(Simplex_tree * st)
- : st_(st) {
- }
+ : st_(st) { }
bool operator()(const Simplex_handle sh1, const Simplex_handle sh2) const {
- if (st_->filtration(sh1) != st_->filtration(sh2)) {
- return st_->filtration(sh1) < st_->filtration(sh2);
+ // Not using st_->filtration(sh1) because it uselessly tests for null_simplex.
+ if (sh1->second.filtration() != sh2->second.filtration()) {
+ return sh1->second.filtration() < sh2->second.filtration();
}
-
- return st_->reverse_lexicographic_order(sh1, sh2); // is sh1 a proper subface of sh2
+ // is sh1 a proper subface of sh2
+ return st_->reverse_lexicographic_order(sh1, sh2);
}
Simplex_tree * st_;
@@ -667,7 +946,8 @@ class Simplex_tree {
* must be undirected_tag. */
template<class OneSkeletonGraph>
void insert_graph(const OneSkeletonGraph& skel_graph) {
- assert(num_simplices() == 0); // the simplex tree must be empty
+ // the simplex tree must be empty
+ assert(num_simplices() == 0);
if (boost::num_vertices(skel_graph) == 0) {
return;
@@ -678,37 +958,37 @@ class Simplex_tree {
dimension_ = 1;
}
- num_simplices_ = boost::num_vertices(skel_graph)
- + boost::num_edges(skel_graph);
root_.members_.reserve(boost::num_vertices(skel_graph));
typename boost::graph_traits<OneSkeletonGraph>::vertex_iterator v_it,
v_it_end;
for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end;
- ++v_it) {
+ ++v_it) {
root_.members_.emplace_hint(
- root_.members_.end(), *v_it,
- Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it)));
+ root_.members_.end(), *v_it,
+ Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it)));
}
typename boost::graph_traits<OneSkeletonGraph>::edge_iterator e_it,
e_it_end;
for (std::tie(e_it, e_it_end) = boost::edges(skel_graph); e_it != e_it_end;
- ++e_it) {
+ ++e_it) {
auto u = source(*e_it, skel_graph);
auto v = target(*e_it, skel_graph);
- if (u < v) { // count edges only once { std::swap(u,v); } // u < v
+ 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)));
+ v,
+ Node(sh->second.children(),
+ boost::get(edge_filtration_t(), skel_graph, *e_it)));
}
}
}
+
/** \brief Expands the Simplex_tree containing only its one skeleton
* until dimension max_dim.
*
@@ -723,7 +1003,7 @@ class Simplex_tree {
void expansion(int max_dim) {
dimension_ = max_dim;
for (Dictionary_it root_it = root_.members_.begin();
- root_it != root_.members_.end(); ++root_it) {
+ root_it != root_.members_.end(); ++root_it) {
if (has_children(root_it)) {
siblings_expansion(root_it->second.children(), max_dim - 1);
}
@@ -734,7 +1014,7 @@ class Simplex_tree {
private:
/** \brief Recursive expansion of the simplex tree.*/
void siblings_expansion(Siblings * siblings, // must contain elements
- int k) {
+ int k) {
if (dimension_ > k) {
dimension_ = k;
}
@@ -745,68 +1025,55 @@ class Simplex_tree {
static std::vector<std::pair<Vertex_handle, Node> > inter; // static, not thread-safe.
for (Dictionary_it s_h = siblings->members().begin();
- s_h != siblings->members().end(); ++s_h, ++next) {
+ s_h != siblings->members().end(); ++s_h, ++next) {
Simplex_handle root_sh = find_vertex(s_h->first);
if (has_children(root_sh)) {
intersection(
- inter, // output intersection
- next, // begin
- siblings->members().end(), // end
- root_sh->second.children()->members().begin(),
- root_sh->second.children()->members().end(),
- s_h->second.filtration());
+ inter, // output intersection
+ next, // begin
+ siblings->members().end(), // end
+ root_sh->second.children()->members().begin(),
+ root_sh->second.children()->members().end(),
+ s_h->second.filtration());
if (inter.size() != 0) {
- this->num_simplices_ += inter.size();
Siblings * new_sib = new Siblings(siblings, // oncles
- s_h->first, // parent
- inter); // boost::container::ordered_unique_range_t
+ s_h->first, // parent
+ inter); // boost::container::ordered_unique_range_t
inter.clear();
s_h->second.assign_children(new_sib);
siblings_expansion(new_sib, k - 1);
} else {
- s_h->second.assign_children(siblings); // ensure the children property
+ // ensure the children property
+ s_h->second.assign_children(siblings);
inter.clear();
}
}
}
}
+
/** \brief Intersects Dictionary 1 [begin1;end1) with Dictionary 2 [begin2,end2)
* and assigns the maximal possible Filtration_value to the Nodes. */
static void intersection(std::vector<std::pair<Vertex_handle, Node> >& intersection,
Dictionary_it begin1, Dictionary_it end1,
Dictionary_it begin2, Dictionary_it end2,
- Filtration_value filtration) {
+ Filtration_value filtration_) {
if (begin1 == end1 || begin2 == end2)
return; // ----->>
while (true) {
if (begin1->first == begin2->first) {
- intersection.push_back(
- std::pair<Vertex_handle, Node>(
- begin1->first,
- Node(NULL, maximum(begin1->second.filtration(), begin2->second.filtration(), filtration))));
- ++begin1;
- ++begin2;
- if (begin1 == end1 || begin2 == end2)
+ Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_});
+ intersection.emplace_back(begin1->first, Node(nullptr, filt));
+ if (++begin1 == end1 || ++begin2 == end2)
+ return; // ----->>
+ } else if (begin1->first < begin2->first) {
+ if (++begin1 == end1)
+ return;
+ } else /* begin1->first > begin2->first */ {
+ if (++begin2 == end2)
return; // ----->>
- } else {
- if (begin1->first < begin2->first) {
- ++begin1;
- if (begin1 == end1)
- return;
- } else {
- ++begin2;
- if (begin2 == end2)
- return; // ----->>
- }
}
}
}
- /** Maximum over 3 values.*/
- static Filtration_value maximum(Filtration_value a, Filtration_value b,
- Filtration_value c) {
- Filtration_value max = (a < b) ? b : a;
- return ((max < c) ? c : max);
- }
public:
/** \brief Write the hasse diagram of the simplicial complex in os.
@@ -817,7 +1084,7 @@ class Simplex_tree {
* of the simplex, and fil is its filtration value. */
void print_hasse(std::ostream& os) {
os << num_simplices() << " " << std::endl;
- for (auto sh : filtration_simplex_range(Indexing_tag())) {
+ for (auto sh : filtration_simplex_range()) {
os << dimension(sh) << " ";
for (auto b_sh : boundary_simplex_range(sh)) {
os << key(b_sh) << " ";
@@ -831,7 +1098,6 @@ class Simplex_tree {
/** \brief Upper bound on the filtration values of the simplices.*/
Filtration_value threshold_;
/** \brief Total number of simplices in the complex, without the empty simplex.*/
- unsigned int num_simplices_;
/** \brief Set of simplex tree Nodes representing the vertices.*/
Siblings root_;
/** \brief Simplices ordered according to a filtration.*/
@@ -841,8 +1107,9 @@ class Simplex_tree {
};
// Print a Simplex_tree in os.
-template<typename T1, typename T2, typename T3>
-std::ostream& operator<<(std::ostream & os, Simplex_tree<T1, T2, T3> & st) {
+
+template<typename...T>
+std::ostream& operator<<(std::ostream & os, Simplex_tree<T...> & st) {
for (auto sh : st.filtration_simplex_range()) {
os << st.dimension(sh) << " ";
for (auto v : st.simplex_vertex_range(sh)) {
@@ -852,35 +1119,35 @@ std::ostream& operator<<(std::ostream & os, Simplex_tree<T1, T2, T3> & st) {
}
return os;
}
-template<typename T1, typename T2, typename T3>
-std::istream& operator>>(std::istream & is, Simplex_tree<T1, T2, T3> & st) {
- // assert(st.num_simplices() == 0);
- std::vector<typename Simplex_tree<T1, T2, T3>::Vertex_handle> simplex;
- typename Simplex_tree<T1, T2, T3>::Filtration_value fil;
- typename Simplex_tree<T1, T2, T3>::Filtration_value max_fil = 0;
+template<typename...T>
+std::istream& operator>>(std::istream & is, Simplex_tree<T...> & st) {
+ typedef Simplex_tree<T...> ST;
+ std::vector<typename ST::Vertex_handle> simplex;
+ typename ST::Filtration_value fil;
+ typename ST::Filtration_value max_fil = 0;
int max_dim = -1;
- size_t num_simplices = 0;
- while (read_simplex(is, simplex, fil)) { // read all simplices in the file as a list of vertices
- ++num_simplices;
- int dim = static_cast<int>(simplex.size() - 1); // Warning : simplex_size needs to be casted in int - Can be 0
+ while (read_simplex(is, simplex, fil)) {
+ // read all simplices in the file as a list of vertices
+ // Warning : simplex_size needs to be casted in int - Can be 0
+ int dim = static_cast<int> (simplex.size() - 1);
if (max_dim < dim) {
max_dim = dim;
}
if (max_fil < fil) {
max_fil = fil;
}
- st.insert_simplex(simplex, fil); // insert every simplex in the simplex tree
+ // insert every simplex in the simplex tree
+ st.insert_simplex(simplex, fil);
simplex.clear();
}
- st.set_num_simplices(num_simplices);
st.set_dimension(max_dim);
st.set_filtration(max_fil);
return is;
}
-
/** @} */ // end defgroup simplex_tree
+
} // namespace Gudhi
-#endif // SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_H_
+#endif // SIMPLEX_TREE_H_
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 06462c88..372ef329 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
@@ -20,10 +20,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
-#define SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
+#ifndef SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
+#define SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
#include <boost/iterator/iterator_facade.hpp>
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 105600
+# include <boost/container/static_vector.hpp>
+#endif
#include <vector>
@@ -131,8 +135,7 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
}
Siblings * for_sib = sib_;
- for (typename std::vector<Vertex_handle>::reverse_iterator rit = suffix_
- .rbegin(); rit != suffix_.rend(); ++rit) {
+ for (auto rit = suffix_.rbegin(); rit != suffix_.rend(); ++rit) {
sh_ = for_sib->find(*rit);
for_sib = sh_->second.children();
}
@@ -142,9 +145,18 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
sib_ = sib_->oncles();
}
+ // Most of the storage should be moved to the range, iterators should be light.
Vertex_handle last_; // last vertex of the simplex
Vertex_handle next_; // next vertex to push in suffix_
+#if BOOST_VERSION >= 105600
+ // 40 seems a conservative bound on the dimension of a Simplex_tree for now,
+ // as it would not fit on the biggest hard-drive.
+ boost::container::static_vector<Vertex_handle, 40> suffix_;
+ // static_vector still has some overhead compared to a trivial hand-made
+ // version using std::aligned_storage, or compared to making suffix_ static.
+#else
std::vector<Vertex_handle> suffix_;
+#endif
Siblings * sib_; // where the next search will start from
Simplex_handle sh_; // current Simplex_handle in the boundary
SimplexTree * st_; // simplex containing the simplicial complex
@@ -303,4 +315,4 @@ class Simplex_tree_skeleton_simplex_iterator : public boost::iterator_facade<
/* @} */ // end addtogroup simplex_tree
} // namespace Gudhi
-#endif // SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
+#endif // SIMPLEX_TREE_SIMPLEX_TREE_ITERATORS_H_
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h
index 1f1a34cc..25d4888a 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h
@@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_NODE_EXPLICIT_STORAGE_H_
-#define SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_NODE_EXPLICIT_STORAGE_H_
+#ifndef SIMPLEX_TREE_SIMPLEX_TREE_NODE_EXPLICIT_STORAGE_H_
+#define SIMPLEX_TREE_SIMPLEX_TREE_NODE_EXPLICIT_STORAGE_H_
#include <vector>
@@ -39,65 +39,34 @@ namespace Gudhi {
* It stores explicitely its own filtration value and its own Simplex_key.
*/
template<class SimplexTree>
-class Simplex_tree_node_explicit_storage {
- public:
+struct Simplex_tree_node_explicit_storage : SimplexTree::Filtration_simplex_base, SimplexTree::Key_simplex_base {
typedef typename SimplexTree::Siblings Siblings;
typedef typename SimplexTree::Filtration_value Filtration_value;
typedef typename SimplexTree::Simplex_key Simplex_key;
- // Default constructor.
- Simplex_tree_node_explicit_storage()
- : children_(NULL),
- simplex_key_(-1),
- filtration_(0) {
- }
-
- Simplex_tree_node_explicit_storage(Siblings * sib,
- Filtration_value filtration)
- : children_(sib),
- simplex_key_(-1),
- filtration_(filtration) {
- }
-
- void assign_key(Simplex_key key) {
- simplex_key_ = key;
+ Simplex_tree_node_explicit_storage(Siblings * sib = nullptr,
+ Filtration_value filtration = 0)
+ : children_(sib) {
+ this->assign_filtration(filtration);
}
/*
- * Assign a children to the node
+ * Assign children to the node
*/
void assign_children(Siblings * children) {
children_ = children;
}
- /*
- *
- */
- void assign_filtration(double filtration_value) {
- filtration_ = filtration_value;
- }
-
- Filtration_value filtration() {
- return filtration_;
- }
/* Careful -> children_ can be NULL*/
Siblings * children() {
return children_;
}
- Simplex_key key() {
- return simplex_key_;
- }
-
private:
Siblings * children_;
-
- // Data attached to simplex, explicit storage
- Simplex_key simplex_key_;
- Filtration_value filtration_; // value in the filtration
};
/* @} */ // end addtogroup simplex_tree
} // namespace Gudhi
-#endif // SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_NODE_EXPLICIT_STORAGE_H_
+#endif // SIMPLEX_TREE_SIMPLEX_TREE_NODE_EXPLICIT_STORAGE_H_
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h
index 977fafa1..158ee1f7 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h
@@ -20,11 +20,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_SIBLINGS_H_
-#define SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_SIBLINGS_H_
+#ifndef SIMPLEX_TREE_SIMPLEX_TREE_SIBLINGS_H_
+#define SIMPLEX_TREE_SIMPLEX_TREE_SIBLINGS_H_
-#include "boost/container/flat_map.hpp"
-#include "Simplex_tree_node_explicit_storage.h"
+#include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h>
+
+#include <boost/container/flat_map.hpp>
#include <utility>
#include <vector>
@@ -71,14 +72,14 @@ class Simplex_tree_siblings {
/* \brief Constructor with initialized set of members.
*
* 'members' must be sorted and unique.*/
- Simplex_tree_siblings(Simplex_tree_siblings * oncles, Vertex_handle parent,
- const std::vector<std::pair<Vertex_handle, Node> > & members)
+ template<typename RandomAccessVertexRange>
+ Simplex_tree_siblings(Simplex_tree_siblings * oncles, Vertex_handle parent, const RandomAccessVertexRange & members)
: oncles_(oncles),
parent_(parent),
members_(boost::container::ordered_unique_range, members.begin(),
members.end()) {
- for (auto map_it = members_.begin(); map_it != members_.end(); map_it++) {
- map_it->second.assign_children(this);
+ for (auto& map_el : members_) {
+ map_el.second.assign_children(this);
}
}
@@ -90,19 +91,12 @@ class Simplex_tree_siblings {
* present in the node.
*/
void insert(Vertex_handle v, Filtration_value filtration_value) {
- typename Dictionary::iterator sh = members_.find(v);
- if (sh != members_.end() && sh->second.filtration() > filtration_value) {
- sh->second.assign_filtration(filtration_value);
- return;
- }
- if (sh == members_.end()) {
- members_.insert(
- std::pair<Vertex_handle, Node>(v, Node(this, filtration_value)));
- return;
- }
+ auto ins = members_.emplace(v, Node(this, filtration_value));
+ if (!ins.second && filtration(ins.first) > filtration_value)
+ ins.first->second.assign_filtration(filtration_value);
}
- typename Dictionary::iterator find(Vertex_handle v) {
+ Dictionary_it find(Vertex_handle v) {
return members_.find(v);
}
@@ -110,7 +104,7 @@ class Simplex_tree_siblings {
return oncles_;
}
- Vertex_handle parent() {
+ Vertex_handle parent() const {
return parent_;
}
@@ -118,7 +112,7 @@ class Simplex_tree_siblings {
return members_;
}
- size_t size() {
+ size_t size() const {
return members_.size();
}
@@ -130,4 +124,4 @@ class Simplex_tree_siblings {
/* @} */ // end addtogroup simplex_tree
} // namespace Gudhi
-#endif // SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_SIMPLEX_TREE_SIBLINGS_H_
+#endif // SIMPLEX_TREE_SIMPLEX_TREE_SIBLINGS_H_
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/indexing_tag.h b/src/Simplex_tree/include/gudhi/Simplex_tree/indexing_tag.h
index 69ffa44b..0adeb46d 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree/indexing_tag.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree/indexing_tag.h
@@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_INDEXING_TAG_H_
-#define SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_INDEXING_TAG_H_
+#ifndef SIMPLEX_TREE_INDEXING_TAG_H_
+#define SIMPLEX_TREE_INDEXING_TAG_H_
namespace Gudhi {
@@ -36,4 +36,4 @@ struct linear_indexing_tag {
// struct zigzag_indexing_tag {};
} // namespace Gudhi
-#endif // SRC_SIMPLEX_TREE_INCLUDE_GUDHI_SIMPLEX_TREE_INDEXING_TAG_H_
+#endif // SIMPLEX_TREE_INDEXING_TAG_H_
diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt
index b6a1c0b6..c9eae163 100644
--- a/src/Simplex_tree/test/CMakeLists.txt
+++ b/src/Simplex_tree/test/CMakeLists.txt
@@ -17,6 +17,9 @@ endif()
add_executable ( SimplexTreeUT simplex_tree_unit_test.cpp )
target_link_libraries(SimplexTreeUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+# Do not forget to copy test files in current binary dir
+file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
# Unitary tests
add_test(NAME SimplexTreeUT
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/SimplexTreeUT
diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
index 6b0a1f3d..fff00d77 100644
--- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp
+++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
@@ -1,17 +1,16 @@
-#define BOOST_TEST_MODULE simplex_tree test
-#include <boost/test/included/unit_test.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/chrono/thread_clock.hpp>
#include <iostream>
#include <string>
-
+#include <algorithm>
#include <utility> // std::pair, std::make_pair
-
#include <cmath> // float comparison
#include <limits>
-#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/reader_utils.h"
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "simplex_tree"
+#include <boost/test/unit_test.hpp>
+
+// ^
+// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined.
#include "gudhi/Simplex_tree.h"
using namespace Gudhi;
@@ -21,7 +20,7 @@ typedef std::pair<typeST::Simplex_handle, bool> typePairSimplexBool;
typedef std::vector<Vertex_handle> typeVectorVertex;
typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-const Vertex_handle DEFAULT_VERTEX_HANDLE = (const Vertex_handle) -1;
+const Vertex_handle DEFAULT_VERTEX_HANDLE = (const Vertex_handle) - 1;
const Filtration_value DEFAULT_FILTRATION_VALUE = (const Filtration_value) 0.0;
void test_empty_simplex_tree(typeST& tst) {
@@ -40,55 +39,52 @@ void test_iterators_on_empty_simplex_tree(typeST& tst) {
std::cout << "Iterator on vertices: " << std::endl;
for (auto vertex : tst.complex_vertex_range()) {
std::cout << "vertice:" << vertex << std::endl;
- BOOST_CHECK(false); // shall be empty
+ BOOST_CHECK(false); // shall be empty
}
std::cout << "Iterator on simplices: " << std::endl;
for (auto simplex : tst.complex_simplex_range()) {
- BOOST_CHECK(simplex != simplex); // shall be empty - to remove warning of non-used simplex
+ BOOST_CHECK(simplex != simplex); // shall be empty - to remove warning of non-used simplex
}
std::cout
<< "Iterator on Simplices in the filtration, with [filtration value]:"
<< std::endl;
for (auto f_simplex : tst.filtration_simplex_range()) {
- BOOST_CHECK(false); // shall be empty
+ BOOST_CHECK(false); // shall be empty
std::cout << "test_iterators_on_empty_simplex_tree - filtration="
<< tst.filtration(f_simplex) << std::endl;
}
}
-BOOST_AUTO_TEST_CASE( simplex_tree_when_empty )
-{
+BOOST_AUTO_TEST_CASE(simplex_tree_when_empty) {
const Filtration_value DEFAULT_FILTRATION_VALUE = 0;
- // TEST OF DEFAULT CONSTRUCTOR
std::cout << "********************************************************************" << std::endl;
std::cout << "TEST OF DEFAULT CONSTRUCTOR" << std::endl;
typeST st;
- test_empty_simplex_tree (st);
+ test_empty_simplex_tree(st);
- test_iterators_on_empty_simplex_tree (st);
+ test_iterators_on_empty_simplex_tree(st);
// TEST OF EMPTY INSERTION
std::cout << "TEST OF EMPTY INSERTION" << std::endl;
typeVectorVertex simplexVectorEmpty;
BOOST_CHECK(simplexVectorEmpty.empty() == true);
typePairSimplexBool returnEmptyValue = st.insert_simplex(simplexVectorEmpty,
- DEFAULT_FILTRATION_VALUE);
+ DEFAULT_FILTRATION_VALUE);
BOOST_CHECK(returnEmptyValue.first == typeST::Simplex_handle(NULL));
BOOST_CHECK(returnEmptyValue.second == true);
- test_empty_simplex_tree (st);
+ test_empty_simplex_tree(st);
- test_iterators_on_empty_simplex_tree (st);
+ test_iterators_on_empty_simplex_tree(st);
}
bool AreAlmostTheSame(float a, float b) {
return std::fabs(a - b) < std::numeric_limits<float>::epsilon();
}
-BOOST_AUTO_TEST_CASE( simplex_tree_from_file )
-{
+BOOST_AUTO_TEST_CASE(simplex_tree_from_file) {
// TEST OF INSERTION
std::cout << "********************************************************************" << std::endl;
std::cout << "TEST OF SIMPLEX TREE FROM A FILE" << std::endl;
@@ -108,16 +104,16 @@ BOOST_AUTO_TEST_CASE( simplex_tree_from_file )
BOOST_CHECK(st.filtration() == 0.4);
int previous_size = 0;
- for( auto f_simplex : st.filtration_simplex_range() )
- {
+ for (auto f_simplex : st.filtration_simplex_range()) {
// Size of simplex
int size = 0;
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- {
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ // Remove warning
+ (void) vertex;
size++;
}
- BOOST_CHECK(AreAlmostTheSame(st.filtration(f_simplex),(0.1* size))); // Specific test: filtration = 0.1 * simplex_size
- BOOST_CHECK(previous_size <= size);// Check list is sorted (because of sorted filtrations in simplex_tree.txt)
+ BOOST_CHECK(AreAlmostTheSame(st.filtration(f_simplex), (0.1 * size))); // Specific test: filtration = 0.1 * simplex_size
+ BOOST_CHECK(previous_size <= size); // Check list is sorted (because of sorted filtrations in simplex_tree.txt)
previous_size = size;
}
simplex_tree_stream.close();
@@ -127,13 +123,13 @@ void test_simplex_tree_contains(typeST& simplexTree, typeSimplex& simplex, int p
auto f_simplex = simplexTree.filtration_simplex_range().begin() + pos;
std::cout << "test_simplex_tree_contains - filtration=" << simplexTree.filtration(*f_simplex) << "||" << simplex.second << std::endl;
- BOOST_CHECK( AreAlmostTheSame(simplexTree.filtration(*f_simplex),simplex.second) );
+ BOOST_CHECK(AreAlmostTheSame(simplexTree.filtration(*f_simplex), simplex.second));
- int simplexIndex=simplex.first.size()-1;
- for( auto vertex : simplexTree.simplex_vertex_range(*f_simplex) )
- {
+ int simplexIndex = simplex.first.size() - 1;
+ std::sort(simplex.first.begin(), simplex.first.end()); // if the simplex wasn't sorted, the next test could fail
+ for (auto vertex : simplexTree.simplex_vertex_range(*f_simplex)) {
std::cout << "test_simplex_tree_contains - vertex=" << vertex << "||" << simplex.first.at(simplexIndex) << std::endl;
- BOOST_CHECK(vertex == simplex.first.at(simplexIndex));
+ BOOST_CHECK(vertex == simplex.first.at(simplexIndex));
BOOST_CHECK(simplexIndex >= 0);
simplexIndex--;
}
@@ -141,7 +137,7 @@ void test_simplex_tree_contains(typeST& simplexTree, typeSimplex& simplex, int p
void test_simplex_tree_insert_returns_true(const typePairSimplexBool& returnValue) {
BOOST_CHECK(returnValue.second == true);
- typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator
+ typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator
BOOST_CHECK(shReturned != typeST::Simplex_handle(NULL));
}
@@ -162,24 +158,26 @@ void set_and_test_simplex_tree_dim_fil(typeST& simplexTree, int vectorSize, cons
std::cout << " set_and_test_simplex_tree_dim_fil - max_fil=" << max_fil
<< std::endl;
}
- unsigned int nb_simplices = simplexTree.num_simplices() + 1;
- simplexTree.set_num_simplices(nb_simplices);
BOOST_CHECK(simplexTree.dimension() == dim_max);
BOOST_CHECK(AreAlmostTheSame(simplexTree.filtration(), max_fil));
- BOOST_CHECK(simplexTree.num_simplices() == nb_simplices);
+
+ // Another way to count simplices:
+ size_t num_simp = 0;
+ for (auto f_simplex : simplexTree.complex_simplex_range()) {
+ // Remove warning
+ (void) f_simplex;
+ num_simp++;
+ }
+
+ BOOST_CHECK(simplexTree.num_simplices() == num_simp);
}
-BOOST_AUTO_TEST_CASE( simplex_tree_insertion )
-{
+BOOST_AUTO_TEST_CASE(simplex_tree_insertion) {
const Filtration_value FIRST_FILTRATION_VALUE = 0.1;
const Filtration_value SECOND_FILTRATION_VALUE = 0.2;
const Filtration_value THIRD_FILTRATION_VALUE = 0.3;
const Filtration_value FOURTH_FILTRATION_VALUE = 0.4;
- Vertex_handle FIRST_VERTEX_HANDLE = (Vertex_handle) 0;
- Vertex_handle SECOND_VERTEX_HANDLE = (Vertex_handle) 1;
- Vertex_handle THIRD_VERTEX_HANDLE = (Vertex_handle) 2;
- Vertex_handle FOURTH_VERTEX_HANDLE = (Vertex_handle) 3;
// TEST OF INSERTION
std::cout << "********************************************************************" << std::endl;
@@ -188,171 +186,131 @@ BOOST_AUTO_TEST_CASE( simplex_tree_insertion )
// ++ FIRST
std::cout << " - INSERT 0" << std::endl;
- typeVectorVertex firstSimplexVector;
- firstSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( firstSimplexVector.size() == 1 );
- typeSimplex firstSimplex = std::make_pair(
- firstSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
- typePairSimplexBool returnValue = st.insert_simplex(firstSimplex.first,
- firstSimplex.second);
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex firstSimplexVector{0};
+ BOOST_CHECK(firstSimplexVector.size() == 1);
+ typeSimplex firstSimplex = std::make_pair(firstSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ typePairSimplexBool returnValue = st.insert_simplex(firstSimplex.first, firstSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, firstSimplexVector.size(), firstSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)1 );
+ BOOST_CHECK(st.num_vertices() == (size_t) 1);
// ++ SECOND
std::cout << " - INSERT 1" << std::endl;
- typeVectorVertex secondSimplexVector;
- secondSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- BOOST_CHECK( secondSimplexVector.size() == 1 );
- typeSimplex secondSimplex = std::make_pair(
- secondSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( secondSimplex.first, secondSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex secondSimplexVector{1};
+ BOOST_CHECK(secondSimplexVector.size() == 1);
+ typeSimplex secondSimplex = std::make_pair(secondSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(secondSimplex.first, secondSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, secondSimplexVector.size(), secondSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)2 );
+ BOOST_CHECK(st.num_vertices() == (size_t) 2);
// ++ THIRD
std::cout << " - INSERT (0,1)" << std::endl;
- typeVectorVertex thirdSimplexVector;
- thirdSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- thirdSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- BOOST_CHECK( thirdSimplexVector.size() == 2 );
- typeSimplex thirdSimplex = std::make_pair(
- thirdSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( thirdSimplex.first, thirdSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex thirdSimplexVector{0, 1};
+ BOOST_CHECK(thirdSimplexVector.size() == 2);
+ typeSimplex thirdSimplex = std::make_pair(thirdSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(thirdSimplex.first, thirdSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, thirdSimplexVector.size(), thirdSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)2 ); // Not incremented !!
+ BOOST_CHECK(st.num_vertices() == (size_t) 2); // Not incremented !!
// ++ FOURTH
std::cout << " - INSERT 2" << std::endl;
- typeVectorVertex fourthSimplexVector;
- fourthSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- BOOST_CHECK( fourthSimplexVector.size() == 1 );
- typeSimplex fourthSimplex = std::make_pair(
- fourthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( fourthSimplex.first, fourthSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex fourthSimplexVector{2};
+ BOOST_CHECK(fourthSimplexVector.size() == 1);
+ typeSimplex fourthSimplex = std::make_pair(fourthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(fourthSimplex.first, fourthSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, fourthSimplexVector.size(), fourthSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)3 );
+ BOOST_CHECK(st.num_vertices() == (size_t) 3);
// ++ FIFTH
std::cout << " - INSERT (2,0)" << std::endl;
- typeVectorVertex fifthSimplexVector;
- fifthSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- fifthSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( fifthSimplexVector.size() == 2 );
- typeSimplex fifthSimplex = std::make_pair(
- fifthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( fifthSimplex.first, fifthSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex fifthSimplexVector{2, 0};
+ BOOST_CHECK(fifthSimplexVector.size() == 2);
+ typeSimplex fifthSimplex = std::make_pair(fifthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(fifthSimplex.first, fifthSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, fifthSimplexVector.size(), fifthSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)3 ); // Not incremented !!
+ BOOST_CHECK(st.num_vertices() == (size_t) 3); // Not incremented !!
// ++ SIXTH
std::cout << " - INSERT (2,1)" << std::endl;
- typeVectorVertex sixthSimplexVector;
- sixthSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- sixthSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- BOOST_CHECK( sixthSimplexVector.size() == 2 );
- typeSimplex sixthSimplex = std::make_pair(
- sixthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( sixthSimplex.first, sixthSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex sixthSimplexVector{2, 1};
+ BOOST_CHECK(sixthSimplexVector.size() == 2);
+ typeSimplex sixthSimplex = std::make_pair(sixthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(sixthSimplex.first, sixthSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, sixthSimplexVector.size(), sixthSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)3 ); // Not incremented !!
+ BOOST_CHECK(st.num_vertices() == (size_t) 3); // Not incremented !!
// ++ SEVENTH
std::cout << " - INSERT (2,1,0)" << std::endl;
- typeVectorVertex seventhSimplexVector;
- seventhSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- seventhSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- seventhSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( seventhSimplexVector.size() == 3 );
- typeSimplex seventhSimplex = std::make_pair(
- seventhSimplexVector, Filtration_value(THIRD_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( seventhSimplex.first, seventhSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex seventhSimplexVector{2, 1, 0};
+ BOOST_CHECK(seventhSimplexVector.size() == 3);
+ typeSimplex seventhSimplex = std::make_pair(seventhSimplexVector, Filtration_value(THIRD_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(seventhSimplex.first, seventhSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, seventhSimplexVector.size(), seventhSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)3 ); // Not incremented !!
+ BOOST_CHECK(st.num_vertices() == (size_t) 3); // Not incremented !!
// ++ EIGHTH
std::cout << " - INSERT 3" << std::endl;
- typeVectorVertex eighthSimplexVector;
- eighthSimplexVector.push_back(FOURTH_VERTEX_HANDLE);
- BOOST_CHECK( eighthSimplexVector.size() == 1 );
- typeSimplex eighthSimplex = std::make_pair(
- eighthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( eighthSimplex.first, eighthSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex eighthSimplexVector{3};
+ BOOST_CHECK(eighthSimplexVector.size() == 1);
+ typeSimplex eighthSimplex = std::make_pair(eighthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(eighthSimplex.first, eighthSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, eighthSimplexVector.size(), eighthSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)4 );
+ BOOST_CHECK(st.num_vertices() == (size_t) 4);
// ++ NINETH
std::cout << " - INSERT (3,0)" << std::endl;
- typeVectorVertex ninethSimplexVector;
- ninethSimplexVector.push_back(FOURTH_VERTEX_HANDLE);
- ninethSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( ninethSimplexVector.size() == 2 );
- typeSimplex ninethSimplex = std::make_pair(
- ninethSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( ninethSimplex.first, ninethSimplex.second );
-
- test_simplex_tree_insert_returns_true (returnValue);
+ typeVectorVertex ninethSimplexVector{3, 0};
+ BOOST_CHECK(ninethSimplexVector.size() == 2);
+ typeSimplex ninethSimplex = std::make_pair(ninethSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(ninethSimplex.first, ninethSimplex.second);
+
+ test_simplex_tree_insert_returns_true(returnValue);
set_and_test_simplex_tree_dim_fil(st, ninethSimplexVector.size(), ninethSimplex.second);
- BOOST_CHECK( st.num_vertices() == (size_t)4 ); // Not incremented !!
+ BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !!
// ++ TENTH
std::cout << " - INSERT 0 (already inserted)" << std::endl;
- typeVectorVertex tenthSimplexVector;
- tenthSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( tenthSimplexVector.size() == 1 );
- typeSimplex tenthSimplex = std::make_pair(
- tenthSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE)); // With a different filtration value
- returnValue =
- st.insert_simplex ( tenthSimplex.first, tenthSimplex.second );
+ typeVectorVertex tenthSimplexVector{0};
+ BOOST_CHECK(tenthSimplexVector.size() == 1);
+ // With a different filtration value
+ typeSimplex tenthSimplex = std::make_pair(tenthSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(tenthSimplex.first, tenthSimplex.second);
BOOST_CHECK(returnValue.second == false);
- typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator
+ typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator
BOOST_CHECK(shReturned == typeST::Simplex_handle(NULL));
- BOOST_CHECK( st.num_vertices() == (size_t)4 ); // Not incremented !!
- BOOST_CHECK( st.dimension() == dim_max );
- BOOST_CHECK( AreAlmostTheSame(st.filtration(), max_fil) );
+ BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !!
+ BOOST_CHECK(st.dimension() == dim_max);
+ BOOST_CHECK(AreAlmostTheSame(st.filtration(), max_fil));
// ++ ELEVENTH
std::cout << " - INSERT (2,1,0) (already inserted)" << std::endl;
- typeVectorVertex eleventhSimplexVector;
- eleventhSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- eleventhSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- eleventhSimplexVector.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( eleventhSimplexVector.size() == 3 );
- typeSimplex eleventhSimplex = std::make_pair(
- eleventhSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
- returnValue =
- st.insert_simplex ( eleventhSimplex.first, eleventhSimplex.second );
+ typeVectorVertex eleventhSimplexVector{2, 1, 0};
+ BOOST_CHECK(eleventhSimplexVector.size() == 3);
+ typeSimplex eleventhSimplex = std::make_pair(eleventhSimplexVector, Filtration_value(FOURTH_FILTRATION_VALUE));
+ returnValue = st.insert_simplex(eleventhSimplex.first, eleventhSimplex.second);
BOOST_CHECK(returnValue.second == false);
- shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator
+ shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator
BOOST_CHECK(shReturned == typeST::Simplex_handle(NULL));
- BOOST_CHECK( st.num_vertices() == (size_t)4 );// Not incremented !!
- BOOST_CHECK( st.dimension() == dim_max );
- BOOST_CHECK( AreAlmostTheSame(st.filtration(), max_fil) );
+ BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !!
+ BOOST_CHECK(st.dimension() == dim_max);
+ BOOST_CHECK(AreAlmostTheSame(st.filtration(), max_fil));
/* Inserted simplex: */
/* 1 */
@@ -372,119 +330,153 @@ BOOST_AUTO_TEST_CASE( simplex_tree_insertion )
// [0.3] 2 1 0
// !! Be careful, simplex are sorted by filtration value on insertion !!
std::cout << "simplex_tree_insertion - first - 0" << std::endl;
- test_simplex_tree_contains(st, firstSimplex, 0);// (0) -> 0
+ test_simplex_tree_contains(st, firstSimplex, 0); // (0) -> 0
std::cout << "simplex_tree_insertion - second - 1" << std::endl;
- test_simplex_tree_contains(st, secondSimplex, 1);// (1) -> 1
+ test_simplex_tree_contains(st, secondSimplex, 1); // (1) -> 1
std::cout << "simplex_tree_insertion - third - 4" << std::endl;
- test_simplex_tree_contains(st, thirdSimplex, 4);// (0,1) -> 4
+ test_simplex_tree_contains(st, thirdSimplex, 4); // (0,1) -> 4
std::cout << "simplex_tree_insertion - fourth - 2" << std::endl;
- test_simplex_tree_contains(st, fourthSimplex, 2);// (2) -> 2
+ test_simplex_tree_contains(st, fourthSimplex, 2); // (2) -> 2
std::cout << "simplex_tree_insertion - fifth - 5" << std::endl;
- test_simplex_tree_contains(st, fifthSimplex, 5);// (2,0) -> 5
+ test_simplex_tree_contains(st, fifthSimplex, 5); // (2,0) -> 5
std::cout << "simplex_tree_insertion - sixth - 6" << std::endl;
- test_simplex_tree_contains(st, sixthSimplex, 6);//(2,1) -> 6
+ test_simplex_tree_contains(st, sixthSimplex, 6); //(2,1) -> 6
std::cout << "simplex_tree_insertion - seventh - 8" << std::endl;
- test_simplex_tree_contains(st, seventhSimplex, 8);// (2,1,0) -> 8
+ test_simplex_tree_contains(st, seventhSimplex, 8); // (2,1,0) -> 8
std::cout << "simplex_tree_insertion - eighth - 3" << std::endl;
- test_simplex_tree_contains(st, eighthSimplex, 3);// (3) -> 3
+ test_simplex_tree_contains(st, eighthSimplex, 3); // (3) -> 3
std::cout << "simplex_tree_insertion - nineth - 7" << std::endl;
- test_simplex_tree_contains(st, ninethSimplex, 7);// (3,0) -> 7
+ test_simplex_tree_contains(st, ninethSimplex, 7); // (3,0) -> 7
// Display the Simplex_tree - Can not be done in the middle of 2 inserts
std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- for( auto f_simplex : st.filtration_simplex_range() )
- {
+ for (auto f_simplex : st.filtration_simplex_range()) {
std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- {
- std::cout << (int)vertex << " ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
}
std::cout << std::endl;
}
}
-BOOST_AUTO_TEST_CASE( NSimplexAndSubfaces_tree_insertion )
-{
- Vertex_handle FIRST_VERTEX_HANDLE = (Vertex_handle)0;
- Vertex_handle SECOND_VERTEX_HANDLE = (Vertex_handle) 1;
- Vertex_handle THIRD_VERTEX_HANDLE = (Vertex_handle) 2;
- Vertex_handle FOURTH_VERTEX_HANDLE = (Vertex_handle) 3;
- Vertex_handle FIFTH_VERTEX_HANDLE = (Vertex_handle) 4;
- Vertex_handle SIXTH_VERTEX_HANDLE = (Vertex_handle) 5;
- Vertex_handle SEVENTH_VERTEX_HANDLE = (Vertex_handle) 6;
- Vertex_handle EIGHTH_VERTEX_HANDLE = (Vertex_handle) 7;
+bool sort_in_decr_order (Vertex_handle i,Vertex_handle j) { return (i>j); }
- // TEST OF INSERTION
+BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) {
std::cout << "********************************************************************" << std::endl;
- std::cout << "TEST OF INSERTION" << std::endl;
+ std::cout << "TEST OF RECURSIVE INSERTION" << std::endl;
typeST st;
+ typePairSimplexBool returnValue;
+ int position = 0;
// ++ FIRST
std::cout << " - INSERT (2,1,0)" << std::endl;
- typeVectorVertex SimplexVector1;
- SimplexVector1.push_back(THIRD_VERTEX_HANDLE);
- SimplexVector1.push_back(SECOND_VERTEX_HANDLE);
- SimplexVector1.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( SimplexVector1.size() == 3 );
- st.insert_simplex_and_subfaces ( SimplexVector1 );
-
- BOOST_CHECK( st.num_vertices() == (size_t)3 ); // +3 (2, 1 and 0 are not existing)
+ typeVectorVertex SimplexVector1{2, 1, 0};
+ BOOST_CHECK(SimplexVector1.size() == 3);
+ returnValue = st.insert_simplex_and_subfaces(SimplexVector1);
+
+ BOOST_CHECK(st.num_vertices() == (size_t) 3); // +3 (2, 1 and 0 are not existing)
+
+ // Check it is well inserted
+ BOOST_CHECK(true == returnValue.second);
+ position = 0;
+ std::sort(SimplexVector1.begin(), SimplexVector1.end(), sort_in_decr_order);
+ for (auto vertex : st.simplex_vertex_range(returnValue.first)) {
+ // Check returned Simplex_handle
+ std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector1[position] << std::endl;
+ BOOST_CHECK(vertex == SimplexVector1[position]);
+ position++;
+ }
// ++ SECOND
std::cout << " - INSERT 3" << std::endl;
- typeVectorVertex SimplexVector2;
- SimplexVector2.push_back(FOURTH_VERTEX_HANDLE);
- BOOST_CHECK( SimplexVector2.size() == 1 );
- st.insert_simplex_and_subfaces ( SimplexVector2 );
-
- BOOST_CHECK( st.num_vertices() == (size_t)4 ); // +1 (3 is not existing)
+ typeVectorVertex SimplexVector2{3};
+ BOOST_CHECK(SimplexVector2.size() == 1);
+ returnValue = st.insert_simplex_and_subfaces(SimplexVector2);
+
+ BOOST_CHECK(st.num_vertices() == (size_t) 4); // +1 (3 is not existing)
+
+ // Check it is well inserted
+ BOOST_CHECK(true == returnValue.second);
+ position = 0;
+ std::sort(SimplexVector2.begin(), SimplexVector2.end(), sort_in_decr_order);
+ for (auto vertex : st.simplex_vertex_range(returnValue.first)) {
+ // Check returned Simplex_handle
+ std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector2[position] << std::endl;
+ BOOST_CHECK(vertex == SimplexVector2[position]);
+ position++;
+ }
// ++ THIRD
std::cout << " - INSERT (0,3)" << std::endl;
- typeVectorVertex SimplexVector3;
- SimplexVector3.push_back(FOURTH_VERTEX_HANDLE);
- SimplexVector3.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( SimplexVector3.size() == 2 );
- st.insert_simplex_and_subfaces ( SimplexVector3 );
-
- BOOST_CHECK( st.num_vertices() == (size_t)4 ); // Not incremented (all are existing)
+ typeVectorVertex SimplexVector3{3, 0};
+ BOOST_CHECK(SimplexVector3.size() == 2);
+ returnValue = st.insert_simplex_and_subfaces(SimplexVector3);
+
+ BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented (all are existing)
+
+ // Check it is well inserted
+ BOOST_CHECK(true == returnValue.second);
+ position = 0;
+ std::sort(SimplexVector3.begin(), SimplexVector3.end(), sort_in_decr_order);
+ for (auto vertex : st.simplex_vertex_range(returnValue.first)) {
+ // Check returned Simplex_handle
+ std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector3[position] << std::endl;
+ BOOST_CHECK(vertex == SimplexVector3[position]);
+ position++;
+ }
// ++ FOURTH
std::cout << " - INSERT (1,0) (already inserted)" << std::endl;
- typeVectorVertex SimplexVector4;
- SimplexVector4.push_back(SECOND_VERTEX_HANDLE);
- SimplexVector4.push_back(FIRST_VERTEX_HANDLE);
- BOOST_CHECK( SimplexVector4.size() == 2 );
- st.insert_simplex_and_subfaces ( SimplexVector4 );
+ typeVectorVertex SimplexVector4{1, 0};
+ BOOST_CHECK(SimplexVector4.size() == 2);
+ returnValue = st.insert_simplex_and_subfaces(SimplexVector4);
- BOOST_CHECK( st.num_vertices() == (size_t)4 ); // Not incremented (all are existing)
+ BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented (all are existing)
+
+ // Check it was not inserted (already there from {2,1,0} insertion)
+ BOOST_CHECK(false == returnValue.second);
// ++ FIFTH
std::cout << " - INSERT (3,4,5)" << std::endl;
- typeVectorVertex SimplexVector5;
- SimplexVector5.push_back(FOURTH_VERTEX_HANDLE);
- SimplexVector5.push_back(FIFTH_VERTEX_HANDLE);
- SimplexVector5.push_back(SIXTH_VERTEX_HANDLE);
- BOOST_CHECK( SimplexVector5.size() == 3 );
- st.insert_simplex_and_subfaces ( SimplexVector5 );
-
- BOOST_CHECK( st.num_vertices() == (size_t)6 );
+ typeVectorVertex SimplexVector5{3, 4, 5};
+ BOOST_CHECK(SimplexVector5.size() == 3);
+ returnValue = st.insert_simplex_and_subfaces(SimplexVector5);
+
+ BOOST_CHECK(st.num_vertices() == (size_t) 6);
+
+ // Check it is well inserted
+ BOOST_CHECK(true == returnValue.second);
+ position = 0;
+ std::sort(SimplexVector5.begin(), SimplexVector5.end(), sort_in_decr_order);
+ for (auto vertex : st.simplex_vertex_range(returnValue.first)) {
+ // Check returned Simplex_handle
+ std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector5[position] << std::endl;
+ BOOST_CHECK(vertex == SimplexVector5[position]);
+ position++;
+ }
// ++ SIXTH
std::cout << " - INSERT (0,1,6,7)" << std::endl;
- typeVectorVertex SimplexVector6;
- SimplexVector6.push_back(FIRST_VERTEX_HANDLE);
- SimplexVector6.push_back(SECOND_VERTEX_HANDLE);
- SimplexVector6.push_back(SEVENTH_VERTEX_HANDLE);
- SimplexVector6.push_back(EIGHTH_VERTEX_HANDLE);
- BOOST_CHECK( SimplexVector6.size() == 4 );
- st.insert_simplex_and_subfaces ( SimplexVector6 );
-
- BOOST_CHECK( st.num_vertices() == (size_t)8 ); // +2 (6 and 7 are not existing - 0 and 1 are already existing)
-
+ typeVectorVertex SimplexVector6{0, 1, 6, 7};
+ BOOST_CHECK(SimplexVector6.size() == 4);
+ returnValue = st.insert_simplex_and_subfaces(SimplexVector6);
+
+ BOOST_CHECK(st.num_vertices() == (size_t) 8); // +2 (6 and 7 are not existing - 0 and 1 are already existing)
+
+ // Check it is well inserted
+ BOOST_CHECK(true == returnValue.second);
+ position = 0;
+ std::sort(SimplexVector6.begin(), SimplexVector6.end(), sort_in_decr_order);
+ for (auto vertex : st.simplex_vertex_range(returnValue.first)) {
+ // Check returned Simplex_handle
+ std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector6[position] << std::endl;
+ BOOST_CHECK(vertex == SimplexVector6[position]);
+ position++;
+ }
+
/* Inserted simplex: */
/* 1 6 */
/* o---o */
@@ -506,18 +498,17 @@ BOOST_AUTO_TEST_CASE( NSimplexAndSubfaces_tree_insertion )
typeSimplex simplexPair4 = std::make_pair(SimplexVector4, DEFAULT_FILTRATION_VALUE);
typeSimplex simplexPair5 = std::make_pair(SimplexVector5, DEFAULT_FILTRATION_VALUE);
typeSimplex simplexPair6 = std::make_pair(SimplexVector6, DEFAULT_FILTRATION_VALUE);
- test_simplex_tree_contains(st,simplexPair1,6); // (2,1,0) is in position 6
- test_simplex_tree_contains(st,simplexPair2,7); // (3) is in position 7
- test_simplex_tree_contains(st,simplexPair3,8); // (3,0) is in position 8
- test_simplex_tree_contains(st,simplexPair4,2); // (1,0) is in position 2
- test_simplex_tree_contains(st,simplexPair5,14); // (3,4,5) is in position 14
- test_simplex_tree_contains(st,simplexPair6,26); // (7,6,1,0) is in position 26
-
+ test_simplex_tree_contains(st, simplexPair1, 6); // (2,1,0) is in position 6
+ test_simplex_tree_contains(st, simplexPair2, 7); // (3) is in position 7
+ test_simplex_tree_contains(st, simplexPair3, 8); // (3,0) is in position 8
+ test_simplex_tree_contains(st, simplexPair4, 2); // (1,0) is in position 2
+ test_simplex_tree_contains(st, simplexPair5, 14); // (3,4,5) is in position 14
+ test_simplex_tree_contains(st, simplexPair6, 26); // (7,6,1,0) is in position 26
+
// ------------------------------------------------------------------------------------------------------------------
// Find in the simplex_tree
// ------------------------------------------------------------------------------------------------------------------
- typeVectorVertex simpleSimplexVector;
- simpleSimplexVector.push_back(SECOND_VERTEX_HANDLE);
+ typeVectorVertex simpleSimplexVector{1};
Simplex_tree<>::Simplex_handle simplexFound = st.find(simpleSimplexVector);
std::cout << "**************IS THE SIMPLEX {1} IN THE SIMPLEX TREE ?\n";
if (simplexFound != st.null_simplex())
@@ -527,9 +518,7 @@ BOOST_AUTO_TEST_CASE( NSimplexAndSubfaces_tree_insertion )
// Check it is found
BOOST_CHECK(simplexFound != st.null_simplex());
- Vertex_handle UNKNOWN_VERTEX_HANDLE = (Vertex_handle) 15;
- typeVectorVertex unknownSimplexVector;
- unknownSimplexVector.push_back(UNKNOWN_VERTEX_HANDLE);
+ typeVectorVertex unknownSimplexVector{15};
simplexFound = st.find(unknownSimplexVector);
std::cout << "**************IS THE SIMPLEX {15} IN THE SIMPLEX TREE ?\n";
if (simplexFound != st.null_simplex())
@@ -547,10 +536,8 @@ BOOST_AUTO_TEST_CASE( NSimplexAndSubfaces_tree_insertion )
std::cout << "***- NO IT ISN'T\n";
// Check it is found
BOOST_CHECK(simplexFound != st.null_simplex());
-
- typeVectorVertex otherSimplexVector;
- otherSimplexVector.push_back(UNKNOWN_VERTEX_HANDLE);
- otherSimplexVector.push_back(SECOND_VERTEX_HANDLE);
+
+ typeVectorVertex otherSimplexVector{1, 15};
simplexFound = st.find(otherSimplexVector);
std::cout << "**************IS THE SIMPLEX {15,1} IN THE SIMPLEX TREE ?\n";
if (simplexFound != st.null_simplex())
@@ -560,10 +547,7 @@ BOOST_AUTO_TEST_CASE( NSimplexAndSubfaces_tree_insertion )
// Check it is NOT found
BOOST_CHECK(simplexFound == st.null_simplex());
- typeVectorVertex invSimplexVector;
- invSimplexVector.push_back(SECOND_VERTEX_HANDLE);
- invSimplexVector.push_back(THIRD_VERTEX_HANDLE);
- invSimplexVector.push_back(FIRST_VERTEX_HANDLE);
+ typeVectorVertex invSimplexVector{1, 2, 0};
simplexFound = st.find(invSimplexVector);
std::cout << "**************IS THE SIMPLEX {1,2,0} IN THE SIMPLEX TREE ?\n";
if (simplexFound != st.null_simplex())
@@ -572,19 +556,191 @@ BOOST_AUTO_TEST_CASE( NSimplexAndSubfaces_tree_insertion )
std::cout << "***- NO IT ISN'T\n";
// Check it is found
BOOST_CHECK(simplexFound != st.null_simplex());
-
+
// Display the Simplex_tree - Can not be done in the middle of 2 inserts
std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- for( auto f_simplex : st.filtration_simplex_range() )
- {
+ for (auto f_simplex : st.filtration_simplex_range()) {
std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for( auto vertex : st.simplex_vertex_range(f_simplex) )
- {
- std::cout << (int)vertex << " ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+}
+
+void test_cofaces(typeST& st, std::vector<Vertex_handle> expected, int dim, std::vector<typeST::Simplex_handle> res) {
+ typeST::Cofaces_simplex_range cofaces;
+ if (dim == 0)
+ cofaces = st.star_simplex_range(st.find(expected));
+ else
+ cofaces = st.cofaces_simplex_range(st.find(expected), dim);
+ for (auto simplex = cofaces.begin(); simplex != cofaces.end(); ++simplex) {
+ typeST::Simplex_vertex_range rg = st.simplex_vertex_range(*simplex);
+ for (auto vertex = rg.begin(); vertex != rg.end(); ++vertex) {
+ std::cout << "(" << *vertex << ")";
}
std::cout << std::endl;
+ BOOST_CHECK(std::find(res.begin(), res.end(), *simplex) != res.end());
}
+}
+
+BOOST_AUTO_TEST_CASE(coface_on_simplex_tree) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST COFACE ALGORITHM" << std::endl;
+ typeST st;
+
+ typeVectorVertex SimplexVector{2, 1, 0};
+ st.insert_simplex_and_subfaces(SimplexVector);
+ SimplexVector = {3, 0};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ SimplexVector = {3, 4, 5};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ SimplexVector = {0, 1, 6, 7};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ /* Inserted simplex: */
+ /* 1 6 */
+ /* o---o */
+ /* /X\7/ */
+ /* o---o---o---o */
+ /* 2 0 3\X/4 */
+ /* o */
+ /* 5 */
+
+ // FIXME
+ st.set_dimension(3);
+
+ std::vector<Vertex_handle> simplex_result;
+ std::vector<typeST::Simplex_handle> result;
+ std::cout << "First test - Star of (3):" << std::endl;
+
+ simplex_result = {3};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {3, 0};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {4, 3};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {5, 4, 3};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {5, 3};
+ result.push_back(st.find(simplex_result));
+ simplex_result.clear();
+
+ std::vector<Vertex_handle> vertex = {3};
+ test_cofaces(st, vertex, 0, result);
+ vertex.clear();
+ result.clear();
+
+ vertex.push_back(1);
+ vertex.push_back(7);
+ std::cout << "Second test - Star of (1,7): " << std::endl;
+
+ simplex_result = {7, 1};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {7, 6, 1, 0};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {7, 1, 0};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {7, 6, 1};
+ result.push_back(st.find(simplex_result));
+
+ test_cofaces(st, vertex, 0, result);
+ result.clear();
+
+ std::cout << "Third test - 2-dimension Cofaces of simplex(1,7) : " << std::endl;
+
+ simplex_result = {7, 1, 0};
+ result.push_back(st.find(simplex_result));
+
+ simplex_result = {7, 6, 1};
+ result.push_back(st.find(simplex_result));
+
+ test_cofaces(st, vertex, 1, result);
+ result.clear();
+
+ std::cout << "Cofaces with a codimension too high (codimension + vetices > tree.dimension) :" << std::endl;
+ test_cofaces(st, vertex, 5, result);
+
+ //std::cout << "Cofaces with an empty codimension" << std::endl;
+ //test_cofaces(st, vertex, -1, result);
+ // std::cout << "Cofaces in an empty simplex tree" << std::endl;
+ // typeST empty_tree;
+ // test_cofaces(empty_tree, vertex, 1, result);
+ //std::cout << "Cofaces of an empty simplex" << std::endl;
+ //vertex.clear();
+ // test_cofaces(st, vertex, 1, result);
+
+}
+
+BOOST_AUTO_TEST_CASE(copy_move_on_simplex_tree) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "TEST COPY MOVE CONSTRUCTORS" << std::endl;
+ typeST st;
+
+ typeVectorVertex SimplexVector{2, 1, 0};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ SimplexVector = {3, 0};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ SimplexVector = {3, 4, 5};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ SimplexVector = {0, 1, 6, 7};
+ st.insert_simplex_and_subfaces(SimplexVector);
+
+ /* Inserted simplex: */
+ /* 1 6 */
+ /* o---o */
+ /* /X\7/ */
+ /* o---o---o---o */
+ /* 2 0 3\X/4 */
+ /* o */
+ /* 5 */
+
+ // FIXME
+ st.set_dimension(3);
+
+ std::cout << "Printing st - address = " << &st << std::endl;
+
+ // Copy constructor
+ typeST st_copy = st;
+ std::cout << "Printing a copy of st - address = " << &st_copy << std::endl;
+
+ // Check the data are the same
+ BOOST_CHECK(st == st_copy);
+ // Check there is a new simplex tree reference
+ BOOST_CHECK(&st != &st_copy);
+
+ // Move constructor
+ typeST st_move = std::move(st);
+ std::cout << "Printing a move of st - address = " << &st_move << std::endl;
+
+ // Check the data are the same
+ BOOST_CHECK(st_move == st_copy);
+ // Check there is a new simplex tree reference
+ BOOST_CHECK(&st_move != &st_copy);
+ BOOST_CHECK(&st_move != &st);
+
+ typeST st_empty;
+ // Check st has been emptied by the move
+ BOOST_CHECK(st == st_empty);
+ BOOST_CHECK(st.filtration() == 0);
+ BOOST_CHECK(st.dimension() == -1);
+ BOOST_CHECK(st.num_simplices() == 0);
+ BOOST_CHECK(st.num_vertices() == (size_t)0);
+
+ std::cout << "Printing st once again- address = " << &st << std::endl;
}
diff --git a/src/Skeleton_blocker/example/CMakeLists.txt b/src/Skeleton_blocker/example/CMakeLists.txt
index d1228526..de0c7bba 100644
--- a/src/Skeleton_blocker/example/CMakeLists.txt
+++ b/src/Skeleton_blocker/example/CMakeLists.txt
@@ -1,10 +1,12 @@
cmake_minimum_required(VERSION 2.6)
project(GUDHIskbl)
-
add_executable(SkeletonBlockerFromSimplices Skeleton_blocker_from_simplices.cpp)
add_executable(SkeletonBlockerIteration Skeleton_blocker_iteration.cpp)
add_executable(SkeletonBlockerLink Skeleton_blocker_link.cpp)
+target_link_libraries(SkeletonBlockerIteration ${Boost_TIMER_LIBRARY} ${Boost_SYSTEM_LIBRARY})
-target_link_libraries(SkeletonBlockerIteration ${Boost_TIMER_LIBRARY} ${Boost_SYSTEM_LIBRARY})
+add_test(SkeletonBlockerFromSimplices ${CMAKE_CURRENT_BINARY_DIR}/SkeletonBlockerFromSimplices)
+add_test(SkeletonBlockerIteration ${CMAKE_CURRENT_BINARY_DIR}/SkeletonBlockerIteration)
+add_test(SkeletonBlockerLink ${CMAKE_CURRENT_BINARY_DIR}/SkeletonBlockerLink)
diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp
index 9f9b3d52..5935a56d 100644
--- a/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp
+++ b/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp
@@ -1,34 +1,33 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
- */
-
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/Skeleton_blocker.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <sstream>
-
-
-#include "gudhi/Skeleton_blocker.h"
+#include <vector>
using namespace std;
using namespace Gudhi;
@@ -36,48 +35,46 @@ using namespace skbl;
typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> Complex;
typedef Complex::Vertex_handle Vertex_handle;
-typedef Complex::Simplex_handle Simplex_handle;
-typedef Complex::Simplex_handle Simplex;
+typedef Complex::Simplex Simplex;
-int main (int argc, char *argv[]){
- std::vector<Simplex_handle> simplices;
+int main(int argc, char *argv[]) {
+ std::vector<Simplex> simplices;
- //add 4 triangles of a tetrahedron 0123
- simplices.push_back(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
- simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(0),Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(0),Vertex_handle(1)));
+ // add 4 triangles of a tetrahedron 0123
+ simplices.push_back(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)));
+ simplices.push_back(Simplex(Vertex_handle(3), Vertex_handle(0), Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(3), Vertex_handle(0), Vertex_handle(1)));
- //get complex from top faces
- Complex complex(make_complex_from_top_faces<Complex>(simplices.begin(),simplices.end()));
+ // get complex from top faces
+ Complex complex(make_complex_from_top_faces<Complex>(simplices.begin(), simplices.end()));
- std::cout << "Simplices:"<<std::endl;
- for(const Simplex & s : complex.simplex_range())
- std::cout << s << " ";
- std::cout << std::endl;
+ std::cout << "Simplices:" << std::endl;
+ for (const Simplex & s : complex.complex_simplex_range())
+ std::cout << s << " ";
+ std::cout << std::endl;
- //One blocker as simplex 0123 is not in the complex but all its proper faces are.
- std::cout << "Blockers: "<<complex.blockers_to_string()<<std::endl;
+ // One blocker as simplex 0123 is not in the complex but all its proper faces are.
+ std::cout << "Blockers: " << complex.blockers_to_string() << std::endl;
- //now build a complex from its full list of simplices
- simplices.clear();
- simplices.push_back(Simplex_handle(Vertex_handle(0)));
- simplices.push_back(Simplex_handle(Vertex_handle(1)));
- simplices.push_back(Simplex_handle(Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(0),Vertex_handle(1)));
- simplices.push_back(Simplex_handle(Vertex_handle(1),Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(2),Vertex_handle(0)));
- complex = Complex(simplices.begin(),simplices.end());
+ // now build a complex from its full list of simplices
+ simplices.clear();
+ simplices.push_back(Simplex(Vertex_handle(0)));
+ simplices.push_back(Simplex(Vertex_handle(1)));
+ simplices.push_back(Simplex(Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(0), Vertex_handle(1)));
+ simplices.push_back(Simplex(Vertex_handle(1), Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(2), Vertex_handle(0)));
+ complex = Complex(simplices.begin(), simplices.end());
- std::cout << "Simplices:"<<std::endl;
- for(const Simplex & s : complex.simplex_range())
- std::cout << s << " ";
- std::cout << std::endl;
+ std::cout << "Simplices:" << std::endl;
+ for (const Simplex & s : complex.complex_simplex_range())
+ std::cout << s << " ";
+ std::cout << std::endl;
- //One blocker as simplex 012 is not in the complex but all its proper faces are.
- std::cout << "Blockers: "<<complex.blockers_to_string()<<std::endl;
+ // One blocker as simplex 012 is not in the complex but all its proper faces are.
+ std::cout << "Blockers: " << complex.blockers_to_string() << std::endl;
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}
-
diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp
index 126e32ec..41b5ee00 100644
--- a/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp
+++ b/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp
@@ -1,24 +1,26 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
- */
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/Skeleton_blocker.h>
#include <boost/timer/timer.hpp>
@@ -29,64 +31,60 @@
#include <sstream>
-#include "gudhi/Skeleton_blocker.h"
-
using namespace std;
using namespace Gudhi;
using namespace skbl;
typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> Complex;
typedef Complex::Vertex_handle Vertex_handle;
-typedef Complex::Simplex_handle Simplex;
+typedef Complex::Simplex Simplex;
-
-Complex build_complete_complex(int n){
- // build a full complex with n vertices and 2^n-1 simplices
- Complex complex;
- for(int i=0;i<n;i++)
- complex.add_vertex();
- for(int i=0;i<n;i++)
- for(int j=0;j<i;j++)
- //note that add_edge, add the edge and all its cofaces
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- return complex;
+Complex build_complete_complex(int n) {
+ // build a full complex with n vertices and 2^n-1 simplices
+ Complex complex;
+ for (int i = 0; i < n; i++)
+ complex.add_vertex();
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < i; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ return complex;
}
-int main (int argc, char *argv[]){
- boost::timer::auto_cpu_timer t;
+int main(int argc, char *argv[]) {
+ boost::timer::auto_cpu_timer t;
- const int n = 15;
+ const int n = 15;
- // build a full complex with n vertices and 2^n-1 simplices
- Complex complex(build_complete_complex(n));
+ // build a full complex with n vertices and 2^n-1 simplices
+ Complex complex(build_complete_complex(n));
- // this is just to illustrate iterators, to count number of vertices
- // or edges, complex.num_vertices() and complex.num_edges() are
- // more appropriated!
- unsigned num_vertices = 0;
- for(auto v : complex.vertex_range()) {
- std::cout << "Vertex " << v <<std::endl;
- ++num_vertices;
- }
+ // this is just to illustrate iterators, to count number of vertices
+ // or edges, complex.num_vertices() and complex.num_edges() are
+ // more appropriated!
+ unsigned num_vertices = 0;
+ for (auto v : complex.vertex_range()) {
+ std::cout << "Vertex " << v << std::endl;
+ ++num_vertices;
+ }
- // such loop can also be done directly with distance as iterators are STL compliant
- auto edges = complex.edge_range();
- unsigned num_edges = std::distance(edges.begin(), edges.end());
+ // such loop can also be done directly with distance as iterators are STL compliant
+ auto edges = complex.edge_range();
+ unsigned num_edges = std::distance(edges.begin(), edges.end());
- unsigned euler = 0;
- unsigned num_simplices = 0;
- // we use a reference to a simplex instead of a copy
- // value here because a simplex is a set of integers
- // and copying it cost time
- for(const Simplex & s : complex.simplex_range()){
- ++num_simplices;
- if(s.dimension()%2 == 0)
- euler += 1;
- else
- euler -= 1;
- }
- std::cout << "Saw "<<num_vertices<<" vertices, "<<num_edges<<" edges and "<<num_simplices<<" simplices"<<std::endl;
- std::cout << "The Euler Characteristic is "<<euler<<std::endl;
- return EXIT_SUCCESS;
+ unsigned euler = 0;
+ unsigned num_simplices = 0;
+ // we use a reference to a simplex instead of a copy
+ // value here because a simplex is a set of integers
+ // and copying it cost time
+ for (const Simplex & s : complex.complex_simplex_range()) {
+ ++num_simplices;
+ if (s.dimension() % 2 == 0)
+ euler += 1;
+ else
+ euler -= 1;
+ }
+ std::cout << "Saw " << num_vertices << " vertices, " << num_edges << " edges and " << num_simplices << " simplices"
+ << std::endl;
+ std::cout << "The Euler Characteristic is " << euler << std::endl;
+ return EXIT_SUCCESS;
}
-
diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp
index 0987cc89..698a8106 100644
--- a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp
+++ b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp
@@ -1,25 +1,26 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
- */
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/Skeleton_blocker.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,9 +28,6 @@
#include <fstream>
#include <sstream>
-
-#include "gudhi/Skeleton_blocker.h"
-
using namespace std;
using namespace Gudhi;
using namespace skbl;
@@ -37,35 +35,37 @@ using namespace skbl;
typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> Complex;
typedef Complex::Vertex_handle Vertex_handle;
typedef Complex::Root_vertex_handle Root_vertex_handle;
-typedef Complex::Simplex_handle Simplex;
+typedef Complex::Simplex Simplex;
+int main(int argc, char *argv[]) {
+ // build a full complex with 4 vertices and 2^4-1 simplices
-int main (int argc, char *argv[]){
- // build a full complex with 4 vertices and 2^4-1 simplices
- // Initial vertices are (0,1,2,3,4)
- Simplex tetrahedron(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3));
- Complex complex;
- complex.add_simplex(tetrahedron);
+ // Create a complex with four vertices (0,1,2,3)
+ Complex complex;
- cout<<"complex:"<<complex.to_string()<<endl;
+ // Add a tetrahedron to this complex
+ Simplex tetrahedron(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3));
+ complex.add_simplex(tetrahedron);
- //build the link of vertex 1, eg a triangle {0,2,3}
- auto link = complex.link(Vertex_handle(1));
- cout<<"link:"<<link.to_string()<<endl;
+ cout << "complex:" << complex.to_string() << endl;
- //Internally link is a subcomplex of 'complex' and its vertices are stored in a vector.
- //They can be accessed via Vertex_handle(x) where x is an index of the vector.
- //In that example, link has three vertices and thus it contains only
- // Vertex_handle(0),Vertex_handle(1) and Vertex_handle(2) are).
- for(int i = 0; i<5; ++i)
- cout << "link.contains_vertex(Vertex_handle("<<i<<")):"<<link.contains_vertex(Vertex_handle(i))<<endl;
- cout<<endl;
+ // build the link of vertex 1, eg a triangle {0,2,3}
+ auto link = complex.link(Vertex_handle(1));
+ cout << "link:" << link.to_string() << endl;
- //To access to the initial vertices eg (0,1,2,3,4), Root_vertex_handle must be used.
- //For instance, to test if the link contains the vertex that was labeled i:
- for(int i = 0; i<5; ++i)
- cout << "link.contains_vertex(Root_vertex_handle("<<i<<")):"<<link.contains_vertex(Root_vertex_handle(i))<<endl;
+ // Internally link is a subcomplex of 'complex' and its vertices are stored in a vector.
+ // They can be accessed via Vertex_handle(x) where x is an index of the vector.
+ // In that example, link has three vertices and thus it contains only
+ // Vertex_handle(0),Vertex_handle(1) and Vertex_handle(2) are).
+ for (int i = 0; i < 5; ++i)
+ cout << "link.contains_vertex(Vertex_handle(" << i << ")):" << link.contains_vertex(Vertex_handle(i)) << endl;
+ cout << endl;
- return EXIT_SUCCESS;
-}
+ // To access to the initial vertices eg (0,1,2,3,4), Root_vertex_handle must be used.
+ // For instance, to test if the link contains the vertex that was labeled i:
+ for (int i = 0; i < 5; ++i)
+ cout << "link.contains_vertex(Root_vertex_handle(" << i << ")):" <<
+ link.contains_vertex(Root_vertex_handle(i)) << endl;
+ return EXIT_SUCCESS;
+}
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
index 289819b5..615b3a81 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
@@ -19,23 +19,24 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_H_
-#include "gudhi/Skeleton_blocker_complex.h"
-#include "gudhi/Skeleton_blocker_geometric_complex.h"
-#include "gudhi/Skeleton_blocker_simplifiable_complex.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h"
+#ifndef SKELETON_BLOCKER_H_
+#define SKELETON_BLOCKER_H_
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h"
+#include <gudhi/Skeleton_blocker_complex.h>
+#include <gudhi/Skeleton_blocker_geometric_complex.h>
+#include <gudhi/Skeleton_blocker_simplifiable_complex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h>
-#include "gudhi/Utils.h" // xxx
-
+#include <gudhi/Utils.h> // xxx
namespace Gudhi {
+
namespace skbl {
+
/** \defgroup skbl Skeleton-Blocker
\author David Salinas
@@ -128,7 +129,7 @@ of a simplicial complex.
\code{.cpp}
typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> Complex;
typedef Complex::Vertex_handle Vertex_handle;
- typedef Complex::Simplex_handle Simplex;
+ typedef Complex::Simplex Simplex;
const int n = 15;
@@ -138,8 +139,7 @@ of a simplicial complex.
complex.add_vertex();
for(int i=0;i<n;i++)
for(int j=0;j<i;j++)
- //note that add_edge adds the edge and all its cofaces
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
+ complex.add_edge_without_blockers(Vertex_handle(i),Vertex_handle(j));
// this is just to illustrate iterators, to count number of vertices
// or edges, complex.num_vertices() and complex.num_edges() are
@@ -158,7 +158,7 @@ of a simplicial complex.
// we use a reference to a simplex instead of a copy
// value here because a simplex is a set of integers
// and copying it cost time
- for(const Simplex & s : complex.simplex_range()){
+ for(const Simplex & s : complex.star_simplex_range()){
++num_simplices;
if(s.dimension()%2 == 0)
euler += 1;
@@ -181,20 +181,20 @@ The Euler Characteristic is 1
\subsection s Constructing a skeleton-blockers from a list of maximal faces or from a list of faces
\code{.cpp}
- std::vector<Simplex_handle> simplices;
+ std::vector<Simplex> simplices;
//add 4 triangles of a tetrahedron 0123
- simplices.push_back(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
- simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(0),Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(0),Vertex_handle(1)));
+ simplices.push_back(Simplex(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
+ simplices.push_back(Simplex(Vertex_handle(3),Vertex_handle(0),Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(3),Vertex_handle(0),Vertex_handle(1)));
Complex complex;
//get complex from top faces
make_complex_from_top_faces(complex,simplices.begin(),simplices.end());
std::cout << "Simplices:"<<std::endl;
- for(const Simplex & s : complex.simplex_range())
+ for(const Simplex & s : complex.star_simplex_range())
std::cout << s << " ";
std::cout << std::endl;
@@ -203,16 +203,16 @@ The Euler Characteristic is 1
//now build a complex from its full list of simplices
simplices.clear();
- simplices.push_back(Simplex_handle(Vertex_handle(0)));
- simplices.push_back(Simplex_handle(Vertex_handle(1)));
- simplices.push_back(Simplex_handle(Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(0),Vertex_handle(1)));
- simplices.push_back(Simplex_handle(Vertex_handle(1),Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(2),Vertex_handle(0)));
+ simplices.push_back(Simplex(Vertex_handle(0)));
+ simplices.push_back(Simplex(Vertex_handle(1)));
+ simplices.push_back(Simplex(Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(0),Vertex_handle(1)));
+ simplices.push_back(Simplex(Vertex_handle(1),Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(2),Vertex_handle(0)));
complex = Complex(simplices.begin(),simplices.end());
std::cout << "Simplices:"<<std::endl;
- for(const Simplex & s : complex.simplex_range())
+ for(const Simplex & s : complex.star_simplex_range())
std::cout << s << " ";
std::cout << std::endl;
@@ -240,14 +240,12 @@ their collaboration to write the two initial papers
\copyright GNU General Public License v3.
-\verbatim Contact: David Salinas, david.salinas@inria.fr \endverbatim
+\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup
-} // namespace skbl
-} // namespace Gudhi
-
-
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_H_
+} // namespace skbl
+} // namespace Gudhi
+#endif // SKELETON_BLOCKER_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h
index 829ab1e8..4ade68e7 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h
@@ -19,10 +19,10 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_COMPLEX_VISITOR_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_COMPLEX_VISITOR_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_COMPLEX_VISITOR_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_COMPLEX_VISITOR_H_
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h"
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h>
namespace Gudhi {
@@ -41,7 +41,7 @@ class Skeleton_blocker_complex_visitor {
virtual void on_add_vertex(Vertex_handle) = 0;
virtual void on_remove_vertex(Vertex_handle) = 0;
- virtual void on_add_edge(Vertex_handle a, Vertex_handle b) = 0;
+ virtual void on_add_edge_without_blockers(Vertex_handle a, Vertex_handle b) = 0;
virtual void on_remove_edge(Vertex_handle a, Vertex_handle b) = 0;
/**
@@ -54,12 +54,12 @@ class Skeleton_blocker_complex_visitor {
* @brief Called when performing an edge contraction when
* an edge bx is replaced by an edge ax (not already present).
* Precisely, this methods is called this way in contract_edge :
- * add_edge(a,x)
+ * add_edge_without_blockers(a,x)
* on_swaped_edge(a,b,x)
* remove_edge(b,x)
*/
virtual void on_swaped_edge(Vertex_handle a, Vertex_handle b,
- Vertex_handle x)=0;
+ Vertex_handle x) = 0;
virtual void on_add_blocker(
const Skeleton_blocker_simplex<Vertex_handle>&) = 0;
virtual void on_delete_blocker(
@@ -79,7 +79,7 @@ class Dummy_complex_visitor : public Skeleton_blocker_complex_visitor<
}
void on_remove_vertex(Vertex_handle) {
}
- void on_add_edge(Vertex_handle a, Vertex_handle b) {
+ void on_add_edge_without_blockers(Vertex_handle a, Vertex_handle b) {
}
void on_remove_edge(Vertex_handle a, Vertex_handle b) {
}
@@ -108,8 +108,8 @@ class Print_complex_visitor : public Skeleton_blocker_complex_visitor<
void on_remove_vertex(Vertex_handle v) {
std::cerr << "on_remove_vertex:" << v << std::endl;
}
- void on_add_edge(Vertex_handle a, Vertex_handle b) {
- std::cerr << "on_add_edge:" << a << "," << b << std::endl;
+ void on_add_edge_without_blockers(Vertex_handle a, Vertex_handle b) {
+ std::cerr << "on_add_edge_without_blockers:" << a << "," << b << std::endl;
}
void on_remove_edge(Vertex_handle a, Vertex_handle b) {
std::cerr << "on_remove_edge:" << a << "," << b << std::endl;
@@ -132,4 +132,4 @@ class Print_complex_visitor : public Skeleton_blocker_complex_visitor<
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_COMPLEX_VISITOR_H_
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_COMPLEX_VISITOR_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h
index 17d58956..876bdba9 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h
@@ -19,10 +19,10 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_LINK_SUPERIOR_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_LINK_SUPERIOR_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_LINK_SUPERIOR_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_LINK_SUPERIOR_H_
-#include "gudhi/Skeleton_blocker_link_complex.h"
+#include <gudhi/Skeleton_blocker_link_complex.h>
namespace Gudhi {
@@ -44,13 +44,13 @@ class Skeleton_blocker_link_superior : public Skeleton_blocker_link_complex<
public:
typedef typename ComplexType::Vertex_handle Vertex_handle;
typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
- typedef typename ComplexType::Simplex_handle Simplex_handle;
+ typedef typename ComplexType::Simplex Simplex;
typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
typedef typename ComplexType::BlockerMap BlockerMap;
typedef typename ComplexType::BlockerPair BlockerPair;
typedef typename ComplexType::BlockerMapIterator BlockerMapIterator;
typedef typename ComplexType::BlockerMapConstIterator BlockerMapConstIterator;
- typedef typename ComplexType::Simplex_handle::Simplex_vertex_const_iterator AddressSimplexConstIterator;
+ typedef typename ComplexType::Simplex::Simplex_vertex_const_iterator AddressSimplexConstIterator;
typedef typename ComplexType::Root_simplex_handle::Simplex_vertex_const_iterator IdSimplexConstIterator;
Skeleton_blocker_link_superior()
@@ -58,7 +58,7 @@ class Skeleton_blocker_link_superior : public Skeleton_blocker_link_complex<
}
Skeleton_blocker_link_superior(const ComplexType & parent_complex,
- Simplex_handle& alpha_parent_adress)
+ Simplex& alpha_parent_adress)
: Skeleton_blocker_link_complex<ComplexType>(parent_complex,
alpha_parent_adress, true) {
}
@@ -74,4 +74,4 @@ class Skeleton_blocker_link_superior : public Skeleton_blocker_link_complex<
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_LINK_SUPERIOR_H_
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_LINK_SUPERIOR_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h
index aaaab8b0..ad2d2f85 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h
@@ -19,15 +19,15 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_
+
+#include <gudhi/Off_reader.h>
#include <string>
#include <vector>
#include <map>
-#include "gudhi/Off_reader.h"
-
namespace Gudhi {
namespace skbl {
@@ -61,7 +61,7 @@ class Skeleton_blocker_off_flag_visitor_reader {
if (!load_only_points_) {
for (size_t i = 0; i < face.size(); ++i)
for (size_t j = i + 1; j < face.size(); ++j) {
- complex_.add_edge(Vertex_handle(face[i]), Vertex_handle(face[j]));
+ complex_.add_edge_without_blockers(Vertex_handle(face[i]), Vertex_handle(face[j]));
}
}
}
@@ -76,12 +76,12 @@ template<typename Complex>
class Skeleton_blocker_off_visitor_reader {
Complex& complex_;
typedef typename Complex::Vertex_handle Vertex_handle;
- typedef typename Complex::Simplex_handle Simplex_handle;
+ typedef typename Complex::Simplex Simplex;
typedef typename Complex::Point Point;
const bool load_only_points_;
std::vector<Point> points_;
- std::vector<Simplex_handle> maximal_faces_;
+ std::vector<Simplex> maximal_faces_;
public:
explicit Skeleton_blocker_off_visitor_reader(Complex& complex, bool load_only_points = false) :
@@ -99,7 +99,7 @@ class Skeleton_blocker_off_visitor_reader {
void maximal_face(const std::vector<int>& face) {
if (!load_only_points_) {
- Simplex_handle s;
+ Simplex s;
for (auto x : face)
s.add_vertex(Vertex_handle(x));
maximal_faces_.emplace_back(s);
@@ -107,7 +107,7 @@ class Skeleton_blocker_off_visitor_reader {
}
void done() {
- complex_ = make_complex_from_top_faces(maximal_faces_.begin(), maximal_faces_.end(),
+ complex_ = make_complex_from_top_faces<Complex>(maximal_faces_.begin(), maximal_faces_.end(),
points_.begin(), points_.end() );
}
};
@@ -197,4 +197,4 @@ class Skeleton_blocker_off_writer {
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_OFF_IO_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h
index d3a5b9d8..8508d9a5 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h
@@ -19,14 +19,14 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_GEOMETRIC_TRAITS_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_GEOMETRIC_TRAITS_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_GEOMETRIC_TRAITS_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_GEOMETRIC_TRAITS_H_
+
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h>
#include <string>
#include <sstream>
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h"
-
namespace Gudhi {
namespace skbl {
@@ -91,4 +91,4 @@ struct Skeleton_blocker_simple_geometric_traits :
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_GEOMETRIC_TRAITS_H_
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_GEOMETRIC_TRAITS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h
index 52e454ea..0d2de767 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h
@@ -19,12 +19,13 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_TRAITS_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_TRAITS_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_TRAITS_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_TRAITS_H_
+
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h>
#include <string>
#include <sstream>
-#include "Skeleton_blocker_simplex.h"
namespace Gudhi {
@@ -77,7 +78,7 @@ struct Skeleton_blocker_simple_traits {
: vertex(val) {
}
- operator int() const { return (int)vertex; }
+ operator int() const { return static_cast<int>(vertex); }
boost_vertex_handle vertex;
@@ -178,4 +179,4 @@ struct Skeleton_blocker_simple_traits {
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_TRAITS_H_
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLE_TRAITS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h
index 10d64e98..714bf23c 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h
@@ -20,8 +20,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_
#include <cassert>
#include <iostream>
@@ -69,7 +69,9 @@ class Skeleton_blocker_simplex {
}
Skeleton_blocker_simplex(std::initializer_list<T>& list) {
- for_each(list.begin(), list.end(), add_vertex);
+ std::for_each(list.begin(), list.end(), [&] (T const& elt) {
+ add_vertex(elt);
+ });
}
template<typename ... Args>
@@ -216,7 +218,7 @@ class Skeleton_blocker_simplex {
}
/**
- * Returns the first vertex of the (oriented) simplex.
+ * Returns the first and smallest vertex of the simplex.
*
* Be careful : assumes the simplex is non-empty.
*/
@@ -226,7 +228,7 @@ class Skeleton_blocker_simplex {
}
/**
- * Returns the last vertex of the (oriented) simplex.
+ * Returns the last and greatest vertex of the simplex.
*
* Be careful : assumes the simplex is non-empty.
*/
@@ -369,5 +371,4 @@ class Skeleton_blocker_simplex {
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_
-
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_SIMPLEX_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h
index e906df75..50a83345 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h
@@ -20,16 +20,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
+#ifndef SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
+#define SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
+
+#include <gudhi/Skeleton_blocker_complex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h>
+#include <gudhi/Utils.h>
#include <map>
#include <vector>
-#include "gudhi/Skeleton_blocker_complex.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h"
-#include "gudhi/Utils.h"
-
namespace Gudhi {
namespace skbl {
@@ -66,34 +66,19 @@ class Skeleton_blocker_sub_complex : public ComplexType {
public:
using ComplexType::add_vertex;
- using ComplexType::add_edge;
+ using ComplexType::add_edge_without_blockers;
using ComplexType::add_blocker;
typedef typename ComplexType::Vertex_handle Vertex_handle;
typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
- typedef typename ComplexType::Simplex_handle Simplex_handle;
+ typedef typename ComplexType::Simplex Simplex;
typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
protected:
- ///**
- //* @brief Returns true iff the simplex formed by all vertices contained in 'addresses_sigma_in_link'
- //* but 'vertex_to_be_ignored' is in 'link'
- //*/
- /*
- template<typename T> friend bool
- proper_face_in_union(
- Skeleton_blocker_sub_complex<T> & link,
- std::vector<boost::optional<typename T::Vertex_handle> > & addresses_sigma_in_link,
- int vertex_to_be_ignored);*/
-
/**
* @brief Determines whether all proper faces of simplex 'sigma' belong to 'link1' \cup 'link2'
* where 'link1' and 'link2' are subcomplexes of the same complex of type ComplexType
*/
- // template<typename T> friend bool
- // proper_faces_in_union(Skeleton_blocker_simplex<typename T::Root_vertex_handle> & sigma, Skeleton_blocker_sub_complex<T> & link1, Skeleton_blocker_sub_complex<T> & link2){
- // template<typename T> friend bool
- // proper_faces_in_union(Skeleton_blocker_simplex<typename T::Root_vertex_handle> & sigma, Skeleton_blocker_sub_complex<T> & link1, Skeleton_blocker_sub_complex<T> & link2);
typedef std::map<Root_vertex_handle, Vertex_handle> IdAddressMap;
typedef typename IdAddressMap::value_type AddressPair;
typedef typename IdAddressMap::iterator IdAddressMapIterator;
@@ -124,11 +109,11 @@ class Skeleton_blocker_sub_complex : public ComplexType {
* It assumes that both vertices corresponding to v1_root and v2_root are present
* in the sub-complex.
*/
- void add_edge(Root_vertex_handle v1_root, Root_vertex_handle v2_root) {
+ void add_edge_without_blockers(Root_vertex_handle v1_root, Root_vertex_handle v2_root) {
auto v1_sub(this->get_address(v1_root));
auto v2_sub(this->get_address(v2_root));
assert(v1_sub && v2_sub);
- this->ComplexType::add_edge(*v1_sub, *v2_sub);
+ this->ComplexType::add_edge_without_blockers(*v1_sub, *v2_sub);
}
/**
@@ -139,7 +124,7 @@ class Skeleton_blocker_sub_complex : public ComplexType {
void add_blocker(const Root_simplex_handle& blocker_root) {
auto blocker_sub = this->get_address(blocker_root);
assert(blocker_sub);
- this->add_blocker(new Simplex_handle(*blocker_sub));
+ this->add_blocker(new Simplex(*blocker_sub));
}
public:
@@ -148,7 +133,7 @@ class Skeleton_blocker_sub_complex : public ComplexType {
* vertices of 'simplex'.
*/
void make_restricted_complex(const ComplexType & parent_complex,
- const Simplex_handle& simplex) {
+ const Simplex& simplex) {
this->clear();
// add vertices to the sub complex
for (auto x : simplex) {
@@ -160,11 +145,11 @@ class Skeleton_blocker_sub_complex : public ComplexType {
// add edges to the sub complex
for (auto x : simplex) {
// x_neigh is the neighbor of x intersected with vertices_simplex
- Simplex_handle x_neigh;
+ Simplex x_neigh;
parent_complex.add_neighbours(x, x_neigh, true);
x_neigh.intersection(simplex);
for (auto y : x_neigh) {
- this->add_edge(parent_complex[x].get_id(), parent_complex[y].get_id());
+ this->add_edge_without_blockers(parent_complex[x].get_id(), parent_complex[y].get_id());
}
}
@@ -173,9 +158,9 @@ class Skeleton_blocker_sub_complex : public ComplexType {
// check if it is the first time we encounter the blocker
if (simplex.contains(*blocker)) {
Root_simplex_handle blocker_root(parent_complex.get_id(*(blocker)));
- Simplex_handle blocker_restr(
+ Simplex blocker_restr(
*(this->get_simplex_address(blocker_root)));
- this->add_blocker(new Simplex_handle(blocker_restr));
+ this->add_blocker(new Simplex(blocker_restr));
}
}
}
@@ -203,7 +188,7 @@ class Skeleton_blocker_sub_complex : public ComplexType {
// * Allocates a simplex in L corresponding to the simplex s in K
// * with its local adresses and returns an AddressSimplex.
// */
- // boost::optional<Simplex_handle> get_address(const Root_simplex_handle & s) const;
+ // boost::optional<Simplex> get_address(const Root_simplex_handle & s) const;
// private:
/**
@@ -235,7 +220,7 @@ bool proper_face_in_union(
// we test that all vertices of 'addresses_sigma_in_link' but 'vertex_to_be_ignored'
// are in link1 if it is the case we construct the corresponding simplex
bool vertices_sigma_are_in_link = true;
- typename ComplexType::Simplex_handle sigma_in_link;
+ typename ComplexType::Simplex sigma_in_link;
for (int i = 0; i < addresses_sigma_in_link.size(); ++i) {
if (i != vertex_to_be_ignored) {
if (!addresses_sigma_in_link[i]) {
@@ -301,5 +286,5 @@ bool proper_faces_in_union(
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
+#endif // SKELETON_BLOCKER_SKELETON_BLOCKER_SUB_COMPLEX_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Top_faces.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Top_faces.h
index 32538f38..eb970195 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Top_faces.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Top_faces.h
@@ -1,67 +1,70 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 TOP_FACES_H_
-#define TOP_FACES_H_
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 SKELETON_BLOCKER_INTERNAL_TOP_FACES_H_
+#define SKELETON_BLOCKER_INTERNAL_TOP_FACES_H_
#include <list>
#include <vector>
#include <set>
+namespace Gudhi {
+
+namespace skbl {
+
template<typename SimplexHandle>
-std::list<SimplexHandle> subfaces(SimplexHandle top_face){
- std::list<SimplexHandle> res;
- if(top_face.dimension()==-1) return res;
- if(top_face.dimension()==0) {
- res.push_back(top_face);
- return res;
- }
- else{
- auto first_vertex = top_face.first_vertex();
- top_face.remove_vertex(first_vertex);
- res = subfaces(top_face);
- std::list<SimplexHandle> copy = res;
- for(auto& simplex : copy){
- simplex.add_vertex(first_vertex);
- }
- res.push_back(SimplexHandle(first_vertex));
- res.splice(res.end(),copy);
- return res;
- }
+std::list<SimplexHandle> subfaces(SimplexHandle top_face) {
+ std::list<SimplexHandle> res;
+ if (top_face.dimension() == -1) return res;
+ if (top_face.dimension() == 0) {
+ res.push_back(top_face);
+ return res;
+ } else {
+ auto first_vertex = top_face.first_vertex();
+ top_face.remove_vertex(first_vertex);
+ res = subfaces(top_face);
+ std::list<SimplexHandle> copy = res;
+ for (auto& simplex : copy) {
+ simplex.add_vertex(first_vertex);
+ }
+ res.push_back(SimplexHandle(first_vertex));
+ res.splice(res.end(), copy);
+ return res;
+ }
}
/**
* add all faces of top_face in simplices_per_dimension
*/
template<typename SimplexHandle>
-void register_faces(
- std::vector< std::set<SimplexHandle> >& simplices_per_dimension,
- const SimplexHandle& top_face){
- std::list<SimplexHandle> subfaces_list = subfaces(top_face);
- for(auto& simplex : subfaces_list ){
- simplices_per_dimension[simplex.dimension()].insert(simplex);
- }
+void register_faces(std::vector< std::set<SimplexHandle> >& simplices_per_dimension,
+ const SimplexHandle& top_face) {
+ std::list<SimplexHandle> subfaces_list = subfaces(top_face);
+ for (auto& simplex : subfaces_list) {
+ simplices_per_dimension[simplex.dimension()].insert(simplex);
+ }
}
+} // namespace skbl
+} // namespace Gudhi
-
-#endif /* TOP_FACES_H_ */
+#endif // SKELETON_BLOCKER_INTERNAL_TOP_FACES_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h
index f2a443dc..499980c4 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h
@@ -1,13 +1,10 @@
-/*
- * Trie.h
- * Created on: Jan 29, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,8 +22,8 @@
*/
-#ifndef TRIE_H_
-#define TRIE_H_
+#ifndef SKELETON_BLOCKER_INTERNAL_TRIE_H_
+#define SKELETON_BLOCKER_INTERNAL_TRIE_H_
#include <memory>
#include <vector>
@@ -35,242 +32,237 @@
namespace Gudhi {
-
namespace skbl {
-
template<typename SimplexHandle>
-struct Trie{
- typedef SimplexHandle Simplex_handle;
- typedef typename SimplexHandle::Vertex_handle Vertex_handle;
-
- Vertex_handle v;
- std::vector<std::shared_ptr<Trie> > childs;
- //std::vector<std::unique_ptr<Trie> > childs; -> use of deleted function
-private:
- const Trie* parent_;
-public:
- Trie():parent_(0){}
- Trie(Vertex_handle v_):v(v_),parent_(0){}
-
- Trie(Vertex_handle v_,Trie* parent):v(v_),parent_(parent){}
-
-
- bool operator==(const Trie& other) const{
- return (v == other.v) ;
- }
-
- void add_child(Trie* child){
- if(child){
- std::shared_ptr<Trie> ptr_to_add(child);
- childs.push_back(ptr_to_add);
- child->parent_ = this;
- }
- }
-
- typedef typename Simplex_handle::Simplex_vertex_const_iterator Simplex_vertex_const_iterator;
-
-
- Trie* make_trie(Simplex_vertex_const_iterator s_it,Simplex_vertex_const_iterator s_end){
- if(s_it == s_end) return 0;
- else{
- Trie* res = new Trie(*s_it);
- Trie* child = make_trie(++s_it,s_end);
- res->add_child(child);
- return res;
- }
- }
-private:
- //go down recursively in the tree while advancing the simplex iterator.
- //when it reaches a leaf, it inserts the remaining that is not present
- void add_simplex_helper(Simplex_vertex_const_iterator s_it,Simplex_vertex_const_iterator s_end){
- assert(*s_it == v);
- ++s_it;
- if(s_it==s_end) return ;
- if(!is_leaf()){
- for(auto child : childs){
- if(child->v == *s_it)
- return child->add_simplex_helper(s_it,s_end);
- }
- //s_it is not found and needs to be inserted
- }
- //not leaf -> remaining of s needs to be inserted
- Trie* son_with_what_remains_of_s(make_trie(s_it,s_end));
- add_child(son_with_what_remains_of_s);
- return;
- }
-
- void maximal_faces_helper(std::vector<Simplex_handle>& res) const{
- if(is_leaf()) res.push_back(simplex());
- else
- for(auto child : childs)
- child->maximal_faces_helper(res);
- }
-
-public:
- /**
- * adds the simplex to the trie
- */
- void add_simplex(const Simplex_handle& s){
- if(s.empty()) return;
- assert(v==s.first_vertex());
- add_simplex_helper(s.begin(),s.end());
- }
-
- std::vector<Simplex_handle> maximal_faces() const{
- std::vector<Simplex_handle> res;
- maximal_faces_helper(res);
- return res;
- }
-
- /**
- * Goes to the root in the trie to consitute simplex
- */
- void add_vertices_up_to_the_root(Simplex_handle& res) const{
- res.add_vertex(v);
- if(parent_)
- parent_->add_vertices_up_to_the_root(res);
- }
-
- Simplex_handle simplex() const{
- Simplex_handle res;
- add_vertices_up_to_the_root(res);
- return res;
- }
-
- bool is_leaf() const{
- return childs.empty();
- }
-
- bool is_root() const{
- return parent_==0;
- }
-
- const Trie* parent() {
- return parent_;
- }
-
- void remove_leaf() {
- assert(is_leaf);
- if(!is_root())
- parent_->childs.erase(this);
- }
-
- /**
- * true iff the simplex corresponds to one node in the trie
- */
- bool contains(const Simplex_handle& s) const{
- Trie const* current = this;
- if(s.empty()) return true;
- if(current->v != s.first_vertex()) return false;
- auto s_pos = s.begin();
- ++s_pos;
- while(s_pos != s.end() && current != 0){
- bool found = false;
- for(const auto child : current->childs){
- if(child->v == *s_pos) {
- ++s_pos;
- current = child.get();
- found = true;
- break;
- }
- }
- if(!found) return false;
- }
- return current!=0;
- }
-
- Trie* go_bottom_left(){
- if(is_leaf())
- return this;
- else
- return (*childs.begin())->go_bottom_left();
- }
-
- friend std::ostream& operator<<(std::ostream& stream, const Trie& trie){
- stream<< "T( "<< trie.v<< " ";
- for(auto t : trie.childs)
- stream << *t ;
- stream<<")";
- return stream;
- }
+struct Trie {
+ typedef SimplexHandle Simplex;
+ typedef typename SimplexHandle::Vertex_handle Vertex_handle;
+
+ Vertex_handle v;
+ std::vector<std::shared_ptr<Trie> > childs;
+ // std::vector<std::unique_ptr<Trie> > childs; -> use of deleted function
+ private:
+ const Trie* parent_;
+
+ public:
+ Trie() : parent_(0) { }
+
+ Trie(Vertex_handle v_) : v(v_), parent_(0) { }
+
+ Trie(Vertex_handle v_, Trie* parent) : v(v_), parent_(parent) { }
+
+ bool operator==(const Trie& other) const {
+ return (v == other.v);
+ }
+
+ void add_child(Trie* child) {
+ if (child) {
+ std::shared_ptr<Trie> ptr_to_add(child);
+ childs.push_back(ptr_to_add);
+ child->parent_ = this;
+ }
+ }
+
+ typedef typename Simplex::Simplex_vertex_const_iterator Simplex_vertex_const_iterator;
+
+ Trie* make_trie(Simplex_vertex_const_iterator s_it, Simplex_vertex_const_iterator s_end) {
+ if (s_it == s_end) {
+ return 0;
+ } else {
+ Trie* res = new Trie(*s_it);
+ Trie* child = make_trie(++s_it, s_end);
+ res->add_child(child);
+ return res;
+ }
+ }
+
+ private:
+ // go down recursively in the tree while advancing the simplex iterator.
+ // when it reaches a leaf, it inserts the remaining that is not present
+ void add_simplex_helper(Simplex_vertex_const_iterator s_it, Simplex_vertex_const_iterator s_end) {
+ assert(*s_it == v);
+ ++s_it;
+ if (s_it == s_end) return;
+ if (!is_leaf()) {
+ for (auto child : childs) {
+ if (child->v == *s_it)
+ return child->add_simplex_helper(s_it, s_end);
+ }
+ // s_it is not found and needs to be inserted
+ }
+ // not leaf -> remaining of s needs to be inserted
+ Trie * son_with_what_remains_of_s(make_trie(s_it, s_end));
+ add_child(son_with_what_remains_of_s);
+ return;
+ }
+
+ void maximal_faces_helper(std::vector<Simplex>& res) const {
+ if (is_leaf()) res.push_back(simplex());
+ else
+ for (auto child : childs)
+ child->maximal_faces_helper(res);
+ }
+
+ public:
+ /**
+ * adds the simplex to the trie
+ */
+ void add_simplex(const Simplex& s) {
+ if (s.empty()) return;
+ assert(v == s.first_vertex());
+ add_simplex_helper(s.begin(), s.end());
+ }
+
+ std::vector<Simplex> maximal_faces() const {
+ std::vector<Simplex> res;
+ maximal_faces_helper(res);
+ return res;
+ }
+
+ /**
+ * Goes to the root in the trie to consitute simplex
+ */
+ void add_vertices_up_to_the_root(Simplex& res) const {
+ res.add_vertex(v);
+ if (parent_)
+ parent_->add_vertices_up_to_the_root(res);
+ }
+
+ Simplex simplex() const {
+ Simplex res;
+ add_vertices_up_to_the_root(res);
+ return res;
+ }
+
+ bool is_leaf() const {
+ return childs.empty();
+ }
+
+ bool is_root() const {
+ return parent_ == 0;
+ }
+
+ const Trie* parent() {
+ return parent_;
+ }
+
+ void remove_leaf() {
+ assert(is_leaf);
+ if (!is_root())
+ parent_->childs.erase(this);
+ }
+
+ /**
+ * true iff the simplex corresponds to one node in the trie
+ */
+ bool contains(const Simplex& s) const {
+ Trie const* current = this;
+ if (s.empty()) return true;
+ if (current->v != s.first_vertex()) return false;
+ auto s_pos = s.begin();
+ ++s_pos;
+ while (s_pos != s.end() && current != 0) {
+ bool found = false;
+ for (const auto child : current->childs) {
+ if (child->v == *s_pos) {
+ ++s_pos;
+ current = child.get();
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return current != 0;
+ }
+
+ Trie* go_bottom_left() {
+ if (is_leaf())
+ return this;
+ else
+ return (*childs.begin())->go_bottom_left();
+ }
+
+ friend std::ostream& operator<<(std::ostream& stream, const Trie& trie) {
+ stream << "T( " << trie.v << " ";
+ for (auto t : trie.childs)
+ stream << *t;
+ stream << ")";
+ return stream;
+ }
};
-
template<typename SimplexHandle>
-struct Tries{
- typedef typename SimplexHandle::Vertex_handle Vertex_handle;
- typedef SimplexHandle Simplex_handle;
-
- typedef Trie<Simplex_handle> STrie;
-
-
- template<typename SimpleHandleOutputIterator>
- Tries(unsigned num_vertices,SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end):
- cofaces_(num_vertices,0){
- for (auto i = 0u; i < num_vertices; ++i)
- cofaces_[i] = new STrie(Vertex_handle(i));
- for (auto s_it = simplex_begin; s_it != simplex_end; ++s_it) {
- if (s_it->dimension() >= 1)
- cofaces_[s_it->first_vertex()]->add_simplex(*s_it);
- }
- }
-
- ~Tries(){
- for(STrie* t : cofaces_)
- delete t;
- }
-
- //return a simplex that consists in all u such uv is an edge and u>v
- Simplex_handle positive_neighbors(Vertex_handle v) const{
- Simplex_handle res;
- for(auto child : cofaces_[v]->childs)
- res.add_vertex(child->v);
- return res;
- }
-
- bool contains(const Simplex_handle& s) const{
- auto first_v = s.first_vertex();
- return cofaces_[first_v]->contains(s);
- }
-
- friend std::ostream& operator<<(std::ostream& stream, const Tries& tries){
- for(auto trie : tries.cofaces_)
- stream<<*trie<<std::endl;
- return stream;
- }
-
- //init_next_dimension must be called first
- std::vector<Simplex_handle> next_dimension_simplices() const{
- std::vector<Simplex_handle> res;
- while(!to_see_.empty() && to_see_.front()->simplex().dimension()==current_dimension_){
- res.emplace_back(to_see_.front()->simplex());
- for(auto child : to_see_.front()->childs)
- to_see_.push_back(child.get());
- to_see_.pop_front();
- }
- ++current_dimension_;
- return res;
- }
-
- void init_next_dimension() const{
- for(auto trie : cofaces_)
- to_see_.push_back(trie);
- }
-
-private:
- mutable std::deque<STrie*> to_see_;
- mutable unsigned current_dimension_=0;
-
-
- std::vector<STrie*> cofaces_;
-
+struct Tries {
+ typedef typename SimplexHandle::Vertex_handle Vertex_handle;
+ typedef SimplexHandle Simplex;
+
+ typedef Trie<Simplex> STrie;
+
+ template<typename SimpleHandleOutputIterator>
+ Tries(unsigned num_vertices, SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) :
+ cofaces_(num_vertices, 0) {
+ for (auto i = 0u; i < num_vertices; ++i)
+ cofaces_[i] = new STrie(Vertex_handle(i));
+ for (auto s_it = simplex_begin; s_it != simplex_end; ++s_it) {
+ if (s_it->dimension() >= 1)
+ cofaces_[s_it->first_vertex()]->add_simplex(*s_it);
+ }
+ }
+
+ ~Tries() {
+ for (STrie* t : cofaces_)
+ delete t;
+ }
+
+ // return a simplex that consists in all u such uv is an edge and u>v
+
+ Simplex positive_neighbors(Vertex_handle v) const {
+ Simplex res;
+ for (auto child : cofaces_[v]->childs)
+ res.add_vertex(child->v);
+ return res;
+ }
+
+ bool contains(const Simplex& s) const {
+ auto first_v = s.first_vertex();
+ return cofaces_[first_v]->contains(s);
+ }
+
+ friend std::ostream& operator<<(std::ostream& stream, const Tries& tries) {
+ for (auto trie : tries.cofaces_)
+ stream << *trie << std::endl;
+ return stream;
+ }
+
+ // init_next_dimension must be called first
+
+ std::vector<Simplex> next_dimension_simplices() const {
+ std::vector<Simplex> res;
+ while (!to_see_.empty() && to_see_.front()->simplex().dimension() == current_dimension_) {
+ res.emplace_back(to_see_.front()->simplex());
+ for (auto child : to_see_.front()->childs)
+ to_see_.push_back(child.get());
+ to_see_.pop_front();
+ }
+ ++current_dimension_;
+ return res;
+ }
+
+ void init_next_dimension() const {
+ for (auto trie : cofaces_)
+ to_see_.push_back(trie);
+ }
+
+ private:
+ mutable std::deque<STrie*> to_see_;
+ mutable unsigned current_dimension_ = 0;
+ std::vector<STrie*> cofaces_;
};
+} // namespace skbl
+} // namespace Gudhi
-}
-
-}
-
-#endif /* TRIE_H_ */
+#endif // SKELETON_BLOCKER_INTERNAL_TRIE_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h
index f6f2c955..4a437ac6 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h
@@ -1,134 +1,131 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_SKELETON_BLOCKERS_BLOCKERS_ITERATORS_H_
-#define GUDHI_SKELETON_BLOCKERS_BLOCKERS_ITERATORS_H_
-
-#include "boost/iterator/iterator_facade.hpp"
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_BLOCKERS_ITERATORS_H_
+#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_BLOCKERS_ITERATORS_H_
+
+#include <boost/iterator/iterator_facade.hpp>
+
+namespace Gudhi {
namespace skbl {
/**
* @brief Iterator through the blockers of a vertex.
- */
-// ReturnType = const Simplex_handle* or Simplex_handle*
+ */
+// ReturnType = const Simplex* or Simplex*
// MapIteratorType = BlockerMapConstIterator or BlockerMapIterator
+
template<typename MapIteratorType, typename ReturnType>
class Blocker_iterator_internal : public boost::iterator_facade<
- Blocker_iterator_internal<MapIteratorType,ReturnType>,
- ReturnType,
- boost::forward_traversal_tag,
- ReturnType
- >{
-private:
- MapIteratorType current_position;
- MapIteratorType end_of_map;
-public:
-
- Blocker_iterator_internal():current_position(){}
-
- Blocker_iterator_internal(MapIteratorType position,MapIteratorType end_of_map_ ):
- current_position(position), end_of_map(end_of_map_)
- { }
-
- bool equal(const Blocker_iterator_internal& other) const{
- return current_position == other.current_position;
- }
-
- void increment(){
- goto_next_blocker();
- }
-
- ReturnType dereference() const {
- return(current_position->second);
- }
-
-private:
- /**
- * Let the current pair be (v,sigma) where v is a vertex and sigma is a blocker.
- * If v is not the first vertex of sigma then we already have seen sigma as a blocker
- * and we look for the next one.
- */
- void goto_next_blocker(){
- do {
- ++current_position;
- } while (!(current_position == end_of_map) && !first_time_blocker_is_seen());
- }
-
- bool first_time_blocker_is_seen() const{
- return current_position->first == current_position->second->first_vertex();
- }
+Blocker_iterator_internal<MapIteratorType, ReturnType>,
+ReturnType,
+boost::forward_traversal_tag,
+ReturnType
+> {
+ private:
+ MapIteratorType current_position;
+ MapIteratorType end_of_map;
+
+ public:
+ Blocker_iterator_internal() : current_position() { }
+
+ Blocker_iterator_internal(MapIteratorType position, MapIteratorType end_of_map_) :
+ current_position(position), end_of_map(end_of_map_) { }
+
+ bool equal(const Blocker_iterator_internal& other) const {
+ return current_position == other.current_position;
+ }
+
+ void increment() {
+ goto_next_blocker();
+ }
+
+ ReturnType dereference() const {
+ return (current_position->second);
+ }
+
+ private:
+ /**
+ * Let the current pair be (v,sigma) where v is a vertex and sigma is a blocker.
+ * If v is not the first vertex of sigma then we already have seen sigma as a blocker
+ * and we look for the next one.
+ */
+ void goto_next_blocker() {
+ do {
+ ++current_position;
+ } while (!(current_position == end_of_map) && !first_time_blocker_is_seen());
+ }
+
+ bool first_time_blocker_is_seen() const {
+ return current_position->first == current_position->second->first_vertex();
+ }
};
-
-
/**
* @brief Iterator through the blockers of a vertex
*/
-// ReturnType = const Simplex_handle* or Simplex_handle*
+// ReturnType = const Simplex* or Simplex*
// MapIteratorType = BlockerMapConstIterator or BlockerMapIterator
+
template<typename MapIteratorType, typename ReturnType>
class Blocker_iterator_around_vertex_internal : public boost::iterator_facade<
- Blocker_iterator_around_vertex_internal<MapIteratorType,ReturnType>,
- ReturnType,
- boost::forward_traversal_tag,
- ReturnType
->{
-private:
- MapIteratorType current_position_;
-public:
-
- Blocker_iterator_around_vertex_internal():current_position_(){}
-
- Blocker_iterator_around_vertex_internal(MapIteratorType position):
- current_position_(position)
- {}
-
- Blocker_iterator_around_vertex_internal& operator=(Blocker_iterator_around_vertex_internal other){
- this->current_position_ = other.current_position_;
- return *this;
- }
-
- bool equal(const Blocker_iterator_around_vertex_internal& other) const{
- return current_position_ == other.current_position_;
- }
-
- void increment(){
- current_position_++;
- }
-
- ReturnType dereference() const{
- return(current_position_->second);
- }
-
-
- MapIteratorType current_position(){
- return this->current_position_;
- }
+Blocker_iterator_around_vertex_internal<MapIteratorType, ReturnType>,
+ReturnType,
+boost::forward_traversal_tag,
+ReturnType
+> {
+ private:
+ MapIteratorType current_position_;
+
+ public:
+ Blocker_iterator_around_vertex_internal() : current_position_() { }
+
+ Blocker_iterator_around_vertex_internal(MapIteratorType position) :
+ current_position_(position) { }
+
+ Blocker_iterator_around_vertex_internal& operator=(Blocker_iterator_around_vertex_internal other) {
+ this->current_position_ = other.current_position_;
+ return *this;
+ }
+
+ bool equal(const Blocker_iterator_around_vertex_internal& other) const {
+ return current_position_ == other.current_position_;
+ }
+
+ void increment() {
+ current_position_++;
+ }
+
+ ReturnType dereference() const {
+ return (current_position_->second);
+ }
+
+ MapIteratorType current_position() {
+ return this->current_position_;
+ }
};
-}
+} // namespace skbl
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_SKELETON_BLOCKERS_BLOCKERS_ITERATORS_H_ */
+#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_BLOCKERS_ITERATORS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_edges_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_edges_iterators.h
index 0be6c74d..ef4c7970 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_edges_iterators.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_edges_iterators.h
@@ -1,167 +1,144 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_SKELETON_BLOCKERS_ITERATORS_EDGES_H_
-#define GUDHI_SKELETON_BLOCKERS_ITERATORS_EDGES_H_
-
-#include "boost/iterator/iterator_facade.hpp"
-
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_EDGES_ITERATORS_H_
+#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_EDGES_ITERATORS_H_
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/graph/adjacency_list.hpp>
+
+#include <utility> // for pair<>
+
+namespace Gudhi {
namespace skbl {
template<typename SkeletonBlockerComplex>
-class Edge_around_vertex_iterator :
- public boost::iterator_facade < Edge_around_vertex_iterator<SkeletonBlockerComplex>
- , typename SkeletonBlockerComplex::Edge_handle const
- , boost::forward_traversal_tag
- , typename SkeletonBlockerComplex::Edge_handle const
- >
-{
- friend class boost::iterator_core_access;
-
- typedef SkeletonBlockerComplex Complex;
- typedef typename Complex::boost_adjacency_iterator boost_adjacency_iterator;
- typedef typename Complex::Vertex_handle Vertex_handle;
- typedef typename Complex::Edge_handle Edge_handle;
-
-private:
-
- const Complex* complex;
- Vertex_handle v;
-
- boost_adjacency_iterator current_;
- boost_adjacency_iterator end_;
-
-public:
-
- Edge_around_vertex_iterator():complex(NULL){
- }
-
- Edge_around_vertex_iterator(const Complex* complex_,Vertex_handle v_):
- complex(complex_),
- v(v_)
- {
- tie(current_,end_) = adjacent_vertices(v.vertex, complex->skeleton);
- }
-
- /**
- * returns an iterator to the end
- */
- Edge_around_vertex_iterator(const Complex* complex_,Vertex_handle v_,int end):
- complex(complex_),
- v(v_)
- {
- tie(current_,end_) = adjacent_vertices(v.vertex, complex->skeleton);
- set_end();
- }
-
- bool equal(const Edge_around_vertex_iterator& other) const{
- return (complex== other.complex) && (v == other.v) && (current_ == other.current_) && (end_ == other.end_);
- }
-
- void increment(){
- if(current_ != end_)
- ++current_;
- }
-
- Edge_handle dereference() const{
- return *(*complex)[std::make_pair(v,static_cast<Vertex_handle>(*current_))];
- }
-
-private:
- //remove this ugly hack
- void set_end(){
- current_ = end_;
- }
+class Edge_around_vertex_iterator : public boost::iterator_facade <Edge_around_vertex_iterator<SkeletonBlockerComplex>
+, typename SkeletonBlockerComplex::Edge_handle const, boost::forward_traversal_tag
+, typename SkeletonBlockerComplex::Edge_handle const> {
+ friend class boost::iterator_core_access;
+
+ typedef SkeletonBlockerComplex Complex;
+ typedef typename Complex::boost_adjacency_iterator boost_adjacency_iterator;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+ typedef typename Complex::Edge_handle Edge_handle;
+
+ private:
+ const Complex* complex;
+ Vertex_handle v;
+
+ boost_adjacency_iterator current_;
+ boost_adjacency_iterator end_;
+
+ public:
+ Edge_around_vertex_iterator() : complex(NULL) { }
+
+ Edge_around_vertex_iterator(const Complex* complex_, Vertex_handle v_) :
+ complex(complex_),
+ v(v_) {
+ tie(current_, end_) = adjacent_vertices(v.vertex, complex->skeleton);
+ }
+
+ /**
+ * returns an iterator to the end
+ */
+ Edge_around_vertex_iterator(const Complex* complex_, Vertex_handle v_, int end) :
+ complex(complex_),
+ v(v_) {
+ tie(current_, end_) = adjacent_vertices(v.vertex, complex->skeleton);
+ set_end();
+ }
+
+ bool equal(const Edge_around_vertex_iterator& other) const {
+ return (complex == other.complex) && (v == other.v) && (current_ == other.current_) && (end_ == other.end_);
+ }
+
+ void increment() {
+ if (current_ != end_)
+ ++current_;
+ }
+
+ Edge_handle dereference() const {
+ return *(*complex)[std::make_pair(v, static_cast<Vertex_handle> (*current_))];
+ }
+
+ private:
+ // remove this ugly hack
+ void set_end() {
+ current_ = end_;
+ }
};
-
-
/**
*@brief Iterator on the edges of a simplicial complex.
*
*/
template<typename SkeletonBlockerComplex>
-class Edge_iterator :
-public boost::iterator_facade < Edge_iterator<SkeletonBlockerComplex>
+class Edge_iterator : public boost::iterator_facade <Edge_iterator<SkeletonBlockerComplex>
, typename SkeletonBlockerComplex::Edge_handle const
, boost::forward_traversal_tag
-, typename SkeletonBlockerComplex::Edge_handle const
->
-
-{
- friend class boost::iterator_core_access;
-public:
- typedef SkeletonBlockerComplex Complex;
- typedef typename Complex::boost_edge_iterator boost_edge_iterator;
- typedef typename Complex::Edge_handle Edge_handle;
-
-
- const Complex* complex;
- std::pair<boost_edge_iterator,boost_edge_iterator> edge_iterator ;
-
- Edge_iterator():complex(NULL){
- }
-
- Edge_iterator(const SkeletonBlockerComplex* complex_):
- complex(complex_),
- edge_iterator(boost::edges(complex_->skeleton))
- {
- }
-
- /**
- * return an iterator to the end
- */
- Edge_iterator(const SkeletonBlockerComplex* complex_,int end):
- complex(complex_),
- edge_iterator(boost::edges(complex_->skeleton))
- {
- edge_iterator.first = edge_iterator.second;
- }
-
-
- bool equal(const Edge_iterator& other) const{
- return (complex == other.complex) && (edge_iterator == other.edge_iterator);
- }
-
- void increment(){
- if(edge_iterator.first != edge_iterator.second){
- ++(edge_iterator.first);
- }
- }
-
- Edge_handle dereference() const{
- return(*(edge_iterator.first));
- }
+, typename SkeletonBlockerComplex::Edge_handle const> {
+ friend class boost::iterator_core_access;
+
+ public:
+ typedef SkeletonBlockerComplex Complex;
+ typedef typename Complex::boost_edge_iterator boost_edge_iterator;
+ typedef typename Complex::Edge_handle Edge_handle;
+
+ const Complex* complex;
+ std::pair<boost_edge_iterator, boost_edge_iterator> edge_iterator;
+
+ Edge_iterator() : complex(NULL) { }
+
+ Edge_iterator(const SkeletonBlockerComplex* complex_) :
+ complex(complex_),
+ edge_iterator(boost::edges(complex_->skeleton)) { }
+
+ /**
+ * return an iterator to the end
+ */
+ Edge_iterator(const SkeletonBlockerComplex* complex_, int end) :
+ complex(complex_),
+ edge_iterator(boost::edges(complex_->skeleton)) {
+ edge_iterator.first = edge_iterator.second;
+ }
+
+ bool equal(const Edge_iterator& other) const {
+ return (complex == other.complex) && (edge_iterator == other.edge_iterator);
+ }
+
+ void increment() {
+ if (edge_iterator.first != edge_iterator.second) {
+ ++(edge_iterator.first);
+ }
+ }
+
+ Edge_handle dereference() const {
+ return (*(edge_iterator.first));
+ }
};
+} // namespace skbl
+} // namespace Gudhi
-}
-
-} // namespace GUDHI
-
-
-#endif /* GUDHI_SKELETON_BLOCKERS_ITERATORS_EDGES_H_ */
-
-
+#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_EDGES_ITERATORS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h
index 20a94734..cc3ed276 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h
@@ -19,17 +19,14 @@
* 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 GUDHI_SKELETON_BLOCKERS_ITERATORS_H_
-#define GUDHI_SKELETON_BLOCKERS_ITERATORS_H_
+#ifndef SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_ITERATORS_H_
+#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_ITERATORS_H_
-#include "Skeleton_blockers_vertices_iterators.h"
-#include "Skeleton_blockers_edges_iterators.h"
-#include "Skeleton_blockers_blockers_iterators.h"
-#include "Skeleton_blockers_triangles_iterators.h"
-#include "Skeleton_blockers_simplices_iterators.h"
+#include <gudhi/Skeleton_blocker/iterators/Skeleton_blockers_vertices_iterators.h>
+#include <gudhi/Skeleton_blocker/iterators/Skeleton_blockers_edges_iterators.h>
+#include <gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h>
+#include <gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h>
+#include <gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h>
-
-
-
-#endif /* GUDHI_SKELETON_BLOCKERS_ITERATORS_H_ */
+#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_ITERATORS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h
index 666ce430..ce565166 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h
@@ -1,46 +1,42 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_KELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
-#define GUDHI_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
+#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
+
+#include <gudhi/Skeleton_blocker_link_complex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h>
+#include <gudhi/Skeleton_blocker/internal/Trie.h>
+#include <gudhi/Utils.h>
+
+#include <boost/iterator/iterator_facade.hpp>
#include <memory>
#include <list>
#include <iostream>
-#include "gudhi/Utils.h"
-#include "boost/iterator/iterator_facade.hpp"
-
-
-#include "gudhi/Skeleton_blocker_link_complex.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h"
-
-#include "gudhi/Skeleton_blocker/internal/Trie.h"
-
namespace Gudhi {
-
namespace skbl {
-
/**
* Link may be Skeleton_blocker_link_complex<SkeletonBlockerComplex> to iterate over all
* simplices around a vertex OR
@@ -49,299 +45,354 @@ namespace skbl {
* The iteration is done by computing a trie with the link and doing a breadth-first traversal
* of the trie.
*/
-template<typename SkeletonBlockerComplex,typename Link>
+template<typename SkeletonBlockerComplex, typename Link>
class Simplex_around_vertex_iterator :
- public boost::iterator_facade < Simplex_around_vertex_iterator<SkeletonBlockerComplex,Link>
-, typename SkeletonBlockerComplex::Simplex_handle
+public boost::iterator_facade < Simplex_around_vertex_iterator<SkeletonBlockerComplex, Link>
+, typename SkeletonBlockerComplex::Simplex
, boost::forward_traversal_tag
-, typename SkeletonBlockerComplex::Simplex_handle
->
-{
- friend class boost::iterator_core_access;
- typedef SkeletonBlockerComplex Complex;
- typedef typename Complex::Vertex_handle Vertex_handle;
- typedef typename Complex::Edge_handle Edge_handle;
- typedef typename Complex::Simplex_handle Simplex_handle;
-
-
- typedef typename Link::Vertex_handle Link_vertex_handle;
- // Link_vertex_handle == Complex_Vertex_handle but this renaming helps avoiding confusion
-
- typedef typename Gudhi::skbl::Trie<Simplex_handle> Trie;
-
-
-private:
- const Complex* complex;
- Vertex_handle v;
- std::shared_ptr<Link> link_v;
- std::shared_ptr<Trie> trie;
- std::list<Trie*> nodes_to_be_seen; // todo deque
-
-public:
- Simplex_around_vertex_iterator():complex(0){
- }
-
- Simplex_around_vertex_iterator(const Complex* complex_,Vertex_handle v_):
- complex(complex_),
- v(v_),
- link_v(new Link(*complex_,v_)),
- trie(new Trie(v_)){
- compute_trie_and_nodes_to_be_seen();
- }
-
- // todo avoid useless copy
- // todo currently just work if copy begin iterator
- Simplex_around_vertex_iterator(const Simplex_around_vertex_iterator& other):
- complex(other.complex),
- v(other.v),
- link_v(other.link_v),
- trie(other.trie),
- nodes_to_be_seen(other.nodes_to_be_seen){
- if(!other.is_end()){
- }
- }
-
- /**
- * returns an iterator to the end
- */
- Simplex_around_vertex_iterator(const Complex* complex_,Vertex_handle v_,bool end):
- complex(complex_),
- v(v_){
- set_end();
- }
-
-private:
-
-
- void compute_trie_and_nodes_to_be_seen(){
- // once we go through every simplices passing through v0
- // we remove v0. That way, it prevents from passing a lot of times
- // though edges leaving v0.
- // another solution would have been to provides an adjacency iterator
- // to superior vertices that avoids lower ones.
- while(!link_v->empty()){
- auto v0 = *(link_v->vertex_range().begin());
- trie->add_child(build_trie(v0,trie.get()));
- link_v->remove_vertex(v0);
- }
- nodes_to_be_seen.push_back(trie.get());
- }
-
- Trie* build_trie(Link_vertex_handle link_vh,Trie* parent){
- Trie* res = new Trie(parent_vertex(link_vh),parent);
- for(Link_vertex_handle nv : link_v->vertex_range(link_vh)) {
- if(link_vh < nv){
- Simplex_handle simplex_node_plus_nv(res->simplex());
- simplex_node_plus_nv.add_vertex(parent_vertex(nv));
- if(complex->contains(simplex_node_plus_nv)){
- res->add_child(build_trie(nv,res));
- }
- }
- }
- return res;
- }
-
- bool is_node_in_complex(Trie* trie){
- return true;
- }
-
- Vertex_handle parent_vertex(Link_vertex_handle link_vh) const{
- return complex->convert_handle_from_another_complex(*link_v,link_vh);
- }
-
-
-
-public:
-
- friend std::ostream& operator<<(std::ostream& stream, const Simplex_around_vertex_iterator& savi){
- stream<< savi.trie<< std::endl; ;
- stream << "("<<savi.nodes_to_be_seen.size()<<") nodes to see\n";
- return stream;
- }
-
- bool equal(const Simplex_around_vertex_iterator& other) const{
- bool same_complex = (complex == other.complex);
- if(!same_complex)
- return false;
-
- if(!(v == other.v))
- return false;
-
- bool both_empty = nodes_to_be_seen.empty() && other.nodes_to_be_seen.empty();
- if(both_empty)
- return true;
-
- bool both_non_empty = !nodes_to_be_seen.empty() && !other.nodes_to_be_seen.empty();
-
- if(!both_non_empty) return false; //one is empty the other is not
-
- bool same_node = (**(nodes_to_be_seen.begin()) == **(other.nodes_to_be_seen.begin()));
- return same_node;
- }
-
- void increment(){
- assert(!is_end());
- Trie* first_node = nodes_to_be_seen.front();
-
- nodes_to_be_seen.pop_front();
-
- for(auto childs : first_node->childs){
- nodes_to_be_seen.push_back(childs.get());
- }
-
- }
-
- Simplex_handle dereference() const{
- assert(!nodes_to_be_seen.empty());
- Trie* first_node = nodes_to_be_seen.front();
- return first_node->simplex();
- }
-
-//private:
- Simplex_handle get_trie_address() const{
- assert(!nodes_to_be_seen.empty());
- return nodes_to_be_seen.front();
- }
-
-private:
- void set_end(){
- nodes_to_be_seen.clear();
- }
-
- bool is_end() const{
- return nodes_to_be_seen.empty();
- }
+, typename SkeletonBlockerComplex::Simplex
+> {
+ friend class boost::iterator_core_access;
+ typedef SkeletonBlockerComplex Complex;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+ typedef typename Complex::Edge_handle Edge_handle;
+ typedef typename Complex::Simplex Simplex;
+
+ // Link_vertex_handle == Complex_Vertex_handle but this renaming helps avoiding confusion
+ typedef typename Link::Vertex_handle Link_vertex_handle;
+
+ typedef typename Gudhi::skbl::Trie<Simplex> Trie;
+
+ private:
+ const Complex* complex;
+ Vertex_handle v;
+ std::shared_ptr<Link> link_v;
+ std::shared_ptr<Trie> trie;
+ std::list<Trie*> nodes_to_be_seen; // todo deque
+
+ public:
+ Simplex_around_vertex_iterator() : complex(0) {}
+
+ Simplex_around_vertex_iterator(const Complex* complex_, Vertex_handle v_) :
+ complex(complex_),
+ v(v_),
+ link_v(new Link(*complex_, v_)),
+ trie(new Trie(v_)) {
+ compute_trie_and_nodes_to_be_seen();
+ }
+
+ // todo avoid useless copy
+ // todo currently just work if copy begin iterator
+ Simplex_around_vertex_iterator(const Simplex_around_vertex_iterator& other) :
+ complex(other.complex),
+ v(other.v),
+ link_v(other.link_v),
+ trie(other.trie),
+ nodes_to_be_seen(other.nodes_to_be_seen) {
+ if (!other.is_end()) {}
+ }
+
+ /**
+ * returns an iterator to the end
+ */
+ Simplex_around_vertex_iterator(const Complex* complex_, Vertex_handle v_, bool end) :
+ complex(complex_),
+ v(v_) {
+ set_end();
+ }
+
+ private:
+ void compute_trie_and_nodes_to_be_seen() {
+ // once we go through every simplices passing through v0
+ // we remove v0. That way, it prevents from passing a lot of times
+ // though edges leaving v0.
+ // another solution would have been to provides an adjacency iterator
+ // to superior vertices that avoids lower ones.
+ while (!link_v->empty()) {
+ auto v0 = *(link_v->vertex_range().begin());
+ trie->add_child(build_trie(v0, trie.get()));
+ link_v->remove_vertex(v0);
+ }
+ nodes_to_be_seen.push_back(trie.get());
+ }
+
+ Trie* build_trie(Link_vertex_handle link_vh, Trie* parent) {
+ Trie* res = new Trie(parent_vertex(link_vh), parent);
+ for (Link_vertex_handle nv : link_v->vertex_range(link_vh)) {
+ if (link_vh < nv) {
+ Simplex simplex_node_plus_nv(res->simplex());
+ simplex_node_plus_nv.add_vertex(parent_vertex(nv));
+ if (complex->contains(simplex_node_plus_nv)) {
+ res->add_child(build_trie(nv, res));
+ }
+ }
+ }
+ return res;
+ }
+
+ bool is_node_in_complex(Trie* trie) {
+ return true;
+ }
+
+ Vertex_handle parent_vertex(Link_vertex_handle link_vh) const {
+ return complex->convert_handle_from_another_complex(*link_v, link_vh);
+ }
+
+ public:
+ friend std::ostream& operator<<(std::ostream& stream, const Simplex_around_vertex_iterator& savi) {
+ stream << savi.trie << std::endl;
+ stream << "(" << savi.nodes_to_be_seen.size() << ") nodes to see\n";
+ return stream;
+ }
+
+ bool equal(const Simplex_around_vertex_iterator& other) const {
+ bool same_complex = (complex == other.complex);
+ if (!same_complex)
+ return false;
+
+ if (!(v == other.v))
+ return false;
+
+ bool both_empty = nodes_to_be_seen.empty() && other.nodes_to_be_seen.empty();
+ if (both_empty)
+ return true;
+
+ bool both_non_empty = !nodes_to_be_seen.empty() && !other.nodes_to_be_seen.empty();
+
+ if (!both_non_empty) return false; // one is empty the other is not
+
+ bool same_node = (**(nodes_to_be_seen.begin()) == **(other.nodes_to_be_seen.begin()));
+ return same_node;
+ }
+
+ void increment() {
+ assert(!is_end());
+ Trie* first_node = nodes_to_be_seen.front();
+
+ nodes_to_be_seen.pop_front();
+
+ for (auto childs : first_node->childs) {
+ nodes_to_be_seen.push_back(childs.get());
+ }
+ }
+
+ Simplex dereference() const {
+ assert(!nodes_to_be_seen.empty());
+ Trie* first_node = nodes_to_be_seen.front();
+ return first_node->simplex();
+ }
+
+ Simplex get_trie_address() const {
+ assert(!nodes_to_be_seen.empty());
+ return nodes_to_be_seen.front();
+ }
+
+ private:
+ void set_end() {
+ nodes_to_be_seen.clear();
+ }
+
+ bool is_end() const {
+ return nodes_to_be_seen.empty();
+ }
};
-
-
template<typename SkeletonBlockerComplex>
class Simplex_iterator :
- public boost::iterator_facade < Simplex_iterator<SkeletonBlockerComplex>
-, typename SkeletonBlockerComplex::Simplex_handle
+public boost::iterator_facade < Simplex_iterator<SkeletonBlockerComplex>
+, typename SkeletonBlockerComplex::Simplex
, boost::forward_traversal_tag
-, typename SkeletonBlockerComplex::Simplex_handle
->
-{
- typedef Skeleton_blocker_link_superior<SkeletonBlockerComplex> Link;
-
- friend class boost::iterator_core_access;
-
- template<class SkBlDS> friend class Skeleton_blocker_complex;
-
-
- typedef SkeletonBlockerComplex Complex;
- typedef typename Complex::Vertex_handle Vertex_handle;
- typedef typename Complex::Edge_handle Edge_handle;
- typedef typename Complex::Simplex_handle Simplex_handle;
-
- typedef typename Complex::Complex_vertex_iterator Complex_vertex_iterator;
-
-
- typedef typename Link::Vertex_handle Link_vertex_handle;
-
-private:
-
- const Complex* complex_;
- Complex_vertex_iterator current_vertex_;
-
- typedef Simplex_around_vertex_iterator<SkeletonBlockerComplex,Link> SAVI;
- SAVI current_simplex_around_current_vertex_;
- SAVI simplices_around_current_vertex_end_;
-
-
-public:
- Simplex_iterator():complex_(0){}
-
- // should not be called if the complex is empty
- Simplex_iterator(const Complex* complex):
- complex_(complex),
- current_vertex_(complex->vertex_range().begin()),
- current_simplex_around_current_vertex_(complex,*current_vertex_),
- simplices_around_current_vertex_end_(complex,*current_vertex_,true)
- {
- assert(!complex->empty());
- }
+, typename SkeletonBlockerComplex::Simplex
+> {
+ typedef Skeleton_blocker_link_superior<SkeletonBlockerComplex> Link;
+
+ friend class boost::iterator_core_access;
+
+ template<class SkBlDS> friend class Skeleton_blocker_complex;
+
+ typedef SkeletonBlockerComplex Complex;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+ typedef typename Complex::Edge_handle Edge_handle;
+ typedef typename Complex::Simplex Simplex;
+ typedef typename Complex::Complex_vertex_iterator Complex_vertex_iterator;
+ typedef typename Link::Vertex_handle Link_vertex_handle;
+
+ private:
+ const Complex* complex_;
+ Complex_vertex_iterator current_vertex_;
+
+ typedef Simplex_around_vertex_iterator<SkeletonBlockerComplex, Link> SAVI;
+ SAVI current_simplex_around_current_vertex_;
+ SAVI simplices_around_current_vertex_end_;
+
+ public:
+ Simplex_iterator() : complex_(0) { }
+
+ Simplex_iterator(const Complex* complex) :
+ complex_(complex),
+ current_vertex_(complex->vertex_range().begin()),
+ current_simplex_around_current_vertex_(complex, *current_vertex_),
+ simplices_around_current_vertex_end_(complex, *current_vertex_, true) {
+ // should not be called if the complex is empty
+ assert(!complex->empty());
+ }
+
+ private:
+ // todo return to private
+ Simplex_iterator(const Complex* complex, bool end) :
+ complex_(complex) {
+ set_end();
+ }
+
+ public:
+ Simplex_iterator(const Simplex_iterator& other)
+ :
+ complex_(other.complex_),
+ current_vertex_(other.current_vertex_),
+ current_simplex_around_current_vertex_(other.current_simplex_around_current_vertex_),
+ simplices_around_current_vertex_end_(other.simplices_around_current_vertex_end_) { }
+
+ friend Simplex_iterator make_begin_iterator(const Complex* complex) {
+ if (complex->empty())
+ return make_end_simplex_iterator(complex);
+ else
+ return Simplex_iterator(complex);
+ }
+
+ friend Simplex_iterator make_end_simplex_iterator(const Complex* complex) {
+ return Simplex_iterator(complex, true);
+ }
+
+ bool equal(const Simplex_iterator& other) const {
+ if (complex_ != other.complex_) return false;
+ if (current_vertex_ != other.current_vertex_) return false;
+ if (is_end() && other.is_end()) return true;
+ if (current_simplex_around_current_vertex_ != other.current_simplex_around_current_vertex_)
+ return false;
+ return true;
+ }
+
+ void increment() {
+ if (current_simplex_around_current_vertex_ != simplices_around_current_vertex_end_) {
+ current_simplex_around_current_vertex_.increment();
+ if (current_simplex_around_current_vertex_ == simplices_around_current_vertex_end_)
+ goto_next_vertex();
+ } else {
+ goto_next_vertex();
+ }
+ }
+
+ void goto_next_vertex() {
+ current_vertex_.increment();
+ if (!is_end()) {
+ current_simplex_around_current_vertex_ = SAVI(complex_, *current_vertex_);
+ simplices_around_current_vertex_end_ = SAVI(complex_, *current_vertex_, true);
+ }
+ }
+
+ Simplex dereference() const {
+ return current_simplex_around_current_vertex_.dereference();
+ }
+
+ private:
+ void set_end() {
+ current_vertex_ = complex_->vertex_range().end();
+ }
+
+ bool is_end() const {
+ return (current_vertex_ == complex_->vertex_range().end());
+ }
+};
-private:
- // todo return to private
- Simplex_iterator(const Complex* complex,bool end):
- complex_(complex)
- {
- set_end();
- }
+/**
+ * Iterator through the maximal faces of the coboundary of a simplex.
+ */
+template<typename SkeletonBlockerComplex, typename Link>
+class Simplex_coboundary_iterator :
+public boost::iterator_facade < Simplex_coboundary_iterator<SkeletonBlockerComplex, Link>
+, typename SkeletonBlockerComplex::Simplex, boost::forward_traversal_tag, typename SkeletonBlockerComplex::Simplex> {
+ friend class boost::iterator_core_access;
+ typedef SkeletonBlockerComplex Complex;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+ typedef typename Complex::Edge_handle Edge_handle;
+ typedef typename Complex::Simplex Simplex;
+ typedef typename Complex::Complex_vertex_iterator Complex_vertex_iterator;
+
+ // Link_vertex_handle == Complex_Vertex_handle but this renaming helps avoiding confusion
+ typedef typename Link::Vertex_handle Link_vertex_handle;
+
+ private:
+ const Complex* complex;
+ const Simplex& sigma;
+ std::shared_ptr<Link> link;
+ Complex_vertex_iterator current_vertex;
+ Complex_vertex_iterator link_vertex_end;
+
+ public:
+ Simplex_coboundary_iterator() : complex(0) {}
+
+ Simplex_coboundary_iterator(const Complex* complex_, const Simplex& sigma_) :
+ complex(complex_),
+ sigma(sigma_),
+ //need only vertices of the link hence the true flag
+ link(new Link(*complex_, sigma_, false, true)) {
+ auto link_vertex_range = link->vertex_range();
+ current_vertex = link_vertex_range.begin();
+ link_vertex_end = link_vertex_range.end();
+ }
+
+ Simplex_coboundary_iterator(const Simplex_coboundary_iterator& other) :
+ complex(other.complex),
+ sigma(other.sigma),
+ link(other.link),
+ current_vertex(other.current_vertex),
+ link_vertex_end(other.link_vertex_end) { }
+
+ // returns an iterator to the end
+ Simplex_coboundary_iterator(const Complex* complex_,const Simplex& sigma_, bool end) :
+ complex(complex_),
+ sigma(sigma_) {
+ // to represent an end iterator without having to build a useless link, we use
+ // the convection that link is not initialized.
+ }
+
+ private:
+ Vertex_handle parent_vertex(Link_vertex_handle link_vh) const {
+ return complex->convert_handle_from_another_complex(*link, link_vh);
+ }
public:
-
- Simplex_iterator(const Simplex_iterator& other)
- :
- complex_(other.complex_),
- current_vertex_(other.current_vertex_),
- current_simplex_around_current_vertex_(other.current_simplex_around_current_vertex_),
- simplices_around_current_vertex_end_(other.simplices_around_current_vertex_end_)
- {
- }
-
- friend Simplex_iterator make_begin_iterator(const Complex* complex){
- if(complex->empty())
- return make_end_simplex_iterator(complex);
- else
- return Simplex_iterator(complex);
- }
-
- friend Simplex_iterator make_end_simplex_iterator(const Complex* complex){
- return Simplex_iterator(complex,true);
- }
-
- bool equal(const Simplex_iterator& other) const{
- if(complex_!=other.complex_) return false;
- if(current_vertex_!=other.current_vertex_) return false;
- if(is_end() && other.is_end()) return true;
- if(current_simplex_around_current_vertex_ != other.current_simplex_around_current_vertex_)
- return false;
- return true;
- }
-
- void increment(){
- if(current_simplex_around_current_vertex_!= simplices_around_current_vertex_end_){
- current_simplex_around_current_vertex_.increment();
- if( current_simplex_around_current_vertex_== simplices_around_current_vertex_end_)
- goto_next_vertex();
- }
- else{
- goto_next_vertex();
- }
- }
-
- void goto_next_vertex(){
- current_vertex_.increment();
- if(!is_end()){
- current_simplex_around_current_vertex_= SAVI(complex_,*current_vertex_);
- simplices_around_current_vertex_end_ = SAVI(complex_,*current_vertex_,true);
- }
- }
-
- Simplex_handle dereference() const{
- return current_simplex_around_current_vertex_.dereference();
- }
+ friend std::ostream& operator<<(std::ostream& stream, const Simplex_coboundary_iterator& sci) {
+ return stream;
+ }
+
+ // assume that iterator points to the same complex and comes from the same simplex
+ bool equal(const Simplex_coboundary_iterator& other) const {
+ assert(complex == other.complex && sigma == other.sigma);
+ if(is_end()) return other.is_end();
+ if(other.is_end()) return is_end();
+ return *current_vertex == *(other.current_vertex);
+ }
+
+ void increment() {
+ ++current_vertex;
+ }
+
+ Simplex dereference() const {
+ Simplex res(sigma);
+ res.add_vertex(parent_vertex(*current_vertex));
+ return res;
+ }
private:
- void set_end(){
- current_vertex_ = complex_->vertex_range().end();
- }
-
- bool is_end() const{
- return (current_vertex_ == complex_->vertex_range().end());
- }
+ bool is_end() const {
+ return !link || current_vertex == link_vertex_end;
+ }
};
-}
-
-} // namespace GUDHI
-
-
-
+} // namespace skbl
+} // namespace Gudhi
-#endif /* SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_ */
+#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_SIMPLICES_ITERATORS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h
index e137d1ea..116023d7 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h
@@ -1,117 +1,108 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
-#define GUDHI_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
-
-#include "boost/iterator/iterator_facade.hpp"
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
+#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
+
+#include <boost/iterator/iterator_facade.hpp>
#include <memory>
-namespace Gudhi{
+namespace Gudhi {
namespace skbl {
-//////////////////////////////////////////////////////////////////////
/**
* \brief Iterator over the triangles that are
* adjacent to a vertex of the simplicial complex.
* \remark Will be removed soon -> dont look
*/
-template<typename Complex,typename LinkType>
+template<typename Complex, typename LinkType>
class Triangle_around_vertex_iterator : public boost::iterator_facade
-< Triangle_around_vertex_iterator <Complex,LinkType>
-, typename Complex::Simplex_handle const
+< Triangle_around_vertex_iterator <Complex, LinkType>
+, typename Complex::Simplex const
, boost::forward_traversal_tag
-, typename Complex::Simplex_handle const
->
-{
- friend class boost::iterator_core_access;
- template<typename T> friend class Triangle_iterator;
-private:
- typedef typename LinkType::Vertex_handle Vertex_handle;
- typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
- typedef typename LinkType::Simplex_handle Simplex_handle;
- typedef typename Complex::Complex_edge_iterator Complex_edge_iterator_;
-
- const Complex* complex_;
- Vertex_handle v_;
- std::shared_ptr<LinkType> link_;
- Complex_edge_iterator_ current_edge_;
- bool is_end_;
-public:
- Triangle_around_vertex_iterator(const Complex* complex,Vertex_handle v):
- complex_(complex),v_(v),link_(new LinkType(*complex,v_)),
- current_edge_(link_->edge_range().begin()),
- is_end_(current_edge_ == link_->edge_range().end()){
- }
-
- /**
- * @brief ugly hack to get an iterator to the end
- */
- Triangle_around_vertex_iterator(const Complex* complex,Vertex_handle v,bool is_end):
- complex_(complex),v_(v),link_(0),is_end_(true){
- }
-
- /**
- * @brief ugly hack to get an iterator to the end
- */
- Triangle_around_vertex_iterator():
- complex_(0),v_(-1),link_(0),is_end_(true){
- }
-
-
- Triangle_around_vertex_iterator(const Triangle_around_vertex_iterator& other){
- v_ = other.v_;
- complex_ = other.complex_;
- is_end_ = other.is_end_;
-
- if(!is_end_){
- link_ = other.link_;
- current_edge_= other.current_edge_;
- }
- }
-
- bool equal(const Triangle_around_vertex_iterator& other) const{
- return (complex_==other.complex_) && ((finished() &&other.finished()) || current_edge_ == other.current_edge_);
- }
-
- Simplex_handle dereference() const{
- Root_vertex_handle v1 = (*link_)[*current_edge_].first();
- Root_vertex_handle v2 = (*link_)[*current_edge_].second();
- return Simplex_handle(v_,*(complex_->get_address(v1)),*(complex_->get_address(v2)));
- }
-
- void increment(){
- ++current_edge_;
- }
-
-private:
- bool finished() const{
- return is_end_ || (current_edge_ == link_->edge_range().end());
- }
-
+, typename Complex::Simplex const> {
+ friend class boost::iterator_core_access;
+ template<typename T> friend class Triangle_iterator;
+ private:
+ typedef typename LinkType::Vertex_handle Vertex_handle;
+ typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
+ typedef typename LinkType::Simplex Simplex;
+ typedef typename Complex::Complex_edge_iterator Complex_edge_iterator_;
+
+ const Complex* complex_;
+ Vertex_handle v_;
+ std::shared_ptr<LinkType> link_;
+ Complex_edge_iterator_ current_edge_;
+ bool is_end_;
+
+ public:
+ Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v) :
+ complex_(complex), v_(v), link_(new LinkType(*complex, v_)),
+ current_edge_(link_->edge_range().begin()),
+ is_end_(current_edge_ == link_->edge_range().end()) { }
+
+ /**
+ * @brief ugly hack to get an iterator to the end
+ */
+ Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v, bool is_end) :
+ complex_(complex), v_(v), link_(0), is_end_(true) { }
+
+ /**
+ * @brief ugly hack to get an iterator to the end
+ */
+ Triangle_around_vertex_iterator() :
+ complex_(0), v_(-1), link_(0), is_end_(true) { }
+
+ Triangle_around_vertex_iterator(const Triangle_around_vertex_iterator& other) {
+ v_ = other.v_;
+ complex_ = other.complex_;
+ is_end_ = other.is_end_;
+
+ if (!is_end_) {
+ link_ = other.link_;
+ current_edge_ = other.current_edge_;
+ }
+ }
+
+ bool equal(const Triangle_around_vertex_iterator& other) const {
+ return (complex_ == other.complex_) && ((finished() && other.finished()) || current_edge_ == other.current_edge_);
+ }
+
+ Simplex dereference() const {
+ Root_vertex_handle v1 = (*link_)[*current_edge_].first();
+ Root_vertex_handle v2 = (*link_)[*current_edge_].second();
+ return Simplex(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2)));
+ }
+
+ void increment() {
+ ++current_edge_;
+ }
+
+ private:
+ bool finished() const {
+ return is_end_ || (current_edge_ == link_->edge_range().end());
+ }
};
-
-
/**
* \brief Iterator over the triangles of the
* simplicial complex.
@@ -119,121 +110,111 @@ private:
*
*/
template<typename SkeletonBlockerComplex>
-class Triangle_iterator :
- public boost::iterator_facade<
- Triangle_iterator <SkeletonBlockerComplex>,
- typename SkeletonBlockerComplex::Simplex_handle const
- , boost::forward_traversal_tag
- , typename SkeletonBlockerComplex::Simplex_handle const
- >
-{
- friend class boost::iterator_core_access;
-private:
- typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
- typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
- typedef typename SkeletonBlockerComplex::Simplex_handle Simplex_handle;
- typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
- typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator;
-
- const SkeletonBlockerComplex* complex_;
- Complex_vertex_iterator current_vertex_;
- STAVI current_triangle_;
- bool is_end_;
-public:
-
- /*
- * @remark assume that the complex is non-empty
- */
- Triangle_iterator(const SkeletonBlockerComplex* complex):
- complex_(complex),
- current_vertex_(complex->vertex_range().begin()),
- current_triangle_(complex,*current_vertex_), // xxx this line is problematic is the complex is empty
- is_end_(false){
-
- assert(!complex->empty());
- gotoFirstTriangle();
- }
-
-private:
- //goto to the first triangle or to the end if none
- void gotoFirstTriangle(){
- if(!is_finished() && current_triangle_.finished()){
- goto_next_vertex();
- }
- }
-public:
-
- /**
- * @brief ugly hack to get an iterator to the end
- * @remark assume that the complex is non-empty
- */
- Triangle_iterator(const SkeletonBlockerComplex* complex,bool is_end):
- complex_(complex),
- current_vertex_(complex->vertex_range().end()),
- current_triangle_(), // xxx this line is problematic is the complex is empty
- is_end_(true){
- }
-
-
- Triangle_iterator& operator=(const Triangle_iterator & other){
- complex_ = other.complex_;
- Complex_vertex_iterator current_vertex_;
- STAVI current_triangle_;
- return *this;
- }
-
-
- bool equal(const Triangle_iterator& other) const{
- bool both_are_finished = is_finished() && other.is_finished();
- bool both_arent_finished = !is_finished() && !other.is_finished();
- // if the two iterators are not finished, they must have the same state
- return (complex_==other.complex_) &&
- (both_are_finished ||
- ( (both_arent_finished) && current_vertex_ == other.current_vertex_ && current_triangle_ == other.current_triangle_));
-
- }
-
- Simplex_handle dereference() const{
- return *current_triangle_;
- }
-
-private:
-
- // goto the next vertex that has a triangle pending or the
- // end vertex iterator if none exists
- void goto_next_vertex(){
- assert(current_triangle_.finished()); //we mush have consume all triangles passing through the vertex
- assert(!is_finished()); // we must not be done
-
- ++current_vertex_;
-
- if(!is_finished()){
- current_triangle_ = STAVI(complex_, *current_vertex_);
- if(current_triangle_.finished())
- goto_next_vertex();
- }
- }
-public:
- void increment(){
- if(!current_triangle_.finished()){
- ++current_triangle_; // problem here
- if(current_triangle_.finished())
- goto_next_vertex();
- }
- else{
- assert(!is_finished());
- goto_next_vertex();
- }
- }
-
-private:
- bool is_finished() const{
- return is_end_ || current_vertex_ == complex_->vertex_range().end();
- }
+class Triangle_iterator : public boost::iterator_facade<
+Triangle_iterator <SkeletonBlockerComplex>,
+typename SkeletonBlockerComplex::Simplex const
+, boost::forward_traversal_tag
+, typename SkeletonBlockerComplex::Simplex const> {
+ friend class boost::iterator_core_access;
+ private:
+ typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
+ typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
+ typedef typename SkeletonBlockerComplex::Simplex Simplex;
+ typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
+ typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator;
+
+ const SkeletonBlockerComplex* complex_;
+ Complex_vertex_iterator current_vertex_;
+ STAVI current_triangle_;
+ bool is_end_;
+
+ public:
+ /*
+ * @remark assume that the complex is non-empty
+ */
+ Triangle_iterator(const SkeletonBlockerComplex* complex) :
+ complex_(complex),
+ current_vertex_(complex->vertex_range().begin()),
+ current_triangle_(complex, *current_vertex_), // xxx this line is problematic is the complex is empty
+ is_end_(false) {
+ assert(!complex->empty());
+ gotoFirstTriangle();
+ }
+
+ private:
+ // goto to the first triangle or to the end if none
+ void gotoFirstTriangle() {
+ if (!is_finished() && current_triangle_.finished()) {
+ goto_next_vertex();
+ }
+ }
+
+ public:
+ /**
+ * @brief ugly hack to get an iterator to the end
+ * @remark assume that the complex is non-empty
+ */
+ Triangle_iterator(const SkeletonBlockerComplex* complex, bool is_end) :
+ complex_(complex),
+ current_vertex_(complex->vertex_range().end()),
+ current_triangle_(), // xxx this line is problematic is the complex is empty
+ is_end_(true) { }
+
+ Triangle_iterator& operator=(const Triangle_iterator & other) {
+ complex_ = other.complex_;
+ Complex_vertex_iterator current_vertex_;
+ STAVI current_triangle_;
+ return *this;
+ }
+
+ bool equal(const Triangle_iterator& other) const {
+ bool both_are_finished = is_finished() && other.is_finished();
+ bool both_arent_finished = !is_finished() && !other.is_finished();
+ // if the two iterators are not finished, they must have the same state
+ return (complex_ == other.complex_) && (both_are_finished || ((both_arent_finished) &&
+ current_vertex_ == other.current_vertex_ && current_triangle_ == other.current_triangle_));
+ }
+
+ Simplex dereference() const {
+ return *current_triangle_;
+ }
+
+ private:
+ // goto the next vertex that has a triangle pending or the
+ // end vertex iterator if none exists
+ void goto_next_vertex() {
+ assert(current_triangle_.finished()); // we mush have consume all triangles passing through the vertex
+ assert(!is_finished()); // we must not be done
+
+ ++current_vertex_;
+
+ if (!is_finished()) {
+ current_triangle_ = STAVI(complex_, *current_vertex_);
+ if (current_triangle_.finished())
+ goto_next_vertex();
+ }
+ }
+
+ public:
+ void increment() {
+ if (!current_triangle_.finished()) {
+ ++current_triangle_; // problem here
+ if (current_triangle_.finished())
+ goto_next_vertex();
+ } else {
+ assert(!is_finished());
+ goto_next_vertex();
+ }
+ }
+
+ private:
+ bool is_finished() const {
+ return is_end_ || current_vertex_ == complex_->vertex_range().end();
+ }
};
-}
+} // namespace skbl
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_ */
+#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_vertices_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_vertices_iterators.h
index a9d4e373..14ae136a 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_vertices_iterators.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_vertices_iterators.h
@@ -1,31 +1,32 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_SKELETON_BLOCKERS_VERTICES_ITERATORS_H_
-#define GUDHI_SKELETON_BLOCKERS_VERTICES_ITERATORS_H_
-
-#include "boost/iterator/iterator_facade.hpp"
-
-
-namespace Gudhi{
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_VERTICES_ITERATORS_H_
+#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_VERTICES_ITERATORS_H_
+
+#include <boost/iterator/iterator_facade.hpp>
+
+#include <utility> // for pair<>
+
+namespace Gudhi {
namespace skbl {
@@ -35,148 +36,137 @@ namespace skbl {
*@remark Incrementation increases Vertex_handle.
*/
template<typename SkeletonBlockerComplex>
-class Vertex_iterator : public boost::iterator_facade
-< Vertex_iterator <SkeletonBlockerComplex>
- , typename SkeletonBlockerComplex::Vertex_handle const
- , boost::forward_traversal_tag
- , typename SkeletonBlockerComplex::Vertex_handle const
- >
-{
- friend class boost::iterator_core_access;
-
- typedef typename SkeletonBlockerComplex::boost_vertex_iterator boost_vertex_iterator;
- typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
-private:
- const SkeletonBlockerComplex* complex;
- std::pair<boost_vertex_iterator,boost_vertex_iterator> vertexIterator;
-
-
-public:
- Vertex_iterator():complex(NULL){
- }
-
- Vertex_iterator(const SkeletonBlockerComplex* complex_):
- complex(complex_),
- vertexIterator(vertices(complex_->skeleton)){
- if(!finished() && !is_active()) {
- goto_next_valid();
- }
- }
-
- /**
- * return an iterator to the end.
- */
- Vertex_iterator(const SkeletonBlockerComplex* complex_,int end):
- complex(complex_),vertexIterator(vertices(complex_->skeleton)){
- vertexIterator.first = vertexIterator.second ;
- }
-
-public:
- void increment () {goto_next_valid();}
- Vertex_handle dereference() const {
- return(Vertex_handle(*(vertexIterator.first)));
- }
-
- bool equal(const Vertex_iterator& other) const{
- return vertexIterator == other.vertexIterator && complex == other.complex;
- }
-
- bool operator<(const Vertex_iterator& other) const{
- return dereference()<other.dereference();
- }
-
-private:
- bool finished() const{
- return vertexIterator.first == vertexIterator.second;
- }
-
- void goto_next_valid(){
- ++vertexIterator.first;
- if(!finished() && !is_active()){
- goto_next_valid();
- }
- }
-
- bool is_active() const{
- return ((*complex)[Vertex_handle(*vertexIterator.first)]).is_active();
- }
-
+class Vertex_iterator : public boost::iterator_facade< Vertex_iterator <SkeletonBlockerComplex>
+, typename SkeletonBlockerComplex::Vertex_handle const
+, boost::forward_traversal_tag
+, typename SkeletonBlockerComplex::Vertex_handle const> {
+ friend class boost::iterator_core_access;
+
+ typedef typename SkeletonBlockerComplex::boost_vertex_iterator boost_vertex_iterator;
+ typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
+ private:
+ const SkeletonBlockerComplex* complex;
+ std::pair<boost_vertex_iterator, boost_vertex_iterator> vertexIterator;
+
+
+ public:
+ Vertex_iterator() : complex(NULL) { }
+
+ Vertex_iterator(const SkeletonBlockerComplex* complex_) :
+ complex(complex_),
+ vertexIterator(vertices(complex_->skeleton)) {
+ if (!finished() && !is_active()) {
+ goto_next_valid();
+ }
+ }
+
+ /**
+ * return an iterator to the end.
+ */
+ Vertex_iterator(const SkeletonBlockerComplex* complex_, int end) :
+ complex(complex_), vertexIterator(vertices(complex_->skeleton)) {
+ vertexIterator.first = vertexIterator.second;
+ }
+
+ public:
+ void increment() {
+ goto_next_valid();
+ }
+
+ Vertex_handle dereference() const {
+ return (Vertex_handle(*(vertexIterator.first)));
+ }
+
+ bool equal(const Vertex_iterator& other) const {
+ return vertexIterator == other.vertexIterator && complex == other.complex;
+ }
+
+ bool operator<(const Vertex_iterator& other) const {
+ return dereference() < other.dereference();
+ }
+
+ private:
+ bool finished() const {
+ return vertexIterator.first == vertexIterator.second;
+ }
+
+ void goto_next_valid() {
+ ++vertexIterator.first;
+ if (!finished() && !is_active()) {
+ goto_next_valid();
+ }
+ }
+
+ bool is_active() const {
+ return ((*complex)[Vertex_handle(*vertexIterator.first)]).is_active();
+ }
};
-
-
-
template<typename SkeletonBlockerComplex>
-class Neighbors_vertices_iterator
-: public boost::iterator_facade < Neighbors_vertices_iterator<SkeletonBlockerComplex>
- , typename SkeletonBlockerComplex::Vertex_handle const
- , boost::forward_traversal_tag
- , typename SkeletonBlockerComplex::Vertex_handle const
- >
-{
- friend class boost::iterator_core_access;
-
- typedef SkeletonBlockerComplex Complex;
- typedef typename Complex::boost_adjacency_iterator boost_adjacency_iterator;
- typedef typename Complex::Vertex_handle Vertex_handle;
- typedef typename Complex::Edge_handle Edge_handle;
-
-private:
-
- const Complex* complex;
- Vertex_handle v;
-
- boost_adjacency_iterator current_;
- boost_adjacency_iterator end_;
-
-public:
- // boost_adjacency_iterator ai, ai_end;
- // for (tie(ai, ai_end) = adjacent_vertices(v.vertex, skeleton); ai != ai_end; ++ai){
-
- Neighbors_vertices_iterator():complex(NULL){
- }
-
- Neighbors_vertices_iterator(const Complex* complex_,Vertex_handle v_):
- complex(complex_),
- v(v_){
- tie(current_,end_) = adjacent_vertices(v.vertex, complex->skeleton);
- }
-
- /**
- * returns an iterator to the end
- */
- Neighbors_vertices_iterator(const Complex* complex_,Vertex_handle v_,int end):
- complex(complex_),
- v(v_){
- tie(current_,end_) = adjacent_vertices(v.vertex, complex->skeleton);
- set_end();
- }
-
-
- void increment () {
- if(current_ != end_)
- ++current_;
- }
-
- Vertex_handle dereference() const {
- return(Vertex_handle(*current_));
- }
-
- bool equal(const Neighbors_vertices_iterator& other) const{
- return (complex== other.complex) && (v == other.v) && (current_ == other.current_) && (end_ == other.end_);
- }
-
-private:
- //todo remove this ugly hack
- void set_end(){
- current_ = end_;
- }
+class Neighbors_vertices_iterator: public boost::iterator_facade < Neighbors_vertices_iterator<SkeletonBlockerComplex>
+, typename SkeletonBlockerComplex::Vertex_handle const
+, boost::forward_traversal_tag
+, typename SkeletonBlockerComplex::Vertex_handle const> {
+ friend class boost::iterator_core_access;
+
+ typedef SkeletonBlockerComplex Complex;
+ typedef typename Complex::boost_adjacency_iterator boost_adjacency_iterator;
+ typedef typename Complex::Vertex_handle Vertex_handle;
+ typedef typename Complex::Edge_handle Edge_handle;
+
+ private:
+ const Complex* complex;
+ Vertex_handle v;
+
+ boost_adjacency_iterator current_;
+ boost_adjacency_iterator end_;
+
+ public:
+ // boost_adjacency_iterator ai, ai_end;
+ // for (tie(ai, ai_end) = adjacent_vertices(v.vertex, skeleton); ai != ai_end; ++ai) {
+
+ Neighbors_vertices_iterator() : complex(NULL) { }
+
+ Neighbors_vertices_iterator(const Complex* complex_, Vertex_handle v_) :
+ complex(complex_),
+ v(v_) {
+ tie(current_, end_) = adjacent_vertices(v.vertex, complex->skeleton);
+ }
+
+ /**
+ * returns an iterator to the end
+ */
+ Neighbors_vertices_iterator(const Complex* complex_, Vertex_handle v_, int end) :
+ complex(complex_),
+ v(v_) {
+ tie(current_, end_) = adjacent_vertices(v.vertex, complex->skeleton);
+ set_end();
+ }
+
+ void increment() {
+ if (current_ != end_)
+ ++current_;
+ }
+
+ Vertex_handle dereference() const {
+ return (Vertex_handle(*current_));
+ }
+
+ bool equal(const Neighbors_vertices_iterator& other) const {
+ return (complex == other.complex) && (v == other.v) && (current_ == other.current_) && (end_ == other.end_);
+ }
+
+ private:
+ // todo remove this ugly hack
+ void set_end() {
+ current_ = end_;
+ }
};
-}
+} // namespace skbl
-} // namespace GUDHI
+} // namespace Gudhi
-#endif /* GUDHI_SKELETON_BLOCKERS_VERTICES_ITERATORS_H_ */
+#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_VERTICES_ITERATORS_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h
index 700830f2..5b774f25 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h
@@ -20,8 +20,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_COMPLEX_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_COMPLEX_H_
+#ifndef SKELETON_BLOCKER_COMPLEX_H_
+#define SKELETON_BLOCKER_COMPLEX_H_
+
+#include <gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h>
+#include <gudhi/Skeleton_blocker_link_complex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h>
+#include <gudhi/Skeleton_blocker/internal/Top_faces.h>
+#include <gudhi/Skeleton_blocker/internal/Trie.h>
+#include <gudhi/Utils.h>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
@@ -40,18 +50,6 @@
#include <algorithm>
#include <utility>
-#include "gudhi/Skeleton_blocker/iterators/Skeleton_blockers_iterators.h"
-#include "gudhi/Skeleton_blocker_link_complex.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h"
-
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h"
-#include "gudhi/Skeleton_blocker/internal/Top_faces.h"
-#include "gudhi/Skeleton_blocker/internal/Trie.h"
-
-#include "gudhi/Utils.h"
-
namespace Gudhi {
namespace skbl {
@@ -94,16 +92,16 @@ class Skeleton_blocker_complex {
/**
* @brief A ordered set of integers that represents a simplex.
*/
- typedef Skeleton_blocker_simplex<Vertex_handle> Simplex_handle;
+ typedef Skeleton_blocker_simplex<Vertex_handle> Simplex;
typedef Skeleton_blocker_simplex<Root_vertex_handle> Root_simplex_handle;
/**
* @brief Handle to a blocker of the complex.
*/
- typedef Simplex_handle* Blocker_handle;
+ typedef Simplex* Blocker_handle;
typedef typename Root_simplex_handle::Simplex_vertex_const_iterator Root_simplex_iterator;
- typedef typename Simplex_handle::Simplex_vertex_const_iterator Simplex_handle_iterator;
+ typedef typename Simplex::Simplex_vertex_const_iterator Simplex_handle_iterator;
protected:
typedef typename boost::adjacency_list<boost::setS, // edges
@@ -128,14 +126,14 @@ class Skeleton_blocker_complex {
typedef typename boost::graph_traits<Graph>::edge_descriptor Edge_handle;
protected:
- typedef std::multimap<Vertex_handle, Simplex_handle *> BlockerMap;
- typedef typename std::multimap<Vertex_handle, Simplex_handle *>::value_type BlockerPair;
- typedef typename std::multimap<Vertex_handle, Simplex_handle *>::iterator BlockerMapIterator;
- typedef typename std::multimap<Vertex_handle, Simplex_handle *>::const_iterator BlockerMapConstIterator;
+ typedef std::multimap<Vertex_handle, Simplex *> BlockerMap;
+ typedef typename std::multimap<Vertex_handle, Simplex *>::value_type BlockerPair;
+ typedef typename std::multimap<Vertex_handle, Simplex *>::iterator BlockerMapIterator;
+ typedef typename std::multimap<Vertex_handle, Simplex *>::const_iterator BlockerMapConstIterator;
protected:
- int num_vertices_;
- int num_blockers_;
+ size_t num_vertices_;
+ size_t num_blockers_;
typedef Skeleton_blocker_complex_visitor<Vertex_handle> Visitor;
// typedef Visitor* Visitor_ptr;
@@ -164,17 +162,17 @@ class Skeleton_blocker_complex {
/**
*@brief constructs a simplicial complex with a given number of vertices and a visitor.
*/
- explicit Skeleton_blocker_complex(int num_vertices_ = 0, Visitor* visitor_ = NULL)
+ explicit Skeleton_blocker_complex(size_t num_vertices_ = 0, Visitor* visitor_ = NULL)
: visitor(visitor_) {
clear();
- for (int i = 0; i < num_vertices_; ++i) {
+ for (size_t i = 0; i < num_vertices_; ++i) {
add_vertex();
}
}
private:
// typedef Trie<Skeleton_blocker_complex<SkeletonBlockerDS>> STrie;
- typedef Trie<Simplex_handle> STrie;
+ typedef Trie<Simplex> STrie;
public:
/**
@@ -182,37 +180,41 @@ class Skeleton_blocker_complex {
* @details is_flag_complex indicates if the complex is a flag complex or not (to know if blockers have to be computed or not).
*/
template<typename SimpleHandleOutputIterator>
- Skeleton_blocker_complex(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end,
+ Skeleton_blocker_complex(SimpleHandleOutputIterator simplices_begin, SimpleHandleOutputIterator simplices_end,
bool is_flag_complex = false, Visitor* visitor_ = NULL)
: num_vertices_(0),
num_blockers_(0),
visitor(visitor_) {
- add_vertex_and_edges(simplex_begin, simplex_end);
+ add_vertices_and_edges(simplices_begin, simplices_end);
if (!is_flag_complex)
// need to compute blockers
- add_blockers(simplex_begin, simplex_end);
+ add_blockers(simplices_begin, simplices_end);
}
private:
+ /**
+ * Add vertices and edges of a simplex in one pass
+ */
template<typename SimpleHandleOutputIterator>
- void add_vertex_and_edges(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) {
+ void add_vertices_and_edges(SimpleHandleOutputIterator simplices_begin, SimpleHandleOutputIterator simplices_end) {
std::vector<std::pair<Vertex_handle, Vertex_handle>> edges;
// first pass to add vertices and edges
int num_vertex = -1;
- for (auto s_it = simplex_begin; s_it != simplex_end; ++s_it) {
+ for (auto s_it = simplices_begin; s_it != simplices_end; ++s_it) {
if (s_it->dimension() == 0) num_vertex = (std::max)(num_vertex, s_it->first_vertex().vertex);
if (s_it->dimension() == 1) edges.emplace_back(s_it->first_vertex(), s_it->last_vertex());
}
while (num_vertex-- >= 0) add_vertex();
for (const auto& e : edges)
- add_edge(e.first, e.second);
+ add_edge_without_blockers(e.first, e.second);
}
+
template<typename SimpleHandleOutputIterator>
- void add_blockers(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) {
- Tries<Simplex_handle> tries(num_vertices(), simplex_begin, simplex_end);
+ void add_blockers(SimpleHandleOutputIterator simplices_begin, SimpleHandleOutputIterator simplices_end) {
+ Tries<Simplex> tries(num_vertices(), simplices_begin, simplices_end);
tries.init_next_dimension();
auto simplices(tries.next_dimension_simplices());
@@ -221,7 +223,7 @@ class Skeleton_blocker_complex {
for (auto& sigma : simplices) {
// common_positive_neighbors is the set of vertices u such that
// for all s in sigma, us is an edge and u>s
- Simplex_handle common_positive_neighbors(tries.positive_neighbors(sigma.last_vertex()));
+ Simplex common_positive_neighbors(tries.positive_neighbors(sigma.last_vertex()));
for (auto sigma_it = sigma.rbegin(); sigma_it != sigma.rend(); ++sigma_it)
if (sigma_it != sigma.rbegin())
common_positive_neighbors.intersection(tries.positive_neighbors(*sigma_it));
@@ -378,6 +380,7 @@ class Skeleton_blocker_complex {
/**
* @brief Adds a vertex to the simplicial complex and returns its Vertex_handle.
+ * @remark Vertex representation is contiguous.
*/
Vertex_handle add_vertex() {
Vertex_handle address(boost::add_vertex(skeleton));
@@ -427,7 +430,7 @@ class Skeleton_blocker_complex {
* @return true iff the simplicial complex contains all vertices
* of simplex sigma
*/
- bool contains_vertices(const Simplex_handle & sigma) const {
+ bool contains_vertices(const Simplex & sigma) const {
for (auto vertex : sigma)
if (!contains_vertex(vertex))
return false;
@@ -535,41 +538,68 @@ class Skeleton_blocker_complex {
* @details it assumes that the edge is present in the complex
*/
- Simplex_handle get_vertices(Edge_handle edge_handle) const {
+ Simplex get_vertices(Edge_handle edge_handle) const {
auto edge((*this)[edge_handle]);
- return Simplex_handle((*this)[edge.first()], (*this)[edge.second()]);
+ return Simplex((*this)[edge.first()], (*this)[edge.second()]);
}
/**
- * @brief Adds an edge between vertices a and b and all its cofaces.
+ * @brief Adds an edge between vertices a and b.
+ * @details For instance, the complex contains edge 01 and 12, then calling
+ * add_edge with vertex 0 and 2 will create a complex containing
+ * the edges 01, 12, 20 but not the triangle 012 (and hence this complex
+ * will contains a blocker 012).
*/
Edge_handle add_edge(Vertex_handle a, Vertex_handle b) {
+ // if the edge is already there we musnt go further
+ // as we may add blockers that should not be here
+ if (contains_edge(a, b))
+ return *((*this)[std::make_pair(a, b)]);
+ auto res = add_edge_without_blockers(a, b);
+ add_blockers_after_simplex_insertion(Simplex(a, b));
+ return res;
+ }
+
+ /**
+ * @brief Adds all edges of s in the complex.
+ */
+ void add_edge(const Simplex& s) {
+ for (auto i = s.begin(); i != s.end(); ++i)
+ for (auto j = i; ++j != s.end(); /**/)
+ add_edge(*i, *j);
+ }
+
+ /**
+ * @brief Adds an edge between vertices a and b without blockers.
+ * @details For instance, the complex contains edge 01 and 12, then calling
+ * add_edge with vertex 0 and 2 will create a complex containing
+ * the triangle 012.
+ */
+ Edge_handle add_edge_without_blockers(Vertex_handle a, Vertex_handle b) {
assert(contains_vertex(a) && contains_vertex(b));
assert(a != b);
auto edge_handle((*this)[std::make_pair(a, b)]);
- // std::pair<Edge_handle,bool> pair_descr_bool = (*this)[std::make_pair(a,b)];
- // Edge_handle edge_descr;
- // bool edge_present = pair_descr_bool.second;
if (!edge_handle) {
edge_handle = boost::add_edge(a.vertex, b.vertex, skeleton).first;
(*this)[*edge_handle].setId(get_id(a), get_id(b));
degree_[a.vertex]++;
degree_[b.vertex]++;
if (visitor)
- visitor->on_add_edge(a, b);
+ visitor->on_add_edge_without_blockers(a, b);
}
return *edge_handle;
}
+
/**
- * @brief Adds all edges and their cofaces of a simplex to the simplicial complex.
+ * @brief Adds all edges of s in the complex without adding blockers.
*/
- void add_edges(const Simplex_handle & sigma) {
- Simplex_handle_iterator i, j;
- for (i = sigma.begin(); i != sigma.end(); ++i)
- for (j = i, j++; j != sigma.end(); ++j)
- add_edge(*i, *j);
+ void add_edge_without_blockers(Simplex s) {
+ for (auto i = s.begin(); i != s.end(); ++i) {
+ for (auto j = i; ++j != s.end(); /**/)
+ add_edge_without_blockers(*i, *j);
+ }
}
/**
@@ -627,7 +657,7 @@ class Skeleton_blocker_complex {
* @return true iff the simplicial complex contains all vertices
* and all edges of simplex sigma
*/
- bool contains_edges(const Simplex_handle & sigma) const {
+ bool contains_edges(const Simplex & sigma) const {
for (auto i = sigma.begin(); i != sigma.end(); ++i) {
if (!contains_vertex(*i))
return false;
@@ -649,15 +679,14 @@ class Skeleton_blocker_complex {
* @brief Adds the simplex to the set of blockers and
* returns a Blocker_handle toward it if was not present before and 0 otherwise.
*/
- Blocker_handle add_blocker(const Simplex_handle& blocker) {
+ Blocker_handle add_blocker(const Simplex& blocker) {
assert(blocker.dimension() > 1);
if (contains_blocker(blocker)) {
- // std::cerr << "ATTEMPT TO ADD A BLOCKER ALREADY THERE ---> BLOCKER IGNORED" << endl;
return 0;
} else {
if (visitor)
visitor->on_add_blocker(blocker);
- Blocker_handle blocker_pt = new Simplex_handle(blocker);
+ Blocker_handle blocker_pt = new Simplex(blocker);
num_blockers_++;
auto vertex = blocker_pt->begin();
while (vertex != blocker_pt->end()) {
@@ -739,7 +768,7 @@ class Skeleton_blocker_complex {
*
* @remark contrarily to delete_blockers does not call the destructor
*/
- void remove_blocker(const Simplex_handle& sigma) {
+ void remove_blocker(const Simplex& sigma) {
assert(contains_blocker(sigma));
for (auto vertex : sigma)
remove_blocker(sigma, vertex);
@@ -777,7 +806,7 @@ class Skeleton_blocker_complex {
/**
* @return true iff s is a blocker of the simplicial complex
*/
- bool contains_blocker(const Simplex_handle & s) const {
+ bool contains_blocker(const Simplex & s) const {
if (s.dimension() < 2)
return false;
@@ -795,7 +824,7 @@ class Skeleton_blocker_complex {
* @return true iff a blocker of the simplicial complex
* is a face of sigma.
*/
- bool blocks(const Simplex_handle & sigma) const {
+ bool blocks(const Simplex & sigma) const {
for (auto s : sigma)
for (auto blocker : const_blocker_range(s))
if (sigma.contains(*blocker))
@@ -810,7 +839,7 @@ class Skeleton_blocker_complex {
* @details Adds to simplex the neighbours of v e.g. \f$ n \leftarrow n \cup N(v) \f$.
* If keep_only_superior is true then only vertices that are greater than v are added.
*/
- virtual void add_neighbours(Vertex_handle v, Simplex_handle & n,
+ virtual void add_neighbours(Vertex_handle v, Simplex & n,
bool keep_only_superior = false) const {
boost_adjacency_iterator ai, ai_end;
for (tie(ai, ai_end) = adjacent_vertices(v.vertex, skeleton); ai != ai_end;
@@ -833,7 +862,7 @@ class Skeleton_blocker_complex {
* todo revoir
*
*/
- virtual void add_neighbours(const Simplex_handle &alpha, Simplex_handle & res,
+ virtual void add_neighbours(const Simplex &alpha, Simplex & res,
bool keep_only_superior = false) const {
res.clear();
auto alpha_vertex = alpha.begin();
@@ -848,9 +877,9 @@ class Skeleton_blocker_complex {
* not neighbours of v e.g. \f$ res \leftarrow res \cap N(v) \f$.
* If 'keep_only_superior' is true then only vertices that are greater than v are keeped.
*/
- virtual void keep_neighbours(Vertex_handle v, Simplex_handle& res,
+ virtual void keep_neighbours(Vertex_handle v, Simplex& res,
bool keep_only_superior = false) const {
- Simplex_handle nv;
+ Simplex nv;
add_neighbours(v, nv, keep_only_superior);
res.intersection(nv);
}
@@ -860,9 +889,9 @@ class Skeleton_blocker_complex {
* neighbours of v eg \f$ res \leftarrow res \setminus N(v) \f$.
* If 'keep_only_superior' is true then only vertices that are greater than v are added.
*/
- virtual void remove_neighbours(Vertex_handle v, Simplex_handle & res,
+ virtual void remove_neighbours(Vertex_handle v, Simplex & res,
bool keep_only_superior = false) const {
- Simplex_handle nv;
+ Simplex nv;
add_neighbours(v, nv, keep_only_superior);
res.difference(nv);
}
@@ -874,7 +903,7 @@ class Skeleton_blocker_complex {
* Constructs the link of 'simplex' with points coordinates.
*/
Link_complex link(Vertex_handle v) const {
- return Link_complex(*this, Simplex_handle(v));
+ return Link_complex(*this, Simplex(v));
}
/**
@@ -887,7 +916,7 @@ class Skeleton_blocker_complex {
/**
* Constructs the link of 'simplex' with points coordinates.
*/
- Link_complex link(const Simplex_handle& simplex) const {
+ Link_complex link(const Simplex& simplex) const {
return Link_complex(*this, simplex);
}
@@ -899,11 +928,11 @@ class Skeleton_blocker_complex {
*/
// xxx rename get_address et place un using dans sub_complex
- boost::optional<Simplex_handle> get_simplex_address(
+ boost::optional<Simplex> get_simplex_address(
const Root_simplex_handle& s) const {
- boost::optional<Simplex_handle> res;
+ boost::optional<Simplex> res;
- Simplex_handle s_address;
+ Simplex s_address;
// Root_simplex_const_iterator i;
for (auto i = s.begin(); i != s.end(); ++i) {
boost::optional<Vertex_handle> address = get_address(*i);
@@ -920,7 +949,7 @@ class Skeleton_blocker_complex {
* @brief returns a simplex with vertices which are the id of vertices of the
* argument.
*/
- Root_simplex_handle get_id(const Simplex_handle& local_simplex) const {
+ Root_simplex_handle get_id(const Simplex& local_simplex) const {
Root_simplex_handle global_simplex;
for (auto x = local_simplex.begin(); x != local_simplex.end(); ++x) {
global_simplex.add_vertex(get_id(*x));
@@ -932,7 +961,7 @@ class Skeleton_blocker_complex {
* @brief returns true iff the simplex s belongs to the simplicial
* complex.
*/
- virtual bool contains(const Simplex_handle & s) const {
+ virtual bool contains(const Simplex & s) const {
if (s.dimension() == -1) {
return false;
} else if (s.dimension() == 0) {
@@ -972,10 +1001,31 @@ class Skeleton_blocker_complex {
return std::distance(triangles.begin(), triangles.end());
}
+
+ /*
+ * @brief returns the number of simplices of a given dimension in the complex.
+ */
+ size_t num_simplices() const {
+ auto simplices = complex_simplex_range();
+ return std::distance(simplices.begin(), simplices.end());
+ }
+
+ /*
+ * @brief returns the number of simplices of a given dimension in the complex.
+ */
+ size_t num_simplices(unsigned dimension) const {
+ // TODO(DS): iterator on k-simplices
+ size_t res = 0;
+ for (const auto& s : complex_simplex_range())
+ if (s.dimension() == dimension)
+ ++res;
+ return res;
+ }
+
/*
* @brief returns the number of blockers in the complex.
*/
- int num_blockers() const {
+ size_t num_blockers() const {
return num_blockers_;
}
@@ -1018,7 +1068,7 @@ class Skeleton_blocker_complex {
}
//@}
- /** @Simplification operations
+ /** @name Simplification operations
*/
//@{
@@ -1061,7 +1111,7 @@ class Skeleton_blocker_complex {
* Furthermore, all simplices tau of the form sigma \setminus simplex_to_be_removed must be added
* whenever the dimension of tau is at least 2.
*/
- void update_blockers_after_remove_star_of_vertex_or_edge(const Simplex_handle& simplex_to_be_removed);
+ void update_blockers_after_remove_star_of_vertex_or_edge(const Simplex& simplex_to_be_removed);
public:
/**
@@ -1078,31 +1128,33 @@ class Skeleton_blocker_complex {
/**
* Remove the star of the simplex 'sigma' which needs to belong to the complex
*/
- void remove_star(const Simplex_handle& sigma);
+ void remove_star(const Simplex& sigma);
/**
- * @brief add a maximal simplex plus all its cofaces.
- * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge).
+ * @brief add a simplex and all its faces.
+ * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge_without_blockers).
*/
- void add_simplex(const Simplex_handle& sigma);
+ void add_simplex(const Simplex& sigma);
private:
+ void add_blockers_after_simplex_insertion(Simplex s);
+
/**
* remove all blockers that contains sigma
*/
- void remove_blocker_containing_simplex(const Simplex_handle& sigma);
+ void remove_blocker_containing_simplex(const Simplex& sigma);
/**
* remove all blockers that contains sigma
*/
- void remove_blocker_include_in_simplex(const Simplex_handle& sigma);
+ void remove_blocker_include_in_simplex(const Simplex& sigma);
public:
enum simplifiable_status {
NOT_HOMOTOPY_EQ, MAYBE_HOMOTOPY_EQ, HOMOTOPY_EQ
};
- simplifiable_status is_remove_star_homotopy_preserving(const Simplex_handle& simplex) {
+ simplifiable_status is_remove_star_homotopy_preserving(const Simplex& simplex) {
// todo write a virtual method 'link' in Skeleton_blocker_complex which will be overloaded by the current one of
// Skeleton_blocker_geometric_complex
// then call it there to build the link and return the value of link.is_contractible()
@@ -1131,7 +1183,7 @@ class Skeleton_blocker_complex {
}
//@}
- /** @Edge contraction operations
+ /** @name Edge contraction operations
*/
//@{
@@ -1174,7 +1226,7 @@ class Skeleton_blocker_complex {
* that may be used to construct a new blocker after contracting ab.
* It requires that the link condition is satisfied.
*/
- void tip_blockers(Vertex_handle a, Vertex_handle b, std::vector<Simplex_handle> & buffer) const;
+ void tip_blockers(Vertex_handle a, Vertex_handle b, std::vector<Simplex> & buffer) const;
private:
/**
@@ -1217,7 +1269,7 @@ class Skeleton_blocker_complex {
private:
void get_blockers_to_be_added_after_contraction(Vertex_handle a, Vertex_handle b,
- std::set<Simplex_handle>& blockers_to_add);
+ std::set<Simplex>& blockers_to_add);
/**
* delete all blockers that passes through a or b
*/
@@ -1358,12 +1410,28 @@ class Skeleton_blocker_complex {
/**
* @brief Returns a Complex_simplex_around_vertex_range over all the simplices around a vertex of the complex
*/
- Complex_simplex_around_vertex_range simplex_range(Vertex_handle v) const {
+ Complex_simplex_around_vertex_range star_simplex_range(Vertex_handle v) const {
assert(contains_vertex(v));
return Complex_simplex_around_vertex_range(
Complex_simplex_around_vertex_iterator(this, v),
Complex_simplex_around_vertex_iterator(this, v, true));
}
+ typedef Simplex_coboundary_iterator<Skeleton_blocker_complex, Link> Complex_simplex_coboundary_iterator;
+
+ /**
+ * @brief Range over the simplices of the coboundary of a simplex.
+ * Methods .begin() and .end() return a Complex_simplex_coboundary_iterator.
+ */
+ typedef boost::iterator_range < Complex_simplex_coboundary_iterator > Complex_coboundary_range;
+
+ /**
+ * @brief Returns a Complex_simplex_coboundary_iterator over the simplices of the coboundary of a simplex.
+ */
+ Complex_coboundary_range coboundary_range(const Simplex& s) const {
+ assert(contains(s));
+ return Complex_coboundary_range(Complex_simplex_coboundary_iterator(this, s),
+ Complex_simplex_coboundary_iterator(this, s, true));
+ }
// typedef Simplex_iterator<Skeleton_blocker_complex,Superior_link> Complex_simplex_iterator;
typedef Simplex_iterator<Skeleton_blocker_complex> Complex_simplex_iterator;
@@ -1373,7 +1441,7 @@ class Skeleton_blocker_complex {
/**
* @brief Returns a Complex_simplex_range over all the simplices of the complex
*/
- Complex_simplex_range simplex_range() const {
+ Complex_simplex_range complex_simplex_range() const {
Complex_simplex_iterator end(this, true);
if (empty()) {
return Complex_simplex_range(end, end);
@@ -1393,7 +1461,7 @@ class Skeleton_blocker_complex {
* @brief Iterator over the blockers adjacent to a vertex
*/
typedef Blocker_iterator_around_vertex_internal<
- typename std::multimap<Vertex_handle, Simplex_handle *>::iterator,
+ typename std::multimap<Vertex_handle, Simplex *>::iterator,
Blocker_handle>
Complex_blocker_around_vertex_iterator;
@@ -1401,12 +1469,13 @@ class Skeleton_blocker_complex {
* @brief Iterator over (constant) blockers adjacent to a vertex
*/
typedef Blocker_iterator_around_vertex_internal<
- typename std::multimap<Vertex_handle, Simplex_handle *>::const_iterator,
+ typename std::multimap<Vertex_handle, Simplex *>::const_iterator,
const Blocker_handle>
Const_complex_blocker_around_vertex_iterator;
typedef boost::iterator_range <Complex_blocker_around_vertex_iterator> Complex_blocker_around_vertex_range;
- typedef boost::iterator_range <Const_complex_blocker_around_vertex_iterator> Const_complex_blocker_around_vertex_range;
+ typedef boost::iterator_range <Const_complex_blocker_around_vertex_iterator>
+ Const_complex_blocker_around_vertex_range;
public:
/**
@@ -1432,7 +1501,7 @@ class Skeleton_blocker_complex {
* @brief Iterator over the blockers.
*/
typedef Blocker_iterator_internal<
- typename std::multimap<Vertex_handle, Simplex_handle *>::iterator,
+ typename std::multimap<Vertex_handle, Simplex *>::iterator,
Blocker_handle>
Complex_blocker_iterator;
@@ -1440,7 +1509,7 @@ class Skeleton_blocker_complex {
* @brief Iterator over the (constant) blockers.
*/
typedef Blocker_iterator_internal<
- typename std::multimap<Vertex_handle, Simplex_handle *>::const_iterator,
+ typename std::multimap<Vertex_handle, Simplex *>::const_iterator,
const Blocker_handle>
Const_complex_blocker_iterator;
@@ -1514,11 +1583,12 @@ class Skeleton_blocker_complex {
* return the total number of simplices
*/
template<typename Complex, typename SimplexHandleIterator>
-Complex make_complex_from_top_faces(SimplexHandleIterator simplex_begin, SimplexHandleIterator simplex_end,
+Complex make_complex_from_top_faces(SimplexHandleIterator simplices_begin, SimplexHandleIterator simplices_end,
bool is_flag_complex = false) {
- typedef typename Complex::Simplex_handle Simplex_handle;
- std::vector<Simplex_handle> simplices;
- for (auto top_face = simplex_begin; top_face != simplex_end; ++top_face) {
+ // TODO(DS): use add_simplex instead! should be more efficient and more elegant :)
+ typedef typename Complex::Simplex Simplex;
+ std::vector<Simplex> simplices;
+ for (auto top_face = simplices_begin; top_face != simplices_end; ++top_face) {
auto subfaces_topface = subfaces(*top_face);
simplices.insert(simplices.end(), subfaces_topface.begin(), subfaces_topface.end());
}
@@ -1531,6 +1601,4 @@ Complex make_complex_from_top_faces(SimplexHandleIterator simplex_begin, Simplex
#include "Skeleton_blocker_simplifiable_complex.h"
-
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_COMPLEX_H_
-
+#endif // SKELETON_BLOCKER_COMPLEX_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h
index 437482cb..5c898152 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h
@@ -19,12 +19,12 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_GEOMETRIC_COMPLEX_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_GEOMETRIC_COMPLEX_H_
+#ifndef SKELETON_BLOCKER_GEOMETRIC_COMPLEX_H_
+#define SKELETON_BLOCKER_GEOMETRIC_COMPLEX_H_
-#include "gudhi/Utils.h"
-#include "gudhi/Skeleton_blocker_complex.h"
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h"
+#include <gudhi/Utils.h>
+#include <gudhi/Skeleton_blocker_complex.h>
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h>
namespace Gudhi {
@@ -46,7 +46,7 @@ public Skeleton_blocker_complex<SkeletonBlockerGeometricDS> {
typedef typename SimplifiableSkeletonblocker::Vertex_handle Vertex_handle;
typedef typename SimplifiableSkeletonblocker::Root_vertex_handle Root_vertex_handle;
typedef typename SimplifiableSkeletonblocker::Edge_handle Edge_handle;
- typedef typename SimplifiableSkeletonblocker::Simplex_handle Simplex_handle;
+ typedef typename SimplifiableSkeletonblocker::Simplex Simplex;
typedef typename SimplifiableSkeletonblocker::Graph_vertex Graph_vertex;
@@ -79,23 +79,6 @@ public Skeleton_blocker_complex<SkeletonBlockerGeometricDS> {
(*this)[Vertex_handle(current++)].point() = Point(point->begin(), point->end());
}
- template<typename SimpleHandleOutputIterator, typename PointIterator>
- friend Skeleton_blocker_geometric_complex make_complex_from_top_faces(
- SimpleHandleOutputIterator simplex_begin,
- SimpleHandleOutputIterator simplex_end,
- PointIterator points_begin,
- PointIterator points_end,
- bool is_flag_complex = false) {
- Skeleton_blocker_geometric_complex complex;
- unsigned current = 0;
- complex =
- make_complex_from_top_faces<Skeleton_blocker_geometric_complex>(simplex_begin, simplex_end, is_flag_complex);
- for (auto point = points_begin; point != points_end; ++point)
- // complex.point(Vertex_handle(current++)) = Point(point->begin(),point->end());
- complex.point(Vertex_handle(current++)) = Point(*point);
- return complex;
- }
-
/**
* @brief Constructor with a list of simplices.
* Points of every vertex are the point constructed with default constructor.
@@ -157,7 +140,7 @@ public Skeleton_blocker_complex<SkeletonBlockerGeometricDS> {
* Constructs the link of 'simplex' with points coordinates.
*/
Geometric_link link(Vertex_handle v) const {
- Geometric_link link(*this, Simplex_handle(v));
+ Geometric_link link(*this, Simplex(v));
// we now add the point info
add_points_to_link(link);
return link;
@@ -166,7 +149,7 @@ public Skeleton_blocker_complex<SkeletonBlockerGeometricDS> {
/**
* Constructs the link of 'simplex' with points coordinates.
*/
- Geometric_link link(const Simplex_handle& simplex) const {
+ Geometric_link link(const Simplex& simplex) const {
Geometric_link link(*this, simplex);
// we now add the point info
add_points_to_link(link);
@@ -189,13 +172,13 @@ public Skeleton_blocker_complex<SkeletonBlockerGeometricDS> {
* Constructs the abstract link of v (without points coordinates).
*/
Abstract_link abstract_link(Vertex_handle v) const {
- return Abstract_link(*this, Simplex_handle(v));
+ return Abstract_link(*this, Simplex(v));
}
/**
* Constructs the link of 'simplex' with points coordinates.
*/
- Abstract_link abstract_link(const Simplex_handle& simplex) const {
+ Abstract_link abstract_link(const Simplex& simplex) const {
return Abstract_link(*this, simplex);
}
@@ -215,8 +198,27 @@ public Skeleton_blocker_complex<SkeletonBlockerGeometricDS> {
}
};
+
+template<typename SkeletonBlockerGeometricComplex, typename SimpleHandleOutputIterator, typename PointIterator>
+SkeletonBlockerGeometricComplex make_complex_from_top_faces(
+ SimpleHandleOutputIterator simplex_begin,
+ SimpleHandleOutputIterator simplex_end,
+ PointIterator points_begin,
+ PointIterator points_end,
+ bool is_flag_complex = false) {
+ typedef SkeletonBlockerGeometricComplex SBGC;
+ SkeletonBlockerGeometricComplex complex;
+ unsigned current = 0;
+ complex =
+ make_complex_from_top_faces<SBGC>(simplex_begin, simplex_end, is_flag_complex);
+ for (auto point = points_begin; point != points_end; ++point)
+ // complex.point(Vertex_handle(current++)) = Point(point->begin(),point->end());
+ complex.point(typename SBGC::Vertex_handle(current++)) = typename SBGC::Point(*point);
+ return complex;
+}
+
} // namespace skbl
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_GEOMETRIC_COMPLEX_H_
+#endif // SKELETON_BLOCKER_GEOMETRIC_COMPLEX_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h
index 725ecce5..85a6b0b5 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h
@@ -19,11 +19,11 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_LINK_COMPLEX_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_LINK_COMPLEX_H_
+#ifndef SKELETON_BLOCKER_LINK_COMPLEX_H_
+#define SKELETON_BLOCKER_LINK_COMPLEX_H_
-#include "gudhi/Utils.h"
-#include "gudhi/Skeleton_blocker_complex.h"
+#include <gudhi/Utils.h>
+#include <gudhi/Skeleton_blocker_complex.h>
namespace Gudhi {
@@ -52,12 +52,11 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
typedef typename ComplexType::Vertex_handle Vertex_handle;
typedef typename ComplexType::Root_vertex_handle Root_vertex_handle;
- typedef typename ComplexType::Simplex_handle Simplex_handle;
+ typedef typename ComplexType::Simplex Simplex;
typedef typename ComplexType::Root_simplex_handle Root_simplex_handle;
typedef typename ComplexType::Blocker_handle Blocker_handle;
- typedef typename ComplexType::Simplex_handle::Simplex_vertex_const_iterator Simplex_handle_iterator;
typedef typename ComplexType::Root_simplex_handle::Simplex_vertex_const_iterator Root_simplex_handle_iterator;
explicit Skeleton_blocker_link_complex(bool only_superior_vertices = false)
@@ -67,13 +66,15 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
/**
* If the parameter only_superior_vertices is true,
* only vertices greater than the one of alpha are added.
+ * Only vertices are computed if only_vertices is true.
*/
Skeleton_blocker_link_complex(const ComplexType & parent_complex,
- const Simplex_handle& alpha_parent_adress,
- bool only_superior_vertices = false)
+ const Simplex& alpha_parent_adress,
+ bool only_superior_vertices = false,
+ bool only_vertices = false)
: only_superior_vertices_(only_superior_vertices) {
if (!alpha_parent_adress.empty())
- build_link(parent_complex, alpha_parent_adress);
+ build_link(parent_complex, alpha_parent_adress, only_vertices);
}
/**
@@ -84,7 +85,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
Vertex_handle a_parent_adress,
bool only_superior_vertices = false)
: only_superior_vertices_(only_superior_vertices) {
- Simplex_handle alpha_simplex(a_parent_adress);
+ Simplex alpha_simplex(a_parent_adress);
build_link(parent_complex, alpha_simplex);
}
@@ -96,7 +97,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
Edge_handle edge, bool only_superior_vertices =
false)
: only_superior_vertices_(only_superior_vertices) {
- Simplex_handle alpha_simplex(parent_complex.first_vertex(edge),
+ Simplex alpha_simplex(parent_complex.first_vertex(edge),
parent_complex.second_vertex(edge));
build_link(parent_complex, alpha_simplex);
}
@@ -108,7 +109,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
* are greater than vertices of alpha_parent_adress are added.
*/
void compute_link_vertices(const ComplexType & parent_complex,
- const Simplex_handle& alpha_parent_adress,
+ const Simplex& alpha_parent_adress,
bool only_superior_vertices,
bool is_alpha_blocker = false) {
if (alpha_parent_adress.dimension() == 0) {
@@ -119,7 +120,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
only_superior_vertices_);
} else {
// we compute the intersection of neighbors of alpha and store it in link_vertices
- Simplex_handle link_vertices_parent;
+ Simplex link_vertices_parent;
parent_complex.add_neighbours(alpha_parent_adress, link_vertices_parent,
only_superior_vertices);
// For all vertex 'v' in this intersection, we go through all its adjacent blockers.
@@ -162,13 +163,8 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
}
void compute_link_edges(const ComplexType & parent_complex,
- const Simplex_handle& alpha_parent_adress,
+ const Simplex& alpha_parent_adress,
bool is_alpha_blocker = false) {
- Simplex_handle_iterator y_link, x_parent, y_parent;
- // ----------------------------
- // Compute edges in the link
- // -------------------------
-
if (this->num_vertices() <= 1)
return;
@@ -194,7 +190,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
}
}
if (new_edge)
- this->add_edge(*x_link, *y_link);
+ this->add_edge_without_blockers(*x_link, *y_link);
}
}
}
@@ -217,7 +213,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
* the blocker is anticollapsed.
*/
void compute_link_blockers(const ComplexType & parent_complex,
- const Simplex_handle& alpha_parent,
+ const Simplex& alpha_parent,
bool is_alpha_blocker = false) {
for (auto x_link : this->vertex_range()) {
Vertex_handle x_parent = *this->give_equivalent_vertex(parent_complex,
@@ -225,7 +221,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
for (auto blocker_parent : parent_complex.const_blocker_range(x_parent)) {
if (!is_alpha_blocker || *blocker_parent != alpha_parent) {
- Simplex_handle sigma_parent(*blocker_parent);
+ Simplex sigma_parent(*blocker_parent);
sigma_parent.difference(alpha_parent);
@@ -239,7 +235,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
for (auto a : alpha_parent) {
for (auto eta_parent : parent_complex.const_blocker_range(a)) {
if (!is_alpha_blocker || *eta_parent != alpha_parent) {
- Simplex_handle eta_minus_alpha(*eta_parent);
+ Simplex eta_minus_alpha(*eta_parent);
eta_minus_alpha.difference(alpha_parent);
if (eta_minus_alpha != sigma_parent
&& sigma_parent.contains_difference(*eta_parent,
@@ -253,7 +249,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
break;
}
if (is_new_blocker)
- this->add_blocker(new Simplex_handle(*sigma_link));
+ this->add_blocker(new Simplex(*sigma_link));
}
}
}
@@ -268,14 +264,15 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
* with vertices that are greater than vertices of alpha_parent_adress.
*/
void build_link(const ComplexType & parent_complex,
- const Simplex_handle& alpha_parent_adress,
- bool is_alpha_blocker = false) {
+ const Simplex& alpha_parent_adress,
+ bool is_alpha_blocker = false,
+ bool only_vertices = false) {
assert(is_alpha_blocker || parent_complex.contains(alpha_parent_adress));
- compute_link_vertices(parent_complex, alpha_parent_adress,
- only_superior_vertices_);
- compute_link_edges(parent_complex, alpha_parent_adress, is_alpha_blocker);
- compute_link_blockers(parent_complex, alpha_parent_adress,
- is_alpha_blocker);
+ compute_link_vertices(parent_complex, alpha_parent_adress, only_superior_vertices_);
+ if(!only_vertices) {
+ compute_link_edges(parent_complex, alpha_parent_adress, is_alpha_blocker);
+ compute_link_blockers(parent_complex, alpha_parent_adress, is_alpha_blocker);
+ }
}
/**
@@ -284,7 +281,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
* removed from the blockers of the complex.
*/
friend void build_link_of_blocker(const ComplexType & parent_complex,
- Simplex_handle& blocker,
+ Simplex& blocker,
Skeleton_blocker_link_complex & result) {
assert(blocker.dimension() >= 2);
assert(parent_complex.contains_blocker(blocker));
@@ -297,4 +294,4 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex<
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_LINK_COMPLEX_H_
+#endif // SKELETON_BLOCKER_LINK_COMPLEX_H_
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h
index dd8d898e..94a125c1 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h
@@ -19,15 +19,15 @@
* 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 SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
-#define SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
+#ifndef SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
+#define SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
+
+#include <gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h>
#include <list>
#include <vector>
#include <set>
-#include "gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h"
-
namespace Gudhi {
namespace skbl {
@@ -45,9 +45,7 @@ bool Skeleton_blocker_complex<SkeletonBlockerDS>::is_popable_blocker(Blocker_han
assert(this->contains_blocker(*sigma));
Skeleton_blocker_link_complex<Skeleton_blocker_complex> link_blocker_sigma;
build_link_of_blocker(*this, *sigma, link_blocker_sigma);
-
- bool res = link_blocker_sigma.is_contractible() == CONTRACTIBLE;
- return res;
+ return link_blocker_sigma.is_contractible() == CONTRACTIBLE;
}
/**
@@ -133,7 +131,7 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_all_popable_blockers(Ve
template<typename SkeletonBlockerDS>
void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(Vertex_handle v) {
// we remove the blockers that are not consistent anymore
- update_blockers_after_remove_star_of_vertex_or_edge(Simplex_handle(v));
+ update_blockers_after_remove_star_of_vertex_or_edge(Simplex(v));
while (this->degree(v) > 0) {
Vertex_handle w(* (adjacent_vertices(v.vertex, this->skeleton).first));
this->remove_edge(v, w);
@@ -148,7 +146,7 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(Vertex_handle v) {
*/
template<typename SkeletonBlockerDS>
void Skeleton_blocker_complex<SkeletonBlockerDS>::update_blockers_after_remove_star_of_vertex_or_edge(
- const Simplex_handle& simplex_to_be_removed) {
+ const Simplex& simplex_to_be_removed) {
std::list <Blocker_handle> blockers_to_update;
if (simplex_to_be_removed.empty()) return;
@@ -159,7 +157,7 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::update_blockers_after_remove_s
}
for (auto blocker_to_update : blockers_to_update) {
- Simplex_handle sub_blocker_to_be_added;
+ Simplex sub_blocker_to_be_added;
bool sub_blocker_need_to_be_added =
(blocker_to_update->dimension() - simplex_to_be_removed.dimension()) >= 2;
if (sub_blocker_need_to_be_added) {
@@ -178,7 +176,7 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::update_blockers_after_remove_s
*/
template<typename SkeletonBlockerDS>
void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(Vertex_handle a, Vertex_handle b) {
- update_blockers_after_remove_star_of_vertex_or_edge(Simplex_handle(a, b));
+ update_blockers_after_remove_star_of_vertex_or_edge(Simplex(a, b));
// we remove the edge
this->remove_edge(a, b);
}
@@ -195,7 +193,7 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(Edge_handle e) {
* Remove the star of the simplex 'sigma' which needs to belong to the complex
*/
template<typename SkeletonBlockerDS>
-void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(const Simplex_handle& sigma) {
+void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(const Simplex& sigma) {
assert(this->contains(sigma));
if (sigma.dimension() == 0) {
remove_star(sigma.first_vertex());
@@ -207,33 +205,41 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_star(const Simplex_hand
}
}
-/**
- * @brief add a maximal simplex plus all its cofaces.
- * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge).
- */
template<typename SkeletonBlockerDS>
-void Skeleton_blocker_complex<SkeletonBlockerDS>::add_simplex(const Simplex_handle& sigma) {
+void Skeleton_blocker_complex<SkeletonBlockerDS>::add_simplex(const Simplex& sigma) {
+ // to add a simplex s, all blockers included in s are first removed
+ // and then all simplex in the coboundary of s are added as blockers
assert(!this->contains(sigma));
assert(sigma.dimension() > 1);
+ if (!contains_vertices(sigma)) {
+ std::cerr << "add_simplex: Some vertices were not present in the complex, adding them" << std::endl;
+ size_t num_vertices_to_add = sigma.last_vertex() - this->num_vertices() + 1;
+ for (size_t i = 0; i < num_vertices_to_add; ++i)
+ this->add_vertex();
+ }
+ assert(contains_vertices(sigma));
+ if (!contains_edges(sigma))
+ add_edge(sigma);
+ remove_blocker_include_in_simplex(sigma);
+ add_blockers_after_simplex_insertion(sigma);
+}
- int num_vertex_to_add = 0;
- for (auto v : sigma)
- if (!contains_vertex(v)) ++num_vertex_to_add;
- while (num_vertex_to_add--) add_vertex();
- for (auto u_it = sigma.begin(); u_it != sigma.end(); ++u_it)
- for (auto v_it = u_it; ++v_it != sigma.end(); /**/) {
- // std::cout << "add edge" << *u_it << " " << *v_it << std::endl;
- add_edge(*u_it, *v_it);
- }
- remove_blocker_include_in_simplex(sigma);
+
+template<typename SkeletonBlockerDS>
+void Skeleton_blocker_complex<SkeletonBlockerDS>::add_blockers_after_simplex_insertion(Simplex sigma) {
+ if (sigma.dimension() < 1) return;
+
+ for (auto s : coboundary_range(sigma)) {
+ this->add_blocker(s);
+ }
}
/**
* remove all blockers that contains sigma
*/
template<typename SkeletonBlockerDS>
-void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_containing_simplex(const Simplex_handle& sigma) {
+void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_containing_simplex(const Simplex& sigma) {
std::vector <Blocker_handle> blockers_to_remove;
for (auto blocker : this->blocker_range(sigma.first_vertex())) {
if (blocker->contains(sigma))
@@ -247,14 +253,26 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_containing_simp
* remove all blockers that contains sigma
*/
template<typename SkeletonBlockerDS>
-void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_include_in_simplex(const Simplex_handle& sigma) {
- std::vector <Blocker_handle> blockers_to_remove;
- for (auto blocker : this->blocker_range(sigma.first_vertex())) {
- if (sigma.contains(*blocker))
- blockers_to_remove.push_back(blocker);
+void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_include_in_simplex(const Simplex& sigma) {
+ // TODO(DS): write efficiently by using only superior blockers
+ // eg for all s, check blockers whose vertices are all greater than s
+ std::set <Blocker_handle> blockers_to_remove;
+ for (auto s : sigma) {
+ for (auto blocker : this->blocker_range(s)) {
+ if (sigma.contains(*blocker))
+ blockers_to_remove.insert(blocker);
+ }
}
- for (auto blocker_to_update : blockers_to_remove)
+ for (auto blocker_to_update : blockers_to_remove) {
+ auto s = *blocker_to_update;
this->delete_blocker(blocker_to_update);
+ // now if there is a vertex v in the link of s
+ // and v is not included in sigma then v.s is a blocker
+ // (all faces of v.s are there since v belongs to the link of s)
+ for (const auto& b : coboundary_range(s))
+ if (!sigma.contains(b))
+ this->add_blocker(b);
+ }
}
/**
@@ -264,21 +282,21 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::remove_blocker_include_in_simp
*/
template<typename SkeletonBlockerDS>
void Skeleton_blocker_complex<SkeletonBlockerDS>::tip_blockers(Vertex_handle a, Vertex_handle b,
- std::vector<Simplex_handle> & buffer) const {
+ std::vector<Simplex> & buffer) const {
for (auto const & blocker : this->const_blocker_range(a)) {
- Simplex_handle beta = (*blocker);
+ Simplex beta = (*blocker);
beta.remove_vertex(a);
buffer.push_back(beta);
}
- Simplex_handle n;
+ Simplex n;
this->add_neighbours(b, n);
this->remove_neighbours(a, n);
n.remove_vertex(a);
for (Vertex_handle y : n) {
- Simplex_handle beta;
+ Simplex beta;
beta.add_vertex(y);
buffer.push_back(beta);
}
@@ -295,7 +313,7 @@ void Skeleton_blocker_complex<SkeletonBlockerDS>::tip_blockers(Vertex_handle a,
template<typename SkeletonBlockerDS>
void
Skeleton_blocker_complex<SkeletonBlockerDS>::swap_edge(Vertex_handle a, Vertex_handle b, Vertex_handle x) {
- this->add_edge(a, x);
+ this->add_edge_without_blockers(a, x);
if (this->visitor) this->visitor->on_swaped_edge(a, b, x);
this->remove_edge(b, x);
}
@@ -338,13 +356,15 @@ void
Skeleton_blocker_complex<SkeletonBlockerDS>::contract_edge(Vertex_handle a, Vertex_handle b) {
assert(this->contains_vertex(a));
assert(this->contains_vertex(b));
- assert(this->contains_edge(a, b));
- // if some blockers passes through 'ab', we remove them.
+ if (this->contains_edge(a, b))
+ this->add_edge_without_blockers(a, b);
+
+ // if some blockers passes through 'ab', we need to remove them.
if (!link_condition(a, b))
delete_blockers_around_edge(a, b);
- std::set<Simplex_handle> blockers_to_add;
+ std::set<Simplex> blockers_to_add;
get_blockers_to_be_added_after_contraction(a, b, blockers_to_add);
@@ -364,9 +384,8 @@ Skeleton_blocker_complex<SkeletonBlockerDS>::contract_edge(Vertex_handle a, Vert
}
template<typename SkeletonBlockerDS>
-void
-Skeleton_blocker_complex<SkeletonBlockerDS>::get_blockers_to_be_added_after_contraction(Vertex_handle a, Vertex_handle b,
- std::set<Simplex_handle>& blockers_to_add) {
+void Skeleton_blocker_complex<SkeletonBlockerDS>::get_blockers_to_be_added_after_contraction(Vertex_handle a,
+ Vertex_handle b, std::set<Simplex>& blockers_to_add) {
blockers_to_add.clear();
typedef Skeleton_blocker_link_complex<Skeleton_blocker_complex<SkeletonBlockerDS> > LinkComplexType;
@@ -374,19 +393,19 @@ Skeleton_blocker_complex<SkeletonBlockerDS>::get_blockers_to_be_added_after_cont
LinkComplexType link_a(*this, a);
LinkComplexType link_b(*this, b);
- std::vector<Simplex_handle> vector_alpha, vector_beta;
+ std::vector<Simplex> vector_alpha, vector_beta;
tip_blockers(a, b, vector_alpha);
tip_blockers(b, a, vector_beta);
for (auto alpha = vector_alpha.begin(); alpha != vector_alpha.end(); ++alpha) {
for (auto beta = vector_beta.begin(); beta != vector_beta.end(); ++beta) {
- Simplex_handle sigma = *alpha;
+ Simplex sigma = *alpha;
sigma.union_vertices(*beta);
Root_simplex_handle sigma_id = this->get_id(sigma);
if (this->contains(sigma) &&
proper_faces_in_union<Skeleton_blocker_complex < SkeletonBlockerDS >> (sigma_id, link_a, link_b)) {
- // Blocker_handle blocker = new Simplex_handle(sigma);
+ // Blocker_handle blocker = new Simplex(sigma);
sigma.add_vertex(a);
blockers_to_add.insert(sigma);
}
@@ -444,4 +463,4 @@ Skeleton_blocker_complex<SkeletonBlockerDS>::notify_changed_edges(Vertex_handle
} // namespace Gudhi
-#endif // SRC_SKELETON_BLOCKER_INCLUDE_GUDHI_SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
+#endif // SKELETON_BLOCKER_SIMPLIFIABLE_COMPLEX_H_
diff --git a/src/Skeleton_blocker/test/CMakeLists.txt b/src/Skeleton_blocker/test/CMakeLists.txt
index e62600a2..8b6fb672 100644
--- a/src/Skeleton_blocker/test/CMakeLists.txt
+++ b/src/Skeleton_blocker/test/CMakeLists.txt
@@ -18,6 +18,10 @@ add_executable(TestSkeletonBlockerComplex TestSkeletonBlockerComplex.cpp)
add_executable(TestSimplifiable TestSimplifiable.cpp)
add_executable(TestGeometricComplex TestGeometricComplex.cpp)
+# Do not forget to copy test files in current binary dir
+file(COPY "test.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+file(COPY "test2.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
add_test(TestSkeletonBlockerComplex ${CMAKE_CURRENT_BINARY_DIR}/TestSkeletonBlockerComplex)
add_test(TestSimplifiable ${CMAKE_CURRENT_BINARY_DIR}/TestSimplifiable)
add_test(TestGeometricComplex ${CMAKE_CURRENT_BINARY_DIR}/TestGeometricComplex)
diff --git a/src/Skeleton_blocker/test/TestGeometricComplex.cpp b/src/Skeleton_blocker/test/TestGeometricComplex.cpp
index bd7af89b..084e2b6b 100644
--- a/src/Skeleton_blocker/test/TestGeometricComplex.cpp
+++ b/src/Skeleton_blocker/test/TestGeometricComplex.cpp
@@ -1,24 +1,24 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
- */
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 <stdio.h>
#include <stdlib.h>
@@ -33,8 +33,8 @@ using namespace std;
using namespace Gudhi;
using namespace skbl;
-struct Geometry_trait{
- typedef std::vector<double> Point;
+struct Geometry_trait {
+ typedef std::vector<double> Point;
};
typedef Geometry_trait::Point Point;
@@ -42,79 +42,77 @@ typedef Skeleton_blocker_simple_geometric_traits<Geometry_trait> Complex_geometr
typedef Skeleton_blocker_geometric_complex< Complex_geometric_traits > Complex;
typedef Complex::Vertex_handle Vertex_handle;
+bool test_constructor1() {
+ Complex complex;
+ Skeleton_blocker_off_reader<Complex> off_reader("test2.off", complex);
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file" << std::endl;
+ return false;
+ }
-bool test_constructor1(){
- Complex complex;
- Skeleton_blocker_off_reader<Complex> off_reader("test2.off",complex);
- if(!off_reader.is_valid()){
- std::cerr << "Unable to read file"<<std::endl;
- return false;
- }
+ std::cout << "complex has " <<
+ complex.num_vertices() << " vertices, " <<
+ complex.num_blockers() << " blockers, " <<
+ complex.num_edges() << " edges and" <<
+ complex.num_triangles() << " triangles.";
- std::cout << "complex has "<<
- complex.num_vertices()<<" vertices, "<<
- complex.num_blockers()<<" blockers, "<<
- complex.num_edges()<<" edges and" <<
- complex.num_triangles()<<" triangles.";
+ if (complex.num_vertices() != 7 || complex.num_edges() != 12 || complex.num_triangles() != 6)
+ return false;
- if(complex.num_vertices()!=7 || complex.num_edges()!=12 || complex.num_triangles() !=6)
- return false;
+ Skeleton_blocker_off_writer<Complex> off_writer("tmp.off", complex);
+ Complex same;
+ Skeleton_blocker_off_reader<Complex> off_reader2("tmp.off", same);
- Skeleton_blocker_off_writer<Complex> off_writer("tmp.off",complex);
- Complex same;
- Skeleton_blocker_off_reader<Complex> off_reader2("tmp.off",same);
+ std::cout << "\ncomplex:" << complex.to_string() << endl;
+ std::cout << "\nsame:" << same.to_string() << endl;
- std::cout<<"\ncomplex:"<<complex.to_string()<<endl;
- std::cout<<"\nsame:"<<same.to_string()<<endl;
-
- return (complex==same);
+ return (complex == same);
}
-bool test_constructor2(){
- Complex complex;
- Skeleton_blocker_off_reader<Complex> off_reader("test2.off",complex);
- if(!off_reader.is_valid()){
- std::cerr << "Unable to read file"<<std::endl;
- return false;
- }
- std::cout << "complex has "<<
- complex.num_vertices()<<" vertices, "<<
- complex.num_blockers()<<" blockers, "<<
- complex.num_edges()<<" edges and" <<
- complex.num_triangles()<<" triangles.";
+bool test_constructor2() {
+ Complex complex;
+ Skeleton_blocker_off_reader<Complex> off_reader("test2.off", complex);
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file" << std::endl;
+ return false;
+ }
+ std::cout << "complex has " <<
+ complex.num_vertices() << " vertices, " <<
+ complex.num_blockers() << " blockers, " <<
+ complex.num_edges() << " edges and" <<
+ complex.num_triangles() << " triangles.";
- if(complex.num_vertices()!=7 || complex.num_edges()!=12 || complex.num_triangles() !=6)
- return false;
+ if (complex.num_vertices() != 7 || complex.num_edges() != 12 || complex.num_triangles() != 6)
+ return false;
- auto link_0 = complex.abstract_link(Vertex_handle(0));
+ auto link_0 = complex.abstract_link(Vertex_handle(0));
- std::cout<<"\n link(0):"<<link_0.to_string()<<endl;
+ std::cout << "\n link(0):" << link_0.to_string() << endl;
- auto link_geometric_0 = complex.link(Vertex_handle(0));
+ auto link_geometric_0 = complex.link(Vertex_handle(0));
- auto print_point = [&](Vertex_handle v){for(auto x : link_geometric_0.point(v)) std::cout <<x<<" "; std::cout<<std::endl;};
+ auto print_point = [&](Vertex_handle v) {
+ for (auto x : link_geometric_0.point(v)) std::cout << x << " ";
+ std::cout << std::endl;
+ };
- std::for_each(link_geometric_0.vertex_range().begin(),link_geometric_0.vertex_range().end(),print_point);
+ std::for_each(link_geometric_0.vertex_range().begin(), link_geometric_0.vertex_range().end(), print_point);
-// for(auto v : link_geometric_0.vertex_range())
-// std::cout<<"point("<<v<<"):"<<link_geometric_0.point(v)<<std::endl;
+ // for(auto v : link_geometric_0.vertex_range())
+ // std::cout<<"point("<<v<<"):"<<link_geometric_0.point(v)<<std::endl;
- return link_0.num_vertices()==2;
+ return link_0.num_vertices() == 2;
}
+int main(int argc, char *argv[]) {
+ Tests tests_geometric_complex;
+ tests_geometric_complex.add("Test constructor 1", test_constructor1);
+ tests_geometric_complex.add("Test constructor 2", test_constructor2);
-
-
-int main (int argc, char *argv[])
-{
- Tests tests_geometric_complex;
- tests_geometric_complex.add("Test constructor 1",test_constructor1);
- tests_geometric_complex.add("Test constructor 2",test_constructor2);
-
- if(tests_geometric_complex.run())
- return EXIT_SUCCESS;
- else
- return EXIT_FAILURE;
+ if (tests_geometric_complex.run())
+ return EXIT_SUCCESS;
+ else
+ return EXIT_FAILURE;
}
diff --git a/src/Skeleton_blocker/test/TestSimplifiable.cpp b/src/Skeleton_blocker/test/TestSimplifiable.cpp
index 09176934..b0855ce9 100644
--- a/src/Skeleton_blocker/test/TestSimplifiable.cpp
+++ b/src/Skeleton_blocker/test/TestSimplifiable.cpp
@@ -1,24 +1,24 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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/>.
- */
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 <stdio.h>
@@ -41,316 +41,382 @@ template<typename ComplexType> class Skeleton_blocker_sub_complex;
typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> Complex;
typedef Complex::Vertex_handle Vertex_handle;
typedef Complex::Root_vertex_handle Root_vertex_handle;
-typedef Skeleton_blocker_simplex<Vertex_handle> Simplex_handle;
+typedef Skeleton_blocker_simplex<Vertex_handle> Simplex;
// true iff v \in complex
-bool assert_vertex(Complex &complex,Vertex_handle v){
- Simplex_handle simplex(v);
- bool test = complex.contains(simplex);
- assert(test);
- return test;
+
+bool assert_vertex(Complex &complex, Vertex_handle v) {
+ Simplex simplex(v);
+ bool test = complex.contains(simplex);
+ assert(test);
+ return test;
}
// true iff the blocker (a,b,c) is in complex
-bool assert_blocker(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c){
- return complex.contains_blocker(Simplex_handle(*complex.get_address(a),*complex.get_address(b),*complex.get_address(c)));
- //return complex.contains_blocker((a),(b),(c));
+bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) {
+
+ return complex.contains_blocker(Simplex(*complex.get_address(a), *complex.get_address(b), *complex.get_address(c)));
+ //return complex.contains_blocker((a),(b),(c));
}
-void build_complete(int n,Complex& complex){
- complex.clear();
- for(int i=0;i<n;i++)
- complex.add_vertex();
- for(int i=0;i<n;i++)
- for(int j=0;j<i;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
+void build_complete(int n, Complex& complex) {
+ complex.clear();
+ for (int i = 0; i < n; i++)
+ complex.add_vertex();
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < i; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
}
-bool test_contraction1(){
- enum { a, b, x, y, z, n };
- Complex complex(n);
- build_complete(n,complex);
- complex.remove_edge(static_cast<Vertex_handle>(b), static_cast<Vertex_handle>(z));
- complex.add_blocker(Simplex_handle(static_cast<Vertex_handle>(a), static_cast<Vertex_handle>(x),
- static_cast<Vertex_handle>(y)));
- complex.add_blocker(Simplex_handle(static_cast<Vertex_handle>(b), static_cast<Vertex_handle>(x),
- static_cast<Vertex_handle>(y)));
-
- // Print result
- cerr << "complex before complex"<< complex.to_string()<<endl;
-
- cerr <<endl<<endl;
- complex.contract_edge(static_cast<Vertex_handle>(a),static_cast<Vertex_handle>(b));
- // Print result
- cerr << "ContractEdge(0,1)\n";
- PRINT(complex.to_string());
-
- // verification
- for (int i=0;i<5;i++)
- if (i!=1) assert_vertex(complex, static_cast<Vertex_handle>(i));
- bool test1 = !complex.contains_edge(static_cast<Vertex_handle>(a),static_cast<Vertex_handle>(b));
- bool test2 = assert_blocker(complex,Root_vertex_handle(a),Root_vertex_handle(x),Root_vertex_handle(y));
- bool test3 = complex.num_edges()==6;
- bool test4 = complex.num_blockers()==1;
- Simplex_handle sigma;
- sigma.add_vertex(static_cast<Vertex_handle>(a));
- sigma.add_vertex(static_cast<Vertex_handle>(x));
- sigma.add_vertex(static_cast<Vertex_handle>(y));
- sigma.add_vertex(static_cast<Vertex_handle>(z));
- bool test5 = !(complex.contains(sigma));
- return test1&&test2&&test3&&test4&&test5;
+bool test_contraction1() {
+
+ enum {
+ a, b, x, y, z, n
+ };
+ Complex complex(n);
+ build_complete(n, complex);
+ complex.remove_edge(static_cast<Vertex_handle> (b), static_cast<Vertex_handle> (z));
+ complex.add_blocker(Simplex(static_cast<Vertex_handle> (a), static_cast<Vertex_handle> (x),
+ static_cast<Vertex_handle> (y)));
+ complex.add_blocker(Simplex(static_cast<Vertex_handle> (b), static_cast<Vertex_handle> (x),
+ static_cast<Vertex_handle> (y)));
+
+ // Print result
+ cerr << "complex before complex" << complex.to_string() << endl;
+
+ cerr << endl << endl;
+ complex.contract_edge(static_cast<Vertex_handle> (a), static_cast<Vertex_handle> (b));
+ // Print result
+ cerr << "ContractEdge(0,1)\n";
+ PRINT(complex.to_string());
+
+ // verification
+ for (int i = 0; i < 5; i++)
+ if (i != 1) assert_vertex(complex, static_cast<Vertex_handle> (i));
+ bool test1 = !complex.contains_edge(static_cast<Vertex_handle> (a), static_cast<Vertex_handle> (b));
+ bool test2 = assert_blocker(complex, Root_vertex_handle(a), Root_vertex_handle(x), Root_vertex_handle(y));
+ bool test3 = complex.num_edges() == 6;
+ bool test4 = complex.num_blockers() == 1;
+ Simplex sigma;
+ sigma.add_vertex(static_cast<Vertex_handle> (a));
+ sigma.add_vertex(static_cast<Vertex_handle> (x));
+ sigma.add_vertex(static_cast<Vertex_handle> (y));
+ sigma.add_vertex(static_cast<Vertex_handle> (z));
+ bool test5 = !(complex.contains(sigma));
+ return test1 && test2 && test3 && test4&&test5;
}
+bool test_contraction2() {
-bool test_contraction2(){
- enum { a, b, x, y, z, n };
- Complex complex(n);
- build_complete(n,complex);
- complex.remove_edge(static_cast<Vertex_handle>(b),static_cast<Vertex_handle>(x));
- Simplex_handle blocker;
- blocker.add_vertex(static_cast<Vertex_handle>(a));
- blocker.add_vertex(static_cast<Vertex_handle>(y));
- blocker.add_vertex(static_cast<Vertex_handle>(z));
+ enum {
+ a, b, x, y, z, n
+ };
+ Complex complex(n);
+ build_complete(n, complex);
+ complex.remove_edge(static_cast<Vertex_handle> (b), static_cast<Vertex_handle> (x));
+ Simplex blocker;
+ blocker.add_vertex(static_cast<Vertex_handle> (a));
+ blocker.add_vertex(static_cast<Vertex_handle> (y));
+ blocker.add_vertex(static_cast<Vertex_handle> (z));
- complex.add_blocker(blocker);
+ complex.add_blocker(blocker);
- // Print result
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl;
- complex.contract_edge(static_cast<Vertex_handle>(a),static_cast<Vertex_handle>(b));
+ // Print result
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
+ complex.contract_edge(static_cast<Vertex_handle> (a), static_cast<Vertex_handle> (b));
- cerr << "complex.ContractEdge(a,b)"<< complex.to_string();
+ cerr << "complex.ContractEdge(a,b)" << complex.to_string();
- cerr <<endl<<endl;
+ cerr << endl << endl;
- // there should be one blocker (a,c,d,e) in the complex
- bool test ;
- test = complex.contains_blocker(Simplex_handle(static_cast<Vertex_handle>(a), static_cast<Vertex_handle>(x),
- static_cast<Vertex_handle>(y),static_cast<Vertex_handle>(z)));
- test = test && complex.num_blockers()==1;
- return test;
+ // there should be one blocker (a,c,d,e) in the complex
+ bool test;
+ test = complex.contains_blocker(Simplex(static_cast<Vertex_handle> (a), static_cast<Vertex_handle> (x),
+ static_cast<Vertex_handle> (y), static_cast<Vertex_handle> (z)));
+ test = test && complex.num_blockers() == 1;
+ return test;
}
-bool test_link_condition1(){
+bool test_link_condition1() {
- Complex complex(0);
- // Build the complexes
- build_complete(4,complex);
- complex.add_blocker(Simplex_handle(static_cast<Vertex_handle>(0), static_cast<Vertex_handle>(1), static_cast<Vertex_handle>(2)));
+ Complex complex(0);
+ // Build the complexes
+ build_complete(4, complex);
+ complex.add_blocker(Simplex(static_cast<Vertex_handle> (0), static_cast<Vertex_handle> (1), static_cast<Vertex_handle> (2)));
- // Print result
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl;
+ // Print result
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
- bool weak_link_condition = complex.link_condition(Vertex_handle(1),Vertex_handle(2),true);
+ bool weak_link_condition = complex.link_condition(Vertex_handle(1), Vertex_handle(2), true);
- bool strong_link_condition = complex.link_condition(Vertex_handle(1),Vertex_handle(2),false);
+ bool strong_link_condition = complex.link_condition(Vertex_handle(1), Vertex_handle(2), false);
- return weak_link_condition && !strong_link_condition;
+ return weak_link_condition && !strong_link_condition;
}
-
-bool test_collapse0(){
- Complex complex(5);
- build_complete(4,complex);
- complex.add_vertex();
- complex.add_edge(static_cast<Vertex_handle>(2), static_cast<Vertex_handle>(4));
- complex.add_edge(static_cast<Vertex_handle>(3), static_cast<Vertex_handle>(4));
- // Print result
- cerr << "initial complex :\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- Simplex_handle simplex_123(static_cast<Vertex_handle>(1), static_cast<Vertex_handle>(2), static_cast<Vertex_handle>(3));
- complex.remove_star(simplex_123);
- cerr << "complex.remove_star(1,2,3):\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- // verification
- bool blocker123_here = complex.contains_blocker(simplex_123);
- cerr <<"----> Ocomplex \n";
- return blocker123_here;
+bool test_collapse0() {
+ Complex complex(5);
+ build_complete(4, complex);
+ complex.add_vertex();
+ complex.add_edge_without_blockers(static_cast<Vertex_handle> (2), static_cast<Vertex_handle> (4));
+ complex.add_edge_without_blockers(static_cast<Vertex_handle> (3), static_cast<Vertex_handle> (4));
+ // Print result
+ cerr << "initial complex :\n" << complex.to_string();
+ cerr << endl << endl;
+
+ Simplex simplex_123(static_cast<Vertex_handle> (1), static_cast<Vertex_handle> (2), static_cast<Vertex_handle> (3));
+ complex.remove_star(simplex_123);
+ cerr << "complex.remove_star(1,2,3):\n" << complex.to_string();
+ cerr << endl << endl;
+
+ // verification
+ bool blocker123_here = complex.contains_blocker(simplex_123);
+ cerr << "----> Ocomplex \n";
+ return blocker123_here;
}
-
-bool test_collapse1(){
- Complex complex(5);
- build_complete(4,complex);
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
- // Print result
- cerr << "initial complex :\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- Simplex_handle simplex_123(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3));
- complex.remove_star(simplex_123);
- cerr << "complex.remove_star(1,2,3):\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- // verification
- bool res = complex.contains_blocker(simplex_123);
- res = res && complex.num_blockers()==1;
- cerr <<"----> Ocomplex \n";
- return res;
+bool test_collapse1() {
+ Complex complex(5);
+ build_complete(4, complex);
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)));
+ // Print result
+ cerr << "initial complex :\n" << complex.to_string();
+ cerr << endl << endl;
+
+ Simplex simplex_123(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3));
+ complex.remove_star(simplex_123);
+ cerr << "complex.remove_star(1,2,3):\n" << complex.to_string();
+ cerr << endl << endl;
+
+ // verification
+ bool res = complex.contains_blocker(simplex_123);
+ res = res && complex.num_blockers() == 1;
+ cerr << "----> Ocomplex \n";
+ return res;
}
-bool test_collapse2(){
- Complex complex(5);
- build_complete(4,complex);
- complex.add_vertex();
- complex.add_edge(Vertex_handle(1),Vertex_handle(4));
- complex.add_edge(Vertex_handle(2),Vertex_handle(4));
- complex.add_edge(Vertex_handle(3),Vertex_handle(4));
- complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)));
- // Print result
- cerr << "initial complex :\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- Simplex_handle sigma(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3));
- complex.remove_star(sigma);
- cerr << "complex.remove_star(1,2,3):\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- // verification
- bool blocker_removed = !complex.contains_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)));
- bool blocker123_here = complex.contains_blocker(sigma);
- return blocker_removed && blocker123_here;
+bool test_collapse2() {
+ Complex complex(5);
+ build_complete(4, complex);
+ complex.add_vertex();
+ complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4));
+ complex.add_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3), Vertex_handle(4)));
+ // Print result
+ cerr << "initial complex :\n" << complex.to_string();
+ cerr << endl << endl;
+
+ Simplex sigma(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3));
+ complex.remove_star(sigma);
+ cerr << "complex.remove_star(1,2,3):\n" << complex.to_string();
+ cerr << endl << endl;
+
+ // verification
+ bool blocker_removed = !complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3), Vertex_handle(4)));
+ bool blocker123_here = complex.contains_blocker(sigma);
+ return blocker_removed && blocker123_here;
}
-bool test_collapse3(){
- Complex complex(5);
- build_complete(4,complex);
- complex.add_vertex();
- complex.add_edge(Vertex_handle(1),Vertex_handle(4));
- complex.add_edge(Vertex_handle(2),Vertex_handle(4));
- complex.add_edge(Vertex_handle(3),Vertex_handle(4));
- complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)));
- // Print result
- cerr << "initial complex:\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- complex.remove_star(static_cast<Vertex_handle>(2));
- cerr << "complex after remove star of 2:\n"<< complex.to_string();
-
- bool blocker134_here = complex.contains_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(3),Vertex_handle(4)));
- bool blocker1234_here = complex.contains_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)));
- return blocker134_here && !blocker1234_here;
+bool test_collapse3() {
+ Complex complex(5);
+ build_complete(4, complex);
+ complex.add_vertex();
+ complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4));
+ complex.add_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3), Vertex_handle(4)));
+ // Print result
+ cerr << "initial complex:\n" << complex.to_string();
+ cerr << endl << endl;
+
+ complex.remove_star(static_cast<Vertex_handle> (2));
+ cerr << "complex after remove star of 2:\n" << complex.to_string();
+
+ bool blocker134_here = complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(3), Vertex_handle(4)));
+ bool blocker1234_here = complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3), Vertex_handle(4)));
+ return blocker134_here && !blocker1234_here;
}
-bool test_add_simplex(){
- Complex complex(5);
- build_complete(4,complex);
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
- // Print result
- cerr << "initial complex:\n"<< complex.to_string();
- cerr <<endl<<endl;
-
- complex.add_simplex(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
- cerr << "complex after add_simplex:\n"<< complex.to_string();
-
- return complex.num_blockers()==0;
+bool test_add_simplex() {
+ Complex complex(4);
+ build_complete(4, complex);
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(3)));
+ cerr << "initial complex:\n" << complex.to_string();
+ cerr << endl << endl;
+
+ complex.add_simplex(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(3)));
+ cerr << "complex after add_simplex:\n" << complex.to_string();
+ return complex.num_blockers() == 1
+ && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)));
}
-bool test_add_simplex2(){
- Complex complex;
- build_complete(4,complex);
- // Print result
- cerr << "initial complex:\n"<< complex.to_string();
- cerr <<endl<<endl;
+bool test_add_simplex2() {
+ Complex complex;
+ build_complete(4, complex);
+ // Print result
+ cerr << "initial complex:\n" << complex.to_string();
+ cerr << endl << endl;
- Complex copy(complex.num_vertices());
+ Complex copy(complex.num_vertices());
- std::vector<Simplex_handle> simplices(complex.simplex_range().begin(),complex.simplex_range().end());
- sort(simplices.begin(),simplices.end(),[&](const Simplex_handle& s1,const Simplex_handle& s2){
- return s1.dimension()<s2.dimension();
- });
- for(const auto & simplex : simplices){
- if(!copy.contains(simplex) && simplex.dimension()==1)
- copy.add_edge(simplex.first_vertex(),simplex.last_vertex());
- if(!copy.contains(simplex) && simplex.dimension()>1)
- copy.add_simplex(simplex);
- }
+ std::vector<Simplex> simplices(complex.complex_simplex_range().begin(), complex.complex_simplex_range().end());
+ sort(simplices.begin(), simplices.end(), [&](const Simplex& s1, const Simplex & s2) {
+ return s1.dimension() < s2.dimension();
+ });
+ for (const auto & simplex : simplices) {
+ if (!copy.contains(simplex) && simplex.dimension() == 1)
+ copy.add_edge_without_blockers(simplex.first_vertex(), simplex.last_vertex());
+ if (!copy.contains(simplex) && simplex.dimension() > 1)
+ copy.add_simplex(simplex);
+ }
- cerr << "complex after add_simplex:\n"<< copy.to_string();
+ cerr << "complex after add_simplex:\n" << copy.to_string();
- return complex.num_blockers()==copy.num_blockers() &&
- complex.num_edges()==copy.num_edges() &&
- complex.num_vertices()==copy.num_vertices();
+ return complex.num_blockers() == copy.num_blockers() &&
+ complex.num_edges() == copy.num_edges() &&
+ complex.num_vertices() == copy.num_vertices();
}
+bool test_add_simplex3() {
+ Complex complex(5);
+ build_complete(5, complex);
+ complex.remove_edge(Vertex_handle(3), Vertex_handle(4));
+ Simplex sigma(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2));
+ complex.add_blocker(sigma);
+ // Print result
+ cerr << "initial complex:\n" << complex.to_string();
+ cerr << endl << endl;
+ complex.add_simplex(sigma);
+ //should create two blockers 0123 and 0124
+ cerr << "complex after adding simplex 012:\n" << complex.to_string();
+ return complex.num_blockers() == 2
+ && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)))
+ && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(4)));
+}
-
-bool test_remove_popable_blockers(){
- Complex complex;
- build_complete(4,complex);
- complex.add_vertex();
- complex.add_edge(Vertex_handle(3),Vertex_handle(4));
- complex.add_edge(Vertex_handle(2),Vertex_handle(4));
- Simplex_handle sigma1=Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3));
- Simplex_handle sigma2=Simplex_handle(Vertex_handle(2),Vertex_handle(3),Vertex_handle(4));
-
- complex.add_blocker(sigma1);
- complex.add_blocker(sigma2);
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl;
- cerr << "complex.RemovePopableBlockers();"<<endl;
- complex.remove_popable_blockers();
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl;
-
- bool test1 = (complex.num_blockers()==1);
-
-
- // test 2
- complex.clear();
- build_complete(4,complex);
- complex.add_vertex();
- complex.add_vertex();
- complex.add_edge(Vertex_handle(3),Vertex_handle(4));
- complex.add_edge(Vertex_handle(2),Vertex_handle(4));
- complex.add_edge(Vertex_handle(2),Vertex_handle(5));
- complex.add_edge(Vertex_handle(3),Vertex_handle(5));
- complex.add_edge(Vertex_handle(4),Vertex_handle(5));
- sigma1=Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3));
- sigma2=Simplex_handle(Vertex_handle(2),Vertex_handle(3),Vertex_handle(4));
-
- complex.add_blocker(sigma1);
- complex.add_blocker(sigma2);
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl; cerr << "complex.RemovePopableBlockers();"<<endl;
- complex.remove_popable_blockers();
- cerr << "complex complex"<< complex.to_string();
-
- cerr <<endl<<endl;
- bool test2 = (complex.num_blockers()==0);
- return test1&&test2;
+bool test_add_simplex4() {
+ int n = 6;
+ Complex complex(n);
+
+ // add all simplex 0..n without i
+ for (int i = 0; i < n; i++) {
+ Simplex s;
+ for (int k = 0; k < n; k++)
+ s.add_vertex(Vertex_handle(k));
+ s.remove_vertex(Vertex_handle(i));
+ complex.add_simplex(s);
+
+ //at step i there is only blocker 0..i
+ if (i < 2 && complex.num_blockers() > 0)
+ return false;
+ if (i >= 2 && complex.num_blockers() != 1) {
+ Simplex b;
+ for (int k = 0; k < i; k++)
+ b.add_vertex(Vertex_handle(i));
+ if (!complex.contains_blocker(b))
+ return false;
+ }
+ TESTVALUE(complex.blockers_to_string());
+ }
+ Simplex s;
+ for (int k = 0; k < n; k++)
+ s.add_vertex(Vertex_handle(k));
+ return complex.num_blockers() == 1 && complex.contains_blocker(s);
}
+bool test_add_edge() {
+ Complex complex(4);
+ for (unsigned i = 0u; i < 4; i++)
+ complex.add_edge(Vertex_handle(i), Vertex_handle((i + 1) % 4));
+
+ // Print result
+ cerr << "initial complex:\n" << complex.to_string();
+ cerr << endl << endl;
+ complex.add_edge(Vertex_handle(1), Vertex_handle(3));
+ //should create two blockers 013 and 012
+ cerr << "complex after adding edge 13:\n" << complex.to_string();
+ return complex.num_blockers() == 2
+ && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(3)))
+ && complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)));
+}
+bool test_remove_popable_blockers() {
+ Complex complex;
+ build_complete(4, complex);
+ complex.add_vertex();
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4));
+ Simplex sigma1 = Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3));
+ Simplex sigma2 = Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4));
+
+ complex.add_blocker(sigma1);
+ complex.add_blocker(sigma2);
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
+ cerr << "complex.RemovePopableBlockers();" << endl;
+ complex.remove_popable_blockers();
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
+
+ bool test1 = (complex.num_blockers() == 1);
+
+
+ // test 2
+ complex.clear();
+ build_complete(4, complex);
+ complex.add_vertex();
+ complex.add_vertex();
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(5));
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(5));
+ complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(5));
+ sigma1 = Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3));
+ sigma2 = Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4));
+
+ complex.add_blocker(sigma1);
+ complex.add_blocker(sigma2);
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
+ cerr << "complex.RemovePopableBlockers();" << endl;
+ complex.remove_popable_blockers();
+ cerr << "complex complex" << complex.to_string();
+
+ cerr << endl << endl;
+ bool test2 = (complex.num_blockers() == 0);
+ return test1&&test2;
+}
-int main (int argc, char *argv[])
-{
- Tests tests_simplifiable_complex;
- tests_simplifiable_complex.add("Test contraction 1",test_contraction1);
- tests_simplifiable_complex.add("Test contraction 2",test_contraction2);
- tests_simplifiable_complex.add("Test Link condition 1",test_link_condition1);
- tests_simplifiable_complex.add("Test remove popable blockers",test_remove_popable_blockers);
+int main(int argc, char *argv[]) {
+ Tests tests_simplifiable_complex;
+ tests_simplifiable_complex.add("Test contraction 1", test_contraction1);
+ tests_simplifiable_complex.add("Test contraction 2", test_contraction2);
+ tests_simplifiable_complex.add("Test Link condition 1", test_link_condition1);
+ tests_simplifiable_complex.add("Test remove popable blockers", test_remove_popable_blockers);
- tests_simplifiable_complex.add("Test collapse 0",test_collapse0);
- tests_simplifiable_complex.add("Test collapse 1",test_collapse1);
- tests_simplifiable_complex.add("Test collapse 2",test_collapse2);
- tests_simplifiable_complex.add("Test collapse 3",test_collapse3);
+ tests_simplifiable_complex.add("Test collapse 0", test_collapse0);
+ tests_simplifiable_complex.add("Test collapse 1", test_collapse1);
+ tests_simplifiable_complex.add("Test collapse 2", test_collapse2);
+ tests_simplifiable_complex.add("Test collapse 3", test_collapse3);
- tests_simplifiable_complex.add("Test add simplex",test_add_simplex);
- tests_simplifiable_complex.add("Test add simplex2",test_add_simplex2);
+ tests_simplifiable_complex.add("Test add edge",test_add_edge);
+ tests_simplifiable_complex.add("Test add simplex", test_add_simplex);
+ tests_simplifiable_complex.add("Test add simplex2", test_add_simplex2);
+ tests_simplifiable_complex.add("Test add simplex3",test_add_simplex3);
+ tests_simplifiable_complex.add("Test add simplex4",test_add_simplex4);
- tests_simplifiable_complex.run();
+ tests_simplifiable_complex.run();
- if(tests_simplifiable_complex.run())
- return EXIT_SUCCESS;
- else
- return EXIT_FAILURE;
+ if (tests_simplifiable_complex.run())
+ return EXIT_SUCCESS;
+ else
+ return EXIT_FAILURE;
}
diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp
index 3dc38572..42482e23 100644
--- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp
+++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp
@@ -42,911 +42,911 @@ using namespace skbl;
typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> Complex;
typedef Complex::Vertex_handle Vertex_handle;
typedef Complex::Root_vertex_handle Root_vertex_handle;
-typedef Complex::Simplex_handle Simplex_handle;
+typedef Complex::Simplex Simplex;
typedef Complex::Root_simplex_handle Root_simplex_handle;
-typedef Simplex_handle::Simplex_vertex_const_iterator Simplex_vertex_const_iterator;
+typedef Simplex::Simplex_vertex_const_iterator Simplex_vertex_const_iterator;
typedef Complex::Edge_handle Edge_handle;
// true if v in complex
-bool assert_vertex(Complex &complex,Vertex_handle v){
- //assert(complex.contains(v));
- return complex.contains(static_cast<Simplex_handle>(v));
-}
-
-bool assert_simplex(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c){
- return true;
- // AddressSimplex simplex((a),(b),(c));
- // return complex.contains(&simplex);
-}
-// true iff the blocker (a,b,c) is in complex
-bool assert_blocker(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c){
- return true;
- //return complex.contains_blocker((a),(b),(c));
+bool assert_vertex(Complex &complex, Vertex_handle v) {
+ //assert(complex.contains(v));
+ return complex.contains(static_cast<Simplex> (v));
}
-// true iff the blocker (a,b,c,d) is in complex
-bool assert_blocker(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c,Root_vertex_handle d){
- return true;
- //Simplex blocker (a,b,c,d);
- //return complex.contains_blocker(&blocker);
-}
-
-
-
-void build_complete(int n,Complex& complex){
- complex.clear();
- for(int i=0;i<n;i++)
- complex.add_vertex();
-
- // for(int i=n-1;i>=0;i--)
- // for(int j=i-1;j>=0;j--)
- // complex.add_edge(Vertex_handle(i),Vertex_handle(j));
-
- for(int i=0;i<n;i++)
- for(int j=0;j<i;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
-}
-
-
-bool test_simplex(){
- // PRINT("test simplex");
- Simplex_handle simplex(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3));
- for (auto i = simplex.begin() ; i != simplex.end() ; ++i){
- PRINT(*i);
- auto j = i;
- for (++j ;
- j != simplex.end() ;
- ++j){
- PRINT(*j);
- }
- }
- return simplex.dimension()==3;
-}
-
-
-bool test_iterator_vertices1(){
- int n = 10;
- Complex complex(10);
- cerr << "complex.num_vertices():"<<complex.num_vertices()<<endl;
- int num_vertex_seen = 0;
- for(auto vi :complex.vertex_range()){
- cerr << "vertex:"<<vi<<endl;
- ++num_vertex_seen;
- }
- return num_vertex_seen == n;
-}
-
-bool test_iterator_vertices2(){
- int n = 10;
- Complex complex(10);
- build_complete(10,complex);
- cerr << "complex.num_vertices():"<<complex.num_vertices()<<endl;
- cerr << "complex.num_edges():"<<complex.num_edges()<<endl;
- int num_vertex_seen = 0;
- for(auto vi :complex.vertex_range(Vertex_handle(2))){
- cerr << "vertex:"<<vi<<endl;
- ++num_vertex_seen;
- }
- std::cerr<<"num_vertex_seen:"<<num_vertex_seen<<std::endl;
- return num_vertex_seen == (n-1);
-}
-
-
-
-bool test_iterator_edge(){
- const int n = 10;
- Complex complex(n);
- for(int i=0;i<n;i++)
- for(int j=0;j<i;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- complex.remove_edge(Vertex_handle(2),Vertex_handle(3));
- complex.remove_edge(Vertex_handle(3),Vertex_handle(5));
- cerr << "complex.num_edges():"<<complex.num_edges()<<endl;
- int num_edges_seen = 0;
- for(auto edge : complex.edge_range()){
- cerr << "edge :"<<complex[edge]<<endl;
- ++num_edges_seen;
- }
-
- return num_edges_seen == n*(n-1)/2-2;
-}
-
-bool test_iterator_edge2(){
- const int n = 10;
- Complex complex(n);
- for(int i=0;i<n;i++)
- for(int j=0;j<i;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- complex.remove_edge(Vertex_handle(2),Vertex_handle(3));
- complex.remove_edge(Vertex_handle(3),Vertex_handle(5));
- cerr << "complex.num_edges():"<<complex.num_edges()<<endl;
- int num_neigbors_seen = 0;
- for(auto neighbor : complex.vertex_range(Vertex_handle(2))){
- cerr << "neighbor"<<neighbor<<endl;
- ++num_neigbors_seen;
- }
- return num_neigbors_seen==8;
-}
-
-
-
-bool test_iterator_edge3(){
- const int n = 10;
- Complex complex(n);
- for(int i=0;i<n;i++)
- for(int j=0;j<i;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- complex.remove_edge(Vertex_handle(2),Vertex_handle(3));
- complex.remove_edge(Vertex_handle(3),Vertex_handle(5));
- cerr << "complex.num_edges():"<<complex.num_edges()<<endl;
- int num_neigbors_seen = 0;
- for(auto edge : complex.edge_range(Vertex_handle(2))){
- std::cerr << edge<< std::endl;
- ++num_neigbors_seen;
- }
- return num_neigbors_seen==8;
-}
-
-
-
-bool test_iterator_triangles(){
- const int n = 7;
- Complex complex(n);
- //create a "ring" around '0'
- for(int i=1;i<n;i++)
- complex.add_edge(Vertex_handle(0),Vertex_handle(i));
- for(int i=1;i<n-1;i++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(i+1));
- complex.add_edge(Vertex_handle(1),Vertex_handle(6));
-
- PRINT(complex.to_string());
-
- int num_triangles_seen=0;
- //for (auto t : complex.triangle_range(5)){
- TEST("triangles around 5 (should be 2 of them):");
- for (auto t : complex.triangle_range(Vertex_handle(5))){
- PRINT(t);
- ++num_triangles_seen;
- }
- bool test = (num_triangles_seen==2);
-
- num_triangles_seen=0;
- TEST("triangles around 0 (should be 6 of them):");
- for (auto t : complex.triangle_range(Vertex_handle(0))){
- PRINT(t);
- ++num_triangles_seen;
- }
- test = test&&(num_triangles_seen==6);
-
- // we now add another triangle
- complex.add_vertex();
- complex.add_edge(Vertex_handle(4),Vertex_handle(7));
- complex.add_edge(Vertex_handle(3),Vertex_handle(7));
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(6)));
- num_triangles_seen=0;
-
- TEST("triangles (should be 6 of them):");
- num_triangles_seen=0;
- for (auto t : complex.triangle_range()){
- PRINT(t);
- ++num_triangles_seen;
- }
- test = test&&(num_triangles_seen==6);
- PRINT(num_triangles_seen);
-
- return test;
+bool assert_simplex(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) {
+ return true;
+ // AddressSimplex simplex((a),(b),(c));
+ // return complex.contains(&simplex);
}
+// true iff the blocker (a,b,c) is in complex
-//#include "combinatorics/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h"
-
-bool test_iterator_simplices(){
- Complex complex(6);
- complex.add_edge(Vertex_handle(0),Vertex_handle(1));
- complex.add_edge(Vertex_handle(1),Vertex_handle(2));
- complex.add_edge(Vertex_handle(2),Vertex_handle(0));
- complex.add_edge(Vertex_handle(1),Vertex_handle(3));
- complex.add_edge(Vertex_handle(2),Vertex_handle(3));
- complex.add_edge(Vertex_handle(2),Vertex_handle(5));
- complex.add_edge(Vertex_handle(3),Vertex_handle(5));
- complex.add_edge(Vertex_handle(2),Vertex_handle(4));
- complex.add_edge(Vertex_handle(4),Vertex_handle(5));
- complex.add_edge(Vertex_handle(3),Vertex_handle(4));
-
- complex.add_blocker(Simplex_handle(Vertex_handle(2),Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)));
-
- bool correct_number_simplices = true;
-
- std::map<Vertex_handle,unsigned> expected_num_simplices;
-
- expected_num_simplices[Vertex_handle(0)] = 4;
- expected_num_simplices[Vertex_handle(1)] = 6;
- expected_num_simplices[Vertex_handle(2)] = 11;
- expected_num_simplices[Vertex_handle(3)] = 9;
- expected_num_simplices[Vertex_handle(4)] = 7;
- expected_num_simplices[Vertex_handle(5)] = 7;
-
- for(auto pair : expected_num_simplices){
- unsigned num_simplices_around = 0;
- for(const auto& simplex : complex.simplex_range(pair.first)){
- simplex.dimension();
- DBGVALUE(simplex);
- ++num_simplices_around;
- }
-
- correct_number_simplices = correct_number_simplices && (num_simplices_around == pair.second);
-
- DBGMSG("current vertex:",pair.first);
- DBGMSG("expected_num_simplices:",pair.second);
- DBGMSG("found:",num_simplices_around);
- }
- return correct_number_simplices;
+bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) {
+ return true;
+ //return complex.contains_blocker((a),(b),(c));
}
+// true iff the blocker (a,b,c,d) is in complex
-
-bool test_iterator_simplices2(){
- Complex complex(2);
- complex.add_edge(Vertex_handle(0),Vertex_handle(1));
-
- for(const auto& s:complex.triangle_range()){
- s.dimension();
- return false; // there are no triangles
- }
-
- unsigned num_simplices = 0 ;
-
-
- DBGVALUE(complex.to_string());
-
- for(const auto& simplex : complex.simplex_range(Vertex_handle(0))){
- simplex.dimension();
- DBGVALUE(simplex);
- }
-
-
- for(const auto& simplex : complex.simplex_range()){
- DBGVALUE(simplex);
- simplex.dimension();
- ++num_simplices;
- }
- bool correct_number_simplices = (num_simplices == 3);
- return correct_number_simplices;
+bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c, Root_vertex_handle d) {
+ return true;
+ //Simplex blocker (a,b,c,d);
+ //return complex.contains_blocker(&blocker);
+}
+
+void build_complete(int n, Complex& complex) {
+ complex.clear();
+ for (int i = 0; i < n; i++)
+ complex.add_vertex();
+
+ // for(int i=n-1;i>=0;i--)
+ // for(int j=i-1;j>=0;j--)
+ // complex.add_edge_without_blockers(Vertex_handle(i),Vertex_handle(j));
+
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < i; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+}
+
+bool test_simplex() {
+ // PRINT("test simplex");
+ Simplex simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3));
+ for (auto i = simplex.begin(); i != simplex.end(); ++i) {
+ PRINT(*i);
+ auto j = i;
+ for (++j;
+ j != simplex.end();
+ ++j) {
+ PRINT(*j);
+ }
+ }
+ return simplex.dimension() == 3;
+}
+
+bool test_num_simplices() {
+ int n = 4;
+ Complex complex;
+ build_complete(n, complex);
+ size_t sum = 0;
+ for (int i = 0; i < n; i++) {
+ PRINT(complex.num_simplices(i));
+ sum += complex.num_simplices(i);
+ }
+ return
+ complex.num_vertices() == n &&
+ complex.num_edges() == 6 &&
+ sum == 15 &&
+ complex.num_simplices() == 15;
+}
+
+
+bool test_iterator_vertices1() {
+ int n = 10;
+ Complex complex(10);
+ cerr << "complex.num_vertices():" << complex.num_vertices() << endl;
+ int num_vertex_seen = 0;
+ for (auto vi : complex.vertex_range()) {
+ cerr << "vertex:" << vi << endl;
+ ++num_vertex_seen;
+ }
+ return num_vertex_seen == n;
+}
+
+bool test_iterator_vertices2() {
+ int n = 10;
+ Complex complex;
+ build_complete(10, complex);
+ cerr << "complex.num_vertices():" << complex.num_vertices() << endl;
+ cerr << "complex.num_edges():" << complex.num_edges() << endl;
+ int num_vertex_seen = 0;
+ for (auto vi : complex.vertex_range(Vertex_handle(2))) {
+ cerr << "vertex:" << vi << endl;
+ ++num_vertex_seen;
+ }
+ std::cerr << "num_vertex_seen:" << num_vertex_seen << std::endl;
+ return num_vertex_seen == (n - 1);
+}
+
+bool test_iterator_edge() {
+ const int n = 10;
+ Complex complex(n);
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < i; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ complex.remove_edge(Vertex_handle(2), Vertex_handle(3));
+ complex.remove_edge(Vertex_handle(3), Vertex_handle(5));
+ cerr << "complex.num_edges():" << complex.num_edges() << endl;
+ int num_edges_seen = 0;
+ for (auto edge : complex.edge_range()) {
+ cerr << "edge :" << complex[edge] << endl;
+ ++num_edges_seen;
+ }
+
+ return num_edges_seen == n * (n - 1) / 2 - 2;
+}
+
+bool test_iterator_edge2() {
+ const int n = 10;
+ Complex complex(n);
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < i; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ complex.remove_edge(Vertex_handle(2), Vertex_handle(3));
+ complex.remove_edge(Vertex_handle(3), Vertex_handle(5));
+ cerr << "complex.num_edges():" << complex.num_edges() << endl;
+ int num_neigbors_seen = 0;
+ for (auto neighbor : complex.vertex_range(Vertex_handle(2))) {
+ cerr << "neighbor" << neighbor << endl;
+ ++num_neigbors_seen;
+ }
+ return num_neigbors_seen == 8;
+}
+
+bool test_iterator_edge3() {
+ const int n = 10;
+ Complex complex(n);
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < i; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ complex.remove_edge(Vertex_handle(2), Vertex_handle(3));
+ complex.remove_edge(Vertex_handle(3), Vertex_handle(5));
+ cerr << "complex.num_edges():" << complex.num_edges() << endl;
+ int num_neigbors_seen = 0;
+ for (auto edge : complex.edge_range(Vertex_handle(2))) {
+ std::cerr << edge << std::endl;
+ ++num_neigbors_seen;
+ }
+ return num_neigbors_seen == 8;
+}
+
+bool test_iterator_triangles() {
+ const int n = 7;
+ Complex complex(n);
+ //create a "ring" around '0'
+ for (int i = 1; i < n; i++)
+ complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(i));
+ for (int i = 1; i < n - 1; i++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(i + 1));
+ complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(6));
+
+ PRINT(complex.to_string());
+
+ int num_triangles_seen = 0;
+ //for (auto t : complex.triangle_range(5)){
+ TEST("triangles around 5 (should be 2 of them):");
+ for (auto t : complex.triangle_range(Vertex_handle(5))) {
+ PRINT(t);
+ ++num_triangles_seen;
+ }
+ bool test = (num_triangles_seen == 2);
+
+ num_triangles_seen = 0;
+ TEST("triangles around 0 (should be 6 of them):");
+ for (auto t : complex.triangle_range(Vertex_handle(0))) {
+ PRINT(t);
+ ++num_triangles_seen;
+ }
+ test = test && (num_triangles_seen == 6);
+
+ // we now add another triangle
+ complex.add_vertex();
+ complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(7));
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(7));
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(6)));
+ num_triangles_seen = 0;
+
+ TEST("triangles (should be 6 of them):");
+ num_triangles_seen = 0;
+ for (auto t : complex.triangle_range()) {
+ PRINT(t);
+ ++num_triangles_seen;
+ }
+ test = test && (num_triangles_seen == 6);
+ PRINT(num_triangles_seen);
+
+ return test;
}
-bool test_iterator_simplices3(){
- Complex complex(3);
- complex.add_edge(Vertex_handle(0),Vertex_handle(1));
- complex.add_edge(Vertex_handle(1),Vertex_handle(2));
- complex.add_edge(Vertex_handle(2),Vertex_handle(0));
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
-
- unsigned num_simplices = 0 ;
-
- for(const auto& simplex : complex.simplex_range(Vertex_handle(0))){
- simplex.dimension();
- DBGVALUE(simplex);
- }
-
+//#include "combinatorics/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h"
- for(const auto& simplex : complex.simplex_range()){
- DBGVALUE(simplex);
- simplex.dimension();
- ++num_simplices;
- }
- bool correct_number_simplices = (num_simplices == 6);
- return correct_number_simplices;
+bool test_iterator_simplices() {
+ Complex complex(6);
+ complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1));
+ complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(2));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(0));
+ complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(3));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(3));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(5));
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(5));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4));
+ complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(5));
+ complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4));
+
+ complex.add_blocker(Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4), Vertex_handle(5)));
+
+ bool correct_number_simplices = true;
+
+ std::map<Vertex_handle, unsigned> expected_num_simplices;
+
+ expected_num_simplices[Vertex_handle(0)] = 4;
+ expected_num_simplices[Vertex_handle(1)] = 6;
+ expected_num_simplices[Vertex_handle(2)] = 11;
+ expected_num_simplices[Vertex_handle(3)] = 9;
+ expected_num_simplices[Vertex_handle(4)] = 7;
+ expected_num_simplices[Vertex_handle(5)] = 7;
+
+ for (auto pair : expected_num_simplices) {
+ unsigned num_simplices_around = 0;
+ for (const auto& simplex : complex.star_simplex_range(pair.first)) {
+ simplex.dimension();
+ DBGVALUE(simplex);
+ ++num_simplices_around;
+ }
+
+ correct_number_simplices = correct_number_simplices && (num_simplices_around == pair.second);
+
+ DBGMSG("current vertex:", pair.first);
+ DBGMSG("expected_num_simplices:", pair.second);
+ DBGMSG("found:", num_simplices_around);
+ }
+ return correct_number_simplices;
+}
+
+bool test_iterator_simplices2() {
+ Complex complex(2);
+ complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1));
+
+ for (const auto& s : complex.triangle_range()) {
+ s.dimension();
+ return false; // there are no triangles
+ }
+
+ unsigned num_simplices = 0;
+
+
+ DBGVALUE(complex.to_string());
+
+ for (const auto& simplex : complex.star_simplex_range(Vertex_handle(0))) {
+ simplex.dimension();
+ DBGVALUE(simplex);
+ }
+
+
+ for (const auto& simplex : complex.complex_simplex_range()) {
+ DBGVALUE(simplex);
+ simplex.dimension();
+ ++num_simplices;
+ }
+ bool correct_number_simplices = (num_simplices == 3);
+ return correct_number_simplices;
+}
+
+bool test_iterator_simplices3() {
+ Complex complex(3);
+ complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1));
+ complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(2));
+ complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(0));
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)));
+
+ unsigned num_simplices = 0;
+
+ for (const auto& simplex : complex.star_simplex_range(Vertex_handle(0))) {
+ simplex.dimension();
+ DBGVALUE(simplex);
+ }
+
+
+ for (const auto& simplex : complex.complex_simplex_range()) {
+ DBGVALUE(simplex);
+ simplex.dimension();
+ ++num_simplices;
+ }
+ bool correct_number_simplices = (num_simplices == 6);
+ return correct_number_simplices;
+}
+
+bool test_iterator_simplices4() {
+ Complex empty_complex;
+ for (auto v : empty_complex.vertex_range()) {
+ (void) v;
+ }
+ for (auto e : empty_complex.edge_range()) {
+ empty_complex[e];
+ }
+ for (auto t : empty_complex.triangle_range()) {
+ t.dimension();
+ }
+ for (auto s : empty_complex.complex_simplex_range()) {
+ s.dimension();
+ }
+ return true;
}
-bool test_iterator_simplices4(){
- Complex empty_complex;
- for(auto v : empty_complex.vertex_range()){
- v;
- }
- for(auto e : empty_complex.edge_range()){
- empty_complex[e];
- }
- for(auto t : empty_complex.triangle_range()){
- t.dimension();
- }
- for(auto s : empty_complex.simplex_range()){
- s.dimension();
- }
- return true;
+bool test_iterator_coboundary() {
+ Complex c;
+ build_complete(4, c);
+ c.remove_edge(Vertex_handle(1), Vertex_handle(3));
+ PRINT(c.to_string());
+ Simplex s02(Vertex_handle(0), Vertex_handle(2));
+ int n = 0;
+ std::set<Simplex> expected;
+ expected.insert(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)));
+ expected.insert(Simplex(Vertex_handle(0), Vertex_handle(2), Vertex_handle(3)));
+ for (const auto & s : c.coboundary_range(s02)) {
+ PRINT(s);
+ if (expected.find(s) == expected.end())
+ return false;
+ ++n;
+ }
+ return n == 2;
}
-
template<typename Map>
-auto blocker_range(Map map) -> decltype( map | boost::adaptors::map_values){
- return map| boost::adaptors::map_values ;
-}
-
-
-bool test_iterator_blockers(){
- Complex complex;
- Simplex_handle alpha;
- Simplex_handle vertex_set_expected;
- // Build the complexes
- for (int i=0;i<20;i++){
- complex.add_vertex();
- }
- for (int i=10;i<15;i++){
- for (int j=i+1;j<15;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- }
-
- complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12)));
- complex.add_blocker(Simplex_handle(Vertex_handle(2),Vertex_handle(1),Vertex_handle(10)));
- complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(9),Vertex_handle(15)));
- complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(9),Vertex_handle(8)));
-
- // Print result
- int num_blockers=0;
- for(auto blockers : complex.blocker_range(Vertex_handle(10))){
- TESTVALUE(*blockers) ;
- num_blockers++;
- }
- bool test = (num_blockers==3);
-
- num_blockers=0;
- for (auto blockers : complex.blocker_range()){
- TESTVALUE(*blockers) ;
- num_blockers++;
- }
- test = test && (num_blockers==4) ;
-
- return test;
-}
-
-
-bool test_link0(){
-
- enum { a, b, c, d, n };
- Complex complex(n);
- complex.add_edge(Vertex_handle(b),Vertex_handle(c));complex.add_edge(Vertex_handle(c),Vertex_handle(d));
- Simplex_handle alpha = Simplex_handle(Vertex_handle(c));
- Skeleton_blocker_link_complex<Complex> L(complex,alpha);
-
- auto L2 = complex.link(alpha);
- if(L!=L2) return false;
-
- PRINT(L.num_vertices());
- PRINT(L.to_string());
-
- bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(b)));
- bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(d)));
- bool test3 = L.num_edges()==0;
- bool test4 = L.num_blockers()==0;
- return test1&&test2&&test3&&test4;
-
-}
-
-bool test_link1(){
- Complex complex;
-
-
- // Build the complexes
- for (int i=0;i<20;i++){
- complex.add_vertex();
- }
- for (int i=10;i<15;i++){
- for (int j=i+1;j<15;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- }
- Simplex_handle alpha(Vertex_handle(12),Vertex_handle(14));
- Skeleton_blocker_link_complex<Complex> L(complex,alpha);
- // Complexes built
-
- auto L2 = complex.link(alpha);
- if(L!=L2) return false;
-
- // verification
- bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10)));
- bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11)));
- bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13)));
- bool test4 = L.num_edges()==3;
- bool test5 = L.num_blockers()==0;
- Root_simplex_handle simplex;
- simplex.add_vertex(Root_vertex_handle(10));
- simplex.add_vertex(Root_vertex_handle(11));
- simplex.add_vertex(Root_vertex_handle(13));
- bool test6(L.get_simplex_address(simplex));
- bool test7 = L.contains(*(L.get_simplex_address(simplex)));
- cerr <<"----> Ocomplex \n";
- return test1&&test2&&test3&&test4&&test5&&test6&&test7 ;
-
-}
-
-
-bool test_link2(){
- Complex complex;
-
- Simplex_handle alpha;
- Simplex_handle vertex_set_expected;
- // Build the complexes
- for (int i=0;i<20;i++){
- complex.add_vertex();
- }
- for (int i=10;i<15;i++){
- for (int j=i+1;j<15;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- }
- complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(13)));
- alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14));
- Skeleton_blocker_link_complex<Complex> L(complex,alpha);
- // Complexes built
-
- // Print result
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl;
- cerr << "L= Link_complex("<<alpha<<") : \n"<<L.to_string();
-
- auto L2 = complex.link(alpha);
- if(L!=L2) return false;
-
-
- // verification
- bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10)));
- bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11)));
- bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13)));
- bool test4 = L.num_edges()==3;
- bool test5 = L.num_blockers()==1;
- Root_simplex_handle simplex;
- simplex.add_vertex(Root_vertex_handle(10));
- simplex.add_vertex(Root_vertex_handle(11));
- simplex.add_vertex(Root_vertex_handle(13));
- bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex)));
- cerr <<"----> Ocomplex \n";
- return test1&&test2&&test3&&test4&&test5&&test6 ;
-}
-
-bool test_link3(){
- Complex complex;
-
- Simplex_handle alpha;
- Simplex_handle vertex_set_expected;
- // Build the complexes
- for (int i=0;i<20;i++){
- complex.add_vertex();
- }
- for (int i=10;i<15;i++){
- for (int j=i+1;j<15;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- }
- complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12)));
- alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14));
- Skeleton_blocker_link_complex<Complex> L(complex,alpha);
- // Complexes built
-
- // Print result
- cerr << "complex complex"<< complex.to_string();
- cerr <<endl<<endl;
- cerr << "L= Link_complex("<<alpha<<") : \n"<<L.to_string();
-
- auto L2 = complex.link(alpha);
- if(L!=L2) return false;
-
-
- // verification
- bool test = assert_vertex(L,*L.get_address(Root_vertex_handle(10)));
- test = test&& assert_vertex(L,*L.get_address(Root_vertex_handle(11)));
- test = test&& assert_vertex(L,*L.get_address(Root_vertex_handle(13)));
- test = test&& L.num_edges()==2;
- test = test&&L.contains_edge(*L.get_address(Root_vertex_handle(10)),*L.get_address(Root_vertex_handle(13)));
- test=test&&L.contains_edge(*L.get_address(Root_vertex_handle(13)),*L.get_address(Root_vertex_handle(11)));
- test=test&&L.num_blockers()==0;
- return test;
-}
-
-bool test_link4(){
- Complex complex;
-
- // Build the complexes
- for (int i=0;i<20;i++){
- complex.add_vertex();
- }
- for (int i=10;i<15;i++){
- for (int j=i+1;j<15;j++)
- complex.add_edge(Vertex_handle(i),Vertex_handle(j));
- }
- complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12),Vertex_handle(13)));
- Simplex_handle alpha(Vertex_handle(12),Vertex_handle(14));
- Skeleton_blocker_link_complex<Complex> L(complex,alpha);
- // Complexes built
-
- // verification
- bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10)));
- bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11)));
- bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13)));
- bool test4 = L.num_edges()==3;
- bool test5 = L.num_blockers()==1;
- Root_simplex_handle simplex;
- simplex.add_vertex(Root_vertex_handle(10));
- simplex.add_vertex(Root_vertex_handle(11));
- simplex.add_vertex(Root_vertex_handle(13));
- bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex)));
- cerr <<"----> Ocomplex \n";
- return test1&&test2&&test3&&test4&&test5&&test6 ;
-
-}
-
-bool test_link5(){
- Complex complex(0,new Print_complex_visitor<Vertex_handle>());
- // Build the complexes
- build_complete(4,complex);
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
-
- Simplex_handle alpha(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2));
+auto blocker_range(Map map) -> decltype(map | boost::adaptors::map_values) {
+ return map | boost::adaptors::map_values;
+}
+
+bool test_iterator_blockers() {
+ Complex complex;
+ Simplex alpha;
+ Simplex vertex_set_expected;
+ // Build the complexes
+ for (int i = 0; i < 20; i++) {
+ complex.add_vertex();
+ }
+ for (int i = 10; i < 15; i++) {
+ for (int j = i + 1; j < 15; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ }
+
+ complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12)));
+ complex.add_blocker(Simplex(Vertex_handle(2), Vertex_handle(1), Vertex_handle(10)));
+ complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(9), Vertex_handle(15)));
+ complex.add_blocker(Simplex(Vertex_handle(1), Vertex_handle(9), Vertex_handle(8)));
+
+ // Print result
+ int num_blockers = 0;
+ for (auto blockers : complex.blocker_range(Vertex_handle(10))) {
+ TESTVALUE(*blockers);
+ num_blockers++;
+ }
+ bool test = (num_blockers == 3);
+
+ num_blockers = 0;
+ for (auto blockers : complex.blocker_range()) {
+ TESTVALUE(*blockers);
+ num_blockers++;
+ }
+ test = test && (num_blockers == 4);
+
+ return test;
+}
+
+bool test_link0() {
+
+ enum {
+ a, b, c, d, n
+ };
+ Complex complex(n);
+ complex.add_edge_without_blockers(Vertex_handle(b), Vertex_handle(c));
+ complex.add_edge_without_blockers(Vertex_handle(c), Vertex_handle(d));
+ Simplex alpha = Simplex(Vertex_handle(c));
+ Skeleton_blocker_link_complex<Complex> L(complex, alpha);
+
+ auto L2 = complex.link(alpha);
+ if (L != L2) return false;
+
+ PRINT(L.num_vertices());
+ PRINT(L.to_string());
+
+ bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(b)));
+ bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(d)));
+ bool test3 = L.num_edges() == 0;
+ bool test4 = L.num_blockers() == 0;
+ return test1 && test2 && test3&&test4;
+
+}
+
+bool test_link1() {
+ Complex complex;
+
+
+ // Build the complexes
+ for (int i = 0; i < 20; i++) {
+ complex.add_vertex();
+ }
+ for (int i = 10; i < 15; i++) {
+ for (int j = i + 1; j < 15; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ }
+ Simplex alpha(Vertex_handle(12), Vertex_handle(14));
+ Skeleton_blocker_link_complex<Complex> L(complex, alpha);
+ // Complexes built
+
+ auto L2 = complex.link(alpha);
+ if (L != L2) return false;
+
+ // verification
+ bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10)));
+ bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11)));
+ bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13)));
+ bool test4 = L.num_edges() == 3;
+ bool test5 = L.num_blockers() == 0;
+ Root_simplex_handle simplex;
+ simplex.add_vertex(Root_vertex_handle(10));
+ simplex.add_vertex(Root_vertex_handle(11));
+ simplex.add_vertex(Root_vertex_handle(13));
+ bool test6(L.get_simplex_address(simplex));
+ bool test7 = L.contains(*(L.get_simplex_address(simplex)));
+ cerr << "----> Ocomplex \n";
+ return test1 && test2 && test3 && test4 && test5 && test6&&test7;
+
+}
+
+bool test_link2() {
+ Complex complex;
+
+ Simplex alpha;
+ Simplex vertex_set_expected;
+ // Build the complexes
+ for (int i = 0; i < 20; i++) {
+ complex.add_vertex();
+ }
+ for (int i = 10; i < 15; i++) {
+ for (int j = i + 1; j < 15; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ }
+ complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(13)));
+ alpha = Simplex(Vertex_handle(12), Vertex_handle(14));
+ Skeleton_blocker_link_complex<Complex> L(complex, alpha);
+ // Complexes built
+
+ // Print result
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
+ cerr << "L= Link_complex(" << alpha << ") : \n" << L.to_string();
+
+ auto L2 = complex.link(alpha);
+ if (L != L2) return false;
+
+
+ // verification
+ bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10)));
+ bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11)));
+ bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13)));
+ bool test4 = L.num_edges() == 3;
+ bool test5 = L.num_blockers() == 1;
+ Root_simplex_handle simplex;
+ simplex.add_vertex(Root_vertex_handle(10));
+ simplex.add_vertex(Root_vertex_handle(11));
+ simplex.add_vertex(Root_vertex_handle(13));
+ bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex)));
+ cerr << "----> Ocomplex \n";
+ return test1 && test2 && test3 && test4 && test5&&test6;
+}
+
+bool test_link3() {
+ Complex complex;
+
+ Simplex alpha;
+ Simplex vertex_set_expected;
+ // Build the complexes
+ for (int i = 0; i < 20; i++) {
+ complex.add_vertex();
+ }
+ for (int i = 10; i < 15; i++) {
+ for (int j = i + 1; j < 15; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ }
+ complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12)));
+ alpha = Simplex(Vertex_handle(12), Vertex_handle(14));
+ Skeleton_blocker_link_complex<Complex> L(complex, alpha);
+ // Complexes built
+
+ // Print result
+ cerr << "complex complex" << complex.to_string();
+ cerr << endl << endl;
+ cerr << "L= Link_complex(" << alpha << ") : \n" << L.to_string();
+
+ auto L2 = complex.link(alpha);
+ if (L != L2) return false;
+
+
+ // verification
+ bool test = assert_vertex(L, *L.get_address(Root_vertex_handle(10)));
+ test = test && assert_vertex(L, *L.get_address(Root_vertex_handle(11)));
+ test = test && assert_vertex(L, *L.get_address(Root_vertex_handle(13)));
+ test = test && L.num_edges() == 2;
+ test = test && L.contains_edge(*L.get_address(Root_vertex_handle(10)), *L.get_address(Root_vertex_handle(13)));
+ test = test && L.contains_edge(*L.get_address(Root_vertex_handle(13)), *L.get_address(Root_vertex_handle(11)));
+ test = test && L.num_blockers() == 0;
+ return test;
+}
+
+bool test_link4() {
+ Complex complex;
+
+ // Build the complexes
+ for (int i = 0; i < 20; i++) {
+ complex.add_vertex();
+ }
+ for (int i = 10; i < 15; i++) {
+ for (int j = i + 1; j < 15; j++)
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j));
+ }
+ complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12), Vertex_handle(13)));
+ Simplex alpha(Vertex_handle(12), Vertex_handle(14));
+ Skeleton_blocker_link_complex<Complex> L(complex, alpha);
+ // Complexes built
+
+ // verification
+ bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10)));
+ bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11)));
+ bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13)));
+ bool test4 = L.num_edges() == 3;
+ bool test5 = L.num_blockers() == 1;
+ Root_simplex_handle simplex;
+ simplex.add_vertex(Root_vertex_handle(10));
+ simplex.add_vertex(Root_vertex_handle(11));
+ simplex.add_vertex(Root_vertex_handle(13));
+ bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex)));
+ cerr << "----> Ocomplex \n";
+ return test1 && test2 && test3 && test4 && test5&&test6;
+
+}
+
+bool test_link5() {
+ Complex complex(0, new Print_complex_visitor<Vertex_handle>());
+ // Build the complexes
+ build_complete(4, complex);
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)));
+
+ Simplex alpha(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2));
+
+
+ Skeleton_blocker_link_complex<Complex> L(complex, alpha); // Complexes built
+
+ // Print result
+ PRINT(complex.to_string());
+ cerr << endl << endl;
+ PRINT(L.to_string());
+
+ // verification
+ return L.num_vertices() == 0;
+}
+
+bool test_link6() {
+ Complex complex(0, new Print_complex_visitor<Vertex_handle>());
+ // Build the complexes
+ build_complete(4, complex);
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)));
+ Simplex alpha(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2));
- Skeleton_blocker_link_complex<Complex> L(complex,alpha); // Complexes built
+ Skeleton_blocker_link_complex<Complex> link_blocker_alpha;
- // Print result
- PRINT(complex.to_string());
- cerr <<endl<<endl;
- PRINT(L.to_string());
+ build_link_of_blocker(complex, alpha, link_blocker_alpha);
+
+ // Print result
+ PRINT(complex.to_string());
+ cerr << endl << endl;
+ PRINT(link_blocker_alpha.to_string());
- // verification
- return L.num_vertices()==0;
+ // verification
+ return link_blocker_alpha.num_vertices() == 1;
}
-bool test_link6(){
- Complex complex(0,new Print_complex_visitor<Vertex_handle>());
- // Build the complexes
- build_complete(4,complex);
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
+bool test_link7() {
+ Complex complex(0, new Print_complex_visitor<Vertex_handle>());
+ // Build the complexes
+ build_complete(6, complex);
+ complex.add_vertex();
+ complex.add_vertex();
+ for (int i = 3; i < 6; ++i) {
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(6));
+ complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(7));
+ }
+ complex.add_edge_without_blockers(Vertex_handle(6), Vertex_handle(7));
+ complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)));
+ complex.add_blocker(Simplex(Vertex_handle(3), Vertex_handle(4), Vertex_handle(5)));
- Simplex_handle alpha(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2));
+ Simplex alpha(Vertex_handle(3), Vertex_handle(4), Vertex_handle(5));
- Skeleton_blocker_link_complex<Complex> link_blocker_alpha;
+ Skeleton_blocker_link_complex<Complex> link_blocker_alpha;
- build_link_of_blocker(complex,alpha,link_blocker_alpha);
+ build_link_of_blocker(complex, alpha, link_blocker_alpha);
- // Print result
- PRINT(complex.to_string());
- cerr <<endl<<endl;
- PRINT(link_blocker_alpha.to_string());
+ //the result should be the edge {6,7} plus the blocker {0,1,2}
- // verification
- return link_blocker_alpha.num_vertices()==1;
-}
-
-
-bool test_link7(){
- Complex complex(0,new Print_complex_visitor<Vertex_handle>());
- // Build the complexes
- build_complete(6,complex);
- complex.add_vertex();
- complex.add_vertex();
- for(int i = 3; i<6; ++i){
- complex.add_edge(Vertex_handle(i),Vertex_handle(6));
- complex.add_edge(Vertex_handle(i),Vertex_handle(7));
- }
- complex.add_edge(Vertex_handle(6),Vertex_handle(7));
- complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
- complex.add_blocker(Simplex_handle(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)));
-
- Simplex_handle alpha(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5));
-
- Skeleton_blocker_link_complex<Complex> link_blocker_alpha;
-
- build_link_of_blocker(complex,alpha,link_blocker_alpha);
+ // Print result
+ PRINT(complex.to_string());
+ cerr << endl << endl;
+ DBGVALUE(link_blocker_alpha.to_string());
- //the result should be the edge {6,7} plus the blocker {0,1,2}
+ Skeleton_blocker_link_complex<Complex> link_blocker_alpha_cpy = link_blocker_alpha;
- // Print result
- PRINT(complex.to_string());
- cerr <<endl<<endl;
- DBGVALUE(link_blocker_alpha.to_string());
+ DBGVALUE(link_blocker_alpha_cpy.to_string());
- Skeleton_blocker_link_complex<Complex> link_blocker_alpha_cpy = link_blocker_alpha;
+ bool equal_complexes =
+ (link_blocker_alpha.num_vertices() == link_blocker_alpha_cpy.num_vertices())
+ &&(link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers())
+ &&(link_blocker_alpha.num_edges() == link_blocker_alpha_cpy.num_edges())
+ ;
+ DBGVALUE((link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers()));
+ DBGVALUE((link_blocker_alpha.num_blockers()));
+ DBGVALUE((link_blocker_alpha_cpy.num_blockers()));
- DBGVALUE(link_blocker_alpha_cpy.to_string());
+ DBGVALUE(equal_complexes);
- bool equal_complexes =
- (link_blocker_alpha.num_vertices() == link_blocker_alpha_cpy.num_vertices())
- &&(link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers())
- &&(link_blocker_alpha.num_edges() == link_blocker_alpha_cpy.num_edges())
- ;
- DBGVALUE((link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers()));
- DBGVALUE((link_blocker_alpha.num_blockers() ));
- DBGVALUE(( link_blocker_alpha_cpy.num_blockers()));
-
- DBGVALUE(equal_complexes);
-
- // verification
- return link_blocker_alpha.num_vertices()==5 && link_blocker_alpha.num_edges()==4 && link_blocker_alpha.num_blockers()==1 && equal_complexes;
+ // verification
+ return link_blocker_alpha.num_vertices() == 5 && link_blocker_alpha.num_edges() == 4 && link_blocker_alpha.num_blockers() == 1 && equal_complexes;
}
-
-
-
-
-
-
-
template<typename SimplexHandle>
-void add_triangle_edges(int a,int b,int c,list<SimplexHandle>& simplices){
- typedef SimplexHandle Simplex_handle;
- typedef typename SimplexHandle::Vertex_handle Vertex_handle;
+void add_triangle_edges(int a, int b, int c, list<SimplexHandle>& simplices) {
+ typedef SimplexHandle Simplex;
+ typedef typename SimplexHandle::Vertex_handle Vertex_handle;
- simplices.push_back(Simplex_handle(Vertex_handle(a),Vertex_handle(b) ));
- simplices.push_back(Simplex_handle(Vertex_handle(b),Vertex_handle(c) ));
- simplices.push_back(Simplex_handle(Vertex_handle(c),Vertex_handle(a) ));
+ simplices.push_back(Simplex(Vertex_handle(a), Vertex_handle(b)));
+ simplices.push_back(Simplex(Vertex_handle(b), Vertex_handle(c)));
+ simplices.push_back(Simplex(Vertex_handle(c), Vertex_handle(a)));
}
template<typename SimplexHandle>
-void add_triangle(int a,int b,int c,list<SimplexHandle>& simplices){
- typedef SimplexHandle Simplex_handle;
- typedef typename SimplexHandle::Vertex_handle Vertex_handle;
- simplices.push_back(Simplex_handle(Vertex_handle(a),Vertex_handle(b),Vertex_handle(c)));
-}
-
-bool test_constructor(){
- list <Simplex_handle> simplices;
-
- simplices.push_back(Simplex_handle(Vertex_handle(0)));
- simplices.push_back(Simplex_handle(Vertex_handle(1)));
- simplices.push_back(Simplex_handle(Vertex_handle(2)));
- simplices.push_back(Simplex_handle(Vertex_handle(3)));
- simplices.push_back(Simplex_handle(Vertex_handle(4)));
- simplices.push_back(Simplex_handle(Vertex_handle(5)));
-
- simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(5) ));
-
- add_triangle_edges(0,1,5,simplices);
- add_triangle_edges(1,2,3,simplices);
- add_triangle_edges(2,3,4,simplices);
- add_triangle_edges(1,3,4,simplices);
- add_triangle_edges(1,2,4,simplices);
-
-
- add_triangle(0,1,5,simplices);
- add_triangle(1,2,3,simplices);
- add_triangle(1,3,4,simplices);
- add_triangle(1,2,4,simplices);
- add_triangle(2,3,4,simplices);
-
- Complex complex(simplices.begin(),simplices.end());
-
- PRINT(complex.to_string());
-
- return ( complex.num_vertices()==6&&complex.num_edges()==10&& complex.num_blockers()==2);
-}
-
-
-list<Simplex_handle> subfaces(Simplex_handle top_face){
- list<Simplex_handle> res;
- if(top_face.dimension()==-1) return res;
- if(top_face.dimension()==0) {
- res.push_back(top_face);
- return res;
- }
- else{
- Vertex_handle first_vertex = top_face.first_vertex();
- top_face.remove_vertex(first_vertex);
- res = subfaces(top_face);
- list<Simplex_handle> copy = res;
- for(auto& simplex : copy){
- simplex.add_vertex(first_vertex);
- }
- res.push_back(Simplex_handle(first_vertex));
- res.splice(res.end(),copy);
- return res;
- }
-}
-
-
-bool test_constructor2(){
- Simplex_handle simplex;
- for(int i =0 ; i < 5;++i)
- simplex.add_vertex(static_cast<Vertex_handle>(i));
-
- list <Simplex_handle> simplices(subfaces(simplex));
- simplices.remove(simplex);
-
- Complex complex(simplices.begin(),simplices.end());
-
- PRINT(complex.to_string());
-
- for(auto b : complex.const_blocker_range()){
- cout << "b:"<<b<<endl;
- }
-
- return ( complex.num_vertices()==5&&complex.num_edges()==10&& complex.num_blockers()==1);
+void add_triangle(int a, int b, int c, list<SimplexHandle>& simplices) {
+ typedef SimplexHandle Simplex;
+ typedef typename SimplexHandle::Vertex_handle Vertex_handle;
+ simplices.push_back(Simplex(Vertex_handle(a), Vertex_handle(b), Vertex_handle(c)));
}
+bool test_constructor() {
+ list <Simplex> simplices;
-bool test_constructor3(){
- typedef Vertex_handle Vh;
- typedef Simplex_handle Sh;
- std::vector<Simplex_handle> simplices;
- auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2))));
- subf.pop_back(); //remove max face -> now a blocker 012
- simplices.insert(simplices.begin(),subf.begin(),subf.end());
- DBGCONT(simplices);
- Complex complex(simplices.begin(),simplices.end());
-
- DBGVALUE(complex.to_string());
+ simplices.push_back(Simplex(Vertex_handle(0)));
+ simplices.push_back(Simplex(Vertex_handle(1)));
+ simplices.push_back(Simplex(Vertex_handle(2)));
+ simplices.push_back(Simplex(Vertex_handle(3)));
+ simplices.push_back(Simplex(Vertex_handle(4)));
+ simplices.push_back(Simplex(Vertex_handle(5)));
- if(complex.num_blockers()!=1) return false;
- Sh expected_blocker(Vh(0),Vh(1),Vh(2));
- for(auto b : complex.const_blocker_range())
- if(*b!=expected_blocker) return false;
+ simplices.push_back(Simplex(Vertex_handle(3), Vertex_handle(5)));
+ add_triangle_edges(0, 1, 5, simplices);
+ add_triangle_edges(1, 2, 3, simplices);
+ add_triangle_edges(2, 3, 4, simplices);
+ add_triangle_edges(1, 3, 4, simplices);
+ add_triangle_edges(1, 2, 4, simplices);
- return complex.num_vertices()==3 && complex.num_blockers()==1;
-}
-
-bool test_constructor4(){
- typedef Vertex_handle Vh;
- typedef Simplex_handle Sh;
- std::vector<Simplex_handle> simplices;
- auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2),Vh(3))));
- simplices.insert(simplices.begin(),subf.begin(),subf.end());
- simplices.push_back(Sh(Vh(4)));
- simplices.push_back(Sh(Vh(4),Vh(1)));
- simplices.push_back(Sh(Vh(4),Vh(0)));
+ add_triangle(0, 1, 5, simplices);
+ add_triangle(1, 2, 3, simplices);
+ add_triangle(1, 3, 4, simplices);
+ add_triangle(1, 2, 4, simplices);
+ add_triangle(2, 3, 4, simplices);
- DBGCONT(simplices);
- Complex complex(simplices.begin(),simplices.end());
+ Complex complex(simplices.begin(), simplices.end());
- DBGVALUE(complex.to_string());
- if(complex.num_blockers()!=1) return false;
- Sh expected_blocker(Vh(0),Vh(1),Vh(4));
- for(auto b : complex.const_blocker_range())
- if(*b!=expected_blocker) return false;
+ PRINT(complex.to_string());
- return complex.num_vertices()==5 && complex.num_blockers()==1 && complex.num_edges()==8;
+ return ( complex.num_vertices() == 6 && complex.num_edges() == 10 && complex.num_blockers() == 2);
}
-
-
-bool test_constructor5(){
- typedef Vertex_handle Vh;
- typedef Simplex_handle Sh;
- std::vector<Simplex_handle> simplices;
- auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2))));
- simplices.insert(simplices.begin(),subf.begin(),subf.end());
-
- simplices.push_back(Sh(Vh(3)));
- simplices.push_back(Sh(Vh(3),Vh(1)));
- simplices.push_back(Sh(Vh(3),Vh(2)));
- simplices.push_back(Sh(Vh(4)));
- simplices.push_back(Sh(Vh(4),Vh(1)));
- simplices.push_back(Sh(Vh(4),Vh(0)));
- simplices.push_back(Sh(Vh(5)));
- simplices.push_back(Sh(Vh(5),Vh(2)));
- simplices.push_back(Sh(Vh(5),Vh(0)));
-
- DBGCONT(simplices);
- Complex complex(simplices.begin(),simplices.end());
-
- DBGVALUE(complex.to_string());
-
- return complex.num_vertices()==6 && complex.num_blockers()==3 && complex.num_edges()==9;
+list<Simplex> subfaces(Simplex top_face) {
+ list<Simplex> res;
+ if (top_face.dimension() == -1) return res;
+ if (top_face.dimension() == 0) {
+ res.push_back(top_face);
+ return res;
+ } else {
+ Vertex_handle first_vertex = top_face.first_vertex();
+ top_face.remove_vertex(first_vertex);
+ res = subfaces(top_face);
+ list<Simplex> copy = res;
+ for (auto& simplex : copy) {
+ simplex.add_vertex(first_vertex);
+ }
+ res.push_back(Simplex(first_vertex));
+ res.splice(res.end(), copy);
+ return res;
+ }
}
+bool test_constructor2() {
+ Simplex simplex;
+ for (int i = 0; i < 5; ++i)
+ simplex.add_vertex(static_cast<Vertex_handle> (i));
-bool test_constructor6(){
- typedef Vertex_handle Vh;
- typedef Simplex_handle Sh;
- std::vector<Simplex_handle> simplices;
- auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2),Vh(3))));
- for(auto s:subf){
- Sh s1(Vh(0),Vh(1),Vh(2),Vh(3));
- Sh s2(Vh(1),Vh(2),Vh(3));
- if(s!=s1 && s!=s2) simplices.push_back(s);
- }
+ list <Simplex> simplices(subfaces(simplex));
+ simplices.remove(simplex);
- DBGCONT(simplices);
- Complex complex(simplices.begin(),simplices.end());
+ Complex complex(simplices.begin(), simplices.end());
- DBGVALUE(complex.to_string());
+ PRINT(complex.to_string());
- if(complex.num_blockers()!=1) return false;
- Sh expected_blocker(Vh(1),Vh(2),Vh(3));
- for(auto b : complex.const_blocker_range())
- if(*b!=expected_blocker) return false;
- return complex.num_vertices()==4 && complex.num_blockers()==1 && complex.num_edges()==6;
-}
+ for (auto b : complex.const_blocker_range()) {
+ cout << "b:" << b << endl;
+ }
-
-bool test_constructor7(){
- typedef Vertex_handle Vh;
- typedef Simplex_handle Sh;
- std::vector<Simplex_handle> simplices;
- simplices.push_back(Sh(Vh(0),Vh(1),Vh(2)));
- simplices.push_back(Sh(Vh(1),Vh(2),Vh(3)));
- simplices.push_back(Sh(Vh(3),Vh(0),Vh(2)));
- simplices.push_back(Sh(Vh(3),Vh(0),Vh(1)));
-
- //get complex from top faces
- Complex complex(make_complex_from_top_faces<Complex>(simplices.begin(),simplices.end()));
-
- DBGVALUE(complex.to_string());
-
- if(complex.num_blockers()!=1) return false;
- Sh expected_blocker(Vh(0),Vh(1),Vh(2),Vh(3));
- for(auto b : complex.const_blocker_range())
- if(*b!=expected_blocker) return false;
- return complex.num_vertices()==4 && complex.num_blockers()==1 && complex.num_edges()==6;
+ return ( complex.num_vertices() == 5 && complex.num_edges() == 10 && complex.num_blockers() == 1);
}
+bool test_constructor3() {
+ typedef Vertex_handle Vh;
+ typedef Simplex Sh;
+ std::vector<Simplex> simplices;
+ auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2))));
+ subf.pop_back(); //remove max face -> now a blocker 012
+ simplices.insert(simplices.begin(), subf.begin(), subf.end());
+ DBGCONT(simplices);
+ Complex complex(simplices.begin(), simplices.end());
-bool test_constructor8(){
- typedef Vertex_handle Vh;
- typedef Simplex_handle Sh;
- std::vector<Simplex_handle> simplices;
- simplices.push_back(Sh(Vh(0),Vh(1)));
- simplices.push_back(Sh(Vh(2),Vh(1)));
- simplices.push_back(Sh(Vh(0),Vh(2)));
- simplices.push_back(Sh(Vh(3),Vh(1)));
- simplices.push_back(Sh(Vh(2),Vh(3)));
+ DBGVALUE(complex.to_string());
- //get complex from top faces
- Complex complex(make_complex_from_top_faces<Complex>(simplices.begin(),simplices.end()));
+ if (complex.num_blockers() != 1) return false;
+ Sh expected_blocker(Vh(0), Vh(1), Vh(2));
+ for (auto b : complex.const_blocker_range())
+ if (*b != expected_blocker) return false;
- DBGVALUE(complex.to_string());
- return complex.num_vertices()==4 && complex.num_blockers()==2 && complex.num_edges()==5;
+ return complex.num_vertices() == 3 && complex.num_blockers() == 1;
}
+bool test_constructor4() {
+ typedef Vertex_handle Vh;
+ typedef Simplex Sh;
+ std::vector<Simplex> simplices;
+ auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2), Vh(3))));
+ simplices.insert(simplices.begin(), subf.begin(), subf.end());
+ simplices.push_back(Sh(Vh(4)));
+ simplices.push_back(Sh(Vh(4), Vh(1)));
+ simplices.push_back(Sh(Vh(4), Vh(0)));
+ DBGCONT(simplices);
+ Complex complex(simplices.begin(), simplices.end());
+ DBGVALUE(complex.to_string());
+ if (complex.num_blockers() != 1) return false;
+ Sh expected_blocker(Vh(0), Vh(1), Vh(4));
+ for (auto b : complex.const_blocker_range())
+ if (*b != expected_blocker) return false;
-int main (int argc, char *argv[])
-{
- Tests tests_complex;
- tests_complex.add("test simplex",test_simplex);
- tests_complex.add("test_link0",test_link0);
- tests_complex.add("test_link1",test_link1);
- tests_complex.add("test_link2",test_link2);
- tests_complex.add("test_link3",test_link3);
- tests_complex.add("test_link4",test_link4);
- tests_complex.add("test_link5",test_link5);
- tests_complex.add("test_link6",test_link6);
- tests_complex.add("test_link7",test_link7);
-
- tests_complex.add("test iterator vertices 1",test_iterator_vertices1);
- tests_complex.add("test iterator vertices 2",test_iterator_vertices2);
- tests_complex.add("test iterator edges",test_iterator_edge);
- tests_complex.add("test iterator edges 2",test_iterator_edge2);
- tests_complex.add("test iterator edges 3",test_iterator_edge3);
-
- tests_complex.add("test iterator simplices",test_iterator_simplices);
- tests_complex.add("test iterator simplices2",test_iterator_simplices2);
- tests_complex.add("test iterator simplices3",test_iterator_simplices3);
- tests_complex.add("test iterator simplices4",test_iterator_simplices4);
-
-
- tests_complex.add("test iterator blockers",test_iterator_blockers);
- tests_complex.add("test_iterator_triangles",test_iterator_triangles);
-
- tests_complex.add("test_constructor_list_simplices",test_constructor);
- tests_complex.add("test_constructor_list_simplices2",test_constructor2);
- tests_complex.add("test_constructor_list_simplices3",test_constructor3);
- tests_complex.add("test_constructor_list_simplices4",test_constructor4);
- tests_complex.add("test_constructor_list_simplices5",test_constructor5);
- tests_complex.add("test_constructor_list_simplices6",test_constructor6);
- tests_complex.add("test_constructor_list_simplices7",test_constructor7);
- tests_complex.add("test_constructor_list_simplices8",test_constructor8);
-
-
- if(tests_complex.run()){
- return EXIT_SUCCESS;
- }
- else{
- return EXIT_FAILURE;
- }
+ return complex.num_vertices() == 5 && complex.num_blockers() == 1 && complex.num_edges() == 8;
+}
- // test_iterator_simplices();
+bool test_constructor5() {
+ typedef Vertex_handle Vh;
+ typedef Simplex Sh;
+ std::vector<Simplex> simplices;
+ auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2))));
+ simplices.insert(simplices.begin(), subf.begin(), subf.end());
+
+ simplices.push_back(Sh(Vh(3)));
+ simplices.push_back(Sh(Vh(3), Vh(1)));
+ simplices.push_back(Sh(Vh(3), Vh(2)));
+ simplices.push_back(Sh(Vh(4)));
+ simplices.push_back(Sh(Vh(4), Vh(1)));
+ simplices.push_back(Sh(Vh(4), Vh(0)));
+ simplices.push_back(Sh(Vh(5)));
+ simplices.push_back(Sh(Vh(5), Vh(2)));
+ simplices.push_back(Sh(Vh(5), Vh(0)));
+
+ DBGCONT(simplices);
+ Complex complex(simplices.begin(), simplices.end());
+
+ DBGVALUE(complex.to_string());
+
+ return complex.num_vertices() == 6 && complex.num_blockers() == 3 && complex.num_edges() == 9;
+}
+
+bool test_constructor6() {
+ typedef Vertex_handle Vh;
+ typedef Simplex Sh;
+ std::vector<Simplex> simplices;
+ auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2), Vh(3))));
+ for (auto s : subf) {
+ Sh s1(Vh(0), Vh(1), Vh(2), Vh(3));
+ Sh s2(Vh(1), Vh(2), Vh(3));
+ if (s != s1 && s != s2) simplices.push_back(s);
+ }
+
+ DBGCONT(simplices);
+ Complex complex(simplices.begin(), simplices.end());
+
+ DBGVALUE(complex.to_string());
+
+ if (complex.num_blockers() != 1) return false;
+ Sh expected_blocker(Vh(1), Vh(2), Vh(3));
+ for (auto b : complex.const_blocker_range())
+ if (*b != expected_blocker) return false;
+ return complex.num_vertices() == 4 && complex.num_blockers() == 1 && complex.num_edges() == 6;
+}
+
+bool test_constructor7() {
+ typedef Vertex_handle Vh;
+ typedef Simplex Sh;
+ std::vector<Simplex> simplices;
+ simplices.push_back(Sh(Vh(0), Vh(1), Vh(2)));
+ simplices.push_back(Sh(Vh(1), Vh(2), Vh(3)));
+ simplices.push_back(Sh(Vh(3), Vh(0), Vh(2)));
+ simplices.push_back(Sh(Vh(3), Vh(0), Vh(1)));
+
+ //get complex from top faces
+ Complex complex(make_complex_from_top_faces<Complex>(simplices.begin(), simplices.end()));
+
+ DBGVALUE(complex.to_string());
+
+ if (complex.num_blockers() != 1) return false;
+ Sh expected_blocker(Vh(0), Vh(1), Vh(2), Vh(3));
+ for (auto b : complex.const_blocker_range())
+ if (*b != expected_blocker) return false;
+ return complex.num_vertices() == 4 && complex.num_blockers() == 1 && complex.num_edges() == 6;
+}
+
+bool test_constructor8() {
+ typedef Vertex_handle Vh;
+ typedef Simplex Sh;
+ std::vector<Simplex> simplices;
+ simplices.push_back(Sh(Vh(0), Vh(1)));
+ simplices.push_back(Sh(Vh(2), Vh(1)));
+ simplices.push_back(Sh(Vh(0), Vh(2)));
+ simplices.push_back(Sh(Vh(3), Vh(1)));
+ simplices.push_back(Sh(Vh(2), Vh(3)));
+
+ //get complex from top faces
+ Complex complex(make_complex_from_top_faces<Complex>(simplices.begin(), simplices.end()));
+
+ DBGVALUE(complex.to_string());
+
+ return complex.num_vertices() == 4 && complex.num_blockers() == 2 && complex.num_edges() == 5;
+}
+
+int main(int argc, char *argv[]) {
+ Tests tests_complex;
+ tests_complex.add("test simplex", test_simplex);
+ tests_complex.add("test_num_simplices", test_num_simplices);
+ tests_complex.add("test_link0", test_link0);
+ tests_complex.add("test_link1", test_link1);
+ tests_complex.add("test_link2", test_link2);
+ tests_complex.add("test_link3", test_link3);
+ tests_complex.add("test_link4", test_link4);
+ tests_complex.add("test_link5", test_link5);
+ tests_complex.add("test_link6", test_link6);
+ tests_complex.add("test_link7", test_link7);
+
+ tests_complex.add("test_constructor_list_simplices", test_constructor);
+ tests_complex.add("test_constructor_list_simplices2", test_constructor2);
+ tests_complex.add("test_constructor_list_simplices3", test_constructor3);
+ tests_complex.add("test_constructor_list_simplices4", test_constructor4);
+ tests_complex.add("test_constructor_list_simplices5", test_constructor5);
+ tests_complex.add("test_constructor_list_simplices6", test_constructor6);
+ tests_complex.add("test_constructor_list_simplices7", test_constructor7);
+ tests_complex.add("test_constructor_list_simplices8", test_constructor8);
+
+ tests_complex.add("test iterator vertices 1", test_iterator_vertices1);
+ tests_complex.add("test iterator vertices 2", test_iterator_vertices2);
+ tests_complex.add("test iterator edges", test_iterator_edge);
+ tests_complex.add("test iterator edges 2", test_iterator_edge2);
+ tests_complex.add("test iterator edges 3", test_iterator_edge3);
+ tests_complex.add("test iterator blockers", test_iterator_blockers);
+ tests_complex.add("test_iterator_triangles", test_iterator_triangles);
+ tests_complex.add("test iterator simplices", test_iterator_simplices);
+ tests_complex.add("test iterator simplices2", test_iterator_simplices2);
+ tests_complex.add("test iterator simplices3", test_iterator_simplices3);
+ tests_complex.add("test iterator simplices4", test_iterator_simplices4);
+ tests_complex.add("test iterator coboundary", test_iterator_coboundary);
+
+ if (tests_complex.run()) {
+ return EXIT_SUCCESS;
+ } else {
+ return EXIT_FAILURE;
+ }
+
+ // test_iterator_simplices();
}
diff --git a/src/Witness_complex/example/Torus_distance.h b/src/Witness_complex/example/Torus_distance.h
deleted file mode 100644
index 5ae127df..00000000
--- a/src/Witness_complex/example/Torus_distance.h
+++ /dev/null
@@ -1,209 +0,0 @@
-#ifndef GUDHI_TORUS_DISTANCE_H_
-#define GUDHI_TORUS_DISTANCE_H_
-
-#include <math.h>
-
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/Epick_d.h>
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::FT FT;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-
-/**
- * \brief Class of distance in a flat torus in dimension D
- *
- */
-class Torus_distance {
-
-public:
- typedef K::FT FT;
- typedef K::Point_d Point_d;
- typedef Point_d Query_item;
- typedef typename CGAL::Dynamic_dimension_tag D;
-
- double box_length = 2;
-
- FT transformed_distance(Query_item q, Point_d p) const
- {
- FT distance = FT(0);
- FT coord = FT(0);
- //std::cout << "Hello skitty!\n";
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1), pit = construct_it(p);
- for(; qit != qe; qit++, pit++)
- {
- coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit)));
- if (coord*coord <= (box_length-coord)*(box_length-coord))
- distance += coord*coord;
- else
- distance += (box_length-coord)*(box_length-coord);
- }
- return distance;
- }
-
- FT min_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r) const {
- FT distance = FT(0);
- FT dist1, dist2;
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if((*qit) < r.min_coord(i))
- {
- dist1 = (r.min_coord(i)-(*qit));
- dist2 = (box_length - r.max_coord(i)+(*qit));
- if (dist1 < dist2)
- distance += dist1*dist1;
- else
- distance += dist2*dist2;
- }
- else if ((*qit) > r.max_coord(i))
- {
- dist1 = (box_length - (*qit)+r.min_coord(i));
- dist2 = ((*qit) - r.max_coord(i));
- if (dist1 < dist2)
- distance += dist1*dist1;
- else
- distance += dist2*dist2;
- }
- }
- return distance;
- }
-
- FT min_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r,
- std::vector<FT>& dists) const {
- FT distance = FT(0);
- FT dist1, dist2;
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- //std::cout << r.max_coord(0) << std::endl;
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if((*qit) < r.min_coord(i))
- {
- dist1 = (r.min_coord(i)-(*qit));
- dist2 = (box_length - r.max_coord(i)+(*qit));
- if (dist1 < dist2)
- {
- dists[i] = dist1;
- distance += dist1*dist1;
- }
- else
- {
- dists[i] = dist2;
- distance += dist2*dist2;
- //std::cout << "Good stuff1\n";
- }
- }
- else if ((*qit) > r.max_coord(i))
- {
- dist1 = (box_length - (*qit)+r.min_coord(i));
- dist2 = ((*qit) - r.max_coord(i));
- if (dist1 < dist2)
- {
- dists[i] = dist1;
- distance += dist1*dist1;
- //std::cout << "Good stuff2\n";
- }
- else
- {
- dists[i] = dist2;
- distance += dist2*dist2;
- }
- }
- };
- return distance;
- }
-
- FT max_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r) const {
- FT distance=FT(0);
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if (box_length <= (r.min_coord(i)+r.max_coord(i)))
- if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) &&
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
- else
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- else
- if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) ||
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
- else
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- }
- return distance;
- }
-
-
- FT max_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r,
- std::vector<FT>& dists) const {
- FT distance=FT(0);
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if (box_length <= (r.min_coord(i)+r.max_coord(i)))
- if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) &&
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- {
- dists[i] = r.max_coord(i)-(*qit);
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
- }
- else
- {
- dists[i] = sqrt(((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)));
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- }
- else
- if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) ||
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- {
- dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)));
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
-
- }
- else
- {
- dists[i] = (*qit)-r.min_coord(i);
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- }
- }
- return distance;
- }
-
- inline FT new_distance(FT dist, FT old_off, FT new_off,
- int ) const {
-
- FT new_dist = dist + (new_off*new_off - old_off*old_off);
- return new_dist;
- }
-
- inline FT transformed_distance(FT d) const {
- return d*d;
- }
-
- inline FT inverse_of_transformed_distance(FT d) const {
- return sqrt(d);
- }
-
-};
-
-#endif
diff --git a/src/Witness_complex/example/protected_sets/output_tikz.h b/src/Witness_complex/example/protected_sets/output_tikz.h
deleted file mode 100644
index edfd9a5f..00000000
--- a/src/Witness_complex/example/protected_sets/output_tikz.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef OUTPUT_TIKZ_H
-#define OUTPUT_TIKZ_H
-
-#include <vector>
-#include <string>
-#include <algorithm>
-#include <fstream>
-#include <cmath>
-
-void write_tikz_plot(std::vector<FT> data, std::string filename)
-{
- int n = data.size();
- FT vmax = *(std::max_element(data.begin(), data.end()));
- //std::cout << std::log10(vmax) << " " << std::floor(std::log10(vmax));
-
- FT order10 = pow(10,std::floor(std::log10(vmax)));
- int digit = std::floor( vmax / order10) + 1;
- if (digit == 4 || digit == 6) digit = 5;
- if (digit > 6) digit = 10;
- FT plot_max = digit*order10;
- std::cout << plot_max << " " << vmax;
- FT hstep = 10.0/(n-1);
- FT wstep = 10.0 / plot_max;
-
- std::cout << "(eps_max-eps_min)/(N-48) = " << (vmax-*data.begin())/(data.size()-48) << "\n";
- std::ofstream ofs(filename, std::ofstream::out);
-
- ofs <<
- "\\documentclass{standalone}\n" <<
- "\\usepackage[utf8]{inputenc}\n" <<
- "\\usepackage{amsmath}\n" <<
- "\\usepackage{tikz}\n\n" <<
- "\\begin{document}\n" <<
- "\\begin{tikzpicture}\n";
-
- ofs << "\\draw[->] (0,0) -- (0,11);" << std::endl <<
- "\\draw[->] (0,0) -- (11,0);" << std::endl <<
- "\\foreach \\i in {1,...,10}" << std::endl <<
- "\\draw (0,\\i) -- (-0.05,\\i);" << std::endl <<
- "\\foreach \\i in {1,...,10}" << std::endl <<
- "\\draw (\\i,0) -- (\\i,-0.05);" << std::endl << std::endl <<
-
- "\\foreach \\i in {1,...,10}" << std::endl <<
- "\\draw[dashed] (-0.05,\\i) -- (11,\\i);" << std::endl << std::endl <<
-
- "\\node at (-0.5,11) {$*$}; " << std::endl <<
- "\\node at (11,-0.5) {$*$}; " << std::endl <<
- "\\node at (-0.5,-0.5) {0}; " << std::endl <<
- "\\node at (-0.5,10) {" << plot_max << "}; " << std::endl <<
- "%\\node at (10,-0.5) {2}; " << std::endl;
-
- ofs << "\\draw[red] (0," << wstep*data[0] << ")";
- for (int i = 1; i < n; ++i)
- ofs << " -- (" << hstep*i << "," << wstep*data[i] << ")";
- ofs << ";\n";
-
- ofs <<
- "\\end{tikzpicture}\n" <<
- "\\end{document}";
-
- ofs.close();
-
-
-
-}
-
-#endif
diff --git a/src/Witness_complex/example/protected_sets/protected_sets.h b/src/Witness_complex/example/protected_sets/protected_sets.h
deleted file mode 100644
index ec627808..00000000
--- a/src/Witness_complex/example/protected_sets/protected_sets.h
+++ /dev/null
@@ -1,597 +0,0 @@
-#ifndef PROTECTED_SETS_H
-#define PROTECTED_SETS_H
-
-#include <algorithm>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-#include <CGAL/Kernel_d/Hyperplane_d.h>
-#include <CGAL/Kernel_d/Vector_d.h>
-
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::Vector_d Vector_d;
-typedef K::Oriented_side_d Oriented_side_d;
-typedef K::Has_on_positive_side_d Has_on_positive_side_d;
-typedef K::Sphere_d Sphere_d;
-typedef K::Hyperplane_d Hyperplane_d;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef Delaunay_triangulation::Vertex_handle Delaunay_vertex;
-typedef Delaunay_triangulation::Full_cell_handle Full_cell_handle;
-
-typedef std::vector<Point_d> Point_Vector;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-FT _sfty = pow(10,-14);
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// AUXILLARY FUNCTIONS
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Insert a point in Delaunay triangulation. If you are working in a flat torus, the procedure adds all the 3^d copies in adjacent cubes as well
- *
- * W is the initial point vector
- * chosen_landmark is the index of the chosen point in W
- * landmarks_ind is the vector of indices of already chosen points in W
- * delaunay is the Delaunay triangulation
- * landmark_count is the current number of chosen vertices
- * torus is true iff you are working on a flat torus [-1,1]^d
- * OUT: Vertex handle to the newly inserted point
- */
-Delaunay_vertex insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector<int>& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count, bool torus)
-{
- if (!torus)
- {
- Delaunay_vertex v =delaunay.insert(W[chosen_landmark]);
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
- return v;
- }
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- Delaunay_vertex v;
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[chosen_landmark][l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- v = delaunay.insert(point);
- }
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
- return v;
- }
-}
-
-/** Small check if the vertex v is in the full cell fc
- */
-
-bool vertex_is_in_full_cell(Delaunay_triangulation::Vertex_handle v, Full_cell_handle fc)
-{
- for (auto v_it = fc->vertices_begin(); v_it != fc->vertices_end(); ++v_it)
- if (*v_it == v)
- return true;
- return false;
-}
-
-/** Fill chosen point vector from indices with copies if you are working on a flat torus
- *
- * IN: W is the point vector
- * OUT: landmarks is the output vector
- * IN: landmarks_ind is the vector of indices
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector<int>& landmarks_ind, bool torus)
-{
- if (!torus)
- for (unsigned j = 0; j < landmarks_ind.size(); ++j)
- landmarks.push_back(W[landmarks_ind[j]]);
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- int nbL = landmarks_ind.size();
- // Fill landmarks
- for (int i = 0; i < nb_cells-1; ++i)
- for (int j = 0; j < nbL; ++j)
- {
- int cell_i = i;
- Point_d point;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[landmarks_ind[j]][l] + 2.0*(cell_i-1));
- cell_i /= 3;
- }
- landmarks.push_back(point);
- }
- }
-}
-
-/** Fill a vector of all simplices in the Delaunay triangulation giving integer indices to vertices
- *
- * IN: t is the Delaunay triangulation
- * OUT: full_cells is the output vector
- */
-
-void fill_full_cell_vector(Delaunay_triangulation& t, std::vector<std::vector<int>>& full_cells)
-{
- // Store vertex indices in a map
- int ind = 0; //index of a vertex
- std::map<Delaunay_triangulation::Vertex_handle, int> index_of_vertex;
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (t.is_infinite(v_it))
- continue;
- else
- index_of_vertex[v_it] = ind++;
- // Write full cells as vectors in full_cells
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- std::vector<int> cell;
- for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it)
- cell.push_back(index_of_vertex[*v_it]);
- full_cells.push_back(cell);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// IS VIOLATED TEST
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Check if a newly created cell is protected from old vertices
- *
- * t is the Delaunay triangulation
- * vertices is the vector containing the point to insert and a facet f in t
- * v1 is the vertex of t, such that f and v1 form a simplex
- * v2 is the vertex of t, such that f and v2 form another simplex
- * delta is the protection constant
- * power_protection is true iff the delta-power protection is used
- */
-
-bool new_cell_is_violated(Delaunay_triangulation& t, std::vector<Point_d>& vertices, const Delaunay_vertex& v1, const Delaunay_vertex v2, FT delta, bool power_protection, FT theta0)
-{
- assert(vertices.size() == vertices[0].size() ||
- vertices.size() == vertices[0].size() + 1); //simplex size = d | d+1
- assert(v1 != v2);
- if (vertices.size() == vertices[0].size() + 1)
- // FINITE CASE
- {
- Sphere_d cs(vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(Euclidean_distance().transformed_distance(center_cs, vertices[0]));
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- {
- //CGAL::Oriented_side side = Oriented_side_d()(cs, (v_it)->point());
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, (v_it)->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- */
- // Check if the simplex is thick enough
- Hyperplane_d tau_h(vertices.begin()+1, vertices.end());
- Vector_d orth_tau = tau_h.orthogonal_vector();
- /*
- p_s1 = Vector_d(*(vertices.begin()), *(vertices.begin()+1));
- */
- //std::cout << "||orth_tau|| = " << sqrt(orth_tau.squared_length()) << "\n";
- FT orth_length = sqrt(orth_tau.squared_length());
- K::Cartesian_const_iterator_d o_it, p_it, s_it, c_it;
- // Compute the altitude
- FT h = 0;
- for (o_it = orth_tau.cartesian_begin(),
- p_it = vertices.begin()->cartesian_begin(),
- s_it = (vertices.begin()+1)->cartesian_begin();
- o_it != orth_tau.cartesian_end();
- ++o_it, ++p_it, ++s_it)
- h += (*o_it)*(*p_it - *s_it)/orth_length;
- h = fabs(h);
- // Is the center inside the box?
- bool inside_the_box = true;
- for (c_it = center_cs.cartesian_begin(); c_it != center_cs.cartesian_end(); ++c_it)
- if (*c_it > 1.0 || *c_it < -1.0)
- {
- inside_the_box = false; break;
- }
- if (inside_the_box && h/r < theta0)
- return true;
- if (!t.is_infinite(v1))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v1->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v2->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- else
- // INFINITE CASE
- {
- Delaunay_triangulation::Vertex_iterator v = t.vertices_begin();
- while (t.is_infinite(v) || std::find(vertices.begin(), vertices.end(), v->point()) == vertices.end())
- v++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v->point(), CGAL::ON_POSITIVE_SIDE);
- Vector_d orth_v = facet_plane.orthogonal_vector();
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- std::vector<FT> coords;
- Point_d p = v_it->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!p_is_inside && p_delta_is_inside)
- return true;
- }
- */
- if (!t.is_infinite(v1))
- {
- std::vector<FT> coords;
- Point_d p = v1->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- std::vector<FT> coords;
- Point_d p = v2->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- }
- return false;
-}
-
-/** Auxillary recursive function to check if the point p violates the protection of the cell c and
- * if there is a violation of an eventual new cell
- *
- * p is the point to insert
- * t is the current triangulation
- * c is the current cell (simplex)
- * parent_cell is the parent cell (simplex)
- * index is the index of the facet between c and parent_cell from parent_cell's point of view
- * D is the dimension of the triangulation
- * delta is the protection constant
- * marked_cells is the vector of all visited cells containing p in their circumscribed ball
- * power_protection is true iff you are working with delta-power protection
- *
- * OUT: true iff inserting p hasn't produced any violation so far
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, Full_cell_handle c, Full_cell_handle parent_cell, int index, int D, FT delta, std::vector<Full_cell_handle>& marked_cells, bool power_protection, FT theta0)
-{
- Euclidean_distance ed;
- std::vector<Point_d> vertices;
- if (!t.is_infinite(c))
- {
- // if the cell is finite, we look if the protection is violated
- for (auto v_it = c->vertices_begin(); v_it != c->vertices_end(); ++v_it)
- vertices.push_back((*v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, vertices[0]));
- FT dist2 = ed.transformed_distance(center_cs, p);
- // if the new point is inside the protection ball of a non conflicting simplex
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- // if the new point is inside the circumscribing ball : continue violation searching on neighbours
- //if (dist2 < r*r)
- //if (dist2 < (5*r+delta)*(5*r+delta))
- if (dist2 < r*r)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells, power_protection, theta0))
- return true;
- }
- }
- // if the new point is outside the protection sphere
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is guaranteed to be finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta, power_protection, theta0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- else
- {
- // Inside of the convex hull is + side. Outside is - side.
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!t.is_infinite(*vh_it))
- vertices.push_back((*vh_it)->point());
- Delaunay_triangulation::Vertex_iterator v_it = t.vertices_begin();
- while (t.is_infinite(v_it) || vertex_is_in_full_cell(v_it, c))
- v_it++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v_it->point(), CGAL::ON_POSITIVE_SIDE);
- //CGAL::Oriented_side outside = Oriented_side_d()(facet_plane, v_it->point());
- Vector_d orth_v = facet_plane.orthogonal_vector();
- std::vector<FT> coords;
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p) && (Oriented_side_d()(facet_plane, p) != CGAL::ZERO);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
-
- // If we work with power protection, we just ignore any conflicts
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- //if the cell is infinite we look at the neighbours regardless
- if (p_is_inside)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells, power_protection, theta0))
- return true;
- }
- }
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is finite if the parent cell is finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- if (!t.is_infinite(parent_cell->vertex(i)))
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta, power_protection, theta0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- //c->tds_data().clear_visited();
- //marked_cells.pop_back();
- return false;
-}
-
-/** Checks if inserting the point p in t will make conflicts
- *
- * p is the point to insert
- * t is the current triangulation
- * D is the dimension of triangulation
- * delta is the protection constant
- * power_protection is true iff you are working with delta-power protection
- * OUT: true iff inserting p produces a violation of delta-protection.
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta, bool power_protection, FT theta0)
-{
- Euclidean_distance ed;
- Delaunay_triangulation::Vertex_handle v;
- Delaunay_triangulation::Face f(t.current_dimension());
- Delaunay_triangulation::Facet ft;
- Delaunay_triangulation::Full_cell_handle c;
- Delaunay_triangulation::Locate_type lt;
- std::vector<Full_cell_handle> marked_cells;
- c = t.locate(p, lt, f, ft, v);
- bool violation_existing_cells = is_violating_protection(p, t, c, c, 0, D, delta, marked_cells, power_protection, theta0);
- for (Full_cell_handle fc : marked_cells)
- fc->tds_data().clear();
- return violation_existing_cells;
-}
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-//!!!!!!!!!!!!! THE INTERFACE FOR LANDMARK CHOICE IS BELOW !!!!!!!!!!//
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////
-// LANDMARK CHOICE PROCEDURE
-///////////////////////////////////////////////////////////////////////
-
-/** Procedure to compute a maximal protected subset from a point cloud. All OUTs should be empty at call.
- *
- * IN: W is the initial point cloud having type Epick_d<Dynamic_dimension_tag>::Point_d
- * IN: nbP is the size of W
- * OUT: landmarks is the output vector for the points
- * OUT: landmarks_ind is the output vector for the indices of the selected points in W
- * IN: delta is the constant of protection
- * OUT: full_cells is the output vector of the simplices in the final Delaunay triangulation
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector<int>& landmarks_ind, FT delta, std::vector<std::vector<int>>& full_cells, bool torus, bool power_protection, FT theta0)
-{
- bool return_ = true;
- unsigned D = W[0].size();
- Torus_distance td;
- Euclidean_distance ed;
- Delaunay_triangulation t(D);
- CGAL::Random rand;
- int landmark_count = 0;
- std::list<int> index_list;
- // shuffle the list of indexes (via a vector)
- {
- std::vector<int> temp_vector;
- for (int i = 0; i < nbP; ++i)
- temp_vector.push_back(i);
- unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed));
- //CGAL::spatial_sort(temp_vector.begin(), temp_vector.end());
- for (std::vector<int>::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it)
- index_list.push_front(*it);
- }
- if (!torus)
- for (unsigned pos1 = 0; pos1 < D+1; ++pos1)
- {
- std::vector<FT> point;
- for (unsigned i = 0; i < pos1; ++i)
- point.push_back(-1);
- if (pos1 != D)
- point.push_back(1);
- for (unsigned i = pos1+1; i < D; ++i)
- point.push_back(0);
- assert(point.size() == D);
- W[index_list.front()] = Point_d(point);
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- }
- else if (D == 2)
- {
- for (int i = 0; i < 4; ++i)
- for (int j = 0; j < 2; ++j)
- {
- W[index_list.front()] = Point_d(std::vector<FT>{i*0.5, j*1.0});
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- W[index_list.front()] = Point_d(std::vector<FT>{0.25+i*0.5, 0.5+j});
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- }
- }
- else
- std::cout << "No torus starter available for dim>2\n";
- std::list<int>::iterator list_it = index_list.begin();
- while (list_it != index_list.end())
- {
- if (!is_violating_protection(W[*list_it], t, D, delta, power_protection, theta0))
- {
- // If no conflicts then insert in every copy of T^3
-
- insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count, torus);
- if (return_)
- {
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- index_list.erase(list_it++);
- /*
- // PIECE OF CODE FOR DEBUGGING PURPOSES
-
- Delaunay_vertex inserted_v = insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count);
- if (triangulation_is_protected(t, delta))
- {
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- { //THAT'S WHERE SOMETHING'S WRONG
- t.remove(inserted_v);
- landmarks_ind.pop_back();
- landmark_count--;
- write_delaunay_mesh(t, W[*list_it], is2d);
- is_violating_protection(W[*list_it], t_old, D, delta); //Called for encore
- }
- */
- //std::cout << "index_list_size() = " << index_list.size() << "\n";
- }
- else
- {
- list_it++;
- //std::cout << "!!!!!WARNING!!!!! A POINT HAS BEEN OMITTED!!!\n";
- }
- //if (list_it != index_list.end())
- // write_delaunay_mesh(t, W[*list_it], is2d);
- }
- fill_landmarks(W, landmarks, landmarks_ind, torus);
- fill_full_cell_vector(t, full_cells);
- /*
- if (triangulation_is_protected(t, delta))
- std::cout << "Triangulation is ok\n";
- else
- {
- std::cout << "Triangulation is BAD!! T_T ă—ăŹă—ăŹ!\n";
- }
- */
- //write_delaunay_mesh(t, W[0], is2d);
- //std::cout << t << std::endl;
-}
-
-#endif
diff --git a/src/Witness_complex/example/protected_sets/protected_sets_paper.cpp b/src/Witness_complex/example/protected_sets/protected_sets_paper.cpp
deleted file mode 100644
index f3df3f1e..00000000
--- a/src/Witness_complex/example/protected_sets/protected_sets_paper.cpp
+++ /dev/null
@@ -1,610 +0,0 @@
-#ifndef PROTECTED_SETS_H
-#define PROTECTED_SETS_H
-
-#include <algorithm>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-#include <CGAL/Kernel_d/Hyperplane_d.h>
-#include <CGAL/Kernel_d/Vector_d.h>
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::Vector_d Vector_d;
-typedef K::Oriented_side_d Oriented_side_d;
-typedef K::Has_on_positive_side_d Has_on_positive_side_d;
-typedef K::Sphere_d Sphere_d;
-typedef K::Hyperplane_d Hyperplane_d;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef Delaunay_triangulation::Vertex_handle Delaunay_vertex;
-typedef Delaunay_triangulation::Full_cell_handle Full_cell_handle;
-
-typedef std::vector<Point_d> Point_Vector;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-FT _sfty = pow(10,-14);
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// AUXILLARY FUNCTIONS
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Insert a point in Delaunay triangulation. If you are working in a flat torus, the procedure adds all the 3^d copies in adjacent cubes as well
- *
- * W is the initial point vector
- * chosen_landmark is the index of the chosen point in W
- * landmarks_ind is the vector of indices of already chosen points in W
- * delaunay is the Delaunay triangulation
- * landmark_count is the current number of chosen vertices
- * torus is true iff you are working on a flat torus [-1,1]^d
- * OUT: Vertex handle to the newly inserted point
- */
-Delaunay_vertex insert_delaunay_landmark_with_copies(Point_d& p, Delaunay_triangulation& delaunay, int& landmark_count, bool torus)
-{
- if (!torus)
- {
- Delaunay_vertex v =delaunay.insert(p);
- landmark_count++;
- return v;
- }
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- Delaunay_vertex v;
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(p[l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- v = delaunay.insert(point);
- }
- landmark_count++;
- return v;
- }
-}
-
-/** Small check if the vertex v is in the full cell fc
- */
-
-bool vertex_is_in_full_cell(Delaunay_triangulation::Vertex_handle v, Full_cell_handle fc)
-{
- for (auto v_it = fc->vertices_begin(); v_it != fc->vertices_end(); ++v_it)
- if (*v_it == v)
- return true;
- return false;
-}
-
-/** Fill chosen point vector from indices with copies if you are working on a flat torus
- *
- * IN: W is the point vector
- * OUT: landmarks is the output vector
- * IN: landmarks_ind is the vector of indices
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector<int>& landmarks_ind, bool torus)
-{
- if (!torus)
- for (unsigned j = 0; j < landmarks_ind.size(); ++j)
- landmarks.push_back(W[landmarks_ind[j]]);
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- int nbL = landmarks_ind.size();
- // Fill landmarks
- for (int i = 0; i < nb_cells-1; ++i)
- for (int j = 0; j < nbL; ++j)
- {
- int cell_i = i;
- Point_d point;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[landmarks_ind[j]][l] + 2.0*(cell_i-1));
- cell_i /= 3;
- }
- landmarks.push_back(point);
- }
- }
-}
-
-/** Fill a vector of all simplices in the Delaunay triangulation giving integer indices to vertices
- *
- * IN: t is the Delaunay triangulation
- * OUT: full_cells is the output vector
- */
-
-void fill_full_cell_vector(Delaunay_triangulation& t, std::vector<std::vector<int>>& full_cells)
-{
- // Store vertex indices in a map
- int ind = 0; //index of a vertex
- std::map<Delaunay_triangulation::Vertex_handle, int> index_of_vertex;
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (t.is_infinite(v_it))
- continue;
- else
- index_of_vertex[v_it] = ind++;
- // Write full cells as vectors in full_cells
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- std::vector<int> cell;
- for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it)
- cell.push_back(index_of_vertex[*v_it]);
- full_cells.push_back(cell);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// IS VIOLATED TEST
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Check if a newly created cell is protected from old vertices
- *
- * t is the Delaunay triangulation
- * vertices is the vector containing the point to insert and a facet f in t
- * v1 is the vertex of t, such that f and v1 form a simplex
- * v2 is the vertex of t, such that f and v2 form another simplex
- * delta is the protection constant
- * power_protection is true iff the delta-power protection is used
- */
-
-bool new_cell_is_violated(Delaunay_triangulation& t, std::vector<Point_d>& vertices, const Delaunay_vertex& v1, const Delaunay_vertex v2, FT delta, bool power_protection, FT theta0)
-{
- assert(vertices.size() == vertices[0].size() ||
- vertices.size() == vertices[0].size() + 1); //simplex size = d | d+1
- assert(v1 != v2);
- if (vertices.size() == vertices[0].size() + 1)
- // FINITE CASE
- {
- Sphere_d cs(vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(Euclidean_distance().transformed_distance(center_cs, vertices[0]));
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- {
- //CGAL::Oriented_side side = Oriented_side_d()(cs, (v_it)->point());
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, (v_it)->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- */
- // Check if the simplex is thick enough
- Hyperplane_d tau_h(vertices.begin()+1, vertices.end());
- Vector_d orth_tau = tau_h.orthogonal_vector();
- /*
- p_s1 = Vector_d(*(vertices.begin()), *(vertices.begin()+1));
- */
- //std::cout << "||orth_tau|| = " << sqrt(orth_tau.squared_length()) << "\n";
- FT orth_length = sqrt(orth_tau.squared_length());
- K::Cartesian_const_iterator_d o_it, p_it, s_it, c_it;
- // Compute the altitude
- FT h = 0;
- for (o_it = orth_tau.cartesian_begin(),
- p_it = vertices.begin()->cartesian_begin(),
- s_it = (vertices.begin()+1)->cartesian_begin();
- o_it != orth_tau.cartesian_end();
- ++o_it, ++p_it, ++s_it)
- h += (*o_it)*(*p_it - *s_it)/orth_length;
- h = fabs(h);
- // Is the center inside the box?
- bool inside_the_box = true;
- for (c_it = center_cs.cartesian_begin(); c_it != center_cs.cartesian_end(); ++c_it)
- if (*c_it > 1.0 || *c_it < -1.0)
- {
- inside_the_box = false; break;
- }
- if (inside_the_box && h/r < theta0)
- return true;
- if (!t.is_infinite(v1))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v1->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v2->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- else
- // INFINITE CASE
- {
- Delaunay_triangulation::Vertex_iterator v = t.vertices_begin();
- while (t.is_infinite(v) || std::find(vertices.begin(), vertices.end(), v->point()) == vertices.end())
- v++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v->point(), CGAL::ON_POSITIVE_SIDE);
- Vector_d orth_v = facet_plane.orthogonal_vector();
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- std::vector<FT> coords;
- Point_d p = v_it->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!p_is_inside && p_delta_is_inside)
- return true;
- }
- */
- if (!t.is_infinite(v1))
- {
- std::vector<FT> coords;
- Point_d p = v1->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- std::vector<FT> coords;
- Point_d p = v2->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- }
- return false;
-}
-
-/** Auxillary recursive function to check if the point p violates the protection of the cell c and
- * if there is a violation of an eventual new cell
- *
- * p is the point to insert
- * t is the current triangulation
- * c is the current cell (simplex)
- * parent_cell is the parent cell (simplex)
- * index is the index of the facet between c and parent_cell from parent_cell's point of view
- * D is the dimension of the triangulation
- * delta is the protection constant
- * marked_cells is the vector of all visited cells containing p in their circumscribed ball
- * power_protection is true iff you are working with delta-power protection
- *
- * OUT: true iff inserting p hasn't produced any violation so far
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, Full_cell_handle c, Full_cell_handle parent_cell, int index, int D, FT delta, std::vector<Full_cell_handle>& marked_cells, bool power_protection, FT theta0)
-{
- Euclidean_distance ed;
- std::vector<Point_d> vertices;
- if (!t.is_infinite(c))
- {
- // if the cell is finite, we look if the protection is violated
- for (auto v_it = c->vertices_begin(); v_it != c->vertices_end(); ++v_it)
- vertices.push_back((*v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, vertices[0]));
- FT dist2 = ed.transformed_distance(center_cs, p);
- // if the new point is inside the protection ball of a non conflicting simplex
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- // if the new point is inside the circumscribing ball : continue violation searching on neighbours
- //if (dist2 < r*r)
- //if (dist2 < (5*r+delta)*(5*r+delta))
- if (dist2 < r*r)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells, power_protection, theta0))
- return true;
- }
- }
- // if the new point is outside the protection sphere
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is guaranteed to be finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta, power_protection, theta0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- else
- {
- // Inside of the convex hull is + side. Outside is - side.
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!t.is_infinite(*vh_it))
- vertices.push_back((*vh_it)->point());
- Delaunay_triangulation::Vertex_iterator v_it = t.vertices_begin();
- while (t.is_infinite(v_it) || vertex_is_in_full_cell(v_it, c))
- v_it++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v_it->point(), CGAL::ON_POSITIVE_SIDE);
- //CGAL::Oriented_side outside = Oriented_side_d()(facet_plane, v_it->point());
- Vector_d orth_v = facet_plane.orthogonal_vector();
- std::vector<FT> coords;
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p) && (Oriented_side_d()(facet_plane, p) != CGAL::ZERO);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
-
- // If we work with power protection, we just ignore any conflicts
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- //if the cell is infinite we look at the neighbours regardless
- if (p_is_inside)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells, power_protection, theta0))
- return true;
- }
- }
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is finite if the parent cell is finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- if (!t.is_infinite(parent_cell->vertex(i)))
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta, power_protection, theta0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- //c->tds_data().clear_visited();
- //marked_cells.pop_back();
- return false;
-}
-
-/** Checks if inserting the point p in t will make conflicts
- *
- * p is the point to insert
- * t is the current triangulation
- * D is the dimension of triangulation
- * delta is the protection constant
- * power_protection is true iff you are working with delta-power protection
- * OUT: true iff inserting p produces a violation of delta-protection.
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta, bool power_protection, FT theta0)
-{
- Euclidean_distance ed;
- Delaunay_triangulation::Vertex_handle v;
- Delaunay_triangulation::Face f(t.current_dimension());
- Delaunay_triangulation::Facet ft;
- Delaunay_triangulation::Full_cell_handle c;
- Delaunay_triangulation::Locate_type lt;
- std::vector<Full_cell_handle> marked_cells;
- c = t.locate(p, lt, f, ft, v);
- bool violation_existing_cells = is_violating_protection(p, t, c, c, 0, D, delta, marked_cells, power_protection, theta0);
- for (Full_cell_handle fc : marked_cells)
- fc->tds_data().clear();
- return violation_existing_cells;
-}
-
-//////////////////////////////////////////////////////////////////////
-// INITIALIZATION
-//////////////////////////////////////////////////////////////////////
-
-void initialize(Search_Tree& W, Delaunay& t, int D, int width, bool torus)
-{
- if (!torus)
- std::cout << "Non-toric case is not supported\n";
- else
- {
- if (D == 2)
- {
- FT stepx = 2.0/width;
- FT stepy = sqrt(3)/width;
- for (int i = 0; i < width; ++i)
- for (int j = 0; j < floor(2*width/sqrt(3)); ++j)
- {
- insert_delaunay_landmark_with_copies(Point_d(step*i,))
- }
- }
- else (D == 3)
- {
-
- }
- else std::cout << "T^d with d>3 not supported";
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-//!!!!!!!!!!!!! THE INTERFACE FOR LANDMARK CHOICE IS BELOW !!!!!!!!!!//
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////
-// LANDMARK CHOICE PROCEDURE AS IN PAPER
-///////////////////////////////////////////////////////////////////////
-
-/** Procedure to compute a maximal protected subset from a point cloud. All OUTs should be empty at call.
- *
- * IN: W is the initial point cloud having type Epick_d<Dynamic_dimension_tag>::Point_d
- * IN: nbP is the size of W
- * OUT: landmarks is the output vector for the points
- * OUT: landmarks_ind is the output vector for the indices of the selected points in W
- * IN: delta is the constant of protection
- * OUT: full_cells is the output vector of the simplices in the final Delaunay triangulation
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-template<class Search_Tree>
-void protected_delaunay_refinement(Search_Tree& W, int nbP, Point_Vector& landmarks, FT delta, bool torus, bool power_protection, FT theta0)
-{
- bool return_ = true;
- unsigned D = W[0].size();
- Torus_distance td;
- Euclidean_distance ed;
- Delaunay_triangulation t(D);
- CGAL::Random rand;
- int landmark_count = 0;
- //std::list<int> index_list;
- // shuffle the list of indexes (via a vector)
- // {
- // std::vector<int> temp_vector;
- // for (int i = 0; i < nbP; ++i)
- // temp_vector.push_back(i);
- // unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- // std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed));
- // //CGAL::spatial_sort(temp_vector.begin(), temp_vector.end());
- // for (std::vector<int>::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it)
- // index_list.push_front(*it);
- // }
- if (torus)
- if (D == 2)
- // \T^2
- {
- for (int i = 0; i < 4; ++i)
- for (int j = 0; j < 2; ++j)
- {
- W[index_list.front()] = Point_d(std::vector<FT>{i*0.5, j*1.0});
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- W[index_list.front()] = Point_d(std::vector<FT>{0.25+i*0.5, 0.5+j});
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- }
- }
- else if (D == 3)
- {
-
- }
- //std::cout << "No torus starter available for dim>2\n";
- std::list<int>::iterator list_it = index_list.begin();
- while (list_it != index_list.end())
- {
- if (!is_violating_protection(W[*list_it], t, D, delta, power_protection, theta0))
- {
- // If no conflicts then insert in every copy of T^3
-
- insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count, torus);
- if (return_)
- {
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- index_list.erase(list_it++);
- /*
- // PIECE OF CODE FOR DEBUGGING PURPOSES
-
- Delaunay_vertex inserted_v = insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count);
- if (triangulation_is_protected(t, delta))
- {
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- { //THAT'S WHERE SOMETHING'S WRONG
- t.remove(inserted_v);
- landmarks_ind.pop_back();
- landmark_count--;
- write_delaunay_mesh(t, W[*list_it], is2d);
- is_violating_protection(W[*list_it], t_old, D, delta); //Called for encore
- }
- */
- //std::cout << "index_list_size() = " << index_list.size() << "\n";
- }
- else
- {
- list_it++;
- //std::cout << "!!!!!WARNING!!!!! A POINT HAS BEEN OMITTED!!!\n";
- }
- //if (list_it != index_list.end())
- // write_delaunay_mesh(t, W[*list_it], is2d);
- }
- fill_landmarks(W, landmarks, landmarks_ind, torus);
- fill_full_cell_vector(t, full_cells);
- /*
- if (triangulation_is_protected(t, delta))
- std::cout << "Triangulation is ok\n";
- else
- {
- std::cout << "Triangulation is BAD!! T_T ă—ăŹă—ăŹ!\n";
- }
- */
- //write_delaunay_mesh(t, W[0], is2d);
- //std::cout << t << std::endl;
-}
-
-#endif
diff --git a/src/Witness_complex/example/protected_sets/protected_sets_paper.h b/src/Witness_complex/example/protected_sets/protected_sets_paper.h
deleted file mode 100644
index 61fcc75b..00000000
--- a/src/Witness_complex/example/protected_sets/protected_sets_paper.h
+++ /dev/null
@@ -1,917 +0,0 @@
-#ifndef PROTECTED_SETS_H
-#define PROTECTED_SETS_H
-
-#include <algorithm>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-#include <CGAL/Kernel_d/Hyperplane_d.h>
-#include <CGAL/Kernel_d/Vector_d.h>
-
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Fuzzy_sphere.h>
-
-#include <boost/heap/fibonacci_heap.hpp>
-#include <boost/heap/policies.hpp>
-
-#include "output_tikz.h"
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::Line_d Line_d;
-typedef K::Vector_d Vector_d;
-typedef K::Oriented_side_d Oriented_side_d;
-typedef K::Has_on_positive_side_d Has_on_positive_side_d;
-typedef K::Sphere_d Sphere_d;
-typedef K::Hyperplane_d Hyperplane_d;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef Delaunay_triangulation::Vertex_handle Delaunay_vertex;
-typedef Delaunay_triangulation::Full_cell_handle Full_cell_handle;
-
-typedef std::vector<Point_d> Point_Vector;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-
-FT _sfty = pow(10,-14);
-
-bool experiment1, experiment2 = false;
-
-/* Experiment 1: epsilon as function on time **********************/
-std::vector<FT> eps_vector;
-
-/* Experiment 2: R/epsilon on delta *******************************/
-std::vector<FT> epsratio_vector;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// AUXILLARY FUNCTIONS
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Insert a point in Delaunay triangulation. If you are working in a flat torus, the procedure adds all the 3^d copies in adjacent cubes as well
- *
- * W is the initial point vector
- * chosen_landmark is the index of the chosen point in W
- * landmarks_ind is the vector of indices of already chosen points in W
- * delaunay is the Delaunay triangulation
- * landmark_count is the current number of chosen vertices
- * torus is true iff you are working on a flat torus [-1,1]^d
- * OUT: Vertex handle to the newly inserted point
- */
-Delaunay_vertex insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector<int>& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count, bool torus)
-{
- if (!torus)
- {
- Delaunay_vertex v =delaunay.insert(W[chosen_landmark]);
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
- return v;
- }
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- Delaunay_vertex v;
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[chosen_landmark][l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- if (i == nb_cells/2)
- v = delaunay.insert(point); //v = center point
- else
- delaunay.insert(point);
- }
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
- return v;
- }
-}
-
-/** Small check if the vertex v is in the full cell fc
- */
-
-bool vertex_is_in_full_cell(Delaunay_triangulation::Vertex_handle v, Full_cell_handle fc)
-{
- for (auto v_it = fc->vertices_begin(); v_it != fc->vertices_end(); ++v_it)
- if (*v_it == v)
- return true;
- return false;
-}
-
-/** Fill chosen point vector from indices with copies if you are working on a flat torus
- *
- * IN: W is the point vector
- * OUT: landmarks is the output vector
- * IN: landmarks_ind is the vector of indices
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector<int>& landmarks_ind, bool torus)
-{
- if (!torus)
- for (unsigned j = 0; j < landmarks_ind.size(); ++j)
- landmarks.push_back(W[landmarks_ind[j]]);
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- int nbL = landmarks_ind.size();
- // Fill landmarks
- for (int i = 0; i < nb_cells-1; ++i)
- for (int j = 0; j < nbL; ++j)
- {
- int cell_i = i;
- Point_d point;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[landmarks_ind[j]][l] + 2.0*(cell_i-1));
- cell_i /= 3;
- }
- landmarks.push_back(point);
- }
- }
-}
-
-/** Fill a vector of all simplices in the Delaunay triangulation giving integer indices to vertices
- *
- * IN: t is the Delaunay triangulation
- * OUT: full_cells is the output vector
- */
-
-void fill_full_cell_vector(Delaunay_triangulation& t, std::vector<std::vector<int>>& full_cells)
-{
- // Store vertex indices in a map
- int ind = 0; //index of a vertex
- std::map<Delaunay_triangulation::Vertex_handle, int> index_of_vertex;
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (t.is_infinite(v_it))
- continue;
- else
- index_of_vertex[v_it] = ind++;
- // Write full cells as vectors in full_cells
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- std::vector<int> cell;
- for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it)
- cell.push_back(index_of_vertex[*v_it]);
- full_cells.push_back(cell);
- }
-}
-
-bool sphere_intersects_cube(Point_d& c, FT r)
-{
- bool in_cube = true;
- // int i = 0, D = p.size();
- for (auto xi = c.cartesian_begin(); xi != c.cartesian_end(); ++xi)
- // if ((*xi < 1.0 || *xi > -1.0) &&
- // (*xi-r < 1.0 || *xi-r > -1.0) &&
- // (*xi+r < 1.0 || *xi+r > -1.0))
-
- if ((*xi-r < -1.0 && *xi+r < -1.0) ||
- (*xi-r > 1.0 && *xi+r > 1.0 ))
- {
- in_cube = false; break;
- }
- return in_cube;
-}
-
-/** Recursive function for checking if the simplex is good,
- * meaning it does not contain a k-face, which is not theta0^(k-1) thick
- */
-
-bool is_theta0_good(std::vector<Point_d>& vertices, FT theta0)
-{
- if (theta0 > 1)
- {
- std::cout << "Warning! theta0 is set > 1\n";
- return false;
- }
- int D = vertices.size()-1;
- if (D <= 1)
- return true; // Edges are always good
- //******** Circumscribed sphere
- Euclidean_distance ed;
- Sphere_d cs(vertices.begin(), vertices.end());
- FT r = sqrt(cs.squared_radius());
- for (std::vector<Point_d>::iterator v_it = vertices.begin(); v_it != vertices.end(); ++v_it)
- {
- std::vector<Point_d> facet;
- for (std::vector<Point_d>::iterator f_it = vertices.begin(); f_it != vertices.end(); ++f_it)
- if (f_it != v_it)
- facet.push_back(*f_it);
- // Compute the altitude
-
- if (vertices[0].size() == 3 && D == 2)
- {
- //Vector_d l = facet[0] - facet[1];
- FT orth_length2 = ed.transformed_distance(facet[0],facet[1]);
- K::Cartesian_const_iterator_d l_it, p_it, s_it, c_it;
- FT h = 0;
- // Scalar product = <sp,l>
- FT scalar = 0;
- for (p_it = v_it->cartesian_begin(),
- s_it = facet[0].cartesian_begin(),
- l_it = facet[1].cartesian_begin();
- p_it != v_it->cartesian_end();
- ++l_it, ++p_it, ++s_it)
- scalar += (*l_it - *s_it)*(*p_it - *s_it);
- // Gram-Schmidt for one vector
- for (p_it = v_it->cartesian_begin(),
- s_it = facet[0].cartesian_begin(),
- l_it = facet[1].cartesian_begin();
- p_it != v_it->cartesian_end();
- ++l_it, ++p_it, ++s_it)
- {
- FT hx = (*p_it - *s_it) - scalar*(*l_it - *s_it)/orth_length2;
- h += hx*hx;
- }
- h = sqrt(h);
-
- if (h/(2*r) < pow(theta0, D-1))
- return false;
- if (!is_theta0_good(facet, theta0))
- return false;
- }
- else
- {
- Hyperplane_d tau_h(facet.begin(), facet.end(), *v_it);
- Vector_d orth_tau = tau_h.orthogonal_vector();
- FT orth_length = sqrt(orth_tau.squared_length());
- K::Cartesian_const_iterator_d o_it, p_it, s_it, c_it;
- FT h = 0;
- for (o_it = orth_tau.cartesian_begin(),
- p_it = v_it->cartesian_begin(),
- s_it = (facet.begin())->cartesian_begin();
- o_it != orth_tau.cartesian_end();
- ++o_it, ++p_it, ++s_it)
- h += (*o_it)*(*p_it - *s_it)/orth_length;
- h = fabs(h);
- if (h/(2*r) < pow(theta0, D-1))
- return false;
- if (!is_theta0_good(facet, theta0))
- return false;
- }
- }
- return true;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// IS VIOLATED TEST
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Check if a newly created cell is protected from old vertices
- *
- * t is the Delaunay triangulation
- * vertices is the vector containing the point to insert and a facet f in t
- * v1 is the vertex of t, such that f and v1 form a simplex
- * v2 is the vertex of t, such that f and v2 form another simplex
- * delta is the protection constant
- * power_protection is true iff the delta-power protection is used
- */
-
-bool new_cell_is_violated(Delaunay_triangulation& t, std::vector<Point_d>& vertices, const Delaunay_vertex& v1, const Delaunay_vertex v2, FT delta, bool power_protection, FT theta0)
-{
- assert(vertices.size() == vertices[0].size() ||
- vertices.size() == vertices[0].size() + 1); //simplex size = d | d+1
- assert(v1 != v2);
- if (vertices.size() == vertices[0].size() + 1)
- // FINITE CASE
- {
- Sphere_d cs(vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(Euclidean_distance().transformed_distance(center_cs, vertices[0]));
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- {
- //CGAL::Oriented_side side = Oriented_side_d()(cs, (v_it)->point());
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, (v_it)->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- */
- // Check if the simplex is theta0-good
- if (!is_theta0_good(vertices, theta0))
- return true;
- // Is the center inside the box? (only Euclidean case)
- // if (!torus)
- // {
- // bool inside_the_box = true;
- // for (c_it = center_cs.cartesian_begin(); c_it != center_cs.cartesian_end(); ++c_it)
- // if (*c_it > 1.0 || *c_it < -1.0)
- // {
- // inside_the_box = false; break;
- // }
- // if (inside_the_box && h/r < theta0)
- // return true;
- // }
- // Check the two vertices (if not infinite)
- if (!t.is_infinite(v1))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v1->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v2->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- else
- // INFINITE CASE
- {
- Delaunay_triangulation::Vertex_iterator v = t.vertices_begin();
- while (t.is_infinite(v) || std::find(vertices.begin(), vertices.end(), v->point()) == vertices.end())
- v++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v->point(), CGAL::ON_POSITIVE_SIDE);
- Vector_d orth_v = facet_plane.orthogonal_vector();
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- std::vector<FT> coords;
- Point_d p = v_it->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!p_is_inside && p_delta_is_inside)
- return true;
- }
- */
- if (!t.is_infinite(v1))
- {
- std::vector<FT> coords;
- Point_d p = v1->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- std::vector<FT> coords;
- Point_d p = v2->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- }
- return false;
-}
-
-/** Auxillary recursive function to check if the point p violates the protection of the cell c and
- * if there is a violation of an eventual new cell
- *
- * p is the point to insert
- * t is the current triangulation
- * c is the current cell (simplex)
- * parent_cell is the parent cell (simplex)
- * index is the index of the facet between c and parent_cell from parent_cell's point of view
- * D is the dimension of the triangulation
- * delta is the protection constant
- * marked_cells is the vector of all visited cells containing p in their circumscribed ball
- * power_protection is true iff you are working with delta-power protection
- *
- * OUT: true iff inserting p hasn't produced any violation so far
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, Full_cell_handle c, Full_cell_handle parent_cell, int index, int D, FT delta, std::vector<Full_cell_handle>& marked_cells, bool power_protection, FT theta0)
-{
- Euclidean_distance ed;
- std::vector<Point_d> vertices;
- if (!t.is_infinite(c))
- {
- // if the cell is finite, we look if the protection is violated
- for (auto v_it = c->vertices_begin(); v_it != c->vertices_end(); ++v_it)
- vertices.push_back((*v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, vertices[0]));
- FT dist2 = ed.transformed_distance(center_cs, p);
- // if the new point is inside the protection ball of a non conflicting simplex
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- // if the new point is inside the circumscribing ball : continue violation searching on neighbours
- //if (dist2 < r*r)
- //if (dist2 < (5*r+delta)*(5*r+delta))
- if (dist2 < r*r)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells, power_protection, theta0))
- return true;
- }
- }
- // if the new point is outside the protection sphere
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is guaranteed to be finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta, power_protection, theta0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- else
- {
- // Inside of the convex hull is + side. Outside is - side.
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!t.is_infinite(*vh_it))
- vertices.push_back((*vh_it)->point());
- Delaunay_triangulation::Vertex_iterator v_it = t.vertices_begin();
- while (t.is_infinite(v_it) || vertex_is_in_full_cell(v_it, c))
- v_it++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v_it->point(), CGAL::ON_POSITIVE_SIDE);
- //CGAL::Oriented_side outside = Oriented_side_d()(facet_plane, v_it->point());
- Vector_d orth_v = facet_plane.orthogonal_vector();
- std::vector<FT> coords;
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p) && (Oriented_side_d()(facet_plane, p) != CGAL::ZERO);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
-
- // If we work with power protection, we just ignore any conflicts
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- //if the cell is infinite we look at the neighbours regardless
- if (p_is_inside)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells, power_protection, theta0))
- return true;
- }
- }
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is finite if the parent cell is finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- if (!t.is_infinite(parent_cell->vertex(i)))
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta, power_protection, theta0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- //c->tds_data().clear_visited();
- //marked_cells.pop_back();
- return false;
-}
-
-/** Checks if inserting the point p in t will make conflicts
- *
- * p is the point to insert
- * t is the current triangulation
- * D is the dimension of triangulation
- * delta is the protection constant
- * power_protection is true iff you are working with delta-power protection
- * OUT: true iff inserting p produces a violation of delta-protection.
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta, bool power_protection, FT theta0)
-{
- Euclidean_distance ed;
- Delaunay_triangulation::Vertex_handle v;
- Delaunay_triangulation::Face f(t.current_dimension());
- Delaunay_triangulation::Facet ft;
- Delaunay_triangulation::Full_cell_handle c;
- Delaunay_triangulation::Locate_type lt;
- std::vector<Full_cell_handle> marked_cells;
- //c = t.locate(p, lt, f, ft, v);
- c = t.locate(p);
- bool violation_existing_cells = is_violating_protection(p, t, c, c, 0, D, delta, marked_cells, power_protection, theta0);
- for (Full_cell_handle fc : marked_cells)
- fc->tds_data().clear();
- return violation_existing_cells;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-// INITIALIZATION
-////////////////////////////////////////////////////////////////////////
-
-// Query for a sphere near a cite in all copies of a torus
-// OUT points_inside
-void torus_search(Tree& treeW, int D, Point_d cite, FT r, std::vector<int>& points_inside)
-{
- int nb_cells = pow(3, D);
- Delaunay_vertex v;
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> cite_copy;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- cite_copy.push_back(cite[l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- Fuzzy_sphere fs(cite_copy, r, 0, treeW.traits());
- treeW.search(std::insert_iterator<std::vector<int>>(points_inside, points_inside.end()), fs);
- }
-}
-
-
-void initialize_torus(Point_Vector& W, Tree& treeW, Delaunay_triangulation& t, FT epsilon, std::vector<int>& landmarks_ind, int& landmark_count)
-{
- int D = W[0].size();
- if (D == 2)
- {
- int xw = 6, yw = 4;
- // Triangular lattice close to regular triangles h=0.866a ~ 0.875a : 48p
- for (int i = 0; i < xw; ++i)
- for (int j = 0; j < yw; ++j)
- {
- Point_d cite1(std::vector<FT>{2.0/xw*i, 1.0/yw*j});
- std::vector<int> points_inside;
- torus_search(treeW, D, cite1, epsilon, points_inside);
- assert(points_inside.size() > 0);
- insert_delaunay_landmark_with_copies(W, *(points_inside.begin()),
- landmarks_ind, t, landmark_count, true);
- Point_d cite2(std::vector<FT>{2.0/xw*(i+0.5), 1.0/yw*(j+0.5)});
- points_inside.clear();
- torus_search(treeW, D, cite2, epsilon, points_inside);
- assert(points_inside.size() > 0);
- insert_delaunay_landmark_with_copies(W, *(points_inside.begin()),
- landmarks_ind, t, landmark_count, true);
- }
- }
- else if (D == 3)
- {
- int wd = 3;
- // Body-centered cubic lattice : 54p
- for (int i = 0; i < wd; ++i)
- for (int j = 0; j < wd; ++j)
- for (int k = 0; k < wd; ++k)
- {
- Point_d cite1(std::vector<FT>{2.0/wd*i, 2.0/wd*j, 2.0/wd*k});
- std::vector<int> points_inside;
- torus_search(treeW, D, cite1, epsilon, points_inside);
- assert(points_inside.size() > 0);
- insert_delaunay_landmark_with_copies(W, *(points_inside.begin()),
- landmarks_ind, t, landmark_count, true);
- Point_d cite2(std::vector<FT>{2.0/wd*(i+0.5), 2.0/wd*(j+0.5), 2.0/wd*(k+0.5)});
- points_inside.clear();
- torus_search(treeW, D, cite2, epsilon, points_inside);
- assert(points_inside.size() > 0);
- insert_delaunay_landmark_with_copies(W, *(points_inside.begin()),
- landmarks_ind, t, landmark_count, true);
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-//!!!!!!!!!!!!! THE INTERFACE FOR LANDMARK CHOICE IS BELOW !!!!!!!!!!//
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-
-// Struct for R_max_heap elements
-
-struct R_max_handle
-{
- FT value;
- Point_d center;
-
- R_max_handle(FT value_, Point_d c): value(value_), center(c)
- {}
-};
-
-struct R_max_compare
-{
- bool operator()(const R_max_handle& rmh1, const R_max_handle& rmh2) const
- {
- return rmh1.value < rmh2.value;
- }
-};
-
-// typedef boost::heap::fibonacci_heap<R_max_handle, boost::heap::compare<R_max_compare>> Heap;
-
-// void make_heap(Delaunay_triangulation& t, Heap& R_max_heap)
-// {
-// R_max_heap.clear();
-// for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
-// {
-// if (t.is_infinite(fc_it))
-// continue;
-// Point_Vector vertices;
-// for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
-// vertices.push_back((*fc_v_it)->point());
-// Sphere_d cs( vertices.begin(), vertices.end());
-// Point_d csc = cs.center();
-// FT r = sqrt(cs.squared_radius());
-// // A ball is in the heap, if it intersects the cube
-// bool accepted = sphere_intersects_cube(csc, sqrt(r));
-// if (!accepted)
-// continue;
-// R_max_heap.push(R_max_handle(r, fc_it, csc));
-// }
-// }
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// SAMPLING RADIUS
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-R_max_handle sampling_radius(Delaunay_triangulation& t)
-{
- FT epsilon2 = 0;
- Point_d final_center;
- Point_d control_point;
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- FT r2 = Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin()));
- if (epsilon2 < r2)
- {
- epsilon2 = r2;
- final_center = csc;
- control_point = (*vertices.begin());
- }
- }
- return R_max_handle(sqrt(epsilon2), final_center);
-}
-
-///////////////////////////////////////////////////////////////////////
-// LANDMARK CHOICE PROCEDURE
-///////////////////////////////////////////////////////////////////////
-
-/** Procedure to compute a maximal protected subset from a point cloud. All OUTs should be empty at call.
- *
- * IN: W is the initial point cloud having type Epick_d<Dynamic_dimension_tag>::Point_d
- * IN: nbP is the size of W
- * OUT: landmarks is the output vector for the points
- * OUT: landmarks_ind is the output vector for the indices of the selected points in W
- * IN: delta is the constant of protection
- * OUT: full_cells is the output vector of the simplices in the final Delaunay triangulation
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void protected_delaunay(Point_Vector& W,
- //Point_Vector& landmarks,
- std::vector<int>& landmarks_ind,
- FT delta,
- FT epsilon,
- FT alpha,
- FT theta0,
- //std::vector<std::vector<int>>& full_cells,
- bool torus,
- bool power_protection
- )
-{
- //bool return_ = true;
- unsigned D = W[0].size();
- int nbP = W.size();
- Torus_distance td;
- Euclidean_distance ed;
- Delaunay_triangulation t(D);
- CGAL::Random rand;
- int landmark_count = 0;
- std::list<int> index_list;
- //****************** Kd Tree W
- STraits traits(&(W[0]));
- Tree treeW(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbP),
- typename Tree::Splitter(),
- traits);
- // shuffle the list of indexes (via a vector)
- {
- std::vector<int> temp_vector;
- for (int i = 0; i < nbP; ++i)
- temp_vector.push_back(i);
- unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed));
- //CGAL::spatial_sort(temp_vector.begin(), temp_vector.end());
- for (std::vector<int>::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it)
- index_list.push_front(*it);
- }
- //******************** Initialize point set
- if (!torus)
- for (unsigned pos1 = 0; pos1 < D+1; ++pos1)
- {
- std::vector<FT> point;
- for (unsigned i = 0; i < pos1; ++i)
- point.push_back(-1);
- if (pos1 != D)
- point.push_back(1);
- for (unsigned i = pos1+1; i < D; ++i)
- point.push_back(0);
- assert(point.size() == D);
- W[index_list.front()] = Point_d(point);
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- }
- else
- initialize_torus(W, treeW, t, epsilon, landmarks_ind, landmark_count);
- //std::cout << "Size of treeW: " << treeW.size() << "\n";
- //std::cout << "Size of t: " << t.number_of_vertices() << "\n";
- //******************* Initialize heap for R_max
- //Heap R_max_heap;
- //make_heap(t, R_max_heap);
-
-
- R_max_handle rh = sampling_radius(t);
- FT epsilon0 = rh.value;
- if (experiment1) eps_vector.push_back(pow(1/rh.value,D));
- //******************** Iterative algorithm
- std::vector<int> candidate_points;
- torus_search(treeW, D,
- rh.center,
- alpha*rh.value,
- candidate_points);
- std::list<int>::iterator list_it;
- std::vector<int>::iterator cp_it = candidate_points.begin();
- while (cp_it != candidate_points.end())
- {
- if (!is_violating_protection(W[*cp_it], t, D, delta, power_protection, theta0))
- {
- insert_delaunay_landmark_with_copies(W, *cp_it, landmarks_ind, t, landmark_count, torus);
- //make_heap(t, R_max_heap);
- rh = sampling_radius(t);
- if (experiment1) eps_vector.push_back(pow(1/rh.value,D));
- //std::cout << "rhvalue = " << rh.value << "\n";
- //std::cout << "D = " <<
- candidate_points.clear();
- torus_search(treeW, D,
- rh.center,
- alpha*rh.value,
- candidate_points);
- /*
- // PIECE OF CODE FOR DEBUGGING PURPOSES
-
- Delaunay_vertex inserted_v = insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count);
- if (triangulation_is_protected(t, delta))
- {
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- { //THAT'S WHERE SOMETHING'S WRONG
- t.remove(inserted_v);
- landmarks_ind.pop_back();
- landmark_count--;
- write_delaunay_mesh(t, W[*list_it], is2d);
- is_violating_protection(W[*list_it], t_old, D, delta); //Called for encore
- }
- */
- //std::cout << "index_list_size() = " << index_list.size() << "\n";
- }
- else
- {
- cp_it++;
- //std::cout << "!!!!!WARNING!!!!! A POINT HAS BEEN OMITTED!!!\n";
- }
- //if (list_it != index_list.end())
- // write_delaunay_mesh(t, W[*list_it], is2d);
- }
- if (experiment2) epsratio_vector.push_back(rh.value/epsilon0);
- std::cout << "The iteration ended when cp_count = " << candidate_points.size() << "\n";
- std::cout << "alphaRmax = " << alpha*rh.value << "\n";
- std::cout << "epsilon' = " << rh.value << "\n";
- std::cout << "nbL = " << landmarks_ind.size() << "\n";
- //fill_landmarks(W, landmarks, landmarks_ind, torus);
- //fill_full_cell_vector(t, full_cells);
- /*
- if (triangulation_is_protected(t, delta))
- std::cout << "Triangulation is ok\n";
- else
- {
- std::cout << "Triangulation is BAD!! T_T ă—ăŹă—ăŹ!\n";
- }
- */
- //write_delaunay_mesh(t, W[0], is2d);
- //std::cout << t << std::endl;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Series of experiments
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void start_experiments(Point_Vector& W, FT theta0, std::vector<int>& landmarks_ind, FT epsilon)
-{
- // Experiment 1
- experiment1 = true;
- protected_delaunay(W, landmarks_ind, 0.1*epsilon, epsilon, 0.5, 0, true, true);
- write_tikz_plot(eps_vector,"epstime.tikz");
- experiment1 = false;
-
- // Experiment 2
- // experiment2 = true;
- // for (FT delta = 0; delta < epsilon; delta += 0.1*epsilon)
- // protected_delaunay(W, landmarks_ind, delta, epsilon, 0.5, 0, true, true);
- // write_tikz_plot(epsratio_vector,"epsratio_delta.tikz");
- // experiment2 = false;
-
-}
-
-#endif
diff --git a/src/Witness_complex/example/protected_sets/protected_sets_paper2.h b/src/Witness_complex/example/protected_sets/protected_sets_paper2.h
deleted file mode 100644
index 04b5e3bc..00000000
--- a/src/Witness_complex/example/protected_sets/protected_sets_paper2.h
+++ /dev/null
@@ -1,1384 +0,0 @@
-#ifndef PROTECTED_SETS_H
-#define PROTECTED_SETS_H
-
-#include <algorithm>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-#include <CGAL/Kernel_d/Hyperplane_d.h>
-#include <CGAL/Kernel_d/Vector_d.h>
-
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Fuzzy_sphere.h>
-
-#include <boost/heap/fibonacci_heap.hpp>
-#include <boost/heap/policies.hpp>
-
-#include "output_tikz.h"
-#include "../output.h"
-#include "../generators.h"
-
-#include <CGAL/point_generators_d.h>
-
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::Line_d Line_d;
-typedef K::Vector_d Vector_d;
-typedef K::Oriented_side_d Oriented_side_d;
-typedef K::Has_on_positive_side_d Has_on_positive_side_d;
-typedef K::Sphere_d Sphere_d;
-typedef K::Hyperplane_d Hyperplane_d;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef Delaunay_triangulation::Vertex_handle Delaunay_vertex;
-typedef Delaunay_triangulation::Full_cell_handle Full_cell_handle;
-
-typedef std::vector<Point_d> Point_Vector;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef CGAL::Random_points_in_ball_d<Point_d> Random_point_iterator;
-
-
-FT _sfty = pow(10,-14);
-
-bool experiment1, experiment2, experiment3, experiment5 = false;
-
-/* Experiment 1: epsilon as function on time **********************/
-std::vector<FT> eps_vector;
-
-/* Experiment 2: R/epsilon on alpha *******************************/
-std::vector<FT> epsratio_vector;
-std::vector<FT> epsslope_vector;
-
-/* Experiment 3: theta on delta ***********************************/
-std::vector<FT> thetamin_vector; FT curr_theta;
-std::vector<FT> gammamin_vector;
-
-/* Statistical data ***********************************************/
-int refused_case1, refused_case2, refused_bad, refused_centers1, refused_centers2;
-
-void initialize_statistics()
-{
- refused_case1 = 0;
- refused_case2 = 0;
- refused_bad = 0;
- refused_centers1 = 0;
- refused_centers2 = 0;
-}
-
-void print_statistics()
-{
- std::cout << " * Old simplex not protected: " << refused_case1 << "\n";
- std::cout << " * New simplex not protected: " << refused_case2 << "\n";
- std::cout << " * New simplex not good: " << refused_bad << "\n";
- std::cout << " * New-old centers too close: " << refused_centers1 << "\n";
- std::cout << " * New-new centers too close: " << refused_centers2 << "\n";
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// AUXILLARY FUNCTIONS
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Insert a point in Delaunay triangulation. If you are working in a flat torus, the procedure adds all the 3^d copies in adjacent cubes as well
- *
- * W is the initial point vector
- * chosen_landmark is the index of the chosen point in W
- * landmarks_ind is the vector of indices of already chosen points in W
- * delaunay is the Delaunay triangulation
- * landmark_count is the current number of chosen vertices
- * torus is true iff you are working on a flat torus [-1,1]^d
- * OUT: Vertex handle to the newly inserted point
- */
-Delaunay_vertex insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector<int>& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count, bool torus)
-{
- if (!torus)
- {
- Delaunay_vertex v =delaunay.insert(W[chosen_landmark]);
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
- return v;
- }
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- Delaunay_vertex v;
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[chosen_landmark][l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- if (i == nb_cells/2)
- v = delaunay.insert(point); //v = center point
- else
- delaunay.insert(point);
- }
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
- return v;
- }
-}
-
-/** Small check if the vertex v is in the full cell fc
- */
-
-bool vertex_is_in_full_cell(Delaunay_triangulation::Vertex_handle v, Full_cell_handle fc)
-{
- for (auto v_it = fc->vertices_begin(); v_it != fc->vertices_end(); ++v_it)
- if (*v_it == v)
- return true;
- return false;
-}
-
-/** Fill chosen point vector from indices with copies if you are working on a flat torus
- *
- * IN: W is the point vector
- * OUT: landmarks is the output vector
- * IN: landmarks_ind is the vector of indices
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector<int>& landmarks_ind, bool torus)
-{
- if (!torus)
- for (unsigned j = 0; j < landmarks_ind.size(); ++j)
- landmarks.push_back(W[landmarks_ind[j]]);
- else
- {
- int D = W[0].size();
- int nb_cells = pow(3, D);
- int nbL = landmarks_ind.size();
- // Fill landmarks
- for (int i = 0; i < nb_cells-1; ++i)
- for (int j = 0; j < nbL; ++j)
- {
- int cell_i = i;
- Point_d point;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[landmarks_ind[j]][l] + 2.0*(cell_i-1));
- cell_i /= 3;
- }
- landmarks.push_back(point);
- }
- }
-}
-
-/** Fill a vector of all simplices in the Delaunay triangulation giving integer indices to vertices
- *
- * IN: t is the Delaunay triangulation
- * OUT: full_cells is the output vector
- */
-
-void fill_full_cell_vector(Delaunay_triangulation& t, std::vector<std::vector<int>>& full_cells)
-{
- // Store vertex indices in a map
- int ind = 0; //index of a vertex
- std::map<Delaunay_triangulation::Vertex_handle, int> index_of_vertex;
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (t.is_infinite(v_it))
- continue;
- else
- index_of_vertex[v_it] = ind++;
- // Write full cells as vectors in full_cells
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- std::vector<int> cell;
- for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it)
- cell.push_back(index_of_vertex[*v_it]);
- full_cells.push_back(cell);
- }
-}
-
-bool sphere_intersects_cube(Point_d& c, FT r)
-{
- bool in_cube = true;
- // int i = 0, D = p.size();
- for (auto xi = c.cartesian_begin(); xi != c.cartesian_end(); ++xi)
- // if ((*xi < 1.0 || *xi > -1.0) &&
- // (*xi-r < 1.0 || *xi-r > -1.0) &&
- // (*xi+r < 1.0 || *xi+r > -1.0))
-
- if ((*xi-r < -1.0 && *xi+r < -1.0) ||
- (*xi-r > 1.0 && *xi+r > 1.0 ))
- {
- in_cube = false; break;
- }
- return in_cube;
-}
-
-/** Recursive function for checking if the simplex is good,
- * meaning it does not contain a k-face, which is not theta0^(k-1) thick
- */
-
-bool is_theta0_good(std::vector<Point_d>& vertices, FT theta0)
-{
- if (theta0 > 1)
- {
- std::cout << "Warning! theta0 is set > 1\n";
- return false;
- }
- int D = vertices.size()-1;
- if (D <= 1)
- return true; // Edges are always good
- //******** Circumscribed sphere
- Euclidean_distance ed;
- Sphere_d cs(vertices.begin(), vertices.end());
- FT r = sqrt(cs.squared_radius());
- for (std::vector<Point_d>::iterator v_it = vertices.begin(); v_it != vertices.end(); ++v_it)
- {
- std::vector<Point_d> facet;
- for (std::vector<Point_d>::iterator f_it = vertices.begin(); f_it != vertices.end(); ++f_it)
- if (f_it != v_it)
- facet.push_back(*f_it);
- // Compute the altitude
-
- if (vertices[0].size() == 3 && D == 2)
- {
- //Vector_d l = facet[0] - facet[1];
- FT orth_length2 = ed.transformed_distance(facet[0],facet[1]);
- K::Cartesian_const_iterator_d l_it, p_it, s_it, c_it;
- FT h = 0;
- // Scalar product = <sp,l>
- FT scalar = 0;
- for (p_it = v_it->cartesian_begin(),
- s_it = facet[0].cartesian_begin(),
- l_it = facet[1].cartesian_begin();
- p_it != v_it->cartesian_end();
- ++l_it, ++p_it, ++s_it)
- scalar += (*l_it - *s_it)*(*p_it - *s_it);
- // Gram-Schmidt for one vector
- for (p_it = v_it->cartesian_begin(),
- s_it = facet[0].cartesian_begin(),
- l_it = facet[1].cartesian_begin();
- p_it != v_it->cartesian_end();
- ++l_it, ++p_it, ++s_it)
- {
- FT hx = (*p_it - *s_it) - scalar*(*l_it - *s_it)/orth_length2;
- h += hx*hx;
- }
- h = sqrt(h);
-
- if (h/(2*r) < pow(theta0, D-1))
- return false;
- if (!is_theta0_good(facet, theta0))
- return false;
- }
- else
- {
- Hyperplane_d tau_h(facet.begin(), facet.end(), *v_it);
- Vector_d orth_tau = tau_h.orthogonal_vector();
- FT orth_length = sqrt(orth_tau.squared_length());
- K::Cartesian_const_iterator_d o_it, p_it, s_it, c_it;
- FT h = 0;
- for (o_it = orth_tau.cartesian_begin(),
- p_it = v_it->cartesian_begin(),
- s_it = (facet.begin())->cartesian_begin();
- o_it != orth_tau.cartesian_end();
- ++o_it, ++p_it, ++s_it)
- h += (*o_it)*(*p_it - *s_it)/orth_length;
- h = fabs(h);
- if (experiment3 && thetamin_vector[thetamin_vector.size()-1] > pow(h/(2*r), 1.0/(D-1)))
- {
- thetamin_vector[thetamin_vector.size()-1] = pow(h/(2*r), 1.0/(D-1));
- //std::cout << "theta=" << h/(2*r) << ", ";
- }
- if (h/(2*r) < pow(theta0, D-1))
- return false;
- if (!is_theta0_good(facet, theta0))
- return false;
- }
- }
- return true;
-}
-
-/** Recursive function for checking the goodness of a simplex,
- * meaning it does not contain a k-face, which is not theta0^(k-1) thick
- */
-
-FT theta(std::vector<Point_d>& vertices)
-{
- FT curr_value = 1.0;
- int D = vertices.size()-1;
- if (D <= 1)
- return 1; // Edges are always good
- //******** Circumscribed sphere
- Euclidean_distance ed;
- Sphere_d cs(vertices.begin(), vertices.end());
- FT r = sqrt(cs.squared_radius());
- for (std::vector<Point_d>::iterator v_it = vertices.begin(); v_it != vertices.end(); ++v_it)
- {
- std::vector<Point_d> facet;
- for (std::vector<Point_d>::iterator f_it = vertices.begin(); f_it != vertices.end(); ++f_it)
- if (f_it != v_it)
- facet.push_back(*f_it);
- // Compute the altitude
- curr_value = std::min(curr_value, theta(facet)); // Check the corresponding facet
- if (vertices[0].size() == 3 && D == 2)
- {
- //Vector_d l = facet[0] - facet[1];
- FT orth_length2 = ed.transformed_distance(facet[0],facet[1]);
- K::Cartesian_const_iterator_d l_it, p_it, s_it, c_it;
- FT h = 0;
- // Scalar product = <sp,l>
- FT scalar = 0;
- for (p_it = v_it->cartesian_begin(),
- s_it = facet[0].cartesian_begin(),
- l_it = facet[1].cartesian_begin();
- p_it != v_it->cartesian_end();
- ++l_it, ++p_it, ++s_it)
- scalar += (*l_it - *s_it)*(*p_it - *s_it);
- // Gram-Schmidt for one vector
- for (p_it = v_it->cartesian_begin(),
- s_it = facet[0].cartesian_begin(),
- l_it = facet[1].cartesian_begin();
- p_it != v_it->cartesian_end();
- ++l_it, ++p_it, ++s_it)
- {
- FT hx = (*p_it - *s_it) - scalar*(*l_it - *s_it)/orth_length2;
- h += hx*hx;
- }
- h = sqrt(h);
- curr_value = std::min(curr_value, std::pow(h/(2*r), 1.0/(D-1)));
- }
- else
- {
- Hyperplane_d tau_h(facet.begin(), facet.end(), *v_it);
- Vector_d orth_tau = tau_h.orthogonal_vector();
- FT orth_length = sqrt(orth_tau.squared_length());
- K::Cartesian_const_iterator_d o_it, p_it, s_it, c_it;
- FT h = 0;
- for (o_it = orth_tau.cartesian_begin(),
- p_it = v_it->cartesian_begin(),
- s_it = (facet.begin())->cartesian_begin();
- o_it != orth_tau.cartesian_end();
- ++o_it, ++p_it, ++s_it)
- h += (*o_it)*(*p_it - *s_it)/orth_length;
- h = fabs(h);
- curr_value = std::min(curr_value, pow(h/(2*r), 1.0/(D-1)));
- }
- }
- return curr_value;
-}
-
-// Doubling in a way 1->2->5->10
-void double_round(int& i)
-{
- FT order10 = pow(10,std::floor(std::log10(i)));
- int digit = std::floor( i / order10);
- std::cout << digit;
- if (digit == 1)
- i *= 2;
- else if (digit == 2)
- i = 5*i/2;
- else if (digit == 5)
- i *= 2;
- else
- std::cout << "digit not correct. digit = " << digit << std::endl;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// IS VIOLATED TEST
-////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/** Check if a newly created cell is protected from old vertices
- *
- * t is the Delaunay triangulation
- * vertices is the vector containing the point to insert and a facet f in t
- * v1 is the vertex of t, such that f and v1 form a simplex
- * v2 is the vertex of t, such that f and v2 form another simplex
- * delta is the protection constant
- * power_protection is true iff the delta-power protection is used
- */
-
-bool new_cell_is_violated(Delaunay_triangulation& t, std::vector<Point_d>& vertices, const Delaunay_vertex& v1, const Delaunay_vertex v2, FT delta0, bool power_protection, FT theta0, FT gamma0)
-{
- assert(vertices.size() == vertices[0].size() ||
- vertices.size() == vertices[0].size() + 1); //simplex size = d | d+1
- assert(v1 != v2);
- if (vertices.size() == vertices[0].size() + 1)
- // FINITE CASE
- {
- Sphere_d cs(vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(Euclidean_distance().transformed_distance(center_cs, vertices[0]));
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- {
- //CGAL::Oriented_side side = Oriented_side_d()(cs, (v_it)->point());
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, (v_it)->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+delta)*(r+delta))
- return true;
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta*delta)
- return true;
- }
- }
- */
- // Is the center inside the box? (only Euclidean case)
- // if (!torus)
- // {
- // bool inside_the_box = true;
- // for (c_it = center_cs.cartesian_begin(); c_it != center_cs.cartesian_end(); ++c_it)
- // if (*c_it > 1.0 || *c_it < -1.0)
- // {
- // inside_the_box = false; break;
- // }
- // if (inside_the_box && h/r < theta0)
- // return true;
- // }
- // Check the two vertices (if not infinite)
- if (!t.is_infinite(v1))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v1->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+r*delta0)*(r+r*delta0))
- { refused_case2++; return true;}
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+r*r*delta0*delta0)
- { refused_case2++; return true;}
- // Check if the centers are not too close
- std::vector<Point_d> sigma(vertices);
- sigma[0] = v1->point();
- Sphere_d cs_sigma(sigma.begin(), sigma.end());
- Point_d csc_sigma = cs_sigma.center();
- FT r_sigma = sqrt(cs_sigma.squared_radius());
- FT dcc = sqrt(Euclidean_distance().transformed_distance(center_cs, csc_sigma));
- if (experiment3 && dcc/r < gammamin_vector[gammamin_vector.size()-1])
- gammamin_vector[gammamin_vector.size()-1] = dcc/r;
- if (experiment3 && dcc/r_sigma < gammamin_vector[gammamin_vector.size()-1])
- gammamin_vector[gammamin_vector.size()-1] = dcc/r_sigma;
- if (dcc < r*gamma0 || dcc < r_sigma*gamma0)
- { refused_centers1++; return true; }
- }
- if (!t.is_infinite(v2))
- {
- FT dist2 = Euclidean_distance().transformed_distance(center_cs, v2->point());
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+r*delta0)*(r+r*delta0))
- { refused_case2++; return true;}
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+r*r*delta0*delta0)
- { refused_case2++; return true;}
- // Check if the centers are not too close
- std::vector<Point_d> sigma(vertices);
- sigma[0] = v2->point();
- Sphere_d cs_sigma(sigma.begin(), sigma.end());
- Point_d csc_sigma = cs_sigma.center();
- FT r_sigma = sqrt(cs_sigma.squared_radius());
- FT dcc = sqrt(Euclidean_distance().transformed_distance(center_cs, csc_sigma));
- if (experiment3 && dcc/r < gammamin_vector[gammamin_vector.size()-1])
- gammamin_vector[gammamin_vector.size()-1] = dcc/r;
- if (experiment3 && dcc/r_sigma < gammamin_vector[gammamin_vector.size()-1])
- gammamin_vector[gammamin_vector.size()-1] = dcc/r_sigma;
- if (dcc < r*gamma0 || dcc < r_sigma*gamma0)
- { refused_centers1++; return true; }
- }
- // Check if the simplex is theta0-good
- if (!is_theta0_good(vertices, theta0))
- { refused_bad++; return true;}
-
- }
- else
- // INFINITE CASE
- {
- Delaunay_triangulation::Vertex_iterator v = t.vertices_begin();
- while (t.is_infinite(v) || std::find(vertices.begin(), vertices.end(), v->point()) == vertices.end())
- v++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v->point(), CGAL::ON_POSITIVE_SIDE);
- Vector_d orth_v = facet_plane.orthogonal_vector();
- /*
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end())
- {
- std::vector<FT> coords;
- Point_d p = v_it->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!p_is_inside && p_delta_is_inside)
- return true;
- }
- */
- if (!t.is_infinite(v1))
- {
- std::vector<FT> coords;
- Point_d p = v1->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta0 / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- if (!t.is_infinite(v2))
- {
- std::vector<FT> coords;
- Point_d p = v2->point();
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta0 / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- }
- }
- return false;
-}
-
-/** Auxillary recursive function to check if the point p violates the protection of the cell c and
- * if there is a violation of an eventual new cell
- *
- * p is the point to insert
- * t is the current triangulation
- * c is the current cell (simplex)
- * parent_cell is the parent cell (simplex)
- * index is the index of the facet between c and parent_cell from parent_cell's point of view
- * D is the dimension of the triangulation
- * delta is the protection constant
- * marked_cells is the vector of all visited cells containing p in their circumscribed ball
- * power_protection is true iff you are working with delta-power protection
- *
- * OUT: true iff inserting p hasn't produced any violation so far
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, Full_cell_handle c, Full_cell_handle parent_cell, int index, int D, FT delta0, std::vector<Full_cell_handle>& marked_cells, bool power_protection, FT theta0, FT gamma0)
-{
- Euclidean_distance ed;
- std::vector<Point_d> vertices;
- if (!t.is_infinite(c))
- {
- // if the cell is finite, we look if the protection is violated
- for (auto v_it = c->vertices_begin(); v_it != c->vertices_end(); ++v_it)
- vertices.push_back((*v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, vertices[0]));
- FT dist2 = ed.transformed_distance(center_cs, p);
- // if the new point is inside the protection ball of a non conflicting simplex
- if (!power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= (r+r*delta0)*(r+r*delta0))
- { refused_case1++; return true;}
- if (power_protection)
- if (dist2 >= r*r-_sfty && dist2 <= r*r+delta0*delta0*r*r)
- { refused_case1++; return true;}
- // if the new point is inside the circumscribing ball : continue violation searching on neighbours
- //if (dist2 < r*r)
- //if (dist2 < (5*r+delta)*(5*r+delta))
- if (dist2 < r*r)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta0, marked_cells, power_protection, theta0, gamma0))
- return true;
- }
- }
- // if the new point is outside the protection sphere
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is guaranteed to be finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta0, power_protection, theta0, gamma0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- else
- {
- // Inside of the convex hull is + side. Outside is - side.
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!t.is_infinite(*vh_it))
- vertices.push_back((*vh_it)->point());
- Delaunay_triangulation::Vertex_iterator v_it = t.vertices_begin();
- while (t.is_infinite(v_it) || vertex_is_in_full_cell(v_it, c))
- v_it++;
- Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v_it->point(), CGAL::ON_POSITIVE_SIDE);
- //CGAL::Oriented_side outside = Oriented_side_d()(facet_plane, v_it->point());
- Vector_d orth_v = facet_plane.orthogonal_vector();
- std::vector<FT> coords;
- auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin();
- for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i)
- coords.push_back((*p_i) - (*orth_i) * delta0 / sqrt(orth_v.squared_length()));
- Point_d p_delta = Point_d(coords);
- bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p) && (Oriented_side_d()(facet_plane, p) != CGAL::ZERO);
- bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta);
-
- // If we work with power protection, we just ignore any conflicts
- if (!power_protection && !p_is_inside && p_delta_is_inside)
- return true;
- //if the cell is infinite we look at the neighbours regardless
- if (p_is_inside)
- {
- c->tds_data().mark_visited();
- marked_cells.push_back(c);
- for (int i = 0; i < D+1; ++i)
- {
- Full_cell_handle next_c = c->neighbor(i);
- if (next_c->tds_data().is_clear() &&
- is_violating_protection(p, t, next_c, c, i, D, delta0, marked_cells, power_protection, theta0, gamma0))
- return true;
- }
- }
- else
- {
- // facet f is on the border of the conflict zone : check protection of simplex {p,f}
- // the new simplex is finite if the parent cell is finite
- vertices.clear(); vertices.push_back(p);
- for (int i = 0; i < D+1; ++i)
- if (i != index)
- if (!t.is_infinite(parent_cell->vertex(i)))
- vertices.push_back(parent_cell->vertex(i)->point());
- Delaunay_vertex vertex_to_check = t.infinite_vertex();
- for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it)
- if (!vertex_is_in_full_cell(*vh_it, parent_cell))
- {
- vertex_to_check = *vh_it; break;
- }
- if (new_cell_is_violated(t, vertices, vertex_to_check, parent_cell->vertex(index), delta0, power_protection, theta0, gamma0))
- //if (new_cell_is_violated(t, vertices, vertex_to_check->point(), delta))
- return true;
- }
- }
- //c->tds_data().clear_visited();
- //marked_cells.pop_back();
- return false;
-}
-
-/** Checks if inserting the point p in t will make conflicts
- *
- * p is the point to insert
- * t is the current triangulation
- * D is the dimension of triangulation
- * delta is the protection constant
- * power_protection is true iff you are working with delta-power protection
- * OUT: true iff inserting p produces a violation of delta-protection.
- */
-
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta0, bool power_protection, FT theta0, FT gamma0)
-{
- Euclidean_distance ed;
- Delaunay_triangulation::Vertex_handle v;
- Delaunay_triangulation::Face f(t.current_dimension());
- Delaunay_triangulation::Facet ft;
- Delaunay_triangulation::Full_cell_handle c;
- Delaunay_triangulation::Locate_type lt;
- std::vector<Full_cell_handle> marked_cells;
- //c = t.locate(p, lt, f, ft, v);
- c = t.locate(p);
- bool violation_existing_cells = is_violating_protection(p, t, c, c, 0, D, delta0, marked_cells, power_protection, theta0, gamma0);
- for (Full_cell_handle fc : marked_cells)
- fc->tds_data().clear();
- return violation_existing_cells;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-// INITIALIZATION
-////////////////////////////////////////////////////////////////////////
-
-// Query for a sphere near a cite in all copies of a torus
-// OUT points_inside
-void torus_search(Tree& treeW, int D, Point_d cite, FT r, std::vector<int>& points_inside)
-{
- int nb_cells = pow(3, D);
- Delaunay_vertex v;
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> cite_copy;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- cite_copy.push_back(cite[l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- Fuzzy_sphere fs(cite_copy, r, 0, treeW.traits());
- treeW.search(std::insert_iterator<std::vector<int>>(points_inside, points_inside.end()), fs);
- }
-}
-
-
-void initialize_torus(Point_Vector& W, Tree& treeW, Delaunay_triangulation& t, FT epsilon, std::vector<int>& landmarks_ind, int& landmark_count, std::vector<bool>& point_taken)
-{
- initialize_statistics();
- int D = W[0].size();
- if (D == 2)
- {
- int xw = 6, yw = 4;
- // Triangular lattice close to regular triangles h=0.866a ~ 0.875a : 48p
- for (int i = 0; i < xw; ++i)
- for (int j = 0; j < yw; ++j)
- {
- Point_d cite1(std::vector<FT>{2.0/xw*i, 2.0/yw*j});
- std::vector<int> points_inside;
- torus_search(treeW, D, cite1, epsilon, points_inside);
- //std::cout << "i=" << i << ", j=" << j << " "; print_vector(points_inside); std::cout << "\n";
- std::vector<int>::iterator p_it = points_inside.begin();
- while (p_it != points_inside.end() && point_taken[*p_it])
- ++p_it;
- assert(p_it != points_inside.end());
- //W[*p_it] = cite1; // debug purpose
- insert_delaunay_landmark_with_copies(W, *p_it,
- landmarks_ind, t, landmark_count, true);
- point_taken[*p_it] = true;
-
- Point_d cite2(std::vector<FT>{2.0/xw*(i+0.5), 2.0/yw*(j+0.5)});
- points_inside.clear();
- torus_search(treeW, D, cite2, epsilon, points_inside);
- //std::cout << "i=" << i << ", j=" << j << " "; print_vector(points_inside); std::cout << "\n";
- p_it = points_inside.begin();
- while (p_it != points_inside.end() && point_taken[*p_it])
- ++p_it;
- assert(p_it != points_inside.end());
- //W[*p_it] = cite2; // debug purpose
- insert_delaunay_landmark_with_copies(W, *p_it,
- landmarks_ind, t, landmark_count, true);
- point_taken[*p_it] = true;
- }
- }
- else if (D == 3)
- {
- int wd = 3;
- // Body-centered cubic lattice : 54p
- for (int i = 0; i < wd; ++i)
- for (int j = 0; j < wd; ++j)
- for (int k = 0; k < wd; ++k)
- {
- Point_d cite1(std::vector<FT>{2.0/wd*i, 2.0/wd*j, 2.0/wd*k});
- std::vector<int> points_inside;
- torus_search(treeW, D, cite1, epsilon, points_inside);
- std::vector<int>::iterator p_it = points_inside.begin();
- while (p_it != points_inside.end() && point_taken[*p_it])
- ++p_it;
- assert(p_it != points_inside.end());
- insert_delaunay_landmark_with_copies(W, *(points_inside.begin()),
- landmarks_ind, t, landmark_count, true);
- point_taken[*p_it] = true;
-
- Point_d cite2(std::vector<FT>{2.0/wd*(i+0.5), 2.0/wd*(j+0.5), 2.0/wd*(k+0.5)});
- points_inside.clear();
- torus_search(treeW, D, cite2, epsilon, points_inside);
- p_it = points_inside.begin();
- while (p_it != points_inside.end() && point_taken[*p_it])
- ++p_it;
- assert(p_it != points_inside.end());
- insert_delaunay_landmark_with_copies(W, *(points_inside.begin()),
- landmarks_ind, t, landmark_count, true);
- point_taken[*p_it] = true;
- }
- }
- //write_mesh
-}
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-//!!!!!!!!!!!!! THE INTERFACE FOR LANDMARK CHOICE IS BELOW !!!!!!!!!!//
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-
-// Struct for R_max_heap elements
-
-struct R_max_handle
-{
- FT value;
- Point_d center;
-
- R_max_handle(FT value_, Point_d c): value(value_), center(c)
- {}
-};
-
-struct R_max_compare
-{
- bool operator()(const R_max_handle& rmh1, const R_max_handle& rmh2) const
- {
- return rmh1.value < rmh2.value;
- }
-};
-
-// typedef boost::heap::fibonacci_heap<R_max_handle, boost::heap::compare<R_max_compare>> Heap;
-
-// void make_heap(Delaunay_triangulation& t, Heap& R_max_heap)
-// {
-// R_max_heap.clear();
-// for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
-// {
-// if (t.is_infinite(fc_it))
-// continue;
-// Point_Vector vertices;
-// for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
-// vertices.push_back((*fc_v_it)->point());
-// Sphere_d cs( vertices.begin(), vertices.end());
-// Point_d csc = cs.center();
-// FT r = sqrt(cs.squared_radius());
-// // A ball is in the heap, if it intersects the cube
-// bool accepted = sphere_intersects_cube(csc, sqrt(r));
-// if (!accepted)
-// continue;
-// R_max_heap.push(R_max_handle(r, fc_it, csc));
-// }
-// }
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// SAMPLING RADIUS
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-R_max_handle sampling_radius(Delaunay_triangulation& t)
-{
- FT epsilon2 = 0;
- Point_d final_center;
- Point_d control_point;
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- FT r2 = Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin()));
- if (epsilon2 < r2)
- {
- epsilon2 = r2;
- final_center = csc;
- control_point = (*vertices.begin());
- }
- }
- return R_max_handle(sqrt(epsilon2), final_center);
-}
-
-FT sampling_fatness(Delaunay_triangulation& t)
-{
- FT curr_theta = 1.0;
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- FT theta_f = theta(vertices);
- curr_theta = std::min(curr_theta, theta_f);
- //std::cout << "theta(sigma) = " << theta_f << "\n";
- }
- return curr_theta;
-}
-
-// Generate an epsilon sample for a given epsilon
-void generate_epsilon_sample_torus(Point_Vector& W, FT epsilon, int dim, Delaunay_triangulation& t)
-{
- W.clear();
- t.clear();
- int point_count = 0;
- std::vector<int> point_ind;
- // std::vector<FT> coords;
- FT curr_eps = 2*dim;
- // Initialize
- // for (int i = 0; i < dim; ++i)
- // coords.push_back(-1);
- // R_max_handle rmh(2*sqrt(dim), Point_d(coords));
- // int N = dim; std::floor(std::pow(1/epsilon,dim));
- // std::cout << N << "\n";
- typedef CGAL::Random_points_in_cube_d<Point_d> Random_cube_iterator;
- Random_cube_iterator rp(dim, 1.0);
- W.push_back(*rp++);
- insert_delaunay_landmark_with_copies(W, W.size()-1, point_ind, t, point_count, true);
- curr_eps = sampling_radius(t).value;
- while (curr_eps > epsilon)
- {
-
- W.push_back(*rp++);
- insert_delaunay_landmark_with_copies(W, W.size()-1, point_ind, t, point_count, true);
-
- Point_d c = sampling_radius(t).center;
- W.push_back(c);
- insert_delaunay_landmark_with_copies(W, W.size()-1, point_ind, t, point_count, true);
- curr_eps = sampling_radius(t).value;
-
- std::cout << "curr_eps = " << curr_eps << "\n";
- }
- // Iterate and insert in a torus
- // while (rmh.value > epsilon)
- // {
- // W.push_back(rmh.center);
- // insert_delaunay_landmark_with_copies(W, W.size()-1, point_ind, t, point_count, true);
- // rmh = sampling_radius(t);
- // //std::cout << rmh.value;
- // }
-}
-
-///////////////////////////////////////////////////////////////////////
-// LANDMARK CHOICE PROCEDURE
-///////////////////////////////////////////////////////////////////////
-
-/** Procedure to compute a maximal protected subset from a point cloud. All OUTs should be empty at call.
- *
- * IN: W is the initial point cloud having type Epick_d<Dynamic_dimension_tag>::Point_d
- * IN: nbP is the size of W
- * OUT: landmarks is the output vector for the points
- * OUT: landmarks_ind is the output vector for the indices of the selected points in W
- * IN: delta is the constant of protection
- * OUT: full_cells is the output vector of the simplices in the final Delaunay triangulation
- * IN: torus is true iff you are working on a flat torus [-1,1]^d
- */
-
-void protected_delaunay(Point_Vector& W,
- //Point_Vector& landmarks,
- std::vector<int>& landmarks_ind,
- FT alpha,
- FT epsilon,
- FT delta0,
- FT theta0,
- FT gamma0,
- //std::vector<std::vector<int>>& full_cells,
- bool torus,
- bool power_protection
- )
-{
- //bool return_ = true;
- unsigned D = W[0].size();
- int nbP = W.size();
- //FT beta = 1/(1-alpha);
- //FT Ad = pow((4*alpha + 8*beta)/alpha, D);
- //FT theta0 = 1/Ad;
- //FT delta0 = pow(1/Ad,D);
- Torus_distance td;
- Euclidean_distance ed;
- Delaunay_triangulation t(D);
- std::vector<bool> point_taken(nbP,false);
- CGAL::Random rand;
- int landmark_count = 0;
- std::list<int> index_list;
- //****************** Kd Tree W
- STraits traits(&(W[0]));
- Tree treeW(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbP),
- typename Tree::Splitter(),
- traits);
- // shuffle the list of indexes (via a vector)
- {
- std::vector<int> temp_vector;
- for (int i = 0; i < nbP; ++i)
- temp_vector.push_back(i);
- unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed));
- //CGAL::spatial_sort(temp_vector.begin(), temp_vector.end());
- for (std::vector<int>::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it)
- index_list.push_front(*it);
- }
- //******************** Initialize point set
- if (!torus)
- for (unsigned pos1 = 0; pos1 < D+1; ++pos1)
- {
- std::vector<FT> point;
- for (unsigned i = 0; i < pos1; ++i)
- point.push_back(-1);
- if (pos1 != D)
- point.push_back(1);
- for (unsigned i = pos1+1; i < D; ++i)
- point.push_back(0);
- assert(point.size() == D);
- W[index_list.front()] = Point_d(point);
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count, torus);
- index_list.pop_front();
- }
- else
- initialize_torus(W, treeW, t, epsilon, landmarks_ind, landmark_count, point_taken);
- //std::cout << "Size of treeW: " << treeW.size() << "\n";
- //std::cout << "Size of t: " << t.number_of_vertices() << "\n";
- //******************* Initialize heap for R_max
- //Heap R_max_heap;
- //make_heap(t, R_max_heap);
-
-
- R_max_handle rh = sampling_radius(t);
- FT epsilon0 = rh.value;
- if (experiment1) eps_vector.push_back(pow(1/rh.value,D));
- //******************** Iterative algorithm
- std::vector<int> candidate_points;
- torus_search(treeW, D,
- rh.center,
- alpha*rh.value,
- candidate_points);
- std::list<int>::iterator list_it;
- std::vector<int>::iterator cp_it = candidate_points.begin();
- while (cp_it != candidate_points.end())
- {
- if (!point_taken[*cp_it] && !is_violating_protection(W[*cp_it], t, D, delta0, power_protection, theta0, gamma0))
- {
- Delaunay_vertex v = insert_delaunay_landmark_with_copies(W, *cp_it, landmarks_ind, t, landmark_count, torus);
- {
- // Simple check if the new cells don't have centers too close one to another
- std::vector<Full_cell_handle> inc_cells;
- std::back_insert_iterator<std::vector<Full_cell_handle>> out(inc_cells);
- t.tds().incident_full_cells(v, out);
-
- std::vector<Sphere_d> spheres;
- for (auto i_it = inc_cells.begin(); i_it != inc_cells.end(); ++i_it)
- {
- std::vector<Point_d> vertices;
- for (auto v_it = (*i_it)->vertices_begin(); v_it != (*i_it)->vertices_end(); ++v_it)
- vertices.push_back((*v_it)->point());
- spheres.push_back(Sphere_d(vertices.begin(), vertices.end()));
- }
- for (auto s_it = spheres.begin(); s_it != spheres.end(); ++s_it)
- for (auto t_it = s_it+1; t_it != spheres.end(); ++t_it)
- {
- FT ddc2 = ed.transformed_distance(s_it->center(),t_it->center());
- if (ddc2 < gamma0*gamma0*s_it->squared_radius() ||
- ddc2 < gamma0*gamma0*t_it->squared_radius())
- { refused_centers2++; }
- }
- }
-
- //std::cout << *cp_it << ",\n";
- //make_heap(t, R_max_heap);
- point_taken[*cp_it] = true;
- rh = sampling_radius(t);
- if (experiment1) eps_vector.push_back(pow(1/rh.value,D));
- //std::cout << "rhvalue = " << rh.value << "\n";
- //std::cout << "D = " <<
- candidate_points.clear();
- torus_search(treeW, D,
- rh.center,
- alpha*rh.value,
- candidate_points);
- cp_it = candidate_points.begin();
- /*
- // PIECE OF CODE FOR DEBUGGING PURPOSES
-
- Delaunay_vertex inserted_v = insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count);
- if (triangulation_is_protected(t, delta))
- {
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- { //THAT'S WHERE SOMETHING'S WRONG
- t.remove(inserted_v);
- landmarks_ind.pop_back();
- landmark_count--;
- write_delaunay_mesh(t, W[*list_it], is2d);
- is_violating_protection(W[*list_it], t_old, D, delta); //Called for encore
- }
- */
- //std::cout << "index_list_size() = " << index_list.size() << "\n";
- }
- else
- {
- cp_it++;
- //std::cout << "!!!!!WARNING!!!!! A POINT HAS BEEN OMITTED!!!\n";
- }
- //if (list_it != index_list.end())
- // write_delaunay_mesh(t, W[*list_it], is2d);
- }
-
- if (experiment2) epsratio_vector.push_back(rh.value/epsilon0);
- if (experiment2) epsslope_vector.push_back( (pow(1/rh.value,D)-pow(1/epsilon0,D))/(landmarks_ind.size() - 48) );
- std::cout << "The iteration ended when cp_count = " << candidate_points.size() << "\n";
- std::cout << "alphaRmax = " << alpha*rh.value << "\n";
- std::cout << "epsilon' = " << rh.value << "\n";
- std::cout << "nbL = " << landmarks_ind.size() << "\n";
- print_statistics();
- //print_vector(landmarks_ind); std::cout << std::endl;
- //std::sort(landmarks_ind.begin(), landmarks_ind.end());
- print_vector(landmarks_ind); std::cout << std::endl;
- if (experiment3) thetamin_vector[thetamin_vector.size()-1] = sampling_fatness(t);
- std::cout << "theta = " << sampling_fatness(t) << "\n";
- //fill_landmarks(W, landmarks, landmarks_ind, torus);
- //fill_full_cell_vector(t, full_cells);
- /*
- if (triangulation_is_protected(t, delta))
- std::cout << "Triangulation is ok\n";
- else
- {
- std::cout << "Triangulation is BAD!! T_T ă—ăŹă—ăŹ!\n";
- }
- */
- write_delaunay_mesh(t, W[0], true);
- //std::cout << t << std::endl;
-}
-
-void run_experiment5(Point_Vector& W,
- int D,
- FT alpha,
- FT epsilon,
- FT delta0,
- FT theta0,
- FT gamma0,
- //std::vector<std::vector<int>>& full_cells,
- bool torus,
- bool power_protection
- )
-{
- // INITIALIZATION
- Delaunay_triangulation t(D);
- std::vector<int> landmarks_ind;
- int landmark_count = 0;
- initialize_statistics();
- if (D == 2)
- {
- int xw = 6, yw = 4;
- // Triangular lattice close to regular triangles h=0.866a ~ 0.875a : 48p
- for (int i = 0; i < xw; ++i)
- for (int j = 0; j < yw; ++j)
- {
- Point_d cite1(std::vector<FT>{2.0/xw*i, 2.0/yw*j});
- W.push_back(cite1); // debug purpose
- insert_delaunay_landmark_with_copies(W, W.size()-1,
- landmarks_ind, t, landmark_count, true);
-
- Point_d cite2(std::vector<FT>{2.0/xw*(i+0.5), 2.0/yw*(j+0.5)});
- W.push_back(cite2); // debug purpose
- insert_delaunay_landmark_with_copies(W, W.size()-1,
- landmarks_ind, t, landmark_count, true);
- }
- }
- else if (D == 3)
- {
- int wd = 3;
- // Body-centered cubic lattice : 54p
- for (int i = 0; i < wd; ++i)
- for (int j = 0; j < wd; ++j)
- for (int k = 0; k < wd; ++k)
- {
- Point_d cite1(std::vector<FT>{2.0/wd*i, 2.0/wd*j, 2.0/wd*k});
- W.push_back(cite1); // debug purpose
- insert_delaunay_landmark_with_copies(W, W.size()-1,
- landmarks_ind, t, landmark_count, true);
-
- Point_d cite2(std::vector<FT>{2.0/wd*(i+0.5), 2.0/wd*(j+0.5), 2.0/wd*(k+0.5)});
- W.push_back(cite2); // debug purpose
- insert_delaunay_landmark_with_copies(W, W.size()-1,
- landmarks_ind, t, landmark_count, true);
- }
- }
-
- // ITERATIONS
- R_max_handle rh = sampling_radius(t);
- Point_d rp = *(Random_point_iterator(D, alpha*rh.value));
- int death_count = 0;
- std::cout << "death count " << death_count << " rp = " << rp << "\n";
- while (death_count < 100)
- {
- std::vector<FT> coords;
- for (auto c_it = rh.center.cartesian_begin(),
- r_it = rp.cartesian_begin();
- c_it != rh.center.cartesian_end();
- ++c_it, ++r_it)
- coords.push_back(*c_it + *r_it);
- Point_d new_p(coords);
- if (!is_violating_protection(new_p, t, D, delta0, power_protection, theta0, gamma0))
- {
- W.push_back(new_p);
- insert_delaunay_landmark_with_copies(W, W.size()-1, landmarks_ind, t, landmark_count, torus);
- rh = sampling_radius(t);
- rp = *(Random_point_iterator(D, alpha*rh.value));
- death_count = 0;
- std::cout << "death count " << death_count << " rp = " << rp << "\n";
- }
- else
- {
- rp = *(Random_point_iterator(D, alpha*rh.value));
- death_count++;
- std::cout << "death count " << death_count << " rp = " << rp << "\n";
- }
- //Point_d new_p = (*rp++) + Vector_d;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Series of experiments
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void start_experiments(Point_Vector& W, FT alpha, std::vector<int>& landmarks_ind, FT epsilon)
-{
- int experiment_no = 1;
- FT delta0 = 0.1;
- FT theta0 = 0.1;
- FT gamma0 = 0.01;
- std::string suffix;
- //std::cout << "ă‚ă†ă“ăťă‚¸ă—ă‚·ăĽć‘ăŚçĄžç§ă®é¨ĺ±‹ă¸:\n";
- while (experiment_no != 0)
- {
- std::cout << "Enter experiment no (0 to exit): ";
- std::cin >> experiment_no;
- switch (experiment_no)
- {
- case 1:
- // Experiment 1
- experiment1 = true;
- eps_vector = {};
- std::cout << "Enter delta0: "; std::cin >> delta0;
- std::cout << "Enter theta0: "; std::cin >> theta0;
- std::cout << "Enter gamma0: "; std::cin >> gamma0;
- protected_delaunay(W, landmarks_ind, alpha, epsilon, delta0, theta0, gamma0, true, true);
- write_tikz_plot(eps_vector,"epstime.tikz");
- experiment1 = false;
- break;
-
- case 2:
- // Experiment 2
- suffix = "";
- experiment2 = true;
- epsratio_vector = {0};
- epsslope_vector = {0};
- std::cout << "File name suffix: ";
- std::cin >> suffix;
- for (FT alpha = 0.01; alpha < 0.999; alpha += 0.01)
- {
- landmarks_ind.clear();
- std::cout << "Test for alpha = " << alpha << "\n";
- protected_delaunay(W, landmarks_ind, alpha, epsilon, delta0, theta0, gamma0, true, true);
- }
- write_tikz_plot(epsratio_vector,"epsratio_alpha." + suffix + ".tex");
- write_tikz_plot(epsslope_vector,"epsslope_alpha." + suffix + ".tex");
- experiment2 = false;
- break;
-
- case 3:
- // Experiment 3
- experiment3 = true;
- thetamin_vector = {};
- gammamin_vector = {};
- theta0 = 0;
- gamma0 = 0;
- for (FT delta0 = 0; delta0 < 0.999; delta0 += 0.05)
- {
- landmarks_ind.clear();
- thetamin_vector.push_back(1.0); //0.7489 fatness of the initialization
- gammamin_vector.push_back(10);
- std::cout << "Test for delta0 = " << delta0 << "\n";
- protected_delaunay(W, landmarks_ind, alpha, epsilon, delta0, theta0, gamma0, true, true);
- }
- write_tikz_plot(thetamin_vector,"thetamin_delta.tex");
- write_tikz_plot(gammamin_vector,"gammamin_delta.tex");
- experiment3 = false;
- break;
-
- // case 4:
- // // Experiment 4
- // {
- // int dim;
- // std::cout << "Enter dimension: ";
- // std::cin >> dim;
- // Delaunay_triangulation t(dim);
- // // for (FT eps = 0.7; eps < 1.1; eps += 0.1)
- // // {
- // // generate_epsilon_sample_torus(W, eps, dim, t);
- // // for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- // // {
- // // if (t.is_infinite(v_it))
- // // continue;
- // // bool in_cube = true;
- // // for (auto xi = v_it->cartesian_begin(); xi != v_it->cartesian_end(); ++xi)
- // // if (*xi > 1.0 || *xi < -1.0)
- // // {
- // // in_cube = false; break;
- // // }
- // // if (!in_cube)
- // // continue;
- // // for (auto t.tds().incident_full_cells())
- // // }
- // // std::cout << "eps = " << eps << ", real epsilon = " << sampling_radius(t).value << "\n";
- // // }
- // // }
- // break;
-
-
- case 5:
- // Experiment 5
- experiment5 = true;
- // std::cout << "Enter dimension: ";
- // std::cin >> dim;
-
- landmarks_ind.clear();
- W.clear();
- run_experiment5(W, alpha, epsilon, delta0, theta0, gamma0, true, true);
- experiment5 = false;
- break;
- }
-
- }
-
-}
-
-#endif
diff --git a/src/Witness_complex/example/witness_complex_cube.cpp b/src/Witness_complex/example/witness_complex_cube.cpp
deleted file mode 100644
index e448c55d..00000000
--- a/src/Witness_complex/example/witness_complex_cube.cpp
+++ /dev/null
@@ -1,590 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// Avoiding the max arity issue with CGAL
-#ifndef BOOST_PARAMETER_MAX_ARITY
-# define BOOST_PARAMETER_MAX_ARITY 12
-#endif
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-#include <algorithm>
-#include <set>
-#include <iterator>
-#include <chrono>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-#include "Torus_distance.h"
-#include "generators.h"
-#include "output.h"
-//#include "protected_sets/protected_sets.h"
-#include "protected_sets/protected_sets_paper2.h"
-
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-#include <CGAL/Kernel_d/Hyperplane_d.h>
-#include <CGAL/enum.h>
-
-#include <CGAL/Kernel_d/Vector_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-#include <CGAL/Fuzzy_sphere.h>
-#include <CGAL/Random.h>
-#include <CGAL/Timer.h>
-#include <CGAL/Delaunay_triangulation.h>
-
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::Vector_d Vector_d;
-typedef K::Oriented_side_d Oriented_side_d;
-typedef K::Has_on_positive_side_d Has_on_positive_side_d;
-
-//typedef CGAL::Point_d<K> Point_d;
-typedef K::FT FT;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-typedef CGAL::Kd_tree<STraits> Tree2;
-
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef std::vector<Point_d> Point_Vector;
-
-//typedef K::Equal_d Equal_d;
-//typedef CGAL::Random_points_in_cube_d<CGAL::Point_d<CGAL::Cartesian_d<FT> > > Random_cube_iterator;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef Delaunay_triangulation::Vertex_handle Delaunay_vertex;
-typedef Delaunay_triangulation::Full_cell_handle Full_cell_handle;
-//typedef CGAL::Sphere_d<K> Sphere_d;
-typedef K::Sphere_d Sphere_d;
-typedef K::Hyperplane_d Hyperplane_d;
-
-/*//////////////////////////////////////
- * GLOBAL VARIABLES ********************
- *//////////////////////////////////////
-
-//NA bool toric=false;
-bool power_protection = true;
-bool grid_points = true;
-bool is2d = true;
-//FT _sfty = pow(10,-14);
-bool torus = false;
-
-
-bool triangulation_is_protected(Delaunay_triangulation& t, FT delta)
-{
- std::cout << "Start protection verification\n";
- Euclidean_distance ed;
- // Fill the map Vertices -> Numbers
- std::map<Delaunay_triangulation::Vertex_handle, int> index_of_vertex;
- int ind = 0;
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- {
- if (t.is_infinite(v_it))
- continue;
- index_of_vertex[v_it] = ind++;
- }
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- if (!t.is_infinite(fc_it))
- {
- std::vector<Point_d> vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(0)->point()));
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- if (!t.is_infinite(v_it))
- //check if vertex belongs to the face
- if (!vertex_is_in_full_cell(v_it, fc_it))
- {
- FT dist2 = ed.transformed_distance(center_cs, v_it->point());
- //if the new point is inside the protection ball of a non conflicting simplex
- //std::cout << "Dist^2 = " << dist2 << " (r+delta)*(r+delta) = " << (r+delta)*(r+delta) << " r^2 = " << r*r <<"\n";
- if (!power_protection)
- if (dist2 <= (r+delta)*(r+delta) && dist2 >= r*r)
- {
- write_delaunay_mesh(t, v_it->point(), is2d);
- // Output the problems
- std::cout << "Problematic vertex " << index_of_vertex[v_it] << " ";
- std::cout << "Problematic cell ";
- for (auto vh_it = fc_it->vertices_begin(); vh_it != fc_it->vertices_end(); ++vh_it)
- if (!t.is_infinite(*vh_it))
- std::cout << index_of_vertex[*vh_it] << " ";
- std::cout << "\n";
- std::cout << "r^2 = " << r*r << ", d^2 = " << dist2 << ", (r+delta)^2 = " << (r+delta)*(r+delta) << "\n";
- return false;
- }
- if (power_protection)
- if (dist2 <= r*r+delta*delta && dist2 >= r*r)
- {
- write_delaunay_mesh(t, v_it->point(), is2d);
- std::cout << "Problematic vertex " << *v_it << " ";
- std::cout << "Problematic cell " << *fc_it << "\n";
- std::cout << "r^2 = " << r*r << ", d^2 = " << dist2 << ", r^2+delta^2 = " << r*r+delta*delta << "\n";
- return false;
- }
- }
- }
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// SAMPLING RADIUS
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-FT sampling_radius(Delaunay_triangulation& t, FT epsilon0)
-{
- FT epsilon2 = 0;
- Point_d control_point;
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- FT r2 = Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin()));
- if (epsilon2 < r2)
- {
- epsilon2 = r2;
- control_point = (*vertices.begin());
- }
- }
- if (epsilon2 < epsilon0*epsilon0)
- {
- std::cout << "ACHTUNG! E' < E\n";
- std::cout << "eps = " << epsilon0 << " eps' = " << sqrt(epsilon2) << "\n";
- write_delaunay_mesh(t, control_point, is2d);
- }
- return sqrt(epsilon2);
-}
-
-FT point_sampling_radius_by_delaunay(Point_Vector& points, FT epsilon0)
-{
- Delaunay_triangulation t(points[0].size());
- t.insert(points.begin(), points.end());
- return sampling_radius(t, epsilon0);
-}
-
-// A little script to make a tikz histogram of epsilon distribution
-// Returns the average epsilon
-FT epsilon_histogram(Delaunay_triangulation& t, int n)
-{
- FT epsilon_max = 0; //sampling_radius(t,0);
- FT sum_epsilon = 0;
- int count_simplices = 0;
- std::vector<int> histo(n+1, 0);
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- {
- if (t.is_infinite(fc_it))
- continue;
- Point_Vector vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs( vertices.begin(), vertices.end());
- Point_d csc = cs.center();
- bool in_cube = true;
- for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi)
- if (*xi > 1.0 || *xi < -1.0)
- {
- in_cube = false; break;
- }
- if (!in_cube)
- continue;
- FT r = sqrt(Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin())));
- if (r > epsilon_max)
- epsilon_max = r;
- sum_epsilon += r;
- count_simplices++;
- histo[floor(r/epsilon_max*n)]++;
- }
- std::ofstream ofs ("histogram.tikz", std::ofstream::out);
- FT barwidth = 20.0/n;
- int max_value = *(std::max_element(histo.begin(), histo.end()));
- std::cout << max_value << std::endl;
- FT ten_power = pow(10, ceil(log10(max_value)));
- FT max_histo = ten_power;
- if (max_value/ten_power < 2)
- max_histo = 0.2*ten_power;
- if (max_value/ten_power < 5)
- max_histo = 0.5*ten_power;
- std::cout << ceil(log10(max_value)) << std::endl << max_histo << std::endl;
- FT unitht = max_histo/10.0;
-
- ofs << "\\draw[->] (0,0) -- (0,11);\n" <<
- "\\draw[->] (0,0) -- (21,0);\n" <<
- "\\foreach \\i in {1,...,10}\n" <<
- "\\draw (0,\\i) -- (-0.1,\\i);\n" <<
- "\\foreach \\i in {1,...,20}\n" <<
- "\\draw (\\i,0) -- (\\i,-0.1);\n" <<
-
- "\\node at (-1,11) {$\\epsilon$};\n" <<
- "\\node at (22,-1) {$\\epsilon/\\epsilon_{max}$};\n" <<
- "\\node at (-0.5,-0.5) {0};\n" <<
- "\\node at (-0.5,10) {" << max_histo << "};\n" <<
- "\\node at (20,-0.5) {1};\n";
-
-
- for (int i = 0; i < n; ++i)
- ofs << "\\draw (" << barwidth*i << "," << histo[i]/unitht << ") -- ("
- << barwidth*(i+1) << "," << histo[i]/unitht << ") -- ("
- << barwidth*(i+1) << ",0) -- (" << barwidth*i << ",0) -- cycle;\n";
-
- ofs.close();
-
- //return sum_epsilon/count_simplices;
- return epsilon_max;
-}
-
-FT epsilon_histogram_by_delaunay(Point_Vector& points, int n)
-{
- Delaunay_triangulation t(points[0].size());
- t.insert(points.begin(), points.end());
- return epsilon_histogram(t, n);
-}
-
-
-int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind, std::vector<std::vector<int>>& full_cells)
-{
- //******************** Preface: origin point
- int D = W[0].size();
- std::vector<FT> orig_vector;
- for (int i=0; i<D; i++)
- orig_vector.push_back(0);
- Point_d origin(orig_vector);
-
- //******************** Constructing a WL matrix
- int nbP = W.size();
- Euclidean_distance ed;
- FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]);
- std::vector<Point_d> landmarks_ext;
- int nb_cells = 1;
- for (int i = 0; i < D; ++i)
- nb_cells *= 3;
- for (int i = 0; i < nb_cells; ++i)
- for (int k = 0; k < nbL; ++k)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0));
- cell_i /= 3;
- }
- landmarks_ext.push_back(point);
- }
- write_points("landmarks/initial_landmarks",landmarks_ext);
- STraits traits(&(landmarks_ext[0]));
- std::vector< std::vector <int> > WL(nbP);
-
- //********************** Neighbor search in a Kd tree
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nb_cells*nbL),
- typename Tree::Splitter(),
- traits);
- std::cout << "Enter (D+1) nearest landmarks\n";
- for (int i = 0; i < nbP; i++)
- {
- Point_d& w = W[i];
- ////Search D+1 nearest neighbours from the tree of landmarks L
- K_neighbor_search search(L, w, D+1, FT(0), true,
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks_ext[0])) );
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end())
- WL[i].push_back((it->first)%nbL);
- }
- if (i == landmarks_ind[WL[i][0]])
- {
- FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]);
- if (dist < lambda)
- lambda = dist;
- }
- }
- std::string out_file = "wl_result";
- //write_wl(out_file,WL);
-
- //******************** Constructng a witness complex
- std::cout << "Entered witness complex construction\n";
- Witness_complex<> witnessComplex;
- witnessComplex.setNbL(nbL);
- witnessComplex.witness_complex(WL);
-
- //******************** Verifying if all full cells are in the complex
-
- int in=0, not_in=0;
- for (auto cell : full_cells)
- {
- //print_vector(cell);
- if (witnessComplex.find(cell) != witnessComplex.null_simplex())
- in++;
- else
- not_in++;
- }
- std::cout << "Out of all the cells in Delaunay triangulation:\n" << in << " are in the witness complex\n" <<
- not_in << " are not.\n";
-
- //******************** Making a set of bad link landmarks
-
- std::cout << "Entered bad links\n";
- std::set< int > perturbL;
- int count_badlinks = 0;
- //std::cout << "Bad links around ";
- std::vector< int > count_bad(D);
- std::vector< int > count_good(D);
- for (auto u: witnessComplex.complex_vertex_range())
- {
- if (!witnessComplex.has_good_link(u, count_bad, count_good))
- {
- count_badlinks++;
- Point_d& l = landmarks[u];
- Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits);
- std::vector<int> curr_perturb;
- L.search(std::insert_iterator<std::vector<int>>(curr_perturb,curr_perturb.begin()),fs);
- for (int i: curr_perturb)
- perturbL.insert(i%nbL);
- }
- }
- for (unsigned int i = 0; i != count_good.size(); i++)
- if (count_good[i] != 0)
- std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl;
- for (unsigned int i = 0; i != count_bad.size(); i++)
- if (count_bad[i] != 0)
- std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl;
- std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
-
- //*********************** Perturb bad link landmarks
- /*
- for (auto u: perturbL)
- {
- Random_point_iterator rp(D,sqrt(lambda)/8);
- std::vector<FT> point;
- for (int i = 0; i < D; i++)
- {
- while (K().squared_distance_d_object()(*rp,origin) < lambda/256)
- rp++;
- FT coord = landmarks[u][i] + (*rp)[i];
- if (coord > 1)
- point.push_back(coord-1);
- else if (coord < -1)
- point.push_back(coord+1);
- else
- point.push_back(coord);
- }
- landmarks[u] = Point_d(point);
- }
- std::cout << "lambda=" << lambda << std::endl;
- */
- char buffer[100];
- int i = sprintf(buffer,"stree_result.txt");
-
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
-
- //write_edges("landmarks/edges", witnessComplex, landmarks);
- /*
- return count_badlinks;
- */
- return 0;
-}
-
-int main (int argc, char * const argv[])
-{
- power_protection = true;//false;
- grid_points = false;//true;
- torus = true;
-
- if (argc != 4)
- {
- std::cerr << "Usage: " << argv[0]
- << " nbP dim delta\n";
- return 0;
- }
- int nbP = atoi(argv[1]);
- int dim = atoi(argv[2]);
- double theta0 = atof(argv[3]);
- //double delta = atof(argv[3]);
-
- is2d = (dim == 2);
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- if (grid_points)
- {
- generate_points_grid(point_vector, (int)pow(nbP, 1.0/dim), dim, torus);
- nbP = (int)pow((int)pow(nbP, 1.0/dim), dim);
- }
- else
- generate_points_random_box(point_vector, nbP, dim);
- FT epsilon = point_sampling_radius_by_delaunay(point_vector, 0);
- //FT epsilon = epsilon_histogram_by_delaunay(point_vector,50);
- std::cout << "Initial epsilon = " << epsilon << std::endl;
- Point_Vector L;
- std::vector<int> chosen_landmarks;
- //write_points("landmarks/initial_pointset",point_vector);
- //write_points("landmarks/initial_landmarks",L);
- CGAL::Timer timer;
-
- int n = 1;
- std::vector<FT> values(n,0);
- std::vector<FT> time(n,0);
-
- //FT step = 0.001;
- //FT delta = 0.01*epsilon;
- //FT alpha = 0.5;
- //FT step = atof(argv[3]);
-
- start_experiments(point_vector, theta0, chosen_landmarks, epsilon);
-
- // for (int i = 0; i < n; i++)
- // //for (int i = 0; bl > 0; i++)
- // {
- // //std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n";
- // //double delta = pow(10, -(1.0*i)/2);
- // //delta = step*i*epsilon;
- // //theta0 = step*i;
- // std::cout << "delta/epsilon = " << delta/epsilon << std::endl;
- // std::cout << "theta0 = " << theta0 << std::endl;
- // // Averaging the result
- // int sum_values = 0;
- // int nb_iterations = 1;
- // std::vector<std::vector<int>> full_cells;
- // for (int i = 0; i < nb_iterations; ++i)
- // {
- // //L = {};
- // chosen_landmarks = {};
- // //full_cells = {};
- // //timer.start();
- // //protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta, epsilon, alpha, theta0, full_cells, torus, power_protection);
- // protected_delaunay(point_vector, chosen_landmarks, delta, epsilon, alpha, theta0, torus, power_protection);
- // //timer.stop();
- // sum_values += chosen_landmarks.size();
- // }
- // //FT epsilon2 = point_sampling_radius_by_delaunay(L, epsilon);
- // //std::cout << "Final epsilon = " << epsilon2 << ". Ratio = " << epsilon2/epsilon << std::endl;
- // //write_points("landmarks/initial_landmarks",L);
- // //std::cout << "delta/epsilon' = " << delta/epsilon2 << std::endl;
- // FT nbL = (sum_values*1.0)/nb_iterations;
- // //values[i] = pow((1.0*nbL)/nbP, -1.0/dim);
- // values[i] = (1.0*nbL)/nbP;
- // std::cout << "Number of landmarks = " << nbL << ", time= " << timer.time() << "s"<< std::endl;
- // //landmark_perturbation(point_vector, nbL, L, chosen_landmarks, full_cells);
- // time[i] = timer.time();
- // timer.reset();
- // //write_points("landmarks/landmarks0",L);
- // }
-
- // // OUTPUT A PLOT
- // FT hstep = 20.0/(n-1);
- // FT wstep = 10.0;
-
- // std::ofstream ofs("N'Nplot.tikz", std::ofstream::out);
- // ofs << "\\draw[red] (0," << wstep*values[0] << ")";
- // for (int i = 1; i < n; ++i)
- // ofs << " -- (" << hstep*i << "," << wstep*values[i] << ")";
- // ofs << ";\n";
- // ofs.close();
- /*
- wstep = 0.1;
- ofs = std::ofstream("time.tikz", std::ofstream::out);
- ofs << "\\draw[red] (0," << wstep*time[0] << ")";
- for (int i = 1; i < n; ++i)
- ofs << " -- (" << hstep*i << "," << wstep*time[i] << ")";
- ofs << ";\n";
- ofs.close();
-
-
- std::vector<std::vector<int>> full_cells;
- timer.start();
- landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta, full_cells);
- timer.stop();
- FT epsilon2 = point_sampling_radius_by_delaunay(L);
- std::cout << "Final epsilon = " << epsilon2 << ". Ratio = " << epsilon/epsilon2 << std::endl;
- write_points("landmarks/initial_landmarks",L);
- int nbL = chosen_landmarks.size();
- std::cout << "Number of landmarks = " << nbL << ", time= " << timer.time() << "s"<< std::endl;
- //landmark_perturbation(point_vector, nbL, L, chosen_landmarks, full_cells);
- timer.reset();
- */
-}
diff --git a/src/Witness_complex/example/witness_complex_cubic_systems.cpp b/src/Witness_complex/example/witness_complex_cubic_systems.cpp
deleted file mode 100644
index 2f4ee1cb..00000000
--- a/src/Witness_complex/example/witness_complex_cubic_systems.cpp
+++ /dev/null
@@ -1,547 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-#include <algorithm>
-#include <set>
-#include <iterator>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-#include "Torus_distance.h"
-
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-
-#include <CGAL/Kernel_d/Vector_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-#include <CGAL/Fuzzy_sphere.h>
-#include <CGAL/Random.h>
-#include <CGAL/Delaunay_triangulation.h>
-
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-//typedef CGAL::Cartesian_d<double> K;
-//typedef CGAL::Point_d<K> Point_d;
-typedef K::FT FT;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-typedef CGAL::Kd_tree<STraits> Tree2;
-
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef std::vector<Point_d> Point_Vector;
-
-//typedef K::Equal_d Equal_d;
-//typedef CGAL::Random_points_in_cube_d<CGAL::Point_d<CGAL::Cartesian_d<FT> > > Random_cube_iterator;
-typedef CGAL::Random_points_in_cube_d<Point_d> Random_cube_iterator;
-typedef CGAL::Random_points_in_ball_d<Point_d> Random_point_iterator;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef CGAL::Sphere_d<K> Sphere_d;
-
-bool toric=false;
-
-
-/**
- * \brief Customized version of read_points
- * which takes into account a possible nbP first line
- *
- */
-inline void
-read_points_cust ( std::string file_name , Point_Vector & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- Point_d p(point.begin(), point.end());
- if (point.size() != 1)
- points.push_back(p);
- }
- in_file.close();
-}
-
-void generate_points_random_box(Point_Vector& W, int nbP, int dim)
-{
- /*
- Random_cube_iterator rp(dim, 1);
- for (int i = 0; i < nbP; i++)
- {
- std::vector<double> point;
- for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it)
- point.push_back(*it);
- W.push_back(Point_d(point));
- rp++;
- }
- */
- Random_cube_iterator rp(dim, 1.0);
- for (int i = 0; i < nbP; i++)
- {
- W.push_back(*rp++);
- }
-}
-
-
-void write_wl( std::string file_name, std::vector< std::vector <int> > & WL)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : WL)
- {
- for (auto l: w)
- ofs << l << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-
-void write_points( std::string file_name, std::vector< Point_d > & points)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : points)
- {
- for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto u: witness_complex.complex_vertex_range())
- for (auto v: witness_complex.complex_vertex_range())
- {
- typeVectorVertex edge = {u,v};
- if (u < v && witness_complex.find(edge) != witness_complex.null_simplex())
- {
- for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n\n\n";
- }
- }
- ofs.close();
-}
-
-
-/** Function that chooses landmarks from W and place it in the kd-tree L.
- * Note: nbL hould be removed if the code moves to Witness_complex
- */
-void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- int chosen_landmark;
- Point_d* p;
- CGAL::Random rand;
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- do chosen_landmark = rand.get_int(0,nbP);
- while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0);
- //rand++;
- //std::cout << "Chose " << chosen_landmark << std::endl;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- landmarks_ind.push_back(chosen_landmark);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- }
-
-void aux_fill_grid(Point_Vector& W, int& width, Point_Vector& landmarks, std::vector<int>& landmarks_ind, std::vector<bool> & curr_pattern)
-{
- int D = W[0].size();
- int nb_points = 1;
- for (int i = 0; i < D; ++i)
- nb_points *= width;
- for (int i = 0; i < nb_points; ++i)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- if (curr_pattern[l])
- point.push_back(-1.0+(2.0/width)*(cell_i%width)+(1.0/width));
- else
- point.push_back(-1.0+(2.0/width)*(cell_i%width));
- cell_i /= width;
- }
- landmarks.push_back(Point_d(point));
- landmarks_ind.push_back(0);//landmarks_ind.push_back(W.size());
- //std::cout << "Added point " << W.size() << std::endl;;
- //W.push_back(Point_d(point));
- }
-}
-
-void aux_put_halves(Point_Vector& W, int& width, Point_Vector& landmarks, std::vector<int>& landmarks_ind, std::vector<bool>& curr_pattern, std::vector<bool>::iterator curr_pattern_it, std::vector<bool>::iterator bool_it, std::vector<bool>::iterator bool_end)
-{
- if (curr_pattern_it != curr_pattern.end())
- {
- if (bool_it != bool_end)
- {
- *curr_pattern_it = false;
- aux_put_halves(W, width, landmarks, landmarks_ind, curr_pattern, curr_pattern_it+1, bool_it, bool_end);
- *curr_pattern_it = true;
- aux_put_halves(W, width, landmarks, landmarks_ind, curr_pattern, curr_pattern_it+1, bool_it+1, bool_end);
- }
- }
- else
- if (*bool_it)
- {
- std::cout << "Filling the pattern ";
- for (bool b: curr_pattern)
- if (b) std::cout << '1';
- else std::cout << '0';
- std::cout << "\n";
- aux_fill_grid(W, width, landmarks, landmarks_ind, curr_pattern);
- }
-}
-
-void landmark_choice_cs(Point_Vector& W, int width, Point_Vector& landmarks, std::vector<int>& landmarks_ind, std::vector<bool>& face_centers)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- //int chosen_landmark;
- CGAL::Random rand;
- //To speed things up check the last true in the code and put it as the finishing condition
- unsigned last_true = face_centers.size()-1;
- while (!face_centers[last_true] && last_true != 0)
- last_true--;
- //Recursive procedure to understand where we put +1/2 in centers' coordinates
- std::vector<bool> curr_pattern(W[0].size(), false);
- aux_put_halves(W, width, landmarks, landmarks_ind, curr_pattern, curr_pattern.begin(), face_centers.begin(), face_centers.begin()+(last_true+1));
- std::cout << "The number of landmarks is: " << landmarks.size() << std::endl;
-
- }
-
-int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- //******************** Preface: origin point
- int D = W[0].size();
- std::vector<FT> orig_vector;
- for (int i=0; i<D; i++)
- orig_vector.push_back(0);
- Point_d origin(orig_vector);
-
- //******************** Constructing a WL matrix
- int nbP = W.size();
- int nbL = landmarks.size();
- Euclidean_distance ed;
- FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]);
- std::vector<Point_d> landmarks_ext;
- int nb_cells = 1;
- for (int i = 0; i < D; ++i)
- nb_cells *= 3;
- for (int i = 0; i < nb_cells; ++i)
- for (int k = 0; k < nbL; ++k)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0));
- cell_i /= 3;
- }
- landmarks_ext.push_back(point);
- }
- write_points("landmarks/initial_landmarks",landmarks_ext);
- STraits traits(&(landmarks_ext[0]));
- std::vector< std::vector <int> > WL(nbP);
-
- //********************** Neighbor search in a Kd tree
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nb_cells*nbL),
- typename Tree::Splitter(),
- traits);
- std::cout << "Enter (D+1) nearest landmarks\n";
- for (int i = 0; i < nbP; i++)
- {
- Point_d& w = W[i];
- ////Search D+1 nearest neighbours from the tree of landmarks L
- K_neighbor_search search(L, w, D+1, FT(0), true,
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks_ext[0])) );
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end())
- WL[i].push_back((it->first)%nbL);
- }
- if (i == landmarks_ind[WL[i][0]])
- {
- FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]);
- if (dist < lambda)
- lambda = dist;
- }
- }
- std::string out_file = "wl_result";
- write_wl(out_file,WL);
-
- //******************** Constructng a witness complex
- std::cout << "Entered witness complex construction\n";
- Witness_complex<> witnessComplex;
- witnessComplex.setNbL(nbL);
- witnessComplex.witness_complex(WL);
-
- //******************** Making a set of bad link landmarks
- std::cout << "Entered bad links\n";
- std::set< int > perturbL;
- int count_badlinks = 0;
- //std::cout << "Bad links around ";
- std::vector< int > count_bad(D);
- std::vector< int > count_good(D);
- for (auto u: witnessComplex.complex_vertex_range())
- {
- if (!witnessComplex.has_good_link(u, count_bad, count_good, D))
- {
- count_badlinks++;
- Point_d& l = landmarks[u];
- Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits);
- std::vector<int> curr_perturb;
- L.search(std::insert_iterator<std::vector<int>>(curr_perturb,curr_perturb.begin()),fs);
- for (int i: curr_perturb)
- perturbL.insert(i%nbL);
- }
- }
- for (unsigned int i = 0; i != count_good.size(); i++)
- if (count_good[i] != 0)
- std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl;
- for (unsigned int i = 0; i != count_bad.size(); i++)
- if (count_bad[i] != 0)
- std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl;
- std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
-
- //*********************** Perturb bad link landmarks
- for (auto u: perturbL)
- {
- Random_point_iterator rp(D,sqrt(lambda)/8);
- std::vector<FT> point;
- for (int i = 0; i < D; i++)
- {
- while (K().squared_distance_d_object()(*rp,origin) < lambda/256)
- rp++;
- FT coord = landmarks[u][i] + (*rp)[i];
- if (coord > 1)
- point.push_back(coord-1);
- else if (coord < -1)
- point.push_back(coord+1);
- else
- point.push_back(coord);
- }
- landmarks[u] = Point_d(point);
- }
- std::cout << "lambda=" << lambda << std::endl;
- char buffer[100];
- int i = sprintf(buffer,"stree_result.txt");
-
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- write_edges("landmarks/edges", witnessComplex, landmarks);
- return count_badlinks;
-}
-
-void exaustive_search(Point_Vector& W, int width)
-{
- int D = W[0].size()+1;
- int nb_points = pow(2,D);
- std::vector<bool> face_centers(D, false);
- int bl = 0; //Bad links
- std::vector<std::vector<bool>> good_patterns;
- for (int i = 0; i < nb_points; ++i)
- {
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- if (cell_i%2 == 0)
- face_centers[l] = false;
- else
- face_centers[l] = true;
- cell_i /= 2;
- }
- std::cout << "**Current pattern ";
- for (bool b: face_centers)
- if (b) std::cout << '1';
- else std::cout << '0';
- std::cout << "\n";
- Point_Vector landmarks;
- std::vector<int> landmarks_ind;
- Point_Vector W_copy(W);
- landmark_choice_cs(W_copy, width, landmarks, landmarks_ind, face_centers);
- if (landmarks.size() != 0)
- {
- bl = landmark_perturbation(W_copy, landmarks, landmarks_ind);
- if ((1.0*bl)/landmarks.size() < 0.5)
- good_patterns.push_back(face_centers);
- }
- }
- std::cout << "The following patterns worked: ";
- for (std::vector<bool> pattern : good_patterns)
- {
- std::cout << "[";
- for (bool b: pattern)
- if (b) std::cout << '1';
- else std::cout << '0';
- std::cout << "] ";
- }
- std::cout << "\n";
-}
-
-int main (int argc, char * const argv[])
-{
- unsigned nbP = atoi(argv[1]);
- unsigned width = atoi(argv[2]);
- unsigned dim = atoi(argv[3]);
- std::string code = (std::string) argv[4];
- bool e_option = false;
- int c;
- if (argc != 5)
- {
- std::cerr << "Usage: " << argv[0]
- << "witness_complex_cubic_systems nbP width dim code || witness_complex_systems -e nbP width dim\n"
- << "where nbP stands for the number of witnesses, width for the width of the grid, dim for dimension "
- << "and code is a sequence of (dim+1) symbols 0 and 1 representing if we take the centers of k-dimensional faces of the cubic system depending if it is 0 or 1."
- << "-e stands for the 'exaustive' option";
- return 0;
- }
- while ((c = getopt (argc, argv, "e::")) != -1)
- switch(c)
- {
- case 'e' :
- e_option = true;
- nbP = atoi(argv[2]);
- width = atoi(argv[3]);
- dim = atoi(argv[4]);
- break;
- default :
- nbP = atoi(argv[1]);
- width = atoi(argv[2]);
- dim = atoi(argv[3]);
- code = (std::string) argv[4];
- }
- Point_Vector point_vector;
- generate_points_random_box(point_vector, nbP, dim);
-
- // Exaustive search
- if (e_option)
- {
- std::cout << "Start exaustive search!\n";
- exaustive_search(point_vector, width);
- return 0;
- }
- // Search with a specific cubic system
- std::vector<bool> face_centers;
- if (code.size() != dim+1)
- {
- std::cerr << "The code should contain (dim+1) symbols";
- return 1;
- }
- for (char c: code)
- if (c == '0')
- face_centers.push_back(false);
- else
- face_centers.push_back(true);
- std::cout << "Let the carnage begin!\n";
- Point_Vector L;
- std::vector<int> chosen_landmarks;
-
- landmark_choice_cs(point_vector, width, L, chosen_landmarks, face_centers);
-
- int nbL = width; //!!!!!!!!!!!!!
- int bl = nbL, curr_min = bl;
- write_points("landmarks/initial_pointset",point_vector);
- //write_points("landmarks/initial_landmarks",L);
- //for (int i = 0; i < 1; i++)
- for (int i = 0; bl > 0; i++)
- {
- std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n";
- bl=landmark_perturbation(point_vector, L, chosen_landmarks);
- if (bl < curr_min)
- curr_min=bl;
- write_points("landmarks/landmarks0",L);
- }
-
-}
diff --git a/src/Witness_complex/example/witness_complex_epsilon.cpp b/src/Witness_complex/example/witness_complex_epsilon.cpp
deleted file mode 100644
index 7f8b985f..00000000
--- a/src/Witness_complex/example/witness_complex_epsilon.cpp
+++ /dev/null
@@ -1,55 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <vector>
-
-#include <CGAL/Epick_d.h>
-#include <CGAL/enum.h>
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-typedef K::FT FT;
-typedef K::Hyperplane_d Hyperplane_d;
-typedef K::Has_on_positive_side_d Has_on_positive_side_d;
-
-int main ()
-{
- std::vector<Point_d> vertices;
- Point_d v1(std::vector<FT>({-1,1}));
- Point_d v2(std::vector<FT>({1,-1}));
- vertices.push_back(v1);
- vertices.push_back(v2);
- Point_d p(std::vector<FT>({-1,-1}));
- Hyperplane_d hp(vertices.begin(), vertices.end());
- //Hyperplane_d hp(vertices.begin(), vertices.end(), p, CGAL::ON_POSITIVE_SIDE);
- if (Has_on_positive_side_d()(hp, p))
- std::cout << "OK\n";
- else
- std::cout << "NOK\n";
- CGAL::Oriented_side side_p = K::Oriented_side_d()(hp, p);
- if (side_p == CGAL::ZERO)
- std::cout << "Point (-1,-1) is on the line passing through (-1,1) and (1,-1)";
- CGAL::Oriented_side side_v2 = K::Oriented_side_d()(hp, v2);
- if (side_v2 != CGAL::ZERO)
- std::cout << "Point (1,-1) is not on the line passing through (-1,1) and (1,-1)";
-}
diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp
deleted file mode 100644
index 49383154..00000000
--- a/src/Witness_complex/example/witness_complex_flat_torus.cpp
+++ /dev/null
@@ -1,851 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-#include <algorithm>
-#include <set>
-#include <iterator>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-//#include <boost/filesystem.hpp>
-
-//#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Euclidean_distance.h>
-
-#include <CGAL/Kernel_d/Vector_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-#include <CGAL/Fuzzy_sphere.h>
-#include <CGAL/Random.h>
-
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-//typedef CGAL::Cartesian_d<double> K;
-//typedef CGAL::Point_d<K> Point_d;
-typedef K::FT FT;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-/**
- * \brief Class of distance in a flat torus in dimension D
- *
- */
-//class Torus_distance : public Euclidean_distance {
-/*
- class Torus_distance {
-
-public:
- typedef K::FT FT;
- typedef K::Point_d Point_d;
- typedef Point_d Query_item;
- typedef typename CGAL::Dynamic_dimension_tag D;
-
- double box_length = 2;
-
- FT transformed_distance(Query_item q, Point_d p) const
- {
- FT distance = FT(0);
- FT coord = FT(0);
- //std::cout << "Hello skitty!\n";
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1), pit = construct_it(p);
- for(; qit != qe; qit++, pit++)
- {
- coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit)));
- if (coord*coord <= (box_length-coord)*(box_length-coord))
- distance += coord*coord;
- else
- distance += (box_length-coord)*(box_length-coord);
- }
- return distance;
- }
-
- FT min_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r) const {
- FT distance = FT(0);
- FT dist1, dist2;
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if((*qit) < r.min_coord(i))
- {
- dist1 = (r.min_coord(i)-(*qit));
- dist2 = (box_length - r.max_coord(i)+(*qit));
- if (dist1 < dist2)
- distance += dist1*dist1;
- else
- distance += dist2*dist2;
- }
- else if ((*qit) > r.max_coord(i))
- {
- dist1 = (box_length - (*qit)+r.min_coord(i));
- dist2 = ((*qit) - r.max_coord(i));
- if (dist1 < dist2)
- distance += dist1*dist1;
- else
- distance += dist2*dist2;
- }
- }
- return distance;
- }
-
- FT min_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r,
- std::vector<FT>& dists) const {
- FT distance = FT(0);
- FT dist1, dist2;
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- //std::cout << r.max_coord(0) << std::endl;
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if((*qit) < r.min_coord(i))
- {
- dist1 = (r.min_coord(i)-(*qit));
- dist2 = (box_length - r.max_coord(i)+(*qit));
- if (dist1 < dist2)
- {
- dists[i] = dist1;
- distance += dist1*dist1;
- }
- else
- {
- dists[i] = dist2;
- distance += dist2*dist2;
- //std::cout << "Good stuff1\n";
- }
- }
- else if ((*qit) > r.max_coord(i))
- {
- dist1 = (box_length - (*qit)+r.min_coord(i));
- dist2 = ((*qit) - r.max_coord(i));
- if (dist1 < dist2)
- {
- dists[i] = dist1;
- distance += dist1*dist1;
- //std::cout << "Good stuff2\n";
- }
- else
- {
- dists[i] = dist2;
- distance += dist2*dist2;
- }
- }
- };
- return distance;
- }
-
- FT max_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r) const {
- FT distance=FT(0);
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if (box_length <= (r.min_coord(i)+r.max_coord(i)))
- if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) &&
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
- else
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- else
- if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) ||
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
- else
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- }
- return distance;
- }
-
-
- FT max_distance_to_rectangle(const Query_item& q,
- const CGAL::Kd_tree_rectangle<FT,D>& r,
- std::vector<FT>& dists) const {
- FT distance=FT(0);
- typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object();
- typename K::Cartesian_const_iterator_d qit = construct_it(q),
- qe = construct_it(q,1);
- for(unsigned int i = 0;qit != qe; i++, qit++)
- {
- if (box_length <= (r.min_coord(i)+r.max_coord(i)))
- if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) &&
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- {
- dists[i] = r.max_coord(i)-(*qit);
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
- }
- else
- {
- dists[i] = sqrt(((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)));
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- }
- else
- if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) ||
- (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0))
- {
- dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)));
- distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit));
-
- }
- else
- {
- dists[i] = (*qit)-r.min_coord(i);
- distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i));
- }
- }
- return distance;
- }
-
- inline FT new_distance(FT dist, FT old_off, FT new_off,
- int ) const {
-
- FT new_dist = dist + (new_off*new_off - old_off*old_off);
- return new_dist;
- }
-
- inline FT transformed_distance(FT d) const {
- return d*d;
- }
-
- inline FT inverse_of_transformed_distance(FT d) const {
- return sqrt(d);
- }
-
-};
-*/
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-typedef CGAL::Kd_tree<STraits> Tree2;
-
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef std::vector<Point_d> Point_Vector;
-
-//typedef K::Equal_d Equal_d;
-//typedef CGAL::Random_points_in_cube_d<CGAL::Point_d<CGAL::Cartesian_d<FT> > > Random_cube_iterator;
-typedef CGAL::Random_points_in_cube_d<Point_d> Random_cube_iterator;
-typedef CGAL::Random_points_in_ball_d<Point_d> Random_point_iterator;
-
-bool toric=false;
-
-/**
- * \brief Customized version of read_points
- * which takes into account a possible nbP first line
- *
- */
-inline void
-read_points_cust ( std::string file_name , Point_Vector & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- Point_d p(point.begin(), point.end());
- if (point.size() != 1)
- points.push_back(p);
- }
- in_file.close();
-}
-
-void generate_points_grid(Point_Vector& W, int width, int D)
-{
- int nb_points = 1;
- for (int i = 0; i < D; ++i)
- nb_points *= width;
- for (int i = 0; i < nb_points; ++i)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back((2.0/width)*(cell_i%width));
- cell_i /= width;
- }
- W.push_back(point);
- }
-}
-
-void generate_points_random_box(Point_Vector& W, int nbP, int dim)
-{
- /*
- Random_cube_iterator rp(dim, 1);
- for (int i = 0; i < nbP; i++)
- {
- std::vector<double> point;
- for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it)
- point.push_back(*it);
- W.push_back(Point_d(point));
- rp++;
- }
- */
- Random_cube_iterator rp(dim, 1.0);
- for (int i = 0; i < nbP; i++)
- {
- W.push_back(*rp++);
- }
-}
-
-/* NOT TORUS RELATED
- */
-void generate_points_sphere(Point_Vector& W, int nbP, int dim)
-{
- CGAL::Random_points_on_sphere_d<Point_d> rp(dim,1);
- for (int i = 0; i < nbP; i++)
- W.push_back(*rp++);
-}
-/*
-void read_points_to_tree (std::string file_name, Tree& tree)
-{
- //I assume here that tree is empty
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector<double> coords;
- std::istringstream iss( line );
- while(iss >> x) { coords.push_back(x); }
- if (coords.size() != 1)
- {
- Point_d point(coords.begin(), coords.end());
- tree.insert(point);
- }
- }
- in_file.close();
-}
-*/
-
-void write_wl( std::string file_name, std::vector< std::vector <int> > & WL)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : WL)
- {
- for (auto l: w)
- ofs << l << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-
-std::vector<Point_d> convert_to_torus(std::vector< Point_d>& points)
-{
- std::vector< Point_d > points_torus;
- for (auto p: points)
- {
- FT theta = M_PI*p[0];
- FT phi = M_PI*p[1];
- std::vector<FT> p_torus;
- p_torus.push_back((1+0.2*cos(theta))*cos(phi));
- p_torus.push_back((1+0.2*cos(theta))*sin(phi));
- p_torus.push_back(0.2*sin(theta));
- points_torus.push_back(Point_d(p_torus));
- }
- return points_torus;
-}
-
-void write_points_torus( std::string file_name, std::vector< Point_d > & points)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- std::vector<Point_d> points_torus = convert_to_torus(points);
- for (auto w : points_torus)
- {
- for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-void write_points( std::string file_name, std::vector< Point_d > & points)
-{
- if (toric) write_points_torus(file_name, points);
- else
- {
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : points)
- {
- for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- }
- ofs.close();
- }
-}
-
-
-void write_edges_torus(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- Point_Vector l_torus = convert_to_torus(landmarks);
- for (auto u: witness_complex.complex_vertex_range())
- for (auto v: witness_complex.complex_vertex_range())
- {
- typeVectorVertex edge = {u,v};
- if (u < v && witness_complex.find(edge) != witness_complex.null_simplex())
- {
- for (auto it = l_torus[u].cartesian_begin(); it != l_torus[u].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- for (auto it = l_torus[v].cartesian_begin(); it != l_torus[v].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n\n\n";
- }
- }
- ofs.close();
-}
-
-void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- if (toric) write_edges_torus(file_name, witness_complex, landmarks);
- else
- {
- for (auto u: witness_complex.complex_vertex_range())
- for (auto v: witness_complex.complex_vertex_range())
- {
- typeVectorVertex edge = {u,v};
- if (u < v && witness_complex.find(edge) != witness_complex.null_simplex())
- {
- for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n\n\n";
- }
- }
- ofs.close();
- }
-}
-
-
-/** Function that chooses landmarks from W and place it in the kd-tree L.
- * Note: nbL hould be removed if the code moves to Witness_complex
- */
-void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- int chosen_landmark;
- Point_d* p;
- CGAL::Random rand;
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- do chosen_landmark = rand.get_int(0,nbP);
- while (std::find(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=landmarks_ind.end());
- //rand++;
- //std::cout << "Chose " << chosen_landmark << std::endl;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- landmarks_ind.push_back(chosen_landmark);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- }
-
-/** \brief Choose landmarks on a body-central cubic system
- */
-void landmark_choice_bcc(Point_Vector &W, int nbP, int width, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- int D = W[0].size();
- int nb_points = 1;
- for (int i = 0; i < D; ++i)
- nb_points *= width;
- for (int i = 0; i < nb_points; ++i)
- {
- std::vector<double> point;
- std::vector<double> cpoint;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(-1.0+(2.0/width)*(cell_i%width));
- cpoint.push_back(-1.0+(2.0/width)*(cell_i%width)+(1.0/width));
- cell_i /= width;
- }
- landmarks.push_back(point);
- landmarks.push_back(cpoint);
- landmarks_ind.push_back(2*i);
- landmarks_ind.push_back(2*i+1);
- }
- std::cout << "The number of landmarks is: " << landmarks.size() << std::endl;
-}
-
-
-int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- //********************Preface: origin point
- int D = W[0].size();
- std::vector<FT> orig_vector;
- for (int i=0; i<D; i++)
- orig_vector.push_back(0);
- Point_d origin(orig_vector);
- //Distance dist;
- //dist.transformed_distance(0,1);
- //******************** Constructing a WL matrix
- int nbP = W.size();
- int nbL = landmarks.size();
- //Point_Vector landmarks_ = landmarks;
- Euclidean_distance ed;
- //Equal_d ed;
- //Point_d p1(std::vector<FT>({0.8,0.8})), p2(std::vector<FT>({0.1,0.1}));
- FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]);
- //std::cout << "Lambda=" << lambda << std::endl;
- //FT lambda = 0.1;//Euclidean_distance();
- std::vector<Point_d> landmarks_ext;
- int nb_cells = 1;
- for (int i = 0; i < D; ++i)
- nb_cells *= 3;
- for (int i = 0; i < nb_cells; ++i)
- for (int k = 0; k < nbL; ++k)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0));
- cell_i /= 3;
- }
- landmarks_ext.push_back(point);
- }
- write_points("landmarks/initial_landmarks",landmarks_ext);
- STraits traits(&(landmarks_ext[0]));
- std::vector< std::vector <int> > WL(nbP);
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nb_cells*nbL),
- typename Tree::Splitter(),
- traits);
- /*Tree2 L2(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbL),
- typename Tree::Splitter(),
- STraits(&(landmarks[0])));
- */
- std::cout << "Enter (D+1) nearest landmarks\n";
- //std::cout << "Size of the tree is " << L.size() << std::endl;
- for (int i = 0; i < nbP; i++)
- {
- //std::cout << "Entered witness number " << i << std::endl;
- Point_d& w = W[i];
- //std::cout << "Safely constructed a point\n";
- ////Search D+1 nearest neighbours from the tree of landmarks L
- /*
- if (w[0]>0.95)
- std::cout << i << std::endl;
- */
- K_neighbor_search search(L, w, D+1, FT(0), true,
- //CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks[0])) );
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks_ext[0])) );
- //std::cout << "Safely found nearest landmarks\n";
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- //Point_etiquette_map::iterator itm = L_i.find(it->first);
- //assert(itm != L_i.end());
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end())
- WL[i].push_back((it->first)%nbL);
- //std::cout << "ITFIRST " << it->first << std::endl;
- //std::cout << i << " " << it->first << ": " << it->second << std::endl;
- }
- if (i == landmarks_ind[WL[i][0]])
- {
- //std::cout << "'";
- FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]);
- if (dist < lambda)
- lambda = dist;
- }
- }
- //std::cout << "\n";
-
- std::string out_file = "wl_result";
- write_wl(out_file,WL);
-
- //******************** Constructng a witness complex
- std::cout << "Entered witness complex construction\n";
- Witness_complex<> witnessComplex;
- witnessComplex.setNbL(nbL);
- witnessComplex.witness_complex(WL);
- /*
- if (witnessComplex.is_witness_complex(WL))
- std::cout << "!!YES. IT IS A WITNESS COMPLEX!!\n";
- else
- std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n";
- */
- //******************** Making a set of bad link landmarks
- std::cout << "Entered bad links\n";
- std::set< int > perturbL;
- int count_badlinks = 0;
- //std::cout << "Bad links around ";
- std::vector< int > count_bad(D);
- std::vector< int > count_good(D);
- for (auto u: witnessComplex.complex_vertex_range())
- {
- //std::cout << "Vertex " << u << " ";
- if (!witnessComplex.has_good_link(u, count_bad, count_good))
- {
- //std::cout << "Landmark " << u << " start!" << std::endl;
- //perturbL.insert(u);
- count_badlinks++;
- //std::cout << u << " ";
- Point_d& l = landmarks[u];
- Fuzzy_sphere fs(l, sqrt(lambda), 0, traits);
- std::vector<int> curr_perturb;
- L.search(std::insert_iterator<std::vector<int>>(curr_perturb,curr_perturb.begin()),fs);
- for (int i: curr_perturb)
- perturbL.insert(i%nbL);
- //L.search(std::inserter(perturbL,perturbL.begin()),fs);
- //L.search(std::ostream_iterator<int>(std::cout,"\n"),fs);
- //std::cout << "PerturbL size is " << perturbL.size() << std::endl;
- }
- }
- for (unsigned int i = 0; i != count_good.size(); i++)
- if (count_good[i] != 0)
- std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl;
- for (unsigned int i = 0; i != count_bad.size(); i++)
- if (count_bad[i] != 0)
- std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl;
- std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
- //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl;
- //*********************** Perturb bad link landmarks
-
- for (auto u: perturbL)
- {
- Random_point_iterator rp(D,sqrt(lambda)/8);
- //std::cout << landmarks[u] << std::endl;
-
- std::vector<FT> point;
- for (int i = 0; i < D; i++)
- {
- while (K().squared_distance_d_object()(*rp,origin) < lambda/256)
- rp++;
- //FT coord = W[landmarks_ind[u]][i] + (*rp)[i];
- FT coord = landmarks[u][i] + (*rp)[i];
- if (coord > 1)
- point.push_back(coord-1);
- else if (coord < -1)
- point.push_back(coord+1);
- else
- point.push_back(coord);
- }
- landmarks[u] = Point_d(point);
- //std::cout << landmarks[u] << std::endl;
- }
-
- //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl;
- std::cout << "lambda=" << lambda << std::endl;
-
- //std::cout << "WL size" << WL.size() << std::endl;
- /*
- std::cout << "L:" << std::endl;
- for (int i = 0; i < landmarks.size(); i++)
- std::cout << landmarks[i] << std::endl;
- */
-
- char buffer[100];
- int i = sprintf(buffer,"stree_result.txt");
-
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- /*
- i = sprintf(buffer,"badlinks.txt");
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.write_bad_links(ofs);
- ofs.close();
- }
- */
- write_edges("landmarks/edges", witnessComplex, landmarks);
- //std::cout << Distance().transformed_distance(Point_d(std::vector<double>({0.1,0.1})), Point_d(std::vector<double>({1.9,1.9}))) << std::endl;
- return count_badlinks;
-}
-
-
-int main (int argc, char * const argv[])
-{
-
- if (argc != 4)
- {
- std::cerr << "Usage: " << argv[0]
- << " nbP nbL dim\n";
- return 0;
- }
- /*
- boost::filesystem::path p;
- for (; argc > 2; --argc, ++argv)
- p /= argv[1];
- */
-
- int nbP = atoi(argv[1]);
- int nbL = atoi(argv[2]);
- int dim = atoi(argv[3]);
- //clock_t start, end;
- //Construct the Simplex Tree
- //Witness_complex<> witnessComplex;
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- //read_points_cust(file_name, point_vector);
- //generate_points_random_box(point_vector, nbP, dim);
- generate_points_grid(point_vector, (int)pow(nbP, 1.0/dim), dim);
- //nbP = (int)(pow((int)pow(nbP, 1.0/dim), dim));
- /*
- for (auto &p: point_vector)
- {
- assert(std::count(point_vector.begin(),point_vector.end(),p) == 1);
- }
- */
- //std::cout << "Successfully read the points\n";
- //witnessComplex.setNbL(nbL);
- // witnessComplex.witness_complex_from_points(point_vector);
- //int nbP = point_vector.size();
- //std::vector<std::vector< int > > WL(nbP);
- //std::set<int> L;
- Point_Vector L;
- std::vector<int> chosen_landmarks;
- //Point_etiquette_map L_i;
- //start = clock();
- //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL);
- bool ok=false;
- while (!ok)
- {
- ok = true;
- L = {};
- chosen_landmarks = {};
- landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks);
-
- //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks);
- for (auto i: chosen_landmarks)
- {
- ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1);
- if (!ok) break;
- }
-
- }
- int bl = nbL, curr_min = bl;
- write_points("landmarks/initial_pointset",point_vector);
- //write_points("landmarks/initial_landmarks",L);
- for (int i = 0; i < 1; i++)
- //for (int i = 0; bl > 0; i++)
- {
- std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n";
- bl=landmark_perturbation(point_vector, L, chosen_landmarks);
- if (bl < curr_min)
- curr_min=bl;
- write_points("landmarks/landmarks0",L);
- }
- //end = clock();
-
- /*
- std::cout << "Landmark choice took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- */
-
- /*
- out_file = "output/"+file_name+"_"+argv[2]+".stree";
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
-
- out_file = "output/"+file_name+"_"+argv[2]+".badlinks";
- std::ofstream ofs2(out_file, std::ofstream::out);
- witnessComplex.write_bad_links(ofs2);
- ofs2.close();
- */
-}
diff --git a/src/Witness_complex/example/witness_complex_from_off.cpp b/src/Witness_complex/example/witness_complex_from_off.cpp
deleted file mode 100644
index 948f09a8..00000000
--- a/src/Witness_complex/example/witness_complex_from_off.cpp
+++ /dev/null
@@ -1,184 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-
-using namespace Gudhi;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-typedef std::vector< std::vector <double> > Point_Vector;
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-
-/**
- * \brief Customized version of read_points
- * which takes into account a possible nbP first line
- *
- */
-inline void
-read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- if (point.size() != 1)
- points.push_back(point);
- }
- in_file.close();
-}
-
-/**
- * \brief Rock age method of reading off file
- *
- */
-inline void
-off_reader_cust ( std::string file_name , std::vector< std::vector< double > > & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- // Line OFF. No need in it
- if (!getline(in_file, line))
- {
- std::cerr << "No line OFF\n";
- return;
- }
- // Line with 3 numbers. No need
- if (!getline(in_file, line))
- {
- std::cerr << "No line with 3 numbers\n";
- return;
- }
- // Reading points
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- points.push_back(point);
- }
- in_file.close();
-}
-
-int main (int argc, char * const argv[])
-{
- if (argc != 3)
- {
- std::cerr << "Usage: " << argv[0]
- << " path_to_point_file nbL \n";
- return 0;
- }
- std::string file_name = argv[1];
- int nbL = atoi(argv[2]);
-
- clock_t start, end;
- //Construct the Simplex Tree
- Witness_complex<> witnessComplex;
-
- /*
- std::cout << "Let the carnage begin!\n";
- start = clock();
- Point_Vector point_vector;
- off_reader_cust(file_name, point_vector);
- std::cout << "Successfully read the points\n";
- witnessComplex.setNbL(nbL);
- witnessComplex.witness_complex_from_points(point_vector);
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- char buffer[100];
- int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]);
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- */
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- off_reader_cust(file_name, point_vector);
- //std::cout << "Successfully read the points\n";
- witnessComplex.setNbL(nbL);
- // witnessComplex.witness_complex_from_points(point_vector);
- std::vector<std::vector< int > > WL;
- std::set<int> L;
- start = clock();
- //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL);
- witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), L);
- witnessComplex.nearest_landmarks(point_vector,L,WL);
- end = clock();
- std::cout << "Landmark choice took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- // Write the WL matrix in a file
- mkdir("output", S_IRWXU);
- const size_t last_slash_idx = file_name.find_last_of("/");
- if (std::string::npos != last_slash_idx)
- {
- file_name.erase(0, last_slash_idx + 1);
- }
- std::string out_file = "output/"+file_name+"_"+argv[2]+".wl";
- //write_wl(out_file,WL);
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
-
- out_file = "output/"+file_name+"_"+argv[2]+".stree";
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
-
- out_file = "output/"+file_name+"_"+argv[2]+".badlinks";
- std::ofstream ofs2(out_file, std::ofstream::out);
- witnessComplex.write_bad_links(ofs2);
- ofs2.close();
-}
diff --git a/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp b/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp
deleted file mode 100644
index 614bb945..00000000
--- a/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp
+++ /dev/null
@@ -1,148 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-//#include <boost/filesystem.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-typedef std::vector< std::vector <double> > Point_Vector;
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-
-/**
- * \brief Customized version of read_points
- * which takes into account a possible nbP first line
- *
- */
-inline void
-read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- if (point.size() != 1)
- points.push_back(point);
- }
- in_file.close();
-}
-
-void write_wl( std::string file_name, std::vector< std::vector <int> > & WL)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : WL)
- {
- for (auto l: w)
- ofs << l << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-void read_wl( std::string file_name, std::vector< std::vector <int> > & WL)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- int x;
- while( getline ( in_file , line ) )
- {
- std::vector< int > witness;
- std::istringstream iss( line );
- while(iss >> x) { witness.push_back(x); }
- WL.push_back(witness);
- }
- in_file.close();
-
-}
-
-int main (int argc, char * const argv[])
-{
- if (argc != 2)
- {
- std::cerr << "Usage: " << argv[0]
- << " path_to_point_file \n";
- return 0;
- }
- /*
- boost::filesystem::path p;
-
- for (; argc > 2; --argc, ++argv)
- p /= argv[1];
- */
- std::string file_name = argv[1];
- //int nbL = atoi(argv[2]);
-
- clock_t start, end;
- //Construct the Simplex Tree
- Witness_complex<> witnessComplex;
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- read_points_cust(file_name, point_vector);
- //std::cout << "Successfully read the points\n";
- // witnessComplex.witness_complex_from_points(point_vector);
- std::vector<std::vector< int > > WL;
- read_wl(file_name,WL);
- witnessComplex.setNbL(WL[0].size());
- // Write the WL matrix in a file
- std::string out_file;
- write_wl(out_file,WL);
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- out_file = "output/"+file_name+"_"+argv[2]+".stree";
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
-
-}
diff --git a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp
deleted file mode 100644
index c45bc0c1..00000000
--- a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp
+++ /dev/null
@@ -1,210 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-#include "generators.h"
-#include "output.h"
-//#include <boost/filesystem.hpp>
-
-//#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::FT FT;
-typedef K::Point_d Point_d;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-
-typedef std::vector<Point_d> Point_Vector;
-
-/** Function that chooses landmarks from W and place it in the kd-tree L.
- * Note: nbL hould be removed if the code moves to Witness_complex
- */
-void landmark_choice_to_tree(Point_Vector &W, int nbP, Point_etiquette_map &L_i, int nbL, std::vector< std::vector <int> > &WL)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- std::vector<Point_d> landmarks;
- int chosen_landmark;
- //std::pair<Point_etiquette_map::iterator,bool> res = std::make_pair(L_i.begin(),false);
- Point_d* p;
- srand(24660);
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- chosen_landmark = rand()%nbP;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbL),
- typename Tree::Splitter(),
- STraits((Point_d*)&(landmarks[0])));
- /*}
-
-
-void d_nearest_landmarks(Point_Vector &W, Tree &L, Point_etiquette_map &L_i, std::vector< std::vector <int> > &WL)
-{*/
- std::cout << "Enter (D+1) nearest landmarks\n";
- std::cout << "Size of the tree is " << L.size() << std::endl;
-//int nbP = W.size();
- int D = W[0].size();
- for (int i = 0; i < nbP; i++)
- {
- //std::cout << "Entered witness number " << i << std::endl;
- Point_d& w = W[i];
- //std::cout << "Safely constructed a point\n";
- //Search D+1 nearest neighbours from the tree of landmarks L
- K_neighbor_search search(L, w, D+1, FT(0), true,
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,CGAL::Euclidean_distance<Traits_base>>((Point_d*)&(landmarks[0])) );
- //std::cout << "Safely found nearest landmarks\n";
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- //Point_etiquette_map::iterator itm = L_i.find(it->first);
- //assert(itm != L_i.end());
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- WL[i].push_back(it->first);
- //std::cout << i << " " << it->first << ": " << it->second << std::endl;
- }
- }
-}
-
-int main (int argc, char * const argv[])
-{
- if (argc != 3)
- {
- std::cerr << "Usage: " << argv[0]
- << " path_to_point_file nbL \n";
- return 0;
- }
- /*
- boost::filesystem::path p;
-
- for (; argc > 2; --argc, ++argv)
- p /= argv[1];
- */
- std::string file_name = argv[1];
- int nbL = atoi(argv[2]);
-
- clock_t start, end;
- //Construct the Simplex Tree
- Witness_complex<> witnessComplex;
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- read_points_cust(file_name, point_vector);
- //std::cout << "Successfully read the points\n";
- witnessComplex.setNbL(nbL);
- // witnessComplex.witness_complex_from_points(point_vector);
- int nbP = point_vector.size();
- std::vector<std::vector< int > > WL(nbP);
- //std::set<int> L;
- Tree L;
- Point_etiquette_map L_i;
- start = clock();
- //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL);
- landmark_choice_to_tree(point_vector, nbP, L_i, nbL, WL);
- //d_nearest_landmarks(point_vector, L, L_i, WL);
- end = clock();
- std::cout << "Landmark choice took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- // Write the WL matrix in a file
- mkdir("output", S_IRWXU);
- const size_t last_slash_idx = file_name.find_last_of("/");
- if (std::string::npos != last_slash_idx)
- {
- file_name.erase(0, last_slash_idx + 1);
- }
- std::string out_file = "output/"+file_name+"_"+argv[2]+".wl";
- write_wl(out_file,WL);
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- /*
- char buffer[100];
- int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]);
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- */
-
- out_file = "output/"+file_name+"_"+argv[2]+".stree";
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
-
- out_file = "output/"+file_name+"_"+argv[2]+".badlinks";
- std::ofstream ofs2(out_file, std::ofstream::out);
- //witnessComplex.write_bad_links(ofs2);
- ofs2.close();
-}
diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp
deleted file mode 100644
index f78bcdab..00000000
--- a/src/Witness_complex/example/witness_complex_perturbations.cpp
+++ /dev/null
@@ -1,462 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-#include <set>
-#include <iterator>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-//#include <boost/filesystem.hpp>
-
-//#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Euclidean_distance.h>
-
-#include <CGAL/Kernel_d/Vector_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-#include <CGAL/Fuzzy_sphere.h>
-#include <CGAL/Origin.h>
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::FT FT;
-typedef K::Point_d Point_d;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-typedef CGAL::Kd_tree<STraits> Tree2;
-
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef std::vector<Point_d> Point_Vector;
-
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-//typedef K::Equal_d Equal_d;
-typedef CGAL::Random_points_in_ball_d<Point_d> Random_point_iterator;
-/**
- * \brief Customized version of read_points
- * which takes into account a possible nbP first line
- *
- */
-inline void
-read_points_cust ( std::string file_name , Point_Vector & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- Point_d p(point.begin(), point.end());
- if (point.size() != 1)
- points.push_back(p);
- }
- in_file.close();
-}
-
-/*
-void read_points_to_tree (std::string file_name, Tree& tree)
-{
- //I assume here that tree is empty
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector<double> coords;
- std::istringstream iss( line );
- while(iss >> x) { coords.push_back(x); }
- if (coords.size() != 1)
- {
- Point_d point(coords.begin(), coords.end());
- tree.insert(point);
- }
- }
- in_file.close();
-}
-*/
-
-void write_wl( std::string file_name, std::vector< std::vector <int> > & WL)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : WL)
- {
- for (auto l: w)
- ofs << l << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-void write_points( std::string file_name, std::vector< Point_d > & WL)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : WL)
- {
- for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-void write_edges_gnuplot(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto u: witness_complex.complex_vertex_range())
- for (auto v: witness_complex.complex_vertex_range())
- {
- typeVectorVertex edge = {u,v};
- if (u < v && witness_complex.find(edge) != witness_complex.null_simplex())
- {
- for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n\n\n";
- }
- }
- ofs.close();
-}
-
-
-
-/** Function that chooses landmarks from W and place it in the kd-tree L.
- * Note: nbL hould be removed if the code moves to Witness_complex
- */
-/*
-void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- //std::vector<Point_d> landmarks;
- int chosen_landmark;
- //std::pair<Point_etiquette_map::iterator,bool> res = std::make_pair(L_i.begin(),false);
- Point_d* p;
- srand(24660);
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- chosen_landmark = rand()%nbP;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- landmarks_ind.push_back(chosen_landmark);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- }
-*/
-
-void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- //std::vector<Point_d> landmarks;
- int chosen_landmark = 0;
- //std::pair<Point_etiquette_map::iterator,bool> res = std::make_pair(L_i.begin(),false);
- Point_d* p;
- CGAL::Random rand;
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- do chosen_landmark = rand.uniform_int(0,nbP);
- while (std::find(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark) != landmarks_ind.end());
- //rand++;
- //std::cout << "Chose " << chosen_landmark << std::endl;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- landmarks_ind.push_back(chosen_landmark);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- }
-
-
-int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- //******************** Constructing a WL matrix
- int nbP = W.size();
- int nbL = landmarks.size();
- //Point_Vector landmarks_ = landmarks;
- Euclidean_distance ed;
- //Equal_d ed;
- FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]);
- //FT lambda = 0.1;//Euclidean_distance();
- std::vector< std::vector <int> > WL(nbP);
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbL),
- typename Tree::Splitter(),
- STraits(&(landmarks[0])));
- /*Tree2 L2(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbL),
- typename Tree::Splitter(),
- STraits(&(landmarks[0])));
- */
- std::cout << "Enter (D+1) nearest landmarks\n";
- //std::cout << "Size of the tree is " << L.size() << std::endl;
- int D = W[0].size();
- clock_t start, end;
- start = clock();
- for (int i = 0; i < nbP; i++)
- {
- //std::cout << "Entered witness number " << i << std::endl;
- Point_d& w = W[i];
- //std::cout << "Safely constructed a point\n";
- ////Search D+1 nearest neighbours from the tree of landmarks L
- K_neighbor_search search(L, w, D+1, FT(0), true,
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,CGAL::Euclidean_distance<Traits_base>>(&(landmarks[0])) );
- //std::cout << "Safely found nearest landmarks\n";
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- //Point_etiquette_map::iterator itm = L_i.find(it->first);
- //assert(itm != L_i.end());
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- WL[i].push_back(it->first);
- //std::cout << "ITFIRST " << it->first << std::endl;
- //std::cout << i << " " << it->first << ": " << it->second << std::endl;
- }
- if (i == landmarks_ind[WL[i][0]])
- {
- //std::cout << "'";
- FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]);
- if (dist < lambda)
- lambda = dist;
- }
- //std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
- }
- //std::cout << "\n";
- end = clock();
- std::cout << "WL matrix construction on " << nbL << " landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n";
-
-
- std::string out_file = "wl_result";
- //write_wl(out_file,WL);
-
- //******************** Constructng a witness complex
- std::cout << "Entered witness complex construction\n";
- Witness_complex<> witnessComplex;
- witnessComplex.setNbL(nbL);
- start = clock();
- witnessComplex.witness_complex(WL);
- end = clock();
- std::cout << "Witness complex construction on " << nbL << " landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n";
- //******************** Making a set of bad link landmarks
- std::cout << "Entered bad links\n";
- std::set< int > perturbL;
- int count_badlinks = 0;
- std::vector< int > count_bad(D);
- std::vector< int > count_good(D);
- //std::cout << "Bad links around ";
- for (auto u: witnessComplex.complex_vertex_range())
- if (!witnessComplex.has_good_link(u, count_bad, count_good))
- {
- //std::cout << "Landmark " << u << " start!" << std::endl;
- //perturbL.insert(u);
- count_badlinks++;
- //std::cout << u << " ";
- Point_d& l = landmarks[u];
- Fuzzy_sphere fs(l, sqrt(lambda)*2, 0, STraits(&(landmarks[0])));
- L.search(std::insert_iterator<std::set<int>>(perturbL,perturbL.begin()),fs);
- //L.search(std::inserter(perturbL,perturbL.begin()),fs);
- //L.search(std::ostream_iterator<int>(std::cout,"\n"),fs);
- //std::cout << "PerturbL size is " << perturbL.size() << std::endl;
- }
- for (unsigned int i = 0; i != count_good.size(); i++)
- if (count_good[i] != 0)
- std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl;
- for (unsigned int i = 0; i != count_bad.size(); i++)
- if (count_bad[i] != 0)
- std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl;
- std::cout << "Bad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
- //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl;
- //*********************** Perturb bad link landmarks
-
- for (auto u: perturbL)
- {
- Random_point_iterator rp(D,sqrt(lambda)/4);
- //std::cout << landmarks[u] << std::endl;
-
- std::vector<FT> point;
- for (int i = 0; i < D; i++)
- {
- point.push_back(W[landmarks_ind[u]][i] + (*rp)[i]);
- }
- landmarks[u] = Point_d(point);
- //std::cout << landmarks[u] << std::endl;
- }
-
- //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl;
- std::cout << "lambda=" << lambda << std::endl;
- // Write the WL matrix in a file
-
- /*
- char buffer[100];
- int i = sprintf(buffer,"stree_result.txt");
-
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- */
- //witnessComplex.write_badlinks("badlinks");
- //write_edges_gnuplot("landmarks/edges", witnessComplex, landmarks);
- return count_badlinks;
-}
-
-
-int main (int argc, char * const argv[])
-{
- if (argc != 3)
- {
- std::cerr << "Usage: " << argv[0]
- << " path_to_point_file nbL \n";
- return 0;
- }
- /*
- boost::filesystem::path p;
-
- for (; argc > 2; --argc, ++argv)
- p /= argv[1];
- */
- std::string file_name = argv[1];
- int nbL = atoi(argv[2]);
-
- //clock_t start, end;
- //Construct the Simplex Tree
- //Witness_complex<> witnessComplex;
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- read_points_cust(file_name, point_vector);
- //std::cout << "Successfully read the points\n";
- //witnessComplex.setNbL(nbL);
- // witnessComplex.witness_complex_from_points(point_vector);
- int nbP = point_vector.size();
- //std::vector<std::vector< int > > WL(nbP);
- //std::set<int> L;
- Point_Vector L;
- std::vector<int> chosen_landmarks;
- //Point_etiquette_map L_i;
- //start = clock();
- //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL);
- landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks);
- int bl = 1;
-
- mkdir("landmarks", S_IRWXU);
- const size_t last_slash_idx = file_name.find_last_of("/");
- if (std::string::npos != last_slash_idx)
- {
- file_name.erase(0, last_slash_idx + 1);
- }
- write_points("landmarks/initial_pointset",point_vector);
- //write_points("landmarks/initial_landmarks",L);
- //for (int i = 0; bl != 0; i++)
- for (int i = 0; i < 1; i++)
- {
- std::cout << "========== Start iteration " << i << " ========\n";
- bl = landmark_perturbation(point_vector, L, chosen_landmarks);
- std::ostringstream os(std::ostringstream::ate);;
- os << "landmarks/landmarks0";
- write_points(os.str(),L);
- }
- //end = clock();
-
- /*
- std::cout << "Landmark choice took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- */
-
- /*
- out_file = "output/"+file_name+"_"+argv[2]+".stree";
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
-
- out_file = "output/"+file_name+"_"+argv[2]+".badlinks";
- std::ofstream ofs2(out_file, std::ofstream::out);
- witnessComplex.write_bad_links(ofs2);
- ofs2.close();
- */
-}
diff --git a/src/Witness_complex/example/witness_complex_protected_delaunay.cpp b/src/Witness_complex/example/witness_complex_protected_delaunay.cpp
deleted file mode 100644
index 77a167a5..00000000
--- a/src/Witness_complex/example/witness_complex_protected_delaunay.cpp
+++ /dev/null
@@ -1,604 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-#include <algorithm>
-#include <set>
-#include <iterator>
-#include <chrono>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-#include "Torus_distance.h"
-
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Euclidean_distance.h>
-#include <CGAL/Kernel_d/Sphere_d.h>
-
-#include <CGAL/Kernel_d/Vector_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-#include <CGAL/Fuzzy_sphere.h>
-#include <CGAL/Random.h>
-#include <CGAL/Delaunay_triangulation.h>
-
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::Point_d Point_d;
-//typedef CGAL::Cartesian_d<double> K;
-//typedef CGAL::Point_d<K> Point_d;
-typedef K::FT FT;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-typedef CGAL::Kd_tree<STraits> Tree2;
-
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef std::vector<Point_d> Point_Vector;
-
-//typedef K::Equal_d Equal_d;
-//typedef CGAL::Random_points_in_cube_d<CGAL::Point_d<CGAL::Cartesian_d<FT> > > Random_cube_iterator;
-typedef CGAL::Random_points_in_cube_d<Point_d> Random_cube_iterator;
-typedef CGAL::Random_points_in_ball_d<Point_d> Random_point_iterator;
-
-typedef CGAL::Delaunay_triangulation<K> Delaunay_triangulation;
-typedef Delaunay_triangulation::Facet Facet;
-typedef CGAL::Sphere_d<K> Sphere_d;
-
-bool toric=false;
-
-
-/**
- * \brief Customized version of read_points
- * which takes into account a possible nbP first line
- *
- */
-inline void
-read_points_cust ( std::string file_name , Point_Vector & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open())
- {
- std::cerr << "Unable to open file " << file_name << std::endl;
- return;
- }
- std::string line;
- double x;
- while( getline ( in_file , line ) )
- {
- std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
- Point_d p(point.begin(), point.end());
- if (point.size() != 1)
- points.push_back(p);
- }
- in_file.close();
-}
-
-void generate_points_grid(Point_Vector& W, int width, int D)
-{
- int nb_points = 1;
- for (int i = 0; i < D; ++i)
- nb_points *= width;
- for (int i = 0; i < nb_points; ++i)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(0.01*(cell_i%width));
- cell_i /= width;
- }
- W.push_back(point);
- }
-}
-
-void generate_points_random_box(Point_Vector& W, int nbP, int dim)
-{
- /*
- Random_cube_iterator rp(dim, 1);
- for (int i = 0; i < nbP; i++)
- {
- std::vector<double> point;
- for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it)
- point.push_back(*it);
- W.push_back(Point_d(point));
- rp++;
- }
- */
- Random_cube_iterator rp(dim, 1.0);
- for (int i = 0; i < nbP; i++)
- {
- W.push_back(*rp++);
- }
-}
-
-
-void write_wl( std::string file_name, std::vector< std::vector <int> > & WL)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : WL)
- {
- for (auto l: w)
- ofs << l << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-
-void write_points( std::string file_name, std::vector< Point_d > & points)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto w : points)
- {
- for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- }
- ofs.close();
-}
-
-void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks)
-{
- std::ofstream ofs (file_name, std::ofstream::out);
- for (auto u: witness_complex.complex_vertex_range())
- for (auto v: witness_complex.complex_vertex_range())
- {
- typeVectorVertex edge = {u,v};
- if (u < v && witness_complex.find(edge) != witness_complex.null_simplex())
- {
- for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n";
- for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it)
- ofs << *it << " ";
- ofs << "\n\n\n";
- }
- }
- ofs.close();
-}
-
-
-/** Function that chooses landmarks from W and place it in the kd-tree L.
- * Note: nbL hould be removed if the code moves to Witness_complex
- */
-void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- int chosen_landmark;
- Point_d* p;
- CGAL::Random rand;
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- do chosen_landmark = rand.get_int(0,nbP);
- while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0);
- //rand++;
- //std::cout << "Chose " << chosen_landmark << std::endl;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- landmarks_ind.push_back(chosen_landmark);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- }
-
-void insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector<int>& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count)
-{
- int D = W[0].size();
- int nb_cells = pow(3, D);
- for (int i = 0; i < nb_cells; ++i)
- {
- std::vector<FT> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[chosen_landmark][l] + 2.0*(cell_i%3-1));
- cell_i /= 3;
- }
- delaunay.insert(point);
- }
- landmarks_ind.push_back(chosen_landmark);
- landmark_count++;
-}
-
-
-
-
-////////////////////////////////////////////////////////////////////////
-// OLD CODE VVVVVVVV
-////////////////////////////////////////////////////////////////////////
-
-
-/*
-bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta)
-{
- Euclidean_distance ed;
- Delaunay_triangulation::Vertex_handle v;
- Delaunay_triangulation::Face f(t.current_dimension());
- Delaunay_triangulation::Facet ft;
- Delaunay_triangulation::Full_cell_handle c;
- Delaunay_triangulation::Locate_type lt;
- c = t.locate(p, lt, f, ft, v);
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- if (!t.is_infinite(fc_it))
- {
- std::vector<Point_d> vertices;
- for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it)
- vertices.push_back((*v_it)->point());
- Sphere_d cs(D, vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point()));
- FT dist2 = ed.transformed_distance(center_cs, p);
- //if the new point is inside the protection ball of a non conflicting simplex
- if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta))
- return true;
- }
- return false;
-}
-
-bool triangulation_is_protected(Delaunay_triangulation& t, FT delta)
-{
- Euclidean_distance ed;
- int D = t.current_dimension();
- for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it)
- if (!t.is_infinite(fc_it))
- for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it)
- {
- //check if vertex belongs to the face
- bool belongs = false;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- if (v_it == *fc_v_it)
- {
- belongs = true;
- break;
- }
- if (!belongs)
- {
- std::vector<Point_d> vertices;
- for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it)
- vertices.push_back((*fc_v_it)->point());
- Sphere_d cs(D, vertices.begin(), vertices.end());
- Point_d center_cs = cs.center();
- FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point()));
- FT dist2 = ed.transformed_distance(center_cs, v_it->point());
- //if the new point is inside the protection ball of a non conflicting simplex
- if (dist2 <= (r+delta)*(r+delta))
- return false;
- }
- }
- return true;
-}
-
-void fill_landmark_copies(Point_Vector& W, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- int D = W[0].size();
- int nb_cells = pow(3, D);
- int nbL = landmarks_ind.size();
- // Fill landmarks
- for (int i = 0; i < nb_cells-1; ++i)
- for (int j = 0; j < nbL; ++j)
- {
- int cell_i = i;
- Point_d point;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(W[landmarks_ind[j]][l] + 2.0*(cell_i-1));
- cell_i /= 3;
- }
- landmarks.push_back(point);
- }
-}
-
-void landmark_choice_by_delaunay(Point_Vector& W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind, FT delta)
-{
- int D = W[0].size();
- Delaunay_triangulation t(D);
- CGAL::Random rand;
- int chosen_landmark;
- int landmark_count = 0;
- for (int i = 0; i <= D+1; ++i)
- {
- do chosen_landmark = rand.get_int(0,nbP);
- while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0);
- insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count);
- }
- while (landmark_count < nbL)
- {
- do chosen_landmark = rand.get_int(0,nbP);
- while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0);
- // If no conflicts then insert in every copy of T^3
- if (!is_violating_protection(W[chosen_landmark], t, D, delta))
- insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count);
- }
- fill_landmark_copies(W, landmarks, landmarks_ind);
-}
-
-
-void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector<int>& landmarks_ind, FT delta)
-{
- int D = W[0].size();
- Torus_distance td;
- Euclidean_distance ed;
- Delaunay_triangulation t(D);
- CGAL::Random rand;
- int landmark_count = 0;
- std::list<int> index_list;
- // shuffle the list of indexes (via a vector)
- {
- std::vector<int> temp_vector;
- for (int i = 0; i < nbP; ++i)
- temp_vector.push_back(i);
- unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed));
- for (std::vector<int>::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it)
- index_list.push_front(*it);
- }
- // add the first D+1 vertices to form one non-empty cell
- for (int i = 0; i <= D+1; ++i)
- {
- insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count);
- index_list.pop_front();
- }
- // add other vertices if they don't violate protection
- std::list<int>::iterator list_it = index_list.begin();
- while (list_it != index_list.end())
- if (!is_violating_protection(W[*list_it], t, D, delta))
- {
- // If no conflicts then insert in every copy of T^3
- insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count);
- index_list.erase(list_it);
- list_it = index_list.begin();
- }
- else
- list_it++;
- fill_landmark_copies(W, landmarks, landmarks_ind);
-}
-
-
-int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- //******************** Preface: origin point
- int D = W[0].size();
- std::vector<FT> orig_vector;
- for (int i=0; i<D; i++)
- orig_vector.push_back(0);
- Point_d origin(orig_vector);
-
- //******************** Constructing a WL matrix
- int nbP = W.size();
- Euclidean_distance ed;
- FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]);
- std::vector<Point_d> landmarks_ext;
- int nb_cells = 1;
- for (int i = 0; i < D; ++i)
- nb_cells *= 3;
- for (int i = 0; i < nb_cells; ++i)
- for (int k = 0; k < nbL; ++k)
- {
- std::vector<double> point;
- int cell_i = i;
- for (int l = 0; l < D; ++l)
- {
- point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0));
- cell_i /= 3;
- }
- landmarks_ext.push_back(point);
- }
- write_points("landmarks/initial_landmarks",landmarks_ext);
- STraits traits(&(landmarks_ext[0]));
- std::vector< std::vector <int> > WL(nbP);
-
- //********************** Neighbor search in a Kd tree
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nb_cells*nbL),
- typename Tree::Splitter(),
- traits);
- std::cout << "Enter (D+1) nearest landmarks\n";
- for (int i = 0; i < nbP; i++)
- {
- Point_d& w = W[i];
- ////Search D+1 nearest neighbours from the tree of landmarks L
- K_neighbor_search search(L, w, D+1, FT(0), true,
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks_ext[0])) );
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end())
- WL[i].push_back((it->first)%nbL);
- }
- if (i == landmarks_ind[WL[i][0]])
- {
- FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]);
- if (dist < lambda)
- lambda = dist;
- }
- }
- std::string out_file = "wl_result";
- write_wl(out_file,WL);
-
- //******************** Constructng a witness complex
- std::cout << "Entered witness complex construction\n";
- Witness_complex<> witnessComplex;
- witnessComplex.setNbL(nbL);
- witnessComplex.witness_complex(WL);
-
- //******************** Making a set of bad link landmarks
- std::cout << "Entered bad links\n";
- std::set< int > perturbL;
- int count_badlinks = 0;
- //std::cout << "Bad links around ";
- std::vector< int > count_bad(D);
- std::vector< int > count_good(D);
- for (auto u: witnessComplex.complex_vertex_range())
- {
- if (!witnessComplex.has_good_link(u, count_bad, count_good))
- {
- count_badlinks++;
- Point_d& l = landmarks[u];
- Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits);
- std::vector<int> curr_perturb;
- L.search(std::insert_iterator<std::vector<int>>(curr_perturb,curr_perturb.begin()),fs);
- for (int i: curr_perturb)
- perturbL.insert(i%nbL);
- }
- }
- for (unsigned int i = 0; i != count_good.size(); i++)
- if (count_good[i] != 0)
- std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl;
- for (unsigned int i = 0; i != count_bad.size(); i++)
- if (count_bad[i] != 0)
- std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl;
- std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
-
- //*********************** Perturb bad link landmarks
- for (auto u: perturbL)
- {
- Random_point_iterator rp(D,sqrt(lambda)/8);
- std::vector<FT> point;
- for (int i = 0; i < D; i++)
- {
- while (K().squared_distance_d_object()(*rp,origin) < lambda/256)
- rp++;
- FT coord = landmarks[u][i] + (*rp)[i];
- if (coord > 1)
- point.push_back(coord-1);
- else if (coord < -1)
- point.push_back(coord+1);
- else
- point.push_back(coord);
- }
- landmarks[u] = Point_d(point);
- }
- std::cout << "lambda=" << lambda << std::endl;
- char buffer[100];
- int i = sprintf(buffer,"stree_result.txt");
-
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- write_edges("landmarks/edges", witnessComplex, landmarks);
- return count_badlinks;
-}
-
-
-int main (int argc, char * const argv[])
-{
- if (argc != 5)
- {
- std::cerr << "Usage: " << argv[0]
- << " nbP nbL dim delta\n";
- return 0;
- }
- int nbP = atoi(argv[1]);
- int nbL = atoi(argv[2]);
- int dim = atoi(argv[3]);
- FT delta = atof(argv[4]);
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- generate_points_random_box(point_vector, nbP, dim);
- Point_Vector L;
- std::vector<int> chosen_landmarks;
- bool ok=false;
- while (!ok)
- {
- ok = true;
- L = {};
- chosen_landmarks = {};
- //landmark_choice_by_delaunay(point_vector, nbP, nbL, L, chosen_landmarks, delta);
- landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta);
- nbL = chosen_landmarks.size();
- std::cout << "Number of landmarks is " << nbL << std::endl;
- //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks);
- for (auto i: chosen_landmarks)
- {
- ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1);
- if (!ok) break;
- }
-
- }
- int bl = nbL, curr_min = bl;
- write_points("landmarks/initial_pointset",point_vector);
- //write_points("landmarks/initial_landmarks",L);
- //for (int i = 0; i < 1; i++)
- for (int i = 0; bl > 0; i++)
- {
- std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n";
- bl=landmark_perturbation(point_vector, nbL, L, chosen_landmarks);
- if (bl < curr_min)
- curr_min=bl;
- write_points("landmarks/landmarks0",L);
- }
-
-}
-*/
diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp
deleted file mode 100644
index bf3015fa..00000000
--- a/src/Witness_complex/example/witness_complex_sphere.cpp
+++ /dev/null
@@ -1,457 +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): Siargey Kachanovich
- *
- * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime>
-#include <utility>
-#include <algorithm>
-#include <set>
-#include <iterator>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-//#include <stdlib.h>
-
-//#include "gudhi/graph_simplicial_complex.h"
-#include "gudhi/Witness_complex.h"
-#include "gudhi/reader_utils.h"
-#include "generators.h"
-#include "output.h"
-//#include <boost/filesystem.hpp>
-
-//#include <CGAL/Delaunay_triangulation.h>
-#include <CGAL/Cartesian_d.h>
-#include <CGAL/Search_traits.h>
-#include <CGAL/Search_traits_adapter.h>
-#include <CGAL/property_map.h>
-#include <CGAL/Epick_d.h>
-#include <CGAL/Orthogonal_k_neighbor_search.h>
-#include <CGAL/Kd_tree.h>
-#include <CGAL/Euclidean_distance.h>
-
-#include <CGAL/Kernel_d/Vector_d.h>
-#include <CGAL/point_generators_d.h>
-#include <CGAL/constructions_d.h>
-#include <CGAL/Fuzzy_sphere.h>
-#include <CGAL/Random.h>
-
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/iterator/zip_iterator.hpp>
-#include <boost/iterator/counting_iterator.hpp>
-#include <boost/range/iterator_range.hpp>
-
-using namespace Gudhi;
-//using namespace boost::filesystem;
-
-typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> K;
-typedef K::FT FT;
-typedef K::Point_d Point_d;
-typedef CGAL::Search_traits<
- FT, Point_d,
- typename K::Cartesian_const_iterator_d,
- typename K::Construct_cartesian_const_iterator_d> Traits_base;
-typedef CGAL::Euclidean_distance<Traits_base> Euclidean_distance;
-
-typedef std::vector< Vertex_handle > typeVectorVertex;
-
-//typedef std::pair<typeVectorVertex, Filtration_value> typeSimplex;
-//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool;
-
-typedef CGAL::Search_traits_adapter<
- std::ptrdiff_t, Point_d*, Traits_base> STraits;
-//typedef K TreeTraits;
-//typedef CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance > Euclidean_adapter;
-//typedef CGAL::Kd_tree<STraits> Kd_tree;
-typedef CGAL::Orthogonal_k_neighbor_search<STraits, CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>> K_neighbor_search;
-typedef K_neighbor_search::Tree Tree;
-typedef K_neighbor_search::Distance Distance;
-typedef K_neighbor_search::iterator KNS_iterator;
-typedef K_neighbor_search::iterator KNS_range;
-typedef boost::container::flat_map<int, int> Point_etiquette_map;
-typedef CGAL::Kd_tree<STraits> Tree2;
-
-typedef CGAL::Fuzzy_sphere<STraits> Fuzzy_sphere;
-
-typedef std::vector<Point_d> Point_Vector;
-
-//typedef K::Equal_d Equal_d;
-
-bool toric=false;
-
-std::vector<Point_d> convert_to_torus(std::vector< Point_d>& points)
-{
- std::vector< Point_d > points_torus;
- for (auto p: points)
- {
- FT theta = M_PI*p[0];
- FT phi = M_PI*p[1];
- std::vector<FT> p_torus;
- p_torus.push_back((1+0.2*cos(theta))*cos(phi));
- p_torus.push_back((1+0.2*cos(theta))*sin(phi));
- p_torus.push_back(0.2*sin(theta));
- points_torus.push_back(Point_d(p_torus));
- }
- return points_torus;
-}
-
-/** Function that chooses landmarks from W and place it in the kd-tree L.
- * Note: nbL hould be removed if the code moves to Witness_complex
- */
-void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- std::cout << "Enter landmark choice to kd tree\n";
- //std::vector<Point_d> landmarks;
- int chosen_landmark;
- //std::pair<Point_etiquette_map::iterator,bool> res = std::make_pair(L_i.begin(),false);
- Point_d* p;
- CGAL::Random rand;
- for (int i = 0; i < nbL; i++)
- {
- // while (!res.second)
- // {
- do chosen_landmark = rand.get_int(0,nbP);
- while (std::find(landmarks_ind.begin(), landmarks_ind.end(), chosen_landmark) != landmarks_ind.end());
- //rand++;
- //std::cout << "Chose " << chosen_landmark << std::endl;
- p = &W[chosen_landmark];
- //L_i.emplace(chosen_landmark,i);
- // }
- landmarks.push_back(*p);
- landmarks_ind.push_back(chosen_landmark);
- //std::cout << "Added landmark " << chosen_landmark << std::endl;
- }
- }
-
-/** \brief A test with 600cell, the generalisation of icosaedre in 4d
- */
-void landmark_choice_600cell(Point_Vector&W, int nbP, int nbL, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- assert(W[0].size() == 4); //4-dimensionality required
- FT phi = (1+sqrt(5))/2;
- FT phi_1 = FT(1)/phi;
- std::vector<FT> p;
- // 16 vertices
- for (FT a = -0.5; a < 1; a += 1)
- for (FT b = -0.5; b < 1; b += 1)
- for (FT c = -0.5; c < 1; c += 1)
- for (FT d = -0.5; d < 1; d += 1)
- landmarks.push_back(Point_d(std::vector<FT>({a,b,c,d})));
- // 8 vertices
- for (FT a = -0.5; a < 1; a += 1)
- {
- landmarks.push_back(Point_d(std::vector<FT>({a,0,0,0})));
- landmarks.push_back(Point_d(std::vector<FT>({0,a,0,0})));
- landmarks.push_back(Point_d(std::vector<FT>({0,0,a,0})));
- landmarks.push_back(Point_d(std::vector<FT>({0,0,0,a})));
- }
- // 96 vertices
- for (FT a = -phi/2; a < phi; a += phi)
- for (FT b = -0.5; b < 1; b += 1)
- for (FT c = -phi_1/2; c < phi_1; c += phi_1)
- {
- landmarks.push_back(Point_d(std::vector<FT>({a,b,c,0})));
- landmarks.push_back(Point_d(std::vector<FT>({b,a,0,c})));
- landmarks.push_back(Point_d(std::vector<FT>({c,0,a,b})));
- landmarks.push_back(Point_d(std::vector<FT>({0,c,b,a})));
- landmarks.push_back(Point_d(std::vector<FT>({a,c,0,b})));
- landmarks.push_back(Point_d(std::vector<FT>({a,0,b,c})));
- landmarks.push_back(Point_d(std::vector<FT>({c,b,0,a})));
- landmarks.push_back(Point_d(std::vector<FT>({0,b,a,c})));
- landmarks.push_back(Point_d(std::vector<FT>({b,0,c,a})));
- landmarks.push_back(Point_d(std::vector<FT>({0,a,c,b})));
- landmarks.push_back(Point_d(std::vector<FT>({b,c,a,0})));
- landmarks.push_back(Point_d(std::vector<FT>({c,a,b,0})));
- }
- for (int i = 0; i < 120; ++i)
- landmarks_ind.push_back(i);
-}
-
-int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector<int>& landmarks_ind)
-{
- //********************Preface: origin point
- clock_t start, end;
- int D = W[0].size();
- std::vector<FT> orig_vector;
- for (int i=0; i<D; i++)
- orig_vector.push_back(0);
- Point_d origin(orig_vector);
- //Distance dist;
- //dist.transformed_distance(0,1);
- //******************** Constructing a WL matrix
- int nbP = W.size();
- int nbL = landmarks.size();
- Euclidean_distance ed;
- FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]);
- //std::cout << "Lambda=" << lambda << std::endl;
- //FT lambda = 0.1;//Euclidean_distance();
- STraits traits(&(landmarks[0]));
- std::vector< std::vector <int> > WL(nbP);
- Tree L(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbL),
- typename Tree::Splitter(),
- traits);
- /*Tree2 L2(boost::counting_iterator<std::ptrdiff_t>(0),
- boost::counting_iterator<std::ptrdiff_t>(nbL),
- typename Tree::Splitter(),
- STraits(&(landmarks[0])));
- */
- std::cout << "Enter (D+1) nearest landmarks\n";
- //std::cout << "Size of the tree is " << L.size() << std::endl;
- start = clock();
- for (int i = 0; i < nbP; i++)
- {
- //std::cout << "Entered witness number " << i << std::endl;
- Point_d& w = W[i];
- //std::cout << "Safely constructed a point\n";
- ////Search D+1 nearest neighbours from the tree of landmarks L
- /*
- if (w[0]>0.95)
- std::cout << i << std::endl;
- */
- K_neighbor_search search(L, w, D, FT(0), true,
- //CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks[0])) );
- CGAL::Distance_adapter<std::ptrdiff_t,Point_d*,Euclidean_distance>(&(landmarks[0])) );
- //std::cout << "Safely found nearest landmarks\n";
- for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it)
- {
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- //Point_etiquette_map::iterator itm = L_i.find(it->first);
- //assert(itm != L_i.end());
- //std::cout << "Entered KNN_it with point at distance " << it->second << "\n";
- WL[i].push_back(it->first);
- //std::cout << "ITFIRST " << it->first << std::endl;
- //std::cout << i << " " << it->first << ": " << it->second << std::endl;
- }
- if (i == landmarks_ind[WL[i][0]])
- {
- //std::cout << "'";
- FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]);
- if (dist < lambda)
- lambda = dist;
- }
- }
- //std::cout << "\n";
- end = clock();
- std::cout << "Landmark choice for " << nbL << " landmarks took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- std::string out_file = "wl_result";
- write_wl(out_file,WL);
-
- //******************** Constructng a witness complex
- std::cout << "Entered witness complex construction\n";
- Witness_complex<> witnessComplex;
- witnessComplex.setNbL(nbL);
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- //witnessComplex.witness_complex(WL);
- /*
- if (witnessComplex.is_witness_complex(WL))
- std::cout << "!!YES. IT IS A WITNESS COMPLEX!!\n";
- else
- std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n";
- */
- //******************** Making a set of bad link landmarks
- std::cout << "Entered bad links\n";
- std::set< int > perturbL;
- int count_badlinks = 0;
- //std::cout << "Bad links around ";
- std::vector< int > count_bad(D);
- std::vector< int > count_good(D);
- for (auto u: witnessComplex.complex_vertex_range())
- if (!witnessComplex.has_good_link(u, count_bad, count_good))
- {
- //std::cout << "Landmark " << u << " start!" << std::endl;
- //perturbL.insert(u);
- count_badlinks++;
- //std::cout << u << " ";
- Point_d& l = landmarks[u];
- Fuzzy_sphere fs(l, sqrt(lambda), 0, traits);
- std::vector<int> curr_perturb;
- L.search(std::insert_iterator<std::vector<int>>(curr_perturb,curr_perturb.begin()),fs);
- for (int i: curr_perturb)
- perturbL.insert(i%nbL);
- //L.search(std::inserter(perturbL,perturbL.begin()),fs);
- //L.search(std::ostream_iterator<int>(std::cout,"\n"),fs);
- //std::cout << "PerturbL size is " << perturbL.size() << std::endl;
- }
- for (unsigned int i = 0; i != count_good.size(); i++)
- if (count_good[i] != 0)
- std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl;
- for (unsigned int i = 0; i != count_bad.size(); i++)
- if (count_bad[i] != 0)
- std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl;
- std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl;
- //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl;
- //*********************** Perturb bad link landmarks
-
- for (auto u: perturbL)
- {
- Random_point_iterator rp(D,sqrt(lambda)/8*nbL/count_badlinks);
- //std::cout << landmarks[u] << std::endl;
-
- std::vector<FT> point;
- for (int i = 0; i < D; i++)
- {
- while (K().squared_distance_d_object()(*rp,origin) < lambda/256)
- rp++;
- FT coord = W[landmarks_ind[u]][i] + (*rp)[i];
- //FT coord = landmarks[u][i] + (*rp)[i];
- if (coord > 1)
- point.push_back(coord-1);
- else if (coord < -1)
- point.push_back(coord+1);
- else
- point.push_back(coord);
- }
- landmarks[u] = Point_d(point);
- //std::cout << landmarks[u] << std::endl;
- }
-
- //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl;
- std::cout << "lambda=" << lambda << std::endl;
-
- //std::cout << "WL size" << WL.size() << std::endl;
- /*
- std::cout << "L:" << std::endl;
- for (int i = 0; i < landmarks.size(); i++)
- std::cout << landmarks[i] << std::endl;
- */
-
- char buffer[100];
- int i = sprintf(buffer,"stree_result.txt");
-
- if (i >= 0)
- {
- std::string out_file = (std::string)buffer;
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
- }
- write_edges("landmarks/edges", witnessComplex, landmarks);
- std::cout << Distance().transformed_distance(Point_d(std::vector<double>({0.1,0.1})), Point_d(std::vector<double>({1.9,1.9}))) << std::endl;
- return count_badlinks;
-}
-
-
-int main (int argc, char * const argv[])
-{
-
- if (argc != 4)
- {
- std::cerr << "Usage: " << argv[0]
- << " nbP nbL dim\n";
- return 0;
- }
- /*
- boost::filesystem::path p;
- for (; argc > 2; --argc, ++argv)
- p /= argv[1];
- */
-
- int nbP = atoi(argv[1]);
- int nbL = atoi(argv[2]);
- int dim = atoi(argv[3]);
- //clock_t start, end;
- //Construct the Simplex Tree
- //Witness_complex<> witnessComplex;
-
- std::cout << "Let the carnage begin!\n";
- Point_Vector point_vector;
- //read_points_cust(file_name, point_vector);
- generate_points_sphere(point_vector, nbP, dim);
- /*
- for (auto &p: point_vector)
- {
- assert(std::count(point_vector.begin(),point_vector.end(),p) == 1);
- }
- */
- //std::cout << "Successfully read the points\n";
- //witnessComplex.setNbL(nbL);
- // witnessComplex.witness_complex_from_points(point_vector);
- //int nbP = point_vector.size();
- //std::vector<std::vector< int > > WL(nbP);
- //std::set<int> L;
- Point_Vector L;
- std::vector<int> chosen_landmarks;
- //Point_etiquette_map L_i;
- //start = clock();
- //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL);
- bool ok=false;
- while (!ok)
- {
- ok = true;
- L = {};
- chosen_landmarks = {};
- landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks);
- //landmark_choice_600cell(point_vector, nbP, nbL, L, chosen_landmarks);
- /*
- for (auto i: chosen_landmarks)
- {
- ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1);
- if (!ok) break;
- }
- */
- }
- int bl = nbL, curr_min = bl;
- //write_points("landmarks/initial_pointset",point_vector);
- //write_points("landmarks/initial_landmarks",L);
-
- for (int i = 0; bl > 0; i++)
- //for (int i = 0; i < 1; i++)
- {
- std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n";
- bl=landmark_perturbation(point_vector, L, chosen_landmarks);
- if (bl < curr_min)
- curr_min=bl;
- //write_points("landmarks/landmarks0",L);
- }
- //end = clock();
-
- /*
- std::cout << "Landmark choice took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- start = clock();
- witnessComplex.witness_complex(WL);
- //
- end = clock();
- std::cout << "Howdy world! The process took "
- << (double)(end-start)/CLOCKS_PER_SEC << " s. \n";
- */
-
- /*
- out_file = "output/"+file_name+"_"+argv[2]+".stree";
- std::ofstream ofs (out_file, std::ofstream::out);
- witnessComplex.st_to_file(ofs);
- ofs.close();
-
- out_file = "output/"+file_name+"_"+argv[2]+".badlinks";
- std::ofstream ofs2(out_file, std::ofstream::out);
- witnessComplex.write_bad_links(ofs2);
- ofs2.close();
- */
-}
diff --git a/src/cmake/modules/FindEigen3.cmake b/src/cmake/modules/FindEigen3.cmake
new file mode 100644
index 00000000..70c07dfb
--- /dev/null
+++ b/src/cmake/modules/FindEigen3.cmake
@@ -0,0 +1,86 @@
+# - Try to find Eigen3 lib
+#
+# This module supports requiring a minimum version, e.g. you can do
+# find_package(Eigen3 3.1.2)
+# to require version 3.1.2 or newer of Eigen3.
+#
+# Once done this will define
+#
+# EIGEN3_FOUND - system has eigen lib with correct version
+# EIGEN3_INCLUDE_DIR - the eigen include directory
+# EIGEN3_VERSION - eigen version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
+# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
+
+include(FindPackageHandleStandardArgs)
+
+if(NOT Eigen3_FIND_VERSION)
+ if(NOT Eigen3_FIND_VERSION_MAJOR)
+ set(Eigen3_FIND_VERSION_MAJOR 2)
+ endif(NOT Eigen3_FIND_VERSION_MAJOR)
+ if(NOT Eigen3_FIND_VERSION_MINOR)
+ set(Eigen3_FIND_VERSION_MINOR 91)
+ endif(NOT Eigen3_FIND_VERSION_MINOR)
+ if(NOT Eigen3_FIND_VERSION_PATCH)
+ set(Eigen3_FIND_VERSION_PATCH 0)
+ endif(NOT Eigen3_FIND_VERSION_PATCH)
+
+ set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
+endif(NOT Eigen3_FIND_VERSION)
+
+macro(_eigen3_get_version)
+ file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
+
+ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
+ set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
+ set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
+ set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
+
+ set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
+endmacro(_eigen3_get_version)
+
+set(EIGEN3_USE_FILE "UseEigen3")
+
+if (EIGEN3_INCLUDE_DIR)
+
+ if (EXISTS ${EIGEN3_INCLUDE_DIR}/signature_of_eigen3_matrix_library)
+ # in cache already and valid
+ _eigen3_get_version()
+ set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
+
+ find_package_handle_standard_args(Eigen3
+ REQUIRED_VARS EIGEN3_INCLUDE_DIR
+ VERSION_VAR EIGEN3_VERSION)
+
+ else()
+ message(STATUS "Eigen3 path specified in cmake variable EIGEN3_INCLUDE_DIR is "
+ "set to ${EIGEN3_INCLUDE_DIR}, but that path does not contains the file "
+ "signature_of_eigen3_matrix_library and is considered as invalid.")
+ endif()
+
+
+
+else (EIGEN3_INCLUDE_DIR)
+
+ find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
+ HINTS ENV EIGEN3_INC_DIR
+ ENV EIGEN3_DIR
+ PATHS ${KDE4_INCLUDE_DIR}
+ PATH_SUFFIXES include eigen3 eigen
+ DOC "Directory containing the Eigen3 header files"
+ )
+
+ if(EIGEN3_INCLUDE_DIR)
+ _eigen3_get_version()
+ endif(EIGEN3_INCLUDE_DIR)
+
+ find_package_handle_standard_args(Eigen3
+ REQUIRED_VARS EIGEN3_INCLUDE_DIR
+ VERSION_VAR EIGEN3_VERSION)
+
+endif(EIGEN3_INCLUDE_DIR)
diff --git a/src/cmake/modules/UseEigen3.cmake b/src/cmake/modules/UseEigen3.cmake
new file mode 100644
index 00000000..e3ed18be
--- /dev/null
+++ b/src/cmake/modules/UseEigen3.cmake
@@ -0,0 +1,9 @@
+# This module setups the compiler for using Eigen v3 library.
+# It assumes that find_package(Eigen3) was already called.
+
+
+include_directories( SYSTEM ${EIGEN3_INCLUDE_DIR} )
+
+add_definitions(-DCGAL_EIGEN3_ENABLED)
+
+set (EIGEN3_SETUP TRUE)
diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h
index 315aa0ac..41b8ba1e 100644
--- a/src/common/doc/main_page.h
+++ b/src/common/doc/main_page.h
@@ -1,72 +1,115 @@
-/**
-\mainpage
-
-\image html "Gudhi_banner.jpg" "" width=20cm
-
-The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ library for
-topological analysis of high-dimensional data whose goal is to provide robust, efficient, flexible and easy to use
-implementations of
-state-of-the-art algorithms and data structures for computational topology.
-This library is part of the <a href="https://project.inria.fr/gudhi/">Gudhi project</a>.
-
-The current release of the library allows to use several data-structures for simplicial complexes :
-simplex tree, Hasse diagram or skeleton-blocker. Several operations can then be done on top of these
-representations such as persistent homology computation or simplification.
-All data-structures are generic and several of their aspects (such as stored elements, policies)
-can be parameterized via template classes.
-We refer to
-\cite gudhilibrary_ICMS14
-for a detailed description of the design of the library.
-
-\section installation Gudhi installation
-
-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 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 2013.
-
-
-\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 examples require the <a href="http://gmplib.org/">GNU Multiple Precision Arithmetic Library</a> (GMP)
-and will not be built if GMP is not installed:
- - Persistent_cohomology/rips_multifield_persistence
- - Simplex_tree/simplex_tree_from_alpha_shapes_3
-
-Having GMP version 4.2 or higher installed is recommended.
-
-\subsection cgal CGAL:
-CGAL is a C++ library which provides easy access to efficient and reliable geometric algorithms.
-
-The following example requires the <a href="http://www.cgal.org/">Computational Geometry Algorithms Library</a> (CGAL)
-and will not be built if CGAL is not installed:
- - Simplex_tree/simplex_tree_from_alpha_shapes_3
-
-Having CGAL version 4.4 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
-
-\subsection demos Demos and examples
-
-To build the demos and libraries, run the following commands in a terminal:
+/*! \mainpage
+ * \image html "Gudhi_banner.jpg" "" width=20cm
+ *
+ * \section Introduction Introduction
+ * The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic open source C++ library for
+ * Computational Topology and Topological Data Analysis
+ * (<a class="el" target="_blank" href="https://en.wikipedia.org/wiki/Topological_data_analysis">TDA</a>).
+ * The GUDHI library is developed as part of the
+ * <a class="el" target="_blank" href="https://project.inria.fr/gudhi/">GUDHI project</a> supported by the European
+ * Research Council. The GUDHI library intends to help the development of new algorithmic solutions in TDA and their
+ * transfer to applications. It provides robust, efficient, flexible and easy to use implementations of
+ * state-of-the-art algorithms and data structures.
+ *
+ * The current release of the GUDHI library includes:
+ *
+ * \li Data structures to represent, construct and manipulate simplicial complexes.
+ * \li Algorithms to compute persistent homology and multi-field persistent homology.
+ * \li Simplication of simplicial complexes by edge contraction.
+ *
+ * All data-structures are generic and several of their aspects can be parameterized via template classes.
+ * We refer to \cite gudhilibrary_ICMS14 for a detailed description of the design of the library.
+ *
+ * The library is available <a class="el" target="_blank" href="https://gforge.inria.fr/frs/?group_id=3865">here</a>
+ * and the documentation is available at this <a class="el" href="http://gudhi.gforge.inria.fr/doc/latest/">
+ * webpage</a>.
+ *
+ * The library comes with data sets, \ref demos and \ref testsuites.
+ *
+ * Gudhi is also accessible though the
+ * <a class="el" target="_blank" href="https://cran.r-project.org/web/packages/TDA/index.html">R package TDA</a>
+ * (Statistical Tools for Topological Data Analysis).
+ *
+ * The development of the GUDHI library is steered by an Editorial Board composed of:
+ *
+ * \li <a class="el" target="_blank" href="http://www-sop.inria.fr/members/Jean-Daniel.Boissonnat/">
+ * Jean-Daniel Boissonnat</a> | INRIA Sophia Antipolis - Méditerranée
+ * \li <a class="el" target="_blank" href="http://geometrica.saclay.inria.fr/team/Marc.Glisse/">Marc Glisse</a> | INRIA Saclay - Ile de France
+ * \li Clément Jamin | INRIA Sophia Antipolis - Méditerranée
+ * \li Vincent Rouvreau | INRIA Saclay - Ile de France
+ *
+*/
-\verbatim
-cd /path-to-gudhi/
+/*! \page installation Gudhi installation
+ * 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 2013.
+ *
+ * \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 Persistent_cohomology/rips_multifield_persistence
+ *
+ * Having GMP version 4.2 or higher installed is recommended.
+ *
+ * \subsection cgal CGAL:
+ * CGAL is a C++ library which provides easy access to efficient and reliable geometric algorithms.
+ *
+ * The following examples require the <a target="_blank" href="http://www.cgal.org/">Computational Geometry Algorithms
+ * Library</a> (CGAL) and will not be built if CGAL is not installed:
+ * \li GudhUI
+ * \li Persistent_cohomology/alpha_shapes_persistence
+ * \li Simplex_tree/simplex_tree_from_alpha_shapes_3
+ *
+ * Having CGAL version 4.4 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
+ *
+ * \subsection demos Demos and examples
+ * To build the demos and libraries, run the following commands in a terminal:
+\verbatim cd /path-to-gudhi/
mkdir build
cd build/
cmake ..
-make
-\endverbatim
-
-\details
+make \endverbatim
+ *
+ * \subsection testsuites Test suites
+ * To test your build, run the following command in a terminal:
+ * \verbatim make test \endverbatim
+ *
+ * \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.
+ *
+*/
-\copyright GNU General Public License v3.
-\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
+/*! \page Upcoming Upcoming
+ *
+ * The library is under active development. New packages to be released next include:
+ * \li Alpha complex.
+ * \li Bottleneck distance.
+ * \li Zig zag persistence.
+ * \li Witness complex.
+ * \li Tangential complex.
+ * \li Clustering.
+*/
+/*! \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/include/gudhi/Clock.h b/src/common/include/gudhi/Clock.h
index 08096c05..04c6ffb9 100644
--- a/src/common/include/gudhi/Clock.h
+++ b/src/common/include/gudhi/Clock.h
@@ -1,82 +1,79 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_CLOCK_H_
-#define GUDHI_CLOCK_H_
-
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 CLOCK_H_
+#define CLOCK_H_
#include <boost/date_time/posix_time/posix_time.hpp>
-class Clock{
-
-public:
- Clock():end_called(false){
- startTime = boost::posix_time::microsec_clock::local_time( );
- }
-
- Clock(const std::string& msg_){
- end_called = false;
- begin();
- msg = msg_;
- }
-
-
- void begin() const{
- end_called = false;
- startTime = boost::posix_time::microsec_clock::local_time( );
- }
-
- void end() const{
- end_called = true;
- endTime = boost::posix_time::microsec_clock::local_time( );
- }
-
- void print() const{
- std::cout << *this << std::endl;
- }
-
- friend std::ostream& operator<< (std::ostream& stream,const Clock& clock){
- if(!clock.end_called)
- clock.end();
-
- if(!clock.end_called) stream << "end not called";
- else{
- stream << clock.msg <<":"<<clock.num_seconds() <<"s";
- }
- return stream;
-
- }
-
- double num_seconds() const{
- if(!end_called) return -1;
- return (endTime-startTime).total_milliseconds()/1000.;
- }
-
-private:
- mutable boost::posix_time::ptime startTime, endTime;
- mutable bool end_called;
- std::string msg;
-
+#include <string>
+
+class Clock {
+ public:
+ Clock() : end_called(false) {
+ startTime = boost::posix_time::microsec_clock::local_time();
+ }
+
+ Clock(const std::string& msg_) {
+ end_called = false;
+ begin();
+ msg = msg_;
+ }
+
+ void begin() const {
+ end_called = false;
+ startTime = boost::posix_time::microsec_clock::local_time();
+ }
+
+ void end() const {
+ end_called = true;
+ endTime = boost::posix_time::microsec_clock::local_time();
+ }
+
+ void print() const {
+ std::cout << *this << std::endl;
+ }
+
+ friend std::ostream& operator<<(std::ostream& stream, const Clock& clock) {
+ if (!clock.end_called)
+ clock.end();
+
+ if (!clock.end_called) {
+ stream << "end not called";
+ } else {
+ stream << clock.msg << ":" << clock.num_seconds() << "s";
+ }
+ return stream;
+ }
+
+ double num_seconds() const {
+ if (!end_called) return -1;
+ return (endTime - startTime).total_milliseconds() / 1000.;
+ }
+
+ private:
+ mutable boost::posix_time::ptime startTime, endTime;
+ mutable bool end_called;
+ std::string msg;
};
-
-#endif /* GUDHI_CLOCK_H_ */
+#endif // CLOCK_H_
diff --git a/src/common/include/gudhi/Off_reader.h b/src/common/include/gudhi/Off_reader.h
index e29218d8..81b9e634 100644
--- a/src/common/include/gudhi/Off_reader.h
+++ b/src/common/include/gudhi/Off_reader.h
@@ -1,13 +1,10 @@
-/*
- * Off_reader.h
- * Created on: Nov 28, 2014
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -25,14 +22,15 @@
*/
-#ifndef GUDHI_OFF_READER_H_
-#define GUDHI_OFF_READER_H_
+#ifndef OFF_READER_H_
+#define OFF_READER_H_
#include <sstream>
#include <iostream>
#include <iterator>
-
+#include <string>
+#include <vector>
namespace Gudhi {
@@ -48,151 +46,144 @@ namespace Gudhi {
*
* The number of edges num_edges is optional and can be left to zero.
*/
-class Off_reader{
-public:
- Off_reader(std::ifstream& stream):stream_(stream){
- }
-// Off_reader(const std::string& name):stream_(name){
-// if(!stream_.is_open())
-// std::cerr <<"could not open file \n";
-// }
-
- ~Off_reader(){
- stream_.close();
- }
-
- /**
- * read an off file and calls the following methods :
- * void init(int dim,int num_vertices,int num_faces,int num_edges); //num_edges may not be set
- * void point(const std::vector<double>& point);
- * void maximal_face(const std::list<int>& face);
- * void done();
- * of the visitor when reading a point or a maximal face.
- */
- template<typename OffVisitor>
- bool read(OffVisitor& off_visitor){
- bool success_read_off_preambule = read_off_preambule(off_visitor);
- if(!success_read_off_preambule) {
- std::cerr <<"could not read off preambule\n";
- return false;
- }
-
- bool success_read_off_points = read_off_points(off_visitor);
- if(!success_read_off_points) {
- std::cerr <<"could not read off points\n";
- return false;
- }
-
- bool success_read_off_faces = read_off_faces(off_visitor);
- if(!success_read_off_faces) {
- std::cerr <<"could not read off faces\n";
- return false;
- }
-
- off_visitor.done();
- return success_read_off_preambule && success_read_off_points && success_read_off_faces;
- }
-
-private:
- std::ifstream& stream_;
-
- struct Off_info{
- int dim;
- int num_vertices;
- int num_edges;
- int num_faces;
- };
-
- Off_info off_info_;
-
- template<typename OffVisitor>
- bool read_off_preambule(OffVisitor& off_visitor){
- std::string line;
- if(!goto_next_uncomment_line(line)) return false;
-
- bool is_off_file = (line.find("OFF") != std::string::npos);
- bool is_noff_file = (line.find("nOFF") != std::string::npos);
-
- if(!is_off_file && !is_noff_file) {
- std::cerr << line<<std::endl;
- std::cerr << "missing off header\n";
- return false;
- }
-
- if(!goto_next_uncomment_line(line)) return false;
- std::istringstream iss(line);
- if(is_off_file){
- off_info_.dim = 3;
- if(!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)){
- std::cerr << "incorrect number of vertices/faces/edges\n";
- return false;
- }
- }
- else
- if(!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)){
- std::cerr << "incorrect number of vertices/faces/edges\n";
- return false;
- }
- off_visitor.init(off_info_.dim,off_info_.num_vertices,off_info_.num_faces,off_info_.num_edges);
-
- return true;
- }
-
- bool goto_next_uncomment_line(std::string& uncomment_line){
- uncomment_line.clear();
- do
- std::getline(stream_, uncomment_line);
- while(uncomment_line[0] == '%');// || uncomment_line.empty());
- return (uncomment_line.size()>0 && uncomment_line[0] != '%');
- }
-
-
- template<typename OffVisitor>
- bool read_off_points(OffVisitor& visitor){
- int num_vertices_to_read = off_info_.num_vertices;
- while(num_vertices_to_read--){
- std::string line;
- if(!goto_next_uncomment_line(line)) return false;
- std::vector<double> point;
- std::istringstream iss(line);
- point.assign(std::istream_iterator<double>(iss),std::istream_iterator<double>());
-// if(point.size() != off_info_.dim) return false;
- visitor.point(point);
- }
- return true;
- }
-
- template<typename OffVisitor>
- bool read_off_faces(OffVisitor& visitor){
- std::string line;
- while(goto_next_uncomment_line(line)){
- std::istringstream iss(line);
- int num_face_vertices;
- iss >> num_face_vertices;
- std::vector<int> face;
- face.assign(std::istream_iterator<int>(iss),std::istream_iterator<int>());
- if(!face.size() == off_info_.num_vertices) return false;
- visitor.maximal_face(face);
- }
- return true;
- }
+class Off_reader {
+ public:
+ Off_reader(std::ifstream& stream) : stream_(stream) { }
+ // Off_reader(const std::string& name):stream_(name){
+ // if(!stream_.is_open())
+ // std::cerr <<"could not open file \n";
+ // }
+
+ ~Off_reader() {
+ stream_.close();
+ }
+
+ /**
+ * read an off file and calls the following methods :
+ * void init(int dim,int num_vertices,int num_faces,int num_edges); //num_edges may not be set
+ * void point(const std::vector<double>& point);
+ * void maximal_face(const std::list<int>& face);
+ * void done();
+ * of the visitor when reading a point or a maximal face.
+ */
+ template<typename OffVisitor>
+ bool read(OffVisitor& off_visitor) {
+ bool success_read_off_preambule = read_off_preambule(off_visitor);
+ if (!success_read_off_preambule) {
+ std::cerr << "could not read off preambule\n";
+ return false;
+ }
+
+ bool success_read_off_points = read_off_points(off_visitor);
+ if (!success_read_off_points) {
+ std::cerr << "could not read off points\n";
+ return false;
+ }
+
+ bool success_read_off_faces = read_off_faces(off_visitor);
+ if (!success_read_off_faces) {
+ std::cerr << "could not read off faces\n";
+ return false;
+ }
+
+ off_visitor.done();
+ return success_read_off_preambule && success_read_off_points && success_read_off_faces;
+ }
+
+ private:
+ std::ifstream& stream_;
+
+ struct Off_info {
+ int dim;
+ int num_vertices;
+ int num_edges;
+ int num_faces;
+ };
+
+ Off_info off_info_;
+
+ template<typename OffVisitor>
+ bool read_off_preambule(OffVisitor& off_visitor) {
+ std::string line;
+ if (!goto_next_uncomment_line(line)) return false;
+
+ bool is_off_file = (line.find("OFF") != std::string::npos);
+ bool is_noff_file = (line.find("nOFF") != std::string::npos);
+
+ if (!is_off_file && !is_noff_file) {
+ std::cerr << line << std::endl;
+ std::cerr << "missing off header\n";
+ return false;
+ }
+
+ if (!goto_next_uncomment_line(line)) return false;
+ std::istringstream iss(line);
+ if (is_off_file) {
+ off_info_.dim = 3;
+ if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
+ std::cerr << "incorrect number of vertices/faces/edges\n";
+ return false;
+ }
+ } else {
+ if (!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
+ std::cerr << "incorrect number of vertices/faces/edges\n";
+ return false;
+ }
+ }
+ off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges);
+
+ return true;
+ }
+
+ bool goto_next_uncomment_line(std::string& uncomment_line) {
+ uncomment_line.clear();
+ do
+ std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%'); // || uncomment_line.empty());
+ return (uncomment_line.size() > 0 && uncomment_line[0] != '%');
+ }
+
+ template<typename OffVisitor>
+ bool read_off_points(OffVisitor& visitor) {
+ int num_vertices_to_read = off_info_.num_vertices;
+ while (num_vertices_to_read--) {
+ std::string line;
+ if (!goto_next_uncomment_line(line)) return false;
+ std::vector<double> point;
+ std::istringstream iss(line);
+ point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
+ // if(point.size() != off_info_.dim) return false;
+ visitor.point(point);
+ }
+ return true;
+ }
+
+ template<typename OffVisitor>
+ bool read_off_faces(OffVisitor& visitor) {
+ std::string line;
+ while (goto_next_uncomment_line(line)) {
+ std::istringstream iss(line);
+ int num_face_vertices;
+ iss >> num_face_vertices;
+ std::vector<int> face;
+ face.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>());
+ if (face.size() != off_info_.dim) return false;
+ visitor.maximal_face(face);
+ }
+ return true;
+ }
};
-
template<typename OFFVisitor>
-void read_off(const std::string& name_file_off,OFFVisitor& vis){
- std::ifstream stream(name_file_off);
- if(!stream.is_open())
- std::cerr <<"could not open file \n";
- else{
- Off_reader off_reader(stream);
- off_reader.read(vis);
- }
+void read_off(const std::string& name_file_off, OFFVisitor& vis) {
+ std::ifstream stream(name_file_off);
+ if (!stream.is_open()) {
+ std::cerr << "could not open file \n";
+ } else {
+ Off_reader off_reader(stream);
+ off_reader.read(vis);
+ }
}
-
-
} // namespace Gudhi
-
-#endif /* GUDHI_OFF_READER_H_ */
+#endif // OFF_READER_H_
diff --git a/src/common/include/gudhi/Point.h b/src/common/include/gudhi/Point.h
index 4023445b..0479e71e 100644
--- a/src/common/include/gudhi/Point.h
+++ b/src/common/include/gudhi/Point.h
@@ -1,13 +1,10 @@
-/*
- * Basic_geometry.h
- * Created on: Feb 10, 2015
- * This file is part of the Gudhi Library. The Gudhi library
+/* 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): David Salinas
*
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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
@@ -24,9 +21,8 @@
*
*/
-
-#ifndef BASIC_GEOMETRY_H_
-#define BASIC_GEOMETRY_H_
+#ifndef POINT_H_
+#define POINT_H_
#include <cmath>
#include <vector>
@@ -34,143 +30,141 @@
#include <cstddef>
#include <initializer_list>
-class Point_d{
-public:
- Point_d(size_t dim=3):coords_(dim,0){}
- Point_d(const Point_d& other):coords_(other.coords_){}
- Point_d(const std::initializer_list<double>& list):coords_(list) {
- }
- template<typename CoordsIt>
- Point_d(CoordsIt begin,CoordsIt end):coords_(begin,end){}
-
- size_t dimension() const{
- return coords_.size();
- }
-
- double x() const{
- return coords_[0];
- }
-
- double y() const{
- return coords_[1];
- }
-
- double z() const{
- return coords_[2];
- }
-
- double& x(){
- return coords_[0];
- }
-
- double& y(){
- return coords_[1];
- }
-
- double& z(){
- return coords_[2];
- }
-
- std::vector<double>::const_iterator begin() const{
- return coords_.begin();
- }
-
- std::vector<double>::const_iterator end() const{
- return coords_.end();
- }
-
- double& operator[](unsigned i){
- return coords_[i];
- }
- const double& operator[](unsigned i) const{
- return coords_[i];
- }
-
- double squared_norm() const{
- double res = 0;
- for(auto x : coords_)
- res+= x*x;
- return res;
- }
-
- friend double squared_dist(const Point_d& p1,const Point_d& p2){
- assert(p1.dimension()==p2.dimension());
- double res = 0;
- for(unsigned i = 0; i < p1.coords_.size(); ++i)
- res+= (p1[i]-p2[i])*(p1[i]-p2[i]);
- return res;
- }
-
- /**
- * dot product
- */
- double operator*(const Point_d& other) const{
- assert(dimension()==other.dimension());
- double res = 0;
- for(unsigned i = 0; i < coords_.size(); ++i)
- res+= coords_[i]*other[i];
- return res;
- }
-
- /**
- * only if points have dimension 3
- */
- Point_d cross_product(const Point_d& other){
- assert(dimension()==3 && other.dimension()==3);
- Point_d res(3);
- res[0] = (*this)[1] * other[2] - (*this)[2] * other[1];
- res[1] = (*this)[2] * other[0] - (*this)[0] * other[2];
- res[2] = (*this)[0] * other[1] - (*this)[1] * other[0];
- return res;
- }
-
- Point_d operator+(const Point_d& other) const{
- assert(dimension()==other.dimension());
- Point_d res(dimension());
- for(unsigned i = 0; i < coords_.size(); ++i)
- res[i] = (*this)[i] + other[i];
- return res;
- }
-
- Point_d operator*(double lambda) const{
- Point_d res(dimension());
- for(unsigned i = 0; i < coords_.size(); ++i)
- res[i] = (*this)[i] * lambda;
- return res;
- }
-
- Point_d operator/(double lambda) const{
- Point_d res(dimension());
- for(unsigned i = 0; i < coords_.size(); ++i)
- res[i] = (*this)[i] / lambda;
- return res;
- }
-
- Point_d operator-(const Point_d& other) const{
- assert(dimension()==other.dimension());
- Point_d res(dimension());
- for(unsigned i = 0; i < coords_.size(); ++i)
- res[i] = (*this)[i] - other[i];
- return res;
- }
-
- friend Point_d unit_normal(const Point_d& p1,const Point_d& p2,const Point_d& p3){
- assert(p1.dimension()==3);
- assert(p2.dimension()==3);
- assert(p3.dimension()==3);
- Point_d p1p2 = p2 - p1;
- Point_d p1p3 = p3 - p1;
- Point_d res(p1p2.cross_product(p1p3));
- return res / std::sqrt(res.squared_norm());
- }
-
-
-private:
- std::vector<double> coords_;
+class Point_d {
+ public:
+ Point_d(size_t dim = 3) : coords_(dim, 0) { }
+
+ Point_d(const Point_d& other) : coords_(other.coords_) { }
+
+ Point_d(const std::initializer_list<double>& list) : coords_(list) { }
+
+ template<typename CoordsIt>
+ Point_d(CoordsIt begin, CoordsIt end) : coords_(begin, end) { }
+
+ size_t dimension() const {
+ return coords_.size();
+ }
+
+ double x() const {
+ return coords_[0];
+ }
+
+ double y() const {
+ return coords_[1];
+ }
+
+ double z() const {
+ return coords_[2];
+ }
+
+ double& x() {
+ return coords_[0];
+ }
+
+ double& y() {
+ return coords_[1];
+ }
+
+ double& z() {
+ return coords_[2];
+ }
+
+ std::vector<double>::const_iterator begin() const {
+ return coords_.begin();
+ }
+
+ std::vector<double>::const_iterator end() const {
+ return coords_.end();
+ }
+
+ double& operator[](unsigned i) {
+ return coords_[i];
+ }
+
+ const double& operator[](unsigned i) const {
+ return coords_[i];
+ }
+
+ double squared_norm() const {
+ double res = 0;
+ for (auto x : coords_)
+ res += x * x;
+ return res;
+ }
+
+ friend double squared_dist(const Point_d& p1, const Point_d& p2) {
+ assert(p1.dimension() == p2.dimension());
+ double res = 0;
+ for (unsigned i = 0; i < p1.coords_.size(); ++i)
+ res += (p1[i] - p2[i])*(p1[i] - p2[i]);
+ return res;
+ }
+
+ /**
+ * dot product
+ */
+ double operator*(const Point_d& other) const {
+ assert(dimension() == other.dimension());
+ double res = 0;
+ for (unsigned i = 0; i < coords_.size(); ++i)
+ res += coords_[i] * other[i];
+ return res;
+ }
+
+ /**
+ * only if points have dimension 3
+ */
+ Point_d cross_product(const Point_d& other) {
+ assert(dimension() == 3 && other.dimension() == 3);
+ Point_d res(3);
+ res[0] = (*this)[1] * other[2] - (*this)[2] * other[1];
+ res[1] = (*this)[2] * other[0] - (*this)[0] * other[2];
+ res[2] = (*this)[0] * other[1] - (*this)[1] * other[0];
+ return res;
+ }
+
+ Point_d operator+(const Point_d& other) const {
+ assert(dimension() == other.dimension());
+ Point_d res(dimension());
+ for (unsigned i = 0; i < coords_.size(); ++i)
+ res[i] = (*this)[i] + other[i];
+ return res;
+ }
+
+ Point_d operator*(double lambda) const {
+ Point_d res(dimension());
+ for (unsigned i = 0; i < coords_.size(); ++i)
+ res[i] = (*this)[i] * lambda;
+ return res;
+ }
+
+ Point_d operator/(double lambda) const {
+ Point_d res(dimension());
+ for (unsigned i = 0; i < coords_.size(); ++i)
+ res[i] = (*this)[i] / lambda;
+ return res;
+ }
+
+ Point_d operator-(const Point_d& other) const {
+ assert(dimension() == other.dimension());
+ Point_d res(dimension());
+ for (unsigned i = 0; i < coords_.size(); ++i)
+ res[i] = (*this)[i] - other[i];
+ return res;
+ }
+
+ friend Point_d unit_normal(const Point_d& p1, const Point_d& p2, const Point_d& p3) {
+ assert(p1.dimension() == 3);
+ assert(p2.dimension() == 3);
+ assert(p3.dimension() == 3);
+ Point_d p1p2 = p2 - p1;
+ Point_d p1p3 = p3 - p1;
+ Point_d res(p1p2.cross_product(p1p3));
+ return res / std::sqrt(res.squared_norm());
+ }
+
+ private:
+ std::vector<double> coords_;
};
-
-
-
-
-#endif /* BASIC_GEOMETRY_H_ */
+#endif // POINT_H_
diff --git a/src/common/include/gudhi/Simple_object_pool.h b/src/common/include/gudhi/Simple_object_pool.h
new file mode 100644
index 00000000..fb9c8e23
--- /dev/null
+++ b/src/common/include/gudhi/Simple_object_pool.h
@@ -0,0 +1,81 @@
+/* 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): Marc Glisse
+ *
+ * Copyright (C) 2015 INRIA Saclay - Ile de 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 SIMPLE_OBJECT_POOL_H_
+#define SIMPLE_OBJECT_POOL_H_
+
+#include <boost/pool/pool.hpp>
+#include <utility>
+
+namespace Gudhi {
+
+/** \private
+ * This is a simpler version of boost::object_pool, that requires
+ * that users explicitly destroy all objects. This lets the
+ * performance scale much better, see
+ * https://svn.boost.org/trac/boost/ticket/3789 .
+ */
+template <class T>
+class Simple_object_pool : protected boost::pool<boost::default_user_allocator_malloc_free> {
+ protected:
+ typedef boost::pool<boost::default_user_allocator_malloc_free> Base;
+ typedef T* pointer;
+
+ Base& base() {
+ return *this;
+ }
+
+ Base const& base()const {
+ return *this;
+ }
+
+ public:
+ typedef T element_type;
+ typedef boost::default_user_allocator_malloc_free user_allocator;
+ typedef typename Base::size_type size_type;
+ typedef typename Base::difference_type difference_type;
+
+ template<class...U>
+ Simple_object_pool(U&&...u) : Base(sizeof (T), std::forward<U>(u)...) { }
+
+ template<class...U>
+ pointer construct(U&&...u) {
+ void* p = base().malloc BOOST_PREVENT_MACRO_SUBSTITUTION();
+ assert(p);
+ try {
+ new(p) T(std::forward<U>(u)...);
+ } catch (...) {
+ base().free BOOST_PREVENT_MACRO_SUBSTITUTION(p);
+ throw;
+ }
+ return static_cast<pointer> (p);
+ }
+
+ void destroy(pointer p) {
+ p->~T();
+ base().free BOOST_PREVENT_MACRO_SUBSTITUTION(p);
+ }
+};
+
+} // namespace Gudhi
+
+#endif // SIMPLE_OBJECT_POOL_H_
diff --git a/src/common/include/gudhi/Test.h b/src/common/include/gudhi/Test.h
index 18b7ca82..6024c822 100644
--- a/src/common/include/gudhi/Test.h
+++ b/src/common/include/gudhi/Test.h
@@ -1,5 +1,28 @@
-#ifndef __TEST_H
-#define __TEST_H
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 TEST_H_
+#define TEST_H_
#include <list>
#include <string>
@@ -8,78 +31,75 @@
#include <iostream>
-#define TEST(a) std::cout << "TEST: " << (a)<<std::endl
-#define TESTMSG(a,b) std::cout << "TEST: " << a<<b<<std::endl
-#define TESTVALUE(a) std::cout << "TEST: " << #a << ": " << a<<std::endl
-
+#define TEST(a) std::cout << "TEST: " << (a) << std::endl
+#define TESTMSG(a, b) std::cout << "TEST: " << a << b << std::endl
+#define TESTVALUE(a) std::cout << "TEST: " << #a << ": " << a << std::endl
/**
* Class to perform test
*/
-class Test
-{
-private :
- std::string name;
- bool (*test)();
-
- std::string separation() const{
- return "+++++++++++++++++++++++++++++++++++++++++++++++++\n";
- }
-
- std::string print_between_plus(std::string& s) const{
- std::stringstream res;
- res << "+++++++++++++++++"<<s<<"+++++++++++++++++\n";
- return res.str();
- }
-
-
-public:
- Test(std::string name_,bool (*test_)()){
- name=name_;
- test =test_;
- }
-
- bool run(){
- std::cout << print_between_plus(name);
- return test();
- }
- std::string getName(){
- return name;
- }
+class Test {
+ private:
+ std::string name;
+ bool (*test)();
+
+ std::string separation() const {
+ return "+++++++++++++++++++++++++++++++++++++++++++++++++\n";
+ }
+
+ std::string print_between_plus(std::string& s) const {
+ std::stringstream res;
+ res << "+++++++++++++++++" << s << "+++++++++++++++++\n";
+ return res.str();
+ }
+
+ public:
+ Test(std::string name_, bool (*test_)()) {
+ name = name_;
+ test = test_;
+ }
+
+ bool run() {
+ std::cout << print_between_plus(name);
+ return test();
+ }
+
+ std::string getName() {
+ return name;
+ }
};
-
-class Tests
-{
-private:
- std::list<Test> tests;
-
-public:
- void add(std::string name_,bool (*test_)()){
- Test test(name_,test_);
- tests.push_back(test);
- }
- bool run(){
- bool tests_succesful(true);
- std::vector<bool> res;
- for (Test test : tests){
- res.push_back(test.run());
- }
- std::cout << "\n\n results of tests : "<<std::endl;
- int i=0;
- for (Test t : tests){
- std::cout << "Test "<<i<< " \""<<t.getName()<<"\" --> ";
- if (res[i++]) std::cout << "OK"<<std::endl;
- else {
- std::cout << "Fail"<<std::endl;
- tests_succesful = false;
- break;
- }
- }
- return tests_succesful;
-
- }
+class Tests {
+ private:
+ std::list<Test> tests;
+
+ public:
+ void add(std::string name_, bool (*test_)()) {
+ Test test(name_, test_);
+ tests.push_back(test);
+ }
+
+ bool run() {
+ bool tests_succesful(true);
+ std::vector<bool> res;
+ for (Test test : tests) {
+ res.push_back(test.run());
+ }
+ std::cout << "\n\n results of tests : " << std::endl;
+ int i = 0;
+ for (Test t : tests) {
+ std::cout << "Test " << i << " \"" << t.getName() << "\" --> ";
+ if (res[i++]) {
+ std::cout << "OK" << std::endl;
+ } else {
+ std::cout << "Fail" << std::endl;
+ tests_succesful = false;
+ break;
+ }
+ }
+ return tests_succesful;
+ }
};
-#endif
+#endif // TEST_H_
diff --git a/src/common/include/gudhi/Utils.h b/src/common/include/gudhi/Utils.h
index 7678685c..43916f11 100644
--- a/src/common/include/gudhi/Utils.h
+++ b/src/common/include/gudhi/Utils.h
@@ -1,48 +1,46 @@
- /* 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): David Salinas
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 GUDHI_UTILS_H_
-#define GUDHI_UTILS_H_
+/* 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): David Salinas
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (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 UTILS_H_
+#define UTILS_H_
-#define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)"<<std::endl
+#define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)" << std::endl
-//#define DBG_VERBOSE
+// #define DBG_VERBOSE
#ifdef DBG_VERBOSE
-#define DBG(a) std::cerr << "DBG: " << (a)<<std::endl
-#define DBGMSG(a,b) std::cerr << "DBG: " << a<<b<<std::endl
-#define DBGVALUE(a) std::cerr << "DBG: " << #a << ": " << a<<std::endl
-#define DBGCONT(a) std::cerr << "DBG: container "<< #a<<" -> "; for(auto x:a) std::cerr<< x << ","; std::cerr<<std::endl
+#define DBG(a) std::cerr << "DBG: " << (a) << std::endl
+#define DBGMSG(a, b) std::cerr << "DBG: " << a << b << std::endl
+#define DBGVALUE(a) std::cerr << "DBG: " << #a << ": " << a << std::endl
+#define DBGCONT(a) std::cerr << "DBG: container " << #a << " -> "; for (auto x : a) std::cerr << x << ","; std::cerr <<
+std::endl
#else
-//#define DBG(a) a
-//#define DBGMSG(a,b) b
-//#define DBGVALUE(a) a
-//#define DBGCONT(a) a
+// #define DBG(a) a
+// #define DBGMSG(a,b) b
+// #define DBGVALUE(a) a
+// #define DBGCONT(a) a
#define DBG(a)
-#define DBGMSG(a,b)
+#define DBGMSG(a, b)
#define DBGVALUE(a)
#define DBGCONT(a)
#endif
-
-
-
-#endif /* UTILS_H_ */
+#endif // UTILS_H_
diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h
index 7a2ab035..e5c79ded 100644
--- a/src/common/include/gudhi/distance_functions.h
+++ b/src/common/include/gudhi/distance_functions.h
@@ -1,37 +1,41 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DISTANCE_FUNCTIONS_H_
+#define DISTANCE_FUNCTIONS_H_
/* Compute the Euclidean distance between two Points given
* by a range of coordinates. The points are assumed to have
* the same dimension. */
template< typename Point >
-double euclidean_distance( Point &p1, Point &p2)
-{
+double euclidean_distance(Point &p1, Point &p2) {
double dist = 0.;
- auto it1 = p1.begin(); auto it2 = p2.begin();
- for(; it1 != p1.end(); ++it1, ++it2)
- {
- double tmp = *it1 - *it2;
- dist += tmp*tmp;
- }
- return sqrt(dist);
+ auto it1 = p1.begin();
+ auto it2 = p2.begin();
+ for (; it1 != p1.end(); ++it1, ++it2) {
+ double tmp = *it1 - *it2;
+ dist += tmp*tmp;
+ }
+ return sqrt(dist);
}
+
+#endif // DISTANCE_FUNCTIONS_H_
diff --git a/src/common/include/gudhi/graph_simplicial_complex.h b/src/common/include/gudhi/graph_simplicial_complex.h
index 1ad9dabd..042ef516 100644
--- a/src/common/include/gudhi/graph_simplicial_complex.h
+++ b/src/common/include/gudhi/graph_simplicial_complex.h
@@ -1,96 +1,99 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
-#ifndef GUDHI_GRAPH_SIMPLICIAL_COMPLEX_FILTRATION_TAG_H
-#define GUDHI_GRAPH_SIMPLICIAL_COMPLEX_FILTRATION_TAG_H
+#ifndef GRAPH_SIMPLICIAL_COMPLEX_H_
+#define GRAPH_SIMPLICIAL_COMPLEX_H_
#include <boost/graph/adjacency_list.hpp>
+#include <utility> // for pair<>
+#include <vector>
+#include <map>
+
/* Edge tag for Boost PropertyGraph. */
struct edge_filtration_t {
typedef boost::edge_property_tag kind;
};
+
/* Vertex tag for Boost PropertyGraph. */
struct vertex_filtration_t {
typedef boost::vertex_property_tag kind;
};
-typedef int Vertex_handle;
-typedef double Filtration_value;
+typedef int Vertex_handle;
+typedef double Filtration_value;
typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS
- , boost::property < vertex_filtration_t, Filtration_value >
- , boost::property < edge_filtration_t, Filtration_value >
- > Graph_t;
+, boost::property < vertex_filtration_t, Filtration_value >
+, boost::property < edge_filtration_t, Filtration_value >
+> Graph_t;
typedef std::pair< Vertex_handle, Vertex_handle > Edge_t;
/** \brief Output the proximity graph of the points.
- *
- * If points contains n elements, the proximity graph is the graph
- * with n vertices, and an edge [u,v] iff the distance function between
- * points u and v is smaller than threshold.
- *
- * The type PointCloud furnishes .begin() and .end() methods, that return
- * iterators with value_type Point.
- */
+ *
+ * If points contains n elements, the proximity graph is the graph
+ * with n vertices, and an edge [u,v] iff the distance function between
+ * points u and v is smaller than threshold.
+ *
+ * The type PointCloud furnishes .begin() and .end() methods, that return
+ * iterators with value_type Point.
+ */
template< typename PointCloud
- , typename Point >
-Graph_t compute_proximity_graph( PointCloud &points
- , Filtration_value threshold
- , Filtration_value distance(Point p1, Point p2) )
-{
- std::vector< Edge_t > edges;
- std::vector< Filtration_value > edges_fil;
+, typename Point >
+Graph_t compute_proximity_graph(PointCloud &points
+ , Filtration_value threshold
+ , Filtration_value distance(Point p1, Point p2)) {
+ std::vector< Edge_t > edges;
+ std::vector< Filtration_value > edges_fil;
std::map< Vertex_handle, Filtration_value > vertices;
Vertex_handle idx_u, idx_v;
Filtration_value fil;
idx_u = 0;
- for(auto it_u = points.begin(); it_u != points.end(); ++it_u)
- {
- idx_v = idx_u+1;
- for(auto it_v = it_u+1; it_v != points.end(); ++it_v, ++idx_v)
- {
- fil = distance(*it_u,*it_v);
- if(fil <= threshold) {
- edges.emplace_back(idx_u,idx_v);
+ for (auto it_u = points.begin(); it_u != points.end(); ++it_u) {
+ idx_v = idx_u + 1;
+ for (auto it_v = it_u + 1; it_v != points.end(); ++it_v, ++idx_v) {
+ fil = distance(*it_u, *it_v);
+ if (fil <= threshold) {
+ edges.emplace_back(idx_u, idx_v);
edges_fil.push_back(fil);
}
}
++idx_u;
}
- Graph_t skel_graph( edges.begin()
- , edges.end()
- , edges_fil.begin()
- , idx_u); //number of points labeled from 0 to idx_u-1
+ Graph_t skel_graph(edges.begin()
+ , edges.end()
+ , edges_fil.begin()
+ , idx_u); // number of points labeled from 0 to idx_u-1
- auto vertex_prop = boost::get(vertex_filtration_t(),skel_graph);
+ auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph);
boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
- for ( std::tie(vi, vi_end) = boost::vertices(skel_graph);
- vi != vi_end; ++vi )
- { boost::put(vertex_prop, *vi, 0.); }
-
+ for (std::tie(vi, vi_end) = boost::vertices(skel_graph);
+ vi != vi_end; ++vi) {
+ boost::put(vertex_prop, *vi, 0.);
+ }
+
return skel_graph;
}
-#endif // GUDHI_GRAPH_SIMPLICIAL_COMPLEX_FILTRATION_TAG_H
+#endif // GRAPH_SIMPLICIAL_COMPLEX_H_
diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h
index ab12c268..e05714c7 100644
--- a/src/common/include/gudhi/reader_utils.h
+++ b/src/common/include/gudhi/reader_utils.h
@@ -1,32 +1,38 @@
- /* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Author(s): Clément Maria
- *
- * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GUDHI_READER_UTILS_H
-#define GUDHI_READER_UTILS_H
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Clément Maria
+ *
+ * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef READER_UTILS_H_
+#define READER_UTILS_H_
+
+#include <gudhi/graph_simplicial_complex.h>
+
+#include <boost/graph/adjacency_list.hpp>
#include <iostream>
#include <fstream>
-#include <boost/graph/adjacency_list.hpp>
-#include "gudhi/graph_simplicial_complex.h"
+#include <map>
+#include <limits> // for numeric_limits<>
+#include <string>
+#include <vector>
/**
* \brief Read a set of points to turn it
@@ -37,22 +43,21 @@
* X21 X22 ... X2d
* etc
*/
-inline void
-read_points ( std::string file_name
- , std::vector< std::vector< double > > & points)
-{
- std::ifstream in_file (file_name.c_str(),std::ios::in);
- if(!in_file.is_open()) {
+inline void read_points(std::string file_name, std::vector< std::vector< double > > & points) {
+ std::ifstream in_file(file_name.c_str(), std::ios::in);
+ if (!in_file.is_open()) {
std::cerr << "Unable to open file " << file_name << std::endl;
- return;}
+ return;
+ }
std::string line;
double x;
- while( getline ( in_file , line ) )
- {
+ while (getline(in_file, line)) {
std::vector< double > point;
- std::istringstream iss( line );
- while(iss >> x) { point.push_back(x); }
+ std::istringstream iss(line);
+ while (iss >> x) {
+ point.push_back(x);
+ }
points.push_back(point);
}
in_file.close();
@@ -70,53 +75,64 @@ read_points ( std::string file_name
* Every simplex must appear exactly once.
* Simplices of dimension more than 1 are ignored.
*/
-inline Graph_t
-read_graph ( std::string file_name )
-{
- std::ifstream in_ (file_name.c_str(),std::ios::in);
- if(!in_.is_open()) { std::cerr << "Unable to open file " << file_name << std::endl; }
-
- std::vector< Edge_t > edges;
- std::vector< Filtration_value > edges_fil;
+inline Graph_t read_graph(std::string file_name) {
+ std::ifstream in_(file_name.c_str(), std::ios::in);
+ if (!in_.is_open()) {
+ std::cerr << "Unable to open file " << file_name << std::endl;
+ }
+
+ std::vector< Edge_t > edges;
+ std::vector< Filtration_value > edges_fil;
std::map< Vertex_handle, Filtration_value > vertices;
-
- std::string line;
- int dim;
- Vertex_handle u,v,max_h = -1;
+
+ std::string line;
+ int dim;
+ Vertex_handle u, v, max_h = -1;
Filtration_value fil;
- while( getline ( in_ , line ) )
- {
- std::istringstream iss( line );
- while(iss >> dim) {
- switch ( dim ) {
- case 0 : {
- iss >> u; iss >> fil;
+ while (getline(in_, line)) {
+ std::istringstream iss(line);
+ while (iss >> dim) {
+ switch (dim) {
+ case 0:
+ {
+ iss >> u;
+ iss >> fil;
vertices[u] = fil;
- if(max_h < u) { max_h = u; }
+ if (max_h < u) {
+ max_h = u;
+ }
break;
}
- case 1 : {
- iss >> u; iss >> v; iss >> fil;
- edges.push_back(Edge_t(u,v));
+ case 1:
+ {
+ iss >> u;
+ iss >> v;
+ iss >> fil;
+ edges.push_back(Edge_t(u, v));
edges_fil.push_back(fil);
break;
}
- default: {break;}
- }
+ default:
+ {
+ break;
+ }
+ }
}
}
in_.close();
- if((size_t)(max_h+1) != vertices.size())
- { std::cerr << "Error: vertices must be labeled from 0 to n-1 \n"; }
+ if ((size_t) (max_h + 1) != vertices.size()) {
+ std::cerr << "Error: vertices must be labeled from 0 to n-1 \n";
+ }
- Graph_t skel_graph(edges.begin(),edges.end(),edges_fil.begin(),vertices.size());
- auto vertex_prop = boost::get(vertex_filtration_t(),skel_graph);
+ Graph_t skel_graph(edges.begin(), edges.end(), edges_fil.begin(), vertices.size());
+ auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph);
boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
auto v_it = vertices.begin();
- for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi,++v_it)
- { boost::put(vertex_prop, *vi, v_it->second); }
+ for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi, ++v_it) {
+ boost::put(vertex_prop, *vi, v_it->second);
+ }
return skel_graph;
}
@@ -133,17 +149,15 @@ read_graph ( std::string file_name )
* Every simplex must appear exactly once.
* Simplices of dimension more than 1 are ignored.
*/
-template< typename Vertex_handle
- , typename Filtration_value >
-bool read_simplex ( std::istream & in_
- , std::vector< Vertex_handle > & simplex
- , Filtration_value & fil )
-{
- int dim=0;
- if(!(in_ >> dim)) return false;
+template< typename Vertex_handle, typename Filtration_value >
+bool read_simplex(std::istream & in_, std::vector< Vertex_handle > & simplex, Filtration_value & fil) {
+ int dim = 0;
+ if (!(in_ >> dim)) return false;
Vertex_handle v;
- for(int i=0; i<dim+1; ++i)
- { in_ >> v; simplex.push_back(v); }
+ for (int i = 0; i < dim + 1; ++i) {
+ in_ >> v;
+ simplex.push_back(v);
+ }
in_ >> fil;
in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return
return true;
@@ -162,20 +176,21 @@ bool read_simplex ( std::istream & in_
* Dimi ki1 ki2 ... kiDimi Fili means that the ith simplex in the
* filtration has dimension Dimi, filtration value fil1 and simplices with
* key ki1 ... kiDimi in its boundary.*/
-template< typename Simplex_key
- , typename Filtration_value >
-bool read_hasse_simplex ( std::istream & in_
- , std::vector< Simplex_key > & boundary
- , Filtration_value & fil )
-{
+template< typename Simplex_key, typename Filtration_value >
+bool read_hasse_simplex(std::istream & in_, std::vector< Simplex_key > & boundary, Filtration_value & fil) {
int dim;
- if(!(in_ >> dim)) return false;
- if(dim == 0) {in_ >> fil; return true;}
+ if (!(in_ >> dim)) return false;
+ if (dim == 0) {
+ in_ >> fil;
+ return true;
+ }
Simplex_key key;
- for(int i=0; i<dim+1; ++i)
- { in_ >> key; boundary.push_back(key); }
+ for (int i = 0; i < dim + 1; ++i) {
+ in_ >> key;
+ boundary.push_back(key);
+ }
in_ >> fil;
return true;
}
-#endif // GUDHI_READER_UTILS_H
+#endif // READER_UTILS_H_