Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zigzag persistence part2 #953

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4f06e5c
rips edge iterator
hschreiber Jul 28, 2023
9eb1e01
Merge remote-tracking branch 'origin/simplex_tree_zigzag_option' into…
hschreiber Aug 1, 2023
0dcf241
Merge remote-tracking branch 'origin/stable_simplex_handles' into osc…
hschreiber Aug 4, 2023
5e530f7
oscillating rips range
hschreiber Aug 4, 2023
40bb36a
Merge remote-tracking branch 'origin/persistence_matrix' into oscilla…
hschreiber Aug 7, 2023
9b0a7cc
oscillating rips persistence, example and benchmark
hschreiber Aug 8, 2023
63aad6a
doc
hschreiber Aug 9, 2023
951cbb8
doc
hschreiber Aug 21, 2023
d63e697
merge updated upstream
hschreiber Aug 21, 2023
b640b89
Merge branch 'GUDHI:master' into oscillating_rips
hschreiber Aug 22, 2023
52376df
Merge branch 'GUDHI:master' into oscillating_rips
hschreiber Aug 25, 2023
8f2dc9c
doc
hschreiber Aug 31, 2023
67637b9
cleanup
hschreiber Aug 31, 2023
ba7ee4d
merge upstream
hschreiber Sep 1, 2023
f0978fc
merge upstream
hschreiber Sep 19, 2024
d8a8273
name fix
hschreiber Sep 24, 2024
da86ef5
add std:: to size_t
hschreiber Sep 25, 2024
0655678
merge upstream part1
hschreiber Jan 8, 2025
3618262
merge upstream part2
hschreiber Jan 8, 2025
656435e
oscillating rips unitary tests part 1
hschreiber Jan 9, 2025
8e1512a
oscillating rips unitary tests part 2
hschreiber Jan 10, 2025
f76a682
doc
hschreiber Jan 14, 2025
9a526f6
biblio misplaced
hschreiber Jan 14, 2025
aac903d
doc + removal of unnecessary flag in edge modifier
hschreiber Jan 16, 2025
b69b288
oscillating rips: more intuitive organization + light iterators
hschreiber Jan 21, 2025
2e973f1
doc
hschreiber Jan 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions biblio/bibliography.bib
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,18 @@ @inproceedings{zigzag
doi = {10.1137/1.9781611973730.14}
}

@inproceedings{osc_zz,
author = {Oudot, Steve and Sheehy, Donald},
year = {2013},
month = {06},
pages = {387-396},
title = {{Zigzag Zoology: Rips Zigzags for Homology Inference}},
volume = {15},
booktitle = {Foundations of Computational Mathematics},
url = {https://doi.org/10.1145/2462356.2462371},
doi = {10.1145/2462356.2462371}
}

%-----------------------------
% UNUSED
%-----------------------------
Expand Down
31 changes: 31 additions & 0 deletions src/Zigzag_persistence/concept/DistanceFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* 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): Hannah Schreiber
*
* Copyright (C) 2023 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/

#ifndef CONCEPT_ZZ_DISTANCE_FUNCTION_H_
#define CONCEPT_ZZ_DISTANCE_FUNCTION_H_

/** @file DistanceFunction.h
* @brief Contains @ref Gudhi::zigzag_persistence::DistanceFunction concept.
*/

#include "PointRange.h"

namespace Gudhi {
namespace zigzag_persistence {

/**
* @brief Distance function taking two points as input and returning the distance between them.
*/
using DistanceFunction = double (*)(const Point&, const Point&);

} // namespace zigzag_persistence
} // namespace Gudhi

#endif // CONCEPT_ZZ_DISTANCE_FUNCTION_H_
49 changes: 49 additions & 0 deletions src/Zigzag_persistence/concept/EdgeModifier.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* 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): Hannah Schreiber
*
* Copyright (C) 2023 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/

#ifndef CONCEPT_ZZ_EDGE_MODIFIER_H_
#define CONCEPT_ZZ_EDGE_MODIFIER_H_

