summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeGUDHIVersion.txt2
-rw-r--r--CMakeLists.txt32
-rw-r--r--biblio/bibliography.bib27
-rw-r--r--biblio/how_to_cite_cgal.bib947
-rw-r--r--biblio/how_to_cite_gudhi.bib9
-rw-r--r--data/bitmap/2d_torus.txt12
-rw-r--r--data/bitmap/3d_torus.txt31
-rw-r--r--data/bitmap/CubicalOneSphere.txt12
-rw-r--r--data/bitmap/CubicalTwoSphere.txt31
-rwxr-xr-xdata/points/alphacomplexdoc.off10
-rwxr-xr-xscripts/generate_version.sh4
-rw-r--r--src/Alpha_complex/doc/Intro_alpha_complex.h168
-rw-r--r--src/Alpha_complex/doc/alpha_complex_doc.ipe595
-rw-r--r--src/Alpha_complex/doc/alpha_complex_doc.pngbin0 -> 25554 bytes
-rw-r--r--src/Alpha_complex/doc/alpha_complex_doc_420.ipe514
-rw-r--r--src/Alpha_complex/doc/alpha_complex_doc_420.pngbin0 -> 80794 bytes
-rw-r--r--src/Alpha_complex/doc/alpha_complex_representation.ipe321
-rw-r--r--src/Alpha_complex/doc/alpha_complex_representation.pngbin0 -> 14606 bytes
-rw-r--r--src/Alpha_complex/example/Alpha_complex_from_off.cpp56
-rw-r--r--src/Alpha_complex/example/Alpha_complex_from_points.cpp62
-rw-r--r--src/Alpha_complex/example/CMakeLists.txt43
-rw-r--r--src/Alpha_complex/example/alphaoffreader_for_doc_32.txt22
-rw-r--r--src/Alpha_complex/example/alphaoffreader_for_doc_60.txt27
-rw-r--r--src/Alpha_complex/include/gudhi/Alpha_complex.h415
-rw-r--r--src/Alpha_complex/test/Alpha_complex_unit_test.cpp243
-rw-r--r--src/Alpha_complex/test/CMakeLists.txt45
-rw-r--r--src/Alpha_complex/test/README12
-rw-r--r--src/Bitmap_cubical_complex/doc/Cubical_complex_representation.ipe732
-rw-r--r--src/Bitmap_cubical_complex/doc/Cubical_complex_representation.pngbin0 -> 19167 bytes
-rw-r--r--src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h157
-rw-r--r--src/Bitmap_cubical_complex/doc/bitmapAllCubes.pngbin0 -> 38944 bytes
-rw-r--r--src/Bitmap_cubical_complex/doc/exampleBitmap.pngbin0 -> 2549 bytes
-rw-r--r--src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp72
-rw-r--r--src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp74
-rw-r--r--src/Bitmap_cubical_complex/example/CMakeLists.txt26
-rw-r--r--src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp83
-rw-r--r--src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h593
-rw-r--r--src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h142
-rw-r--r--src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h815
-rw-r--r--src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h306
-rw-r--r--src/Bitmap_cubical_complex/test/Bitmap_test.cpp1378
-rw-r--r--src/Bitmap_cubical_complex/test/CMakeLists.txt24
-rw-r--r--src/CMakeLists.txt23
-rw-r--r--src/Contraction/doc/sphere_contraction_representation.pngbin0 -> 44839 bytes
-rw-r--r--src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h2
-rw-r--r--src/Contraction/include/gudhi/Edge_contraction.h5
-rw-r--r--src/Contraction/include/gudhi/Skeleton_blocker_contractor.h2
-rw-r--r--src/Doxyfile42
-rw-r--r--src/GudhUI/CMakeLists.txt5
-rw-r--r--src/GudhUI/model/Model.h2
-rw-r--r--src/GudhUI/utils/Bar_code_persistence.h90
-rw-r--r--src/GudhUI/utils/Persistence_compute.h14
-rw-r--r--src/GudhUI/view/FirstCoordProjector.h4
-rw-r--r--src/Persistent_cohomology/concept/FilteredComplex.h2
-rw-r--r--src/Persistent_cohomology/doc/3DTorus_poch.pngbin0 -> 40164 bytes
-rw-r--r--src/Persistent_cohomology/example/CMakeLists.txt72
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp (renamed from src/Persistent_cohomology/example/alpha_shapes_persistence.cpp)27
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_persistence.cpp117
-rw-r--r--src/Persistent_cohomology/example/rips_persistence.cpp3
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h15
-rw-r--r--src/Persistent_cohomology/test/CMakeLists.txt8
-rw-r--r--src/Simplex_tree/doc/Simplex_tree_representation.pngbin0 -> 39217 bytes
-rw-r--r--src/Simplex_tree/example/CMakeLists.txt9
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree.h186
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h3
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h4
-rw-r--r--src/Simplex_tree/test/CMakeLists.txt3
-rw-r--r--src/Simplex_tree/test/simplex_tree_unit_test.cpp352
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h3
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h2
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h2
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h2
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h2
-rw-r--r--src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h2
-rw-r--r--src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp2
-rw-r--r--src/Witness_complex/doc/Witness_complex_doc.h6
-rw-r--r--src/Witness_complex/doc/Witness_complex_representation.pngbin0 -> 48899 bytes
-rw-r--r--src/Witness_complex/test/CMakeLists.txt4
-rw-r--r--src/common/doc/Gudhi_banner.jpgbin34437 -> 0 bytes
-rw-r--r--src/common/doc/Gudhi_banner.pngbin0 -> 34877 bytes
-rw-r--r--src/common/doc/footer.html29
-rw-r--r--src/common/doc/header.html82
-rw-r--r--src/common/doc/main_page.h307
-rw-r--r--src/common/doc/stylesheet.css1367
-rw-r--r--src/common/example/CGAL_points_off_reader.cpp44
-rw-r--r--src/common/example/CMakeLists.txt22
-rw-r--r--src/common/example/cgaloffreader_result.txt7
-rw-r--r--src/common/include/gudhi/Debug_utils.h (renamed from src/common/include/gudhi/Utils.h)41
-rw-r--r--src/common/include/gudhi/Off_reader.h49
-rw-r--r--src/common/include/gudhi/Points_off_io.h177
-rw-r--r--src/common/include/gudhi/distance_functions.h4
-rw-r--r--src/common/include/gudhi/reader_utils.h6
-rw-r--r--src/common/test/CMakeLists.txt39
-rw-r--r--src/common/test/README14
-rw-r--r--src/common/test/dtoffrw_alphashapedoc_result.off7
-rw-r--r--src/common/test/points_off_reader_unit_test.cpp78
96 files changed, 11107 insertions, 223 deletions
diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt
index 19d10535..20767813 100644
--- a/CMakeGUDHIVersion.txt
+++ b/CMakeGUDHIVersion.txt
@@ -1,5 +1,5 @@
set (GUDHI_MAJOR_VERSION 1)
-set (GUDHI_MINOR_VERSION 2)
+set (GUDHI_MINOR_VERSION 3)
set (GUDHI_PATCH_VERSION 0)
set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f56cca1..6ad3a58f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ project(GUDHIdev)
include(CMakeGUDHIVersion.txt)
# Generate GUDHI official version file
-configure_file(GUDHIVersion.cmake.in "${PROJECT_BINARY_DIR}/GUDHIVersion.cmake" @ONLY)
+configure_file(GUDHIVersion.cmake.in "${CMAKE_SOURCE_DIR}/GUDHIVersion.cmake" @ONLY)
find_package(Boost REQUIRED COMPONENTS system filesystem unit_test_framework chrono timer program_options thread REQUIRED)
@@ -34,6 +34,11 @@ else()
# 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.
find_package(CGAL)
+ # Only CGAL versions > 4.4 supports what Gudhi uses from CGAL
+ if (CGAL_VERSION VERSION_LESS 4.4.0)
+ message("CGAL version ${CGAL_VERSION} is considered too old to be used by Gudhi.")
+ unset(CGAL_FOUND)
+ endif()
if(CGAL_FOUND)
include( ${CGAL_USE_FILE} )
endif()
@@ -58,6 +63,10 @@ else()
# Find TBB package for parallel sort - not mandatory, just optional.
set(TBB_FIND_QUIETLY ON)
find_package(TBB)
+ if (TBB_FOUND)
+ message("TBB found in ${TBB_LIBRARY_DIRS}")
+ add_definitions(-DGUDHI_USE_TBB)
+ endif()
# Required programs for unitary tests purpose
FIND_PROGRAM( GCOVR_PATH gcovr )
@@ -69,7 +78,10 @@ else()
if (GPROF_PATH)
message("gprof found in ${GPROF_PATH}")
endif()
-
+FIND_PROGRAM( DIFF_PATH diff )
+if (DIFF_PATH)
+ message("diff found in ${DIFF_PATH}")
+endif()
# BOOST ISSUE result_of vs C++11
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
@@ -82,7 +94,15 @@ else()
message(STATUS "boost include dirs:" ${Boost_INCLUDE_DIRS})
message(STATUS "boost library dirs:" ${Boost_LIBRARY_DIRS})
+ if (DEBUG_TRACES)
+ # For programs to be more verbose
+ message(STATUS "DEBUG_TRACES are activated")
+ add_definitions(-DDEBUG_TRACES)
+ endif()
+
include_directories(src/common/include/)
+ include_directories(src/Alpha_complex/include/)
+ include_directories(src/Bitmap_cubical_complex/include/)
include_directories(src/Bottleneck/include/)
include_directories(src/Contraction/include/)
include_directories(src/Hasse_complex/include/)
@@ -91,6 +111,8 @@ else()
include_directories(src/Skeleton_blocker/include/)
include_directories(src/Witness_complex/include/)
+ add_subdirectory(src/common/example)
+ add_subdirectory(src/common/test)
add_subdirectory(src/Simplex_tree/test)
add_subdirectory(src/Simplex_tree/example)
add_subdirectory(src/Persistent_cohomology/test)
@@ -100,6 +122,10 @@ else()
add_subdirectory(src/Contraction/example)
add_subdirectory(src/Witness_complex/test)
add_subdirectory(src/Witness_complex/example)
+ add_subdirectory(src/Bitmap_cubical_complex/test)
+ add_subdirectory(src/Bitmap_cubical_complex/example)
+ add_subdirectory(src/Alpha_complex/example)
+ add_subdirectory(src/Alpha_complex/test)
# data points generator
add_subdirectory(data/points/generator)
@@ -109,3 +135,5 @@ else()
add_subdirectory(src/GudhUI)
endif()
+
+
diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib
index 3fd1c10a..9fc01a5d 100644
--- a/biblio/bibliography.bib
+++ b/biblio/bibliography.bib
@@ -927,3 +927,30 @@ misc{jplex_cite,
year = "2009",
note = "http://comptop.stanford.edu/programs/jplex/"
}
+
+@book{kaczynski2004computational,
+ title={Computational Homology},
+ author={Kaczynski, T. and Mischaikow, K. and Mrozek, M.},
+ isbn={9780387408538},
+ lccn={03061109},
+ series={Applied Mathematical Sciences},
+ url={https://books.google.fr/books?id=AShKtpi3GecC},
+ year={2004},
+ publisher={Springer New York}
+}
+
+@ARTICLE{peikert2012topological,
+year={2012},
+isbn={978-3-642-23174-2},
+booktitle={Topological Methods in Data Analysis and Visualization II},
+series={Mathematics and Visualization},
+editor={Peikert, Ronald and Hauser, Helwig and Carr, Hamish and Fuchs, Raphael},
+doi={10.1007/978-3-642-23175-9_7},
+title={Efficient Computation of Persistent Homology for Cubical Data},
+url={http://dx.doi.org/10.1007/978-3-642-23175-9_7},
+publisher={Springer Berlin Heidelberg},
+author={Wagner, Hubert and Chen, Chao and Vucini, Erald},
+pages={91-106},
+language={English}
+}
+
diff --git a/biblio/how_to_cite_cgal.bib b/biblio/how_to_cite_cgal.bib
new file mode 100644
index 00000000..7336ee81
--- /dev/null
+++ b/biblio/how_to_cite_cgal.bib
@@ -0,0 +1,947 @@
+@book{ cgal:eb-15b
+, title = "{CGAL} User and Reference Manual"
+, author = "{The CGAL Project}"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, year = 2015
+, url = "http://doc.cgal.org/4.7/Manual/packages.html"
+}
+@incollection{cgal:h-af-15b
+, author = "Michael Hemmer"
+, title = "Algebraic Foundations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgAlgebraicFoundationsSummary"
+, year = 2015
+}
+
+@incollection{cgal:hhkps-nt-15b
+, author = "Michael Hemmer and Susan Hert and Sylvain Pion and Stefan Schirra"
+, title = "Number Types"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgNumberTypesSummary"
+, year = 2015
+}
+
+@incollection{cgal:h-ma-15b
+, author = "Michael Hemmer and Sylvain Pion"
+, title = "Modular Arithmetic"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgModularArithmeticSummary"
+, year = 2015
+}
+
+@incollection{cgal:h-p-15b
+, author = "Michael Hemmer"
+, title = "Polynomial"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPolynomialSummary"
+, year = 2015
+}
+
+@incollection{cgal:bht-ak-15b
+, author = "Eric Berberich and Michael Hemmer and Michael Kerber and Sylvain Lazard and Luis Pe{\~n}aranda and Monique Teillaud"
+, title = "Algebraic Kernel"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgAlgebraicKerneldSummary"
+, year = 2015
+}
+
+@incollection{cgal:h-msms-15b
+, author = "Michael Hoffmann"
+, title = "Monotone and Sorted Matrix Search"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgMatrixSearchSummary"
+, year = 2015
+}
+
+@incollection{cgal:fgsw-lqps-15b
+, author = "Kaspar Fischer and Bernd G{\"a}rtner and Sven Sch{\"o}nherr and Frans Wessendorp"
+, title = "Linear and Quadratic Programming Solver"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgQPSolverSummary"
+, year = 2015
+}
+
+@incollection{cgal:bfghhkps-lgk23-15b
+, author = "Herv{\'e} Br{\"o}nnimann and Andreas Fabri and Geert-Jan Giezeman and Susan Hert and Michael Hoffmann and Lutz Kettner and Sylvain Pion and Stefan Schirra"
+, title = "{2D} and {3D} Linear Geometry Kernel"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgKernel23Summary"
+, year = 2015
+}
+
+@incollection{cgal:s-gkd-15b
+, author = "Michael Seel"
+, title = "{dD} Geometry Kernel"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgKernelDSummary"
+, year = 2015
+}
+
+@incollection{cgal:cpt-cgk2-15b
+, author = "Pedro Machado Manh{\~a}es de Castro and Sylvain Pion and Monique Teillaud"
+, title = "{2D} Circular Geometry Kernel"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgCircularKernel2Summary"
+, year = 2015
+}
+
+@incollection{cgal:cclt-sgk3-15b
+, author = "Pedro Machado Manh{\~a}es de Castro and Fr{\'e}d{\'e}ric Cazals and S{\'e}bastien Loriot and Monique Teillaud"
+, title = "{3D} Spherical Geometry Kernel"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSphericalKernel3Summary"
+, year = 2015
+}
+
+@incollection{cgal:hs-chep2-15b
+, author = "Susan Hert and Stefan Schirra"
+, title = "{2D} Convex Hulls and Extreme Points"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgConvexHull2Summary"
+, year = 2015
+}
+
+@incollection{cgal:hs-ch3-15b
+, author = "Susan Hert and Stefan Schirra"
+, title = "{3D} Convex Hulls"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgConvexHull3Summary"
+, year = 2015
+}
+
+@incollection{cgal:hs-chdt3-15b
+, author = "Susan Hert and Michael Seel"
+, title = "{dD} Convex Hulls and Delaunay Triangulations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgConvexHullDSummary"
+, year = 2015
+}
+
+@incollection{cgal:gw-p2-15b
+, author = "Geert-Jan Giezeman and Wieger Wesselink"
+, title = "{2D} Polygons"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPolygon2Summary"
+, year = 2015
+}
+
+@incollection{cgal:fwzh-rbso2-15b
+, author = "Efi Fogel and Ophir Setter and Ron Wein and Guy Zucker and Baruch Zukerman and Dan Halperin"
+, title = "{2D} Regularized Boolean Set-Operations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgBooleanSetOperations2Summary"
+, year = 2015
+}
+
+@incollection{cgal:s-bonp2-15b
+, author = "Michael Seel"
+, title = "{2D} Boolean Operations on Nef Polygons"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgNef2Summary"
+, year = 2015
+}
+
+@incollection{cgal:hk-bonpes2-15b
+, author = "Peter Hachenberger and Lutz Kettner"
+, title = "{2D} Boolean Operations on Nef Polygons Embedded on the Sphere"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgNefS2Summary"
+, year = 2015
+}
+
+@incollection{cgal:h-pp2-15b
+, author = "Susan Hert"
+, title = "{2D} Polygon Partitioning"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPolygonPartitioning2Summary"
+, year = 2015
+}
+
+@incollection{cgal:c-sspo2-15b
+, author = "Fernando Cacciola"
+, title = "{2D} Straight Skeleton and Polygon Offsetting"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgStraightSkeleton2Summary"
+, year = 2015
+}
+
+@incollection{cgal:w-rms2-15b
+, author = "Ron Wein and Alon Baram and Eyal Flato and Efi Fogel and Michael Hemmer and Sebastian Morr"
+, title = "{2D} Minkowski Sums"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgMinkowskiSum2Summary"
+, year = 2015
+}
+
+@incollection{cgal:f-ps2-15b
+, author = "Andreas Fabri"
+, title = "{2D} Polyline Simplification"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPolylineSimplification2Summary"
+, year = 2015
+}
+
+@incollection{hhb-visibility-2-15b
+, author = "Michael Hemmer and Kan Huang and Francisc Bungiu and Ning Xu"
+, title = "{2D} Visibility Computation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgVisibility_2Summary"
+, year = 2015
+}
+
+@incollection{cgal:k-ps-15b
+, author = "Lutz Kettner"
+, title = "{3D} Polyhedral Surface"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPolyhedronSummary"
+, year = 2015
+}
+
+@incollection{cgal:k-hds-15b
+, author = "Lutz Kettner"
+, title = "Halfedge Data Structures"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgHDSSummary"
+, year = 2015
+}
+
+@incollection{cgal:bsmf-sm-15b
+, author = "Mario Botsch and Daniel Sieger and Philipp Moeller and Andreas Fabri"
+, title = "Surface Mesh"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceMeshSummary"
+, year = 2015
+}
+
+@incollection{cgal:d-cm-15b
+, author = "Guillaume Damiand"
+, title = "Combinatorial Maps"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgCombinatorialMapsSummary"
+, year = 2015
+}
+
+@incollection{cgal:d-lcc-12-15b
+, author = "Guillaume Damiand"
+, title = "Linear Cell Complex"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgLinearCellComplexSummary"
+, year = 2015
+}
+
+@incollection{cgal:hk-bonp3-15b
+, author = "Peter Hachenberger and Lutz Kettner"
+, title = "{3D} Boolean Operations on Nef Polyhedra"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgNef3Summary"
+, year = 2015
+}
+
+@incollection{cgal:h-emspe-15b
+, author = "Peter Hachenberger"
+, title = "Convex Decomposition of Polyhedra"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgConvexDecomposition3Summary"
+, year = 2015
+}
+
+@incollection{cgal:h-msp3-15b
+, author = "Peter Hachenberger"
+, title = "{3D} Minkowski Sum of Polyhedra"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgMinkowskiSum3Summary"
+, year = 2015
+}
+
+@incollection{cgal:wfzh-a2-15b
+, author = "Ron Wein and Eric Berberich and Efi Fogel and Dan Halperin and Michael Hemmer and Oren Salzman and Baruch Zukerman"
+, title = "{2D} Arrangements"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgArrangement2Summary"
+, year = 2015
+}
+
+@incollection{cgal:wfz-ic2-15b
+, author = "Baruch Zukerman and Ron Wein and Efi Fogel"
+, title = "{2D} Intersection of Curves"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgIntersectionOfCurves2Summary"
+, year = 2015
+}
+
+@incollection{cgal:p-sr2-15b
+, author = "Eli Packer"
+, title = "{2D} Snap Rounding"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSnapRounding2Summary"
+, year = 2015
+}
+
+@incollection{cgal:w-e2-15b
+, author = "Ron Wein"
+, title = "{2D} Envelopes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgEnvelope2Summary"
+, year = 2015
+}
+
+@incollection{cgal:mwz-e3-15b
+, author = "Dan Halperin and Michal Meyerovitch and Ron Wein and Baruch Zukerman"
+, title = "{3D} Envelopes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgEnvelope3Summary"
+, year = 2015
+}
+
+@incollection{cgal:y-t2-15b
+, author = "Mariette Yvinec"
+, title = "{2D} Triangulation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgTriangulation2Summary"
+, year = 2015
+}
+
+@incollection{cgal:py-tds2-15b
+, author = "Sylvain Pion and Mariette Yvinec"
+, title = "{2D} Triangulation Data Structure"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgTDS2Summary"
+, year = 2015
+}
+
+@incollection{cgal:k-pt2-13-15b
+, author = "Nico Kruithof"
+, title = "{2D} Periodic Triangulations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPeriodic2Triangulation2Summary"
+, year = 2015
+}
+
+@incollection{cgal:pt-t3-15b
+, author = "Cl{\'e}ment Jamin and Sylvain Pion and Monique Teillaud"
+, title = "{3D} Triangulations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgTriangulation3Summary"
+, year = 2015
+}
+
+@incollection{cgal:pt-tds3-15b
+, author = "Cl{\'e}ment Jamin and Sylvain Pion and Monique Teillaud"
+, title = "{3D} Triangulation Data Structure"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgTDS3Summary"
+, year = 2015
+}
+
+@incollection{cgal:ct-pt3-15b
+, author = "Manuel Caroli and Monique Teillaud"
+, title = "{3D} Periodic Triangulations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPeriodic3Triangulation3Summary"
+, year = 2015
+}
+
+@incollection{cgal:hdj-t-15b
+, author = "Samuel Hornus and Olivier Devillers and Cl{\'e}ment Jamin"
+, title = "{dD} Triangulations"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgTriangulationsSummary"
+, year = 2015
+}
+
+@incollection{cgal:d-as2-15b
+, author = "Tran Kai Frank Da"
+, title = "{2D} Alpha Shapes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgAlphaShape2Summary"
+, year = 2015
+}
+
+@incollection{cgal:dy-as3-15b
+, author = "Tran Kai Frank Da and S{\'e}bastien Loriot and Mariette Yvinec"
+, title = "{3D} Alpha Shapes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgAlphaShapes3Summary"
+, year = 2015
+}
+
+@incollection{cgal:k-sdg2-15b
+, author = "Menelaos Karavelas"
+, title = "{2D} Segment Delaunay Graphs"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSegmentDelaunayGraph2Summary"
+, year = 2015
+}
+
+@incollection{cgal:cdp-sdglinf2-15b
+, author = "Panagiotis Cheilaris and Sandeep Kumar Dey and Evanthia Papadopoulou"
+, title = "L Infinity Segment Delaunay Graphs"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSDGLinfSummary"
+, year = 2015
+}
+
+@incollection{cgal:ky-ag2-15b
+, author = "Menelaos Karavelas and Mariette Yvinec"
+, title = "{2D} Apollonius Graphs (Delaunay Graphs of Disks)"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgApolloniusGraph2Summary"
+, year = 2015
+}
+
+@incollection{cgal:k-vda2-15b
+, author = "Menelaos Karavelas"
+, title = "{2D} Voronoi Diagram Adaptor"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgVoronoiDiagramAdaptor2Summary"
+, year = 2015
+}
+
+@incollection{cgal:r-ctm2-15b
+, author = "Laurent Rineau"
+, title = "{2D} Conforming Triangulations and Meshes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgMesh2Summary"
+, year = 2015
+}
+
+@incollection{cgal:ry-smg-15b
+, author = "Laurent Rineau and Mariette Yvinec"
+, title = "{3D} Surface Mesh Generation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceMesher3Summary"
+, year = 2015
+}
+
+@incollection{cgal:asg-srps-15b
+, author = "Pierre Alliez and Laurent Saboret and Ga{\"e}l Guennebaud"
+, title = "Surface Reconstruction from Point Sets"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceReconstructionFromPointSetsSummary"
+, year = 2015
+}
+
+@incollection{cgal:ssr3-15b
+, author = "Thijs van Lankveld"
+, title = "Scale-Space Surface Reconstruction"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgScaleSpaceReconstruction3Summary"
+, year = 2015
+}
+
+@incollection{cgal:dc-afsr-15b
+, author = "Tran Kai Frank Da and David Cohen-Steiner"
+, title = "Advancing Front Surface Reconstruction"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgAdvancingFrontSurfaceReconstructionSummary"
+, year = 2015
+}
+
+@incollection{cgal:k-ssm3-15b
+, author = "Nico Kruithof"
+, title = "{3D} Skin Surface Meshing"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSkinSurface3Summary"
+, year = 2015
+}
+
+@incollection{cgal:rty-m3-15b
+, author = "Pierre Alliez and Cl{\'e}ment Jamin and Laurent Rineau and St{\'e}phane Tayeb and Jane Tournois and Mariette Yvinec"
+, title = "{3D} Mesh Generation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgMesh_3Summary"
+, year = 2015
+}
+
+@incollection{cgal:lty-pmp-15b
+, author = "S{\'e}bastien Loriot and Jane Tournois and Ilker O. Yaz"
+, title = "Polygon Mesh Processing"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPolygonMeshProcessingSummary"
+, year = 2015
+}
+
+@incollection{cgal:s-ssm2-15b
+, author = "Le-Jeng Andy Shiue"
+, title = "{3D} Surface Subdivision Methods"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceSubdivisionMethods3Summary"
+, year = 2015
+}
+
+@incollection{cgal:y-smsimpl-15b
+, author = "Ilker O. Yaz and S{\'e}bastien Loriot"
+, title = "Triangulated Surface Mesh Segmentation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceSegmentationSummary"
+, year = 2015
+}
+
+@incollection{cgal:c-tsms-12-15b
+, author = "Fernando Cacciola"
+, title = "Triangulated Surface Mesh Simplification"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceMeshSimplificationSummary"
+, year = 2015
+}
+
+@incollection{cgal:lsxy-tsmd-15b
+, author = "S{\'e}bastien Loriot and Olga Sorkine-Hornung and Yin Xu and Ilker O. Yaz"
+, title = "Triangulated Surface Mesh Deformation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceModelingSummary"
+, year = 2015
+}
+
+@incollection{cgal:sal-pptsm2-15b
+, author = "Laurent Saboret and Pierre Alliez and Bruno L{\'e}vy"
+, title = "Planar Parameterization of Triangulated Surface Meshes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceParameterizationSummary"
+, year = 2015
+}
+
+@incollection{cgal:klcdv-tsmsp-15b
+, author = "Stephen Kiazyk and S{\'e}bastien Loriot and {\'E}ric Colin de Verdi{\`e}re"
+, title = "Triangulated Surface Mesh Shortest Paths"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSurfaceMeshShortestPathSummary"
+, year = 2015
+}
+
+@incollection{cgal:glt-tsms-15b
+, author = "Xiang Gao and S{\'e}bastien Loriot and Andrea Tagliasacchi"
+, title = "Triangulated Surface Mesh Skeletonization"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgMeanCurvatureSkeleton3Summary"
+, year = 2015
+}
+
+@incollection{cgal:cp-arutsm-15b
+, author = "Marc Pouget and Fr{\'e}d{\'e}ric Cazals"
+, title = "Approximation of Ridges and Umbilics on Triangulated Surface Meshes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgRidges_3Summary"
+, year = 2015
+}
+
+@incollection{cgal:pc-eldp-15b
+, author = "Marc Pouget and Fr{\'e}d{\'e}ric Cazals"
+, title = "Estimation of Local Differential Properties of Point-Sampled Surfaces"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgJet_fitting_3Summary"
+, year = 2015
+}
+
+@incollection{cgal:ass-psp-15b
+, author = "Pierre Alliez and Cl{\'e}ment Jamin and Quentin M{\'e}rigot and Jocelyn Meyron and Laurent Saboret and Nader Salman and Shihao Wu"
+, title = "Point Set Processing"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPointSetProcessingSummary"
+, year = 2015
+}
+
+@incollection{cgal:ovja-pssd-15b
+, author = "Sven Oesau and Yannick Verdie and Cl{\'e}ment Jamin and Pierre Alliez"
+, title = "Point Set Shape Detection"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPointSetShapeDetection3Summary"
+, year = 2015
+}
+
+@incollection{cgal:m-ps-15b
+, author = "Abdelkrim Mebarki"
+, title = "{2D} Placement of Streamlines"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPlacementOfStreamlines2Summary"
+, year = 2015
+}
+
+@incollection{cgal:b-ss2-15b
+, author = "Matthias B{\"a}sken"
+, title = "{2D} Range and Neighbor Search"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPointSet2Summary"
+, year = 2015
+}
+
+@incollection{cgal:f-isl-15b
+, author = "Andreas Fabri"
+, title = "Interval Skip List"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgIntervalSkipListSummary"
+, year = 2015
+}
+
+@incollection{cgal:tf-ssd-15b
+, author = "Hans Tangelder and Andreas Fabri"
+, title = "{dD} Spatial Searching"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSpatialSearchingDSummary"
+, year = 2015
+}
+
+@incollection{cgal:n-rstd-15b
+, author = "Gabriele Neyer"
+, title = "{dD} Range and Segment Trees"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgRangeSegmentTreesDSummary"
+, year = 2015
+}
+
+@incollection{cgal:kmz-isiobd-15b
+, author = "Lutz Kettner and Andreas Meyer and Afra Zomorodian"
+, title = "Intersecting Sequences of {dD} Iso-oriented Boxes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgBoxIntersectionDSummary"
+, year = 2015
+}
+
+@incollection{cgal:atw-aabb-15b
+, author = "Pierre Alliez and St{\'e}phane Tayeb and Camille Wormser"
+, title = "{3D} Fast Intersection and Distance Computation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgAABB_treeSummary"
+, year = 2015
+}
+
+@incollection{cgal:dd-ss-15b
+, author = "Christophe Delage and Olivier Devillers"
+, title = "Spatial Sorting"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgSpatialSortingSummary"
+, year = 2015
+}
+
+@incollection{cgal:fghhs-bv-15b
+, author = "Kaspar Fischer and Bernd G{\"a}rtner and Thomas Herrmann and Michael Hoffmann and Sven Sch{\"o}nherr"
+, title = "Bounding Volumes"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgBoundingVolumesSummary"
+, year = 2015
+}
+
+@incollection{cgal:hp-ia-15b
+, author = "Michael Hoffmann and Eli Packer"
+, title = "Inscribed Areas"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgInscribedAreasSummary"
+, year = 2015
+}
+
+@incollection{cgal:fghhs-od-15b
+, author = "Kaspar Fischer and Bernd G{\"a}rtner and Thomas Herrmann and Michael Hoffmann and Sven Sch{\"o}nherr"
+, title = "Optimal Distances"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgOptimalDistancesSummary"
+, year = 2015
+}
+
+@incollection{cgal:ap-pcad-15b
+, author = "Pierre Alliez and Sylvain Pion and Ankit Gupta"
+, title = "Principal Component Analysis"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgPrincipalComponentAnalysisDSummary"
+, year = 2015
+}
+
+@incollection{cgal:f-i-15b
+, author = "Julia Fl{\"o}totto"
+, title = "{2D} and Surface Function Interpolation"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgInterpolation2Summary"
+, year = 2015
+}
+
+@incollection{cgal:abha-gbc-15b
+, author = "Dmitry Anisimov and David Bommes and Kai Hormann and Pierre Alliez"
+, title = "{2D} Generalized Barycentric Coordinates"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgBarycentric_coordinates_2Summary"
+, year = 2015
+}
+
+@incollection{cgal:r-kds-15b
+, author = "Daniel Russel"
+, title = "Kinetic Data Structures"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgKdsSummary"
+, year = 2015
+}
+
+@incollection{cgal:r-kdsf-15b
+, author = "Daniel Russel"
+, title = "Kinetic Framework"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgKdsFrameworkSummary"
+, year = 2015
+}
+
+@incollection{cgal:hkpw-se-15b
+, author = "Michael Hoffmann and Lutz Kettner and Sylvain Pion and Ron Wein"
+, title = "STL Extensions for {CGAL}"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgStlExtensionSummary"
+, year = 2015
+}
+
+@incollection{cgal:cfw-cbgl-15b
+, author = "Andreas Fabri and Fernando Cacciola and Philipp Moeller and Ron Wein"
+, title = "{CGAL} and the {Boost} Graph Library"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgBGLSummary"
+, year = 2015
+}
+
+@incollection{cgal:fs-cbpm-15b
+, author = "Andreas Fabri and Laurent Saboret"
+, title = "{CGAL} and {Boost} Property Maps"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgProperty_mapSummary"
+, year = 2015
+}
+
+@incollection{cgal:dksy-hc-15b
+, author = "Olivier Devillers and Lutz Kettner and Sylvain Pion and Michael Seel and Mariette Yvinec"
+, title = "Handles and Circulators"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgHandlesAndCirculatorsSummary"
+, year = 2015
+}
+
+@incollection{cgal:dhhk-gog-15b
+, author = "Pedro M. M. de Castro and Olivier Devillers and Susan Hert and Michael Hoffmann and Lutz Kettner and Sven Sch{\"o}nherr and Alexandru Tifrea"
+, title = "Geometric Object Generators"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgGeneratorsSummary"
+, year = 2015
+}
+
+@incollection{cgal:kps-pthum-15b
+, author = "Lutz Kettner and Sylvain Pion and Michael Seel"
+, title = "Profiling tools, Hash Map, Union-find, Modifiers"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgProfilingToolsSummary"
+, year = 2015
+}
+
+@incollection{cgal:fgk-ios-12-15b
+, author = "Andreas Fabri and Geert-Jan Giezeman and Lutz Kettner"
+, title = "IO Streams"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgIOstreamsSummary"
+, year = 2015
+}
+
+@incollection{cgal:fp-gv-15b
+, author = "Andreas Fabri and Sylvain Pion"
+, title = "Geomview"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgGeomviewSummary"
+, year = 2015
+}
+
+@incollection{cgal:fr-cqgvf-15b
+, author = "Andreas Fabri and Laurent Rineau"
+, title = "{CGAL} and the {Qt} Graphics View Framework"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgGraphicsViewSummary"
+, year = 2015
+}
+
+@incollection{cgal:lp-gi-15b
+, author = "Olivier Devillers and S{\'e}bastien Loriot and Sylvain Pion"
+, title = "{CGAL} Ipelets"
+, publisher = "{CGAL Editorial Board}"
+, edition = "{4.7}"
+, booktitle = "{CGAL} User and Reference Manual"
+, url = "http://doc.cgal.org/4.7/Manual/packages.html#PkgCGALIpeletsSummary"
+, year = 2015
+}
diff --git a/biblio/how_to_cite_gudhi.bib b/biblio/how_to_cite_gudhi.bib
index 851dd5d9..c899d9fc 100644
--- a/biblio/how_to_cite_gudhi.bib
+++ b/biblio/how_to_cite_gudhi.bib
@@ -42,3 +42,12 @@
, year = 2015
}
+@incollection{gudhi:Alpha complex
+, author = "Vincent Rouvreau"
+, title = "Alpha complex"
+, publisher = "{GUDHI Editorial Board}"
+, booktitle = "{GUDHI} User and Reference Manual"
+, url = "http://gudhi.gforge.inria.fr/doc/latest/group__alpha__complex.html"
+, year = 2015
+}
+
diff --git a/data/bitmap/2d_torus.txt b/data/bitmap/2d_torus.txt
new file mode 100644
index 00000000..8ccd45c6
--- /dev/null
+++ b/data/bitmap/2d_torus.txt
@@ -0,0 +1,12 @@
+2
+-3
+-3
+0
+0
+0
+0
+10
+0
+0
+0
+0
diff --git a/data/bitmap/3d_torus.txt b/data/bitmap/3d_torus.txt
new file mode 100644
index 00000000..896e6c61
--- /dev/null
+++ b/data/bitmap/3d_torus.txt
@@ -0,0 +1,31 @@
+3
+-3
+-3
+-3
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+10
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/data/bitmap/CubicalOneSphere.txt b/data/bitmap/CubicalOneSphere.txt
new file mode 100644
index 00000000..4dec3fc6
--- /dev/null
+++ b/data/bitmap/CubicalOneSphere.txt
@@ -0,0 +1,12 @@
+2
+3
+3
+0
+0
+0
+0
+100
+0
+0
+0
+0
diff --git a/data/bitmap/CubicalTwoSphere.txt b/data/bitmap/CubicalTwoSphere.txt
new file mode 100644
index 00000000..32f5d933
--- /dev/null
+++ b/data/bitmap/CubicalTwoSphere.txt
@@ -0,0 +1,31 @@
+3
+3
+3
+3
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+100
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/data/points/alphacomplexdoc.off b/data/points/alphacomplexdoc.off
new file mode 100755
index 00000000..bb790193
--- /dev/null
+++ b/data/points/alphacomplexdoc.off
@@ -0,0 +1,10 @@
+nOFF
+2 7 0 0
+1.0 1.0
+7.0 0.0
+4.0 6.0
+9.0 6.0
+0.0 14.0
+2.0 19.0
+9.0 17.0
+
diff --git a/scripts/generate_version.sh b/scripts/generate_version.sh
index 84232a00..bf30f101 100755
--- a/scripts/generate_version.sh
+++ b/scripts/generate_version.sh
@@ -44,8 +44,6 @@ echo $VERSION_DIR
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
@@ -55,11 +53,11 @@ 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/CMakeGUDHIVersion.txt $VERSION_DIR
cp $ROOT_DIR/GUDHIVersion.cmake.in $VERSION_DIR
# PACKAGE LEVEL COPY
PACKAGE_INC_DIR="/include"
-#PACKAGE_SRC_DIR="/source"
PACKAGE_EX_DIR="/example"
PACKAGE_CONCEPT_DIR="/concept"
PACKAGE_DOC_DIR="/doc"
diff --git a/src/Alpha_complex/doc/Intro_alpha_complex.h b/src/Alpha_complex/doc/Intro_alpha_complex.h
new file mode 100644
index 00000000..226bb257
--- /dev/null
+++ b/src/Alpha_complex/doc/Intro_alpha_complex.h
@@ -0,0 +1,168 @@
+/* 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 DOC_ALPHA_COMPLEX_INTRO_ALPHA_COMPLEX_H_
+#define DOC_ALPHA_COMPLEX_INTRO_ALPHA_COMPLEX_H_
+
+// needs namespace for Doxygen to link on classes
+namespace Gudhi {
+// needs namespace for Doxygen to link on classes
+namespace alphacomplex {
+
+/** \defgroup alpha_complex Alpha complex
+ *
+ * \author Vincent Rouvreau
+ *
+ * @{
+ *
+ * \section definition Definition
+ *
+ * Alpha_complex is a <a target="_blank" href="https://en.wikipedia.org/wiki/Simplicial_complex">simplicial complex</a>
+ * constructed from the finite cells of a Delaunay Triangulation.
+ *
+ * The filtration value of each simplex is computed as the square of the circumradius of the simplex if the circumsphere is empty (the simplex is then said to be Gabriel), and as the minimum of the filtration
+ * values of the codimension 1 cofaces that make it not Gabriel otherwise.
+ *
+ * All simplices that have a filtration value strictly greater than a given alpha squared value are not inserted into
+ * the complex.
+ *
+ * \image html "alpha_complex_representation.png" "Alpha-complex representation"
+ *
+ * Alpha_complex is constructing a `Simplex_tree` using <a target="_blank"
+ * href="http://doc.cgal.org/latest/Triangulation/index.html#Chapter_Triangulations">Delaunay Triangulation</a>
+ * \cite cgal:hdj-t-15b from <a target="_blank" href="http://www.cgal.org/">CGAL</a> (the Computational Geometry
+ * Algorithms Library \cite cgal:eb-15b).
+ *
+ * The complex is a template class requiring an Epick_d <a target="_blank"
+ * href="http://doc.cgal.org/latest/Kernel_d/index.html#Chapter_dD_Geometry_Kernel">dD Geometry Kernel</a>
+ * \cite cgal:s-gkd-15b from CGAL as template parameter.
+ *
+ * \remark When Alpha_complex is constructed with an infinite value of alpha, the complex is a Delaunay complex.
+ *
+ * \section pointsexample Example from points
+ *
+ * This example builds the Delaunay triangulation from the given points in a 2D static kernel, and initializes the
+ * alpha complex with it.
+ *
+ * Then, it is asked to display information about the alpha complex.
+ *
+ * \include Alpha_complex/Alpha_complex_from_points.cpp
+ *
+ * When launching:
+ *
+ * \code $> ./alphapoints
+ * \endcode
+ *
+ * the program output is:
+ *
+ * \include Alpha_complex/alphaoffreader_for_doc_60.txt
+ *
+ * \section algorithm Algorithm
+ *
+ * \subsection datastructure Data structure
+ *
+ * In order to build the alpha complex, first, a Simplex tree is built from the cells of a Delaunay Triangulation.
+ * (The filtration value is set to NaN, which stands for unknown value):
+ * \image html "alpha_complex_doc.png" "Simplex tree structure construction example"
+ *
+ * \subsection filtrationcomputation Filtration value computation algorithm
+ *
+ * \f{algorithm}{
+ * \caption{Filtration value computation algorithm}\label{alpha}
+ * \begin{algorithmic}
+ * \For{i : dimension $\rightarrow$ 0}
+ * \ForAll{$\sigma$ of dimension i}
+ * \If {filtration($\sigma$) is NaN}
+ * \State filtration($\sigma$) = $\alpha^2(\sigma)$
+ * \EndIf
+ * \ForAll{$\tau$ face of $\sigma$} \Comment{propagate alpha filtration value}
+ * \If {filtration($\tau$) is not NaN}
+ * \State filtration($\tau$) = min (filtration($\tau$), filtration($\sigma$))
+ * \Else
+ * \If {$\tau$ is not Gabriel for $\sigma$}
+ * \State filtration($\tau$) = filtration($\sigma$)
+ * \EndIf
+ * \EndIf
+ * \EndFor
+ * \EndFor
+ * \EndFor
+ * \State make\_filtration\_non\_decreasing()
+ * \State prune\_above\_filtration()
+ * \end{algorithmic}
+ * \f}
+ *
+ * \subsubsection dimension2 Dimension 2
+ *
+ * From the example above, it means the algorithm looks into each triangle ([0,1,2], [0,2,4], [1,2,3], ...),
+ * computes the filtration value of the triangle, and then propagates the filtration value as described
+ * here :
+ * \image html "alpha_complex_doc_420.png" "Filtration value propagation example"
+ *
+ * \subsubsection dimension1 Dimension 1
+ *
+ * Then, the algorithm looks into each edge ([0,1], [0,2], [1,2], ...),
+ * computes the filtration value of the edge (in this case, propagation will have no effect).
+ *
+ * \subsubsection dimension0 Dimension 0
+ *
+ * Finally, the algorithm looks into each vertex ([0], [1], [2], [3], [4], [5] and [6]) and
+ * sets the filtration value (0 in case of a vertex - propagation will have no effect).
+ *
+ * \subsubsection nondecreasing Non decreasing filtration values
+ *
+ * As the squared radii computed by CGAL are an approximation, it might happen that these alpha squared values do not quite define a proper filtration (i.e. non-decreasing with respect to inclusion).
+ * We fix that up by calling `Simplex_tree::make_filtration_non_decreasing()`.
+ *
+ * \subsubsection pruneabove Prune above given filtration value
+ *
+ * The simplex tree is pruned from the given maximum alpha squared value (cf. `Simplex_tree::prune_above_filtration()`).
+ * In the following example, the value is given by the user as argument of the program.
+ *
+ *
+ * \section offexample Example from OFF file
+ *
+ * This example builds the Delaunay triangulation in a dynamic kernel, and initializes the alpha complex with it.
+ *
+ *
+ * Then, it is asked to display information about the alpha complex.
+ *
+ * \include Alpha_complex/Alpha_complex_from_off.cpp
+ *
+ * When launching:
+ *
+ * \code $> ./alphaoffreader ../../data/points/alphacomplexdoc.off 32.0
+ * \endcode
+ *
+ * the program output is:
+ *
+ * \include Alpha_complex/alphaoffreader_for_doc_32.txt
+ *
+ * \copyright GNU General Public License v3.
+ * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
+ */
+/** @} */ // end defgroup alpha_complex
+
+} // namespace alphacomplex
+
+} // namespace Gudhi
+
+#endif // DOC_ALPHA_COMPLEX_INTRO_ALPHA_COMPLEX_H_
diff --git a/src/Alpha_complex/doc/alpha_complex_doc.ipe b/src/Alpha_complex/doc/alpha_complex_doc.ipe
new file mode 100644
index 00000000..baf0d26a
--- /dev/null
+++ b/src/Alpha_complex/doc/alpha_complex_doc.ipe
@@ -0,0 +1,595 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70107" creator="Ipe 7.1.10">
+<info created="D:20150603143945" modified="D:20160406112209"/>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+0.5 0 0 0.5 0 0 e
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+-0.5 -0.5 m
+0.5 -0.5 l
+0.5 0.5 l
+-0.5 0.5 l
+h
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="small" value="\small"/>
+<textsize name="tiny" value="\tiny"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" matrix="1 0 0 1 -240 0" stroke="darkcyan">
+320 580 m
+350 520 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -240 0" stroke="darkcyan">
+320 580 m
+280 660 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -240 0" stroke="darkcyan">
+320 580 m
+370 580 l
+350 520 l
+320 580 l
+</path>
+<text matrix="1 0 0 1 -260 0" transformations="translations" pos="380 530" stroke="darkcyan" type="label" width="118.196" height="8.307" depth="2.32" valign="baseline" size="large">Delaunay triangulation</text>
+<text matrix="1 0 0 1 -242.155 -3.50128" transformations="translations" pos="282.952 524.893" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 -240 0" transformations="translations" pos="352.708 510.349" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<text matrix="1 0 0 1 -240 0" transformations="translations" pos="310.693 578.759" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text matrix="1 0 0 1 -240 0" transformations="translations" pos="375.332 578.49" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 -240 0" transformations="translations" pos="272.179 660.635" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 -239.3 -10.1537" transformations="translations" pos="296.419 724.197" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 -240 0" transformations="translations" pos="375.332 689.453" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 -240 0" stroke="darkcyan">
+280 660 m
+300 710 l
+370 690 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 -240 0" stroke="darkcyan">
+320 580 m
+370 690 l
+370 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -240 0" stroke="darkcyan">
+280 660 m
+370 690 l
+320 580 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 104.05 -60.1773" stroke="black">
+4 0 0 4 320 704 e
+</path>
+<path matrix="1 0 0 1 104.05 -60.1773" stroke="black">
+322.919 706.788 m
+317.189 701.058 l
+317.189 701.203 l
+</path>
+<path matrix="1 0 0 1 104.05 -60.1773" stroke="black">
+317.551 706.934 m
+322.629 701.058 l
+</path>
+<path matrix="1 0 0 1 50 0" stroke="black">
+240 620 m
+220 600 l
+</path>
+<path matrix="1 0 0 1 50 0" stroke="black">
+240 620 m
+220 640 l
+</path>
+<text transformations="translations" pos="180 620" stroke="black" type="label" width="97.274" height="6.926" depth="1.93" valign="baseline">Simplex tree structure</text>
+<path stroke="black">
+280 630 m
+170 630 l
+</path>
+<path stroke="black">
+280 610 m
+170 610 l
+</path>
+<use matrix="1 0 0 1 -239.3 -10.1537" name="mark/fdisk(sfx)" pos="300 720" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -240 0" name="mark/fdisk(sfx)" pos="370 690" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -240 0" name="mark/fdisk(sfx)" pos="280 660" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -240 0" name="mark/fdisk(sfx)" pos="320 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -240 0" name="mark/fdisk(sfx)" pos="370 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -240 0" name="mark/fdisk(sfx)" pos="350 520" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -240 0" name="mark/fdisk(sfx)" pos="290 530" size="normal" stroke="black" fill="white"/>
+<text matrix="1 0 0 1 4 -96" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<path matrix="1 0 0 1 4 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 24 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<path matrix="1 0 0 1 36 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<path matrix="1 0 0 1 24 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 24 -76" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 12 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<path matrix="1 0 0 1 12 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<path matrix="1 0 0 1 24 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 12 -96" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 64 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<path matrix="1 0 0 1 64 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 52 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<path matrix="1 0 0 1 52 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 36 -96" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 104 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 104 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 92 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<path matrix="1 0 0 1 92 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<path matrix="1 0 0 1 96 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 84 -96" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<text matrix="1 0 0 1 148 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 148 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 136 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<path matrix="1 0 0 1 136 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<path matrix="1 0 0 1 120 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 108 -76" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 120 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 108 -76" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+292 716 m
+292 728 l
+316 728 l
+316 716 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+316 716 m
+316 728 l
+340 728 l
+340 716 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+340 716 m
+340 728 l
+364 728 l
+364 716 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+364 716 m
+364 728 l
+388 728 l
+388 716 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+388 716 m
+388 728 l
+412 728 l
+412 716 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+412 716 m
+412 728 l
+436 728 l
+436 716 l
+h
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+436 716 m
+436 728 l
+460 728 l
+460 716 l
+h
+</path>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="304 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="328 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="352 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="376 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="400 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="424 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 48 -96" transformations="translations" pos="448 720" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 -12 -96" stroke="black">
+436 708 m
+436 716 l
+</path>
+<path matrix="1 0 0 1 28 -96" stroke="black">
+364 708 m
+364 716 l
+</path>
+<path matrix="1 0 0 1 36 -96" stroke="black">
+364 688 m
+364 696 l
+</path>
+<path matrix="1 0 0 1 36 -96" stroke="black">
+320 688 m
+320 696 l
+</path>
+<path matrix="1 0 0 1 36 -96" stroke="black">
+296 708 m
+308 716 l
+308 716 l
+</path>
+<path matrix="1 0 0 1 48 -96" stroke="black">
+264 688 m
+268 696 l
+</path>
+<path matrix="1 0 0 1 40 -96" stroke="black">
+292 688 m
+292 696 l
+</path>
+<path matrix="1 0 0 1 36 -96" stroke="black">
+388 736 m
+388 728 l
+</path>
+<path stroke="black">
+372 612 m
+376 620 l
+</path>
+<path stroke="black">
+448 612 m
+448 620 l
+</path>
+<text matrix="1 0 0 1 80 -76" transformations="translations" pos="304 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<path matrix="1 0 0 1 80 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<path matrix="1 0 0 1 80 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 68 -96" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 24 -96" stroke="black">
+364 688 m
+364 696 l
+</path>
+<path matrix="1 0 0 1 136 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 124 -96" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 136 -96" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 124 -96" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 4 -116" stroke="black">
+436 708 m
+436 716 l
+</path>
+<path matrix="1 0 0 1 168 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 156 -76" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 168 -76" stroke="black">
+300 688 m
+300 676 l
+312 676 l
+312 688 l
+h
+</path>
+<text matrix="1 0 0 1 156 -76" transformations="translations" pos="316 680" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 36 -96" stroke="black">
+436 708 m
+436 716 l
+</path>
+</page>
+</ipe>
diff --git a/src/Alpha_complex/doc/alpha_complex_doc.png b/src/Alpha_complex/doc/alpha_complex_doc.png
new file mode 100644
index 00000000..0b6201da
--- /dev/null
+++ b/src/Alpha_complex/doc/alpha_complex_doc.png
Binary files differ
diff --git a/src/Alpha_complex/doc/alpha_complex_doc_420.ipe b/src/Alpha_complex/doc/alpha_complex_doc_420.ipe
new file mode 100644
index 00000000..5d1d29d4
--- /dev/null
+++ b/src/Alpha_complex/doc/alpha_complex_doc_420.ipe
@@ -0,0 +1,514 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70107" creator="Ipe 7.1.10">
+<info created="D:20150603143945" modified="D:20151130095019"/>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+0.5 0 0 0.5 0 0 e
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+-0.5 -0.5 m
+0.5 -0.5 l
+0.5 0.5 l
+-0.5 0.5 l
+h
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="small" value="\small"/>
+<textsize name="tiny" value="\tiny"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" matrix="1 0 0 1 0 80" stroke="lightgray">
+320 580 m
+350 520 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 0 80" stroke="darkcyan" pen="heavier">
+320 580 m
+280 660 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 0 80" stroke="lightgray">
+320 580 m
+370 580 l
+350 520 l
+320 580 l
+</path>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="380 530" stroke="darkcyan" type="label" width="54.628" height="8.965" depth="2.99" valign="baseline" size="large">Cell [4,2,0]</text>
+<text matrix="1 0 0 1 -2.15463 76.4987" transformations="translations" pos="282.952 524.893" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="352.708 510.349" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="310.693 578.759" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="375.332 578.49" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="272.179 660.635" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 0.700256 69.8463" transformations="translations" pos="296.419 724.197" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="375.332 689.453" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 0 80" stroke="lightgray">
+280 660 m
+300 710 l
+370 690 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 0 80" stroke="lightgray">
+320 580 m
+370 690 l
+370 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 0 80" stroke="lightgray">
+280 660 m
+370 690 l
+320 580 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 0 80" stroke="darkcyan">
+77.2727 0 0 77.2727 243.636 591.818 e
+</path>
+<path matrix="1 0 0 1 0 80" stroke="darkcyan">
+243.428 591.569 m
+186.061 643.28 l
+</path>
+<text matrix="1 0 0 1 0 80" transformations="translations" pos="212.724 627.389" stroke="darkcyan" type="label" width="18.785" height="4.294" depth="1.49" valign="baseline">$\alpha_{420}$</text>
+<path matrix="1 0 0 1 -264 -162" stroke="lightgray">
+320 580 m
+350 520 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -264 -162" stroke="lightgray">
+320 580 m
+280 660 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -264 -162" stroke="lightgray">
+320 580 m
+370 580 l
+350 520 l
+320 580 l
+</path>
+<text matrix="0.582962 0 0 1 -211.265 -209.555" transformations="translations" pos="380 530" stroke="darkcyan" type="label" width="231.798" height="8.965" depth="2.99" valign="baseline" size="large">[2,0] is Gabriel $\rightarrow$ $\alpha_{20}$ is not$\\$
+modified (NaN)
+</text>
+<text matrix="1 0 0 1 -266.155 -165.501" transformations="translations" pos="282.952 524.893" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 -264 -162" transformations="translations" pos="310.693 578.759" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text matrix="1 0 0 1 -264 -162" transformations="translations" pos="375.332 578.49" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 -264 -172" transformations="translations" pos="272.179 660.635" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 -263.3 -172.154" transformations="translations" pos="296.419 724.197" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 -264 -162" transformations="translations" pos="375.332 689.453" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 -264 -162" stroke="lightgray">
+280 660 m
+300 710 l
+370 690 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 -264 -162" stroke="lightgray">
+320 580 m
+370 690 l
+370 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -264 -162" stroke="lightgray">
+280 660 m
+370 690 l
+320 580 l
+280 660 l
+</path>
+<text matrix="1 0 0 1 -166.834 -240.52" transformations="translations" pos="212.724 627.389" stroke="darkcyan" type="label" width="14.814" height="4.294" depth="1.49" valign="baseline">$\alpha_{20}$</text>
+<path matrix="1 0 0 1 -264 -162" stroke="darkcyan" pen="heavier">
+290 530 m
+320 580 l
+</path>
+<path matrix="1 0 0 1 -264 -162" stroke="darkcyan">
+29.1548 0 0 29.1548 305 555 e
+</path>
+<path matrix="1 0 0 1 -264 -162" stroke="darkcyan">
+304.883 555.015 m
+334.509 555.015 l
+</path>
+<path matrix="1 0 0 1 -37.2997 -163.65" stroke="lightgray">
+320 580 m
+350 520 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -38 -164" stroke="lightgray">
+320 580 m
+280 660 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -38 -164" stroke="lightgray">
+320 580 m
+370 580 l
+350 520 l
+320 580 l
+</path>
+<text matrix="1 0 0 1 -199.21 -189.117" transformations="translations" pos="380 530" stroke="darkred" type="label" width="168.308" height="8.965" depth="2.99" valign="baseline" size="large">[0,4] is not Gabriel $\rightarrow$ $\alpha_{40} = \alpha_{420}$</text>
+<text matrix="1 0 0 1 -40.1546 -167.501" transformations="translations" pos="282.952 524.893" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 -38 -164" transformations="translations" pos="375.332 578.49" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 -37.2997 -174.154" transformations="translations" pos="296.419 724.197" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 -38 -164" transformations="translations" pos="375.332 689.453" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 -38 -164" stroke="lightgray">
+280 660 m
+300 710 l
+370 690 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 -38 -164" stroke="lightgray">
+320 580 m
+370 690 l
+370 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 -38 -164" stroke="lightgray">
+280 660 m
+370 690 l
+320 580 l
+280 660 l
+</path>
+<text matrix="1 0 0 1 52.4654 -193.97" transformations="translations" pos="212.724 627.389" stroke="darkcyan" type="label" width="14.814" height="4.294" depth="1.49" valign="baseline">$\alpha_{40}$</text>
+<path matrix="1 0 0 1 -38 -164" stroke="darkcyan" pen="heavier">
+290 530 m
+280 660 l
+</path>
+<path matrix="1 0 0 1 126 -162" stroke="lightgray">
+320 580 m
+350 520 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 126 -162" stroke="lightgray">
+320 580 m
+280 660 l
+290 530 l
+320 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 126 -162" stroke="lightgray">
+320 580 m
+370 580 l
+350 520 l
+320 580 l
+</path>
+<text matrix="1 0 0 1 123.845 -165.501" transformations="translations" pos="282.952 524.893" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 126 -162" transformations="translations" pos="352.708 510.349" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<text matrix="1 0 0 1 126 -162" transformations="translations" pos="310.693 578.759" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text matrix="1 0 0 1 126 -162" transformations="translations" pos="375.332 578.49" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 126.7 -172.154" transformations="translations" pos="296.419 724.197" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 126 -162" transformations="translations" pos="375.332 689.453" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 126 -162" stroke="lightgray">
+280 660 m
+300 710 l
+370 690 l
+280 660 l
+</path>
+<path matrix="1 0 0 1 126 -162" stroke="lightgray">
+320 580 m
+370 690 l
+370 580 l
+320 580 l
+</path>
+<path matrix="1 0 0 1 126 -162" stroke="lightgray">
+280 660 m
+370 690 l
+320 580 l
+280 660 l
+</path>
+<text matrix="1 0 0 1 225.859 -165.729" transformations="translations" pos="212.724 627.389" stroke="darkcyan" type="label" width="14.814" height="4.294" depth="1.49" valign="baseline">$\alpha_{42}$</text>
+<text matrix="1 0 0 1 122 -164" transformations="translations" pos="272.179 660.635" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<path stroke="darkcyan" pen="heavier">
+406.093 497.775 m
+446.094 418.092 l
+</path>
+<path stroke="darkcyan">
+44.5799 0 0 44.5799 425.934 457.774 e
+</path>
+<path stroke="darkcyan">
+425.854 457.774 m
+470.795 457.774 l
+</path>
+<text matrix="1 0 0 1 -48.9756 -209.799" transformations="translations" pos="380 530" stroke="darkcyan" type="label" width="231.798" height="8.965" depth="2.99" valign="baseline" size="large">[2,4] is Gabriel $\rightarrow$ $\alpha_{42}$ is not modified (NaN)
+</text>
+<path stroke="darkblue" arrow="normal/normal">
+205.028 596.091 m
+110.946 544.02 l
+</path>
+<path stroke="darkblue" arrow="normal/normal">
+280.768 588.99 m
+280.768 547.57 l
+</path>
+<path stroke="darkblue" arrow="normal/normal">
+341.123 594.316 m
+413.904 554.079 l
+</path>
+<text matrix="1 0 0 1 39.645 -2.36686" transformations="translations" pos="199.703 569.464" stroke="darkblue" type="label" width="93.206" height="7.473" depth="2.49" valign="baseline">For all faces of [4,2,0]</text>
+<text matrix="1 0 0 1 -93.391 2.68003" transformations="translations" pos="104.437 300.174" stroke="black" type="label" width="208.621" height="6.926" depth="1.93" valign="baseline">N.B. : is Gabriel on a single point has no sense.</text>
+<text matrix="1 0 0 1 -36.9231 10" transformations="translations" pos="48 784" stroke="black" type="label" width="118.324" height="7.473" depth="2.49" valign="baseline">Dimension =2 - $\sigma$ = [4,2,0]</text>
+<path stroke="darkcyan">
+247.333 430.892 m
+311.764 430.892 l
+</path>
+<use matrix="1 0 0 1 0.700256 69.8463" name="mark/fdisk(sfx)" pos="300 720" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="370 690" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="280 660" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="243.636 591.818" size="normal" stroke="darkcyan" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="370 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="350 520" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="320 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 0 80" name="mark/fdisk(sfx)" pos="290 530" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -263.3 -172.154" name="mark/fdisk(sfx)" pos="300 720" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="280 660" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="370 690" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="370 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="350 520" size="normal" stroke="black" fill="white"/>
+<text matrix="1 0 0 1 -264 -162" transformations="translations" pos="352.708 510.349" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="305 555" size="normal" stroke="darkcyan" fill="white"/>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="290 530" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -264 -162" name="mark/fdisk(sfx)" pos="320 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -37.2997 -174.154" name="mark/fdisk(sfx)" pos="300 720" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -38 -164" name="mark/fdisk(sfx)" pos="370 690" size="normal" stroke="black" fill="white"/>
+<text matrix="1 0 0 1 -38 -164" transformations="translations" pos="272.179 660.635" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<use name="mark/fdisk(sfx)" pos="247 431" size="normal" stroke="darkcyan" fill="white"/>
+<use matrix="1 0 0 1 -38 -164" name="mark/fdisk(sfx)" pos="350 520" size="normal" stroke="black" fill="white"/>
+<text matrix="1 0 0 1 -38 -164" transformations="translations" pos="352.708 510.349" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<use matrix="1 0 0 1 -38 -164" name="mark/fdisk(sfx)" pos="370 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -38 -164" name="mark/fdisk(sfx)" pos="320 580" size="normal" stroke="darkred" fill="white"/>
+<text matrix="1 0 0 1 -38 -164" transformations="translations" pos="310.693 578.759" stroke="darkred" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<path matrix="1 0 0 1 -38 -164" stroke="darkred" pen="heavier">
+65.192 0 0 65.192 285 595 e
+</path>
+<use matrix="1 0 0 1 -38 -164" name="mark/fdisk(sfx)" pos="290 530" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 126 -162" name="mark/fdisk(sfx)" pos="290 530" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 126.7 -172.154" name="mark/fdisk(sfx)" pos="300 720" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 126 -162" name="mark/fdisk(sfx)" pos="370 690" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 126 -162" name="mark/fdisk(sfx)" pos="280 660" size="normal" stroke="black" fill="white"/>
+<use name="mark/fdisk(sfx)" pos="425.934 457.774" size="normal" stroke="darkcyan" fill="white"/>
+<use matrix="1 0 0 1 126 -162" name="mark/fdisk(sfx)" pos="320 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 126 -162" name="mark/fdisk(sfx)" pos="370 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 126 -162" name="mark/fdisk(sfx)" pos="350 520" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -38 -164" name="mark/fdisk(sfx)" pos="280 660" size="normal" stroke="black" fill="white"/>
+</page>
+</ipe>
diff --git a/src/Alpha_complex/doc/alpha_complex_doc_420.png b/src/Alpha_complex/doc/alpha_complex_doc_420.png
new file mode 100644
index 00000000..ef7187f7
--- /dev/null
+++ b/src/Alpha_complex/doc/alpha_complex_doc_420.png
Binary files differ
diff --git a/src/Alpha_complex/doc/alpha_complex_representation.ipe b/src/Alpha_complex/doc/alpha_complex_representation.ipe
new file mode 100644
index 00000000..e8096b93
--- /dev/null
+++ b/src/Alpha_complex/doc/alpha_complex_representation.ipe
@@ -0,0 +1,321 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70107" creator="Ipe 7.1.10">
+<info created="D:20150603143945" modified="D:20160404172133"/>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+0.5 0 0 0.5 0 0 e
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+-0.5 -0.5 m
+0.5 -0.5 l
+0.5 0.5 l
+-0.5 0.5 l
+h
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="small" value="\small"/>
+<textsize name="tiny" value="\tiny"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" fill="lightblue">
+109.771 601.912 m
+159.595 601.797 l
+140.058 541.915 l
+h
+</path>
+<path fill="lightblue">
+79.8776 552.169 m
+109.756 601.699 l
+139.812 542.209 l
+h
+</path>
+<path fill="lightblue">
+69.8453 682.419 m
+159.925 712.208 l
+90.12 732.039 l
+h
+</path>
+<text matrix="1 0 0 1 -230.178 22.1775" transformations="translations" pos="380 530" stroke="seagreen" type="label" width="76.735" height="8.307" depth="2.32" valign="baseline" size="large">Alpha complex</text>
+<text matrix="1 0 0 1 -212.333 18.6762" transformations="translations" pos="282.952 524.893" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<text matrix="1 0 0 1 -210.178 22.1775" transformations="translations" pos="352.708 510.349" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<text matrix="1 0 0 1 -210.178 22.1775" transformations="translations" pos="310.693 578.759" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text matrix="1 0 0 1 -210.178 22.1775" transformations="translations" pos="375.332 578.49" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<text matrix="1 0 0 1 -210.178 22.1775" transformations="translations" pos="272.179 660.635" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<text matrix="1 0 0 1 -209.478 12.0238" transformations="translations" pos="296.419 724.197" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<text matrix="1 0 0 1 -210.178 22.1775" transformations="translations" pos="375.332 689.453" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 31.9779 -58.7483" stroke="darkgray">
+58.1341 0 0 58.1341 218.925 692.601 e
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+60 710 m
+40 660 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+40 660 m
+130 690 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+130 690 m
+60 710 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+40 660 m
+80 580 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+80 580 m
+130 580 l
+130 580 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+130 580 m
+110 520 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+110 520 m
+50 530 l
+50 530 l
+50 530 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+50 530 m
+80 580 l
+</path>
+<path matrix="1 0 0 1 29.8225 22.1775" stroke="black" pen="heavier">
+130 580 m
+130 690 l
+</path>
+<use matrix="1 0 0 1 142.618 -109.867" name="mark/fdisk(sfx)" pos="108.285 743.72" size="normal" stroke="darkgray" fill="white"/>
+<path matrix="1 0 0 1 142.618 -109.867" stroke="darkgray">
+108.275 743.531 m
+166.45 743.531 l
+</path>
+<text matrix="1 0 0 1 142.618 -109.867" transformations="translations" pos="127.397 746.763" stroke="darkgray" type="label" width="6.41" height="4.289" depth="0" valign="baseline">$\alpha$</text>
+<use matrix="1 0 0 1 -209.478 12.0238" name="mark/fdisk(sfx)" pos="300 720" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -210.178 22.1775" name="mark/fdisk(sfx)" pos="280 660" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -210.178 22.1775" name="mark/fdisk(sfx)" pos="370 690" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -210.178 22.1775" name="mark/fdisk(sfx)" pos="370 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -210.178 22.1775" name="mark/fdisk(sfx)" pos="290 530" size="normal" stroke="black" fill="white"/>
+<path matrix="1 0 0 1 -40 -8" stroke="black" pen="heavier">
+150.038 609.9 m
+179.929 549.727 l
+</path>
+<use matrix="1 0 0 1 -210.178 22.1775" name="mark/fdisk(sfx)" pos="320 580" size="normal" stroke="black" fill="white"/>
+<use matrix="1 0 0 1 -210.178 22.1775" name="mark/fdisk(sfx)" pos="350 520" size="normal" stroke="black" fill="white"/>
+</page>
+</ipe>
diff --git a/src/Alpha_complex/doc/alpha_complex_representation.png b/src/Alpha_complex/doc/alpha_complex_representation.png
new file mode 100644
index 00000000..7b81cd69
--- /dev/null
+++ b/src/Alpha_complex/doc/alpha_complex_representation.png
Binary files differ
diff --git a/src/Alpha_complex/example/Alpha_complex_from_off.cpp b/src/Alpha_complex/example/Alpha_complex_from_off.cpp
new file mode 100644
index 00000000..963ef5ca
--- /dev/null
+++ b/src/Alpha_complex/example/Alpha_complex_from_off.cpp
@@ -0,0 +1,56 @@
+#include <gudhi/Alpha_complex.h>
+#include <CGAL/Epick_d.h>
+
+#include <iostream>
+#include <string>
+
+void usage(int nbArgs, char * const progName) {
+ std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
+ std::cerr << "Usage: " << progName << " filename.off alpha_square_max_value [ouput_file.txt]\n";
+ std::cerr << " i.e.: " << progName << " ../../data/points/alphacomplexdoc.off 60.0\n";
+ exit(-1); // ----- >>
+}
+
+int main(int argc, char **argv) {
+ if ((argc != 3) && (argc != 4)) usage(argc, (argv[0] - 1));
+
+ std::string off_file_name(argv[1]);
+ double alpha_square_max_value = atof(argv[2]);
+
+ // ----------------------------------------------------------------------------
+ // Init of an alpha complex from an OFF file
+ // ----------------------------------------------------------------------------
+ typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
+ Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_name, alpha_square_max_value);
+
+ std::streambuf* streambufffer;
+ std::ofstream ouput_file_stream;
+
+ if (argc == 4) {
+ ouput_file_stream.open(std::string(argv[3]));
+ streambufffer = ouput_file_stream.rdbuf();
+ } else {
+ streambufffer = std::cout.rdbuf();
+ }
+
+ std::ostream output_stream(streambufffer);
+
+ // ----------------------------------------------------------------------------
+ // Display information about the alpha complex
+ // ----------------------------------------------------------------------------
+ output_stream << "Alpha complex is of dimension " << alpha_complex_from_file.dimension() <<
+ " - " << alpha_complex_from_file.num_simplices() << " simplices - " <<
+ alpha_complex_from_file.num_vertices() << " vertices." << std::endl;
+
+ output_stream << "Iterator on alpha complex simplices in the filtration order, with [filtration value]:" << std::endl;
+ for (auto f_simplex : alpha_complex_from_file.filtration_simplex_range()) {
+ output_stream << " ( ";
+ for (auto vertex : alpha_complex_from_file.simplex_vertex_range(f_simplex)) {
+ output_stream << vertex << " ";
+ }
+ output_stream << ") -> " << "[" << alpha_complex_from_file.filtration(f_simplex) << "] ";
+ output_stream << std::endl;
+ }
+ ouput_file_stream.close();
+ return 0;
+}
diff --git a/src/Alpha_complex/example/Alpha_complex_from_points.cpp b/src/Alpha_complex/example/Alpha_complex_from_points.cpp
new file mode 100644
index 00000000..cd17af1e
--- /dev/null
+++ b/src/Alpha_complex/example/Alpha_complex_from_points.cpp
@@ -0,0 +1,62 @@
+#include <CGAL/Epick_d.h>
+#include <gudhi/Alpha_complex.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <limits> // for numeric limits
+
+typedef CGAL::Epick_d< CGAL::Dimension_tag<2> > Kernel;
+typedef Kernel::Point_d Point;
+typedef std::vector<Point> Vector_of_points;
+
+void usage(int nbArgs, char * const progName) {
+ std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
+ std::cerr << "Usage: " << progName << " [alpha_square_max_value]\n";
+ std::cerr << " i.e.: " << progName << " 60.0\n";
+ exit(-1); // ----- >>
+}
+
+int main(int argc, char **argv) {
+ if ((argc != 1) && (argc != 2)) usage(argc, (argv[0] - 1));
+
+ // Delaunay complex if alpha_square_max_value is not given by the user.
+ double alpha_square_max_value = std::numeric_limits<double>::infinity();
+ if (argc == 2)
+ alpha_square_max_value = atof(argv[1]);
+
+ // ----------------------------------------------------------------------------
+ // Init of a list of points
+ // ----------------------------------------------------------------------------
+ Vector_of_points points;
+ points.push_back(Point(1.0, 1.0));
+ points.push_back(Point(7.0, 0.0));
+ points.push_back(Point(4.0, 6.0));
+ points.push_back(Point(9.0, 6.0));
+ points.push_back(Point(0.0, 14.0));
+ points.push_back(Point(2.0, 19.0));
+ points.push_back(Point(9.0, 17.0));
+
+ // ----------------------------------------------------------------------------
+ // Init of an alpha complex from the list of points
+ // ----------------------------------------------------------------------------
+ Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_points(points, alpha_square_max_value);
+
+ // ----------------------------------------------------------------------------
+ // Display information about the alpha complex
+ // ----------------------------------------------------------------------------
+ std::cout << "Alpha complex is of dimension " << alpha_complex_from_points.dimension() <<
+ " - " << alpha_complex_from_points.num_simplices() << " simplices - " <<
+ alpha_complex_from_points.num_vertices() << " vertices." << std::endl;
+
+ std::cout << "Iterator on alpha complex simplices in the filtration order, with [filtration value]:" << std::endl;
+ for (auto f_simplex : alpha_complex_from_points.filtration_simplex_range()) {
+ std::cout << " ( ";
+ for (auto vertex : alpha_complex_from_points.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << ") -> " << "[" << alpha_complex_from_points.filtration(f_simplex) << "] ";
+ std::cout << std::endl;
+ }
+ return 0;
+}
diff --git a/src/Alpha_complex/example/CMakeLists.txt b/src/Alpha_complex/example/CMakeLists.txt
new file mode 100644
index 00000000..f1346867
--- /dev/null
+++ b/src/Alpha_complex/example/CMakeLists.txt
@@ -0,0 +1,43 @@
+cmake_minimum_required(VERSION 2.6)
+project(GUDHIAlphaShapesExample)
+
+# need CGAL 4.7
+# cmake -DCGAL_DIR=~/workspace/CGAL-4.7-Ic-41 ../../..
+if(CGAL_FOUND)
+ if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ message(STATUS "CGAL version: ${CGAL_VERSION}.")
+
+ find_package(Eigen3 3.1.0)
+ if (EIGEN3_FOUND)
+ message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
+ include( ${EIGEN3_USE_FILE} )
+
+ add_executable ( alphapoints Alpha_complex_from_points.cpp )
+ target_link_libraries(alphapoints ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ add_executable ( alphaoffreader Alpha_complex_from_off.cpp )
+ target_link_libraries(alphaoffreader ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ if (TBB_FOUND)
+ target_link_libraries(alphapoints ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(alphaoffreader ${TBB_RELEASE_LIBRARY})
+ endif()
+
+ add_test(alphapoints ${CMAKE_CURRENT_BINARY_DIR}/alphapoints)
+ # Do not forget to copy test files in current binary dir
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ add_test(alphaoffreader_doc_60 ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader alphacomplexdoc.off 60.0 ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_result_60.txt)
+ add_test(alphaoffreader_doc_32 ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader alphacomplexdoc.off 32.0 ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_result_32.txt)
+ if (DIFF_PATH)
+ # Do not forget to copy test results files in current binary dir
+ file(COPY "alphaoffreader_for_doc_32.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+ file(COPY "alphaoffreader_for_doc_60.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+ add_test(alphaoffreader_doc_60_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_result_60.txt ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_for_doc_60.txt)
+ add_test(alphaoffreader_doc_32_diff_files ${DIFF_PATH} ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_result_32.txt ${CMAKE_CURRENT_BINARY_DIR}/alphaoffreader_for_doc_32.txt)
+ endif()
+ 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_complex/example/alphaoffreader_for_doc_32.txt b/src/Alpha_complex/example/alphaoffreader_for_doc_32.txt
new file mode 100644
index 00000000..13183e86
--- /dev/null
+++ b/src/Alpha_complex/example/alphaoffreader_for_doc_32.txt
@@ -0,0 +1,22 @@
+Alpha complex is of dimension 2 - 20 simplices - 7 vertices.
+Iterator on alpha complex simplices in the filtration order, with [filtration value]:
+ ( 0 ) -> [0]
+ ( 1 ) -> [0]
+ ( 2 ) -> [0]
+ ( 3 ) -> [0]
+ ( 4 ) -> [0]
+ ( 5 ) -> [0]
+ ( 6 ) -> [0]
+ ( 3 2 ) -> [6.25]
+ ( 5 4 ) -> [7.25]
+ ( 2 0 ) -> [8.5]
+ ( 1 0 ) -> [9.25]
+ ( 3 1 ) -> [10]
+ ( 2 1 ) -> [11.25]
+ ( 3 2 1 ) -> [12.5]
+ ( 2 1 0 ) -> [12.9959]
+ ( 6 5 ) -> [13.25]
+ ( 4 2 ) -> [20]
+ ( 6 4 ) -> [22.7367]
+ ( 6 5 4 ) -> [22.7367]
+ ( 6 3 ) -> [30.25]
diff --git a/src/Alpha_complex/example/alphaoffreader_for_doc_60.txt b/src/Alpha_complex/example/alphaoffreader_for_doc_60.txt
new file mode 100644
index 00000000..71f29a00
--- /dev/null
+++ b/src/Alpha_complex/example/alphaoffreader_for_doc_60.txt
@@ -0,0 +1,27 @@
+Alpha complex is of dimension 2 - 25 simplices - 7 vertices.
+Iterator on alpha complex simplices in the filtration order, with [filtration value]:
+ ( 0 ) -> [0]
+ ( 1 ) -> [0]
+ ( 2 ) -> [0]
+ ( 3 ) -> [0]
+ ( 4 ) -> [0]
+ ( 5 ) -> [0]
+ ( 6 ) -> [0]
+ ( 3 2 ) -> [6.25]
+ ( 5 4 ) -> [7.25]
+ ( 2 0 ) -> [8.5]
+ ( 1 0 ) -> [9.25]
+ ( 3 1 ) -> [10]
+ ( 2 1 ) -> [11.25]
+ ( 3 2 1 ) -> [12.5]
+ ( 2 1 0 ) -> [12.9959]
+ ( 6 5 ) -> [13.25]
+ ( 4 2 ) -> [20]
+ ( 6 4 ) -> [22.7367]
+ ( 6 5 4 ) -> [22.7367]
+ ( 6 3 ) -> [30.25]
+ ( 6 2 ) -> [36.5]
+ ( 6 3 2 ) -> [36.5]
+ ( 6 4 2 ) -> [37.2449]
+ ( 4 0 ) -> [59.7107]
+ ( 4 2 0 ) -> [59.7107]
diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h
new file mode 100644
index 00000000..ca2b68ca
--- /dev/null
+++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h
@@ -0,0 +1,415 @@
+/* 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 ALPHA_COMPLEX_H_
+#define ALPHA_COMPLEX_H_
+
+// to construct a simplex_tree from Delaunay_triangulation
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Debug_utils.h>
+// to construct Alpha_complex from a OFF file of points
+#include <gudhi/Points_off_io.h>
+
+#include <stdlib.h>
+#include <math.h> // isnan, fmax
+
+#include <CGAL/Delaunay_triangulation.h>
+#include <CGAL/Epick_d.h>
+#include <CGAL/Spatial_sort_traits_adapter_d.h>
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include <limits> // NaN
+#include <map>
+#include <utility> // std::pair
+#include <stdexcept>
+#include <numeric> // for std::iota
+
+namespace Gudhi {
+
+namespace alphacomplex {
+
+/**
+ * \class Alpha_complex Alpha_complex.h gudhi/Alpha_complex.h
+ * \brief Alpha complex data structure.
+ *
+ * \ingroup alpha_complex
+ *
+ * \details
+ * The data structure can be constructed from a CGAL Delaunay triangulation (for more informations on CGAL Delaunay
+ * triangulation, please refer to the corresponding chapter in page http://doc.cgal.org/latest/Triangulation/) or from
+ * an OFF file (cf. Points_off_reader).
+ *
+ * Please refer to \ref alpha_complex for examples.
+ *
+ * The complex is a template class requiring an Epick_d <a target="_blank"
+ * href="http://doc.cgal.org/latest/Kernel_d/index.html#Chapter_dD_Geometry_Kernel">dD Geometry Kernel</a>
+ * \cite cgal:s-gkd-15b from CGAL as template, default value is <a target="_blank"
+ * href="http://doc.cgal.org/latest/Kernel_d/classCGAL_1_1Epick__d.html">CGAL::Epick_d</a>
+ * < <a target="_blank" href="http://doc.cgal.org/latest/Kernel_23/classCGAL_1_1Dynamic__dimension__tag.html">
+ * CGAL::Dynamic_dimension_tag </a> >
+ *
+ * \remark When Alpha_complex is constructed with an infinite value of alpha, the complex is a Delaunay complex.
+ *
+ */
+template<class Kernel = CGAL::Epick_d<CGAL::Dynamic_dimension_tag>>
+class Alpha_complex : public Simplex_tree<> {
+ public:
+ // Add an int in TDS to save point index in the structure
+ typedef CGAL::Triangulation_data_structure<CGAL::Dynamic_dimension_tag,
+ CGAL::Triangulation_vertex<Kernel, std::ptrdiff_t>,
+ CGAL::Triangulation_full_cell<Kernel> > TDS;
+ /** \brief A Delaunay triangulation of a set of points in \f$ \mathbb{R}^D\f$.*/
+ typedef CGAL::Delaunay_triangulation<Kernel, TDS> Delaunay_triangulation;
+
+ /** \brief A point in Euclidean space.*/
+ typedef typename Kernel::Point_d Point_d;
+ /** \brief Geometric traits class that provides the geometric types and predicates needed by Delaunay
+ * triangulations.*/
+ typedef Kernel Geom_traits;
+
+ private:
+ // From Simplex_tree
+ // Type required to insert into a simplex_tree (with or without subfaces).
+ typedef std::vector<Vertex_handle> Vector_vertex;
+
+ // Simplex_result is the type returned from simplex_tree insert function.
+ typedef typename std::pair<Simplex_handle, bool> Simplex_result;
+
+ typedef typename Kernel::Compute_squared_radius_d Squared_Radius;
+ typedef typename Kernel::Side_of_bounded_sphere_d Is_Gabriel;
+ typedef typename Kernel::Point_dimension_d Point_Dimension;
+
+ // Type required to compute squared radius, or side of bounded sphere on a vector of points.
+ typedef typename std::vector<Point_d> Vector_of_CGAL_points;
+
+ // Vertex_iterator type from CGAL.
+ typedef typename Delaunay_triangulation::Vertex_iterator CGAL_vertex_iterator;
+
+ // size_type type from CGAL.
+ typedef typename Delaunay_triangulation::size_type size_type;
+
+ // Map type to switch from simplex tree vertex handle to CGAL vertex iterator.
+ typedef typename std::map< Vertex_handle, CGAL_vertex_iterator > Vector_vertex_iterator;
+
+ private:
+ /** \brief Vertex iterator vector to switch from simplex tree vertex handle to CGAL vertex iterator.
+ * Vertex handles are inserted sequentially, starting at 0.*/
+ Vector_vertex_iterator vertex_handle_to_iterator_;
+ /** \brief Pointer on the CGAL Delaunay triangulation.*/
+ Delaunay_triangulation* triangulation_;
+ /** \brief Kernel for triangulation_ functions access.*/
+ Kernel kernel_;
+
+ public:
+ /** \brief Alpha_complex constructor from an OFF file name.
+ * Uses the Delaunay_triangulation_off_reader to construct the Delaunay triangulation required to initialize
+ * the Alpha_complex.
+ *
+ * Duplicate points are inserted once in the Alpha_complex. This is the reason why the vertices may be not contiguous.
+ *
+ * @param[in] off_file_name OFF file [path and] name.
+ * @param[in] max_alpha_square maximum for alpha square value. Default value is +\f$\infty\f$.
+ */
+ Alpha_complex(const std::string& off_file_name,
+ Filtration_value max_alpha_square = std::numeric_limits<Filtration_value>::infinity())
+ : triangulation_(nullptr) {
+ Gudhi::Points_off_reader<Point_d> off_reader(off_file_name);
+ if (!off_reader.is_valid()) {
+ std::cerr << "Alpha_complex - Unable to read file " << off_file_name << "\n";
+ exit(-1); // ----- >>
+ }
+
+ init_from_range(off_reader.get_point_cloud(), max_alpha_square);
+ }
+
+ /** \brief Alpha_complex constructor from a list of points.
+ *
+ * Duplicate points are inserted once in the Alpha_complex. This is the reason why the vertices may be not contiguous.
+ *
+ * @param[in] points Range of points to triangulate. Points must be in Kernel::Point_d
+ * @param[in] max_alpha_square maximum for alpha square value. Default value is +\f$\infty\f$.
+ *
+ * The type InputPointRange must be a range for which std::begin and
+ * std::end return input iterators on a Kernel::Point_d.
+ *
+ * @post Compare num_simplices with InputPointRange points number (not the same in case of duplicate points).
+ */
+ template<typename InputPointRange >
+ Alpha_complex(const InputPointRange& points,
+ Filtration_value max_alpha_square = std::numeric_limits<Filtration_value>::infinity())
+ : triangulation_(nullptr) {
+ init_from_range(points, max_alpha_square);
+ }
+
+ /** \brief Alpha_complex destructor.
+ *
+ * @warning Deletes the Delaunay triangulation.
+ */
+ ~Alpha_complex() {
+ delete triangulation_;
+ }
+
+ // Forbid copy/move constructor/assignment operator
+ Alpha_complex(const Alpha_complex& other) = delete;
+ Alpha_complex& operator= (const Alpha_complex& other) = delete;
+ Alpha_complex (Alpha_complex&& other) = delete;
+ Alpha_complex& operator= (Alpha_complex&& other) = delete;
+
+ /** \brief get_point returns the point corresponding to the vertex given as parameter.
+ *
+ * @param[in] vertex Vertex handle of the point to retrieve.
+ * @return The point found.
+ * @exception std::out_of_range In case vertex is not found (cf. std::vector::at).
+ */
+ Point_d get_point(Vertex_handle vertex) const {
+ return vertex_handle_to_iterator_.at(vertex)->point();
+ }
+
+ private:
+ template<typename InputPointRange >
+ void init_from_range(const InputPointRange& points, Filtration_value max_alpha_square) {
+ auto first = std::begin(points);
+ auto last = std::end(points);
+ if (first != last) {
+ // point_dimension function initialization
+ Point_Dimension point_dimension = kernel_.point_dimension_d_object();
+
+ // Delaunay triangulation is point dimension.
+ triangulation_ = new Delaunay_triangulation(point_dimension(*first));
+
+ std::vector<Point_d> points(first, last);
+
+ // Creates a vector {0, 1, ..., N-1}
+ std::vector<std::ptrdiff_t> indices(boost::counting_iterator<std::ptrdiff_t>(0),
+ boost::counting_iterator<std::ptrdiff_t>(points.size()));
+
+ // Sort indices considering CGAL spatial sort
+ typedef CGAL::Spatial_sort_traits_adapter_d<Kernel, Point_d*> Search_traits_d;
+ spatial_sort(indices.begin(), indices.end(), Search_traits_d(&(points[0])));
+
+ typename Delaunay_triangulation::Full_cell_handle hint;
+ for (auto index : indices) {
+ typename Delaunay_triangulation::Vertex_handle pos = triangulation_->insert(points[index], hint);
+ // Save index value as data to retrieve it after insertion
+ pos->data() = index;
+ hint = pos->full_cell();
+ }
+ init(max_alpha_square);
+ }
+ }
+
+ /** \brief Initialize the Alpha_complex from the Delaunay triangulation.
+ *
+ * @param[in] max_alpha_square maximum for alpha square value.
+ *
+ * @warning Delaunay triangulation must be already constructed with at least one vertex and dimension must be more
+ * than 0.
+ *
+ * Initialization can be launched once.
+ */
+ void init(Filtration_value max_alpha_square) {
+ if (triangulation_ == nullptr) {
+ std::cerr << "Alpha_complex init - Cannot init from a NULL triangulation\n";
+ return; // ----- >>
+ }
+ if (triangulation_->number_of_vertices() < 1) {
+ std::cerr << "Alpha_complex init - Cannot init from a triangulation without vertices\n";
+ return; // ----- >>
+ }
+ if (triangulation_->maximal_dimension() < 1) {
+ std::cerr << "Alpha_complex init - Cannot init from a zero-dimension triangulation\n";
+ return; // ----- >>
+ }
+ if (num_vertices() > 0) {
+ std::cerr << "Alpha_complex init - Cannot init twice\n";
+ return; // ----- >>
+ }
+
+ set_dimension(triangulation_->maximal_dimension());
+
+ // --------------------------------------------------------------------------------------------
+ // double map to retrieve simplex tree vertex handles from CGAL vertex iterator and vice versa
+ // Loop on triangulation vertices list
+ for (CGAL_vertex_iterator vit = triangulation_->vertices_begin(); vit != triangulation_->vertices_end(); ++vit) {
+ if (!triangulation_->is_infinite(*vit)) {
+#ifdef DEBUG_TRACES
+ std::cout << "Vertex insertion - " << vit->data() << " -> " << vit->point() << std::endl;
+#endif // DEBUG_TRACES
+ vertex_handle_to_iterator_.emplace(vit->data(), vit);
+ }
+ }
+ // --------------------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------------------
+ // Simplex_tree construction from loop on triangulation finite full cells list
+ for (auto cit = triangulation_->finite_full_cells_begin(); cit != triangulation_->finite_full_cells_end(); ++cit) {
+ Vector_vertex vertexVector;
+#ifdef DEBUG_TRACES
+ std::cout << "Simplex_tree insertion ";
+#endif // DEBUG_TRACES
+ for (auto vit = cit->vertices_begin(); vit != cit->vertices_end(); ++vit) {
+ if (*vit != nullptr) {
+#ifdef DEBUG_TRACES
+ std::cout << " " << (*vit)->data();
+#endif // DEBUG_TRACES
+ // Vector of vertex construction for simplex_tree structure
+ vertexVector.push_back((*vit)->data());
+ }
+ }
+#ifdef DEBUG_TRACES
+ std::cout << std::endl;
+#endif // DEBUG_TRACES
+ // Insert each simplex and its subfaces in the simplex tree - filtration is NaN
+ insert_simplex_and_subfaces(vertexVector, std::numeric_limits<double>::quiet_NaN());
+ }
+ // --------------------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------------------
+ // ### For i : d -> 0
+ for (int decr_dim = dimension(); decr_dim >= 0; decr_dim--) {
+ // ### Foreach Sigma of dim i
+ for (auto f_simplex : skeleton_simplex_range(decr_dim)) {
+ int f_simplex_dim = dimension(f_simplex);
+ if (decr_dim == f_simplex_dim) {
+ Vector_of_CGAL_points pointVector;
+#ifdef DEBUG_TRACES
+ std::cout << "Sigma of dim " << decr_dim << " is";
+#endif // DEBUG_TRACES
+ for (auto vertex : simplex_vertex_range(f_simplex)) {
+ pointVector.push_back(get_point(vertex));
+#ifdef DEBUG_TRACES
+ std::cout << " " << vertex;
+#endif // DEBUG_TRACES
+ }
+#ifdef DEBUG_TRACES
+ std::cout << std::endl;
+#endif // DEBUG_TRACES
+ // ### If filt(Sigma) is NaN : filt(Sigma) = alpha(Sigma)
+ if (isnan(filtration(f_simplex))) {
+ Filtration_value alpha_complex_filtration = 0.0;
+ // No need to compute squared_radius on a single point - alpha is 0.0
+ if (f_simplex_dim > 0) {
+ // squared_radius function initialization
+ Squared_Radius squared_radius = kernel_.compute_squared_radius_d_object();
+
+ alpha_complex_filtration = squared_radius(pointVector.begin(), pointVector.end());
+ }
+ assign_filtration(f_simplex, alpha_complex_filtration);
+#ifdef DEBUG_TRACES
+ std::cout << "filt(Sigma) is NaN : filt(Sigma) =" << filtration(f_simplex) << std::endl;
+#endif // DEBUG_TRACES
+ }
+ propagate_alpha_filtration(f_simplex, decr_dim);
+ }
+ }
+ }
+ // --------------------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------------------
+ // As Alpha value is an approximation, we have to make filtration non decreasing while increasing the dimension
+ bool modified_filt = make_filtration_non_decreasing();
+ // Remove all simplices that have a filtration value greater than max_alpha_square
+ // Remark: prune_above_filtration does not require initialize_filtration to be done before.
+ modified_filt |= prune_above_filtration(max_alpha_square);
+ if (modified_filt) {
+ initialize_filtration();
+ }
+ // --------------------------------------------------------------------------------------------
+ }
+
+ template<typename Simplex_handle>
+ void propagate_alpha_filtration(Simplex_handle f_simplex, int decr_dim) {
+ // ### Foreach Tau face of Sigma
+ for (auto f_boundary : boundary_simplex_range(f_simplex)) {
+#ifdef DEBUG_TRACES
+ std::cout << " | --------------------------------------------------\n";
+ std::cout << " | Tau ";
+ for (auto vertex : simplex_vertex_range(f_boundary)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << "is a face of Sigma\n";
+ std::cout << " | isnan(filtration(Tau)=" << isnan(filtration(f_boundary)) << std::endl;
+#endif // DEBUG_TRACES
+ // ### If filt(Tau) is not NaN
+ if (!isnan(filtration(f_boundary))) {
+ // ### filt(Tau) = fmin(filt(Tau), filt(Sigma))
+ Filtration_value alpha_complex_filtration = fmin(filtration(f_boundary), filtration(f_simplex));
+ assign_filtration(f_boundary, alpha_complex_filtration);
+#ifdef DEBUG_TRACES
+ std::cout << " | filt(Tau) = fmin(filt(Tau), filt(Sigma)) = " << filtration(f_boundary) << std::endl;
+#endif // DEBUG_TRACES
+ // ### Else
+ } else {
+ // No need to compute is_gabriel for dimension <= 2
+ // i.e. : Sigma = (3,1) => Tau = 1
+ if (decr_dim > 1) {
+ // insert the Tau points in a vector for is_gabriel function
+ Vector_of_CGAL_points pointVector;
+#ifdef DEBUG_TRACES
+ Vertex_handle vertexForGabriel = Vertex_handle();
+#endif // DEBUG_TRACES
+ for (auto vertex : simplex_vertex_range(f_boundary)) {
+ pointVector.push_back(get_point(vertex));
+ }
+ // Retrieve the Sigma point that is not part of Tau - parameter for is_gabriel function
+ Point_d point_for_gabriel;
+ for (auto vertex : simplex_vertex_range(f_simplex)) {
+ point_for_gabriel = get_point(vertex);
+ if (std::find(pointVector.begin(), pointVector.end(), point_for_gabriel) == pointVector.end()) {
+#ifdef DEBUG_TRACES
+ // vertex is not found in Tau
+ vertexForGabriel = vertex;
+#endif // DEBUG_TRACES
+ // No need to continue loop
+ break;
+ }
+ }
+ // is_gabriel function initialization
+ Is_Gabriel is_gabriel = kernel_.side_of_bounded_sphere_d_object();
+ bool is_gab = is_gabriel(pointVector.begin(), pointVector.end(), point_for_gabriel)
+ != CGAL::ON_BOUNDED_SIDE;
+#ifdef DEBUG_TRACES
+ std::cout << " | Tau is_gabriel(Sigma)=" << is_gab << " - vertexForGabriel=" << vertexForGabriel << std::endl;
+#endif // DEBUG_TRACES
+ // ### If Tau is not Gabriel of Sigma
+ if (false == is_gab) {
+ // ### filt(Tau) = filt(Sigma)
+ Filtration_value alpha_complex_filtration = filtration(f_simplex);
+ assign_filtration(f_boundary, alpha_complex_filtration);
+#ifdef DEBUG_TRACES
+ std::cout << " | filt(Tau) = filt(Sigma) = " << filtration(f_boundary) << std::endl;
+#endif // DEBUG_TRACES
+ }
+ }
+ }
+ }
+ }
+};
+
+} // namespace alphacomplex
+
+} // namespace Gudhi
+
+#endif // ALPHA_COMPLEX_H_
diff --git a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp
new file mode 100644
index 00000000..80b39924
--- /dev/null
+++ b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp
@@ -0,0 +1,243 @@
+/* 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_DYN_LINK
+#define BOOST_TEST_MODULE "alpha_complex"
+#include <boost/test/unit_test.hpp>
+
+#include <CGAL/Delaunay_triangulation.h>
+#include <CGAL/Epick_d.h>
+
+#include <cmath> // float comparison
+#include <limits>
+#include <string>
+#include <vector>
+
+#include <gudhi/Alpha_complex.h>
+
+// Use dynamic_dimension_tag for the user to be able to set dimension
+typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel_d;
+// The triangulation uses the default instantiation of the TriangulationDataStructure template parameter
+
+BOOST_AUTO_TEST_CASE(ALPHA_DOC_OFF_file) {
+ // ----------------------------------------------------------------------------
+ //
+ // Init of an alpha-complex from a OFF file
+ //
+ // ----------------------------------------------------------------------------
+ std::string off_file_name("alphacomplexdoc.off");
+ double max_alpha_square_value = 60.0;
+ std::cout << "========== OFF FILE NAME = " << off_file_name << " - alpha²=" <<
+ max_alpha_square_value << "==========" << std::endl;
+
+ Gudhi::alphacomplex::Alpha_complex<Kernel_d> alpha_complex_from_file(off_file_name, max_alpha_square_value);
+
+ const int DIMENSION = 2;
+ std::cout << "alpha_complex_from_file.dimension()=" << alpha_complex_from_file.dimension() << std::endl;
+ BOOST_CHECK(alpha_complex_from_file.dimension() == DIMENSION);
+
+ const int NUMBER_OF_VERTICES = 7;
+ std::cout << "alpha_complex_from_file.num_vertices()=" << alpha_complex_from_file.num_vertices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_file.num_vertices() == NUMBER_OF_VERTICES);
+
+ const int NUMBER_OF_SIMPLICES = 25;
+ std::cout << "alpha_complex_from_file.num_simplices()=" << alpha_complex_from_file.num_simplices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_file.num_simplices() == NUMBER_OF_SIMPLICES);
+
+}
+
+BOOST_AUTO_TEST_CASE(ALPHA_DOC_OFF_file_filtered) {
+ // ----------------------------------------------------------------------------
+ //
+ // Init of an alpha-complex from a OFF file
+ //
+ // ----------------------------------------------------------------------------
+ std::string off_file_name("alphacomplexdoc.off");
+ double max_alpha_square_value = 59.0;
+ std::cout << "========== OFF FILE NAME = " << off_file_name << " - alpha²=" <<
+ max_alpha_square_value << "==========" << std::endl;
+
+ // Use of the default dynamic kernel
+ Gudhi::alphacomplex::Alpha_complex<> alpha_complex_from_file(off_file_name, max_alpha_square_value);
+
+ const int DIMENSION = 2;
+ std::cout << "alpha_complex_from_file.dimension()=" << alpha_complex_from_file.dimension() << std::endl;
+ BOOST_CHECK(alpha_complex_from_file.dimension() == DIMENSION);
+
+ const int NUMBER_OF_VERTICES = 7;
+ std::cout << "alpha_complex_from_file.num_vertices()=" << alpha_complex_from_file.num_vertices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_file.num_vertices() == NUMBER_OF_VERTICES);
+
+ const int NUMBER_OF_SIMPLICES = 23;
+ std::cout << "alpha_complex_from_file.num_simplices()=" << alpha_complex_from_file.num_simplices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_file.num_simplices() == NUMBER_OF_SIMPLICES);
+}
+
+bool are_almost_the_same(float a, float b) {
+ return std::fabs(a - b) < std::numeric_limits<float>::epsilon();
+}
+
+// Use dynamic_dimension_tag for the user to be able to set dimension
+typedef CGAL::Epick_d< CGAL::Dimension_tag<4> > Kernel_s;
+typedef Kernel_s::Point_d Point;
+typedef std::vector<Point> Vector_of_points;
+
+
+bool is_point_in_list(Vector_of_points points_list, Point point) {
+ for (auto& point_in_list : points_list) {
+ if (point_in_list == point) {
+ return true; // point found
+ }
+ }
+ return false; // point not found
+}
+
+BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) {
+ // ----------------------------------------------------------------------------
+ // Init of a list of points
+ // ----------------------------------------------------------------------------
+ Vector_of_points points;
+ std::vector<double> coords = { 0.0, 0.0, 0.0, 1.0 };
+ points.push_back(Point(coords.begin(), coords.end()));
+ coords = { 0.0, 0.0, 1.0, 0.0 };
+ points.push_back(Point(coords.begin(), coords.end()));
+ coords = { 0.0, 1.0, 0.0, 0.0 };
+ points.push_back(Point(coords.begin(), coords.end()));
+ coords = { 1.0, 0.0, 0.0, 0.0 };
+ points.push_back(Point(coords.begin(), coords.end()));
+
+ // ----------------------------------------------------------------------------
+ // Init of an alpha complex from the list of points
+ // ----------------------------------------------------------------------------
+ Gudhi::alphacomplex::Alpha_complex<Kernel_s> alpha_complex_from_points(points);
+
+ std::cout << "========== Alpha_complex_from_points ==========" << std::endl;
+
+ // Another way to check num_simplices
+ std::cout << "Iterator on alpha complex simplices in the filtration order, with [filtration value]:" << std::endl;
+ int num_simplices = 0;
+ for (auto f_simplex : alpha_complex_from_points.filtration_simplex_range()) {
+ num_simplices++;
+ std::cout << " ( ";
+ for (auto vertex : alpha_complex_from_points.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << ") -> " << "[" << alpha_complex_from_points.filtration(f_simplex) << "] ";
+ std::cout << std::endl;
+ }
+ BOOST_CHECK(num_simplices == 15);
+ std::cout << "alpha_complex_from_points.num_simplices()=" << alpha_complex_from_points.num_simplices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_points.num_simplices() == 15);
+
+ std::cout << "alpha_complex_from_points.dimension()=" << alpha_complex_from_points.dimension() << std::endl;
+ BOOST_CHECK(alpha_complex_from_points.dimension() == 4);
+ std::cout << "alpha_complex_from_points.num_vertices()=" << alpha_complex_from_points.num_vertices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_points.num_vertices() == 4);
+
+ for (auto f_simplex : alpha_complex_from_points.filtration_simplex_range()) {
+ switch (alpha_complex_from_points.dimension(f_simplex)) {
+ case 0:
+ BOOST_CHECK(are_almost_the_same(alpha_complex_from_points.filtration(f_simplex), 0.0));
+ break;
+ case 1:
+ BOOST_CHECK(are_almost_the_same(alpha_complex_from_points.filtration(f_simplex), 1.0/2.0));
+ break;
+ case 2:
+ BOOST_CHECK(are_almost_the_same(alpha_complex_from_points.filtration(f_simplex), 2.0/3.0));
+ break;
+ case 3:
+ BOOST_CHECK(are_almost_the_same(alpha_complex_from_points.filtration(f_simplex), 3.0/4.0));
+ break;
+ default:
+ BOOST_CHECK(false); // Shall not happen
+ break;
+ }
+ }
+
+ Point p0 = alpha_complex_from_points.get_point(0);
+ std::cout << "alpha_complex_from_points.get_point(0)=" << p0 << std::endl;
+ BOOST_CHECK(4 == p0.dimension());
+ BOOST_CHECK(is_point_in_list(points, p0));
+
+ Point p1 = alpha_complex_from_points.get_point(1);
+ std::cout << "alpha_complex_from_points.get_point(1)=" << p1 << std::endl;
+ BOOST_CHECK(4 == p1.dimension());
+ BOOST_CHECK(is_point_in_list(points, p1));
+
+ Point p2 = alpha_complex_from_points.get_point(2);
+ std::cout << "alpha_complex_from_points.get_point(2)=" << p2 << std::endl;
+ BOOST_CHECK(4 == p2.dimension());
+ BOOST_CHECK(is_point_in_list(points, p2));
+
+ Point p3 = alpha_complex_from_points.get_point(3);
+ std::cout << "alpha_complex_from_points.get_point(3)=" << p3 << std::endl;
+ BOOST_CHECK(4 == p3.dimension());
+ BOOST_CHECK(is_point_in_list(points, p3));
+
+ // Test to the limit
+ BOOST_CHECK_THROW (alpha_complex_from_points.get_point(4), std::out_of_range);
+ BOOST_CHECK_THROW (alpha_complex_from_points.get_point(-1), std::out_of_range);
+ BOOST_CHECK_THROW (alpha_complex_from_points.get_point(1234), std::out_of_range);
+
+ // Test after prune_above_filtration
+ bool modified = alpha_complex_from_points.prune_above_filtration(0.6);
+ if (modified) {
+ alpha_complex_from_points.initialize_filtration();
+ }
+ BOOST_CHECK(modified);
+
+ // Another way to check num_simplices
+ std::cout << "Iterator on alpha complex simplices in the filtration order, with [filtration value]:" << std::endl;
+ num_simplices = 0;
+ for (auto f_simplex : alpha_complex_from_points.filtration_simplex_range()) {
+ num_simplices++;
+ std::cout << " ( ";
+ for (auto vertex : alpha_complex_from_points.simplex_vertex_range(f_simplex)) {
+ std::cout << vertex << " ";
+ }
+ std::cout << ") -> " << "[" << alpha_complex_from_points.filtration(f_simplex) << "] ";
+ std::cout << std::endl;
+ }
+ BOOST_CHECK(num_simplices == 10);
+ std::cout << "alpha_complex_from_points.num_simplices()=" << alpha_complex_from_points.num_simplices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_points.num_simplices() == 10);
+
+ std::cout << "alpha_complex_from_points.dimension()=" << alpha_complex_from_points.dimension() << std::endl;
+ BOOST_CHECK(alpha_complex_from_points.dimension() == 4);
+ std::cout << "alpha_complex_from_points.num_vertices()=" << alpha_complex_from_points.num_vertices() << std::endl;
+ BOOST_CHECK(alpha_complex_from_points.num_vertices() == 4);
+
+ for (auto f_simplex : alpha_complex_from_points.filtration_simplex_range()) {
+ switch (alpha_complex_from_points.dimension(f_simplex)) {
+ case 0:
+ BOOST_CHECK(are_almost_the_same(alpha_complex_from_points.filtration(f_simplex), 0.0));
+ break;
+ case 1:
+ BOOST_CHECK(are_almost_the_same(alpha_complex_from_points.filtration(f_simplex), 1.0/2.0));
+ break;
+ default:
+ BOOST_CHECK(false); // Shall not happen
+ break;
+ }
+ }
+
+}
diff --git a/src/Alpha_complex/test/CMakeLists.txt b/src/Alpha_complex/test/CMakeLists.txt
new file mode 100644
index 00000000..e24588d7
--- /dev/null
+++ b/src/Alpha_complex/test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 2.6)
+project(GUDHIAlphaComplexTest)
+
+if (GCOVR_PATH)
+ # for gcovr to make coverage reports - Corbera Jenkins plugin
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
+endif()
+if (GPROF_PATH)
+ # for gprof to make coverage reports - Jenkins
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
+endif()
+
+# need CGAL 4.7
+# cmake -DCGAL_DIR=~/workspace/CGAL-4.7-Ic-41 ../../..
+if(CGAL_FOUND)
+ if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ message(STATUS "CGAL version: ${CGAL_VERSION}.")
+
+ 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 ( AlphaComplexUT Alpha_complex_unit_test.cpp )
+ target_link_libraries(AlphaComplexUT ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ if (TBB_FOUND)
+ target_link_libraries(AlphaComplexUT ${TBB_RELEASE_LIBRARY})
+ endif()
+
+ # Do not forget to copy test files in current binary dir
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+ add_test(AlphaComplexUT ${CMAKE_CURRENT_BINARY_DIR}/AlphaComplexUT
+ # XML format for Jenkins xUnit plugin
+ --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/AlphaComplexUT.xml --log_level=test_suite --report_level=no)
+
+ else()
+ message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha complex feature.")
+ endif()
+ else()
+ message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha complex feature. Version 4.6.0 is required.")
+ endif ()
+endif()
+
diff --git a/src/Alpha_complex/test/README b/src/Alpha_complex/test/README
new file mode 100644
index 00000000..45b87d91
--- /dev/null
+++ b/src/Alpha_complex/test/README
@@ -0,0 +1,12 @@
+To compile:
+***********
+
+cmake .
+make
+
+To launch with details:
+***********************
+
+./AlphaComplexUnitTest --report_level=detailed --log_level=all
+
+ ==> echo $? returns 0 in case of success (non-zero otherwise)
diff --git a/src/Bitmap_cubical_complex/doc/Cubical_complex_representation.ipe b/src/Bitmap_cubical_complex/doc/Cubical_complex_representation.ipe
new file mode 100644
index 00000000..bec245e7
--- /dev/null
+++ b/src/Bitmap_cubical_complex/doc/Cubical_complex_representation.ipe
@@ -0,0 +1,732 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70107" creator="Ipe 7.1.10">
+<info created="D:20160330102945" modified="D:20160330104654"/>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/ptarc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fptarc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+0.5 0 0 0.5 0 0 e
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+-0.5 -0.5 m
+0.5 -0.5 l
+0.5 0.5 l
+-0.5 0.5 l
+h
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="small" value="\small"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textsize name="tiny" value="\tiny"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<opacity name="10%" value="0.1"/>
+<opacity name="30%" value="0.3"/>
+<opacity name="50%" value="0.5"/>
+<opacity name="75%" value="0.75"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">0</text>
+<path stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<text transformations="translations" pos="212 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<path matrix="1 0 0 1 64 0" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 64 0" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<path matrix="1 0 0 1 64 0" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<text matrix="1 0 0 1 64 0" transformations="translations" pos="212 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<path matrix="1 0 0 1 128 0" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 128 0" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<path matrix="1 0 0 1 128 0" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<text matrix="1 0 0 1 128 0" transformations="translations" pos="212 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<path matrix="1 0 0 1 192 0" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 192 0" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">6</text>
+<path matrix="1 0 0 1 192 0" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<text matrix="1 0 0 1 192 0" transformations="translations" pos="212 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">7</text>
+<path matrix="1 0 0 1 256 0" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 256 0" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">8</text>
+<path matrix="1 0 0 1 0 -32" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 0 -48" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<path matrix="1 0 0 1 0 -32" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 64 -32" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 64 -48" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<path matrix="1 0 0 1 64 -32" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<text matrix="1 0 0 1 96 -48" transformations="translations" pos="212 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<path matrix="1 0 0 1 128 -32" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text matrix="1 0 0 1 192 -48" transformations="translations" pos="180 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">4</text>
+<path matrix="1 0 0 1 128 -32" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<text matrix="1 0 0 1 224 -48" transformations="translations" pos="212 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">5</text>
+<path matrix="1 0 0 1 192 -32" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 192 -32" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 256 -32" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 -32 0" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 -32 64" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 0 64" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 -32 128" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<text transformations="translations" pos="132 484" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">1</text>
+<text transformations="translations" pos="132 548" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">2</text>
+<text transformations="translations" pos="132 612" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">3</text>
+<path matrix="1 0 0 1 32 0" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<text transformations="translations" pos="180 516" stroke="black" type="label" width="4.981" height="6.42" depth="0" valign="baseline">9</text>
+<path matrix="1 0 0 1 96 0" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<text transformations="translations" pos="244 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">11</text>
+<path matrix="1 0 0 1 160 0" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 224 0" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 288 0" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 0 64" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 0 64" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 64 64" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 64 64" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 128 64" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 128 64" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 192 64" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 192 64" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 256 64" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 0 128" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 0 128" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 64 128" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 64 128" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 128 128" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 128 128" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 192 128" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 192 128" stroke="black" fill="lightgreen">
+192 496 m
+192 480 l
+240 480 l
+240 496 l
+h
+</path>
+<path matrix="1 0 0 1 256 128" stroke="black" fill="lightblue">
+176 496 m
+176 480 l
+192 480 l
+192 496 l
+h
+</path>
+<path matrix="1 0 0 1 32 64" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 96 64" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 160 64" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 224 64" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path matrix="1 0 0 1 288 64" stroke="black" fill="lightgreen">
+160 496 m
+160 544 l
+144 544 l
+144 496 l
+h
+</path>
+<path stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 64 0" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 128 0" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 192 0" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 0 64" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 64 64" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 128 64" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<path matrix="1 0 0 1 192 64" stroke="black" fill="lightgray">
+192 544 m
+192 496 l
+240 496 l
+240 544 l
+h
+</path>
+<text transformations="translations" pos="212 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">10</text>
+<text transformations="translations" pos="276 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">12</text>
+<text transformations="translations" pos="308 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">13</text>
+<text transformations="translations" pos="340 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">14</text>
+<text transformations="translations" pos="372 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">15</text>
+<text transformations="translations" pos="404 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">16</text>
+<text transformations="translations" pos="436 516" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">17</text>
+<text transformations="translations" pos="180 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">18</text>
+<text transformations="translations" pos="212 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">19</text>
+<text transformations="translations" pos="244 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">20</text>
+<text transformations="translations" pos="276 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">21</text>
+<text transformations="translations" pos="308 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">22</text>
+<text transformations="translations" pos="340 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">23</text>
+<text transformations="translations" pos="372 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">24</text>
+<text transformations="translations" pos="404 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">25</text>
+<text transformations="translations" pos="436 548" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">26</text>
+<text transformations="translations" pos="180 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">27</text>
+<text transformations="translations" pos="212 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">28</text>
+<text transformations="translations" pos="244 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">29</text>
+<text transformations="translations" pos="276 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">30</text>
+<text transformations="translations" pos="308 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">31</text>
+<text transformations="translations" pos="340 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">32</text>
+<text transformations="translations" pos="372 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">33</text>
+<text transformations="translations" pos="404 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">34</text>
+<text transformations="translations" pos="436 580" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">35</text>
+<text transformations="translations" pos="180 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">36</text>
+<text transformations="translations" pos="212 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">37</text>
+<text transformations="translations" pos="244 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">38</text>
+<text transformations="translations" pos="276 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">39</text>
+<text transformations="translations" pos="308 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">40</text>
+<text transformations="translations" pos="340 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">41</text>
+<text transformations="translations" pos="372 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">42</text>
+<text transformations="translations" pos="404 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">43</text>
+<text transformations="translations" pos="436 612" stroke="black" type="label" width="9.963" height="6.42" depth="0" valign="baseline">44</text>
+<path stroke="black" arrow="normal/normal">
+152 456 m
+472 456 l
+</path>
+<path stroke="black" arrow="normal/normal">
+152 456 m
+152 648 l
+</path>
+</page>
+</ipe>
diff --git a/src/Bitmap_cubical_complex/doc/Cubical_complex_representation.png b/src/Bitmap_cubical_complex/doc/Cubical_complex_representation.png
new file mode 100644
index 00000000..afb2a75e
--- /dev/null
+++ b/src/Bitmap_cubical_complex/doc/Cubical_complex_representation.png
Binary files differ
diff --git a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h
new file mode 100644
index 00000000..83921427
--- /dev/null
+++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h
@@ -0,0 +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): Pawel Dlotko
+ *
+ * Copyright (C) 2015 INRIA Sophia-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 DOC_GUDHI_CUBICAL_COMPLEX_COMPLEX_H_
+#define DOC_GUDHI_CUBICAL_COMPLEX_COMPLEX_H_
+
+namespace Gudhi {
+
+namespace Cubical_complex {
+
+/** \defgroup cubical_complex Cubical complex
+ *
+ * \author Pawel Dlotko
+ *
+ * @{
+ *
+
+ * Bitmap_cubical_complex is an example of a structured complex useful in computational mathematics (specially rigorous
+ * numerics) and image analysis. The presented implementation of cubical complexes is based on the following
+ * definition.
+ *
+ * An <em>elementary interval</em> is an interval of a form \f$ [n,n+1] \f$, or \f$[n,n]\f$, for \f$ n \in \mathcal{Z}
+ * \f$. The first one is called <em>non-degenerate</em>, while the second one is \a degenerate interval. A
+ * <em>boundary of a elementary interval</em> is a chain \f$\partial [n,n+1] = [n+1,n+1]-[n,n] \f$ in case of
+ * non-degenerated elementary interval and \f$\partial [n,n] = 0 \f$ in case of degenerate elementary interval. An
+ * <em>elementary cube</em> \f$ C \f$ is a product of elementary intervals, \f$C=I_1 \times \ldots \times I_n\f$.
+ * <em>Embedding dimension</em> of a cube is n, the number of elementary intervals (degenerate or not) in the product.
+ * A <em>dimension of a cube</em> \f$C=I_1 \times ... \times I_n\f$ is the number of non degenerate elementary
+ * intervals in the product. A <em>boundary of a cube</em> \f$C=I_1 \times \ldots \times I_n\f$ is a chain obtained
+ * in the following way:
+ * \f[\partial C = (\partial I_1 \times \ldots \times I_n) + (I_1 \times \partial I_2 \times \ldots \times I_n) +
+ * \ldots + (I_1 \times I_2 \times \ldots \times \partial I_n).\f]
+ * A <em>cubical complex</em> \f$\mathcal{K}\f$ is a collection of cubes closed under operation of taking boundary
+ * (i.e. boundary of every cube from the collection is in the collection). A cube \f$C\f$ in cubical complex
+ * \f$\mathcal{K}\f$ is <em>maximal</em> if it is not in a boundary of any other cube in \f$\mathcal{K}\f$. A \a
+ * support of a cube \f$C\f$ is the set in \f$\mathbb{R}^n\f$ occupied by \f$C\f$ (\f$n\f$ is the embedding dimension
+ * of \f$C\f$).
+ *
+ * Cubes may be equipped with a filtration values in which case we have filtered cubical complex. All the cubical
+ * complexes considered in this implementation are filtered cubical complexes (although, the range of a filtration may
+ * be a set of two elements).
+ *
+ * For further details and theory of cubical complexes, please consult \cite kaczynski2004computational as well as the
+ * following paper \cite peikert2012topological .
+ *
+ * \section datastructure Data structure.
+ *
+ * The implementation of Cubical complex provides a representation of complexes that occupy a rectangular region in
+ * \f$\mathbb{R}^n\f$. This extra assumption allows for a memory efficient way of storing cubical complexes in a form
+ * of so called bitmaps. Let \f$R = [b_1,e_1] \times \ldots \times [b_n,e_n]\f$, for \f$b_1,...b_n,e_1,...,e_n \in
+ * \mathbb{Z}\f$, \f$b_i \leq d_i\f$ be the considered rectangular region and let \f$\mathcal{K}\f$ be a filtered
+ * cubical complex having the rectangle \f$R\f$ as its support. Note that the structure of the coordinate system gives
+ * a way a lexicographical ordering of cells of \f$\mathcal{K}\f$. This ordering is a base of the presented
+ * bitmap-based implementation. In this implementation, the whole cubical complex is stored as a vector of the values
+ * of filtration. This, together with dimension of \f$\mathcal{K}\f$ and the sizes of \f$\mathcal{K}\f$ in all
+ * directions, allows to determine, dimension, neighborhood, boundary and coboundary of every cube \f$C \in
+ * \mathcal{K}\f$.
+ *
+ * \image html "Cubical_complex_representation.png" Cubical complex.
+ *
+ * Note that the cubical complex in the figure above is, in a natural way, a product of one dimensional cubical
+ * complexes in \f$\mathbb{R}\f$. The number of all cubes in each direction is equal \f$2n+1\f$, where \f$n\f$ is the
+ * number of maximal cubes in the considered direction. Let us consider a cube at the position \f$k\f$ in the bitmap.
+ * Knowing the sizes of the bitmap, by a series of modulo operation, we can determine which elementary intervals are
+ * present in the product that gives the cube \f$C\f$. In a similar way, we can compute boundary and the coboundary of
+ * each cube. Further details can be found in the literature.
+ *
+ * \section inputformat Input Format.
+ *
+ * In the current implantation, filtration is given at the maximal cubes, and it is then extended by the lower star
+ * filtration to all cubes. There are a number of constructors that can be used to construct cubical complex by users
+ * who want to use the code directly. They can be found in the \a Bitmap_cubical_complex class.
+ * Currently one input from a text file is used. It uses a format used already in Perseus software
+ * (http://www.sas.upenn.edu/~vnanda/perseus/) by Vidit Nanda.
+ * Below we are providing a description of the format. The first line contains a number d begin the dimension of the
+ * bitmap (2 in the example below). Next d lines are the numbers of top dimensional cubes in each dimensions (3 and 3
+ * in the example below). Next, in lexicographical order, the filtration of top dimensional cubes is given (1 4 6 8
+ * 20 4 7 6 5 in the example below).
+ *
+ *
+ * \image html "exampleBitmap.png" "Example of a input data."
+ *
+ * The input file for the following complex is:
+ * \verbatim
+2
+3
+3
+1
+4
+6
+8
+20
+4
+7
+6
+5
+\endverbatim
+
+ * \section PeriodicBoundaryConditions Periodic boundary conditions
+ * Often one would like to impose periodic boundary conditions to the cubical complex. Let \f$ I_1\times ... \times
+ * I_n \f$ be a box that is decomposed with a cubical complex \f$ \mathcal{K} \f$. Imposing periodic boundary
+ * conditions in the direction i, means that the left and the right side of a complex \f$ \mathcal{K} \f$ are
+ * considered the same. In particular, if for a bitmap \f$ \mathcal{K} \f$ periodic boundary conditions are imposed
+ * in all directions, then complex \f$ \mathcal{K} \f$ became n-dimensional torus. One can use various constructors
+ * from the file Bitmap_cubical_complex_periodic_boundary_conditions_base.h to construct cubical complex with periodic
+ * boundary conditions. One can also use Perseus style input files. To indicate periodic boundary conditions in a
+ * given direction, then number of top dimensional cells in this direction have to be multiplied by -1. For instance:
+
+ *\verbatim
+2
+-3
+3
+1
+4
+6
+8
+20
+4
+7
+6
+5
+\endverbatim
+
+ * Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y.
+
+ * \section BitmapExamples Examples
+ * End user programs are available in example/Bitmap_cubical_complex folder.
+ *
+ * \copyright GNU General Public License v3.
+ */
+/** @} */ // end defgroup cubical_complex
+
+} // namespace Cubical_complex
+
+} // namespace Gudhi
+
+#endif // DOC_GUDHI_CUBICAL_COMPLEX_COMPLEX_H_
diff --git a/src/Bitmap_cubical_complex/doc/bitmapAllCubes.png b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.png
new file mode 100644
index 00000000..77167b13
--- /dev/null
+++ b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.png
Binary files differ
diff --git a/src/Bitmap_cubical_complex/doc/exampleBitmap.png b/src/Bitmap_cubical_complex/doc/exampleBitmap.png
new file mode 100644
index 00000000..069c6eb2
--- /dev/null
+++ b/src/Bitmap_cubical_complex/doc/exampleBitmap.png
Binary files differ
diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp
new file mode 100644
index 00000000..7c7e8ac5
--- /dev/null
+++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp
@@ -0,0 +1,72 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 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/>.
+ */
+
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/Bitmap_cubical_complex.h>
+#include <gudhi/Persistent_cohomology.h>
+
+// standard stuff
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+int main(int argc, char** argv) {
+ std::cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " <<
+ "complexes provided in text files in Perseus style (the only numbered in the first line is a dimension D of a" <<
+ "bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let " <<
+ "N denote product of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are " <<
+ "filtrations of top dimensional cells. We assume that the cells are in the lexicographical order. See " <<
+ "CubicalOneSphere.txt or CubicalTwoSphere.txt for example.\n" << std::endl;
+
+ int p = 2;
+ double min_persistence = 0;
+
+ if (argc != 2) {
+ std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " <<
+ "the input. The program will now terminate.\n";
+ return 1;
+ }
+
+ typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_base<double> Bitmap_cubical_complex_base;
+ typedef Gudhi::Cubical_complex::Bitmap_cubical_complex<Bitmap_cubical_complex_base> Bitmap_cubical_complex;
+ typedef Gudhi::persistent_cohomology::Field_Zp Field_Zp;
+ typedef Gudhi::persistent_cohomology::Persistent_cohomology<Bitmap_cubical_complex, Field_Zp> Persistent_cohomology;
+
+ Bitmap_cubical_complex b(argv[1]);
+
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology pcoh(b);
+ pcoh.init_coefficients(p); // initializes the coefficient field for homology
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ std::stringstream ss;
+ ss << argv[1] << "_persistence";
+ std::ofstream out(ss.str().c_str());
+ pcoh.output_diagram(out);
+ out.close();
+
+ std::cout << "Result in file: " << ss.str().c_str() << "\n";
+
+ return 0;
+}
+
diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp
new file mode 100644
index 00000000..2c5d7fd3
--- /dev/null
+++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp
@@ -0,0 +1,74 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 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/>.
+ */
+
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/Bitmap_cubical_complex.h>
+#include <gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h>
+#include <gudhi/Persistent_cohomology.h>
+
+// standard stuff
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+int main(int argc, char** argv) {
+ std::cout << "This program computes persistent homology, by using " <<
+ "Bitmap_cubical_complex_periodic_boundary_conditions class, of cubical complexes provided in text files in " <<
+ "Perseus style (the only numbered in the first line is a dimension D of a bitmap. In the lines I between 2 " <<
+ "and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product of the numbers " <<
+ "in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We " <<
+ "assume that the cells are in the lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for" <<
+ " example.\n" << std::endl;
+
+ int p = 2;
+ double min_persistence = 0;
+
+ if (argc != 2) {
+ std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " <<
+ "the input. The program will now terminate.\n";
+ return 1;
+ }
+
+ typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base<double> Bitmap_base;
+ typedef Gudhi::Cubical_complex::Bitmap_cubical_complex< Bitmap_base > Bitmap_cubical_complex;
+
+ Bitmap_cubical_complex b(argv[1]);
+
+ typedef Gudhi::persistent_cohomology::Field_Zp Field_Zp;
+ typedef Gudhi::persistent_cohomology::Persistent_cohomology<Bitmap_cubical_complex, Field_Zp> Persistent_cohomology;
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology pcoh(b, true);
+ pcoh.init_coefficients(p); // initializes the coefficient field for homology
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ std::stringstream ss;
+ ss << argv[1] << "_persistence";
+ std::ofstream out(ss.str().c_str());
+ pcoh.output_diagram(out);
+ out.close();
+
+ std::cout << "Result in file: " << ss.str().c_str() << "\n";
+
+ return 0;
+}
+
diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt
new file mode 100644
index 00000000..ad86b763
--- /dev/null
+++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.6)
+project(GUDHIBitmap)
+
+add_executable ( Bitmap_cubical_complex Bitmap_cubical_complex.cpp )
+target_link_libraries(Bitmap_cubical_complex ${Boost_SYSTEM_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(Bitmap_cubical_complex ${TBB_RELEASE_LIBRARY})
+endif()
+add_test(Bitmap_cubical_complex_one_sphere ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalOneSphere.txt)
+add_test(Bitmap_cubical_complex_two_sphere ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt)
+
+add_executable ( Random_bitmap_cubical_complex Random_bitmap_cubical_complex.cpp )
+target_link_libraries(Random_bitmap_cubical_complex ${Boost_SYSTEM_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(Random_bitmap_cubical_complex ${TBB_RELEASE_LIBRARY})
+endif()
+add_test(Random_bitmap_cubical_complex ${CMAKE_CURRENT_BINARY_DIR}/Random_bitmap_cubical_complex 2 100 100)
+
+add_executable ( Bitmap_cubical_complex_periodic_boundary_conditions Bitmap_cubical_complex_periodic_boundary_conditions.cpp )
+target_link_libraries(Bitmap_cubical_complex_periodic_boundary_conditions ${Boost_SYSTEM_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(Bitmap_cubical_complex_periodic_boundary_conditions ${TBB_RELEASE_LIBRARY})
+endif()
+add_test(Bitmap_cubical_complex_periodic_2d_torus ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex_periodic_boundary_conditions ${CMAKE_SOURCE_DIR}/data/bitmap/2d_torus.txt)
+add_test(Bitmap_cubical_complex_periodic_3d_torus ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex_periodic_boundary_conditions ${CMAKE_SOURCE_DIR}/data/bitmap/3d_torus.txt)
+
diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp
new file mode 100644
index 00000000..416ad8f2
--- /dev/null
+++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp
@@ -0,0 +1,83 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 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/>.
+ */
+
+
+// for persistence algorithm
+#include <gudhi/reader_utils.h>
+#include <gudhi/Bitmap_cubical_complex.h>
+#include <gudhi/Persistent_cohomology.h>
+
+// standard stuff
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+int main(int argc, char** argv) {
+ srand(time(0));
+
+ std::cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " <<
+ "complexes. The first parameter of the program is the dimension D of the bitmap. The next D parameters are " <<
+ "number of top dimensional cubes in each dimension of the bitmap. The program will create random cubical " <<
+ "complex of that sizes and compute persistent homology of it." << std::endl;
+
+ int p = 2;
+ double min_persistence = 0;
+
+ if (argc < 3) {
+ std::cerr << "Wrong number of parameters, the program will now terminate\n";
+ return 1;
+ }
+
+ size_t dimensionOfBitmap = (size_t) atoi(argv[1]);
+ std::vector< unsigned > sizes;
+ size_t multipliers = 1;
+ for (size_t dim = 0; dim != dimensionOfBitmap; ++dim) {
+ unsigned sizeInThisDimension = (unsigned) atoi(argv[2 + dim]);
+ sizes.push_back(sizeInThisDimension);
+ multipliers *= sizeInThisDimension;
+ }
+
+ std::vector< double > data;
+ for (size_t i = 0; i != multipliers; ++i) {
+ data.push_back(rand() / static_cast<double>(RAND_MAX));
+ }
+
+ typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_base<double> Bitmap_cubical_complex_base;
+ typedef Gudhi::Cubical_complex::Bitmap_cubical_complex<Bitmap_cubical_complex_base> Bitmap_cubical_complex;
+ Bitmap_cubical_complex b(sizes, data);
+
+ // Compute the persistence diagram of the complex
+ typedef Gudhi::persistent_cohomology::Field_Zp Field_Zp;
+ typedef Gudhi::persistent_cohomology::Persistent_cohomology<Bitmap_cubical_complex, Field_Zp> Persistent_cohomology;
+ Persistent_cohomology pcoh(b);
+ pcoh.init_coefficients(p); // initializes the coefficient field for homology
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ std::stringstream ss;
+ ss << "randomComplex_persistence";
+ std::ofstream out(ss.str().c_str());
+ pcoh.output_diagram(out);
+ out.close();
+
+ return 0;
+}
+
diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h
new file mode 100644
index 00000000..56fa297c
--- /dev/null
+++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h
@@ -0,0 +1,593 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 2015 INRIA Sophia-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 BITMAP_CUBICAL_COMPLEX_H_
+#define BITMAP_CUBICAL_COMPLEX_H_
+
+#include <gudhi/Bitmap_cubical_complex_base.h>
+#include <gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h>
+
+#ifdef GUDHI_USE_TBB
+#include <tbb/parallel_sort.h>
+#endif
+
+#include <limits>
+#include <utility> // for pair<>
+#include <algorithm> // for sort
+#include <vector>
+#include <numeric> // for iota
+
+namespace Gudhi {
+
+namespace Cubical_complex {
+
+// global variable, was used just for debugging.
+const bool globalDbg = false;
+
+template <typename T> class is_before_in_filtration;
+
+/**
+ * @brief Cubical complex represented as a bitmap.
+ * @ingroup cubical_complex
+ * @details This is a Bitmap_cubical_complex class. It joints a functionalities of Bitmap_cubical_complex_base and
+ * Bitmap_cubical_complex_periodic_boundary_conditions_base classes into
+ * Gudhi persistent homology engine. It is a template class that inherit from its template parameter. The template
+ * parameter is supposed to be either Bitmap_cubical_complex_base or
+ * Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ **/
+template <typename T>
+class Bitmap_cubical_complex : public T {
+ public:
+ //*********************************************//
+ // Typedefs and typenames
+ //*********************************************//
+ typedef size_t Simplex_key;
+ typedef typename T::filtration_type Filtration_value;
+ typedef Simplex_key Simplex_handle;
+
+
+ //*********************************************//
+ // Constructors
+ //*********************************************//
+ // Over here we need to define various input types. I am proposing the following ones:
+ // Perseus style
+ // TODO(PD) H5 files?
+ // TODO(PD) binary files with little endiangs / big endians ?
+ // TODO(PD) constructor from a vector of elements of a type T. ?
+
+ /**
+ * Constructor form a Perseus-style file.
+ **/
+ Bitmap_cubical_complex(const char* perseus_style_file) :
+ T(perseus_style_file), key_associated_to_simplex(this->total_number_of_cells + 1) {
+ if (globalDbg) {
+ std::cerr << "Bitmap_cubical_complex( const char* perseus_style_file )\n";
+ }
+ for (size_t i = 0; i != this->total_number_of_cells; ++i) {
+ this->key_associated_to_simplex[i] = i;
+ }
+ // we initialize this only once, in each constructor, when the bitmap is constructed.
+ // If the user decide to change some elements of the bitmap, then this procedure need
+ // to be called again.
+ this->initialize_simplex_associated_to_key();
+ }
+
+ /**
+ * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells
+ * in the following directions and vector of element of a type T
+ * with filtration on top dimensional cells.
+ **/
+ Bitmap_cubical_complex(const std::vector<unsigned>& dimensions,
+ const std::vector<typename T::filtration_type>& top_dimensional_cells) :
+ T(dimensions, top_dimensional_cells),
+ key_associated_to_simplex(this->total_number_of_cells + 1) {
+ for (size_t i = 0; i != this->total_number_of_cells; ++i) {
+ this->key_associated_to_simplex[i] = i;
+ }
+ // we initialize this only once, in each constructor, when the bitmap is constructed.
+ // If the user decide to change some elements of the bitmap, then this procedure need
+ // to be called again.
+ this->initialize_simplex_associated_to_key();
+ }
+
+ /**
+ * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells
+ * in the following directions and vector of element of a type T::filtration_type
+ * with filtration on top dimensional cells. The last parameter of the constructor is a vector of boolean of a length
+ * equal to the dimension of cubical complex.
+ * If the position i on this vector is true, then we impose periodic boundary conditions in this direction.
+ **/
+ Bitmap_cubical_complex(const std::vector<unsigned>& dimensions,
+ const std::vector<typename T::filtration_type>& top_dimensional_cells,
+ std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed) :
+ T(dimensions, top_dimensional_cells, directions_in_which_periodic_b_cond_are_to_be_imposed),
+ key_associated_to_simplex(this->total_number_of_cells + 1) {
+ for (size_t i = 0; i != this->total_number_of_cells; ++i) {
+ this->key_associated_to_simplex[i] = i;
+ }
+ // we initialize this only once, in each constructor, when the bitmap is constructed.
+ // If the user decide to change some elements of the bitmap, then this procedure need
+ // to be called again.
+ this->initialize_simplex_associated_to_key();
+ }
+
+ /**
+ * Destructor of the Bitmap_cubical_complex class.
+ **/
+ virtual ~Bitmap_cubical_complex() {}
+
+ //*********************************************//
+ // Other 'easy' functions
+ //*********************************************//
+
+ /**
+ * Returns number of all cubes in the complex.
+ **/
+ size_t num_simplices()const {
+ return this->total_number_of_cells;
+ }
+
+ /**
+ * Returns a Simplex_handle to a cube that do not exist in this complex.
+ **/
+ static Simplex_handle null_simplex() {
+ if (globalDbg) {
+ std::cerr << "Simplex_handle null_simplex()\n";
+ }
+ return std::numeric_limits<Simplex_handle>::max();
+ }
+
+ /**
+ * Returns dimension of the complex.
+ **/
+ inline size_t dimension()const {
+ return this->sizes.size();
+ }
+
+ /**
+ * Return dimension of a cell pointed by the Simplex_handle.
+ **/
+ inline unsigned dimension(Simplex_handle sh)const {
+ if (globalDbg) {
+ std::cerr << "unsigned dimension(const Simplex_handle& sh)\n";
+ }
+ if (sh != std::numeric_limits<Simplex_handle>::max()) return this->get_dimension_of_a_cell(sh);
+ return -1;
+ }
+
+ /**
+ * Return the filtration of a cell pointed by the Simplex_handle.
+ **/
+ typename T::filtration_type filtration(Simplex_handle sh) {
+ if (globalDbg) {
+ std::cerr << "T::filtration_type filtration(const Simplex_handle& sh)\n";
+ }
+ // Returns the filtration value of a simplex.
+ if (sh != std::numeric_limits<Simplex_handle>::max()) return this->data[sh];
+ return std::numeric_limits<Simplex_handle>::max();
+ }
+
+ /**
+ * Return a key which is not a key of any cube in the considered data structure.
+ **/
+ static Simplex_key null_key() {
+ if (globalDbg) {
+ std::cerr << "Simplex_key null_key()\n";
+ }
+ return std::numeric_limits<Simplex_handle>::max();
+ }
+
+ /**
+ * Return the key of a cube pointed by the Simplex_handle.
+ **/
+ Simplex_key key(Simplex_handle sh)const {
+ if (globalDbg) {
+ std::cerr << "Simplex_key key(const Simplex_handle& sh)\n";
+ }
+ if (sh != std::numeric_limits<Simplex_handle>::max()) {
+ return this->key_associated_to_simplex[sh];
+ }
+ return this->null_key();
+ }
+
+ /**
+ * Return the Simplex_handle given the key of the cube.
+ **/
+ Simplex_handle simplex(Simplex_key key) {
+ if (globalDbg) {
+ std::cerr << "Simplex_handle simplex(Simplex_key key)\n";
+ }
+ if (key != std::numeric_limits<Simplex_handle>::max()) {
+ return this->simplex_associated_to_key[ key ];
+ }
+ return null_simplex();
+ }
+
+ /**
+ * Assign key to a cube pointed by the Simplex_handle
+ **/
+ void assign_key(Simplex_handle sh, Simplex_key key) {
+ if (globalDbg) {
+ std::cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n";
+ }
+ if (key == std::numeric_limits<Simplex_handle>::max()) return;
+ this->key_associated_to_simplex[sh] = key;
+ this->simplex_associated_to_key[key] = sh;
+ }
+
+ /**
+ * Function called from a constructor. It is needed for Filtration_simplex_iterator to work.
+ **/
+ void initialize_simplex_associated_to_key();
+
+ //*********************************************//
+ // Iterators
+ //*********************************************//
+
+ /**
+ * Boundary_simplex_range class provides ranges for boundary iterators.
+ **/
+ typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator;
+ typedef typename std::vector< Simplex_handle > Boundary_simplex_range;
+
+ /**
+ * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration.
+ * Secondary criteria for filtration are:
+ * (1) Dimension of a cube (lower dimensional comes first).
+ * (2) Position in the data structure (the ones that are earlies in the data structure comes first).
+ **/
+ class Filtration_simplex_range;
+
+ class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > {
+ // Iterator over all simplices of the complex in the order of the indexing scheme.
+ // 'value_type' must be 'Simplex_handle'.
+ public:
+ Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { }
+
+ Filtration_simplex_iterator() : b(NULL), position(0) { }
+
+ Filtration_simplex_iterator operator++() {
+ if (globalDbg) {
+ std::cerr << "Filtration_simplex_iterator operator++\n";
+ }
+ ++this->position;
+ return (*this);
+ }
+
+ Filtration_simplex_iterator operator++(int) {
+ Filtration_simplex_iterator result = *this;
+ ++(*this);
+ return result;
+ }
+
+ Filtration_simplex_iterator& operator=(const Filtration_simplex_iterator& rhs) {
+ if (globalDbg) {
+ std::cerr << "Filtration_simplex_iterator operator =\n";
+ }
+ this->b = rhs.b;
+ this->position = rhs.position;
+ return (*this);
+ }
+
+ bool operator==(const Filtration_simplex_iterator& rhs)const {
+ if (globalDbg) {
+ std::cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n";
+ }
+ return ( this->position == rhs.position);
+ }
+
+ bool operator!=(const Filtration_simplex_iterator& rhs)const {
+ if (globalDbg) {
+ std::cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n";
+ }
+ return !(*this == rhs);
+ }
+
+ Simplex_handle operator*() {
+ if (globalDbg) {
+ std::cerr << "Simplex_handle operator*()\n";
+ }
+ return this->b->simplex_associated_to_key[ this->position ];
+ }
+
+ friend class Filtration_simplex_range;
+
+ private:
+ Bitmap_cubical_complex<T>* b;
+ size_t position;
+ };
+
+ /**
+ * @brief Filtration_simplex_range provides the ranges for Filtration_simplex_iterator.
+ **/
+ class Filtration_simplex_range {
+ // Range over the simplices of the complex in the order of the filtration.
+ // .begin() and .end() return type Filtration_simplex_iterator.
+ public:
+ typedef Filtration_simplex_iterator const_iterator;
+ typedef Filtration_simplex_iterator iterator;
+
+ Filtration_simplex_range(Bitmap_cubical_complex<T>* b) : b(b) { }
+
+ Filtration_simplex_iterator begin() {
+ if (globalDbg) {
+ std::cerr << "Filtration_simplex_iterator begin() \n";
+ }
+ return Filtration_simplex_iterator(this->b);
+ }
+
+ Filtration_simplex_iterator end() {
+ if (globalDbg) {
+ std::cerr << "Filtration_simplex_iterator end()\n";
+ }
+ Filtration_simplex_iterator it(this->b);
+ it.position = this->b->simplex_associated_to_key.size();
+ return it;
+ }
+
+ private:
+ Bitmap_cubical_complex<T>* b;
+ };
+
+
+
+ //*********************************************//
+ // Methods to access iterators from the container:
+
+ /**
+ * boundary_simplex_range creates an object of a Boundary_simplex_range class
+ * that provides ranges for the Boundary_simplex_iterator.
+ **/
+ Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) {
+ return this->get_boundary_of_a_cell(sh);
+ }
+
+ /**
+ * filtration_simplex_range creates an object of a Filtration_simplex_range class
+ * that provides ranges for the Filtration_simplex_iterator.
+ **/
+ Filtration_simplex_range filtration_simplex_range() {
+ if (globalDbg) {
+ std::cerr << "Filtration_simplex_range filtration_simplex_range()\n";
+ }
+ // Returns a range over the simplices of the complex in the order of the filtration
+ return Filtration_simplex_range(this);
+ }
+ //*********************************************//
+
+
+
+ //*********************************************//
+ // Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are
+ // there.
+ // TODO(PD) the file IndexingTag.h in the Gudhi library contains an empty structure, so
+ // I understand that this is something that was planned (for simplicial maps?)
+ // but was never finished. The only idea I have here is to use the same empty structure from
+ // IndexingTag.h file, but only if the compiler needs it. If the compiler
+ // do not need it, then I would rather not add here elements which I do not understand.
+ // typedef Indexing_tag
+
+ /**
+ * Function needed for compatibility with Gudhi. Not useful for other purposes.
+ **/
+ std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
+ std::vector< size_t > bdry = this->get_boundary_of_a_cell(sh);
+ if (globalDbg) {
+ std::cerr << "std::pair<Simplex_handle, Simplex_handle> endpoints( Simplex_handle sh )\n";
+ std::cerr << "bdry.size() : " << bdry.size() << std::endl;
+ }
+ // this method returns two first elements from the boundary of sh.
+ if (bdry.size() < 2)
+ throw("Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the "
+ "boundary.");
+ return std::make_pair(bdry[0], bdry[1]);
+ }
+
+
+ /**
+ * Class needed for compatibility with Gudhi. Not useful for other purposes.
+ **/
+ class Skeleton_simplex_range;
+
+ class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > {
+ // Iterator over all simplices of the complex in the order of the indexing scheme.
+ // 'value_type' must be 'Simplex_handle'.
+ public:
+ Skeleton_simplex_iterator(Bitmap_cubical_complex* b, size_t d) : b(b), dimension(d) {
+ if (globalDbg) {
+ std::cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n";
+ }
+ // find the position of the first simplex of a dimension d
+ this->position = 0;
+ while (
+ (this->position != b->data.size()) &&
+ (this->b->get_dimension_of_a_cell(this->position) != this->dimension)
+ ) {
+ ++this->position;
+ }
+ }
+
+ Skeleton_simplex_iterator() : b(NULL), position(0), dimension(0) { }
+
+ Skeleton_simplex_iterator operator++() {
+ if (globalDbg) {
+ std::cerr << "Skeleton_simplex_iterator operator++()\n";
+ }
+ // increment the position as long as you did not get to the next element of the dimension dimension.
+ ++this->position;
+ while (
+ (this->position != this->b->data.size()) &&
+ (this->b->get_dimension_of_a_cell(this->position) != this->dimension)
+ ) {
+ ++this->position;
+ }
+ return (*this);
+ }
+
+ Skeleton_simplex_iterator operator++(int) {
+ Skeleton_simplex_iterator result = *this;
+ ++(*this);
+ return result;
+ }
+
+ Skeleton_simplex_iterator& operator=(const Skeleton_simplex_iterator& rhs) {
+ if (globalDbg) {
+ std::cerr << "Skeleton_simplex_iterator operator =\n";
+ }
+ this->b = rhs.b;
+ this->position = rhs.position;
+ this->dimension = rhs.dimension;
+ return (*this);
+ }
+
+ bool operator==(const Skeleton_simplex_iterator& rhs)const {
+ if (globalDbg) {
+ std::cerr << "bool operator ==\n";
+ }
+ return ( this->position == rhs.position);
+ }
+
+ bool operator!=(const Skeleton_simplex_iterator& rhs)const {
+ if (globalDbg) {
+ std::cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n";
+ }
+ return !(*this == rhs);
+ }
+
+ Simplex_handle operator*() {
+ if (globalDbg) {
+ std::cerr << "Simplex_handle operator*() \n";
+ }
+ return this->position;
+ }
+
+ friend class Skeleton_simplex_range;
+ private:
+ Bitmap_cubical_complex<T>* b;
+ size_t position;
+ unsigned dimension;
+ };
+
+ /**
+ * @brief Class needed for compatibility with Gudhi. Not useful for other purposes.
+ **/
+ class Skeleton_simplex_range {
+ // Range over the simplices of the complex in the order of the filtration.
+ // .begin() and .end() return type Filtration_simplex_iterator.
+ public:
+ typedef Skeleton_simplex_iterator const_iterator;
+ typedef Skeleton_simplex_iterator iterator;
+
+ Skeleton_simplex_range(Bitmap_cubical_complex<T>* b, unsigned dimension) : b(b), dimension(dimension) { }
+
+ Skeleton_simplex_iterator begin() {
+ if (globalDbg) {
+ std::cerr << "Skeleton_simplex_iterator begin()\n";
+ }
+ return Skeleton_simplex_iterator(this->b, this->dimension);
+ }
+
+ Skeleton_simplex_iterator end() {
+ if (globalDbg) {
+ std::cerr << "Skeleton_simplex_iterator end()\n";
+ }
+ Skeleton_simplex_iterator it(this->b, this->dimension);
+ it.position = this->b->data.size();
+ return it;
+ }
+
+ private:
+ Bitmap_cubical_complex<T>* b;
+ unsigned dimension;
+ };
+
+ /**
+ * Function needed for compatibility with Gudhi. Not useful for other purposes.
+ **/
+ Skeleton_simplex_range skeleton_simplex_range(unsigned dimension) {
+ if (globalDbg) {
+ std::cerr << "Skeleton_simplex_range skeleton_simplex_range( unsigned dimension )\n";
+ }
+ return Skeleton_simplex_range(this, dimension);
+ }
+
+ friend class is_before_in_filtration<T>;
+
+ protected:
+ std::vector< size_t > key_associated_to_simplex;
+ std::vector< size_t > simplex_associated_to_key;
+}; // Bitmap_cubical_complex
+
+template <typename T>
+void Bitmap_cubical_complex<T>::initialize_simplex_associated_to_key() {
+ if (globalDbg) {
+ std::cerr << "void Bitmap_cubical_complex<T>::initialize_elements_ordered_according_to_filtration() \n";
+ }
+ this->simplex_associated_to_key = std::vector<size_t>(this->data.size());
+ std::iota(std::begin(simplex_associated_to_key), std::end(simplex_associated_to_key), 0);
+#ifdef GUDHI_USE_TBB
+ tbb::parallel_sort(simplex_associated_to_key.begin(), simplex_associated_to_key.end(),
+ is_before_in_filtration<T>(this));
+#else
+ std::sort(simplex_associated_to_key.begin(), simplex_associated_to_key.end(), is_before_in_filtration<T>(this));
+#endif
+
+ // we still need to deal here with a key_associated_to_simplex:
+ for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) {
+ this->key_associated_to_simplex[ simplex_associated_to_key[i] ] = i;
+ }
+}
+
+template <typename T>
+class is_before_in_filtration {
+ public:
+ explicit is_before_in_filtration(Bitmap_cubical_complex<T> * CC)
+ : CC_(CC) { }
+
+ bool operator()(const typename Bitmap_cubical_complex<T>::Simplex_handle& sh1,
+ const typename Bitmap_cubical_complex<T>::Simplex_handle& sh2) const {
+ // Not using st_->filtration(sh1) because it uselessly tests for null_simplex.
+ typename T::filtration_type fil1 = CC_->data[sh1];
+ typename T::filtration_type fil2 = CC_->data[sh2];
+ if (fil1 != fil2) {
+ return fil1 < fil2;
+ }
+ // in this case they are on the same filtration level, so the dimension decide.
+ size_t dim1 = CC_->get_dimension_of_a_cell(sh1);
+ size_t dim2 = CC_->get_dimension_of_a_cell(sh2);
+ if (dim1 != dim2) {
+ return dim1 < dim2;
+ }
+ // in this case both filtration and dimensions of the considered cubes are the same. To have stable sort, we simply
+ // compare their positions in the bitmap:
+ return sh1 < sh2;
+ }
+
+ protected:
+ Bitmap_cubical_complex<T>* CC_;
+};
+
+} // namespace Cubical_complex
+
+} // namespace Gudhi
+
+#endif // BITMAP_CUBICAL_COMPLEX_H_
diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h
new file mode 100644
index 00000000..3a8c3988
--- /dev/null
+++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h
@@ -0,0 +1,142 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 2015 INRIA Sophia-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 BITMAP_CUBICAL_COMPLEX_COUNTER_H_
+#define BITMAP_CUBICAL_COMPLEX_COUNTER_H_
+
+#include <iostream>
+#include <vector>
+
+namespace Gudhi {
+
+namespace Cubical_complex {
+
+/**
+ * @brief This is an implementation of a counter being a vector of integers.
+ * @details The constructor of the class takes as an input two vectors W and V.
+ * It assumes that W < V coordinatewise.
+ * If the initial counter W is not specified, it is assumed to be vector of zeros.
+ * The class allows to iterate between W and V by using increment() function.
+ * The increment() function returns a bool value.
+ * The current counter reach the end counter V if the value returned by the increment function is FALSE.
+ * This class is needed for the implementation of a bitmapCubicalComplex.
+ **/
+class counter {
+ public:
+ /**
+ * Constructor of a counter class. It takes only the parameter which is the end value of the counter.
+ * The default beginning value is a vector of the same length as the endd, filled-in with zeros.
+ **/
+ counter(const std::vector<unsigned>& endd) : begin(endd.size(), 0), end(endd), current(endd.size(), 0) { }
+
+ /**
+ * Constructor of a counter class. It takes as the input beginn and end vector.
+ * It assumes that begin vector is lexicographically below the end vector.
+ **/
+ counter(const std::vector< unsigned >& beginn, const std::vector< unsigned >& endd) : begin(beginn), end(endd), current(endd.size(), 0) {
+ if (beginn.size() != endd.size())
+ throw "In constructor of a counter, begin and end vectors do not have the same size. Program terminate";
+ }
+
+ /**
+ * Function to increment the counter. If the value returned by the function is true,
+ * then the incrementation process was successful.
+ * If the value of the function is false, that means, that the counter have reached its end-value.
+ **/
+ bool increment() {
+ size_t i = 0;
+ while ((i != this->end.size()) && (this->current[i] == this->end[i])) {
+ ++i;
+ }
+
+ if (i == this->end.size())return false;
+ ++this->current[i];
+ for (size_t j = 0; j != i; ++j) {
+ this->current[j] = this->begin[j];
+ }
+ return true;
+ }
+
+ /**
+ * Function to check if we are at the end of counter.
+ **/
+ bool isFinal() {
+ for (size_t i = 0; i != this->current.size(); ++i) {
+ if (this->current[i] == this->end[i])return true;
+ }
+ return false;
+ }
+
+ /**
+ * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition.
+ * Its aim is to find an counter corresponding to the element the following
+ * boundary element is identified with when periodic boundary conditions are imposed.
+ **/
+ std::vector< unsigned > find_opposite(const std::vector< bool >& directionsForPeriodicBCond) {
+ std::vector< unsigned > result;
+ for (size_t i = 0; i != this->current.size(); ++i) {
+ if ((this->current[i] == this->end[i]) && (directionsForPeriodicBCond[i] == true)) {
+ result.push_back(this->begin[i]);
+ } else {
+ result.push_back(this->current[i]);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Function checking at which positions the current value of a counter is the final value of the counter.
+ **/
+ std::vector< bool > directions_of_finals() {
+ std::vector< bool > result;
+ for (size_t i = 0; i != this->current.size(); ++i) {
+ if (this->current[i] == this->end[i]) {
+ result.push_back(true);
+ } else {
+ result.push_back(false);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Function to write counter to the stream.
+ **/
+ friend std::ostream& operator<<(std::ostream& out, const counter& c) {
+ // std::cerr << "c.current.size() : " << c.current.size() << endl;
+ for (size_t i = 0; i != c.current.size(); ++i) {
+ out << c.current[i] << " ";
+ }
+ return out;
+ }
+
+ private:
+ std::vector< unsigned > begin;
+ std::vector< unsigned > end;
+ std::vector< unsigned > current;
+};
+
+} // namespace Cubical_complex
+
+} // namespace Gudhi
+
+#endif // BITMAP_CUBICAL_COMPLEX_COUNTER_H_
diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h
new file mode 100644
index 00000000..2f74ba9e
--- /dev/null
+++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h
@@ -0,0 +1,815 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 2015 INRIA Sophia-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 BITMAP_CUBICAL_COMPLEX_BASE_H_
+#define BITMAP_CUBICAL_COMPLEX_BASE_H_
+
+#include <gudhi/Bitmap_cubical_complex/counter.h>
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include <fstream>
+#include <algorithm>
+#include <iterator>
+#include <limits>
+#include <utility> // for pair<>
+
+namespace Gudhi {
+
+namespace Cubical_complex {
+
+/**
+ * @brief Cubical complex represented as a bitmap, class with basic implementation.
+ * @ingroup cubical_complex
+ * @details This is a class implementing a basic bitmap data structure to store cubical complexes.
+ * It implements only the most basic subroutines.
+ * The idea of the bitmap is the following. Our aim is to have a memory efficient
+ * data structure to store d-dimensional cubical complex
+ * C being a cubical decomposition
+ * of a rectangular region of a space. This is achieved by storing C as a
+ * vector of bits (this is where the name 'bitmap' came from).
+ * Each cell is represented by a single
+ * bit (in case of black and white bitmaps, or by a single element of a type T
+ * (here T is a filtration type of a bitmap, typically a double).
+ * All the informations needed for homology and
+ * persistent homology computations (like dimension of a cell, boundary and
+ * coboundary elements of a cell, are then obtained from the
+ * position of the element in C.
+ * The default filtration used in this implementation is the lower star filtration.
+ */
+template <typename T>
+class Bitmap_cubical_complex_base {
+ public:
+ typedef T filtration_type;
+
+ /**
+ *Default constructor
+ **/
+ Bitmap_cubical_complex_base() :
+ total_number_of_cells(0) { }
+ /**
+ * There are a few constructors of a Bitmap_cubical_complex_base class.
+ * First one, that takes vector<unsigned>, creates an empty bitmap of a dimension equal
+ * the number of elements in the
+ * input vector and size in the i-th dimension equal the number in the position i-of the input vector.
+ */
+ Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes);
+ /**
+ * The second constructor takes as a input a Perseus style file. For more details,
+ * please consult the documentations of
+ * Perseus software as well as examples attached to this
+ * implementation.
+ **/
+ Bitmap_cubical_complex_base(const char* perseus_style_file);
+ /**
+ * The last constructor of a Bitmap_cubical_complex_base class accepts vector of dimensions (as the first one)
+ * together with vector of filtration values of top dimensional cells.
+ **/
+ Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions, const std::vector<T>& top_dimensional_cells);
+
+ /**
+ * Destructor of the Bitmap_cubical_complex_base class.
+ **/
+ virtual ~Bitmap_cubical_complex_base() { }
+
+ /**
+ * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell
+ * and get_cell_data are the basic
+ * functions that compute boundary / coboundary / dimension and the filtration
+ * value form a position of a cell in the structure of a bitmap. The input parameter of all of those function is a
+ * non-negative integer, indicating a position of a cube in the data structure.
+ * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to
+ * the positions of (co)boundary element of the input cell.
+ */
+ virtual inline std::vector< size_t > get_boundary_of_a_cell(size_t cell)const;
+ /**
+ * The functions get_coboundary_of_a_cell, get_coboundary_of_a_cell,
+ * get_dimension_of_a_cell and get_cell_data are the basic
+ * functions that compute boundary / coboundary / dimension and the filtration
+ * value form a position of a cell in the structure of a bitmap.
+ * The input parameter of all of those function is a non-negative integer,
+ * indicating a position of a cube in the data structure.
+ * In the case of functions that compute (co)boundary, the output is a vector if
+ * non-negative integers pointing to the
+ * positions of (co)boundary element of the input cell.
+ **/
+ virtual inline std::vector< size_t > get_coboundary_of_a_cell(size_t cell)const;
+ /**
+ * In the case of get_dimension_of_a_cell function, the output is a non-negative integer
+ * indicating the dimension of a cell.
+ **/
+ inline unsigned get_dimension_of_a_cell(size_t cell)const;
+ /**
+ * In the case of get_cell_data, the output parameter is a reference to the value of a cube in a given position.
+ * This allows reading and changing the value of filtration. Note that if the value of a filtration is changed, the
+ * code do not check if we have a filtration or not. i.e. it do not check if the value of a filtration of a cell is
+ * not smaller than the value of a filtration of its boundary and not greater than the value of its coboundary.
+ **/
+ inline T& get_cell_data(size_t cell);
+
+
+ /**
+ * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells.
+ * Then, there are a few ways one can pick the filtration of lower dimensional
+ * cells. The most typical one is by so called lower star filtration. This function is always called by any
+ * constructor which takes the top dimensional cells. If you use such a constructor,
+ * then there is no need to call this function. Call it only if you are putting the filtration
+ * of the cells by your own (for instance by using Top_dimensional_cells_iterator).
+ **/
+ void impose_lower_star_filtration(); // assume that top dimensional cells are already set.
+
+ /**
+ * Returns dimension of a complex.
+ **/
+ inline unsigned dimension()const {
+ return sizes.size();
+ }
+
+ /**
+ * Returns number of all cubes in the data structure.
+ **/
+ inline unsigned size()const {
+ return this->data.size();
+ }
+
+ /**
+ * Writing to stream operator. By using it we get the values T of cells in order in which they are stored in the
+ * structure. This procedure is used for debugging purposes.
+ **/
+ template <typename K>
+ friend std::ostream& operator<<(std::ostream & os, const Bitmap_cubical_complex_base<K>& b);
+
+ /**
+ * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values
+ * equally distributed in the range of data.
+ * Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute
+ * persistence gets worst. When dealing with this type of data, one may want to put different values on cells to
+ * some number of bins. The function put_data_to_bins( size_t number_of_bins ) is designed for that purpose.
+ * The parameter of the function is the number of bins (distinct values) we want to have in the cubical complex.
+ **/
+ void put_data_to_bins(size_t number_of_bins);
+
+ /**
+ * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values
+ * equally distributed in the range of data.
+ * Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute
+ * persistence gets worst. When dealing with this type of data, one may want to put different values on cells to
+ * some number of bins. The function put_data_to_bins( T diameter_of_bin ) is designed for that purpose.
+ * The parameter of it is the diameter of each bin. Note that the bottleneck distance between the persistence
+ * diagram of the cubical complex before and after using such a function will be bounded by the parameter
+ * diameter_of_bin.
+ **/
+ void put_data_to_bins(T diameter_of_bin);
+
+ /**
+ * Functions to find min and max values of filtration.
+ **/
+ std::pair< T, T > min_max_filtration();
+
+ // ITERATORS
+
+ /**
+ * @brief Iterator through all cells in the complex (in order they appear in the structure -- i.e.
+ * in lexicographical order).
+ **/
+ class All_cells_iterator : std::iterator< std::input_iterator_tag, T > {
+ public:
+ All_cells_iterator() {
+ this->counter = 0;
+ }
+
+ All_cells_iterator operator++() {
+ // first find first element of the counter that can be increased:
+ ++this->counter;
+ return *this;
+ }
+
+ All_cells_iterator operator++(int) {
+ All_cells_iterator result = *this;
+ ++(*this);
+ return result;
+ }
+
+ All_cells_iterator& operator=(const All_cells_iterator& rhs) {
+ this->counter = rhs.counter;
+ return *this;
+ }
+
+ bool operator==(const All_cells_iterator& rhs)const {
+ if (this->counter != rhs.counter)return false;
+ return true;
+ }
+
+ bool operator!=(const All_cells_iterator& rhs)const {
+ return !(*this == rhs);
+ }
+
+ /*
+ * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as
+ * an argument of the following functions:
+ * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell
+ * boundary and coboundary and dimension
+ * and in function get_cell_data to get a filtration of a cell.
+ */
+ size_t operator*() {
+ return this->counter;
+ }
+ friend class Bitmap_cubical_complex_base;
+ protected:
+ size_t counter;
+ };
+
+ /**
+ * Function returning a All_cells_iterator to the first cell of the bitmap.
+ **/
+ All_cells_iterator all_cells_iterator_begin() {
+ All_cells_iterator a;
+ return a;
+ }
+
+ /**
+ * Function returning a All_cells_iterator to the last cell of the bitmap.
+ **/
+ All_cells_iterator all_cells_iterator_end() {
+ All_cells_iterator a;
+ a.counter = this->data.size();
+ return a;
+ }
+
+ /**
+ * @brief All_cells_range class provides ranges for All_cells_iterator
+ **/
+ class All_cells_range {
+ public:
+ All_cells_range(Bitmap_cubical_complex_base* b) : b(b) { }
+
+ All_cells_iterator begin() {
+ return b->all_cells_iterator_begin();
+ }
+
+ All_cells_iterator end() {
+ return b->all_cells_iterator_end();
+ }
+ private:
+ Bitmap_cubical_complex_base<T>* b;
+ };
+
+ All_cells_range all_cells_range() {
+ return All_cells_range(this);
+ }
+
+
+ /**
+ * Boundary_range class provides ranges for boundary iterators.
+ **/
+ typedef typename std::vector< size_t >::const_iterator Boundary_iterator;
+ typedef typename std::vector< size_t > Boundary_range;
+
+ /**
+ * boundary_simplex_range creates an object of a Boundary_simplex_range class
+ * that provides ranges for the Boundary_simplex_iterator.
+ **/
+ Boundary_range boundary_range(size_t sh) {
+ return this->get_boundary_of_a_cell(sh);
+ }
+
+ /**
+ * Coboundary_range class provides ranges for boundary iterators.
+ **/
+ typedef typename std::vector< size_t >::const_iterator Coboundary_iterator;
+ typedef typename std::vector< size_t > Coboundary_range;
+
+ /**
+ * boundary_simplex_range creates an object of a Boundary_simplex_range class
+ * that provides ranges for the Boundary_simplex_iterator.
+ **/
+ Coboundary_range coboundary_range(size_t sh) {
+ return this->get_coboundary_of_a_cell(sh);
+ }
+
+ /**
+ * @brief Iterator through top dimensional cells of the complex. The cells appear in order they are stored
+ * in the structure (i.e. in lexicographical order)
+ **/
+ class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, T > {
+ public:
+ Top_dimensional_cells_iterator(Bitmap_cubical_complex_base& b) : b(b) {
+ this->counter = std::vector<size_t>(b.dimension());
+ // std::fill( this->counter.begin() , this->counter.end() , 0 );
+ }
+
+ Top_dimensional_cells_iterator operator++() {
+ // first find first element of the counter that can be increased:
+ size_t dim = 0;
+ while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1))++dim;
+
+ if (dim != this->b.dimension()) {
+ ++this->counter[dim];
+ for (size_t i = 0; i != dim; ++i) {
+ this->counter[i] = 0;
+ }
+ } else {
+ ++this->counter[0];
+ }
+ return *this;
+ }
+
+ Top_dimensional_cells_iterator operator++(int) {
+ Top_dimensional_cells_iterator result = *this;
+ ++(*this);
+ return result;
+ }
+
+ Top_dimensional_cells_iterator& operator=(const Top_dimensional_cells_iterator& rhs) {
+ this->counter = rhs.counter;
+ this->b = rhs.b;
+ return *this;
+ }
+
+ bool operator==(const Top_dimensional_cells_iterator& rhs)const {
+ if (&this->b != &rhs.b)return false;
+ if (this->counter.size() != rhs.counter.size())return false;
+ for (size_t i = 0; i != this->counter.size(); ++i) {
+ if (this->counter[i] != rhs.counter[i])return false;
+ }
+ return true;
+ }
+
+ bool operator!=(const Top_dimensional_cells_iterator& rhs)const {
+ return !(*this == rhs);
+ }
+
+ /*
+ * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as
+ * an argument of the following functions:
+ * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell
+ * boundary and coboundary and dimension
+ * and in function get_cell_data to get a filtration of a cell.
+ */
+ size_t operator*() {
+ return this->compute_index_in_bitmap();
+ }
+
+ size_t compute_index_in_bitmap()const {
+ size_t index = 0;
+ for (size_t i = 0; i != this->counter.size(); ++i) {
+ index += (2 * this->counter[i] + 1) * this->b.multipliers[i];
+ }
+ return index;
+ }
+
+ void print_counter()const {
+ for (size_t i = 0; i != this->counter.size(); ++i) {
+ std::cout << this->counter[i] << " ";
+ }
+ }
+ friend class Bitmap_cubical_complex_base;
+ protected:
+ std::vector< size_t > counter;
+ Bitmap_cubical_complex_base& b;
+ };
+
+ /**
+ * Function returning a Top_dimensional_cells_iterator to the first top dimensional cell of the bitmap.
+ **/
+ Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin() {
+ Top_dimensional_cells_iterator a(*this);
+ return a;
+ }
+
+ /**
+ * Function returning a Top_dimensional_cells_iterator to the last top dimensional cell of the bitmap.
+ **/
+ Top_dimensional_cells_iterator top_dimensional_cells_iterator_end() {
+ Top_dimensional_cells_iterator a(*this);
+ for (size_t i = 0; i != this->dimension(); ++i) {
+ a.counter[i] = this->sizes[i] - 1;
+ }
+ a.counter[0]++;
+ return a;
+ }
+
+ /**
+ * @brief Top_dimensional_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range
+ **/
+ class Top_dimensional_cells_range {
+ public:
+ Top_dimensional_cells_range(Bitmap_cubical_complex_base* b) : b(b) { }
+
+ Top_dimensional_cells_iterator begin() {
+ return b->top_dimensional_cells_iterator_begin();
+ }
+
+ Top_dimensional_cells_iterator end() {
+ return b->top_dimensional_cells_iterator_end();
+ }
+ private:
+ Bitmap_cubical_complex_base<T>* b;
+ };
+
+ Top_dimensional_cells_range top_dimensional_cells_range() {
+ return Top_dimensional_cells_range(this);
+ }
+
+
+ //****************************************************************************************************************//
+ //****************************************************************************************************************//
+ //****************************************************************************************************************//
+ //****************************************************************************************************************//
+
+ inline size_t number_cells()const {
+ return this->total_number_of_cells;
+ }
+
+ //****************************************************************************************************************//
+ //****************************************************************************************************************//
+ //****************************************************************************************************************//
+ //****************************************************************************************************************//
+
+ protected:
+ std::vector<unsigned> sizes;
+ std::vector<unsigned> multipliers;
+ std::vector<T> data;
+ size_t total_number_of_cells;
+
+ void set_up_containers(const std::vector<unsigned>& sizes) {
+ unsigned multiplier = 1;
+ for (size_t i = 0; i != sizes.size(); ++i) {
+ this->sizes.push_back(sizes[i]);
+ this->multipliers.push_back(multiplier);
+ multiplier *= 2 * sizes[i] + 1;
+ }
+ this->data = std::vector<T>(multiplier, std::numeric_limits<T>::max());
+ this->total_number_of_cells = multiplier;
+ }
+
+ size_t compute_position_in_bitmap(const std::vector< unsigned >& counter) {
+ size_t position = 0;
+ for (size_t i = 0; i != this->multipliers.size(); ++i) {
+ position += this->multipliers[i] * counter[i];
+ }
+ return position;
+ }
+
+ std::vector<unsigned> compute_counter_for_given_cell(size_t cell)const {
+ std::vector<unsigned> counter;
+ counter.reserve(this->sizes.size());
+ for (size_t dim = this->sizes.size(); dim != 0; --dim) {
+ counter.push_back(cell / this->multipliers[dim - 1]);
+ cell = cell % this->multipliers[dim - 1];
+ }
+ std::reverse(counter.begin(), counter.end());
+ return counter;
+ }
+ void read_perseus_style_file(const char* perseus_style_file);
+ void setup_bitmap_based_on_top_dimensional_cells_list(const std::vector<unsigned>& sizes_in_following_directions,
+ const std::vector<T>& top_dimensional_cells);
+ Bitmap_cubical_complex_base(const char* perseus_style_file, std::vector<bool> directions);
+ Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes, std::vector<bool> directions);
+ Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& top_dimensional_cells,
+ std::vector<bool> directions);
+};
+
+template <typename T>
+void Bitmap_cubical_complex_base<T>::put_data_to_bins(size_t number_of_bins) {
+ bool bdg = false;
+
+ std::pair< T, T > min_max = this->min_max_filtration();
+ T dx = (min_max.second - min_max.first) / (T) number_of_bins;
+
+ // now put the data into the appropriate bins:
+ for (size_t i = 0; i != this->data.size(); ++i) {
+ if (bdg) {
+ std::cerr << "Before binning : " << this->data[i] << std::endl;
+ }
+ this->data[i] = min_max.first + dx * (this->data[i] - min_max.first) / number_of_bins;
+ if (bdg) {
+ std::cerr << "After binning : " << this->data[i] << std::endl;
+ getchar();
+ }
+ }
+}
+
+template <typename T>
+void Bitmap_cubical_complex_base<T>::put_data_to_bins(T diameter_of_bin) {
+ bool bdg = false;
+ std::pair< T, T > min_max = this->min_max_filtration();
+
+ size_t number_of_bins = (min_max.second - min_max.first) / diameter_of_bin;
+ // now put the data into the appropriate bins:
+ for (size_t i = 0; i != this->data.size(); ++i) {
+ if (bdg) {
+ std::cerr << "Before binning : " << this->data[i] << std::endl;
+ }
+ this->data[i] = min_max.first + diameter_of_bin * (this->data[i] - min_max.first) / number_of_bins;
+ if (bdg) {
+ std::cerr << "After binning : " << this->data[i] << std::endl;
+ getchar();
+ }
+ }
+}
+
+template <typename T>
+std::pair< T, T > Bitmap_cubical_complex_base<T>::min_max_filtration() {
+ std::pair< T, T > min_max(std::numeric_limits<T>::max(), std::numeric_limits<T>::min());
+ for (size_t i = 0; i != this->data.size(); ++i) {
+ if (this->data[i] < min_max.first)min_max.first = this->data[i];
+ if (this->data[i] > min_max.second)min_max.second = this->data[i];
+ }
+ return min_max;
+}
+
+template <typename K>
+std::ostream& operator<<(std::ostream & out, const Bitmap_cubical_complex_base<K>& b) {
+ for (typename Bitmap_cubical_complex_base<K>::all_cells_const_iterator
+ it = b.all_cells_const_begin(); it != b.all_cells_const_end(); ++it) {
+ out << *it << " ";
+ }
+ return out;
+}
+
+template <typename T>
+Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base
+(const std::vector<unsigned>& sizes) {
+ this->set_up_containers(sizes);
+}
+
+template <typename T>
+void Bitmap_cubical_complex_base<T>::setup_bitmap_based_on_top_dimensional_cells_list(const std::vector<unsigned>& sizes_in_following_directions,
+ const std::vector<T>& top_dimensional_cells) {
+ this->set_up_containers(sizes_in_following_directions);
+
+ size_t number_of_top_dimensional_elements = 1;
+ for (size_t i = 0; i != sizes_in_following_directions.size(); ++i) {
+ number_of_top_dimensional_elements *= sizes_in_following_directions[i];
+ }
+ if (number_of_top_dimensional_elements != top_dimensional_cells.size()) {
+ std::cerr << "Error in constructor Bitmap_cubical_complex_base ( std::vector<size_t> sizes_in_following_directions"
+ << ", std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from "
+ << "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector."
+ << std::endl;
+ throw("Error in constructor Bitmap_cubical_complex_base( std::vector<size_t> sizes_in_following_directions,"
+ "std::vector<T> top_dimensional_cells ). Number of top dimensional elements that follow from "
+ "sizes_in_following_directions vector is different than the size of top_dimensional_cells vector.");
+ }
+
+ Bitmap_cubical_complex_base<T>::Top_dimensional_cells_iterator it(*this);
+ size_t index = 0;
+ for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
+ this->get_cell_data(*it) = top_dimensional_cells[index];
+ ++index;
+ }
+ this->impose_lower_star_filtration();
+}
+
+template <typename T>
+Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base
+(const std::vector<unsigned>& sizes_in_following_directions, const std::vector<T>& top_dimensional_cells) {
+ this->setup_bitmap_based_on_top_dimensional_cells_list(sizes_in_following_directions, top_dimensional_cells);
+}
+
+template <typename T>
+void Bitmap_cubical_complex_base<T>::read_perseus_style_file(const char* perseus_style_file) {
+ bool dbg = false;
+ std::ifstream inFiltration;
+ inFiltration.open(perseus_style_file);
+ unsigned dimensionOfData;
+ inFiltration >> dimensionOfData;
+
+ if (dbg) {
+ std::cerr << "dimensionOfData : " << dimensionOfData << std::endl;
+ getchar();
+ }
+
+ std::vector<unsigned> sizes;
+ sizes.reserve(dimensionOfData);
+ for (size_t i = 0; i != dimensionOfData; ++i) {
+ unsigned size_in_this_dimension;
+ inFiltration >> size_in_this_dimension;
+ sizes.push_back(size_in_this_dimension);
+ if (dbg) {
+ std::cerr << "size_in_this_dimension : " << size_in_this_dimension << std::endl;
+ }
+ }
+ this->set_up_containers(sizes);
+
+ Bitmap_cubical_complex_base<T>::Top_dimensional_cells_iterator it(*this);
+ it = this->top_dimensional_cells_iterator_begin();
+
+ while (!inFiltration.eof()) {
+ T filtrationLevel;
+ inFiltration >> filtrationLevel;
+ if (dbg) {
+ std::cerr << "Cell of an index : "
+ << it.compute_index_in_bitmap()
+ << " and dimension: "
+ << this->get_dimension_of_a_cell(it.compute_index_in_bitmap())
+ << " get the value : " << filtrationLevel << std::endl;
+ }
+ this->get_cell_data(*it) = filtrationLevel;
+ ++it;
+ }
+ inFiltration.close();
+ this->impose_lower_star_filtration();
+}
+
+template <typename T>
+Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const char* perseus_style_file,
+ std::vector<bool> directions) {
+ // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
+ // conditions.
+ // It ignores the last parameter of the function.
+ this->read_perseus_style_file(perseus_style_file);
+}
+
+template <typename T>
+Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& sizes,
+ std::vector<bool> directions) {
+ // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
+ // conditions.
+ // It ignores the last parameter of the function.
+ this->set_up_containers(sizes);
+}
+
+template <typename T>
+Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& top_dimensional_cells,
+ std::vector<bool> directions) {
+ // this constructor is here just for compatibility with a class that creates cubical complexes with periodic boundary
+ // conditions.
+ // It ignores the last parameter of the function.
+ this->setup_bitmap_based_on_top_dimensional_cells_list(dimensions, top_dimensional_cells);
+}
+
+template <typename T>
+Bitmap_cubical_complex_base<T>::Bitmap_cubical_complex_base(const char* perseus_style_file) {
+ this->read_perseus_style_file(perseus_style_file);
+}
+
+template <typename T>
+std::vector< size_t > Bitmap_cubical_complex_base<T>::get_boundary_of_a_cell(size_t cell)const {
+ std::vector< size_t > boundary_elements;
+
+ // Speed traded of for memory. Check if it is better in practice.
+ boundary_elements.reserve(this->dimension()*2);
+
+ size_t cell1 = cell;
+ for (size_t i = this->multipliers.size(); i != 0; --i) {
+ unsigned position = cell1 / this->multipliers[i - 1];
+ if (position % 2 == 1) {
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ }
+ cell1 = cell1 % this->multipliers[i - 1];
+ }
+ return boundary_elements;
+}
+
+template <typename T>
+std::vector< size_t > Bitmap_cubical_complex_base<T>::get_coboundary_of_a_cell(size_t cell)const {
+ std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell);
+ std::vector< size_t > coboundary_elements;
+ size_t cell1 = cell;
+ for (size_t i = this->multipliers.size(); i != 0; --i) {
+ unsigned position = cell1 / this->multipliers[i - 1];
+ if (position % 2 == 0) {
+ if ((cell > this->multipliers[i - 1]) && (counter[i - 1] != 0)) {
+ coboundary_elements.push_back(cell - this->multipliers[i - 1]);
+ }
+ if (
+ (cell + this->multipliers[i - 1] < this->data.size()) && (counter[i - 1] != 2 * this->sizes[i - 1])) {
+ coboundary_elements.push_back(cell + this->multipliers[i - 1]);
+ }
+ }
+ cell1 = cell1 % this->multipliers[i - 1];
+ }
+ return coboundary_elements;
+}
+
+template <typename T>
+unsigned Bitmap_cubical_complex_base<T>::get_dimension_of_a_cell(size_t cell)const {
+ bool dbg = false;
+ if (dbg) std::cerr << "\n\n\n Computing position o a cell of an index : " << cell << std::endl;
+ unsigned dimension = 0;
+ for (size_t i = this->multipliers.size(); i != 0; --i) {
+ unsigned position = cell / this->multipliers[i - 1];
+
+ if (dbg) {
+ std::cerr << "i-1 :" << i - 1 << std::endl;
+ std::cerr << "cell : " << cell << std::endl;
+ std::cerr << "position : " << position << std::endl;
+ std::cerr << "multipliers[" << i - 1 << "] = " << this->multipliers[i - 1] << std::endl;
+ getchar();
+ }
+
+ if (position % 2 == 1) {
+ if (dbg) std::cerr << "Nonzero length in this direction \n";
+ dimension++;
+ }
+ cell = cell % this->multipliers[i - 1];
+ }
+ return dimension;
+}
+
+template <typename T>
+inline T& Bitmap_cubical_complex_base<T>::get_cell_data(size_t cell) {
+ return this->data[cell];
+}
+
+template <typename T>
+void Bitmap_cubical_complex_base<T>::impose_lower_star_filtration() {
+ bool dbg = false;
+
+ // this vector will be used to check which elements have already been taken care of in imposing lower star filtration
+ std::vector<bool> is_this_cell_considered(this->data.size(), false);
+
+ size_t size_to_reserve = 1;
+ for (size_t i = 0; i != this->multipliers.size(); ++i) {
+ size_to_reserve *= (size_t) ((this->multipliers[i] - 1) / 2);
+ }
+
+ std::vector<size_t> indices_to_consider;
+ indices_to_consider.reserve(size_to_reserve);
+ // we assume here that we already have a filtration on the top dimensional cells and
+ // we have to extend it to lower ones.
+ typename Bitmap_cubical_complex_base<T>::Top_dimensional_cells_iterator it(*this);
+ for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
+ indices_to_consider.push_back(it.compute_index_in_bitmap());
+ }
+
+ while (indices_to_consider.size()) {
+ if (dbg) {
+ std::cerr << "indices_to_consider in this iteration \n";
+ for (size_t i = 0; i != indices_to_consider.size(); ++i) {
+ std::cout << indices_to_consider[i] << " ";
+ }
+ getchar();
+ }
+ std::vector<size_t> new_indices_to_consider;
+ for (size_t i = 0; i != indices_to_consider.size(); ++i) {
+ std::vector<size_t> bd = this->get_boundary_of_a_cell(indices_to_consider[i]);
+ for (size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) {
+ if (dbg) {
+ std::cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[ bd[boundaryIt] ]
+ << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[ indices_to_consider[i] ]
+ << std::endl;
+ getchar();
+ }
+ if (this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ]) {
+ this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ];
+ if (dbg) {
+ std::cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : "
+ << this->data[ indices_to_consider[i] ] << std::endl;
+ getchar();
+ }
+ }
+ if (is_this_cell_considered[ bd[boundaryIt] ] == false) {
+ new_indices_to_consider.push_back(bd[boundaryIt]);
+ is_this_cell_considered[ bd[boundaryIt] ] = true;
+ }
+ }
+ }
+ indices_to_consider.swap(new_indices_to_consider);
+ }
+}
+
+template <typename T>
+bool compareFirstElementsOfTuples(const std::pair< std::pair< T, size_t >, char >& first,
+ const std::pair< std::pair< T, size_t >, char >& second) {
+ if (first.first.first < second.first.first) {
+ return true;
+ } else {
+ if (first.first.first > second.first.first) {
+ return false;
+ }
+ // in this case first.first.first == second.first.first, so we need to compare dimensions
+ return first.second < second.second;
+ }
+}
+
+} // namespace Cubical_complex
+
+} // namespace Gudhi
+
+#endif // BITMAP_CUBICAL_COMPLEX_BASE_H_
diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
new file mode 100644
index 00000000..0d0f2f84
--- /dev/null
+++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
@@ -0,0 +1,306 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 2015 INRIA Sophia-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 BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_
+#define BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_
+
+#include <gudhi/Bitmap_cubical_complex_base.h>
+
+#include <cmath>
+#include <limits> // for numeric_limits<>
+#include <vector>
+
+namespace Gudhi {
+
+namespace Cubical_complex {
+
+// in this class, we are storing all the elements which are in normal bitmap (i.e. the bitmap without the periodic
+// boundary conditions). But, we set up the iterators and the procedures to compute boundary and coboundary in the way
+// that it is all right. We assume here that all the cells that are on the left / bottom and so on remains, while all
+// the cells on the right / top are not in the Bitmap_cubical_complex_periodic_boundary_conditions_base
+
+/**
+ * @brief Cubical complex with periodic boundary conditions represented as a bitmap.
+ * @ingroup cubical_complex
+ * @details This is a class implementing a bitmap data structure with periodic boundary conditions. Most of the functions are
+ * identical to the functions from Bitmap_cubical_complex_base.
+ * The ones that needed to be updated are the constructors and get_boundary_of_a_cell and get_coboundary_of_a_cell.
+ */
+template <typename T>
+class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base<T> {
+ public:
+ // constructors that take an extra parameter:
+
+ /**
+ * Default constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ */
+ Bitmap_cubical_complex_periodic_boundary_conditions_base() { }
+ /**
+ * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following
+ * parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of booleans. If
+ * at i-th position of this vector there is true value, that means that periodic boundary conditions are to be
+ * imposed in this direction. In case of false, the periodic boundary conditions will not be imposed in the direction
+ * i.
+ */
+ Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes,
+ const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed);
+ /**
+ * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the name of Perseus
+ * style file as an input. Please consult the documentation about the specification of the file.
+ */
+ Bitmap_cubical_complex_periodic_boundary_conditions_base(const char* perseusStyleFile);
+ /**
+ * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following
+ * parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of top dimensional
+ * cells (ordered lexicographically) and (3) vector of booleans. If at i-th position of this vector there is true
+ * value, that means that periodic boundary conditions are to be imposed in this direction. In case of false, the
+ * periodic boundary conditions will not be imposed in the direction i.
+ */
+ Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& topDimensionalCells,
+ const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed);
+
+ /**
+ * Destructor of the Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ **/
+ virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base() {}
+
+ // overwritten methods co compute boundary and coboundary
+ /**
+ * A version of a function that return boundary of a given cell for an object of
+ * Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ */
+ virtual std::vector< size_t > get_boundary_of_a_cell(size_t cell) const;
+
+ /**
+ * A version of a function that return coboundary of a given cell for an object of
+ * Bitmap_cubical_complex_periodic_boundary_conditions_base class.
+ */
+ virtual std::vector< size_t > get_coboundary_of_a_cell(size_t cell) const;
+
+ protected:
+ std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed;
+
+ void set_up_containers(const std::vector<unsigned>& sizes) {
+ unsigned multiplier = 1;
+ for (size_t i = 0; i != sizes.size(); ++i) {
+ this->sizes.push_back(sizes[i]);
+ this->multipliers.push_back(multiplier);
+
+ if (directions_in_which_periodic_b_cond_are_to_be_imposed[i]) {
+ multiplier *= 2 * sizes[i];
+ } else {
+ multiplier *= 2 * sizes[i] + 1;
+ }
+ }
+ // std::reverse( this->sizes.begin() , this->sizes.end() );
+ this->data = std::vector<T>(multiplier, std::numeric_limits<T>::max());
+ this->total_number_of_cells = multiplier;
+ }
+ Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes);
+ Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& topDimensionalCells);
+ void construct_complex_based_on_top_dimensional_cells(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& topDimensionalCells,
+ const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed);
+};
+
+template <typename T>
+void Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::construct_complex_based_on_top_dimensional_cells(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& topDimensionalCells,
+ const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) {
+ this->directions_in_which_periodic_b_cond_are_to_be_imposed = directions_in_which_periodic_b_cond_are_to_be_imposed;
+ this->set_up_containers(dimensions);
+
+ size_t i = 0;
+ for (auto it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) {
+ this->get_cell_data(*it) = topDimensionalCells[i];
+ ++i;
+ }
+ this->impose_lower_star_filtration();
+}
+
+template <typename T>
+Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes,
+ const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) {
+ this->directions_in_which_periodic_b_cond_are_to_be_imposed(directions_in_which_periodic_b_cond_are_to_be_imposed);
+ this->set_up_containers(sizes);
+}
+
+template <typename T>
+Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const char* perseus_style_file) {
+ // for Perseus style files:
+ bool dbg = false;
+
+ std::ifstream inFiltration;
+ inFiltration.open(perseus_style_file);
+ unsigned dimensionOfData;
+ inFiltration >> dimensionOfData;
+
+ this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(dimensionOfData, false);
+
+ std::vector<unsigned> sizes;
+ sizes.reserve(dimensionOfData);
+ for (size_t i = 0; i != dimensionOfData; ++i) {
+ int size_in_this_dimension;
+ inFiltration >> size_in_this_dimension;
+ if (size_in_this_dimension < 0) {
+ this->directions_in_which_periodic_b_cond_are_to_be_imposed[i] = true;
+ }
+ sizes.push_back(abs(size_in_this_dimension));
+ }
+ this->set_up_containers(sizes);
+
+ typename Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Top_dimensional_cells_iterator it(*this);
+ it = this->top_dimensional_cells_iterator_begin();
+
+ while (!inFiltration.eof()) {
+ double filtrationLevel;
+ inFiltration >> filtrationLevel;
+ if (inFiltration.eof())break;
+
+ if (dbg) {
+ std::cerr << "Cell of an index : "
+ << it.compute_index_in_bitmap()
+ << " and dimension: "
+ << this->get_dimension_of_a_cell(it.compute_index_in_bitmap())
+ << " get the value : " << filtrationLevel << std::endl;
+ }
+ this->get_cell_data(*it) = filtrationLevel;
+ ++it;
+ }
+ inFiltration.close();
+ this->impose_lower_star_filtration();
+}
+
+template <typename T>
+Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& sizes) {
+ this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(sizes.size(), false);
+ this->set_up_containers(sizes);
+}
+
+template <typename T>
+Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& topDimensionalCells) {
+ std::vector<bool> directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector<bool>(dimensions.size(), false);
+ this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells,
+ directions_in_which_periodic_b_cond_are_to_be_imposed);
+}
+
+template <typename T>
+Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::
+Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector<unsigned>& dimensions,
+ const std::vector<T>& topDimensionalCells,
+ const std::vector<bool>& directions_in_which_periodic_b_cond_are_to_be_imposed) {
+ this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells,
+ directions_in_which_periodic_b_cond_are_to_be_imposed);
+}
+
+// ***********************Methods************************ //
+
+template <typename T>
+std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::get_boundary_of_a_cell(size_t cell) const {
+ bool dbg = false;
+ if (dbg) {
+ std::cerr << "Computations of boundary of a cell : " << cell << std::endl;
+ }
+
+ std::vector< size_t > boundary_elements;
+ size_t cell1 = cell;
+ for (size_t i = this->multipliers.size(); i != 0; --i) {
+ unsigned position = cell1 / this->multipliers[i - 1];
+ // this cell have a nonzero length in this direction, therefore we can compute its boundary in this direction.
+
+ if (position % 2 == 1) {
+ // if there are no periodic boundary conditions in this direction, we do not have to do anything.
+ if (!directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) {
+ // std::cerr << "A\n";
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ if (dbg) {
+ std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " ";
+ }
+ } else {
+ // in this direction we have to do boundary conditions. Therefore, we need to check if we are not at the end.
+ if (position != 2 * this->sizes[ i - 1 ] - 1) {
+ // std::cerr << "B\n";
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell + this->multipliers[ i - 1 ]);
+ if (dbg) {
+ std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " ";
+ }
+ } else {
+ // std::cerr << "C\n";
+ boundary_elements.push_back(cell - this->multipliers[ i - 1 ]);
+ boundary_elements.push_back(cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ]);
+ if (dbg) {
+ std::cerr << cell - this->multipliers[ i - 1 ] << " " <<
+ cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ] << " ";
+ }
+ }
+ }
+ }
+ cell1 = cell1 % this->multipliers[i - 1];
+ }
+ return boundary_elements;
+}
+
+template <typename T>
+std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base<T>::get_coboundary_of_a_cell(size_t cell) const {
+ std::vector<unsigned> counter = this->compute_counter_for_given_cell(cell);
+ std::vector< size_t > coboundary_elements;
+ size_t cell1 = cell;
+ for (size_t i = this->multipliers.size(); i != 0; --i) {
+ unsigned position = cell1 / this->multipliers[i - 1];
+ // if the cell has zero length in this direction, then it will have cbd in this direction.
+ if (position % 2 == 0) {
+ if (!this->directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) {
+ // no periodic boundary conditions in this direction
+ if ((counter[i - 1] != 0) && (cell > this->multipliers[i - 1])) {
+ coboundary_elements.push_back(cell - this->multipliers[i - 1]);
+ }
+ if ((counter[i - 1] != 2 * this->sizes[i - 1]) && (cell + this->multipliers[i - 1] < this->data.size())) {
+ coboundary_elements.push_back(cell + this->multipliers[i - 1]);
+ }
+ } else {
+ // we want to have periodic boundary conditions in this direction
+ if (counter[i - 1] != 0) {
+ coboundary_elements.push_back(cell - this->multipliers[i - 1]);
+ coboundary_elements.push_back(cell + this->multipliers[i - 1]);
+ } else {
+ // in this case counter[i-1] == 0.
+ coboundary_elements.push_back(cell + this->multipliers[i - 1]);
+ coboundary_elements.push_back(cell + (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[i - 1]);
+ }
+ }
+ }
+
+ cell1 = cell1 % this->multipliers[i - 1];
+ }
+ return coboundary_elements;
+}
+
+} // namespace Cubical_complex
+
+} // namespace Gudhi
+
+#endif // BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_
diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp
new file mode 100644
index 00000000..a9162cee
--- /dev/null
+++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp
@@ -0,0 +1,1378 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Pawel Dlotko
+ *
+ * Copyright (C) 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_DYN_LINK
+#define BOOST_TEST_MODULE "cubical_complex"
+#include <boost/test/unit_test.hpp>
+
+#include <gudhi/reader_utils.h>
+#include <gudhi/Bitmap_cubical_complex.h>
+#include <gudhi/Persistent_cohomology.h>
+
+// standard stuff
+#include <iostream>
+#include <sstream>
+#include <vector>
+
+
+typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_base<double> Bitmap_cubical_complex_base;
+typedef Gudhi::Cubical_complex::Bitmap_cubical_complex<Bitmap_cubical_complex_base> Bitmap_cubical_complex;
+
+typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base<double>
+Bitmap_cubical_complex_periodic_boundary_conditions_base;
+typedef Gudhi::Cubical_complex::Bitmap_cubical_complex<Bitmap_cubical_complex_periodic_boundary_conditions_base>
+Bitmap_cubical_complex_periodic_boundary_conditions;
+
+BOOST_AUTO_TEST_CASE(check_dimension) {
+ std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector<unsigned> dimensions({3, 3});
+
+ Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells);
+ BOOST_CHECK(increasing.dimension() == 2);
+}
+
+BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) {
+ std::vector< double > expectedFiltrationValues1({0, 0, 0, 0, 100, 0, 0, 0, 0});
+
+ std::vector< double > expectedFiltrationValues2({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector< double > oneDimensionalCycle({0, 0, 0, 0, 100, 0, 0, 0, 0});
+
+ std::vector<unsigned> dimensions({3, 3});
+
+ Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells);
+ Bitmap_cubical_complex hole(dimensions, oneDimensionalCycle);
+
+
+ int i = 0;
+ for (Bitmap_cubical_complex::Top_dimensional_cells_iterator
+ it = increasing.top_dimensional_cells_iterator_begin(); it != increasing.top_dimensional_cells_iterator_end(); ++it) {
+ BOOST_CHECK(increasing.get_cell_data(*it) == expectedFiltrationValues2[i]);
+ ++i;
+ }
+ i = 0;
+ for (Bitmap_cubical_complex::Top_dimensional_cells_iterator
+ it = hole.top_dimensional_cells_iterator_begin(); it != hole.top_dimensional_cells_iterator_end(); ++it) {
+ BOOST_CHECK(hole.get_cell_data(*it) == expectedFiltrationValues1[i]);
+ ++i;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(compute_boundary_test_1) {
+ std::vector<double> boundary0;
+ std::vector<double> boundary1;
+ boundary1.push_back(0);
+ boundary1.push_back(2);
+ std::vector<double> boundary2;
+ std::vector<double> boundary3;
+ boundary3.push_back(2);
+ boundary3.push_back(4);
+ std::vector<double> boundary4;
+ std::vector<double> boundary5;
+ boundary5.push_back(4);
+ boundary5.push_back(6);
+ std::vector<double> boundary6;
+ std::vector<double> boundary7;
+ boundary7.push_back(0);
+ boundary7.push_back(14);
+ std::vector<double> boundary8;
+ boundary8.push_back(1);
+ boundary8.push_back(15);
+ boundary8.push_back(7);
+ boundary8.push_back(9);
+ std::vector<double> boundary9;
+ boundary9.push_back(2);
+ boundary9.push_back(16);
+ std::vector<double> boundary10;
+ boundary10.push_back(3);
+ boundary10.push_back(17);
+ boundary10.push_back(9);
+ boundary10.push_back(11);
+ std::vector<double> boundary11;
+ boundary11.push_back(4);
+ boundary11.push_back(18);
+ std::vector<double> boundary12;
+ boundary12.push_back(5);
+ boundary12.push_back(19);
+ boundary12.push_back(11);
+ boundary12.push_back(13);
+ std::vector<double> boundary13;
+ boundary13.push_back(6);
+ boundary13.push_back(20);
+ std::vector<double> boundary14;
+ std::vector<double> boundary15;
+ boundary15.push_back(14);
+ boundary15.push_back(16);
+ std::vector<double> boundary16;
+ std::vector<double> boundary17;
+ boundary17.push_back(16);
+ boundary17.push_back(18);
+ std::vector<double> boundary18;
+ std::vector<double> boundary19;
+ boundary19.push_back(18);
+ boundary19.push_back(20);
+ std::vector<double> boundary20;
+ std::vector<double> boundary21;
+ boundary21.push_back(14);
+ boundary21.push_back(28);
+ std::vector<double> boundary22;
+ boundary22.push_back(15);
+ boundary22.push_back(29);
+ boundary22.push_back(21);
+ boundary22.push_back(23);
+ std::vector<double> boundary23;
+ boundary23.push_back(16);
+ boundary23.push_back(30);
+ std::vector<double> boundary24;
+ boundary24.push_back(17);
+ boundary24.push_back(31);
+ boundary24.push_back(23);
+ boundary24.push_back(25);
+ std::vector<double> boundary25;
+ boundary25.push_back(18);
+ boundary25.push_back(32);
+ std::vector<double> boundary26;
+ boundary26.push_back(19);
+ boundary26.push_back(33);
+ boundary26.push_back(25);
+ boundary26.push_back(27);
+ std::vector<double> boundary27;
+ boundary27.push_back(20);
+ boundary27.push_back(34);
+ std::vector<double> boundary28;
+ std::vector<double> boundary29;
+ boundary29.push_back(28);
+ boundary29.push_back(30);
+ std::vector<double> boundary30;
+ std::vector<double> boundary31;
+ boundary31.push_back(30);
+ boundary31.push_back(32);
+ std::vector<double> boundary32;
+ std::vector<double> boundary33;
+ boundary33.push_back(32);
+ boundary33.push_back(34);
+ std::vector<double> boundary34;
+ std::vector<double> boundary35;
+ boundary35.push_back(28);
+ boundary35.push_back(42);
+ std::vector<double> boundary36;
+ boundary36.push_back(29);
+ boundary36.push_back(43);
+ boundary36.push_back(35);
+ boundary36.push_back(37);
+ std::vector<double> boundary37;
+ boundary37.push_back(30);
+ boundary37.push_back(44);
+ std::vector<double> boundary38;
+ boundary38.push_back(31);
+ boundary38.push_back(45);
+ boundary38.push_back(37);
+ boundary38.push_back(39);
+ std::vector<double> boundary39;
+ boundary39.push_back(32);
+ boundary39.push_back(46);
+ std::vector<double> boundary40;
+ boundary40.push_back(33);
+ boundary40.push_back(47);
+ boundary40.push_back(39);
+ boundary40.push_back(41);
+ std::vector<double> boundary41;
+ boundary41.push_back(34);
+ boundary41.push_back(48);
+ std::vector<double> boundary42;
+ std::vector<double> boundary43;
+ boundary43.push_back(42);
+ boundary43.push_back(44);
+ std::vector<double> boundary44;
+ std::vector<double> boundary45;
+ boundary45.push_back(44);
+ boundary45.push_back(46);
+ std::vector<double> boundary46;
+ std::vector<double> boundary47;
+ boundary47.push_back(46);
+ boundary47.push_back(48);
+ std::vector<double> boundary48;
+ std::vector< std::vector<double> > boundaries;
+ boundaries.push_back(boundary0);
+ boundaries.push_back(boundary1);
+ boundaries.push_back(boundary2);
+ boundaries.push_back(boundary3);
+ boundaries.push_back(boundary4);
+ boundaries.push_back(boundary5);
+ boundaries.push_back(boundary6);
+ boundaries.push_back(boundary7);
+ boundaries.push_back(boundary8);
+ boundaries.push_back(boundary9);
+ boundaries.push_back(boundary10);
+ boundaries.push_back(boundary11);
+ boundaries.push_back(boundary12);
+ boundaries.push_back(boundary13);
+ boundaries.push_back(boundary14);
+ boundaries.push_back(boundary15);
+ boundaries.push_back(boundary16);
+ boundaries.push_back(boundary17);
+ boundaries.push_back(boundary18);
+ boundaries.push_back(boundary19);
+ boundaries.push_back(boundary20);
+ boundaries.push_back(boundary21);
+ boundaries.push_back(boundary22);
+ boundaries.push_back(boundary23);
+ boundaries.push_back(boundary24);
+ boundaries.push_back(boundary25);
+ boundaries.push_back(boundary26);
+ boundaries.push_back(boundary27);
+ boundaries.push_back(boundary28);
+ boundaries.push_back(boundary29);
+ boundaries.push_back(boundary30);
+ boundaries.push_back(boundary31);
+ boundaries.push_back(boundary32);
+ boundaries.push_back(boundary33);
+ boundaries.push_back(boundary34);
+ boundaries.push_back(boundary35);
+ boundaries.push_back(boundary36);
+ boundaries.push_back(boundary37);
+ boundaries.push_back(boundary38);
+ boundaries.push_back(boundary39);
+ boundaries.push_back(boundary40);
+ boundaries.push_back(boundary41);
+ boundaries.push_back(boundary42);
+ boundaries.push_back(boundary43);
+ boundaries.push_back(boundary44);
+ boundaries.push_back(boundary45);
+ boundaries.push_back(boundary46);
+ boundaries.push_back(boundary47);
+ boundaries.push_back(boundary48);
+
+
+
+ std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector<unsigned> dimensions({3, 3});
+
+ Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells);
+ for (size_t i = 0; i != increasing.size(); ++i) {
+ std::vector< size_t > bd = increasing.get_boundary_of_a_cell(i);
+ for (size_t j = 0; j != bd.size(); ++j) {
+ BOOST_CHECK(boundaries[i][j] == bd[j]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(compute_boundary_test_2) {
+ std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector<unsigned> dimensions({3, 3});
+
+ Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells);
+
+
+ std::vector<double> coboundaryElements;
+ coboundaryElements.push_back(7);
+ coboundaryElements.push_back(1);
+ coboundaryElements.push_back(8);
+ coboundaryElements.push_back(9);
+ coboundaryElements.push_back(1);
+ coboundaryElements.push_back(3);
+ coboundaryElements.push_back(10);
+ coboundaryElements.push_back(11);
+ coboundaryElements.push_back(3);
+ coboundaryElements.push_back(5);
+ coboundaryElements.push_back(12);
+ coboundaryElements.push_back(13);
+ coboundaryElements.push_back(5);
+ coboundaryElements.push_back(8);
+ coboundaryElements.push_back(8);
+ coboundaryElements.push_back(10);
+ coboundaryElements.push_back(10);
+ coboundaryElements.push_back(12);
+ coboundaryElements.push_back(12);
+ coboundaryElements.push_back(7);
+ coboundaryElements.push_back(21);
+ coboundaryElements.push_back(15);
+ coboundaryElements.push_back(8);
+ coboundaryElements.push_back(22);
+ coboundaryElements.push_back(9);
+ coboundaryElements.push_back(23);
+ coboundaryElements.push_back(15);
+ coboundaryElements.push_back(17);
+ coboundaryElements.push_back(10);
+ coboundaryElements.push_back(24);
+ coboundaryElements.push_back(11);
+ coboundaryElements.push_back(25);
+ coboundaryElements.push_back(17);
+ coboundaryElements.push_back(19);
+ coboundaryElements.push_back(12);
+ coboundaryElements.push_back(26);
+ coboundaryElements.push_back(13);
+ coboundaryElements.push_back(27);
+ coboundaryElements.push_back(19);
+ coboundaryElements.push_back(22);
+ coboundaryElements.push_back(22);
+ coboundaryElements.push_back(24);
+ coboundaryElements.push_back(24);
+ coboundaryElements.push_back(26);
+ coboundaryElements.push_back(26);
+ coboundaryElements.push_back(21);
+ coboundaryElements.push_back(35);
+ coboundaryElements.push_back(29);
+ coboundaryElements.push_back(22);
+ coboundaryElements.push_back(36);
+ coboundaryElements.push_back(23);
+ coboundaryElements.push_back(37);
+ coboundaryElements.push_back(29);
+ coboundaryElements.push_back(31);
+ coboundaryElements.push_back(24);
+ coboundaryElements.push_back(38);
+ coboundaryElements.push_back(25);
+ coboundaryElements.push_back(39);
+ coboundaryElements.push_back(31);
+ coboundaryElements.push_back(33);
+ coboundaryElements.push_back(26);
+ coboundaryElements.push_back(40);
+ coboundaryElements.push_back(27);
+ coboundaryElements.push_back(41);
+ coboundaryElements.push_back(33);
+ coboundaryElements.push_back(36);
+ coboundaryElements.push_back(36);
+ coboundaryElements.push_back(38);
+ coboundaryElements.push_back(38);
+ coboundaryElements.push_back(40);
+ coboundaryElements.push_back(40);
+ coboundaryElements.push_back(35);
+ coboundaryElements.push_back(43);
+ coboundaryElements.push_back(36);
+ coboundaryElements.push_back(37);
+ coboundaryElements.push_back(43);
+ coboundaryElements.push_back(45);
+ coboundaryElements.push_back(38);
+ coboundaryElements.push_back(39);
+ coboundaryElements.push_back(45);
+ coboundaryElements.push_back(47);
+ coboundaryElements.push_back(40);
+ coboundaryElements.push_back(41);
+ coboundaryElements.push_back(47);
+ size_t number = 0;
+ for (size_t i = 0; i != increasing.size(); ++i) {
+ std::vector< size_t > bd = increasing.get_coboundary_of_a_cell(i);
+ for (size_t j = 0; j != bd.size(); ++j) {
+ BOOST_CHECK(coboundaryElements[number] == bd[j]);
+ ++number;
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(compute_boundary_test_3) {
+ std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector<unsigned> dimensions({3, 3});
+
+ Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells);
+
+ std::vector<unsigned> dim;
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(0);
+
+ for (size_t i = 0; i != increasing.size(); ++i) {
+ BOOST_CHECK(increasing.get_dimension_of_a_cell(i) == dim[i]);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) {
+ std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ std::vector<unsigned> dimensions({3, 3});
+
+ Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells);
+
+ std::vector< unsigned > dim;
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+ dim.push_back(0);
+ dim.push_back(1);
+ dim.push_back(1);
+ dim.push_back(2);
+
+ std::vector<double> fil;
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(1);
+ fil.push_back(2);
+ fil.push_back(2);
+ fil.push_back(2);
+ fil.push_back(2);
+ fil.push_back(2);
+ fil.push_back(2);
+ fil.push_back(3);
+ fil.push_back(3);
+ fil.push_back(3);
+ fil.push_back(3);
+ fil.push_back(3);
+ fil.push_back(3);
+ fil.push_back(4);
+ fil.push_back(4);
+ fil.push_back(4);
+ fil.push_back(4);
+ fil.push_back(4);
+ fil.push_back(4);
+ fil.push_back(5);
+ fil.push_back(5);
+ fil.push_back(5);
+ fil.push_back(5);
+ fil.push_back(6);
+ fil.push_back(6);
+ fil.push_back(6);
+ fil.push_back(6);
+ fil.push_back(7);
+ fil.push_back(7);
+ fil.push_back(7);
+ fil.push_back(7);
+ fil.push_back(7);
+ fil.push_back(7);
+ fil.push_back(8);
+ fil.push_back(8);
+ fil.push_back(8);
+ fil.push_back(8);
+ fil.push_back(9);
+ fil.push_back(9);
+ fil.push_back(9);
+ fil.push_back(9);
+
+
+ Bitmap_cubical_complex::Filtration_simplex_range range = increasing.filtration_simplex_range();
+ size_t position = 0;
+ for (Bitmap_cubical_complex::Filtration_simplex_iterator it = range.begin(); it != range.end(); ++it) {
+ BOOST_CHECK(increasing.dimension(*it) == dim[position]);
+ BOOST_CHECK(increasing.filtration(*it) == fil[position]);
+ ++position;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) {
+ std::vector< double > filtration({0, 0, 0, 0});
+
+ std::vector<unsigned> dimensions({2, 2});
+
+ std::vector<bool> periodic_directions({true, true});
+
+ Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtration, periodic_directions);
+ BOOST_CHECK(cmplx.dimension() == 2);
+
+
+ std::vector<double> boundary0;
+ std::vector<double> boundary1;
+ boundary1.push_back(0);
+ boundary1.push_back(2);
+ std::vector<double> boundary2;
+ std::vector<double> boundary3;
+ boundary3.push_back(2);
+ boundary3.push_back(0);
+ std::vector<double> boundary4;
+ boundary4.push_back(0);
+ boundary4.push_back(8);
+ std::vector<double> boundary5;
+ boundary5.push_back(1);
+ boundary5.push_back(9);
+ boundary5.push_back(4);
+ boundary5.push_back(6);
+ std::vector<double> boundary6;
+ boundary6.push_back(2);
+ boundary6.push_back(10);
+ std::vector<double> boundary7;
+ boundary7.push_back(3);
+ boundary7.push_back(11);
+ boundary7.push_back(6);
+ boundary7.push_back(4);
+ std::vector<double> boundary8;
+ std::vector<double> boundary9;
+ boundary9.push_back(8);
+ boundary9.push_back(10);
+ std::vector<double> boundary10;
+ std::vector<double> boundary11;
+ boundary11.push_back(10);
+ boundary11.push_back(8);
+ std::vector<double> boundary12;
+ boundary12.push_back(8);
+ boundary12.push_back(0);
+ std::vector<double> boundary13;
+ boundary13.push_back(9);
+ boundary13.push_back(1);
+ boundary13.push_back(12);
+ boundary13.push_back(14);
+ std::vector<double> boundary14;
+ boundary14.push_back(10);
+ boundary14.push_back(2);
+ std::vector<double> boundary15;
+ boundary15.push_back(11);
+ boundary15.push_back(3);
+ boundary15.push_back(14);
+ boundary15.push_back(12);
+
+ std::vector< std::vector<double> > boundaries;
+ boundaries.push_back(boundary0);
+ boundaries.push_back(boundary1);
+ boundaries.push_back(boundary2);
+ boundaries.push_back(boundary3);
+ boundaries.push_back(boundary4);
+ boundaries.push_back(boundary5);
+ boundaries.push_back(boundary6);
+ boundaries.push_back(boundary7);
+ boundaries.push_back(boundary8);
+ boundaries.push_back(boundary9);
+ boundaries.push_back(boundary10);
+ boundaries.push_back(boundary11);
+ boundaries.push_back(boundary12);
+ boundaries.push_back(boundary13);
+ boundaries.push_back(boundary14);
+ boundaries.push_back(boundary15);
+
+ for (size_t i = 0; i != cmplx.size(); ++i) {
+ std::vector< size_t > bd = cmplx.get_boundary_of_a_cell(i);
+ for (size_t j = 0; j != bd.size(); ++j) {
+ BOOST_CHECK(boundaries[i][j] == bd[j]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) {
+ std::vector< double > filtration({0, 0, 0, 0});
+
+ std::vector<unsigned> dimensions({2, 2});
+
+ std::vector<bool> periodic_directions({true, true});
+
+ Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtration, periodic_directions);
+ BOOST_CHECK(cmplx.dimension() == 2);
+
+
+ std::vector<double> coboundary0;
+ coboundary0.push_back(4);
+ coboundary0.push_back(12);
+ coboundary0.push_back(1);
+ coboundary0.push_back(3);
+ std::vector<double> coboundary1;
+ coboundary1.push_back(5);
+ coboundary1.push_back(13);
+ std::vector<double> coboundary2;
+ coboundary2.push_back(6);
+ coboundary2.push_back(14);
+ coboundary2.push_back(1);
+ coboundary2.push_back(3);
+ std::vector<double> coboundary3;
+ coboundary3.push_back(7);
+ coboundary3.push_back(15);
+ std::vector<double> coboundary4;
+ coboundary4.push_back(5);
+ coboundary4.push_back(7);
+ std::vector<double> coboundary5;
+ std::vector<double> coboundary6;
+ coboundary6.push_back(5);
+ coboundary6.push_back(7);
+ std::vector<double> coboundary7;
+ std::vector<double> coboundary8;
+ coboundary8.push_back(4);
+ coboundary8.push_back(12);
+ coboundary8.push_back(9);
+ coboundary8.push_back(11);
+ std::vector<double> coboundary9;
+ coboundary9.push_back(5);
+ coboundary9.push_back(13);
+ std::vector<double> coboundary10;
+ coboundary10.push_back(6);
+ coboundary10.push_back(14);
+ coboundary10.push_back(9);
+ coboundary10.push_back(11);
+ std::vector<double> coboundary11;
+ coboundary11.push_back(7);
+ coboundary11.push_back(15);
+ std::vector<double> coboundary12;
+ coboundary12.push_back(13);
+ coboundary12.push_back(15);
+ std::vector<double> coboundary13;
+ std::vector<double> coboundary14;
+ coboundary14.push_back(13);
+ coboundary14.push_back(15);
+ std::vector<double> coboundary15;
+
+ std::vector< std::vector<double> > coboundaries;
+ coboundaries.push_back(coboundary0);
+ coboundaries.push_back(coboundary1);
+ coboundaries.push_back(coboundary2);
+ coboundaries.push_back(coboundary3);
+ coboundaries.push_back(coboundary4);
+ coboundaries.push_back(coboundary5);
+ coboundaries.push_back(coboundary6);
+ coboundaries.push_back(coboundary7);
+ coboundaries.push_back(coboundary8);
+ coboundaries.push_back(coboundary9);
+ coboundaries.push_back(coboundary10);
+ coboundaries.push_back(coboundary11);
+ coboundaries.push_back(coboundary12);
+ coboundaries.push_back(coboundary13);
+ coboundaries.push_back(coboundary14);
+ coboundaries.push_back(coboundary15);
+
+ for (size_t i = 0; i != cmplx.size(); ++i) {
+ std::vector< size_t > cbd = cmplx.get_coboundary_of_a_cell(i);
+ for (size_t j = 0; j != cbd.size(); ++j) {
+ BOOST_CHECK(coboundaries[i][j] == cbd[j]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) {
+ std::vector< double > filtrationOrg({0, 1, 2, 3});
+
+ std::vector<unsigned> dimensions({2, 2});
+
+ std::vector<bool> periodic_directions({true, true});
+
+ Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtrationOrg, periodic_directions);
+ BOOST_CHECK(cmplx.dimension() == 2);
+
+
+ std::vector<double> filtration;
+ filtration.push_back(0); // 0
+ filtration.push_back(0); // 1
+ filtration.push_back(0); // 2
+ filtration.push_back(1); // 3
+ filtration.push_back(0); // 4
+ filtration.push_back(0); // 5
+ filtration.push_back(0); // 6
+ filtration.push_back(1); // 7
+ filtration.push_back(0); // 8
+ filtration.push_back(0); // 9
+ filtration.push_back(0); // 10
+ filtration.push_back(1); // 11
+ filtration.push_back(2); // 12
+ filtration.push_back(2); // 13
+ filtration.push_back(2); // 14
+ filtration.push_back(3); // 15
+
+
+ for (size_t i = 0; i != cmplx.size(); ++i) {
+ BOOST_CHECK(filtration[i] == cmplx.get_cell_data(i));
+ }
+}
+BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check)
+{
+ std::vector< double > expected_filtration;
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+
+ std::vector<unsigned> expected_dimension;
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+
+ std::vector<size_t> expected_boundary;
+ expected_boundary.push_back(0);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(4);
+ expected_boundary.push_back(0);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(1);
+ expected_boundary.push_back(11);
+ expected_boundary.push_back(5);
+ expected_boundary.push_back(7);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(3);
+ expected_boundary.push_back(13);
+ expected_boundary.push_back(7);
+ expected_boundary.push_back(9);
+ expected_boundary.push_back(4);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(20);
+ expected_boundary.push_back(11);
+ expected_boundary.push_back(21);
+ expected_boundary.push_back(15);
+ expected_boundary.push_back(17);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(13);
+ expected_boundary.push_back(23);
+ expected_boundary.push_back(17);
+ expected_boundary.push_back(19);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(24);
+ expected_boundary.push_back(20);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(24);
+
+
+ std::vector<size_t> expected_coboundary;
+ expected_coboundary.push_back(5);
+ expected_coboundary.push_back(1);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(7);
+ expected_coboundary.push_back(1);
+ expected_coboundary.push_back(3);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(9);
+ expected_coboundary.push_back(3);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(5);
+ expected_coboundary.push_back(15);
+ expected_coboundary.push_back(11);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(7);
+ expected_coboundary.push_back(17);
+ expected_coboundary.push_back(11);
+ expected_coboundary.push_back(13);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(9);
+ expected_coboundary.push_back(19);
+ expected_coboundary.push_back(13);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(15);
+ expected_coboundary.push_back(21);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(17);
+ expected_coboundary.push_back(21);
+ expected_coboundary.push_back(23);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(19);
+ expected_coboundary.push_back(23);
+
+
+
+ std::vector< unsigned > sizes(2);
+ sizes[0] = 2;
+ sizes[1] = 2;
+
+ std::vector< double > data(4);
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 2;
+ data[3] = 3;
+
+ Bitmap_cubical_complex_base ba( sizes , data );
+ int i = 0;
+ int bd_it = 0;
+ int cbd_it = 0;
+ for ( Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin() ; it != ba.all_cells_iterator_end() ; ++it )
+ {
+ BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) );
+ BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) );
+
+ Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it);
+ for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd )
+ {
+ BOOST_CHECK( expected_boundary[bd_it] == *bd );
+ ++bd_it;
+ }
+
+ Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it);
+ for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd )
+ {
+ BOOST_CHECK( expected_coboundary[cbd_it] == *cbd );
+ ++cbd_it;
+ }
+ ++i;
+ }
+}
+
+
+
+
+
+
+
+
+BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check_2)
+{
+ std::vector< double > expected_filtration;
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+
+ std::vector<unsigned> expected_dimension;
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+
+ std::vector<size_t> expected_boundary;
+ expected_boundary.push_back(0);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(4);
+ expected_boundary.push_back(0);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(1);
+ expected_boundary.push_back(11);
+ expected_boundary.push_back(5);
+ expected_boundary.push_back(7);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(3);
+ expected_boundary.push_back(13);
+ expected_boundary.push_back(7);
+ expected_boundary.push_back(9);
+ expected_boundary.push_back(4);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(20);
+ expected_boundary.push_back(11);
+ expected_boundary.push_back(21);
+ expected_boundary.push_back(15);
+ expected_boundary.push_back(17);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(13);
+ expected_boundary.push_back(23);
+ expected_boundary.push_back(17);
+ expected_boundary.push_back(19);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(24);
+ expected_boundary.push_back(20);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(24);
+
+
+ std::vector<size_t> expected_coboundary;
+ expected_coboundary.push_back(5);
+ expected_coboundary.push_back(1);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(7);
+ expected_coboundary.push_back(1);
+ expected_coboundary.push_back(3);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(9);
+ expected_coboundary.push_back(3);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(5);
+ expected_coboundary.push_back(15);
+ expected_coboundary.push_back(11);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(7);
+ expected_coboundary.push_back(17);
+ expected_coboundary.push_back(11);
+ expected_coboundary.push_back(13);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(9);
+ expected_coboundary.push_back(19);
+ expected_coboundary.push_back(13);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(15);
+ expected_coboundary.push_back(21);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(17);
+ expected_coboundary.push_back(21);
+ expected_coboundary.push_back(23);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(19);
+ expected_coboundary.push_back(23);
+
+
+
+ std::vector< unsigned > sizes(2);
+ sizes[0] = 2;
+ sizes[1] = 2;
+
+ std::vector< double > data(4);
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 2;
+ data[3] = 3;
+
+ Bitmap_cubical_complex_base ba( sizes , data );
+ int i = 0;
+ int bd_it = 0;
+ int cbd_it = 0;
+
+ Bitmap_cubical_complex_base::All_cells_range range(&ba);
+ for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it )
+ {
+ BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) );
+ BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) );
+
+ Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it);
+ for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd )
+ {
+ BOOST_CHECK( expected_boundary[bd_it] == *bd );
+ ++bd_it;
+ }
+
+ Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it);
+ for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd )
+ {
+ BOOST_CHECK( expected_coboundary[cbd_it] == *cbd );
+ ++cbd_it;
+ }
+ ++i;
+ }
+}
+
+
+
+
+
+
+BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check)
+{
+ std::vector< double > expected_filtration;
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+
+ std::vector<unsigned> expected_dimension;
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(2);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+ expected_dimension.push_back(1);
+ expected_dimension.push_back(0);
+
+ std::vector<size_t> expected_boundary;
+ expected_boundary.push_back(0);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(4);
+ expected_boundary.push_back(0);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(1);
+ expected_boundary.push_back(11);
+ expected_boundary.push_back(5);
+ expected_boundary.push_back(7);
+ expected_boundary.push_back(2);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(3);
+ expected_boundary.push_back(13);
+ expected_boundary.push_back(7);
+ expected_boundary.push_back(9);
+ expected_boundary.push_back(4);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(10);
+ expected_boundary.push_back(20);
+ expected_boundary.push_back(11);
+ expected_boundary.push_back(21);
+ expected_boundary.push_back(15);
+ expected_boundary.push_back(17);
+ expected_boundary.push_back(12);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(13);
+ expected_boundary.push_back(23);
+ expected_boundary.push_back(17);
+ expected_boundary.push_back(19);
+ expected_boundary.push_back(14);
+ expected_boundary.push_back(24);
+ expected_boundary.push_back(20);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(22);
+ expected_boundary.push_back(24);
+
+
+ std::vector<size_t> expected_coboundary;
+ expected_coboundary.push_back(5);
+ expected_coboundary.push_back(1);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(7);
+ expected_coboundary.push_back(1);
+ expected_coboundary.push_back(3);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(9);
+ expected_coboundary.push_back(3);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(5);
+ expected_coboundary.push_back(15);
+ expected_coboundary.push_back(11);
+ expected_coboundary.push_back(6);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(7);
+ expected_coboundary.push_back(17);
+ expected_coboundary.push_back(11);
+ expected_coboundary.push_back(13);
+ expected_coboundary.push_back(8);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(9);
+ expected_coboundary.push_back(19);
+ expected_coboundary.push_back(13);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(15);
+ expected_coboundary.push_back(21);
+ expected_coboundary.push_back(16);
+ expected_coboundary.push_back(17);
+ expected_coboundary.push_back(21);
+ expected_coboundary.push_back(23);
+ expected_coboundary.push_back(18);
+ expected_coboundary.push_back(19);
+ expected_coboundary.push_back(23);
+
+
+
+ std::vector< unsigned > sizes(2);
+ sizes[0] = 2;
+ sizes[1] = 2;
+
+ std::vector< double > data(4);
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 2;
+ data[3] = 3;
+
+ Bitmap_cubical_complex_base ba( sizes , data );
+ int i = 0;
+ int bd_it = 0;
+ int cbd_it = 0;
+
+ Bitmap_cubical_complex_base::All_cells_range range = ba.all_cells_range();
+ for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it )
+ {
+ BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) );
+ BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) );
+
+ Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it);
+ for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd )
+ {
+ BOOST_CHECK( expected_boundary[bd_it] == *bd );
+ ++bd_it;
+ }
+
+ Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it);
+ for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd )
+ {
+ BOOST_CHECK( expected_coboundary[cbd_it] == *cbd );
+ ++cbd_it;
+ }
+ ++i;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(Top_dimensional_cells_iterator_range_check)
+{
+ std::vector< double > expected_filtration;
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(0);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(1);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(2);
+ expected_filtration.push_back(3);
+ expected_filtration.push_back(3);
+
+
+ std::vector< unsigned > sizes(2);
+ sizes[0] = 2;
+ sizes[1] = 2;
+
+ std::vector< double > data(4);
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 2;
+ data[3] = 3;
+
+ Bitmap_cubical_complex_base ba( sizes , data );
+ int i = 0;
+
+ Bitmap_cubical_complex_base::Top_dimensional_cells_range range = ba.top_dimensional_cells_range();
+ for ( Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it = range.begin() ; it != range.end() ; ++it )
+ {
+ BOOST_CHECK( data[i] == ba.get_cell_data( *it ) );
+ BOOST_CHECK( ba.get_dimension_of_a_cell( *it ) == 2 );
+ ++i;
+ }
+}
+
diff --git a/src/Bitmap_cubical_complex/test/CMakeLists.txt b/src/Bitmap_cubical_complex/test/CMakeLists.txt
new file mode 100644
index 00000000..0e5340c7
--- /dev/null
+++ b/src/Bitmap_cubical_complex/test/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 2.6)
+project(GUDHIBitmapCCUT)
+
+if (GCOVR_PATH)
+ # for gcovr to make coverage reports - Corbera Jenkins plugin
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
+endif()
+if (GPROF_PATH)
+ # for gprof to make coverage reports - Jenkins
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
+endif()
+
+add_executable ( BitmapCCUT Bitmap_test.cpp )
+target_link_libraries(BitmapCCUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(BitmapCCUT ${TBB_RELEASE_LIBRARY})
+endif()
+
+# Unitary tests
+add_test(NAME BitmapCCUT
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/BitmapCCUT
+ # XML format for Jenkins xUnit plugin
+ --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/BitmapCCUT.xml --log_level=test_suite --report_level=no)
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a1b0b589..1700ddaa 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.6)
project(GUDHI)
include("CMakeGUDHIVersion.txt")
+# Generate GUDHI official version file
+configure_file(GUDHIVersion.cmake.in "${CMAKE_SOURCE_DIR}/GUDHIVersion.cmake" @ONLY)
enable_testing()
@@ -29,6 +31,11 @@ else()
# 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.
find_package(CGAL)
+ # Only CGAL versions > 4.4 supports what Gudhi uses from CGAL
+ if (CGAL_VERSION VERSION_LESS 4.4.0)
+ message("CGAL version ${CGAL_VERSION} is considered too old to be used by Gudhi.")
+ unset(CGAL_FOUND)
+ endif()
if(CGAL_FOUND)
include( ${CGAL_USE_FILE} )
endif()
@@ -53,6 +60,10 @@ else()
# Find TBB package for parallel sort - not mandatory, just optional.
set(TBB_FIND_QUIETLY ON)
find_package(TBB)
+ if (TBB_FOUND)
+ message("TBB found in ${TBB_LIBRARY_DIRS}")
+ add_definitions(-DGUDHI_USE_TBB)
+ endif()
# BOOST ISSUE result_of vs C++11
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
@@ -62,15 +73,24 @@ else()
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
+ if (DEBUG_TRACES)
+ message(STATUS "DEBUG_TRACES are activated")
+ # For programs to be more verbose
+ add_definitions(-DDEBUG_TRACES)
+ endif()
+
#---------------------------------------------------------------------------------------
# Gudhi compilation part
include_directories(include)
+ add_subdirectory(example/common)
add_subdirectory(example/Simplex_tree)
add_subdirectory(example/Persistent_cohomology)
add_subdirectory(example/Skeleton_blocker)
add_subdirectory(example/Contraction)
+ add_subdirectory(example/Bitmap_cubical_complex)
add_subdirectory(example/Witness_complex)
+ add_subdirectory(example/Alpha_complex)
# data points generator
add_subdirectory(data/points/generator)
@@ -86,8 +106,9 @@ else()
# (this registers the build-tree with a global CMake-registry)
export(PACKAGE GUDHI)
+ message("++ make install will install ${PROJECT_NAME} in the following directory : ${CMAKE_INSTALL_PREFIX}")
# Create the GUDHIConfig.cmake and GUDHIConfigVersion files
- set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
+ set(CONF_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/include")
configure_file(GUDHIConfig.cmake.in "${PROJECT_BINARY_DIR}/GUDHIConfig.cmake" @ONLY)
configure_file(GUDHIConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/GUDHIConfigVersion.cmake" @ONLY)
diff --git a/src/Contraction/doc/sphere_contraction_representation.png b/src/Contraction/doc/sphere_contraction_representation.png
new file mode 100644
index 00000000..edf37bf3
--- /dev/null
+++ b/src/Contraction/doc/sphere_contraction_representation.png
Binary files differ
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 919df243..250bba27 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
@@ -23,8 +23,8 @@
#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>
+#include <gudhi/Debug_utils.h>
namespace Gudhi {
diff --git a/src/Contraction/include/gudhi/Edge_contraction.h b/src/Contraction/include/gudhi/Edge_contraction.h
index ee3e3de1..1b2cdee9 100644
--- a/src/Contraction/include/gudhi/Edge_contraction.h
+++ b/src/Contraction/include/gudhi/Edge_contraction.h
@@ -30,7 +30,7 @@
#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/Debug_utils.h>
namespace Gudhi {
@@ -46,7 +46,7 @@ namespace contraction {
The purpose of this package is to offer a user-friendly interface for edge contraction simplification of huge simplicial complexes.
It uses the \ref skbl data-structure whose size remains small during simplification
of most used geometrical complexes of topological data analysis such as the Rips or the Delaunay complexes. In practice, the
-size of this data-structure is even uch lower than the total number of simplices.
+size of this data-structure is even much lower than the total number of simplices.
The edge contraction operation consists in identifying two vertices of a simplicial complex.
A lot of algorithms have been developed in computer graphics that allows to reduce efficiently the size of 2-dimensional simplicial complexes
@@ -226,7 +226,6 @@ Time to simplify and enumerate simplices:
\copyright GNU General Public License v3.
-\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup
} // namespace contraction
diff --git a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h
index d6350a2c..f650473a 100644
--- a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h
+++ b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h
@@ -37,7 +37,7 @@
#include <gudhi/Contraction/policies/Contraction_visitor.h>
#include <gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h>
-#include <gudhi/Utils.h>
+#include <gudhi/Debug_utils.h>
#include <boost/scoped_array.hpp>
diff --git a/src/Doxyfile b/src/Doxyfile
index 6585e50c..6ddfb55d 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile
@@ -32,19 +32,19 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
-PROJECT_NAME = "Gudhi"
+PROJECT_NAME = "GUDHI"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = "1.2.0"
+PROJECT_NUMBER = "1.3.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
# quick idea about the purpose of the project. Keep the description short.
-PROJECT_BRIEF =
+PROJECT_BRIEF = "C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding."
# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
# the documentation. The maximum height of the logo should not exceed 55 pixels
@@ -153,7 +153,7 @@ STRIP_FROM_PATH =
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
-STRIP_FROM_INC_PATH =
+STRIP_FROM_INC_PATH = include concept
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
@@ -580,27 +580,27 @@ STRICT_PROTO_MATCHING = NO
# documentation.
# The default value is: YES.
-GENERATE_TODOLIST = YES
+GENERATE_TODOLIST = NO
# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
# test list. This list is created by putting \test commands in the
# documentation.
# The default value is: YES.
-GENERATE_TESTLIST = YES
+GENERATE_TESTLIST = NO
# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
# list. This list is created by putting \bug commands in the documentation.
# The default value is: YES.
-GENERATE_BUGLIST = YES
+GENERATE_BUGLIST = NO
# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
# the deprecated list. This list is created by putting \deprecated commands in
# the documentation.
# The default value is: YES.
-GENERATE_DEPRECATEDLIST= YES
+GENERATE_DEPRECATEDLIST= NO
# The ENABLED_SECTIONS tag can be used to enable conditional documentation
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
@@ -673,6 +673,7 @@ LAYOUT_FILE =
# also \cite for info how to create references.
CITE_BIB_FILES = biblio/bibliography.bib \
+ biblio/how_to_cite_cgal.bib \
biblio/how_to_cite_gudhi.bib
#---------------------------------------------------------------------------
@@ -779,7 +780,9 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
-EXCLUDE =
+EXCLUDE = data/ \
+ example/ \
+ GudhUI/
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@@ -812,14 +815,15 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include
# command).
-EXAMPLE_PATH = biblio/
+EXAMPLE_PATH = biblio/ \
+ example/
# 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
# *.h) to filter out the source-files in the directories. If left blank all
# files are included.
-EXAMPLE_PATTERNS =
+EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude commands
@@ -833,9 +837,13 @@ EXAMPLE_RECURSIVE = NO
# \image command).
IMAGE_PATH = doc/Skeleton_blocker/ \
+ doc/Alpha_complex/ \
doc/common/ \
doc/Contraction/ \
- doc/Witness_complex/
+ doc/Simplex_tree/ \
+ doc/Persistent_cohomology/ \
+ doc/Witness_complex/ \
+ doc/Bitmap_cubical_complex/
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -1039,7 +1047,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_HEADER =
+HTML_HEADER = doc/common/header.html
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1049,7 +1057,7 @@ HTML_HEADER =
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_FOOTER =
+HTML_FOOTER = doc/common/footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1061,7 +1069,7 @@ HTML_FOOTER =
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
-HTML_STYLESHEET =
+HTML_STYLESHEET = doc/common/stylesheet.css
# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
# defined cascading style sheet that is included after the standard style sheets
@@ -1544,7 +1552,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
# The default value is: YES.
-GENERATE_LATEX = YES
+GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1596,7 +1604,7 @@ PAPER_TYPE = a4
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
-EXTRA_PACKAGES = amsfonts amsmath amssymb
+EXTRA_PACKAGES = amsfonts amsmath amssymb algorithm algpseudocode
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt
index 1ee43d91..a7e64319 100644
--- a/src/GudhUI/CMakeLists.txt
+++ b/src/GudhUI/CMakeLists.txt
@@ -57,6 +57,11 @@ if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )
target_link_libraries( GudhUI ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} )
target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
+if (TBB_FOUND)
+ target_link_libraries( GudhUI ${TBB_RELEASE_LIBRARY})
+endif()
+
+###############################################################################
else()
message(STATUS "NOTICE: GudhUI requires CGAL, the QGLViewer, OpenGL and Qt4, and will not be compiled.")
diff --git a/src/GudhUI/model/Model.h b/src/GudhUI/model/Model.h
index 07a67a0c..1c39c0d7 100644
--- a/src/GudhUI/model/Model.h
+++ b/src/GudhUI/model/Model.h
@@ -71,7 +71,7 @@ class CGAL_geometric_flag_complex_wrapper {
void maximal_face(std::vector<int> vertices) {
if (!load_only_points_) {
- std::cout << "size:" << vertices.size() << std::endl;
+ // 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]));
diff --git a/src/GudhUI/utils/Bar_code_persistence.h b/src/GudhUI/utils/Bar_code_persistence.h
new file mode 100644
index 00000000..b527d684
--- /dev/null
+++ b/src/GudhUI/utils/Bar_code_persistence.h
@@ -0,0 +1,90 @@
+#include <math.h> // isfinite
+
+#include <QtGui/QApplication>
+
+#include <QGraphicsView>
+#include <QGraphicsScene>
+#include <QPointF>
+#include <QVector>
+#include <QGraphicsTextItem>
+
+#include <iostream>
+#include <vector>
+#include <limits> // NaN, infinity
+#include <utility> // for pair
+#include <string>
+
+#ifndef UTILS_BAR_CODE_PERSISTENCE_H_
+#define UTILS_BAR_CODE_PERSISTENCE_H_
+
+class Bar_code_persistence {
+ private:
+ typedef std::vector<std::pair<double, double>> Persistence;
+ Persistence persistence_vector;
+ double min_birth;
+ double max_death;
+
+ public:
+ Bar_code_persistence()
+ : min_birth(std::numeric_limits<double>::quiet_NaN()),
+ max_death(std::numeric_limits<double>::quiet_NaN()) { }
+
+ void insert(double birth, double death) {
+ persistence_vector.push_back(std::make_pair(birth, death));
+ if (std::isfinite(birth)) {
+ if ((birth < min_birth) || (std::isnan(min_birth)))
+ min_birth = birth;
+ if ((birth > max_death) || (std::isnan(max_death)))
+ max_death = birth;
+ }
+ if (std::isfinite(death))
+ if ((death > max_death) || (std::isnan(max_death)))
+ max_death = death;
+ }
+
+ void show(const std::string& window_title) {
+ // Create a view, put a scene in it
+ QGraphicsView * view = new QGraphicsView();
+ QGraphicsScene * scene = new QGraphicsScene();
+ view->setScene(scene);
+ double ratio = 600.0 / (max_death - min_birth);
+ // std::cout << "min_birth=" << min_birth << " - max_death=" << max_death << " - ratio=" << ratio << std::endl;
+
+ double height = 0.0, birth = 0.0, death = 0.0;
+ int pers_num = 1;
+ for (auto& persistence : persistence_vector) {
+ height = 5.0 * pers_num;
+ // std::cout << "[" << pers_num << "] birth=" << persistence.first << " - death=" << persistence.second << std::endl;
+ if (std::isfinite(persistence.first))
+ birth = ((persistence.first - min_birth) * ratio) + 50.0;
+ else
+ birth = 0.0;
+
+ if (std::isfinite(persistence.second))
+ death = ((persistence.second - min_birth) * ratio) + 50.0;
+ else
+ death = 700.0;
+
+ scene->addLine(birth, height, death, height, QPen(Qt::blue, 2));
+ pers_num++;
+ }
+ height += 10.0;
+ // scale line
+ scene->addLine(0, height, 700.0, height, QPen(Qt::black, 1));
+ int modulo = 0;
+ for (double scale = 50.0; scale < 700.0; scale += 50.0) {
+ modulo++;
+ // scale small dash
+ scene->addLine(scale, height - 3.0, scale, height + 3.0, QPen(Qt::black, 1));
+ // scale text
+ QString scale_value = QString::number(((scale - 50.0) / ratio) + min_birth);
+ QGraphicsTextItem* dimText = scene->addText(scale_value, QFont("Helvetica", 8));
+ dimText->setPos(scale - (3.0 * scale_value.size()), height + 9.0 * (modulo % 2));
+ }
+ view->setWindowTitle(window_title.c_str());
+ // Show the view
+ view->show();
+ }
+};
+
+#endif // UTILS_BAR_CODE_PERSISTENCE_H_
diff --git a/src/GudhUI/utils/Persistence_compute.h b/src/GudhUI/utils/Persistence_compute.h
index 0b9961d3..97165490 100644
--- a/src/GudhUI/utils/Persistence_compute.h
+++ b/src/GudhUI/utils/Persistence_compute.h
@@ -46,10 +46,6 @@ struct Persistence_params {
* 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;
@@ -61,9 +57,7 @@ template<typename SkBlComplex> class Persistence_compute {
* 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) {
+ Persistence_compute(SkBlComplex& complex, std::ostream& stream, const Persistence_params& params) {
// 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;
@@ -87,10 +81,10 @@ template<typename SkBlComplex> class Persistence_compute {
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";
+ stream << "persistence: \n";
+ stream << "p dimension birth death: \n";
- pcoh.output_diagram(stream_);
+ pcoh.output_diagram(stream);
}
};
diff --git a/src/GudhUI/view/FirstCoordProjector.h b/src/GudhUI/view/FirstCoordProjector.h
index 529d2d42..a4027b7f 100644
--- a/src/GudhUI/view/FirstCoordProjector.h
+++ b/src/GudhUI/view/FirstCoordProjector.h
@@ -32,8 +32,10 @@ class FirstCoordProjector3D : public Projector3D {
typedef Projector3D::Point_3 Point_3;
Point_3 operator()(const Point& p) const {
- assert(p.dimension() >= 3);
+ if (p.dimension() >= 3)
return Point_3(p.x(), p.y(), p.z());
+ else if (p.dimension() >= 2)
+ return Point_3(p.x(), p.y(), 0.0);
}
};
diff --git a/src/Persistent_cohomology/concept/FilteredComplex.h b/src/Persistent_cohomology/concept/FilteredComplex.h
index e47babe4..c19698df 100644
--- a/src/Persistent_cohomology/concept/FilteredComplex.h
+++ b/src/Persistent_cohomology/concept/FilteredComplex.h
@@ -139,6 +139,6 @@ Filtration_simplex_range filtration_simplex_range();
* @todo use an enum? Just a bool?
*/
//int is_before_in_filtration(Simplex_handle s, Simplex_handle t);
-/*************************************************/
+/*************************************************/
};
diff --git a/src/Persistent_cohomology/doc/3DTorus_poch.png b/src/Persistent_cohomology/doc/3DTorus_poch.png
new file mode 100644
index 00000000..1c9d8328
--- /dev/null
+++ b/src/Persistent_cohomology/doc/3DTorus_poch.png
Binary files differ
diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt
index 95506631..2f94ed15 100644
--- a/src/Persistent_cohomology/example/CMakeLists.txt
+++ b/src/Persistent_cohomology/example/CMakeLists.txt
@@ -7,24 +7,31 @@ add_definitions( -DBOOST_ALL_DYN_LINK )
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_test(rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.2 -d 3 -p 3 -m 100)
-
+
add_executable(parallel_rips_persistence parallel_rips_persistence.cpp)
target_link_libraries(parallel_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
-
-add_test(parallel_rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/parallel_rips_persistence ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.txt -r 0.3 -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})
+
+if (TBB_FOUND)
+ target_link_libraries(plain_homology ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(persistence_from_simple_simplex_tree ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(rips_persistence ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(parallel_rips_persistence ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(persistence_from_file ${TBB_RELEASE_LIBRARY})
+endif()
+
+add_test(plain_homology ${CMAKE_CURRENT_BINARY_DIR}/plain_homology)
+add_test(persistence_from_simple_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_simple_simplex_tree 1 0)
+add_test(rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/rips_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.2 -d 3 -p 3 -m 100)
+add_test(parallel_rips_persistence_3 ${CMAKE_CURRENT_BINARY_DIR}/parallel_rips_persistence ${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.txt -r 0.3 -d 3 -p 3 -m 100)
add_test(persistence_from_file_3_2_0 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 2 -m 0)
add_test(persistence_from_file_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
@@ -34,20 +41,45 @@ if(GMPXX_FOUND AND GMP_FOUND)
add_executable(rips_multifield_persistence rips_multifield_persistence.cpp )
target_link_libraries(rips_multifield_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
- add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.2 -d 3 -p 2 -q 71 -m 100)
-
add_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)
+ if (TBB_FOUND)
+ target_link_libraries(rips_multifield_persistence ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(performance_rips_persistence ${TBB_RELEASE_LIBRARY})
endif()
+
+ add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.2 -d 3 -p 2 -q 71 -m 100)
+
+ if(CGAL_FOUND)
+ add_executable(alpha_complex_3d_persistence alpha_complex_3d_persistence.cpp)
+ target_link_libraries(alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
+ if (TBB_FOUND)
+ target_link_libraries(alpha_complex_3d_persistence ${TBB_RELEASE_LIBRARY})
+ endif()
+ add_test(alpha_complex_3d_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_complex_3d_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 2 0.5)
+
+ if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ message(STATUS "CGAL version: ${CGAL_VERSION}.")
+
+ find_package(Eigen3 3.1.0)
+ if (EIGEN3_FOUND)
+ message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
+ include( ${EIGEN3_USE_FILE} )
+
+ add_executable (alpha_complex_persistence alpha_complex_persistence.cpp)
+ target_link_libraries(alpha_complex_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+ if (TBB_FOUND)
+ target_link_libraries(alpha_complex_persistence ${TBB_RELEASE_LIBRARY})
+ endif()
+
+ 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 ()
+ else()
+ # message(WARNING "CGAL not found.")
+ endif()
endif()
diff --git a/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
index 92c0b065..01497c7c 100644
--- a/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
@@ -39,9 +39,6 @@
#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;
@@ -66,11 +63,12 @@ typedef Alpha_shape_3::Edge Edge_3;
typedef std::list<Alpha_shape_3::Vertex_handle> Vertex_list;
// gudhi type definition
-typedef Simplex_tree<Simplex_tree_options_fast_persistence> ST;
+typedef Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence> ST;
typedef ST::Vertex_handle Simplex_tree_vertex;
typedef std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex > Alpha_shape_simplex_tree_map;
typedef std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex> Alpha_shape_simplex_tree_pair;
typedef std::vector< Simplex_tree_vertex > Simplex_tree_vector_vertex;
+typedef Gudhi::persistent_cohomology::Persistent_cohomology< ST, Gudhi::persistent_cohomology::Field_Zp > PCOH;
Vertex_list from(const Cell_handle& ch) {
Vertex_list the_list;
@@ -125,26 +123,21 @@ void usage(char * const progName) {
}
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";
+ // program args management
+ if (argc != 4) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
usage(argv[0]);
}
+ int coeff_field_characteristic = atoi(argv[2]);
+
Filtration_value min_persistence = 0.0;
- returnedScanValue = sscanf(argv[3], "%lf", &min_persistence);
+ int returnedScanValue = sscanf(argv[3], "%lf", &min_persistence);
if ((returnedScanValue == EOF) || (min_persistence < -1.0)) {
std::cerr << "Error: " << argv[3] << " is not correct\n";
usage(argv[0]);
}
- // program args management
- if (argc != 4) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
- usage(argv[0]);
- }
-
// Read points from file
std::string filegraph = argv[1];
std::list<Point_3> lp;
@@ -240,7 +233,7 @@ int main(int argc, char * const argv[]) {
}
}
// Construction of the simplex_tree
- Filtration_value filtr = std::sqrt(*the_alpha_value_iterator);
+ Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator);
#ifdef DEBUG_TRACES
std::cout << "filtration = " << filtr << std::endl;
#endif // DEBUG_TRACES
@@ -282,7 +275,7 @@ int main(int argc, char * const argv[]) {
std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl;
// Compute the persistence diagram of the complex
- Persistent_cohomology< ST, Field_Zp > pcoh(simplex_tree);
+ PCOH pcoh(simplex_tree);
// initializes the coefficient field for homology
pcoh.init_coefficients(coeff_field_characteristic);
diff --git a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
new file mode 100644
index 00000000..8f9f077c
--- /dev/null
+++ b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
@@ -0,0 +1,117 @@
+#include <boost/program_options.hpp>
+
+#include <CGAL/Epick_d.h>
+
+#include <gudhi/Alpha_complex.h>
+#include <gudhi/Persistent_cohomology.h>
+
+#include <iostream>
+#include <string>
+#include <limits> // for numeric_limits
+
+void program_options(int argc, char * argv[]
+ , std::string & off_file_points
+ , std::string & output_file_diag
+ , Filtration_value & alpha_square_max_value
+ , int & coeff_field_characteristic
+ , Filtration_value & min_persistence);
+
+int main(int argc, char **argv) {
+ std::string off_file_points;
+ std::string output_file_diag;
+ Filtration_value alpha_square_max_value;
+ int coeff_field_characteristic;
+ Filtration_value min_persistence;
+
+ program_options(argc, argv, off_file_points, output_file_diag, alpha_square_max_value,
+ coeff_field_characteristic, min_persistence);
+
+ // ----------------------------------------------------------------------------
+ // Init of an alpha complex from an OFF file
+ // ----------------------------------------------------------------------------
+ typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
+ Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_points, alpha_square_max_value);
+
+ // ----------------------------------------------------------------------------
+ // Display information about the alpha complex
+ // ----------------------------------------------------------------------------
+ std::cout << "Alpha complex is of dimension " << alpha_complex_from_file.dimension() <<
+ " - " << alpha_complex_from_file.num_simplices() << " simplices - " <<
+ alpha_complex_from_file.num_vertices() << " vertices." << std::endl;
+
+ // Sort the simplices in the order of the filtration
+ alpha_complex_from_file.initialize_filtration();
+
+ std::cout << "Simplex_tree dim: " << alpha_complex_from_file.dimension() << std::endl;
+ // Compute the persistence diagram of the complex
+ Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::alphacomplex::Alpha_complex<Kernel>,
+ Gudhi::persistent_cohomology::Field_Zp > pcoh(alpha_complex_from_file);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ // Output the diagram in filediag
+ if (output_file_diag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::cout << "Result in file: " << output_file_diag << std::endl;
+ std::ofstream out(output_file_diag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
+
+ return 0;
+}
+
+void program_options(int argc, char * argv[]
+ , std::string & off_file_points
+ , std::string & output_file_diag
+ , Filtration_value & alpha_square_max_value
+ , int & coeff_field_characteristic
+ , Filtration_value & min_persistence) {
+ namespace po = boost::program_options;
+ po::options_description hidden("Hidden options");
+ hidden.add_options()
+ ("input-file", po::value<std::string>(&off_file_points),
+ "Name of 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>(&output_file_diag)->default_value(std::string()),
+ "Name of file in which the persistence diagram is written. Default print in std::cout")
+ ("max-alpha-square-value,r",
+ po::value<Filtration_value>(&alpha_square_max_value)->default_value(std::numeric_limits<Filtration_value>::infinity()),
+ "Maximal alpha square value for the Alpha complex construction.")
+ ("field-charac,p", po::value<int>(&coeff_field_characteristic)->default_value(11),
+ "Characteristic p of the coefficient field Z/pZ for computing homology.")
+ ("min-persistence,m", po::value<Filtration_value>(&min_persistence),
+ "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals");
+
+ po::positional_options_description pos;
+ pos.add("input-file", 1);
+
+ po::options_description all;
+ all.add(visible).add(hidden);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).
+ options(all).positional(pos).run(), vm);
+ po::notify(vm);
+
+ if (vm.count("help") || !vm.count("input-file")) {
+ std::cout << std::endl;
+ std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
+ std::cout << "of an Alpha 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/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp
index 2d926a0d..cab49395 100644
--- a/src/Persistent_cohomology/example/rips_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence.cpp
@@ -30,6 +30,7 @@
#include <string>
#include <vector>
+#include <limits> // infinity
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
@@ -115,7 +116,7 @@ void program_options(int argc, char * argv[]
("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),
+ ("max-edge-length,r", po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
"Maximal length of an edge for the Rips complex construction.")
("cpx-dimension,d", po::value<int>(&dim_max)->default_value(1),
"Maximal dimension of the Rips complex we want to compute.")
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
index 643b810c..1b86f1f9 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
@@ -48,6 +48,7 @@ namespace persistent_cohomology {
/** \defgroup persistent_cohomology Persistent Cohomology
*
+ \author Clément Maria
Computation of persistent cohomology using the algorithm of
\cite DBLP:journals/dcg/SilvaMV11 and \cite DBLP:journals/corr/abs-1208-5018
@@ -63,15 +64,6 @@ namespace persistent_cohomology {
composed of three elements:
topological spaces, their homology groups and an evolution scheme.
- The theory of homology consists in attaching to a topological space a sequence of
- (homology) groups,
- capturing global topological features
- like connected components, holes, cavities, etc. Persistent homology studies the evolution
- -- birth, life and death -- of
- these features when the topological space is changing. Consequently, the theory is essentially
- composed of three elements:
- topological spaces, their homology groups and an evolution scheme.
-
<DT>Topological Spaces:</DT>
Topological spaces are represented by simplicial complexes.
Let \f$V = \{1, \cdots ,|V|\}\f$ be a set of <EM>vertices</EM>.
@@ -178,11 +170,6 @@ points sampling a Klein bottle in \f$\mathbb{R}^5\f$ with a simplex tree, its co
Hasse diagram and the computation of persistent homology and multi-field persistent homology for the
different representations.
-
-
- \author Clément Maria
- \version 1.0
- \date 2014
\copyright GNU General Public License v3.
@{
*/
diff --git a/src/Persistent_cohomology/test/CMakeLists.txt b/src/Persistent_cohomology/test/CMakeLists.txt
index d16be5be..459cc000 100644
--- a/src/Persistent_cohomology/test/CMakeLists.txt
+++ b/src/Persistent_cohomology/test/CMakeLists.txt
@@ -12,6 +12,9 @@ endif()
add_executable ( PersistentCohomologyUT persistent_cohomology_unit_test.cpp )
target_link_libraries(PersistentCohomologyUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(PersistentCohomologyUT ${TBB_RELEASE_LIBRARY})
+endif()
# Unitary tests
add_test(NAME PersistentCohomologyUT
@@ -22,7 +25,10 @@ add_test(NAME PersistentCohomologyUT
if(GMPXX_FOUND AND GMP_FOUND)
add_executable ( PersistentCohomologyMultiFieldUT persistent_cohomology_unit_test_multi_field.cpp )
- target_link_libraries(PersistentCohomologyMultiFieldUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+target_link_libraries(PersistentCohomologyMultiFieldUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+if (TBB_FOUND)
+ target_link_libraries(PersistentCohomologyMultiFieldUT ${TBB_RELEASE_LIBRARY})
+endif()
# Unitary tests
add_test(NAME PersistentCohomologyMultiFieldUT
diff --git a/src/Simplex_tree/doc/Simplex_tree_representation.png b/src/Simplex_tree/doc/Simplex_tree_representation.png
new file mode 100644
index 00000000..9d401520
--- /dev/null
+++ b/src/Simplex_tree/doc/Simplex_tree_representation.png
Binary files differ
diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt
index 200161a6..89a4e053 100644
--- a/src/Simplex_tree/example/CMakeLists.txt
+++ b/src/Simplex_tree/example/CMakeLists.txt
@@ -2,10 +2,16 @@ cmake_minimum_required(VERSION 2.6)
project(GUDHISimplexTreeFromFile)
add_executable ( simplex_tree_from_cliques_of_graph simplex_tree_from_cliques_of_graph.cpp )
+if (TBB_FOUND)
+ target_link_libraries(simplex_tree_from_cliques_of_graph ${TBB_RELEASE_LIBRARY})
+endif()
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 )
+if (TBB_FOUND)
+ target_link_libraries(simple_simplex_tree ${TBB_RELEASE_LIBRARY})
+endif()
add_test(simple_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/simple_simplex_tree)
add_executable ( mini_simplex_tree mini_simplex_tree.cpp )
@@ -16,5 +22,8 @@ add_test(mini_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/mini_simplex_tree)
if(GMP_FOUND AND CGAL_FOUND)
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} ${Boost_SYSTEM_LIBRARY})
+ if (TBB_FOUND)
+ target_link_libraries(simplex_tree_from_alpha_shapes_3 ${TBB_RELEASE_LIBRARY})
+ endif()
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()
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h
index 8a1a1344..b6dc8e13 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h
@@ -30,24 +30,28 @@
#include <gudhi/reader_utils.h>
#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Debug_utils.h>
#include <boost/container/flat_map.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
+#include <boost/range/adaptor/reversed.hpp>
#ifdef GUDHI_USE_TBB
#include <tbb/parallel_sort.h>
#endif
-#include <algorithm>
#include <utility>
#include <vector>
#include <functional> // for greater<>
+#include <stdexcept>
+#include <limits> // Inf
#include <initializer_list>
+#include <algorithm> // for std::max
namespace Gudhi {
-
/** \defgroup simplex_tree Filtered Complexes
+ * \author Cl&eacute;ment Maria
*
* A simplicial complex \f$\mathbf{K}\f$
* on a set of vertices \f$V = \{1, \cdots ,|V|\}\f$ is a collection of simplices
@@ -68,16 +72,13 @@ namespace Gudhi {
The simplex tree is an efficient and flexible
data structure for representing general (filtered) simplicial complexes. The data structure
is described in \cite boissonnatmariasimplextreealgorithmica
+ \image html "Simplex_tree_representation.png" "Simplex tree representation"
The second one is the Hasse_complex. The Hasse complex is a data structure representing
explicitly all co-dimension 1 incidence relations in a complex. It is consequently faster
when accessing the boundary of a simplex, but is less compact and harder to construct from
scratch.
-
- * \author Clément Maria
- * \version 1.0
- * \date 2014
* \copyright GNU General Public License v3.
* @{
*/
@@ -85,6 +86,7 @@ namespace Gudhi {
struct Simplex_tree_options_full_featured;
/**
+ * \class Simplex_tree Simplex_tree.h gudhi/Simplex_tree.h
* \brief Simplex Tree data structure for representing simplicial complexes.
*
* \details Every simplex \f$[v_0, \cdots ,v_d]\f$ admits a canonical orientation
@@ -138,7 +140,8 @@ class Simplex_tree {
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;
+ 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) {}
@@ -304,7 +307,8 @@ class Simplex_tree {
* of the simplex.
*
* @param[in] sh Simplex for which the boundary is computed. */
- Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) {
+ template<class SimplexHandle>
+ Boundary_simplex_range boundary_simplex_range(SimplexHandle sh) {
return Boundary_simplex_range(Boundary_simplex_iterator(this, sh),
Boundary_simplex_iterator(this));
}
@@ -445,6 +449,15 @@ class Simplex_tree {
}
}
+ /** \brief Sets the filtration value of a simplex.
+ * \exception std::invalid_argument In debug mode, if sh is a null_simplex.
+ */
+ void assign_filtration(Simplex_handle sh, Filtration_value fv) {
+ GUDHI_CHECK(sh != null_simplex(),
+ std::invalid_argument("Simplex_tree::assign_filtration - cannot assign filtration on null_simplex"));
+ sh->second.assign_filtration(fv);
+ }
+
/** \brief Returns an upper bound of the filtration values of the simplices. */
Filtration_value filtration() const {
return threshold_;
@@ -514,9 +527,10 @@ class Simplex_tree {
return dimension_;
}
- /** \brief Returns true iff the node in the simplex tree pointed by
+ /** \brief Returns true if the node in the simplex tree pointed by
* sh has children.*/
- bool has_children(Simplex_handle sh) const {
+ template<class SimplexHandle>
+ bool has_children(SimplexHandle sh) const {
return (sh->second.children()->parent() == sh->first);
}
@@ -582,7 +596,19 @@ class Simplex_tree {
private:
/** \brief Inserts a simplex represented by a vector of vertex.
- \warning the vector must be sorted by increasing vertex handle order */
+ * @param[in] simplex vector of Vertex_handles, representing the vertices of the new simplex. The vector must be
+ * sorted by increasing vertex handle order.
+ * @param[in] filtration the filtration value assigned to the new simplex.
+ * @return 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.
+ *
+ */
std::pair<Simplex_handle, bool> insert_vertex_vector(const std::vector<Vertex_handle>& simplex,
Filtration_value filtration) {
Siblings * curr_sib = &root_;
@@ -615,7 +641,7 @@ class Simplex_tree {
*
* @param[in] simplex range of Vertex_handles, representing the vertices of the new simplex
* @param[in] filtration the filtration value assigned to the new simplex.
- * The return type is a pair. If the new simplex is inserted successfully (i.e. it was not in the
+ * @return 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
@@ -654,7 +680,7 @@ class Simplex_tree {
*
* @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.
- * The return type is a pair. If the new simplex is inserted successfully (i.e. it was not in the
+ * @return 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
@@ -663,7 +689,7 @@ class Simplex_tree {
* 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>>
+ 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);
@@ -717,7 +743,7 @@ class Simplex_tree {
} 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;
+ std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Error vector not empty\n";
exit(-1);
}
std::vector<Vertex_handle> first_simplex(1, the_simplex.back());
@@ -726,7 +752,7 @@ class Simplex_tree {
insert_result = insert_vertex_vector(first_simplex, filtration);
} else {
- std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Recursivity error" << std::endl;
+ std::cerr << "Simplex_tree::rec_insert_simplex_and_subfaces - Recursivity error\n";
exit(-1);
}
return insert_result;
@@ -739,7 +765,6 @@ class Simplex_tree {
sh->second.assign_key(key);
}
- public:
/** Returns the two Simplex_handle corresponding to the endpoints of
* and edge. sh must point to a 1-dimensional simplex. This is an
* optimized version of the boundary computation. */
@@ -749,7 +774,8 @@ class Simplex_tree {
}
/** Returns the Siblings containing a simplex.*/
- Siblings * self_siblings(Simplex_handle sh) {
+ template<class SimplexHandle>
+ Siblings* self_siblings(SimplexHandle sh) {
if (sh->second.children()->parent() == sh->first)
return sh->second.children()->oncles();
else
@@ -798,10 +824,11 @@ class Simplex_tree {
* possible.
*/
#ifdef GUDHI_USE_TBB
- tbb::parallel_sort(filtration_vect_, is_before_in_filtration(this));
+ std::cout << "TBB is ON !!!" << std::endl;
+ tbb::parallel_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(this));
#else
- std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(),
- is_before_in_filtration(this));
+ std::cout << "TBB is OFF..." << std::endl;
+ std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(this));
#endif
}
@@ -928,7 +955,7 @@ class Simplex_tree {
bool operator()(const Simplex_handle sh1, const Simplex_handle sh2) const {
// 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 sh1->second.filtration() < sh2->second.filtration();
}
// is sh1 a proper subface of sh2
return st_->reverse_lexicographic_order(sh1, sh2);
@@ -1105,6 +1132,120 @@ class Simplex_tree {
}
}
+ public:
+ /** \brief Browse the simplex tree to ensure the filtration is not decreasing.
+ * The simplex tree is browsed starting from the root until the leaf, and the filtration values are set with their
+ * parent value (increased), in case the values are decreasing.
+ * @return The filtration modification information.
+ * \post Some simplex tree functions require the filtration to be valid. `make_filtration_non_decreasing()`
+ * function is not launching `initialize_filtration()` but returns the filtration modification information. If the
+ * complex has changed , please call `initialize_filtration()` to recompute it.
+ */
+ bool make_filtration_non_decreasing() {
+ bool modified = false;
+ // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree
+ for (auto& simplex : boost::adaptors::reverse(root_.members())) {
+ if (has_children(&simplex)) {
+ modified |= rec_make_filtration_non_decreasing(simplex.second.children());
+ }
+ }
+ return modified;
+ }
+
+ private:
+ /** \brief Recursively Browse the simplex tree to ensure the filtration is not decreasing.
+ * @param[in] sib Siblings to be parsed.
+ * @return The filtration modification information in order to trigger initialize_filtration.
+ */
+ bool rec_make_filtration_non_decreasing(Siblings * sib) {
+ bool modified = false;
+
+ // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree
+ for (auto& simplex : boost::adaptors::reverse(sib->members())) {
+ // Find the maximum filtration value in the border
+ Boundary_simplex_range boundary = boundary_simplex_range(&simplex);
+ Boundary_simplex_iterator max_border = std::max_element(std::begin(boundary), std::end(boundary),
+ [](Simplex_handle sh1, Simplex_handle sh2) {
+ return filtration(sh1) < filtration(sh2);
+ });
+
+ Filtration_value max_filt_border_value = filtration(*max_border);
+ if (simplex.second.filtration() < max_filt_border_value) {
+ // Store the filtration modification information
+ modified = true;
+ simplex.second.assign_filtration(max_filt_border_value);
+ }
+ if (has_children(&simplex)) {
+ modified |= rec_make_filtration_non_decreasing(simplex.second.children());
+ }
+ }
+ // Make the modified information to be traced by upper call
+ return modified;
+ }
+
+ public:
+ /** \brief Prune above filtration value given as parameter.
+ * @param[in] filtration Maximum threshold value.
+ * @return The filtration modification information.
+ * \post Some simplex tree functions require the filtration to be valid. `prune_above_filtration()`
+ * function is not launching `initialize_filtration()` but returns the filtration modification information. If the
+ * complex has changed , please call `initialize_filtration()` to recompute it.
+ */
+ bool prune_above_filtration(Filtration_value filtration) {
+ return rec_prune_above_filtration(root(), filtration);
+ }
+
+ private:
+ bool rec_prune_above_filtration(Siblings* sib, Filtration_value filt) {
+ auto&& list = sib->members();
+ auto last = std::remove_if(list.begin(), list.end(), [=](Dit_value_t& simplex) {
+ if (simplex.second.filtration() <= filt) return false;
+ if (has_children(&simplex)) rec_delete(simplex.second.children());
+ return true;
+ });
+
+ bool modified = (last != list.end());
+ if (last == list.begin() && sib != root()) {
+ // Removing the whole siblings, parent becomes a leaf.
+ sib->oncles()->members()[sib->parent()].assign_children(sib->oncles());
+ delete sib;
+ return true;
+ } else {
+ // Keeping some elements of siblings. Remove the others, and recurse in the remaining ones.
+ list.erase(last, list.end());
+ for (auto&& simplex : list)
+ if (has_children(&simplex))
+ modified |= rec_prune_above_filtration(simplex.second.children(), filt);
+ }
+ return modified;
+ }
+
+ public:
+ /** \brief Remove a maximal simplex.
+ * @param[in] sh Simplex handle on the maximal simplex to remove.
+ * \pre Please check the simplex has no coface before removing it.
+ * \exception std::invalid_argument In debug mode, if sh has children.
+ * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done).
+ */
+ void remove_maximal_simplex(Simplex_handle sh) {
+ // Guarantee the simplex has no children
+ GUDHI_CHECK(!has_children(sh),
+ std::invalid_argument("Simplex_tree::remove_maximal_simplex - argument has children"));
+
+ // Simplex is a leaf, it means the child is the Siblings owning the leaf
+ Siblings* child = sh->second.children();
+
+ if ((child->size() > 1) || (child == root())) {
+ // Not alone, just remove it from members
+ // Special case when child is the root of the simplex tree, just remove it from members
+ child->erase(sh);
+ } else {
+ // Sibling is emptied : must be deleted, and its parent must point on his own Sibling
+ child->oncles()->members().at(child->parent()).assign_children(child->oncles());
+ delete child;
+ }
+ }
+
private:
Vertex_handle null_vertex_;
/** \brief Upper bound on the filtration values of the simplices.*/
@@ -1119,7 +1260,6 @@ class Simplex_tree {
};
// Print a Simplex_tree in os.
-
template<typename...T>
std::ostream& operator<<(std::ostream & os, Simplex_tree<T...> & st) {
for (auto sh : st.filtration_simplex_range()) {
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 936b7a1f..7e0a454d 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
@@ -104,7 +104,8 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade<
st_(st) {
}
- Simplex_tree_boundary_simplex_iterator(SimplexTree * st, Simplex_handle sh)
+ template<class SimplexHandle>
+ Simplex_tree_boundary_simplex_iterator(SimplexTree * st, SimplexHandle sh)
: last_(sh->first),
sib_(nullptr),
st_(st) {
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 072afc8d..1eca7f6f 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
@@ -116,6 +116,10 @@ class Simplex_tree_siblings {
return members_.size();
}
+ void erase(const Dictionary_it iterator) {
+ members_.erase(iterator);
+ }
+
Simplex_tree_siblings * oncles_;
Vertex_handle parent_;
Dictionary members_;
diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt
index 1f2f7d33..609d8669 100644
--- a/src/Simplex_tree/test/CMakeLists.txt
+++ b/src/Simplex_tree/test/CMakeLists.txt
@@ -12,6 +12,9 @@ endif()
add_executable ( SimplexTreeUT simplex_tree_unit_test.cpp )
target_link_libraries(SimplexTreeUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(SimplexTreeUT ${TBB_RELEASE_LIBRARY})
+endif()
# Do not forget to copy test files in current binary dir
file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
index 874c3363..b1bb23b1 100644
--- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp
+++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
@@ -795,3 +795,355 @@ BOOST_AUTO_TEST_CASE(non_contiguous) {
test_simplex_is_vertex(st, *++i, 3);
BOOST_CHECK(++i == std::end(b));
}
+
+BOOST_AUTO_TEST_CASE(make_filtration_non_decreasing) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "MAKE FILTRATION NON DECREASING" << std::endl;
+ typedef Simplex_tree<> typeST;
+ typeST st;
+
+ st.insert_simplex_and_subfaces({2, 1, 0}, 2.0);
+ st.insert_simplex_and_subfaces({3, 0}, 2.0);
+ st.insert_simplex_and_subfaces({3, 4, 5}, 2.0);
+
+ // Inserted simplex:
+ // 1
+ // o
+ // /X\
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+
+ std::cout << "Check default insertion ensures the filtration values are non decreasing" << std::endl;
+ BOOST_CHECK(!st.make_filtration_non_decreasing());
+
+ // Because of non decreasing property of simplex tree, { 0 } , { 1 } and { 0, 1 } are going to be set from value 2.0
+ // to 1.0
+ st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);
+
+ // Inserted simplex:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+
+ std::cout << "Check default second insertion ensures the filtration values are non decreasing" << std::endl;
+ BOOST_CHECK(!st.make_filtration_non_decreasing());
+
+ // Copy original simplex tree
+ typeST st_copy = st;
+
+ // Modify specific values for st to become like st_copy thanks to make_filtration_non_decreasing
+ st.assign_filtration(st.find({0,1,6,7}), 0.8);
+ st.assign_filtration(st.find({0,1,6}), 0.9);
+ st.assign_filtration(st.find({0,6}), 0.6);
+ st.assign_filtration(st.find({3,4,5}), 1.2);
+ st.assign_filtration(st.find({3,4}), 1.1);
+ st.assign_filtration(st.find({4,5}), 1.99);
+
+ std::cout << "Check the simplex_tree is rolled back in case of decreasing filtration values" << std::endl;
+ BOOST_CHECK(st.make_filtration_non_decreasing());
+ BOOST_CHECK(st == st_copy);
+
+ // Other simplex tree
+ typeST st_other;
+ st_other.insert_simplex_and_subfaces({2, 1, 0}, 3.0); // This one is different from st
+ st_other.insert_simplex_and_subfaces({3, 0}, 2.0);
+ st_other.insert_simplex_and_subfaces({3, 4, 5}, 2.0);
+ st_other.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);
+
+ // Modify specific values for st to become like st_other thanks to make_filtration_non_decreasing
+ st.assign_filtration(st.find({2}), 3.0);
+ // By modifying just the simplex {2}
+ // {0,1,2}, {1,2} and {0,2} will be modified
+
+ std::cout << "Check the simplex_tree is repaired in case of decreasing filtration values" << std::endl;
+ BOOST_CHECK(st.make_filtration_non_decreasing());
+ BOOST_CHECK(st == st_other);
+
+ // Modify specific values for st still to be non-decreasing
+ st.assign_filtration(st.find({0,1,2}), 10.0);
+ st.assign_filtration(st.find({0,2}), 9.0);
+ st.assign_filtration(st.find({0,1,6,7}), 50.0);
+ st.assign_filtration(st.find({0,1,6}), 49.0);
+ st.assign_filtration(st.find({0,1,7}), 48.0);
+ // Other copy simplex tree
+ typeST st_other_copy = st;
+
+ std::cout << "Check the simplex_tree is not modified in case of non-decreasing filtration values" << std::endl;
+ BOOST_CHECK(!st.make_filtration_non_decreasing());
+ BOOST_CHECK(st == st_other_copy);
+
+}
+
+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;
+};
+
+BOOST_AUTO_TEST_CASE(remove_maximal_simplex) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl;
+
+
+ typedef Simplex_tree<MyOptions> miniST;
+ miniST st;
+
+ // FIXME
+ st.set_dimension(3);
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7});
+ st.insert_simplex_and_subfaces({3, 4, 5});
+
+ // Constructs a copy at this state for further test purpose
+ miniST st_pruned = st;
+
+ st.insert_simplex_and_subfaces({3, 0});
+ st.insert_simplex_and_subfaces({2, 1, 0});
+
+ // Constructs a copy at this state for further test purpose
+ miniST st_complete = st;
+ // st_complete and st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+ // st_pruned:
+ // 1 6
+ // o---o
+ // \7/
+ // o o---o
+ // 0 3\X/4
+ // o
+ // 5
+
+#ifdef GUDHI_DEBUG
+ std::cout << "Check exception throw in debug mode" << std::endl;
+ // throw excpt because sh has children
+ BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument);
+ BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument);
+ BOOST_CHECK(st == st_complete);
+#endif
+
+ st.remove_maximal_simplex(st.find({0, 2}));
+ st.remove_maximal_simplex(st.find({0, 1, 2}));
+ st.remove_maximal_simplex(st.find({1, 2}));
+ st.remove_maximal_simplex(st.find({2}));
+ st.remove_maximal_simplex(st.find({0, 3}));
+
+ BOOST_CHECK(st == st_pruned);
+ // Remove all, but as the simplex tree is not storing filtration, there is no modification
+ st.prune_above_filtration(0.0);
+ BOOST_CHECK(st == st_pruned);
+
+ miniST st_wo_seven;
+ // FIXME
+ st_wo_seven.set_dimension(3);
+
+ st_wo_seven.insert_simplex_and_subfaces({0, 1, 6});
+ st_wo_seven.insert_simplex_and_subfaces({3, 4, 5});
+ // st_wo_seven:
+ // 1 6
+ // o---o
+ // \X/
+ // o o---o
+ // 0 3\X/4
+ // o
+ // 5
+
+ // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not)
+ st.remove_maximal_simplex(st.find({0, 1, 6, 7}));
+ st.remove_maximal_simplex(st.find({0, 1, 7}));
+ st.remove_maximal_simplex(st.find({0, 6, 7}));
+ st.remove_maximal_simplex(st.find({0, 7}));
+ st.remove_maximal_simplex(st.find({1, 6, 7}));
+ st.remove_maximal_simplex(st.find({1, 7}));
+ st.remove_maximal_simplex(st.find({6, 7}));
+ st.remove_maximal_simplex(st.find({7}));
+
+ BOOST_CHECK(st == st_wo_seven);
+}
+
+BOOST_AUTO_TEST_CASE(prune_above_filtration) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "PRUNE ABOVE FILTRATION" << std::endl;
+ typedef Simplex_tree<> typeST;
+ typeST st;
+
+ // FIXME
+ st.set_dimension(3);
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);
+ st.insert_simplex_and_subfaces({3, 4, 5}, 2.0);
+
+ // Constructs a copy at this state for further test purpose
+ typeST st_pruned = st;
+ st_pruned.initialize_filtration(); // reset
+
+ st.insert_simplex_and_subfaces({3, 0}, 3.0);
+ st.insert_simplex_and_subfaces({2, 1, 0}, 4.0);
+
+ // Constructs a copy at this state for further test purpose
+ typeST st_complete = st;
+ // st_complete and st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+ // st_pruned:
+ // 1 6
+ // o---o
+ // \7/
+ // o o---o
+ // 0 3\X/4
+ // o
+ // 5
+
+ bool simplex_is_changed = false;
+ // Check the no action cases
+ // greater than initial filtration value
+ simplex_is_changed = st.prune_above_filtration(10.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_complete);
+ BOOST_CHECK(!simplex_is_changed);
+ // equal to initial filtration value
+ simplex_is_changed = st.prune_above_filtration(6.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_complete);
+ BOOST_CHECK(!simplex_is_changed);
+ // lower than initial filtration value, but still greater than the maximum filtration value
+ simplex_is_changed = st.prune_above_filtration(5.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_complete);
+ BOOST_CHECK(!simplex_is_changed);
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << 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 << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ // Check the pruned cases
+ simplex_is_changed = st.prune_above_filtration(2.5);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_pruned);
+ BOOST_CHECK(simplex_is_changed);
+
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << std::endl;
+
+ simplex_is_changed = st.prune_above_filtration(2.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+
+ std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << std::endl;
+
+ BOOST_CHECK(st == st_pruned);
+ BOOST_CHECK(!simplex_is_changed);
+
+ typeST st_empty;
+ // FIXME
+ st_empty.set_dimension(3);
+ simplex_is_changed = st.prune_above_filtration(0.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << std::endl;
+
+ BOOST_CHECK(st == st_empty);
+ BOOST_CHECK(simplex_is_changed);
+
+ // Test case to the limit
+ simplex_is_changed = st.prune_above_filtration(-1.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_empty);
+ BOOST_CHECK(!simplex_is_changed);
+}
+
+BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl;
+ typedef Simplex_tree<MyOptions> typeST;
+ typeST st;
+
+ // FIXME
+ st.set_dimension(3);
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7});
+ st.insert_simplex_and_subfaces({3, 4, 5});
+ st.insert_simplex_and_subfaces({3, 0});
+ st.insert_simplex_and_subfaces({2, 1, 0});
+
+ // st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+
+ st.initialize_filtration();
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(st.num_simplices() == 27);
+
+ // Test case to the limit - With these options, there is no filtration, which means filtration is 0
+ bool simplex_is_changed = st.prune_above_filtration(1.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(!simplex_is_changed);
+ BOOST_CHECK(st.num_simplices() == 27);
+
+ simplex_is_changed = st.prune_above_filtration(0.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(!simplex_is_changed);
+ BOOST_CHECK(st.num_simplices() == 27);
+
+ // Test case to the limit
+ simplex_is_changed = st.prune_above_filtration(-1.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(simplex_is_changed);
+ BOOST_CHECK(st.num_simplices() == 0);
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
+
+} \ No newline at end of file
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
index 615b3a81..8584cd16 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h
@@ -31,7 +31,7 @@
#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/Debug_utils.h>
namespace Gudhi {
@@ -240,7 +240,6 @@ their collaboration to write the two initial papers
\copyright GNU General Public License v3.
-\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
*/
/** @} */ // end defgroup
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 50a83345..0dd5dd54 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
@@ -25,7 +25,7 @@
#include <gudhi/Skeleton_blocker_complex.h>
#include <gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h>
-#include <gudhi/Utils.h>
+#include <gudhi/Debug_utils.h>
#include <map>
#include <vector>
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 ce565166..b8d99201 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
@@ -25,7 +25,7 @@
#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 <gudhi/Debug_utils.h>
#include <boost/iterator/iterator_facade.hpp>
diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h
index 5b774f25..fd85f0c2 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h
@@ -31,7 +31,7 @@
#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 <gudhi/Debug_utils.h>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
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 5c898152..040f7950 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h
@@ -22,9 +22,9 @@
#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/Debug_utils.h>
namespace Gudhi {
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 85a6b0b5..e3c16d88 100644
--- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h
+++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h
@@ -22,8 +22,8 @@
#ifndef SKELETON_BLOCKER_LINK_COMPLEX_H_
#define SKELETON_BLOCKER_LINK_COMPLEX_H_
-#include <gudhi/Utils.h>
#include <gudhi/Skeleton_blocker_complex.h>
+#include <gudhi/Debug_utils.h>
namespace Gudhi {
diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp
index 71b1833b..2a3f0501 100644
--- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp
+++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp
@@ -24,7 +24,7 @@
#include <string>
#include <fstream>
#include <sstream>
-#include "gudhi/Utils.h"
+#include "gudhi/Debug_utils.h"
#include "gudhi/Test.h"
#include "gudhi/Skeleton_blocker.h"
//#include "gudhi/Skeleton_blocker_link_complex.h"
diff --git a/src/Witness_complex/doc/Witness_complex_doc.h b/src/Witness_complex/doc/Witness_complex_doc.h
index e9f78170..60dfd27b 100644
--- a/src/Witness_complex/doc/Witness_complex_doc.h
+++ b/src/Witness_complex/doc/Witness_complex_doc.h
@@ -6,6 +6,8 @@
\author Siargey Kachanovich
+ \image html "Witness_complex_representation.png" "Witness complex representation"
+
\section Definitions
Witness complex \f$ Wit(W,L) \f$ is a simplicial complex defined on two sets of points in \f$\mathbb{R}^D\f$:
@@ -18,7 +20,9 @@
\f$ \sigma \subset L \f$ is witnessed if there exists a point \f$w \in W\f$ such that
w is closer to the vertices of \f$ \sigma \f$ than other points in \f$ L \f$ and all of its faces are witnessed as well.
-
+
+ The data structure is described in \cite boissonnatmariasimplextreealgorithmica .
+
\section Implementation
The principal class of this module is Gudhi::Witness_complex.
diff --git a/src/Witness_complex/doc/Witness_complex_representation.png b/src/Witness_complex/doc/Witness_complex_representation.png
new file mode 100644
index 00000000..1d31a490
--- /dev/null
+++ b/src/Witness_complex/doc/Witness_complex_representation.png
Binary files differ
diff --git a/src/Witness_complex/test/CMakeLists.txt b/src/Witness_complex/test/CMakeLists.txt
index 9422c152..37bef2d0 100644
--- a/src/Witness_complex/test/CMakeLists.txt
+++ b/src/Witness_complex/test/CMakeLists.txt
@@ -4,14 +4,10 @@ project(GUDHIWitnessComplexUT)
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()
add_executable ( simple_witness_complexUT simple_witness_complex.cpp )
diff --git a/src/common/doc/Gudhi_banner.jpg b/src/common/doc/Gudhi_banner.jpg
deleted file mode 100644
index ebd3d8af..00000000
--- a/src/common/doc/Gudhi_banner.jpg
+++ /dev/null
Binary files differ
diff --git a/src/common/doc/Gudhi_banner.png b/src/common/doc/Gudhi_banner.png
new file mode 100644
index 00000000..18e8a672
--- /dev/null
+++ b/src/common/doc/Gudhi_banner.png
Binary files differ
diff --git a/src/common/doc/footer.html b/src/common/doc/footer.html
new file mode 100644
index 00000000..7b4cdc5c
--- /dev/null
+++ b/src/common/doc/footer.html
@@ -0,0 +1,29 @@
+<!-- HTML footer for doxygen 1.8.6-->
+<!-- start footer part -->
+<table style="width:100%">
+ <tr class="no-bullet shadow-black">
+ <td class="network-entypo">
+<!--BEGIN PROJECT_NAME--> $projectname
+<!--BEGIN PROJECT_NUMBER-->&#160;Version $projectnumber<!--END PROJECT_NUMBER-->
+<!--BEGIN PROJECT_BRIEF-->&#160;-&#160;$projectbrief<!--END PROJECT_BRIEF-->
+<!--END PROJECT_NAME-->
+ </td>
+ <td class="network-entypo">
+<!--BEGIN GENERATE_TREEVIEW-->
+ $generatedby
+ <a href="http://www.doxygen.org/index.html">
+ <img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion
+<!--END GENERATE_TREEVIEW-->
+ </td>
+ </tr>
+</table>
+
+<!--BEGIN !GENERATE_TREEVIEW-->
+<hr class="footer"/><address class="footer"><small> tralala
+$generatedby &#160;<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
+</a> $doxygenversion
+</small></address>
+<!--END !GENERATE_TREEVIEW-->
+</body>
+</html>
diff --git a/src/common/doc/header.html b/src/common/doc/header.html
new file mode 100644
index 00000000..c958390c
--- /dev/null
+++ b/src/common/doc/header.html
@@ -0,0 +1,82 @@
+<!-- HTML header for doxygen 1.8.6-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- GUDHI website : class="no-js" lang="en" is necessary -->
+<html xmlns="http://www.w3.org/1999/xhtml" class="no-js" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen $doxygenversion"/>
+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
+<!-- GUDHI website css for header BEGIN -->
+<link rel="stylesheet" type="text/css" href="http://gudhi.gforge.inria.fr/assets/css/styles_feeling_responsive.css" />
+<!-- GUDHI website css for header END -->
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
+$treeview
+$search
+$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+$extrastylesheet
+</head>
+<body>
+
+<!-- GUDHI website header BEGIN -->
+<div id="navigation" class="sticky">
+ <nav class="top-bar" role="navigation" data-topbar>
+ <section class="top-bar-section">
+ <ul class="right">
+ <li class="divider"></li>
+ <li><a href="http://gudhi.gforge.inria.fr/contact/">Contact</a></li>
+ </ul>
+ <ul class="left">
+ <li><a href="http://gudhi.gforge.inria.fr/"> <img src="http://gudhi.gforge.inria.fr/assets/img/home.png" alt="&nbsp;&nbsp;GUDHI">&nbsp;&nbsp;GUDHI </a></li>
+ <li class="divider"></li>
+ <li class="has-dropdown">
+ <a href="#">Project</a>
+ <ul class="dropdown">
+ <li><a href="http://gudhi.gforge.inria.fr/people/">People</a></li>
+ <li><a href="http://gudhi.gforge.inria.fr/getinvolved/">Get involved</a></li>
+ <li><a href="http://gudhi.gforge.inria.fr/partners/">Partners and Funding</a></li>
+ <li><a href="http://gudhi.gforge.inria.fr/relatedprojects/">Related projects</a></li>
+ </ul>
+ </li>
+ <li class="divider"></li>
+ <li class="has-dropdown">
+ <a href="#">Download</a>
+ <ul class="dropdown">
+ <li><a href="http://gudhi.gforge.inria.fr/licensing/">Licensing</a></li>
+ <li><a href="https://gforge.inria.fr/frs/?group_id=3865" target="_blank">Get the sources</a></li>
+ <li><a href="http://gudhi.gforge.inria.fr/doc/latest/installation.html">Installation manual</a></li>
+ </ul>
+ </li>
+ <li class="divider"></li>
+ <li><a href="http://gudhi.gforge.inria.fr/doc/latest/modules.html">Documentation</a></li>
+ <li class="divider"></li>
+ <li><a href="http://gudhi.gforge.inria.fr/interfaces/">Interfaces</a></li>
+ <li class="divider"></li>
+ </ul>
+ </section>
+ </nav>
+</div><!-- /#navigation -->
+<!-- GUDHI website header BEGIN -->
+
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+
+<!--BEGIN TITLEAREA-->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 30px;">
+ <!--BEGIN DISABLE_INDEX-->
+ <!--BEGIN SEARCHENGINE-->
+ <td>$searchbox</td>
+ <!--END SEARCHENGINE-->
+ <!--END DISABLE_INDEX-->
+ </tr>
+ </tbody>
+</table>
+</div>
+<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h
index 41b8ba1e..063e0a11 100644
--- a/src/common/doc/main_page.h
+++ b/src/common/doc/main_page.h
@@ -1,15 +1,14 @@
/*! \mainpage
- * \image html "Gudhi_banner.jpg" "" width=20cm
+ * \tableofcontents
+ * \image html "Gudhi_banner.png" "" width=20cm
*
* \section Introduction Introduction
- * The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic open source C++ library for
+ * The Gudhi library (Geometry 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 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:
*
@@ -20,24 +19,138 @@
* 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
- *
+ \section DataStructures Data structures
+ \subsection AlphaComplexDataStructure Alpha complex
+ \image html "alpha_complex_representation.png" "Alpha complex representation"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> Vincent Rouvreau<br>
+ <b>Introduced in:</b> GUDHI 1.3.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ Alpha_complex is a simplicial complex constructed from the finite cells of a Delaunay Triangulation.<br>
+ The filtration value of each simplex is computed as the square of the circumradius of the simplex if the
+ circumsphere is empty (the simplex is then said to be Gabriel), and as the minimum of the filtration
+ values of the codimension 1 cofaces that make it not Gabriel otherwise.
+ All simplices that have a filtration value strictly greater than a given alpha squared value are not inserted into
+ the complex.<br>
+ <b>User manual:</b> \ref alpha_complex - <b>Reference manual:</b> Gudhi::alphacomplex::Alpha_complex
+ </td>
+ </tr>
+</table>
+ \subsection CubicalComplexDataStructure Cubical complex
+ \image html "Cubical_complex_representation.png" "Cubical complex representation"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> Pawel Dlotko<br>
+ <b>Introduced in:</b> GUDHI 1.3.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ The cubical complex is an example of a structured complex useful in computational mathematics (specially
+ rigorous numerics) and image analysis.<br>
+ <b>User manual:</b> \ref cubical_complex - <b>Reference manual:</b> Gudhi::Cubical_complex::Bitmap_cubical_complex
+ </td>
+ </tr>
+</table>
+ \subsection SimplexTreeDataStructure Simplex tree
+ \image html "Simplex_tree_representation.png" "Simplex tree representation"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> Cl&eacute;ment Maria<br>
+ <b>Introduced in:</b> GUDHI 1.0.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ The simplex tree is an efficient and flexible
+ data structure for representing general (filtered) simplicial complexes. The data structure
+ is described in \cite boissonnatmariasimplextreealgorithmica .<br>
+ <b>User manual:</b> \ref simplex_tree - <b>Reference manual:</b> Gudhi::Simplex_tree
+ </td>
+ </tr>
+</table>
+ \subsection SkeletonBlockerDataStructure Skeleton blocker
+ \image html "ds_representation.png" "Skeleton blocker representation"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> David Salinas<br>
+ <b>Introduced in:</b> GUDHI 1.1.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ The Skeleton-Blocker data-structure proposes a light encoding for simplicial complexes by storing only an *implicit*
+ representation of its simplices \cite socg_blockers_2011,\cite blockers2012. Intuitively, it just stores the
+ 1-skeleton of a simplicial complex with a graph and the set of its "missing faces" that is very small in practice.
+ This data-structure handles all simplicial complexes operations such as simplex enumeration or simplex removal but
+ operations that are particularly efficient are operations that do not require simplex enumeration such as edge
+ iteration, link computation or simplex contraction.<br>
+ <b>User manual:</b> \ref skbl - <b>Reference manual:</b> Gudhi::skbl::Skeleton_blocker_complex
+ </td>
+ </tr>
+</table>
+ \subsection WitnessComplexDataStructure Witness complex
+ \image html "Witness_complex_representation.png" "Witness complex representation"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> Siargey Kachanovich<br>
+ <b>Introduced in:</b> GUDHI 1.3.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ Witness complex \f$ Wit(W,L) \f$ is a simplicial complex defined on two sets of points in \f$\mathbb{R}^D\f$.
+ The data structure is described in \cite boissonnatmariasimplextreealgorithmica .<br>
+ <b>User manual:</b> \ref witness_complex - <b>Reference manual:</b> Gudhi::witness_complex::SimplicialComplexForWitness
+ </td>
+ </tr>
+</table>
+
+ \section Toolbox Toolbox
+ \subsection ContractionToolbox Contraction
+ \image html "sphere_contraction_representation.png" "Sphere contraction example"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> David Salinas<br>
+ <b>Introduced in:</b> GUDHI 1.1.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ The purpose of this package is to offer a user-friendly interface for edge contraction simplification of huge
+ simplicial complexes. It uses the \ref skbl data-structure whose size remains small during simplification of most
+ used geometrical complexes of topological data analysis such as the Rips or the Delaunay complexes. In practice,
+ the size of this data-structure is even much lower than the total number of simplices.<br>
+ <b>User manual:</b> \ref contr
+ </td>
+ </tr>
+</table>
+ \subsection PersistentCohomologyToolbox Persistent Cohomology
+ \image html "3DTorus_poch.png" "Rips Persistent Cohomology on a 3D Torus"
+<table border="0">
+ <tr>
+ <td width="25%">
+ <b>Author:</b> Cl&eacute;ment Maria<br>
+ <b>Introduced in:</b> GUDHI 1.0.0<br>
+ <b>Copyright:</b> GPL v3<br>
+ </td>
+ <td width="75%">
+ The theory of homology consists in attaching to a topological space a sequence of (homology) groups, capturing
+ global topological features like connected components, holes, cavities, etc. Persistent homology studies the
+ evolution -- birth, life and death -- of these features when the topological space is changing. Consequently, the
+ theory is essentially composed of three elements: topological spaces, their homology groups and an evolution
+ scheme.
+ Computation of persistent cohomology using the algorithm of \cite DBLP:journals/dcg/SilvaMV11 and
+ \cite DBLP:journals/corr/abs-1208-5018 and the Compressed Annotation Matrix implementation of
+ \cite DBLP:conf/esa/BoissonnatDM13 .<br>
+ <b>User manual:</b> \ref persistent_cohomology - <b>Reference manual:</b> Gudhi::persistent_cohomology::Persistent_cohomology
+ </td>
+ </tr>
+</table>
*/
/*! \page installation Gudhi installation
@@ -47,7 +160,7 @@
*
* \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.
+ * more recent. It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2015.
*
* \subsection gmp GMP:
* The multi-field persistent homology algorithm requires GMP which is a free library for arbitrary-precision
@@ -55,29 +168,114 @@
*
* 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
+ * \li <a href="_persistent_cohomology_2alpha_shapes_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_shapes_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2performance_rips_persistence_8cpp-example.html">
+ * Persistent_cohomology/performance_rips_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
+ * Persistent_cohomology/rips_multifield_persistence.cpp</a>
+ * \li <a href="_simplex_tree_2simplex_tree_from_alpha_shapes_3_8cpp-example.html">
+ * Simplex_tree/simplex_tree_from_alpha_shapes_3.cpp</a>
*
* 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
*
+ * The following examples require the <a target="_blank" href="http://www.cgal.org/">Computational Geometry Algorithms
+ * Library</a> (CGAL \cite cgal:eb-15b) and will not be built if CGAL is not installed:
+ * \li <a href="_persistent_cohomology_2alpha_complex_3d_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_persistence.cpp</a>
+ * \li <a href="_simplex_tree_2simplex_tree_from_alpha_shapes_3_8cpp-example.html">
+ * Simplex_tree/simplex_tree_from_alpha_shapes_3.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a>
+ *
+ * The following example requires CGAL version &ge; 4.6:
+ * \li <a href="_witness_complex_2witness_complex_sphere_8cpp-example.html">
+ * Witness_complex/witness_complex_sphere.cpp</a>
+ *
+ * The following example requires CGAL version &ge; 4.7:
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a>
+ * \li <a href="common_2_c_g_a_l_points_off_reader_8cpp-example.html">
+ * common/CGAL_points_off_reader.cpp</a>
+ *
+ * \subsection eigen3 Eigen3:
+ * <a target="_blank" href="http://eigen.tuxfamily.org/">Eigen3</a> is a C++ template library for linear algebra:
+ * matrices, vectors, numerical solvers, and related algorithms.
+ *
+ * The following example requires the <a target="_blank" href="http://eigen.tuxfamily.org/">Eigen3</a> and will not be
+ * built if Eigen3 is not installed:
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a> (requires also Eigen3)
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a> (requires also Eigen3)
+ * \li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_persistence.cpp</a>
+ *
+ * \subsection tbb Threading Building Blocks:
+ * <a target="_blank" href="https://www.threadingbuildingblocks.org/">Intel&reg; TBB</a> lets you easily write parallel
+ * C++ programs that take full advantage of multicore performance, that are portable and composable, and that have
+ * future-proof scalability.
+ *
+ * Having Intel&reg; TBB installed is recommended to parallelize and accelerate some GUDHI computations.
+ *
+ * The following examples are using Intel&reg; TBB if installed:
+ * \li <a href="_alpha_complex_2_alpha_complex_from_off_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_off.cpp</a>
+ * \li <a href="_alpha_complex_2_alpha_complex_from_points_8cpp-example.html">
+ * Alpha_complex/Alpha_complex_from_points.cpp</a>
+ * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_8cpp-example.html">
+ * Bitmap_cubical_complex/Bitmap_cubical_complex.cpp</a>
+ * \li <a href="_bitmap_cubical_complex_2_bitmap_cubical_complex_periodic_boundary_conditions_8cpp-example.html">
+ * Bitmap_cubical_complex/Bitmap_cubical_complex_periodic_boundary_conditions.cpp</a>
+ * \li <a href="_bitmap_cubical_complex_2_random_bitmap_cubical_complex_8cpp-example.html">
+ * Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp</a>
+ * \li <a href="_persistent_cohomology_2alpha_complex_3d_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_3d_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2alpha_complex_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_complex_persistence.cpp</a>
+ * \li <a href="_simplex_tree_2simple_simplex_tree_8cpp-example.html">
+ * Simplex_tree/simple_simplex_tree.cpp</a>
+ * \li <a href="_simplex_tree_2simplex_tree_from_alpha_shapes_3_8cpp-example.html">
+ * Simplex_tree/simplex_tree_from_alpha_shapes_3.cpp</a>
+ * \li <a href="_simplex_tree_2simplex_tree_from_cliques_of_graph_8cpp-example.html">
+ * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp</a>
+ * \li <a href="_persistent_cohomology_2alpha_shapes_persistence_8cpp-example.html">
+ * Persistent_cohomology/alpha_shapes_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2parallel_rips_persistence_8cpp-example.html">
+ * Persistent_cohomology/parallel_rips_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2performance_rips_persistence_8cpp-example.html">
+ * Persistent_cohomology/performance_rips_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2persistence_from_file_8cpp-example.html">
+ * Persistent_cohomology/persistence_from_file.cpp</a>
+ * \li <a href="_persistent_cohomology_2persistence_from_simple_simplex_tree_8cpp-example.html">
+ * Persistent_cohomology/persistence_from_simple_simplex_tree.cpp</a>
+ * \li <a href="_persistent_cohomology_2plain_homology_8cpp-example.html">
+ * Persistent_cohomology/plain_homology.cpp</a>
+ * \li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
+ * Persistent_cohomology/rips_multifield_persistence.cpp</a>
+ * \li <a href="_persistent_cohomology_2rips_persistence_8cpp-example.html">
+ * Persistent_cohomology/rips_persistence.cpp</a>
+ *
* \subsection demos Demos and examples
- * To build the demos and libraries, run the following commands in a terminal:
+ * To build the demos and examples, run the following commands in a terminal:
\verbatim cd /path-to-gudhi/
mkdir build
cd build/
cmake ..
make \endverbatim
+ * A list of examples is available <a href="examples.html">here</a>.
*
* \subsection testsuites Test suites
* To test your build, run the following command in a terminal:
@@ -91,17 +289,6 @@ make \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.
@@ -113,3 +300,33 @@ make \endverbatim
* \verbinclude biblio/how_to_cite_gudhi.bib
*/
+// List of Gudhi examples - Doxygen needs at least a file tag to analyse comments
+/*! @file Examples
+ * @example Alpha_complex/Alpha_complex_from_off.cpp
+ * @example Alpha_complex/Alpha_complex_from_points.cpp
+ * @example Bitmap_cubical_complex/Bitmap_cubical_complex.cpp
+ * @example Bitmap_cubical_complex/Bitmap_cubical_complex_periodic_boundary_conditions.cpp
+ * @example Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp
+ * @example common/CGAL_points_off_reader.cpp
+ * @example Contraction/Garland_heckbert.cpp
+ * @example Contraction/Rips_contraction.cpp
+ * @example Persistent_cohomology/alpha_complex_3d_persistence.cpp
+ * @example Persistent_cohomology/alpha_complex_persistence.cpp
+ * @example Persistent_cohomology/parallel_rips_persistence.cpp
+ * @example Persistent_cohomology/performance_rips_persistence.cpp
+ * @example Persistent_cohomology/persistence_from_file.cpp
+ * @example Persistent_cohomology/persistence_from_simple_simplex_tree.cpp
+ * @example Persistent_cohomology/plain_homology.cpp
+ * @example Persistent_cohomology/rips_multifield_persistence.cpp
+ * @example Persistent_cohomology/rips_persistence.cpp
+ * @example Simplex_tree/mini_simplex_tree.cpp
+ * @example Simplex_tree/simple_simplex_tree.cpp
+ * @example Simplex_tree/simplex_tree_from_alpha_shapes_3.cpp
+ * @example Simplex_tree/simplex_tree_from_cliques_of_graph.cpp
+ * @example Skeleton_blocker/Skeleton_blocker_from_simplices.cpp
+ * @example Skeleton_blocker/Skeleton_blocker_iteration.cpp
+ * @example Skeleton_blocker/Skeleton_blocker_link.cpp
+ * @example Witness_complex/witness_complex_from_file.cpp
+ * @example Witness_complex/witness_complex_sphere.cpp
+ */
+
diff --git a/src/common/doc/stylesheet.css b/src/common/doc/stylesheet.css
new file mode 100644
index 00000000..1df177a4
--- /dev/null
+++ b/src/common/doc/stylesheet.css
@@ -0,0 +1,1367 @@
+/* The standard CSS for doxygen 1.8.6 */
+
+body, table, div, p, dl {
+ font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+ font-size: 150%;
+}
+
+.title {
+ font: 400 14px/28px Roboto,sans-serif;
+ font-size: 150%;
+ font-weight: bold;
+ margin: 10px 2px;
+}
+
+h2.groupheader {
+ border-bottom: 1px solid #879ECB;
+ color: #354C7B;
+ font-size: 150%;
+ font-weight: normal;
+ margin-top: 1.75em;
+ padding-top: 8px;
+ padding-bottom: 4px;
+ width: 100%;
+}
+
+h3.groupheader {
+ font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ -webkit-transition: text-shadow 0.5s linear;
+ -moz-transition: text-shadow 0.5s linear;
+ -ms-transition: text-shadow 0.5s linear;
+ -o-transition: text-shadow 0.5s linear;
+ transition: text-shadow 0.5s linear;
+ margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+ text-shadow: 0 0 15px cyan;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+ margin-top: 2px;
+}
+
+p.starttd {
+ margin-top: 0px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #3D578C;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #4665A2;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #9CAFD4;
+ color: #ffffff;
+ border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+ color: #4665A2;
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+ color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+pre.fragment {
+ border: 1px solid #C4CFE5;
+ background-color: #FBFCFD;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+div.fragment {
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ background-color: #FBFCFD;
+ border: 1px solid #C4CFE5;
+}
+
+div.line {
+ font-family: monospace, fixed;
+ font-size: 13px;
+ min-height: 13px;
+ line-height: 1.0;
+ text-wrap: unrestricted;
+ white-space: -moz-pre-wrap; /* Moz */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ white-space: pre-wrap; /* CSS3 */
+ word-wrap: break-word; /* IE 5.5+ */
+ text-indent: -53px;
+ padding-left: 53px;
+ padding-bottom: 0px;
+ margin: 0px;
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+div.line.glow {
+ background-color: cyan;
+ box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+ padding-right: 4px;
+ text-align: right;
+ border-right: 2px solid #0F0;
+ background-color: #E8E8E8;
+ white-space: pre;
+}
+span.lineno a {
+ background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+ background-color: #C8C8C8;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px;
+ padding: 0.2em;
+ border: solid thin #333;
+ border-radius: 0.5em;
+ -webkit-border-radius: .5em;
+ -moz-border-radius: .5em;
+ box-shadow: 2px 2px 3px #999;
+ -webkit-box-shadow: 2px 2px 3px #999;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+ background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background-color: white;
+ color: black;
+ margin: 0;
+}
+
+div.contents {
+ margin-top: 10px;
+ margin-left: 12px;
+ margin-right: 8px;
+}
+
+td.indexkey {
+ background-color: #EBEFF6;
+ font-weight: bold;
+ border: 1px solid #C4CFE5;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+ white-space: nowrap;
+ vertical-align: top;
+}
+
+td.indexvalue {
+ background-color: #EBEFF6;
+ border: 1px solid #C4CFE5;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+address.footer {
+ text-align: right;
+ padding-right: 12px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+blockquote {
+ background-color: #F7F8FB;
+ border-left: 2px solid #9CAFD4;
+ margin: 0 24px 0 4px;
+ padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+/*
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+ background: #EBEFF6;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+ border-spacing: 0px;
+ padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+ -webkit-transition-property: background-color, box-shadow;
+ -webkit-transition-duration: 0.5s;
+ -moz-transition-property: background-color, box-shadow;
+ -moz-transition-duration: 0.5s;
+ -ms-transition-property: background-color, box-shadow;
+ -ms-transition-duration: 0.5s;
+ -o-transition-property: background-color, box-shadow;
+ -o-transition-duration: 0.5s;
+ transition-property: background-color, box-shadow;
+ transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+ background-color: cyan;
+ box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #F9FAFC;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memSeparator {
+ border-bottom: 1px solid #DEE4F0;
+ line-height: 1px;
+ margin: 0px;
+ padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memItemRight {
+ width: 100%;
+}
+
+.memTemplParams {
+ color: #4665A2;
+ white-space: nowrap;
+ font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #4665A2;
+ font-weight: normal;
+ margin-left: 9px;
+}
+
+.memnav {
+ background-color: #EBEFF6;
+ border: 1px solid #A3B4D7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.mempage {
+ width: 100%;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+ margin-right: 5px;
+ -webkit-transition: box-shadow 0.5s linear;
+ -moz-transition: box-shadow 0.5s linear;
+ -ms-transition: box-shadow 0.5s linear;
+ -o-transition: box-shadow 0.5s linear;
+ transition: box-shadow 0.5s linear;
+ display: table !important;
+ width: 100%;
+}
+
+.memitem.glow {
+ box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memname td {
+ vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+ border-top: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 0px 6px 0px;
+ color: #253555;
+ font-weight: bold;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+ /* opera specific markup */
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ /* firefox specific markup */
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-topleft: 4px;
+ /* webkit specific markup */
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+
+}
+
+.memdoc, dl.reflist dd {
+ border-bottom: 1px solid #A8B8D9;
+ border-left: 1px solid #A8B8D9;
+ border-right: 1px solid #A8B8D9;
+ padding: 6px 10px 2px 10px;
+ background-color: #FBFCFD;
+ border-top-width: 0;
+ background-image:url('nav_g.png');
+ background-repeat:repeat-x;
+ background-color: #FFFFFF;
+ /* opera specific markup */
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+ padding: 5px;
+}
+
+dl.reflist dd {
+ margin: 0px 0px 10px 0px;
+ padding: 5px;
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+.paramname code {
+ line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+.params .paramname, .retval .paramname {
+ font-weight: bold;
+ vertical-align: top;
+}
+
+.params .paramtype {
+ font-style: italic;
+ vertical-align: top;
+}
+
+.params .paramdir {
+ font-family: "courier new",courier,monospace;
+ vertical-align: top;
+}
+
+table.mlabels {
+ border-spacing: 0px;
+}
+
+td.mlabels-left {
+ width: 100%;
+ padding: 0px;
+}
+
+td.mlabels-right {
+ vertical-align: bottom;
+ padding: 0px;
+ white-space: nowrap;
+}
+
+span.mlabels {
+ margin-left: 8px;
+}
+
+span.mlabel {
+ background-color: #728DC1;
+ border-top:1px solid #5373B4;
+ border-left:1px solid #5373B4;
+ border-right:1px solid #C4CFE5;
+ border-bottom:1px solid #C4CFE5;
+ text-shadow: none;
+ color: white;
+ margin-right: 4px;
+ padding: 2px 3px;
+ border-radius: 3px;
+ font-size: 7pt;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view when not used as main index */
+
+div.directory {
+ margin: 10px 0px;
+ border-top: 1px solid #A8B8D9;
+ border-bottom: 1px solid #A8B8D9;
+ width: 100%;
+}
+
+.directory table {
+ border-collapse:collapse;
+}
+
+.directory td {
+ margin: 0px;
+ padding: 0px;
+ vertical-align: top;
+}
+
+.directory td.entry {
+ white-space: nowrap;
+ padding-right: 6px;
+ padding-top: 3px;
+}
+
+.directory td.entry a {
+ outline:none;
+}
+
+.directory td.entry a img {
+ border: none;
+}
+
+.directory td.desc {
+ width: 100%;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 3px;
+ border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+ padding-left: 6px;
+ background-color: #F7F8FB;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+.directory .levels {
+ white-space: nowrap;
+ width: 100%;
+ text-align: right;
+ font-size: 9pt;
+}
+
+.directory .levels span {
+ cursor: pointer;
+ padding-left: 2px;
+ padding-right: 2px;
+ color: #3D578C;
+}
+
+div.dynheader {
+ margin-top: 8px;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+address {
+ font-style: normal;
+ color: #2A3D61;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #2D4068;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #374F7F;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+}
+
+table.fieldtable {
+ /*width: 100%;*/
+ margin-bottom: 10px;
+ border: 1px solid #A8B8D9;
+ border-spacing: 0px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+ -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+ padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+ white-space: nowrap;
+ border-right: 1px solid #A8B8D9;
+ border-bottom: 1px solid #A8B8D9;
+ vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+ padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+ border-bottom: 1px solid #A8B8D9;
+ /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+ margin-top: 0px;
+}
+
+.fieldtable td.fielddoc p:last-child {
+ margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+ border-bottom: none;
+}
+
+.fieldtable th {
+ background-image:url('nav_f.png');
+ background-repeat:repeat-x;
+ background-color: #E2E8F2;
+ font-size: 90%;
+ color: #253555;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-topright: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+ top: 0px;
+ left: 10px;
+ height: 36px;
+ background-image: url('tab_b.png');
+ z-index: 101;
+ overflow: hidden;
+ font-size: 13px;
+}
+
+.navpath ul
+{
+ font-size: 11px;
+ background-image:url('tab_b.png');
+ background-repeat:repeat-x;
+ background-position: 0 -5px;
+ height:30px;
+ line-height:30px;
+ color:#8AA0CC;
+ border:solid 1px #C2CDE4;
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+}
+
+.navpath li
+{
+ list-style-type:none;
+ float:left;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:url('bc_s.png');
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+ height:32px;
+ display:block;
+ text-decoration: none;
+ outline: none;
+ color: #283A5D;
+ font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+ text-decoration: none;
+}
+
+.navpath li.navelem a:hover
+{
+ color:#6884BD;
+}
+
+.navpath li.footer
+{
+ list-style-type:none;
+ float:right;
+ padding-left:10px;
+ padding-right:15px;
+ background-image:none;
+ background-repeat:no-repeat;
+ background-position:right;
+ color:#364D7C;
+ font-size: 8pt;
+}
+
+
+div.summary
+{
+ float: right;
+ font-size: 8pt;
+ padding-right: 5px;
+ width: 50%;
+ text-align: right;
+}
+
+div.summary a
+{
+ white-space: nowrap;
+}
+
+div.ingroups
+{
+ font-size: 8pt;
+ width: 50%;
+ text-align: left;
+}
+
+div.ingroups a
+{
+ white-space: nowrap;
+}
+
+div.header
+{
+ background-image:url('nav_h.png');
+ background-repeat:repeat-x;
+ background-color: #F9FAFC;
+ margin: 0px;
+ border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+ padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+ padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+ margin-left: 0px;
+ padding-left: 0px;
+}
+
+dl.note
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00D000;
+}
+
+dl.deprecated
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #505050;
+}
+
+dl.todo
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug
+{
+ margin-left:-7px;
+ padding-left: 3px;
+ border-left:4px solid;
+ border-color: #C08050;
+}
+
+dl.section dd {
+ margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+ text-align: center;
+ vertical-align: bottom;
+ border-collapse: separate;
+}
+
+#projectlogo img
+{
+ border: 0px none;
+}
+
+#projectname
+{
+ border: 0px none;
+ font: 300% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 2px 0px;
+}
+
+#projectbrief
+{
+ font: 60% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#projectnumber
+{
+ font: 80% Tahoma, Arial,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+
+#titlearea
+{
+ padding: 0px;
+ margin: 0px;
+ width: 100%;
+ border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+ text-align: center;
+}
+
+.dotgraph
+{
+ text-align: center;
+}
+
+.mscgraph
+{
+ text-align: center;
+}
+
+.diagraph
+{
+ text-align: center;
+}
+
+.caption
+{
+ font-weight: bold;
+}
+
+div.zoom
+{
+ border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+ margin-bottom:50px;
+}
+
+dl.citelist dt {
+ color:#334975;
+ float:left;
+ font-weight:bold;
+ margin-right:10px;
+ padding:5px;
+}
+
+dl.citelist dd {
+ margin:2px 0;
+ padding:5px 0;
+}
+
+div.toc {
+ padding: 14px 25px;
+ background-color: #F4F6FA;
+ border: 1px solid #D8DFEE;
+ border-radius: 7px 7px 7px 7px;
+ float: right;
+ height: auto;
+ margin: 0 20px 10px 10px;
+ width: 200px;
+}
+
+div.toc li {
+ background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+ font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+ margin-top: 5px;
+ padding-left: 10px;
+ padding-top: 2px;
+}
+
+div.toc h3 {
+ font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+ color: #4665A2;
+ border-bottom: 0 none;
+ margin: 0;
+}
+
+div.toc ul {
+ list-style: none outside none;
+ border: medium none;
+ padding: 0px;
+}
+
+div.toc li.level1 {
+ margin-left: 0px;
+}
+
+div.toc li.level2 {
+ margin-left: 15px;
+}
+
+div.toc li.level3 {
+ margin-left: 30px;
+}
+
+div.toc li.level4 {
+ margin-left: 45px;
+}
+
+.inherit_header {
+ font-weight: bold;
+ color: gray;
+ cursor: pointer;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.inherit_header td {
+ padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+ display: none;
+}
+
+tr.heading h2 {
+ margin-top: 12px;
+ margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+ position: absolute;
+ display: none;
+}
+
+#powerTip {
+ cursor: default;
+ white-space: nowrap;
+ background-color: white;
+ border: 1px solid gray;
+ border-radius: 4px 4px 4px 4px;
+ box-shadow: 1px 1px 7px gray;
+ display: none;
+ font-size: smaller;
+ max-width: 80%;
+ opacity: 0.9;
+ padding: 1ex 1em 1em;
+ position: absolute;
+ z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+ color: grey;
+ font-style: italic;
+}
+
+#powerTip div.ttname a {
+ font-weight: bold;
+}
+
+#powerTip div.ttname {
+ font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+ color: #006318;
+}
+
+#powerTip div {
+ margin: 0px;
+ padding: 0px;
+ font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+ content: "";
+ position: absolute;
+ margin: 0px;
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.w:after, #powerTip.w:before,
+#powerTip.e:after, #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+}
+
+#powerTip.n:after, #powerTip.s:after,
+#powerTip.w:after, #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+ border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before, #powerTip.s:before,
+#powerTip.w:before, #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+ border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after, #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+ top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+ border-top-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+#powerTip.n:before {
+ border-top-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+ left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+ right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+ left: 14px;
+}
+
+#powerTip.s:after, #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+ bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+ border-bottom-color: #ffffff;
+ border-width: 10px;
+ margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+ border-bottom-color: #808080;
+ border-width: 11px;
+ margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+ left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+ right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+ left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+ left: 100%;
+}
+#powerTip.e:after {
+ border-left-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.e:before {
+ border-left-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+ right: 100%;
+}
+#powerTip.w:after {
+ border-right-color: #ffffff;
+ border-width: 10px;
+ top: 50%;
+ margin-top: -10px;
+}
+#powerTip.w:before {
+ border-right-color: #808080;
+ border-width: 11px;
+ top: 50%;
+ margin-top: -11px;
+}
+
+@media print
+{
+ #top { display: none; }
+ #side-nav { display: none; }
+ #nav-path { display: none; }
+ body { overflow:visible; }
+ h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+ .summary { display: none; }
+ .memitem { page-break-inside: avoid; }
+ #doc-content
+ {
+ margin-left:0 !important;
+ height:auto !important;
+ width:auto !important;
+ overflow:inherit;
+ display:inline;
+ }
+}
+
diff --git a/src/common/example/CGAL_points_off_reader.cpp b/src/common/example/CGAL_points_off_reader.cpp
new file mode 100644
index 00000000..45e9f1e6
--- /dev/null
+++ b/src/common/example/CGAL_points_off_reader.cpp
@@ -0,0 +1,44 @@
+#include <gudhi/Points_off_io.h>
+
+// For CGAL points type in dimension d
+// cf. http://doc.cgal.org/latest/Kernel_d/classCGAL_1_1Point__d.html
+#include <CGAL/Epick_d.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
+typedef typename Kernel::Point_d Point_d;
+
+void usage(int argc, char * const progName) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
+ std::cerr << "Usage: " << progName << " inputFile.off" << std::endl;
+ exit(-1);
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) usage(argc, (argv[0] - 1));
+
+ std::string offInputFile(argv[1]);
+ // Read the OFF file (input file name given as parameter) and triangulate points
+ Gudhi::Points_off_reader<Point_d> off_reader(offInputFile);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ exit(-1);
+ }
+
+ // Retrieve the triangulation
+ std::vector<Point_d> point_cloud = off_reader.get_point_cloud();
+
+ int n = 0;
+ for (auto point : point_cloud) {
+ std::cout << "Point[" << n << "] = ";
+ for (int i = 0; i < point.dimension(); i++)
+ std::cout << point[i] << " ";
+ std::cout << "\n";
+ ++n;
+ }
+ return 0;
+}
diff --git a/src/common/example/CMakeLists.txt b/src/common/example/CMakeLists.txt
new file mode 100644
index 00000000..5aeaa8c6
--- /dev/null
+++ b/src/common/example/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 2.6)
+project(GUDHIDelaunayTriangulationOffFileReadWrite)
+
+# need CGAL 4.7
+if(CGAL_FOUND)
+ if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ find_package(Eigen3 3.1.0)
+ if (EIGEN3_FOUND)
+ message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
+ include( ${EIGEN3_USE_FILE} )
+
+ add_executable ( cgaloffreader CGAL_points_off_reader.cpp )
+ target_link_libraries(cgaloffreader ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ add_test(cgaloffreader ${CMAKE_CURRENT_BINARY_DIR}/cgaloffreader ${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off)
+
+ 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/common/example/cgaloffreader_result.txt b/src/common/example/cgaloffreader_result.txt
new file mode 100644
index 00000000..1deb8dbd
--- /dev/null
+++ b/src/common/example/cgaloffreader_result.txt
@@ -0,0 +1,7 @@
+Point[0] = 1 1
+Point[1] = 7 0
+Point[2] = 4 6
+Point[3] = 9 6
+Point[4] = 0 14
+Point[5] = 2 19
+Point[6] = 9 17
diff --git a/src/common/include/gudhi/Utils.h b/src/common/include/gudhi/Debug_utils.h
index 43916f11..7573a9db 100644
--- a/src/common/include/gudhi/Utils.h
+++ b/src/common/include/gudhi/Debug_utils.h
@@ -19,28 +19,37 @@
* 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_
+#ifndef DEBUG_UTILS_H_
+#define DEBUG_UTILS_H_
+#include <iostream>
+
+#ifndef NDEBUG
+ // GUDHI_DEBUG is the Gudhi official flag for debug mode.
+ #define GUDHI_DEBUG
+#endif
+
+// GUDHI_CHECK throw an exception if expression is false in debug mode, but does nothing in release mode
+// Could assert in release mode, but cmake sets NDEBUG (for "NO DEBUG") in this mode, means assert does nothing.
+#ifdef GUDHI_DEBUG
+ #define GUDHI_CHECK(expression, excpt) if ((expression) == 0) throw excpt
+#else
+ #define GUDHI_CHECK(expression, excpt) (void) 0
+#endif
#define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)" << std::endl
// #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::cout << "DBG: " << (a) << std::endl
+ #define DBGMSG(a, b) std::cout << "DBG: " << a << b << std::endl
+ #define DBGVALUE(a) std::cout << "DBG: " << #a << ": " << a << std::endl
+ #define DBGCONT(a) std::cout << "DBG: container " << #a << " -> "; for (auto x : a) std::cout << x << ","; std::cout << std::endl
#else
-// #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 DBGVALUE(a)
-#define DBGCONT(a)
+ #define DBG(a) (void) 0
+ #define DBGMSG(a, b) (void) 0
+ #define DBGVALUE(a) (void) 0
+ #define DBGCONT(a) (void) 0
#endif
-#endif // UTILS_H_
+#endif // DEBUG_UTILS_H_
diff --git a/src/common/include/gudhi/Off_reader.h b/src/common/include/gudhi/Off_reader.h
index 81b9e634..4fcd2af2 100644
--- a/src/common/include/gudhi/Off_reader.h
+++ b/src/common/include/gudhi/Off_reader.h
@@ -31,40 +31,35 @@
#include <iterator>
#include <string>
#include <vector>
+#include <fstream>
namespace Gudhi {
-/**
- * Read an off file and calls a visitor methods while reading it.
- * An off file must have its first/snd line in this format :
- * OFF
- * num_vert num_faces num_edges
- *
- * A noff file must have its first/snd line in this format :
- * nOFF
- * dim num_vert num_faces num_edges
- *
- * The number of edges num_edges is optional and can be left to zero.
+/** \brief OFF file reader top class visitor.
+ *
+ * OFF file must be conform to format described here :
+ * http://www.geomview.org/docs/html/OFF.html
*/
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.
+ /** \brief
+ * Read an OFF file and calls the following methods :
+ *
+ * <CODE>void init(int dim,int num_vertices,int num_faces,int num_edges); // from file header - num_edges may not be set
+ *
+ * void point(const std::vector<double>& point); // for each point read
+ *
+ * void maximal_face(const std::list<int>& face); // for each face read
+ *
+ * void done(); // upon file read is finished</CODE>
+ *
+ * of the visitor when reading a point or a maximal face. Edges are not taken into account.
*/
template<typename OffVisitor>
bool read(OffVisitor& off_visitor) {
@@ -118,7 +113,7 @@ class Off_reader {
if (!goto_next_uncomment_line(line)) return false;
std::istringstream iss(line);
- if (is_off_file) {
+ if ((is_off_file) && (!is_noff_file)) {
off_info_.dim = 3;
if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) {
std::cerr << "incorrect number of vertices/faces/edges\n";
@@ -126,8 +121,8 @@ class Off_reader {
}
} 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;
+ 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);
@@ -138,7 +133,7 @@ class Off_reader {
bool goto_next_uncomment_line(std::string& uncomment_line) {
uncomment_line.clear();
do
- std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%'); // || uncomment_line.empty());
+ std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%');
return (uncomment_line.size() > 0 && uncomment_line[0] != '%');
}
@@ -166,7 +161,7 @@ class Off_reader {
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;
+ // if (face.size() != (off_info_.dim + 1)) return false;
visitor.maximal_face(face);
}
return true;
diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h
new file mode 100644
index 00000000..77f36be2
--- /dev/null
+++ b/src/common/include/gudhi/Points_off_io.h
@@ -0,0 +1,177 @@
+/* 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 POINTS_OFF_IO_H_
+#define POINTS_OFF_IO_H_
+
+#include <gudhi/Off_reader.h>
+
+#include <string>
+#include <vector>
+#include <fstream>
+#include <map>
+
+namespace Gudhi {
+
+/**
+ * \brief OFF file visitor implementation according to Off_reader in order to read points from an OFF file.
+ */
+template<typename Point_d>
+class Points_off_visitor_reader {
+ private:
+ std::vector<Point_d> point_cloud;
+
+ public:
+ /** \brief Off_reader visitor init implementation.
+ *
+ * The init parameters are set from OFF file header.
+ * Dimension value is required in order to construct Alpha complex.
+ *
+ * @param[in] dim space dimension of vertices.
+ * @param[in] num_vertices number of vertices in the OFF file (not used).
+ * @param[in] num_faces number of faces in the OFF file (not used).
+ * @param[in] num_edges number of edges in the OFF file (not used).
+ */
+ void init(int dim, int num_vertices, int num_faces, int num_edges) {
+#ifdef DEBUG_TRACES
+ std::cout << "Points_off_visitor_reader::init - dim=" << dim << " - num_vertices=" <<
+ num_vertices << " - num_faces=" << num_faces << " - num_edges=" << num_edges << std::endl;
+#endif // DEBUG_TRACES
+ if (num_faces > 0) {
+ std::cerr << "Points_off_visitor_reader::init faces are not taken into account from OFF file for Points.\n";
+ }
+ if (num_edges > 0) {
+ std::cerr << "Points_off_visitor_reader::init edges are not taken into account from OFF file for Points.\n";
+ }
+ }
+
+ /** \brief Off_reader visitor point implementation.
+ *
+ * The point function is called on each vertex line from OFF file.
+ * This function inserts the vertex in the Alpha complex.
+ *
+ * @param[in] point vector of vertex coordinates.
+ */
+ void point(const std::vector<double>& point) {
+#ifdef DEBUG_TRACES
+ std::cout << "Points_off_visitor_reader::point ";
+ for (auto coordinate : point) {
+ std::cout << coordinate << " | ";
+ }
+ std::cout << std::endl;
+#endif // DEBUG_TRACES
+ // Fill the point cloud
+ point_cloud.push_back(Point_d(point.size(), point.begin(), point.end()));
+ }
+
+ // Off_reader visitor maximal_face implementation - Only points are read
+ void maximal_face(const std::vector<int>& face) { }
+
+ // Off_reader visitor done implementation - Only points are read
+ void done() { }
+
+ /** \brief Point cloud getter.
+ *
+ * @return point_cloud.
+ */
+ const std::vector<Point_d>& get_point_cloud() const {
+ return point_cloud;
+ }
+};
+
+/**
+ * \brief OFF file reader implementation in order to read points from an OFF file.
+ *
+ * This class is using the Points_off_visitor_reader to visit the OFF file according to Off_reader.
+ *
+ * Point_d must have a constructor with the following form:
+ *
+ * \code template<class InputIterator > Point_d::Point_d(int d, InputIterator first, InputIterator last) \endcode
+ *
+ * where d is the point dimension.
+ *
+ * \section Example
+ *
+ * This example loads points from an OFF file and builds a vector of CGAL points in dimension d.
+ * Then, it is asked to display the points.
+ *
+ * \include common/CGAL_points_off_reader.cpp
+ *
+ * When launching:
+ *
+ * \code $> ./cgaloffreader ../../data/points/alphacomplexdoc.off
+ * \endcode
+ *
+ * the program output is:
+ *
+ * \include common/cgaloffreader_result.txt
+ */
+template<typename Point_d>
+class Points_off_reader {
+ public:
+ /** \brief Reads the OFF file and constructs the Alpha complex from the points
+ * that are in the OFF file.
+ *
+ * @param[in] name_file OFF file to read.
+ *
+ * \post Check with is_valid() function to see if read operation was successful.
+ */
+ Points_off_reader(const std::string& name_file)
+ : valid_(false) {
+ std::ifstream stream(name_file);
+ if (stream.is_open()) {
+ Off_reader off_reader(stream);
+ Points_off_visitor_reader<Point_d> off_visitor;
+ valid_ = off_reader.read(off_visitor);
+ if (valid_) {
+ point_cloud = off_visitor.get_point_cloud();
+ }
+ } else {
+ std::cerr << "Points_off_reader::Points_off_reader could not open file " << name_file << "\n";
+ }
+ }
+
+ /** \brief Returns if the OFF file read operation was successful or not.
+ *
+ * @return OFF file read status.
+ */
+ bool is_valid() const {
+ return valid_;
+ }
+
+ /** \brief Point cloud getter.
+ *
+ * @return point_cloud.
+ */
+ const std::vector<Point_d>& get_point_cloud() const {
+ return point_cloud;
+ }
+
+ private:
+ /** \brief point_cloud.*/
+ std::vector<Point_d> point_cloud;
+ /** \brief OFF file read status.*/
+ bool valid_;
+};
+
+} // namespace Gudhi
+
+#endif // POINTS_OFF_IO_H_
diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h
index e5c79ded..cd518581 100644
--- a/src/common/include/gudhi/distance_functions.h
+++ b/src/common/include/gudhi/distance_functions.h
@@ -23,6 +23,8 @@
#ifndef DISTANCE_FUNCTIONS_H_
#define DISTANCE_FUNCTIONS_H_
+#include <cmath> // for std::sqrt
+
/* Compute the Euclidean distance between two Points given
* by a range of coordinates. The points are assumed to have
* the same dimension. */
@@ -35,7 +37,7 @@ double euclidean_distance(Point &p1, Point &p2) {
double tmp = *it1 - *it2;
dist += tmp*tmp;
}
- return sqrt(dist);
+ return std::sqrt(dist);
}
#endif // DISTANCE_FUNCTIONS_H_
diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h
index e05714c7..899f9df6 100644
--- a/src/common/include/gudhi/reader_utils.h
+++ b/src/common/include/gudhi/reader_utils.h
@@ -58,7 +58,9 @@ inline void read_points(std::string file_name, std::vector< std::vector< double
while (iss >> x) {
point.push_back(x);
}
- points.push_back(point);
+ // Check for empty lines
+ if (!point.empty())
+ points.push_back(point);
}
in_file.close();
}
@@ -159,7 +161,7 @@ bool read_simplex(std::istream & in_, std::vector< Vertex_handle > & simplex, Fi
simplex.push_back(v);
}
in_ >> fil;
- in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return
+ in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return
return true;
}
diff --git a/src/common/test/CMakeLists.txt b/src/common/test/CMakeLists.txt
new file mode 100644
index 00000000..789546ae
--- /dev/null
+++ b/src/common/test/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required(VERSION 2.6)
+project(GUDHIDelaunayTriangulationOffFileReadWriteUT)
+
+if (GCOVR_PATH)
+ # for gcovr to make coverage reports - Corbera Jenkins plugin
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
+endif()
+if (GPROF_PATH)
+ # for gprof to make coverage reports - Jenkins
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
+endif()
+
+# need CGAL 4.7
+if(CGAL_FOUND)
+ if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ find_package(Eigen3 3.1.0)
+ if (EIGEN3_FOUND)
+ message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
+ include( ${EIGEN3_USE_FILE} )
+
+ add_executable ( poffreader_UT points_off_reader_unit_test.cpp )
+ target_link_libraries(poffreader_UT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+
+ # Do not forget to copy test files in current binary dir
+ file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+ # Unitary tests
+ add_test(poffreader_UT ${CMAKE_CURRENT_BINARY_DIR}/poffreader_UT
+ # XML format for Jenkins xUnit plugin
+ --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/poffreader_UT.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/common/test/README b/src/common/test/README
new file mode 100644
index 00000000..f2a7eb5a
--- /dev/null
+++ b/src/common/test/README
@@ -0,0 +1,14 @@
+To compile:
+***********
+
+cmake .
+make
+
+To launch with details:
+***********************
+
+./dtoffrw_UT --report_level=detailed --log_level=all
+
+ ==> echo $? returns 0 in case of success (non-zero otherwise)
+
+
diff --git a/src/common/test/dtoffrw_alphashapedoc_result.off b/src/common/test/dtoffrw_alphashapedoc_result.off
new file mode 100644
index 00000000..1deb8dbd
--- /dev/null
+++ b/src/common/test/dtoffrw_alphashapedoc_result.off
@@ -0,0 +1,7 @@
+Point[0] = 1 1
+Point[1] = 7 0
+Point[2] = 4 6
+Point[3] = 9 6
+Point[4] = 0 14
+Point[5] = 2 19
+Point[6] = 9 17
diff --git a/src/common/test/points_off_reader_unit_test.cpp b/src/common/test/points_off_reader_unit_test.cpp
new file mode 100644
index 00000000..73e19cbc
--- /dev/null
+++ b/src/common/test/points_off_reader_unit_test.cpp
@@ -0,0 +1,78 @@
+/* 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/>.
+ */
+
+#include <gudhi/Points_off_io.h>
+
+// For CGAL points type in dimension d
+// cf. http://doc.cgal.org/latest/Kernel_d/classCGAL_1_1Point__d.html
+#include <CGAL/Epick_d.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "points_off_read_write"
+#include <boost/test/unit_test.hpp>
+
+typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
+typedef typename Kernel::Point_d Point_d;
+
+BOOST_AUTO_TEST_CASE( points_doc_test )
+{
+ // Read the OFF file (input file name given as parameter) and triangulates points
+ Gudhi::Points_off_reader<Point_d> off_reader("alphacomplexdoc.off");
+ // Check the read operation was correct
+ BOOST_CHECK(off_reader.is_valid());
+
+ // Retrieve the triangulation
+ std::vector<Point_d> point_cloud = off_reader.get_point_cloud();
+ BOOST_CHECK(point_cloud.size() == 7);
+
+ std::vector<Point_d> expected_points;
+ std::vector<double> point = {1.0, 1.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+ point = {7.0, 0.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+ point = {4.0, 6.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+ point = {9.0, 6.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+ point = {0.0, 14.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+ point = {2.0, 19.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+ point = {9.0, 17.0};
+ expected_points.push_back(Point_d(2, point.begin(), point.end()));
+
+ BOOST_CHECK(point_cloud == expected_points);
+}
+
+BOOST_AUTO_TEST_CASE( Delaunay_triangulation_unexisting_file_read_test )
+{
+ Gudhi::Points_off_reader<Point_d> off_reader("some_impossible_weird_file_name.off");
+ // Check the read operation was correct
+ BOOST_CHECK(!off_reader.is_valid());
+
+ std::vector<Point_d> point_cloud = off_reader.get_point_cloud();
+ BOOST_CHECK(point_cloud.size() == 0);
+}