-- cgit v1.2.3 From 8194773c116763e538b6a542fccbd92ec1537372 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 23 Jun 2017 15:07:18 +0000 Subject: First version of expansion with blocker oracle git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2562 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 755af58e3688d00b43edd9616fd903cce1eca704 --- src/Simplex_tree/example/CMakeLists.txt | 24 ----------- src/Simplex_tree/include/gudhi/Simplex_tree.h | 59 ++++++++++++++++++++------- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index cfac0da6..d05bb187 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -36,27 +36,3 @@ if(GMP_FOUND AND CGAL_FOUND) install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin) endif() - - -add_executable(rips_step_by_step rips_step_by_step.cpp) -target_link_libraries(rips_step_by_step ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}) -if (TBB_FOUND) - target_link_libraries(rips_step_by_step ${TBB_LIBRARIES}) -endif() - -add_executable(cgal_rips_step_by_step cgal_rips_step_by_step.cpp) -target_link_libraries(cgal_rips_step_by_step ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}) -if (TBB_FOUND) - target_link_libraries(cgal_rips_step_by_step ${TBB_LIBRARIES}) -endif() - -add_executable(cgal_euclidean_distance cgal_euclidean_distance.cpp) -if (TBB_FOUND) - target_link_libraries(cgal_euclidean_distance ${TBB_LIBRARIES}) -endif() - -add_executable(subsamp_rips_step_by_step subsamp_rips_step_by_step.cpp) -target_link_libraries(subsamp_rips_step_by_step ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}) -if (TBB_FOUND) - target_link_libraries(subsamp_rips_step_by_step ${TBB_LIBRARIES}) -endif() diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 317bce23..a83623a5 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1007,11 +1007,35 @@ class Simplex_tree { * The Simplex_tree must contain no simplex of dimension bigger than * 1 when calling the method. */ void expansion(int max_dim) { + expansion_with_blockers(max_dim, + [](Simplex_handle origin_sh, + Simplex_handle dict1_sh, + Simplex_handle dict2_sh) { + // Default blocker is always insert with the maximal filtration value between + // origin, dict1 and dict2 + return std::make_pair(true, (std::max)({origin_sh->second.filtration(), + dict1_sh->second.filtration(), + dict2_sh->second.filtration()})); }); + } + + /** \brief Expands the Simplex_tree containing only its one skeleton + * until dimension max_dim. + * + * The expanded simplicial complex until dimension \f$d\f$ + * attached to a graph \f$G\f$ is the maximal simplicial complex of + * dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. + * The filtration value assigned to a simplex is the maximal filtration + * value of one of its edges. + * + * The Simplex_tree must contain no simplex of dimension bigger than + * 1 when calling the method. */ + template< typename Blocker > + void expansion_with_blockers(int max_dim, Blocker blocker_expansion_function) { dimension_ = max_dim; for (Dictionary_it root_it = root_.members_.begin(); root_it != root_.members_.end(); ++root_it) { if (has_children(root_it)) { - siblings_expansion(root_it->second.children(), max_dim - 1); + siblings_expansion_with_blockers(root_it->second.children(), max_dim - 1, blocker_expansion_function); } } dimension_ = max_dim - dimension_; @@ -1019,8 +1043,9 @@ class Simplex_tree { private: /** \brief Recursive expansion of the simplex tree.*/ - void siblings_expansion(Siblings * siblings, // must contain elements - int k) { + template< typename Blocker > + void siblings_expansion_with_blockers(Siblings * siblings, // must contain elements + int k, Blocker blocker_expansion_function) { if (dimension_ > k) { dimension_ = k; } @@ -1034,20 +1059,21 @@ class Simplex_tree { s_h != siblings->members().end(); ++s_h, ++next) { Simplex_handle root_sh = find_vertex(s_h->first); if (has_children(root_sh)) { - intersection( - inter, // output intersection - next, // begin - siblings->members().end(), // end - root_sh->second.children()->members().begin(), - root_sh->second.children()->members().end(), - s_h->second.filtration()); + intersection_with_blockers( + inter, // output intersection + next, // begin + siblings->members().end(), // end + root_sh->second.children()->members().begin(), + root_sh->second.children()->members().end(), + s_h, blocker_expansion_function); if (inter.size() != 0) { Siblings * new_sib = new Siblings(siblings, // oncles s_h->first, // parent inter); // boost::container::ordered_unique_range_t + // As siblings_expansion_with_blockers is recusively called, inter must be cleared before inter.clear(); s_h->second.assign_children(new_sib); - siblings_expansion(new_sib, k - 1); + siblings_expansion_with_blockers(new_sib, k - 1, blocker_expansion_function); } else { // ensure the children property s_h->second.assign_children(siblings); @@ -1059,16 +1085,19 @@ class Simplex_tree { /** \brief Intersects Dictionary 1 [begin1;end1) with Dictionary 2 [begin2,end2) * and assigns the maximal possible Filtration_value to the Nodes. */ - static void intersection(std::vector >& intersection, + template< typename Blocker > + static void intersection_with_blockers(std::vector >& intersection, Dictionary_it begin1, Dictionary_it end1, Dictionary_it begin2, Dictionary_it end2, - Filtration_value filtration_) { + Dictionary_it origin_sh, + Blocker blocker_expansion_function) { if (begin1 == end1 || begin2 == end2) return; // ----->> while (true) { if (begin1->first == begin2->first) { - Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_}); - intersection.emplace_back(begin1->first, Node(nullptr, filt)); + std::pair blocker_result = blocker_expansion_function(origin_sh, begin1, begin2); + if (blocker_result.first) + intersection.emplace_back(begin1->first, Node(nullptr, blocker_result.second)); if (++begin1 == end1 || ++begin2 == end2) return; // ----->> } else if (begin1->first < begin2->first) { -- cgit v1.2.3 From 5c4d2b4a40ca149702253a2412cb7a63a182ff92 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 26 Jun 2017 15:17:28 +0000 Subject: A test of Cech complex with oracle blocker git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2563 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6c4325dd1ca53a92f4f3de3ed32323c8b6505f5d --- src/Simplex_tree/example/CMakeLists.txt | 9 + .../example/cech_complex_step_by_step.cpp | 240 +++++++++++++++++++++ src/Simplex_tree/include/gudhi/Simplex_tree.h | 11 +- src/common/include/gudhi/Points_off_io.h | 2 +- 4 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 src/Simplex_tree/example/cech_complex_step_by_step.cpp diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index d05bb187..5dbbfcc0 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -36,3 +36,12 @@ if(GMP_FOUND AND CGAL_FOUND) install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin) endif() + +add_executable ( Simplex_tree_example_cech_complex_step_by_step cech_complex_step_by_step.cpp) +target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${Boost_PROGRAM_OPTIONS_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${TBB_LIBRARIES}) +endif() +add_test(NAME Simplex_tree_example_cech_complex_step_by_step COMMAND $ + "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" "-r" "12." "-d" "3") +install(TARGETS Simplex_tree_example_cech_complex_step_by_step DESTINATION bin) diff --git a/src/Simplex_tree/example/cech_complex_step_by_step.cpp b/src/Simplex_tree/example/cech_complex_step_by_step.cpp new file mode 100644 index 00000000..b5cda443 --- /dev/null +++ b/src/Simplex_tree/example/cech_complex_step_by_step.cpp @@ -0,0 +1,240 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Clément Maria + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +// #include +// #include +// #include +#include +#include +#include + +#include + +#include +#include +#include // infinity +#include // for pair +#include + +// ---------------------------------------------------------------------------- +// rips_persistence_step_by_step is an example of each step that is required to +// build a Rips over a Simplex_tree. Please refer to rips_persistence to see +// how to do the same thing with the Rips_complex wrapper for less detailed +// steps. +// ---------------------------------------------------------------------------- + +// Types definition +using Simplex_tree = Gudhi::Simplex_tree; +using Vertex_handle = Simplex_tree::Vertex_handle; +using Simplex_handle = Simplex_tree::Simplex_handle; +using Filtration_value = Simplex_tree::Filtration_value; +using Siblings = Simplex_tree::Siblings; +using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS +, boost::property < vertex_filtration_t, Filtration_value > +, boost::property < edge_filtration_t, Filtration_value > +>; +using Edge_t = std::pair< Vertex_handle, Vertex_handle >; + +// using Kernel = CGAL::Epick_d< CGAL::Dimension_tag<2> >;// CGAL::Dynamic_dimension_tag >; +typedef CGAL::Cartesian_d Kernel; +typedef CGAL::Optimisation_d_traits_d Traits; +typedef CGAL::Min_sphere_d Min_sphere; + +using Point = Kernel::Point_d; +using Points_off_reader = Gudhi::Points_off_reader; +// using Min_sphere = CGAL::Min_sphere_d; + +class Cech_blocker { + public: + std::pair operator()(Simplex_handle origin_sh, Simplex_handle dict1_sh, Simplex_handle dict2_sh, Siblings* siblings) { + //std::vector path = {dict1_sh->first, origin_sh->first}; + Siblings* sib_path = siblings; + std::vector sphere_points = {point_cloud_[dict1_sh->first], point_cloud_[origin_sh->first]}; + do { + //path.push_back(sib_path->parent()); + sphere_points.push_back(point_cloud_[sib_path->parent()]); + sib_path = sib_path->oncles(); + } while (sib_path->oncles() != nullptr); + /*std::cout << square_threshold_ << "-"; + for (auto vh : path) { + std::cout << vh << " "; + } + std::cout << std::endl;*/ + Min_sphere min_sphere(sphere_points.begin(), sphere_points.end()); + //std::cout << min_sphere.squared_radius() << std::endl; + Filtration_value squared_diameter = min_sphere.squared_radius() * 4.; + // Default blocker is always insert with the maximal filtration value between + // origin, dict1 and dict2 + return std::make_pair(squared_diameter < square_threshold_, + squared_diameter); + } + Cech_blocker(Filtration_value threshold, const std::vector& point_cloud) + : square_threshold_(threshold * threshold), + point_cloud_(point_cloud) { } + private: + Filtration_value square_threshold_; + std::vector point_cloud_; +}; + +template< typename InputPointRange> +Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold); + +void program_options(int argc, char * argv[] + , std::string & off_file_points + , Filtration_value & threshold + , int & dim_max); + +int main(int argc, char * argv[]) { + std::string off_file_points; + Filtration_value threshold; + int dim_max; + + program_options(argc, argv, off_file_points, threshold, dim_max); + + // Extract the points from the file filepoints + Points_off_reader off_reader(off_file_points); + + // Compute the proximity graph of the points + Graph_t prox_graph = compute_proximity_graph(off_reader.get_point_cloud(), threshold); + + //Min_sphere sph1(off_reader.get_point_cloud()[0], off_reader.get_point_cloud()[1], off_reader.get_point_cloud()[2]); + // Construct the Rips complex in a Simplex Tree + Simplex_tree st; + // insert the proximity graph in the simplex tree + st.insert_graph(prox_graph); + // expand the graph until dimension dim_max + st.expansion_with_blockers(dim_max, Cech_blocker(threshold, off_reader.get_point_cloud())); + + std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; + std::cout << " and has dimension " << st.dimension() << " \n"; + + // Sort the simplices in the order of the filtration + st.initialize_filtration(); + + std::cout << "********************************************************************\n"; + // Display the Simplex_tree - Can not be done in the middle of 2 inserts + std::cout << "* The complex contains " << st.num_simplices() << " simplices\n"; + std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << static_cast(vertex) << " "; + } + std::cout << std::endl; + } + + return 0; +} + +void program_options(int argc, char * argv[] + , std::string & off_file_points + , Filtration_value & threshold + , int & dim_max) { + namespace po = boost::program_options; + po::options_description hidden("Hidden options"); + hidden.add_options() + ("input-file", po::value(&off_file_points), + "Name of an OFF file containing a point set.\n"); + + po::options_description visible("Allowed options", 100); + visible.add_options() + ("help,h", "produce help message") + ("max-edge-length,r", + po::value(&threshold)->default_value(std::numeric_limits::infinity()), + "Maximal length of an edge for the Rips complex construction.") + ("cpx-dimension,d", po::value(&dim_max)->default_value(1), + "Maximal dimension of the Rips complex we want to compute."); + + po::positional_options_description pos; + pos.add("input-file", 1); + + po::options_description all; + all.add(visible).add(hidden); + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv). + options(all).positional(pos).run(), vm); + po::notify(vm); + + if (vm.count("help") || !vm.count("input-file")) { + std::cout << std::endl; + std::cout << "Construct a Cech complex defined on a set of input points.\n \n"; + + std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl; + std::cout << visible << std::endl; + std::abort(); + } +} + +/** Output the proximity graph of the points. + * + * If points contains n elements, the proximity graph is the graph + * with n vertices, and an edge [u,v] iff the distance function between + * points u and v is smaller than threshold. + * + * The type PointCloud furnishes .begin() and .end() methods, that return + * iterators with value_type Point. + */ +template< typename InputPointRange> +Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold) { + std::vector< Edge_t > edges; + std::vector< Filtration_value > edges_fil; + + Kernel k; + Filtration_value square_threshold = threshold * threshold; + + Vertex_handle idx_u, idx_v; + Filtration_value fil; + idx_u = 0; + for (auto it_u = points.begin(); it_u != points.end(); ++it_u) { + idx_v = idx_u + 1; + for (auto it_v = it_u + 1; it_v != points.end(); ++it_v, ++idx_v) { + fil = k.squared_distance_d_object()(*it_u, *it_v); + if (fil <= square_threshold) { + edges.emplace_back(idx_u, idx_v); + edges_fil.push_back(fil); + } + } + ++idx_u; + } + + Graph_t skel_graph(edges.begin() + , edges.end() + , edges_fil.begin() + , idx_u); // number of points labeled from 0 to idx_u-1 + + auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph); + + boost::graph_traits::vertex_iterator vi, vi_end; + for (std::tie(vi, vi_end) = boost::vertices(skel_graph); + vi != vi_end; ++vi) { + boost::put(vertex_prop, *vi, 0.); + } + + return skel_graph; +} diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index a83623a5..dbed47b8 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1010,7 +1010,8 @@ class Simplex_tree { expansion_with_blockers(max_dim, [](Simplex_handle origin_sh, Simplex_handle dict1_sh, - Simplex_handle dict2_sh) { + Simplex_handle dict2_sh, + Siblings* siblings) { // Default blocker is always insert with the maximal filtration value between // origin, dict1 and dict2 return std::make_pair(true, (std::max)({origin_sh->second.filtration(), @@ -1044,7 +1045,7 @@ class Simplex_tree { private: /** \brief Recursive expansion of the simplex tree.*/ template< typename Blocker > - void siblings_expansion_with_blockers(Siblings * siblings, // must contain elements + void siblings_expansion_with_blockers(Siblings* siblings, // must contain elements int k, Blocker blocker_expansion_function) { if (dimension_ > k) { dimension_ = k; @@ -1065,7 +1066,8 @@ class Simplex_tree { siblings->members().end(), // end root_sh->second.children()->members().begin(), root_sh->second.children()->members().end(), - s_h, blocker_expansion_function); + s_h, siblings, + blocker_expansion_function); if (inter.size() != 0) { Siblings * new_sib = new Siblings(siblings, // oncles s_h->first, // parent @@ -1090,12 +1092,13 @@ class Simplex_tree { Dictionary_it begin1, Dictionary_it end1, Dictionary_it begin2, Dictionary_it end2, Dictionary_it origin_sh, + Siblings* siblings, Blocker blocker_expansion_function) { if (begin1 == end1 || begin2 == end2) return; // ----->> while (true) { if (begin1->first == begin2->first) { - std::pair blocker_result = blocker_expansion_function(origin_sh, begin1, begin2); + std::pair blocker_result = blocker_expansion_function(origin_sh, begin1, begin2, siblings); if (blocker_result.first) intersection.emplace_back(begin1->first, Node(nullptr, blocker_result.second)); if (++begin1 == end1 || ++begin2 == end2) diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h index 29af8a8a..2104b411 100644 --- a/src/common/include/gudhi/Points_off_io.h +++ b/src/common/include/gudhi/Points_off_io.h @@ -85,7 +85,7 @@ class Points_off_visitor_reader { std::cout << std::endl; #endif // DEBUG_TRACES // Fill the point cloud - point_cloud.push_back(Point_d(point.begin(), point.end())); + point_cloud.push_back(Point_d(point.end() - point.begin(), point.begin(), point.end())); } // Off_reader visitor maximal_face implementation - Only points are read -- cgit v1.2.3 From 0423b7024dee787659b76fff4b4f659546a40aea Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 29 Jun 2017 15:57:04 +0000 Subject: First working version of expansion insertion (different from rips expansion). git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2570 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6a6bb4052c3111e783e9e138619f1e945c856708 --- src/Simplex_tree/example/CMakeLists.txt | 17 +++ src/Simplex_tree/example/block.cpp | 82 +++++++++++ src/Simplex_tree/example/simple_simplex_tree.cpp | 35 ++++- src/Simplex_tree/include/gudhi/Simplex_tree.h | 167 ++++++++++++++++------- 4 files changed, 251 insertions(+), 50 deletions(-) create mode 100644 src/Simplex_tree/example/block.cpp diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index 5dbbfcc0..d5f512b3 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -45,3 +45,20 @@ endif() add_test(NAME Simplex_tree_example_cech_complex_step_by_step COMMAND $ "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" "-r" "12." "-d" "3") install(TARGETS Simplex_tree_example_cech_complex_step_by_step DESTINATION bin) + + +# +# TO BE REMOVED !! +# + +#add_executable ( rips_step_by_step rips_step_by_step.cpp) +#target_link_libraries(rips_step_by_step ${Boost_PROGRAM_OPTIONS_LIBRARY}) +#if (TBB_FOUND) +# target_link_libraries(rips_step_by_step ${TBB_LIBRARIES}) +#endif() + + +add_executable ( block block.cpp ) +if (TBB_FOUND) + target_link_libraries(block ${TBB_LIBRARIES}) +endif() diff --git a/src/Simplex_tree/example/block.cpp b/src/Simplex_tree/example/block.cpp new file mode 100644 index 00000000..07ec3921 --- /dev/null +++ b/src/Simplex_tree/example/block.cpp @@ -0,0 +1,82 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2014 + * + * 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 . + */ + +#include +#include + +#include +#include // for pair +#include + +using Simplex_tree = Gudhi::Simplex_tree<>; +using Vertex_handle = Simplex_tree::Vertex_handle; +using Filtration_value = Simplex_tree::Filtration_value; +using typeVectorVertex = std::vector< Vertex_handle >; +using typePairSimplexBool = std::pair< Simplex_tree::Simplex_handle, bool >; + +int main(int argc, char * const argv[]) { + + // Construct the Simplex Tree + Simplex_tree simplexTree; + + simplexTree.insert_simplex({0, 1}); + simplexTree.insert_simplex({0, 2}); + simplexTree.insert_simplex({0, 3}); + simplexTree.insert_simplex({1, 2}); + simplexTree.insert_simplex({1, 3}); + simplexTree.insert_simplex({2, 3}); + simplexTree.insert_simplex({2, 4}); + simplexTree.insert_simplex({3, 6}); + simplexTree.insert_simplex({4, 5}); + simplexTree.insert_simplex({4, 6}); + simplexTree.insert_simplex({5, 6}); + simplexTree.insert_simplex({6}); + + std::cout << "********************************************************************\n"; + // Display the Simplex_tree - Can not be done in the middle of 2 inserts + std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplexTree.filtration_simplex_range()) { + std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + simplexTree.expansion_with_blockers(3, [](){return true;}); + + simplexTree.initialize_filtration(); + std::cout << "********************************************************************\n"; + // Display the Simplex_tree - Can not be done in the middle of 2 inserts + std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplexTree.filtration_simplex_range()) { + std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + return 0; +} diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp index 60f9a35e..f27d7ab8 100644 --- a/src/Simplex_tree/example/simple_simplex_tree.cpp +++ b/src/Simplex_tree/example/simple_simplex_tree.cpp @@ -195,9 +195,8 @@ int main(int argc, char * const argv[]) { std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; for (auto f_simplex : simplexTree.filtration_simplex_range()) { std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; - for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) { - std::cout << static_cast(vertex) << " "; - } + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; std::cout << std::endl; } // [0.1] 0 @@ -250,5 +249,35 @@ int main(int argc, char * const argv[]) { std::cout << "***+ YES IT IS!\n"; else std::cout << "***- NO IT ISN'T\n"; + + invSimplexVector = { 0, 1 }; + simplexFound = simplexTree.find({ 0, 1 }); + std::cout << "**************IS THE SIMPLEX {0,1} IN THE SIMPLEX TREE ?\n"; + if (simplexFound != simplexTree.null_simplex()) + std::cout << "***+ YES IT IS!\n"; + else + std::cout << "***- NO IT ISN'T\n"; + + std::cout << "**************COFACES OF {0,1} IN CODIMENSION 1 ARE\n"; + for (auto& simplex : simplexTree.cofaces_simplex_range(simplexTree.find({0,1}), 1)) { + for (auto vertex : simplexTree.simplex_vertex_range(simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + std::cout << "**************STARS OF {0,1} ARE\n"; + for (auto& simplex : simplexTree.star_simplex_range(simplexTree.find({0,1}))) { + for (auto vertex : simplexTree.simplex_vertex_range(simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + std::cout << "**************BOUNDARIES OF {0,1,2} ARE\n"; + for (auto& simplex : simplexTree.boundary_simplex_range(simplexTree.find({0,1,2}))) { + for (auto vertex : simplexTree.simplex_vertex_range(simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + return 0; } diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index dbed47b8..ff31fd89 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1007,36 +1007,11 @@ class Simplex_tree { * The Simplex_tree must contain no simplex of dimension bigger than * 1 when calling the method. */ void expansion(int max_dim) { - expansion_with_blockers(max_dim, - [](Simplex_handle origin_sh, - Simplex_handle dict1_sh, - Simplex_handle dict2_sh, - Siblings* siblings) { - // Default blocker is always insert with the maximal filtration value between - // origin, dict1 and dict2 - return std::make_pair(true, (std::max)({origin_sh->second.filtration(), - dict1_sh->second.filtration(), - dict2_sh->second.filtration()})); }); - } - - /** \brief Expands the Simplex_tree containing only its one skeleton - * until dimension max_dim. - * - * The expanded simplicial complex until dimension \f$d\f$ - * attached to a graph \f$G\f$ is the maximal simplicial complex of - * dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. - * The filtration value assigned to a simplex is the maximal filtration - * value of one of its edges. - * - * The Simplex_tree must contain no simplex of dimension bigger than - * 1 when calling the method. */ - template< typename Blocker > - void expansion_with_blockers(int max_dim, Blocker blocker_expansion_function) { dimension_ = max_dim; for (Dictionary_it root_it = root_.members_.begin(); root_it != root_.members_.end(); ++root_it) { if (has_children(root_it)) { - siblings_expansion_with_blockers(root_it->second.children(), max_dim - 1, blocker_expansion_function); + siblings_expansion(root_it->second.children(), max_dim - 1); } } dimension_ = max_dim - dimension_; @@ -1044,9 +1019,8 @@ class Simplex_tree { private: /** \brief Recursive expansion of the simplex tree.*/ - template< typename Blocker > - void siblings_expansion_with_blockers(Siblings* siblings, // must contain elements - int k, Blocker blocker_expansion_function) { + void siblings_expansion(Siblings * siblings, // must contain elements + int k) { if (dimension_ > k) { dimension_ = k; } @@ -1060,22 +1034,20 @@ class Simplex_tree { s_h != siblings->members().end(); ++s_h, ++next) { Simplex_handle root_sh = find_vertex(s_h->first); if (has_children(root_sh)) { - intersection_with_blockers( - inter, // output intersection - next, // begin - siblings->members().end(), // end - root_sh->second.children()->members().begin(), - root_sh->second.children()->members().end(), - s_h, siblings, - blocker_expansion_function); + intersection( + inter, // output intersection + next, // begin + siblings->members().end(), // end + root_sh->second.children()->members().begin(), + root_sh->second.children()->members().end(), + s_h->second.filtration()); if (inter.size() != 0) { Siblings * new_sib = new Siblings(siblings, // oncles s_h->first, // parent inter); // boost::container::ordered_unique_range_t - // As siblings_expansion_with_blockers is recusively called, inter must be cleared before inter.clear(); s_h->second.assign_children(new_sib); - siblings_expansion_with_blockers(new_sib, k - 1, blocker_expansion_function); + siblings_expansion(new_sib, k - 1); } else { // ensure the children property s_h->second.assign_children(siblings); @@ -1087,20 +1059,16 @@ class Simplex_tree { /** \brief Intersects Dictionary 1 [begin1;end1) with Dictionary 2 [begin2,end2) * and assigns the maximal possible Filtration_value to the Nodes. */ - template< typename Blocker > - static void intersection_with_blockers(std::vector >& intersection, + static void intersection(std::vector >& intersection, Dictionary_it begin1, Dictionary_it end1, Dictionary_it begin2, Dictionary_it end2, - Dictionary_it origin_sh, - Siblings* siblings, - Blocker blocker_expansion_function) { + Filtration_value filtration_) { if (begin1 == end1 || begin2 == end2) return; // ----->> while (true) { if (begin1->first == begin2->first) { - std::pair blocker_result = blocker_expansion_function(origin_sh, begin1, begin2, siblings); - if (blocker_result.first) - intersection.emplace_back(begin1->first, Node(nullptr, blocker_result.second)); + Filtration_value filt = (std::max)({begin1->second.filtration(), begin2->second.filtration(), filtration_}); + intersection.emplace_back(begin1->first, Node(nullptr, filt)); if (++begin1 == end1 || ++begin2 == end2) return; // ----->> } else if (begin1->first < begin2->first) { @@ -1113,6 +1081,111 @@ class Simplex_tree { } } + + + /*-------------------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------------------*/ + + public: + /** \brief Expands the Simplex_tree containing only its one skeleton + * until dimension max_dim. + * + * The expanded simplicial complex until dimension \f$d\f$ + * attached to a graph \f$G\f$ is the maximal simplicial complex of + * dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. + * The filtration value assigned to a simplex is the maximal filtration + * value of one of its edges. + * + * The Simplex_tree must contain no simplex of dimension bigger than + * 1 when calling the method. */ + template< typename Blocker > + void expansion_with_blockers(int max_dim, Blocker blocker_expansion_function) { + dimension_ = max_dim; + // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree + for (auto& simplex : boost::adaptors::reverse(root_.members())) { + if (has_children(&simplex)) { + std::cout << " *** root on " << static_cast(simplex.first) << std::endl; + siblings_expansion_with_blockers(simplex.second.children(), max_dim - 1, blocker_expansion_function); + } + } + dimension_ = max_dim - dimension_; + } + + private: + /** \brief Recursive expansion of the simplex tree.*/ + template< typename Blocker > + void siblings_expansion_with_blockers(Siblings* siblings, // must contain elements + int k, Blocker blocker_expansion_function) { + if (dimension_ > k) { + dimension_ = k; + } + if (k == 0) + return; + // No need to go deeper + if (siblings->members().size() < 2) + return; + // Reverse loop starting before the last one for 'next' to be the last one + for (auto simplex = siblings->members().rbegin() + 1; simplex != siblings->members().rend(); simplex++) { + auto next = siblings->members().rbegin(); + std::vector > intersection; + while(next != simplex) { + bool to_be_inserted = true; + std::cout << "to_be_inserted = " << to_be_inserted << " dim = " << k << " simplex = " << simplex->first << " - next = " << next->first << std::endl; + + for (auto& border : boundary_simplex_range(simplex)) { + to_be_inserted = to_be_inserted && find_child(border, next->first); + + for (auto vertex : simplex_vertex_range(border)) { + std::cout << "(" << vertex << ")"; + } + std::cout << " | "; + } + std::cout << std::endl; + if (to_be_inserted) { + std::cout << next->first << " to be inserted." << std::endl; + intersection.emplace_back(next->first, Node(nullptr, 0.0)); + } + + // loop until simplex is reached + next++; + } + if (intersection.size() != 0) { + // Reverse the order to insert + std::reverse(std::begin(intersection), std::end(intersection)); + Siblings * new_sib = new Siblings(siblings, // oncles + simplex->first, // parent + intersection); // boost::container::ordered_unique_range_t + // intersection must be cleared before the function to be called recursively + intersection.clear(); + simplex->second.assign_children(new_sib); + siblings_expansion_with_blockers(new_sib, k - 1, blocker_expansion_function); + } else { + // ensure the children property + simplex->second.assign_children(siblings); + intersection.clear(); + } + + } + + } + + /** \private Returns true if vh is a member of sh*/ + bool find_child(Simplex_handle sh, Vertex_handle vh) { + std::vector child = {vh}; + std::cout << "+" << vh; + for (auto vertex : simplex_vertex_range(sh)) { + std::cout << "+" << vertex; + child.push_back(vertex); + } + std::cout << " => " << (find(child) != null_simplex()) << "___ "; + return find(child) != null_simplex(); + } + + /*-------------------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------------------*/ + public: /** \brief Write the hasse diagram of the simplicial complex in os. * -- cgit v1.2.3 From 7c205b2cb36b9d8b04556cc81afb4940f27743fc Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Sat, 1 Jul 2017 21:57:42 +0000 Subject: Example of blocker and Cech Complex implementation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2573 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 88a98ef49630989833a09b59d9b1e4713b409c0b --- src/Simplex_tree/example/CMakeLists.txt | 32 +++++------ src/Simplex_tree/example/block.cpp | 42 ++++++++------- .../example/cech_complex_step_by_step.cpp | 62 +++++++++------------- 3 files changed, 63 insertions(+), 73 deletions(-) diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index d5f512b3..7a30979f 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -35,30 +35,26 @@ if(GMP_FOUND AND CGAL_FOUND) install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin) -endif() + # + # TO BE REMOVED !! + # -add_executable ( Simplex_tree_example_cech_complex_step_by_step cech_complex_step_by_step.cpp) -target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${Boost_PROGRAM_OPTIONS_LIBRARY}) -if (TBB_FOUND) - target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${TBB_LIBRARIES}) -endif() -add_test(NAME Simplex_tree_example_cech_complex_step_by_step COMMAND $ - "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" "-r" "12." "-d" "3") -install(TARGETS Simplex_tree_example_cech_complex_step_by_step DESTINATION bin) + add_executable ( Simplex_tree_example_cech_complex_step_by_step cech_complex_step_by_step.cpp ) + target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${GMP_LIBRARIES} ${CGAL_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}) + if (TBB_FOUND) + target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${TBB_LIBRARIES}) + endif() + add_test(NAME Simplex_tree_example_cech_complex_step_by_step COMMAND $ + "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" "-d" "3" "-r" "6.0") +endif() # # TO BE REMOVED !! # -#add_executable ( rips_step_by_step rips_step_by_step.cpp) -#target_link_libraries(rips_step_by_step ${Boost_PROGRAM_OPTIONS_LIBRARY}) -#if (TBB_FOUND) -# target_link_libraries(rips_step_by_step ${TBB_LIBRARIES}) -#endif() - - -add_executable ( block block.cpp ) +add_executable ( Simplex_tree_example_block block.cpp ) if (TBB_FOUND) - target_link_libraries(block ${TBB_LIBRARIES}) + target_link_libraries(Simplex_tree_example_block ${TBB_LIBRARIES}) endif() +add_test(NAME Simplex_tree_example_block COMMAND $) diff --git a/src/Simplex_tree/example/block.cpp b/src/Simplex_tree/example/block.cpp index 07ec3921..75b8d1ea 100644 --- a/src/Simplex_tree/example/block.cpp +++ b/src/Simplex_tree/example/block.cpp @@ -28,31 +28,27 @@ #include using Simplex_tree = Gudhi::Simplex_tree<>; -using Vertex_handle = Simplex_tree::Vertex_handle; -using Filtration_value = Simplex_tree::Filtration_value; -using typeVectorVertex = std::vector< Vertex_handle >; -using typePairSimplexBool = std::pair< Simplex_tree::Simplex_handle, bool >; +using Simplex_handle = Simplex_tree::Simplex_handle; int main(int argc, char * const argv[]) { // Construct the Simplex Tree Simplex_tree simplexTree; - simplexTree.insert_simplex({0, 1}); - simplexTree.insert_simplex({0, 2}); - simplexTree.insert_simplex({0, 3}); - simplexTree.insert_simplex({1, 2}); - simplexTree.insert_simplex({1, 3}); - simplexTree.insert_simplex({2, 3}); - simplexTree.insert_simplex({2, 4}); - simplexTree.insert_simplex({3, 6}); - simplexTree.insert_simplex({4, 5}); - simplexTree.insert_simplex({4, 6}); - simplexTree.insert_simplex({5, 6}); - simplexTree.insert_simplex({6}); + simplexTree.insert_simplex({0, 1}, 0.); + simplexTree.insert_simplex({0, 2}, 1.); + simplexTree.insert_simplex({0, 3}, 2.); + simplexTree.insert_simplex({1, 2}, 3.); + simplexTree.insert_simplex({1, 3}, 4.); + simplexTree.insert_simplex({2, 3}, 5.); + simplexTree.insert_simplex({2, 4}, 6.); + simplexTree.insert_simplex({3, 6}, 7.); + simplexTree.insert_simplex({4, 5}, 8.); + simplexTree.insert_simplex({4, 6}, 9.); + simplexTree.insert_simplex({5, 6}, 10.); + simplexTree.insert_simplex({6}, 11.); std::cout << "********************************************************************\n"; - // Display the Simplex_tree - Can not be done in the middle of 2 inserts std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; @@ -63,11 +59,19 @@ int main(int argc, char * const argv[]) { std::cout << std::endl; } - simplexTree.expansion_with_blockers(3, [](){return true;}); + simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){ + bool result = false; + for (auto vertex : simplexTree.simplex_vertex_range(sh)) { + if (vertex == 6) + result = true; + std::cout << "#(" << vertex << ")#"; + } + std::cout << std::endl; + return result; + }); simplexTree.initialize_filtration(); std::cout << "********************************************************************\n"; - // Display the Simplex_tree - Can not be done in the middle of 2 inserts std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; diff --git a/src/Simplex_tree/example/cech_complex_step_by_step.cpp b/src/Simplex_tree/example/cech_complex_step_by_step.cpp index b5cda443..1805c792 100644 --- a/src/Simplex_tree/example/cech_complex_step_by_step.cpp +++ b/src/Simplex_tree/example/cech_complex_step_by_step.cpp @@ -28,9 +28,9 @@ // #include // #include // #include -#include -#include -#include +#include +#include +#include #include @@ -59,44 +59,34 @@ using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirec >; using Edge_t = std::pair< Vertex_handle, Vertex_handle >; -// using Kernel = CGAL::Epick_d< CGAL::Dimension_tag<2> >;// CGAL::Dynamic_dimension_tag >; -typedef CGAL::Cartesian_d Kernel; -typedef CGAL::Optimisation_d_traits_d Traits; -typedef CGAL::Min_sphere_d Min_sphere; - +using Kernel = CGAL::Epick_d< CGAL::Dimension_tag<2> >;// CGAL::Dynamic_dimension_tag >; using Point = Kernel::Point_d; +using Traits = CGAL::Min_sphere_of_points_d_traits_d; +using Min_sphere = CGAL::Min_sphere_of_spheres_d; + using Points_off_reader = Gudhi::Points_off_reader; -// using Min_sphere = CGAL::Min_sphere_d; class Cech_blocker { public: - std::pair operator()(Simplex_handle origin_sh, Simplex_handle dict1_sh, Simplex_handle dict2_sh, Siblings* siblings) { - //std::vector path = {dict1_sh->first, origin_sh->first}; - Siblings* sib_path = siblings; - std::vector sphere_points = {point_cloud_[dict1_sh->first], point_cloud_[origin_sh->first]}; - do { - //path.push_back(sib_path->parent()); - sphere_points.push_back(point_cloud_[sib_path->parent()]); - sib_path = sib_path->oncles(); - } while (sib_path->oncles() != nullptr); - /*std::cout << square_threshold_ << "-"; - for (auto vh : path) { - std::cout << vh << " "; + bool operator()(Simplex_handle sh) { + std::vector points; + for (auto vertex : simplex_tree_.simplex_vertex_range(sh)) { + points.push_back(point_cloud_[vertex]); + std::cout << "#(" << vertex << ")#"; } - std::cout << std::endl;*/ - Min_sphere min_sphere(sphere_points.begin(), sphere_points.end()); - //std::cout << min_sphere.squared_radius() << std::endl; - Filtration_value squared_diameter = min_sphere.squared_radius() * 4.; - // Default blocker is always insert with the maximal filtration value between - // origin, dict1 and dict2 - return std::make_pair(squared_diameter < square_threshold_, - squared_diameter); + Min_sphere ms(points.begin(),points.end()); + Filtration_value radius = ms.radius(); + std::cout << "radius = " << radius << " - " << (radius > threshold_) << std::endl; + simplex_tree_.assign_filtration(sh, radius); + return (radius > threshold_); } - Cech_blocker(Filtration_value threshold, const std::vector& point_cloud) - : square_threshold_(threshold * threshold), + Cech_blocker(Simplex_tree& simplex_tree, Filtration_value threshold, const std::vector& point_cloud) + : simplex_tree_(simplex_tree), + threshold_(threshold), point_cloud_(point_cloud) { } private: - Filtration_value square_threshold_; + Simplex_tree simplex_tree_; + Filtration_value threshold_; std::vector point_cloud_; }; @@ -127,7 +117,7 @@ int main(int argc, char * argv[]) { // insert the proximity graph in the simplex tree st.insert_graph(prox_graph); // expand the graph until dimension dim_max - st.expansion_with_blockers(dim_max, Cech_blocker(threshold, off_reader.get_point_cloud())); + st.expansion_with_blockers(dim_max, Cech_blocker(st, threshold, off_reader.get_point_cloud())); std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; std::cout << " and has dimension " << st.dimension() << " \n"; @@ -206,8 +196,6 @@ Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value thresh std::vector< Filtration_value > edges_fil; Kernel k; - Filtration_value square_threshold = threshold * threshold; - Vertex_handle idx_u, idx_v; Filtration_value fil; idx_u = 0; @@ -215,7 +203,9 @@ Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value thresh idx_v = idx_u + 1; for (auto it_v = it_u + 1; it_v != points.end(); ++it_v, ++idx_v) { fil = k.squared_distance_d_object()(*it_u, *it_v); - if (fil <= square_threshold) { + // For Cech Complex, threshold is a radius (distance /2) + fil = std::sqrt(fil) / 2.; + if (fil <= threshold) { edges.emplace_back(idx_u, idx_v); edges_fil.push_back(fil); } -- cgit v1.2.3 From 093866604f986dded2db6a96d7dbc4b6d1f7194a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 5 Jul 2017 15:03:57 +0000 Subject: Fix default filtration value given by the graph_expansion method with blocker git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2585 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 38586e3c9a622c74c6b6658bdc0a6776c5ea5d5a --- src/Simplex_tree/example/CMakeLists.txt | 17 -- src/Simplex_tree/example/block.cpp | 30 ++- .../example/cech_complex_step_by_step.cpp | 230 --------------------- src/Simplex_tree/include/gudhi/Simplex_tree.h | 93 +++++---- 4 files changed, 61 insertions(+), 309 deletions(-) delete mode 100644 src/Simplex_tree/example/cech_complex_step_by_step.cpp diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index 7a30979f..4557deb3 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -34,25 +34,8 @@ if(GMP_FOUND AND CGAL_FOUND) "${CMAKE_SOURCE_DIR}/data/points/bunny_5000.off") install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin) - - # - # TO BE REMOVED !! - # - - add_executable ( Simplex_tree_example_cech_complex_step_by_step cech_complex_step_by_step.cpp ) - target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${GMP_LIBRARIES} ${CGAL_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY}) - if (TBB_FOUND) - target_link_libraries(Simplex_tree_example_cech_complex_step_by_step ${TBB_LIBRARIES}) - endif() - add_test(NAME Simplex_tree_example_cech_complex_step_by_step COMMAND $ - "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" "-d" "3" "-r" "6.0") - endif() -# -# TO BE REMOVED !! -# - add_executable ( Simplex_tree_example_block block.cpp ) if (TBB_FOUND) target_link_libraries(Simplex_tree_example_block ${TBB_LIBRARIES}) diff --git a/src/Simplex_tree/example/block.cpp b/src/Simplex_tree/example/block.cpp index 75b8d1ea..67697b89 100644 --- a/src/Simplex_tree/example/block.cpp +++ b/src/Simplex_tree/example/block.cpp @@ -24,15 +24,13 @@ #include #include -#include // for pair -#include using Simplex_tree = Gudhi::Simplex_tree<>; using Simplex_handle = Simplex_tree::Simplex_handle; int main(int argc, char * const argv[]) { - // Construct the Simplex Tree + // Construct the Simplex Tree with a 1-skeleton graph example Simplex_tree simplexTree; simplexTree.insert_simplex({0, 1}, 0.); @@ -46,31 +44,27 @@ int main(int argc, char * const argv[]) { simplexTree.insert_simplex({4, 5}, 8.); simplexTree.insert_simplex({4, 6}, 9.); simplexTree.insert_simplex({5, 6}, 10.); - simplexTree.insert_simplex({6}, 11.); - - std::cout << "********************************************************************\n"; - std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; - std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; - std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; - for (auto f_simplex : simplexTree.filtration_simplex_range()) { - std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; - for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) - std::cout << "(" << vertex << ")"; - std::cout << std::endl; - } + simplexTree.insert_simplex({6}, 10.); simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){ bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. for (auto vertex : simplexTree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices if (vertex == 6) result = true; - std::cout << "#(" << vertex << ")#"; + std::cout << vertex << ", "; } - std::cout << std::endl; + std::cout << "] ( " << simplexTree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + return result; }); - simplexTree.initialize_filtration(); std::cout << "********************************************************************\n"; std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; diff --git a/src/Simplex_tree/example/cech_complex_step_by_step.cpp b/src/Simplex_tree/example/cech_complex_step_by_step.cpp deleted file mode 100644 index 1805c792..00000000 --- a/src/Simplex_tree/example/cech_complex_step_by_step.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Clément Maria - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -// #include -// #include -// #include -#include -#include -#include - -#include - -#include -#include -#include // infinity -#include // for pair -#include - -// ---------------------------------------------------------------------------- -// rips_persistence_step_by_step is an example of each step that is required to -// build a Rips over a Simplex_tree. Please refer to rips_persistence to see -// how to do the same thing with the Rips_complex wrapper for less detailed -// steps. -// ---------------------------------------------------------------------------- - -// Types definition -using Simplex_tree = Gudhi::Simplex_tree; -using Vertex_handle = Simplex_tree::Vertex_handle; -using Simplex_handle = Simplex_tree::Simplex_handle; -using Filtration_value = Simplex_tree::Filtration_value; -using Siblings = Simplex_tree::Siblings; -using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS -, boost::property < vertex_filtration_t, Filtration_value > -, boost::property < edge_filtration_t, Filtration_value > ->; -using Edge_t = std::pair< Vertex_handle, Vertex_handle >; - -using Kernel = CGAL::Epick_d< CGAL::Dimension_tag<2> >;// CGAL::Dynamic_dimension_tag >; -using Point = Kernel::Point_d; -using Traits = CGAL::Min_sphere_of_points_d_traits_d; -using Min_sphere = CGAL::Min_sphere_of_spheres_d; - -using Points_off_reader = Gudhi::Points_off_reader; - -class Cech_blocker { - public: - bool operator()(Simplex_handle sh) { - std::vector points; - for (auto vertex : simplex_tree_.simplex_vertex_range(sh)) { - points.push_back(point_cloud_[vertex]); - std::cout << "#(" << vertex << ")#"; - } - Min_sphere ms(points.begin(),points.end()); - Filtration_value radius = ms.radius(); - std::cout << "radius = " << radius << " - " << (radius > threshold_) << std::endl; - simplex_tree_.assign_filtration(sh, radius); - return (radius > threshold_); - } - Cech_blocker(Simplex_tree& simplex_tree, Filtration_value threshold, const std::vector& point_cloud) - : simplex_tree_(simplex_tree), - threshold_(threshold), - point_cloud_(point_cloud) { } - private: - Simplex_tree simplex_tree_; - Filtration_value threshold_; - std::vector point_cloud_; -}; - -template< typename InputPointRange> -Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold); - -void program_options(int argc, char * argv[] - , std::string & off_file_points - , Filtration_value & threshold - , int & dim_max); - -int main(int argc, char * argv[]) { - std::string off_file_points; - Filtration_value threshold; - int dim_max; - - program_options(argc, argv, off_file_points, threshold, dim_max); - - // Extract the points from the file filepoints - Points_off_reader off_reader(off_file_points); - - // Compute the proximity graph of the points - Graph_t prox_graph = compute_proximity_graph(off_reader.get_point_cloud(), threshold); - - //Min_sphere sph1(off_reader.get_point_cloud()[0], off_reader.get_point_cloud()[1], off_reader.get_point_cloud()[2]); - // Construct the Rips complex in a Simplex Tree - Simplex_tree st; - // insert the proximity graph in the simplex tree - st.insert_graph(prox_graph); - // expand the graph until dimension dim_max - st.expansion_with_blockers(dim_max, Cech_blocker(st, threshold, off_reader.get_point_cloud())); - - std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; - std::cout << " and has dimension " << st.dimension() << " \n"; - - // Sort the simplices in the order of the filtration - st.initialize_filtration(); - - std::cout << "********************************************************************\n"; - // Display the Simplex_tree - Can not be done in the middle of 2 inserts - std::cout << "* The complex contains " << st.num_simplices() << " simplices\n"; - std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << "\n"; - std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; - for (auto f_simplex : st.filtration_simplex_range()) { - std::cout << " " << "[" << st.filtration(f_simplex) << "] "; - for (auto vertex : st.simplex_vertex_range(f_simplex)) { - std::cout << static_cast(vertex) << " "; - } - std::cout << std::endl; - } - - return 0; -} - -void program_options(int argc, char * argv[] - , std::string & off_file_points - , Filtration_value & threshold - , int & dim_max) { - namespace po = boost::program_options; - po::options_description hidden("Hidden options"); - hidden.add_options() - ("input-file", po::value(&off_file_points), - "Name of an OFF file containing a point set.\n"); - - po::options_description visible("Allowed options", 100); - visible.add_options() - ("help,h", "produce help message") - ("max-edge-length,r", - po::value(&threshold)->default_value(std::numeric_limits::infinity()), - "Maximal length of an edge for the Rips complex construction.") - ("cpx-dimension,d", po::value(&dim_max)->default_value(1), - "Maximal dimension of the Rips complex we want to compute."); - - po::positional_options_description pos; - pos.add("input-file", 1); - - po::options_description all; - all.add(visible).add(hidden); - - po::variables_map vm; - po::store(po::command_line_parser(argc, argv). - options(all).positional(pos).run(), vm); - po::notify(vm); - - if (vm.count("help") || !vm.count("input-file")) { - std::cout << std::endl; - std::cout << "Construct a Cech complex defined on a set of input points.\n \n"; - - std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl; - std::cout << visible << std::endl; - std::abort(); - } -} - -/** Output the proximity graph of the points. - * - * If points contains n elements, the proximity graph is the graph - * with n vertices, and an edge [u,v] iff the distance function between - * points u and v is smaller than threshold. - * - * The type PointCloud furnishes .begin() and .end() methods, that return - * iterators with value_type Point. - */ -template< typename InputPointRange> -Graph_t compute_proximity_graph(InputPointRange &points, Filtration_value threshold) { - std::vector< Edge_t > edges; - std::vector< Filtration_value > edges_fil; - - Kernel k; - Vertex_handle idx_u, idx_v; - Filtration_value fil; - idx_u = 0; - for (auto it_u = points.begin(); it_u != points.end(); ++it_u) { - idx_v = idx_u + 1; - for (auto it_v = it_u + 1; it_v != points.end(); ++it_v, ++idx_v) { - fil = k.squared_distance_d_object()(*it_u, *it_v); - // For Cech Complex, threshold is a radius (distance /2) - fil = std::sqrt(fil) / 2.; - if (fil <= threshold) { - edges.emplace_back(idx_u, idx_v); - edges_fil.push_back(fil); - } - } - ++idx_u; - } - - Graph_t skel_graph(edges.begin() - , edges.end() - , edges_fil.begin() - , idx_u); // number of points labeled from 0 to idx_u-1 - - auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph); - - boost::graph_traits::vertex_iterator vi, vi_end; - for (std::tie(vi, vi_end) = boost::vertices(skel_graph); - vi != vi_end; ++vi) { - boost::put(vertex_prop, *vi, 0.); - } - - return skel_graph; -} diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index ff31fd89..72cb9401 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1081,31 +1081,23 @@ class Simplex_tree { } } - - - /*-------------------------------------------------------------------------------------------------------------------------*/ - /*-------------------------------------------------------------------------------------------------------------------------*/ - /*-------------------------------------------------------------------------------------------------------------------------*/ - public: - /** \brief Expands the Simplex_tree containing only its one skeleton - * until dimension max_dim. + /** \brief Expands the Simplex_tree containing only its one skeleton until dimension max_dim according with a user + * given blocker expansion oracle * - * The expanded simplicial complex until dimension \f$d\f$ - * attached to a graph \f$G\f$ is the maximal simplicial complex of - * dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. - * The filtration value assigned to a simplex is the maximal filtration - * value of one of its edges. + * The expanded simplicial complex until dimension \f$d\f$ attached to a graph \f$G\f$ is the maximal simplicial + * complex of dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. + * The filtration value assigned to a simplex is the maximal filtration value of one of its edges. + * The blocker expansion oracle shall answer true on a Simplex_handle if this Simplex_handle has to be removed, + * false otherwise. The blocker expansion oracle can re-assign the filtration value. * - * The Simplex_tree must contain no simplex of dimension bigger than - * 1 when calling the method. */ + * The Simplex_tree must contain no simplex of dimension bigger than 1 when calling the method. */ template< typename Blocker > void expansion_with_blockers(int max_dim, Blocker blocker_expansion_function) { dimension_ = max_dim; // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree for (auto& simplex : boost::adaptors::reverse(root_.members())) { if (has_children(&simplex)) { - std::cout << " *** root on " << static_cast(simplex.first) << std::endl; siblings_expansion_with_blockers(simplex.second.children(), max_dim - 1, blocker_expansion_function); } } @@ -1113,7 +1105,7 @@ class Simplex_tree { } private: - /** \brief Recursive expansion of the simplex tree.*/ + /** \brief Recursive expansion with blockers of the simplex tree.*/ template< typename Blocker > void siblings_expansion_with_blockers(Siblings* siblings, // must contain elements int k, Blocker blocker_expansion_function) { @@ -1131,22 +1123,16 @@ class Simplex_tree { std::vector > intersection; while(next != simplex) { bool to_be_inserted = true; - std::cout << "to_be_inserted = " << to_be_inserted << " dim = " << k << " simplex = " << simplex->first << " - next = " << next->first << std::endl; - + Filtration_value filt = simplex->second.filtration(); + // If all the boundaries are present, 'next' needs to be inserted for (auto& border : boundary_simplex_range(simplex)) { - to_be_inserted = to_be_inserted && find_child(border, next->first); - - for (auto vertex : simplex_vertex_range(border)) { - std::cout << "(" << vertex << ")"; - } - std::cout << " | "; + Simplex_handle border_child = find_child(border, next->first); + to_be_inserted = to_be_inserted && (border_child != null_simplex()); + filt = std::max(filt, filtration(border_child)); } - std::cout << std::endl; if (to_be_inserted) { - std::cout << next->first << " to be inserted." << std::endl; - intersection.emplace_back(next->first, Node(nullptr, 0.0)); + intersection.emplace_back(next->first, Node(nullptr, filt)); } - // loop until simplex is reached next++; } @@ -1158,34 +1144,50 @@ class Simplex_tree { intersection); // boost::container::ordered_unique_range_t // intersection must be cleared before the function to be called recursively intersection.clear(); - simplex->second.assign_children(new_sib); - siblings_expansion_with_blockers(new_sib, k - 1, blocker_expansion_function); + + std::vector blocked_new_sib_list; + // As all intersections are inserted, we can call the blocker function on all new_sib members + for (auto new_sib_member = new_sib->members().begin(); + new_sib_member != new_sib->members().end(); + new_sib_member++) { + bool blocker_result = blocker_expansion_function(new_sib_member); + // new_sib member has been blocked by the blocker function + // add it to the list to be removed - do not perform it while looping on it + if (blocker_result) + blocked_new_sib_list.push_back(new_sib_member); + } + bool removed = false; + for (auto& blocked_new_sib_member : blocked_new_sib_list){ + removed = removed || remove_maximal_simplex(blocked_new_sib_member); + } + if (removed) { + // ensure the children property + simplex->second.assign_children(siblings); + } else { + // ensure recursive call + simplex->second.assign_children(new_sib); + siblings_expansion_with_blockers(new_sib, k - 1, blocker_expansion_function); + } } else { // ensure the children property simplex->second.assign_children(siblings); intersection.clear(); } - } - } - /** \private Returns true if vh is a member of sh*/ - bool find_child(Simplex_handle sh, Vertex_handle vh) { + /* \private Returns the Simplex_handle composed of the vertex list (from the Simplex_handle), plus the given + * Vertex_handle. + * Returns null_simplex() if it does not exist + */ + Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) { std::vector child = {vh}; - std::cout << "+" << vh; for (auto vertex : simplex_vertex_range(sh)) { - std::cout << "+" << vertex; child.push_back(vertex); } - std::cout << " => " << (find(child) != null_simplex()) << "___ "; - return find(child) != null_simplex(); + return find(child); } - /*-------------------------------------------------------------------------------------------------------------------------*/ - /*-------------------------------------------------------------------------------------------------------------------------*/ - /*-------------------------------------------------------------------------------------------------------------------------*/ - public: /** \brief Write the hasse diagram of the simplicial complex in os. * @@ -1295,11 +1297,12 @@ class Simplex_tree { public: /** \brief Remove a maximal simplex. * @param[in] sh Simplex handle on the maximal simplex to remove. + * @return true if siblings was deleted, false otherwise. * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done). */ - void remove_maximal_simplex(Simplex_handle sh) { + bool remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children GUDHI_CHECK(!has_children(sh), std::invalid_argument("Simplex_tree::remove_maximal_simplex - argument has children")); @@ -1315,7 +1318,9 @@ class Simplex_tree { // Sibling is emptied : must be deleted, and its parent must point on his own Sibling child->oncles()->members().at(child->parent()).assign_children(child->oncles()); delete child; + return true; } + return false; } private: -- cgit v1.2.3 From 40aaa716132bb2f6a6110e229d91345618bf1088 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 5 Jul 2017 17:50:45 +0000 Subject: Checkin tests and fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2586 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0f9cbe3d6b94e939e151dea989ae99f7e4f3bffa --- src/Simplex_tree/example/CMakeLists.txt | 8 +- src/Simplex_tree/example/block.cpp | 80 ------- .../example/graph_expansion_with_blocker.cpp | 79 +++++++ src/Simplex_tree/test/CMakeLists.txt | 8 + .../simplex_tree_graph_expansion_unit_test.cpp | 235 +++++++++++++++++++++ src/common/include/gudhi/Points_off_io.h | 2 +- 6 files changed, 328 insertions(+), 84 deletions(-) delete mode 100644 src/Simplex_tree/example/block.cpp create mode 100644 src/Simplex_tree/example/graph_expansion_with_blocker.cpp create mode 100644 src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index 4557deb3..c414c019 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -36,8 +36,10 @@ if(GMP_FOUND AND CGAL_FOUND) install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin) endif() -add_executable ( Simplex_tree_example_block block.cpp ) +add_executable ( Simplex_tree_example_graph_expansion_with_blocker graph_expansion_with_blocker.cpp ) if (TBB_FOUND) - target_link_libraries(Simplex_tree_example_block ${TBB_LIBRARIES}) + target_link_libraries(Simplex_tree_example_graph_expansion_with_blocker ${TBB_LIBRARIES}) endif() -add_test(NAME Simplex_tree_example_block COMMAND $) +add_test(NAME Simplex_tree_example_graph_expansion_with_blocker COMMAND $) + +install(TARGETS Simplex_tree_example_graph_expansion_with_blocker DESTINATION bin) diff --git a/src/Simplex_tree/example/block.cpp b/src/Simplex_tree/example/block.cpp deleted file mode 100644 index 67697b89..00000000 --- a/src/Simplex_tree/example/block.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Vincent Rouvreau - * - * Copyright (C) 2014 - * - * 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 . - */ - -#include -#include - -#include - -using Simplex_tree = Gudhi::Simplex_tree<>; -using Simplex_handle = Simplex_tree::Simplex_handle; - -int main(int argc, char * const argv[]) { - - // Construct the Simplex Tree with a 1-skeleton graph example - Simplex_tree simplexTree; - - simplexTree.insert_simplex({0, 1}, 0.); - simplexTree.insert_simplex({0, 2}, 1.); - simplexTree.insert_simplex({0, 3}, 2.); - simplexTree.insert_simplex({1, 2}, 3.); - simplexTree.insert_simplex({1, 3}, 4.); - simplexTree.insert_simplex({2, 3}, 5.); - simplexTree.insert_simplex({2, 4}, 6.); - simplexTree.insert_simplex({3, 6}, 7.); - simplexTree.insert_simplex({4, 5}, 8.); - simplexTree.insert_simplex({4, 6}, 9.); - simplexTree.insert_simplex({5, 6}, 10.); - simplexTree.insert_simplex({6}, 10.); - - simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){ - bool result = false; - std::cout << "Blocker on ["; - // User can loop on the vertices from the given simplex_handle i.e. - for (auto vertex : simplexTree.simplex_vertex_range(sh)) { - // We block the expansion, if the vertex '6' is in the given list of vertices - if (vertex == 6) - result = true; - std::cout << vertex << ", "; - } - std::cout << "] ( " << simplexTree.filtration(sh); - // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) - simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.); - - std::cout << " + 1. ) = " << result << std::endl; - - return result; - }); - - std::cout << "********************************************************************\n"; - std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; - std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; - std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; - for (auto f_simplex : simplexTree.filtration_simplex_range()) { - std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; - for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) - std::cout << "(" << vertex << ")"; - std::cout << std::endl; - } - - return 0; -} diff --git a/src/Simplex_tree/example/graph_expansion_with_blocker.cpp b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp new file mode 100644 index 00000000..d0d3f038 --- /dev/null +++ b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp @@ -0,0 +1,79 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2014 + * + * 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 . + */ + +#include + +#include + +using Simplex_tree = Gudhi::Simplex_tree<>; +using Simplex_handle = Simplex_tree::Simplex_handle; + +int main(int argc, char * const argv[]) { + + // Construct the Simplex Tree with a 1-skeleton graph example + Simplex_tree simplexTree; + + simplexTree.insert_simplex({0, 1}, 0.); + simplexTree.insert_simplex({0, 2}, 1.); + simplexTree.insert_simplex({0, 3}, 2.); + simplexTree.insert_simplex({1, 2}, 3.); + simplexTree.insert_simplex({1, 3}, 4.); + simplexTree.insert_simplex({2, 3}, 5.); + simplexTree.insert_simplex({2, 4}, 6.); + simplexTree.insert_simplex({3, 6}, 7.); + simplexTree.insert_simplex({4, 5}, 8.); + simplexTree.insert_simplex({4, 6}, 9.); + simplexTree.insert_simplex({5, 6}, 10.); + simplexTree.insert_simplex({6}, 10.); + + simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){ + bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. + for (auto vertex : simplexTree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices + if (vertex == 6) + result = true; + std::cout << vertex << ", "; + } + std::cout << "] ( " << simplexTree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + + return result; + }); + + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplexTree.dimension() << " - filtration " << simplexTree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplexTree.filtration_simplex_range()) { + std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] "; + for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + return 0; +} diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 17b0f2c2..2408d937 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -13,3 +13,11 @@ endif() file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) gudhi_add_coverage_test(Simplex_tree_test_unit) + +add_executable ( Simplex_tree_test_unit_graph_expansion simplex_tree_graph_expansion_unit_test.cpp ) +target_link_libraries(Simplex_tree_test_unit_graph_expansion ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_test_unit_graph_expansion ${TBB_LIBRARIES}) +endif() + +gudhi_add_coverage_test(Simplex_tree_test_unit_graph_expansion) diff --git a/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp new file mode 100644 index 00000000..bef82275 --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include // std::pair, std::make_pair +#include // float comparison +#include +#include // greater + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree" +#include +#include + +// ^ +// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +typedef boost::mpl::list, Simplex_tree> list_of_tested_variants; + + +bool AreAlmostTheSame(float a, float b) { + return std::fabs(a - b) < std::numeric_limits::epsilon(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_with_blockers_3, typeST, list_of_tested_variants) { + using Simplex_handle = typename typeST::Simplex_handle; + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion_with_blockers(3, [&](Simplex_handle sh){ + bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. + for (auto vertex : simplex_tree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices + if (vertex == 6) + result = true; + std::cout << vertex << ", "; + } + std::cout << "] ( " << simplex_tree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplex_tree.assign_filtration(sh, simplex_tree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + + return result; + }); + + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_with_blockers_3\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplex_tree.dimension() << " - filtration " << simplex_tree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 23); + BOOST_CHECK(simplex_tree.dimension() == 3); + // {4, 5, 6} shall be blocked + BOOST_CHECK(simplex_tree.find({4, 5, 6}) == simplex_tree.null_simplex()); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 6.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 6.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2,3})), 7.)); + +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_with_blockers_2, typeST, list_of_tested_variants) { + using Simplex_handle = typename typeST::Simplex_handle; + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion_with_blockers(2, [&](Simplex_handle sh){ + bool result = false; + std::cout << "Blocker on ["; + // User can loop on the vertices from the given simplex_handle i.e. + for (auto vertex : simplex_tree.simplex_vertex_range(sh)) { + // We block the expansion, if the vertex '6' is in the given list of vertices + if (vertex == 6) + result = true; + std::cout << vertex << ", "; + } + std::cout << "] ( " << simplex_tree.filtration(sh); + // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries) + simplex_tree.assign_filtration(sh, simplex_tree.filtration(sh) + 1.); + + std::cout << " + 1. ) = " << result << std::endl; + + return result; + }); + + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_with_blockers_2\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplex_tree.dimension() << " - filtration " << simplex_tree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 22); + BOOST_CHECK(simplex_tree.dimension() == 2); + // {4, 5, 6} shall be blocked + BOOST_CHECK(simplex_tree.find({4, 5, 6}) == simplex_tree.null_simplex()); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 6.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 6.)); + BOOST_CHECK(simplex_tree.find({0,1,2,3}) == simplex_tree.null_simplex()); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion, typeST, list_of_tested_variants) { + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion(3); + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_3\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplex_tree.dimension() << " - filtration " << simplex_tree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 24); + BOOST_CHECK(simplex_tree.dimension() == 3); + + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({4,5,6})), 10.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 3.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2,3})), 5.)); + +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_2, typeST, list_of_tested_variants) { + // Construct the Simplex Tree with a 1-skeleton graph example + typeST simplex_tree; + + simplex_tree.insert_simplex({0, 1}, 0.); + simplex_tree.insert_simplex({0, 2}, 1.); + simplex_tree.insert_simplex({0, 3}, 2.); + simplex_tree.insert_simplex({1, 2}, 3.); + simplex_tree.insert_simplex({1, 3}, 4.); + simplex_tree.insert_simplex({2, 3}, 5.); + simplex_tree.insert_simplex({2, 4}, 6.); + simplex_tree.insert_simplex({3, 6}, 7.); + simplex_tree.insert_simplex({4, 5}, 8.); + simplex_tree.insert_simplex({4, 6}, 9.); + simplex_tree.insert_simplex({5, 6}, 10.); + simplex_tree.insert_simplex({6}, 10.); + + simplex_tree.expansion(2); + + std::cout << "********************************************************************\n"; + std::cout << "simplex_tree_expansion_2\n"; + std::cout << "********************************************************************\n"; + std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices\n"; + std::cout << " - dimension " << simplex_tree.dimension() << " - filtration " << simplex_tree.filtration() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : simplex_tree.filtration_simplex_range()) { + std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] "; + for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + + BOOST_CHECK(simplex_tree.num_simplices() == 23); + BOOST_CHECK(simplex_tree.dimension() == 2); + + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({4,5,6})), 10.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 3.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 4.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 5.)); + BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 5.)); + BOOST_CHECK(simplex_tree.find({0,1,2,3}) == simplex_tree.null_simplex()); +} diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h index 2104b411..29af8a8a 100644 --- a/src/common/include/gudhi/Points_off_io.h +++ b/src/common/include/gudhi/Points_off_io.h @@ -85,7 +85,7 @@ class Points_off_visitor_reader { std::cout << std::endl; #endif // DEBUG_TRACES // Fill the point cloud - point_cloud.push_back(Point_d(point.end() - point.begin(), point.begin(), point.end())); + point_cloud.push_back(Point_d(point.begin(), point.end())); } // Off_reader visitor maximal_face implementation - Only points are read -- cgit v1.2.3 From 73c3f473fa9d4dc6965607edd1ad748d26cfb86b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 6 Jul 2017 07:10:41 +0000 Subject: Doc example addition git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2587 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: eec20e1b4242460fbe97a9622d69ad35bfdca8b7 --- src/Simplex_tree/doc/Intro_simplex_tree.h | 9 ++++++--- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- src/common/doc/main_page.h | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Simplex_tree/doc/Intro_simplex_tree.h b/src/Simplex_tree/doc/Intro_simplex_tree.h index f5b72ff6..769491d9 100644 --- a/src/Simplex_tree/doc/Intro_simplex_tree.h +++ b/src/Simplex_tree/doc/Intro_simplex_tree.h @@ -67,10 +67,13 @@ Information of the Simplex Tree: Number of vertices = 10 Number of simplices = 98 \endcode * * \li - * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp - Simplex tree is computed and displayed from a 3D alpha - * complex (Requires CGAL, GMP and GMPXX to be installed) - * + * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp - Simplex tree is computed and displayed + * from a 3D alpha complex (Requires CGAL, GMP and GMPXX to be installed). * + * \li + * Simplex_tree/graph_expansion_with_blocker.cpp - Simple simplex tree construction from a one-skeleton graph with + * a simple blocker expansion method. + * * \subsection filteredcomplexeshassecomplex Hasse complex * The second one is the Hasse_complex. The Hasse complex is a data structure representing explicitly all co-dimension * 1 incidence relations in a complex. It is consequently faster when accessing the boundary of a simplex, but is less diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 72cb9401..b7ec2c1c 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1089,7 +1089,7 @@ class Simplex_tree { * complex of dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. * The filtration value assigned to a simplex is the maximal filtration value of one of its edges. * The blocker expansion oracle shall answer true on a Simplex_handle if this Simplex_handle has to be removed, - * false otherwise. The blocker expansion oracle can re-assign the filtration value. + * false otherwise. The blocker expansion oracle can re-assign the filtration value if needed. * * The Simplex_tree must contain no simplex of dimension bigger than 1 when calling the method. */ template< typename Blocker > diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index bd4615f5..7219bcfa 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -364,6 +364,8 @@ make doxygen * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp * \li * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp + * \li + * Simplex_tree/graph_expansion_with_blocker.cpp * \li * Persistent_cohomology/alpha_complex_3d_persistence.cpp * \li @@ -450,6 +452,7 @@ make doxygen * @example Simplex_tree/simple_simplex_tree.cpp * @example Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp * @example Simplex_tree/simplex_tree_from_cliques_of_graph.cpp + * @example Simplex_tree/graph_expansion_with_blocker.cpp * @example Skeleton_blocker/Skeleton_blocker_from_simplices.cpp * @example Skeleton_blocker/Skeleton_blocker_iteration.cpp * @example Skeleton_blocker/Skeleton_blocker_link.cpp -- cgit v1.2.3 From deb3ac325f84a6e023923da4cc8e2886d98c3132 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 6 Jul 2017 07:35:16 +0000 Subject: Uused variable git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2589 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: eb0f479d8bdd70010918c80e2902eed9a25806c4 --- src/Simplex_tree/example/simple_simplex_tree.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp index f27d7ab8..33face2a 100644 --- a/src/Simplex_tree/example/simple_simplex_tree.cpp +++ b/src/Simplex_tree/example/simple_simplex_tree.cpp @@ -250,7 +250,6 @@ int main(int argc, char * const argv[]) { else std::cout << "***- NO IT ISN'T\n"; - invSimplexVector = { 0, 1 }; simplexFound = simplexTree.find({ 0, 1 }); std::cout << "**************IS THE SIMPLEX {0,1} IN THE SIMPLEX TREE ?\n"; if (simplexFound != simplexTree.null_simplex()) -- cgit v1.2.3 From 4be27acc9ad9d1c1d8f67c0c3839022b910b8b75 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Aug 2017 08:13:28 +0000 Subject: Code review : use boost::adaptors::reverse(intersection) instead of std::reverse Doc review : siblings make no sense to a user git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2630 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0c9f2b3159294687241ad994e0c7fa7098d31285 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index b7ec2c1c..7815b95d 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1138,10 +1138,10 @@ class Simplex_tree { } if (intersection.size() != 0) { // Reverse the order to insert - std::reverse(std::begin(intersection), std::end(intersection)); + //std::reverse(std::begin(intersection), std::end(intersection)); Siblings * new_sib = new Siblings(siblings, // oncles simplex->first, // parent - intersection); // boost::container::ordered_unique_range_t + boost::adaptors::reverse(intersection)); // boost::container::ordered_unique_range_t // intersection must be cleared before the function to be called recursively intersection.clear(); @@ -1297,7 +1297,7 @@ class Simplex_tree { public: /** \brief Remove a maximal simplex. * @param[in] sh Simplex handle on the maximal simplex to remove. - * @return true if siblings was deleted, false otherwise. + * @return true if simplex was deleted, false otherwise. * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done). -- cgit v1.2.3 From 3d2b438a5d6c08b84df3aefe4a0753f4f0c3e49c Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Aug 2017 09:56:37 +0000 Subject: Doc review : expansion_with_blockers doc Code review : blocker_expansion_function reamed block_simplex. Add of concept in doc. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2631 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5746beb589e80e329cc7233c5cb54d733256f793 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 34 +++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 7815b95d..88092b3d 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1082,23 +1082,31 @@ class Simplex_tree { } public: - /** \brief Expands the Simplex_tree containing only its one skeleton until dimension max_dim according with a user - * given blocker expansion oracle + /** \brief Expands a simplex tree containing only a graph. Simplices corresponding to cliques in the graph are added + * incrementally, faces before cofaces, unless the simplex has dimension larger than `max_dim` or `block_simplex` + * returns true for this simplex. * - * The expanded simplicial complex until dimension \f$d\f$ attached to a graph \f$G\f$ is the maximal simplicial - * complex of dimension at most \f$d\f$ admitting the graph \f$G\f$ as \f$1\f$-skeleton. - * The filtration value assigned to a simplex is the maximal filtration value of one of its edges. - * The blocker expansion oracle shall answer true on a Simplex_handle if this Simplex_handle has to be removed, - * false otherwise. The blocker expansion oracle can re-assign the filtration value if needed. + * @param[in] max_dim Expansion maximal dimension value. + * @param[in] block_simplex Blocker oracle. Its concept is bool block_simplex(Simplex_handle sh) * - * The Simplex_tree must contain no simplex of dimension bigger than 1 when calling the method. */ + * The function identifies a candidate simplex whose faces are all already in the complex, inserts + * it with a filtration value corresponding to the maximum of the filtration values of the faces, then calls + * `block_simplex` on a `Simplex_handle` for this new simplex. If `block_simplex` returns true, the simplex is + * removed, otherwise it is kept. Note that the evaluation of `block_simplex` is a good time to update the + * filtration value of the simplex if you want a customized value. The algorithm then proceeds with the next + * candidate. + * + * @warning several candidates of the same dimension may be inserted simultaneously before calling `block_simplex`, + * so if you examine the complex in `block_simplex`, you may hit a few simplices that have not been vetted by + * `block_simplex` yet. + */ template< typename Blocker > - void expansion_with_blockers(int max_dim, Blocker blocker_expansion_function) { + void expansion_with_blockers(int max_dim, Blocker block_simplex) { dimension_ = max_dim; // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree for (auto& simplex : boost::adaptors::reverse(root_.members())) { if (has_children(&simplex)) { - siblings_expansion_with_blockers(simplex.second.children(), max_dim - 1, blocker_expansion_function); + siblings_expansion_with_blockers(simplex.second.children(), max_dim - 1, block_simplex); } } dimension_ = max_dim - dimension_; @@ -1108,7 +1116,7 @@ class Simplex_tree { /** \brief Recursive expansion with blockers of the simplex tree.*/ template< typename Blocker > void siblings_expansion_with_blockers(Siblings* siblings, // must contain elements - int k, Blocker blocker_expansion_function) { + int k, Blocker block_simplex) { if (dimension_ > k) { dimension_ = k; } @@ -1150,7 +1158,7 @@ class Simplex_tree { for (auto new_sib_member = new_sib->members().begin(); new_sib_member != new_sib->members().end(); new_sib_member++) { - bool blocker_result = blocker_expansion_function(new_sib_member); + bool blocker_result = block_simplex(new_sib_member); // new_sib member has been blocked by the blocker function // add it to the list to be removed - do not perform it while looping on it if (blocker_result) @@ -1166,7 +1174,7 @@ class Simplex_tree { } else { // ensure recursive call simplex->second.assign_children(new_sib); - siblings_expansion_with_blockers(new_sib, k - 1, blocker_expansion_function); + siblings_expansion_with_blockers(new_sib, k - 1, block_simplex); } } else { // ensure the children property -- cgit v1.2.3 From fa0388bc3896f881b35fa6c333ceb0116d3e7fdb Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Aug 2017 13:36:42 +0000 Subject: Code review : find_child implementation improvement git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2632 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c4024b5a56b64dd168a5de1422a857ccebd606fb --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 88092b3d..aa097a38 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1189,11 +1189,16 @@ class Simplex_tree { * Returns null_simplex() if it does not exist */ Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) { - std::vector child = {vh}; - for (auto vertex : simplex_vertex_range(sh)) { - child.push_back(vertex); - } - return find(child); + if (!has_children(sh)) + return null_simplex(); + + Simplex_handle child = sh->second.children()->find(vh); + // Specific case of boost::flat_map does not find, returns boost::flat_map::end() + // in simplex tree we want a null_simplex() + if (child == sh->second.children()->members().end()) + return null_simplex(); + + return child; } public: -- cgit v1.2.3 From eead3066ec52bdc1eaedf5d6bbd3957ce711b036 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Aug 2017 14:37:50 +0000 Subject: Code review : no need to clear intersection git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2633 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9a59d20c5786b012229cc5db45181ba165af8f8a --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index aa097a38..b1767f63 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1146,13 +1146,9 @@ class Simplex_tree { } if (intersection.size() != 0) { // Reverse the order to insert - //std::reverse(std::begin(intersection), std::end(intersection)); Siblings * new_sib = new Siblings(siblings, // oncles simplex->first, // parent boost::adaptors::reverse(intersection)); // boost::container::ordered_unique_range_t - // intersection must be cleared before the function to be called recursively - intersection.clear(); - std::vector blocked_new_sib_list; // As all intersections are inserted, we can call the blocker function on all new_sib members for (auto new_sib_member = new_sib->members().begin(); @@ -1179,7 +1175,6 @@ class Simplex_tree { } else { // ensure the children property simplex->second.assign_children(siblings); - intersection.clear(); } } } -- cgit v1.2.3 From 3e9006eeb1c731e63fce5aa71802997284abe461 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Aug 2017 15:33:05 +0000 Subject: Code review : dimension_ is now set on the fly git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2634 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 12974878db3242c442c09268437de4d56e704593 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index b1767f63..ee173c70 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1102,23 +1102,20 @@ class Simplex_tree { */ template< typename Blocker > void expansion_with_blockers(int max_dim, Blocker block_simplex) { - dimension_ = max_dim; // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree for (auto& simplex : boost::adaptors::reverse(root_.members())) { if (has_children(&simplex)) { - siblings_expansion_with_blockers(simplex.second.children(), max_dim - 1, block_simplex); + siblings_expansion_with_blockers(simplex.second.children(), max_dim, max_dim - 1, block_simplex); } } - dimension_ = max_dim - dimension_; } private: /** \brief Recursive expansion with blockers of the simplex tree.*/ template< typename Blocker > - void siblings_expansion_with_blockers(Siblings* siblings, // must contain elements - int k, Blocker block_simplex) { - if (dimension_ > k) { - dimension_ = k; + void siblings_expansion_with_blockers(Siblings* siblings, int max_dim, int k, Blocker block_simplex) { + if (dimension_ < max_dim - k) { + dimension_ = max_dim - k; } if (k == 0) return; @@ -1170,7 +1167,7 @@ class Simplex_tree { } else { // ensure recursive call simplex->second.assign_children(new_sib); - siblings_expansion_with_blockers(new_sib, k - 1, block_simplex); + siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex); } } else { // ensure the children property -- cgit v1.2.3 From 5fb66b3c664b2343776b97327c4bde9eb6c69351 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 30 Aug 2017 09:18:40 +0000 Subject: Code review better use a break to end loop when we know it is not needed to be inserted. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2640 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2f5fe60856598f0b45c86fd91beda407bcf6938d --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index ee173c70..f7df277c 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1132,7 +1132,10 @@ class Simplex_tree { // If all the boundaries are present, 'next' needs to be inserted for (auto& border : boundary_simplex_range(simplex)) { Simplex_handle border_child = find_child(border, next->first); - to_be_inserted = to_be_inserted && (border_child != null_simplex()); + if (border_child == null_simplex()) { + to_be_inserted=false; + break; + } filt = std::max(filt, filtration(border_child)); } if (to_be_inserted) { -- cgit v1.2.3 From b9ca395bdade623ccfc58e92a98e90bf7eae6f17 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 11 Sep 2017 19:40:56 +0000 Subject: Code review: constify find_child and for instead of while loop git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2657 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e136c1a8b6d5bbc213383f1e6a2e00a875424ad1 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index f7df277c..f48dd048 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1124,9 +1124,8 @@ class Simplex_tree { return; // Reverse loop starting before the last one for 'next' to be the last one for (auto simplex = siblings->members().rbegin() + 1; simplex != siblings->members().rend(); simplex++) { - auto next = siblings->members().rbegin(); std::vector > intersection; - while(next != simplex) { + for(auto next = siblings->members().rbegin(); next != simplex; next++) { bool to_be_inserted = true; Filtration_value filt = simplex->second.filtration(); // If all the boundaries are present, 'next' needs to be inserted @@ -1141,8 +1140,6 @@ class Simplex_tree { if (to_be_inserted) { intersection.emplace_back(next->first, Node(nullptr, filt)); } - // loop until simplex is reached - next++; } if (intersection.size() != 0) { // Reverse the order to insert @@ -1183,7 +1180,7 @@ class Simplex_tree { * Vertex_handle. * Returns null_simplex() if it does not exist */ - Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) { + Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) const { if (!has_children(sh)) return null_simplex(); -- cgit v1.2.3 From fb41612243f07ee6faaca02f70d09d4501c24bb1 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 11 Sep 2017 19:49:36 +0000 Subject: Code review: remove reference and explicit type (instead of auto) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2658 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3ba33efc13a3a650f2c2d20bb803aca3b475603a --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index f48dd048..ff6ffa67 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1129,7 +1129,7 @@ class Simplex_tree { bool to_be_inserted = true; Filtration_value filt = simplex->second.filtration(); // If all the boundaries are present, 'next' needs to be inserted - for (auto& border : boundary_simplex_range(simplex)) { + for (Simplex_handle border : boundary_simplex_range(simplex)) { Simplex_handle border_child = find_child(border, next->first); if (border_child == null_simplex()) { to_be_inserted=false; -- cgit v1.2.3 From f25099a09b2c0c4a6a317f2c869bc819462d7edf Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 11 Sep 2017 19:53:33 +0000 Subject: Doc review: rephrase git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2659 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b8a04218fa043e2bd273f77233d794e2c9522060 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index ff6ffa67..5cb13053 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1097,8 +1097,8 @@ class Simplex_tree { * candidate. * * @warning several candidates of the same dimension may be inserted simultaneously before calling `block_simplex`, - * so if you examine the complex in `block_simplex`, you may hit a few simplices that have not been vetted by - * `block_simplex` yet. + * so if you examine the complex in `block_simplex`, you may hit a few simplices of the same dimension that have not + * been vetted by `block_simplex` yet, or have already been rejected but not yet removed. */ template< typename Blocker > void expansion_with_blockers(int max_dim, Blocker block_simplex) { -- cgit v1.2.3 From de09c3d3a8c86b1538f66c674f6f9819abec16cc Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 11 Sep 2017 20:08:29 +0000 Subject: Doc review: bad doc review fix git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2660 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a024a1570e282c5ebd1c675d687372ee3dab0ed0 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 5cb13053..730b552f 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1302,7 +1302,7 @@ class Simplex_tree { public: /** \brief Remove a maximal simplex. * @param[in] sh Simplex handle on the maximal simplex to remove. - * @return true if simplex was deleted, false otherwise. + * @return true if the leaf's branch has no other leaves (branch's children has been re-assigned), false otherwise. * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done). -- cgit v1.2.3 -- cgit v1.2.3 From c9f8ebc4d43d4a861aab1dabc2d31f2f6ed640d2 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 20 Sep 2017 10:45:50 +0000 Subject: Merge modifications for simplex_tree automatic dimension set git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2689 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c18c6316d51f476a795b59c8b870db1aaf0b4591 --- src/Alpha_complex/include/gudhi/Alpha_complex.h | 2 - src/Alpha_complex/test/Alpha_complex_unit_test.cpp | 4 +- .../example/alpha_complex_3d_persistence.cpp | 1 - .../example/exact_alpha_complex_3d_persistence.cpp | 1 - .../periodic_alpha_complex_3d_persistence.cpp | 1 - .../persistence_from_simple_simplex_tree.cpp | 1 - .../example/plain_homology.cpp | 2 - .../example/rips_persistence_step_by_step.cpp | 5 +- .../weighted_alpha_complex_3d_persistence.cpp | 1 - .../test/betti_numbers_unit_test.cpp | 4 - .../test/persistent_cohomology_unit_test.cpp | 2 - src/Simplex_tree/include/gudhi/Simplex_tree.h | 47 ++- src/Simplex_tree/test/CMakeLists.txt | 14 +- src/Simplex_tree/test/README | 2 +- .../test/simplex_tree_remove_unit_test.cpp | 346 +++++++++++++++++++++ src/Simplex_tree/test/simplex_tree_unit_test.cpp | 289 +---------------- .../include/gudhi/Strong_witness_complex.h | 1 - .../include/gudhi/Witness_complex.h | 1 - src/cython/include/Tangential_complex_interface.h | 2 - src/cython/test/test_simplex_tree.py | 11 +- 20 files changed, 421 insertions(+), 316 deletions(-) create mode 100644 src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h index 1ff95c3d..5f7d7622 100644 --- a/src/Alpha_complex/include/gudhi/Alpha_complex.h +++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h @@ -268,8 +268,6 @@ class Alpha_complex { return false; // ----- >> } - complex.set_dimension(triangulation_->maximal_dimension()); - // -------------------------------------------------------------------------------------------- // Simplex_tree construction from loop on triangulation finite full cells list if (triangulation_->number_of_vertices() > 0) { diff --git a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp index 7380547f..166373fe 100644 --- a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp +++ b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp @@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) { BOOST_CHECK(simplex_tree.num_simplices() == 15); std::cout << "simplex_tree.dimension()=" << simplex_tree.dimension() << std::endl; - BOOST_CHECK(simplex_tree.dimension() == 4); + BOOST_CHECK(simplex_tree.dimension() == 3); std::cout << "simplex_tree.num_vertices()=" << simplex_tree.num_vertices() << std::endl; BOOST_CHECK(simplex_tree.num_vertices() == 4); @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) { BOOST_CHECK(simplex_tree.num_simplices() == 10); std::cout << "simplex_tree.dimension()=" << simplex_tree.dimension() << std::endl; - BOOST_CHECK(simplex_tree.dimension() == 4); + BOOST_CHECK(simplex_tree.dimension() == 1); std::cout << "simplex_tree.num_vertices()=" << simplex_tree.num_vertices() << std::endl; BOOST_CHECK(simplex_tree.num_vertices() == 4); diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp index fd227b82..40eb3576 100644 --- a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp @@ -203,7 +203,6 @@ int main(int argc, char * const argv[]) { std::cout << "This shall not happen" << std::endl; } simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); #ifdef DEBUG_TRACES std::cout << "vertices \t\t" << count_vertices << std::endl; diff --git a/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp index 8a335075..9881debf 100644 --- a/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp @@ -205,7 +205,6 @@ int main(int argc, char * const argv[]) { std::cout << "This shall not happen" << std::endl; } simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); #ifdef DEBUG_TRACES std::cout << "vertices \t\t" << count_vertices << std::endl; diff --git a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp index 8928cfc2..71faebd7 100644 --- a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp @@ -222,7 +222,6 @@ int main(int argc, char * const argv[]) { std::cout << "This shall not happen" << std::endl; } simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); #ifdef DEBUG_TRACES std::cout << "vertices \t\t" << count_vertices << std::endl; diff --git a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp index 7ca9410a..7809d5ff 100644 --- a/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp +++ b/src/Persistent_cohomology/example/persistence_from_simple_simplex_tree.cpp @@ -142,7 +142,6 @@ int main(int argc, char * const argv[]) { /* An edge [11,6] */ /* An edge [10,12,2] */ - st.set_dimension(2); st.set_filtration(0.4); std::cout << "The complex contains " << st.num_simplices() << " simplices - " << st.num_vertices() << " vertices " diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp index 50f692f2..a5ae09c8 100644 --- a/src/Persistent_cohomology/example/plain_homology.cpp +++ b/src/Persistent_cohomology/example/plain_homology.cpp @@ -64,8 +64,6 @@ int main() { st.insert_simplex_and_subfaces(edge03); st.insert_simplex(edge13); st.insert_simplex(vertex4); - // FIXME: Remove this line - st.set_dimension(2); // Sort the simplices in the order of the filtration st.initialize_filtration(); diff --git a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp index 554eeba6..75580aac 100644 --- a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp +++ b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp @@ -88,6 +88,9 @@ int main(int argc, char * argv[]) { Simplex_tree st; // insert the proximity graph in the simplex tree st.insert_graph(prox_graph); + std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; + std::cout << " and has dimension " << st.dimension() << " \n"; +/* // expand the graph until dimension dim_max st.expansion(dim_max); @@ -112,7 +115,7 @@ int main(int argc, char * argv[]) { pcoh.output_diagram(out); out.close(); } - +*/ return 0; } diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp index 34b90933..968db753 100644 --- a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp @@ -223,7 +223,6 @@ int main(int argc, char * const argv[]) { std::cout << "This shall not happen" << std::endl; } simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); #ifdef DEBUG_TRACES std::cout << "vertices \t\t" << count_vertices << std::endl; diff --git a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp index da418034..0a08d200 100644 --- a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp +++ b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp @@ -62,8 +62,6 @@ BOOST_AUTO_TEST_CASE( plain_homology_betti_numbers ) st.insert_simplex_and_subfaces(edge04); st.insert_simplex(edge14); st.insert_simplex(vertex5); - // FIXME: Remove this line - st.set_dimension(3); // Sort the simplices in the order of the filtration st.initialize_filtration(); @@ -170,8 +168,6 @@ BOOST_AUTO_TEST_CASE( betti_numbers ) st.insert_simplex_and_subfaces(edge04, 2.0); st.insert_simplex(edge14, 2.0); st.insert_simplex(vertex5, 1.0); - // FIXME: Remove this line - st.set_dimension(3); // Sort the simplices in the order of the filtration st.initialize_filtration(); diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index f8174020..887aa25f 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -197,8 +197,6 @@ BOOST_AUTO_TEST_CASE( persistence_constructor_exception ) // To make number of simplices = 255 const short simplex_0[] = {0, 1, 2, 3, 4, 5, 6, 7}; st.insert_simplex_and_subfaces(simplex_0); - // FIXME: Remove this line - st.set_dimension(8); // Sort the simplices in the order of the filtration st.initialize_filtration(); diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 317bce23..478ed80f 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -601,7 +601,11 @@ class Simplex_tree { // if filtration value unchanged return std::pair(null_simplex(), false); } - // otherwise the insertion has succeeded + // otherwise the insertion has succeeded - size is a size_type + if (static_cast(simplex.size()) - 1 > dimension_) { + // Update dimension if needed + dimension_ = static_cast(simplex.size()) - 1; + } return res_insert; } @@ -1159,7 +1163,11 @@ class Simplex_tree { * complex has changed , please call `initialize_filtration()` to recompute it. */ bool prune_above_filtration(Filtration_value filtration) { - return rec_prune_above_filtration(root(), filtration); + bool modified = rec_prune_above_filtration(root(), filtration); + if (modified) { + auto_dimension_set(dimension()); + } + return modified; } private: @@ -1187,6 +1195,33 @@ class Simplex_tree { return modified; } + private: + /** \brief Resets the Simplex_tree dimension. + * @param[in] old_dimension The former dimension value until the loop stopped when it is reached. + * @return The dimension modification information. + * \pre Please check the simplex has not a too low dimension value. + * This cannot happen if set_dimension has not been performed. + */ + bool auto_dimension_set(int old_dimension) { + int new_dimension = -1; + for (Simplex_handle sh : skeleton_simplex_range(old_dimension)) { +#ifdef DEBUG_TRACES + for (auto vertex : simplex_vertex_range(sh)) { + std::cout << " " << vertex; + } + std::cout << std::endl; +#endif // DEBUG_TRACES + + int sh_dimension = dimension(sh); + if (sh_dimension >= old_dimension) + return false; + new_dimension = std::max(new_dimension, sh_dimension); + } + set_dimension(new_dimension); + return true; + } + + public: /** \brief Remove a maximal simplex. * @param[in] sh Simplex handle on the maximal simplex to remove. @@ -1207,9 +1242,17 @@ class Simplex_tree { // Special case when child is the root of the simplex tree, just remove it from members child->erase(sh); } else { + // Keep information before remove action + int sh_dim = dimension(sh); + // Sibling is emptied : must be deleted, and its parent must point on his own Sibling child->oncles()->members().at(child->parent()).assign_children(child->oncles()); delete child; + + // No need to reset dimension in case maximal simplex is not the maximal dimension one + if (sh_dim >= dimension()) { + auto_dimension_set(sh_dim); + } } } diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 81999de6..1c169ff7 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -3,13 +3,21 @@ project(Simplex_tree_tests) include(GUDHI_test_coverage) +# Do not forget to copy test files in current binary dir +file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + add_executable ( Simplex_tree_test_unit simplex_tree_unit_test.cpp ) target_link_libraries(Simplex_tree_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) if (TBB_FOUND) target_link_libraries(Simplex_tree_test_unit ${TBB_LIBRARIES}) endif() -# Do not forget to copy test files in current binary dir -file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - gudhi_add_coverage_test(Simplex_tree_test_unit) + +add_executable ( Simplex_tree_remove_test_unit simplex_tree_remove_unit_test.cpp ) +target_link_libraries(Simplex_tree_remove_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_remove_test_unit ${TBB_LIBRARIES}) +endif() + +gudhi_add_coverage_test(Simplex_tree_remove_test_unit) diff --git a/src/Simplex_tree/test/README b/src/Simplex_tree/test/README index 21c3d871..df2ab89a 100644 --- a/src/Simplex_tree/test/README +++ b/src/Simplex_tree/test/README @@ -9,6 +9,6 @@ make To launch with details: *********************** -./SimplexTreeUT --report_level=detailed --log_level=all +./Simplex_tree_test_unit --report_level=detailed --log_level=all ==> echo $? returns 0 in case of success (non-zero otherwise) diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp new file mode 100644 index 00000000..ad71fed3 --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -0,0 +1,346 @@ +#include + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree_remove" +#include +#include + +// ^ +// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +struct MyOptions : Simplex_tree_options_full_featured { + // Not doing persistence, so we don't need those + static const bool store_key = false; + static const bool store_filtration = false; + // I have few vertices + typedef short Vertex_handle; +}; + +using Mini_stree = Simplex_tree; +using Stree = Simplex_tree<>; + +BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { + std::cout << "********************************************************************" << std::endl; + std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl; + + Mini_stree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}); + st.insert_simplex_and_subfaces({3, 4, 5}); + + // Constructs a copy at this state for further test purpose + Mini_stree st_pruned = st; + + st.insert_simplex_and_subfaces({3, 0}); + st.insert_simplex_and_subfaces({2, 1, 0}); + + // Constructs a copy at this state for further test purpose + Mini_stree st_complete = st; + // st_complete and st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + // st_pruned: + // 1 6 + // o---o + // \7/ + // o o---o + // 0 3\X/4 + // o + // 5 + +#ifdef GUDHI_DEBUG + std::cout << "Check exception throw in debug mode" << std::endl; + // throw excpt because sh has children + BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument); + BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument); + BOOST_CHECK(st == st_complete); +#endif + std::cout << "st.remove_maximal_simplex({0, 2})" << std::endl; + st.remove_maximal_simplex(st.find({0, 2})); + std::cout << "st.remove_maximal_simplex({0, 1, 2})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 2})); + std::cout << "st.remove_maximal_simplex({1, 2})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2})); + std::cout << "st.remove_maximal_simplex({2})" << std::endl; + st.remove_maximal_simplex(st.find({2})); + std::cout << "st.remove_maximal_simplex({3})" << std::endl; + st.remove_maximal_simplex(st.find({0, 3})); + + BOOST_CHECK(st == st_pruned); + // Remove all, but as the simplex tree is not storing filtration, there is no modification + st.prune_above_filtration(0.0); + BOOST_CHECK(st == st_pruned); + + Mini_stree st_wo_seven; + + st_wo_seven.insert_simplex_and_subfaces({0, 1, 6}); + st_wo_seven.insert_simplex_and_subfaces({3, 4, 5}); + // st_wo_seven: + // 1 6 + // o---o + // \X/ + // o o---o + // 0 3\X/4 + // o + // 5 + + // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not) + std::cout << "st.remove_maximal_simplex({0, 1, 6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 6, 7})); + std::cout << "st.remove_maximal_simplex({0, 1, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 7})); + std::cout << "st.remove_maximal_simplex({0, 6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 6, 7})); + std::cout << "st.remove_maximal_simplex({0, 7})" << std::endl; + st.remove_maximal_simplex(st.find({0, 7})); + std::cout << "st.remove_maximal_simplex({1, 6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({1, 6, 7})); + std::cout << "st.remove_maximal_simplex({1, 7})" << std::endl; + st.remove_maximal_simplex(st.find({1, 7})); + std::cout << "st.remove_maximal_simplex({6, 7})" << std::endl; + st.remove_maximal_simplex(st.find({6, 7})); + std::cout << "st.remove_maximal_simplex({7})" << std::endl; + st.remove_maximal_simplex(st.find({7})); + + std::cout << "st.dimension()=" << st.dimension() << " | st_wo_seven.dimension()=" << st_wo_seven.dimension() << std::endl; + BOOST_CHECK(st == st_wo_seven); +} + +BOOST_AUTO_TEST_CASE(auto_dimension_set) { + std::cout << "********************************************************************" << std::endl; + std::cout << "DIMENSION ON REMOVE MAXIMAL SIMPLEX" << std::endl; + + Mini_stree st; + + st.insert_simplex_and_subfaces({0, 1, 2}); + st.insert_simplex_and_subfaces({0, 1, 3}); + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + st.insert_simplex_and_subfaces({6, 7, 8, 9}); + st.insert_simplex_and_subfaces({6, 7, 8, 10}); + + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({6, 7, 8, 10})" << std::endl; + st.remove_maximal_simplex(st.find({6, 7, 8, 10})); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({6, 7, 8, 9})" << std::endl; + st.remove_maximal_simplex(st.find({6, 7, 8, 9})); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + BOOST_CHECK(st.dimension() == 2); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + BOOST_CHECK(st.dimension() == 2); + + std::cout << "st.insert_simplex_and_subfaces({0, 1, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({0, 1, 3, 4}); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.remove_maximal_simplex({0, 1, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 3, 4})); + BOOST_CHECK(st.dimension() == 2); + + std::cout << "st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6})" << std::endl; + st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6}); + BOOST_CHECK(st.dimension() == 6); + + std::cout << "st.remove_maximal_simplex({0, 1, 2, 3, 4, 5, 6})" << std::endl; + st.remove_maximal_simplex(st.find({0, 1, 2, 3, 4, 5, 6})); + BOOST_CHECK(st.dimension() == 5); + +} + +BOOST_AUTO_TEST_CASE(prune_above_filtration) { + std::cout << "********************************************************************" << std::endl; + std::cout << "PRUNE ABOVE FILTRATION" << std::endl; + + Stree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0); + st.insert_simplex_and_subfaces({3, 4, 5}, 2.0); + + // Constructs a copy at this state for further test purpose + Stree st_pruned = st; + st_pruned.initialize_filtration(); // reset + + st.insert_simplex_and_subfaces({3, 0}, 3.0); + st.insert_simplex_and_subfaces({2, 1, 0}, 4.0); + + // Constructs a copy at this state for further test purpose + Stree st_complete = st; + // st_complete and st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + // st_pruned: + // 1 6 + // o---o + // \7/ + // o o---o + // 0 3\X/4 + // o + // 5 + + bool simplex_is_changed = false; + // Check the no action cases + // greater than initial filtration value + simplex_is_changed = st.prune_above_filtration(10.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_complete); + BOOST_CHECK(!simplex_is_changed); + // equal to initial filtration value + simplex_is_changed = st.prune_above_filtration(6.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_complete); + BOOST_CHECK(!simplex_is_changed); + // lower than initial filtration value, but still greater than the maximum filtration value + simplex_is_changed = st.prune_above_filtration(5.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_complete); + BOOST_CHECK(!simplex_is_changed); + + // Display the Simplex_tree + std::cout << "The complex contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + // Check the pruned cases + simplex_is_changed = st.prune_above_filtration(2.5); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_pruned); + BOOST_CHECK(simplex_is_changed); + + // Display the Simplex_tree + std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + + simplex_is_changed = st.prune_above_filtration(2.0); + if (simplex_is_changed) + st.initialize_filtration(); + + std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + + BOOST_CHECK(st == st_pruned); + BOOST_CHECK(!simplex_is_changed); + + Stree st_empty; + simplex_is_changed = st.prune_above_filtration(0.0); + if (simplex_is_changed) + st.initialize_filtration(); + + // Display the Simplex_tree + std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices"; + std::cout << " - dimension " << st.dimension() << std::endl; + + BOOST_CHECK(st == st_empty); + BOOST_CHECK(simplex_is_changed); + + // Test case to the limit + simplex_is_changed = st.prune_above_filtration(-1.0); + if (simplex_is_changed) + st.initialize_filtration(); + BOOST_CHECK(st == st_empty); + BOOST_CHECK(!simplex_is_changed); +} + +BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) { + std::cout << "********************************************************************" << std::endl; + std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl; + + Mini_stree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}); + st.insert_simplex_and_subfaces({3, 4, 5}); + st.insert_simplex_and_subfaces({3, 0}); + st.insert_simplex_and_subfaces({2, 1, 0}); + + // st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + + st.initialize_filtration(); + + // Display the Simplex_tree + std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(st.num_simplices() == 27); + + // Test case to the limit - With these options, there is no filtration, which means filtration is 0 + bool simplex_is_changed = st.prune_above_filtration(1.0); + if (simplex_is_changed) + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(!simplex_is_changed); + BOOST_CHECK(st.num_simplices() == 27); + + simplex_is_changed = st.prune_above_filtration(0.0); + if (simplex_is_changed) + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(!simplex_is_changed); + BOOST_CHECK(st.num_simplices() == 27); + + // Test case to the limit + simplex_is_changed = st.prune_above_filtration(-1.0); + if (simplex_is_changed) + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl; + BOOST_CHECK(simplex_is_changed); + BOOST_CHECK(st.num_simplices() == 0); + + // Display the Simplex_tree + std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; + +} diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index b06d7ec9..7323aa6c 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -148,16 +148,9 @@ void test_simplex_tree_insert_returns_true(const typePairSimplexBool& returnValu // Global variables double max_fil = 0.0; -int dim_max = -1; template void set_and_test_simplex_tree_dim_fil(typeST& simplexTree, int vectorSize, const Filtration_value& fil) { - if (vectorSize > dim_max + 1) { - dim_max = vectorSize - 1; - simplexTree.set_dimension(dim_max); - std::cout << " set_and_test_simplex_tree_dim_fil - dim_max=" << dim_max - << std::endl; - } if (fil > max_fil) { max_fil = fil; simplexTree.set_filtration(max_fil); @@ -165,7 +158,7 @@ void set_and_test_simplex_tree_dim_fil(typeST& simplexTree, int vectorSize, cons << std::endl; } - BOOST_CHECK(simplexTree.dimension() == dim_max); + BOOST_CHECK(simplexTree.dimension() >= vectorSize - 1); BOOST_CHECK(AreAlmostTheSame(simplexTree.filtration(), max_fil)); // Another way to count simplices: @@ -189,7 +182,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_insertion, typeST, list_of_tested_var const Filtration_value THIRD_FILTRATION_VALUE = 0.3; const Filtration_value FOURTH_FILTRATION_VALUE = 0.4; // reset since we run the test several times - dim_max = -1; max_fil = 0.0; // TEST OF INSERTION @@ -308,8 +300,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_insertion, typeST, list_of_tested_var // Simplex_handle = boost::container::flat_map< typeST::Vertex_handle, Node >::iterator typename typeST::Simplex_handle shReturned = returnValue.first; BOOST_CHECK(shReturned == typename typeST::Simplex_handle(nullptr)); + std::cout << "st.num_vertices()=" << st.num_vertices() << std::endl; BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !! - BOOST_CHECK(st.dimension() == dim_max); BOOST_CHECK(AreAlmostTheSame(st.filtration(), max_fil)); // ++ ELEVENTH @@ -324,7 +316,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_insertion, typeST, list_of_tested_var shReturned = returnValue.first; BOOST_CHECK(shReturned == typename typeST::Simplex_handle(nullptr)); BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !! - BOOST_CHECK(st.dimension() == dim_max); + std::cout << " - INSERT (2,1,0) (already inserted)" << std::endl; + BOOST_CHECK(st.dimension() == 2); BOOST_CHECK(AreAlmostTheSame(st.filtration(), max_fil)); /* Inserted simplex: */ @@ -630,9 +623,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(coface_on_simplex_tree, typeST, list_of_tested_var /* o */ /* 5 */ - // FIXME - st.set_dimension(3); - std::vector simplex_result; std::vector result; std::cout << "First test - Star of (3):" << std::endl; @@ -729,9 +719,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_ /* o */ /* 5 */ - // FIXME - st.set_dimension(3); - std::cout << "Printing st - address = " << &st << std::endl; // Copy constructor @@ -882,271 +869,3 @@ BOOST_AUTO_TEST_CASE(make_filtration_non_decreasing) { BOOST_CHECK(st == st_other_copy); } - -struct MyOptions : Simplex_tree_options_full_featured { - // Not doing persistence, so we don't need those - static const bool store_key = false; - static const bool store_filtration = false; - // I have few vertices - typedef short Vertex_handle; -}; - -BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { - std::cout << "********************************************************************" << std::endl; - std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl; - - - typedef Simplex_tree miniST; - miniST st; - - // FIXME - st.set_dimension(3); - - st.insert_simplex_and_subfaces({0, 1, 6, 7}); - st.insert_simplex_and_subfaces({3, 4, 5}); - - // Constructs a copy at this state for further test purpose - miniST st_pruned = st; - - st.insert_simplex_and_subfaces({3, 0}); - st.insert_simplex_and_subfaces({2, 1, 0}); - - // Constructs a copy at this state for further test purpose - miniST st_complete = st; - // st_complete and st: - // 1 6 - // o---o - // /X\7/ - // o---o---o---o - // 2 0 3\X/4 - // o - // 5 - // st_pruned: - // 1 6 - // o---o - // \7/ - // o o---o - // 0 3\X/4 - // o - // 5 - -#ifdef GUDHI_DEBUG - std::cout << "Check exception throw in debug mode" << std::endl; - // throw excpt because sh has children - BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument); - BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument); - BOOST_CHECK(st == st_complete); -#endif - - st.remove_maximal_simplex(st.find({0, 2})); - st.remove_maximal_simplex(st.find({0, 1, 2})); - st.remove_maximal_simplex(st.find({1, 2})); - st.remove_maximal_simplex(st.find({2})); - st.remove_maximal_simplex(st.find({0, 3})); - - BOOST_CHECK(st == st_pruned); - // Remove all, but as the simplex tree is not storing filtration, there is no modification - st.prune_above_filtration(0.0); - BOOST_CHECK(st == st_pruned); - - miniST st_wo_seven; - // FIXME - st_wo_seven.set_dimension(3); - - st_wo_seven.insert_simplex_and_subfaces({0, 1, 6}); - st_wo_seven.insert_simplex_and_subfaces({3, 4, 5}); - // st_wo_seven: - // 1 6 - // o---o - // \X/ - // o o---o - // 0 3\X/4 - // o - // 5 - - // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not) - st.remove_maximal_simplex(st.find({0, 1, 6, 7})); - st.remove_maximal_simplex(st.find({0, 1, 7})); - st.remove_maximal_simplex(st.find({0, 6, 7})); - st.remove_maximal_simplex(st.find({0, 7})); - st.remove_maximal_simplex(st.find({1, 6, 7})); - st.remove_maximal_simplex(st.find({1, 7})); - st.remove_maximal_simplex(st.find({6, 7})); - st.remove_maximal_simplex(st.find({7})); - - BOOST_CHECK(st == st_wo_seven); -} - -BOOST_AUTO_TEST_CASE(prune_above_filtration) { - std::cout << "********************************************************************" << std::endl; - std::cout << "PRUNE ABOVE FILTRATION" << std::endl; - typedef Simplex_tree<> typeST; - typeST st; - - // FIXME - st.set_dimension(3); - - st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0); - st.insert_simplex_and_subfaces({3, 4, 5}, 2.0); - - // Constructs a copy at this state for further test purpose - typeST st_pruned = st; - st_pruned.initialize_filtration(); // reset - - st.insert_simplex_and_subfaces({3, 0}, 3.0); - st.insert_simplex_and_subfaces({2, 1, 0}, 4.0); - - // Constructs a copy at this state for further test purpose - typeST st_complete = st; - // st_complete and st: - // 1 6 - // o---o - // /X\7/ - // o---o---o---o - // 2 0 3\X/4 - // o - // 5 - // st_pruned: - // 1 6 - // o---o - // \7/ - // o o---o - // 0 3\X/4 - // o - // 5 - - bool simplex_is_changed = false; - // Check the no action cases - // greater than initial filtration value - simplex_is_changed = st.prune_above_filtration(10.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_complete); - BOOST_CHECK(!simplex_is_changed); - // equal to initial filtration value - simplex_is_changed = st.prune_above_filtration(6.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_complete); - BOOST_CHECK(!simplex_is_changed); - // lower than initial filtration value, but still greater than the maximum filtration value - simplex_is_changed = st.prune_above_filtration(5.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_complete); - BOOST_CHECK(!simplex_is_changed); - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; - for (auto f_simplex : st.filtration_simplex_range()) { - std::cout << " " << "[" << st.filtration(f_simplex) << "] "; - for (auto vertex : st.simplex_vertex_range(f_simplex)) { - std::cout << (int) vertex << " "; - } - std::cout << std::endl; - } - - // Check the pruned cases - simplex_is_changed = st.prune_above_filtration(2.5); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_pruned); - BOOST_CHECK(simplex_is_changed); - - // Display the Simplex_tree - std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - - simplex_is_changed = st.prune_above_filtration(2.0); - if (simplex_is_changed) - st.initialize_filtration(); - - std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - - BOOST_CHECK(st == st_pruned); - BOOST_CHECK(!simplex_is_changed); - - typeST st_empty; - // FIXME - st_empty.set_dimension(3); - simplex_is_changed = st.prune_above_filtration(0.0); - if (simplex_is_changed) - st.initialize_filtration(); - - // Display the Simplex_tree - std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - - BOOST_CHECK(st == st_empty); - BOOST_CHECK(simplex_is_changed); - - // Test case to the limit - simplex_is_changed = st.prune_above_filtration(-1.0); - if (simplex_is_changed) - st.initialize_filtration(); - BOOST_CHECK(st == st_empty); - BOOST_CHECK(!simplex_is_changed); -} - -BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) { - std::cout << "********************************************************************" << std::endl; - std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl; - typedef Simplex_tree typeST; - typeST st; - - // FIXME - st.set_dimension(3); - - st.insert_simplex_and_subfaces({0, 1, 6, 7}); - st.insert_simplex_and_subfaces({3, 4, 5}); - st.insert_simplex_and_subfaces({3, 0}); - st.insert_simplex_and_subfaces({2, 1, 0}); - - // st: - // 1 6 - // o---o - // /X\7/ - // o---o---o---o - // 2 0 3\X/4 - // o - // 5 - - st.initialize_filtration(); - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(st.num_simplices() == 27); - - // Test case to the limit - With these options, there is no filtration, which means filtration is 0 - bool simplex_is_changed = st.prune_above_filtration(1.0); - if (simplex_is_changed) - st.initialize_filtration(); - // Display the Simplex_tree - std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(!simplex_is_changed); - BOOST_CHECK(st.num_simplices() == 27); - - simplex_is_changed = st.prune_above_filtration(0.0); - if (simplex_is_changed) - st.initialize_filtration(); - // Display the Simplex_tree - std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(!simplex_is_changed); - BOOST_CHECK(st.num_simplices() == 27); - - // Test case to the limit - simplex_is_changed = st.prune_above_filtration(-1.0); - if (simplex_is_changed) - st.initialize_filtration(); - // Display the Simplex_tree - std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl; - BOOST_CHECK(simplex_is_changed); - BOOST_CHECK(st.num_simplices() == 0); - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; - -} \ No newline at end of file diff --git a/src/Witness_complex/include/gudhi/Strong_witness_complex.h b/src/Witness_complex/include/gudhi/Strong_witness_complex.h index 6f4bcf60..c18335d3 100644 --- a/src/Witness_complex/include/gudhi/Strong_witness_complex.h +++ b/src/Witness_complex/include/gudhi/Strong_witness_complex.h @@ -127,7 +127,6 @@ class Strong_witness_complex { if ((Landmark_id)simplex.size() - 1 > complex_dim) complex_dim = simplex.size() - 1; } - complex.set_dimension(complex_dim); return true; } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index bcfe8484..53c38520 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -130,7 +130,6 @@ class Witness_complex { } k++; } - complex.set_dimension(k-1); return true; } diff --git a/src/cython/include/Tangential_complex_interface.h b/src/cython/include/Tangential_complex_interface.h index 5e9dc0e4..ecf014b3 100644 --- a/src/cython/include/Tangential_complex_interface.h +++ b/src/cython/include/Tangential_complex_interface.h @@ -106,8 +106,6 @@ class Tangential_complex_interface { void create_simplex_tree(Simplex_tree<>* simplex_tree) { int max_dim = tangential_complex_->create_complex>(*simplex_tree); - // FIXME - simplex_tree->set_dimension(max_dim); simplex_tree->initialize_filtration(); } diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index 3ae537e3..a6d6a9f3 100755 --- a/src/cython/test/test_simplex_tree.py +++ b/src/cython/test/test_simplex_tree.py @@ -34,9 +34,13 @@ def test_insertion(): # insert test assert st.insert([0, 1]) == True + + assert st.dimension() == 1 + assert st.insert([0, 1, 2], filtration=4.0) == True - # FIXME: Remove this line - st.set_dimension(2) + + assert st.dimension() == 2 + assert st.num_simplices() == 7 assert st.num_vertices() == 3 @@ -87,8 +91,9 @@ def test_insertion(): assert st.find([2]) == True st.initialize_filtration() - assert st.persistence() == [(1, (4.0, float('inf'))), (0, (0.0, float('inf')))] + assert st.persistence(persistence_dim_max = True) == [(1, (4.0, float('inf'))), (0, (0.0, float('inf')))] assert st.__is_persistence_defined() == True + assert st.betti_numbers() == [1, 1] assert st.persistent_betti_numbers(-0.1, 10000.0) == [0, 0] assert st.persistent_betti_numbers(0.0, 10000.0) == [1, 0] -- cgit v1.2.3 From 664b4dcbeb549e89128802b2402d60cb6d28268d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 20 Sep 2017 13:49:41 +0000 Subject: Add tests limits git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2690 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fc3e0cb28170f49a598d50fc7e32ac2d9d191447 --- .../test/simplex_tree_remove_unit_test.cpp | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp index ad71fed3..df89008e 100644 --- a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -169,6 +169,56 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.remove_maximal_simplex(st.find({0, 1, 3, 4})); BOOST_CHECK(st.dimension() == 2); + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + BOOST_CHECK(st.dimension() == 3); + + // Check you can override the dimension + // This is a limit test case - shall not happen + st.set_dimension(1); + BOOST_CHECK(st.dimension() == 1); + + // Here no siblings is erased - automatic dimension is not launched. + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + BOOST_CHECK(st.dimension() == 1); + + // Here sibling is erased - automatic dimension is launched. + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + BOOST_CHECK(st.dimension() == 2); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 5}); + BOOST_CHECK(st.dimension() == 3); + + std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; + st.insert_simplex_and_subfaces({1, 2, 3, 4}); + BOOST_CHECK(st.dimension() == 3); + + // Check you can override the dimension + // This is a limit test case - shall not happen + st.set_dimension(6); + BOOST_CHECK(st.dimension() == 6); + + // Here no siblings is erased - automatic dimension is not launched. + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + BOOST_CHECK(st.dimension() == 6); + + // Here sibling is erased - automatic dimension is launched but dim is always than te one set. + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; + st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + BOOST_CHECK(st.dimension() == 6); + + // Reset with the correct value + st.set_dimension(2); + BOOST_CHECK(st.dimension() == 2); + std::cout << "st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6})" << std::endl; st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6}); BOOST_CHECK(st.dimension() == 6); -- cgit v1.2.3 From e2f26211caaef3c3a564e5858d513b25804eb35e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 20 Sep 2017 18:39:29 +0000 Subject: Separate and improve simplex tree iostream operators to test automatic dimension set on iostream operators git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2693 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: dafd077f3ed20eafaccdb27d56e02b3d9e5c44a7 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 10 +-- src/Simplex_tree/test/CMakeLists.txt | 8 +++ .../simplex_tree_iostream_operator_unit_test.cpp | 83 ++++++++++++++++++++++ .../test/simplex_tree_remove_unit_test.cpp | 1 - src/Simplex_tree/test/simplex_tree_unit_test.cpp | 35 --------- 5 files changed, 93 insertions(+), 44 deletions(-) create mode 100644 src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 478ed80f..76e594d3 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -763,7 +763,8 @@ class Simplex_tree { /** Set an upper bound for the filtration values. */ void set_filtration(Filtration_value fil) { - threshold_ = fil; + if (Options::store_filtration) + threshold_ = fil; } /** Set a dimension for the simplicial complex. */ @@ -1288,14 +1289,8 @@ std::istream& operator>>(std::istream & is, Simplex_tree & st) { std::vector simplex; typename ST::Filtration_value fil; typename ST::Filtration_value max_fil = 0; - int max_dim = -1; while (read_simplex(is, simplex, fil)) { // read all simplices in the file as a list of vertices - // Warning : simplex_size needs to be casted in int - Can be 0 - int dim = static_cast (simplex.size() - 1); - if (max_dim < dim) { - max_dim = dim; - } if (max_fil < fil) { max_fil = fil; } @@ -1303,7 +1298,6 @@ std::istream& operator>>(std::istream & is, Simplex_tree & st) { st.insert_simplex(simplex, fil); simplex.clear(); } - st.set_dimension(max_dim); st.set_filtration(max_fil); return is; diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 1c169ff7..8684ad2a 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -21,3 +21,11 @@ if (TBB_FOUND) endif() gudhi_add_coverage_test(Simplex_tree_remove_test_unit) + +add_executable ( Simplex_tree_iostream_operator_test_unit simplex_tree_iostream_operator_unit_test.cpp ) +target_link_libraries(Simplex_tree_iostream_operator_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Simplex_tree_iostream_operator_test_unit ${TBB_LIBRARIES}) +endif() + +gudhi_add_coverage_test(Simplex_tree_iostream_operator_test_unit) diff --git a/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp new file mode 100644 index 00000000..402c31e2 --- /dev/null +++ b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp @@ -0,0 +1,83 @@ +#include + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "simplex_tree_iostream_operator" +#include +#include + +// ^ +// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. +#include "gudhi/Simplex_tree.h" + +using namespace Gudhi; + +struct MyOptions : Simplex_tree_options_full_featured { + // Not doing persistence, so we don't need those + static const bool store_key = false; + static const bool store_filtration = false; + // I have few vertices + typedef short Vertex_handle; +}; + +typedef boost::mpl::list, + Simplex_tree, + Simplex_tree + > list_of_tested_variants; + +BOOST_AUTO_TEST_CASE_TEMPLATE(iostream_operator, Stree_type, list_of_tested_variants) { + std::cout << "********************************************************************" << std::endl; + std::cout << "SIMPLEX TREE IOSTREAM OPERATOR" << std::endl; + + Stree_type st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}, 4.0); + st.insert_simplex_and_subfaces({3, 4, 5}, 3.0); + st.insert_simplex_and_subfaces({3, 0}, 2.0); + st.insert_simplex_and_subfaces({2, 1, 0}, 3.0); + // FIXME + st.set_filtration(4.0); + + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The ORIGINAL complex contains " << st.num_simplices() << " simplices" << std::endl; + std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + // st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + std::string iostream_file("simplex_tree_for_iostream_operator_unit_test.txt"); + std::ofstream simplex_tree_ostream(iostream_file.c_str()); + simplex_tree_ostream << st; + simplex_tree_ostream.close(); + + Stree_type read_st; + std::ifstream simplex_tree_istream(iostream_file.c_str()); + simplex_tree_istream >> read_st; + + // Display the Simplex_tree + std::cout << "The READ complex contains " << read_st.num_simplices() << " simplices" << std::endl; + std::cout << " - dimension " << read_st.dimension() << " - filtration " << read_st.filtration() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : read_st.filtration_simplex_range()) { + std::cout << " " << "[" << read_st.filtration(f_simplex) << "] "; + for (auto vertex : read_st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + BOOST_CHECK(st == read_st); +} diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp index df89008e..1e6cea52 100644 --- a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -3,7 +3,6 @@ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "simplex_tree_remove" #include -#include // ^ // /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index 7323aa6c..f67ff010 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -86,41 +86,6 @@ bool AreAlmostTheSame(float a, float b) { return std::fabs(a - b) < std::numeric_limits::epsilon(); } -BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_from_file, typeST, list_of_tested_variants) { - // TEST OF INSERTION - std::cout << "********************************************************************" << std::endl; - std::cout << "TEST OF SIMPLEX TREE FROM A FILE" << std::endl; - typeST st; - - std::string inputFile("simplex_tree_for_unit_test.txt"); - std::ifstream simplex_tree_stream(inputFile.c_str()); - simplex_tree_stream >> st; - - // Display the Simplex_tree - std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl; - std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl; - - // Check - BOOST_CHECK(st.num_simplices() == 143353); - BOOST_CHECK(st.dimension() == 3); - BOOST_CHECK(AreAlmostTheSame(st.filtration(), 0.4)); - - int previous_size = 0; - for (auto f_simplex : st.filtration_simplex_range()) { - // Size of simplex - int size = 0; - for (auto vertex : st.simplex_vertex_range(f_simplex)) { - // Remove warning - (void) vertex; - size++; - } - BOOST_CHECK(AreAlmostTheSame(st.filtration(f_simplex), (0.1 * size))); // Specific test: filtration = 0.1 * simplex_size - BOOST_CHECK(previous_size <= size); // Check list is sorted (because of sorted filtrations in simplex_tree.txt) - previous_size = size; - } - simplex_tree_stream.close(); -} - template void test_simplex_tree_contains(typeST& simplexTree, typeSimplex& simplex, int pos) { auto f_simplex = simplexTree.filtration_simplex_range().begin() + pos; -- cgit v1.2.3 From c762ffb234a86d6acce63546bfacbf419ca62bbc Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 20 Sep 2017 20:33:19 +0000 Subject: Roll back simplex tree set_filtration modification (assign_filtration asserts in debug) and modify test git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2694 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d08cc4b4f310784975b81d10b7ebd78063c42378 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 1 - .../simplex_tree_iostream_operator_unit_test.cpp | 60 +++++++++++++++++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 76e594d3..dc684594 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -763,7 +763,6 @@ class Simplex_tree { /** Set an upper bound for the filtration values. */ void set_filtration(Filtration_value fil) { - if (Options::store_filtration) threshold_ = fil; } diff --git a/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp index 402c31e2..fed764d9 100644 --- a/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp @@ -20,8 +20,7 @@ struct MyOptions : Simplex_tree_options_full_featured { }; typedef boost::mpl::list, - Simplex_tree, - Simplex_tree + Simplex_tree > list_of_tested_variants; BOOST_AUTO_TEST_CASE_TEMPLATE(iostream_operator, Stree_type, list_of_tested_variants) { @@ -81,3 +80,60 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(iostream_operator, Stree_type, list_of_tested_vari BOOST_CHECK(st == read_st); } + + +BOOST_AUTO_TEST_CASE(mini_iostream_operator) { + std::cout << "********************************************************************" << std::endl; + std::cout << "MINI SIMPLEX TREE IOSTREAM OPERATOR" << std::endl; + + Simplex_tree st; + + st.insert_simplex_and_subfaces({0, 1, 6, 7}); + st.insert_simplex_and_subfaces({3, 4, 5}); + st.insert_simplex_and_subfaces({3, 0}); + st.insert_simplex_and_subfaces({2, 1, 0}); + + st.initialize_filtration(); + // Display the Simplex_tree + std::cout << "The ORIGINAL complex contains " << st.num_simplices() << " simplices" << std::endl; + std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + // st: + // 1 6 + // o---o + // /X\7/ + // o---o---o---o + // 2 0 3\X/4 + // o + // 5 + std::string iostream_file("simplex_tree_for_iostream_operator_unit_test.txt"); + std::ofstream simplex_tree_ostream(iostream_file.c_str()); + simplex_tree_ostream << st; + simplex_tree_ostream.close(); + + Simplex_tree read_st; + std::ifstream simplex_tree_istream(iostream_file.c_str()); + simplex_tree_istream >> read_st; + + // Display the Simplex_tree + std::cout << "The READ complex contains " << read_st.num_simplices() << " simplices" << std::endl; + std::cout << " - dimension " << read_st.dimension() << " - filtration " << read_st.filtration() << std::endl; + std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl; + for (auto f_simplex : read_st.filtration_simplex_range()) { + std::cout << " " << "[" << read_st.filtration(f_simplex) << "] "; + for (auto vertex : read_st.simplex_vertex_range(f_simplex)) { + std::cout << (int) vertex << " "; + } + std::cout << std::endl; + } + + BOOST_CHECK(st == read_st); +} -- cgit v1.2.3 From 409874ad0812c863a924bd4482d76c718620c0b9 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 21 Sep 2017 06:22:19 +0000 Subject: Add some comments for readability git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2697 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 986cc3b862ceca993a6fdd8cdee6da2c1ed4cc14 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index dc684594..5d1885b8 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1204,6 +1204,7 @@ class Simplex_tree { */ bool auto_dimension_set(int old_dimension) { int new_dimension = -1; + // Browse the tree from te left to the right as higher dimension cells are more likely on the left part of the tree for (Simplex_handle sh : skeleton_simplex_range(old_dimension)) { #ifdef DEBUG_TRACES for (auto vertex : simplex_vertex_range(sh)) { @@ -1214,6 +1215,7 @@ class Simplex_tree { int sh_dimension = dimension(sh); if (sh_dimension >= old_dimension) + // Stop browsing as soon as the dimension is reached, no need to go furter return false; new_dimension = std::max(new_dimension, sh_dimension); } -- cgit v1.2.3 From 346ba542c13db7e49e6d81412144ed21ac46bd83 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 21 Sep 2017 06:41:40 +0000 Subject: Remove set_dimension from examples git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2698 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: cde0919e6bb53ad8ace21f1c6894708468449276 --- src/Simplex_tree/example/mini_simplex_tree.cpp | 2 -- src/Simplex_tree/example/simple_simplex_tree.cpp | 1 - src/cython/example/simplex_tree_example.py | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/Simplex_tree/example/mini_simplex_tree.cpp b/src/Simplex_tree/example/mini_simplex_tree.cpp index ad99df23..19e45361 100644 --- a/src/Simplex_tree/example/mini_simplex_tree.cpp +++ b/src/Simplex_tree/example/mini_simplex_tree.cpp @@ -52,8 +52,6 @@ int main() { auto edge03 = {0, 3}; st.insert_simplex_and_subfaces(triangle012); st.insert_simplex_and_subfaces(edge03); - // FIXME: Remove this line - st.set_dimension(2); auto edge02 = {0, 2}; ST::Simplex_handle e = st.find(edge02); diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp index 60f9a35e..26d663fb 100644 --- a/src/Simplex_tree/example/simple_simplex_tree.cpp +++ b/src/Simplex_tree/example/simple_simplex_tree.cpp @@ -186,7 +186,6 @@ int main(int argc, char * const argv[]) { // ++ GENERAL VARIABLE SET simplexTree.set_filtration(FOURTH_FILTRATION_VALUE); // Max filtration value - simplexTree.set_dimension(2); // Max dimension = 2 -> (2,1,0) std::cout << "********************************************************************\n"; // Display the Simplex_tree - Can not be done in the middle of 2 inserts diff --git a/src/cython/example/simplex_tree_example.py b/src/cython/example/simplex_tree_example.py index 3af20fcf..7e4b0b6c 100755 --- a/src/cython/example/simplex_tree_example.py +++ b/src/cython/example/simplex_tree_example.py @@ -48,8 +48,6 @@ if st.insert([0, 1, 2], filtration=4.0): else: print("Not inserted...") -# FIXME: Remove this line -st.set_dimension(3) print("dimension=", st.dimension()) st.set_filtration(4.0) -- cgit v1.2.3 From 21b1120bfa2047eca025ae759dce2d05f6c86c43 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 22 Sep 2017 05:37:51 +0000 Subject: Remove automatic_dimension_set call from remove and prune functions Make it public to be available Modify tests accordingly git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2703 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2ff42d5327ae76b121390a913c4e548d6f59ea99 --- src/Alpha_complex/test/Alpha_complex_unit_test.cpp | 2 +- src/Simplex_tree/include/gudhi/Simplex_tree.h | 36 ++++------ .../test/simplex_tree_remove_unit_test.cpp | 78 ++++++++++++++-------- 3 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp index 166373fe..e60089c4 100644 --- a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp +++ b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) { BOOST_CHECK(simplex_tree.num_simplices() == 10); std::cout << "simplex_tree.dimension()=" << simplex_tree.dimension() << std::endl; - BOOST_CHECK(simplex_tree.dimension() == 1); + BOOST_CHECK(simplex_tree.dimension() == 3); std::cout << "simplex_tree.num_vertices()=" << simplex_tree.num_vertices() << std::endl; BOOST_CHECK(simplex_tree.num_vertices() == 4); diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 5d1885b8..fd6cd72a 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1161,13 +1161,11 @@ class Simplex_tree { * \post Some simplex tree functions require the filtration to be valid. `prune_above_filtration()` * function is not launching `initialize_filtration()` but returns the filtration modification information. If the * complex has changed , please call `initialize_filtration()` to recompute it. + * \post Be aware that `prune_above_filtration()` may change the simplex tree dimension (`automatic_dimension_set()` + * to be done). */ bool prune_above_filtration(Filtration_value filtration) { - bool modified = rec_prune_above_filtration(root(), filtration); - if (modified) { - auto_dimension_set(dimension()); - } - return modified; + return rec_prune_above_filtration(root(), filtration); } private: @@ -1195,17 +1193,16 @@ class Simplex_tree { return modified; } - private: - /** \brief Resets the Simplex_tree dimension. - * @param[in] old_dimension The former dimension value until the loop stopped when it is reached. + public: + /** \brief Deep search simplex tree dimension reset. * @return The dimension modification information. - * \pre Please check the simplex has not a too low dimension value. - * This cannot happen if set_dimension has not been performed. + * \pre Be sure the simplex tree has not a too low dimension value as the deep search stops when the former dimension + * has been reached (cf. `dimension()` and `set_dimension()` methods). */ - bool auto_dimension_set(int old_dimension) { + bool automatic_dimension_set() { int new_dimension = -1; // Browse the tree from te left to the right as higher dimension cells are more likely on the left part of the tree - for (Simplex_handle sh : skeleton_simplex_range(old_dimension)) { + for (Simplex_handle sh : skeleton_simplex_range(dimension_)) { #ifdef DEBUG_TRACES for (auto vertex : simplex_vertex_range(sh)) { std::cout << " " << vertex; @@ -1214,12 +1211,12 @@ class Simplex_tree { #endif // DEBUG_TRACES int sh_dimension = dimension(sh); - if (sh_dimension >= old_dimension) + if (sh_dimension >= dimension_) // Stop browsing as soon as the dimension is reached, no need to go furter return false; new_dimension = std::max(new_dimension, sh_dimension); } - set_dimension(new_dimension); + dimension_ = new_dimension; return true; } @@ -1229,7 +1226,8 @@ class Simplex_tree { * @param[in] sh Simplex handle on the maximal simplex to remove. * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. - * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done). + * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done). + * \post Be aware that removing may change the simplex tree dimension (`automatic_dimension_set()` to be done). */ void remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children @@ -1244,17 +1242,9 @@ class Simplex_tree { // Special case when child is the root of the simplex tree, just remove it from members child->erase(sh); } else { - // Keep information before remove action - int sh_dim = dimension(sh); - // Sibling is emptied : must be deleted, and its parent must point on his own Sibling child->oncles()->members().at(child->parent()).assign_children(child->oncles()); delete child; - - // No need to reset dimension in case maximal simplex is not the maximal dimension one - if (sh_dim >= dimension()) { - auto_dimension_set(sh_dim); - } } } diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp index 1e6cea52..87c77801 100644 --- a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -108,7 +108,12 @@ BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { st.remove_maximal_simplex(st.find({6, 7})); std::cout << "st.remove_maximal_simplex({7})" << std::endl; st.remove_maximal_simplex(st.find({7})); - + + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 3); + + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << " | st_wo_seven.dimension()=" << st_wo_seven.dimension() << std::endl; BOOST_CHECK(st == st_wo_seven); } @@ -130,100 +135,112 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { std::cout << "st.remove_maximal_simplex({6, 7, 8, 10})" << std::endl; st.remove_maximal_simplex(st.find({6, 7, 8, 10})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({6, 7, 8, 9})" << std::endl; st.remove_maximal_simplex(st.find({6, 7, 8, 9})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 3); + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 2); std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 5}); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 4}); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 5})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 3); + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 2); std::cout << "st.insert_simplex_and_subfaces({0, 1, 3, 4})" << std::endl; st.insert_simplex_and_subfaces({0, 1, 3, 4}); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({0, 1, 3, 4})" << std::endl; st.remove_maximal_simplex(st.find({0, 1, 3, 4})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 3); + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 2); std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 5}); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 4}); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); + // Check you can override the dimension // This is a limit test case - shall not happen st.set_dimension(1); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 1); - - // Here no siblings is erased - automatic dimension is not launched. - std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; - st.remove_maximal_simplex(st.find({1, 2, 3, 4})); + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + // check automatic_dimension_set() is not giving the rigt answer because dimension is too low BOOST_CHECK(st.dimension() == 1); - // Here sibling is erased - automatic dimension is launched. - std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; - st.remove_maximal_simplex(st.find({1, 2, 3, 5})); - BOOST_CHECK(st.dimension() == 2); - - std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; - st.insert_simplex_and_subfaces({1, 2, 3, 5}); - BOOST_CHECK(st.dimension() == 3); - - std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; - st.insert_simplex_and_subfaces({1, 2, 3, 4}); - BOOST_CHECK(st.dimension() == 3); // Check you can override the dimension // This is a limit test case - shall not happen st.set_dimension(6); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 6); + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + // check automatic_dimension_set() resets the correct dimension + BOOST_CHECK(st.dimension() == 3); - // Here no siblings is erased - automatic dimension is not launched. - std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; - st.remove_maximal_simplex(st.find({1, 2, 3, 5})); - BOOST_CHECK(st.dimension() == 6); - - // Here sibling is erased - automatic dimension is launched but dim is always than te one set. - std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; - st.remove_maximal_simplex(st.find({1, 2, 3, 4})); - BOOST_CHECK(st.dimension() == 6); // Reset with the correct value - st.set_dimension(2); - BOOST_CHECK(st.dimension() == 2); + st.set_dimension(3); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 3); std::cout << "st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6})" << std::endl; st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6}); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 6); std::cout << "st.remove_maximal_simplex({0, 1, 2, 3, 4, 5, 6})" << std::endl; st.remove_maximal_simplex(st.find({0, 1, 2, 3, 4, 5, 6})); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 6); + st.automatic_dimension_set(); + std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 5); } @@ -325,6 +342,11 @@ BOOST_AUTO_TEST_CASE(prune_above_filtration) { // Display the Simplex_tree std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices"; std::cout << " - dimension " << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == 3); + + st.automatic_dimension_set(); + std::cout << "dimension=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == -1); BOOST_CHECK(st == st_empty); BOOST_CHECK(simplex_is_changed); -- cgit v1.2.3 From 697884f4193c32723922aa5edfef37d09d198fac Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 26 Sep 2017 19:57:06 +0000 Subject: Doc review : Simplex tree remove maximal simplex is an implementatino detail that is not needed by the developper git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2717 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d096485bf30e50c804cf349f040f57764770136f --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 730b552f..fe1e87b4 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1302,10 +1302,11 @@ class Simplex_tree { public: /** \brief Remove a maximal simplex. * @param[in] sh Simplex handle on the maximal simplex to remove. - * @return true if the leaf's branch has no other leaves (branch's children has been re-assigned), false otherwise. + * @return a boolean value that is an implementation detail, and that the user is supposed to ignore * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done). + * \internal @return true if the leaf's branch has no other leaves (branch's children has been re-assigned), false otherwise. */ bool remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children -- cgit v1.2.3 From f697664c4d8d3cce26e49f07447dbe51f3bd570e Mon Sep 17 00:00:00 2001 From: pdlotko Date: Tue, 26 Sep 2017 20:34:36 +0000 Subject: adding a version of periodic weighted alpha shape (that unfortunatelly do not work yet...) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2718 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 611967b7fc8257fb2ae27ecc42f0e303c183755a --- src/Persistent_cohomology/example/CMakeLists.txt | 6 + .../weighted_alpha_complex_3d_persistence.cpp | 222 +++++----- ...ghted_periodic_alpha_complex_3d_persistence.cpp | 490 +++++++++++++++++++++ 3 files changed, 607 insertions(+), 111 deletions(-) create mode 100644 src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index f47de4c3..cc421bff 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -75,11 +75,16 @@ if(CGAL_FOUND) target_link_libraries(exact_alpha_complex_3d_persistence ${CGAL_LIBRARY}) add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) target_link_libraries(weighted_alpha_complex_3d_persistence ${CGAL_LIBRARY}) + add_executable(weighted_periodic_alpha_complex_3d_persistence weighted_periodic_alpha_complex_3d_persistence.cpp) + target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${CGAL_LIBRARY}) + + if (TBB_FOUND) target_link_libraries(alpha_complex_3d_persistence ${TBB_LIBRARIES}) target_link_libraries(exact_alpha_complex_3d_persistence ${TBB_LIBRARIES}) target_link_libraries(weighted_alpha_complex_3d_persistence ${TBB_LIBRARIES}) + target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES}) endif(TBB_FOUND) add_test(NAME Persistent_cohomology_example_alpha_complex_3d COMMAND $ "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "2" "0.45") @@ -91,6 +96,7 @@ if(CGAL_FOUND) install(TARGETS alpha_complex_3d_persistence DESTINATION bin) install(TARGETS exact_alpha_complex_3d_persistence DESTINATION bin) install(TARGETS weighted_alpha_complex_3d_persistence DESTINATION bin) + install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) add_executable (alpha_complex_persistence alpha_complex_persistence.cpp) diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp index ce45d16d..9e806c7a 100644 --- a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp @@ -136,129 +136,129 @@ int main(int argc, char * const argv[]) { std::cout << "Alpha shape computed in GENERAL mode" << std::endl; #endif // DEBUG_TRACES - // filtration with alpha values from alpha shape - std::vector the_objects; - std::vector the_alpha_values; + // filtration with alpha values from alpha shape + std::vector the_objects; + std::vector the_alpha_values; - Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), - std::back_inserter(the_alpha_values)); + Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), + std::back_inserter(the_alpha_values)); - as.filtration_with_alpha_values(disp); -#ifdef DEBUG_TRACES - std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; -#endif // DEBUG_TRACES + as.filtration_with_alpha_values(disp); + #ifdef DEBUG_TRACES + std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; + #endif // DEBUG_TRACES - Alpha_shape_3::size_type count_vertices = 0; - Alpha_shape_3::size_type count_edges = 0; - Alpha_shape_3::size_type count_facets = 0; - Alpha_shape_3::size_type count_cells = 0; + Alpha_shape_3::size_type count_vertices = 0; + Alpha_shape_3::size_type count_edges = 0; + Alpha_shape_3::size_type count_facets = 0; + Alpha_shape_3::size_type count_cells = 0; - // Loop on objects vector - Vertex_list vertex_list; - ST simplex_tree; - Alpha_shape_simplex_tree_map map_cgal_simplex_tree; - std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); - int dim_max = 0; - Filtration_value filtration_max = 0.0; - for (auto object_iterator : the_objects) { - // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { - vertex_list = from_cell(*cell); - count_cells++; - if (dim_max < 3) { - // Cell is of dim 3 - dim_max = 3; - } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { - vertex_list = from_facet(*facet); - count_facets++; - if (dim_max < 2) { - // Facet is of dim 2 - dim_max = 2; - } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { - vertex_list = from_edge(*edge); - count_edges++; - if (dim_max < 1) { - // Edge_3 is of dim 1 - dim_max = 1; - } - } else if (const Alpha_shape_3::Vertex_handle * vertex = - CGAL::object_cast(&object_iterator)) { - count_vertices++; - vertex_list = from_vertex(*vertex); - } - // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex - Simplex_tree_vector_vertex the_simplex_tree; - for (auto the_alpha_shape_vertex : vertex_list) { - Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); - if (the_map_iterator == map_cgal_simplex_tree.end()) { - // alpha shape not found - Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); -#ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; -#endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); - } else { - // alpha shape found - Simplex_tree_vertex vertex = the_map_iterator->second; -#ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; -#endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - } - } - // Construction of the simplex_tree - Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); -#ifdef DEBUG_TRACES - std::cout << "filtration = " << filtr << std::endl; -#endif // DEBUG_TRACES - if (filtr > filtration_max) { - filtration_max = filtr; - } - simplex_tree.insert_simplex(the_simplex_tree, filtr); - if (the_alpha_value_iterator != the_alpha_values.end()) - ++the_alpha_value_iterator; - else - std::cout << "This shall not happen" << std::endl; - } - simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); + // Loop on objects vector + Vertex_list vertex_list; + ST simplex_tree; + Alpha_shape_simplex_tree_map map_cgal_simplex_tree; + std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); + int dim_max = 0; + Filtration_value filtration_max = 0.0; + for (auto object_iterator : the_objects) { + // Retrieve Alpha shape vertex list from object + if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + vertex_list = from_cell(*cell); + count_cells++; + if (dim_max < 3) { + // Cell is of dim 3 + dim_max = 3; + } + } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + vertex_list = from_facet(*facet); + count_facets++; + if (dim_max < 2) { + // Facet is of dim 2 + dim_max = 2; + } + } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + vertex_list = from_edge(*edge); + count_edges++; + if (dim_max < 1) { + // Edge_3 is of dim 1 + dim_max = 1; + } + } else if (const Alpha_shape_3::Vertex_handle * vertex = + CGAL::object_cast(&object_iterator)) { + count_vertices++; + vertex_list = from_vertex(*vertex); + } + // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex + Simplex_tree_vector_vertex the_simplex_tree; + for (auto the_alpha_shape_vertex : vertex_list) { + Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); + if (the_map_iterator == map_cgal_simplex_tree.end()) { + // alpha shape not found + Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); + #ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; + #endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); + } else { + // alpha shape found + Simplex_tree_vertex vertex = the_map_iterator->second; + #ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; + #endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + } + } + // Construction of the simplex_tree + Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); + #ifdef DEBUG_TRACES + std::cout << "filtration = " << filtr << std::endl; + #endif // DEBUG_TRACES + if (filtr > filtration_max) { + filtration_max = filtr; + } + simplex_tree.insert_simplex(the_simplex_tree, filtr); + if (the_alpha_value_iterator != the_alpha_values.end()) + ++the_alpha_value_iterator; + else + std::cout << "This shall not happen" << std::endl; + } + simplex_tree.set_filtration(filtration_max); + simplex_tree.set_dimension(dim_max); -#ifdef DEBUG_TRACES - std::cout << "vertices \t\t" << count_vertices << std::endl; - std::cout << "edges \t\t" << count_edges << std::endl; - std::cout << "facets \t\t" << count_facets << std::endl; - std::cout << "cells \t\t" << count_cells << std::endl; + #ifdef DEBUG_TRACES + std::cout << "vertices \t\t" << count_vertices << std::endl; + std::cout << "edges \t\t" << count_edges << std::endl; + std::cout << "facets \t\t" << count_facets << std::endl; + std::cout << "cells \t\t" << count_cells << std::endl; - std::cout << "Information of the Simplex Tree: " << std::endl; - std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; - std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; - std::cout << " Dimension = " << simplex_tree.dimension() << " "; - std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; -#endif // DEBUG_TRACES + std::cout << "Information of the Simplex Tree: " << std::endl; + std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; + std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; + std::cout << " Dimension = " << simplex_tree.dimension() << " "; + std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; + #endif // DEBUG_TRACES -#ifdef DEBUG_TRACES - std::cout << "Iterator on vertices: " << std::endl; - for (auto vertex : simplex_tree.complex_vertex_range()) { - std::cout << vertex << " "; - } -#endif // DEBUG_TRACES + #ifdef DEBUG_TRACES + std::cout << "Iterator on vertices: " << std::endl; + for (auto vertex : simplex_tree.complex_vertex_range()) { + std::cout << vertex << " "; + } + #endif // DEBUG_TRACES - // Sort the simplices in the order of the filtration - simplex_tree.initialize_filtration(); + // Sort the simplices in the order of the filtration + simplex_tree.initialize_filtration(); - std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; - // Compute the persistence diagram of the complex - Persistent_cohomology pcoh(simplex_tree, true); - // initializes the coefficient field for homology - pcoh.init_coefficients(coeff_field_characteristic); + std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(simplex_tree, true); + // initializes the coefficient field for homology + pcoh.init_coefficients(coeff_field_characteristic); - pcoh.compute_persistent_cohomology(min_persistence); + pcoh.compute_persistent_cohomology(min_persistence); - pcoh.output_diagram(); + pcoh.output_diagram(); return 0; } diff --git a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp new file mode 100644 index 00000000..70c0572d --- /dev/null +++ b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp @@ -0,0 +1,490 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2014 INRIA + * + * 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 . + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alpha_complex_3d_helper.h" +/* +// Traits +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using PK = CGAL::Periodic_3_Delaunay_triangulation_traits_3; + +using Vb = CGAL::Alpha_shape_vertex_base_3; +using Fb = CGAL::Alpha_shape_cell_base_3; +using Tds = CGAL::Triangulation_data_structure_3; +//using Triangulation_3 = CGAL::Regular_triangulation_3; +using Alpha_shape_3 = CGAL::Alpha_shape_3; + +//vertex type +using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>; +using Vb = CGAL::Triangulation_vertex_base_3; +using AsVb = CGAL::Alpha_shape_vertex_base_3; + +// Cell type +using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>; +using Cb = CGAL::Triangulation_cell_base_3; +using P3DT3 = CGAL::Periodic_3_Delaunay_triangulation_3; +using Point_3 = PK::Point_3; + +// From file type definition +using Point_3 = Gt::Bare_point; +using Weighted_point_3 = Gt::Weighted_point; + +// filtration with alpha values needed type definition +using Alpha_value_type = Alpha_shape_3::FT; +using Object = CGAL::Object; +using Dispatch = CGAL::Dispatch_output_iterator< + CGAL::cpp11::tuple, + CGAL::cpp11::tuple >, + std::back_insert_iterator< std::vector > > >; +using Cell_handle = Alpha_shape_3::Cell_handle; +using Facet = Alpha_shape_3::Facet; +using Edge_3 = Alpha_shape_3::Edge; +using Vertex_handle = Alpha_shape_3::Vertex_handle; +using Vertex_list = std::list; + +// gudhi type definition +using ST = Gudhi::Simplex_tree; +using Filtration_value = ST::Filtration_value; +using Simplex_tree_vertex = ST::Vertex_handle; +using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_pair = std::pair; +using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; +using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< + ST, Gudhi::persistent_cohomology::Field_Zp >; + */ + + + +// Traits +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using PK = CGAL::Periodic_3_Delaunay_triangulation_traits_3; +using Gt = CGAL::Regular_triangulation_euclidean_traits_3; +// Vertex type +using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>; +using Vb = CGAL::Triangulation_vertex_base_3; +using AsVb = CGAL::Alpha_shape_vertex_base_3; +// Cell type +using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>; +using Cb = CGAL::Triangulation_cell_base_3; +using AsCb = CGAL::Alpha_shape_cell_base_3; +using Tds = CGAL::Triangulation_data_structure_3; +using P3DT3 = CGAL::Periodic_3_Delaunay_triangulation_3; +using Alpha_shape_3 = CGAL::Alpha_shape_3; +using Point_3 = CGAL::Periodic_3_Delaunay_triangulation_traits_3::Point_3; + +// From file type definition +using Point_3 = Gt::Bare_point; +using Weighted_point_3 = Gt::Weighted_point; + +// filtration with alpha values needed type definition +using Alpha_value_type = Alpha_shape_3::FT; +using Object = CGAL::Object; +using Dispatch = CGAL::Dispatch_output_iterator< + CGAL::cpp11::tuple, + CGAL::cpp11::tuple >, + std::back_insert_iterator< std::vector > > >; +using Cell_handle = Alpha_shape_3::Cell_handle; +using Facet = Alpha_shape_3::Facet; +using Edge_3 = Alpha_shape_3::Edge; +using Vertex_handle = Alpha_shape_3::Vertex_handle; +using Vertex_list = std::list; + +// gudhi type definition +using ST = Gudhi::Simplex_tree; +using Filtration_value = ST::Filtration_value; +using Simplex_tree_vertex = ST::Vertex_handle; +using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_pair = std::pair; +using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; +using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< + ST, Gudhi::persistent_cohomology::Field_Zp >; + + +void usage(char * const progName) { + std::cerr << "Usage: " << progName << + " path_to_the_OFF_File path_to_weight_file path_to_the_cuboid_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; + exit(-1); +} + +int main(int argc, char * const argv[]) { + // program args management + if (argc != 6) { + std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; + //file with points, file with weights, cuboid file, field characteristics, minimum persistence. + usage(argv[0]); + } + + int coeff_field_characteristic = atoi(argv[4]); + Filtration_value min_persistence = strtof(argv[5], nullptr); + + // Read points from file + std::string offInputFile(argv[1]); + // Read the OFF file (input file name given as parameter) and triangulate points + Gudhi::Points_3D_off_reader off_reader(offInputFile); + // Check the read operation was correct + if (!off_reader.is_valid()) { + std::cerr << "Unable to read file " << offInputFile << std::endl; + usage(argv[0]); + } + + // Retrieve the triangulation + std::vector lp = off_reader.get_point_cloud(); + + // Read weights information from file + std::ifstream weights_ifstr(argv[2]); + std::vector wp; + if (weights_ifstr.good()) { + double weight = 0.0; + std::size_t index = 0; + wp.reserve(lp.size()); + // Attempt read the weight in a double format, return false if it fails + while ((weights_ifstr >> weight) && (index < lp.size())) { + wp.push_back(Weighted_point_3(lp[index], weight)); + index++; + } + if (index != lp.size()) { + std::cerr << "Bad number of weights in file " << argv[2] << std::endl; + usage(argv[0]); + } + } else { + std::cerr << "Unable to read file " << argv[2] << std::endl; + usage(argv[0]); + } + + // Read iso_cuboid_3 information from file + std::ifstream iso_cuboid_str(argv[3]); + double x_min, y_min, z_min, x_max, y_max, z_max; + if (iso_cuboid_str.good()) { + iso_cuboid_str >> x_min >> y_min >> z_min >> x_max >> y_max >> z_max; + } else { + std::cerr << "Unable to read file " << argv[3] << std::endl; + usage(argv[0]); + } + + std::cout << "wp.size() : " << wp.size() << std::endl; + + // Define the periodic cube + P3DT3 pdt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max)); + // Heuristic for inserting large point sets (if pts is reasonably large) + pdt.insert(wp.begin(), wp.end(), true); + // As pdt won't be modified anymore switch to 1-sheeted cover if possible + if (pdt.is_triangulation_in_1_sheet()) pdt.convert_to_1_sheeted_covering(); + std::cout << "Periodic Delaunay computed." << std::endl; + + // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. This is the default mode + // Maybe need to set it to GENERAL mode + Alpha_shape_3 as(pdt, 0, Alpha_shape_3::GENERAL); + + + + + + + + + + + // filtration with alpha values from alpha shape + std::vector the_objects; + std::vector the_alpha_values; + + Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), + std::back_inserter(the_alpha_values)); + + as.filtration_with_alpha_values(disp); +#ifdef DEBUG_TRACES + std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; +#endif // DEBUG_TRACES + + Alpha_shape_3::size_type count_vertices = 0; + Alpha_shape_3::size_type count_edges = 0; + Alpha_shape_3::size_type count_facets = 0; + Alpha_shape_3::size_type count_cells = 0; + + // Loop on objects vector + Vertex_list vertex_list; + ST simplex_tree; + Alpha_shape_simplex_tree_map map_cgal_simplex_tree; + std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); + int dim_max = 0; + Filtration_value filtration_max = 0.0; + for (auto object_iterator : the_objects) { + // Retrieve Alpha shape vertex list from object + if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + vertex_list = from_cell(*cell); + count_cells++; + if (dim_max < 3) { + // Cell is of dim 3 + dim_max = 3; + } + } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + vertex_list = from_facet(*facet); + count_facets++; + if (dim_max < 2) { + // Facet is of dim 2 + dim_max = 2; + } + } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + vertex_list = from_edge(*edge); + count_edges++; + if (dim_max < 1) { + // Edge_3 is of dim 1 + dim_max = 1; + } + } else if (const Alpha_shape_3::Vertex_handle * vertex = + CGAL::object_cast(&object_iterator)) { + count_vertices++; + vertex_list = from_vertex(*vertex); + } + // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex + Simplex_tree_vector_vertex the_simplex_tree; + for (auto the_alpha_shape_vertex : vertex_list) { + Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); + if (the_map_iterator == map_cgal_simplex_tree.end()) { + // alpha shape not found + Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); + } else { + // alpha shape found + Simplex_tree_vertex vertex = the_map_iterator->second; +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + } + } + // Construction of the simplex_tree + Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); +#ifdef DEBUG_TRACES + std::cout << "filtration = " << filtr << std::endl; +#endif // DEBUG_TRACES + if (filtr > filtration_max) { + filtration_max = filtr; + } + simplex_tree.insert_simplex(the_simplex_tree, filtr); + if (the_alpha_value_iterator != the_alpha_values.end()) + ++the_alpha_value_iterator; + else + std::cout << "This shall not happen" << std::endl; + } + simplex_tree.set_filtration(filtration_max); + simplex_tree.set_dimension(dim_max); + +#ifdef DEBUG_TRACES + std::cout << "vertices \t\t" << count_vertices << std::endl; + std::cout << "edges \t\t" << count_edges << std::endl; + std::cout << "facets \t\t" << count_facets << std::endl; + std::cout << "cells \t\t" << count_cells << std::endl; + + + std::cout << "Information of the Simplex Tree: " << std::endl; + std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; + std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; + std::cout << " Dimension = " << simplex_tree.dimension() << " "; + std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; +#endif // DEBUG_TRACES + +#ifdef DEBUG_TRACES + std::cout << "Iterator on vertices: " << std::endl; + for (auto vertex : simplex_tree.complex_vertex_range()) { + std::cout << vertex << " "; + } +#endif // DEBUG_TRACES + + // Sort the simplices in the order of the filtration + simplex_tree.initialize_filtration(); + + std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(simplex_tree, true); + // initializes the coefficient field for homology + pcoh.init_coefficients(coeff_field_characteristic); + + pcoh.compute_persistent_cohomology(min_persistence); + + pcoh.output_diagram(); + + + + + + + + + + +/* + // filtration with alpha values from alpha shape + std::vector the_objects; + std::vector the_alpha_values; + + Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), + std::back_inserter(the_alpha_values)); + + as.filtration_with_alpha_values(disp); +#ifdef DEBUG_TRACES + std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; +#endif // DEBUG_TRACES + + Alpha_shape_3::size_type count_vertices = 0; + Alpha_shape_3::size_type count_edges = 0; + Alpha_shape_3::size_type count_facets = 0; + Alpha_shape_3::size_type count_cells = 0; + + // Loop on objects vector + Vertex_list vertex_list; + ST simplex_tree; + Alpha_shape_simplex_tree_map map_cgal_simplex_tree; + std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); + int dim_max = 0; + Filtration_value filtration_max = 0.0; + for (auto object_iterator : the_objects) { + // Retrieve Alpha shape vertex list from object + if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + vertex_list = from_cell(*cell); + count_cells++; + if (dim_max < 3) { + // Cell is of dim 3 + dim_max = 3; + } + } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + vertex_list = from_facet(*facet); + count_facets++; + if (dim_max < 2) { + // Facet is of dim 2 + dim_max = 2; + } + } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + vertex_list = from_edge(*edge); + count_edges++; + if (dim_max < 1) { + // Edge_3 is of dim 1 + dim_max = 1; + } + } else if (const Alpha_shape_3::Vertex_handle * vertex = + CGAL::object_cast(&object_iterator)) { + count_vertices++; + vertex_list = from_vertex(*vertex); + } + // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex + Simplex_tree_vector_vertex the_simplex_tree; + for (auto the_alpha_shape_vertex : vertex_list) { + Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); + if (the_map_iterator == map_cgal_simplex_tree.end()) { + // alpha shape not found + Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); + } else { + // alpha shape found + Simplex_tree_vertex vertex = the_map_iterator->second; +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + } + } + // Construction of the simplex_tree + Filtration_value filtr = (*the_alpha_value_iterator); +#ifdef DEBUG_TRACES + std::cout << "filtration = " << filtr << std::endl; +#endif // DEBUG_TRACES + if (filtr > filtration_max) { + filtration_max = filtr; + } + simplex_tree.insert_simplex(the_simplex_tree, filtr); + if (the_alpha_value_iterator != the_alpha_values.end()) + ++the_alpha_value_iterator; + else + std::cout << "This shall not happen" << std::endl; + } + simplex_tree.set_filtration(filtration_max); + simplex_tree.set_dimension(dim_max); + +#ifdef DEBUG_TRACES + std::cout << "vertices \t\t" << count_vertices << std::endl; + std::cout << "edges \t\t" << count_edges << std::endl; + std::cout << "facets \t\t" << count_facets << std::endl; + std::cout << "cells \t\t" << count_cells << std::endl; + + + std::cout << "Information of the Simplex Tree: " << std::endl; + std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; + std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; + std::cout << " Dimension = " << simplex_tree.dimension() << " "; + std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; +#endif // DEBUG_TRACES + +#ifdef DEBUG_TRACES + std::cout << "Iterator on vertices: " << std::endl; + for (auto vertex : simplex_tree.complex_vertex_range()) { + std::cout << vertex << " "; + } +#endif // DEBUG_TRACES + + // Sort the simplices in the order of the filtration + simplex_tree.initialize_filtration(); + + std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(simplex_tree, true); + // initializes the coefficient field for homology + pcoh.init_coefficients(coeff_field_characteristic); + + pcoh.compute_persistent_cohomology(min_persistence); + + pcoh.output_diagram(); + */ + + return 0; +} -- cgit v1.2.3 From 768c70aa382a7b0b561ea842720f5963a412b88e Mon Sep 17 00:00:00 2001 From: cjamin Date: Fri, 29 Sep 2017 08:40:52 +0000 Subject: Rename a few functions in Kd_tree_search git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2730 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f009977d25c76cc0f6116093a448fab258c8626b --- .../doc/Intro_spatial_searching.h | 2 +- .../example/example_spatial_searching.cpp | 22 +++++++------- .../include/gudhi/Kd_tree_search.h | 34 +++++++++++----------- src/Spatial_searching/test/test_Kd_tree_search.cpp | 24 +++++++-------- src/Subsampling/include/gudhi/sparsify_point_set.h | 2 +- .../include/gudhi/Tangential_complex.h | 16 +++++----- .../gudhi/Euclidean_strong_witness_complex.h | 2 +- .../include/gudhi/Euclidean_witness_complex.h | 2 +- .../test/test_euclidean_simple_witness_complex.cpp | 2 +- 9 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/Spatial_searching/doc/Intro_spatial_searching.h b/src/Spatial_searching/doc/Intro_spatial_searching.h index 22652ac4..1ee5e92e 100644 --- a/src/Spatial_searching/doc/Intro_spatial_searching.h +++ b/src/Spatial_searching/doc/Intro_spatial_searching.h @@ -46,7 +46,7 @@ namespace spatial_searching { * * \section spatial_searching_examples Example * - * This example generates 500 random points, then performs near search, and queries for nearest and farthest points using different methods. + * This example generates 500 random points, then performs all-near-neighbors searches, and queries for nearest and furthest neighbors using different methods. * * \include Spatial_searching/example_spatial_searching.cpp * diff --git a/src/Spatial_searching/example/example_spatial_searching.cpp b/src/Spatial_searching/example/example_spatial_searching.cpp index 201b589e..034ad24a 100644 --- a/src/Spatial_searching/example/example_spatial_searching.cpp +++ b/src/Spatial_searching/example/example_spatial_searching.cpp @@ -24,34 +24,34 @@ int main(void) { // 10-nearest neighbor query std::cout << "10 nearest neighbors from points[20]:\n"; - auto knn_range = points_ds.query_k_nearest_neighbors(points[20], 10, true); + auto knn_range = points_ds.k_nearest_neighbors(points[20], 10, true); for (auto const& nghb : knn_range) std::cout << nghb.first << " (sq. dist. = " << nghb.second << ")\n"; // Incremental nearest neighbor query std::cout << "Incremental nearest neighbors:\n"; - auto inn_range = points_ds.query_incremental_nearest_neighbors(points[45]); + auto inn_range = points_ds.incremental_nearest_neighbors(points[45]); // Get the neighbors in distance order until we hit the first point for (auto ins_iterator = inn_range.begin(); ins_iterator->first != 0; ++ins_iterator) std::cout << ins_iterator->first << " (sq. dist. = " << ins_iterator->second << ")\n"; - // 10-farthest neighbor query - std::cout << "10 farthest neighbors from points[20]:\n"; - auto kfn_range = points_ds.query_k_farthest_neighbors(points[20], 10, true); + // 10-furthest neighbor query + std::cout << "10 furthest neighbors from points[20]:\n"; + auto kfn_range = points_ds.k_furthest_neighbors(points[20], 10, true); for (auto const& nghb : kfn_range) std::cout << nghb.first << " (sq. dist. = " << nghb.second << ")\n"; - // Incremental farthest neighbor query - std::cout << "Incremental farthest neighbors:\n"; - auto ifn_range = points_ds.query_incremental_farthest_neighbors(points[45]); + // Incremental furthest neighbor query + std::cout << "Incremental furthest neighbors:\n"; + auto ifn_range = points_ds.incremental_furthest_neighbors(points[45]); // Get the neighbors in distance reverse order until we hit the first point for (auto ifs_iterator = ifn_range.begin(); ifs_iterator->first != 0; ++ifs_iterator) std::cout << ifs_iterator->first << " (sq. dist. = " << ifs_iterator->second << ")\n"; - // Near search - std::cout << "Near search:\n"; + // All-near-neighbors search + std::cout << "All-near-neighbors search:\n"; std::vector rs_result; - points_ds.near_search(points[45], 0.5, std::back_inserter(rs_result)); + points_ds.all_near_neighbors(points[45], 0.5, std::back_inserter(rs_result)); K k; for (auto const& p_idx : rs_result) std::cout << p_idx << " (sq. dist. = " << k.squared_distance_d_object()(points[p_idx], points[45]) << ")\n"; diff --git a/src/Spatial_searching/include/gudhi/Kd_tree_search.h b/src/Spatial_searching/include/gudhi/Kd_tree_search.h index af04736b..ef428002 100644 --- a/src/Spatial_searching/include/gudhi/Kd_tree_search.h +++ b/src/Spatial_searching/include/gudhi/Kd_tree_search.h @@ -42,19 +42,19 @@ namespace spatial_searching { /** * \class Kd_tree_search Kd_tree_search.h gudhi/Kd_tree_search.h - * \brief Spatial tree data structure to perform (approximate) nearest and farthest neighbor search. + * \brief Spatial tree data structure to perform (approximate) nearest and furthest neighbor search. * * \ingroup spatial_searching * * \details * The class Kd_tree_search is a tree-based data structure, based on * CGAL dD spatial searching data structures. - * It provides a simplified API to perform (approximate) nearest and farthest neighbor searches. Contrary to CGAL default behavior, the tree + * It provides a simplified API to perform (approximate) nearest and furthest neighbor searches. Contrary to CGAL default behavior, the tree * does not store the points themselves, but stores indices. * - * There are two types of queries: the k-nearest or k-farthest neighbor query, where k is fixed and the k nearest - * or farthest points are computed right away, - * and the incremental nearest or farthest neighbor query, where no number of neighbors is provided during the call, as the + * There are two types of queries: the k-nearest or k-furthest neighbor query, where k is fixed and the k nearest + * or furthest points are computed right away, + * and the incremental nearest or furthest neighbor query, where no number of neighbors is provided during the call, as the * neighbors will be computed incrementally when the iterator on the range is incremented. * * \tparam Search_traits must be a model of the K_neighbor_search; typedef typename K_neighbor_search::Tree Tree; typedef typename K_neighbor_search::Distance Distance; - /// \brief The range returned by a k-nearest or k-farthest neighbor search. + /// \brief The range returned by a k-nearest or k-furthest neighbor search. /// Its value type is `std::pair` where `first` is the index /// of a point P and `second` is the squared distance between P and the query point. typedef K_neighbor_search KNS_range; @@ -104,7 +104,7 @@ class Kd_tree_search { typedef CGAL::Orthogonal_incremental_neighbor_search< STraits, Distance, CGAL::Sliding_midpoint, Tree> Incremental_neighbor_search; - /// \brief The range returned by an incremental nearest or farthest neighbor search. + /// \brief The range returned by an incremental nearest or furthest neighbor search. /// Its value type is `std::pair` where `first` is the index /// of a point P and `second` is the squared distance between P and the query point. typedef Incremental_neighbor_search INS_range; @@ -171,7 +171,7 @@ class Kd_tree_search { /// @param[in] sorted Indicates if the computed sequence of k-nearest neighbors needs to be sorted. /// @param[in] eps Approximation factor. /// @return A range (whose `value_type` is `std::size_t`) containing the k-nearest neighbors. - KNS_range query_k_nearest_neighbors( + KNS_range k_nearest_neighbors( Point const& p, unsigned int k, bool sorted = true, @@ -197,7 +197,7 @@ class Kd_tree_search { /// neighbors sorted by their distance to p. /// All the neighbors are not computed by this function, but they will be /// computed incrementally when the iterator on the range is incremented. - INS_range query_incremental_nearest_neighbors(Point const& p, FT eps = FT(0)) const { + INS_range incremental_nearest_neighbors(Point const& p, FT eps = FT(0)) const { // Initialize the search structure, and search all N points // Note that we need to pass the Distance explicitly since it needs to // know the property map @@ -211,13 +211,13 @@ class Kd_tree_search { return search; } - /// \brief Search for the k-farthest points from a query point. + /// \brief Search for the k-furthest points from a query point. /// @param[in] p The query point. - /// @param[in] k Number of farthest points to search. - /// @param[in] sorted Indicates if the computed sequence of k-farthest neighbors needs to be sorted. + /// @param[in] k Number of furthest points to search. + /// @param[in] sorted Indicates if the computed sequence of k-furthest neighbors needs to be sorted. /// @param[in] eps Approximation factor. - /// @return A range (whose `value_type` is `std::size_t`) containing the k-farthest neighbors. - KNS_range query_k_farthest_neighbors( + /// @return A range (whose `value_type` is `std::size_t`) containing the k-furthest neighbors. + KNS_range k_furthest_neighbors( Point const& p, unsigned int k, bool sorted = true, @@ -236,14 +236,14 @@ class Kd_tree_search { return search; } - /// \brief Search incrementally for the farthest neighbors from a query point. + /// \brief Search incrementally for the furthest neighbors from a query point. /// @param[in] p The query point. /// @param[in] eps Approximation factor. /// @return A range (whose `value_type` is `std::size_t`) /// containing the neighbors sorted by their distance to p. /// All the neighbors are not computed by this function, but they will be /// computed incrementally when the iterator on the range is incremented. - INS_range query_incremental_farthest_neighbors(Point const& p, FT eps = FT(0)) const { + INS_range incremental_furthest_neighbors(Point const& p, FT eps = FT(0)) const { // Initialize the search structure, and search all N points // Note that we need to pass the Distance explicitly since it needs to // know the property map @@ -264,7 +264,7 @@ class Kd_tree_search { /// Note: `it` is used this way: `*it++ = each_point`. /// @param[in] eps Approximation factor. template - void near_search(Point const& p, + void all_near_neighbors(Point const& p, FT radius, OutputIterator it, FT eps = FT(0)) const { diff --git a/src/Spatial_searching/test/test_Kd_tree_search.cpp b/src/Spatial_searching/test/test_Kd_tree_search.cpp index 663a103a..8a8334c3 100644 --- a/src/Spatial_searching/test/test_Kd_tree_search.cpp +++ b/src/Spatial_searching/test/test_Kd_tree_search.cpp @@ -48,12 +48,12 @@ BOOST_AUTO_TEST_CASE(test_Kd_tree_search) { Points_ds points_ds(points); - // Test query_k_nearest_neighbors + // Test k_nearest_neighbors std::size_t closest_pt_index = - points_ds.query_k_nearest_neighbors(points[10], 1, false).begin()->first; + points_ds.k_nearest_neighbors(points[10], 1, false).begin()->first; BOOST_CHECK(closest_pt_index == 10); - auto kns_range = points_ds.query_k_nearest_neighbors(points[20], 10, true); + auto kns_range = points_ds.k_nearest_neighbors(points[20], 10, true); std::vector knn_result; FT last_dist = -1.; @@ -63,12 +63,12 @@ BOOST_AUTO_TEST_CASE(test_Kd_tree_search) { last_dist = nghb.second; } - // Test query_incremental_nearest_neighbors + // Test incremental_nearest_neighbors closest_pt_index = - points_ds.query_incremental_nearest_neighbors(points[10]).begin()->first; + points_ds.incremental_nearest_neighbors(points[10]).begin()->first; BOOST_CHECK(closest_pt_index == 10); - auto inn_range = points_ds.query_incremental_nearest_neighbors(points[20]); + auto inn_range = points_ds.incremental_nearest_neighbors(points[20]); std::vector inn_result; last_dist = -1.; @@ -83,8 +83,8 @@ BOOST_AUTO_TEST_CASE(test_Kd_tree_search) { // Same result for KNN and INN? BOOST_CHECK(knn_result == inn_result); - // Test query_k_farthest_neighbors - auto kfn_range = points_ds.query_k_farthest_neighbors(points[20], 10, true); + // Test k_furthest_neighbors + auto kfn_range = points_ds.k_furthest_neighbors(points[20], 10, true); std::vector kfn_result; last_dist = kfn_range.begin()->second; @@ -94,8 +94,8 @@ BOOST_AUTO_TEST_CASE(test_Kd_tree_search) { last_dist = nghb.second; } - // Test query_k_farthest_neighbors - auto ifn_range = points_ds.query_incremental_farthest_neighbors(points[20]); + // Test k_furthest_neighbors + auto ifn_range = points_ds.incremental_furthest_neighbors(points[20]); std::vector ifn_result; last_dist = ifn_range.begin()->second; @@ -110,10 +110,10 @@ BOOST_AUTO_TEST_CASE(test_Kd_tree_search) { // Same result for KFN and IFN? BOOST_CHECK(kfn_result == ifn_result); - // Test near search + // Test all_near_neighbors Point rs_q(rd.get_double(-1., 1), rd.get_double(-1., 1), rd.get_double(-1., 1), rd.get_double(-1., 1)); std::vector rs_result; - points_ds.near_search(rs_q, 0.5, std::back_inserter(rs_result)); + points_ds.all_near_neighbors(rs_q, 0.5, std::back_inserter(rs_result)); K k; for (auto const& p_idx : rs_result) BOOST_CHECK(k.squared_distance_d_object()(points[p_idx], rs_q) <= 0.5); diff --git a/src/Subsampling/include/gudhi/sparsify_point_set.h b/src/Subsampling/include/gudhi/sparsify_point_set.h index 507f8c79..7d3b97fb 100644 --- a/src/Subsampling/include/gudhi/sparsify_point_set.h +++ b/src/Subsampling/include/gudhi/sparsify_point_set.h @@ -83,7 +83,7 @@ sparsify_point_set( *output_it++ = *it_pt; - auto ins_range = points_ds.query_incremental_nearest_neighbors(*it_pt); + auto ins_range = points_ds.incremental_nearest_neighbors(*it_pt); // If another point Q is closer that min_squared_dist, mark Q to be dropped for (auto const& neighbor : ins_range) { diff --git a/src/Tangential_complex/include/gudhi/Tangential_complex.h b/src/Tangential_complex/include/gudhi/Tangential_complex.h index 9fa7c825..a5cefd6a 100644 --- a/src/Tangential_complex/include/gudhi/Tangential_complex.h +++ b/src/Tangential_complex/include/gudhi/Tangential_complex.h @@ -1093,8 +1093,8 @@ class Tangential_complex { std::size_t num_inserted_points = 1; #endif // const int NUM_NEIGHBORS = 150; - // KNS_range ins_range = m_points_ds.query_k_nearest_neighbors(center_pt, NUM_NEIGHBORS); - INS_range ins_range = m_points_ds.query_incremental_nearest_neighbors(center_pt); + // KNS_range ins_range = m_points_ds.k_nearest_neighbors(center_pt, NUM_NEIGHBORS); + INS_range ins_range = m_points_ds.incremental_nearest_neighbors(center_pt); // While building the local triangulation, we keep the radius // of the sphere "star sphere" centered at "center_vertex" @@ -1203,7 +1203,7 @@ class Tangential_complex { Point center_point = compute_perturbed_point(i); // Among updated point, what is the closer from our center point? std::size_t closest_pt_index = - updated_pts_ds.query_k_nearest_neighbors(center_point, 1, false).begin()->first; + updated_pts_ds.k_nearest_neighbors(center_point, 1, false).begin()->first; typename K::Construct_weighted_point_d k_constr_wp = m_k.construct_weighted_point_d_object(); @@ -1315,11 +1315,10 @@ class Tangential_complex { m_k.compute_coordinate_d_object(); #ifdef GUDHI_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM - KNS_range kns_range = m_points_ds_for_tse.query_k_nearest_neighbors( - p, num_pts_for_pca, false); + KNS_range kns_range = m_points_ds_for_tse.k_nearest_neighbors(p, num_pts_for_pca, false); const Points &points_for_pca = m_points_for_tse; #else - KNS_range kns_range = m_points_ds.query_k_nearest_neighbors(p, num_pts_for_pca, false); + KNS_range kns_range = m_points_ds.k_nearest_neighbors(p, num_pts_for_pca, false); const Points &points_for_pca = m_points; #endif @@ -1413,11 +1412,10 @@ class Tangential_complex { const Point &p = m_points[*it_index]; #ifdef GUDHI_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM - KNS_range kns_range = m_points_ds_for_tse.query_k_nearest_neighbors( - p, num_pts_for_pca, false); + KNS_range kns_range = m_points_ds_for_tse.k_nearest_neighbors(p, num_pts_for_pca, false); const Points &points_for_pca = m_points_for_tse; #else - KNS_range kns_range = m_points_ds.query_k_nearest_neighbors(p, num_pts_for_pca, false); + KNS_range kns_range = m_points_ds.k_nearest_neighbors(p, num_pts_for_pca, false); const Points &points_for_pca = m_points; #endif diff --git a/src/Witness_complex/include/gudhi/Euclidean_strong_witness_complex.h b/src/Witness_complex/include/gudhi/Euclidean_strong_witness_complex.h index fb669ef8..4f3cef4f 100644 --- a/src/Witness_complex/include/gudhi/Euclidean_strong_witness_complex.h +++ b/src/Witness_complex/include/gudhi/Euclidean_strong_witness_complex.h @@ -84,7 +84,7 @@ class Euclidean_strong_witness_complex : landmarks_(std::begin(landmarks), std::end(landmarks)), landmark_tree_(landmarks_) { nearest_landmark_table_.reserve(boost::size(witnesses)); for (auto w : witnesses) - nearest_landmark_table_.push_back(landmark_tree_.query_incremental_nearest_neighbors(w)); + nearest_landmark_table_.push_back(landmark_tree_.incremental_nearest_neighbors(w)); } /** \brief Returns the point corresponding to the given vertex. diff --git a/src/Witness_complex/include/gudhi/Euclidean_witness_complex.h b/src/Witness_complex/include/gudhi/Euclidean_witness_complex.h index 6afe9a5d..ff8bb139 100644 --- a/src/Witness_complex/include/gudhi/Euclidean_witness_complex.h +++ b/src/Witness_complex/include/gudhi/Euclidean_witness_complex.h @@ -86,7 +86,7 @@ class Euclidean_witness_complex : landmarks_(std::begin(landmarks), std::end(landmarks)), landmark_tree_(landmarks) { nearest_landmark_table_.reserve(boost::size(witnesses)); for (auto w : witnesses) - nearest_landmark_table_.push_back(landmark_tree_.query_incremental_nearest_neighbors(w)); + nearest_landmark_table_.push_back(landmark_tree_.incremental_nearest_neighbors(w)); } /** \brief Returns the point corresponding to the given vertex. diff --git a/src/Witness_complex/test/test_euclidean_simple_witness_complex.cpp b/src/Witness_complex/test/test_euclidean_simple_witness_complex.cpp index 62fd1157..4f718203 100644 --- a/src/Witness_complex/test/test_euclidean_simple_witness_complex.cpp +++ b/src/Witness_complex/test/test_euclidean_simple_witness_complex.cpp @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(simple_witness_complex) { Kd_tree landmark_tree(landmarks); Nearest_landmark_table nearest_landmark_table; for (auto w: witnesses) - nearest_landmark_table.push_back(landmark_tree.query_incremental_nearest_neighbors(w)); + nearest_landmark_table.push_back(landmark_tree.incremental_nearest_neighbors(w)); // Weak witness complex: Euclidean version EuclideanWitnessComplex eucl_witness_complex(landmarks, -- cgit v1.2.3 From 36d71f6a62d0390c5a8193171c92e75a85889b4a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 29 Sep 2017 21:06:08 +0000 Subject: Doc issue fix git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2733 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ea0323fed1ca42ecee50d6fbf9db9fbfb3e64cc9 --- src/Persistent_cohomology/doc/Intro_persistent_cohomology.h | 11 ++++++----- src/cython/doc/cubical_complex_user.rst | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h index e17e5926..6400116b 100644 --- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h +++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h @@ -189,10 +189,10 @@ and a weights file. \code $> ./weighted_alpha_complex_3d_persistence ../../data/points/tore3D_300.off ../../data/points/tore3D_300.weights 2 0.45 \endcode \code Simplex_tree dim: 3 -2 -0 0 inf -2 1 0.0682162 1.0001 -2 1 0.0934117 1.00003 -2 2 0.56444 1.03938 \endcode +2 0 -1 inf +2 1 -0.931784 0.000103311 +2 1 -0.906588 2.60165e-05 +2 2 -0.43556 0.0393798 \endcode \li Persistent_cohomology/alpha_complex_persistence.cpp computes the persistent homology with @@ -208,7 +208,8 @@ Simplex_tree dim: 3 \li Persistent_cohomology/periodic_alpha_complex_3d_persistence.cpp computes the persistent homology with \f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the periodic alpha complex on points sampling from an OFF file. -\code $> ./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off 3 1.0 \endcode +\code $> ./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off +../../data/points/iso_cuboid_3_in_0_1.txt 3 1.0 \endcode \code Periodic Delaunay computed. Simplex_tree dim: 3 3 0 0 inf diff --git a/src/cython/doc/cubical_complex_user.rst b/src/cython/doc/cubical_complex_user.rst index 36fa3ba9..4f902d0a 100644 --- a/src/cython/doc/cubical_complex_user.rst +++ b/src/cython/doc/cubical_complex_user.rst @@ -59,7 +59,7 @@ directions, allows to determine, dimension, neighborhood, boundary and coboundar :math:`C \in \mathcal{K}`. .. figure:: - img/Cubical_complex_representation.png + ../../doc/Bitmap_cubical_complex/Cubical_complex_representation.png :alt: Cubical complex. :figclass: align-center @@ -87,7 +87,7 @@ in the example below). Next, in lexicographical order, the filtration of top dim 20 4 7 6 5 in the example below). .. figure:: - img/exampleBitmap.png + ../../doc/Bitmap_cubical_complex/exampleBitmap.png :alt: Example of a input data. :figclass: align-center @@ -97,7 +97,7 @@ The input file for the following complex is: .. literalinclude:: cubicalcomplexdoc.txt -.. centered:: data/bitmap/cubicalcomplexdoc.txt +.. centered:: ../../data/bitmap/cubicalcomplexdoc.txt .. testcode:: @@ -130,7 +130,7 @@ For instance: .. literalinclude:: periodiccubicalcomplexdoc.txt -.. centered:: data/bitmap/periodiccubicalcomplexdoc.txt +.. centered:: ../../data/bitmap/periodiccubicalcomplexdoc.txt Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y. -- cgit v1.2.3 From b9132f99c06c91f825854073512eacd87624579e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 29 Sep 2017 21:08:06 +0000 Subject: Gudhi version 2.0.1 git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2734 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3ce829b94a61b9649b663ee85bc68b74f75eb59e --- CMakeGUDHIVersion.txt | 2 +- src/Doxyfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeGUDHIVersion.txt b/CMakeGUDHIVersion.txt index 87daf28e..bfef1590 100644 --- a/CMakeGUDHIVersion.txt +++ b/CMakeGUDHIVersion.txt @@ -1,6 +1,6 @@ set (GUDHI_MAJOR_VERSION 2) set (GUDHI_MINOR_VERSION 0) -set (GUDHI_PATCH_VERSION 1-rc2) +set (GUDHI_PATCH_VERSION 1) set(GUDHI_VERSION ${GUDHI_MAJOR_VERSION}.${GUDHI_MINOR_VERSION}.${GUDHI_PATCH_VERSION}) message(STATUS "GUDHI version : ${GUDHI_VERSION}") diff --git a/src/Doxyfile b/src/Doxyfile index 7f5975eb..0ef81e5c 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "GUDHI" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "2.0.1-rc2" +PROJECT_NUMBER = "2.0.1" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a -- cgit v1.2.3 From 8868bb6e355a4aec8e084aaf73a1ed1cf47a8589 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 29 Sep 2017 21:43:01 +0000 Subject: Build doc issue git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2736 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 438179e355d47083f9db2c237d7ceb132c7b0168 --- src/cython/doc/cubical_complex_user.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cython/doc/cubical_complex_user.rst b/src/cython/doc/cubical_complex_user.rst index 4f902d0a..2bfac62a 100644 --- a/src/cython/doc/cubical_complex_user.rst +++ b/src/cython/doc/cubical_complex_user.rst @@ -95,7 +95,7 @@ in the example below). Next, in lexicographical order, the filtration of top dim The input file for the following complex is: -.. literalinclude:: cubicalcomplexdoc.txt +.. literalinclude:: ../../data/bitmap/cubicalcomplexdoc.txt .. centered:: ../../data/bitmap/cubicalcomplexdoc.txt @@ -128,7 +128,7 @@ complex with periodic boundary conditions. One can also use Perseus style input conditions in a given direction, then number of top dimensional cells in this direction have to be multiplied by -1. For instance: -.. literalinclude:: periodiccubicalcomplexdoc.txt +.. literalinclude:: ../../data/bitmap/periodiccubicalcomplexdoc.txt .. centered:: ../../data/bitmap/periodiccubicalcomplexdoc.txt -- cgit v1.2.3 From 8d21e4d56cc40e94b395a3a497757c149b4b9f1c Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Sun, 1 Oct 2017 20:35:12 +0000 Subject: Euclidean Witness examples requires CGAL >= 4.8.1 because it is using subsampling (CMake and install doc) Bad link to Gudhi bibtex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2741 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8c1b84a4030029ec7d1470c49662e15836cf02de --- src/cython/CMakeLists.txt | 25 +++++++++++++------------ src/cython/doc/citation.rst | 2 +- src/cython/doc/installation.rst | 23 ++++++++++++----------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index ec8589f0..afca9d60 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -185,6 +185,19 @@ if(CYTHON_FOUND) 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) + # Subsampling add_gudhi_py_test(test_subsampling) @@ -218,18 +231,6 @@ if(CYTHON_FOUND) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) # Euclidean witness - 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) - add_gudhi_py_test(test_euclidean_witness_complex) endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) diff --git a/src/cython/doc/citation.rst b/src/cython/doc/citation.rst index 6cdfb7cc..f4fdf83b 100644 --- a/src/cython/doc/citation.rst +++ b/src/cython/doc/citation.rst @@ -12,4 +12,4 @@ Manual, as well as for publications directly related to the GUDHI library. GUDHI bibtex ************ -.. literalinclude:: how_to_cite_gudhi.bib +.. literalinclude:: ../../biblio/how_to_cite_gudhi.bib diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst index f98a5039..c182f176 100644 --- a/src/cython/doc/installation.rst +++ b/src/cython/doc/installation.rst @@ -68,31 +68,32 @@ The :doc:`Alpha complex `, C++ library which provides easy access to efficient and reliable geometric algorithms. -Having CGAL version 4.6.0 or higher installed is recommended. The procedure to -install this library according to your operating system is detailed +Having CGAL, the Computational Geometry Algorithms Library, version 4.7.0 or +higher installed is recommended. The procedure to install this library +according to your operating system is detailed `here `_. -The following examples require the Computational Geometry Algorithms Library: - -.. only:: builder_html - - * :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>` - -The following example requires CGAL version ≥ 4.7.0: +The following examples requires CGAL version ≥ 4.7.0: .. only:: builder_html * :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>` * :download:`alpha_complex_from_points_example.py <../example/alpha_complex_from_points_example.py>` -The following example requires CGAL version ≥ 4.8.0: +The following examples requires CGAL version ≥ 4.8.0: .. only:: builder_html * :download:`bottleneck_basic_example.py <../example/bottleneck_basic_example.py>` * :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>` +The following examples requires CGAL version ≥ 4.8.1: + +.. only:: builder_html + + * :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>` + Eigen3 ====== -- cgit v1.2.3 From 9ed5279c478f5d79151e7f99390da7eb23f11550 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 2 Oct 2017 15:47:32 +0000 Subject: Fix weighted_alpha_complex_3d_persistence to work with CGAL 4.11 (2 cpp and cmake compiles the correct one) Homogeneize alpha_complex_3d* codes Fix weighted_periodic_alpha_complex_3d_persistence with CGAL doc help Add grid off file with weights to test weighted_periodic_alpha_complex_3d_persistence git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2744 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ecc4f3629e75bd986ffd22ec348f0412163e4dbd --- data/points/grid_10_10_10_in_0_2.off | 127 +++++++++ data/points/grid_10_10_10_in_0_2.weights | 126 +++++++++ src/Persistent_cohomology/example/CMakeLists.txt | 41 ++- .../example/alpha_complex_3d_helper.h | 8 +- .../example/alpha_complex_3d_persistence.cpp | 34 +-- .../periodic_alpha_complex_3d_persistence.cpp | 36 ++- .../weighted_alpha_complex_3d_persistence.cpp | 263 +++++++++---------- ...a_complex_3d_persistence_old_cgal_interface.cpp | 262 ++++++++++++++++++ ...ghted_periodic_alpha_complex_3d_persistence.cpp | 292 ++++----------------- 9 files changed, 757 insertions(+), 432 deletions(-) create mode 100644 data/points/grid_10_10_10_in_0_2.off create mode 100644 data/points/grid_10_10_10_in_0_2.weights create mode 100644 src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp diff --git a/data/points/grid_10_10_10_in_0_2.off b/data/points/grid_10_10_10_in_0_2.off new file mode 100644 index 00000000..7618e065 --- /dev/null +++ b/data/points/grid_10_10_10_in_0_2.off @@ -0,0 +1,127 @@ +OFF +125 0 0 +0 0 0 +0 0 0.2 +0 0 0.4 +0 0 0.6 +0 0 0.8 +0 0.2 0 +0 0.2 0.2 +0 0.2 0.4 +0 0.2 0.6 +0 0.2 0.8 +0 0.4 0 +0 0.4 0.2 +0 0.4 0.4 +0 0.4 0.6 +0 0.4 0.8 +0 0.6 0 +0 0.6 0.2 +0 0.6 0.4 +0 0.6 0.6 +0 0.6 0.8 +0 0.8 0 +0 0.8 0.2 +0 0.8 0.4 +0 0.8 0.6 +0 0.8 0.8 +0.2 0 0 +0.2 0 0.2 +0.2 0 0.4 +0.2 0 0.6 +0.2 0 0.8 +0.2 0.2 0 +0.2 0.2 0.2 +0.2 0.2 0.4 +0.2 0.2 0.6 +0.2 0.2 0.8 +0.2 0.4 0 +0.2 0.4 0.2 +0.2 0.4 0.4 +0.2 0.4 0.6 +0.2 0.4 0.8 +0.2 0.6 0 +0.2 0.6 0.2 +0.2 0.6 0.4 +0.2 0.6 0.6 +0.2 0.6 0.8 +0.2 0.8 0 +0.2 0.8 0.2 +0.2 0.8 0.4 +0.2 0.8 0.6 +0.2 0.8 0.8 +0.4 0 0 +0.4 0 0.2 +0.4 0 0.4 +0.4 0 0.6 +0.4 0 0.8 +0.4 0.2 0 +0.4 0.2 0.2 +0.4 0.2 0.4 +0.4 0.2 0.6 +0.4 0.2 0.8 +0.4 0.4 0 +0.4 0.4 0.2 +0.4 0.4 0.4 +0.4 0.4 0.6 +0.4 0.4 0.8 +0.4 0.6 0 +0.4 0.6 0.2 +0.4 0.6 0.4 +0.4 0.6 0.6 +0.4 0.6 0.8 +0.4 0.8 0 +0.4 0.8 0.2 +0.4 0.8 0.4 +0.4 0.8 0.6 +0.4 0.8 0.8 +0.6 0 0 +0.6 0 0.2 +0.6 0 0.4 +0.6 0 0.6 +0.6 0 0.8 +0.6 0.2 0 +0.6 0.2 0.2 +0.6 0.2 0.4 +0.6 0.2 0.6 +0.6 0.2 0.8 +0.6 0.4 0 +0.6 0.4 0.2 +0.6 0.4 0.4 +0.6 0.4 0.6 +0.6 0.4 0.8 +0.6 0.6 0 +0.6 0.6 0.2 +0.6 0.6 0.4 +0.6 0.6 0.6 +0.6 0.6 0.8 +0.6 0.8 0 +0.6 0.8 0.2 +0.6 0.8 0.4 +0.6 0.8 0.6 +0.6 0.8 0.8 +0.8 0 0 +0.8 0 0.2 +0.8 0 0.4 +0.8 0 0.6 +0.8 0 0.8 +0.8 0.2 0 +0.8 0.2 0.2 +0.8 0.2 0.4 +0.8 0.2 0.6 +0.8 0.2 0.8 +0.8 0.4 0 +0.8 0.4 0.2 +0.8 0.4 0.4 +0.8 0.4 0.6 +0.8 0.4 0.8 +0.8 0.6 0 +0.8 0.6 0.2 +0.8 0.6 0.4 +0.8 0.6 0.6 +0.8 0.6 0.8 +0.8 0.8 0 +0.8 0.8 0.2 +0.8 0.8 0.4 +0.8 0.8 0.6 +0.8 0.8 0.8 diff --git a/data/points/grid_10_10_10_in_0_2.weights b/data/points/grid_10_10_10_in_0_2.weights new file mode 100644 index 00000000..3672ecfd --- /dev/null +++ b/data/points/grid_10_10_10_in_0_2.weights @@ -0,0 +1,126 @@ +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 + diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index cc421bff..f6c866dc 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -73,30 +73,18 @@ if(CGAL_FOUND) target_link_libraries(alpha_complex_3d_persistence ${CGAL_LIBRARY}) add_executable(exact_alpha_complex_3d_persistence exact_alpha_complex_3d_persistence.cpp) target_link_libraries(exact_alpha_complex_3d_persistence ${CGAL_LIBRARY}) - add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) - target_link_libraries(weighted_alpha_complex_3d_persistence ${CGAL_LIBRARY}) - add_executable(weighted_periodic_alpha_complex_3d_persistence weighted_periodic_alpha_complex_3d_persistence.cpp) - target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${CGAL_LIBRARY}) - - if (TBB_FOUND) target_link_libraries(alpha_complex_3d_persistence ${TBB_LIBRARIES}) target_link_libraries(exact_alpha_complex_3d_persistence ${TBB_LIBRARIES}) - target_link_libraries(weighted_alpha_complex_3d_persistence ${TBB_LIBRARIES}) - target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES}) endif(TBB_FOUND) add_test(NAME Persistent_cohomology_example_alpha_complex_3d COMMAND $ "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "2" "0.45") add_test(NAME Persistent_cohomology_example_exact_alpha_complex_3d COMMAND $ "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "2" "0.45") - add_test(NAME Persistent_cohomology_example_weighted_alpha_complex_3d COMMAND $ - "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.weights" "2" "0.45") install(TARGETS alpha_complex_3d_persistence DESTINATION bin) install(TARGETS exact_alpha_complex_3d_persistence DESTINATION bin) - install(TARGETS weighted_alpha_complex_3d_persistence DESTINATION bin) - install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) add_executable (alpha_complex_persistence alpha_complex_persistence.cpp) @@ -125,4 +113,33 @@ if(CGAL_FOUND) install(TARGETS custom_persistence_sort DESTINATION bin) endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + + if (NOT CGAL_VERSION VERSION_LESS 4.11.0) + add_executable(weighted_periodic_alpha_complex_3d_persistence weighted_periodic_alpha_complex_3d_persistence.cpp) + target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${CGAL_LIBRARY}) + if (TBB_FOUND) + target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES}) + endif(TBB_FOUND) + + install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) + + # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the new interface + add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) + else(NOT CGAL_VERSION VERSION_LESS 4.11.0) + # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the old interface + add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp) + endif (NOT CGAL_VERSION VERSION_LESS 4.11.0) + + # cf. if (NOT CGAL_VERSION VERSION_LESS 4.11.0) and else(NOT CGAL_VERSION VERSION_LESS 4.11.0) + # same target name on purpose + target_link_libraries(weighted_alpha_complex_3d_persistence ${CGAL_LIBRARY}) + if (TBB_FOUND) + target_link_libraries(weighted_alpha_complex_3d_persistence ${TBB_LIBRARIES}) + endif(TBB_FOUND) + + install(TARGETS weighted_alpha_complex_3d_persistence DESTINATION bin) + + add_test(NAME Persistent_cohomology_example_weighted_alpha_complex_3d COMMAND $ + "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.weights" "2" "0.45") + endif(CGAL_FOUND) diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_helper.h b/src/Persistent_cohomology/example/alpha_complex_3d_helper.h index 7865e4ec..6b3b7d5d 100644 --- a/src/Persistent_cohomology/example/alpha_complex_3d_helper.h +++ b/src/Persistent_cohomology/example/alpha_complex_3d_helper.h @@ -23,7 +23,7 @@ #ifndef ALPHA_COMPLEX_3D_HELPER_H_ #define ALPHA_COMPLEX_3D_HELPER_H_ -template +template Vertex_list from_cell(const Cell_handle& ch) { Vertex_list the_list; for (auto i = 0; i < 4; i++) { @@ -35,7 +35,7 @@ Vertex_list from_cell(const Cell_handle& ch) { return the_list; } -template +template Vertex_list from_facet(const Facet& fct) { Vertex_list the_list; for (auto i = 0; i < 4; i++) { @@ -49,7 +49,7 @@ Vertex_list from_facet(const Facet& fct) { return the_list; } -template +template Vertex_list from_edge(const Edge_3& edg) { Vertex_list the_list; for (auto i = 0; i < 4; i++) { @@ -63,7 +63,7 @@ Vertex_list from_edge(const Edge_3& edg) { return the_list; } -template +template Vertex_list from_vertex(const Vertex_handle& vh) { Vertex_list the_list; #ifdef DEBUG_TRACES diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp index fd227b82..a0db9b42 100644 --- a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp @@ -56,10 +56,10 @@ using Point_3 = Kernel::Point_3; // filtration with alpha values needed type definition using Alpha_value_type = Alpha_shape_3::FT; using Object = CGAL::Object; -using Dispatch = CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple >, - std::back_insert_iterator< std::vector > > >; +using Dispatch = + CGAL::Dispatch_output_iterator, + CGAL::cpp11::tuple >, + std::back_insert_iterator > > >; using Cell_handle = Alpha_shape_3::Cell_handle; using Facet = Alpha_shape_3::Facet; using Edge_3 = Alpha_shape_3::Edge; @@ -70,18 +70,19 @@ using Vertex_list = std::list; using ST = Gudhi::Simplex_tree; using Filtration_value = ST::Filtration_value; using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_map = std::map; using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; -using PCOH = Gudhi::persistent_cohomology::Persistent_cohomology< ST, Gudhi::persistent_cohomology::Field_Zp >; +using Simplex_tree_vector_vertex = std::vector; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology; void usage(const std::string& progName) { - std::cerr << "Usage: " << progName << - " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; + std::cerr << "Usage: " << progName + << " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); } -int main(int argc, char * const argv[]) { +int main(int argc, char* const argv[]) { // program args management if (argc != 4) { std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; @@ -142,28 +143,28 @@ int main(int argc, char * const argv[]) { Filtration_value filtration_max = 0.0; for (auto object_iterator : the_objects) { // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { vertex_list = from_cell(*cell); count_cells++; if (dim_max < 3) { // Cell is of dim 3 dim_max = 3; } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { vertex_list = from_facet(*facet); count_facets++; if (dim_max < 2) { // Facet is of dim 2 dim_max = 2; } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { vertex_list = from_edge(*edge); count_edges++; if (dim_max < 1) { // Edge_3 is of dim 1 dim_max = 1; } - } else if (const Vertex_handle * vertex = CGAL::object_cast(&object_iterator)) { + } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { count_vertices++; vertex_list = from_vertex(*vertex); } @@ -189,7 +190,7 @@ int main(int argc, char * const argv[]) { } } // Construction of the simplex_tree - Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); + Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); #ifdef DEBUG_TRACES std::cout << "filtration = " << filtr << std::endl; #endif // DEBUG_TRACES @@ -211,7 +212,6 @@ int main(int argc, char * const argv[]) { std::cout << "facets \t\t" << count_facets << std::endl; std::cout << "cells \t\t" << count_cells << std::endl; - std::cout << "Information of the Simplex Tree: " << std::endl; std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; @@ -231,7 +231,7 @@ int main(int argc, char * const argv[]) { std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; // Compute the persistence diagram of the complex - PCOH pcoh(simplex_tree); + Persistent_cohomology pcoh(simplex_tree, true); // initializes the coefficient field for homology pcoh.init_coefficients(coeff_field_characteristic); diff --git a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp index 8928cfc2..33efbdc7 100644 --- a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp @@ -63,10 +63,10 @@ using Point_3 = PK::Point_3; // filtration with alpha values needed type definition using Alpha_value_type = Alpha_shape_3::FT; using Object = CGAL::Object; -using Dispatch = CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple >, - std::back_insert_iterator< std::vector > > >; +using Dispatch = + CGAL::Dispatch_output_iterator, + CGAL::cpp11::tuple >, + std::back_insert_iterator > > >; using Cell_handle = Alpha_shape_3::Cell_handle; using Facet = Alpha_shape_3::Facet; using Edge_3 = Alpha_shape_3::Edge; @@ -77,19 +77,19 @@ using Vertex_list = std::list; using ST = Gudhi::Simplex_tree; using Filtration_value = ST::Filtration_value; using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_map = std::map; using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; -using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< - ST, Gudhi::persistent_cohomology::Field_Zp >; +using Simplex_tree_vector_vertex = std::vector; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology; -void usage(char * const progName) { - std::cerr << "Usage: " << progName << - " path_to_file_graph path_to_iso_cuboid_3_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; +void usage(char* const progName) { + std::cerr << "Usage: " << progName << " path_to_file_graph path_to_iso_cuboid_3_file " + "coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); } -int main(int argc, char * const argv[]) { +int main(int argc, char* const argv[]) { // program args management if (argc != 5) { std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; @@ -160,29 +160,28 @@ int main(int argc, char * const argv[]) { Filtration_value filtration_max = 0.0; for (auto object_iterator : the_objects) { // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { vertex_list = from_cell(*cell); count_cells++; if (dim_max < 3) { // Cell is of dim 3 dim_max = 3; } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { vertex_list = from_facet(*facet); count_facets++; if (dim_max < 2) { // Facet is of dim 2 dim_max = 2; } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { vertex_list = from_edge(*edge); count_edges++; if (dim_max < 1) { // Edge_3 is of dim 1 dim_max = 1; } - } else if (const Alpha_shape_3::Vertex_handle * vertex = - CGAL::object_cast(&object_iterator)) { + } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { count_vertices++; vertex_list = from_vertex(*vertex); } @@ -208,7 +207,7 @@ int main(int argc, char * const argv[]) { } } // Construction of the simplex_tree - Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); + Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); #ifdef DEBUG_TRACES std::cout << "filtration = " << filtr << std::endl; #endif // DEBUG_TRACES @@ -230,7 +229,6 @@ int main(int argc, char * const argv[]) { std::cout << "facets \t\t" << count_facets << std::endl; std::cout << "cells \t\t" << count_cells << std::endl; - std::cout << "Information of the Simplex Tree: " << std::endl; std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp index 9e806c7a..92fed4c1 100644 --- a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -44,26 +43,26 @@ #include "alpha_complex_3d_helper.h" -// Traits using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using Gt = CGAL::Regular_triangulation_euclidean_traits_3; -using Vb = CGAL::Alpha_shape_vertex_base_3; -using Fb = CGAL::Alpha_shape_cell_base_3; -using Tds = CGAL::Triangulation_data_structure_3; -using Triangulation_3 = CGAL::Regular_triangulation_3; +using Rvb = CGAL::Regular_triangulation_vertex_base_3; +using Vb = CGAL::Alpha_shape_vertex_base_3; +using Rcb = CGAL::Regular_triangulation_cell_base_3; +using Cb = CGAL::Alpha_shape_cell_base_3; +using Tds = CGAL::Triangulation_data_structure_3; +using Triangulation_3 = CGAL::Regular_triangulation_3; using Alpha_shape_3 = CGAL::Alpha_shape_3; // From file type definition -using Point_3 = Gt::Bare_point; -using Weighted_point_3 = Gt::Weighted_point; +using Point_3 = Triangulation_3::Bare_point; +using Weighted_point_3 = Triangulation_3::Weighted_point; // filtration with alpha values needed type definition using Alpha_value_type = Alpha_shape_3::FT; using Object = CGAL::Object; -using Dispatch = CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple >, - std::back_insert_iterator< std::vector > > >; +using Dispatch = + CGAL::Dispatch_output_iterator, + CGAL::cpp11::tuple >, + std::back_insert_iterator > > >; using Cell_handle = Alpha_shape_3::Cell_handle; using Facet = Alpha_shape_3::Facet; using Edge_3 = Alpha_shape_3::Edge; @@ -74,19 +73,19 @@ using Vertex_list = std::list; using ST = Gudhi::Simplex_tree; using Filtration_value = ST::Filtration_value; using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_map = std::map; using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; -using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< - ST, Gudhi::persistent_cohomology::Field_Zp >; +using Simplex_tree_vector_vertex = std::vector; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology; -void usage(char * const progName) { - std::cerr << "Usage: " << progName << - " path_to_file_graph path_to_weight_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; +void usage(char* const progName) { + std::cerr << "Usage: " << progName << " path_to_file_graph path_to_weight_file coeff_field_characteristic[integer > " + "0] min_persistence[float >= -1.0]\n"; exit(-1); } -int main(int argc, char * const argv[]) { +int main(int argc, char* const argv[]) { // program args management if (argc != 5) { std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; @@ -136,129 +135,127 @@ int main(int argc, char * const argv[]) { std::cout << "Alpha shape computed in GENERAL mode" << std::endl; #endif // DEBUG_TRACES - // filtration with alpha values from alpha shape - std::vector the_objects; - std::vector the_alpha_values; + // filtration with alpha values from alpha shape + std::vector the_objects; + std::vector the_alpha_values; - Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), - std::back_inserter(the_alpha_values)); + Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), + std::back_inserter(the_alpha_values)); - as.filtration_with_alpha_values(disp); - #ifdef DEBUG_TRACES - std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; - #endif // DEBUG_TRACES - - Alpha_shape_3::size_type count_vertices = 0; - Alpha_shape_3::size_type count_edges = 0; - Alpha_shape_3::size_type count_facets = 0; - Alpha_shape_3::size_type count_cells = 0; + as.filtration_with_alpha_values(disp); +#ifdef DEBUG_TRACES + std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; +#endif // DEBUG_TRACES - // Loop on objects vector - Vertex_list vertex_list; - ST simplex_tree; - Alpha_shape_simplex_tree_map map_cgal_simplex_tree; - std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); - int dim_max = 0; - Filtration_value filtration_max = 0.0; - for (auto object_iterator : the_objects) { - // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { - vertex_list = from_cell(*cell); - count_cells++; - if (dim_max < 3) { - // Cell is of dim 3 - dim_max = 3; - } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { - vertex_list = from_facet(*facet); - count_facets++; - if (dim_max < 2) { - // Facet is of dim 2 - dim_max = 2; - } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { - vertex_list = from_edge(*edge); - count_edges++; - if (dim_max < 1) { - // Edge_3 is of dim 1 - dim_max = 1; - } - } else if (const Alpha_shape_3::Vertex_handle * vertex = - CGAL::object_cast(&object_iterator)) { - count_vertices++; - vertex_list = from_vertex(*vertex); - } - // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex - Simplex_tree_vector_vertex the_simplex_tree; - for (auto the_alpha_shape_vertex : vertex_list) { - Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); - if (the_map_iterator == map_cgal_simplex_tree.end()) { - // alpha shape not found - Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); - #ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; - #endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); - } else { - // alpha shape found - Simplex_tree_vertex vertex = the_map_iterator->second; - #ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; - #endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - } - } - // Construction of the simplex_tree - Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); - #ifdef DEBUG_TRACES - std::cout << "filtration = " << filtr << std::endl; - #endif // DEBUG_TRACES - if (filtr > filtration_max) { - filtration_max = filtr; - } - simplex_tree.insert_simplex(the_simplex_tree, filtr); - if (the_alpha_value_iterator != the_alpha_values.end()) - ++the_alpha_value_iterator; - else - std::cout << "This shall not happen" << std::endl; - } - simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); + Alpha_shape_3::size_type count_vertices = 0; + Alpha_shape_3::size_type count_edges = 0; + Alpha_shape_3::size_type count_facets = 0; + Alpha_shape_3::size_type count_cells = 0; - #ifdef DEBUG_TRACES - std::cout << "vertices \t\t" << count_vertices << std::endl; - std::cout << "edges \t\t" << count_edges << std::endl; - std::cout << "facets \t\t" << count_facets << std::endl; - std::cout << "cells \t\t" << count_cells << std::endl; + // Loop on objects vector + Vertex_list vertex_list; + ST simplex_tree; + Alpha_shape_simplex_tree_map map_cgal_simplex_tree; + std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); + int dim_max = 0; + Filtration_value filtration_max = 0.0; + for (auto object_iterator : the_objects) { + // Retrieve Alpha shape vertex list from object + if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { + vertex_list = from_cell(*cell); + count_cells++; + if (dim_max < 3) { + // Cell is of dim 3 + dim_max = 3; + } + } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { + vertex_list = from_facet(*facet); + count_facets++; + if (dim_max < 2) { + // Facet is of dim 2 + dim_max = 2; + } + } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { + vertex_list = from_edge(*edge); + count_edges++; + if (dim_max < 1) { + // Edge_3 is of dim 1 + dim_max = 1; + } + } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { + count_vertices++; + vertex_list = from_vertex(*vertex); + } + // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex + Simplex_tree_vector_vertex the_simplex_tree; + for (auto the_alpha_shape_vertex : vertex_list) { + Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); + if (the_map_iterator == map_cgal_simplex_tree.end()) { + // alpha shape not found + Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); + } else { + // alpha shape found + Simplex_tree_vertex vertex = the_map_iterator->second; +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + } + } + // Construction of the simplex_tree + Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); +#ifdef DEBUG_TRACES + std::cout << "filtration = " << filtr << std::endl; +#endif // DEBUG_TRACES + if (filtr > filtration_max) { + filtration_max = filtr; + } + simplex_tree.insert_simplex(the_simplex_tree, filtr); + if (the_alpha_value_iterator != the_alpha_values.end()) + ++the_alpha_value_iterator; + else + std::cout << "This shall not happen" << std::endl; + } + simplex_tree.set_filtration(filtration_max); + simplex_tree.set_dimension(dim_max); +#ifdef DEBUG_TRACES + std::cout << "vertices \t\t" << count_vertices << std::endl; + std::cout << "edges \t\t" << count_edges << std::endl; + std::cout << "facets \t\t" << count_facets << std::endl; + std::cout << "cells \t\t" << count_cells << std::endl; - std::cout << "Information of the Simplex Tree: " << std::endl; - std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; - std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; - std::cout << " Dimension = " << simplex_tree.dimension() << " "; - std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; - #endif // DEBUG_TRACES + std::cout << "Information of the Simplex Tree: " << std::endl; + std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; + std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; + std::cout << " Dimension = " << simplex_tree.dimension() << " "; + std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; +#endif // DEBUG_TRACES - #ifdef DEBUG_TRACES - std::cout << "Iterator on vertices: " << std::endl; - for (auto vertex : simplex_tree.complex_vertex_range()) { - std::cout << vertex << " "; - } - #endif // DEBUG_TRACES +#ifdef DEBUG_TRACES + std::cout << "Iterator on vertices: " << std::endl; + for (auto vertex : simplex_tree.complex_vertex_range()) { + std::cout << vertex << " "; + } +#endif // DEBUG_TRACES - // Sort the simplices in the order of the filtration - simplex_tree.initialize_filtration(); + // Sort the simplices in the order of the filtration + simplex_tree.initialize_filtration(); - std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; - // Compute the persistence diagram of the complex - Persistent_cohomology pcoh(simplex_tree, true); - // initializes the coefficient field for homology - pcoh.init_coefficients(coeff_field_characteristic); + std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(simplex_tree, true); + // initializes the coefficient field for homology + pcoh.init_coefficients(coeff_field_characteristic); - pcoh.compute_persistent_cohomology(min_persistence); + pcoh.compute_persistent_cohomology(min_persistence); - pcoh.output_diagram(); + pcoh.output_diagram(); return 0; } diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp new file mode 100644 index 00000000..e2c48755 --- /dev/null +++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp @@ -0,0 +1,262 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2014 INRIA + * + * 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 . + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alpha_complex_3d_helper.h" + +// Traits +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Gt = CGAL::Regular_triangulation_euclidean_traits_3; +using Vb = CGAL::Alpha_shape_vertex_base_3; +using Fb = CGAL::Alpha_shape_cell_base_3; +using Tds = CGAL::Triangulation_data_structure_3; +using Triangulation_3 = CGAL::Regular_triangulation_3; +using Alpha_shape_3 = CGAL::Alpha_shape_3; + +// From file type definition +using Point_3 = Gt::Bare_point; +using Weighted_point_3 = Gt::Weighted_point; + +// filtration with alpha values needed type definition +using Alpha_value_type = Alpha_shape_3::FT; +using Object = CGAL::Object; +using Dispatch = + CGAL::Dispatch_output_iterator, + CGAL::cpp11::tuple >, + std::back_insert_iterator > > >; +using Cell_handle = Alpha_shape_3::Cell_handle; +using Facet = Alpha_shape_3::Facet; +using Edge_3 = Alpha_shape_3::Edge; +using Vertex_handle = Alpha_shape_3::Vertex_handle; +using Vertex_list = std::list; + +// gudhi type definition +using ST = Gudhi::Simplex_tree; +using Filtration_value = ST::Filtration_value; +using Simplex_tree_vertex = ST::Vertex_handle; +using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_pair = std::pair; +using Simplex_tree_vector_vertex = std::vector; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology; + +void usage(char* const progName) { + std::cerr << "Usage: " << progName << " path_to_file_graph path_to_weight_file coeff_field_characteristic[integer > " + "0] min_persistence[float >= -1.0]\n"; + exit(-1); +} + +int main(int argc, char* const argv[]) { + // program args management + if (argc != 5) { + std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; + usage(argv[0]); + } + + int coeff_field_characteristic = atoi(argv[3]); + Filtration_value min_persistence = strtof(argv[4], nullptr); + + // Read points from file + std::string offInputFile(argv[1]); + // Read the OFF file (input file name given as parameter) and triangulate points + Gudhi::Points_3D_off_reader off_reader(offInputFile); + // Check the read operation was correct + if (!off_reader.is_valid()) { + std::cerr << "Unable to read file " << offInputFile << std::endl; + usage(argv[0]); + } + + // Retrieve the triangulation + std::vector lp = off_reader.get_point_cloud(); + + // Read weights information from file + std::ifstream weights_ifstr(argv[2]); + std::vector wp; + if (weights_ifstr.good()) { + double weight = 0.0; + std::size_t index = 0; + wp.reserve(lp.size()); + // Attempt read the weight in a double format, return false if it fails + while ((weights_ifstr >> weight) && (index < lp.size())) { + wp.push_back(Weighted_point_3(lp[index], weight)); + index++; + } + if (index != lp.size()) { + std::cerr << "Bad number of weights in file " << argv[2] << std::endl; + usage(argv[0]); + } + } else { + std::cerr << "Unable to read file " << argv[2] << std::endl; + usage(argv[0]); + } + + // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. + Alpha_shape_3 as(wp.begin(), wp.end(), 0, Alpha_shape_3::GENERAL); +#ifdef DEBUG_TRACES + std::cout << "Alpha shape computed in GENERAL mode" << std::endl; +#endif // DEBUG_TRACES + + // filtration with alpha values from alpha shape + std::vector the_objects; + std::vector the_alpha_values; + + Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), + std::back_inserter(the_alpha_values)); + + as.filtration_with_alpha_values(disp); +#ifdef DEBUG_TRACES + std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; +#endif // DEBUG_TRACES + + Alpha_shape_3::size_type count_vertices = 0; + Alpha_shape_3::size_type count_edges = 0; + Alpha_shape_3::size_type count_facets = 0; + Alpha_shape_3::size_type count_cells = 0; + + // Loop on objects vector + Vertex_list vertex_list; + ST simplex_tree; + Alpha_shape_simplex_tree_map map_cgal_simplex_tree; + std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); + int dim_max = 0; + Filtration_value filtration_max = 0.0; + for (auto object_iterator : the_objects) { + // Retrieve Alpha shape vertex list from object + if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { + vertex_list = from_cell(*cell); + count_cells++; + if (dim_max < 3) { + // Cell is of dim 3 + dim_max = 3; + } + } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { + vertex_list = from_facet(*facet); + count_facets++; + if (dim_max < 2) { + // Facet is of dim 2 + dim_max = 2; + } + } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { + vertex_list = from_edge(*edge); + count_edges++; + if (dim_max < 1) { + // Edge_3 is of dim 1 + dim_max = 1; + } + } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { + count_vertices++; + vertex_list = from_vertex(*vertex); + } + // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex + Simplex_tree_vector_vertex the_simplex_tree; + for (auto the_alpha_shape_vertex : vertex_list) { + Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); + if (the_map_iterator == map_cgal_simplex_tree.end()) { + // alpha shape not found + Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); + } else { + // alpha shape found + Simplex_tree_vertex vertex = the_map_iterator->second; +#ifdef DEBUG_TRACES + std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; +#endif // DEBUG_TRACES + the_simplex_tree.push_back(vertex); + } + } + // Construction of the simplex_tree + Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); +#ifdef DEBUG_TRACES + std::cout << "filtration = " << filtr << std::endl; +#endif // DEBUG_TRACES + if (filtr > filtration_max) { + filtration_max = filtr; + } + simplex_tree.insert_simplex(the_simplex_tree, filtr); + if (the_alpha_value_iterator != the_alpha_values.end()) + ++the_alpha_value_iterator; + else + std::cout << "This shall not happen" << std::endl; + } + simplex_tree.set_filtration(filtration_max); + simplex_tree.set_dimension(dim_max); + +#ifdef DEBUG_TRACES + std::cout << "vertices \t\t" << count_vertices << std::endl; + std::cout << "edges \t\t" << count_edges << std::endl; + std::cout << "facets \t\t" << count_facets << std::endl; + std::cout << "cells \t\t" << count_cells << std::endl; + + std::cout << "Information of the Simplex Tree: " << std::endl; + std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; + std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; + std::cout << " Dimension = " << simplex_tree.dimension() << " "; + std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; +#endif // DEBUG_TRACES + +#ifdef DEBUG_TRACES + std::cout << "Iterator on vertices: " << std::endl; + for (auto vertex : simplex_tree.complex_vertex_range()) { + std::cout << vertex << " "; + } +#endif // DEBUG_TRACES + + // Sort the simplices in the order of the filtration + simplex_tree.initialize_filtration(); + + std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(simplex_tree, true); + // initializes the coefficient field for homology + pcoh.init_coefficients(coeff_field_characteristic); + + pcoh.compute_persistent_cohomology(min_persistence); + + pcoh.output_diagram(); + + return 0; +} diff --git a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp index 70c0572d..14f12c0e 100644 --- a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp @@ -27,13 +27,11 @@ #include #include -#include -#include +#include +#include #include #include -#include - #include #include #include @@ -45,87 +43,33 @@ #include #include "alpha_complex_3d_helper.h" -/* -// Traits -using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using PK = CGAL::Periodic_3_Delaunay_triangulation_traits_3; - -using Vb = CGAL::Alpha_shape_vertex_base_3; -using Fb = CGAL::Alpha_shape_cell_base_3; -using Tds = CGAL::Triangulation_data_structure_3; -//using Triangulation_3 = CGAL::Regular_triangulation_3; -using Alpha_shape_3 = CGAL::Alpha_shape_3; - -//vertex type -using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>; -using Vb = CGAL::Triangulation_vertex_base_3; -using AsVb = CGAL::Alpha_shape_vertex_base_3; - -// Cell type -using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>; -using Cb = CGAL::Triangulation_cell_base_3; -using P3DT3 = CGAL::Periodic_3_Delaunay_triangulation_3; -using Point_3 = PK::Point_3; - -// From file type definition -using Point_3 = Gt::Bare_point; -using Weighted_point_3 = Gt::Weighted_point; -// filtration with alpha values needed type definition -using Alpha_value_type = Alpha_shape_3::FT; -using Object = CGAL::Object; -using Dispatch = CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple >, - std::back_insert_iterator< std::vector > > >; -using Cell_handle = Alpha_shape_3::Cell_handle; -using Facet = Alpha_shape_3::Facet; -using Edge_3 = Alpha_shape_3::Edge; -using Vertex_handle = Alpha_shape_3::Vertex_handle; -using Vertex_list = std::list; - -// gudhi type definition -using ST = Gudhi::Simplex_tree; -using Filtration_value = ST::Filtration_value; -using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; -using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; -using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< - ST, Gudhi::persistent_cohomology::Field_Zp >; - */ - - - // Traits using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using K = CGAL::Exact_predicates_inexact_constructions_kernel; -using PK = CGAL::Periodic_3_Delaunay_triangulation_traits_3; -using Gt = CGAL::Regular_triangulation_euclidean_traits_3; +using PK = CGAL::Periodic_3_regular_triangulation_traits_3; + // Vertex type using DsVb = CGAL::Periodic_3_triangulation_ds_vertex_base_3<>; -using Vb = CGAL::Triangulation_vertex_base_3; -using AsVb = CGAL::Alpha_shape_vertex_base_3; +using Vb = CGAL::Regular_triangulation_vertex_base_3; +using AsVb = CGAL::Alpha_shape_vertex_base_3; // Cell type using DsCb = CGAL::Periodic_3_triangulation_ds_cell_base_3<>; -using Cb = CGAL::Triangulation_cell_base_3; -using AsCb = CGAL::Alpha_shape_cell_base_3; -using Tds = CGAL::Triangulation_data_structure_3; -using P3DT3 = CGAL::Periodic_3_Delaunay_triangulation_3; -using Alpha_shape_3 = CGAL::Alpha_shape_3; -using Point_3 = CGAL::Periodic_3_Delaunay_triangulation_traits_3::Point_3; +using Cb = CGAL::Regular_triangulation_cell_base_3; +using AsCb = CGAL::Alpha_shape_cell_base_3; +using Tds = CGAL::Triangulation_data_structure_3; +using P3RT3 = CGAL::Periodic_3_regular_triangulation_3; +using Alpha_shape_3 = CGAL::Alpha_shape_3; -// From file type definition -using Point_3 = Gt::Bare_point; -using Weighted_point_3 = Gt::Weighted_point; +using Point_3 = P3RT3::Bare_point; +using Weighted_point_3 = P3RT3::Weighted_point; // filtration with alpha values needed type definition using Alpha_value_type = Alpha_shape_3::FT; using Object = CGAL::Object; -using Dispatch = CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple >, - std::back_insert_iterator< std::vector > > >; +using Dispatch = + CGAL::Dispatch_output_iterator, + CGAL::cpp11::tuple >, + std::back_insert_iterator > > >; using Cell_handle = Alpha_shape_3::Cell_handle; using Facet = Alpha_shape_3::Facet; using Edge_3 = Alpha_shape_3::Edge; @@ -136,24 +80,23 @@ using Vertex_list = std::list; using ST = Gudhi::Simplex_tree; using Filtration_value = ST::Filtration_value; using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_map = std::map; using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; -using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology< - ST, Gudhi::persistent_cohomology::Field_Zp >; - - -void usage(char * const progName) { - std::cerr << "Usage: " << progName << - " path_to_the_OFF_File path_to_weight_file path_to_the_cuboid_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; +using Simplex_tree_vector_vertex = std::vector; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology; + +void usage(char* const progName) { + std::cerr << "Usage: " << progName << " path_to_the_OFF_File path_to_weight_file path_to_the_cuboid_file " + "coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); -} - -int main(int argc, char * const argv[]) { +} + +int main(int argc, char* const argv[]) { // program args management if (argc != 6) { std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; - //file with points, file with weights, cuboid file, field characteristics, minimum persistence. + // file with points, file with weights, cuboid file, field characteristics, minimum persistence. usage(argv[0]); } @@ -169,10 +112,10 @@ int main(int argc, char * const argv[]) { std::cerr << "Unable to read file " << offInputFile << std::endl; usage(argv[0]); } - + // Retrieve the triangulation std::vector lp = off_reader.get_point_cloud(); - + // Read weights information from file std::ifstream weights_ifstr(argv[2]); std::vector wp; @@ -182,7 +125,7 @@ int main(int argc, char * const argv[]) { wp.reserve(lp.size()); // Attempt read the weight in a double format, return false if it fails while ((weights_ifstr >> weight) && (index < lp.size())) { - wp.push_back(Weighted_point_3(lp[index], weight)); + wp.push_back(Weighted_point_3(lp[index], weight)); index++; } if (index != lp.size()) { @@ -193,7 +136,7 @@ int main(int argc, char * const argv[]) { std::cerr << "Unable to read file " << argv[2] << std::endl; usage(argv[0]); } - + // Read iso_cuboid_3 information from file std::ifstream iso_cuboid_str(argv[3]); double x_min, y_min, z_min, x_max, y_max, z_max; @@ -203,164 +146,21 @@ int main(int argc, char * const argv[]) { std::cerr << "Unable to read file " << argv[3] << std::endl; usage(argv[0]); } - + std::cout << "wp.size() : " << wp.size() << std::endl; // Define the periodic cube - P3DT3 pdt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max)); + P3RT3 prt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max)); // Heuristic for inserting large point sets (if pts is reasonably large) - pdt.insert(wp.begin(), wp.end(), true); - // As pdt won't be modified anymore switch to 1-sheeted cover if possible - if (pdt.is_triangulation_in_1_sheet()) pdt.convert_to_1_sheeted_covering(); + prt.insert(wp.begin(), wp.end(), true); + // As prt won't be modified anymore switch to 1-sheeted cover if possible + if (prt.is_triangulation_in_1_sheet()) prt.convert_to_1_sheeted_covering(); std::cout << "Periodic Delaunay computed." << std::endl; // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. This is the default mode // Maybe need to set it to GENERAL mode - Alpha_shape_3 as(pdt, 0, Alpha_shape_3::GENERAL); - - - - - - - - - - - // filtration with alpha values from alpha shape - std::vector the_objects; - std::vector the_alpha_values; - - Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), - std::back_inserter(the_alpha_values)); - - as.filtration_with_alpha_values(disp); -#ifdef DEBUG_TRACES - std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; -#endif // DEBUG_TRACES - - Alpha_shape_3::size_type count_vertices = 0; - Alpha_shape_3::size_type count_edges = 0; - Alpha_shape_3::size_type count_facets = 0; - Alpha_shape_3::size_type count_cells = 0; - - // Loop on objects vector - Vertex_list vertex_list; - ST simplex_tree; - Alpha_shape_simplex_tree_map map_cgal_simplex_tree; - std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); - int dim_max = 0; - Filtration_value filtration_max = 0.0; - for (auto object_iterator : the_objects) { - // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { - vertex_list = from_cell(*cell); - count_cells++; - if (dim_max < 3) { - // Cell is of dim 3 - dim_max = 3; - } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { - vertex_list = from_facet(*facet); - count_facets++; - if (dim_max < 2) { - // Facet is of dim 2 - dim_max = 2; - } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { - vertex_list = from_edge(*edge); - count_edges++; - if (dim_max < 1) { - // Edge_3 is of dim 1 - dim_max = 1; - } - } else if (const Alpha_shape_3::Vertex_handle * vertex = - CGAL::object_cast(&object_iterator)) { - count_vertices++; - vertex_list = from_vertex(*vertex); - } - // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex - Simplex_tree_vector_vertex the_simplex_tree; - for (auto the_alpha_shape_vertex : vertex_list) { - Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); - if (the_map_iterator == map_cgal_simplex_tree.end()) { - // alpha shape not found - Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); -#ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; -#endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); - } else { - // alpha shape found - Simplex_tree_vertex vertex = the_map_iterator->second; -#ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; -#endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - } - } - // Construction of the simplex_tree - Filtration_value filtr = /*std::sqrt*/(*the_alpha_value_iterator); -#ifdef DEBUG_TRACES - std::cout << "filtration = " << filtr << std::endl; -#endif // DEBUG_TRACES - if (filtr > filtration_max) { - filtration_max = filtr; - } - simplex_tree.insert_simplex(the_simplex_tree, filtr); - if (the_alpha_value_iterator != the_alpha_values.end()) - ++the_alpha_value_iterator; - else - std::cout << "This shall not happen" << std::endl; - } - simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); + Alpha_shape_3 as(prt, 0, Alpha_shape_3::GENERAL); -#ifdef DEBUG_TRACES - std::cout << "vertices \t\t" << count_vertices << std::endl; - std::cout << "edges \t\t" << count_edges << std::endl; - std::cout << "facets \t\t" << count_facets << std::endl; - std::cout << "cells \t\t" << count_cells << std::endl; - - - std::cout << "Information of the Simplex Tree: " << std::endl; - std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; - std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; - std::cout << " Dimension = " << simplex_tree.dimension() << " "; - std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; -#endif // DEBUG_TRACES - -#ifdef DEBUG_TRACES - std::cout << "Iterator on vertices: " << std::endl; - for (auto vertex : simplex_tree.complex_vertex_range()) { - std::cout << vertex << " "; - } -#endif // DEBUG_TRACES - - // Sort the simplices in the order of the filtration - simplex_tree.initialize_filtration(); - - std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; - // Compute the persistence diagram of the complex - Persistent_cohomology pcoh(simplex_tree, true); - // initializes the coefficient field for homology - pcoh.init_coefficients(coeff_field_characteristic); - - pcoh.compute_persistent_cohomology(min_persistence); - - pcoh.output_diagram(); - - - - - - - - - - -/* // filtration with alpha values from alpha shape std::vector the_objects; std::vector the_alpha_values; @@ -387,29 +187,29 @@ int main(int argc, char * const argv[]) { Filtration_value filtration_max = 0.0; for (auto object_iterator : the_objects) { // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { vertex_list = from_cell(*cell); count_cells++; if (dim_max < 3) { // Cell is of dim 3 dim_max = 3; } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { vertex_list = from_facet(*facet); count_facets++; if (dim_max < 2) { // Facet is of dim 2 dim_max = 2; } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { vertex_list = from_edge(*edge); count_edges++; if (dim_max < 1) { // Edge_3 is of dim 1 dim_max = 1; } - } else if (const Alpha_shape_3::Vertex_handle * vertex = - CGAL::object_cast(&object_iterator)) { + } else if (const Alpha_shape_3::Vertex_handle* vertex = + CGAL::object_cast(&object_iterator)) { count_vertices++; vertex_list = from_vertex(*vertex); } @@ -435,7 +235,7 @@ int main(int argc, char * const argv[]) { } } // Construction of the simplex_tree - Filtration_value filtr = (*the_alpha_value_iterator); + Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); #ifdef DEBUG_TRACES std::cout << "filtration = " << filtr << std::endl; #endif // DEBUG_TRACES @@ -457,7 +257,6 @@ int main(int argc, char * const argv[]) { std::cout << "facets \t\t" << count_facets << std::endl; std::cout << "cells \t\t" << count_cells << std::endl; - std::cout << "Information of the Simplex Tree: " << std::endl; std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; @@ -484,7 +283,6 @@ int main(int argc, char * const argv[]) { pcoh.compute_persistent_cohomology(min_persistence); pcoh.output_diagram(); - */ return 0; } -- cgit v1.2.3 From 8a3c2975bab46014e9c89837ee5d39cb68473350 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 2 Oct 2017 20:12:44 +0000 Subject: Fix weighted periodic git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2746 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: bf90bfffbc00efe5f391e45ac8ece6ff6e9d57ea --- data/points/grid_10_10_10_in_0_2.weights | 251 ++++++++++----------- src/Persistent_cohomology/example/CMakeLists.txt | 7 + ...ghted_periodic_alpha_complex_3d_persistence.cpp | 4 +- 3 files changed, 134 insertions(+), 128 deletions(-) diff --git a/data/points/grid_10_10_10_in_0_2.weights b/data/points/grid_10_10_10_in_0_2.weights index 3672ecfd..fea8f879 100644 --- a/data/points/grid_10_10_10_in_0_2.weights +++ b/data/points/grid_10_10_10_in_0_2.weights @@ -1,126 +1,125 @@ -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 - +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index f6c866dc..5f711961 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -123,6 +123,13 @@ if(CGAL_FOUND) install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) + add_executable(test_cgal test_cgal.cpp) + target_link_libraries(test_cgal ${CGAL_LIBRARY}) + if (TBB_FOUND) + target_link_libraries(test_cgal ${TBB_LIBRARIES}) + endif(TBB_FOUND) + + # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the new interface add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) else(NOT CGAL_VERSION VERSION_LESS 4.11.0) diff --git a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp index 14f12c0e..2ecb3f24 100644 --- a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp @@ -147,12 +147,12 @@ int main(int argc, char* const argv[]) { usage(argv[0]); } - std::cout << "wp.size() : " << wp.size() << std::endl; - // Define the periodic cube P3RT3 prt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max)); + std::cout << "1 " << std::endl; // Heuristic for inserting large point sets (if pts is reasonably large) prt.insert(wp.begin(), wp.end(), true); + std::cout << "2 " << std::endl; // As prt won't be modified anymore switch to 1-sheeted cover if possible if (prt.is_triangulation_in_1_sheet()) prt.convert_to_1_sheeted_covering(); std::cout << "Periodic Delaunay computed." << std::endl; -- cgit v1.2.3 From eda3bbcf1d3701a8798dc0bda54708e9dc78d03e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 2 Oct 2017 20:13:48 +0000 Subject: remove test_cgal git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2747 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9b036eb3ccef79e012eacb045a0dda37db1de994 --- src/Persistent_cohomology/example/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index 5f711961..f6c866dc 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -123,13 +123,6 @@ if(CGAL_FOUND) install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) - add_executable(test_cgal test_cgal.cpp) - target_link_libraries(test_cgal ${CGAL_LIBRARY}) - if (TBB_FOUND) - target_link_libraries(test_cgal ${TBB_LIBRARIES}) - endif(TBB_FOUND) - - # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the new interface add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) else(NOT CGAL_VERSION VERSION_LESS 4.11.0) -- cgit v1.2.3 From f1e2834261bae80eb216bcd9317538e5de4375a9 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 2 Oct 2017 20:38:02 +0000 Subject: Fix weighted periodic alpa complex 3d example test git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2748 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ddf754a1f8046c7b17db89668cf8d4dd95f69dac --- data/points/grid_10_10_10_in_0_1.weights | 1000 ++++++++++++++++++++ src/Persistent_cohomology/example/CMakeLists.txt | 6 +- ...ghted_periodic_alpha_complex_3d_persistence.cpp | 2 - 3 files changed, 1005 insertions(+), 3 deletions(-) create mode 100644 data/points/grid_10_10_10_in_0_1.weights diff --git a/data/points/grid_10_10_10_in_0_1.weights b/data/points/grid_10_10_10_in_0_1.weights new file mode 100644 index 00000000..48926e09 --- /dev/null +++ b/data/points/grid_10_10_10_in_0_1.weights @@ -0,0 +1,1000 @@ +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 +1e-6 diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index f6c866dc..be23de35 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -105,7 +105,7 @@ if(CGAL_FOUND) add_test(NAME Persistent_cohomology_example_alpha_complex COMMAND $ "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "-p" "2" "-m" "0.45") add_test(NAME Persistent_cohomology_example_periodic_alpha_complex_3d COMMAND $ - "${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off" "${CMAKE_SOURCE_DIR}/data/points/iso_cuboid_3_in_0_1.txt" "2" "0") + "${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off" "${CMAKE_SOURCE_DIR}/data/points/iso_cuboid_3_in_0_1.txt" "3" "1.0") add_test(NAME Persistent_cohomology_example_custom_persistence_sort COMMAND $) install(TARGETS alpha_complex_persistence DESTINATION bin) @@ -121,6 +121,10 @@ if(CGAL_FOUND) target_link_libraries(weighted_periodic_alpha_complex_3d_persistence ${TBB_LIBRARIES}) endif(TBB_FOUND) + add_test(NAME Persistent_cohomology_example_weigted_periodic_alpha_complex_3d COMMAND $ + "${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.off" "${CMAKE_SOURCE_DIR}/data/points/grid_10_10_10_in_0_1.weights" + "${CMAKE_SOURCE_DIR}/data/points/iso_cuboid_3_in_0_1.txt" "3" "1.0") + install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the new interface diff --git a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp index 2ecb3f24..ab2e29b4 100644 --- a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp @@ -149,10 +149,8 @@ int main(int argc, char* const argv[]) { // Define the periodic cube P3RT3 prt(PK::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max)); - std::cout << "1 " << std::endl; // Heuristic for inserting large point sets (if pts is reasonably large) prt.insert(wp.begin(), wp.end(), true); - std::cout << "2 " << std::endl; // As prt won't be modified anymore switch to 1-sheeted cover if possible if (prt.is_triangulation_in_1_sheet()) prt.convert_to_1_sheeted_covering(); std::cout << "Periodic Delaunay computed." << std::endl; -- cgit v1.2.3 From b9d4c8c0073fbd8c0b0bf999ae6ee7d3de60501d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 5 Oct 2017 17:16:48 +0000 Subject: Doc review : fix find_child explanation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/graph_expansion_with_blocker_oracle@2758 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 30759214110b29a525cbbf2d97ff84b92b4eace2 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index fe1e87b4..a8c01f84 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1177,7 +1177,7 @@ class Simplex_tree { } /* \private Returns the Simplex_handle composed of the vertex list (from the Simplex_handle), plus the given - * Vertex_handle. + * Vertex_handle if the Vertex_handle is found in the Simplex_handle children list. * Returns null_simplex() if it does not exist */ Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) const { -- cgit v1.2.3 From f0cd234b570b0d48c7b5e83af9ce5925eeb40961 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 5 Oct 2017 17:59:50 +0000 Subject: Doc review : prune_above_filtration about automatic_dimension_set mechanism was too strict. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2760 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: bccef80ba3f70f87dff28cfa3a85c50f072f695e --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index fd6cd72a..6494aa5d 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1161,8 +1161,9 @@ class Simplex_tree { * \post Some simplex tree functions require the filtration to be valid. `prune_above_filtration()` * function is not launching `initialize_filtration()` but returns the filtration modification information. If the * complex has changed , please call `initialize_filtration()` to recompute it. - * \post Be aware that `prune_above_filtration()` may change the simplex tree dimension (`automatic_dimension_set()` - * to be done). + * \post Note that the dimension of the simplicial complex may be lower after calling `prune_above_filtration()` + * than it was before. However, `Simplex_tree::dimension()` will return the old value, which remains a valid upper + * bound. If you care, you can call `automatic_dimension_set()` to recompute the exact dimension. */ bool prune_above_filtration(Filtration_value filtration) { return rec_prune_above_filtration(root(), filtration); -- cgit v1.2.3 From 479bcccbaede8aa59ae28c8cd9b15de08053a817 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 5 Oct 2017 18:03:24 +0000 Subject: Doc review : automatic_dimension_set return documentation was not clear git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2761 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 04b4dee9d228923f36062001529476251eac4ef0 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 6494aa5d..8a827086 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1196,7 +1196,7 @@ class Simplex_tree { public: /** \brief Deep search simplex tree dimension reset. - * @return The dimension modification information. + * @return True if the dimension was modified, false otherwise. * \pre Be sure the simplex tree has not a too low dimension value as the deep search stops when the former dimension * has been reached (cf. `dimension()` and `set_dimension()` methods). */ -- cgit v1.2.3 From fb7c3e76da15aca382ed7a6795d1a6fb3c1716c2 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 10 Oct 2017 12:52:35 +0000 Subject: Fix CGAL 4.11 bug and remove old_interface file. Better done with #if git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2774 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9a905b04cfa2718f9d5abc80e14ab1ee26d16279 --- src/Persistent_cohomology/example/CMakeLists.txt | 8 +- .../weighted_alpha_complex_3d_persistence.cpp | 25 +- ...a_complex_3d_persistence_old_cgal_interface.cpp | 262 --------------------- 3 files changed, 25 insertions(+), 270 deletions(-) delete mode 100644 src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index be23de35..e82ef04c 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -127,15 +127,9 @@ if(CGAL_FOUND) install(TARGETS weighted_periodic_alpha_complex_3d_persistence DESTINATION bin) - # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the new interface - add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) - else(NOT CGAL_VERSION VERSION_LESS 4.11.0) - # On CGAL 4.11, the weighted alpha shape 3 interface was changed - the old interface - add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp) endif (NOT CGAL_VERSION VERSION_LESS 4.11.0) - # cf. if (NOT CGAL_VERSION VERSION_LESS 4.11.0) and else(NOT CGAL_VERSION VERSION_LESS 4.11.0) - # same target name on purpose + add_executable(weighted_alpha_complex_3d_persistence weighted_alpha_complex_3d_persistence.cpp) target_link_libraries(weighted_alpha_complex_3d_persistence ${CGAL_LIBRARY}) if (TBB_FOUND) target_link_libraries(weighted_alpha_complex_3d_persistence ${TBB_LIBRARIES}) diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp index 92fed4c1..85b0ab34 100644 --- a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp @@ -26,11 +26,17 @@ #include #include +#include #include #include #include #include +// For CGAL < 4.11 +#if CGAL_VERSION_NR < 1041100000 +#include +#endif // CGAL_VERSION_NR < 1041100000 + #include #include #include @@ -44,17 +50,34 @@ #include "alpha_complex_3d_helper.h" using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; + +// For CGAL < 4.11 +#if CGAL_VERSION_NR < 1041100000 +using Gt = CGAL::Regular_triangulation_euclidean_traits_3; +using Vb = CGAL::Alpha_shape_vertex_base_3; +using Fb = CGAL::Alpha_shape_cell_base_3; +using Tds = CGAL::Triangulation_data_structure_3; +using Triangulation_3 = CGAL::Regular_triangulation_3; + +// From file type definition +using Point_3 = Gt::Bare_point; +using Weighted_point_3 = Gt::Weighted_point; + +// For CGAL >= 4.11 +#else // CGAL_VERSION_NR < 1041100000 using Rvb = CGAL::Regular_triangulation_vertex_base_3; using Vb = CGAL::Alpha_shape_vertex_base_3; using Rcb = CGAL::Regular_triangulation_cell_base_3; using Cb = CGAL::Alpha_shape_cell_base_3; using Tds = CGAL::Triangulation_data_structure_3; using Triangulation_3 = CGAL::Regular_triangulation_3; -using Alpha_shape_3 = CGAL::Alpha_shape_3; // From file type definition using Point_3 = Triangulation_3::Bare_point; using Weighted_point_3 = Triangulation_3::Weighted_point; +#endif // CGAL_VERSION_NR < 1041100000 + +using Alpha_shape_3 = CGAL::Alpha_shape_3; // filtration with alpha values needed type definition using Alpha_value_type = Alpha_shape_3::FT; diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp deleted file mode 100644 index e2c48755..00000000 --- a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence_old_cgal_interface.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Vincent Rouvreau - * - * Copyright (C) 2014 INRIA - * - * 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 . - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alpha_complex_3d_helper.h" - -// Traits -using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using Gt = CGAL::Regular_triangulation_euclidean_traits_3; -using Vb = CGAL::Alpha_shape_vertex_base_3; -using Fb = CGAL::Alpha_shape_cell_base_3; -using Tds = CGAL::Triangulation_data_structure_3; -using Triangulation_3 = CGAL::Regular_triangulation_3; -using Alpha_shape_3 = CGAL::Alpha_shape_3; - -// From file type definition -using Point_3 = Gt::Bare_point; -using Weighted_point_3 = Gt::Weighted_point; - -// filtration with alpha values needed type definition -using Alpha_value_type = Alpha_shape_3::FT; -using Object = CGAL::Object; -using Dispatch = - CGAL::Dispatch_output_iterator, - CGAL::cpp11::tuple >, - std::back_insert_iterator > > >; -using Cell_handle = Alpha_shape_3::Cell_handle; -using Facet = Alpha_shape_3::Facet; -using Edge_3 = Alpha_shape_3::Edge; -using Vertex_handle = Alpha_shape_3::Vertex_handle; -using Vertex_list = std::list; - -// gudhi type definition -using ST = Gudhi::Simplex_tree; -using Filtration_value = ST::Filtration_value; -using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; -using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector; -using Persistent_cohomology = - Gudhi::persistent_cohomology::Persistent_cohomology; - -void usage(char* const progName) { - std::cerr << "Usage: " << progName << " path_to_file_graph path_to_weight_file coeff_field_characteristic[integer > " - "0] min_persistence[float >= -1.0]\n"; - exit(-1); -} - -int main(int argc, char* const argv[]) { - // program args management - if (argc != 5) { - std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; - usage(argv[0]); - } - - int coeff_field_characteristic = atoi(argv[3]); - Filtration_value min_persistence = strtof(argv[4], nullptr); - - // Read points from file - std::string offInputFile(argv[1]); - // Read the OFF file (input file name given as parameter) and triangulate points - Gudhi::Points_3D_off_reader off_reader(offInputFile); - // Check the read operation was correct - if (!off_reader.is_valid()) { - std::cerr << "Unable to read file " << offInputFile << std::endl; - usage(argv[0]); - } - - // Retrieve the triangulation - std::vector lp = off_reader.get_point_cloud(); - - // Read weights information from file - std::ifstream weights_ifstr(argv[2]); - std::vector wp; - if (weights_ifstr.good()) { - double weight = 0.0; - std::size_t index = 0; - wp.reserve(lp.size()); - // Attempt read the weight in a double format, return false if it fails - while ((weights_ifstr >> weight) && (index < lp.size())) { - wp.push_back(Weighted_point_3(lp[index], weight)); - index++; - } - if (index != lp.size()) { - std::cerr << "Bad number of weights in file " << argv[2] << std::endl; - usage(argv[0]); - } - } else { - std::cerr << "Unable to read file " << argv[2] << std::endl; - usage(argv[0]); - } - - // alpha shape construction from points. CGAL has a strange behavior in REGULARIZED mode. - Alpha_shape_3 as(wp.begin(), wp.end(), 0, Alpha_shape_3::GENERAL); -#ifdef DEBUG_TRACES - std::cout << "Alpha shape computed in GENERAL mode" << std::endl; -#endif // DEBUG_TRACES - - // filtration with alpha values from alpha shape - std::vector the_objects; - std::vector the_alpha_values; - - Dispatch disp = CGAL::dispatch_output(std::back_inserter(the_objects), - std::back_inserter(the_alpha_values)); - - as.filtration_with_alpha_values(disp); -#ifdef DEBUG_TRACES - std::cout << "filtration_with_alpha_values returns : " << the_objects.size() << " objects" << std::endl; -#endif // DEBUG_TRACES - - Alpha_shape_3::size_type count_vertices = 0; - Alpha_shape_3::size_type count_edges = 0; - Alpha_shape_3::size_type count_facets = 0; - Alpha_shape_3::size_type count_cells = 0; - - // Loop on objects vector - Vertex_list vertex_list; - ST simplex_tree; - Alpha_shape_simplex_tree_map map_cgal_simplex_tree; - std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); - int dim_max = 0; - Filtration_value filtration_max = 0.0; - for (auto object_iterator : the_objects) { - // Retrieve Alpha shape vertex list from object - if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { - vertex_list = from_cell(*cell); - count_cells++; - if (dim_max < 3) { - // Cell is of dim 3 - dim_max = 3; - } - } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { - vertex_list = from_facet(*facet); - count_facets++; - if (dim_max < 2) { - // Facet is of dim 2 - dim_max = 2; - } - } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { - vertex_list = from_edge(*edge); - count_edges++; - if (dim_max < 1) { - // Edge_3 is of dim 1 - dim_max = 1; - } - } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { - count_vertices++; - vertex_list = from_vertex(*vertex); - } - // Construction of the vector of simplex_tree vertex from list of alpha_shapes vertex - Simplex_tree_vector_vertex the_simplex_tree; - for (auto the_alpha_shape_vertex : vertex_list) { - Alpha_shape_simplex_tree_map::iterator the_map_iterator = map_cgal_simplex_tree.find(the_alpha_shape_vertex); - if (the_map_iterator == map_cgal_simplex_tree.end()) { - // alpha shape not found - Simplex_tree_vertex vertex = map_cgal_simplex_tree.size(); -#ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] not found - insert " << vertex << std::endl; -#endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - map_cgal_simplex_tree.insert(Alpha_shape_simplex_tree_pair(the_alpha_shape_vertex, vertex)); - } else { - // alpha shape found - Simplex_tree_vertex vertex = the_map_iterator->second; -#ifdef DEBUG_TRACES - std::cout << "vertex [" << the_alpha_shape_vertex->point() << "] found in " << vertex << std::endl; -#endif // DEBUG_TRACES - the_simplex_tree.push_back(vertex); - } - } - // Construction of the simplex_tree - Filtration_value filtr = /*std::sqrt*/ (*the_alpha_value_iterator); -#ifdef DEBUG_TRACES - std::cout << "filtration = " << filtr << std::endl; -#endif // DEBUG_TRACES - if (filtr > filtration_max) { - filtration_max = filtr; - } - simplex_tree.insert_simplex(the_simplex_tree, filtr); - if (the_alpha_value_iterator != the_alpha_values.end()) - ++the_alpha_value_iterator; - else - std::cout << "This shall not happen" << std::endl; - } - simplex_tree.set_filtration(filtration_max); - simplex_tree.set_dimension(dim_max); - -#ifdef DEBUG_TRACES - std::cout << "vertices \t\t" << count_vertices << std::endl; - std::cout << "edges \t\t" << count_edges << std::endl; - std::cout << "facets \t\t" << count_facets << std::endl; - std::cout << "cells \t\t" << count_cells << std::endl; - - std::cout << "Information of the Simplex Tree: " << std::endl; - std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; - std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; - std::cout << " Dimension = " << simplex_tree.dimension() << " "; - std::cout << " filtration = " << simplex_tree.filtration() << std::endl << std::endl; -#endif // DEBUG_TRACES - -#ifdef DEBUG_TRACES - std::cout << "Iterator on vertices: " << std::endl; - for (auto vertex : simplex_tree.complex_vertex_range()) { - std::cout << vertex << " "; - } -#endif // DEBUG_TRACES - - // Sort the simplices in the order of the filtration - simplex_tree.initialize_filtration(); - - std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; - // Compute the persistence diagram of the complex - Persistent_cohomology pcoh(simplex_tree, true); - // initializes the coefficient field for homology - pcoh.init_coefficients(coeff_field_characteristic); - - pcoh.compute_persistent_cohomology(min_persistence); - - pcoh.output_diagram(); - - return 0; -} -- cgit v1.2.3 From 63666b64129b8ca4ba95504393f863e01f76c51b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 10 Oct 2017 14:32:18 +0000 Subject: Fix tests and homogenize code git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/weighted_alpha_complex_fix@2775 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: bdcc278981e2683a5b49f241f07704f3d5c7ca4e --- data/points/grid_10_10_10_in_0_2.off | 127 --------------------- data/points/grid_10_10_10_in_0_2.weights | 125 -------------------- .../example/alpha_complex_3d_persistence.cpp | 11 +- .../example/exact_alpha_complex_3d_persistence.cpp | 47 ++++---- .../periodic_alpha_complex_3d_persistence.cpp | 4 +- .../weighted_alpha_complex_3d_persistence.cpp | 5 +- ...ghted_periodic_alpha_complex_3d_persistence.cpp | 8 +- 7 files changed, 32 insertions(+), 295 deletions(-) delete mode 100644 data/points/grid_10_10_10_in_0_2.off delete mode 100644 data/points/grid_10_10_10_in_0_2.weights diff --git a/data/points/grid_10_10_10_in_0_2.off b/data/points/grid_10_10_10_in_0_2.off deleted file mode 100644 index 7618e065..00000000 --- a/data/points/grid_10_10_10_in_0_2.off +++ /dev/null @@ -1,127 +0,0 @@ -OFF -125 0 0 -0 0 0 -0 0 0.2 -0 0 0.4 -0 0 0.6 -0 0 0.8 -0 0.2 0 -0 0.2 0.2 -0 0.2 0.4 -0 0.2 0.6 -0 0.2 0.8 -0 0.4 0 -0 0.4 0.2 -0 0.4 0.4 -0 0.4 0.6 -0 0.4 0.8 -0 0.6 0 -0 0.6 0.2 -0 0.6 0.4 -0 0.6 0.6 -0 0.6 0.8 -0 0.8 0 -0 0.8 0.2 -0 0.8 0.4 -0 0.8 0.6 -0 0.8 0.8 -0.2 0 0 -0.2 0 0.2 -0.2 0 0.4 -0.2 0 0.6 -0.2 0 0.8 -0.2 0.2 0 -0.2 0.2 0.2 -0.2 0.2 0.4 -0.2 0.2 0.6 -0.2 0.2 0.8 -0.2 0.4 0 -0.2 0.4 0.2 -0.2 0.4 0.4 -0.2 0.4 0.6 -0.2 0.4 0.8 -0.2 0.6 0 -0.2 0.6 0.2 -0.2 0.6 0.4 -0.2 0.6 0.6 -0.2 0.6 0.8 -0.2 0.8 0 -0.2 0.8 0.2 -0.2 0.8 0.4 -0.2 0.8 0.6 -0.2 0.8 0.8 -0.4 0 0 -0.4 0 0.2 -0.4 0 0.4 -0.4 0 0.6 -0.4 0 0.8 -0.4 0.2 0 -0.4 0.2 0.2 -0.4 0.2 0.4 -0.4 0.2 0.6 -0.4 0.2 0.8 -0.4 0.4 0 -0.4 0.4 0.2 -0.4 0.4 0.4 -0.4 0.4 0.6 -0.4 0.4 0.8 -0.4 0.6 0 -0.4 0.6 0.2 -0.4 0.6 0.4 -0.4 0.6 0.6 -0.4 0.6 0.8 -0.4 0.8 0 -0.4 0.8 0.2 -0.4 0.8 0.4 -0.4 0.8 0.6 -0.4 0.8 0.8 -0.6 0 0 -0.6 0 0.2 -0.6 0 0.4 -0.6 0 0.6 -0.6 0 0.8 -0.6 0.2 0 -0.6 0.2 0.2 -0.6 0.2 0.4 -0.6 0.2 0.6 -0.6 0.2 0.8 -0.6 0.4 0 -0.6 0.4 0.2 -0.6 0.4 0.4 -0.6 0.4 0.6 -0.6 0.4 0.8 -0.6 0.6 0 -0.6 0.6 0.2 -0.6 0.6 0.4 -0.6 0.6 0.6 -0.6 0.6 0.8 -0.6 0.8 0 -0.6 0.8 0.2 -0.6 0.8 0.4 -0.6 0.8 0.6 -0.6 0.8 0.8 -0.8 0 0 -0.8 0 0.2 -0.8 0 0.4 -0.8 0 0.6 -0.8 0 0.8 -0.8 0.2 0 -0.8 0.2 0.2 -0.8 0.2 0.4 -0.8 0.2 0.6 -0.8 0.2 0.8 -0.8 0.4 0 -0.8 0.4 0.2 -0.8 0.4 0.4 -0.8 0.4 0.6 -0.8 0.4 0.8 -0.8 0.6 0 -0.8 0.6 0.2 -0.8 0.6 0.4 -0.8 0.6 0.6 -0.8 0.6 0.8 -0.8 0.8 0 -0.8 0.8 0.2 -0.8 0.8 0.4 -0.8 0.8 0.6 -0.8 0.8 0.8 diff --git a/data/points/grid_10_10_10_in_0_2.weights b/data/points/grid_10_10_10_in_0_2.weights deleted file mode 100644 index fea8f879..00000000 --- a/data/points/grid_10_10_10_in_0_2.weights +++ /dev/null @@ -1,125 +0,0 @@ -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 -1e-6 diff --git a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp index a0db9b42..df96fcfd 100644 --- a/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/alpha_complex_3d_persistence.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "alpha_complex_3d_helper.h" @@ -78,7 +79,7 @@ using Persistent_cohomology = void usage(const std::string& progName) { std::cerr << "Usage: " << progName - << " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; + << " path_to_the_OFF_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); } @@ -90,13 +91,7 @@ int main(int argc, char* const argv[]) { } int coeff_field_characteristic = atoi(argv[2]); - - Filtration_value min_persistence = 0.0; - int returnedScanValue = sscanf(argv[3], "%f", &min_persistence); - if ((returnedScanValue == EOF) || (min_persistence < -1.0)) { - std::cerr << "Error: " << argv[3] << " is not correct\n"; - usage(argv[0]); - } + Filtration_value min_persistence = strtof(argv[3], nullptr); // Read points from file std::string offInputFile(argv[1]); diff --git a/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp index 8a335075..b189e980 100644 --- a/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/exact_alpha_complex_3d_persistence.cpp @@ -4,7 +4,7 @@ * * Author(s): Vincent Rouvreau * - * Copyright (C) 2014 INRIA Saclay (France) + * Copyright (C) 2014 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 @@ -39,6 +39,7 @@ #include #include #include +#include #include "alpha_complex_3d_helper.h" @@ -57,32 +58,33 @@ using Point_3 = Kernel::Point_3; // filtration with alpha values needed type definition using Alpha_value_type = Alpha_shape_3::FT; using Object = CGAL::Object; -using Dispatch = CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple >, - std::back_insert_iterator< std::vector > > >; +using Dispatch = + CGAL::Dispatch_output_iterator, + CGAL::cpp11::tuple >, + std::back_insert_iterator > > >; using Cell_handle = Alpha_shape_3::Cell_handle; using Facet = Alpha_shape_3::Facet; using Edge_3 = Alpha_shape_3::Edge; using Vertex_handle = Alpha_shape_3::Vertex_handle; -using Vertex_list = std::list; +using Vertex_list = std::list; // gudhi type definition using ST = Gudhi::Simplex_tree; using Filtration_value = ST::Filtration_value; using Simplex_tree_vertex = ST::Vertex_handle; -using Alpha_shape_simplex_tree_map = std::map; +using Alpha_shape_simplex_tree_map = std::map; using Alpha_shape_simplex_tree_pair = std::pair; -using Simplex_tree_vector_vertex = std::vector< Simplex_tree_vertex >; -using PCOH = Gudhi::persistent_cohomology::Persistent_cohomology< ST, Gudhi::persistent_cohomology::Field_Zp >; +using Simplex_tree_vector_vertex = std::vector; +using Persistent_cohomology = + Gudhi::persistent_cohomology::Persistent_cohomology; -void usage(char * const progName) { - std::cerr << "Usage: " << progName << - " path_to_file_graph coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; +void usage(const std::string& progName) { + std::cerr << "Usage: " << progName + << " path_to_the_OFF_file coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); } -int main(int argc, char * const argv[]) { +int main(int argc, char* const argv[]) { // program args management if (argc != 4) { std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; @@ -90,13 +92,7 @@ int main(int argc, char * const argv[]) { } int coeff_field_characteristic = atoi(argv[2]); - - Filtration_value min_persistence = 0.0; - int returnedScanValue = sscanf(argv[3], "%f", &min_persistence); - if ((returnedScanValue == EOF) || (min_persistence < -1.0)) { - std::cerr << "Error: " << argv[3] << " is not correct\n"; - usage(argv[0]); - } + Filtration_value min_persistence = strtof(argv[3], nullptr); // Read points from file std::string offInputFile(argv[1]); @@ -143,28 +139,28 @@ int main(int argc, char * const argv[]) { Filtration_value filtration_max = 0.0; for (auto object_iterator : the_objects) { // Retrieve Alpha shape vertex list from object - if (const Cell_handle * cell = CGAL::object_cast(&object_iterator)) { + if (const Cell_handle* cell = CGAL::object_cast(&object_iterator)) { vertex_list = from_cell(*cell); count_cells++; if (dim_max < 3) { // Cell is of dim 3 dim_max = 3; } - } else if (const Facet * facet = CGAL::object_cast(&object_iterator)) { + } else if (const Facet* facet = CGAL::object_cast(&object_iterator)) { vertex_list = from_facet(*facet); count_facets++; if (dim_max < 2) { // Facet is of dim 2 dim_max = 2; } - } else if (const Edge_3 * edge = CGAL::object_cast(&object_iterator)) { + } else if (const Edge_3* edge = CGAL::object_cast(&object_iterator)) { vertex_list = from_edge(*edge); count_edges++; if (dim_max < 1) { // Edge_3 is of dim 1 dim_max = 1; } - } else if (const Vertex_handle * vertex = CGAL::object_cast(&object_iterator)) { + } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { count_vertices++; vertex_list = from_vertex(*vertex); } @@ -213,7 +209,6 @@ int main(int argc, char * const argv[]) { std::cout << "facets \t\t" << count_facets << std::endl; std::cout << "cells \t\t" << count_cells << std::endl; - std::cout << "Information of the Simplex Tree: " << std::endl; std::cout << " Number of vertices = " << simplex_tree.num_vertices() << " "; std::cout << " Number of simplices = " << simplex_tree.num_simplices() << std::endl << std::endl; @@ -233,7 +228,7 @@ int main(int argc, char * const argv[]) { std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; // Compute the persistence diagram of the complex - PCOH pcoh(simplex_tree); + Persistent_cohomology pcoh(simplex_tree, true); // initializes the coefficient field for homology pcoh.init_coefficients(coeff_field_characteristic); diff --git a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp index 33efbdc7..63731a4a 100644 --- a/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/periodic_alpha_complex_3d_persistence.cpp @@ -83,8 +83,8 @@ using Simplex_tree_vector_vertex = std::vector; using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology; -void usage(char* const progName) { - std::cerr << "Usage: " << progName << " path_to_file_graph path_to_iso_cuboid_3_file " +void usage(const std::string& progName) { + std::cerr << "Usage: " << progName << " path_to_the_OFF_file path_to_iso_cuboid_3_file " "coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); } diff --git a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp index 85b0ab34..96cc57e9 100644 --- a/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_alpha_complex_3d_persistence.cpp @@ -49,6 +49,7 @@ #include "alpha_complex_3d_helper.h" +// Alpha_shape_3 templates type definitions using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; // For CGAL < 4.11 @@ -102,8 +103,8 @@ using Simplex_tree_vector_vertex = std::vector; using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology; -void usage(char* const progName) { - std::cerr << "Usage: " << progName << " path_to_file_graph path_to_weight_file coeff_field_characteristic[integer > " +void usage(const std::string& progName) { + std::cerr << "Usage: " << progName << " path_to_the_OFF_file path_to_weight_file coeff_field_characteristic[integer > " "0] min_persistence[float >= -1.0]\n"; exit(-1); } diff --git a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp index ab2e29b4..a4a2a9f8 100644 --- a/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp +++ b/src/Persistent_cohomology/example/weighted_periodic_alpha_complex_3d_persistence.cpp @@ -86,8 +86,8 @@ using Simplex_tree_vector_vertex = std::vector; using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology; -void usage(char* const progName) { - std::cerr << "Usage: " << progName << " path_to_the_OFF_File path_to_weight_file path_to_the_cuboid_file " +void usage(const std::string& progName) { + std::cerr << "Usage: " << progName << " path_to_the_OFF_file path_to_weight_file path_to_the_cuboid_file " "coeff_field_characteristic[integer > 0] min_persistence[float >= -1.0]\n"; exit(-1); } @@ -96,7 +96,6 @@ int main(int argc, char* const argv[]) { // program args management if (argc != 6) { std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n"; - // file with points, file with weights, cuboid file, field characteristics, minimum persistence. usage(argv[0]); } @@ -206,8 +205,7 @@ int main(int argc, char* const argv[]) { // Edge_3 is of dim 1 dim_max = 1; } - } else if (const Alpha_shape_3::Vertex_handle* vertex = - CGAL::object_cast(&object_iterator)) { + } else if (const Vertex_handle* vertex = CGAL::object_cast(&object_iterator)) { count_vertices++; vertex_list = from_vertex(*vertex); } -- cgit v1.2.3 From 4e3cf64d56874353aea48ccc1820069bbf37671a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 19 Oct 2017 20:35:41 +0000 Subject: Code review : remove template specification for std::max Fix cython tests accordingly to the other modifications git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2794 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e1009a3304455fa26fbd368c4cce4451bc3d7784 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 4 ++-- src/cython/test/test_simplex_tree.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 8a827086..a2febe54 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1202,7 +1202,7 @@ class Simplex_tree { */ bool automatic_dimension_set() { int new_dimension = -1; - // Browse the tree from te left to the right as higher dimension cells are more likely on the left part of the tree + // Browse the tree from the left to the right as higher dimension cells are more likely on the left part of the tree for (Simplex_handle sh : skeleton_simplex_range(dimension_)) { #ifdef DEBUG_TRACES for (auto vertex : simplex_vertex_range(sh)) { @@ -1215,7 +1215,7 @@ class Simplex_tree { if (sh_dimension >= dimension_) // Stop browsing as soon as the dimension is reached, no need to go furter return false; - new_dimension = std::max(new_dimension, sh_dimension); + new_dimension = std::max(new_dimension, sh_dimension); } dimension_ = new_dimension; return true; diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index a6d6a9f3..177cfdad 100755 --- a/src/cython/test/test_simplex_tree.py +++ b/src/cython/test/test_simplex_tree.py @@ -94,12 +94,12 @@ def test_insertion(): assert st.persistence(persistence_dim_max = True) == [(1, (4.0, float('inf'))), (0, (0.0, float('inf')))] assert st.__is_persistence_defined() == True - assert st.betti_numbers() == [1, 1] - assert st.persistent_betti_numbers(-0.1, 10000.0) == [0, 0] - assert st.persistent_betti_numbers(0.0, 10000.0) == [1, 0] - assert st.persistent_betti_numbers(3.9, 10000.0) == [1, 0] - assert st.persistent_betti_numbers(4.0, 10000.0) == [1, 1] - assert st.persistent_betti_numbers(9999.0, 10000.0) == [1, 1] + assert st.betti_numbers() == [1, 1, 0] + assert st.persistent_betti_numbers(-0.1, 10000.0) == [0, 0, 0] + assert st.persistent_betti_numbers(0.0, 10000.0) == [1, 0, 0] + assert st.persistent_betti_numbers(3.9, 10000.0) == [1, 0, 0] + assert st.persistent_betti_numbers(4.0, 10000.0) == [1, 1, 0] + assert st.persistent_betti_numbers(9999.0, 10000.0) == [1, 1, 0] def test_expansion(): st = SimplexTree() -- cgit v1.2.3 From e36dafedbab909ef1d16eceb133cd8b80dd1763d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 20 Oct 2017 08:10:05 +0000 Subject: Doc review: remove_maximal_simplex about automatic_dimension_set mechanism was too strict. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2795 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0226b3ee6a082b109185c9eff8c1601b61d4f667 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index a2febe54..7841c793 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1228,7 +1228,9 @@ class Simplex_tree { * \pre Please check the simplex has no coface before removing it. * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done). - * \post Be aware that removing may change the simplex tree dimension (`automatic_dimension_set()` to be done). + * \post Note that the dimension of the simplicial complex may be lower after calling `remove_maximal_simplex()` + * than it was before. However, `Simplex_tree::dimension()` will return the old value, which remains a valid upper + * bound. If you care, you can call `automatic_dimension_set()` to recompute the exact dimension. */ void remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children -- cgit v1.2.3 From 6fff7c1774365f99c93d57bdf3595e6b89f16b0a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 20 Oct 2017 08:24:03 +0000 Subject: Code review : rename automatic_dimension_set with downgrade_dimension git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2796 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3b094bc579367d40790c3791f2c4a3700a3d93ae --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 8 ++++---- .../test/simplex_tree_remove_unit_test.cpp | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 7841c793..986cc071 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1163,7 +1163,7 @@ class Simplex_tree { * complex has changed , please call `initialize_filtration()` to recompute it. * \post Note that the dimension of the simplicial complex may be lower after calling `prune_above_filtration()` * than it was before. However, `Simplex_tree::dimension()` will return the old value, which remains a valid upper - * bound. If you care, you can call `automatic_dimension_set()` to recompute the exact dimension. + * bound. If you care, you can call `downgrade_dimension()` to recompute the exact dimension. */ bool prune_above_filtration(Filtration_value filtration) { return rec_prune_above_filtration(root(), filtration); @@ -1195,12 +1195,12 @@ class Simplex_tree { } public: - /** \brief Deep search simplex tree dimension reset. + /** \brief Deep search simplex tree dimension recompute. * @return True if the dimension was modified, false otherwise. * \pre Be sure the simplex tree has not a too low dimension value as the deep search stops when the former dimension * has been reached (cf. `dimension()` and `set_dimension()` methods). */ - bool automatic_dimension_set() { + bool downgrade_dimension() { int new_dimension = -1; // Browse the tree from the left to the right as higher dimension cells are more likely on the left part of the tree for (Simplex_handle sh : skeleton_simplex_range(dimension_)) { @@ -1230,7 +1230,7 @@ class Simplex_tree { * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done). * \post Note that the dimension of the simplicial complex may be lower after calling `remove_maximal_simplex()` * than it was before. However, `Simplex_tree::dimension()` will return the old value, which remains a valid upper - * bound. If you care, you can call `automatic_dimension_set()` to recompute the exact dimension. + * bound. If you care, you can call `downgrade_dimension()` to recompute the exact dimension. */ void remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp index 87c77801..747e7eeb 100644 --- a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << " | st_wo_seven.dimension()=" << st_wo_seven.dimension() << std::endl; BOOST_CHECK(st == st_wo_seven); @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.remove_maximal_simplex(st.find({1, 2, 3, 5})); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 2); @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.remove_maximal_simplex(st.find({1, 2, 3, 4})); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 2); @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.remove_maximal_simplex(st.find({0, 1, 3, 4})); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 2); @@ -208,9 +208,9 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.set_dimension(1); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 1); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << std::endl; - // check automatic_dimension_set() is not giving the rigt answer because dimension is too low + // check downgrade_dimension() is not giving the rigt answer because dimension is too low BOOST_CHECK(st.dimension() == 1); @@ -219,9 +219,9 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.set_dimension(6); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 6); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << std::endl; - // check automatic_dimension_set() resets the correct dimension + // check downgrade_dimension() resets the correct dimension BOOST_CHECK(st.dimension() == 3); @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.remove_maximal_simplex(st.find({0, 1, 2, 3, 4, 5, 6})); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 6); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 5); @@ -344,7 +344,7 @@ BOOST_AUTO_TEST_CASE(prune_above_filtration) { std::cout << " - dimension " << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == 3); - st.automatic_dimension_set(); + st.downgrade_dimension(); std::cout << "dimension=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == -1); -- cgit v1.2.3 From 0f7b41e0357063fcb8a06b17b90fe9fe7b4bda83 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 20 Oct 2017 14:18:03 +0000 Subject: Use simplices iterator instead of skeleton iterator git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2798 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 856d2655901b01dd3e75f428f364ab7ac4f07aee --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 986cc071..ce0994da 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1203,7 +1203,7 @@ class Simplex_tree { bool downgrade_dimension() { int new_dimension = -1; // Browse the tree from the left to the right as higher dimension cells are more likely on the left part of the tree - for (Simplex_handle sh : skeleton_simplex_range(dimension_)) { + for (Simplex_handle sh : complex_simplex_range()) { #ifdef DEBUG_TRACES for (auto vertex : simplex_vertex_range(sh)) { std::cout << " " << vertex; -- cgit v1.2.3 From 8f7e5a1259287ee39595623e87149cb07ab2e293 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 26 Oct 2017 20:16:33 +0000 Subject: Code review: downgrade_dimension renamed lower_upper_bound_dimension and make it private. Automatically when dimension_to_be_lowered_ is set (on removal) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2810 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c764433bcc5357acc6454683d4f4182c7c960d6d --- src/Alpha_complex/test/Alpha_complex_unit_test.cpp | 2 +- src/Simplex_tree/include/gudhi/Simplex_tree.h | 34 ++++++-- .../test/simplex_tree_remove_unit_test.cpp | 98 ++++++++++++---------- src/cython/test/test_simplex_tree.py | 12 +-- 4 files changed, 87 insertions(+), 59 deletions(-) diff --git a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp index e60089c4..166373fe 100644 --- a/src/Alpha_complex/test/Alpha_complex_unit_test.cpp +++ b/src/Alpha_complex/test/Alpha_complex_unit_test.cpp @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_from_points) { BOOST_CHECK(simplex_tree.num_simplices() == 10); std::cout << "simplex_tree.dimension()=" << simplex_tree.dimension() << std::endl; - BOOST_CHECK(simplex_tree.dimension() == 3); + BOOST_CHECK(simplex_tree.dimension() == 1); std::cout << "simplex_tree.num_vertices()=" << simplex_tree.num_vertices() << std::endl; BOOST_CHECK(simplex_tree.num_vertices() == 4); diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index ce0994da..54f5de13 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -492,7 +492,16 @@ class Simplex_tree { } /** \brief Returns an upper bound on the dimension of the simplicial complex. */ - int dimension() const { + int upper_bound_dimension() const { + return dimension_; + } + + /** \brief Returns the dimension of the simplicial complex. + \details This function is not constant time because it can trigger `lower_upper_bound_dimension()` if required. + */ + int dimension() { + if (dimension_to_be_lowered_) + lower_upper_bound_dimension(); return dimension_; } @@ -1162,8 +1171,8 @@ class Simplex_tree { * function is not launching `initialize_filtration()` but returns the filtration modification information. If the * complex has changed , please call `initialize_filtration()` to recompute it. * \post Note that the dimension of the simplicial complex may be lower after calling `prune_above_filtration()` - * than it was before. However, `Simplex_tree::dimension()` will return the old value, which remains a valid upper - * bound. If you care, you can call `downgrade_dimension()` to recompute the exact dimension. + * than it was before. However, `upper_bond_dimension()` will return the old value, which remains a valid upper + * bound. If you care, you can call `dimension()` to recompute the exact dimension. */ bool prune_above_filtration(Filtration_value filtration) { return rec_prune_above_filtration(root(), filtration); @@ -1175,6 +1184,8 @@ class Simplex_tree { auto last = std::remove_if(list.begin(), list.end(), [=](Dit_value_t& simplex) { if (simplex.second.filtration() <= filt) return false; if (has_children(&simplex)) rec_delete(simplex.second.children()); + // dimension may need to be lowered + dimension_to_be_lowered_ = true; return true; }); @@ -1183,6 +1194,8 @@ class Simplex_tree { // Removing the whole siblings, parent becomes a leaf. sib->oncles()->members()[sib->parent()].assign_children(sib->oncles()); delete sib; + // dimension may need to be lowered + dimension_to_be_lowered_ = true; return true; } else { // Keeping some elements of siblings. Remove the others, and recurse in the remaining ones. @@ -1194,13 +1207,15 @@ class Simplex_tree { return modified; } - public: + private: /** \brief Deep search simplex tree dimension recompute. * @return True if the dimension was modified, false otherwise. * \pre Be sure the simplex tree has not a too low dimension value as the deep search stops when the former dimension - * has been reached (cf. `dimension()` and `set_dimension()` methods). + * has been reached (cf. `upper_bound_dimension()` and `set_dimension()` methods). */ - bool downgrade_dimension() { + bool lower_upper_bound_dimension() { + // reset automatic detection to recompute + dimension_to_be_lowered_ = false; int new_dimension = -1; // Browse the tree from the left to the right as higher dimension cells are more likely on the left part of the tree for (Simplex_handle sh : complex_simplex_range()) { @@ -1229,8 +1244,8 @@ class Simplex_tree { * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done). * \post Note that the dimension of the simplicial complex may be lower after calling `remove_maximal_simplex()` - * than it was before. However, `Simplex_tree::dimension()` will return the old value, which remains a valid upper - * bound. If you care, you can call `downgrade_dimension()` to recompute the exact dimension. + * than it was before. However, `upper_bond_dimension()` will return the old value, which remains a valid upper + * bound. If you care, you can call `dimension()` to recompute the exact dimension. */ void remove_maximal_simplex(Simplex_handle sh) { // Guarantee the simplex has no children @@ -1248,6 +1263,8 @@ class Simplex_tree { // Sibling is emptied : must be deleted, and its parent must point on his own Sibling child->oncles()->members().at(child->parent()).assign_children(child->oncles()); delete child; + // dimension may need to be lowered + dimension_to_be_lowered_ = true; } } @@ -1262,6 +1279,7 @@ class Simplex_tree { std::vector filtration_vect_; /** \brief Upper bound on the dimension of the simplicial complex.*/ int dimension_; + bool dimension_to_be_lowered_ = false; }; // Print a Simplex_tree in os. diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp index 747e7eeb..dc37375c 100644 --- a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp @@ -109,11 +109,15 @@ BOOST_AUTO_TEST_CASE(remove_maximal_simplex) { std::cout << "st.remove_maximal_simplex({7})" << std::endl; st.remove_maximal_simplex(st.find({7})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 3); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); - st.downgrade_dimension(); + // Check dimension calls lower_upper_bound_dimension to recompute dimension + BOOST_CHECK(st.dimension() == 2); + BOOST_CHECK(st.upper_bound_dimension() == 2); + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() + << " | st_wo_seven.upper_bound_dimension()=" << st_wo_seven.upper_bound_dimension() << std::endl; std::cout << "st.dimension()=" << st.dimension() << " | st_wo_seven.dimension()=" << st_wo_seven.dimension() << std::endl; BOOST_CHECK(st == st_wo_seven); } @@ -131,116 +135,121 @@ BOOST_AUTO_TEST_CASE(auto_dimension_set) { st.insert_simplex_and_subfaces({6, 7, 8, 9}); st.insert_simplex_and_subfaces({6, 7, 8, 10}); + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({6, 7, 8, 10})" << std::endl; st.remove_maximal_simplex(st.find({6, 7, 8, 10})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({6, 7, 8, 9})" << std::endl; st.remove_maximal_simplex(st.find({6, 7, 8, 9})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 4})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 5})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 3); - st.downgrade_dimension(); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 2); + std::cout << "st.dimension()=" << st.dimension() << std::endl; std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 5}); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 4}); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); + std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 5})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); + std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl; st.remove_maximal_simplex(st.find({1, 2, 3, 4})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 3); - st.downgrade_dimension(); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 2); + std::cout << "st.dimension()=" << st.dimension() << std::endl; std::cout << "st.insert_simplex_and_subfaces({0, 1, 3, 4})" << std::endl; st.insert_simplex_and_subfaces({0, 1, 3, 4}); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.remove_maximal_simplex({0, 1, 3, 4})" << std::endl; st.remove_maximal_simplex(st.find({0, 1, 3, 4})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 3); - st.downgrade_dimension(); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 2); + std::cout << "st.dimension()=" << st.dimension() << std::endl; std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 5}); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl; st.insert_simplex_and_subfaces({1, 2, 3, 4}); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); // Check you can override the dimension // This is a limit test case - shall not happen st.set_dimension(1); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 1); - st.downgrade_dimension(); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - // check downgrade_dimension() is not giving the rigt answer because dimension is too low + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 1); + // check dimension() and lower_upper_bound_dimension() is not giving the right answer because dimension is too low BOOST_CHECK(st.dimension() == 1); // Check you can override the dimension // This is a limit test case - shall not happen st.set_dimension(6); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 6); + // check dimension() do not launch lower_upper_bound_dimension() BOOST_CHECK(st.dimension() == 6); - st.downgrade_dimension(); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - // check downgrade_dimension() resets the correct dimension - BOOST_CHECK(st.dimension() == 3); // Reset with the correct value st.set_dimension(3); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); BOOST_CHECK(st.dimension() == 3); std::cout << "st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6})" << std::endl; st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6}); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 6); BOOST_CHECK(st.dimension() == 6); std::cout << "st.remove_maximal_simplex({0, 1, 2, 3, 4, 5, 6})" << std::endl; st.remove_maximal_simplex(st.find({0, 1, 2, 3, 4, 5, 6})); - std::cout << "st.dimension()=" << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 6); - st.downgrade_dimension(); - std::cout << "st.dimension()=" << st.dimension() << std::endl; + std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 6); BOOST_CHECK(st.dimension() == 5); } @@ -336,17 +345,18 @@ BOOST_AUTO_TEST_CASE(prune_above_filtration) { Stree st_empty; simplex_is_changed = st.prune_above_filtration(0.0); + BOOST_CHECK(simplex_is_changed == true); if (simplex_is_changed) st.initialize_filtration(); // Display the Simplex_tree std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices"; - std::cout << " - dimension " << st.dimension() << std::endl; - BOOST_CHECK(st.dimension() == 3); + std::cout << " - upper_bound_dimension " << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == 3); - st.downgrade_dimension(); - std::cout << "dimension=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == -1); + std::cout << "upper_bound_dimension=" << st.upper_bound_dimension() << std::endl; + BOOST_CHECK(st.upper_bound_dimension() == -1); BOOST_CHECK(st == st_empty); BOOST_CHECK(simplex_is_changed); diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index 177cfdad..a6d6a9f3 100755 --- a/src/cython/test/test_simplex_tree.py +++ b/src/cython/test/test_simplex_tree.py @@ -94,12 +94,12 @@ def test_insertion(): assert st.persistence(persistence_dim_max = True) == [(1, (4.0, float('inf'))), (0, (0.0, float('inf')))] assert st.__is_persistence_defined() == True - assert st.betti_numbers() == [1, 1, 0] - assert st.persistent_betti_numbers(-0.1, 10000.0) == [0, 0, 0] - assert st.persistent_betti_numbers(0.0, 10000.0) == [1, 0, 0] - assert st.persistent_betti_numbers(3.9, 10000.0) == [1, 0, 0] - assert st.persistent_betti_numbers(4.0, 10000.0) == [1, 1, 0] - assert st.persistent_betti_numbers(9999.0, 10000.0) == [1, 1, 0] + assert st.betti_numbers() == [1, 1] + assert st.persistent_betti_numbers(-0.1, 10000.0) == [0, 0] + assert st.persistent_betti_numbers(0.0, 10000.0) == [1, 0] + assert st.persistent_betti_numbers(3.9, 10000.0) == [1, 0] + assert st.persistent_betti_numbers(4.0, 10000.0) == [1, 1] + assert st.persistent_betti_numbers(9999.0, 10000.0) == [1, 1] def test_expansion(): st = SimplexTree() -- cgit v1.2.3 From 8659c97eff5e4ef0321509abe36f8baa78c2f35b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 6 Nov 2017 12:33:36 +0000 Subject: doc review : upper_bond_dimension to be replaced with upper_bound_dimension git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2829 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ca70d79176d406f63c3372dd7e062f108365b99f --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index b2d380ea..03dfce70 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1268,7 +1268,7 @@ class Simplex_tree { * function is not launching `initialize_filtration()` but returns the filtration modification information. If the * complex has changed , please call `initialize_filtration()` to recompute it. * \post Note that the dimension of the simplicial complex may be lower after calling `prune_above_filtration()` - * than it was before. However, `upper_bond_dimension()` will return the old value, which remains a valid upper + * than it was before. However, `upper_bound_dimension()` will return the old value, which remains a valid upper * bound. If you care, you can call `dimension()` to recompute the exact dimension. */ bool prune_above_filtration(Filtration_value filtration) { @@ -1342,7 +1342,7 @@ class Simplex_tree { * \exception std::invalid_argument In debug mode, if sh has children. * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done). * \post Note that the dimension of the simplicial complex may be lower after calling `remove_maximal_simplex()` - * than it was before. However, `upper_bond_dimension()` will return the old value, which remains a valid upper + * than it was before. However, `upper_bound_dimension()` will return the old value, which remains a valid upper * bound. If you care, you can call `dimension()` to recompute the exact dimension. * \internal @return true if the leaf's branch has no other leaves (branch's children has been re-assigned), false otherwise. */ -- cgit v1.2.3 From b4298589ad5e2cf7136b0ff7a0be29a246b2f956 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 6 Nov 2017 13:14:02 +0000 Subject: Doc review : dimension() method documentation can not mention lower_upper_bound_dimension as it is a private method. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2830 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fec09d2a0b0f896c848a13c54d21625d08efc997 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 03dfce70..7da767cb 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -487,7 +487,8 @@ class Simplex_tree { } /** \brief Returns the dimension of the simplicial complex. - \details This function is not constant time because it can trigger `lower_upper_bound_dimension()` if required. + \details This function is not constant time because it can recompute dimension if required (can be triggered by + `remove_maximal_simplex()` or `prune_above_filtration()`). */ int dimension() { if (dimension_to_be_lowered_) -- cgit v1.2.3 From 961d3264b4554cdd03d1c5a13e714e1ea38733ff Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 6 Nov 2017 13:39:43 +0000 Subject: Rollback commented lines git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_automatic_dimension_set@2831 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 052a8f264877e7ffa87f8c81abf0f0c83cb60d54 --- src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp index 75580aac..554eeba6 100644 --- a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp +++ b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp @@ -88,9 +88,6 @@ int main(int argc, char * argv[]) { Simplex_tree st; // insert the proximity graph in the simplex tree st.insert_graph(prox_graph); - std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; - std::cout << " and has dimension " << st.dimension() << " \n"; -/* // expand the graph until dimension dim_max st.expansion(dim_max); @@ -115,7 +112,7 @@ int main(int argc, char * argv[]) { pcoh.output_diagram(out); out.close(); } -*/ + return 0; } -- cgit v1.2.3 -- cgit v1.2.3 From e571676d88695603961798b1e284c50f151fdf18 Mon Sep 17 00:00:00 2001 From: cjamin Date: Mon, 6 Nov 2017 13:58:53 +0000 Subject: Fix typedef git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cgal_4.11.fix@2833 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1f970c56378222a29d03724d4ebd2e3c3084ba57 --- src/Tangential_complex/include/gudhi/Tangential_complex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tangential_complex/include/gudhi/Tangential_complex.h b/src/Tangential_complex/include/gudhi/Tangential_complex.h index a5cefd6a..6f061922 100644 --- a/src/Tangential_complex/include/gudhi/Tangential_complex.h +++ b/src/Tangential_complex/include/gudhi/Tangential_complex.h @@ -155,7 +155,7 @@ class Tangential_complex { >::type Triangulation; typedef typename Triangulation::Geom_traits Tr_traits; typedef typename Triangulation::Weighted_point Tr_point; - typedef typename Triangulation::Bare_point Tr_bare_point; + typedef typename Tr_traits::Base::Point_d Tr_bare_point; typedef typename Triangulation::Vertex_handle Tr_vertex_handle; typedef typename Triangulation::Full_cell_handle Tr_full_cell_handle; typedef typename Tr_traits::Vector_d Tr_vector; -- cgit v1.2.3 -- cgit v1.2.3