/** @file EdgeModifier.h
* @brief Contains @ref Gudhi::zigzag_persistence::EdgeModifier concept.
*/

namespace Gudhi {
namespace zigzag_persistence {

/**
* @brief Methods whose purposes are to modify the filtration value of a given edge following a rule.
* The concept is for example realized by @ref Identity_edge_modifier or @ref Square_root_edge_modifier "".
*/
template <typename Filtration_value>
class EdgeModifier {
public:
/**
* @brief Applies the modifier to the given value and returns it.
*
* @param f Value to modify.
* @return The modified value of @p f.
*/
static Filtration_value apply_modifier(Filtration_value f);

/**
* @brief Applies the inverse modifier to the given value and returns it.
* So, apply_inverse_modifier(apply_modifier(f)) == f (modulo some possible precision errors.).
*
* @param f Value to modify.
* @return The modified value of @p f.
*/
static Filtration_value apply_inverse_modifier(Filtration_value f);
};

} // namespace zigzag_persistence
} // namespace Gudhi

#endif // CONCEPT_ZZ_EDGE_MODIFIER_H_
61 changes: 61 additions & 0 deletions src/Zigzag_persistence/concept/PointRange.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* 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): Hannah Schreiber
*
* Copyright (C) 2023 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/

#ifndef CONCEPT_ZZ_POINT_RANGE_H_
#define CONCEPT_ZZ_POINT_RANGE_H_

/** @file PointRange.h
* @brief Contains @ref Gudhi::zigzag_persistence::Point and @ref Gudhi::zigzag_persistence::PointRange concept.
*/

namespace Gudhi {
namespace zigzag_persistence {

/**
* @brief Data structure representing a point of fixed dimension. The structure of the point does not matter
* it-self as long as it corresponds to the input type of the @ref DistanceFunction concept.
*/
class Point{};

/**
* @brief Range of @ref Point. If used with @ref Oscillating_rips_edge_order_policy::FARTHEST_POINT_ORDERING
* order policy, it has to be a random access range.
*/
class PointRange {
public:
/**
* @brief Returns begin iterator.
*/
auto begin();

/**
* @brief Returns end iterator.
*/
auto end();

/**
* @brief Returns size of the range.
*/
std::size_t size();

/**
* @brief Necessary only if used with @ref Oscillating_rips_edge_order_policy::FARTHEST_POINT_ORDERING.
* Returns the element at the given index.
*
* @param index Index of the element to return.
* @return Point at index @p index.
*/
Point operator[](std::size_t index);
};

} // namespace zigzag_persistence
} // namespace Gudhi

#endif // CONCEPT_ZZ_POINT_RANGE_H_
112 changes: 112 additions & 0 deletions src/Zigzag_persistence/concept/StableFilteredComplex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* 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): Hannah Schreiber
*
* Copyright (C) 2023 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/

#ifndef CONCEPT_ZZ_STABLE_COMPLEX_TYPE_H_
#define CONCEPT_ZZ_STABLE_COMPLEX_TYPE_H_

/** @file StableFilteredComplex.h
* @brief Contains @ref Gudhi::zigzag_persistence::StableFilteredComplex concept.
*/

