diff options
Diffstat (limited to 'src')
57 files changed, 746 insertions, 914 deletions
diff --git a/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp b/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp index fd9f0858..fd164b22 100644 --- a/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp +++ b/src/Bottleneck_distance/example/alpha_rips_persistence_bottleneck_distance.cpp @@ -74,7 +74,7 @@ int main(int argc, char * argv[]) { // -------------------------------------------- // Rips persistence // -------------------------------------------- - Rips_complex rips_complex(off_reader.get_point_cloud(), threshold, Euclidean_distance()); + Rips_complex rips_complex(off_reader.get_point_cloud(), threshold, Gudhi::Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree rips_stree; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4fa73662..0c16c9cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,8 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") set(GUDHI_USER_VERSION_DIR ${CMAKE_SOURCE_DIR}) include(${CMAKE_MODULE_PATH}/GUDHI_doxygen_target.txt) +# This variable is used by Cython CMakeLists.txt to know its path +set(GUDHI_CYTHON_PATH "cython") # For third parties libraries management - To be done last as CGAL updates CMAKE_MODULE_PATH include("${CMAKE_MODULE_PATH}/GUDHI_third_party_libraries.txt") @@ -56,12 +58,9 @@ add_subdirectory(example/Bottleneck_distance) # data points generator add_subdirectory(data/points/generator) -# Please let GudhUI in last compilation position as QT is known to modify CMAKE_CXX_FLAGS -# GudhUI add_subdirectory(GudhUI) -# This variable is used by Cython CMakeLists.txt to know its path -set(GUDHI_CYTHON_PATH "cython") +# specific for cython module add_subdirectory(${GUDHI_CYTHON_PATH}) #--------------------------------------------------------------------------------------- diff --git a/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp index ba752999..252e8aef 100644 --- a/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp +++ b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp @@ -83,7 +83,7 @@ int main(int argc, char * argv[]) { // Compute the proximity graph of the points start = std::chrono::system_clock::now(); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Gudhi::Euclidean_distance()); end = std::chrono::system_clock::now(); elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); std::cout << "Compute Rips graph in " << elapsed_sec << " ms.\n"; diff --git a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp index 7674b5a5..dae36ed2 100644 --- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp @@ -62,7 +62,7 @@ int main(int argc, char * argv[]) { program_options(argc, argv, off_file_points, filediag, threshold, dim_max, min_p, max_p, min_persistence); Points_off_reader off_reader(off_file_points); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Gudhi::Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree simplex_tree; diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp index c6378de7..d504798b 100644 --- a/src/Persistent_cohomology/example/rips_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_persistence.cpp @@ -60,7 +60,7 @@ int main(int argc, char * argv[]) { program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence); Points_off_reader off_reader(off_file_points); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Gudhi::Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree simplex_tree; 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 b159c62e..554eeba6 100644 --- a/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp +++ b/src/Persistent_cohomology/example/rips_persistence_step_by_step.cpp @@ -82,7 +82,7 @@ int main(int argc, char * argv[]) { // Compute the proximity graph of the points Graph_t prox_graph = compute_proximity_graph(off_reader.get_point_cloud(), threshold - , Euclidean_distance()); + , Gudhi::Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree st; diff --git a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp index 63da9847..9618f278 100644 --- a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp +++ b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp @@ -70,7 +70,7 @@ int main(int argc, char * argv[]) { program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence); Points_off_reader off_reader(off_file_points); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Gudhi::Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree& st = *new Simplex_tree; diff --git a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp index 0ed3fddf..da418034 100644 --- a/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp +++ b/src/Persistent_cohomology/test/betti_numbers_unit_test.cpp @@ -9,8 +9,8 @@ #define BOOST_TEST_MODULE "betti_numbers" #include <boost/test/unit_test.hpp> -#include "gudhi/Simplex_tree.h" -#include "gudhi/Persistent_cohomology.h" +#include <gudhi/Simplex_tree.h> +#include <gudhi/Persistent_cohomology.h> struct MiniSTOptions : Gudhi::Simplex_tree_options_full_featured { // Implicitly use 0 as filtration value for all simplices diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 6efd749e..e2e0bc71 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -10,10 +10,10 @@ #define BOOST_TEST_MODULE "persistent_cohomology" #include <boost/test/unit_test.hpp> -#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/reader_utils.h" -#include "gudhi/Simplex_tree.h" -#include "gudhi/Persistent_cohomology.h" +#include <gudhi/graph_simplicial_complex.h> +#include <gudhi/reader_utils.h> +#include <gudhi/Simplex_tree.h> +#include <gudhi/Persistent_cohomology.h> using namespace Gudhi; using namespace Gudhi::persistent_cohomology; diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp index 1a6e3296..6a7ecbec 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp @@ -9,11 +9,11 @@ #define BOOST_TEST_MODULE "persistent_cohomology_multi_field" #include <boost/test/unit_test.hpp> -#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/reader_utils.h" -#include "gudhi/Simplex_tree.h" -#include "gudhi/Persistent_cohomology.h" -#include "gudhi/Persistent_cohomology/Multi_field.h" +#include <gudhi/graph_simplicial_complex.h> +#include <gudhi/reader_utils.h> +#include <gudhi/Simplex_tree.h> +#include <gudhi/Persistent_cohomology.h> +#include <gudhi/Persistent_cohomology/Multi_field.h> using namespace Gudhi; using namespace Gudhi::persistent_cohomology; diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp index 3fd69ebc..a1db8910 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp @@ -27,7 +27,7 @@ int main() { // Init of a Rips complex from points // ---------------------------------------------------------------------------- double threshold = 12.0; - Rips_complex rips_complex_from_points(points, threshold, Euclidean_distance()); + Rips_complex rips_complex_from_points(points, threshold, Gudhi::Euclidean_distance()); Simplex_tree stree; rips_complex_from_points.create_complex(stree, 1); diff --git a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp index a1e4e255..de2e4ea4 100644 --- a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp @@ -32,7 +32,7 @@ int main(int argc, char **argv) { // Init of a Rips complex from an OFF file // ---------------------------------------------------------------------------- Gudhi::Points_off_reader<Point> off_reader(off_file_name); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Gudhi::Euclidean_distance()); std::streambuf* streambufffer; std::ofstream ouput_file_stream; diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp index ae68ba0d..fc2179f2 100644 --- a/src/Rips_complex/test/test_rips_complex.cpp +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { rips_threshold << "==========" << std::endl; Gudhi::Points_off_reader<Point> off_reader(off_file_name); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, Gudhi::Euclidean_distance()); const int DIMENSION_1 = 1; Simplex_tree st; @@ -89,10 +89,10 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { std::cout << vertex << ","; vp.push_back(off_reader.get_point_cloud().at(vertex)); } - std::cout << ") - distance =" << Euclidean_distance()(vp.at(0), vp.at(1)) << + std::cout << ") - distance =" << Gudhi::Euclidean_distance()(vp.at(0), vp.at(1)) << " - filtration =" << st.filtration(f_simplex) << std::endl; BOOST_CHECK(vp.size() == 2); - BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), Euclidean_distance()(vp.at(0), vp.at(1)))); + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), Gudhi::Euclidean_distance()(vp.at(0), vp.at(1)))); } } @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(Rips_create_complex_throw) { rips_threshold << "==========" << std::endl; Gudhi::Points_off_reader<Point> off_reader(off_file_name); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, Euclidean_distance()); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, Gudhi::Euclidean_distance()); Simplex_tree stree; std::vector<int> simplex = {0, 1, 2}; diff --git a/src/Subsampling/example/example_choose_n_farthest_points.cpp b/src/Subsampling/example/example_choose_n_farthest_points.cpp index 533aba74..ebf631fc 100644 --- a/src/Subsampling/example/example_choose_n_farthest_points.cpp +++ b/src/Subsampling/example/example_choose_n_farthest_points.cpp @@ -19,7 +19,9 @@ int main(void) { K k; std::vector<Point_d> results; - Gudhi::subsampling::choose_n_farthest_points(k, points, 100, std::back_inserter(results)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 100, + Gudhi::subsampling::random_starting_point, + std::back_inserter(results)); std::cout << "Before sparsification: " << points.size() << " points.\n"; std::cout << "After sparsification: " << results.size() << " points.\n"; diff --git a/src/Subsampling/example/example_custom_kernel.cpp b/src/Subsampling/example/example_custom_kernel.cpp index 25b5bf6c..2d42bdde 100644 --- a/src/Subsampling/example/example_custom_kernel.cpp +++ b/src/Subsampling/example/example_custom_kernel.cpp @@ -54,7 +54,9 @@ int main(void) { std::vector<Point_d> points = {0, 1, 2, 3}; std::vector<Point_d> results; - Gudhi::subsampling::choose_n_farthest_points(k, points, 2, std::back_inserter(results)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 2, + Gudhi::subsampling::random_starting_point, + std::back_inserter(results)); std::cout << "Before sparsification: " << points.size() << " points.\n"; std::cout << "After sparsification: " << results.size() << " points.\n"; std::cout << "Result table: {" << results[0] << "," << results[1] << "}\n"; diff --git a/src/Subsampling/include/gudhi/choose_n_farthest_points.h b/src/Subsampling/include/gudhi/choose_n_farthest_points.h index 5e908090..86500b28 100644 --- a/src/Subsampling/include/gudhi/choose_n_farthest_points.h +++ b/src/Subsampling/include/gudhi/choose_n_farthest_points.h @@ -25,16 +25,9 @@ #include <boost/range.hpp> -#include <gudhi/Kd_tree_search.h> - -#include <gudhi/Clock.h> - -#include <CGAL/Search_traits.h> -#include <CGAL/Search_traits_adapter.h> -#include <CGAL/Fuzzy_sphere.h> +#include <gudhi/Null_output_iterator.h> #include <iterator> -#include <algorithm> // for sort #include <vector> #include <random> #include <limits> // for numeric_limits<> @@ -43,36 +36,51 @@ namespace Gudhi { namespace subsampling { +/** + * \ingroup subsampling + */ +enum : std::size_t { +/** + * Argument for `choose_n_farthest_points` to indicate that the starting point should be picked randomly. + */ + random_starting_point = std::size_t(-1) +}; + /** * \ingroup subsampling * \brief Subsample by a greedy strategy of iteratively adding the farthest point from the * current chosen point set to the subsampling. - * The iteration starts with the landmark `starting point`. + * The iteration starts with the landmark `starting point` or, if `starting point==random_starting_point`, with a random landmark. * \tparam Kernel must provide a type Kernel::Squared_distance_d which is a model of the * concept <a target="_blank" - * href="http://doc.cgal.org/latest/Kernel_d/classKernel__d_1_1Squared__distance__d.html">Kernel_d::Squared_distance_d</a> - * concept. - * It must also contain a public member 'squared_distance_d_object' of this type. + * href="http://doc.cgal.org/latest/Kernel_d/classKernel__d_1_1Squared__distance__d.html">Kernel_d::Squared_distance_d</a> (despite the name, taken from CGAL, this can be any kind of metric or proximity measure). + * It must also contain a public member `squared_distance_d_object()` that returns an object of this type. * \tparam Point_range Range whose value type is Kernel::Point_d. It must provide random-access * via `operator[]` and the points should be stored contiguously in memory. - * \tparam OutputIterator Output iterator whose value type is Kernel::Point_d. - * \details It chooses `final_size` points from a random access range `input_pts` and - * outputs it in the output iterator `output_it`. + * \tparam PointOutputIterator Output iterator whose value type is Kernel::Point_d. + * \tparam DistanceOutputIterator Output iterator for distances. + * \details It chooses `final_size` points from a random access range + * `input_pts` and outputs them in the output iterator `output_it`. It also + * outputs the distance from each of those points to the set of previous + * points in `dist_it`. * @param[in] k A kernel object. * @param[in] input_pts Const reference to the input points. * @param[in] final_size The size of the subsample to compute. * @param[in] starting_point The seed in the farthest point algorithm. - * @param[out] output_it The output iterator. + * @param[out] output_it The output iterator for points. + * @param[out] dist_it The optional output iterator for distances. * */ template < typename Kernel, typename Point_range, -typename OutputIterator> +typename PointOutputIterator, +typename DistanceOutputIterator = Null_output_iterator> void choose_n_farthest_points(Kernel const &k, Point_range const &input_pts, std::size_t final_size, std::size_t starting_point, - OutputIterator output_it) { + PointOutputIterator output_it, + DistanceOutputIterator dist_it = {}) { std::size_t nb_points = boost::size(input_pts); if (final_size > nb_points) final_size = nb_points; @@ -81,6 +89,14 @@ void choose_n_farthest_points(Kernel const &k, if (final_size < 1) return; + if (starting_point == random_starting_point) { + // Choose randomly the first landmark + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<std::size_t> dis(0, (input_pts.size() - 1)); + starting_point = dis(gen); + } + typename Kernel::Squared_distance_d sqdist = k.squared_distance_d_object(); std::size_t current_number_of_landmarks = 0; // counter for landmarks @@ -92,6 +108,7 @@ void choose_n_farthest_points(Kernel const &k, for (current_number_of_landmarks = 0; current_number_of_landmarks != final_size; current_number_of_landmarks++) { // curr_max_w at this point is the next landmark *output_it++ = input_pts[curr_max_w]; + *dist_it++ = dist_to_L[curr_max_w]; std::size_t i = 0; for (auto& p : input_pts) { double curr_dist = sqdist(p, *(std::begin(input_pts) + curr_max_w)); @@ -109,47 +126,6 @@ void choose_n_farthest_points(Kernel const &k, } } -/** - * \ingroup subsampling - * \brief Subsample by a greedy strategy of iteratively adding the farthest point from the - * current chosen point set to the subsampling. - * The iteration starts with a random landmark. - * \tparam Kernel must provide a type Kernel::Squared_distance_d which is a model of the - * concept <a target="_blank" - * href="http://doc.cgal.org/latest/Kernel_d/classKernel__d_1_1Squared__distance__d.html">Kernel_d::Squared_distance_d</a> - * concept. - * It must also contain a public member 'squared_distance_d_object' of this type. - * \tparam Point_range Range whose value type is Kernel::Point_d. It must provide random-access - * via `operator[]` and the points should be stored contiguously in memory. - * \tparam OutputIterator Output iterator whose value type is Kernel::Point_d. - * \details It chooses `final_size` points from a random access range `input_pts` and - * outputs it in the output iterator `output_it`. - * @param[in] k A kernel object. - * @param[in] input_pts Const reference to the input points. - * @param[in] final_size The size of the subsample to compute. - * @param[out] output_it The output iterator. - * - */ -template < typename Kernel, -typename Point_range, -typename OutputIterator> -void choose_n_farthest_points(Kernel const& k, - Point_range const &input_pts, - unsigned final_size, - OutputIterator output_it) { - // Tests to the limit - if ((final_size < 1) || (input_pts.size() == 0)) - return; - - // Choose randomly the first landmark - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(0, (input_pts.size() - 1)); - std::size_t starting_point = dis(gen); - - choose_n_farthest_points(k, input_pts, final_size, starting_point, output_it); -} - } // namespace subsampling } // namespace Gudhi diff --git a/src/Subsampling/test/test_choose_n_farthest_points.cpp b/src/Subsampling/test/test_choose_n_farthest_points.cpp index 0bc0dff4..ee9d4c77 100644 --- a/src/Subsampling/test/test_choose_n_farthest_points.cpp +++ b/src/Subsampling/test/test_choose_n_farthest_points.cpp @@ -25,7 +25,7 @@ // #endif #define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE "witness_complex_points" +#define BOOST_TEST_MODULE Subsampling - test choose_n_farthest_points #include <boost/test/unit_test.hpp> #include <boost/mpl/list.hpp> @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_choose_farthest_point, Kernel, list_of_tested landmarks.clear(); Kernel k; - Gudhi::subsampling::choose_n_farthest_points(k, points, 100, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 100, Gudhi::subsampling::random_starting_point, std::back_inserter(landmarks)); BOOST_CHECK(landmarks.size() == 100); for (auto landmark : landmarks) @@ -70,34 +70,45 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_choose_farthest_point_limits, Kernel, list_of typedef typename Kernel::FT FT; typedef typename Kernel::Point_d Point_d; std::vector< Point_d > points, landmarks; + std::vector< FT > distances; landmarks.clear(); Kernel k; // Choose -1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + landmarks.clear(); distances.clear(); // Choose 0 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 0, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 0, -1, std::back_inserter(landmarks), std::back_inserter(distances)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + landmarks.clear(); distances.clear(); // Choose 1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 1, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + landmarks.clear(); distances.clear(); std::vector<FT> point({0.0, 0.0, 0.0, 0.0}); points.push_back(Point_d(point.begin(), point.end())); - // Choose -1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, std::back_inserter(landmarks)); - BOOST_CHECK(landmarks.size() == 1); - landmarks.clear(); + // Choose -1 farthest points in a one point cloud + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 1 && distances.size() == 1); + BOOST_CHECK(distances[0] == std::numeric_limits<FT>::infinity()); + landmarks.clear(); distances.clear(); // Choose 0 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 0, std::back_inserter(landmarks)); - BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + Gudhi::subsampling::choose_n_farthest_points(k, points, 0, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 0 && distances.size() == 0); + landmarks.clear(); distances.clear(); // Choose 1 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 1, std::back_inserter(landmarks)); - BOOST_CHECK(landmarks.size() == 1); - landmarks.clear(); + Gudhi::subsampling::choose_n_farthest_points(k, points, 1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 1 && distances.size() == 1); + BOOST_CHECK(distances[0] == std::numeric_limits<FT>::infinity()); + landmarks.clear(); distances.clear(); + std::vector<FT> point2({1.0, 0.0, 0.0, 0.0}); + points.push_back(Point_d(point2.begin(), point2.end())); + // Choose all farthest points in a one point cloud + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 2 && distances.size() == 2); + BOOST_CHECK(distances[0] == std::numeric_limits<FT>::infinity()); + BOOST_CHECK(distances[1] == 1); + landmarks.clear(); distances.clear(); } diff --git a/src/cmake/modules/GUDHI_third_party_libraries.txt b/src/cmake/modules/GUDHI_third_party_libraries.txt index 75f73537..2ddc9f1f 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.txt +++ b/src/cmake/modules/GUDHI_third_party_libraries.txt @@ -1,6 +1,6 @@ # This files manage third party libraries required by GUDHI -find_package(Boost REQUIRED COMPONENTS system filesystem unit_test_framework chrono timer date_time program_options thread REQUIRED) +find_package(Boost REQUIRED COMPONENTS system filesystem unit_test_framework chrono timer date_time program_options thread) if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This program requires Boost and will not be compiled.") @@ -105,3 +105,49 @@ LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) message(STATUS "boost include dirs:" ${Boost_INCLUDE_DIRS}) message(STATUS "boost library dirs:" ${Boost_LIBRARY_DIRS}) + +macro( find_the_lib placeholder THE_LIBS ) + set (THE_LIB_WE_FOUND "NO") + foreach(THE_LIB ${THE_LIBS}) + if(EXISTS ${THE_LIB}) + get_filename_component(THE_LIB_WE ${THE_LIB} NAME_WE) + if (NOT THE_LIB_WE_FOUND) + set (THE_LIB_WE_FOUND "YES") + set(returnValue "${THE_LIB_WE}") + endif(NOT THE_LIB_WE_FOUND) + endif(EXISTS ${THE_LIB}) + endforeach(THE_LIB ${THE_LIBS}) +endmacro( find_the_lib ) + +# Find the correct Python interpreter. +# Can be set with -DPYTHON_EXECUTABLE=/usr/bin/python3 or -DPython_ADDITIONAL_VERSIONS=3 for instance. +if(PYTHON_EXECUTABLE) + if(NOT EXISTS "${PYTHON_EXECUTABLE}") + message(FATAL_ERROR "ERROR: ${PYTHON_EXECUTABLE} does not exist.") + endif(NOT EXISTS "${PYTHON_EXECUTABLE}") +endif(PYTHON_EXECUTABLE) +find_package(PythonInterp) + +if(NOT GUDHI_CYTHON_PATH) + message(FATAL_ERROR "ERROR: GUDHI_CYTHON_PATH is not valid.") +endif(NOT GUDHI_CYTHON_PATH) + +if(PYTHONINTERP_FOUND) + # Default found version 2 + if(PYTHON_VERSION_MAJOR EQUAL 2) + FIND_PROGRAM(CYTHON_PATH cython) + # Unitary tests are available through py.test + find_program( PYTEST_PATH py.test ) + # Documentation generation is available through sphinx + find_program( SPHINX_PATH sphinx-build ) + elseif(PYTHON_VERSION_MAJOR EQUAL 3) + FIND_PROGRAM(CYTHON_PATH cython3) + # Unitary tests are available through py.test + find_program( PYTEST_PATH py.test ) + # Documentation generation is available through sphinx + set(SPHINX_PATH "${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/doc/python3-sphinx-build") + else() + message(FATAL_ERROR "ERROR: Try to compile the Cython interface. Python version ${PYTHON_VERSION_STRING} is not valid.") + endif(PYTHON_VERSION_MAJOR EQUAL 2) +endif(PYTHONINTERP_FOUND) + diff --git a/src/common/include/gudhi/Null_output_iterator.h b/src/common/include/gudhi/Null_output_iterator.h new file mode 100644 index 00000000..42e6e449 --- /dev/null +++ b/src/common/include/gudhi/Null_output_iterator.h @@ -0,0 +1,48 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Marc Glisse + * + * Copyright (C) 2017 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef NULL_OUTPUT_ITERATOR_H_ +#define NULL_OUTPUT_ITERATOR_H_ + +#include <iterator> + +namespace Gudhi { + +/** An output iterator that ignores whatever it is given. */ +struct Null_output_iterator { + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + Null_output_iterator& operator++() {return *this;} + Null_output_iterator operator++(int) {return *this;} + struct proxy { + template<class T> + proxy& operator=(T&&){return *this;} + }; + proxy operator*()const{return {};} +}; +} // namespace Gudhi + +#endif // NULL_OUTPUT_ITERATOR_H_ diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index 22747637..f6e2ab5a 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -27,6 +27,8 @@ #include <type_traits> // for std::decay #include <iterator> // for std::begin, std::end +namespace Gudhi { + /** @file * @brief Global distance functions */ @@ -48,4 +50,6 @@ class Euclidean_distance { } }; +} // namespace Gudhi + #endif // DISTANCE_FUNCTIONS_H_ diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 2131505d..51c208aa 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -1,225 +1,284 @@ cmake_minimum_required(VERSION 2.8) project(Cython) -macro( find_the_lib placeholder THE_LIBS ) - set (THE_LIB_WE_FOUND "NO") - foreach(THE_LIB ${THE_LIBS}) - if(EXISTS ${THE_LIB}) - get_filename_component(THE_LIB_WE ${THE_LIB} NAME_WE) - if (NOT THE_LIB_WE_FOUND) - set (THE_LIB_WE_FOUND "YES") - set(returnValue "${THE_LIB_WE}") - endif(NOT THE_LIB_WE_FOUND) - endif(EXISTS ${THE_LIB}) - endforeach(THE_LIB ${THE_LIBS}) -endmacro( find_the_lib ) - -FIND_PROGRAM( PYTHON_PATH python ) -FIND_PROGRAM( CYTHON_PATH cython ) - -if(PYTHON_PATH AND CYTHON_PATH) - find_package(Boost REQUIRED COMPONENTS system REQUIRED) - - if(NOT Boost_FOUND) - message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") - else(NOT Boost_FOUND) - - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") - if(WIN32) - set( returnValue "" ) - find_the_lib (${returnValue} ${Boost_SYSTEM_LIBRARY}) - set(BOOST_SYSTEM_LIB_NAME ${returnValue}) - else() - set(BOOST_SYSTEM_LIB_NAME "boost_system") - endif() - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'${BOOST_SYSTEM_LIB_NAME}', ") - - # Gudhi and CGAL compilation option - if(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") - else(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") - endif(MSVC) - if(CMAKE_COMPILER_IS_GNUCXX) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") - endif(CMAKE_COMPILER_IS_GNUCXX) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") - endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - if (DEBUG_TRACES) - # For programs to be more verbose - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") - endif() - - find_package(Eigen3 3.1.0) - - if (EIGEN3_FOUND) - # No problem, even if no CGAL found - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") - endif (EIGEN3_FOUND) - - # Copy recursively include, cython, example, doc and test repositories before packages finding - # Some tests and doc files are removed in case some packages are not found - file(COPY include DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY cython DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY example DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY test DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY doc DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - # Developper version for doc images - file(GLOB GUDHI_DEV_DOC_IMAGES "${CMAKE_SOURCE_DIR}/src/*/doc/*.png") - file(COPY ${GUDHI_DEV_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - file(GLOB GUDHI_DEV_DOC_IMAGES "${CMAKE_SOURCE_DIR}/src/*/doc/*.svg") - file(COPY ${GUDHI_DEV_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - # User version for doc images - file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.png") - file(COPY ${GUDHI_USER_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.svg") - file(COPY ${GUDHI_USER_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") - # Biblio - file(GLOB GUDHI_BIB_FILES "${CMAKE_SOURCE_DIR}/biblio/*.bib") - file(COPY ${GUDHI_BIB_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - # Cubical complex perseus doc example - file(GLOB GUDHI_CUBICAL_PERSEUS_FILES "${CMAKE_SOURCE_DIR}/data/bitmap/*cubicalcomplexdoc.txt") - file(COPY ${GUDHI_CUBICAL_PERSEUS_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - file(COPY "${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - # Persistence graphical tools examples - file(COPY "${CMAKE_SOURCE_DIR}/data/bitmap/3d_torus.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - file(COPY "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") - - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # If CGAL_VERSION >= 4.8.1, include subsampling - set(GUDHI_CYTHON_SUBSAMPLING "include 'cython/subsampling.pyx'") - set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include 'cython/tangential_complex.pyx'") - set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include 'cython/bottleneck_distance.pyx'") - else (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # Remove subsampling unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_subsampling.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_user.rst") - # Remove tangential complex and bottleneck unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_tangential_complex.py) - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_bottleneck_distance.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_user.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_user.rst") - endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) - if (NOT CGAL_VERSION VERSION_LESS 4.7.0) - # If CGAL_VERSION >= 4.7.0, include alpha - set(GUDHI_CYTHON_ALPHA_COMPLEX "include 'cython/alpha_complex.pyx'") - else (NOT CGAL_VERSION VERSION_LESS 4.7.0) - # Remove alpha complex unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_alpha_complex.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_sum.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_user.rst") - endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) - if (NOT CGAL_VERSION VERSION_LESS 4.6.0) - # If CGAL_VERSION >= 4.6.0, include euclidean versions of witness complex - set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX - "include 'cython/euclidean_witness_complex.pyx'\ninclude 'cython/euclidean_strong_witness_complex.pyx'\n") - else (NOT CGAL_VERSION VERSION_LESS 4.6.0) - # Remove alpha complex unitary tests - file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_euclidean_witness_complex.py) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/euclidean_witness_complex_ref.rst") - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/euclidean_strong_witness_complex_ref.rst") - endif (NOT CGAL_VERSION VERSION_LESS 4.6.0) - - if(CGAL_FOUND) - # Add CGAL compilation args - if(CGAL_HEADER_ONLY) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") - else(CGAL_HEADER_ONLY) - if(WIN32) - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL-vc140-mt-4.7', ") - else(WIN32) - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL', ") - endif(WIN32) - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") - endif(CGAL_HEADER_ONLY) - # GMP and GMPXX are not required, but if present, CGAL will link with them. - if(GMP_FOUND) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") - if(WIN32) - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'libgmp-10', ") - else(WIN32) - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmp', ") - endif(WIN32) - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") - if(GMPXX_FOUND) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmpxx', ") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") - endif(GMPXX_FOUND) - endif(GMP_FOUND) - endif(CGAL_FOUND) - - # Specific for Mac - if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-mmacosx-version-min=10.9', ") - set(GUDHI_CYTHON_EXTRA_LINK_ARGS "${GUDHI_CYTHON_EXTRA_LINK_ARGS}'-mmacosx-version-min=10.9', ") - endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - # Loop on INCLUDE_DIRECTORIES PROPERTY - get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) - foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") - endforeach() - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") - - if (TBB_FOUND) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") - set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'tbb', 'tbbmalloc', ") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") - endif() - - # Generate cythonize_gudhi.py file to cythonize Gudhi - configure_file(cythonize_gudhi.py.in "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" @ONLY) - # Generate gudhi.pyx - Gudhi cython file - configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) - - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" +if(CYTHON_PATH) + message("${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_PATH} - py.test is ${PYTEST_PATH} - Sphinx is ${SPHINX_PATH}") + + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + if(WIN32) + set( returnValue "" ) + find_the_lib (${returnValue} ${Boost_SYSTEM_LIBRARY}) + set(BOOST_SYSTEM_LIB_NAME ${returnValue}) + else() + set(BOOST_SYSTEM_LIB_NAME "boost_system") + endif() + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'${BOOST_SYSTEM_LIB_NAME}', ") + + # Gudhi and CGAL compilation option + if(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") + else(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") + endif(MSVC) + if(CMAKE_COMPILER_IS_GNUCXX) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") + endif(CMAKE_COMPILER_IS_GNUCXX) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") + endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + if (DEBUG_TRACES) + # For programs to be more verbose + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") + endif() + + if (EIGEN3_FOUND) + # No problem, even if no CGAL found + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") + endif (EIGEN3_FOUND) + + # Copy recursively include, cython, example, doc and test repositories before packages finding + # Some tests and doc files are removed in case some packages are not found + file(COPY include DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + file(COPY cython DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + file(COPY example DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + file(COPY test DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + file(COPY doc DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + # Developper version for doc images + file(GLOB GUDHI_DEV_DOC_IMAGES "${CMAKE_SOURCE_DIR}/src/*/doc/*.png") + file(COPY ${GUDHI_DEV_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") + file(GLOB GUDHI_DEV_DOC_IMAGES "${CMAKE_SOURCE_DIR}/src/*/doc/*.svg") + file(COPY ${GUDHI_DEV_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") + # User version for doc images + file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.png") + file(COPY ${GUDHI_USER_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") + file(GLOB GUDHI_USER_DOC_IMAGES "${CMAKE_SOURCE_DIR}/doc/*/*.svg") + file(COPY ${GUDHI_USER_DOC_IMAGES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/img") + # Biblio + file(GLOB GUDHI_BIB_FILES "${CMAKE_SOURCE_DIR}/biblio/*.bib") + file(COPY ${GUDHI_BIB_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") + # Cubical complex perseus doc example + file(GLOB GUDHI_CUBICAL_PERSEUS_FILES "${CMAKE_SOURCE_DIR}/data/bitmap/*cubicalcomplexdoc.txt") + file(COPY ${GUDHI_CUBICAL_PERSEUS_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") + file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") + file(COPY "${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") + # Persistence graphical tools examples + file(COPY "${CMAKE_SOURCE_DIR}/data/bitmap/3d_torus.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") + file(COPY "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/") + + if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + # If CGAL_VERSION >= 4.8.1, include subsampling + set(GUDHI_CYTHON_SUBSAMPLING "include 'cython/subsampling.pyx'") + set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include 'cython/tangential_complex.pyx'") + set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include 'cython/bottleneck_distance.pyx'") + else (NOT CGAL_VERSION VERSION_LESS 4.8.1) + # Remove subsampling unitary tests + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_subsampling.py) + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_ref.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_sum.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/subsampling_user.rst") + # Remove tangential complex and bottleneck unitary tests + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_tangential_complex.py) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_bottleneck_distance.py) + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_ref.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_sum.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/bottleneck_distance_user.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_ref.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_sum.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/tangential_complex_user.rst") + endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_VERSION VERSION_LESS 4.7.0) + # If CGAL_VERSION >= 4.7.0, include alpha + set(GUDHI_CYTHON_ALPHA_COMPLEX "include 'cython/alpha_complex.pyx'") + else (NOT CGAL_VERSION VERSION_LESS 4.7.0) + # Remove alpha complex unitary tests + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_alpha_complex.py) + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_ref.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_sum.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/alpha_complex_user.rst") + endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) + if (NOT CGAL_VERSION VERSION_LESS 4.6.0) + # If CGAL_VERSION >= 4.6.0, include euclidean versions of witness complex + set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX + "include 'cython/euclidean_witness_complex.pyx'\ninclude 'cython/euclidean_strong_witness_complex.pyx'\n") + else (NOT CGAL_VERSION VERSION_LESS 4.6.0) + # Remove alpha complex unitary tests + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_euclidean_witness_complex.py) + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/euclidean_witness_complex_ref.rst") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doc/euclidean_strong_witness_complex_ref.rst") + endif (NOT CGAL_VERSION VERSION_LESS 4.6.0) + + if(CGAL_FOUND) + # Add CGAL compilation args + if(CGAL_HEADER_ONLY) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") + else(CGAL_HEADER_ONLY) + if(WIN32) + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL-vc140-mt-4.7', ") + else(WIN32) + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL', ") + endif(WIN32) + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") + endif(CGAL_HEADER_ONLY) + # GMP and GMPXX are not required, but if present, CGAL will link with them. + if(GMP_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") + if(WIN32) + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'libgmp-10', ") + else(WIN32) + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmp', ") + endif(WIN32) + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") + if(GMPXX_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmpxx', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") + endif(GMPXX_FOUND) + endif(GMP_FOUND) + endif(CGAL_FOUND) + + # Specific for Mac + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-mmacosx-version-min=10.12', ") + set(GUDHI_CYTHON_EXTRA_LINK_ARGS "${GUDHI_CYTHON_EXTRA_LINK_ARGS}'-mmacosx-version-min=10.12', ") + endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + + # Loop on INCLUDE_DIRECTORIES PROPERTY + get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") + endforeach() + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") + + if (TBB_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'tbb', 'tbbmalloc', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") + endif() + + # set sphinx-build in make files + configure_file(doc/Makefile.in "${CMAKE_CURRENT_BINARY_DIR}/doc/Makefile" @ONLY) + configure_file(doc/make.bat.in "${CMAKE_CURRENT_BINARY_DIR}/doc/make.bat" @ONLY) + + # Generate cythonize_gudhi.py file to cythonize Gudhi + configure_file(cythonize_gudhi.py.in "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" @ONLY) + # Generate gudhi.pyx - Gudhi cython file + configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" "build_ext" "--inplace") + + add_custom_target(cython ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") + + if(UNIX) + set( ENV{PYTHONPATH} $ENV{PYTHONPATH}:${CMAKE_CURRENT_BINARY_DIR}/ ) + endif(UNIX) + + # Test examples + add_test(NAME alpha_complex_from_points_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/alpha_complex_from_points_example.py") + set_tests_properties(alpha_complex_from_points_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) + set_tests_properties(alpha_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME alpha_rips_persistence_bottleneck_distance_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" + -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) + set_tests_properties(alpha_rips_persistence_bottleneck_distance_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME bottleneck_basic_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/bottleneck_basic_example.py") + set_tests_properties(bottleneck_basic_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_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) + set_tests_properties(euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_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) + set_tests_properties(euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" + --no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) + set_tests_properties(periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME random_cubical_complex_persistence_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/random_cubical_complex_persistence_example.py" + 10 10 10) + set_tests_properties(random_cubical_complex_persistence_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) + set_tests_properties(rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3) + set_tests_properties(rips_complex_diagram_persistence_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME rips_complex_from_points_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/rips_complex_from_points_example.py) + set_tests_properties(rips_complex_from_points_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME simplex_tree_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/simplex_tree_example.py) + set_tests_properties(simplex_tree_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) + set_tests_properties(tangential_complex_plain_homology_from_off_file_example_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + add_test(NAME witness_complex_from_nearest_landmark_table_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/example/witness_complex_from_nearest_landmark_table.py) + set_tests_properties(witness_complex_from_nearest_landmark_table_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + + # Unitary tests are available through py.test + if(PYTEST_PATH) + add_test( + NAME gudhi_cython_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND python "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" "build_ext" "--inplace") - - add_custom_target(cython ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") - - if(UNIX) - set( ENV{PYTHONPATH} $ENV{PYTHONPATH}:${CMAKE_CURRENT_BINARY_DIR}/ ) - endif(UNIX) - - # Unitary tests are available through py.test - find_program( PYTEST_PATH py.test ) - if(PYTEST_PATH) - add_test( - NAME gudhi_cython_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTEST_PATH}) - set_tests_properties(gudhi_cython_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") - endif(PYTEST_PATH) - - # Documentation generation is available through sphinx - find_program( SPHINX_PATH sphinx-build ) - if(SPHINX_PATH) - if (UNIX) - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMAND make html doctest) - else (UNIX) - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc - COMMAND make.bat html) - endif (UNIX) - endif(SPHINX_PATH) - endif(NOT Boost_FOUND) -endif(PYTHON_PATH AND CYTHON_PATH) + COMMAND ${PYTHON_EXECUTABLE} "${PYTEST_PATH}") + set_tests_properties(gudhi_cython_py_test PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}") + endif(PYTEST_PATH) + + # Documentation generation is available through sphinx + if(SPHINX_PATH) + if (UNIX) + add_custom_target(sphinx + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMAND make html doctest) + else (UNIX) + add_custom_target(sphinx + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc + COMMAND make.bat html doctest) + endif (UNIX) + endif(SPHINX_PATH) +endif(CYTHON_PATH) diff --git a/src/cython/cython/alpha_complex.pyx b/src/cython/cython/alpha_complex.pyx index da537c2e..a0e8f9b7 100644 --- a/src/cython/cython/alpha_complex.pyx +++ b/src/cython/cython/alpha_complex.pyx @@ -78,7 +78,7 @@ cdef class AlphaComplex: def __cinit__(self, points=None, off_file=''): if off_file is not '': if os.path.isfile(off_file): - self.thisptr = new Alpha_complex_interface(off_file, True) + self.thisptr = new Alpha_complex_interface(str.encode(off_file), True) else: print("file " + off_file + " not found.") else: diff --git a/src/cython/cython/bottleneck_distance.pyx b/src/cython/cython/bottleneck_distance.pyx index ee3e6ef9..9fb377ff 100644 --- a/src/cython/cython/bottleneck_distance.pyx +++ b/src/cython/cython/bottleneck_distance.pyx @@ -33,7 +33,7 @@ cdef extern from "Bottleneck_distance_interface.h" namespace "Gudhi::persistence double bottleneck(vector[pair[double, double]], vector[pair[double, double]], double) double bottleneck(vector[pair[double, double]], vector[pair[double, double]]) -def bottleneck_distance(diagram_1, diagram_2, e=0.0): +def bottleneck_distance(diagram_1, diagram_2, e=None): """This function returns the point corresponding to a given vertex. :param diagram_1: The first diagram. @@ -53,7 +53,9 @@ def bottleneck_distance(diagram_1, diagram_2, e=0.0): :rtype: float :returns: the bottleneck distance. """ - if e is 0.0: + if e is None: + # Default value is the smallest double value (not 0, 0 is for exact version) return bottleneck(diagram_1, diagram_2) else: + # Can be 0 for exact version return bottleneck(diagram_1, diagram_2, e) diff --git a/src/cython/cython/cubical_complex.pyx b/src/cython/cython/cubical_complex.pyx index e1344f49..ffc85130 100644 --- a/src/cython/cython/cubical_complex.pyx +++ b/src/cython/cython/cubical_complex.pyx @@ -60,16 +60,16 @@ cdef class CubicalComplex: def __init__(self, dimensions=None, top_dimensional_cells=None, perseus_file=''): """CubicalComplex constructor from dimensions and - top_dimensional_cells or from a perseus file style name. + top_dimensional_cells or from a Perseus-style file name. :param dimensions: A list of number of top dimensional cells. :type dimensions: list of int - :param top_dimensional_cells: A list of top dimensional cells. + :param top_dimensional_cells: A list of cells filtration values. :type top_dimensional_cells: list of double Or - :param perseus_file: A perseus file style name. + :param perseus_file: A Perseus-style file name. :type perseus_file: string """ @@ -80,12 +80,12 @@ cdef class CubicalComplex: self.thisptr = new Bitmap_cubical_complex_base_interface(dimensions, top_dimensional_cells) elif (dimensions is None) and (top_dimensional_cells is None) and (perseus_file is not ''): if os.path.isfile(perseus_file): - self.thisptr = new Bitmap_cubical_complex_base_interface(perseus_file) + self.thisptr = new Bitmap_cubical_complex_base_interface(str.encode(perseus_file)) else: print("file " + perseus_file + " not found.") else: print("CubicalComplex can be constructed from dimensions and " - "top_dimensional_cells or from a perseus file style name.") + "top_dimensional_cells or from a Perseus-style file name.") def __dealloc__(self): if self.thisptr != NULL: diff --git a/src/cython/cython/off_reader.pyx b/src/cython/cython/off_reader.pyx index 78c37969..b6e107ef 100644 --- a/src/cython/cython/off_reader.pyx +++ b/src/cython/cython/off_reader.pyx @@ -43,7 +43,7 @@ def read_off(off_file=''): """ if off_file is not '': if os.path.isfile(off_file): - return read_points_from_OFF_file(off_file) + return read_points_from_OFF_file(str.encode(off_file)) else: print("file " + off_file + " not found.") diff --git a/src/cython/cython/periodic_cubical_complex.pyx b/src/cython/cython/periodic_cubical_complex.pyx index 1445d429..581c7b69 100644 --- a/src/cython/cython/periodic_cubical_complex.pyx +++ b/src/cython/cython/periodic_cubical_complex.pyx @@ -60,16 +60,16 @@ cdef class PeriodicCubicalComplex: def __init__(self, dimensions=None, top_dimensional_cells=None, perseus_file=''): """PeriodicCubicalComplex constructor from dimensions and - top_dimensional_cells or from a perseus file style name. + top_dimensional_cells or from a Perseus-style file name. :param dimensions: A list of number of top dimensional cells. :type dimensions: list of int - :param top_dimensional_cells: A list of top dimensional cells. + :param top_dimensional_cells: A list of cells filtration values. :type top_dimensional_cells: list of double Or - :param perseus_file: A perseus file style name. + :param perseus_file: A Perseus-style file name. :type perseus_file: string """ @@ -80,12 +80,12 @@ cdef class PeriodicCubicalComplex: self.thisptr = new Periodic_cubical_complex_base_interface(dimensions, top_dimensional_cells) elif (dimensions is None) and (top_dimensional_cells is None) and (perseus_file is not ''): if os.path.isfile(perseus_file): - self.thisptr = new Periodic_cubical_complex_base_interface(perseus_file) + self.thisptr = new Periodic_cubical_complex_base_interface(str.encode(perseus_file)) else: print("file " + perseus_file + " not found.") else: print("CubicalComplex can be constructed from dimensions and " - "top_dimensional_cells or from a perseus file style name.") + "top_dimensional_cells or from a Perseus-style file name.") def __dealloc__(self): if self.thisptr != NULL: diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx index 6bfb4482..ad9b0a4d 100644 --- a/src/cython/cython/rips_complex.pyx +++ b/src/cython/cython/rips_complex.pyx @@ -80,7 +80,7 @@ cdef class RipsComplex: def __cinit__(self, points=None, off_file='', distance_matrix=None, csv_file='', max_edge_length=float('inf')): if off_file is not '': if os.path.isfile(off_file): - self.thisptr = new Rips_complex_interface(off_file, + self.thisptr = new Rips_complex_interface(str.encode(off_file), max_edge_length, True, True) @@ -88,7 +88,7 @@ cdef class RipsComplex: print("file " + off_file + " not found.") elif csv_file is not '': if os.path.isfile(csv_file): - self.thisptr = new Rips_complex_interface(csv_file, + self.thisptr = new Rips_complex_interface(str.encode(csv_file), max_edge_length, False, True) diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx index 148227e1..9d40a8b5 100644 --- a/src/cython/cython/simplex_tree.pyx +++ b/src/cython/cython/simplex_tree.pyx @@ -46,9 +46,8 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": bint find_simplex(vector[int] simplex) bint insert_simplex_and_subfaces(vector[int] simplex, double filtration) - bint insert_simplex(vector[int] simplex, double filtration) - vector[pair[vector[int], double]] get_filtered_tree() - vector[pair[vector[int], double]] get_skeleton_tree(int dimension) + vector[pair[vector[int], double]] get_filtration() + vector[pair[vector[int], double]] get_skeleton(int dimension) vector[pair[vector[int], double]] get_star(vector[int] simplex) vector[pair[vector[int], double]] get_cofaces(vector[int] simplex, int dimension) @@ -103,14 +102,6 @@ cdef class SimplexTree: """ return self.pcohptr != NULL - def get_filtration(self): - """This function returns the main simplicial complex filtration value. - - :returns: The simplicial complex filtration value. - :rtype: float - """ - return self.thisptr.filtration() - def filtration(self, simplex): """This function returns the simplicial complex filtration value for a given N-simplex. @@ -137,7 +128,7 @@ cdef class SimplexTree: .. note:: This function must be launched before persistence, betti_numbers, - persistent_betti_numbers or get_filtered_tree after inserting or + persistent_betti_numbers or get_filtration after inserting or removing simplices. """ self.thisptr.initialize_filtration() @@ -197,24 +188,7 @@ cdef class SimplexTree: complex.push_back(i) return self.thisptr.find_simplex(complex) - def insert_simplex(self, simplex, filtration=0.0): - """This function inserts the given N-simplex with the given filtration - value (default value is '0.0'). - - :param simplex: The N-simplex to insert, represented by a list of - vertex. - :type simplex: list of int. - :param filtration: The filtration value of the simplex. - :type filtration: float. - :returns: true if the simplex was found, false otherwise. - :rtype: bool - """ - cdef vector[int] complex - for i in simplex: - complex.push_back(i) - return self.thisptr.insert_simplex(complex, <double>filtration) - - def insert_simplex_and_subfaces(self, simplex, filtration=0.0): + def insert(self, simplex, filtration=0.0): """This function inserts the given N-simplex and its subfaces with the given filtration value (default value is '0.0'). @@ -232,36 +206,36 @@ cdef class SimplexTree: return self.thisptr.insert_simplex_and_subfaces(complex, <double>filtration) - def get_filtered_tree(self): - """This function returns the tree sorted by increasing filtration - values. + def get_filtration(self): + """This function returns a list of all simplices with their given + filtration values. - :returns: The tree sorted by increasing filtration values. + :returns: The simplices sorted by increasing filtration values. :rtype: list of tuples(simplex, filtration) """ - cdef vector[pair[vector[int], double]] filtered_tree \ - = self.thisptr.get_filtered_tree() + cdef vector[pair[vector[int], double]] filtration \ + = self.thisptr.get_filtration() ct = [] - for filtered_complex in filtered_tree: + for filtered_complex in filtration: v = [] for vertex in filtered_complex.first: v.append(vertex) ct.append((v, filtered_complex.second)) return ct - def get_skeleton_tree(self, dimension): - """This function returns the tree skeleton of a maximum given - dimension. + def get_skeleton(self, dimension): + """This function returns the (simplices of the) skeleton of a maximum + given dimension. :param dimension: The skeleton dimension value. :type dimension: int. - :returns: The skeleton tree of a maximum dimension. + :returns: The (simplices of the) skeleton of a maximum dimension. :rtype: list of tuples(simplex, filtration) """ - cdef vector[pair[vector[int], double]] sk_tree \ - = self.thisptr.get_skeleton_tree(<int>dimension) + cdef vector[pair[vector[int], double]] skeletons \ + = self.thisptr.get_skeleton(<int>dimension) ct = [] - for filtered_complex in sk_tree: + for filtered_complex in skeletons: v = [] for vertex in filtered_complex.first: v.append(vertex) @@ -273,7 +247,7 @@ cdef class SimplexTree: :param simplex: The N-simplex, represented by a list of vertex. :type simplex: list of int. - :returns: The star tree of a simplex. + :returns: The (simplices of the) star of a simplex. :rtype: list of tuples(simplex, filtration) """ cdef vector[int] complex @@ -298,7 +272,7 @@ cdef class SimplexTree: :param codimension: The codimension. If codimension = 0, all cofaces are returned (equivalent of get_star function) :type codimension: int. - :returns: The coface tree of a simplex. + :returns: The (simplices of the) cofaces of a simplex :rtype: list of tuples(simplex, filtration) """ cdef vector[int] complex diff --git a/src/cython/cython/subsampling.pyx b/src/cython/cython/subsampling.pyx index a25d196d..894a4fbe 100644 --- a/src/cython/cython/subsampling.pyx +++ b/src/cython/cython/subsampling.pyx @@ -65,10 +65,10 @@ def choose_n_farthest_points(points=None, off_file='', nb_points=0, starting_poi if off_file is not '': if os.path.isfile(off_file): if starting_point is '': - return subsampling_n_farthest_points_from_file(off_file, + return subsampling_n_farthest_points_from_file(str.encode(off_file), nb_points) else: - return subsampling_n_farthest_points_from_file(off_file, + return subsampling_n_farthest_points_from_file(str.encode(off_file), nb_points, starting_point) else: @@ -101,7 +101,8 @@ def pick_n_random_points(points=None, off_file='', nb_points=0): """ if off_file is not '': if os.path.isfile(off_file): - return subsampling_n_random_points_from_file(off_file, nb_points) + return subsampling_n_random_points_from_file(str.encode(off_file), + nb_points) else: print("file " + off_file + " not found.") else: @@ -128,7 +129,7 @@ def sparsify_point_set(points=None, off_file='', min_squared_dist=0.0): """ if off_file is not '': if os.path.isfile(off_file): - return subsampling_sparsify_points_from_file(off_file, + return subsampling_sparsify_points_from_file(str.encode(off_file), min_squared_dist) else: print("file " + off_file + " not found.") diff --git a/src/cython/cython/tangential_complex.pyx b/src/cython/cython/tangential_complex.pyx index 52bd8111..d55bb050 100644 --- a/src/cython/cython/tangential_complex.pyx +++ b/src/cython/cython/tangential_complex.pyx @@ -70,7 +70,7 @@ cdef class TangentialComplex: def __cinit__(self, points=None, off_file=''): if off_file is not '': if os.path.isfile(off_file): - self.thisptr = new Tangential_complex_interface(off_file, True) + self.thisptr = new Tangential_complex_interface(str.encode(off_file), True) else: print("file " + off_file + " not found.") else: diff --git a/src/cython/doc/Makefile b/src/cython/doc/Makefile deleted file mode 100644 index be3ff7c4..00000000 --- a/src/cython/doc/Makefile +++ /dev/null @@ -1,181 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -f examples.inc - rm -rf $(BUILDDIR)/* - -# GUDHI specific : Examples.inc is generated with generate_examples.py (and deleted on clean) - -html: - ./generate_examples.py - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pouet.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pouet.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/pouet" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pouet" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/src/cython/doc/Makefile.in b/src/cython/doc/Makefile.in new file mode 100644 index 00000000..526350b3 --- /dev/null +++ b/src/cython/doc/Makefile.in @@ -0,0 +1,44 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = @SPHINX_PATH@ +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -f examples.inc + rm -rf $(BUILDDIR)/* + +# GUDHI specific : Examples.inc is generated with generate_examples.py (and deleted on clean) + +html: + ./generate_examples.py + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/src/cython/doc/alpha_complex_user.rst b/src/cython/doc/alpha_complex_user.rst index 68e53a77..2356944d 100644 --- a/src/cython/doc/alpha_complex_user.rst +++ b/src/cython/doc/alpha_complex_user.rst @@ -30,7 +30,7 @@ This example builds the Delaunay triangulation from the given points, and initia repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in simplex_tree.get_filtered_tree(): + for filtered_value in simplex_tree.get_filtration(): print(filtered_value) The output is: @@ -164,7 +164,7 @@ Then, it is asked to display information about the alpha complex: repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in simplex_tree.get_filtered_tree(): + for filtered_value in simplex_tree.get_filtration(): print(filtered_value) the program output is: diff --git a/src/cython/doc/bottleneck_distance_user.rst b/src/cython/doc/bottleneck_distance_user.rst index 3bc170f4..8c29d069 100644 --- a/src/cython/doc/bottleneck_distance_user.rst +++ b/src/cython/doc/bottleneck_distance_user.rst @@ -26,7 +26,7 @@ This example computes the bottleneck distance from 2 persistence diagrams: message = "Bottleneck distance approximation=" + repr(gudhi.bottleneck_distance(diag1, diag2, 0.1)) print(message) - message = "Bottleneck distance exact value=" + repr(gudhi.bottleneck_distance(diag1, diag2)) + message = "Bottleneck distance exact value=" + repr(gudhi.bottleneck_distance(diag1, diag2, 0)) print(message) The output is: diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst index e7d8c210..373e0717 100644 --- a/src/cython/doc/installation.rst +++ b/src/cython/doc/installation.rst @@ -4,12 +4,19 @@ Installation Compiling ********* -The library uses c++11 and requires `Boost <http://www.boost.org/>`_ with version -1.48.0 or more recent. It is a multi-platform library and compiles on Linux, -Mac OSX and Visual Studio 2015. +The library uses c++11 and requires `Boost <http://www.boost.org/>`_ with +version 1.48.0 or more recent. It is a multi-platform library and compiles on +Linux, Mac OSX and Visual Studio 2015. It also requires cmake to generate makefiles, and cython to compile the library. +On `Windows <https://wiki.python.org/moin/WindowsCompilers>`_ , only Python +3.5 and 3.6 are available because of the required Visual Studio version. + +On other systems, if you have several Python/cython installed, the version 2.X +will be used by default, but you can force it by adding +:code:`-DPython_ADDITIONAL_VERSIONS=3` to the cmake command. + GUDHI Cythonization =================== @@ -23,8 +30,6 @@ To build the GUDHI cython module, run the following commands in a terminal: cmake .. make cython -A list of examples is available here. - Test suites =========== @@ -33,9 +38,9 @@ following command in a terminal: .. code-block:: bash - cd /path-to-gudhi/build/src/cython + cd /path-to-gudhi/build/cython # For windows, you have to set PYTHONPATH environment variable - export PYTHONPATH='$PYTHONPATH:/path-to-gudhi/build/src/cython' + export PYTHONPATH='$PYTHONPATH:/path-to-gudhi/build/cython' py.test Documentation diff --git a/src/cython/doc/make.bat b/src/cython/doc/make.bat deleted file mode 100644 index ba009a90..00000000 --- a/src/cython/doc/make.bat +++ /dev/null @@ -1,246 +0,0 @@ -@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. xml to make Docutils-native XML files
- echo. pseudoxml to make pseudoxml-XML files for display purposes
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- del examples.inc
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-
-%SPHINXBUILD% 2> nul
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-:: GUDHI specific : Examples.inc is generated with generate_examples.py (and deleted on clean)
-
-if "%1" == "html" (
- generate_examples.py
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
-
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pouet.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pouet.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdf" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf
- cd %BUILDDIR%/..
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdfja" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf-ja
- cd %BUILDDIR%/..
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-if "%1" == "xml" (
- %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The XML files are in %BUILDDIR%/xml.
- goto end
-)
-
-if "%1" == "pseudoxml" (
- %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
- goto end
-)
-
-:end
diff --git a/src/cython/doc/make.bat.in b/src/cython/doc/make.bat.in new file mode 100644 index 00000000..ff1a6d56 --- /dev/null +++ b/src/cython/doc/make.bat.in @@ -0,0 +1,67 @@ +@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=@SPHINX_PATH@
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ del examples.inc
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+:: GUDHI specific : Examples.inc is generated with generate_examples.py (and deleted on clean)
+
+if "%1" == "html" (
+ generate_examples.py
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/src/cython/doc/python3-sphinx-build b/src/cython/doc/python3-sphinx-build new file mode 100755 index 00000000..44b94169 --- /dev/null +++ b/src/cython/doc/python3-sphinx-build @@ -0,0 +1,11 @@ +#!/usr/bin/python3 + +""" +Emulate sphinx-build for python3 +""" + +from sys import exit, argv +from sphinx import main + +if __name__ == '__main__': + exit(main(argv)) diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index 027c3bf7..c89409a0 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -60,7 +60,7 @@ Finally, it is asked to display information about the simplicial complex. repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in simplex_tree.get_filtered_tree(): + for filtered_value in simplex_tree.get_filtration(): print(filtered_value) When launching (Rips maximal distance between 2 points is 12.0, is expanded @@ -107,7 +107,7 @@ Finally, it is asked to display information about the Rips complex. repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in simplex_tree.get_filtered_tree(): + for filtered_value in simplex_tree.get_filtration(): print(filtered_value) the program output is: @@ -162,7 +162,7 @@ Finally, it is asked to display information about the simplicial complex. repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in simplex_tree.get_filtered_tree(): + for filtered_value in simplex_tree.get_filtration(): print(filtered_value) When launching (Rips maximal distance between 2 points is 12.0, is expanded @@ -209,7 +209,7 @@ Finally, it is asked to display information about the Rips complex. repr(simplex_tree.num_simplices()) + ' simplices - ' + \ repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in simplex_tree.get_filtered_tree(): + for filtered_value in simplex_tree.get_filtration(): print(filtered_value) the program output is: diff --git a/src/cython/doc/simplex_tree_user.rst b/src/cython/doc/simplex_tree_user.rst index 6b55c4e7..b2efca8b 100644 --- a/src/cython/doc/simplex_tree_user.rst +++ b/src/cython/doc/simplex_tree_user.rst @@ -35,16 +35,18 @@ Example import gudhi st = gudhi.SimplexTree() - if st.insert_simplex([0, 1]): + if st.insert([0, 1]): print("[0, 1] inserted") - if st.insert_simplex_and_subfaces([0, 1, 2], filtration=4.0): + if st.insert([0, 1, 2], filtration=4.0): print("[0, 1, 2] inserted") if st.find([0, 1]): print("[0, 1] found") - print("num_vertices=", st.num_vertices()) - print("num_simplices=", st.num_simplices()) - print("skeleton_tree(2) =") - for sk_value in st.get_skeleton_tree(2): + result_str = 'num_vertices=' + repr(st.num_vertices()) + print(result_str) + result_str = 'num_simplices=' + repr(st.num_simplices()) + print(result_str) + print("skeleton(2) =") + for sk_value in st.get_skeleton(2): print(sk_value) @@ -52,16 +54,16 @@ The output is: .. testoutput:: - [0, 1] inserted - [0, 1, 2] inserted - [0, 1] found - ('num_vertices=', 3) - ('num_simplices=', 7) - skeleton_tree(2) = - ([0, 1, 2], 4.0) - ([0, 1], 0.0) - ([0, 2], 4.0) - ([0], 0.0) - ([1, 2], 4.0) - ([1], 4.0) - ([2], 4.0) + [0, 1] inserted + [0, 1, 2] inserted + [0, 1] found + num_vertices=3 + num_simplices=7 + skeleton(2) = + ([0, 1, 2], 4.0) + ([0, 1], 0.0) + ([0, 2], 4.0) + ([0], 0.0) + ([1, 2], 4.0) + ([1], 0.0) + ([2], 4.0) diff --git a/src/cython/doc/tangential_complex_user.rst b/src/cython/doc/tangential_complex_user.rst index 6a7e6e41..24f68f85 100644 --- a/src/cython/doc/tangential_complex_user.rst +++ b/src/cython/doc/tangential_complex_user.rst @@ -133,7 +133,7 @@ This example builds the Tangential complex of point set read in an OFF file. ' - ' + repr(st.num_simplices()) + ' simplices - ' + \ repr(st.num_vertices()) + ' vertices.' print(result_str) - for filtered_value in st.get_filtered_tree(): + for filtered_value in st.get_filtration(): print(filtered_value) The output is: diff --git a/src/cython/example/alpha_complex_from_points_example.py b/src/cython/example/alpha_complex_from_points_example.py index 688edb65..7d6278ce 100755 --- a/src/cython/example/alpha_complex_from_points_example.py +++ b/src/cython/example/alpha_complex_from_points_example.py @@ -59,7 +59,7 @@ else: print("[4] Not found...") print("dimension=", simplex_tree.dimension()) -print("filtered_tree=", simplex_tree.get_filtered_tree()) +print("filtrations=", simplex_tree.get_filtration()) print("star([0])=", simplex_tree.get_star([0])) print("coface([0], 1)=", simplex_tree.get_cofaces([0], 1)) diff --git a/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py index 2474fc87..2371c36c 100755 --- a/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py @@ -32,7 +32,7 @@ __license__ = "GPL v3" parser = argparse.ArgumentParser(description='EuclideanStrongWitnessComplex creation from ' 'points read in a OFF file.', epilog='Example: ' - 'example/witness_complex_diagram_persistence_from_off_file_example.py ' + 'example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py ' '-f ../data/points/tore3D_300.off -a 1.0 -n 20 -d 2' '- Constructs a strong witness complex with the ' 'points from the given OFF file.') diff --git a/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py b/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py index 5a75417b..5748aa8a 100755 --- a/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py +++ b/src/cython/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py @@ -32,7 +32,7 @@ __license__ = "GPL v3" parser = argparse.ArgumentParser(description='EuclideanWitnessComplex creation from ' 'points read in a OFF file.', epilog='Example: ' - 'example/witness_complex_diagram_persistence_from_off_file_example.py ' + 'example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py ' '-f ../data/points/tore3D_300.off -a 1.0 -n 20 -d 2' '- Constructs a weak witness complex with the ' 'points from the given OFF file.') diff --git a/src/cython/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py b/src/cython/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py index db530161..00334121 100755 --- a/src/cython/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py +++ b/src/cython/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py @@ -49,7 +49,7 @@ def is_file_perseus(file): return False parser = argparse.ArgumentParser(description='Periodic cubical complex from a ' - 'perseus file style name.', + 'Perseus-style file name.', epilog='Example: ' './periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py' ' -f ../data/bitmap/CubicalTwoSphere.txt') diff --git a/src/cython/example/random_cubical_complex_persistence_example.py b/src/cython/example/random_cubical_complex_persistence_example.py index 1c55f777..c832d6bf 100755 --- a/src/cython/example/random_cubical_complex_persistence_example.py +++ b/src/cython/example/random_cubical_complex_persistence_example.py @@ -2,6 +2,7 @@ import gudhi import numpy +from functools import reduce import argparse import operator @@ -54,4 +55,4 @@ if dimension_multiplication > 1: print(cubical_complex.persistence(homology_coeff_field=2, min_persistence=0)) print("betti_numbers()=") - print(cubical_complex.betti_numbers())
\ No newline at end of file + print(cubical_complex.betti_numbers()) diff --git a/src/cython/example/rips_complex_from_points_example.py b/src/cython/example/rips_complex_from_points_example.py index 9b7fc79d..5d411b1a 100755 --- a/src/cython/example/rips_complex_from_points_example.py +++ b/src/cython/example/rips_complex_from_points_example.py @@ -35,6 +35,6 @@ rips = gudhi.RipsComplex(points=[[0, 0], [1, 0], [0, 1], [1, 1]], simplex_tree = rips.create_simplex_tree(max_dimension=1) -print("filtered_tree=", simplex_tree.get_filtered_tree()) +print("filtrations=", simplex_tree.get_filtration()) print("star([0])=", simplex_tree.get_star([0])) print("coface([0], 1)=", simplex_tree.get_cofaces([0], 1)) diff --git a/src/cython/example/simplex_tree_example.py b/src/cython/example/simplex_tree_example.py index bf5f17a2..3af20fcf 100755 --- a/src/cython/example/simplex_tree_example.py +++ b/src/cython/example/simplex_tree_example.py @@ -61,6 +61,6 @@ print("filtration[4, 2]=", st.filtration([4, 2])) print("num_simplices=", st.num_simplices()) print("num_vertices=", st.num_vertices()) -print("skeleton_tree[2]=", st.get_skeleton_tree(2)) -print("skeleton_tree[1]=", st.get_skeleton_tree(1)) -print("skeleton_tree[0]=", st.get_skeleton_tree(0)) +print("skeleton[2]=", st.get_skeleton(2)) +print("skeleton[1]=", st.get_skeleton(1)) +print("skeleton[0]=", st.get_skeleton(0)) diff --git a/src/cython/include/Rips_complex_interface.h b/src/cython/include/Rips_complex_interface.h index 1879bd74..6d813f4a 100644 --- a/src/cython/include/Rips_complex_interface.h +++ b/src/cython/include/Rips_complex_interface.h @@ -49,7 +49,7 @@ class Rips_complex_interface { if (euclidean) { // Rips construction where values is a vector of points rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(values, threshold, - Euclidean_distance()); + Gudhi::Euclidean_distance()); } else { // Rips construction where values is a distance matrix rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(values, threshold); @@ -61,7 +61,8 @@ class Rips_complex_interface { // Rips construction where file_name is an OFF file Gudhi::Points_off_reader<Point_d> off_reader(file_name); rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(off_reader.get_point_cloud(), - threshold, Euclidean_distance()); + threshold, + Gudhi::Euclidean_distance()); } else { // Rips construction where values is a distance matrix Distance_matrix distances = diff --git a/src/cython/include/Simplex_tree_interface.h b/src/cython/include/Simplex_tree_interface.h index 4266b3ef..45ce1916 100644 --- a/src/cython/include/Simplex_tree_interface.h +++ b/src/cython/include/Simplex_tree_interface.h @@ -52,29 +52,32 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> { return (Base::find(vh) != Base::null_simplex()); } + bool insert(const Simplex& simplex, Filtration_value filtration = 0) { + Insertion_result result = Base::insert_simplex_and_subfaces(simplex, filtration); + return (result.second); + } + + // Do not interface this function, only used in alpha complex interface for complex creation bool insert_simplex(const Simplex& simplex, Filtration_value filtration = 0) { Insertion_result result = Base::insert_simplex(simplex, filtration); - Base::initialize_filtration(); return (result.second); } + // Do not interface this function, only used in interface for complex creation bool insert_simplex_and_subfaces(const Simplex& simplex, Filtration_value filtration = 0) { Insertion_result result = Base::insert_simplex_and_subfaces(simplex, filtration); - Base::initialize_filtration(); return (result.second); } // Do not interface this function, only used in strong witness interface for complex creation bool insert_simplex(const std::vector<std::size_t>& complex, Filtration_value filtration = 0) { Insertion_result result = Base::insert_simplex(complex, filtration); - Base::initialize_filtration(); return (result.second); } // Do not interface this function, only used in strong witness interface for complex creation bool insert_simplex_and_subfaces(const std::vector<std::size_t>& complex, Filtration_value filtration = 0) { Insertion_result result = Base::insert_simplex_and_subfaces(complex, filtration); - Base::initialize_filtration(); return (result.second); } @@ -87,28 +90,29 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> { Base::initialize_filtration(); } - Complex get_filtered_tree() { - Complex filtered_tree; + Complex get_filtration() { + Base::initialize_filtration(); + Complex filtrations; for (auto f_simplex : Base::filtration_simplex_range()) { Simplex simplex; for (auto vertex : Base::simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - filtered_tree.push_back(std::make_pair(simplex, Base::filtration(f_simplex))); + filtrations.push_back(std::make_pair(simplex, Base::filtration(f_simplex))); } - return filtered_tree; + return filtrations; } - Complex get_skeleton_tree(int dimension) { - Complex skeleton_tree; + Complex get_skeleton(int dimension) { + Complex skeletons; for (auto f_simplex : Base::skeleton_simplex_range(dimension)) { Simplex simplex; for (auto vertex : Base::simplex_vertex_range(f_simplex)) { simplex.insert(simplex.begin(), vertex); } - skeleton_tree.push_back(std::make_pair(simplex, Base::filtration(f_simplex))); + skeletons.push_back(std::make_pair(simplex, Base::filtration(f_simplex))); } - return skeleton_tree; + return skeletons; } Complex get_star(const Simplex& simplex) { @@ -140,6 +144,7 @@ class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> { } void create_persistence(Gudhi::Persistent_cohomology_interface<Base>* pcoh) { + Base::initialize_filtration(); pcoh = new Gudhi::Persistent_cohomology_interface<Base>(*this); } }; diff --git a/src/cython/include/Subsampling_interface.h b/src/cython/include/Subsampling_interface.h index 1c6032c0..b0f4a50a 100644 --- a/src/cython/include/Subsampling_interface.h +++ b/src/cython/include/Subsampling_interface.h @@ -46,7 +46,7 @@ std::vector<std::vector<double>> subsampling_n_farthest_points(const std::vector unsigned nb_points) { std::vector<std::vector<double>> landmarks; Subsampling_dynamic_kernel k; - choose_n_farthest_points(k, points, nb_points, std::back_inserter(landmarks)); + choose_n_farthest_points(k, points, nb_points, random_starting_point, std::back_inserter(landmarks)); return landmarks; } diff --git a/src/cython/test/test_alpha_complex.py b/src/cython/test/test_alpha_complex.py index 2625d529..2c76d9d7 100755 --- a/src/cython/test/test_alpha_complex.py +++ b/src/cython/test/test_alpha_complex.py @@ -42,7 +42,7 @@ def test_infinite_alpha(): assert simplex_tree.num_simplices() == 11 assert simplex_tree.num_vertices() == 4 - assert simplex_tree.get_filtered_tree() == \ + assert simplex_tree.get_filtration() == \ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 0.25), ([0, 2], 0.25), ([1, 3], 0.25), ([2, 3], 0.25), ([1, 2], 0.5), ([0, 1, 2], 0.5), @@ -76,7 +76,7 @@ def test_filtered_alpha(): assert filtered_alpha.get_point(4) == [] assert filtered_alpha.get_point(125) == [] - assert simplex_tree.get_filtered_tree() == \ + assert simplex_tree.get_filtration() == \ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 0.25), ([0, 2], 0.25), ([1, 3], 0.25), ([2, 3], 0.25)] diff --git a/src/cython/test/test_cubical_complex.py b/src/cython/test/test_cubical_complex.py index c8df8089..2e281ee4 100755 --- a/src/cython/test/test_cubical_complex.py +++ b/src/cython/test/test_cubical_complex.py @@ -45,7 +45,7 @@ def test_dimension_or_perseus_file_constructor(): test_file.write('2\n3\n3\n0\n0\n0\n0\n100\n0\n0\n0\n0\n') test_file.close() # CubicalComplex can be constructed from dimensions and - # top_dimensional_cells OR from a perseus file style name. + # top_dimensional_cells OR from a Perseus-style file name. cub = CubicalComplex(dimensions=[3, 3], top_dimensional_cells = [1,2,3,4,5,6,7,8,9], perseus_file='CubicalOneSphere.txt') diff --git a/src/cython/test/test_euclidean_witness_complex.py b/src/cython/test/test_euclidean_witness_complex.py index 0947cc09..737f1ef4 100755 --- a/src/cython/test/test_euclidean_witness_complex.py +++ b/src/cython/test/test_euclidean_witness_complex.py @@ -42,7 +42,7 @@ def test_witness_complex(): assert landmarks[1] == euclidean_witness_complex.get_point(1) assert landmarks[2] == euclidean_witness_complex.get_point(2) - assert simplex_tree.get_filtered_tree() == [([0], 0.0), ([1], 0.0), + assert simplex_tree.get_filtration() == [([0], 0.0), ([1], 0.0), ([0, 1], 0.0), ([2], 0.0), ([0, 2], 0.0), ([1, 2], 0.0), ([0, 1, 2], 0.0)] @@ -61,11 +61,11 @@ def test_strong_witness_complex(): assert landmarks[1] == euclidean_strong_witness_complex.get_point(1) assert landmarks[2] == euclidean_strong_witness_complex.get_point(2) - assert simplex_tree.get_filtered_tree() == [([0], 0.0), ([1], 0.0), ([2], 0.0)] + assert simplex_tree.get_filtration() == [([0], 0.0), ([1], 0.0), ([2], 0.0)] simplex_tree = euclidean_strong_witness_complex.create_simplex_tree(max_alpha_square=100.0) - assert simplex_tree.get_filtered_tree() == [([0], 0.0), ([1], 0.0), + assert simplex_tree.get_filtration() == [([0], 0.0), ([1], 0.0), ([2], 0.0), ([1, 2], 15.0), ([0, 2], 34.0), ([0, 1], 37.0), ([0, 1, 2], 37.0)] diff --git a/src/cython/test/test_rips_complex.py b/src/cython/test/test_rips_complex.py index 286a645b..c7d2ead4 100755 --- a/src/cython/test/test_rips_complex.py +++ b/src/cython/test/test_rips_complex.py @@ -44,7 +44,7 @@ def test_rips_from_points(): assert simplex_tree.num_simplices() == 10 assert simplex_tree.num_vertices() == 4 - assert simplex_tree.get_filtered_tree() == \ + assert simplex_tree.get_filtration() == \ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 1.0), ([0, 2], 1.0), ([1, 3], 1.0), ([2, 3], 1.0), ([1, 2], 1.4142135623730951), @@ -83,7 +83,7 @@ def test_rips_from_distance_matrix(): assert simplex_tree.num_simplices() == 10 assert simplex_tree.num_vertices() == 4 - assert simplex_tree.get_filtered_tree() == \ + assert simplex_tree.get_filtration() == \ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0), ([0, 1], 1.0), ([0, 2], 1.0), ([1, 3], 1.0), ([2, 3], 1.0), ([1, 2], 1.4142135623730951), diff --git a/src/cython/test/test_simplex_tree.py b/src/cython/test/test_simplex_tree.py index af5b639a..3ae537e3 100755 --- a/src/cython/test/test_simplex_tree.py +++ b/src/cython/test/test_simplex_tree.py @@ -33,8 +33,8 @@ def test_insertion(): assert st.__is_persistence_defined() == False # insert test - assert st.insert_simplex([0, 1]) == True - assert st.insert_simplex_and_subfaces([0, 1, 2], filtration=4.0) == True + assert st.insert([0, 1]) == True + assert st.insert([0, 1, 2], filtration=4.0) == True # FIXME: Remove this line st.set_dimension(2) assert st.num_simplices() == 7 @@ -55,31 +55,30 @@ def test_insertion(): # filtration test st.set_filtration(5.0) st.initialize_filtration() - assert st.get_filtration() == 5.0 assert st.filtration([0, 1, 2]) == 4.0 assert st.filtration([0, 2]) == 4.0 assert st.filtration([1, 2]) == 4.0 assert st.filtration([2]) == 4.0 assert st.filtration([0, 1]) == 0.0 assert st.filtration([0]) == 0.0 - assert st.filtration([1]) == 4.0 + assert st.filtration([1]) == 0.0 - # skeleton_tree test - assert st.get_skeleton_tree(2) == \ + # skeleton test + assert st.get_skeleton(2) == \ [([0, 1, 2], 4.0), ([0, 1], 0.0), ([0, 2], 4.0), - ([0], 0.0), ([1, 2], 4.0), ([1], 4.0), ([2], 4.0)] - assert st.get_skeleton_tree(1) == \ + ([0], 0.0), ([1, 2], 4.0), ([1], 0.0), ([2], 4.0)] + assert st.get_skeleton(1) == \ [([0, 1], 0.0), ([0, 2], 4.0), ([0], 0.0), - ([1, 2], 4.0), ([1], 4.0), ([2], 4.0)] - assert st.get_skeleton_tree(0) == \ - [([0], 0.0), ([1], 4.0), ([2], 4.0)] + ([1, 2], 4.0), ([1], 0.0), ([2], 4.0)] + assert st.get_skeleton(0) == \ + [([0], 0.0), ([1], 0.0), ([2], 4.0)] # remove_maximal_simplex test assert st.get_cofaces([0, 1, 2], 1) == [] st.remove_maximal_simplex([0, 1, 2]) - assert st.get_skeleton_tree(2) == \ + assert st.get_skeleton(2) == \ [([0, 1], 0.0), ([0, 2], 4.0), ([0], 0.0), - ([1, 2], 4.0), ([1], 4.0), ([2], 4.0)] + ([1, 2], 4.0), ([1], 0.0), ([2], 4.0)] assert st.find([0, 1, 2]) == False assert st.find([0, 1]) == True assert st.find([0, 2]) == True @@ -103,20 +102,20 @@ def test_expansion(): assert st.__is_persistence_defined() == False # insert test - assert st.insert_simplex_and_subfaces([3, 2], 0.1) == True - assert st.insert_simplex_and_subfaces([2, 0], 0.2) == True - assert st.insert_simplex_and_subfaces([1, 0], 0.3) == True - assert st.insert_simplex_and_subfaces([3, 1], 0.4) == True - assert st.insert_simplex_and_subfaces([2, 1], 0.5) == True - assert st.insert_simplex_and_subfaces([6, 5], 0.6) == True - assert st.insert_simplex_and_subfaces([4, 2], 0.7) == True - assert st.insert_simplex_and_subfaces([3, 0], 0.8) == True - assert st.insert_simplex_and_subfaces([6, 4], 0.9) == True - assert st.insert_simplex_and_subfaces([6, 3], 1.0) == True + assert st.insert([3, 2], 0.1) == True + assert st.insert([2, 0], 0.2) == True + assert st.insert([1, 0], 0.3) == True + assert st.insert([3, 1], 0.4) == True + assert st.insert([2, 1], 0.5) == True + assert st.insert([6, 5], 0.6) == True + assert st.insert([4, 2], 0.7) == True + assert st.insert([3, 0], 0.8) == True + assert st.insert([6, 4], 0.9) == True + assert st.insert([6, 3], 1.0) == True assert st.num_vertices() == 7 assert st.num_simplices() == 17 - assert st.get_filtered_tree() == [([2], 0.1), ([3], 0.1), ([2, 3], 0.1), + assert st.get_filtration() == [([2], 0.1), ([3], 0.1), ([2, 3], 0.1), ([0], 0.2), ([0, 2], 0.2), ([1], 0.3), ([0, 1], 0.3), ([1, 3], 0.4), ([1, 2], 0.5), ([5], 0.6), ([6], 0.6), ([5, 6], 0.6), ([4], 0.7), ([2, 4], 0.7), ([0, 3], 0.8), ([4, 6], 0.9), ([3, 6], 1.0)] @@ -126,7 +125,7 @@ def test_expansion(): assert st.num_simplices() == 22 st.initialize_filtration() - assert st.get_filtered_tree() == [([2], 0.1), ([3], 0.1), ([2, 3], 0.1), + assert st.get_filtration() == [([2], 0.1), ([3], 0.1), ([2, 3], 0.1), ([0], 0.2), ([0, 2], 0.2), ([1], 0.3), ([0, 1], 0.3), ([1, 3], 0.4), ([1, 2], 0.5), ([0, 1, 2], 0.5), ([1, 2, 3], 0.5), ([5], 0.6), ([6], 0.6), ([5, 6], 0.6), ([4], 0.7), ([2, 4], 0.7), ([0, 3], 0.8), ([0, 1, 3], 0.8), diff --git a/src/cython/test/test_tangential_complex.py b/src/cython/test/test_tangential_complex.py index c191baa4..8aa4023c 100755 --- a/src/cython/test/test_tangential_complex.py +++ b/src/cython/test/test_tangential_complex.py @@ -40,7 +40,7 @@ def test_tangential(): assert st.num_simplices() == 6 assert st.num_vertices() == 4 - assert st.get_filtered_tree() == \ + assert st.get_filtration() == \ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([0, 2], 0.0), ([3], 0.0), ([1, 3], 0.0)] assert st.get_cofaces([0], 1) == [([0, 2], 0.0)] |