Skip to content

Commit

Permalink
cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidLapous committed Sep 26, 2023
1 parent 36de642 commit 82ce7d0
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 94 deletions.
2 changes: 1 addition & 1 deletion src/Simplex_tree/concept/SimplexTreeOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

23 changes: 7 additions & 16 deletions src/Simplex_tree/include/gudhi/Simplex_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
23 changes: 10 additions & 13 deletions src/python/include/Simplex_tree_interface_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,15 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface<Simplex_tree_

Extended_filtration_data efd;

// bool find_simplex(const Simplex& simplex) {
// return (Base::find(simplex) != Base::null_simplex());
// }
bool find_simplex(const Simplex& simplex) {
return (Base::find(simplex) != Base::null_simplex());
}

void assign_simplex_filtration(const Simplex& simplex, const Filtration_value& filtration) {
Base::assign_filtration(Base::find(simplex), filtration);
Base::clear_filtration();
}
// void assign_simplex_filtration(const Simplex& simplex, const Python_filtration_type& filtration) {
// Filtration_value& filtration_ = *(Filtration_value*)(&filtration); // Jardinage for no copy.
// Base::assign_filtration(Base::find(simplex), filtration_);
// Base::clear_filtration();
// }


bool insert(const Simplex& simplex, const Filtration_value& filtration ) {
Insertion_result result = Base::insert_simplex_and_subfaces(simplex, filtration);
Expand Down Expand Up @@ -104,7 +100,7 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface<Simplex_tree_
}
typename SimplexTreeOptions::value_type* simplex_filtration(const Simplex& simplex) {
auto& filtration = Base::filtration_mutable(Base::find(simplex));
return &filtration[0];
return &filtration[0]; // We return the pointer to get a numpy view afterward
}


Expand Down Expand Up @@ -168,6 +164,8 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface<Simplex_tree_
Base::assign_key(Base::find(simplex), key);
return;
}

// Fills a parameter with a lower-star filtration
void fill_lowerstar(const std::vector<options_multi::value_type>& filtration, int axis){
using value_type=options_multi::value_type;
for (auto &SimplexHandle : Base::complex_simplex_range()){
Expand All @@ -180,6 +178,8 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface<Simplex_tree_
// Base::assign_filtration(SimplexHandle, current_birth);
}
}


using simplices_list = std::vector<std::vector<int>>;
simplices_list get_simplices_of_dimension(int dimension){
simplices_list simplex_list;
Expand Down Expand Up @@ -215,9 +215,6 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface<Simplex_tree_
void resize_all_filtrations(int num){ //TODO : that is for 1 critical filtrations
if (num < 0) return;
for(const auto &SimplexHandle : Base::complex_simplex_range()){
// std::vector<options_multi::value_type> new_filtration_value = Base::filtration(SimplexHandle);
// new_filtration_value.resize(num);
// Base::assign_filtration(SimplexHandle, new_filtration_value);
Base::filtration_mutable(SimplexHandle).resize(num);;
}
}
Expand All @@ -229,7 +226,7 @@ class Simplex_tree_interface_multi : public Simplex_tree_interface<Simplex_tree_
using interface_std = Simplex_tree<Simplex_tree_options_full_featured>; // Interface not necessary (smaller so should do less segfaults)
using interface_multi = Simplex_tree_interface_multi<Simplex_tree_options_multidimensional_filtration>;


// 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<interface_multi::Options::value_type> basepoint, int dimension){ // for python
auto &st = get_simplextree_from_pointer<interface_std>(newsplxptr);
auto &st_multi = get_simplextree_from_pointer<interface_multi>(splxptr);
Expand Down
29 changes: 10 additions & 19 deletions src/python/include/Simplex_tree_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ using simplextree_multi = Simplex_tree<options_multi>;
using multi_filtration_type = std::vector<options_multi::value_type>;
using multi_filtration_grid = std::vector<multi_filtration_type>;


// 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<class simplextreeinterface>
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<class simplextree_std, class simplextree_multi>
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<std::min(static_cast<unsigned int>(default_values.size()), static_cast<unsigned int>(num_parameters-1));i++)
f[i+1] = default_values[i];
Expand All @@ -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);

