Skip to content

Rearrange left/right DCB tail integral evaluation for numerical stability when n1 or n2 is very close to 1#1253

Open
erfz wants to merge 1 commit into
cms-analysis:mainfrom
erfz:DCB_tail-integral_numerical-stability
Open

Rearrange left/right DCB tail integral evaluation for numerical stability when n1 or n2 is very close to 1#1253
erfz wants to merge 1 commit into
cms-analysis:mainfrom
erfz:DCB_tail-integral_numerical-stability

Conversation

@erfz

@erfz erfz commented May 22, 2026

Copy link
Copy Markdown

When using RooDoubleCBFast, we noticed that the raw, unnormalized integral (which is returned by RooDoubleCBFast::analyticalIntegral) of the left (right) power-law tail blows up/is unstable when n1 (n2) is very close to 1 -- but not close enough that the integral is given by the logarithm in the code.

In the attached slides , I show that the current threshold in the code where the log is used for the integral, (n1 - 1) < 1e-5 (same for n2), does not need to be changed to fix this issue. It turns out that the fix is simply to rearrange the evaluation of line 186 for the right tail and line 149 for the left tail to be done in an algebraically equivalent, but more numerically stable way. This is done in the commit.

See the attached slides for:

  • example of DCB fit where the right tail integral blows up
  • explanation of the issue
  • minimal working example that demonstrates the raw, unnormalized integral of the tail blowing up

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR refactors power computation factorization in the analyticalIntegral function of RooDoubleCBFast. Left and right-tail integral calculations now separate base power computations (leftpow and rightpow) from subsequent fast_pow applications, reorganizing how exponentiation combines with offset terms.

Changes

Tail Integral Power Refactoring

Layer / File(s) Summary
Left and right-tail power factorization in analyticalIntegral
src/RooDoubleCBFast.cc
Left-tail integral now computes leftpow as fast_pow(n1invalpha1, n1) separately and applies it to results of fast_pow(...) on offset terms. Right-tail integral similarly separates rightpow as fast_pow(n2invalpha2, n2) and combines it with offset-based fast_pow results. Both refactor how base expressions and exponents interact.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

The changes involve mathematical computation refactoring across two coupled integral tail regions with high code block complexity. Verification requires careful inspection of exponent handling, term factorization, and mathematical equivalence between old and new power computation patterns.

Poem

🐰 A rabbit's cry of pow! Oh pow!
Old factors danced in mystical rows,
Now left and right have learned to bow,
Separate terms in elegant flow,
Math sings true as fast_pow glows! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: rearranging DCB tail integral evaluation for numerical stability when n1/n2 is near 1, which matches the core objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/RooDoubleCBFast.cc (1)

141-149: ⚡ Quick win

Add a regression for the just-above-threshold tail path.

This rewrite targets a very specific instability, but nothing here locks in the fabs(n?-1) > 1e-5 branch that was blowing up before. Please add a test with n1/n2 just above the cutoff and an integration range fully in the corresponding tail, asserting the integral stays finite and matches the logarithmic form closely.

Also applies to: 178-186

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/RooDoubleCBFast.cc` around lines 141 - 149, The tail-path math for
left1/left2 (and the analogous right-side code around lines with n2) becomes
unstable when n1 or n2 are just above 1; add a small-epsilon branch to
RooDoubleCBFast that detects |n1-1|<1e-5 (and similarly |n2-1|<1e-5) and uses
the logarithmic/limit form (use exp((1.-n1)*log(term)) or the first-order log
expansion) instead of direct fast_pow to compute left1/left2 (symbols: left1,
left2, n1, n2, n1invalpha1, alpha1, tmin, thigh and the matching right-side
variables), and add a regression unit test that sets n1 (and separately n2) just
above 1 with an integration range fully inside the tail and asserts the integral
is finite and matches the expected logarithmic-limit value within tolerance.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/RooDoubleCBFast.cc`:
- Around line 141-149: The tail-path math for left1/left2 (and the analogous
right-side code around lines with n2) becomes unstable when n1 or n2 are just
above 1; add a small-epsilon branch to RooDoubleCBFast that detects |n1-1|<1e-5
(and similarly |n2-1|<1e-5) and uses the logarithmic/limit form (use
exp((1.-n1)*log(term)) or the first-order log expansion) instead of direct
fast_pow to compute left1/left2 (symbols: left1, left2, n1, n2, n1invalpha1,
alpha1, tmin, thigh and the matching right-side variables), and add a regression
unit test that sets n1 (and separately n2) just above 1 with an integration
range fully inside the tail and asserts the integral is finite and matches the
expected logarithmic-limit value within tolerance.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 999b4fa6-8e6d-4b48-a403-3097db2fac2f

📥 Commits

Reviewing files that changed from the base of the PR and between da0a2f4 and c259a4c.

📒 Files selected for processing (1)
  • src/RooDoubleCBFast.cc

@codecov

codecov Bot commented May 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 20.90%. Comparing base (da0a2f4) to head (c259a4c).

Files with missing lines Patch % Lines
src/RooDoubleCBFast.cc 66.66% 2 Missing ⚠️

❌ Your patch check has failed because the patch coverage (66.66%) is below the target coverage (98.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1253   +/-   ##
=======================================
  Coverage   20.90%   20.90%           
=======================================
  Files         195      195           
  Lines       26316    26316           
  Branches     3947     3947           
=======================================
  Hits         5502     5502           
  Misses      20814    20814           
Files with missing lines Coverage Δ
src/RooDoubleCBFast.cc 75.51% <66.66%> (ø)
Files with missing lines Coverage Δ
src/RooDoubleCBFast.cc 75.51% <66.66%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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