diff --git a/CMakeLists.txt b/CMakeLists.txt index ccd0635dd5..52e2763b41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,8 @@ add_gudhi_module(Toplex_map) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) add_gudhi_module(Persistence_matrix) +add_gudhi_module(Multi_persistence) +add_gudhi_module(Multi_filtration) # Include module CMake subdirectories # GUDHI_SUB_DIRECTORIES is managed in CMAKE_MODULE_PATH/GUDHI_modules.cmake diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b7992e03b8..680fcc427e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,8 @@ add_gudhi_module(Toplex_map) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) add_gudhi_module(Persistence_matrix) +add_gudhi_module(Multi_persistence) +add_gudhi_module(Multi_filtration) set(GUDHI_BIBLIO_DIR ${CMAKE_SOURCE_DIR}) # For "make doxygen" - Requires GUDHI_USER_VERSION_DIR to be set diff --git a/src/Multi_filtration/include/gudhi/Multi_critical_filtration.h b/src/Multi_filtration/include/gudhi/Multi_critical_filtration.h new file mode 100644 index 0000000000..8d754ea37a --- /dev/null +++ b/src/Multi_filtration/include/gudhi/Multi_critical_filtration.h @@ -0,0 +1,500 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): David Loiseaux + * + * Copyright (C) 2023 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef MULTI_CRITICAL_FILTRATIONS_H_ +#define MULTI_CRITICAL_FILTRATIONS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Gudhi::multi_filtration { + +/** + * Multi-critical filtration extension to \ref One_critical_filtration . + * If the `co` parameter is set to true, it reverses the poset order, + * i.e., the order \f$\le\f$ in \f$\mathbb R^n\f$ becomes \f$\ge\f$. + * + * if `multi_filtration_` contains the points \f$(a_1, a_2, \ldots, a_k) \in (\mathbb R^n)^k\f$, + * then a new point \f$x\f$ will be in this filtration if there exists an \f$a_i\f$ such that + * \f$a_i \le x\f$. + * + * \ingroup multi_filtration + + */ +template class Multi_critical_filtration { +public: + using value_type = T; + using OneCritical = One_critical_filtration; // Type of the One critical subtype + template + using Base = Multi_critical_filtration; + std::size_t num_parameters() const { return multi_filtration_.size() == 0 ? 0 : multi_filtration_[0].size(); } + Multi_critical_filtration() : multi_filtration_(1) + { + multi_filtration_[0] = co ? One_critical_filtration::inf() : One_critical_filtration::minus_inf(); + }; // initialize at 1, with 0 parameter (consistent with below) + Multi_critical_filtration(int n) + : multi_filtration_({One_critical_filtration( + n)}){}; // minus infinity by default + Multi_critical_filtration(int n, T value) + : multi_filtration_({One_critical_filtration( + n, value)}){}; // std::vector(n, value){}; + Multi_critical_filtration(std::initializer_list init) + : multi_filtration_({One_critical_filtration( + init)}){}; // : std::vector({std::vector(init)}; + Multi_critical_filtration(const std::vector &v) : multi_filtration_({v}){}; + Multi_critical_filtration(std::vector &&v) : multi_filtration_({std::move(v)}){}; + Multi_critical_filtration(const std::vector> &v) : multi_filtration_(v){}; + Multi_critical_filtration(std::vector> &&v) : multi_filtration_(std::move(v)){}; + Multi_critical_filtration(typename std::vector::iterator it_begin, + typename std::vector::iterator it_end) + : multi_filtration_( + {One_critical_filtration(it_begin, it_end)}){}; + Multi_critical_filtration(typename std::vector::const_iterator it_begin, + typename std::vector::const_iterator it_end) + : multi_filtration_({One_critical_filtration( + it_begin, it_end)}){}; // : std::vector(it_begin, it_end){}; + Multi_critical_filtration(const Multi_critical_filtration &other) + : multi_filtration_(other.multi_filtration_){}; + + Multi_critical_filtration &operator=(const Multi_critical_filtration &other) { + this->multi_filtration_ = other.multi_filtration_; + return *this; + } + inline friend bool + operator==(const Multi_critical_filtration &self, + const Multi_critical_filtration &to_compare) { + if (self.num_generators() != to_compare.num_generators()) + return false; + auto it = to_compare.begin(); + for (auto i = 0u; i < self.num_generators(); i++) { + if (self[i] != *(it++)) + return false; + } + return true; + } + void reserve(std::size_t n) { this->multi_filtration_.reserve(n); } + void set_num_generators(std::size_t n) {this->multi_filtration_.resize(n);} + + inline bool is_inf() const { + return this->multi_filtration_.size() == 1 && + this->multi_filtration_[0].is_inf(); + } + inline bool is_minus_inf() const { + return this->multi_filtration_.size() == 1 && + this->multi_filtration_[0].is_minus_inf(); + } + inline bool is_nan() const { + return this->multi_filtration_.size() == 1 && + this->multi_filtration_[0].is_nan(); + } + inline bool is_finite() const { + if (this->empty()) + return false; + for (auto &stuff : *this) { + if (!stuff.is_finite()) + return false; + } + return true; + } + + operator OneCritical() const { + assert(this->num_generators() == 1); + return this->multi_filtration_[0]; + } + + OneCritical &operator[](std::size_t i) { return this->multi_filtration_[i]; } + inline OneCritical factorize_below() const { + if (this->num_generators() == 0) [[unlikely]] + return OneCritical(); + OneCritical result(multi_filtration_[0].num_parameters(), OneCritical::T_inf); + for (const auto &stuff : this->multi_filtration_) { + if (stuff.is_nan() || stuff.is_minus_inf()) + return stuff; + if (stuff.is_inf()) + continue; + for (std::size_t i = 0; i < stuff.num_parameters(); ++i) { + result[i] = std::min(result[i], stuff[i]); + } + } + return result; + } + /* + * returns the smallest value for the poset order that is bigger than all of the values + * in this multi filtration + */ + inline OneCritical factorize_above() const { + if (this->num_generators() == 0) [[unlikely]] + return OneCritical(); + OneCritical result(multi_filtration_[0].num_parameters(), -OneCritical::T_inf); + for (auto &stuff : this->multi_filtration_) { + if (stuff.is_nan() || stuff.is_inf()) + return stuff; + if (stuff.is_minus_inf()) + continue; + for (std::size_t i = 0; i < stuff.num_parameters(); ++i) { + result[i] = std::max(result[i], stuff[i]); + } + } + return result; + } + /** \brief This functions take the filtration value `this` and pushes it to + * the cone \f$ \{ y\in \mathbb R^n : y>=x \} \f$. After calling this method, + * the value of this is updated to \f$ \mathrm{this} = \min \{ y\in \mathbb + * R^n : y>=this \}\cap \{ y\in \mathbb R^n : y>=x \} + * @param[in] x The target filtration value on which to push `this`. + */ + inline void push_to(const One_critical_filtration &x) { + if (this->is_inf() || this->is_nan() || x.is_nan() || x.is_minus_inf()) + return; + if (x.is_inf() || this->is_minus_inf()) { + *this = x; + return; + } + for (auto &stuff : *this) { + stuff.push_to(x); + } + } + // TODO : this is not well defined for kcritical <-> kcritical + + /** \brief This functions take the filtration value `this` and pulls it to the + * cone \f$ \{ y\in \mathbb R^n : y<=x \} \f$. After calling this method, the + * value of this is updated to \f$ \mathrm{this} = \max \{ y\in \mathbb R^n : + * y<=this \}\cap \{ y\in \mathbb R^n : y<=x \} + * @param[in] x The target filtration value on which to push `this`. + */ + inline void pull_to(const One_critical_filtration &x) { + if (x.is_inf() || this->is_nan() || x.is_nan() || this->is_minus_inf()) + return; + if (this->is_inf() || x.is_minus_inf()) { + *this = x; + return; + } + for (auto &stuff : *this) { + stuff.pull_to(x); + } + } + // cannot be const, as gudhi iterators are not const + template inline U linear_projection(const std::vector &x) { + if constexpr (co) { + U projection = std::numeric_limits::lowest(); + for (const auto &y : *this) { + projection = std::max(projection, y.linear_projection(x)); + } + return projection; + } else { + U projection = std::numeric_limits::max(); + for (auto &y : *this) { // cannot be const (Gudhi) + projection = std::min(projection, y.linear_projection(x)); + } + return projection; + } + } + + /* + * Checks if b is cleanable with respect to a + */ + static inline bool dominates(const OneCritical&a, const OneCritical&b, value_type max_error) { + if constexpr (co) + return a - max_error <= b; + else { + return a + max_error >= b; + } + } + + static inline bool dominates(const OneCritical&a, const OneCritical&b) { + if constexpr (co) + return a <= b; + else { + return a >= b; + } + } + static inline bool strictly_dominates(const OneCritical&a, const OneCritical&b) { + if constexpr (co) + return a < b; + else { + return a > b; + } + } + + /* + * Same method as the one in OneCriticalFiltration. + * Given a grid, and assuming that `this` are the coordianates + * in this grid, evaluate `this` into this grid + */ + template + inline Multi_critical_filtration + evaluate_in_grid(const std::vector>& grid) const { + Multi_critical_filtration out(this->num_generators()); + for (std::size_t i = 0; i < this->num_generators(); ++i){ + out[i] = this->operator[](i).evaluate_in_grid(grid); + } + return out; + } + + /* + * Remove redundant values + */ + inline void clean(value_type max_error = 0) { + // A bit ugly, todo : erase+removeif ? + for (std::size_t i = 0; i < multi_filtration_.size(); i++) { + for (std::size_t j = 0; j < multi_filtration_.size(); j++) { + if (i == j) + continue; + if (dominates(multi_filtration_[j], multi_filtration_[i], max_error)) { + multi_filtration_[i].clear(); + } + while (j < multi_filtration_.size() && dominates(multi_filtration_[i], multi_filtration_[j], max_error)) { + multi_filtration_[j].clear(); + i--; + } + } + } + multi_filtration_.erase( + std::remove_if(multi_filtration_.begin(), multi_filtration_.end(), + [](const One_critical_filtration &a) { + return a.empty(); + }), + multi_filtration_.end()); + } + + + /* + * Adds a birth point to the list of births, + * if it is useful (according to the method `dominate`) + */ + inline void add_point(const One_critical_filtration &x) { + const bool verbose = false; + if (multi_filtration_.empty()) { + if constexpr (verbose) + std::cout << "Adding x=" << x << " (currently empty)" << std::endl; + multi_filtration_.push_back(x); + return; + } + for (const auto &y : multi_filtration_){ + if (dominates(x,y)){ + return; + } + } + if constexpr (verbose) + std::cout << "x: " << x << " is useful, removing unnecessary entries" + << std::endl; + multi_filtration_.erase( + std::remove_if(multi_filtration_.begin(), multi_filtration_.end(), + [&x](const One_critical_filtration &y) { + if constexpr (verbose) { + if (dominates(y, x)) { + std::cout << "Removing y=" << y << std::endl; + } else { + std::cout << "Keeping y=" << y << std::endl; + } + } + return dominates(y, x); + }), + multi_filtration_.end()); + + multi_filtration_.push_back(x); + } + inline void re_clean(){ + // Ensures all points are useful again. Can be useful if points are added manually. + // TODO : maybe optimize + Multi_critical_filtration out; // should be inf + out.multi_filtration_.reserve(this->multi_filtration_.size()); + for (const auto& x : multi_filtration_){ + out.add_point(x); + } + std::swap(multi_filtration_, out); + } + + // easy debug + inline friend std::ostream &operator<<(std::ostream &stream, + const Multi_critical_filtration &truc) { + if (truc.is_inf()) { + stream << "[inf, ..., inf]"; + return stream; + } + if (truc.is_minus_inf()) { + stream << "[-inf, ..., -inf]"; + return stream; + } + if (truc.is_nan()) { + stream << "[NaN]"; + return stream; + } + stream << "(k=" << truc.multi_filtration_.size() << ")["; + for (const auto &machin : truc) { + stream << machin << "; "; + } + if (truc.multi_filtration_.size() > 0) { + stream << "\b" + << "\b"; + } + stream << "]"; + return stream; + } + inline void clear() { multi_filtration_.clear(); } + inline bool empty() const { return multi_filtration_.empty(); } + inline const OneCritical& operator[] (std::size_t i) const { return multi_filtration_[i]; } + + inline typename std::vector>::iterator + begin() { + return multi_filtration_.begin(); + } + inline typename std::vector>::iterator + end() { + return multi_filtration_.end(); + } + inline typename std::vector< + One_critical_filtration>::const_iterator + begin() const { + return multi_filtration_.begin(); + } + inline typename std::vector< + One_critical_filtration>::const_iterator + end() const { + return multi_filtration_.end(); + } + + + /* + * Same as its one critical counterpart. + * If a grid is given, projects multifiltration_ on this grid and returns + * multi critical filtration composed of the coordinates in the given grid + * + */ + template + inline Multi_critical_filtration + coordinates_in_grid(const std::vector& grid) const { + assert(grid.size() >= this->num_generators()); + Multi_critical_filtration out(this->num_generators()); + for (std::size_t i = 0u; i < this->num_generators(); ++i) { + out[i] = this->multi_filtration_[i].coordinates_in_grid(grid); + } + return out; + } + /* + * Same as `coordinates_in_grid`, but does the operation in-place. + * + */ + template + inline void coordinates_in_grid_inplace(const std::vector& grid, + bool coordinate = true) { + assert(grid.size() >= this->num_generators()); + for (auto &x : this->multi_filtration_) { + x.coordinates_in_grid_inplace(grid, coordinate); + } + } + template inline Multi_critical_filtration astype() const { + std::vector> out(this->num_generators()); + for (std::size_t i = 0u; i < this->num_generators(); ++i) { + out[i] = this->multi_filtration_[i].template astype(); + } + return Multi_critical_filtration(std::move(out)); + } + inline void push_back(const OneCritical& x){ + multi_filtration_.push_back(x); + } + inline const std::vector>& as_vector() const { + return multi_filtration_; + } + + inline std::vector> as_VECTOR() const { + std::vector> out(this->num_generators(), + std::vector(this->num_parameters())); + for (std::size_t i = 0; i < this->num_generators(); ++i) { + for (std::size_t j = 0; j < this->num_parameters(); ++j) { + out[i][j] = multi_filtration_[i][j]; + } + } + return out; + } + + inline void _clean(bool keep_inf=true) { + multi_filtration_.erase(std::remove_if(multi_filtration_.begin(), multi_filtration_.end(), + [keep_inf](const OneCritical &a) { + return a.empty() || + ((!keep_inf) && + (a.is_inf() || a.is_minus_inf())); + }), + multi_filtration_.end()); + } + inline std::size_t num_generators() const { + return multi_filtration_.size(); + } + + + + // TODO : this costs a lot... optimize / cheat in some way for python ? + /* + * Checks if `this`, seen as a birth curve is under the `other` birth curve, + * + */ + inline bool operator<(const Multi_critical_filtration &other) const { + //check if this curves is below other's curve + // ie for each guy in this, check if there is a guy in other that dominates him + for (std::size_t i = 0u; i < multi_filtration_.size(); ++i) { + for (std::size_t j = 0u; j < other.multi_filtration_.size(); ++j) { + // i(const Multi_critical_filtration &other) const { + return other < *this; + } + + /* + * Checks if `this`, seen as a birth curve is under the `other` birth curve, + */ + inline bool operator<=(const Multi_critical_filtration &other) const { + //check if this curves is below other's curve + // ie for each guy in this, check if there is a guy in other that dominates him + for (std::size_t i = 0u; i < multi_filtration_.size(); ++i) { + for (std::size_t j = 0u; j < other.multi_filtration_.size(); ++j) { + // i <= j + if (dominates(other.multi_filtration_[j], multi_filtration_[i])) + continue; + } + return false; + } + return true; + } + /* + * Checks if `this`, seen as a birth curve is over the `other` birth curve, + */ + inline bool operator>=(const Multi_critical_filtration &other) const { + return other <= *this; + } + +public: + // for compiler + constexpr static const T T_inf = One_critical_filtration::T_inf; + constexpr static const bool is_multi_critical = true; + +private: + std::vector> multi_filtration_; +}; + +} // namespace Gudhi::multi_filtration + +#endif // MULTI_CRITICAL_FILTRATIONS_H_ diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Finitely_critical_filtrations.h b/src/Multi_filtration/include/gudhi/One_critical_filtration.h similarity index 50% rename from src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Finitely_critical_filtrations.h rename to src/Multi_filtration/include/gudhi/One_critical_filtration.h index 17b84a7aee..bfc0ae01b4 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Finitely_critical_filtrations.h +++ b/src/Multi_filtration/include/gudhi/One_critical_filtration.h @@ -1,7 +1,6 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which - * is released under MIT. See file LICENSE or go to - * https://gudhi.inria.fr/licensing/ for full license details. Author(s): David - +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): David Loiseaux * * Copyright (C) 2023 Inria * @@ -9,8 +8,8 @@ * - YYYY/MM Author: Description of the modification */ -#ifndef FINITELY_CRITICAL_FILTRATIONS_H_ -#define FINITELY_CRITICAL_FILTRATIONS_H_ +#ifndef ONE_CRITICAL_FILTRATIONS_H_ +#define ONE_CRITICAL_FILTRATIONS_H_ #include #include @@ -21,13 +20,13 @@ #include #include -namespace Gudhi::multiparameter::multi_filtrations { +namespace Gudhi::multi_filtration { /** * \brief Vector-like filtration value, for multiparameter persistence, with * numpy-like methods. * - * \ingroup multiparameter + * \ingroup multi_filtration * * \details Child of `std::vector` that has numpy-like pointwise operators. * One critical simplicial filtrations are filtrations such that the lifetime @@ -538,514 +537,29 @@ class One_critical_filtration : public std::vector { constexpr static bool is_multi_critical = false; }; -/** - * Multi-critical filtration extension to \ref One_critical_filtration . - * If the `co` parameter is set to true, it reverses the poset order, - * i.e., the order \f$\le\f$ in \f$\mathbb R^n\f$ becomes \f$\ge\f$. - * - * if `multi_filtration_` contains the points \f$(a_1, a_2, \ldots, a_k) \in (\mathbb R^n)^k\f$, - * then a new point \f$x\f$ will be in this filtration if there exists an \f$a_i\f$ such that - * \f$a_i \le x\f$. - * - */ -template class Multi_critical_filtration { -public: - using value_type = T; - using OneCritical = One_critical_filtration; // Type of the One critical subtype - template - using Base = Multi_critical_filtration; - std::size_t num_parameters() const { return multi_filtration_.size() == 0 ? 0 : multi_filtration_[0].size(); } - Multi_critical_filtration() : multi_filtration_(1) - { - multi_filtration_[0] = co ? One_critical_filtration::inf() : One_critical_filtration::minus_inf(); - }; // initialize at 1, with 0 parameter (consistent with below) - Multi_critical_filtration(int n) - : multi_filtration_({One_critical_filtration( - n)}){}; // minus infinity by default - Multi_critical_filtration(int n, T value) - : multi_filtration_({One_critical_filtration( - n, value)}){}; // std::vector(n, value){}; - Multi_critical_filtration(std::initializer_list init) - : multi_filtration_({One_critical_filtration( - init)}){}; // : std::vector({std::vector(init)}; - Multi_critical_filtration(const std::vector &v) : multi_filtration_({v}){}; - Multi_critical_filtration(std::vector &&v) : multi_filtration_({std::move(v)}){}; - Multi_critical_filtration(const std::vector> &v) : multi_filtration_(v){}; - Multi_critical_filtration(std::vector> &&v) : multi_filtration_(std::move(v)){}; - Multi_critical_filtration(typename std::vector::iterator it_begin, - typename std::vector::iterator it_end) - : multi_filtration_( - {One_critical_filtration(it_begin, it_end)}){}; - Multi_critical_filtration(typename std::vector::const_iterator it_begin, - typename std::vector::const_iterator it_end) - : multi_filtration_({One_critical_filtration( - it_begin, it_end)}){}; // : std::vector(it_begin, it_end){}; - Multi_critical_filtration(const Multi_critical_filtration &other) - : multi_filtration_(other.multi_filtration_){}; - - Multi_critical_filtration &operator=(const Multi_critical_filtration &other) { - this->multi_filtration_ = other.multi_filtration_; - return *this; - } - inline friend bool - operator==(const Multi_critical_filtration &self, - const Multi_critical_filtration &to_compare) { - if (self.num_generators() != to_compare.num_generators()) - return false; - auto it = to_compare.begin(); - for (auto i = 0u; i < self.num_generators(); i++) { - if (self[i] != *(it++)) - return false; - } - return true; - } - void reserve(std::size_t n) { this->multi_filtration_.reserve(n); } - void set_num_generators(std::size_t n) {this->multi_filtration_.resize(n);} - - inline bool is_inf() const { - return this->multi_filtration_.size() == 1 && - this->multi_filtration_[0].is_inf(); - } - inline bool is_minus_inf() const { - return this->multi_filtration_.size() == 1 && - this->multi_filtration_[0].is_minus_inf(); - } - inline bool is_nan() const { - return this->multi_filtration_.size() == 1 && - this->multi_filtration_[0].is_nan(); - } - inline bool is_finite() const { - if (this->empty()) - return false; - for (auto &stuff : *this) { - if (!stuff.is_finite()) - return false; - } - return true; - } - - operator OneCritical() const { - assert(this->num_generators() == 1); - return this->multi_filtration_[0]; - } - - OneCritical &operator[](std::size_t i) { return this->multi_filtration_[i]; } - inline OneCritical factorize_below() const { - if (this->num_generators() == 0) [[unlikely]] - return OneCritical(); - OneCritical result(multi_filtration_[0].num_parameters(), OneCritical::T_inf); - for (const auto &stuff : this->multi_filtration_) { - if (stuff.is_nan() || stuff.is_minus_inf()) - return stuff; - if (stuff.is_inf()) - continue; - for (std::size_t i = 0; i < stuff.num_parameters(); ++i) { - result[i] = std::min(result[i], stuff[i]); - } - } - return result; - } - /* - * returns the smallest value for the poset order that is bigger than all of the values - * in this multi filtration - */ - inline OneCritical factorize_above() const { - if (this->num_generators() == 0) [[unlikely]] - return OneCritical(); - OneCritical result(multi_filtration_[0].num_parameters(), -OneCritical::T_inf); - for (auto &stuff : this->multi_filtration_) { - if (stuff.is_nan() || stuff.is_inf()) - return stuff; - if (stuff.is_minus_inf()) - continue; - for (std::size_t i = 0; i < stuff.num_parameters(); ++i) { - result[i] = std::max(result[i], stuff[i]); - } - } - return result; - } - /** \brief This functions take the filtration value `this` and pushes it to - * the cone \f$ \{ y\in \mathbb R^n : y>=x \} \f$. After calling this method, - * the value of this is updated to \f$ \mathrm{this} = \min \{ y\in \mathbb - * R^n : y>=this \}\cap \{ y\in \mathbb R^n : y>=x \} - * @param[in] x The target filtration value on which to push `this`. - */ - inline void push_to(const One_critical_filtration &x) { - if (this->is_inf() || this->is_nan() || x.is_nan() || x.is_minus_inf()) - return; - if (x.is_inf() || this->is_minus_inf()) { - *this = x; - return; - } - for (auto &stuff : *this) { - stuff.push_to(x); - } - } - // TODO : this is not well defined for kcritical <-> kcritical - - /** \brief This functions take the filtration value `this` and pulls it to the - * cone \f$ \{ y\in \mathbb R^n : y<=x \} \f$. After calling this method, the - * value of this is updated to \f$ \mathrm{this} = \max \{ y\in \mathbb R^n : - * y<=this \}\cap \{ y\in \mathbb R^n : y<=x \} - * @param[in] x The target filtration value on which to push `this`. - */ - inline void pull_to(const One_critical_filtration &x) { - if (x.is_inf() || this->is_nan() || x.is_nan() || this->is_minus_inf()) - return; - if (this->is_inf() || x.is_minus_inf()) { - *this = x; - return; - } - for (auto &stuff : *this) { - stuff.pull_to(x); - } - } - // cannot be const, as gudhi iterators are not const - template inline U linear_projection(const std::vector &x) { - if constexpr (co) { - U projection = std::numeric_limits::lowest(); - for (const auto &y : *this) { - projection = std::max(projection, y.linear_projection(x)); - } - return projection; - } else { - U projection = std::numeric_limits::max(); - for (auto &y : *this) { // cannot be const (Gudhi) - projection = std::min(projection, y.linear_projection(x)); - } - return projection; - } - } - - /* - * Checks if b is cleanable with respect to a - */ - static inline bool dominates(const OneCritical&a, const OneCritical&b, value_type max_error) { - if constexpr (co) - return a - max_error <= b; - else { - return a + max_error >= b; - } - } - - static inline bool dominates(const OneCritical&a, const OneCritical&b) { - if constexpr (co) - return a <= b; - else { - return a >= b; - } - } - static inline bool strictly_dominates(const OneCritical&a, const OneCritical&b) { - if constexpr (co) - return a < b; - else { - return a > b; - } - } - - /* - * Same method as the one in OneCriticalFiltration. - * Given a grid, and assuming that `this` are the coordianates - * in this grid, evaluate `this` into this grid - */ - template - inline Multi_critical_filtration - evaluate_in_grid(const std::vector>& grid) const { - Multi_critical_filtration out(this->num_generators()); - for (std::size_t i = 0; i < this->num_generators(); ++i){ - out[i] = this->operator[](i).evaluate_in_grid(grid); - } - return out; - } - - /* - * Remove redundant values - */ - inline void clean(value_type max_error = 0) { - // A bit ugly, todo : erase+removeif ? - for (std::size_t i = 0; i < multi_filtration_.size(); i++) { - for (std::size_t j = 0; j < multi_filtration_.size(); j++) { - if (i == j) - continue; - if (dominates(multi_filtration_[j], multi_filtration_[i], max_error)) { - multi_filtration_[i].clear(); - } - while (j < multi_filtration_.size() && dominates(multi_filtration_[i], multi_filtration_[j], max_error)) { - multi_filtration_[j].clear(); - i--; - } - } - } - multi_filtration_.erase( - std::remove_if(multi_filtration_.begin(), multi_filtration_.end(), - [](const One_critical_filtration &a) { - return a.empty(); - }), - multi_filtration_.end()); - } - - - /* - * Adds a birth point to the list of births, - * if it is useful (according to the method `dominate`) - */ - inline void add_point(const One_critical_filtration &x) { - const bool verbose = false; - if (multi_filtration_.empty()) { - if constexpr (verbose) - std::cout << "Adding x=" << x << " (currently empty)" << std::endl; - multi_filtration_.push_back(x); - return; - } - for (const auto &y : multi_filtration_){ - if (dominates(x,y)){ - return; - } - } - if constexpr (verbose) - std::cout << "x: " << x << " is useful, removing unnecessary entries" - << std::endl; - multi_filtration_.erase( - std::remove_if(multi_filtration_.begin(), multi_filtration_.end(), - [&x](const One_critical_filtration &y) { - if constexpr (verbose) { - if (dominates(y, x)) { - std::cout << "Removing y=" << y << std::endl; - } else { - std::cout << "Keeping y=" << y << std::endl; - } - } - return dominates(y, x); - }), - multi_filtration_.end()); - - multi_filtration_.push_back(x); - } - inline void re_clean(){ - // Ensures all points are useful again. Can be useful if points are added manually. - // TODO : maybe optimize - Multi_critical_filtration out; // should be inf - out.multi_filtration_.reserve(this->multi_filtration_.size()); - for (const auto& x : multi_filtration_){ - out.add_point(x); - } - std::swap(multi_filtration_, out); - } - - // easy debug - inline friend std::ostream &operator<<(std::ostream &stream, - const Multi_critical_filtration &truc) { - if (truc.is_inf()) { - stream << "[inf, ..., inf]"; - return stream; - } - if (truc.is_minus_inf()) { - stream << "[-inf, ..., -inf]"; - return stream; - } - if (truc.is_nan()) { - stream << "[NaN]"; - return stream; - } - stream << "(k=" << truc.multi_filtration_.size() << ")["; - for (const auto &machin : truc) { - stream << machin << "; "; - } - if (truc.multi_filtration_.size() > 0) { - stream << "\b" - << "\b"; - } - stream << "]"; - return stream; - } - inline void clear() { multi_filtration_.clear(); } - inline bool empty() const { return multi_filtration_.empty(); } - inline const OneCritical& operator[] (std::size_t i) const { return multi_filtration_[i]; } - - inline typename std::vector>::iterator - begin() { - return multi_filtration_.begin(); - } - inline typename std::vector>::iterator - end() { - return multi_filtration_.end(); - } - inline typename std::vector< - One_critical_filtration>::const_iterator - begin() const { - return multi_filtration_.begin(); - } - inline typename std::vector< - One_critical_filtration>::const_iterator - end() const { - return multi_filtration_.end(); - } - - - /* - * Same as its one critical counterpart. - * If a grid is given, projects multifiltration_ on this grid and returns - * multi critical filtration composed of the coordinates in the given grid - * - */ - template - inline Multi_critical_filtration - coordinates_in_grid(const std::vector& grid) const { - assert(grid.size() >= this->num_generators()); - Multi_critical_filtration out(this->num_generators()); - for (std::size_t i = 0u; i < this->num_generators(); ++i) { - out[i] = this->multi_filtration_[i].coordinates_in_grid(grid); - } - return out; - } - /* - * Same as `coordinates_in_grid`, but does the operation in-place. - * - */ - template - inline void coordinates_in_grid_inplace(const std::vector& grid, - bool coordinate = true) { - assert(grid.size() >= this->num_generators()); - for (auto &x : this->multi_filtration_) { - x.coordinates_in_grid_inplace(grid, coordinate); - } - } - template inline Multi_critical_filtration astype() const { - std::vector> out(this->num_generators()); - for (std::size_t i = 0u; i < this->num_generators(); ++i) { - out[i] = this->multi_filtration_[i].template astype(); - } - return Multi_critical_filtration(std::move(out)); - } - inline void push_back(const OneCritical& x){ - multi_filtration_.push_back(x); - } - inline const std::vector>& as_vector() const { - return multi_filtration_; - } - - inline std::vector> as_VECTOR() const { - std::vector> out(this->num_generators(), - std::vector(this->num_parameters())); - for (std::size_t i = 0; i < this->num_generators(); ++i) { - for (std::size_t j = 0; j < this->num_parameters(); ++j) { - out[i][j] = multi_filtration_[i][j]; - } - } - return out; - } - - inline void _clean(bool keep_inf=true) { - multi_filtration_.erase(std::remove_if(multi_filtration_.begin(), multi_filtration_.end(), - [keep_inf](const OneCritical &a) { - return a.empty() || - ((!keep_inf) && - (a.is_inf() || a.is_minus_inf())); - }), - multi_filtration_.end()); - } - inline std::size_t num_generators() const { - return multi_filtration_.size(); - } - - - - // TODO : this costs a lot... optimize / cheat in some way for python ? - /* - * Checks if `this`, seen as a birth curve is under the `other` birth curve, - * - */ - inline bool operator<(const Multi_critical_filtration &other) const { - //check if this curves is below other's curve - // ie for each guy in this, check if there is a guy in other that dominates him - for (std::size_t i = 0u; i < multi_filtration_.size(); ++i) { - for (std::size_t j = 0u; j < other.multi_filtration_.size(); ++j) { - // i(const Multi_critical_filtration &other) const { - return other < *this; - } - - /* - * Checks if `this`, seen as a birth curve is under the `other` birth curve, - */ - inline bool operator<=(const Multi_critical_filtration &other) const { - //check if this curves is below other's curve - // ie for each guy in this, check if there is a guy in other that dominates him - for (std::size_t i = 0u; i < multi_filtration_.size(); ++i) { - for (std::size_t j = 0u; j < other.multi_filtration_.size(); ++j) { - // i <= j - if (dominates(other.multi_filtration_[j], multi_filtration_[i])) - continue; - } - return false; - } - return true; - } - /* - * Checks if `this`, seen as a birth curve is over the `other` birth curve, - */ - inline bool operator>=(const Multi_critical_filtration &other) const { - return other <= *this; - } - -public: - // for compiler - constexpr static const T T_inf = One_critical_filtration::T_inf; - constexpr static const bool is_multi_critical = true; - -private: - std::vector> multi_filtration_; -}; - -} // namespace Gudhi::multiparameter::multi_filtrations +} // namespace Gudhi::multi_filtration namespace std { template -class numeric_limits> { +class numeric_limits> { public: static constexpr bool has_infinity = std::numeric_limits::has_infinity; - static Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration - infinity() throw() { - return Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration( - 1, std::numeric_limits::infinity()); + static Gudhi::multi_filtration::One_critical_filtration infinity() throw() { + return Gudhi::multi_filtration::One_critical_filtration(1, std::numeric_limits::infinity()); }; - static Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration - minus_infinity() throw() { - return Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration( - 1, -std::numeric_limits::infinity()); + static Gudhi::multi_filtration::One_critical_filtration minus_infinity() throw() { + return Gudhi::multi_filtration::One_critical_filtration(1, -std::numeric_limits::infinity()); }; - static Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration - max() throw() { - return Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration(1, std::numeric_limits::max()); + static Gudhi::multi_filtration::One_critical_filtration max() throw() { + return Gudhi::multi_filtration::One_critical_filtration(1, std::numeric_limits::max()); }; - static Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration - quiet_NaN() throw() { - return Gudhi::multiparameter::multi_filtrations:: - One_critical_filtration(1, - numeric_limits::quiet_NaN()); + static Gudhi::multi_filtration::One_critical_filtrationquiet_NaN() throw() { + return Gudhi::multi_filtration::One_critical_filtration(1, numeric_limits::quiet_NaN()); }; }; } // namespace std -#endif // FINITELY_CRITICAL_FILTRATIONS_H_ +#endif // ONE_CRITICAL_FILTRATIONS_H_ diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Box.h b/src/Multi_persistence/include/gudhi/Box.h similarity index 90% rename from src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Box.h rename to src/Multi_persistence/include/gudhi/Box.h index f7ce8ef5d2..961db27c90 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Box.h +++ b/src/Multi_persistence/include/gudhi/Box.h @@ -1,36 +1,32 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which - * is released under MIT. See file LICENSE or go to - * https://gudhi.inria.fr/licensing/ for full license details. Author(s): David - * Loiseaux +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): David Loiseaux * * Copyright (C) 2023 Inria * * Modification(s): * - YYYY/MM Author: Description of the modification */ -/** - * @file box.h - * @author David Loiseaux - * @brief BOX. - */ + #ifndef BOX_H_INCLUDED #define BOX_H_INCLUDED -#include #include #include -#include "Finitely_critical_filtrations.h" +#include + + +namespace Gudhi::multi_persistence { /** * @brief Simple box in \f$\mathbb R^n\f$ . + * + * @ingroup multi_persistence */ - -namespace Gudhi::multiparameter::multi_filtrations { - template class Box { - using point_type = One_critical_filtration; + using point_type = Gudhi::multi_filtration::One_critical_filtration; public: Box(); @@ -177,6 +173,6 @@ template inline void Box::threshold_down(point_type &x) const { return; } -} // namespace Gudhi::multiparameter::multi_filtrations +} // namespace Gudhi::multi_persistence #endif // BOX_H_INCLUDED diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Line.h b/src/Multi_persistence/include/gudhi/Line.h similarity index 87% rename from src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Line.h rename to src/Multi_persistence/include/gudhi/Line.h index 3bc69638c5..453cb31f05 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/multi_filtrations/Line.h +++ b/src/Multi_persistence/include/gudhi/Line.h @@ -1,36 +1,39 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which - * is released under MIT. See file LICENSE or go to - * https://gudhi.inria.fr/licensing/ for full license details. Author(s): David - * Loiseaux +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): David Loiseaux * - * tCopyright (C) 2023 Inria + * Copyright (C) 2023 Inria * * Modification(s): * - YYYY/MM Author: Description of the modification */ + #ifndef LINE_FILTRATION_TRANSLATION_H_INCLUDED #define LINE_FILTRATION_TRANSLATION_H_INCLUDED -#include "Box.h" -#include "Finitely_critical_filtrations.h" #include #include -namespace Gudhi::multiparameter::multi_filtrations { +#include +#include +#include + +namespace Gudhi::multi_persistence { -/* -* A line in \f$\mathbb R^n\f$, with some helpers to project points on it. -* When the direction is not given, it is assumed to be diagonal. -* As the line has a builtin parametrization, points in \f$\mathbb R^n\f$ -* that are on a line are given a time parameter in \f$\mathbb R\f$. -* The method that end with a 2 returns the time t, while the other -* ones return the full coordinates -*/ +/* A line in \f$\mathbb R^n\f$, with some helpers to project points on it. + * When the direction is not given, it is assumed to be diagonal. + * As the line has a builtin parametrization, points in \f$\mathbb R^n\f$ + * that are on a line are given a time parameter in \f$\mathbb R\f$. + * The method that end with a 2 returns the time t, while the other + * ones return the full coordinates + * + * @ingroup multi_persistence + */ template class Line { public: - using point_type = One_critical_filtration; - using kcritical_point_type = Multi_critical_filtration; + using point_type = Gudhi::multi_filtration::One_critical_filtration; + using kcritical_point_type = Gudhi::multi_filtration::Multi_critical_filtration; /* * Checks that the argument define a correct, positively slopped line. */ @@ -95,7 +98,7 @@ template class Line { }; template inline bool Line::check_direction() const { bool is_trivial=true; - for (const auto& stuff : basepoint_){ + for (const auto& stuff : basepOne_critical_filtrationoint_){ if (!stuff){ is_trivial = false;} if (stuff < 0){ throw std::invalid_argument("Direction should have positive entries.");} } @@ -113,7 +116,7 @@ Line::Line(const point_type &x, const point_type &v) : basepoint_(x), direction_(v) {check_direction();} -template +template One_critical_filtration inline typename Line::point_type Line::push_forward(point_type x) const { // TODO remove copy if (x.is_inf() || x.is_nan() || x.is_minus_inf()) @@ -257,6 +260,6 @@ Line::get_bounds(const Box &box) const { return {this->push_forward(box.get_bottom_corner()), this->push_back(box.get_upper_corner())}; } -} // namespace Gudhi::multiparameter::multi_filtrations +} // namespace Gudhi::multi_persistence #endif // LINE_FILTRATION_TRANSLATION_H_INCLUDED diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_multi.h b/src/Multi_persistence/include/gudhi/Simplex_tree_multi.h similarity index 88% rename from src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_multi.h rename to src/Multi_persistence/include/gudhi/Simplex_tree_multi.h index d43b047143..fd8a27fa53 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_multi.h +++ b/src/Multi_persistence/include/gudhi/Simplex_tree_multi.h @@ -14,8 +14,11 @@ #include #include -namespace Gudhi::multiparameter { -/** Model of SimplexTreeOptions, with a multiparameter filtration. */ +namespace Gudhi::multi_persistence { + +/** Model of SimplexTreeOptions, with a multiparameter filtration. + * \ingroup multi_persistence + * */ template struct Simplex_tree_options_multidimensional_filtration { public: @@ -36,14 +39,13 @@ struct Simplex_tree_options_multidimensional_filtration { * \brief Turns a 1-parameter simplextree into a multiparameter simplextree, * and keeps the 1-filtration in the 1st axis. * Default values can be specified. - * \ingroup multiparameter + * \ingroup multi_persistence * \tparam simplextree_std A non-multi simplextree * \tparam simplextree_multi A multi simplextree * \param st Simplextree to copy * \param st_multi Multiparameter simplextree container to fill. - * \param default_values If given, this vector is assume to be of size - * `num_parameters-1` and contains the default values of axes `1` to - * `num_parameters`. + * \param default_values If given, this vector is assume to be of size `num_parameters-1` and contains the default + * values of axes `1` to `num_parameters`. * */ template void multify(simplextree_std &st, simplextree_multi &st_multi, @@ -94,11 +96,13 @@ void multify(simplextree_std &st, simplextree_multi &st_multi, /** * \brief Turns a multiparameter-parameter simplextree into a 1-parameter - * simplextree. \ingroup multiparameter \tparam simplextree_std A non-multi - * simplextree \tparam simplextree_multi A multi simplextree \param st - * Simplextree to fill. \param st_multi Multiparameter simplextree to convert - * into a 1 parameter simplex tree. \param dimension The filtration parameter to - * put into the 1 parameter simplextree. + * simplextree. + * \ingroup multi_persistence + * \tparam simplextree_std A non-multi simplextree + * \tparam simplextree_multi A multi simplextree + * \param st Simplextree to fill. + * \param st_multi Multiparameter simplextree to convert into a 1 parameter simplex tree. + * \param dimension The filtration parameter to put into the 1 parameter simplextree. * */ template void flatten(simplextree_std &st, simplextree_multi &st_multi, @@ -122,7 +126,6 @@ void flatten(simplextree_std &st, simplextree_multi &st_multi, } } - -} // namespace Gudhi::multiparameter +} // namespace Gudhi::multi_persistence #endif // SIMPLEX_TREE_MULTI_H_ diff --git a/src/Simplex_tree/concept/SimplexTreeOptions.h b/src/Simplex_tree/concept/SimplexTreeOptions.h index d4aad91603..9050211dc7 100644 --- a/src/Simplex_tree/concept/SimplexTreeOptions.h +++ b/src/Simplex_tree/concept/SimplexTreeOptions.h @@ -44,7 +44,7 @@ struct SimplexTreeOptions { /// which has a `push_to` method that allows to push the filtration value `this` onto the set of points /// \f$ \{ y\in \mathrm{Filtration_value} : y\geq x\}\f$ /// that are greater than another filtration value \f$ x \f$. - /// An example of such a class is Gudhi::multiparameter::multi_filtrations::Finitely_critical_multi_filtration . + /// An example of such a class is Gudhi::multi_persistence::Finitely_critical_multi_filtration . static const bool is_multi_parameter; }; diff --git a/src/Simplex_tree/example/simplex_tree_multi.cpp b/src/Simplex_tree/example/simplex_tree_multi.cpp index 9ac7448bb0..aa81150cd2 100644 --- a/src/Simplex_tree/example/simplex_tree_multi.cpp +++ b/src/Simplex_tree/example/simplex_tree_multi.cpp @@ -9,8 +9,7 @@ */ #include -#include -#include +#include #include #include @@ -20,7 +19,7 @@ struct ST_MULTI { typedef Gudhi::linear_indexing_tag Indexing_tag; typedef int Vertex_handle; typedef float value_type; - using Filtration_value = Gudhi::multiparameter::multi_filtrations::One_critical_filtration; + using Filtration_value = Gudhi::multi_filtration::One_critical_filtration; typedef std::uint32_t Simplex_key; static const bool store_key = true; static const bool store_filtration = true; @@ -52,6 +51,7 @@ int main() { ST::Simplex_handle e = st.find(edge02); // Finitely_critical_multi_filtration has an operator<< std::cout << st.filtration(e) << std::endl; - GUDHI_CHECK(st.filtration(st.find(edge03)) == ST_MULTI::Filtration_value({4, 5, 6}), "edge03 does not have the right value."); + GUDHI_CHECK(st.filtration(st.find(edge03)) == ST_MULTI::Filtration_value({4, 5, 6}), + "edge03 does not have the right value."); } diff --git a/src/Simplex_tree/test/simplex_tree_multi_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_multi_unit_test.cpp index 2e9949c750..a801124115 100644 --- a/src/Simplex_tree/test/simplex_tree_multi_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_multi_unit_test.cpp @@ -25,22 +25,16 @@ #include #include -// ^ -// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. -#include "gudhi/Simplex_tree/Simplex_tree_multi.h" -#include "gudhi/Simplex_tree/multi_filtrations/Finitely_critical_filtrations.h" +#include +#include +#include using namespace Gudhi; -using namespace Gudhi::multiparameter; -using Gudhi::multiparameter::multi_filtrations::One_critical_filtration; -using Gudhi::multiparameter::multi_filtrations::Multi_critical_filtration; -using namespace Gudhi; -using namespace Gudhi::multiparameter; -using OneCriticalFiltration = One_critical_filtration; -using KCriticalFiltration = Multi_critical_filtration; +using OneCriticalFiltration = Gudhi::multi_filtration::One_critical_filtration; +using Stree_options_multi_filtration = Gudhi::multi_persistence::Simplex_tree_options_multidimensional_filtration; using typeST_STD = Simplex_tree; -using Stree_multi = Simplex_tree>; +using Stree_multi = Simplex_tree; typedef boost::mpl::list list_of_tested_variants; @@ -106,10 +100,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_when_empty, typeST, list_of_tested_va test_iterators_on_empty_simplex_tree(st); } -bool AreAlmostTheSame(float a, float b) { - return std::fabs(a - b) < std::numeric_limits::epsilon(); -} -bool AreAlmostTheSame(One_critical_filtration a, One_critical_filtration b) { +bool AreAlmostTheSame(Gudhi::multi_filtration::One_critical_filtration a, + Gudhi::multi_filtration::One_critical_filtration b) { assert(a.size() == b.size()); for (auto i=0u; i std::numeric_limits::epsilon()) @@ -661,7 +653,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multify_simplex_tree, typeST, list_of_tested_varia st.insert_simplex_and_subfaces({1,2,3}, 1.); BOOST_CHECK(st.get_number_of_parameters() == 1); int num_parameters = 3; - Gudhi::multiparameter::multify(st,st_multi,num_parameters,{2.,3.}); //fills st_multi by simplices of filtration [{st.filtration(sh)}, default_values[0],default_values[1], ...] + Gudhi::multi_persistence::multify(st,st_multi,num_parameters,{2.,3.}); //fills st_multi by simplices of filtration [{st.filtration(sh)}, default_values[0],default_values[1], ...] BOOST_CHECK(st_multi.get_number_of_parameters() == num_parameters); // num parameters is defined by multify BOOST_CHECK(st_multi.num_simplices() == st.num_simplices()); // simplicial complexes should be the same for (auto sh : st_multi.complex_simplex_range()){ @@ -673,7 +665,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multify_simplex_tree, typeST, list_of_tested_varia for (int dimension=0; dimension < 3; dimension++){ st.clear(); - Gudhi::multiparameter::flatten(st, st_multi, dimension); + Gudhi::multi_persistence::flatten(st, st_multi, dimension); for (auto sh : st.complex_simplex_range()){ BOOST_CHECK(st.filtration(sh) == dimension +1); } @@ -682,7 +674,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(multify_simplex_tree, typeST, list_of_tested_varia // std::clog << "********************************************************************" << std::endl; // std::clog << "TEST LINEAR PROJECTION" << std::endl; // // st has already the same simplicial complex as st_multi, and the filtration values of st_multi are all {1,2,3} - // Gudhi::multiparameter::linear_projection(st,st_multi,{17,37,73}); // sets the filtration values of st to the dot product of st_multi.filtration and {17,37,73}. + // Gudhi::multi_persistence::linear_projection(st,st_multi,{17,37,73}); // sets the filtration values of st to the dot product of st_multi.filtration and {17,37,73}. // for (auto sh : st.complex_simplex_range()){ // BOOST_CHECK(st.filtration(sh) == 1*17 + 2*37 + 3*73); // } @@ -823,7 +815,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_multi_filtration_multify) { Stree_multi st_multi; OneCriticalFiltration default_multi (3, std::numeric_limits::quiet_NaN()); - Gudhi::multiparameter::multify(st, st_multi, 3, default_multi); + Gudhi::multi_persistence::multify(st, st_multi, 3, default_multi); for (auto f_simplex : st_multi.complex_simplex_range()) { std::clog << "vertex = ("; @@ -839,13 +831,13 @@ BOOST_AUTO_TEST_CASE(simplex_tree_multi_filtration_multify) { { Simplex_tree<> copy; - Gudhi::multiparameter::flatten(copy, st_multi, 0); + Gudhi::multi_persistence::flatten(copy, st_multi, 0); BOOST_CHECK(st == copy); } { Simplex_tree<> copy; - Gudhi::multiparameter::flatten(copy, st_multi, 1); + Gudhi::multi_persistence::flatten(copy, st_multi, 1); for (auto f_simplex : copy.complex_simplex_range()) { std::clog << "vertex = ("; for (auto vertex : copy.simplex_vertex_range(f_simplex)) {