Skip to content

Add lbeta - #1498

Merged
NAThompson merged 10 commits into
developfrom
lbeta
Oct 3, 2026
Merged

NAThompson merged 10 commits into
developfrom
lbeta

Conversation

@NAThompson

@NAThompson NAThompson commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

lbeta takes the log of beta's Lanczos form term by term, so it neither underflows nor cancels for large arguments. Groundwork for #1173.

Also marks cropped ulps_plot points with crosses in their function's color, so clipped errors stay attributable when several functions share a plot.

ulps against a 200-digit reference (400 for cpp_bin_float_100): lbeta in blue, log(beta) in orange; crosses are clipped or -inf.

lbeta(a, a)
lbeta(a, 1e6)
lbeta(a, 2.5)
lbeta(a, 0.1)
lbeta(a, 7.25), cpp_bin_float_100

🤖 Generated with Claude Code

@NAThompson

Copy link
Copy Markdown
Collaborator Author

@JacobHass8 , @dschmitz89 : We'll work here on lbeta and then the we'll be able to push #1359 past the finish line.

@NAThompson

NAThompson commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator Author

reporting/performance/lbeta_performance.cpp:

float double long double
lbeta(a, b) 28.9 ns 41.9 ns 42.3 ns
log(beta(a, b)) 30.4 ns 51.1 ns 49.6 ns
lgamma(a) + lgamma(b) - lgamma(a + b) 41.4 ns 52.3 ns 52.2 ns

@NAThompson

Copy link
Copy Markdown
Collaborator Author

@dschmitz89 , @jzmaddock , @JacobHass8 : Ready for review.

@dschmitz89

Copy link
Copy Markdown
Contributor

The error plots look good to me. Could you explain them a little though to someone who is not used to them? The y axis unit are ULPs, so we see epsilon differences? And what are the green lines? Error Percentiles?

@NAThompson

NAThompson commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator Author

@dschmitz89 : The green lines are "condition number envelopes".

In general, it's hard to achieve correctly rounded outputs for correctly rounded inputs without using higher intermediate precision and massive slowdown. So instead we take a checkdown and say "the input itself is probably rounded to half an ulp."

So $f(\hat{x}) = f(x(1+u)) \approx f(x) + xu f'(x)$. Then we compute $f(x)$ at very high precision as the reference, yielding the relative error $\frac{ |xuf'(x)| }{ |f(x)| }$. The value $\frac{ |xf'(x)| }{ |f(x)| }$ is the condition number of function evaluation.

Of course, this can go below a half-ulp, which is the best achievable accuracy. So we take $g(x) := \max(0.5, |xf'(x)|/|f(x)| )$, then $g$ is the positive half of the green line. It is a reasonable scale for acceptable accuracy.

@mborland

mborland commented Oct 2, 2026

Copy link
Copy Markdown
Member

@NAThompson once this is generally good can you add a CUDA test since the function is marked as GPU compatible?

@NAThompson

Copy link
Copy Markdown
Collaborator Author

@mborland : Done.

Comment thread include/boost/math/special_functions/beta.hpp Outdated
Comment thread include/boost/math/special_functions/beta.hpp Outdated
Comment thread test/test_lbeta.cpp
@jzmaddock

Copy link
Copy Markdown
Collaborator

This looks good to me, I'll add some specific comments in the code.

Comment thread include/boost/math/special_functions/beta.hpp Outdated
NAThompson and others added 10 commits October 2, 2026 21:49
…on's color

lbeta takes the log of beta's Lanczos form term by term, so it neither underflows nor cancels for large arguments. Groundwork for #1173.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
real_concept's own log is double precision on platforms with a wider long double.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… arithmetic

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It is negligible for beta but costs up to 20 ulps in the log when a is huge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Previously it returned NaN; also fixes "Stirling" in the beta docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generic path otherwise threw from log1p or tripped an assertion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@NAThompson
NAThompson merged commit 0cb2b4c into develop Oct 3, 2026
48 checks passed
@NAThompson

Copy link
Copy Markdown
Collaborator Author

@dschmitz89 , @mborland , @jzmaddock , @JacobHass8 : Feel free to add any additional comments on these and I'll take them on in a fixup commit.

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.

5 participants