namespace Gudhi {
namespace zigzag_persistence {

/**
* @brief Data structure storing the simplices and their filtration values in the current complex.
* The concept is realized for example by
* @ref Gudhi::Simplex_tree < Gudhi::zigzag_persistence::Simplex_tree_options_oscillating_rips >.
*/
class StableFilteredComplex {
public:
/**
* @brief Integer type that needs to be long enough to store the numbers of arrows in the zigzag filtration.
*/
typename Simplex_key;

/**
* @brief Handle to specify a simplex. The simplex handles have to be stable, that is, they do not invalidate when
* a simplex is added or removed from the complex (except for the removed simplices them-selves of course).
*/
typename Simplex_handle;

/**
* @brief Type for filtration values. Usually 'double'.
*/
typename Filtration_value;

/**
* @brief Removes the given simplex. Assumes that the simplex is maximal and can be safely removed.
*
* @param sh Simplex handle representing the simplex to remove.
*/
void remove_maximal_simplex(Simplex_handle sh);

/**
* @brief Adds a vertex or an edge in a flag complex, as well as all
* simplices of its star, defined to maintain the property
* of the complex to be a flag complex, truncated at dimension dim_max.
*
* @param u ID of one end of the edge.
* @param v ID of the other end of the edge. If @p u == @p v, then the input is considered as a vertex.
* @param fil Filtration value of the edge.
* @param dim_max Maximal dimension of the expansion. If set to -1, the expansion goes as far as possible.
* @param added_simplices Container for all new simplices induced by the insertion of the edge.
* If not empty at start, the content of the container should @b not be erased by the method.
*/
void insert_edge_as_flag(int u,
int v,
Filtration_value fil,
int dim_max,
std::vector<Simplex_handle>& added_simplices);

/**
* @brief Returns the key associated to the given simplex.
*/
Simplex_key key(Simplex_handle sh);

/**
* @brief Assignes the given value to the given simplex as a key.
*/
void assign_key(Simplex_handle sh, Simplex_key key);

/**
* @brief Finds the given simplex in the complex and returns the associated simplex handle.
*
* @tparam VertexRange Range over the vertices of a simplex.
* @param simplex Simplex to find represented by its vertices.
* @return The simplex handle associated to @p simplex if the simplex is found.
*/
template <class VertexRange>
Simplex_handle find(const VertexRange& simplex);

/**
* @brief Returns the filtration value of the given simplex.
*/
Filtration_value filtration(Simplex_handle sh);

/**
* @brief Returns a range (with begin() and end() methods) over the star of the given simplex, including the simplex.
*
* @param simplex Simplex to compute the star from.
* @return A iterable range over the star of @p simplex.
*/
auto star_simplex_range(const Simplex_handle simplex);

/**
* @brief Returns a range over the vertices of a simplex. The vertices have to be ordered monotonously by their
* labels.
*/
auto simplex_vertex_range(Simplex_handle sh) const;
};

} // namespace zigzag_persistence
} // namespace Gudhi

