summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-04-14 12:49:09 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-04-14 12:49:09 +0000
commit437ccdf9616d91534af91cd8a0090b6f32d6e65b (patch)
tree39177c3c8a1ce2f74af6aa9434cd92afcf6854af /src
parent8bcb704e4772e9dda428d4de27a30e74eca7ff6a (diff)
Add of src/common/include/gudhi/Points_3D_off_io.h to read specific 3D OFF Files for CGAL Point_3
Add an example to read 3D OFF Files for CGAL Point_3 Modify alpha_complex_3d_persistence.cpp to read OFF files Add periodic_alpha_complex_3d_persistence.cpp in Persistent_cohomology examples Add info about new examples in README git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/periodic_alpha_complex_3d@1116 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6b423b598869a0f4f9c62d93c93b69efd93c0161
Diffstat (limited to 'src')
-rw-r--r--src/Persistent_cohomology/example/CMakeLists.txt8
-rw-r--r--src/Persistent_cohomology/example/README98
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp24
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_persistence.cpp2
-rw-r--r--src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp303
-rw-r--r--src/common/example/CGAL_3D_points_off_reader.cpp41
-rw-r--r--src/common/example/CGAL_points_off_reader.cpp18
-rw-r--r--src/common/example/CMakeLists.txt4
-rw-r--r--src/common/include/gudhi/Points_3D_off_io.h206
-rw-r--r--src/common/include/gudhi/Points_off_io.h15
10 files changed, 686 insertions, 33 deletions
diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt
index 2f94ed15..ee6ba541 100644
--- a/src/Persistent_cohomology/example/CMakeLists.txt
+++ b/src/Persistent_cohomology/example/CMakeLists.txt
@@ -53,8 +53,14 @@ if(GMPXX_FOUND AND GMP_FOUND)
if(CGAL_FOUND)
add_executable(alpha_complex_3d_persistence alpha_complex_3d_persistence.cpp)
target_link_libraries(alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
+
+ add_executable(periodic_alpha_complex_3d_persistence periodic_alpha_complex_3d_persistence.cpp)
+ target_link_libraries(periodic_alpha_complex_3d_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
+ add_test(periodic_alpha_complex_3d_persistence_2_0 ${CMAKE_CURRENT_BINARY_DIR}/alpha_complex_3d_persistence ${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off 2 0)
+
if (TBB_FOUND)
target_link_libraries(alpha_complex_3d_persistence ${TBB_RELEASE_LIBRARY})
+ target_link_libraries(periodic_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)
@@ -65,7 +71,7 @@ if(GMPXX_FOUND AND GMP_FOUND)
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)
diff --git a/src/Persistent_cohomology/example/README b/src/Persistent_cohomology/example/README
index 8c71ccf5..92b80c76 100644
--- a/src/Persistent_cohomology/example/README
+++ b/src/Persistent_cohomology/example/README
@@ -4,13 +4,13 @@ cd /path-to-example/
cmake .
make
-
-Example of use :
+***********************************************************************************************************************
+Example of use of RIPS:
Computation of the persistent homology with Z/2Z coefficients of the Rips complex on points
sampling a Klein bottle:
-./rips_persistence ../../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -m 100
+./rips_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -m 100
output:
210 0 0 inf
@@ -29,7 +29,7 @@ where
with Z/3Z coefficients:
-./rips_persistence ../../../data/points/Kl.txt -r 0.25 -d 3 -p 3 -m 100
+./rips_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 3 -m 100
output:
3 0 0 inf
@@ -37,7 +37,7 @@ output:
and the computation with Z/2Z and Z/3Z coefficients simultaneously:
-./rips_multifield_persistence ../../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 3 -m 100
+./rips_multifield_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 3 -m 100
output:
6 0 0 inf
@@ -47,10 +47,96 @@ output:
and finally the computation with all Z/pZ for 2 <= p <= 71 (20 first prime numbers):
- ./rips_multifield_persistence ../../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100
+ ./rips_multifield_persistence ../../data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100
output:
557940830126698960967415390 0 0 inf
557940830126698960967415390 1 0.0702103 inf
2 1 0.0702103 inf
2 2 0.159992 inf
+
+***********************************************************************************************************************
+Example of use of ALPHA:
+
+For a more verbose mode, please run cmake with option "DEBUG_TRACES=TRUE" and recompile the programs.
+
+1) 3D special case
+------------------
+Computation of the persistent homology with Z/2Z coefficients of the alpha complex on points
+sampling a torus 3D:
+
+./alpha_complex_3d_persistence ../../data/points/tore3D_300.off 2 0.45
+
+output:
+Simplex_tree dim: 3
+2 0 0 inf
+2 1 0.0682162 1.0001
+2 1 0.0934117 1.00003
+2 2 0.56444 1.03938
+
+Here we retrieve expected Betti numbers on a tore 3D:
+Betti numbers[0] = 1
+Betti numbers[1] = 2
+Betti numbers[2] = 1
+
+N.B.: alpha_complex_3d_persistence accepts only OFF files in 3D dimension.
+
+2) d-Dimension case
+-------------------
+Computation of the persistent homology with Z/2Z coefficients of the alpha complex on points
+sampling a torus 3D:
+
+./alpha_complex_persistence -r 32 -p 2 -m 0.45 ../../data/points/tore3D_300.off
+
+output:
+Alpha complex is of dimension 3 - 9273 simplices - 300 vertices.
+Simplex_tree dim: 3
+2 0 0 inf
+2 1 0.0682162 1.0001
+2 1 0.0934117 1.00003
+2 2 0.56444 1.03938
+
+Here we retrieve expected Betti numbers on a tore 3D:
+Betti numbers[0] = 1
+Betti numbers[1] = 2
+Betti numbers[2] = 1
+
+N.B.: alpha_complex_persistence accepts OFF files in d-Dimension.
+
+3) 3D periodic special case
+---------------------------
+./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off 2 0.0
+
+output:
+Periodic Delaunay computed.
+Simplex_tree dim: 3
+2 0 0.0866025 inf
+2 1 0.0866025 inf
+2 1 0.0866025 inf
+2 1 0.0866025 inf
+2 2 0.0866025 inf
+2 2 0.0866025 inf
+2 2 0.0866025 inf
+
+N.B.: periodic_alpha_complex_3d_persistence accepts only OFF files in 3D dimension. In this example, the periodic cube
+is hard coded to { x = [0,1]; y = [0,1]; z = [0,1] }
+
+***********************************************************************************************************************
+Example of use of PLAIN HOMOLOGY:
+
+This example computes the plain homology of the following simplicial complex without filtration values:
+ /* Complex to build. */
+ /* 1 3 */
+ /* o---o */
+ /* /X\ / */
+ /* o---o o */
+ /* 2 0 4 */
+
+./plain_homology
+
+output:
+2 0 0 inf
+2 0 0 inf
+2 1 0 inf
+
+Here we retrieve the 2 entities {0,1,2,3} and {4} (Betti numbers[0] = 2) and the hole in {0,1,3} (Betti numbers[1] = 1) \ No newline at end of file
diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
index 01497c7c..48fbb91a 100644
--- a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp
@@ -20,9 +20,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gudhi/graph_simplicial_complex.h>
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Points_3D_off_io.h>
#include <boost/variant.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
@@ -139,20 +139,18 @@ int main(int argc, char * const argv[]) {
}
// Read points from file
- std::string filegraph = argv[1];
- std::list<Point_3> lp;
- std::ifstream is(filegraph.c_str());
- int n;
- is >> n;
-#ifdef DEBUG_TRACES
- std::cout << "Reading " << n << " points " << std::endl;
-#endif // DEBUG_TRACES
- Point_3 p;
- for (; n > 0; n--) {
- is >> p;
- lp.push_back(p);
+ std::string offInputFile(argv[1]);
+ // Read the OFF file (input file name given as parameter) and triangulate points
+ Gudhi::Points_3D_off_reader<Point_3> off_reader(offInputFile);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ usage(argv[0]);
}
+ // Retrieve the triangulation
+ std::vector<Point_3> lp = off_reader.get_point_cloud();
+
// alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode.
Alpha_shape_3 as(lp.begin(), lp.end(), 0, Alpha_shape_3::GENERAL);
#ifdef DEBUG_TRACES
diff --git a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
index 8f9f077c..17fb84d2 100644
--- a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
@@ -29,7 +29,7 @@ int main(int argc, char **argv) {
// ----------------------------------------------------------------------------
// Init of an alpha complex from an OFF file
// ----------------------------------------------------------------------------
- typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
+ using Kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >;
Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_points, alpha_square_max_value);
// ----------------------------------------------------------------------------
diff --git a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp
new file mode 100644
index 00000000..e9425066
--- /dev/null
+++ b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp
@@ -0,0 +1,303 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2014 INRIA Saclay (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Persistent_cohomology.h>
+#include <gudhi/Points_3D_off_io.h>
+#include <boost/variant.hpp>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Periodic_3_Delaunay_triangulation_traits_3.h>
+#include <CGAL/Periodic_3_Delaunay_triangulation_3.h>
+#include <CGAL/Alpha_shape_3.h>
+#include <CGAL/iterator.h>
+
+#include <fstream>
+#include <cmath>
+#include <string>
+#include <tuple>
+#include <map>
+#include <utility>
+#include <list>
+#include <vector>
+
+// Traits
+using K = CGAL::Exact_predicates_inexact_constructions_kernel;
+using PK = CGAL::Periodic_3_Delaunay_triangulation_traits_3<K>;
+// Vertex type
+using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>;
+using Vb = CGAL::Triangulation_vertex_base_3<PK,DsVb>;
+using AsVb = CGAL::Alpha_shape_vertex_base_3<PK,Vb>;
+// Cell type
+using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>;
+using Cb = CGAL::Triangulation_cell_base_3<PK,DsCb>;
+using AsCb = CGAL::Alpha_shape_cell_base_3<PK,Cb>;
+using Tds = CGAL::Triangulation_data_structure_3<AsVb,AsCb>;
+using P3DT3 = CGAL::Periodic_3_Delaunay_triangulation_3<PK,Tds>;
+using Alpha_shape_3 = CGAL::Alpha_shape_3<P3DT3>;
+using Point_3 = PK::Point_3;
+
+// filtration with alpha values needed type definition
+using Alpha_value_type = Alpha_shape_3::FT;
+using Object = CGAL::Object;
+using Dispatch = CGAL::Dispatch_output_iterator<
+ CGAL::cpp11::tuple<Object, Alpha_value_type>,
+ CGAL::cpp11::tuple<std::back_insert_iterator< std::vector<Object> >,
+ std::back_insert_iterator< std::vector<Alpha_value_type> > > >;
+using Cell_handle = Alpha_shape_3::Cell_handle;
+using Facet = Alpha_shape_3::Facet;
+using Edge_3 = Alpha_shape_3::Edge;
+using Vertex_list = std::list<Alpha_shape_3::Vertex_handle>;
+
+// gudhi type definition
+using ST = Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_persistence>;
+using Simplex_tree_vertex = ST::Vertex_handle;
+using Alpha_shape_simplex_tree_map = std::map<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex >;
+using Alpha_shape_simplex_tree_pair = std::pair<Alpha_shape_3::Vertex_handle, Simplex_tree_vertex>;
+using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >;
+using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology<
+ ST, Gudhi::persistent_cohomology::Field_Zp >;
+
+Vertex_list from(const Cell_handle& ch) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+#ifdef DEBUG_TRACES
+ std::cout << "from cell[" << i << "]=" << ch->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(ch->vertex(i));
+ }
+ return the_list;
+}
+
+Vertex_list from(const Facet& fct) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+ if (fct.second != i) {
+#ifdef DEBUG_TRACES
+ std::cout << "from facet=[" << i << "]" << fct.first->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(fct.first->vertex(i));
+ }
+ }
+ return the_list;
+}
+
+Vertex_list from(const Edge_3& edg) {
+ Vertex_list the_list;
+ for (auto i = 0; i < 4; i++) {
+ if ((edg.second == i) || (edg.third == i)) {
+#ifdef DEBUG_TRACES
+ std::cout << "from edge[" << i << "]=" << edg.first->vertex(i)->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(edg.first->vertex(i));
+ }
+ }
+ return the_list;
+}
+
+Vertex_list from(const Alpha_shape_3::Vertex_handle& vh) {
+ Vertex_list the_list;
+#ifdef DEBUG_TRACES
+ std::cout << "from vertex=" << vh->point() << std::endl;
+#endif // DEBUG_TRACES
+ the_list.push_back(vh);
+ return the_list;
+}
+
+void usage(char * const progName) {
+ std::cerr << "Usage: " << progName <<
+ " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n";
+ exit(-1);
+}
+
+int main(int argc, char * const argv[]) {
+ // program args management
+ if (argc != 4) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
+ usage(argv[0]);
+ }
+
+ int coeff_field_characteristic = 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";
+ usage(argv[0]);
+ }
+
+ Filtration_value min_persistence = 0.0;
+ 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]);
+ }
+
+ // Read points from file
+ std::string offInputFile(argv[1]);
+ // Read the OFF file (input file name given as parameter) and triangulate points
+ Gudhi::Points_3D_off_reader<Point_3> off_reader(offInputFile);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ usage(argv[0]);
+ }
+
+ // Retrieve the triangulation
+ std::vector<Point_3> lp = off_reader.get_point_cloud();
+
+ // Define the periodic cube
+ P3DT3 pdt(PK::Iso_cuboid_3(0,0,0,1,1,1));
+ // Heuristic for inserting large point sets (if pts is reasonably large)
+ pdt.insert(lp.begin(), lp.end(), true);
+ // As pdt won't be modified anymore switch to 1-sheeted cover if possible
+ if (pdt.is_triangulation_in_1_sheet()) pdt.convert_to_1_sheeted_covering();
+ std::cout << "Periodic Delaunay computed." << std::endl;
+
+ // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. This is the default mode
+ // Maybe need to set it to GENERAL mode
+ Alpha_shape_3 as(pdt, Alpha_shape_3::GENERAL);
+
+ // filtration with alpha values from alpha shape
+ std::vector<Object> the_objects;
+ std::vector<Alpha_value_type> the_alpha_values;
+
+ Dispatch disp = CGAL::dispatch_output<Object, Alpha_value_type>(std::back_inserter(the_objects),
+ std::back_inserter(the_alpha_values));
+
+ as.filtration_with_alpha_values(disp);
+#ifdef DEBUG_TRACES
+ std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl;
+#endif // DEBUG_TRACES
+
+ Alpha_shape_3::size_type count_vertices = 0;
+ Alpha_shape_3::size_type count_edges = 0;
+ Alpha_shape_3::size_type count_facets = 0;
+ Alpha_shape_3::size_type count_cells = 0;
+
+ // Loop on objects vector
+ Vertex_list vertex_list;
+ ST simplex_tree;
+ Alpha_shape_simplex_tree_map map_cgal_simplex_tree;
+ std::vector<Alpha_value_type>::iterator the_alpha_value_iterator = the_alpha_values.begin();
+ int dim_max = 0;
+ Filtration_value filtration_max = 0.0;
+ for (auto object_iterator : the_objects) {
+ // Retrieve Alpha shape vertex list from object
+ if (const Cell_handle * cell = CGAL::object_cast<Cell_handle>(&object_iterator)) {
+ vertex_list = from(*cell);
+ count_cells++;
+ if (dim_max < 3) {
+ // Cell is of dim 3
+ dim_max = 3;
+ }
+ } else if (const Facet * facet = CGAL::object_cast<Facet>(&object_iterator)) {
+ vertex_list = from(*facet);
+ count_facets++;
+ if (dim_max < 2) {
+ // Facet is of dim 2
+ dim_max = 2;
+ }
+ } else if (const Edge_3 * edge = CGAL::object_cast<Edge_3>(&object_iterator)) {
+ vertex_list = from(*edge);
+ count_edges++;
+ if (dim_max < 1) {
+ // Edge_3 is of dim 1
+ dim_max = 1;
+ }
+ } else if (const Alpha_shape_3::Vertex_handle * vertex =
+ CGAL::object_cast<Alpha_shape_3::Vertex_handle>(&object_iterator)) {
+ count_vertices++;
+ vertex_list = from(*vertex);
+ }
+ // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex
+ Simplex_tree_vector_vertex the_simplex_tree;
+ for (auto the_alpha_shape_vertex : vertex_list) {
+ Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex);
+ if (the_map_iterator == map_cgal_simplex_tree.end()) {
+ // alpha shape not found
+ Simplex_tree_vertex vertex = map_cgal_simplex_tree.size();
+#ifdef DEBUG_TRACES
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex));
+ } else {
+ // alpha shape found
+ Simplex_tree_vertex vertex = the_map_iterator->second;
+#ifdef DEBUG_TRACES
+ std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl;
+#endif // DEBUG_TRACES
+ the_simplex_tree.push_back(vertex);
+ }
+ }
+ // Construction of the simplex_tree
+ Filtration_value filtr = std::sqrt(*the_alpha_value_iterator);
+#ifdef DEBUG_TRACES
+ std::cout << "filtration = " << filtr << std::endl;
+#endif // DEBUG_TRACES
+ if (filtr > filtration_max) {
+ filtration_max = filtr;
+ }
+ simplex_tree.insert_simplex(the_simplex_tree, filtr);
+ if (the_alpha_value_iterator != the_alpha_values.end())
+ ++the_alpha_value_iterator;
+ else
+ std::cout << "This shall not happen" << std::endl;
+ }
+ simplex_tree.set_filtration(filtration_max);
+ simplex_tree.set_dimension(dim_max);
+
+#ifdef DEBUG_TRACES
+ std::cout << "vertices \t\t" << count_vertices << std::endl;
+ std::cout << "edges \t\t" << count_edges << std::endl;
+ std::cout << "facets \t\t" << count_facets << std::endl;
+ std::cout << "cells \t\t" << count_cells << std::endl;
+
+
+ std::cout << "Information of the Simplex Tree: " << std::endl;
+ std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " ";
+ std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl;
+ std::cout << " Dimension = " << simplex_tree.dimension() << " ";
+ std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl;
+#endif // DEBUG_TRACES
+
+#ifdef DEBUG_TRACES
+ std::cout << "Iterator on vertices: " << std::endl;
+ for (auto vertex : simplex_tree.complex_vertex_range()) {
+ std::cout << vertex << " ";
+ }
+#endif // DEBUG_TRACES
+
+ // Sort the simplices in the order of the filtration
+ simplex_tree.initialize_filtration();
+
+ std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl;
+ // Compute the persistence diagram of the complex
+ Persistent_cohomology pcoh(simplex_tree);
+ // initializes the coefficient field for homology
+ pcoh.init_coefficients(coeff_field_characteristic);
+
+ pcoh.compute_persistent_cohomology(min_persistence);
+
+ pcoh.output_diagram();
+
+ return 0;
+}
diff --git a/src/common/example/CGAL_3D_points_off_reader.cpp b/src/common/example/CGAL_3D_points_off_reader.cpp
new file mode 100644
index 00000000..d48bb17d
--- /dev/null
+++ b/src/common/example/CGAL_3D_points_off_reader.cpp
@@ -0,0 +1,41 @@
+#include <gudhi/Points_3D_off_io.h>
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
+using Point_3 = Kernel::Point_3;
+
+void usage(char * const progName) {
+ std::cerr << "Usage: " << progName << " inputFile.off" << std::endl;
+ exit(-1);
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
+ usage(argv[0]);
+ }
+
+ std::string offInputFile(argv[1]);
+ // Read the OFF file (input file name given as parameter) and triangulate points
+ Gudhi::Points_3D_off_reader<Point_3> off_reader(offInputFile);
+ // Check the read operation was correct
+ if (!off_reader.is_valid()) {
+ std::cerr << "Unable to read file " << offInputFile << std::endl;
+ usage(argv[0]);
+ }
+
+ // Retrieve the triangulation
+ std::vector<Point_3> point_cloud = off_reader.get_point_cloud();
+
+ int n {0};
+ for (auto point : point_cloud) {
+ ++n;
+ std::cout << "Point[" << n << "] = (" << point[0] << ", " << point[1] << ", " << point[2] << ")\n";
+ }
+ return 0;
+}
diff --git a/src/common/example/CGAL_points_off_reader.cpp b/src/common/example/CGAL_points_off_reader.cpp
index 45e9f1e6..997b47c1 100644
--- a/src/common/example/CGAL_points_off_reader.cpp
+++ b/src/common/example/CGAL_points_off_reader.cpp
@@ -8,17 +8,19 @@
#include <string>
#include <vector>
-typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
-typedef typename Kernel::Point_d Point_d;
+using Kernel = CGAL::Epick_d< CGAL::Dynamic_dimension_tag >;
+using Point_d = typename Kernel::Point_d;
-void usage(int argc, char * const progName) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
+void usage(char * const progName) {
std::cerr << "Usage: " << progName << " inputFile.off" << std::endl;
exit(-1);
}
int main(int argc, char **argv) {
- if (argc != 2) usage(argc, (argv[0] - 1));
+ if (argc != 2) {
+ std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
+ usage(argv[0]);
+ }
std::string offInputFile(argv[1]);
// Read the OFF file (input file name given as parameter) and triangulate points
@@ -26,16 +28,16 @@ int main(int argc, char **argv) {
// Check the read operation was correct
if (!off_reader.is_valid()) {
std::cerr << "Unable to read file " << offInputFile << std::endl;
- exit(-1);
+ usage(argv[0]);
}
// Retrieve the triangulation
std::vector<Point_d> point_cloud = off_reader.get_point_cloud();
- int n = 0;
+ int n {0};
for (auto point : point_cloud) {
std::cout << "Point[" << n << "] = ";
- for (int i = 0; i < point.dimension(); i++)
+ for (int i {0}; i < point.dimension(); i++)
std::cout << point[i] << " ";
std::cout << "\n";
++n;
diff --git a/src/common/example/CMakeLists.txt b/src/common/example/CMakeLists.txt
index 5aeaa8c6..ee6c9058 100644
--- a/src/common/example/CMakeLists.txt
+++ b/src/common/example/CMakeLists.txt
@@ -3,6 +3,10 @@ project(GUDHIDelaunayTriangulationOffFileReadWrite)
# need CGAL 4.7
if(CGAL_FOUND)
+ add_executable ( cgal3Doffreader CGAL_3D_points_off_reader.cpp )
+ target_link_libraries(cgal3Doffreader ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ add_test(cgal3Doffreader ${CMAKE_CURRENT_BINARY_DIR}/cgaloffreader ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off)
+
if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
diff --git a/src/common/include/gudhi/Points_3D_off_io.h b/src/common/include/gudhi/Points_3D_off_io.h
new file mode 100644
index 00000000..02e6f910
--- /dev/null
+++ b/src/common/include/gudhi/Points_3D_off_io.h
@@ -0,0 +1,206 @@
+/* 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_3D_OFF_IO_H_
+#define POINTS_3D_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_3>
+class Points_3D_off_visitor_reader {
+ private:
+ std::vector<Point_3> point_cloud_;
+ bool valid_;
+
+ public:
+
+ /** @brief Off_reader visitor init implementation.
+ *
+ * The init parameters are set from OFF file header.
+ * Dimension value is required and the value must be 3.
+ *
+ * @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_3D_off_visitor_reader::init - dim=" << dim << " - num_vertices=" <<
+ num_vertices << " - num_faces=" << num_faces << " - num_edges=" << num_edges << std::endl;
+#endif // DEBUG_TRACES
+ if (dim == 3) {
+ valid_ = true;
+ } else {
+ valid_ = false;
+ std::cerr << "Points_3D_off_reader::Points_3D_off_reader cannot read OFF files in dimension " << dim << "\n";
+ }
+
+ if (num_faces > 0) {
+ std::cerr << "Points_3D_off_visitor_reader::init faces are not taken into account from OFF file for Points.\n";
+ }
+ if (num_edges > 0) {
+ std::cerr << "Points_3D_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 vector of points.
+ *
+ * @param[in] point vector of vertex coordinates.
+ *
+ * @details
+ * Point_3 must have a constructor with the following form:
+ *
+ * @code template<class InputIterator > Point_3::Point_3(double x, double y, double z) @endcode
+ */
+ void point(const std::vector<double>& point) {
+ if (valid_) {
+#ifdef DEBUG_TRACES
+ std::cout << "Points_3D_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_3(point[0], point[1], point[2]));
+ }
+ }
+
+ // 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 The point cloud.
+ */
+ const std::vector<Point_3>& get_point_cloud() const {
+ return point_cloud_;
+ }
+
+ /** @brief Returns if the OFF file read operation was successful or not.
+ *
+ * @return OFF file read status.
+ */
+ bool is_valid() const {
+ return valid_;
+ }
+};
+
+/**
+ * \@brief OFF file reader implementation in order to read dimension 3 points from an OFF file.
+ *
+ * @details
+ * This class is using the Points_3D_off_visitor_reader to visit the OFF file according to Off_reader.
+ *
+ * Point_3 must have a constructor with the following form:
+ *
+ * @code template<class InputIterator > Point_3::Point_3(double x, double y, double z) @endcode
+ *
+ * @section Example
+ *
+ * This example loads points from an OFF file and builds a vector of CGAL points in dimension 3.
+ * Then, it is asked to display the points.
+ *
+ * Asserts
+ *
+ * @include common/CGAL_Points_3D_off_reader.cpp
+ *
+ * When launching:
+ *
+ * @code $> ./cgal3Doffreader ../../data/points/alphacomplexdoc.off
+ * @endcode
+ *
+ * the program output is:
+ *
+ * @include common/cgal3Doffreader_result.txt
+ */
+template<typename Point_3>
+class Points_3D_off_reader {
+ public:
+
+ /** @brief Reads the OFF file and constructs a vector of points 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_3D_off_reader(const std::string& name_file)
+ : valid_(false) {
+ std::ifstream stream(name_file);
+ if (stream.is_open()) {
+ Off_reader off_reader(stream);
+ Points_3D_off_visitor_reader<Point_3> off_visitor;
+ valid_ = off_reader.read(off_visitor);
+ valid_ = valid_ && off_visitor.is_valid();
+ if (valid_) {
+ point_cloud = off_visitor.get_point_cloud();
+ }
+ } else {
+ std::cerr << "Points_3D_off_reader::Points_3D_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_3>& get_point_cloud() const {
+ return point_cloud;
+ }
+
+ private:
+ /** @brief point_cloud.*/
+ std::vector<Point_3> point_cloud;
+ /** @brief OFF file read status.*/
+ bool valid_;
+};
+
+} // namespace Gudhi
+
+#endif // POINTS_3D_OFF_IO_H_
diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h
index 77f36be2..74b49386 100644
--- a/src/common/include/gudhi/Points_off_io.h
+++ b/src/common/include/gudhi/Points_off_io.h
@@ -43,7 +43,7 @@ class Points_off_visitor_reader {
/** \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.
+ * Dimension value is required in order to construct a vector of points.
*
* @param[in] dim space dimension of vertices.
* @param[in] num_vertices number of vertices in the OFF file (not used).
@@ -63,12 +63,19 @@ class Points_off_visitor_reader {
}
}
- /** \brief Off_reader visitor point implementation.
+ /** @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.
+ * This function inserts the vertex in the vector of points.
*
* @param[in] point vector of vertex coordinates.
+ *
+ * @details
+ * 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.
*/
void point(const std::vector<double>& point) {
#ifdef DEBUG_TRACES
@@ -127,7 +134,7 @@ class Points_off_visitor_reader {
template<typename Point_d>
class Points_off_reader {
public:
- /** \brief Reads the OFF file and constructs the Alpha complex from the points
+ /** \brief Reads the OFF file and constructs a vector of points from the points
* that are in the OFF file.
*
* @param[in] name_file OFF file to read.