From 0dcebad6a0c9d9f7968b582522fbbf548758d9c0 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Mon, 26 Feb 2018 12:53:46 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3257 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 25ee894f17d60c05f961faec7bfa41f510d91827 --- src/Nerve_GIC/include/gudhi/GIC.h | 56 ++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 642b88b0..c5fd4d22 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -115,7 +115,7 @@ class Cover_complex { std::vector distribution; std::map > - cover; // function associating to each data point its vectors of cover elements to which it belongs. + 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 @@ -1044,13 +1044,31 @@ class Cover_complex { minf = std::min(minf, it->second); } + /*int magic[] = {-2}; + st.insert_simplex(magic, -3); + 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); } + for (auto const& simplex : simplices) { + if(simplex.size() == 1){ + st.insert_simplex(it->first, -2 + (it->second - minf)/(maxf - minf)); + int[] cone_edge = {-2,it->first}; + st.insert_simplex(cone_edge, 2 - (it->second - minf)/(maxf - minf)); + } + else{ + st.insert_simplex(simplex, -2.5); + std::vector splx = simplex; splx.push_back(-2); + st.insert_simplex(splx, 0); + } + } + + st.make_filtration_non_decreasing();*/ + + + // Build filtration for (auto simplex : st.complex_simplex_range()) { double filta = std::numeric_limits::lowest(); @@ -1062,7 +1080,7 @@ class Cover_complex { continue; } filta = std::max(-2 + (cover_std[vertex] - minf) / (maxf - minf), filta); - filts = std::max(2 - (cover_std[vertex] - minf) / (maxf - minf), filts); + filts = std::max( 2 - (cover_std[vertex] - minf) / (maxf - minf), filts); } if (ascending) st.assign_filtration(simplex, filta); @@ -1071,11 +1089,10 @@ class Cover_complex { } int magic[] = {-2}; st.assign_filtration(st.find(magic), -3); + st.initialize_filtration(); // 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 @@ -1201,6 +1218,27 @@ class Cover_complex { } } + private: + std::vector > subfaces(std::vector simplex){ + if (simplex.size() == 1){ + std::vector > dummy; dummy.clear(); + std::vector empty; empty.clear(); + dummy.push_bakc(empty); dummy.push_back(simplex); return dummy; + } + else{ + int popped_vertex = simplex[simplex.size()-1]; + std::vector popped_simplex = simplex; popped_simplex.pop_back(); + std::vector > subf1 = subfaces(popped_simplex); std::vector > subf2; + for (int i = 0; i < subf1.size(); i++){ + std::vector face = subf1[i]; + face.push_back(popped_vertex); + subf2.push_back(face); + } + subf1.insert(subf1.end(), subf2.begin(), subf2.end() ); + return subf1; + } + } + public: /** \brief Computes the simplices of the simplicial complex. */ -- cgit v1.2.3 From 6141868f2336a2650e0f9ac755735aee30d56356 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Tue, 27 Feb 2018 15:32:07 +0000 Subject: added parallelization with TBB + some map changed to vector + construction of PD git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3258 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b1990a9f139015217e5a59cc87e1f6b5296be6b3 --- src/Nerve_GIC/include/gudhi/GIC.h | 287 ++++++++++++++++++---------------- src/cmake/modules/GUDHI_modules.cmake | 2 +- 2 files changed, 154 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index c5fd4d22..1805959b 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -23,6 +23,12 @@ #ifndef GIC_H_ #define GIC_H_ +#ifdef GUDHI_USE_TBB +#include +#include +#include +#endif + #include #include #include @@ -99,9 +105,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,7 +119,7 @@ class Cover_complex { Persistence_diagram PD; std::vector distribution; - std::map > + 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. @@ -140,8 +145,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 +281,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++; } } @@ -431,17 +437,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); @@ -466,7 +484,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; @@ -480,7 +498,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]); char coordinate[100]; sprintf(coordinate, "coordinate %d", k); functional_cover = true; @@ -495,7 +513,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; } @@ -713,37 +731,70 @@ 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 + tbb::task_scheduler_init init(4); + 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++) @@ -805,25 +856,48 @@ class Cover_complex { std::vector mindist(n); 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); @@ -863,7 +937,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; @@ -876,7 +950,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)); } @@ -888,7 +962,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. @@ -1044,52 +1118,19 @@ class Cover_complex { minf = std::min(minf, it->second); } - /*int magic[] = {-2}; - st.insert_simplex(magic, -3); - + // Build filtration for (auto const& simplex : simplices) { std::vector splx = simplex; splx.push_back(-2); st.insert_simplex_and_subfaces(splx, -3); } - for (auto const& simplex : simplices) { - if(simplex.size() == 1){ - st.insert_simplex(it->first, -2 + (it->second - minf)/(maxf - minf)); - int[] cone_edge = {-2,it->first}; - st.insert_simplex(cone_edge, 2 - (it->second - minf)/(maxf - minf)); - } - else{ - st.insert_simplex(simplex, -2.5); - std::vector splx = simplex; splx.push_back(-2); - st.insert_simplex(splx, 0); - } - } - - st.make_filtration_non_decreasing();*/ - - - - // 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.initialize_filtration(); + st.make_filtration_non_decreasing(); // Compute PD Gudhi::persistent_cohomology::Persistent_cohomology pcoh(st); pcoh.init_coefficients(2); @@ -1099,7 +1140,7 @@ class Cover_complex { 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; @@ -1218,27 +1259,6 @@ class Cover_complex { } } - private: - std::vector > subfaces(std::vector simplex){ - if (simplex.size() == 1){ - std::vector > dummy; dummy.clear(); - std::vector empty; empty.clear(); - dummy.push_bakc(empty); dummy.push_back(simplex); return dummy; - } - else{ - int popped_vertex = simplex[simplex.size()-1]; - std::vector popped_simplex = simplex; popped_simplex.pop_back(); - std::vector > subf1 = subfaces(popped_simplex); std::vector > subf2; - for (int i = 0; i < subf1.size(); i++){ - std::vector face = subf1[i]; - face.push_back(popped_vertex); - subf2.push_back(face); - } - subf1.insert(subf1.end(), subf2.begin(), subf2.end() ); - return subf1; - } - } - public: /** \brief Computes the simplices of the simplicial complex. */ @@ -1249,8 +1269,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/cmake/modules/GUDHI_modules.cmake b/src/cmake/modules/GUDHI_modules.cmake index f95d0c34..276fb2cc 100644 --- a/src/cmake/modules/GUDHI_modules.cmake +++ b/src/cmake/modules/GUDHI_modules.cmake @@ -17,7 +17,7 @@ function(add_gudhi_module file_path) endfunction(add_gudhi_module) option(WITH_GUDHI_BENCHMARK "Activate/desactivate benchmark compilation" OFF) -option(WITH_GUDHI_EXAMPLE "Activate/desactivate examples compilation and installation" OFF) +option(WITH_GUDHI_EXAMPLE "Activate/desactivate examples compilation and installation" ON) option(WITH_GUDHI_PYTHON "Activate/desactivate python module compilation and installation" ON) option(WITH_GUDHI_TEST "Activate/desactivate examples compilation and installation" ON) option(WITH_GUDHI_UTILITIES "Activate/desactivate utilities compilation and installation" ON) -- cgit v1.2.3 From 2e60e1e4737729a1f772a9cbdb83583fbb166f71 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Wed, 28 Mar 2018 09:41:38 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3309 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1af850057913b691b237bde016ef11de9d65b91b --- src/Nerve_GIC/include/gudhi/GIC.h | 1 - src/Nerve_GIC/test/test_GIC.cpp | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 1805959b..80d4c024 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -732,7 +732,6 @@ class Cover_complex { } #ifdef GUDHI_USE_TBB - tbb::task_scheduler_init init(4); if (verbose) std::cout << "Computing connected components (parallelized)..." << std::endl; tbb::parallel_for(0, res, [&](int i){ // Compute connected components 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 eb1a95034622365303f30a6987c15f9fe80bd8ab Mon Sep 17 00:00:00 2001 From: mcarrier Date: Thu, 29 Mar 2018 15:38:20 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3320 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 21f1574da074759d38553d2a7c87f6c979f77934 --- src/Nerve_GIC/include/gudhi/GIC.h | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 80d4c024..bd15225f 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -143,18 +143,6 @@ class Cover_complex { std::string point_cloud_name; std::string color_name; - // Point comparator - struct Less { - Less(std::vector func) { Fct = func; } - std::vector Fct; - bool operator()(int a, int b) { - if (Fct[a] == Fct[b]) - return a < b; - else - return Fct[a] < Fct[b]; - } - }; - // Remove all edges of a graph. void remove_edges(Graph& G) { boost::graph_traits::edge_iterator ei, ei_end; @@ -280,8 +268,7 @@ class Cover_complex { point.assign(std::istream_iterator(iss), std::istream_iterator()); 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); + vertices.push_back(boost::add_vertex(one_skeleton)); cover.emplace_back(); i++; } } @@ -675,7 +662,7 @@ class Cover_complex { // Sort points according to function values std::vector points(n); for (int i = 0; i < n; i++) points[i] = i; - std::sort(points.begin(), points.end(), Less(this->func)); + std::sort(points.begin(), points.end(), [=](const int & p1, const int & p2){return (this->func[p1] < this->func[p2]);}); int id = 0; int pos = 0; @@ -1179,8 +1166,9 @@ class Cover_complex { int id = std::floor(u * (this->n)); boot[j] = id; Cboot.point_cloud[j] = this->point_cloud[id]; - Cboot.func.emplace(j, this->func[id]); + Cboot.func.push_back(this->func[id]); } + Cboot.set_color_from_vector(Cboot.func); for (int j = 0; j < n; j++) { std::vector dist(n); for (int k = 0; k < n; k++) dist[k] = distances[boot[j]][boot[k]]; -- cgit v1.2.3 From 78335c71e46bd3b77d1595edef63cedbe6cf006c Mon Sep 17 00:00:00 2001 From: mcarrier Date: Fri, 30 Mar 2018 08:37:43 +0000 Subject: changed functions for bootstrap git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3322 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b26ac991e90767fb0de3d91d01ffe1ef25c572fe --- src/Nerve_GIC/example/CoordGIC.cpp | 3 +++ src/Nerve_GIC/include/gudhi/GIC.h | 45 +++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/example/CoordGIC.cpp b/src/Nerve_GIC/example/CoordGIC.cpp index c03fcbb3..7e595382 100644 --- a/src/Nerve_GIC/example/CoordGIC.cpp +++ b/src/Nerve_GIC/example/CoordGIC.cpp @@ -66,6 +66,9 @@ int main(int argc, char **argv) { GIC.find_simplices(); + GIC.compute_distribution(10); + GIC.compute_p_value(); + GIC.plot_DOT(); Gudhi::Simplex_tree<> stree; diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index bd15225f..e6c508fc 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -415,9 +415,7 @@ class Cover_complex { template double set_graph_from_automatic_rips(Distance distance, int N = 100) { int m = floor(n / std::exp((1 + rate_power) * std::log(std::log(n) / std::log(rate_constant)))); - m = std::min(m, n - 1); - std::vector samples(m); - double delta = 0; + m = std::min(m, n - 1); std::vector samples(m); double delta = 0; if (verbose) std::cout << n << " points in R^" << data_dimension << std::endl; if (verbose) std::cout << "Subsampling " << m << " points" << std::endl; @@ -1152,23 +1150,25 @@ class Cover_complex { * @param[in] N number of bootstrap iterations. * */ - template - void compute_distribution(int N = 100) { - if (distribution.size() >= N) { + void compute_distribution(unsigned int N = 100) { + unsigned int sz = distribution.size(); + if (sz >= N) { std::cout << "Already done!" << std::endl; } else { - for (int i = 0; i < N - distribution.size(); i++) { - Cover_complex Cboot; - Cboot.n = this->n; + for (unsigned int i = 0; i < N - sz; i++) { + if (verbose) std::cout << "Computing " << i << "th bootstrap, bottleneck distance = "; + + Cover_complex Cboot; Cboot.n = this->n; Cboot.data_dimension = this->data_dimension; Cboot.type = this->type; Cboot.functional_cover = true; + std::vector boot(this->n); for (int j = 0; j < this->n; j++) { double u = GetUniform(); - int id = std::floor(u * (this->n)); - boot[j] = id; - Cboot.point_cloud[j] = this->point_cloud[id]; - Cboot.func.push_back(this->func[id]); + int id = std::floor(u * (this->n)); boot[j] = id; + Cboot.point_cloud.push_back(this->point_cloud[id]); Cboot.cover.emplace_back(); Cboot.func.push_back(this->func[id]); + boost::add_vertex(Cboot.one_skeleton_OFF); Cboot.vertices.push_back(boost::add_vertex(Cboot.one_skeleton)); } Cboot.set_color_from_vector(Cboot.func); + for (int j = 0; j < n; j++) { std::vector dist(n); for (int k = 0; k < n; k++) dist[k] = distances[boot[j]][boot[k]]; @@ -1181,8 +1181,9 @@ class Cover_complex { Cboot.set_cover_from_function(); Cboot.find_simplices(); Cboot.compute_PD(); - - distribution.push_back(Gudhi::persistence_diagram::bottleneck_distance(this->PD, Cboot.PD)); + double db = Gudhi::persistence_diagram::bottleneck_distance(this->PD, Cboot.PD); + if (verbose) std::cout << db << std::endl; + distribution.push_back(db); } std::sort(distribution.begin(), distribution.end()); @@ -1196,7 +1197,7 @@ class Cover_complex { * */ double compute_distance_from_confidence_level(double alpha) { - int N = distribution.size(); + unsigned int N = distribution.size(); return distribution[std::floor(alpha * N)]; } @@ -1207,9 +1208,11 @@ class Cover_complex { * */ double compute_confidence_level_from_distance(double d) { - int N = distribution.size(); - for (int i = 0; i < N; i++) - if (distribution[i] > d) return i * 1.0 / N; + unsigned int N = distribution.size(); + double level = 1; + for (unsigned int i = 0; i < N; i++) + if (distribution[i] > d){ level = i * 1.0 / N; break; } + return level; } public: @@ -1221,7 +1224,9 @@ class Cover_complex { double distancemin = -std::numeric_limits::lowest(); int N = PD.size(); for (int i = 0; i < N; i++) distancemin = std::min(distancemin, 0.5 * (PD[i].second - PD[i].first)); - return 1 - compute_confidence_level_from_distance(distancemin); + double p_value = 1 - compute_confidence_level_from_distance(distancemin); + if (verbose) std::cout << "p value = " << p_value << std::endl; + return p_value; } // ******************************************************************************************************************* -- cgit v1.2.3 From 2528ddff5d820020374ece89228006409c224e78 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Mon, 28 May 2018 02:39:20 +0000 Subject: added mutex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3468 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0527349c20f3e44c4f3db196df13ccdd4c265bbb --- src/Nerve_GIC/include/gudhi/GIC.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 8834858c..4bd2c849 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -416,7 +416,7 @@ class Cover_complex { template double set_graph_from_automatic_rips(Distance distance, int N = 100) { int m = floor(n / std::exp((1 + rate_power) * std::log(std::log(n) / std::log(rate_constant)))); - m = std::min(m, n - 1); std::vector samples(m); double delta = 0; + m = std::min(m, n - 1); double delta = 0; if (verbose) std::cout << n << " points in R^" << data_dimension << std::endl; if (verbose) std::cout << "Subsampling " << m << " points" << std::endl; @@ -424,7 +424,9 @@ class Cover_complex { if (distances.size() == 0) compute_pairwise_distances(distance); #ifdef GUDHI_USE_TBB + tbb::mutex deltamutex; tbb::parallel_for(0, N, [&](int i){ + std::vector samples(m); SampleWithoutReplacement(n, m, samples); double hausdorff_dist = 0; for (int j = 0; j < n; j++) { @@ -432,10 +434,13 @@ class Cover_complex { for (int k = 1; k < m; k++) mj = std::min(mj, distances[j][samples[k]]); hausdorff_dist = std::max(hausdorff_dist, mj); } + deltamutex.lock(); delta += hausdorff_dist / N; + deltamutex.unlock(); }); #else for (int i = 0; i < N; i++) { + std::vector samples(m); SampleWithoutReplacement(n, m, samples); double hausdorff_dist = 0; for (int j = 0; j < n; j++) { @@ -718,12 +723,11 @@ class Cover_complex { } #ifdef GUDHI_USE_TBB - if (verbose) std::cout << "Computing connected components (parallelized)..." << std::endl; + if (verbose) std::cout << "Computing connected components (parallelized)..." << std::endl; tbb::mutex covermutex, idmutex; 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); + 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; @@ -737,16 +741,20 @@ class Cover_complex { int identifier = ((i + component[j])*(i + component[j]) + 3 * i + component[j]) / 2; // Update covers + covermutex.lock(); 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; + covermutex.unlock(); } // Maximal dimension is total number of connected components + idmutex.lock(); id += max + 1; + idmutex.unlock(); }); #else if (verbose) std::cout << "Computing connected components..." << std::endl; -- cgit v1.2.3 From 68b93015eaf44d45a3a85747b4f3c53bb755e8af Mon Sep 17 00:00:00 2001 From: mcarrier Date: Mon, 11 Jun 2018 02:50:07 +0000 Subject: small change in bootstrap code git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3577 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: da8a421316d545b400f82eca3f426912b4767a8d --- src/Nerve_GIC/include/gudhi/GIC.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 4bd2c849..2a50acd7 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -1184,8 +1184,8 @@ class Cover_complex { } Cboot.set_graph_from_automatic_rips(Gudhi::Euclidean_distance()); - Cboot.set_automatic_resolution(); Cboot.set_gain(); + Cboot.set_automatic_resolution(); Cboot.set_cover_from_function(); Cboot.find_simplices(); Cboot.compute_PD(); @@ -1206,7 +1206,9 @@ class Cover_complex { */ double compute_distance_from_confidence_level(double alpha) { unsigned int N = distribution.size(); - return distribution[std::floor(alpha * N)]; + double d = distribution[std::floor(alpha * N)]; + if (verbose) std::cout << "Distance corresponding to confidence " << alpha << " is " << d << std::endl; + return d; } public: @@ -1220,6 +1222,7 @@ class Cover_complex { double level = 1; for (unsigned int i = 0; i < N; i++) if (distribution[i] > d){ level = i * 1.0 / N; break; } + if (verbose) std::cout << "Confidence level of distance " << d << " is " << level << std::endl; return level; } @@ -1231,7 +1234,7 @@ class Cover_complex { double compute_p_value() { double distancemin = -std::numeric_limits::lowest(); int N = PD.size(); - for (int i = 0; i < N; i++) distancemin = std::min(distancemin, 0.5 * (PD[i].second - PD[i].first)); + for (int i = 0; i < N; i++) distancemin = std::min(distancemin, 0.5 * std::abs(PD[i].second - PD[i].first)); double p_value = 1 - compute_confidence_level_from_distance(distancemin); if (verbose) std::cout << "p value = " << p_value << std::endl; return p_value; -- cgit v1.2.3 From 5f8c3b95f41f623be2f999ce38640c39f4c448da Mon Sep 17 00:00:00 2001 From: mcarrier Date: Mon, 11 Jun 2018 08:53:27 +0000 Subject: minor change git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3578 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 262dc4f45eba9f5ada23b078d52be54b4eb60a41 --- src/Nerve_GIC/include/gudhi/GIC.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 2a50acd7..6b8df6dc 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -1232,8 +1232,7 @@ class Cover_complex { * */ double compute_p_value() { - double distancemin = -std::numeric_limits::lowest(); - int N = PD.size(); + double distancemin = 0; int N = PD.size(); for (int i = 0; i < N; i++) distancemin = std::min(distancemin, 0.5 * std::abs(PD[i].second - PD[i].first)); double p_value = 1 - compute_confidence_level_from_distance(distancemin); if (verbose) std::cout << "p value = " << p_value << std::endl; -- cgit v1.2.3 From d34354883a5021ab9beaa03f7739378caf3e5683 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Mon, 11 Jun 2018 14:43:39 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3579 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4fe9f0185421f9c2be697f0db323c042f7c8e7ca --- src/Nerve_GIC/include/gudhi/GIC.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 6b8df6dc..8cd7bdbf 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -1232,7 +1232,7 @@ class Cover_complex { * */ double compute_p_value() { - double distancemin = 0; int N = PD.size(); + double distancemin = std::numeric_limits::max(); int N = PD.size(); for (int i = 0; i < N; i++) distancemin = std::min(distancemin, 0.5 * std::abs(PD[i].second - PD[i].first)); double p_value = 1 - compute_confidence_level_from_distance(distancemin); if (verbose) std::cout << "p value = " << p_value << std::endl; -- cgit v1.2.3 From f5c97bc9fd1c247045d35ddf261f9afe4d024406 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 20 Jul 2018 15:03:46 +0000 Subject: First try at interfacing the sparse rips in python. Needs at least documentation and tests. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3697 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 75bef59e90355853ee24807ca7453c4bb0a38f43 --- src/Rips_complex/doc/Intro_rips_complex.h | 5 ++- src/Simplex_tree/include/gudhi/Simplex_tree.h | 1 + src/cython/cython/rips_complex.pyx | 50 ++++++++++++++++----------- src/cython/include/Rips_complex_interface.h | 39 ++++++++++++++------- src/cython/test/test_rips_complex.py | 1 - 5 files changed, 60 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/doc/Intro_rips_complex.h b/src/Rips_complex/doc/Intro_rips_complex.h index 712d3b6e..3db5287e 100644 --- a/src/Rips_complex/doc/Intro_rips_complex.h +++ b/src/Rips_complex/doc/Intro_rips_complex.h @@ -53,7 +53,10 @@ namespace rips_complex { * The number of simplices in the full Rips complex is exponential in the * number of vertices, it is thus usually restricted, by excluding all the * simplices with filtration value larger than some threshold, and keeping only - * the dim_max-skeleton. + * the dim_max-skeleton. It may also be a good idea to start by making the + * point set sparser, for instance with + * `Gudhi::subsampling::sparsify_point_set`, since small clusters of points + * have a disproportionate cost without affecting the persistence diagram much. * * In order to build this complex, the algorithm first builds the graph. * The filtration value of each edge is computed from a user-given distance diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index ee96d5a2..2c4c53a3 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1035,6 +1035,7 @@ class Simplex_tree { * The Simplex_tree must contain no simplex of dimension bigger than * 1 when calling the method. */ void expansion(int max_dim) { + if (max_dim <= 1) return; dimension_ = max_dim; for (Dictionary_it root_it = root_.members_.begin(); root_it != root_.members_.end(); ++root_it) { diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx index 59c16bff..620130ca 100644 --- a/src/cython/cython/rips_complex.pyx +++ b/src/cython/cython/rips_complex.pyx @@ -33,7 +33,11 @@ __license__ = "GPL v3" cdef extern from "Rips_complex_interface.h" namespace "Gudhi": cdef cppclass Rips_complex_interface "Gudhi::rips_complex::Rips_complex_interface": - Rips_complex_interface(vector[vector[double]] values, double threshold, bool euclidean) + Rips_complex_interface() + void init_points(vector[vector[double]] values, double threshold) + void init_matrix(vector[vector[double]] values, double threshold) + void init_points_sparse(vector[vector[double]] values, double threshold, double sparse) + void init_matrix_sparse(vector[vector[double]] values, double threshold, double sparse) void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, int dim_max) # RipsComplex python interface @@ -44,14 +48,14 @@ cdef class RipsComplex: function, or a distance matrix. """ - cdef Rips_complex_interface * thisptr + cdef Rips_complex_interface thisref # Fake constructor that does nothing but documenting the constructor - def __init__(self, points=None, distance_matrix=None, max_edge_length=float('inf')): + def __init__(self, points=None, distance_matrix=None, max_edge_length=float('inf'), sparse=None): """RipsComplex constructor. :param max_edge_length: Rips value. - :type max_edge_length: int + :type max_edge_length: float :param points: A list of points in d-Dimension. :type points: list of list of double @@ -61,27 +65,31 @@ cdef class RipsComplex: :param distance_matrix: A distance matrix (full square or lower triangular). :type points: list of list of double + + And in both cases + :param sparse: If this is not None, it switches to building a sparse Rips and represents the approximation parameter epsilon. + :type sparse: float """ # The real cython constructor - def __cinit__(self, points=None, distance_matrix=None, max_edge_length=float('inf')): - if distance_matrix is not None: - self.thisptr = new Rips_complex_interface(distance_matrix, max_edge_length, False) + def __cinit__(self, points=None, distance_matrix=None, max_edge_length=float('inf'), sparse=None): + if sparse is not None: + if distance_matrix is not None: + self.thisref.init_matrix_sparse(distance_matrix, max_edge_length, sparse) + else: + if points is None: + # Empty Rips construction + points=[] + self.thisref.init_points_sparse(points, max_edge_length, sparse) else: - if points is None: - # Empty Rips construction - points=[] - self.thisptr = new Rips_complex_interface(points, max_edge_length, True) - - - def __dealloc__(self): - if self.thisptr != NULL: - del self.thisptr + if distance_matrix is not None: + self.thisref.init_matrix(distance_matrix, max_edge_length) + else: + if points is None: + # Empty Rips construction + points=[] + self.thisref.init_points(points, max_edge_length) - def __is_defined(self): - """Returns true if RipsComplex pointer is not NULL. - """ - return self.thisptr != NULL def create_simplex_tree(self, max_dimension=1): """ @@ -92,5 +100,5 @@ cdef class RipsComplex: :rtype: SimplexTree """ simplex_tree = SimplexTree() - self.thisptr.create_simplex_tree(simplex_tree.thisptr, max_dimension) + self.thisref.create_simplex_tree(simplex_tree.thisptr, max_dimension) return simplex_tree diff --git a/src/cython/include/Rips_complex_interface.h b/src/cython/include/Rips_complex_interface.h index 8b6c9c35..f6fc79a1 100644 --- a/src/cython/include/Rips_complex_interface.h +++ b/src/cython/include/Rips_complex_interface.h @@ -25,8 +25,11 @@ #include #include +#include #include +#include + #include "Simplex_tree_interface.h" #include @@ -43,28 +46,38 @@ class Rips_complex_interface { using Distance_matrix = std::vector::Filtration_value>>; public: - Rips_complex_interface(const std::vector>& values, double threshold, bool euclidean) { - if (euclidean) { - // Rips construction where values is a vector of points - rips_complex_ = new Rips_complex::Filtration_value>(values, threshold, - Gudhi::Euclidean_distance()); - } else { - // Rips construction where values is a distance matrix - rips_complex_ = new Rips_complex::Filtration_value>(values, threshold); - } + void init_points(const std::vector>& points, double threshold) { + rips_complex_.emplace(points, threshold, Gudhi::Euclidean_distance()); + } + void init_matrix(const std::vector>& matrix, double threshold) { + rips_complex_.emplace(matrix, threshold); } - ~Rips_complex_interface() { - delete rips_complex_; + void init_points_sparse(const std::vector>& points, double threshold, double epsilon) { + sparse_rips_complex_.emplace(points, Gudhi::Euclidean_distance(), epsilon); + threshold_ = threshold; + } + void init_matrix_sparse(const std::vector>& matrix, double threshold, double epsilon) { + sparse_rips_complex_.emplace(matrix, epsilon); + threshold_ = threshold; } void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, int dim_max) { - rips_complex_->create_complex(*simplex_tree, dim_max); + if (rips_complex_) + rips_complex_->create_complex(*simplex_tree, dim_max); + else { + sparse_rips_complex_->create_complex(*simplex_tree, dim_max); + // This pruning should be done much earlier! It isn't that useful for sparse Rips, but it would be inconsistent not to do it. + simplex_tree->prune_above_filtration(threshold_); + } simplex_tree->initialize_filtration(); } private: - Rips_complex::Filtration_value>* rips_complex_; + // std::variant would work, but we don't require C++17 yet, and boost::variant is not super convenient. Anyway, storing a graph would make more sense. Or changing the interface completely so there is no such storage. + boost::optional::Filtration_value>> rips_complex_; + boost::optional::Filtration_value>> sparse_rips_complex_; + double threshold_; }; } // namespace rips_complex diff --git a/src/cython/test/test_rips_complex.py b/src/cython/test/test_rips_complex.py index c37b5400..2eb1c61c 100755 --- a/src/cython/test/test_rips_complex.py +++ b/src/cython/test/test_rips_complex.py @@ -30,7 +30,6 @@ __license__ = "GPL v3" def test_empty_rips(): rips_complex = RipsComplex() - assert rips_complex.__is_defined() == True def test_rips_from_points(): point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] -- cgit v1.2.3 From d52036da23f887d56d13dd4f93c1049eb44301b1 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 3 Aug 2018 09:41:38 +0000 Subject: plot persistence density functionnality with its documentation Fix some documentation issue in other graphiacl tools Add scipy as a dependency git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3736 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6481f1d6aa176bcf587f8875298a91cd22ac0319 --- src/cython/cython/persistence_graphical_tools.py | 74 +++++++++++++++++++++- src/cython/doc/persistence_graphical_tools_ref.rst | 1 + .../doc/persistence_graphical_tools_user.rst | 9 ++- src/cython/setup.py.in | 1 + 4 files changed, 80 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 216ab8d6..7f604368 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -1,7 +1,9 @@ import matplotlib.pyplot as plt import matplotlib.patches as mpatches import numpy as np +from scipy.stats import kde import os +import math """This file is part of the Gudhi Library. The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ @@ -79,6 +81,8 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). A reasonable value is between 0.05 and 0.5 - default is 0.1. :type inf_delta: float. + :param legend: Display the dimension color legend (default is False). + :type legend: boolean. :returns: A matplotlib object containing horizontal bar plot of persistence (launch `show()` method on it to display it). """ @@ -154,6 +158,8 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). A reasonable value is between 0.05 and 0.5 - default is 0.1. :type inf_delta: float. + :param legend: Display the dimension color legend (default is False). + :type legend: boolean. :returns: A matplotlib object containing diagram plot of persistence (launch `show()` method on it to display it). """ @@ -174,7 +180,6 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] (min_birth, max_death) = __min_birth_max_death(persistence, band) - ind = 0 delta = ((max_death - min_birth) * inf_delta) # Replace infinity values with max_death + delta for diagram to be more # readable @@ -201,7 +206,6 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, # Infinite death case for diagram to be nicer plt.scatter(interval[1][0], infinity, alpha=alpha, color = palette[interval[0]]) - ind = ind + 1 if legend: dimensions = list(set(item[0] for item in persistence)) @@ -213,3 +217,69 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, # Ends plot on infinity value and starts a little bit before min_birth plt.axis([axis_start, infinity, axis_start, infinity + delta]) return plt + +def plot_persistence_density(persistence=[], persistence_file='', nbins=300, + max_plots=1000, cmap=plt.cm.hot_r, legend=False): + """This function plots the persistence density from persistence values list + or from a :doc:`persistence file `. Be aware that this + function does not distinguish the dimension, it is up to you to select the + required one. + + :param persistence: Persistence values list. + :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A :doc:`persistence file ` style name + (reset persistence if both are set). + :type persistence_file: string + :param nbins: Evaluate a gaussian kde on a regular grid of nbins x nbins + over data extents (default is 300) + :type nbins: int. + :param max_plots: number of maximal plots to be displayed + Set it to 0 to see all, Default value is 1000. + (persistence will be sorted by life time if max_plots is set) + :type max_plots: int. + :param cmap: A matplotlib colormap (default is matplotlib.pyplot.cm.hot_r). + :type cmap: cf. matplotlib colormap. + :param legend: Display the color bar values (default is False). + :type legend: boolean. + :returns: A matplotlib object containing diagram plot of persistence + (launch `show()` method on it to display it). + """ + if persistence_file is not '': + if os.path.isfile(persistence_file): + # Reset persistence + persistence = [] + diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) + for key in diag.keys(): + for persistence_interval in diag[key]: + persistence.append((key, persistence_interval)) + else: + print("file " + persistence_file + " not found.") + return None + + if max_plots > 0 and max_plots < len(persistence): + # Sort by life time, then takes only the max_plots elements + persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] + + # Set as numpy array birth and death (remove undefined values - inf and NaN) + birth = np.asarray([(interval[1][0]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + death = np.asarray([(interval[1][1]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + + # line display of equation : birth = death + x = np.linspace(death.min(), birth.max(), 1000) + plt.plot(x, x, color='k', linewidth=1.0) + + # Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents + k = kde.gaussian_kde([birth,death]) + xi, yi = np.mgrid[birth.min():birth.max():nbins*1j, death.min():death.max():nbins*1j] + zi = k(np.vstack([xi.flatten(), yi.flatten()])) + + # Make the plot + plt.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) + + if legend: + plt.colorbar() + + plt.title('Persistence density') + plt.xlabel('Birth') + plt.ylabel('Death') + return plt diff --git a/src/cython/doc/persistence_graphical_tools_ref.rst b/src/cython/doc/persistence_graphical_tools_ref.rst index a2c6bcef..54aff4bc 100644 --- a/src/cython/doc/persistence_graphical_tools_ref.rst +++ b/src/cython/doc/persistence_graphical_tools_ref.rst @@ -9,3 +9,4 @@ Persistence graphical tools reference manual .. autofunction:: gudhi.__min_birth_max_death .. autofunction:: gudhi.plot_persistence_barcode .. autofunction:: gudhi.plot_persistence_diagram +.. autofunction:: gudhi.plot_persistence_density diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index 292915eb..b21de06a 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -43,6 +43,9 @@ This function can display the persistence result as a diagram: legend=True) plt.show() +Persistence density +------------------- + If you want more information on a specific dimension, for instance: .. plot:: @@ -56,7 +59,7 @@ If you want more information on a specific dimension, for instance: gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file=\ persistence_file) dim = 1 - # Display all points with some transparency - plt = gudhi.plot_persistence_diagram([(dim,interval) for interval in diag[dim]], - max_plots=0, alpha=0.1) + # Display persistence density + plt = gudhi.plot_persistence_density([(dim,interval) for interval in diag[dim]], + max_plots=0, legend=True) plt.show() diff --git a/src/cython/setup.py.in b/src/cython/setup.py.in index ee381a1b..22b2954e 100644 --- a/src/cython/setup.py.in +++ b/src/cython/setup.py.in @@ -49,6 +49,7 @@ setup( install_requires = [ "matplotlib", "numpy", + "scipy", "cython", ], ) -- cgit v1.2.3 From feb6244de8f602e36fe101eb553ad5a6265665ee Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 3 Aug 2018 09:55:26 +0000 Subject: Add SciPy as a dependency in the installation process documentation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3737 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2d9d2c3f32ba3af5e9565f89e986ac437370b68e --- src/cython/doc/installation.rst | 9 ++++++++- src/cython/doc/persistence_graphical_tools_sum.inc | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst index 43ff85c5..ff6c7273 100644 --- a/src/cython/doc/installation.rst +++ b/src/cython/doc/installation.rst @@ -143,7 +143,7 @@ The following examples require the `Matplotlib `_: * :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>` * :download:`euclidean_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py>` -Numpy +NumPy ===== The :doc:`persistence graphical tools ` @@ -164,6 +164,13 @@ The following examples require the `NumPy `_: * :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>` * :download:`euclidean_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py>` +SciPy +===== + +The :doc:`persistence graphical tools ` +module requires `SciPy `_, a Python-based ecosystem of +open-source software for mathematics, science, and engineering. + Threading Building Blocks ========================= diff --git a/src/cython/doc/persistence_graphical_tools_sum.inc b/src/cython/doc/persistence_graphical_tools_sum.inc index d602daa7..c793a352 100644 --- a/src/cython/doc/persistence_graphical_tools_sum.inc +++ b/src/cython/doc/persistence_graphical_tools_sum.inc @@ -1,11 +1,11 @@ ================================================================= =================================== =================================== :Author: Vincent Rouvreau :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 -:Requires: Matplotlib Numpy +:Requires: Matplotlib Numpy Scipy ================================================================= =================================== =================================== +-----------------------------------------------------------------+-----------------------------------------------------------------------+ | .. figure:: | These graphical tools comes on top of persistence results and allows | -| img/graphical_tools_representation.png | the user to build easily barcode and persistence diagram. | +| img/graphical_tools_representation.png | the user to build easily persistence barcode, diagram or density. | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------------+ | :doc:`persistence_graphical_tools_user` | :doc:`persistence_graphical_tools_ref` | -- cgit v1.2.3 From 2f10f837b791a1b002a18f1ba2b22de918eb54fe Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 16 Aug 2018 13:40:06 +0000 Subject: Code review : Try to import module. Functions are unavailable if not available. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3785 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 53c89a30f7992aa8d20e8330628c03291cea6473 --- .../modules/GUDHI_third_party_libraries.cmake | 1 + src/cython/CMakeLists.txt | 8 +- src/cython/cython/persistence_graphical_tools.py | 202 +++++++++++---------- 3 files changed, 108 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index f03c2177..1ad0c1fd 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -143,6 +143,7 @@ if( PYTHONINTERP_FOUND ) find_python_module("pytest") find_python_module("matplotlib") find_python_module("numpy") + find_python_module("scipy") endif() if(NOT GUDHI_CYTHON_PATH) diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 1849a6ec..542be9b0 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -54,10 +54,8 @@ if(CYTHON_FOUND) if(NUMPY_FOUND) add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}") endif() - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") + if(SCIPY_FOUND) + add_gudhi_debug_info("Scipy version ${SCIPY_VERSION}") endif() message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_VERSION} - Sphinx is ${SPHINX_PATH}") @@ -368,7 +366,7 @@ if(CYTHON_FOUND) add_gudhi_py_test(test_reader_utils) # Documentation generation is available through sphinx - requires all modules - if(SPHINX_PATH AND MATPLOTLIB_FOUND AND NUMPY_FOUND AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + if(SPHINX_PATH AND MATPLOTLIB_FOUND AND NUMPY_FOUND AND SCIPY_FOUND AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") # User warning - Sphinx is a static pages generator, and configured to work fine with user_version # Images and biblio warnings because not found on developper version diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index e172c65b..e154c0b2 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -24,44 +24,42 @@ __author__ = "Vincent Rouvreau, Bertrand Michel" __copyright__ = "Copyright (C) 2016 Inria" __license__ = "GPL v3" +def __min_birth_max_death(persistence, band=0.): + """This function returns (min_birth, max_death) from the persistence. + + :param persistence: The persistence to plot. + :type persistence: list of tuples(dimension, tuple(birth, death)). + :param band: band + :type band: float. + :returns: (float, float) -- (min_birth, max_death). + """ + # Look for minimum birth date and maximum death date for plot optimisation + max_death = 0 + min_birth = persistence[0][1][0] + for interval in reversed(persistence): + if float(interval[1][1]) != float('inf'): + if float(interval[1][1]) > max_death: + max_death = float(interval[1][1]) + if float(interval[1][0]) > max_death: + max_death = float(interval[1][0]) + if float(interval[1][0]) < min_birth: + min_birth = float(interval[1][0]) + if band > 0.: + max_death += band + return (min_birth, max_death) + +""" +Only 13 colors for the palette +""" +palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00', + '#000000', '#880000', '#008800', '#000088', '#888800', '#880088', + '#008888'] + try: import matplotlib.pyplot as plt import matplotlib.patches as mpatches import numpy as np - from scipy.stats import kde import os - import math - - def __min_birth_max_death(persistence, band=0.): - """This function returns (min_birth, max_death) from the persistence. - - :param persistence: The persistence to plot. - :type persistence: list of tuples(dimension, tuple(birth, death)). - :param band: band - :type band: float. - :returns: (float, float) -- (min_birth, max_death). - """ - # Look for minimum birth date and maximum death date for plot optimisation - max_death = 0 - min_birth = persistence[0][1][0] - for interval in reversed(persistence): - if float(interval[1][1]) != float('inf'): - if float(interval[1][1]) > max_death: - max_death = float(interval[1][1]) - if float(interval[1][0]) > max_death: - max_death = float(interval[1][0]) - if float(interval[1][0]) < min_birth: - min_birth = float(interval[1][0]) - if band > 0.: - max_death += band - return (min_birth, max_death) - - """ - Only 13 colors for the palette - """ - palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00', - '#000000', '#880000', '#008800', '#000088', '#888800', '#880088', - '#008888'] def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, max_barcodes=1000, inf_delta=0.1, legend=False): @@ -220,71 +218,79 @@ try: plt.axis([axis_start, infinity, axis_start, infinity + delta]) return plt - def plot_persistence_density(persistence=[], persistence_file='', nbins=300, - max_plots=1000, cmap=plt.cm.hot_r, legend=False): - """This function plots the persistence density from persistence values list - or from a :doc:`persistence file `. Be aware that this - function does not distinguish the dimension, it is up to you to select the - required one. - - :param persistence: Persistence values list. - :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A :doc:`persistence file ` style name - (reset persistence if both are set). - :type persistence_file: string - :param nbins: Evaluate a gaussian kde on a regular grid of nbins x nbins - over data extents (default is 300) - :type nbins: int. - :param max_plots: number of maximal plots to be displayed - Set it to 0 to see all, Default value is 1000. - (persistence will be sorted by life time if max_plots is set) - :type max_plots: int. - :param cmap: A matplotlib colormap (default is matplotlib.pyplot.cm.hot_r). - :type cmap: cf. matplotlib colormap. - :param legend: Display the color bar values (default is False). - :type legend: boolean. - :returns: A matplotlib object containing diagram plot of persistence - (launch `show()` method on it to display it). - """ - if persistence_file is not '': - if os.path.isfile(persistence_file): - # Reset persistence - persistence = [] - diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) - for key in diag.keys(): - for persistence_interval in diag[key]: - persistence.append((key, persistence_interval)) - else: - print("file " + persistence_file + " not found.") - return None - - if max_plots > 0 and max_plots < len(persistence): - # Sort by life time, then takes only the max_plots elements - persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] - - # Set as numpy array birth and death (remove undefined values - inf and NaN) - birth = np.asarray([(interval[1][0]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) - death = np.asarray([(interval[1][1]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) - - # line display of equation : birth = death - x = np.linspace(death.min(), birth.max(), 1000) - plt.plot(x, x, color='k', linewidth=1.0) - - # Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents - k = kde.gaussian_kde([birth,death]) - xi, yi = np.mgrid[birth.min():birth.max():nbins*1j, death.min():death.max():nbins*1j] - zi = k(np.vstack([xi.flatten(), yi.flatten()])) - - # Make the plot - plt.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) - - if legend: - plt.colorbar() - - plt.title('Persistence density') - plt.xlabel('Birth') - plt.ylabel('Death') - return plt + try: + from scipy.stats import kde + import math + + def plot_persistence_density(persistence=[], persistence_file='', nbins=300, + max_plots=1000, cmap=plt.cm.hot_r, legend=False): + """This function plots the persistence density from persistence values list + or from a :doc:`persistence file `. Be aware that this + function does not distinguish the dimension, it is up to you to select the + required one. + + :param persistence: Persistence values list. + :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A :doc:`persistence file ` style name + (reset persistence if both are set). + :type persistence_file: string + :param nbins: Evaluate a gaussian kde on a regular grid of nbins x nbins + over data extents (default is 300) + :type nbins: int. + :param max_plots: number of maximal plots to be displayed + Set it to 0 to see all, Default value is 1000. + (persistence will be sorted by life time if max_plots is set) + :type max_plots: int. + :param cmap: A matplotlib colormap (default is matplotlib.pyplot.cm.hot_r). + :type cmap: cf. matplotlib colormap. + :param legend: Display the color bar values (default is False). + :type legend: boolean. + :returns: A matplotlib object containing diagram plot of persistence + (launch `show()` method on it to display it). + """ + if persistence_file is not '': + if os.path.isfile(persistence_file): + # Reset persistence + persistence = [] + diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) + for key in diag.keys(): + for persistence_interval in diag[key]: + persistence.append((key, persistence_interval)) + else: + print("file " + persistence_file + " not found.") + return None + + if max_plots > 0 and max_plots < len(persistence): + # Sort by life time, then takes only the max_plots elements + persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] + + # Set as numpy array birth and death (remove undefined values - inf and NaN) + birth = np.asarray([(interval[1][0]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + death = np.asarray([(interval[1][1]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + + # line display of equation : birth = death + x = np.linspace(death.min(), birth.max(), 1000) + plt.plot(x, x, color='k', linewidth=1.0) + + # Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents + k = kde.gaussian_kde([birth,death]) + xi, yi = np.mgrid[birth.min():birth.max():nbins*1j, death.min():death.max():nbins*1j] + zi = k(np.vstack([xi.flatten(), yi.flatten()])) + + # Make the plot + plt.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) + + if legend: + plt.colorbar() + + plt.title('Persistence density') + plt.xlabel('Birth') + plt.ylabel('Death') + return plt + + except ImportError: + # Continue in case of import error, functions won't be available + pass except ImportError: # Continue in case of import error, functions won't be available -- cgit v1.2.3 From efab7ccf5850ccc58018b7f856d209c4094e67c5 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 16 Aug 2018 14:35:08 +0000 Subject: Bug fix git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3788 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d8b898ca963d8d956307bb1dfd8abea1acbe6c96 --- src/cython/cython/persistence_graphical_tools.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index e154c0b2..14c4cf3f 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -205,7 +205,6 @@ try: # Infinite death case for diagram to be nicer plt.scatter(interval[1][0], infinity, alpha=alpha, color = palette[interval[0]]) - ind = ind + 1 if legend: dimensions = list(set(item[0] for item in persistence)) -- cgit v1.2.3 From b7354cd2ab0b265787348866da5d08cce15aee66 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 09:38:55 +0000 Subject: Code review : add a parameter to select dimension for plot_persistence_density. Default is None and mix all dimensions git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3794 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 493f5ecfad2bcf0ee4a40ec7b315863c471d088f --- src/cython/cython/persistence_graphical_tools.py | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 14c4cf3f..949f5c37 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -221,26 +221,31 @@ try: from scipy.stats import kde import math - def plot_persistence_density(persistence=[], persistence_file='', nbins=300, - max_plots=1000, cmap=plt.cm.hot_r, legend=False): - """This function plots the persistence density from persistence values list - or from a :doc:`persistence file `. Be aware that this - function does not distinguish the dimension, it is up to you to select the - required one. + def plot_persistence_density(persistence=[], persistence_file='', + nbins=300, max_plots=1000, dimension=None, + cmap=plt.cm.hot_r, legend=False): + """This function plots the persistence density from persistence + values list or from a :doc:`persistence file `. Be + aware that this function does not distinguish the dimension, it is + up to you to select the required one. :param persistence: Persistence values list. :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A :doc:`persistence file ` style name - (reset persistence if both are set). + :param persistence_file: A :doc:`persistence file ` + style name (reset persistence if both are set). :type persistence_file: string - :param nbins: Evaluate a gaussian kde on a regular grid of nbins x nbins - over data extents (default is 300) + :param nbins: Evaluate a gaussian kde on a regular grid of nbins x + nbins over data extents (default is 300) :type nbins: int. :param max_plots: number of maximal plots to be displayed Set it to 0 to see all, Default value is 1000. (persistence will be sorted by life time if max_plots is set) :type max_plots: int. - :param cmap: A matplotlib colormap (default is matplotlib.pyplot.cm.hot_r). + :param dimension: the dimension to be selected in the intervals + (default is None to mix all dimensions). + :type dimension: int. + :param cmap: A matplotlib colormap (default is + matplotlib.pyplot.cm.hot_r). :type cmap: cf. matplotlib colormap. :param legend: Display the color bar values (default is False). :type legend: boolean. @@ -259,13 +264,21 @@ try: print("file " + persistence_file + " not found.") return None - if max_plots > 0 and max_plots < len(persistence): + persistence_dim = [] + if dimension is not None: + persistence_dim = [(dim_interval) for dim_interval in persistence if (dim_interval[0] == dimension)] + else: + persistence_dim = persistence + + if max_plots > 0 and max_plots < len(persistence_dim): # Sort by life time, then takes only the max_plots elements - persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] + persistence_dim = sorted(persistence_dim, + key=lambda life_time: life_time[1][1]-life_time[1][0], + reverse=True)[:max_plots] # Set as numpy array birth and death (remove undefined values - inf and NaN) - birth = np.asarray([(interval[1][0]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) - death = np.asarray([(interval[1][1]) for interval in persistence if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + birth = np.asarray([(interval[1][0]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + death = np.asarray([(interval[1][1]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) # line display of equation : birth = death x = np.linspace(death.min(), birth.max(), 1000) -- cgit v1.2.3 From 1865751c055ad01ba159a13d22e42204195c2ccb Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 09:50:15 +0000 Subject: Doc review : rephrase max_plots explanation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3795 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f6059d3a242eed53dfdddb76ffed33f99892f4bc --- src/cython/cython/persistence_graphical_tools.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 949f5c37..0b3357f8 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -138,21 +138,22 @@ try: def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, band=0., max_plots=1000, inf_delta=0.1, legend=False): - """This function plots the persistence diagram from persistence values list - or from a :doc:`persistence file `. + """This function plots the persistence diagram from persistence values + list or from a :doc:`persistence file `. :param persistence: Persistence values list. :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). :type persistence_file: string - :param alpha: plot transparency value (0.0 transparent through 1.0 opaque - default is 0.6). + :param alpha: plot transparency value (0.0 transparent through 1.0 + opaque - default is 0.6). :type alpha: float. :param band: band (not displayed if :math:`\leq` 0. - default is 0.) :type band: float. - :param max_plots: number of maximal plots to be displayed - Set it to 0 to see all, Default value is 1000. - (persistence will be sorted by life time if max_plots is set) + :param max_plots: maximal number of points to display. Selected points + are those with the longest life time. Set it to 0 to see all, + default value is 1000. :type max_plots: int. :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). A reasonable value is between 0.05 and 0.5 - default is 0.1. @@ -237,9 +238,9 @@ try: :param nbins: Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents (default is 300) :type nbins: int. - :param max_plots: number of maximal plots to be displayed - Set it to 0 to see all, Default value is 1000. - (persistence will be sorted by life time if max_plots is set) + :param max_plots: maximal number of points to display. Selected points + are those with the longest life time. Set it to 0 to see all, + default value is 1000. :type max_plots: int. :param dimension: the dimension to be selected in the intervals (default is None to mix all dimensions). -- cgit v1.2.3 From 67ae5aa70e70097f72f868ebba1fa8e7ff96297d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 12:41:10 +0000 Subject: doc review : modification of persistence barcode example to make it more relevant git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3796 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 17acc09cdf7d09b13c177334efb1e309c4fd8d9c --- .../doc/persistence_graphical_tools_user.rst | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index b21de06a..0047f9c8 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -19,12 +19,15 @@ This function can display the persistence result as a barcode: import gudhi - perseus_file = gudhi.__root_source_dir__ + '/data/bitmap/3d_torus.txt' - periodic_cc = gudhi.PeriodicCubicalComplex(perseus_file=perseus_file) - diag = periodic_cc.persistence() - print("diag = ", diag) - plt = gudhi.plot_persistence_barcode(diag) - plt.show() + off_file = gudhi.__root_source_dir__ + '/data/points/tore3D_300.off' + point_cloud = gudhi.read_off(off_file=off_file) + + rips_complex = gudhi.RipsComplex(points=point_cloud, max_edge_length=0.7) + simplex_tree = rips_complex.create_simplex_tree(max_dimension=3) + diag = simplex_tree.persistence(min_persistence=0.4) + + plot = gudhi.plot_persistence_barcode(diag) + plot.show() Show persistence as a diagram ----------------------------- @@ -53,13 +56,9 @@ If you want more information on a specific dimension, for instance: import gudhi + # rips_on_tore3D_1307.pers obtained from write_persistence_diagram method persistence_file=gudhi.__root_source_dir__ + \ '/data/persistence_diagram/rips_on_tore3D_1307.pers' - diag = \ - gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file=\ - persistence_file) - dim = 1 - # Display persistence density - plt = gudhi.plot_persistence_density([(dim,interval) for interval in diag[dim]], - max_plots=0, legend=True) + plt = gudhi.plot_persistence_density(persistence_file=persistence_file, + max_plots=0, dimension=1, legend=True) plt.show() -- cgit v1.2.3 From a5464d68d2848d21fc777809ab686b1bbf4e0139 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 13:32:41 +0000 Subject: Code review : Add a bw_method parameter to plot_persistence_density for the standard deviation of the Gaussian git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3799 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3bbc988434951bb429acd44b1f31f8310bb9ba9c --- src/cython/cython/persistence_graphical_tools.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 0b3357f8..026e365d 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -223,7 +223,8 @@ try: import math def plot_persistence_density(persistence=[], persistence_file='', - nbins=300, max_plots=1000, dimension=None, + nbins=300, bw_method=None, + max_plots=1000, dimension=None, cmap=plt.cm.hot_r, legend=False): """This function plots the persistence density from persistence values list or from a :doc:`persistence file `. Be @@ -238,6 +239,14 @@ try: :param nbins: Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents (default is 300) :type nbins: int. + :param bw_method: The method used to calculate the estimator + bandwidth. This can be 'scott', 'silverman', a scalar constant + or a callable. If a scalar, this will be used directly as + kde.factor. If a callable, it should take a gaussian_kde + instance as only parameter and return a scalar. If None + (default), 'scott' is used. See scipy.stats.gaussian_kde + documentation for more details. + :type bw_method: str, scalar or callable, optional. :param max_plots: maximal number of points to display. Selected points are those with the longest life time. Set it to 0 to see all, default value is 1000. @@ -286,7 +295,7 @@ try: plt.plot(x, x, color='k', linewidth=1.0) # Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents - k = kde.gaussian_kde([birth,death]) + k = kde.gaussian_kde([birth,death], bw_method=bw_method) xi, yi = np.mgrid[birth.min():birth.max():nbins*1j, death.min():death.max():nbins*1j] zi = k(np.vstack([xi.flatten(), yi.flatten()])) -- cgit v1.2.3 From 24c661e98b8f8e0f2c492fcf63e68615dbd9ae84 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 13:45:08 +0000 Subject: Doc review : inf_delta explanation improvement git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3800 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 01fff74d79228431d77a46b713ac656ab7e84dc0 --- src/cython/cython/persistence_graphical_tools.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 026e365d..4c8467bd 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -71,14 +71,16 @@ try: :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). :type persistence_file: string - :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6). + :param alpha: barcode transparency value (0.0 transparent through 1.0 + opaque - default is 0.6). :type alpha: float. :param max_barcodes: number of maximal barcodes to be displayed. Set it to 0 to see all, Default value is 1000. (persistence will be sorted by life time if max_barcodes is set) :type max_barcodes: int. - :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). - A reasonable value is between 0.05 and 0.5 - default is 0.1. + :param inf_delta: Infinity is placed at ((max_death - min_birth) x + inf_delta) above the highest point. A reasonable value is between + 0.05 and 0.5 - default is 0.1. :type inf_delta: float. :param legend: Display the dimension color legend (default is False). :type legend: boolean. @@ -155,8 +157,9 @@ try: are those with the longest life time. Set it to 0 to see all, default value is 1000. :type max_plots: int. - :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta). - A reasonable value is between 0.05 and 0.5 - default is 0.1. + :param inf_delta: Infinity is placed at ((max_death - min_birth) x + inf_delta) above the highest point. A reasonable value is between + 0.05 and 0.5 - default is 0.1. :type inf_delta: float. :param legend: Display the dimension color legend (default is False). :type legend: boolean. -- cgit v1.2.3 From 7e1d78ec22e0e53bbf4a36aaea1b77fa48f5d40d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 13:58:46 +0000 Subject: Code review : Rename max_plots with max_intervals for persistence density git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3801 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8d20ee2f721b856bba69bc5bc10db26032649129 --- src/cython/cython/persistence_graphical_tools.py | 14 +++++++------- src/cython/doc/persistence_graphical_tools_user.rst | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 4c8467bd..96b579bd 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -250,10 +250,10 @@ try: (default), 'scott' is used. See scipy.stats.gaussian_kde documentation for more details. :type bw_method: str, scalar or callable, optional. - :param max_plots: maximal number of points to display. Selected points - are those with the longest life time. Set it to 0 to see all, - default value is 1000. - :type max_plots: int. + :param max_intervals: maximal number of intervals to display. + Selected points are those with the longest life time. Set it + to 0 to see all. Default value is 1000. + :type max_intervals: int. :param dimension: the dimension to be selected in the intervals (default is None to mix all dimensions). :type dimension: int. @@ -283,11 +283,11 @@ try: else: persistence_dim = persistence - if max_plots > 0 and max_plots < len(persistence_dim): - # Sort by life time, then takes only the max_plots elements + if max_intervals > 0 and max_intervals < len(persistence_dim): + # Sort by life time, then takes only the max_intervals elements persistence_dim = sorted(persistence_dim, key=lambda life_time: life_time[1][1]-life_time[1][0], - reverse=True)[:max_plots] + reverse=True)[:max_intervals] # Set as numpy array birth and death (remove undefined values - inf and NaN) birth = np.asarray([(interval[1][0]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index 0047f9c8..fda086c3 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -60,5 +60,5 @@ If you want more information on a specific dimension, for instance: persistence_file=gudhi.__root_source_dir__ + \ '/data/persistence_diagram/rips_on_tore3D_1307.pers' plt = gudhi.plot_persistence_density(persistence_file=persistence_file, - max_plots=0, dimension=1, legend=True) + max_intervals=0, dimension=1, legend=True) plt.show() -- cgit v1.2.3 From 6ebc098c9bbf233b5a4325faec04236feedab191 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 14:48:08 +0000 Subject: Code review : rename max_plots and max_barcodes as max_intervals for peristence_graphical_tools git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3803 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ad73f7e6cc6d72c3ba24b5ac947265c78a29f387 --- src/cython/cython/persistence_graphical_tools.py | 43 ++++++++++++++---------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 96b579bd..85d2a5ad 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -62,7 +62,8 @@ try: import os def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, - max_barcodes=1000, inf_delta=0.1, legend=False): + max_intervals=1000, max_barcodes=1000, + inf_delta=0.1, legend=False): """This function plots the persistence bar code from persistence values list or from a :doc:`persistence file `. @@ -74,10 +75,10 @@ try: :param alpha: barcode transparency value (0.0 transparent through 1.0 opaque - default is 0.6). :type alpha: float. - :param max_barcodes: number of maximal barcodes to be displayed. - Set it to 0 to see all, Default value is 1000. - (persistence will be sorted by life time if max_barcodes is set) - :type max_barcodes: int. + :param max_intervals: maximal number of intervals to display. + Selected points are those with the longest life time. Set it + to 0 to see all. Default value is 1000. + :type max_intervals: int. :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta) above the highest point. A reasonable value is between 0.05 and 0.5 - default is 0.1. @@ -99,9 +100,13 @@ try: print("file " + persistence_file + " not found.") return None - if max_barcodes > 0 and max_barcodes < len(persistence): - # Sort by life time, then takes only the max_plots elements - persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_barcodes] + if max_barcodes is not 1000: + print('Deprecated parameter. It has been replaced by max_intervals') + max_intervals = max_barcodes + + if max_intervals > 0 and max_intervals < len(persistence): + # Sort by life time, then takes only the max_intervals elements + persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_intervals] persistence = sorted(persistence, key=lambda birth: birth[1][0]) @@ -139,7 +144,7 @@ try: return plt def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, - band=0., max_plots=1000, inf_delta=0.1, legend=False): + band=0., max_intervals=1000, max_plots=1000, inf_delta=0.1, legend=False): """This function plots the persistence diagram from persistence values list or from a :doc:`persistence file `. @@ -153,10 +158,10 @@ try: :type alpha: float. :param band: band (not displayed if :math:`\leq` 0. - default is 0.) :type band: float. - :param max_plots: maximal number of points to display. Selected points - are those with the longest life time. Set it to 0 to see all, - default value is 1000. - :type max_plots: int. + :param max_intervals: maximal number of intervals to display. + Selected points are those with the longest life time. Set it + to 0 to see all. Default value is 1000. + :type max_intervals: int. :param inf_delta: Infinity is placed at ((max_death - min_birth) x inf_delta) above the highest point. A reasonable value is between 0.05 and 0.5 - default is 0.1. @@ -178,9 +183,13 @@ try: print("file " + persistence_file + " not found.") return None - if max_plots > 0 and max_plots < len(persistence): - # Sort by life time, then takes only the max_plots elements - persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_plots] + if max_plots is not 1000: + print('Deprecated parameter. It has been replaced by max_intervals') + max_intervals = max_plots + + if max_intervals > 0 and max_intervals < len(persistence): + # Sort by life time, then takes only the max_intervals elements + persistence = sorted(persistence, key=lambda life_time: life_time[1][1]-life_time[1][0], reverse=True)[:max_intervals] (min_birth, max_death) = __min_birth_max_death(persistence, band) delta = ((max_death - min_birth) * inf_delta) @@ -227,7 +236,7 @@ try: def plot_persistence_density(persistence=[], persistence_file='', nbins=300, bw_method=None, - max_plots=1000, dimension=None, + max_intervals=1000, dimension=None, cmap=plt.cm.hot_r, legend=False): """This function plots the persistence density from persistence values list or from a :doc:`persistence file `. Be -- cgit v1.2.3 From b301bf80daaac521f16d43120a8a30a2af9eb515 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 17 Aug 2018 15:29:19 +0000 Subject: Makes clearer dependencies for each function of persistence graphical tools git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3804 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7572f54368ff235f5e78df74121bf6b1ee107177 --- src/cython/doc/persistence_graphical_tools_sum.inc | 2 +- src/cython/doc/persistence_graphical_tools_user.rst | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/doc/persistence_graphical_tools_sum.inc b/src/cython/doc/persistence_graphical_tools_sum.inc index c793a352..5577cf99 100644 --- a/src/cython/doc/persistence_graphical_tools_sum.inc +++ b/src/cython/doc/persistence_graphical_tools_sum.inc @@ -1,6 +1,6 @@ ================================================================= =================================== =================================== :Author: Vincent Rouvreau :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 -:Requires: Matplotlib Numpy Scipy +:Requires: matplotlib numpy scipy ================================================================= =================================== =================================== +-----------------------------------------------------------------+-----------------------------------------------------------------------+ diff --git a/src/cython/doc/persistence_graphical_tools_user.rst b/src/cython/doc/persistence_graphical_tools_user.rst index fda086c3..b2124fdd 100644 --- a/src/cython/doc/persistence_graphical_tools_user.rst +++ b/src/cython/doc/persistence_graphical_tools_user.rst @@ -12,6 +12,9 @@ Definition Show persistence as a barcode ----------------------------- +.. note:: + this function requires matplotlib and numpy to be available + This function can display the persistence result as a barcode: .. plot:: @@ -32,6 +35,9 @@ This function can display the persistence result as a barcode: Show persistence as a diagram ----------------------------- +.. note:: + this function requires matplotlib and numpy to be available + This function can display the persistence result as a diagram: .. plot:: @@ -49,6 +55,9 @@ This function can display the persistence result as a diagram: Persistence density ------------------- +.. note:: + this function requires matplotlib, numpy and scipy to be available + If you want more information on a specific dimension, for instance: .. plot:: -- cgit v1.2.3 From 0f59a8c583ac1bd9dd37057682038f44723de104 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 30 Aug 2018 09:33:12 +0000 Subject: A thread_local was missing git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3845 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 739268e9feab840a1d8a405dad696ca95330623a --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index ee96d5a2..3ab23c12 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1057,7 +1057,10 @@ class Simplex_tree { Dictionary_it next = siblings->members().begin(); ++next; - thread_local std::vector > inter; +#ifdef GUDHI_CAN_USE_CXX11_THREAD_LOCAL + thread_local +#endif // GUDHI_CAN_USE_CXX11_THREAD_LOCAL + std::vector > inter; for (Dictionary_it s_h = siblings->members().begin(); s_h != siblings->members().end(); ++s_h, ++next) { Simplex_handle root_sh = find_vertex(s_h->first); -- cgit v1.2.3 From 30554aab477f1a189f7270326b706f09e681e24a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 09:24:41 +0000 Subject: Add debug traces git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3851 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 00f56b397048aca87422e6da9385b2622acf1094 --- src/cython/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 1849a6ec..97a99e59 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -1,7 +1,9 @@ project(Cython) function( add_gudhi_cython_lib THE_LIB ) + message("##### add_gudhi_cython_lib on ${THE_LIB}") if(EXISTS ${THE_LIB}) + message("##### EXISTS") get_filename_component(THE_LIB_FILE_NAME ${THE_LIB} NAME_WE) if(WIN32) message("++ ${THE_LIB} => THE_LIB_FILE_NAME = ${THE_LIB_FILE_NAME}") -- cgit v1.2.3 From 16c796735dafe95e4c93d80a0785f2a0a8e0e1cd Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 09:34:26 +0000 Subject: Add debug traces git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3852 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1a99305e1bfab4d86f5a10371dbad3438f3b0580 --- src/cython/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 97a99e59..37e3de79 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -132,6 +132,7 @@ if(CYTHON_FOUND) if(CGAL_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) + message("##### add_gudhi_cython_lib on ${Boost_THREAD_LIBRARY}") add_gudhi_cython_lib(${Boost_THREAD_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() @@ -141,6 +142,7 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") + message("##### add_gudhi_cython_lib on ${CGAL_LIBRARY}") add_gudhi_cython_lib(${CGAL_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, -- cgit v1.2.3 From 8d3550092122a71b70bd310d5fd9e9976bc0b9dd Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 11:07:09 +0000 Subject: Add debug traces git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3853 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e8792fc3427cb4f4e92f3297aa3f4aea57c54e60 --- src/cython/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 37e3de79..41230a69 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -132,7 +132,7 @@ if(CYTHON_FOUND) if(CGAL_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - message("##### add_gudhi_cython_lib on ${Boost_THREAD_LIBRARY}") + message("##### add_gudhi_cython_lib Boost_THREAD_LIBRARY - ${Boost_THREAD_LIBRARY}") add_gudhi_cython_lib(${Boost_THREAD_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() @@ -142,10 +142,11 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") - message("##### add_gudhi_cython_lib on ${CGAL_LIBRARY}") + message("##### add_gudhi_cython_lib CGAL_LIBRARY - ${CGAL_LIBRARY}") add_gudhi_cython_lib(${CGAL_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, + message("##### add_gudhi_cython_lib Boost_SYSTEM_LIBRARY - ${Boost_SYSTEM_LIBRARY}") add_gudhi_cython_lib(${Boost_SYSTEM_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif(CGAL_HEADER_ONLY) @@ -153,6 +154,7 @@ if(CYTHON_FOUND) if(GMP_FOUND) add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") + message("##### add_gudhi_cython_lib GMP_LIBRARIES - ${GMP_LIBRARIES}") add_gudhi_cython_lib(${GMP_LIBRARIES}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") if(GMPXX_FOUND) -- cgit v1.2.3 From 6048f92357bbce6de009c2441d9354e5f2f4b8ae Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 11:16:58 +0000 Subject: Add CGAL_LIBRARIES git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3854 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0b8ee8cf61dca1b74481d556615e55caa39246ae --- src/cython/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 41230a69..50355f84 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -142,6 +142,8 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") + message("##### add_gudhi_cython_lib CGAL_LIBRARIES - ${CGAL_LIBRARIES}") + add_gudhi_cython_lib(${CGAL_LIBRARIES}) message("##### add_gudhi_cython_lib CGAL_LIBRARY - ${CGAL_LIBRARY}") add_gudhi_cython_lib(${CGAL_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") -- cgit v1.2.3 From fd7e0464bde1a357fda43ced4ff26b36bdc58a56 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 11:23:50 +0000 Subject: Pass parameters to cmake function through double quote for unset variables case git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3855 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 57ff4e884e6575cc7938da3937a7a0090567ad74 --- src/cython/CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 50355f84..f9eccaa3 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -133,7 +133,7 @@ if(CYTHON_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) message("##### add_gudhi_cython_lib Boost_THREAD_LIBRARY - ${Boost_THREAD_LIBRARY}") - add_gudhi_cython_lib(${Boost_THREAD_LIBRARY}) + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() # Add CGAL compilation args @@ -143,13 +143,13 @@ if(CYTHON_FOUND) else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") message("##### add_gudhi_cython_lib CGAL_LIBRARIES - ${CGAL_LIBRARIES}") - add_gudhi_cython_lib(${CGAL_LIBRARIES}) + add_gudhi_cython_lib("${CGAL_LIBRARIES}") message("##### add_gudhi_cython_lib CGAL_LIBRARY - ${CGAL_LIBRARY}") - add_gudhi_cython_lib(${CGAL_LIBRARY}) + add_gudhi_cython_lib("${CGAL_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, message("##### add_gudhi_cython_lib Boost_SYSTEM_LIBRARY - ${Boost_SYSTEM_LIBRARY}") - add_gudhi_cython_lib(${Boost_SYSTEM_LIBRARY}) + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif(CGAL_HEADER_ONLY) # GMP and GMPXX are not required, but if present, CGAL will link with them. @@ -157,12 +157,12 @@ if(CYTHON_FOUND) add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") message("##### add_gudhi_cython_lib GMP_LIBRARIES - ${GMP_LIBRARIES}") - add_gudhi_cython_lib(${GMP_LIBRARIES}) + add_gudhi_cython_lib("${GMP_LIBRARIES}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") if(GMPXX_FOUND) add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") - add_gudhi_cython_lib(${GMPXX_LIBRARIES}) + add_gudhi_cython_lib("${GMPXX_LIBRARIES}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") endif(GMPXX_FOUND) endif(GMP_FOUND) @@ -184,8 +184,8 @@ if(CYTHON_FOUND) if (TBB_FOUND AND WITH_GUDHI_USE_TBB) add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") - add_gudhi_cython_lib(${TBB_RELEASE_LIBRARY}) - add_gudhi_cython_lib(${TBB_MALLOC_RELEASE_LIBRARY}) + add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") endif() -- cgit v1.2.3 From 2ffe7a5477803025b3de2abf59725d8dc2588f73 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 11:38:56 +0000 Subject: Try with boost release and debug lib versions git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3856 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 130a4319577ef0ec8c10a87c98b7ffcf6f16d808 --- src/cython/CMakeLists.txt | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index f9eccaa3..fb613639 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -132,8 +132,14 @@ if(CYTHON_FOUND) if(CGAL_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - message("##### add_gudhi_cython_lib Boost_THREAD_LIBRARY - ${Boost_THREAD_LIBRARY}") - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY}") + message("##### Boost_THREAD_LIBRARY - ${Boost_THREAD_LIBRARY}") + if(CMAKE_BUILD_TYPE MATCHES Debug) + message("##### Boost_THREAD_LIBRARY_DEBUG - ${Boost_THREAD_LIBRARY_DEBUG}") + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") + else() + message("##### Boost_THREAD_LIBRARY_RELEASE - ${Boost_THREAD_LIBRARY_RELEASE}") + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") + endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() # Add CGAL compilation args @@ -142,14 +148,20 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") - message("##### add_gudhi_cython_lib CGAL_LIBRARIES - ${CGAL_LIBRARIES}") + message("##### CGAL_LIBRARIES - ${CGAL_LIBRARIES}") add_gudhi_cython_lib("${CGAL_LIBRARIES}") - message("##### add_gudhi_cython_lib CGAL_LIBRARY - ${CGAL_LIBRARY}") + message("##### CGAL_LIBRARY - ${CGAL_LIBRARY}") add_gudhi_cython_lib("${CGAL_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, - message("##### add_gudhi_cython_lib Boost_SYSTEM_LIBRARY - ${Boost_SYSTEM_LIBRARY}") - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY}") + message("##### Boost_SYSTEM_LIBRARY - ${Boost_SYSTEM_LIBRARY}") + if(CMAKE_BUILD_TYPE MATCHES Debug) + message("##### Boost_SYSTEM_LIBRARY_DEBUG - ${Boost_SYSTEM_LIBRARY_DEBUG}") + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") + else() + message("##### Boost_SYSTEM_LIBRARY_RELEASE - ${Boost_SYSTEM_LIBRARY_RELEASE}") + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif(CGAL_HEADER_ONLY) # GMP and GMPXX are not required, but if present, CGAL will link with them. -- cgit v1.2.3 From c5b865f6e9e1ae60de2720c76aee1dfccf470023 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 11:59:31 +0000 Subject: Works fine in debug and release mode git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_cgal_non_header_only_compilation_issue@3857 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2cc11e2a6e7f8eed6c234c17cad7ff04efdbc659 --- src/cython/CMakeLists.txt | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index fb613639..90a2fcf7 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -1,9 +1,7 @@ project(Cython) function( add_gudhi_cython_lib THE_LIB ) - message("##### add_gudhi_cython_lib on ${THE_LIB}") if(EXISTS ${THE_LIB}) - message("##### EXISTS") get_filename_component(THE_LIB_FILE_NAME ${THE_LIB} NAME_WE) if(WIN32) message("++ ${THE_LIB} => THE_LIB_FILE_NAME = ${THE_LIB_FILE_NAME}") @@ -132,12 +130,9 @@ if(CYTHON_FOUND) if(CGAL_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - message("##### Boost_THREAD_LIBRARY - ${Boost_THREAD_LIBRARY}") if(CMAKE_BUILD_TYPE MATCHES Debug) - message("##### Boost_THREAD_LIBRARY_DEBUG - ${Boost_THREAD_LIBRARY_DEBUG}") add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") else() - message("##### Boost_THREAD_LIBRARY_RELEASE - ${Boost_THREAD_LIBRARY_RELEASE}") add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") @@ -148,18 +143,13 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") - message("##### CGAL_LIBRARIES - ${CGAL_LIBRARIES}") add_gudhi_cython_lib("${CGAL_LIBRARIES}") - message("##### CGAL_LIBRARY - ${CGAL_LIBRARY}") add_gudhi_cython_lib("${CGAL_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, - message("##### Boost_SYSTEM_LIBRARY - ${Boost_SYSTEM_LIBRARY}") if(CMAKE_BUILD_TYPE MATCHES Debug) - message("##### Boost_SYSTEM_LIBRARY_DEBUG - ${Boost_SYSTEM_LIBRARY_DEBUG}") add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") else() - message("##### Boost_SYSTEM_LIBRARY_RELEASE - ${Boost_SYSTEM_LIBRARY_RELEASE}") add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") @@ -168,7 +158,6 @@ if(CYTHON_FOUND) if(GMP_FOUND) add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") - message("##### add_gudhi_cython_lib GMP_LIBRARIES - ${GMP_LIBRARIES}") add_gudhi_cython_lib("${GMP_LIBRARIES}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") if(GMPXX_FOUND) -- cgit v1.2.3 From ec9100908202bb5b7a6ba835edeabf3272d70e98 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 31 Aug 2018 12:38:13 +0000 Subject: Link with release third parties library version, even in debug mode git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3863 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e33e15081b3029d9dfd4edc464d91b0db47e1754 --- src/cython/CMakeLists.txt | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 90a2fcf7..cf57d872 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -130,11 +130,7 @@ if(CYTHON_FOUND) if(CGAL_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") - else() - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") - endif() + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() # Add CGAL compilation args @@ -143,15 +139,10 @@ if(CYTHON_FOUND) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") - add_gudhi_cython_lib("${CGAL_LIBRARIES}") add_gudhi_cython_lib("${CGAL_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, - if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") - else() - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") - endif() + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif(CGAL_HEADER_ONLY) # GMP and GMPXX are not required, but if present, CGAL will link with them. -- cgit v1.2.3 From fa19484e31dbe0b63d50475f15e654a5e1a0c4e1 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 4 Sep 2018 09:34:24 +0000 Subject: Use debug or release version to link with python package git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3871 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: afbd5c833ddc3a525d7091ab186714825109eb87 --- CMakeGUDHIVersion.txt | 2 +- src/cython/CMakeLists.txt | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt index 3ddc907a..ebaddd47 100644 --- a/CMakeGUDHIVersion.txt +++ b/CMakeGUDHIVersion.txt @@ -1,6 +1,6 @@ set (GUDHI_MAJOR_VERSION 2) set (GUDHI_MINOR_VERSION 3) -set (GUDHI_PATCH_VERSION 0.rc3) +set (GUDHI_PATCH_VERSION 0) set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION}) message(STATUS "GUDHI version : ${GUDHI_VERSION}") diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index cf57d872..09ea28f1 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -130,7 +130,11 @@ if(CYTHON_FOUND) if(CGAL_FOUND) can_cgal_use_cxx11_thread_local() if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") + else() + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") + endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() # Add CGAL compilation args @@ -142,7 +146,11 @@ if(CYTHON_FOUND) add_gudhi_cython_lib("${CGAL_LIBRARY}") set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") + else() + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif(CGAL_HEADER_ONLY) # GMP and GMPXX are not required, but if present, CGAL will link with them. @@ -176,8 +184,13 @@ if(CYTHON_FOUND) if (TBB_FOUND AND WITH_GUDHI_USE_TBB) add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") - add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") - add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${TBB_DEBUG_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_DEBUG_LIBRARY}") + else() + add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") + endif() set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") endif() -- cgit v1.2.3 From 44aaa06e1da4a2e4557886c9c7096edbe9d00f53 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 10 Sep 2018 08:37:45 +0000 Subject: Doc review : Add a link to scipy.stats.gaussian_kde official documentation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3878 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: dd6e1a4131be1ed0306a48f9b095e0d09ddee848 --- src/cython/cython/persistence_graphical_tools.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 85d2a5ad..f5550e3a 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -256,8 +256,10 @@ try: or a callable. If a scalar, this will be used directly as kde.factor. If a callable, it should take a gaussian_kde instance as only parameter and return a scalar. If None - (default), 'scott' is used. See scipy.stats.gaussian_kde - documentation for more details. + (default), 'scott' is used. See + `scipy.stats.gaussian_kde documentation + `_ + for more details. :type bw_method: str, scalar or callable, optional. :param max_intervals: maximal number of intervals to display. Selected points are those with the longest life time. Set it -- cgit v1.2.3 From 629a456684e9bbf4c2ef5dbfefebe85e9c04a39d Mon Sep 17 00:00:00 2001 From: glisse Date: Mon, 10 Sep 2018 09:23:07 +0000 Subject: Add minimal testing for sparse rips in python git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3879 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 14cde17f1ef634539937b215e82bcfe3c8c784f0 --- src/cython/test/test_rips_complex.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/cython/test/test_rips_complex.py b/src/cython/test/test_rips_complex.py index 2eb1c61c..73cdac17 100755 --- a/src/cython/test/test_rips_complex.py +++ b/src/cython/test/test_rips_complex.py @@ -67,6 +67,18 @@ def test_filtered_rips_from_points(): assert simplex_tree.num_simplices() == 8 assert simplex_tree.num_vertices() == 4 +def test_sparse_filtered_rips_from_points(): + point_list = [[0, 0], [1, 0], [0, 1], [1, 1]] + filtered_rips = RipsComplex(points=point_list, max_edge_length=1.0, sparse=.001) + + simplex_tree = filtered_rips.create_simplex_tree(max_dimension=1) + + assert simplex_tree.__is_defined() == True + assert simplex_tree.__is_persistence_defined() == False + + assert simplex_tree.num_simplices() == 8 + assert simplex_tree.num_vertices() == 4 + def test_rips_from_distance_matrix(): distance_matrix = [[0], [1, 0], -- cgit v1.2.3 From 4bf56301ea1aa0c43855bea88344c80db237adbb Mon Sep 17 00:00:00 2001 From: glisse Date: Mon, 10 Sep 2018 09:29:57 +0000 Subject: sparse rips example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3880 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8dfc1b3218d3ac3e97a04bf25e59e2d48fc8db1d --- .../example/sparse_rips_persistence_diagram.py | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 src/cython/example/sparse_rips_persistence_diagram.py (limited to 'src') diff --git a/src/cython/example/sparse_rips_persistence_diagram.py b/src/cython/example/sparse_rips_persistence_diagram.py new file mode 100755 index 00000000..3bed87c1 --- /dev/null +++ b/src/cython/example/sparse_rips_persistence_diagram.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +import gudhi + +"""This file is part of the Gudhi Library. The Gudhi library + (Geometric Understanding in Higher Dimensions) is a generic C++ + library for computational topology. + + Author(s): Marc Glisse + + Copyright (C) 2016 Inria + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +""" + +__author__ = "Marc Glisse" +__copyright__ = "Copyright (C) 2016 Inria" +__license__ = "GPL v3" + +print("#####################################################################") +print("RipsComplex creation from points") +rips = gudhi.RipsComplex(points=[[0, 0], [0, 0.1], [1, 0], [0, 1], [1, 1]], + max_edge_length=42, sparse=.5) + +simplex_tree = rips.create_simplex_tree(max_dimension=2) + + +diag = simplex_tree.persistence(homology_coeff_field=2, min_persistence=0) +print("diag=", diag) + +pplot = gudhi.plot_persistence_diagram(diag) +pplot.show() -- cgit v1.2.3 From bdbbbc71e7d82526b24f76cc3b9916ad53919d41 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 10 Sep 2018 09:32:00 +0000 Subject: Code review : More explicit message when import fails in plot persistence graphical tools git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3881 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 96f9e3da3bd68d6cba65242b9890c4beb463c863 --- src/cython/cython/persistence_graphical_tools.py | 309 ++++++++++++----------- 1 file changed, 161 insertions(+), 148 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index f5550e3a..e66643d2 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -55,39 +55,39 @@ palette = ['#ff0000', '#00ff00', '#0000ff', '#00ffff', '#ff00ff', '#ffff00', '#000000', '#880000', '#008800', '#000088', '#888800', '#880088', '#008888'] -try: - import matplotlib.pyplot as plt - import matplotlib.patches as mpatches - import numpy as np - import os - - def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, - max_intervals=1000, max_barcodes=1000, - inf_delta=0.1, legend=False): - """This function plots the persistence bar code from persistence values list - or from a :doc:`persistence file `. - - :param persistence: Persistence values list. - :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A :doc:`persistence file ` style name - (reset persistence if both are set). - :type persistence_file: string - :param alpha: barcode transparency value (0.0 transparent through 1.0 - opaque - default is 0.6). - :type alpha: float. - :param max_intervals: maximal number of intervals to display. - Selected points are those with the longest life time. Set it - to 0 to see all. Default value is 1000. - :type max_intervals: int. - :param inf_delta: Infinity is placed at ((max_death - min_birth) x - inf_delta) above the highest point. A reasonable value is between - 0.05 and 0.5 - default is 0.1. - :type inf_delta: float. - :param legend: Display the dimension color legend (default is False). - :type legend: boolean. - :returns: A matplotlib object containing horizontal bar plot of persistence - (launch `show()` method on it to display it). - """ +def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, + max_intervals=1000, max_barcodes=1000, + inf_delta=0.1, legend=False): + """This function plots the persistence bar code from persistence values list + or from a :doc:`persistence file `. + + :param persistence: Persistence values list. + :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A :doc:`persistence file ` style name + (reset persistence if both are set). + :type persistence_file: string + :param alpha: barcode transparency value (0.0 transparent through 1.0 + opaque - default is 0.6). + :type alpha: float. + :param max_intervals: maximal number of intervals to display. + Selected points are those with the longest life time. Set it + to 0 to see all. Default value is 1000. + :type max_intervals: int. + :param inf_delta: Infinity is placed at ((max_death - min_birth) x + inf_delta) above the highest point. A reasonable value is between + 0.05 and 0.5 - default is 0.1. + :type inf_delta: float. + :param legend: Display the dimension color legend (default is False). + :type legend: boolean. + :returns: A matplotlib object containing horizontal bar plot of persistence + (launch `show()` method on it to display it). + """ + try: + import matplotlib.pyplot as plt + import matplotlib.patches as mpatches + import numpy as np + import os + if persistence_file is not '': if os.path.isfile(persistence_file): # Reset persistence @@ -143,34 +143,43 @@ try: plt.axis([axis_start, infinity, 0, ind]) return plt - def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, - band=0., max_intervals=1000, max_plots=1000, inf_delta=0.1, legend=False): - """This function plots the persistence diagram from persistence values - list or from a :doc:`persistence file `. - - :param persistence: Persistence values list. - :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A :doc:`persistence file ` style name - (reset persistence if both are set). - :type persistence_file: string - :param alpha: plot transparency value (0.0 transparent through 1.0 - opaque - default is 0.6). - :type alpha: float. - :param band: band (not displayed if :math:`\leq` 0. - default is 0.) - :type band: float. - :param max_intervals: maximal number of intervals to display. - Selected points are those with the longest life time. Set it - to 0 to see all. Default value is 1000. - :type max_intervals: int. - :param inf_delta: Infinity is placed at ((max_death - min_birth) x - inf_delta) above the highest point. A reasonable value is between - 0.05 and 0.5 - default is 0.1. - :type inf_delta: float. - :param legend: Display the dimension color legend (default is False). - :type legend: boolean. - :returns: A matplotlib object containing diagram plot of persistence - (launch `show()` method on it to display it). - """ + except ImportError: + print("This function is not available, you may be missing numpy and/or matplotlib.") + +def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, + band=0., max_intervals=1000, max_plots=1000, inf_delta=0.1, legend=False): + """This function plots the persistence diagram from persistence values + list or from a :doc:`persistence file `. + + :param persistence: Persistence values list. + :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A :doc:`persistence file ` style name + (reset persistence if both are set). + :type persistence_file: string + :param alpha: plot transparency value (0.0 transparent through 1.0 + opaque - default is 0.6). + :type alpha: float. + :param band: band (not displayed if :math:`\leq` 0. - default is 0.) + :type band: float. + :param max_intervals: maximal number of intervals to display. + Selected points are those with the longest life time. Set it + to 0 to see all. Default value is 1000. + :type max_intervals: int. + :param inf_delta: Infinity is placed at ((max_death - min_birth) x + inf_delta) above the highest point. A reasonable value is between + 0.05 and 0.5 - default is 0.1. + :type inf_delta: float. + :param legend: Display the dimension color legend (default is False). + :type legend: boolean. + :returns: A matplotlib object containing diagram plot of persistence + (launch `show()` method on it to display it). + """ + try: + import matplotlib.pyplot as plt + import matplotlib.patches as mpatches + import numpy as np + import os + if persistence_file is not '': if os.path.isfile(persistence_file): # Reset persistence @@ -230,104 +239,108 @@ try: plt.axis([axis_start, infinity, axis_start, infinity + delta]) return plt + except ImportError: + print("This function is not available, you may be missing numpy and/or matplotlib.") + +def plot_persistence_density(persistence=[], persistence_file='', + nbins=300, bw_method=None, + max_intervals=1000, dimension=None, + cmap=None, legend=False): + """This function plots the persistence density from persistence + values list or from a :doc:`persistence file `. Be + aware that this function does not distinguish the dimension, it is + up to you to select the required one. + + :param persistence: Persistence values list. + :type persistence: list of tuples(dimension, tuple(birth, death)). + :param persistence_file: A :doc:`persistence file ` + style name (reset persistence if both are set). + :type persistence_file: string + :param nbins: Evaluate a gaussian kde on a regular grid of nbins x + nbins over data extents (default is 300) + :type nbins: int. + :param bw_method: The method used to calculate the estimator + bandwidth. This can be 'scott', 'silverman', a scalar constant + or a callable. If a scalar, this will be used directly as + kde.factor. If a callable, it should take a gaussian_kde + instance as only parameter and return a scalar. If None + (default), 'scott' is used. See + `scipy.stats.gaussian_kde documentation + `_ + for more details. + :type bw_method: str, scalar or callable, optional. + :param max_intervals: maximal number of intervals to display. + Selected points are those with the longest life time. Set it + to 0 to see all. Default value is 1000. + :type max_intervals: int. + :param dimension: the dimension to be selected in the intervals + (default is None to mix all dimensions). + :type dimension: int. + :param cmap: A matplotlib colormap (default is + matplotlib.pyplot.cm.hot_r). + :type cmap: cf. matplotlib colormap. + :param legend: Display the color bar values (default is False). + :type legend: boolean. + :returns: A matplotlib object containing diagram plot of persistence + (launch `show()` method on it to display it). + """ try: + import matplotlib.pyplot as plt + import numpy as np from scipy.stats import kde + import os import math - def plot_persistence_density(persistence=[], persistence_file='', - nbins=300, bw_method=None, - max_intervals=1000, dimension=None, - cmap=plt.cm.hot_r, legend=False): - """This function plots the persistence density from persistence - values list or from a :doc:`persistence file `. Be - aware that this function does not distinguish the dimension, it is - up to you to select the required one. - - :param persistence: Persistence values list. - :type persistence: list of tuples(dimension, tuple(birth, death)). - :param persistence_file: A :doc:`persistence file ` - style name (reset persistence if both are set). - :type persistence_file: string - :param nbins: Evaluate a gaussian kde on a regular grid of nbins x - nbins over data extents (default is 300) - :type nbins: int. - :param bw_method: The method used to calculate the estimator - bandwidth. This can be 'scott', 'silverman', a scalar constant - or a callable. If a scalar, this will be used directly as - kde.factor. If a callable, it should take a gaussian_kde - instance as only parameter and return a scalar. If None - (default), 'scott' is used. See - `scipy.stats.gaussian_kde documentation - `_ - for more details. - :type bw_method: str, scalar or callable, optional. - :param max_intervals: maximal number of intervals to display. - Selected points are those with the longest life time. Set it - to 0 to see all. Default value is 1000. - :type max_intervals: int. - :param dimension: the dimension to be selected in the intervals - (default is None to mix all dimensions). - :type dimension: int. - :param cmap: A matplotlib colormap (default is - matplotlib.pyplot.cm.hot_r). - :type cmap: cf. matplotlib colormap. - :param legend: Display the color bar values (default is False). - :type legend: boolean. - :returns: A matplotlib object containing diagram plot of persistence - (launch `show()` method on it to display it). - """ - if persistence_file is not '': - if os.path.isfile(persistence_file): - # Reset persistence - persistence = [] - diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) - for key in diag.keys(): - for persistence_interval in diag[key]: - persistence.append((key, persistence_interval)) - else: - print("file " + persistence_file + " not found.") - return None - - persistence_dim = [] - if dimension is not None: - persistence_dim = [(dim_interval) for dim_interval in persistence if (dim_interval[0] == dimension)] + if persistence_file is not '': + if os.path.isfile(persistence_file): + # Reset persistence + persistence = [] + diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file) + for key in diag.keys(): + for persistence_interval in diag[key]: + persistence.append((key, persistence_interval)) else: - persistence_dim = persistence + print("file " + persistence_file + " not found.") + return None - if max_intervals > 0 and max_intervals < len(persistence_dim): - # Sort by life time, then takes only the max_intervals elements - persistence_dim = sorted(persistence_dim, - key=lambda life_time: life_time[1][1]-life_time[1][0], - reverse=True)[:max_intervals] + persistence_dim = [] + if dimension is not None: + persistence_dim = [(dim_interval) for dim_interval in persistence if (dim_interval[0] == dimension)] + else: + persistence_dim = persistence - # Set as numpy array birth and death (remove undefined values - inf and NaN) - birth = np.asarray([(interval[1][0]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) - death = np.asarray([(interval[1][1]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + if max_intervals > 0 and max_intervals < len(persistence_dim): + # Sort by life time, then takes only the max_intervals elements + persistence_dim = sorted(persistence_dim, + key=lambda life_time: life_time[1][1]-life_time[1][0], + reverse=True)[:max_intervals] - # line display of equation : birth = death - x = np.linspace(death.min(), birth.max(), 1000) - plt.plot(x, x, color='k', linewidth=1.0) + # Set as numpy array birth and death (remove undefined values - inf and NaN) + birth = np.asarray([(interval[1][0]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) + death = np.asarray([(interval[1][1]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))]) - # Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents - k = kde.gaussian_kde([birth,death], bw_method=bw_method) - xi, yi = np.mgrid[birth.min():birth.max():nbins*1j, death.min():death.max():nbins*1j] - zi = k(np.vstack([xi.flatten(), yi.flatten()])) + # line display of equation : birth = death + x = np.linspace(death.min(), birth.max(), 1000) + plt.plot(x, x, color='k', linewidth=1.0) - # Make the plot - plt.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) + # Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents + k = kde.gaussian_kde([birth,death], bw_method=bw_method) + xi, yi = np.mgrid[birth.min():birth.max():nbins*1j, death.min():death.max():nbins*1j] + zi = k(np.vstack([xi.flatten(), yi.flatten()])) - if legend: - plt.colorbar() + # default cmap value cannot be done at argument definition level as matplotlib is not yet defined. + if cmap is None: + cmap = plt.cm.hot_r + # Make the plot + plt.pcolormesh(xi, yi, zi.reshape(xi.shape), cmap=cmap) - plt.title('Persistence density') - plt.xlabel('Birth') - plt.ylabel('Death') - return plt + if legend: + plt.colorbar() - except ImportError: - # Continue in case of import error, functions won't be available - pass + plt.title('Persistence density') + plt.xlabel('Birth') + plt.ylabel('Death') + return plt -except ImportError: - # Continue in case of import error, functions won't be available - pass + except ImportError: + print("This function is not available, you may be missing numpy, matplotlib and/or scipy.") -- cgit v1.2.3 From 24683e8d0134e7ede7033f05b83c44dd72ff7e3a Mon Sep 17 00:00:00 2001 From: mcarrier Date: Tue, 18 Sep 2018 22:01:20 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3897 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f5fe42a6f42443ca7217c69f8a18780cdb85669e --- src/Nerve_GIC/include/gudhi/GIC.h | 18 ++++++++++++++++++ src/cython/cython/nerve_gic.pyx | 9 +++++++++ 2 files changed, 27 insertions(+) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 2c37dfae..242ecf7d 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -389,6 +389,24 @@ class Cover_complex { distances[index[boost::source(*ei, one_skeleton)]][index[boost::target(*ei, one_skeleton)]]); } + public: + /** \brief Reads and stores the distance matrices from vector stored in memory. + * + * @param[in] distance_matrix input vector representing the distance matrix. + * + */ + template + void set_distances_from_range(InputRange const & distance_matrix) { + n = distance_matrix.size(); data_dimension = 0; point_cloud_name = "matrix"; + for(int i = 0; i < n; i++){ + point_cloud.emplace_back(); + boost::add_vertex(one_skeleton_OFF); + vertices.push_back(boost::add_vertex(one_skeleton)); + cover.emplace_back(); + } + distances = distance_matrix; + } + public: // Pairwise distances. /** \private \brief Computes all pairwise distances. */ diff --git a/src/cython/cython/nerve_gic.pyx b/src/cython/cython/nerve_gic.pyx index 01dd0a4b..5f01b379 100644 --- a/src/cython/cython/nerve_gic.pyx +++ b/src/cython/cython/nerve_gic.pyx @@ -68,6 +68,7 @@ cdef extern from "Nerve_gic_interface.h" namespace "Gudhi": void plot_DOT() void plot_OFF() void set_point_cloud_from_range(vector[vector[double]] cloud) + void set_distances_from_range(vector[vector[double]] distance_matrix) # CoverComplex python interface cdef class CoverComplex: @@ -111,6 +112,14 @@ cdef class CoverComplex: """ return self.thisptr.set_point_cloud_from_range(cloud) + def set_distances_from_range(self, distance_matrix): + """ Reads and stores the input distance matrix from a vector stored in memory. + + :param distance_matrix: Input vector containing the distance matrix. + :type distance_matrix: vector[vector[double]] + """ + return self.thisptr.set_distances_from_range(distance_matrix) + def compute_confidence_level_from_distance(self, distance): """Computes the confidence level of a specific bottleneck distance threshold. -- cgit v1.2.3 From cae907acde52894ea1a20f3a0c0c22538c1b4128 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Thu, 20 Sep 2018 21:44:01 +0000 Subject: fixed small bug on persistence diagrams git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@3901 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: cbeecd2f928b4c4df13acf5a7a2083882fdc98d2 --- src/Nerve_GIC/include/gudhi/GIC.h | 55 +++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 242ecf7d..30f89d65 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -397,12 +397,16 @@ class Cover_complex { */ template void set_distances_from_range(InputRange const & distance_matrix) { - n = distance_matrix.size(); data_dimension = 0; point_cloud_name = "matrix"; - for(int i = 0; i < n; i++){ - point_cloud.emplace_back(); - boost::add_vertex(one_skeleton_OFF); - vertices.push_back(boost::add_vertex(one_skeleton)); - cover.emplace_back(); + if(point_cloud.size() == 0){ + n = distance_matrix.size(); + point_cloud_name = "matrix"; + data_dimension = 0; + for(int i = 0; i < n; i++){ + point_cloud.emplace_back(); + boost::add_vertex(one_skeleton_OFF); + vertices.push_back(boost::add_vertex(one_skeleton)); + cover.emplace_back(); + } } distances = distance_matrix; } @@ -536,9 +540,17 @@ class Cover_complex { * */ void set_function_from_coordinate(int 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); + if(point_cloud[0].size() > 0){ + for (int i = 0; i < n; i++) func.push_back(point_cloud[i][k]); + functional_cover = true; + cover_name = "coordinate " + std::to_string(k); + } + else{ + std::cout << "Only pairwise distances provided---cannot access " << k << "th coordinate; returning null vector instead" << std::endl; + for (int i = 0; i < n; i++) func.push_back(0.0); + functional_cover = true; + cover_name = "null"; + } } public: // Set function from vector. @@ -989,9 +1001,17 @@ class Cover_complex { * */ void set_color_from_coordinate(int k = 0) { - 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)); + if(point_cloud[0].size() > 0){ + 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)); + } + else{ + std::cout << "Only pairwise distances provided---cannot access " << k << "th coordinate; returning null vector instead" << std::endl; + for (int i = 0; i < n; i++) func.push_back(0.0); + functional_cover = true; + cover_name = "null"; + } } public: // Set color from vector. @@ -1157,15 +1177,18 @@ class Cover_complex { // Build filtration for (auto const& simplex : simplices) { - std::vector splx = simplex; splx.push_back(-2); + std::vector splx = simplex; + splx.push_back(-2); st.insert_simplex_and_subfaces(splx, -3); } 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)); + if(st.find(vert) != st.null_simplex()){ + st.assign_filtration(st.find(vert), -2 + (val - minf)/(maxf - minf)); + st.assign_filtration(st.find(edge), 2 - (val - minf)/(maxf - minf)); + } } st.make_filtration_non_decreasing(); @@ -1267,7 +1290,7 @@ class Cover_complex { unsigned int N = distribution.size(); double level = 1; for (unsigned int i = 0; i < N; i++) - if (distribution[i] > d){ level = i * 1.0 / N; break; } + if (distribution[i] >= d){ level = i * 1.0 / N; break; } if (verbose) std::cout << "Confidence level of distance " << d << " is " << level << std::endl; return level; } -- cgit v1.2.3 From d95c0d8f3d28067527116a2c1eac06f5bf083995 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 28 Sep 2018 09:00:25 +0000 Subject: https://gitlab.inria.fr/GUDHI/gudhi-devel/issues/32 - [Cmake - Qt5] CMake outputs an error when Qt5 is not installed Modify/add cmake messages for missing modules git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cmake_missing_modules_clarification_vincent@3912 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 37e1035f7c27ce994e05386801d72959696de7d4 --- CMakeLists.txt | 12 +- src/CMakeLists.txt | 12 +- src/GudhUI/CMakeLists.txt | 81 ++- src/cmake/modules/GUDHI_doxygen_target.cmake | 8 +- src/cmake/modules/GUDHI_modules.cmake | 5 +- .../modules/GUDHI_third_party_libraries.cmake | 4 +- src/cython/CMakeLists.txt | 681 +++++++++++---------- 7 files changed, 434 insertions(+), 369 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index afacede9..d61df992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,10 @@ include(CMakeGUDHIVersion.txt) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") +# Reset cache +set(GUDHI_MODULES "" CACHE INTERNAL "GUDHI_MODULES") +set(GUDHI_MISSING_MODULES "" CACHE INTERNAL "GUDHI_MISSING_MODULES") + # This variable is used by Cython CMakeLists.txt and by GUDHI_third_party_libraries to know its path set(GUDHI_CYTHON_PATH "src/cython") @@ -37,8 +41,6 @@ add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) -message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") - # Include module CMake subdirectories # GUDHI_SUB_DIRECTORIES is managed in CMAKE_MODULE_PATH/GUDHI_modules.cmake foreach(GUDHI_MODULE ${GUDHI_MODULES}) @@ -54,9 +56,15 @@ add_subdirectory(src/GudhUI) if (WITH_GUDHI_PYTHON) # specific for cython module add_subdirectory(${GUDHI_CYTHON_PATH}) +else() + message("++ Python module will not be compiled because WITH_GUDHI_PYTHON is set to OFF") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python") endif() # For "make user_version" - Requires GUDHI_modules to be performed include(GUDHI_user_version_target) # For "make doxygen" - Requires GUDHI_USER_VERSION_DIR to be set - Done in GUDHI_user_version_target for dev version include(GUDHI_doxygen_target) + +message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") +message("++ GUDHI_MISSING_MODULES list is:\"${GUDHI_MISSING_MODULES}\"") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c446104..b40d506a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,9 @@ include(CMakeGUDHIVersion.txt) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") +set(GUDHI_MODULES "" CACHE INTERNAL "GUDHI_MODULES") +set(GUDHI_MISSING_MODULES "" CACHE INTERNAL "GUDHI_MISSING_MODULES") + # This variable is used by Cython CMakeLists.txt and by GUDHI_third_party_libraries to know its path set(GUDHI_CYTHON_PATH "cython") @@ -35,8 +38,6 @@ add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) -message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") - # For "make doxygen" - Requires GUDHI_USER_VERSION_DIR to be set set(GUDHI_USER_VERSION_DIR ${CMAKE_SOURCE_DIR}) include(GUDHI_doxygen_target) @@ -60,7 +61,14 @@ add_subdirectory(GudhUI) if (WITH_GUDHI_PYTHON) # specific for cython module add_subdirectory(${GUDHI_CYTHON_PATH}) +else() + message("++ Python module will not be compiled because WITH_GUDHI_PYTHON is set to OFF") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python") endif() + +message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") +message("++ GUDHI_MISSING_MODULES list is:\"${GUDHI_MISSING_MODULES}\"") + #--------------------------------------------------------------------------------------- #--------------------------------------------------------------------------------------- diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt index b357b8f7..0945e758 100644 --- a/src/GudhUI/CMakeLists.txt +++ b/src/GudhUI/CMakeLists.txt @@ -1,40 +1,55 @@ project(GudhUI) # Need to find OpenGL first as find_package(Qt5) tries to #include"GL/gl.h" on some platforms -find_package(OpenGL) +find_package(OpenGL QUIET) if (OPENGL_FOUND) - find_package(Qt5 COMPONENTS Widgets Xml OpenGL) - find_package(QGLViewer) - - if ( CGAL_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND NOT CGAL_VERSION VERSION_EQUAL 4.8.0) - - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTOUIC ON) - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - SET(Boost_USE_STATIC_LIBS ON) - SET(Boost_USE_MULTITHREAD OFF) - include_directories (${QGLVIEWER_INCLUDE_DIR}) - - add_executable ( GudhUI - gui/gudhui.cpp - gui/MainWindow.cpp - gui/Menu_k_nearest_neighbors.cpp - gui/Menu_uniform_neighbors.cpp - gui/Menu_edge_contraction.cpp - gui/Menu_persistence.cpp - view/Viewer_instructor.cpp - view/Viewer.cpp - ) - target_link_libraries( GudhUI Qt5::Widgets Qt5::Xml Qt5::OpenGL ) - target_link_libraries( GudhUI ${QGLVIEWER_LIBRARIES} ) - target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) - if (TBB_FOUND) - target_link_libraries( GudhUI ${TBB_LIBRARIES}) + find_package(Qt5 COMPONENTS Widgets Xml OpenGL QUIET) + if (Qt5_FOUND) + find_package(QGLViewer QUIET) + if ( QGLVIEWER_FOUND) + + if ( CGAL_FOUND AND NOT CGAL_VERSION VERSION_EQUAL 4.8.0) + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTOUIC ON) + set(CMAKE_INCLUDE_CURRENT_DIR ON) + + SET(Boost_USE_STATIC_LIBS ON) + SET(Boost_USE_MULTITHREAD OFF) + include_directories (${QGLVIEWER_INCLUDE_DIR}) + + add_executable ( GudhUI + gui/gudhui.cpp + gui/MainWindow.cpp + gui/Menu_k_nearest_neighbors.cpp + gui/Menu_uniform_neighbors.cpp + gui/Menu_edge_contraction.cpp + gui/Menu_persistence.cpp + view/Viewer_instructor.cpp + view/Viewer.cpp + ) + target_link_libraries( GudhUI Qt5::Widgets Qt5::Xml Qt5::OpenGL ) + target_link_libraries( GudhUI ${QGLVIEWER_LIBRARIES} ) + target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) + if (TBB_FOUND) + target_link_libraries( GudhUI ${TBB_LIBRARIES}) + endif() + + install(TARGETS GudhUI DESTINATION bin) + set(GUDHI_MODULES ${GUDHI_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MODULES") + else() + message("++ GudhUI will not be compiled because CGAL < 4.8.0 or not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif() + else() + message("++ GudhUI will not be compiled because QGLViewer is not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() - - install(TARGETS GudhUI DESTINATION bin) - + else() + message("++ GudhUI will not be compiled because Qt5 COMPONENTS Widgets Xml OpenGL are not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() -endif(OPENGL_FOUND) +else() + message("++ GudhUI will not be compiled because OpenGL is not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") +endif() diff --git a/src/cmake/modules/GUDHI_doxygen_target.cmake b/src/cmake/modules/GUDHI_doxygen_target.cmake index 9e10e566..7a84c4e0 100644 --- a/src/cmake/modules/GUDHI_doxygen_target.cmake +++ b/src/cmake/modules/GUDHI_doxygen_target.cmake @@ -1,7 +1,7 @@ # add a target to generate API documentation with Doxygen -find_package(Doxygen) +find_package(Doxygen QUIET) if(DOXYGEN_FOUND) - # configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + set(GUDHI_MODULES ${GUDHI_MODULES} "cpp-documentation" CACHE INTERNAL "GUDHI_MODULES") # starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated if(TARGET Doxygen::doxygen) @@ -16,4 +16,6 @@ if(DOXYGEN_FOUND) # In dev version, doxygen target depends on user_version target. Not existing in user version add_dependencies(doxygen user_version) endif() -endif(DOXYGEN_FOUND) +else() + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "cpp-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") +endif() diff --git a/src/cmake/modules/GUDHI_modules.cmake b/src/cmake/modules/GUDHI_modules.cmake index f95d0c34..aab1dd08 100644 --- a/src/cmake/modules/GUDHI_modules.cmake +++ b/src/cmake/modules/GUDHI_modules.cmake @@ -1,11 +1,12 @@ # A function to add a new module in GUDHI -set(GUDHI_MODULES "") set(GUDHI_MODULES_FULL_LIST "") function(add_gudhi_module file_path) option("WITH_MODULE_GUDHI_${file_path}" "Activate/desactivate ${file_path} compilation and installation" ON) if (WITH_MODULE_GUDHI_${file_path}) - set(GUDHI_MODULES ${GUDHI_MODULES} ${file_path} PARENT_SCOPE) + set(GUDHI_MODULES ${GUDHI_MODULES} ${file_path} CACHE INTERNAL "GUDHI_MODULES") + else() + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} ${file_path} CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() # Required by user_version set(GUDHI_MODULES_FULL_LIST ${GUDHI_MODULES_FULL_LIST} ${file_path} PARENT_SCOPE) diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index f03c2177..122754d5 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -21,11 +21,11 @@ endif() # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html # but it implies to use cmake version 3.1 at least. -find_package(CGAL) +find_package(CGAL QUIET) # 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.") + message("++ CGAL version ${CGAL_VERSION} is considered too old to be used by Gudhi.") unset(CGAL_FOUND) endif() if(CGAL_FOUND) diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 09ea28f1..8fcd6cbf 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -31,375 +31,406 @@ function( add_gudhi_debug_info DEBUG_INFO ) set(GUDHI_CYTHON_DEBUG_INFO "${GUDHI_CYTHON_DEBUG_INFO} \"${DEBUG_INFO}\\n\" \\\n" PARENT_SCOPE) endfunction( add_gudhi_debug_info ) - -if(CYTHON_FOUND) - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}off_reader;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}simplex_tree;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}rips_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}cubical_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}periodic_cubical_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}reader_utils;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}witness_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}strong_witness_complex;") - - add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}") - add_gudhi_debug_info("Cython version ${CYTHON_VERSION}") - if(PYTEST_FOUND) - add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}") - endif() - if(MATPLOTLIB_FOUND) - add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}") - endif() - if(NUMPY_FOUND) - add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}") - endif() - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) +if(PYTHONINTERP_FOUND) + if(CYTHON_FOUND) + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}off_reader;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}simplex_tree;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}rips_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}cubical_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}periodic_cubical_complex;") set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - endif() + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}reader_utils;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}witness_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}strong_witness_complex;") + + add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}") + add_gudhi_debug_info("Cython version ${CYTHON_VERSION}") + if(PYTEST_FOUND) + add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}") + endif() + if(MATPLOTLIB_FOUND) + add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}") + endif() + if(NUMPY_FOUND) + add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}") + endif() + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") + endif() - message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_VERSION} - Sphinx is ${SPHINX_PATH}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_SYSTEM_NO_DEPRECATED', ") - - # Gudhi and CGAL compilation option - if(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") - else(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") - endif(MSVC) - if(CMAKE_COMPILER_IS_GNUCXX) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") - endif(CMAKE_COMPILER_IS_GNUCXX) - if (CMAKE_CXX_COMPILER_ID MATCHES Intel) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") - endif(CMAKE_CXX_COMPILER_ID MATCHES Intel) - if (DEBUG_TRACES) - # For programs to be more verbose - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") - endif() + message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_VERSION} - Sphinx is ${SPHINX_PATH}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_SYSTEM_NO_DEPRECATED', ") + + # Gudhi and CGAL compilation option + if(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") + else(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") + endif(MSVC) + if(CMAKE_COMPILER_IS_GNUCXX) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") + endif(CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_ID MATCHES Intel) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") + endif(CMAKE_CXX_COMPILER_ID MATCHES Intel) + if (DEBUG_TRACES) + # For programs to be more verbose + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") + endif() - if (EIGEN3_FOUND) - add_gudhi_debug_info("Eigen3 version ${EIGEN3_VERSION}") - # No problem, even if no CGAL found - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") - endif (EIGEN3_FOUND) - - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) - set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/bottleneck_distance.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}bottleneck_distance;") - set(GUDHI_CYTHON_NERVE_GIC "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/nerve_gic.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}nerve_gic;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}bottleneck_distance;") - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}nerve_gic;") - endif () - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - set(GUDHI_CYTHON_SUBSAMPLING "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/subsampling.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}subsampling;") - set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/tangential_complex.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}tangential_complex;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}subsampling;") - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}tangential_complex;") - endif () - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) - set(GUDHI_CYTHON_ALPHA_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/alpha_complex.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}alpha_complex;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}alpha_complex;") - endif () - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) - set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX - "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_witness_complex.pyx'\ninclude '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_strong_witness_complex.pyx'\n") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_witness_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_strong_witness_complex;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_witness_complex;") - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_strong_witness_complex;") - endif () - - add_gudhi_debug_info("Installed modules are: ${GUDHI_CYTHON_MODULES}") - if(GUDHI_CYTHON_MISSING_MODULES) - add_gudhi_debug_info("Missing modules are: ${GUDHI_CYTHON_MISSING_MODULES}") - endif() + if (EIGEN3_FOUND) + add_gudhi_debug_info("Eigen3 version ${EIGEN3_VERSION}") + # No problem, even if no CGAL found + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") + endif (EIGEN3_FOUND) + + if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/bottleneck_distance.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}bottleneck_distance;") + set(GUDHI_CYTHON_NERVE_GIC "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/nerve_gic.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}nerve_gic;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}bottleneck_distance;") + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}nerve_gic;") + endif () + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + set(GUDHI_CYTHON_SUBSAMPLING "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/subsampling.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}subsampling;") + set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/tangential_complex.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}tangential_complex;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}subsampling;") + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}tangential_complex;") + endif () + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + set(GUDHI_CYTHON_ALPHA_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/alpha_complex.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}alpha_complex;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}alpha_complex;") + endif () + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX + "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_witness_complex.pyx'\ninclude '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_strong_witness_complex.pyx'\n") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_witness_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_strong_witness_complex;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_witness_complex;") + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_strong_witness_complex;") + endif () - if(CGAL_FOUND) - can_cgal_use_cxx11_thread_local() - if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") - else() - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") - endif() - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + add_gudhi_debug_info("Installed modules are: ${GUDHI_CYTHON_MODULES}") + if(GUDHI_CYTHON_MISSING_MODULES) + add_gudhi_debug_info("Missing modules are: ${GUDHI_CYTHON_MISSING_MODULES}") endif() - # Add CGAL compilation args - if(CGAL_HEADER_ONLY) - add_gudhi_debug_info("CGAL header only version ${CGAL_VERSION}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") - else(CGAL_HEADER_ONLY) - add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") - add_gudhi_cython_lib("${CGAL_LIBRARY}") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") - # If CGAL is not header only, CGAL library may link with boost system, + + if(CGAL_FOUND) + can_cgal_use_cxx11_thread_local() + if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") + else() + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") + endif() + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + endif() + # Add CGAL compilation args + if(CGAL_HEADER_ONLY) + add_gudhi_debug_info("CGAL header only version ${CGAL_VERSION}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") + else(CGAL_HEADER_ONLY) + add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") + add_gudhi_cython_lib("${CGAL_LIBRARY}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") + # If CGAL is not header only, CGAL library may link with boost system, + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") + else() + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + endif() + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + endif(CGAL_HEADER_ONLY) + # GMP and GMPXX are not required, but if present, CGAL will link with them. + if(GMP_FOUND) + add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") + add_gudhi_cython_lib("${GMP_LIBRARIES}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") + if(GMPXX_FOUND) + add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") + add_gudhi_cython_lib("${GMPXX_LIBRARIES}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") + endif(GMPXX_FOUND) + endif(GMP_FOUND) + endif(CGAL_FOUND) + + # Specific for Mac + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-mmacosx-version-min=10.12', ") + set(GUDHI_CYTHON_EXTRA_LINK_ARGS "${GUDHI_CYTHON_EXTRA_LINK_ARGS}'-mmacosx-version-min=10.12', ") + endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + + # Loop on INCLUDE_DIRECTORIES PROPERTY + get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") + endforeach() + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") + + if (TBB_FOUND AND WITH_GUDHI_USE_TBB) + add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") + add_gudhi_cython_lib("${TBB_DEBUG_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_DEBUG_LIBRARY}") else() - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") endif() - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") - endif(CGAL_HEADER_ONLY) - # GMP and GMPXX are not required, but if present, CGAL will link with them. - if(GMP_FOUND) - add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") - add_gudhi_cython_lib("${GMP_LIBRARIES}") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") - if(GMPXX_FOUND) - add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") - add_gudhi_cython_lib("${GMPXX_LIBRARIES}") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") - endif(GMPXX_FOUND) - endif(GMP_FOUND) - endif(CGAL_FOUND) - - # Specific for Mac - if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-mmacosx-version-min=10.12', ") - set(GUDHI_CYTHON_EXTRA_LINK_ARGS "${GUDHI_CYTHON_EXTRA_LINK_ARGS}'-mmacosx-version-min=10.12', ") - endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - # Loop on INCLUDE_DIRECTORIES PROPERTY - get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) - foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") - endforeach() - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") - - if (TBB_FOUND AND WITH_GUDHI_USE_TBB) - add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") - if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${TBB_DEBUG_LIBRARY}") - add_gudhi_cython_lib("${TBB_MALLOC_DEBUG_LIBRARY}") - else() - add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") - add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") endif() - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") - endif() - if(UNIX) - set( GUDHI_CYTHON_RUNTIME_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}") - endif(UNIX) - - # Generate setup.py file to cythonize Gudhi - This file must be named setup.py by convention - configure_file(setup.py.in "${CMAKE_CURRENT_BINARY_DIR}/setup.py" @ONLY) - # Generate gudhi.pyx - Gudhi cython file - configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) - - add_custom_command( - OUTPUT gudhi.so - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/setup.py" "build_ext" "--inplace") - - add_custom_target(cython ALL DEPENDS gudhi.so - COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") - - # For installation purpose - # TODO(VR) : files matching pattern mechanism is copying all cython directory - install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DESTINATION "${PYTHON_SITE_PACKAGES}/" FILES_MATCHING - PATTERN "*.so" - PATTERN "*.dylib" - PATTERN "*.pyd") - - # Test examples - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - # Bottleneck and Alpha - add_test(NAME alpha_rips_persistence_bottleneck_distance_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" - -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) + if(UNIX) + set( GUDHI_CYTHON_RUNTIME_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}") + endif(UNIX) + + # Generate setup.py file to cythonize Gudhi - This file must be named setup.py by convention + configure_file(setup.py.in "${CMAKE_CURRENT_BINARY_DIR}/setup.py" @ONLY) + # Generate gudhi.pyx - Gudhi cython file + configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) + + add_custom_command( + OUTPUT gudhi.so + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/setup.py" "build_ext" "--inplace") + + add_custom_target(cython ALL DEPENDS gudhi.so + COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") + + # For installation purpose + # TODO(VR) : files matching pattern mechanism is copying all cython directory + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DESTINATION "${PYTHON_SITE_PACKAGES}/" FILES_MATCHING + PATTERN "*.so" + PATTERN "*.dylib" + PATTERN "*.pyd") + + # Test examples + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + # Bottleneck and Alpha + add_test(NAME alpha_rips_persistence_bottleneck_distance_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" + -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) + + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + # Tangential + add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" + --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) + + add_gudhi_py_test(test_tangential_complex) + + # Witness complex AND Subsampling + add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + + add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + endif() - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - # Tangential - add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test + # Subsampling + add_gudhi_py_test(test_subsampling) + + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + # Bottleneck + add_test(NAME bottleneck_basic_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" - --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/bottleneck_basic_example.py") - add_gudhi_py_test(test_tangential_complex) + add_gudhi_py_test(test_bottleneck_distance) - # Witness complex AND Subsampling - add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test + # Cover complex + file(COPY ${CMAKE_SOURCE_DIR}/data/points/human.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + add_test(NAME cover_complex_nerve_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/nerve_of_a_covering.py" + -f human.off -c 2 -r 10 -g 0.3) - add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test + add_test(NAME cover_complex_coordinate_gic_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) - endif() + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/coordinate_graph_induced_complex.py" + -f human.off -c 0 -v) - # Subsampling - add_gudhi_py_test(test_subsampling) + add_test(NAME cover_complex_functional_gic_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/functional_graph_induced_complex.py" + -o lucky_cat.off + -f lucky_cat_PCA1 -v) - endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # Bottleneck - add_test(NAME bottleneck_basic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/bottleneck_basic_example.py") + add_test(NAME cover_complex_voronoi_gic_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/voronoi_graph_induced_complex.py" + -f human.off -n 700 -v) - add_gudhi_py_test(test_bottleneck_distance) + add_gudhi_py_test(test_cover_complex) + endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # Cover complex - file(COPY ${CMAKE_SOURCE_DIR}/data/points/human.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - add_test(NAME cover_complex_nerve_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/nerve_of_a_covering.py" - -f human.off -c 2 -r 10 -g 0.3) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + # Alpha + add_test(NAME alpha_complex_from_points_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") - add_test(NAME cover_complex_coordinate_gic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/coordinate_graph_induced_complex.py" - -f human.off -c 0 -v) + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) + endif() - add_test(NAME cover_complex_functional_gic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/functional_graph_induced_complex.py" - -o lucky_cat.off - -f lucky_cat_PCA1 -v) + add_gudhi_py_test(test_alpha_complex) - add_test(NAME cover_complex_voronoi_gic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/voronoi_graph_induced_complex.py" - -f human.off -n 700 -v) + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) - add_gudhi_py_test(test_cover_complex) - endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + # Euclidean witness + add_gudhi_py_test(test_euclidean_witness_complex) - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) - # Alpha - add_test(NAME alpha_complex_from_points_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + # Cubical + add_test(NAME periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) - endif() - - add_gudhi_py_test(test_alpha_complex) + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" + --no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) - endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + if(NUMPY_FOUND) + add_test(NAME random_cubical_complex_persistence_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py" + 10 10 10) + endif() - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) - # Euclidean witness - add_gudhi_py_test(test_euclidean_witness_complex) + add_gudhi_py_test(test_cubical_complex) - endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + # Rips + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) - # Cubical - add_test(NAME periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" - --no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) + add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3) + endif() - if(NUMPY_FOUND) - add_test(NAME random_cubical_complex_persistence_example_py_test + add_test(NAME rips_complex_from_points_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py" - 10 10 10) - endif() + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_from_points_example.py) - add_gudhi_py_test(test_cubical_complex) + add_gudhi_py_test(test_rips_complex) - # Rips - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) - - add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test + # Simplex tree + add_test(NAME simplex_tree_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3) - endif() - - add_test(NAME rips_complex_from_points_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_from_points_example.py) - - add_gudhi_py_test(test_rips_complex) - - # Simplex tree - add_test(NAME simplex_tree_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/simplex_tree_example.py) - - add_gudhi_py_test(test_simplex_tree) + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/simplex_tree_example.py) - # Witness - add_test(NAME witness_complex_from_nearest_landmark_table_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/witness_complex_from_nearest_landmark_table.py) + add_gudhi_py_test(test_simplex_tree) - add_gudhi_py_test(test_witness_complex) - - # Reader utils - add_gudhi_py_test(test_reader_utils) - - # Documentation generation is available through sphinx - requires all modules - if(SPHINX_PATH AND MATPLOTLIB_FOUND AND NUMPY_FOUND AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") - # User warning - Sphinx is a static pages generator, and configured to work fine with user_version - # Images and biblio warnings because not found on developper version - if (GUDHI_CYTHON_PATH STREQUAL "src/cython") - set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") - endif() - # sphinx target requires gudhi.so, because conf.py reads gudhi version from it - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) - - add_test(NAME sphinx_py_test + # Witness + add_test(NAME witness_complex_from_nearest_landmark_table_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) - - endif() -endif(CYTHON_FOUND) + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/witness_complex_from_nearest_landmark_table.py) + + add_gudhi_py_test(test_witness_complex) + + # Reader utils + add_gudhi_py_test(test_reader_utils) + + # Documentation generation is available through sphinx - requires all modules + if(SPHINX_PATH) + if(MATPLOTLIB_FOUND) + if(NUMPY_FOUND) + if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") + # User warning - Sphinx is a static pages generator, and configured to work fine with user_version + # Images and biblio warnings because not found on developper version + if (GUDHI_CYTHON_PATH STREQUAL "src/cython") + set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") + endif() + # sphinx target requires gudhi.so, because conf.py reads gudhi version from it + add_custom_target(sphinx + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) + + add_test(NAME sphinx_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) + + # Set missing or not modules + set(GUDHI_MODULES ${GUDHI_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MODULES") + else(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + message("++ Python documentation module will not be compiled because it requires a CGAL with Eigen3 version greater or equal than 4.8.1") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + else(NUMPY_FOUND) + message("++ Python module will not be compiled because numpy was not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(NUMPY_FOUND) + else(MATPLOTLIB_FOUND) + message("++ Python module will not be compiled because matplotlib was not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(MATPLOTLIB_FOUND) + else(SPHINX_PATH) + message("++ Python module will not be compiled because sphinx and sphinxcontrib-bibtex were not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(SPHINX_PATH) + + + # Set missing or not modules + set(GUDHI_MODULES ${GUDHI_MODULES} "python" CACHE INTERNAL "GUDHI_MODULES") + else(CYTHON_FOUND) + message("++ Python module will not be compiled because cython was not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(CYTHON_FOUND) +else(PYTHONINTERP_FOUND) + message("++ Python module will not be compiled because no Python interpreter was found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python" CACHE INTERNAL "GUDHI_MISSING_MODULES") +endif(PYTHONINTERP_FOUND) -- cgit v1.2.3 From 2ca563e4e1a12443773cd58ab65ef65286bc31dd Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 28 Sep 2018 09:14:37 +0000 Subject: Python Nerve and Graph Induced Complex was introduced in GUDHI 2.3.0 (not 2.1.0) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3914 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8e34cf876daf73288caed371c7ce9c51f07fbf7f --- src/cython/doc/nerve_gic_complex_sum.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/doc/nerve_gic_complex_sum.rst b/src/cython/doc/nerve_gic_complex_sum.rst index 72782c7a..523c119f 100644 --- a/src/cython/doc/nerve_gic_complex_sum.rst +++ b/src/cython/doc/nerve_gic_complex_sum.rst @@ -1,5 +1,5 @@ ================================================================= =================================== =================================== -:Author: Mathieu Carrière :Introduced in: GUDHI 2.1.0 :Copyright: GPL v3 +:Author: Mathieu Carrière :Introduced in: GUDHI 2.3.0 :Copyright: GPL v3 :Requires: CGAL :math:`\geq` 4.8.1 ================================================================= =================================== =================================== -- cgit v1.2.3 From c279cfdad04340d8844466a688d60a66786392c9 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 28 Sep 2018 09:22:44 +0000 Subject: Fix typo in installation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3915 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b7f7c3344fef9915a48ee29764063a91f3d860a4 --- src/common/doc/installation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index c27e4f56..df7eed37 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -18,7 +18,7 @@ cmake .. make \endverbatim * By default, examples are disabled. You can activate their compilation with * ccmake (on Linux and Mac OSX), - * cmake-gui (on Windows) or y mofifying the + * cmake-gui (on Windows) or by modifying the * cmake command as follows : \verbatim cmake -DWITH_GUDHI_EXAMPLE=ON .. make \endverbatim -- cgit v1.2.3 From 338b2f41bd14f04193a0b2f6fb0a2321443be45b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 2 Oct 2018 07:45:51 +0000 Subject: Doc review: max_intervals documentation in plot_persistence_density git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3917 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 90cfd77ad4aad4cdb0937f43dd4f802688f98295 --- src/cython/cython/persistence_graphical_tools.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index e66643d2..139a2332 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -269,7 +269,8 @@ def plot_persistence_density(persistence=[], persistence_file='', `_ for more details. :type bw_method: str, scalar or callable, optional. - :param max_intervals: maximal number of intervals to display. + :param max_intervals: maximal number of points used in the density + estimation. Selected points are those with the longest life time. Set it to 0 to see all. Default value is 1000. :type max_intervals: int. -- cgit v1.2.3 From 5469c3637df2efd1a70a165484b992727782d15c Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 2 Oct 2018 07:51:22 +0000 Subject: Doc review : "Selected points are" -> "Selected intervals are" git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3918 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 79857a4609428fc623f8f4656762261ea664cf12 --- src/cython/cython/persistence_graphical_tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index 139a2332..abc205bb 100755 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -70,7 +70,7 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, opaque - default is 0.6). :type alpha: float. :param max_intervals: maximal number of intervals to display. - Selected points are those with the longest life time. Set it + Selected intervals are those with the longest life time. Set it to 0 to see all. Default value is 1000. :type max_intervals: int. :param inf_delta: Infinity is placed at ((max_death - min_birth) x @@ -162,7 +162,7 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, :param band: band (not displayed if :math:`\leq` 0. - default is 0.) :type band: float. :param max_intervals: maximal number of intervals to display. - Selected points are those with the longest life time. Set it + Selected intervals are those with the longest life time. Set it to 0 to see all. Default value is 1000. :type max_intervals: int. :param inf_delta: Infinity is placed at ((max_death - min_birth) x @@ -271,7 +271,7 @@ def plot_persistence_density(persistence=[], persistence_file='', :type bw_method: str, scalar or callable, optional. :param max_intervals: maximal number of points used in the density estimation. - Selected points are those with the longest life time. Set it + Selected intervals are those with the longest life time. Set it to 0 to see all. Default value is 1000. :type max_intervals: int. :param dimension: the dimension to be selected in the intervals -- cgit v1.2.3 From b4c51b3d92564e2e93e8fa4fe55f98cd06bba57a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 2 Oct 2018 08:13:28 +0000 Subject: Code review : remove executable property Doc review : Rephrase inf_delta explanation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3919 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b45697b675a20cdca7bb42fa7a555df6c35fe0fd --- src/cython/cython/persistence_graphical_tools.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) mode change 100755 => 100644 src/cython/cython/persistence_graphical_tools.py (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py old mode 100755 new mode 100644 index abc205bb..e63b350b --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -61,7 +61,7 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, """This function plots the persistence bar code from persistence values list or from a :doc:`persistence file `. - :param persistence: Persistence values list. + :param persistence: Persistence intervals values list grouped by dimension. :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). @@ -73,9 +73,9 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6, Selected intervals are those with the longest life time. Set it to 0 to see all. Default value is 1000. :type max_intervals: int. - :param inf_delta: Infinity is placed at ((max_death - min_birth) x - inf_delta) above the highest point. A reasonable value is between - 0.05 and 0.5 - default is 0.1. + :param inf_delta: Infinity is placed at :code:`((max_death - min_birth) x + inf_delta)` above :code:`max_death` value. A reasonable value is + between 0.05 and 0.5 - default is 0.1. :type inf_delta: float. :param legend: Display the dimension color legend (default is False). :type legend: boolean. @@ -151,7 +151,7 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, """This function plots the persistence diagram from persistence values list or from a :doc:`persistence file `. - :param persistence: Persistence values list. + :param persistence: Persistence intervals values list grouped by dimension. :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). @@ -165,9 +165,9 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6, Selected intervals are those with the longest life time. Set it to 0 to see all. Default value is 1000. :type max_intervals: int. - :param inf_delta: Infinity is placed at ((max_death - min_birth) x - inf_delta) above the highest point. A reasonable value is between - 0.05 and 0.5 - default is 0.1. + :param inf_delta: Infinity is placed at :code:`((max_death - min_birth) x + inf_delta)` above :code:`max_death` value. A reasonable value is + between 0.05 and 0.5 - default is 0.1. :type inf_delta: float. :param legend: Display the dimension color legend (default is False). :type legend: boolean. @@ -251,7 +251,7 @@ def plot_persistence_density(persistence=[], persistence_file='', aware that this function does not distinguish the dimension, it is up to you to select the required one. - :param persistence: Persistence values list. + :param persistence: Persistence intervals values list grouped by dimension. :type persistence: list of tuples(dimension, tuple(birth, death)). :param persistence_file: A :doc:`persistence file ` style name (reset persistence if both are set). -- cgit v1.2.3 From 2dde0fc4ea8f24173789a1ce9a9442cb02b96e86 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 2 Oct 2018 08:23:51 +0000 Subject: Doc review : Explain that plot persistence density function doesn't handle degenerate data git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/plot_persistence_density_vincent@3920 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7794f7959b98b0245e26077d2f2639f33655d5c9 --- src/cython/cython/persistence_graphical_tools.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py index e63b350b..d7be936f 100644 --- a/src/cython/cython/persistence_graphical_tools.py +++ b/src/cython/cython/persistence_graphical_tools.py @@ -249,7 +249,8 @@ def plot_persistence_density(persistence=[], persistence_file='', """This function plots the persistence density from persistence values list or from a :doc:`persistence file `. Be aware that this function does not distinguish the dimension, it is - up to you to select the required one. + up to you to select the required one. This function also does not handle + degenerate data set (scipy correlation matrix inversion can fail). :param persistence: Persistence intervals values list grouped by dimension. :type persistence: list of tuples(dimension, tuple(birth, death)). -- cgit v1.2.3 From 42e599ebd89231c276a3c6e1b9121ea13f25d118 Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 2 Oct 2018 09:21:13 +0000 Subject: More doc changes for python sparse rips git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3921 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f9a33e3c4a6fc6d68a81b753a88ff9d39bdcfb9f --- biblio/bibliography.bib | 3 +- src/Rips_complex/doc/Intro_rips_complex.h | 2 +- src/cython/cython/rips_complex.pyx | 3 +- src/cython/doc/rips_complex_user.rst | 52 ++++++++++++++++++++----------- 4 files changed, 38 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index 16f43d6f..e85876d3 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -1073,9 +1073,10 @@ language={English} @article{buchet16efficient, title = {Efficient and Robust Persistent Homology for Measures}, author = {Micka\"{e}l Buchet and Fr\'{e}d\'{e}ric Chazal and Steve Y. Oudot and Donald Sheehy}, - booktitle = {Computational Geometry: Theory and Applications}, + journal = {Computational Geometry: Theory and Applications}, volume = {58}, pages = {70--96}, + doi = "https://doi.org/10.1016/j.comgeo.2016.07.001", year = {2016} } diff --git a/src/Rips_complex/doc/Intro_rips_complex.h b/src/Rips_complex/doc/Intro_rips_complex.h index 3db5287e..e54ae57c 100644 --- a/src/Rips_complex/doc/Intro_rips_complex.h +++ b/src/Rips_complex/doc/Intro_rips_complex.h @@ -39,7 +39,7 @@ namespace rips_complex { * (Wikipedia) * is an abstract simplicial complex * defined on a finite metric space, where each simplex corresponds to a subset - * of point whose diameter is smaller that some given threshold. + * of points whose diameter is smaller that some given threshold. * Varying the threshold, we can also see the Rips complex as a filtration of * the \f$(n-1)-\f$dimensional simplex, where the filtration value of each * simplex is the diameter of the corresponding subset of points. diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx index 620130ca..ecf039b6 100644 --- a/src/cython/cython/rips_complex.pyx +++ b/src/cython/cython/rips_complex.pyx @@ -62,8 +62,7 @@ cdef class RipsComplex: Or - :param distance_matrix: A distance matrix (full square or lower - triangular). + :param distance_matrix: A distance matrix (full square or lower triangular). :type points: list of list of double And in both cases diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index a8c06cf9..9fa3a677 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -7,27 +7,22 @@ Rips complex user manual Definition ---------- -======================================================= ===================================== ===================================== -:Authors: Clément Maria, Pawel Dlotko, Vincent Rouvreau :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 -======================================================= ===================================== ===================================== +==================================================================== ================================ ====================== +:Authors: Clément Maria, Pawel Dlotko, Vincent Rouvreau, Marc Glisse :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 +==================================================================== ================================ ====================== +-------------------------------------------+----------------------------------------------------------------------+ | :doc:`rips_complex_user` | :doc:`rips_complex_ref` | +-------------------------------------------+----------------------------------------------------------------------+ -`Rips complex `_ is a one skeleton graph that allows to -construct a simplicial complex from it. The input can be a point cloud with a given distance function, or a distance -matrix. +The `Rips complex `_ is a simplicial complex defined as the clique complex of a graph. The graph is defined on a set of points with one vertex for each point and an edge between any 2 points, of weight (aka filtration value) the distance between the 2 points. This graph (and thus the complex) can be restricted to edges shorter than some threshold, to reduce its size. -The filtration value of each edge is computed from a user-given distance function, or directly from the distance -matrix. +The input discrete metric space can be provided as a point cloud plus a distance function, or as a distance matrix. -All edges that have a filtration value strictly greater than a given threshold value are not inserted into the complex. +When creating a simplicial complex from the graph, `RipsComplex` inserts the graph into the data +structure, and then expands the simplicial complex (adds the simplices corresponding to cliques) when required. The expansion can be stopped at dimension `max_dimension`, by default 1. -When creating a simplicial complex from this one skeleton graph, Rips inserts the one skeleton graph into the data -structure, and then expands the simplicial complex when required. - -Vertex name correspond to the index of the point in the given range (aka. the point cloud). +A vertex name corresponds to the index of the point in the given range (aka. the point cloud). .. figure:: ../../doc/Rips_complex/rips_complex_representation.png @@ -38,8 +33,27 @@ Vertex name correspond to the index of the point in the given range (aka. the po On this example, as edges (4,5), (4,6) and (5,6) are in the complex, simplex (4,5,6) is added with the filtration value set with :math:`max(filtration(4,5), filtration(4,6), filtration(5,6))`. And so on for simplex (0,1,2,3). -If the Rips_complex interfaces are not detailed enough for your need, please refer to rips_persistence_step_by_step.cpp -example, where the graph construction over the Simplex_tree is more detailed. +If the `RipsComplex` interfaces are not detailed enough for your need, please refer to rips_persistence_step_by_step.cpp +C++ example, where the graph construction over the Simplex_tree is more detailed. + +A Rips complex can easily become huge, even if we limit the length of the edges +and the dimension of the simplices. One easy trick, before building a Rips +complex on a point cloud, is to call `sparsify_point_set` which removes points +that are too close to each other. This does not change its persistence diagram +by more than the length used to define "too close". + +A more general technique is to use a sparse approximation of the Rips +introduced by Don Sheehy :cite:`sheehy13linear`. We are using the version +described in :cite:`buchet16efficient` (except that we multiply all filtration +values by 2, to match the usual Rips complex), which proves a +:math:`\frac{1+\epsilon}{1-\epsilon}`-interleaving, although in practice the +error is usually smaller. A more intuitive presentation of the idea is +available in :cite:`cavanna15geometric`, and in a video +:cite:`cavanna15visualizing`. Passing an extra argument `sparse=0.3` at the +construction of a `RipsComplex` object asks it to build a sparse Rips with +parameter `ε=0.3`, while the default `sparse=None` builds the +regular Rips complex. + Point cloud ----------- @@ -47,7 +61,7 @@ Point cloud Example from a point cloud ^^^^^^^^^^^^^^^^^^^^^^^^^^ -This example builds the one skeleton graph from the given points, and max_edge_length value. +This example builds the neighborhood graph from the given points, up to max_edge_length. Then it creates a :doc:`Simplex_tree ` with it. Finally, it is asked to display information about the simplicial complex. @@ -92,10 +106,12 @@ until dimension 1 - one skeleton graph in other words), the output is: [4, 6] -> 9.49 [3, 6] -> 11.00 +Notice that if we use `rips_complex = gudhi.RipsComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]], max_edge_length=12.0, sparse=2)`, asking for very sparse version (theory only gives some guarantee on the meaning of the output if `sparse<1`), 2 to 5 edges disappear, depending on the random vertex used to start the sparsification. + Example from OFF file ^^^^^^^^^^^^^^^^^^^^^ -This example builds the :doc:`Rips_complex ` from the given +This example builds the :doc:`RipsComplex ` from the given points in an OFF file, and max_edge_length value. Then it creates a :doc:`Simplex_tree ` with it. @@ -200,7 +216,7 @@ until dimension 1 - one skeleton graph in other words), the output is: Example from csv file ^^^^^^^^^^^^^^^^^^^^^ -This example builds the :doc:`Rips_complex ` from the given +This example builds the :doc:`RipsComplex ` from the given distance matrix in a csv file, and max_edge_length value. Then it creates a :doc:`Simplex_tree ` with it. -- cgit v1.2.3 From cae07e49a1700613bf709f7d0bbf3d1c640d4a2c Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 2 Oct 2018 11:09:47 +0000 Subject: Catch exception by const& git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3922 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1b0cea99516d6b42e5ab3b0fdb21468b321e6d6c --- src/cython/include/Alpha_complex_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/include/Alpha_complex_interface.h b/src/cython/include/Alpha_complex_interface.h index 8cf527fc..faa059d1 100644 --- a/src/cython/include/Alpha_complex_interface.h +++ b/src/cython/include/Alpha_complex_interface.h @@ -60,7 +60,7 @@ class Alpha_complex_interface { Point_d ph = alpha_complex_->get_point(vh); for (auto coord = ph.cartesian_begin(); coord < ph.cartesian_end(); coord++) vd.push_back(*coord); - } catch (std::out_of_range outofrange) { + } catch (std::out_of_range const&) { // std::out_of_range is thrown in case not found. Other exceptions must be re-thrown } return vd; -- cgit v1.2.3 From c71757a513b4f83dae517db6fecd6ab1739a15de Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 3 Oct 2018 08:04:21 +0000 Subject: Modify "-pedantic" compiler option management in order to be traced Modify windows warning level git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/windows_warning_removal_vincent@3926 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1c6e61fb968b6b4072b86a520e2edf78aedf1ffa --- CMakeLists.txt | 2 -- src/cmake/modules/GUDHI_compilation_flags.cmake | 13 ++++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index d61df992..76e5b528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,6 @@ set(GUDHI_CYTHON_PATH "src/cython") include(GUDHI_third_party_libraries NO_POLICY_SCOPE) include(GUDHI_compilation_flags) -# Only for dev version -add_cxx_compiler_flag("-pedantic") # Add your new module in the list, order is not important include(GUDHI_modules) diff --git a/src/cmake/modules/GUDHI_compilation_flags.cmake b/src/cmake/modules/GUDHI_compilation_flags.cmake index a01d6e13..86cd531b 100644 --- a/src/cmake/modules/GUDHI_compilation_flags.cmake +++ b/src/cmake/modules/GUDHI_compilation_flags.cmake @@ -5,7 +5,7 @@ include(CheckCXXSourceCompiles) # add a compiler flag only if it is accepted macro(add_cxx_compiler_flag _flag) - string(REPLACE "-" "_" _flag_var ${_flag}) + string(REPLACE "-" "_" "/" _flag_var ${_flag}) check_cxx_accepts_flag("${_flag}" CXX_COMPILER_${_flag_var}_OK) if(CXX_COMPILER_${_flag_var}_OK) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}") @@ -43,12 +43,15 @@ set (CMAKE_CXX_STANDARD 11) enable_testing() if(MSVC) - # Turn off some VC++ warnings - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") + add_cxx_compiler_flag("/W3") +else() + add_cxx_compiler_flag("-Wall") + # Only for dev version + if(PROJECT_NAME STREQUAL "GUDHIdev") + add_cxx_compiler_flag("-pedantic") + endif() endif() -add_cxx_compiler_flag("-Wall") - if (DEBUG_TRACES) # For programs to be more verbose message(STATUS "DEBUG_TRACES are activated") -- cgit v1.2.3 From 76c4bde05eb39e17579c63c7e161648ec689bac6 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 4 Oct 2018 14:09:04 +0000 Subject: Documentation change for github website git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3932 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7044071afd3a3e629ea66ed3647c00d023f60692 --- src/Alpha_complex/utilities/alphacomplex.md | 4 ++-- src/Bottleneck_distance/utilities/bottleneckdistance.md | 2 +- src/Witness_complex/utilities/witnesscomplex.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Alpha_complex/utilities/alphacomplex.md b/src/Alpha_complex/utilities/alphacomplex.md index 0fe98837..b1a33e4b 100644 --- a/src/Alpha_complex/utilities/alphacomplex.md +++ b/src/Alpha_complex/utilities/alphacomplex.md @@ -143,7 +143,7 @@ where * `` is the path to the input point cloud in [nOFF ASCII format](http://www.geomview.org/docs/html/OFF.html). * `` is the path to the file describing the periodic domain. It must be in the format described -[here](/doc/latest/fileformats.html#FileFormatsIsoCuboid). +[here]({{ site.officialurl }}/doc/latest/fileformats.html#FileFormatsIsoCuboid). **Allowed options** @@ -161,5 +161,5 @@ periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off N.B.: -* Cuboid file must be in the format described [here](/doc/latest/fileformats.html#FileFormatsIsoCuboid). +* Cuboid file must be in the format described [here]({{ site.officialurl }}/doc/latest/fileformats.html#FileFormatsIsoCuboid). * Filtration values are alpha square values. diff --git a/src/Bottleneck_distance/utilities/bottleneckdistance.md b/src/Bottleneck_distance/utilities/bottleneckdistance.md index 939eb911..a81426cf 100644 --- a/src/Bottleneck_distance/utilities/bottleneckdistance.md +++ b/src/Bottleneck_distance/utilities/bottleneckdistance.md @@ -22,5 +22,5 @@ This program computes the Bottleneck distance between two persistence diagram fi where -* `` and `` must be in the format described [here](/doc/latest/fileformats.html#FileFormatsPers). +* `` and `` must be in the format described [here]({{ site.officialurl }}/doc/latest/fileformats.html#FileFormatsPers). * `` is an error bound on the bottleneck distance (set by default to the smallest positive double value). diff --git a/src/Witness_complex/utilities/witnesscomplex.md b/src/Witness_complex/utilities/witnesscomplex.md index da453cce..7ea397b9 100644 --- a/src/Witness_complex/utilities/witnesscomplex.md +++ b/src/Witness_complex/utilities/witnesscomplex.md @@ -10,7 +10,7 @@ Leave the lines above as it is required by the web site generator 'Jekyll' {:/comment} -For more details about the witness complex, please read the [user manual of the package](/doc/latest/group__witness__complex.html). +For more details about the witness complex, please read the [user manual of the package]({{ site.officialurl }}/doc/latest/group__witness__complex.html). ## weak_witness_persistence ## This program computes the persistent homology with coefficient field *Z/pZ* of a Weak witness complex defined on a set of input points. -- cgit v1.2.3 From 9e7c5464fd0f3e12e0b309e7b8ebbad1f830e4a7 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 5 Oct 2018 13:43:21 +0000 Subject: pasto git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3933 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3fc8b696f0c457256e0c8bf74ffffa580dbb69d4 --- src/cython/cython/simplex_tree.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index e302486b..8397d9d9 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -515,7 +515,7 @@ cdef class SimplexTree: :returns: The persistence intervals. :rtype: list of pair of list of int - :note: intervals_in_dim function requires + :note: persistence_pairs function requires :func:`persistence()` function to be launched first. """ -- cgit v1.2.3 From f1d0acdc9f3f8d886996cc078242b48598a3275a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 5 Oct 2018 14:42:49 +0000 Subject: Message to debug Mac issue git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3934 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 24e8a83ab317c5d94140638c76f91e68c1b3ce0f --- src/cmake/modules/GUDHI_third_party_libraries.cmake | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index 2464517c..b020ebfc 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -127,6 +127,10 @@ function( find_python_module PYTHON_MODULE_NAME ) RESULT_VARIABLE PYTHON_MODULE_RESULT OUTPUT_VARIABLE PYTHON_MODULE_VERSION ERROR_VARIABLE PYTHON_MODULE_ERROR) + message ("PYTHON_MODULE_NAME = ${PYTHON_MODULE_NAME} + - PYTHON_MODULE_RESULT = ${PYTHON_MODULE_RESULT} + - PYTHON_MODULE_VERSION = ${PYTHON_MODULE_VERSION} + - PYTHON_MODULE_ERROR = ${PYTHON_MODULE_ERROR}") if(PYTHON_MODULE_RESULT EQUAL 0) # Remove carriage return string(STRIP ${PYTHON_MODULE_VERSION} PYTHON_MODULE_VERSION) -- cgit v1.2.3 From 0567f550258966a12911cd3ffe490852c022c358 Mon Sep 17 00:00:00 2001 From: glisse Date: Sat, 6 Oct 2018 14:01:16 +0000 Subject: Doc tweaks. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3936 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3c75c674876bcb38d0a87de41d406832baf61b55 --- biblio/bibliography.bib | 2 ++ src/cython/cython/rips_complex.pyx | 1 + src/cython/doc/rips_complex_user.rst | 5 ++--- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index e85876d3..a8c040ed 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -1084,6 +1084,7 @@ language={English} author = {Nicholas J. Cavanna and Mahmoodreza Jahanseir and Donald R. Sheehy}, booktitle = {Proceedings of the Canadian Conference on Computational Geometry}, title = {A Geometric Perspective on Sparse Filtrations}, + url = {http://research.cs.queensu.ca/cccg2015/CCCG15-papers/01.pdf}, year = {2015} } @@ -1102,5 +1103,6 @@ language={English} volume = {49}, number = {4}, pages = {778--796}, + doi = "10.1007/s00454-013-9513-1", year = {2013} } diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx index ecf039b6..cb9aad2e 100644 --- a/src/cython/cython/rips_complex.pyx +++ b/src/cython/cython/rips_complex.pyx @@ -66,6 +66,7 @@ cdef class RipsComplex: :type points: list of list of double And in both cases + :param sparse: If this is not None, it switches to building a sparse Rips and represents the approximation parameter epsilon. :type sparse: float """ diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index 9fa3a677..95bb40b6 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -15,12 +15,11 @@ Definition | :doc:`rips_complex_user` | :doc:`rips_complex_ref` | +-------------------------------------------+----------------------------------------------------------------------+ -The `Rips complex `_ is a simplicial complex defined as the clique complex of a graph. The graph is defined on a set of points with one vertex for each point and an edge between any 2 points, of weight (aka filtration value) the distance between the 2 points. This graph (and thus the complex) can be restricted to edges shorter than some threshold, to reduce its size. +The `Rips complex `_ is a simplicial complex that generalizes proximity (ε-ball) graphs to higher dimensions. The vertices correspond to the input points, and a simplex is present if and only if its diameter is smaller than some parameter α. Considering all parameters α defines a filtered simplicial complex, where the filtration value of a simplex is its diameter. The filtration can be restricted to values α smaller than some threshold, to reduce its size. The input discrete metric space can be provided as a point cloud plus a distance function, or as a distance matrix. -When creating a simplicial complex from the graph, `RipsComplex` inserts the graph into the data -structure, and then expands the simplicial complex (adds the simplices corresponding to cliques) when required. The expansion can be stopped at dimension `max_dimension`, by default 1. +When creating a simplicial complex from the graph, `RipsComplex` first builds the graph and inserts it into the data structure. It then expands the simplicial complex (adds the simplices corresponding to cliques) when required. The expansion can be stopped at dimension `max_dimension`, by default 1. A vertex name corresponds to the index of the point in the given range (aka. the point cloud). -- cgit v1.2.3 From c537a466ffdd812d92098bcea04cdf6f0bfc64ec Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 10 Oct 2018 21:17:19 +0000 Subject: Example text and copyright year git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3937 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6d5bf6a2c55f7c4fd4f3f5159651b3ffa057ffdd --- src/cython/example/sparse_rips_persistence_diagram.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cython/example/sparse_rips_persistence_diagram.py b/src/cython/example/sparse_rips_persistence_diagram.py index 3bed87c1..d58c244c 100755 --- a/src/cython/example/sparse_rips_persistence_diagram.py +++ b/src/cython/example/sparse_rips_persistence_diagram.py @@ -8,7 +8,7 @@ import gudhi Author(s): Marc Glisse - Copyright (C) 2016 Inria + Copyright (C) 2018 Inria This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,11 +25,11 @@ import gudhi """ __author__ = "Marc Glisse" -__copyright__ = "Copyright (C) 2016 Inria" +__copyright__ = "Copyright (C) 2018 Inria" __license__ = "GPL v3" print("#####################################################################") -print("RipsComplex creation from points") +print("Sparse RipsComplex creation from points") rips = gudhi.RipsComplex(points=[[0, 0], [0, 0.1], [1, 0], [0, 1], [1, 1]], max_edge_length=42, sparse=.5) -- cgit v1.2.3 From d16910a5c74552b3b1feffc3e793ec5b6d52f952 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 10 Oct 2018 21:43:35 +0000 Subject: Use math instead of unicode for epsilon git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3938 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8cccce774b7406d90a55d0e2827fad6dc3855b39 --- src/cython/doc/rips_complex_user.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index 95bb40b6..cddf4f16 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -45,7 +45,7 @@ A more general technique is to use a sparse approximation of the Rips introduced by Don Sheehy :cite:`sheehy13linear`. We are using the version described in :cite:`buchet16efficient` (except that we multiply all filtration values by 2, to match the usual Rips complex), which proves a -:math:`\frac{1+\epsilon}{1-\epsilon}`-interleaving, although in practice the +:math:`\frac{1+\varepsilon}{1-\varepsilon}`-interleaving, although in practice the error is usually smaller. A more intuitive presentation of the idea is available in :cite:`cavanna15geometric`, and in a video :cite:`cavanna15visualizing`. Passing an extra argument `sparse=0.3` at the -- cgit v1.2.3 From b6f3903f0ce07fe243ea7a3c18098043114f7f6a Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 10 Oct 2018 21:52:27 +0000 Subject: epsilon + code block git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3939 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6a88d96a67d9d02f95e63fd627c295abebb49ce8 --- src/cython/doc/rips_complex_user.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index cddf4f16..933643e2 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -15,7 +15,7 @@ Definition | :doc:`rips_complex_user` | :doc:`rips_complex_ref` | +-------------------------------------------+----------------------------------------------------------------------+ -The `Rips complex `_ is a simplicial complex that generalizes proximity (ε-ball) graphs to higher dimensions. The vertices correspond to the input points, and a simplex is present if and only if its diameter is smaller than some parameter α. Considering all parameters α defines a filtered simplicial complex, where the filtration value of a simplex is its diameter. The filtration can be restricted to values α smaller than some threshold, to reduce its size. +The `Rips complex `_ is a simplicial complex that generalizes proximity (:math:`\varepsilon`-ball) graphs to higher dimensions. The vertices correspond to the input points, and a simplex is present if and only if its diameter is smaller than some parameter α. Considering all parameters α defines a filtered simplicial complex, where the filtration value of a simplex is its diameter. The filtration can be restricted to values α smaller than some threshold, to reduce its size. The input discrete metric space can be provided as a point cloud plus a distance function, or as a distance matrix. @@ -50,7 +50,7 @@ error is usually smaller. A more intuitive presentation of the idea is available in :cite:`cavanna15geometric`, and in a video :cite:`cavanna15visualizing`. Passing an extra argument `sparse=0.3` at the construction of a `RipsComplex` object asks it to build a sparse Rips with -parameter `ε=0.3`, while the default `sparse=None` builds the +parameter :math:`\varepsilon=0.3`, while the default `sparse=None` builds the regular Rips complex. @@ -105,7 +105,13 @@ until dimension 1 - one skeleton graph in other words), the output is: [4, 6] -> 9.49 [3, 6] -> 11.00 -Notice that if we use `rips_complex = gudhi.RipsComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]], max_edge_length=12.0, sparse=2)`, asking for very sparse version (theory only gives some guarantee on the meaning of the output if `sparse<1`), 2 to 5 edges disappear, depending on the random vertex used to start the sparsification. +Notice that if we use + +.. code-block:: python + + rips_complex = gudhi.RipsComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]], max_edge_length=12.0, sparse=2) + +asking for a very sparse version (theory only gives some guarantee on the meaning of the output if `sparse<1`), 2 to 5 edges disappear, depending on the random vertex used to start the sparsification. Example from OFF file ^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From e9d843d0a5c48315c45e8639e8bf9b79ccf904af Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 10 Oct 2018 21:55:26 +0000 Subject: add example to the list of examples git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3940 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fe3c41785e3bb72766f7a817851583f82b9f7d15 --- src/cython/doc/examples.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cython/doc/examples.rst b/src/cython/doc/examples.rst index 1f02f8a2..edbc2f72 100644 --- a/src/cython/doc/examples.rst +++ b/src/cython/doc/examples.rst @@ -22,6 +22,7 @@ Examples * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>` * :download:`rips_complex_diagram_persistence_from_distance_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py>` * :download:`rips_persistence_diagram.py <../example/rips_persistence_diagram.py>` + * :download:`sparse_rips_persistence_diagram.py <../example/sparse_rips_persistence_diagram.py>` * :download:`random_cubical_complex_persistence_example.py <../example/random_cubical_complex_persistence_example.py>` * :download:`coordinate_graph_induced_complex.py <../example/coordinate_graph_induced_complex.py>` * :download:`functional_graph_induced_complex.py <../example/functional_graph_induced_complex.py>` -- cgit v1.2.3 From 665ba1dfe82b663ed755267b74c62706ec6eb88a Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 10 Oct 2018 22:04:13 +0000 Subject: add myself as coauthor git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3941 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 61cf8acdce3bc5cb0c8261166e195eccc3f8bb54 --- src/cython/doc/rips_complex_sum.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cython/doc/rips_complex_sum.inc b/src/cython/doc/rips_complex_sum.inc index 5616bfa9..ea26769a 100644 --- a/src/cython/doc/rips_complex_sum.inc +++ b/src/cython/doc/rips_complex_sum.inc @@ -1,6 +1,6 @@ -================================================================= =================================== =================================== -:Author: Clément Maria, Pawel Dlotko, Vincent Rouvreau :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 -================================================================= =================================== =================================== +===================================================================== =========================== =================================== +:Author: Clément Maria, Pawel Dlotko, Vincent Rouvreau, Marc Glisse :Introduced in: GUDHI 2.0.0 :Copyright: GPL v3 +===================================================================== =========================== =================================== +----------------------------------------------------------------+------------------------------------------------------------------------+ | .. figure:: | Rips complex is a simplicial complex constructed from a one skeleton | -- cgit v1.2.3 From 354da3ae06ffa2479d56e9ea45cefbe218da2c76 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 10 Oct 2018 22:11:23 +0000 Subject: Make RipsComplex a clickable link git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3942 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 642ae449f85cf8516fc632716ea14b22f74ec517 --- src/cython/doc/rips_complex_user.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index 933643e2..e0c71cd1 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -19,7 +19,7 @@ The `Rips complex ` The input discrete metric space can be provided as a point cloud plus a distance function, or as a distance matrix. -When creating a simplicial complex from the graph, `RipsComplex` first builds the graph and inserts it into the data structure. It then expands the simplicial complex (adds the simplices corresponding to cliques) when required. The expansion can be stopped at dimension `max_dimension`, by default 1. +When creating a simplicial complex from the graph, :doc:`RipsComplex ` first builds the graph and inserts it into the data structure. It then expands the simplicial complex (adds the simplices corresponding to cliques) when required. The expansion can be stopped at dimension `max_dimension`, by default 1. A vertex name corresponds to the index of the point in the given range (aka. the point cloud). -- cgit v1.2.3 From 07c214f675595b75a2a9d1f8dc2888487aa6086a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 17 Oct 2018 08:11:14 +0000 Subject: Some indentation fix git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/sparserips-python@3960 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6dce53b98bc0b299a3621602f385b3b44e16d489 --- src/cython/doc/rips_complex_user.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index e0c71cd1..0aeffe55 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -69,7 +69,7 @@ Finally, it is asked to display information about the simplicial complex. import gudhi rips_complex = gudhi.RipsComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]], - max_edge_length=12.0) + max_edge_length=12.0) simplex_tree = rips_complex.create_simplex_tree(max_dimension=1) result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ @@ -109,9 +109,11 @@ Notice that if we use .. code-block:: python - rips_complex = gudhi.RipsComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]], max_edge_length=12.0, sparse=2) + rips_complex = gudhi.RipsComplex(points=[[1, 1], [7, 0], [4, 6], [9, 6], [0, 14], [2, 19], [9, 17]], + max_edge_length=12.0, sparse=2) -asking for a very sparse version (theory only gives some guarantee on the meaning of the output if `sparse<1`), 2 to 5 edges disappear, depending on the random vertex used to start the sparsification. +asking for a very sparse version (theory only gives some guarantee on the meaning of the output if `sparse<1`), +2 to 5 edges disappear, depending on the random vertex used to start the sparsification. Example from OFF file ^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From 4f07edab3e86ffe9f0bcd8c055592dff22fab2ce Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 18 Oct 2018 19:30:14 +0000 Subject: Add persistence_dim_max argument in simplex tree persistence documentation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3963 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ef8f3b0c2b0e3cdbda73687f1e65877213918830 --- src/cython/cython/simplex_tree.pyx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index 8397d9d9..0ab97f80 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -44,8 +44,8 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": void set_dimension(int dimension) int dimension() int upper_bound_dimension() - bint find_simplex(vector[int] simplex) - bint insert_simplex_and_subfaces(vector[int] simplex, + bool find_simplex(vector[int] simplex) + bool insert_simplex_and_subfaces(vector[int] simplex, double filtration) vector[pair[vector[int], double]] get_filtration() vector[pair[vector[int], double]] get_skeleton(int dimension) @@ -355,7 +355,7 @@ cdef class SimplexTree: :param filtration: Maximum threshold value. :type filtration: float. :returns: The filtration modification information. - :rtype: bint + :rtype: bool .. note:: @@ -406,7 +406,7 @@ cdef class SimplexTree: value than its faces by increasing the filtration values. :returns: The filtration modification information. - :rtype: bint + :rtype: bool .. note:: @@ -432,6 +432,10 @@ cdef class SimplexTree: 0.0. Sets min_persistence to -1.0 to see all values. :type min_persistence: float. + :param persistence_dim_max: If true, the persistent homology for the + maximal dimension in the complex is computed. If false, it is + ignored. Default is false. + :type persistence_dim_max: bool :returns: The persistence of the simplicial complex. :rtype: list of pairs(dimension, pair(birth, death)) """ -- cgit v1.2.3 From 025f24d720dfdfbe4e5dafb594e811bbf5ead2f7 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 24 Oct 2018 14:40:49 +0000 Subject: True interleaving distance for the sparse Rips. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3964 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6c342750c0ea2e7d48e8c3fc9cc2a4d04f8b379b --- src/Rips_complex/utilities/ripscomplex.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/utilities/ripscomplex.md b/src/Rips_complex/utilities/ripscomplex.md index 6df49310..108cdd50 100644 --- a/src/Rips_complex/utilities/ripscomplex.md +++ b/src/Rips_complex/utilities/ripscomplex.md @@ -85,7 +85,7 @@ properly, this is a known issue. ## sparse_rips_persistence ## This program computes the persistent homology with coefficient field *Z/pZ* -of a sparse (1+epsilon)-approximation of the Rips complex defined on a set of input Euclidean points. The output diagram contains one bar per line, written with the convention: +of a sparse (1+epsilon)/(1-epsilon)-approximation of the Rips complex defined on a set of input Euclidean points. The output diagram contains one bar per line, written with the convention: `p dim birth death` @@ -99,7 +99,7 @@ where `dim` is the dimension of the homological feature, `birth` and `death` are * `-h [ --help ]` Produce help message * `-o [ --output-file ]` Name of file in which the persistence diagram is written. Default print in standard output. -* `-e [ --approximation ]` (default = .5) Epsilon, where the sparse Rips complex is a (1+epsilon)-approximation of the Rips complex. +* `-e [ --approximation ]` (default = .5) Epsilon, where the sparse Rips complex is a (1+epsilon)/(1-epsilon)-approximation of the Rips complex. * `-d [ --cpx-dimension ]` (default = 1) Maximal dimension of the Rips complex we want to compute. * `-p [ --field-charac ]` (default = 11) Characteristic p of the coefficient field Z/pZ for computing homology. * `-m [ --min-persistence ]` (default = 0) Minimal lifetime of homology feature to be recorded. Enter a negative value to see zero length intervals. -- cgit v1.2.3 From e8401b6fd2f9ff533824a6773f592b448d0863ed Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 31 Oct 2018 11:48:04 +0000 Subject: Make dependency with boost 1.56 instead of 1.48 git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/boost_1.56_vincent@3967 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a5941b8c4f65ec8e6f62117aceb5f22e0142f255 --- src/cmake/modules/GUDHI_third_party_libraries.cmake | 2 +- src/common/doc/installation.h | 2 +- src/cython/doc/installation.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index b020ebfc..cde3725c 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -1,6 +1,6 @@ # This files manage third party libraries required by GUDHI -find_package(Boost 1.48.0 REQUIRED COMPONENTS system filesystem unit_test_framework program_options thread) +find_package(Boost 1.56.0 REQUIRED COMPONENTS system filesystem unit_test_framework program_options thread) if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This program requires Boost and will not be compiled.") diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index df7eed37..bf2d0a87 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -5,7 +5,7 @@ * Examples of GUDHI headers inclusion can be found in \ref utilities. * * \section compiling Compiling - * The library uses c++11 and requires Boost ≥ 1.48.0 + * The library uses c++11 and requires Boost ≥ 1.56.0 * and CMake ≥ 3.1. * It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2015. * diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst index ef2f7af2..040f6b4a 100644 --- a/src/cython/doc/installation.rst +++ b/src/cython/doc/installation.rst @@ -7,7 +7,7 @@ Installation Compiling ********* -The library uses c++11 and requires `Boost `_ ≥ 1.48.0 +The library uses c++11 and requires `Boost `_ ≥ 1.56.0 and `CMake `_ ≥ 3.1. It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2015. -- cgit v1.2.3