GUDHI upstream patch map
This document maps the current Morse persistence prototype to a small first GUDHI patch. It is not a patch itself; it is the checklist we can use before copying code into a GUDHI branch.
The local GUDHI source inspected for this map is:
/Users/laurentnajman/Documents/A trier au propre/PortableDisqueE/src/gudhi.3.12.0
First patch objective
The first upstream patch should add a header-only C++ module that computes
Morse persistence directly on Gudhi::Simplex_tree<>:
same-level Morse sequence construction;
fused Morse sequence and reference-map construction;
Morse persistence over
Z2as the first public coefficient scope;local simplex ids mapped back to
Simplex_tree::Simplex_handle;a tiny example and a small maintainer-style test matrix.
The first patch should not include Python bindings, benchmark machinery, experimental flooding strategies as stable API, or cubical complexes. The prototype already has prime-field experiments, but exposing coefficient selection should be a later discussion rather than part of this first API.
GUDHI module hook
GUDHI modules are enabled in the root CMakeLists.txt with add_gudhi_module.
The first upstream patch would add:
add_gudhi_module(Morse_persistence)
near the existing module list in:
CMakeLists.txt
The GUDHI module machinery then looks for optional subdirectories such as:
example/Morse_persistence/CMakeLists.txt
test/Morse_persistence/CMakeLists.txt
utilities/Morse_persistence/CMakeLists.txt
The local 3.12.0 source tree does not contain a top-level C++ test/
directory, but cmake/modules/GUDHI_modules.cmake supports a test/<module>
subdirectory when WITH_GUDHI_TEST and Boost::unit_test_framework are
available. The test path should therefore be prepared in the patch, even if the
local source archive we inspected does not include other C++ test directories.
Header files to move
The prototype currently exposes the GUDHI-shaped wrapper under:
morseframes/include/gudhi/Morse_persistence.h
morseframes/include/gudhi/Morse_persistence/complex_view.h
morseframes/include/gudhi/Morse_persistence/diagram.h
morseframes/include/gudhi/Morse_persistence/morse_sequence.h
morseframes/include/gudhi/Morse_persistence/persistence_reducer.h
morseframes/include/gudhi/Morse_persistence/reference_map.h
morseframes/include/gudhi/Morse_persistence/strategy.h
In a GUDHI branch, these should become:
include/gudhi/Morse_persistence.h
include/gudhi/Morse_persistence/complex_view.h
include/gudhi/Morse_persistence/diagram.h
include/gudhi/Morse_persistence/morse_sequence.h
include/gudhi/Morse_persistence/persistence_reducer.h
include/gudhi/Morse_persistence/reference_map.h
include/gudhi/Morse_persistence/strategy.h
The implementation currently depends on prototype kernel headers under:
morseframes/include/morseframes/annotation.hpp
morseframes/include/morseframes/complex_view.hpp
morseframes/include/morseframes/debug_checks.hpp
morseframes/include/morseframes/filtered_complex.hpp
morseframes/include/morseframes/instrumentation.hpp
morseframes/include/morseframes/inverse_annotation_store.hpp
morseframes/include/morseframes/morse_reference_api.hpp
morseframes/include/morseframes/morse_sequence.hpp
morseframes/include/morseframes/reference_persistence.hpp
morseframes/include/morseframes/simplex_tree_builder.hpp
morseframes/include/morseframes/simplex_tree_morse.hpp
morseframes/include/morseframes/working_sets.hpp
For the first GUDHI branch, these should not remain under the local
morseframes/ prototype include root. A clean layout would be:
include/gudhi/Morse_persistence/internal/annotation.h
include/gudhi/Morse_persistence/internal/complex_view_concept.h
include/gudhi/Morse_persistence/internal/debug_checks.h
include/gudhi/Morse_persistence/internal/filtered_complex.h
include/gudhi/Morse_persistence/internal/instrumentation.h
include/gudhi/Morse_persistence/internal/inverse_annotation_store.h
include/gudhi/Morse_persistence/internal/morse_reference_api.h
include/gudhi/Morse_persistence/internal/morse_sequence.h
include/gudhi/Morse_persistence/internal/reference_persistence.h
include/gudhi/Morse_persistence/internal/simplex_tree_builder.h
include/gudhi/Morse_persistence/internal/simplex_tree_morse.h
include/gudhi/Morse_persistence/internal/working_sets.h
The public wrappers should include only public GUDHI paths. Internal headers
should include other internal headers with gudhi/Morse_persistence/internal/...
paths. This is a mechanical namespace/include rewrite, not an algorithmic
change.
Namespace map
The current prototype kernel uses:
namespace morseframes { ... }
For GUDHI, the public API already uses:
namespace Gudhi {
namespace morse_persistence {
...
}
}
Recommended upstream structure:
namespace Gudhi {
namespace morse_persistence {
// Public API.
namespace internal {
// Implementation details.
}
}
}
This keeps the public namespace consistent with the wrapper already used in the prototype and makes it clear which types are stable API.
Public API to keep in the first patch
Keep the public API small:
#include <gudhi/Morse_persistence.h>
auto result = Gudhi::morse_persistence::compute_morse_persistence(
simplex_tree,
Gudhi::morse_persistence::Morse_sequence_strategy::F_MAX);
Stable public types and functions:
Morse_sequence_strategy
Simplex_id
Vertex_id
Level_id
Persistence_pair
Essential_interval
Persistence_diagram
Morse_step_type
Morse_step
Morse_sequence
Simplex_tree_view<SimplexTree>
Simplex_tree_morse_result<SimplexTree>
Simplex_tree_morse_frame<SimplexTree>
make_simplex_tree_view(simplex_tree)
compute_morse_sequence_and_reference_map(...)
compute_morse_persistence(...)
compute_morse_persistence_with_metrics(...)
off_diagonal_pairs(diagram)
Expose these strategies as the stable first set:
SAME_LEVEL_REDUCTION
F_MAX
F_MIN
PLATEAU_GREEDY
Keep these internal for experiments and omit them from the first public GUDHI-facing API:
EXPERIMENTAL_SATURATED
EXPERIMENTAL_FLOODING_MAX
EXPERIMENTAL_FLOODING_MIN
EXPERIMENTAL_FLOODING_MINMAX
EXPERIMENTAL_FLOODING_MAXMIN
The wrapper enum now follows this conservative choice. The internal kernel still keeps these strategies so the experimental report and benchmarks can continue to compare them while the strategy taxonomy is settled.
Example files
The prototype candidate example is:
morseframes/examples/example_morse_persistence_from_simplex_tree.cpp
In GUDHI it should move to:
example/Morse_persistence/example_morse_persistence_from_simplex_tree.cpp
Add a module example CMake file:
example/Morse_persistence/CMakeLists.txt
with:
add_executable_with_targets(
Morse_persistence_example_from_simplex_tree
example_morse_persistence_from_simplex_tree.cpp
TBB::tbb)
add_test(
NAME Morse_persistence_example_from_simplex_tree
COMMAND $<TARGET_FILE:Morse_persistence_example_from_simplex_tree>)
If maintainers prefer no TBB::tbb dependency for a header-only example, this
can be reduced to the same pattern used by simpler modules, but most GUDHI
examples use add_executable_with_targets(... TBB::tbb).
Test files
The prototype maintainer-style test is currently embedded in:
morseframes/tests/test_gudhi_simplex_tree_view.cpp
For a GUDHI branch, split or rename it as:
test/Morse_persistence/test_morse_persistence_simplex_tree.cpp
test/Morse_persistence/CMakeLists.txt
The current skeleton test uses a small runtime CHECK(...) helper rather than
plain assert(...), because GUDHI release builds define NDEBUG. The CMake
file can be kept as an executable plus add_test, or converted to the GUDHI
Boost-test helper if maintainers prefer that convention:
include(GUDHI_boost_test)
add_executable(
Morse_persistence_test_simplex_tree
test_morse_persistence_simplex_tree.cpp)
gudhi_add_boost_test(Morse_persistence_test_simplex_tree)
If the exact GUDHI test archive used for submission follows a different module-test convention, keep the same test body but adapt the CMake wrapper to that branch.
The first test matrix should include:
single vertex
single increasing edge
filled triangle on one plateau
triangle with tail
two components joined late
1-cycle killed by later triangle
direct Simplex_tree view versus compact import
all stable public strategies on the same complex
Each strategy test should check:
every simplex appears exactly once
regular pairs are same-level face/coface pairs
reference recurrence is valid
off-diagonal intervals match ordinary Z2 persistence
essential intervals match ordinary Z2 persistence
local ids map back to non-null Simplex_tree handles
For plateau examples, do not make zero-length interval multiplicity part of the public test contract. Valid reductions may represent diagonal intervals differently.
Documentation files
Add a Doxygen intro page:
doc/Morse_persistence/Intro_morse_persistence.h
The minimal first page should state:
the module computes persistence via same-level Morse sequences and reference maps;
it works directly on
Gudhi::Simplex_tree;plateaus are handled directly, without lower-star refinement;
the first public coefficient field is
Z2;the first target is ordinary persistence, not extended persistence;
simplex handles in the result are valid only while the input Simplex-tree is alive and structurally unchanged.
Add the example to:
doc/common/examples.h
under a new Morse_persistence section, unless GUDHI’s example-list generator
is run instead.
CMake summary
Root file:
CMakeLists.txt
Add:
add_gudhi_module(Morse_persistence)
Example file:
example/Morse_persistence/CMakeLists.txt
Test file:
test/Morse_persistence/CMakeLists.txt
No utility executable is needed in the first patch. Benchmarks should stay out of the first upstream patch.
What to leave out of the first patch
Leave these in the prototype for now:
Python bindings;
benchmark scripts and CSV/report generation;
flooding strategies as stable public API;
prime-field coefficient selection as public API;
composite
Z_ncoefficients;cubical-complex support;
terrain/image benchmark datasets;
adaptive strategy selection;
the research experiment report.
This keeps the first GUDHI discussion about one thing: whether the
Simplex_tree Morse persistence API and implementation shape are acceptable.
Pre-submission checklist
Before copying into a GUDHI branch:
Rewrite
morseframes::implementation namespace intoGudhi::morse_persistence::internal.Rewrite prototype include paths from
morseframes/...togudhi/Morse_persistence/internal/....Decide whether experimental strategies are omitted or left behind an explicit experimental name.
Keep the public coefficient scope at
Z2; leave prime-field and composite coefficient choices outside the first patch.Keep the runtime
CHECK(...)helper or convert it into Boost unit tests if the target GUDHI branch expects Boost tests.Build with:
cmake -S . -B build -DWITH_GUDHI_EXAMPLE=ON -DWITH_GUDHI_TEST=ON
cmake --build build --target Morse_persistence_example_from_simplex_tree
ctest --test-dir build -R Morse_persistence
Run the example manually and check that it prints one finite off-diagonal
H0interval and one essentialH0interval on the plateau-plus-tail complex.