refactor: extract shared TROP bootstrap resampling loop#554
Merged
Conversation
Deduplicate the byte-identical per-draw pairs-bootstrap loop in TROP._bootstrap_variance (trop_local.py) and TROP._bootstrap_variance_global (trop_global.py) into a shared module-level helper _run_trop_bootstrap_loop in trop_local.py (imported by trop_global.py, mirroring the existing _setup_trop_data pattern). The two loops differed only in the per-draw refit call, now passed as a fit_callable closure. Pure bit-identical refactor - no estimate / SE / RNG / warning change: - RNG setup and the Rust-backend dispatch stay inline (the helper is RNG-free; indices are pre-generated before dispatch, so cross-backend parity holds). - the post-loop warnings (whose wording legitimately differs between local and global) and np.std(ddof=1) stay inline in each method. - the closures resolve self._fit_*_with_fixed_lambda at call time, so the tests that monkeypatch them still intercept. Verified bit-identical: local + global bootstrap SE and the full bootstrap distributions match exactly pre/post on a fixed seed (Python fallback). Full TROP suite + Rust parity gate (119 tests, incl. atol=1e-14/1e-5 bootstrap seed-reproducibility) pass; 6 new direct unit tests cover the helper. Closes the TROP bootstrap-dedup TODO row. Behavior-preserving, so no REGISTRY / CHANGELOG change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Overall Assessment✅ Looks good — no unmitigated P0/P1 findings. Executive Summary
MethodologyFinding: P3 informational — behavior-preserving TROP bootstrap extraction
Code QualityFinding: None
PerformanceFinding: None
MaintainabilityFinding: P3 informational — TODO cleanup matches implemented work
Tech DebtFinding: None
SecurityFinding: None
Documentation/TestsFinding: P3 informational — targeted tests added; local execution unavailable here
|
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.
Summary
TROP._bootstrap_variance(trop_local.py) andTROP._bootstrap_variance_global(trop_global.py) into a new module-level helper_run_trop_bootstrap_loopintrop_local.py(imported bytrop_global.py, mirroring the existing_setup_trop_datapattern). The two loops differed only in the per-draw refit call, now passed as afit_callableclosure.TODO.md.This is a pure, behavior-preserving refactor: RNG setup and the Rust-backend dispatch stay inline (the helper is RNG-free; the stratified bootstrap indices are pre-generated before dispatch, so the Rust/Python cross-backend parity is preserved); the post-loop warnings — whose wording legitimately differs between local and global — and the
np.std(ddof=1)SE computation stay inline in each method; and the closures resolveself._fit_*_with_fixed_lambdaat call time, so the existing monkeypatching tests still intercept.Methodology references
control_units.dtype. This branch is unreachable in a real fit (_setup_trop_datarejects an empty treated/control pool before the bootstrap runs), and the resultingboot_datais byte-identical regardless sincef"{u}_{idx}"coerces every unit id tostr.Validation
tests/test_trop.py+tests/test_rust_backend.py::TestTROPRustEdgeCaseParity= 119 passed (including theatol=1e-14global /1e-5local bootstrap seed-reproducibility parity tests and the NaN-SE / proportional-failure-rate guards). Added 6 direct unit tests for the helper (tests/test_trop.py::TestRunTropBootstrapLoop): resampling + renamed ids, finite filter, exception skip, non-convergence tracker passthrough, and the empty-pool branches.black/ruff/mypyclean on the changed lines (no new errors).Security / privacy
🤖 Generated with Claude Code