Skip to content

integrators: stabilize the MC error estimate (tail diagnostic, replicas, disclosed budgets) - #38

Merged
oshaughnessy-junior merged 1 commit into
rift_O4dfrom
rift_O4d_mc_error_v2
Jul 29, 2026
Merged

integrators: stabilize the MC error estimate (tail diagnostic, replicas, disclosed budgets)#38
oshaughnessy-junior merged 1 commit into
rift_O4dfrom
rift_O4d_mc_error_v2

Conversation

@oshaughnessy-junior

Copy link
Copy Markdown
Owner

integrators: stabilize the MC error estimate (tail diagnostic, replicas, disclosed budgets)

Supersedes #37, rebased onto rift_O4d per review (base now includes the hard shape-gate suite and optional-plugin isolation). Same single commit, cherry-picked; one trivial conflict vs the AV warm-start block, resolved keeping both.

What this changes

The reported sigma/L is the pooled weight sample-variance -- algebraically 1/ESS_hat - 1/n restated, computed from the SAME weights as the integral. It is tail-blind and fails conditionally on the run being wrong (a run that misses the peak reports BOTH low lnL AND small sigma). Changes:

  • statutils: pareto_khat_from_log (Zhang-Stephens GPD tail fit, PSIS xi convention), ess_from_log_weights, block_scatter_sigma (delete-one jackknife over per-chunk lnZ), bootstrap_lnZ_quantiles.
  • mcsampler / mcsamplerGPU: per-chunk lnZ recorded; finalize emits pareto_khat, n_ESS, sigma_lnZ_block, lnZ_ci90 via dict_return; fixes _rvs['weights'] appending onto joint_s_prior.
  • mcsamplerAdaptiveVolume: adds the missing Var(lnV) (live volume is a stochastic product of per-cycle binomial survival fractions) and trunc_p^2 terms to the returned relative variance, disclosed in dict_return.
  • ILE batchmode: floors sigma at the between-chunk scatter; prints k-hat and bootstrap CI; opt-in --mc-error-replicas (+ sigma/khat/ESS triggers) reruns cold replicas in-process, combined by the LINEAR mean with scatter-based error. Default off.
  • util_CleanILE: replaces inverse-variance combination (which overweights exactly the replica that missed the peak: correlated low-lnL/low-sigma) with the ntot-weighted linear mean and max(propagated, scatter) error.

Merge-gate evidence (this head = junior/rift_O4d @ cbb67cc + 1 commit)

  • Fast CI: test_mcsamplerEnsemble_extended.py --as-test --n-max 100000 exit 0, and --use-lnL variant exit 0 (CPU, CUDA_VISIBLE_DEVICES="").
  • Shape-recovery gate (standard preset, 96 runs, CPU, same seeds both sides):
    • base rift_O4d: 8 strict failures, 5 warn-only, 45 starved
    • this PR: 4 strict failures, 5 warn-only, 45 starved
    • compare_shape_results.py: 0 blocking regressions (strict = AV, GMM); 5 IMPROVED(fail->pass); 4 PREEXISTING-FAIL (fail on both).
  • Honest reading of the "improvement": the per-target AV lnZ biases are byte-identical between base and PR (same seeds; the sampling path is untouched) -- e.g. mix_d8_n1_s101 bias +0.642 on both sides. What changed is the tolerance, which the gate scales by the reported sigma: with the previously-missing Var(lnV) + trunc_p^2 terms disclosed, several borderline targets now pass because the error bar is honest, not because the bias shrank. The residual AV lnZ biases (d4_n1_s202 -0.289, d6_n1_s101 +0.528, d8_n1_s101 +0.642) are pre-existing and are exactly the class of error this PR's k-hat flag + replicate-when-loud machinery is designed to expose downstream.
  • Pre-existing (both sides, per policy ticketed not blocking): GMM mix_d2_n1_s101 shape failure; AV lnZ biases above.
  • Gate artifacts on CIT: ~/RIFT_develUWM/src/research-projects-RIT/.claude/worktrees/{base_shape.json,pr_shape.json,base_shape.log,pr_shape.log} (run via run_shape_recovery.sh, SHAPE_JOBS=8).