Expand All @@ -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<class simplextree_std, class simplextree_multi>
void flatten(simplextree_std &st, simplextree_multi &st_multi, const int dimension = 0){
for (const auto &simplex_handle : st_multi.complex_simplex_range()){
Expand All @@ -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<class simplextree_std, class simplextree_multi>
void linear_projection(simplextree_std &st, simplextree_multi &st_multi, const std::vector<typename simplextree_multi::Options::value_type>& linear_form){
auto sh = st.complex_simplex_range().begin();
Expand All @@ -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<class simplextree_std, class simplextree_multi>
void flatten_diag(simplextree_std &st, simplextree_multi &st_multi, const std::vector<typename simplextree_multi::Options::value_type> basepoint, int dimension){
Expand Down Expand Up @@ -146,18 +143,16 @@ inline void find_coordinates(vector_like& x, const multi_filtration_grid &grid){
if constexpr (std::numeric_limits<typename vector_like::value_type>::has_infinity)
if (to_project == std::numeric_limits<typename vector_like::value_type>::infinity()){
x[parameter] = std::numeric_limits<typename vector_like::value_type>::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 << "\n";
while (to_project > filtration[i] && i<filtration.size()) {
i++;
// std::cout << to_project<< " " <<filtration[i]<<" " <<i << "\n";
}
if (i==0)
x[parameter] = 0;
Expand All @@ -167,13 +162,7 @@ continue;
d2 = std::abs(filtration[i] - to_project);
x[parameter] = d1<d2 ? i-1 : i;
}
// std::vector<options_multi::value_type> 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;
}


Expand All @@ -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<multi_filtration_grid> get_filtration_values(const uintptr_t splxptr, const std::vector<int> &degrees){
Simplex_tree<options_multi> &st_multi = *(Gudhi::Simplex_tree<options_multi>*)(splxptr);
int num_parameters = st_multi.get_number_of_parameters();
Expand Down
14 changes: 1 addition & 13 deletions src/python/include/multi_filtrations/box.h
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -74,7 +74,6 @@ inline Box<T>::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 !");
}
Expand All @@ -89,11 +88,6 @@ inline Box<T>::Box(const std::pair<point_type, point_type> &box)
template<typename T>
inline void Box<T>::inflate(T delta)
{
// #pragma omp simd
// for (int i = 0; i < bottomCorner_.size(); i++){
// bottomCorner_[i] -= delta;
// upperCorner_[i] += delta;
// }
bottomCorner_ -= delta;
upperCorner_ += delta;
}
Expand Down Expand Up @@ -151,12 +145,6 @@ inline bool Box<T>::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_;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ template<typename T=float>
class Finitely_critical_multi_filtration : public std::vector<T> {
// Class to prevent doing illegal stuff with the standard library, e.g., compare two vectors
public:
// explicit Finitely_critical_multi_filtration(std::vector<T>& v) : ptr_(&v) {
// }; // Conversion
// using std::vector<T>::vector;
Finitely_critical_multi_filtration() : std::vector<T>() {};
Finitely_critical_multi_filtration(int n) : std::vector<T>(n, -std::numeric_limits<T>::infinity()) {}; // minus infinity by default
Finitely_critical_multi_filtration(int n, T value) : std::vector<T>(n,value) {};
Expand All @@ -32,24 +29,9 @@ class Finitely_critical_multi_filtration : public std::vector<T> {



//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<T>::infinity()) //TODO FIXME, we have to check every coord of b instead of 1
// return a[0] != std::numeric_limits<T>::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;
Expand All @@ -60,16 +42,6 @@ class Finitely_critical_multi_filtration : public std::vector<T> {
}
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<T>::infinity()) //TODO FIXME, we have to check every coord of b instead of 1
// return a[0] != std::numeric_limits<T>::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;
Expand All @@ -82,11 +54,11 @@ class Finitely_critical_multi_filtration : public std::vector<T> {
//GREATER THAN OPERATORS
friend bool operator>(const Finitely_critical_multi_filtration& a, const Finitely_critical_multi_filtration& b)
{
return b<a; // C'est honteux.
return b<a;
}
friend bool operator>=(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){
Expand Down Expand Up @@ -133,8 +105,10 @@ class Finitely_critical_multi_filtration : public std::vector<T> {
return std::vector<Finitely_critical_multi_filtration<T>>(to_convert.begin(), to_convert.end());;
}
void push_to(const Finitely_critical_multi_filtration<T>& 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];
}
Expand All @@ -145,6 +119,8 @@ class Finitely_critical_multi_filtration : public std::vector<T> {
);
}


// scalar product of a filtration value with x.
T linear_projection(const std::vector<T>& x){
T projection=0;
unsigned int size = std::min(x.size(), this->size());
Expand Down

0 comments on commit 82ce7d0

Please sign in to comment.