Fix computereeb reset pos performance - #108
Merged
Merged
Conversation
ishikaghosh2201
requested review from
lizliz
and
a lite review from Copilot
September 17, 2026 16:09
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Deferred node removal leaves a dangling self.pos entry; two minor test/comment fixes are also noted.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
tests/test_reeb_class.py:318
- This call does not exercise the tied-filtration collapse branch:
ahas value 0.0 whilechas value 1.0, soadd_edge('a', 'c')takes the ordinary edge path. Consequently this regression test would still pass if the collapse branch reverted to calling its internal methods with the defaultreset_pos=True; build an edge into/out ofcand calladd_edge('b', 'c', reset_pos=False)so the equal-valued collapse and its recursive calls are actually covered.
R.add_edge('a', 'c', reset_pos=False)
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
Corrected the spelling of 'unconditionally' in a comment. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
7 tasks
…utereeb-reset-pos-performance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
computeReebbuilds a Reeb graph one node/edge at a time but never overrodeadd_node/add_edge'sreset_posdefault ofTrue, so every single insertion triggered a fullset_pos_from_f()layout pass (ascipy.optimize.minimizeL-BFGS-B call) over the entire graph built so far — O(N) full layout recomputations instead of one. This PR:computeReebto passreset_pos=Falseon every internaladd_node/add_edgecall, and callsR.set_pos_from_f()exactly once after the graph is fully built.ReebGraphuncovered while verifying the above didn't change the graph's mathematical structure:add_edge's tied-filtration-value collapse branch now forwardsreset_posto its internal recursiveadd_edge/remove_nodecalls instead of silently defaulting toTrueand doing an unwanted recompute regardless of what the caller asked for.remove_nodeno longer bundles thepos_fdict cleanup insideif reset_pos:. Deleting a removed vertex's position entry is O(1) bookkeeping, not the expensive part, and gating it behindreset_posleft a danglingpos_fentry (pointing at a vertex no longer in the graph) wheneverremove_node(..., reset_pos=False)was used — e.g. fromremove_nodes_fromor theadd_edgecollapse path above.No public API changes;
reset_poskeyword and its default (True) are unchanged everywhere.Motivation and Context
Fixes #107. On a 287-node test graph (49-vertex triangle-mesh patch),
computeReebtook 124s; profiling showedreeb_x_layout/scipy.optimize.minimizeas the dominant cost, called 574 times for a graph with only 287 nodes. The fix brings this down to ~0.5s (~200x speedup) with an identical resulting graph.How has this been tested?
computeReebon the same input and compared the full node set, full (directed) edge set, andfdict for exact equality (not just cardinality or sorted values) — all identical.tests/test_lowerstar_class.py:test_computeReeb_pos_f_consistencyandtest_computeReeb_torus_pos_f_consistency: aftercomputeReeb,nodes/f.keys()/pos_f.keys()all match exactly, everypos_f[v][1] == f[v], and every edge points to the higher function value.test_computeReeb_performance: assertscomputeReebon a 176-node torus grid completes in well under 5s (fixed version: ~0.4s; unpatched version: ~9s on the same input), guarding against the O(N) behavior being reintroduced.tests/test_reeb_class.py:test_remove_node_deferred_pos_cleanup: confirmsremove_node(v, reset_pos=False)dropsv's stalepos_fentry immediately rather than leaving it dangling.test_add_edge_collapse_respects_reset_pos_false: builds a graph that exercisesadd_edge's tied-value collapse branch entirely withreset_pos=False, and confirmspos_fstays untouched (empty) until an explicitset_pos_from_f()call, i.e. the internal recursive calls correctly forwardreset_posinstead of defaulting toTrue.make tests): all 68 tests (63 pre-existing + 5 new) pass.add_edge/remove_nodein the source tree (not just tests) to confirm the change is behavior-preserving for the defaultreset_pos=Truecase (the vast majority of callers) and only changes behavior — strictly for the better — wherereset_pos=Falseis already used. Confirmed the two subclasses with custom overrides,MapperGraphandMergeTree, both just forwardreset_postosuper()and are already exercised by pre-existing tests that check the exact invariants this PR protects (test_mapper_class.py::test_add_edge's same-value collapse case, andtest_merge_tree.py'scheck_mthelper assertingnodes == pos_f.keys()).Types of changes
Checklist
pyproject.tomlfile if a new version needs to be pushed to pypi. Note that if the number isn't incremented, the package will not be pushed to pypi, which is useful if this PR is only for updating documentation.make formatto clean up the code withblack.make tests).