Validation beyond the gate (paper repo demos/error_estimate/): 19/19 unit/e2e checks incl. GPD k-hat recovery on known tails; log-normal toy quantifying the conditional underestimate (coverage 0.90->0.24 over tau=1..5; inverse-variance combine bias -0.86 vs -0.26 nats for linear mean).

🤖 Generated with Claude Code

…as, disclosed budgets)

The reported sigma_lnL is the pooled weight sample-variance -- algebraically
1/ESS_hat - 1/n restated, computed from the SAME weights as the integral.  It
is tail-blind: a run that misses the likelihood peak reports BOTH a low lnL
AND a small sigma, so the error bar fails conditionally on the run being wrong
(toy model: median underestimate 1.0-2.4x for tau=1-5, 90% coverage collapses
to 0.24, reported sigma ANTI-correlated with actual error; corroborated by
dslice exports where sigmaL understates redraw scatter 3-18x at high SNR).

Defenses, all disclosed in the job log:

* statutils: new helpers pareto_khat_from_log (Zhang-Stephens GPD tail fit,
  PSIS xi convention), ess_from_log_weights, block_scatter_sigma (delete-one
  jackknife over per-chunk lnZ), bootstrap_lnZ_quantiles.
* mcsampler + mcsamplerGPU: record per-chunk lnZ during the run; at finalize
  emit pareto_khat, n_ESS, sigma_lnZ_block, and (when relative error > 0.3)
  bootstrap lnZ quantiles via dict_return.  Also fix a bug where the
  _rvs['weights'] record appended new weights onto joint_s_prior.
* mcsamplerAdaptiveVolume: the naive term is blind to the stochastic live
  volume (Z ~ V*mean(w)) and to the truncated probability; accumulate
  Var(lnV) per cycle and add var_lnV + trunc_p^2 to the returned relative
  variance, with components in dict_return.
* ILE (integrate_likelihood_extrinsic_batchmode): floor the reported sigma at
  the between-chunk scatter; print k-hat (k>0.7: sigma is a lower bound) and
  bootstrap CI; new opt-in --mc-error-replicas N (+ --mc-error-sigma-trigger
  0.4, --mc-error-khat-trigger 0.7, --mc-error-ess-trigger 30): when
  triggered, rerun cold replicas in-process and report the LINEAR mean of the
  replica integrals with sigma = max(propagated, replica scatter), neff = sum;
  posterior export keeps the best-converged replica.  Default off.
* util_CleanILE: combine repeated evaluations by the ntot-weighted LINEAR
  mean with sigma = max(propagated, between-replica scatter).  The previous
  1/sigma^2 weighting overweighted exactly the replica that missed the peak
  (low lnL AND low sigma): toy model shows -0.86 nat combine bias vs -0.26
  for the linear mean.

Validation: 19/19 in the roboto-paper demos/error_estimate/run_validation.py
(k-hat recovers GPD k=0.3/0.7 to +-0.04; all samplers emit the diagnostics;
CleanILE matches the new formula) and .travis test_mcsamplerEnsemble_extended
--as-test passes both variants unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@oshaughnessy-junior

Copy link
Copy Markdown
Owner Author

2026-08-16 00:42 UTC read-only interhost monitoring: PR #94 (b775c6de over rift_O4d@364a22fd), PR #96 (652731b6 over the same base), and PR #97 (2db91e67 over rift_O4d@d904e72d) are draft OPEN/CLEAN. Each exact head has successful private dispatch and CI (#94 31901722562/31901723554; #96 31823833402/31823833384; #97 31907523507/31907523919), but no exact-head review. The Stage-8 plan-only observer outcome is still absent; active-developer interlock preserved. No route, queue, worker, source, checkout, review, push, merge, permission, UUID, or diagnostic mutation occurred. Evidence: activities/2026-08-06-PRReviewSessionRouter/runs/2026-08-16-interhost-pr94-pr96-pr97-monitoring-0042.md. Next: monitor only new heads or exact-head review outcomes; do not run the diagnostic until the observer outcome is recorded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant