-- cgit v1.2.3 From 753ab8e366bb7d44b6cbe5e26d95c13317fc48c9 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 13 Feb 2018 16:55:41 +0000 Subject: Add documentation tests for example_vector_double_points_off_reader Fix Marc's comments about reader git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/offreaderfix_vincent@3243 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7dfb928c064c1286c1903cb91600ebace7a8fd47 --- src/common/example/CMakeLists.txt | 11 +++++++- src/common/example/cgaloffreader_result.txt | 7 ------ .../example/example_CGAL_3D_points_off_reader.cpp | 6 ++--- .../example/example_CGAL_points_off_reader.cpp | 6 ++--- .../example_vector_double_points_off_reader.cpp | 14 ++++++----- .../example/vectordoubleoffreader_result.txt | 7 ++++++ src/common/include/gudhi/Off_reader.h | 29 ++++++++++++---------- src/common/include/gudhi/Points_off_io.h | 4 +-- 8 files changed, 49 insertions(+), 35 deletions(-) delete mode 100644 src/common/example/cgaloffreader_result.txt create mode 100644 src/common/example/vectordoubleoffreader_result.txt diff --git a/src/common/example/CMakeLists.txt b/src/common/example/CMakeLists.txt index afe865d4..1273c699 100644 --- a/src/common/example/CMakeLists.txt +++ b/src/common/example/CMakeLists.txt @@ -3,11 +3,20 @@ project(Common_examples) add_executable ( vector_double_off_reader example_vector_double_points_off_reader.cpp ) target_link_libraries(vector_double_off_reader ${CGAL_LIBRARY}) +file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) add_test(NAME Common_example_vector_double_off_reader COMMAND $ - "${CMAKE_SOURCE_DIR}/data/points/SO3_10000.off") + "alphacomplexdoc.off") install(TARGETS vector_double_off_reader DESTINATION bin) +if (DIFF_PATH) + # Do not forget to copy test results files in current binary dir + file(COPY "vectordoubleoffreader_result.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + + add_test(Common_example_vector_double_off_reader_diff_files ${DIFF_PATH} + ${CMAKE_CURRENT_BINARY_DIR}/vectordoubleoffreader_result.txt ${CMAKE_CURRENT_BINARY_DIR}/alphacomplexdoc.off.txt) +endif() + if(CGAL_FOUND) add_executable ( cgal_3D_off_reader example_CGAL_3D_points_off_reader.cpp ) target_link_libraries(cgal_3D_off_reader ${CGAL_LIBRARY}) diff --git a/src/common/example/cgaloffreader_result.txt b/src/common/example/cgaloffreader_result.txt deleted file mode 100644 index 1deb8dbd..00000000 --- a/src/common/example/cgaloffreader_result.txt +++ /dev/null @@ -1,7 +0,0 @@ -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/example/example_CGAL_3D_points_off_reader.cpp b/src/common/example/example_CGAL_3D_points_off_reader.cpp index 665b7a29..4658d8d5 100644 --- a/src/common/example/example_CGAL_3D_points_off_reader.cpp +++ b/src/common/example/example_CGAL_3D_points_off_reader.cpp @@ -20,12 +20,12 @@ int main(int argc, char **argv) { usage(argv[0]); } - std::string offInputFile(argv[1]); + std::string off_input_file(argv[1]); // Read the OFF file (input file name given as parameter) and triangulate points - Gudhi::Points_3D_off_reader off_reader(offInputFile); + Gudhi::Points_3D_off_reader off_reader(off_input_file); // Check the read operation was correct if (!off_reader.is_valid()) { - std::cerr << "Unable to read file " << offInputFile << std::endl; + std::cerr << "Unable to read file " << off_input_file << std::endl; usage(argv[0]); } diff --git a/src/common/example/example_CGAL_points_off_reader.cpp b/src/common/example/example_CGAL_points_off_reader.cpp index 8c6a6b54..f45683a5 100644 --- a/src/common/example/example_CGAL_points_off_reader.cpp +++ b/src/common/example/example_CGAL_points_off_reader.cpp @@ -22,12 +22,12 @@ int main(int argc, char **argv) { usage(argv[0]); } - std::string offInputFile(argv[1]); + std::string off_input_file(argv[1]); // Read the OFF file (input file name given as parameter) and triangulate points - Gudhi::Points_off_reader off_reader(offInputFile); + Gudhi::Points_off_reader off_reader(off_input_file); // Check the read operation was correct if (!off_reader.is_valid()) { - std::cerr << "Unable to read file " << offInputFile << std::endl; + std::cerr << "Unable to read file " << off_input_file << std::endl; usage(argv[0]); } diff --git a/src/common/example/example_vector_double_points_off_reader.cpp b/src/common/example/example_vector_double_points_off_reader.cpp index 8aecb26e..5093da85 100644 --- a/src/common/example/example_vector_double_points_off_reader.cpp +++ b/src/common/example/example_vector_double_points_off_reader.cpp @@ -17,25 +17,27 @@ int main(int argc, char **argv) { usage(argv[0]); } - std::string offInputFile(argv[1]); + std::string off_input_file(argv[1]); // Read the OFF file (input file name given as parameter) and triangulate points - Gudhi::Points_off_reader off_reader(offInputFile); + Gudhi::Points_off_reader off_reader(off_input_file); // Check the read operation was correct if (!off_reader.is_valid()) { - std::cerr << "Unable to read file " << offInputFile << std::endl; + std::cerr << "Unable to read file " << off_input_file << std::endl; usage(argv[0]); } // Retrieve the triangulation std::vector point_cloud = off_reader.get_point_cloud(); + std::ofstream output_file(off_input_file + ".txt"); int n {0}; for (auto point : point_cloud) { - std::cout << "Point[" << n << "] = "; + output_file << "Point[" << n << "] = "; for (std::size_t i {0}; i < point.size(); i++) - std::cout << point[i] << " "; - std::cout << "\n"; + output_file << point[i] << " "; + output_file << "\n"; ++n; } + output_file.close(); return 0; } diff --git a/src/common/example/vectordoubleoffreader_result.txt b/src/common/example/vectordoubleoffreader_result.txt new file mode 100644 index 00000000..1deb8dbd --- /dev/null +++ b/src/common/example/vectordoubleoffreader_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/Off_reader.h b/src/common/include/gudhi/Off_reader.h index 4fcd2af2..32320e4d 100644 --- a/src/common/include/gudhi/Off_reader.h +++ b/src/common/include/gudhi/Off_reader.h @@ -105,25 +105,26 @@ class Off_reader { bool is_off_file = (line.find("OFF") != std::string::npos); bool is_noff_file = (line.find("nOFF") != std::string::npos); + + if (!is_off_file && !is_noff_file) { std::cerr << line << std::endl; std::cerr << "missing off header\n"; return false; } + if (is_noff_file) { + // Should be on a separate line, but we accept it on the same line as the number of vertices + stream_ >> off_info_.dim; + } else { + off_info_.dim = 3; + } + if (!goto_next_uncomment_line(line)) return false; std::istringstream iss(line); - 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"; - return false; - } - } else { - if (!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) { + if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) { std::cerr << "incorrect number of vertices/faces/edges\n"; return false; - } } off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges); @@ -131,10 +132,12 @@ 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] == '%'); - return (uncomment_line.size() > 0 && uncomment_line[0] != '%'); + do { + // skip whitespace, including empty lines + if (!std::ifstream::sentry(stream_)) return false; + std::getline(stream_, uncomment_line); + } while (uncomment_line[0] == '#'); + return (bool)stream_; } template diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h index 29af8a8a..08f324c6 100644 --- a/src/common/include/gudhi/Points_off_io.h +++ b/src/common/include/gudhi/Points_off_io.h @@ -126,9 +126,9 @@ class Points_off_visitor_reader { * \code $> ./vector_double_off_reader ../../data/points/alphacomplexdoc.off * \endcode * - * the program output is: + * the program outputs a file ../../data/points/alphacomplexdoc.off.txt: * - * \include common/cgaloffreader_result.txt + * \include common/vectordoubleoffreader_result.txt */ template class Points_off_reader { -- cgit v1.2.3 From 37b73679e141696471abc5a1665c0955b9465f80 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 13 Feb 2018 17:01:01 +0000 Subject: Fix Kl.off strange format git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/offreaderfix_vincent@3244 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1e297c5703ddd59e5b1af6c65a4fbe2a4c318c33 --- data/points/Kl.off | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/points/Kl.off b/data/points/Kl.off index 911bcd23..8930a321 100644 --- a/data/points/Kl.off +++ b/data/points/Kl.off @@ -1,5 +1,5 @@ -OFF -10000 0 0 +nOFF +5 10000 0 0 0.5 0 0 0 1 0.562791 0 0.125333 0 0.998027 0.625333 0 0.24869 0 0.992115 -- cgit v1.2.3 From f95d9eb65491241f953a5dcaef57f1dbf077bd60 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 6 Mar 2018 15:56:04 +0000 Subject: Add offline_header.html for Debian package generation that requires self-contained documentation. Command for generation : ( cat Doxyfile ; echo "HTML_HEADER = doc/common/offline_header.html" ) | doxygen - git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3266 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7bd88e71f56b8c7929cfc8475dd49ff2b0901b53 --- src/common/doc/offline_header.html | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/common/doc/offline_header.html diff --git a/src/common/doc/offline_header.html b/src/common/doc/offline_header.html new file mode 100644 index 00000000..6a02a895 --- /dev/null +++ b/src/common/doc/offline_header.html @@ -0,0 +1,41 @@ + + + + + + + + +$projectname: $title +$title + + + + +$treeview +$search +$mathjax + +$extrastylesheet + + + + +
+ + +
+ + + + + + + + + + +
$searchbox
+
+ + -- cgit v1.2.3 From b77699a3188d6674427cffaa35f26ec57aadec8b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 8 Mar 2018 17:13:25 +0000 Subject: Web site review after Editorial Board Do not need to import gudhi twice in py git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3270 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7d7a4bba27f4cbcad5f8b18cb86587a15e6a8435 --- src/Alpha_complex/utilities/alphacomplex.md | 10 ++++++++++ src/Bitmap_cubical_complex/utilities/cubicalcomplex.md | 10 ++++++++++ src/Bottleneck_distance/utilities/bottleneckdistance.md | 10 ++++++++++ src/Nerve_GIC/utilities/covercomplex.md | 10 ++++++++++ src/Rips_complex/utilities/ripscomplex.md | 10 ++++++++++ src/Witness_complex/utilities/witnesscomplex.md | 10 ++++++++++ src/common/utilities/pointsetgenerator.md | 16 +++++++++++++--- src/cython/example/bottleneck_basic_example.py | 2 -- 8 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/Alpha_complex/utilities/alphacomplex.md b/src/Alpha_complex/utilities/alphacomplex.md index aace85d3..ede749a9 100644 --- a/src/Alpha_complex/utilities/alphacomplex.md +++ b/src/Alpha_complex/utilities/alphacomplex.md @@ -1,3 +1,13 @@ +--- +layout: page +title: "Alpha complex" +meta_title: "Alpha complex" +teaser: "" +permalink: /alphacomplex/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} # Alpha complex # diff --git a/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md b/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md index 6e1b2578..a1bb9007 100644 --- a/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md +++ b/src/Bitmap_cubical_complex/utilities/cubicalcomplex.md @@ -1,3 +1,13 @@ +--- +layout: page +title: "Cubical complex" +meta_title: "Cubical complex" +teaser: "" +permalink: /cubicalcomplex/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} # Cubical complex# diff --git a/src/Bottleneck_distance/utilities/bottleneckdistance.md b/src/Bottleneck_distance/utilities/bottleneckdistance.md index 526f5822..f2749acc 100644 --- a/src/Bottleneck_distance/utilities/bottleneckdistance.md +++ b/src/Bottleneck_distance/utilities/bottleneckdistance.md @@ -1,3 +1,13 @@ +--- +layout: page +title: "Bottleneck distance" +meta_title: "Bottleneck distance" +teaser: "" +permalink: /bottleneckdistance/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} # Bottleneck distance # diff --git a/src/Nerve_GIC/utilities/covercomplex.md b/src/Nerve_GIC/utilities/covercomplex.md index f33cb2e0..6d16d16f 100644 --- a/src/Nerve_GIC/utilities/covercomplex.md +++ b/src/Nerve_GIC/utilities/covercomplex.md @@ -1,3 +1,13 @@ +--- +layout: page +title: "Cover complex" +meta_title: "Cover complex" +teaser: "" +permalink: /covercomplex/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} # Cover complex # diff --git a/src/Rips_complex/utilities/ripscomplex.md b/src/Rips_complex/utilities/ripscomplex.md index 4291fae7..c1f2210e 100644 --- a/src/Rips_complex/utilities/ripscomplex.md +++ b/src/Rips_complex/utilities/ripscomplex.md @@ -1,3 +1,13 @@ +--- +layout: page +title: "Rips complex" +meta_title: "Rips complex" +teaser: "" +permalink: /ripscomplex/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} # Rips complex # diff --git a/src/Witness_complex/utilities/witnesscomplex.md b/src/Witness_complex/utilities/witnesscomplex.md index 2341759b..3be9bc55 100644 --- a/src/Witness_complex/utilities/witnesscomplex.md +++ b/src/Witness_complex/utilities/witnesscomplex.md @@ -1,3 +1,13 @@ +--- +layout: page +title: "Witness complex" +meta_title: "Witness complex" +teaser: "" +permalink: /witnesscomplex/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} # Witness complex # diff --git a/src/common/utilities/pointsetgenerator.md b/src/common/utilities/pointsetgenerator.md index 284715d4..3b23e668 100644 --- a/src/common/utilities/pointsetgenerator.md +++ b/src/common/utilities/pointsetgenerator.md @@ -1,6 +1,16 @@ - - -# common # +--- +layout: page +title: "OFF point set generator" +meta_title: "OFF point set generator" +teaser: "" +permalink: /pointsetgenerator/ +--- +{::comment} +Leave the lines above as it is required by the web site generator 'Jekyll' +{:/comment} + + +# Miscellaneous # ## off_file_from_shape_generator ## diff --git a/src/cython/example/bottleneck_basic_example.py b/src/cython/example/bottleneck_basic_example.py index 31cecb29..a7fa01c1 100755 --- a/src/cython/example/bottleneck_basic_example.py +++ b/src/cython/example/bottleneck_basic_example.py @@ -28,8 +28,6 @@ __author__ = "Francois Godi, Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 INRIA" __license__ = "GPL v3" -import gudhi - diag1 = [[2.7, 3.7],[9.6, 14.],[34.2, 34.974], [3.,float('Inf')]] diag2 = [[2.8, 4.45],[9.5, 14.1],[3.2,float('Inf')]] -- cgit v1.2.3 From 74d2aab913ce02ba1755ff4fc08e37e38cbb499a Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 13 Mar 2018 14:51:06 +0000 Subject: Simplex_key clarifications in FilteredComplex concept. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3284 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a42ef2c14a64a769c9a8c8ddc37071ba260b17bf --- src/Persistent_cohomology/concept/FilteredComplex.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Persistent_cohomology/concept/FilteredComplex.h b/src/Persistent_cohomology/concept/FilteredComplex.h index c19698df..d6b662e9 100644 --- a/src/Persistent_cohomology/concept/FilteredComplex.h +++ b/src/Persistent_cohomology/concept/FilteredComplex.h @@ -31,7 +31,7 @@ struct FilteredComplex typedef unspecified Simplex_handle; /** \brief Key associated to each simplex. * - * Must be a signed integer type. */ + * Must be an integer type. */ typedef unspecified Simplex_key; /** \brief Type for the value of the filtration function. * @@ -67,8 +67,8 @@ struct FilteredComplex Simplex_key key ( Simplex_handle sh ); /** \brief Returns the simplex that has index idx in the filtration. * - * This is never called on null_key(). */ - Simplex_handle simplex ( Simplex_key idx ); + * This is only called on valid indices. */ + Simplex_handle simplex ( size_t idx ); /** \brief Assign a key to a simplex. */ void assign_key(Simplex_handle sh, Simplex_key key); -- cgit v1.2.3 From 564427b6cad42ad98e9633589b128c07674c1dd6 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 28 Mar 2018 09:58:12 +0000 Subject: Fix header that was not pointing on the correct web site. Cpp documentation header was not good git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3310 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 520635bb2f09419b4b70f71c0838d45ae15354b3 --- src/common/doc/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/doc/header.html b/src/common/doc/header.html index d69b28fa..2f54e68d 100644 --- a/src/common/doc/header.html +++ b/src/common/doc/header.html @@ -9,7 +9,7 @@ $projectname: $title $title - + -- cgit v1.2.3 From 9cceba4f1ed5cca6daa273166a2ec38fe0ab6c91 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 28 Mar 2018 10:09:36 +0000 Subject: Merge last Nerve_GIC development from eponym branch git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3311 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c57e5f6f364b6162f607edd07f3a31577e640fcb --- src/Nerve_GIC/include/gudhi/GIC.h | 254 +++++++++++++++++++++++--------------- src/Nerve_GIC/test/test_GIC.cpp | 3 + 2 files changed, 157 insertions(+), 100 deletions(-) diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 40ff7a4a..f5b67be6 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -23,6 +23,11 @@ #ifndef GIC_H_ #define GIC_H_ +#ifdef GUDHI_USE_TBB +#include +#include +#endif + #include #include #include @@ -99,9 +104,8 @@ class Cover_complex { int data_dimension; // dimension of input data. int n; // number of points. - std::map func; // function used to compute the output simplicial complex. - std::map - func_color; // function used to compute the colors of the nodes of the output simplicial complex. + std::vector func; // function used to compute the output simplicial complex. + std::vector func_color; // function used to compute the colors of the nodes of the output simplicial complex. bool functional_cover = false; // whether we use a cover with preimages of a function or not. Graph one_skeleton_OFF; // one-skeleton given by the input OFF file (if it exists). @@ -114,8 +118,8 @@ class Cover_complex { Persistence_diagram PD; std::vector distribution; - std::map > - cover; // function associating to each data point its vectors of cover elements to which it belongs. + std::vector > + cover; // function associating to each data point the vector of cover elements to which it belongs. std::map > cover_back; // inverse of cover, in order to get the data points associated to a specific cover element. std::map cover_std; // standard function (induced by func) used to compute the extended persistence @@ -140,8 +144,8 @@ class Cover_complex { // Point comparator struct Less { - Less(std::map func) { Fct = func; } - std::map Fct; + Less(std::vector func) { Fct = func; } + std::vector Fct; bool operator()(int a, int b) { if (Fct[a] == Fct[b]) return a < b; @@ -276,6 +280,7 @@ class Cover_complex { point_cloud.emplace_back(point.begin(), point.begin() + data_dimension); boost::add_vertex(one_skeleton_OFF); vertices.push_back(boost::add_vertex(one_skeleton)); + std::vector dummy; dummy.clear(); cover.push_back(dummy); i++; } } @@ -430,17 +435,29 @@ class Cover_complex { if (distances.size() == 0) compute_pairwise_distances(distance); - // #pragma omp parallel for - for (int i = 0; i < N; i++) { - SampleWithoutReplacement(n, m, samples); - double hausdorff_dist = 0; - for (int j = 0; j < n; j++) { - double mj = distances[j][samples[0]]; - for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]); - hausdorff_dist = std::max(hausdorff_dist, mj); + #ifdef GUDHI_USE_TBB + tbb::parallel_for(0, N, [&](int i){ + SampleWithoutReplacement(n, m, samples); + double hausdorff_dist = 0; + for (int j = 0; j < n; j++) { + double mj = distances[j][samples[0]]; + for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]); + hausdorff_dist = std::max(hausdorff_dist, mj); + } + delta += hausdorff_dist / N; + }); + #else + for (int i = 0; i < N; i++) { + SampleWithoutReplacement(n, m, samples); + double hausdorff_dist = 0; + for (int j = 0; j < n; j++) { + double mj = distances[j][samples[0]]; + for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]); + hausdorff_dist = std::max(hausdorff_dist, mj); + } + delta += hausdorff_dist / N; } - delta += hausdorff_dist / N; - } + #endif if (verbose) std::cout << "delta = " << delta << std::endl; set_graph_from_rips(delta, distance); @@ -465,7 +482,7 @@ class Cover_complex { while (std::getline(input, line)) { std::stringstream stream(line); stream >> f; - func.emplace(i, f); + func.push_back(f); i++; } functional_cover = true; @@ -479,7 +496,7 @@ class Cover_complex { * */ void set_function_from_coordinate(int k) { - for (int i = 0; i < n; i++) func.emplace(i, point_cloud[i][k]); + for (int i = 0; i < n; i++) func.push_back(point_cloud[i][k]); functional_cover = true; cover_name = "coordinate " + std::to_string(k); } @@ -492,7 +509,7 @@ class Cover_complex { */ template void set_function_from_range(InputRange const& function) { - for (int i = 0; i < n; i++) func.emplace(i, function[i]); + for (int i = 0; i < n; i++) func.push_back(function[i]); functional_cover = true; } @@ -710,37 +727,69 @@ class Cover_complex { funcstd[i] = 0.5 * (u + v); } - if (verbose) std::cout << "Computing connected components..." << std::endl; - // #pragma omp parallel for - for (int i = 0; i < res; i++) { - // Compute connected components - Graph G = one_skeleton.create_subgraph(); - int num = preimages[i].size(); - std::vector component(num); - for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G); - boost::connected_components(G, &component[0]); - int max = 0; - - // For each point in preimage - for (int j = 0; j < num; j++) { - // Update number of components in preimage - if (component[j] > max) max = component[j]; - - // Identify component with Cantor polynomial N^2 -> N - int identifier = (std::pow(i + component[j], 2) + 3 * i + component[j]) / 2; - - // Update covers - cover[preimages[i][j]].push_back(identifier); - cover_back[identifier].push_back(preimages[i][j]); - cover_fct[identifier] = i; - cover_std[identifier] = funcstd[i]; - cover_color[identifier].second += func_color[preimages[i][j]]; - cover_color[identifier].first += 1; - } + #ifdef GUDHI_USE_TBB + if (verbose) std::cout << "Computing connected components (parallelized)..." << std::endl; + tbb::parallel_for(0, res, [&](int i){ + // Compute connected components + Graph G = one_skeleton.create_subgraph(); + int num = preimages[i].size(); + std::vector component(num); + for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G); + boost::connected_components(G, &component[0]); + int max = 0; + + // For each point in preimage + for (int j = 0; j < num; j++) { + // Update number of components in preimage + if (component[j] > max) max = component[j]; + + // Identify component with Cantor polynomial N^2 -> N + int identifier = ((i + component[j])*(i + component[j]) + 3 * i + component[j]) / 2; + + // Update covers + cover[preimages[i][j]].push_back(identifier); + cover_back[identifier].push_back(preimages[i][j]); + cover_fct[identifier] = i; + cover_std[identifier] = funcstd[i]; + cover_color[identifier].second += func_color[preimages[i][j]]; + cover_color[identifier].first += 1; + } - // Maximal dimension is total number of connected components - id += max + 1; - } + // Maximal dimension is total number of connected components + id += max + 1; + }); + #else + if (verbose) std::cout << "Computing connected components..." << std::endl; + for (int i = 0; i < res; i++) { + // Compute connected components + Graph G = one_skeleton.create_subgraph(); + int num = preimages[i].size(); + std::vector component(num); + for (int j = 0; j < num; j++) boost::add_vertex(index[vertices[preimages[i][j]]], G); + boost::connected_components(G, &component[0]); + int max = 0; + + // For each point in preimage + for (int j = 0; j < num; j++) { + // Update number of components in preimage + if (component[j] > max) max = component[j]; + + // Identify component with Cantor polynomial N^2 -> N + int identifier = (std::pow(i + component[j], 2) + 3 * i + component[j]) / 2; + + // Update covers + cover[preimages[i][j]].push_back(identifier); + cover_back[identifier].push_back(preimages[i][j]); + cover_fct[identifier] = i; + cover_std[identifier] = funcstd[i]; + cover_color[identifier].second += func_color[preimages[i][j]]; + cover_color[identifier].first += 1; + } + + // Maximal dimension is total number of connected components + id += max + 1; + } + #endif maximal_dim = id - 1; for (std::map >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++) @@ -803,24 +852,46 @@ class Cover_complex { for (int j = 0; j < n; j++) mindist[j] = std::numeric_limits::max(); // Compute the geodesic distances to subsamples with Dijkstra - // #pragma omp parallel for - for (int i = 0; i < m; i++) { - if (verbose) std::cout << "Computing geodesic distances to seed " << i << "..." << std::endl; - int seed = voronoi_subsamples[i]; - std::vector dmap(n); - boost::dijkstra_shortest_paths( - one_skeleton, vertices[seed], - boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index))); - - for (int j = 0; j < n; j++) - if (mindist[j] > dmap[j]) { - mindist[j] = dmap[j]; - if (cover[j].size() == 0) - cover[j].push_back(i); - else - cover[j][0] = i; - } - } + #ifdef GUDHI_USE_TBB + if (verbose) std::cout << "Computing geodesic distances (parallelized)..." << std::endl; + tbb::mutex coverMutex; tbb::mutex mindistMutex; + tbb::parallel_for(0, m, [&](int i){ + int seed = voronoi_subsamples[i]; + std::vector dmap(n); + boost::dijkstra_shortest_paths( + one_skeleton, vertices[seed], + boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index))); + + coverMutex.lock(); mindistMutex.lock(); + for (int j = 0; j < n; j++) + if (mindist[j] > dmap[j]) { + mindist[j] = dmap[j]; + if (cover[j].size() == 0) + cover[j].push_back(i); + else + cover[j][0] = i; + } + coverMutex.unlock(); mindistMutex.unlock(); + }); + #else + for (int i = 0; i < m; i++) { + if (verbose) std::cout << "Computing geodesic distances to seed " << i << "..." << std::endl; + int seed = voronoi_subsamples[i]; + std::vector dmap(n); + boost::dijkstra_shortest_paths( + one_skeleton, vertices[seed], + boost::weight_map(weight).distance_map(boost::make_iterator_property_map(dmap.begin(), index))); + + for (int j = 0; j < n; j++) + if (mindist[j] > dmap[j]) { + mindist[j] = dmap[j]; + if (cover[j].size() == 0) + cover[j].push_back(i); + else + cover[j][0] = i; + } + } + #endif for (int i = 0; i < n; i++) { cover_back[cover[i][0]].push_back(i); @@ -860,7 +931,7 @@ class Cover_complex { while (std::getline(input, line)) { std::stringstream stream(line); stream >> f; - func_color.emplace(i, f); + func_color.push_back(f); i++; } color_name = color_file_name; @@ -873,7 +944,7 @@ class Cover_complex { * */ void set_color_from_coordinate(int k = 0) { - for (int i = 0; i < n; i++) func_color[i] = point_cloud[i][k]; + for (int i = 0; i < n; i++) func_color.push_back(point_cloud[i][k]); color_name = "coordinate "; color_name.append(std::to_string(k)); } @@ -885,7 +956,7 @@ class Cover_complex { * */ void set_color_from_vector(std::vector color) { - for (unsigned int i = 0; i < color.size(); i++) func_color[i] = color[i]; + for (unsigned int i = 0; i < color.size(); i++) func_color.push_back(color[i]); } public: // Create a .dot file that can be compiled with neato to produce a .pdf file. @@ -1039,45 +1110,29 @@ class Cover_complex { minf = std::min(minf, it->second); } + // Build filtration for (auto const& simplex : simplices) { - // Add a simplex and a cone on it - std::vector splx = simplex; - splx.push_back(-2); - st.insert_simplex_and_subfaces(splx); + std::vector splx = simplex; splx.push_back(-2); + st.insert_simplex_and_subfaces(splx, -3); } - // Build filtration - for (auto simplex : st.complex_simplex_range()) { - double filta = std::numeric_limits::lowest(); - double filts = filta; - bool ascending = true; - for (auto vertex : st.simplex_vertex_range(simplex)) { - if (vertex == -2) { - ascending = false; - continue; - } - filta = std::max(-2 + (cover_std[vertex] - minf) / (maxf - minf), filta); - filts = std::max(2 - (cover_std[vertex] - minf) / (maxf - minf), filts); - } - if (ascending) - st.assign_filtration(simplex, filta); - else - st.assign_filtration(simplex, filts); + for (std::map::iterator it = cover_std.begin(); it != cover_std.end(); it++) { + int vertex = it->first; float val = it->second; + int vert[] = {vertex}; int edge[] = {vertex, -2}; + st.assign_filtration(st.find(vert), -2 + (val - minf)/(maxf - minf)); + st.assign_filtration(st.find(edge), 2 - (val - minf)/(maxf - minf)); } - int magic[] = {-2}; - st.assign_filtration(st.find(magic), -3); + st.make_filtration_non_decreasing(); // Compute PD - st.initialize_filtration(); - Gudhi::persistent_cohomology::Persistent_cohomology pcoh(st); - pcoh.init_coefficients(2); + Gudhi::persistent_cohomology::Persistent_cohomology pcoh(st); pcoh.init_coefficients(2); pcoh.compute_persistent_cohomology(); // Output PD int max_dim = st.dimension(); for (int i = 0; i < max_dim; i++) { std::vector > bars = pcoh.intervals_in_dimension(i); - int num_bars = bars.size(); + int num_bars = bars.size(); if(i == 0) num_bars -= 1; if(verbose) std::cout << num_bars << " interval(s) in dimension " << i << ":" << std::endl; for (int j = 0; j < num_bars; j++) { double birth = bars[j].first; @@ -1206,8 +1261,7 @@ class Cover_complex { } if (type == "Nerve") { - for(auto& simplex : cover) - simplices.push_back(simplex.second); + for(int i = 0; i < n; i++) simplices.push_back(cover[i]); std::sort(simplices.begin(), simplices.end()); std::vector >::iterator it = std::unique(simplices.begin(), simplices.end()); simplices.resize(std::distance(simplices.begin(), it)); diff --git a/src/Nerve_GIC/test/test_GIC.cpp b/src/Nerve_GIC/test/test_GIC.cpp index d633753c..e3067d35 100644 --- a/src/Nerve_GIC/test/test_GIC.cpp +++ b/src/Nerve_GIC/test/test_GIC.cpp @@ -39,6 +39,7 @@ BOOST_AUTO_TEST_CASE(check_nerve) { N.set_type("Nerve"); std::string cloud_file_name("data/cloud"); N.read_point_cloud(cloud_file_name); + N.set_color_from_coordinate(); std::string graph_file_name("data/graph"); N.set_graph_from_file(graph_file_name); std::string cover_file_name("data/cover"); @@ -58,6 +59,7 @@ BOOST_AUTO_TEST_CASE(check_GIC) { GIC.set_type("GIC"); std::string cloud_file_name("data/cloud"); GIC.read_point_cloud(cloud_file_name); + GIC.set_color_from_coordinate(); std::string graph_file_name("data/graph"); GIC.set_graph_from_file(graph_file_name); std::string cover_file_name("data/cover"); @@ -77,6 +79,7 @@ BOOST_AUTO_TEST_CASE(check_voronoiGIC) { GIC.set_type("GIC"); std::string cloud_file_name("data/cloud"); GIC.read_point_cloud(cloud_file_name); + GIC.set_color_from_coordinate(); std::string graph_file_name("data/graph"); GIC.set_graph_from_file(graph_file_name); GIC.set_cover_from_Voronoi(Gudhi::Euclidean_distance(), 2); -- cgit v1.2.3 From 91448f9ae1c13c74441f521a25d29375bc4643ee Mon Sep 17 00:00:00 2001 From: glisse Date: Thu, 29 Mar 2018 15:17:42 +0000 Subject: Use CGAL::NT_converter to convert filtration values. Alpha_complex may produce something different from what the Simplex_tree expects, convert it explicitly. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3317 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d6c7492bbf48401a9f63f6462c7704e380eff6e1 --- src/Alpha_complex/include/gudhi/Alpha_complex.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h index 63c6675c..91305032 100644 --- a/src/Alpha_complex/include/gudhi/Alpha_complex.h +++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h @@ -34,6 +34,7 @@ #include #include #include // for CGAL::Identity_property_map +#include #include #include @@ -323,8 +324,9 @@ class Alpha_complex { if (f_simplex_dim > 0) { // squared_radius function initialization Squared_Radius squared_radius = kernel_.compute_squared_radius_d_object(); + CGAL::NT_converter cv; - alpha_complex_filtration = squared_radius(pointVector.begin(), pointVector.end()); + alpha_complex_filtration = cv(squared_radius(pointVector.begin(), pointVector.end())); } complex.assign_filtration(f_simplex, alpha_complex_filtration); #ifdef DEBUG_TRACES -- cgit v1.2.3 From 8447fa7575ae4db0db6daa8e03a0c2f9a374df7c Mon Sep 17 00:00:00 2001 From: glisse Date: Thu, 29 Mar 2018 15:19:20 +0000 Subject: Use add_edge_without_blockers in GudhUI. When the meaning of add_edge changed, GudhUI was not updated. The old functionality is available as add_edge_without_blockers. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3318 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 58b10f79177736cc99e35fb526e4c987d615ae4c --- src/GudhUI/model/Model.h | 2 +- src/GudhUI/utils/Critical_points.h | 2 +- src/GudhUI/utils/K_nearest_builder.h | 2 +- src/GudhUI/utils/Rips_builder.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GudhUI/model/Model.h b/src/GudhUI/model/Model.h index fc284cc6..072d1185 100644 --- a/src/GudhUI/model/Model.h +++ b/src/GudhUI/model/Model.h @@ -74,7 +74,7 @@ class CGAL_geometric_flag_complex_wrapper { // std::cout << "size:" << vertices.size() << std::endl; for (std::size_t i = 0; i < vertices.size(); ++i) for (std::size_t j = i + 1; j < vertices.size(); ++j) - complex_.add_edge(Vertex_handle(vertices[i]), Vertex_handle(vertices[j])); + complex_.add_edge_without_blockers(Vertex_handle(vertices[i]), Vertex_handle(vertices[j])); } } diff --git a/src/GudhUI/utils/Critical_points.h b/src/GudhUI/utils/Critical_points.h index 2a18e079..e7b9ef31 100644 --- a/src/GudhUI/utils/Critical_points.h +++ b/src/GudhUI/utils/Critical_points.h @@ -79,7 +79,7 @@ template class Critical_points { unsigned pos = 0; for (Edge e : edges) { std::cout << "edge " << pos++ << "/" << edges.size() << "\n"; - auto eh = filled_complex_.add_edge(e.first, e.second); + auto eh = filled_complex_.add_edge_without_blockers(e.first, e.second); int is_contractible(is_link_reducible(eh)); switch (is_contractible) { diff --git a/src/GudhUI/utils/K_nearest_builder.h b/src/GudhUI/utils/K_nearest_builder.h index 7be0a4f4..4000a331 100644 --- a/src/GudhUI/utils/K_nearest_builder.h +++ b/src/GudhUI/utils/K_nearest_builder.h @@ -81,7 +81,7 @@ template class K_nearest_builder { for (auto it = ++search.begin(); it != search.end(); ++it) { Vertex_handle q(std::get<1>(it->first)); if (p != q && complex_.contains_vertex(p) && complex_.contains_vertex(q)) - complex_.add_edge(p, q); + complex_.add_edge_without_blockers(p, q); } } } diff --git a/src/GudhUI/utils/Rips_builder.h b/src/GudhUI/utils/Rips_builder.h index b22f4db6..59b4bee2 100644 --- a/src/GudhUI/utils/Rips_builder.h +++ b/src/GudhUI/utils/Rips_builder.h @@ -60,7 +60,7 @@ template class Rips_builder { std::cout.flush(); for (auto q = p; ++q != vertices.end(); /**/) if (squared_eucl_distance(complex_.point(*p), complex_.point(*q)) < 4 * alpha * alpha) - complex_.add_edge(*p, *q); + complex_.add_edge_without_blockers(*p, *q); } std::cout << std::endl; } -- cgit v1.2.3