Skip to content

Commit

Permalink
Merge pull request #978 from VincentRouvreau/rework_simplex_tree_options
Browse files Browse the repository at this point in the history
Rework simplex tree options
  • Loading branch information
VincentRouvreau authored Nov 20, 2023
2 parents edce2af + a6c5e0a commit ec56efe
Show file tree
Hide file tree
Showing 36 changed files with 242 additions and 181 deletions.
10 changes: 5 additions & 5 deletions src/Persistent_cohomology/example/plain_homology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
#include <cstdint> // for std::uint8_t

/* We could perfectly well use the default Simplex_tree<> (which uses
* Simplex_tree_options_full_featured), the following simply demonstrates
* Simplex_tree_options_default), the following simply demonstrates
* how to save on storage by not storing a filtration value. */

struct MyOptions : Gudhi::Simplex_tree_options_full_featured {
// Implicitly use 0 as filtration value for all simplices
static const bool store_filtration = false;
// The persistence algorithm needs this
struct MyOptions : Gudhi::Simplex_tree_options_minimal {
// Implicitly use 0 as filtration value for all simplices - inherited from Simplex_tree_options_minimal
// static const bool store_filtration = false;
// However the persistence algorithm needs this
static const bool store_key = true;
// I have few vertices
typedef short Vertex_handle;
Expand Down
2 changes: 1 addition & 1 deletion src/Persistent_cohomology/test/betti_numbers_unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <gudhi/Simplex_tree.h>
#include <gudhi/Persistent_cohomology.h>

struct MiniSTOptions : Gudhi::Simplex_tree_options_full_featured {
struct MiniSTOptions : Gudhi::Simplex_tree_options_minimal {
// Implicitly use 0 as filtration value for all simplices
static const bool store_filtration = false;
// The persistence algorithm needs this
Expand Down
17 changes: 13 additions & 4 deletions src/Simplex_tree/benchmark/simplex_tree_cofaces_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,23 @@ void benchmark_stars_computation(int nb_vertices) {
std::clog << benchmark_cofaces << std::endl;
}

struct Simplex_tree_options_stable_simplex_handles {
struct Stree_basic_cofaces_options {
typedef Gudhi::linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef double Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = false;
static const bool link_nodes_by_label = false;
static const bool stable_simplex_handles = false;
};

struct Stree_fast_cofaces_options : Stree_basic_cofaces_options {
static const bool link_nodes_by_label = true;
};

struct Stree_fast_cofaces_stable_simplex_handles_options : Stree_basic_cofaces_options {
static const bool link_nodes_by_label = true;
static const bool stable_simplex_handles = true;
};
Expand All @@ -105,13 +114,13 @@ int main(int argc, char *argv[]) {
nb_vertices = atoi(argv[1]);

std::clog << "** Without cofaces computation optimization" << std::endl;
benchmark_stars_computation<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>(nb_vertices);
benchmark_stars_computation<Gudhi::Simplex_tree<Stree_basic_cofaces_options>>(nb_vertices);

std::clog << "** With cofaces computation optimization" << std::endl;
benchmark_stars_computation<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_fast_cofaces>>(nb_vertices);
benchmark_stars_computation<Gudhi::Simplex_tree<Stree_fast_cofaces_options>>(nb_vertices);

std::clog << "** With cofaces computation optimization and stable simplex handles" << std::endl;
benchmark_stars_computation<Gudhi::Simplex_tree<Simplex_tree_options_stable_simplex_handles> >(nb_vertices);
benchmark_stars_computation<Gudhi::Simplex_tree<Stree_fast_cofaces_stable_simplex_handles_options> >(nb_vertices);

return EXIT_SUCCESS;
}
28 changes: 17 additions & 11 deletions src/Simplex_tree/concept/SimplexTreeOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,34 @@
* - YYYY/MM Author: Description of the modification
*/

/** \brief Concept of the template parameter for the class `Gudhi::Simplex_tree<SimplexTreeOptions>`.
/** @brief Concept of the template parameter for the class `Gudhi::Simplex_tree<SimplexTreeOptions>`.
*
* One model for this is `Gudhi::Simplex_tree_options_full_featured`. If you want to provide your own, it is recommended that you derive from it and override some parts instead of writing a class from scratch.
* A model for this is `Gudhi::Simplex_tree_options_full_featured` or `Gudhi::Simplex_tree_options_minimal`.
* If you want to provide your own, it is recommended that you derive from it and override some parts instead of
* writing a class from scratch.
*/
struct SimplexTreeOptions {
/// Forced for now.
/** @brief Forced for now. */
typedef IndexingTag Indexing_tag;
/// Must be a signed integer type. It admits a total order <.
/** @brief Must be a signed integer type. It admits a total order <. */
typedef VertexHandle Vertex_handle;
/// Must be comparable with operator<.
/** @brief Must be comparable with operator<. */
typedef FiltrationValue Filtration_value;
/// Must be an integer type.
/** @brief Must be an integer type. */
typedef SimplexKey Simplex_key;
/// If true, each simplex has extra storage for one `Simplex_key`. Necessary for `Persistent_cohomology`.
/** @brief If true, each simplex has extra storage for one `Simplex_key`. Necessary for `Persistent_cohomology`. */
static const bool store_key;
/// If true, each simplex has extra storage for one `Filtration_value`, and this value is propagated by operations like `Gudhi::Simplex_tree::expansion`. Without it, `Persistent_cohomology` degenerates to computing usual (non-persistent) cohomology.
/** @brief If true, each simplex has extra storage for one `Filtration_value`, and this value is propagated by
* operations like `Gudhi::Simplex_tree::expansion`. Without it, `Persistent_cohomology` degenerates to computing
* usual (non-persistent) cohomology.
*/
static const bool store_filtration;
/// If true, the list of vertices present in the complex must always be 0, ..., num_vertices-1, without any hole.

/** @brief If true, the list of vertices present in the complex must always be 0, ..., num_vertices-1, without any hole. */
static constexpr bool contiguous_vertices;
/// If true, the lists of `Node` with same label are stored to enhance cofaces and stars access.
/** @brief If true, the lists of `Node` with same label are stored to enhance cofaces and stars access. */
static const bool link_nodes_by_label;
/// If true, Simplex_handle will not be invalidated after insertions or removals.
/** @brief If true, Simplex_handle will not be invalidated after insertions or removals. */
static const bool stable_simplex_handles;
};

9 changes: 4 additions & 5 deletions src/Simplex_tree/example/mini_simplex_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
#include <iostream>
#include <initializer_list>

struct MyOptions : Gudhi::Simplex_tree_options_full_featured {
// Not doing persistence, so we don't need those
static const bool store_key = false;
static const bool store_filtration = false;
// I have few vertices
// With Gudhi::Simplex_tree_options_minimal filtration values are not stored and persistence cannot be computed.
// I can still improve the memory footprint
struct MyOptions : Gudhi::Simplex_tree_options_minimal {
// As I have few vertices
typedef short Vertex_handle;
};

Expand Down
57 changes: 2 additions & 55 deletions src/Simplex_tree/include/gudhi/Simplex_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
#ifndef SIMPLEX_TREE_H_
#define SIMPLEX_TREE_H_

#include <gudhi/Simplex_tree/simplex_tree_options.h>
#include <gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h>
#include <gudhi/Simplex_tree/Simplex_tree_siblings.h>
#include <gudhi/Simplex_tree/Simplex_tree_iterators.h>
#include <gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h>
#include <gudhi/Simplex_tree/indexing_tag.h>
#include <gudhi/Simplex_tree/serialization_utils.h> // for Gudhi::simplex_tree::de/serialize_trivial
#include <gudhi/Simplex_tree/hooks_simplex_base.h>

Expand Down Expand Up @@ -53,7 +53,6 @@
#include <limits> // Inf
#include <initializer_list>
#include <algorithm> // for std::max
#include <cstdint> // for std::uint32_t
#include <iterator> // for std::distance
#include <type_traits> // for std::conditional
#include <unordered_map>
Expand All @@ -79,8 +78,6 @@ namespace Gudhi {
*/
enum class Extended_simplex_type {UP, DOWN, EXTRA};

struct Simplex_tree_options_full_featured;

/**
* \class Simplex_tree Simplex_tree.h gudhi/Simplex_tree.h
* \brief Simplex Tree data structure for representing simplicial complexes.
Expand All @@ -94,7 +91,7 @@ struct Simplex_tree_options_full_featured;
*
*/

template<typename SimplexTreeOptions = Simplex_tree_options_full_featured>
template<typename SimplexTreeOptions = Simplex_tree_options_default>
class Simplex_tree {
public:
typedef SimplexTreeOptions Options;
Expand Down Expand Up @@ -2597,56 +2594,6 @@ std::istream& operator>>(std::istream & is, Simplex_tree<T...> & st) {
return is;
}

/** Model of SimplexTreeOptions.
*
* Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint32_t>::max()</CODE>
* (about 4 billions of simplices). */
struct Simplex_tree_options_full_featured {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef double Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = false;
static const bool link_nodes_by_label = false;
static const bool stable_simplex_handles = false;
};

/** Model of SimplexTreeOptions, faster than `Simplex_tree_options_full_featured` but note the unsafe
* `contiguous_vertices` option.
*
* Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint32_t>::max()</CODE>
* (about 4 billions of simplices). */
struct Simplex_tree_options_fast_persistence {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef float Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = true;
static const bool link_nodes_by_label = false;
static const bool stable_simplex_handles = false;
};

/** Model of SimplexTreeOptions, faster cofaces than `Simplex_tree_options_full_featured`, note the
* `link_nodes_by_label` option.
*
* Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint32_t>::max()</CODE>
* (about 4 billions of simplices). */
struct Simplex_tree_options_fast_cofaces {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef double Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = false;
static const bool link_nodes_by_label = true;
static const bool stable_simplex_handles = false;
};

/** @}*/ // end addtogroup simplex_tree

} // namespace Gudhi
Expand Down
96 changes: 96 additions & 0 deletions src/Simplex_tree/include/gudhi/Simplex_tree/simplex_tree_options.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* 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): Vincent Rouvreau
*
* Copyright (C) 2023 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/

#ifndef SIMPLEX_TREE_SIMPLEX_TREE_OPTIONS_H_
#define SIMPLEX_TREE_SIMPLEX_TREE_OPTIONS_H_

#include <gudhi/Simplex_tree/indexing_tag.h>

#include <cstdint>

namespace Gudhi {

/** \addtogroup simplex_tree
* Pre-defined options for the Simplex_tree.
* @{
*/

/** Model of SimplexTreeOptions.
*
* Default options version of the Simplex_tree.
*
* Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint32_t>::max()</CODE>
* (about 4 billions of simplices). */
struct Simplex_tree_options_default {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef double Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = false;
static const bool link_nodes_by_label = false;
static const bool stable_simplex_handles = false;
};

/** Model of SimplexTreeOptions.
*
* Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint32_t>::max()</CODE>
* (about 4 billions of simplices). */
struct Simplex_tree_options_full_featured {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef double Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = false;
static const bool link_nodes_by_label = true;
static const bool stable_simplex_handles = true;
};

/** Model of SimplexTreeOptions.
*
* Minimal version of the Simplex_tree. No filtration values are stored and it is impossible to compute persistence
* with these options. */
struct Simplex_tree_options_minimal {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef double Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = false;
static const bool store_filtration = false;
static const bool contiguous_vertices = false;
static const bool link_nodes_by_label = false;
static const bool stable_simplex_handles = false;
};

/** @private @brief Model of SimplexTreeOptions, faster than `Simplex_tree_options_default` but note the unsafe
* `contiguous_vertices` option.
*
* Maximum number of simplices to compute persistence is <CODE>std::numeric_limits<std::uint32_t>::max()</CODE>
* (about 4 billions of simplices). */
struct Simplex_tree_options_fast_persistence {
typedef linear_indexing_tag Indexing_tag;
typedef int Vertex_handle;
typedef float Filtration_value;
typedef std::uint32_t Simplex_key;
static const bool store_key = true;
static const bool store_filtration = true;
static const bool contiguous_vertices = true;
static const bool link_nodes_by_label = false;
static const bool stable_simplex_handles = false;
};

/** @}*/ // end addtogroup simplex_tree

} // namespace Gudhi

#endif // SIMPLEX_TREE_SIMPLEX_TREE_OPTIONS_H_
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct Simplex_tree_options_stable_simplex_handles {

typedef boost::mpl::list<Simplex_tree<>,
Simplex_tree<Simplex_tree_options_fast_persistence>,
Simplex_tree<Simplex_tree_options_fast_cofaces>,
Simplex_tree<Simplex_tree_options_full_featured>,
Simplex_tree<Simplex_tree_options_stable_simplex_handles> > list_of_tested_variants;

template<typename Simplex_tree>
Expand Down Expand Up @@ -202,7 +202,7 @@ std::vector<std::vector<typename Simplex_tree::Vertex_handle>> get_star(Simplex_

BOOST_AUTO_TEST_CASE(simplex_fast_cofaces_rule_of_five) {
// Only for fast cofaces version to check the data structure for this feature is up to date
using STree = Simplex_tree<Simplex_tree_options_fast_cofaces>;
using STree = Simplex_tree<Simplex_tree_options_full_featured>;
STree st;

st.insert_simplex_and_subfaces({2, 1, 0}, 3.0);
Expand Down
Loading

0 comments on commit ec56efe

Please sign in to comment.