From 599d68cd916f533bdb66dd9e684dd5703233b6bb Mon Sep 17 00:00:00 2001 From: Gard Spreemann Date: Wed, 25 Sep 2019 14:29:41 +0200 Subject: Delete all files in order to incorporate upstream's move to git. --- .../gudhi/Tangential_complex/Simplicial_complex.h | 539 --------------------- include/gudhi/Tangential_complex/config.h | 43 -- include/gudhi/Tangential_complex/utilities.h | 195 -------- 3 files changed, 777 deletions(-) delete mode 100644 include/gudhi/Tangential_complex/Simplicial_complex.h delete mode 100644 include/gudhi/Tangential_complex/config.h delete mode 100644 include/gudhi/Tangential_complex/utilities.h (limited to 'include/gudhi/Tangential_complex') diff --git a/include/gudhi/Tangential_complex/Simplicial_complex.h b/include/gudhi/Tangential_complex/Simplicial_complex.h deleted file mode 100644 index f79186b0..00000000 --- a/include/gudhi/Tangential_complex/Simplicial_complex.h +++ /dev/null @@ -1,539 +0,0 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Clement Jamin - * - * Copyright (C) 2016 Inria - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef TANGENTIAL_COMPLEX_SIMPLICIAL_COMPLEX_H_ -#define TANGENTIAL_COMPLEX_SIMPLICIAL_COMPLEX_H_ - -#include -#include -#include -#include - -#include - -// For is_pure_pseudomanifold -#include -#include -#include -#include - -#include -#include -#include -#include // for map<> -#include // for vector<> -#include // for set<> - -namespace Gudhi { -namespace tangential_complex { -namespace internal { - -class Simplicial_complex { - public: - typedef boost::container::flat_set Simplex; - typedef std::set Simplex_set; - - // If perform_checks = true, the function: - // - won't insert the simplex if it is already in a higher dim simplex - // - will erase any lower-dim simplices that are faces of the new simplex - // Returns true if the simplex was added - bool add_simplex( - const Simplex &s, bool perform_checks = true) { - if (perform_checks) { - unsigned int num_pts = static_cast (s.size()); - std::vector to_erase; - bool check_higher_dim_simpl = true; - for (Complex::iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - // Check if the simplex is not already in a higher dim simplex - if (check_higher_dim_simpl - && it_simplex->size() > num_pts - && std::includes(it_simplex->begin(), it_simplex->end(), - s.begin(), s.end())) { - // No need to insert it, then - return false; - } - // Check if the simplex includes some lower-dim simplices - if (it_simplex->size() < num_pts - && std::includes(s.begin(), s.end(), - it_simplex->begin(), it_simplex->end())) { - to_erase.push_back(it_simplex); - // We don't need to check higher-sim simplices any more - check_higher_dim_simpl = false; - } - } - for (std::vector::const_iterator it = to_erase.begin(); - it != to_erase.end(); ++it) { - m_complex.erase(*it); - } - } - return m_complex.insert(s).second; - } - - const Simplex_set &simplex_range() const { - return m_complex; - } - - bool empty() { - return m_complex.empty(); - } - - void clear() { - m_complex.clear(); - } - - template - void get_simplices_matching_test(Test test, Output_it out) { - for (Complex::const_iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - if (test(*it_simplex)) - *out++ = *it_simplex; - } - } - - // When a simplex S has only one co-face C, we can remove S and C - // without changing the topology - - void collapse(int max_simplex_dim, bool quiet = false) { -#ifdef DEBUG_TRACES - if (!quiet) - std::cerr << "Collapsing... "; -#endif - // We note k = max_simplex_dim - 1 - int k = max_simplex_dim - 1; - - typedef Complex::iterator Simplex_iterator; - typedef std::vector Simplex_iterator_list; - typedef std::map Cofaces_map; - - std::size_t num_collapsed_maximal_simplices = 0; - do { - num_collapsed_maximal_simplices = 0; - // Create a map associating each non-maximal k-faces to the list of its - // maximal cofaces - Cofaces_map cofaces_map; - for (Complex::const_iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - if (static_cast (it_simplex->size()) > k + 1) { - std::vector k_faces; - // Get the k-faces composing the simplex - combinations(*it_simplex, k + 1, std::back_inserter(k_faces)); - for (const auto &comb : k_faces) - cofaces_map[comb].push_back(it_simplex); - } - } - - // For each non-maximal k-face F, if F has only one maximal coface Cf: - // - Look for the other k-faces F2, F3... of Cf in the map and: - // * if the list contains only Cf, clear the list (we don't remove the - // list since it creates troubles with the iterators) and add the F2, - // F3... to the complex - // * otherwise, remove Cf from the associated list - // - Remove Cf from the complex - for (Cofaces_map::const_iterator it_map_elt = cofaces_map.begin(), - it_map_end = cofaces_map.end(); - it_map_elt != it_map_end; - ++it_map_elt) { - if (it_map_elt->second.size() == 1) { - std::vector k_faces; - const Simplex_iterator_list::value_type &it_Cf = - *it_map_elt->second.begin(); - GUDHI_CHECK(it_Cf->size() == max_simplex_dim + 1, - std::logic_error("Wrong dimension")); - // Get the k-faces composing the simplex - combinations(*it_Cf, k + 1, std::back_inserter(k_faces)); - for (const auto &f2 : k_faces) { - // Skip F - if (f2 != it_map_elt->first) { - Cofaces_map::iterator it_comb_in_map = cofaces_map.find(f2); - if (it_comb_in_map->second.size() == 1) { - it_comb_in_map->second.clear(); - m_complex.insert(f2); - } else { // it_comb_in_map->second.size() > 1 - Simplex_iterator_list::iterator it = std::find(it_comb_in_map->second.begin(), - it_comb_in_map->second.end(), - it_Cf); - GUDHI_CHECK(it != it_comb_in_map->second.end(), - std::logic_error("Error: it == it_comb_in_map->second.end()")); - it_comb_in_map->second.erase(it); - } - } - } - m_complex.erase(it_Cf); - ++num_collapsed_maximal_simplices; - } - } - // Repeat until no maximal simplex got removed - } while (num_collapsed_maximal_simplices > 0); - - // Collapse the lower dimension simplices - if (k > 0) - collapse(max_simplex_dim - 1, true); - -#ifdef DEBUG_TRACES - if (!quiet) - std::cerr << "done.\n"; -#endif - } - - void display_stats() const { - std::cerr << yellow << "Complex stats:\n" << white; - - if (m_complex.empty()) { - std::cerr << " * No simplices.\n"; - } else { - // Number of simplex for each dimension - std::map simplex_stats; - - for (Complex::const_iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - ++simplex_stats[static_cast (it_simplex->size()) - 1]; - } - - for (std::map::const_iterator it_map = simplex_stats.begin(); - it_map != simplex_stats.end(); ++it_map) { - std::cerr << " * " << it_map->first << "-simplices: " - << it_map->second << "\n"; - } - } - } - - // verbose_level = 0, 1 or 2 - bool is_pure_pseudomanifold__do_not_check_if_stars_are_connected(int simplex_dim, - bool allow_borders = false, - bool exit_at_the_first_problem = false, - int verbose_level = 0, - std::size_t *p_num_wrong_dim_simplices = NULL, - std::size_t *p_num_wrong_number_of_cofaces = NULL) const { - typedef Simplex K_1_face; - typedef std::map Cofaces_map; - - std::size_t num_wrong_dim_simplices = 0; - std::size_t num_wrong_number_of_cofaces = 0; - - // Counts the number of cofaces of each K_1_face - - // Create a map associating each non-maximal k-faces to the list of its - // maximal cofaces - Cofaces_map cofaces_map; - for (Complex::const_iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - if (static_cast (it_simplex->size()) != simplex_dim + 1) { - if (verbose_level >= 2) - std::cerr << "Found a simplex with dim = " - << it_simplex->size() - 1 << "\n"; - ++num_wrong_dim_simplices; - } else { - std::vector k_1_faces; - // Get the facets composing the simplex - combinations( - *it_simplex, simplex_dim, std::back_inserter(k_1_faces)); - for (const auto &k_1_face : k_1_faces) { - ++cofaces_map[k_1_face]; - } - } - } - - for (Cofaces_map::const_iterator it_map_elt = cofaces_map.begin(), - it_map_end = cofaces_map.end(); - it_map_elt != it_map_end; - ++it_map_elt) { - if (it_map_elt->second != 2 - && (!allow_borders || it_map_elt->second != 1)) { - if (verbose_level >= 2) - std::cerr << "Found a k-1-face with " - << it_map_elt->second << " cofaces\n"; - - if (exit_at_the_first_problem) - return false; - else - ++num_wrong_number_of_cofaces; - } - } - - bool ret = num_wrong_dim_simplices == 0 && num_wrong_number_of_cofaces == 0; - - if (verbose_level >= 1) { - std::cerr << "Pure pseudo-manifold: "; - if (ret) { - std::cerr << green << "YES" << white << "\n"; - } else { - std::cerr << red << "NO" << white << "\n" - << " * Number of wrong dimension simplices: " - << num_wrong_dim_simplices << "\n" - << " * Number of wrong number of cofaces: " - << num_wrong_number_of_cofaces << "\n"; - } - } - - if (p_num_wrong_dim_simplices) - *p_num_wrong_dim_simplices = num_wrong_dim_simplices; - if (p_num_wrong_number_of_cofaces) - *p_num_wrong_number_of_cofaces = num_wrong_number_of_cofaces; - - return ret; - } - - template - std::size_t num_K_simplices() const { - Simplex_set k_simplices; - - for (Complex::const_iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - if (it_simplex->size() == K + 1) { - k_simplices.insert(*it_simplex); - } else if (it_simplex->size() > K + 1) { - // Get the k-faces composing the simplex - combinations( - *it_simplex, K + 1, std::inserter(k_simplices, k_simplices.begin())); - } - } - - return k_simplices.size(); - } - - std::ptrdiff_t euler_characteristic(bool verbose = false) const { - if (verbose) - std::cerr << "\nComputing Euler characteristic of the complex...\n"; - - std::size_t num_vertices = num_K_simplices<0>(); - std::size_t num_edges = num_K_simplices<1>(); - std::size_t num_triangles = num_K_simplices<2>(); - - std::ptrdiff_t ec = - (std::ptrdiff_t) num_vertices - - (std::ptrdiff_t) num_edges - + (std::ptrdiff_t) num_triangles; - - if (verbose) - std::cerr << "Euler characteristic: V - E + F = " - << num_vertices << " - " << num_edges << " + " << num_triangles << " = " - << blue - << ec - << white << "\n"; - - return ec; - } - - // TODO(CJ): ADD COMMENTS - - bool is_pure_pseudomanifold( - int simplex_dim, - std::size_t num_vertices, - bool allow_borders = false, - bool exit_at_the_first_problem = false, - int verbose_level = 0, - std::size_t *p_num_wrong_dim_simplices = NULL, - std::size_t *p_num_wrong_number_of_cofaces = NULL, - std::size_t *p_num_unconnected_stars = NULL, - Simplex_set *p_wrong_dim_simplices = NULL, - Simplex_set *p_wrong_number_of_cofaces_simplices = NULL, - Simplex_set *p_unconnected_stars_simplices = NULL) const { - // If simplex_dim == 1, we do not need to check if stars are connected - if (simplex_dim == 1) { - if (p_num_unconnected_stars) - *p_num_unconnected_stars = 0; - return is_pure_pseudomanifold__do_not_check_if_stars_are_connected(simplex_dim, - allow_borders, - exit_at_the_first_problem, - verbose_level, - p_num_wrong_dim_simplices, - p_num_wrong_number_of_cofaces); - } - // Associates each vertex (= the index in the vector) - // to its star (list of simplices) - typedef std::vector > Stars; - std::size_t num_wrong_dim_simplices = 0; - std::size_t num_wrong_number_of_cofaces = 0; - std::size_t num_unconnected_stars = 0; - - // Fills a Stars data structure - Stars stars; - stars.resize(num_vertices); - for (Complex::const_iterator it_simplex = m_complex.begin(), - it_simplex_end = m_complex.end(); - it_simplex != it_simplex_end; - ++it_simplex) { - if (static_cast (it_simplex->size()) != simplex_dim + 1) { - if (verbose_level >= 2) - std::cerr << "Found a simplex with dim = " - << it_simplex->size() - 1 << "\n"; - ++num_wrong_dim_simplices; - if (p_wrong_dim_simplices) - p_wrong_dim_simplices->insert(*it_simplex); - } else { - for (Simplex::const_iterator it_point_idx = it_simplex->begin(); - it_point_idx != it_simplex->end(); - ++it_point_idx) { - stars[*it_point_idx].push_back(it_simplex); - } - } - } - - // Now, for each star, we have a vector of its d-simplices - // i.e. one index for each d-simplex - // Boost Graph only deals with indexes, so we also need indexes for the - // (d-1)-simplices - std::size_t center_vertex_index = 0; - for (Stars::const_iterator it_star = stars.begin(); - it_star != stars.end(); - ++it_star, ++center_vertex_index) { - typedef std::map > - Dm1_faces_to_adj_D_faces; - Dm1_faces_to_adj_D_faces dm1_faces_to_adj_d_faces; - - for (std::size_t i_dsimpl = 0; i_dsimpl < it_star->size(); ++i_dsimpl) { - Simplex dm1_simpl_of_link = *((*it_star)[i_dsimpl]); - dm1_simpl_of_link.erase(center_vertex_index); - // Copy it to a vector so that we can use operator[] on it - std::vector dm1_simpl_of_link_vec( - dm1_simpl_of_link.begin(), dm1_simpl_of_link.end()); - - CGAL::Combination_enumerator dm2_simplices( - simplex_dim - 1, 0, simplex_dim); - for (; !dm2_simplices.finished(); ++dm2_simplices) { - Simplex dm2_simpl; - for (int j = 0; j < simplex_dim - 1; ++j) - dm2_simpl.insert(dm1_simpl_of_link_vec[dm2_simplices[j]]); - dm1_faces_to_adj_d_faces[dm2_simpl].push_back(i_dsimpl); - } - } - - Adj_graph adj_graph; - std::vector d_faces_descriptors; - d_faces_descriptors.resize(it_star->size()); - for (std::size_t j = 0; j < it_star->size(); ++j) - d_faces_descriptors[j] = boost::add_vertex(adj_graph); - - Dm1_faces_to_adj_D_faces::const_iterator dm1_to_d_it = - dm1_faces_to_adj_d_faces.begin(); - Dm1_faces_to_adj_D_faces::const_iterator dm1_to_d_it_end = - dm1_faces_to_adj_d_faces.end(); - for (std::size_t i_km1_face = 0; - dm1_to_d_it != dm1_to_d_it_end; - ++dm1_to_d_it, ++i_km1_face) { - Graph_vertex km1_gv = boost::add_vertex(adj_graph); - - for (std::vector::const_iterator kface_it = - dm1_to_d_it->second.begin(); - kface_it != dm1_to_d_it->second.end(); - ++kface_it) { - boost::add_edge(km1_gv, *kface_it, adj_graph); - } - - if (dm1_to_d_it->second.size() != 2 - && (!allow_borders || dm1_to_d_it->second.size() != 1)) { - ++num_wrong_number_of_cofaces; - if (p_wrong_number_of_cofaces_simplices) { - for (auto idx : dm1_to_d_it->second) - p_wrong_number_of_cofaces_simplices->insert(*((*it_star)[idx])); - } - } - } - - // What is left is to check the connexity - bool is_connected = true; - if (boost::num_vertices(adj_graph) > 0) { - std::vector components(boost::num_vertices(adj_graph)); - is_connected = - (boost::connected_components(adj_graph, &components[0]) == 1); - } - - if (!is_connected) { - if (verbose_level >= 2) - std::cerr << "Error: star #" << center_vertex_index - << " is not connected\n"; - ++num_unconnected_stars; - if (p_unconnected_stars_simplices) { - for (std::vector::const_iterator - it_simpl = it_star->begin(), - it_simpl_end = it_star->end(); - it_simpl != it_simpl_end; - ++it_simpl) { - p_unconnected_stars_simplices->insert(**it_simpl); - } - } - } - } - - // Each one has been counted several times ("simplex_dim" times) - num_wrong_number_of_cofaces /= simplex_dim; - - bool ret = - num_wrong_dim_simplices == 0 - && num_wrong_number_of_cofaces == 0 - && num_unconnected_stars == 0; - - if (verbose_level >= 1) { - std::cerr << "Pure pseudo-manifold: "; - if (ret) { - std::cerr << green << "YES" << white << "\n"; - } else { - std::cerr << red << "NO" << white << "\n" - << " * Number of wrong dimension simplices: " - << num_wrong_dim_simplices << "\n" - << " * Number of wrong number of cofaces: " - << num_wrong_number_of_cofaces << "\n" - << " * Number of not-connected stars: " - << num_unconnected_stars << "\n"; - } - } - - if (p_num_wrong_dim_simplices) - *p_num_wrong_dim_simplices = num_wrong_dim_simplices; - if (p_num_wrong_number_of_cofaces) - *p_num_wrong_number_of_cofaces = num_wrong_number_of_cofaces; - if (p_num_unconnected_stars) - *p_num_unconnected_stars = num_unconnected_stars; - - return ret; - } - - private: - typedef Simplex_set Complex; - - // graph is an adjacency list - typedef boost::adjacency_list Adj_graph; - // map that gives to a certain simplex its node in graph and its dimension - typedef boost::graph_traits::vertex_descriptor Graph_vertex; - typedef boost::graph_traits::edge_descriptor Graph_edge; - - Complex m_complex; -}; // class Simplicial_complex - -} // namespace internal -} // namespace tangential_complex -} // namespace Gudhi - -#endif // TANGENTIAL_COMPLEX_SIMPLICIAL_COMPLEX_H_ diff --git a/include/gudhi/Tangential_complex/config.h b/include/gudhi/Tangential_complex/config.h deleted file mode 100644 index e1af1ea6..00000000 --- a/include/gudhi/Tangential_complex/config.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Clement Jamin - * - * Copyright (C) 2016 Inria - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef TANGENTIAL_COMPLEX_CONFIG_H_ -#define TANGENTIAL_COMPLEX_CONFIG_H_ - -#include - -// ========================= Debugging & profiling ============================= -// #define GUDHI_TC_PROFILING -// #define GUDHI_TC_VERY_VERBOSE -// #define GUDHI_TC_PERFORM_EXTRA_CHECKS -// #define GUDHI_TC_SHOW_DETAILED_STATS_FOR_INCONSISTENCIES - -// ========================= Strategy ========================================== -#define GUDHI_TC_PERTURB_POSITION -// #define GUDHI_TC_PERTURB_WEIGHT - -// ========================= Parameters ======================================== - -// PCA will use GUDHI_TC_BASE_VALUE_FOR_PCA^intrinsic_dim points -const std::size_t GUDHI_TC_BASE_VALUE_FOR_PCA = 5; - -#endif // TANGENTIAL_COMPLEX_CONFIG_H_ diff --git a/include/gudhi/Tangential_complex/utilities.h b/include/gudhi/Tangential_complex/utilities.h deleted file mode 100644 index 2dd46118..00000000 --- a/include/gudhi/Tangential_complex/utilities.h +++ /dev/null @@ -1,195 +0,0 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Clement Jamin - * - * Copyright (C) 2016 Inria - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef TANGENTIAL_COMPLEX_UTILITIES_H_ -#define TANGENTIAL_COMPLEX_UTILITIES_H_ - -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include // for std::sqrt - -namespace Gudhi { -namespace tangential_complex { -namespace internal { - -// Provides copy constructors to std::atomic so that -// it can be used in a vector -template -struct Atomic_wrapper -: public std::atomic { - typedef std::atomic Base; - - Atomic_wrapper() { } - - Atomic_wrapper(const T &t) : Base(t) { } - - Atomic_wrapper(const std::atomic &a) : Base(a.load()) { } - - Atomic_wrapper(const Atomic_wrapper &other) : Base(other.load()) { } - - Atomic_wrapper &operator=(const T &other) { - Base::store(other); - return *this; - } - - Atomic_wrapper &operator=(const std::atomic &other) { - Base::store(other.load()); - return *this; - } - - Atomic_wrapper &operator=(const Atomic_wrapper &other) { - Base::store(other.load()); - return *this; - } -}; - -// Modifies v in-place -template -typename K::Vector_d& normalize_vector(typename K::Vector_d& v, - K const& k) { - v = k.scaled_vector_d_object()( - v, typename K::FT(1) / std::sqrt(k.squared_length_d_object()(v))); - return v; -} - -template -struct Basis { - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_d Point; - typedef typename Kernel::Vector_d Vector; - typedef typename std::vector::const_iterator const_iterator; - - std::size_t m_origin; - std::vector m_vectors; - - std::size_t origin() const { - return m_origin; - } - - void set_origin(std::size_t o) { - m_origin = o; - } - - const_iterator begin() const { - return m_vectors.begin(); - } - - const_iterator end() const { - return m_vectors.end(); - } - - std::size_t size() const { - return m_vectors.size(); - } - - Vector& operator[](const std::size_t i) { - return m_vectors[i]; - } - - const Vector& operator[](const std::size_t i) const { - return m_vectors[i]; - } - - void push_back(const Vector& v) { - m_vectors.push_back(v); - } - - void reserve(const std::size_t s) { - m_vectors.reserve(s); - } - - Basis() { } - - Basis(std::size_t origin) : m_origin(origin) { } - - Basis(std::size_t origin, const std::vector& vectors) - : m_origin(origin), m_vectors(vectors) { } - - int dimension() const { - return static_cast (m_vectors.size()); - } -}; - -// 1st line: number of points -// Then one point per line -template -std::ostream &export_point_set( - Kernel const& k, - Point_range const& points, - std::ostream & os, - const char *coord_separator = " ") { - // Kernel functors - typename Kernel::Construct_cartesian_const_iterator_d ccci = - k.construct_cartesian_const_iterator_d_object(); - - os << points.size() << "\n"; - - typename Point_range::const_iterator it_p = points.begin(); - typename Point_range::const_iterator it_p_end = points.end(); - // For each point p - for (; it_p != it_p_end; ++it_p) { - for (auto it = ccci(*it_p); it != ccci(*it_p, 0); ++it) - os << CGAL::to_double(*it) << coord_separator; - - os << "\n"; - } - - return os; -} - -// Compute all the k-combinations of elements -// Output_iterator::value_type must be -// boost::container::flat_set -template -void combinations(const Elements_container elements, int k, - Output_iterator combinations) { - std::size_t n = elements.size(); - std::vector booleans(n, false); - std::fill(booleans.begin() + n - k, booleans.end(), true); - do { - boost::container::flat_set combination; - typename Elements_container::const_iterator it_elt = elements.begin(); - for (std::size_t i = 0; i < n; ++i, ++it_elt) { - if (booleans[i]) - combination.insert(*it_elt); - } - *combinations++ = combination; - } while (std::next_permutation(booleans.begin(), booleans.end())); -} - -} // namespace internal -} // namespace tangential_complex -} // namespace Gudhi - -#endif // TANGENTIAL_COMPLEX_UTILITIES_H_ -- cgit v1.2.3