#endif // CONCEPT_ZZ_STABLE_COMPLEX_TYPE_H_
28 changes: 21 additions & 7 deletions src/Zigzag_persistence/concept/ZigzagOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,37 @@ namespace zigzag_persistence {
/**
* @ingroup zigzag_persistence
*
* @brief List of options used for the filtered zigzag persistence computation.
* @brief List of options used for the filtered zigzag persistence computation. An implementation of this concept is
* @ref Default_filtered_zigzag_options "", which inherits from @ref Default_zigzag_options for the common types.
* Another implementation is
* @ref Gudhi::zigzag_persistence::Default_oscillating_rips_zigzag_options "Default_oscillating_rips_zigzag_options".
*/
struct FilteredZigzagOptions {
/**
* @brief Numerical type for the cell IDs used internally and other indexations. It must be signed.
* @brief Type for filtration values.
*/
using Internal_key = unspecified;
using Filtration_value = unspecified;

/**
* @brief Type for the cell IDs used at insertion and in the boundaries given as argument.
* Has to be usable as key in a hashtable, so "hashable" and comparable.
*/
using Cell_key = unspecified;

/**
* @brief Type for filtration values.
* @brief Hash method for @ref Cell_key type. Could simply be 'std::hash<Cell_key>' if the specialization exists;
*/
using Filtration_value = unspecified;
using Cell_key_hash = unspecified;

/**
* @brief Equality comparator for @ref Cell_key type. Could simply be 'std::equal_to<Cell_key>' if the specialization
* exists;
*/
using Cell_key_equal = unspecified;

/**
* @brief Numerical type for the cell IDs used internally and other indexations. It must be signed.
*/
using Internal_key = unspecified;

/**
* @brief Type for the dimension values.
Expand All @@ -55,7 +68,8 @@ struct FilteredZigzagOptions {
/**
* @ingroup zigzag_persistence
*
* @brief List of options used for the zigzag persistence computation.
* @brief List of options used for the zigzag persistence computation. An implementation of this concept is
* @ref Default_zigzag_options "".
*/
struct ZigzagOptions {
/**
Expand Down
39 changes: 39 additions & 0 deletions src/Zigzag_persistence/doc/Intro_zigzag_persistence.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,43 @@ namespace zigzag_persistence {
* which can be processed without overreaching memory space. For this purpose, it is possible to feed the module with
* information about the filtration "on the fly" to avoid loading the whole filtration at once. Information about the
* current barcode can be retrieved between any steps via callback methods.
*
* \subsection zigzagrips Oscillating Rips
*
* A typical example of zigzag filtrations are oscillating Rips filtrations. Similar to standard
* @ref ripsdefinition "Rips filtrations", they completely depend on their edges. But here we look at neighborhoods
* "oscillating" in size around the points, so edges are added but also removed. We refer for example to \cite osc_zz
* for more theoretical details.
*
* This module implements the construction of such an oscillating Rips filtration as follows:
* \image html "osc_rips.svg" width=70%
*
* If \f$ P \f$ is the set of points generating the rips filtration, \f$ P_i \f$ corresponds to the subset containing
* the \f$ i \f$ first points. So, at each forward inclusion, one vertex is added.
*
* The superscript of \f$ \mathcal{R} \f$ corresponds to the filtration values which will be associated to the cycles.
* The sequence of \f$ \varepsilon \f$ should be decreasing and end with \f$ 0 \f$. The sequence can either be specified
* by the user or automatically generated by choosing the distance of the added point from the other already added
* points from the set. In the second case, the user has to specify how the order of the points should be decided.
*
* The subscript of \f$ \mathcal{R} \f$ corresponds like usual to the radius of the Rips complex. It is generated from
* the current epsilon / filtration value by multiplying it alternatively by two coefficients: \f$ \nu \leqslant \mu \f$.
* Both multipliers have to be specified by the user.
*
* The construction is based on two types of classes:
* - @ref Oscillating_rips_edge_iterator_range and @ref Oscillating_rips_edge_vector_range_constructor computes the
* range of inserted and removed vertices and edges in the filtration based on the elements descipted above.
* - @ref Oscillating_rips_simplex_iterator_range and @ref Oscillating_rips_simplex_vector_range_constructor infers
* from @ref Oscillating_rips_edge_iterator_range or @ref Oscillating_rips_edge_vector_range_constructor all simplices
* from higher dimensions (i.e. > 1) of the filtration if necessary.
* For this purpose, a data structure able to represent a flag complex is additionally needed
* (such as @ref Gudhi::Simplex_tree). Note that the edge range is passed by template, so the user
* can potentially pass any other type of edge range as long as the dereferenced format corresponds and the sequence
* makes sense as a zigzag filtration.
*
* If only the barcode of the filtration is of interest and not the filtration it-self, the helper method
* @ref compute_oscillating_rips_persistence can be used. It will directly feed to the filtration constructed by the
* two classes above into @ref Zigzag_persistence "".
*
* \section zigzagexamples Examples
*
Expand Down Expand Up @@ -88,6 +125,8 @@ namespace zigzag_persistence {
* to use the @ref Filtered_zigzag_persistence_with_storage class within an input loop.
* \li \gudhi_example_link{Zigzag_persistence,example_zzfiltration_from_file.cpp} - An example of a "stream-like" usage
* with @ref Filtered_zigzag_persistence by reading off the filtration from a file.
* \li \gudhi_example_link{Zigzag_persistence,example_oscillating_rips_persistence.cpp} - An example of a how to
* compute the persistence of an oscillating rips filtration.
*
* @}
*/
Expand Down
Loading
Loading