From 82ce7d0fb937366a8dd9a72af60a96de2636d669 Mon Sep 17 00:00:00 2001 From: David Loiseaux Date: Tue, 26 Sep 2023 16:55:19 +0200 Subject: [PATCH] cleaning --- src/Simplex_tree/concept/SimplexTreeOptions.h | 2 +- src/Simplex_tree/include/gudhi/Simplex_tree.h | 23 ++++------- .../include/Simplex_tree_interface_multi.h | 23 +++++------ src/python/include/Simplex_tree_multi.h | 29 +++++--------- src/python/include/multi_filtrations/box.h | 14 +------ .../finitely_critical_filtrations.h | 40 ++++--------------- 6 files changed, 37 insertions(+), 94 deletions(-) diff --git a/src/Simplex_tree/concept/SimplexTreeOptions.h b/src/Simplex_tree/concept/SimplexTreeOptions.h index 1f216338fe..45e5f03bca 100644 --- a/src/Simplex_tree/concept/SimplexTreeOptions.h +++ b/src/Simplex_tree/concept/SimplexTreeOptions.h @@ -31,7 +31,7 @@ struct SimplexTreeOptions { static const bool link_nodes_by_label; /// If true, Simplex_handle will not be invalidated after insertions or removals. static const bool stable_simplex_handles; - + /// If true, assumes that Filtration_value is vector-like instead of float-like. This also assumes that Filtration_values is a class, which has a push_to method to push a filtration value $x$ onto $this>=0$. static const bool is_multi_parameter; }; diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 2c9efbca70..5b92c90804 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -153,7 +153,6 @@ class Simplex_tree { struct Filtration_simplex_base_real { Filtration_simplex_base_real() : filt_{} {} void assign_filtration(const Filtration_value& f) { filt_ = f; } - // Filtration_value filtration() const { return filt_; } const Filtration_value& filtration() const { return filt_; } Filtration_value& filtration() { return filt_; } private: @@ -980,22 +979,14 @@ class Simplex_tree { Simplex_handle simplex_one = insertion_result.first; bool one_is_new = insertion_result.second; if (!one_is_new) { - if (!(filtration(simplex_one) <= filt)) { // TODO : For multipersistence, it's not clear what should be the default, especially for multicritical filtrations + if (!(filtration(simplex_one) <= filt)) { if constexpr (SimplexTreeOptions::is_multi_parameter){ + // By default, does nothing and assumes that the user is smart. if (filt < filtration(simplex_one)){ - // assign_filtration(simplex_one, filt); - // I don't really like this behavior. - // It prevents inserting simplices by default at the smallest possible position after its childrens. - // e.g., if (python) we type : st.insert([0], [1,0]), st.insert([1], [0,1]), st.insert([0,1]) - // we may want st.filtration([0,1]) to be [1,1]. (maybe after a make_filtration_decreasing from user) - // Furthermore, this may more sense as default value -> 0 can erase filtration values of childrens... + // placeholder for comparable filtrations } - else{ // As multicritical filtrations are not well supported yet, its not safe to concatenate yet. - // two incomparables filtrations values -> we concatenate - // std::cout << "incomparable -> concatenate" << std::endl; - // Filtration_value new_filtration = filtration(simplex_one); - // new_filtration.insert_new(filt); // we assume then that Filtration_value has a insert_new method. - // assign_filtration(simplex_one, new_filtration); + else{ + // placeholder for incomparable filtrations } } else{ // non-multiparameter @@ -1633,10 +1624,10 @@ class Simplex_tree { if (dim == 0) return; // Find the maximum filtration value in the border Boundary_simplex_range&& boundary = boundary_simplex_range(sh); - typename SimplexTreeOptions::Filtration_value max_filt_border_value; + Filtration_value max_filt_border_value; if constexpr (SimplexTreeOptions::is_multi_parameter){ // in that case, we assume that Filtration_value has a `push_to` member to handle this. - max_filt_border_value = typename SimplexTreeOptions::Filtration_value(this->number_of_parameters_); + max_filt_border_value = Filtration_value(this->number_of_parameters_); for (auto &face_sh : boundary){ max_filt_border_value.push_to(filtration(face_sh)); // pushes the value of max_filt_border_value to reach simplex' filtration } diff --git a/src/python/include/Simplex_tree_interface_multi.h b/src/python/include/Simplex_tree_interface_multi.h index 139def9ee2..9c0e14bcf0 100644 --- a/src/python/include/Simplex_tree_interface_multi.h +++ b/src/python/include/Simplex_tree_interface_multi.h @@ -48,19 +48,15 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface& filtration, int axis){ using value_type=options_multi::value_type; for (auto &SimplexHandle : Base::complex_simplex_range()){ @@ -180,6 +178,8 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface>; simplices_list get_simplices_of_dimension(int dimension){ simplices_list simplex_list; @@ -215,9 +215,6 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface new_filtration_value = Base::filtration(SimplexHandle); - // new_filtration_value.resize(num); - // Base::assign_filtration(SimplexHandle, new_filtration_value); Base::filtration_mutable(SimplexHandle).resize(num);; } } @@ -229,7 +226,7 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface; // Interface not necessary (smaller so should do less segfaults) using interface_multi = Simplex_tree_interface_multi; - +// Wrappers of the functions in Simplex_tree_multi.h, to deal with the "pointer only" python interface void flatten_diag_from_ptr(const uintptr_t splxptr, const uintptr_t newsplxptr, const std::vector basepoint, int dimension){ // for python auto &st = get_simplextree_from_pointer(newsplxptr); auto &st_multi = get_simplextree_from_pointer(splxptr); diff --git a/src/python/include/Simplex_tree_multi.h b/src/python/include/Simplex_tree_multi.h index 2fcdf35821..2725346e5e 100644 --- a/src/python/include/Simplex_tree_multi.h +++ b/src/python/include/Simplex_tree_multi.h @@ -53,16 +53,16 @@ using simplextree_multi = Simplex_tree; using multi_filtration_type = std::vector; using multi_filtration_grid = std::vector; - +// Retrieves a simplextree from a pointer. As the python simplex_tree and simplex_tree_multi don't know each other we have to exchange them using pointers. template simplextreeinterface& get_simplextree_from_pointer(const uintptr_t splxptr){ //DANGER simplextreeinterface &st = *(simplextreeinterface*)(splxptr); return st; } + +// Turns a 1-parameter simplextree into a multiparameter simplextree, and keeps the 1-filtration in the 1st axis template void multify(simplextree_std &st, simplextree_multi &st_multi, const int num_parameters, const typename simplextree_multi::Options::Filtration_value& default_values={}){ - // if (default_values.size() -1 > num_parameters) - // {std::cerr << "default values too large !\n"; throw ;} typename simplextree_multi::Options::Filtration_value f(num_parameters); for (auto i = 0u; i(default_values.size()), static_cast(num_parameters-1));i++) f[i+1] = default_values[i]; @@ -75,7 +75,6 @@ void multify(simplextree_std &st, simplextree_multi &st_multi, const int num_par if (num_parameters > 0) f[0] = st.filtration(simplex_handle); - // std::cout << "Inserting " << f << "\n"; auto filtration_copy = f; st_multi.insert_simplex(simplex,filtration_copy); @@ -84,7 +83,7 @@ void multify(simplextree_std &st, simplextree_multi &st_multi, const int num_par - +// Turns a multi-parameter simplextree into a 1-parameter simplextree template void flatten(simplextree_std &st, simplextree_multi &st_multi, const int dimension = 0){ for (const auto &simplex_handle : st_multi.complex_simplex_range()){ @@ -96,6 +95,7 @@ void flatten(simplextree_std &st, simplextree_multi &st_multi, const int dimensi } } +// Applies a linear form (i.e. scalar product with Riesz rpz) to the filtration to flatten a simplextree multi template void linear_projection(simplextree_std &st, simplextree_multi &st_multi, const std::vector& linear_form){ auto sh = st.complex_simplex_range().begin(); @@ -108,9 +108,6 @@ void linear_projection(simplextree_std &st, simplextree_multi &st_multi, const s st.assign_filtration(*sh, projected_filtration); } } -// For python interface. Do not use. - - template void flatten_diag(simplextree_std &st, simplextree_multi &st_multi, const std::vector basepoint, int dimension){ @@ -146,18 +143,16 @@ inline void find_coordinates(vector_like& x, const multi_filtration_grid &grid){ if constexpr (std::numeric_limits::has_infinity) if (to_project == std::numeric_limits::infinity()){ x[parameter] = std::numeric_limits::infinity(); -continue; + continue; } - if (to_project >= filtration.back()){ x[parameter] = filtration.size()-1; continue; - } // deals with infinite value at the end of the grid, TODO DEAL + } // deals with infinite value at the end of the grid + unsigned int i = 0; - // std::cout << to_project<< " " < filtration[i] && i distance_vector(filtration.size()); - // for (int i = 0; i < (int)filtration.size(); i++){ - // distance_vector[i] = std::abs(to_project - filtration[i]); - // } - // coordinates[parameter] = std::distance(distance_vector.begin(), std::min_element(distance_vector.begin(), distance_vector.end())); } - // return x; } @@ -197,6 +186,8 @@ void squeeze_filtration(uintptr_t splxptr, const multi_filtration_grid &grid, bo } return; } + +// retrieves the filtration values of a simplextree. Useful to generate a grid. std::vector get_filtration_values(const uintptr_t splxptr, const std::vector °rees){ Simplex_tree &st_multi = *(Gudhi::Simplex_tree*)(splxptr); int num_parameters = st_multi.get_number_of_parameters(); diff --git a/src/python/include/multi_filtrations/box.h b/src/python/include/multi_filtrations/box.h index ea16686ac3..a4c28fdf1f 100644 --- a/src/python/include/multi_filtrations/box.h +++ b/src/python/include/multi_filtrations/box.h @@ -28,7 +28,7 @@ /** - * @brief Holds the square box on which to compute. + * @brief Simple box in $\mathbb R^n$ . */ namespace Gudhi::multiparameter::multi_filtrations{ @@ -74,7 +74,6 @@ inline Box::Box(const point_type &bottomCorner, const point_type &upperCorner upperCorner_(upperCorner) { assert(bottomCorner.size() == upperCorner.size() - // && is_smaller(bottomCorner, upperCorner) && bottomCorner <= upperCorner && "This box is trivial !"); } @@ -89,11 +88,6 @@ inline Box::Box(const std::pair &box) template inline void Box::inflate(T delta) { -// #pragma omp simd - // for (int i = 0; i < bottomCorner_.size(); i++){ - // bottomCorner_[i] -= delta; - // upperCorner_[i] += delta; - // } bottomCorner_ -= delta; upperCorner_ += delta; } @@ -151,12 +145,6 @@ inline bool Box::contains(const point_type &point) const { if (point.size() != bottomCorner_.size()) return false; - // for (int i = 0; i < (int)point.size(); i++){ - // if (point[i] < bottomCorner_[i]) return false; - // if (point[i] > upperCorner_[i]) return false; - // } - - // return true; return bottomCorner_ <= point && point <= upperCorner_; } diff --git a/src/python/include/multi_filtrations/finitely_critical_filtrations.h b/src/python/include/multi_filtrations/finitely_critical_filtrations.h index 0832f7b676..a75c45c641 100644 --- a/src/python/include/multi_filtrations/finitely_critical_filtrations.h +++ b/src/python/include/multi_filtrations/finitely_critical_filtrations.h @@ -11,9 +11,6 @@ template class Finitely_critical_multi_filtration : public std::vector { // Class to prevent doing illegal stuff with the standard library, e.g., compare two vectors public: - // explicit Finitely_critical_multi_filtration(std::vector& v) : ptr_(&v) { - // }; // Conversion - // using std::vector::vector; Finitely_critical_multi_filtration() : std::vector() {}; Finitely_critical_multi_filtration(int n) : std::vector(n, -std::numeric_limits::infinity()) {}; // minus infinity by default Finitely_critical_multi_filtration(int n, T value) : std::vector(n,value) {}; @@ -32,24 +29,9 @@ class Finitely_critical_multi_filtration : public std::vector { - //TODO : multicritical -> iterator over filtrations - - // LESS THAN OPERATORS friend bool operator<(const Finitely_critical_multi_filtration& a, const Finitely_critical_multi_filtration& b) { bool isSame = true; - // if (a.size() != b.size()){ - - - // if (a.size()>1 && b.size() >1){ - // std::cerr << "Filtrations are not of the same size ! (" << a.size() << " " << b.size() << ")."; - // throw; - // } - // // {inf, inf, ...} can be stored as {inf} - // if (b[0] == std::numeric_limits::infinity()) //TODO FIXME, we have to check every coord of b instead of 1 - // return a[0] != std::numeric_limits::infinity(); - // return false; - // } int n = std::min(a.size(), b.size()); for (int i = 0; i < n; ++i){ if (a[i] > b[i]) return false; @@ -60,16 +42,6 @@ class Finitely_critical_multi_filtration : public std::vector { } friend bool operator<=(const Finitely_critical_multi_filtration& a, const Finitely_critical_multi_filtration& b) { - // if (a.size() != b.size()){ - // if (a.size()>1 && b.size() >1){ - // std::cerr << "Filtrations are not of the same size ! (" << a.size() << " " << b.size() << ")."; - // throw; - // } - // // {inf, inf, ...} can be stored as {inf} - // if (b[0] == std::numeric_limits::infinity()) //TODO FIXME, we have to check every coord of b instead of 1 - // return a[0] != std::numeric_limits::infinity(); - // return false; - // } int n = std::min(a.size(), b.size()); for (int i = 0; i < n; ++i){ if (a[i] > b[i]) return false; @@ -82,11 +54,11 @@ class Finitely_critical_multi_filtration : public std::vector { //GREATER THAN OPERATORS friend bool operator>(const Finitely_critical_multi_filtration& a, const Finitely_critical_multi_filtration& b) { - return b=(const Finitely_critical_multi_filtration& a, const Finitely_critical_multi_filtration& b) { - return b<=a; // C'est honteux. + return b<=a; } Finitely_critical_multi_filtration& operator=(const Finitely_critical_multi_filtration& a){ @@ -133,8 +105,10 @@ class Finitely_critical_multi_filtration : public std::vector { return std::vector>(to_convert.begin(), to_convert.end());; } void push_to(const Finitely_critical_multi_filtration& x){ - if (this->size() != x.size()) - {std::cerr << "Does only work with 1-critical filtrations ! Sizes " << this->size() << " and " << x.size() << "are different !" << std::endl; return;} + if (this->size() != x.size()){ + std::cerr << "Does only work with 1-critical filtrations ! Sizes " << this->size() << " and " << x.size() << "are different !" << std::endl; + throw std::logic_error("Bad sizes"); + } for (unsigned int i = 0; i < x.size(); i++) this->at(i) = this->at(i) > x[i] ? this->at(i) : x[i]; } @@ -145,6 +119,8 @@ class Finitely_critical_multi_filtration : public std::vector { ); } + + // scalar product of a filtration value with x. T linear_projection(const std::vector& x){ T projection=0; unsigned int size = std::min(x.size(), this->size());