Skip to content

Add derivative support for std::beta and introduce digamma function utility#1733

Merged
vgvassilev merged 2 commits intovgvassilev:masterfrom
leetcodez:clean-beta-pr
Mar 5, 2026
Merged

Add derivative support for std::beta and introduce digamma function utility#1733
vgvassilev merged 2 commits intovgvassilev:masterfrom
leetcodez:clean-beta-pr

Conversation

@leetcodez
Copy link
Copy Markdown
Contributor

Added a digamma utility to into BuiltInDerivatives.h It handles the math using a standard asymptotic expansion and uses a recurrence shift for smaller values of x to ensure the floating-point results stay accurate.
implemented beta_pushforward and beta_pullback.

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

// CHECK-NEXT: return _t0.pushforward;
// CHECK-NEXT: }

double f_beta(double x, double y) { return std::beta(x, y); }
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

We need to also properly update test/Features/stl-cmath.cpp

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done and done

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@leetcodez leetcodez requested a review from vgvassilev February 19, 2026 06:47
namespace std {
template <typename T>
inline T beta(T x, T y) {
return std::tgamma(x) * std::tgamma(y) / std::tgamma(x + y);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

We need to update the description on the top of this file accordingly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have updated the file description!

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@vgvassilev
Copy link
Copy Markdown
Owner

@guitargeek, can you take a look at this PR?

@guitargeek
Copy link
Copy Markdown
Collaborator

Hi, thanks for the PR! How did you come up with this particular implementation of the digamma function? Is it reusing code from the GNU scientific library? You have reference for this "standard asymptotic expansion" that can be linked to inline in the code?

@leetcodez
Copy link
Copy Markdown
Contributor Author

@guitargeek
No, I did not reference or reuse any code from the GNU Scientific Library for this.
The logic is a direct implementation of the standard asymptotic expansion for the digamma function my specific reference for the expansion is wolfram mathworld--https://mathworld.wolfram.com/DigammaFunction.html (equation 12,13)

@guitargeek
Copy link
Copy Markdown
Collaborator

Thanks. But how did you make the decision to stop expanding the series after 6 terms? I don't see anything about this in the wolfram.com link, unless I'm missing it. You also have some reference to justify that, since you referred to as "standard"?

Also, since the formula is an approximation, which is very important to know, I'd still prefer if this critical info is commented inline in the code.

Another thing: since the digamma is an approximation, there is a risk that approximation errors compound in higher-order derivatives. So what about implementing the trigamma function to be used as a custom derivative for the digamma? That's something I also suggested for ROOT.

Thanks you very much again for contributing on this important feature!

@leetcodez
Copy link
Copy Markdown
Contributor Author

Hey @guitargeek, thanks for the overview

You are totally right about the compounding errors. Trusting AD to differentiate through an asymptotic approximation is definitely a bad idea for higher-order derivatives. I would love to add a trigamma implementation to this PR or a subsequent PR.

As for the 6-term cutoff: once we push the input to x >= 8, the 6th term evaluates to ~2.4e-11 which puts us against the limit of a 64-bit double. I reckon adding anything beyond that just burns CPU cycles for no real gain in accuracy, i could implement it past the 6th term if you would like me to!

As for the most important part, I'll get those inline comments updated and start working on the trigamma implementation.

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

CUDA_HOST_DEVICE void beta_pullback(T x, T y, U d_z, T* d_x, T* d_y) {
T b = clad_beta_primal(x, y);
T psi_xy = clad_digamma(x + y);
if (d_x)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can d_x and d_y be nullptr?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, If you only request the derivative with respect to one of the arguments, clad passes a nullptr for the inactive variable's adjoint.
The if checks are there to make sure we don't segfault when trying to write to them. I just followed the same pattern used by the other _pullback functions in this file to keep things consistent.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Oh, I see. Thanks. It seems that we are not properly adding these if-checks for many pre-existing built-in derivatives functions.

@leetcodez leetcodez requested a review from parth-07 March 1, 2026 11:10
Copy link
Copy Markdown
Collaborator

@guitargeek guitargeek left a comment

Choose a reason for hiding this comment

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

Thanks, looks good to me at this point!

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 4, 2026

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 5, 2026

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Copy Markdown
Owner

@vgvassilev vgvassilev left a comment

Choose a reason for hiding this comment

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

LGTM!

@vgvassilev vgvassilev merged commit 3492433 into vgvassilev:master Mar 5, 2026
39 checks passed
guitargeek added a commit to guitargeek/root that referenced this pull request Apr 20, 2026
This function was introduced about 2 years ago as a quick fix to make
`LnGamma` differentiable with Clad, but it was inconvenient because it
depended on the external GSL library.

Since vgvassilev/clad#1733, Clad natively
implements a `digamma` function, so we can use this one now that we
updated to Clad 2.3.
guitargeek added a commit to root-project/root that referenced this pull request Apr 20, 2026
This function was introduced about 2 years ago as a quick fix to make
`LnGamma` differentiable with Clad, but it was inconvenient because it
depended on the external GSL library.

Since vgvassilev/clad#1733, Clad natively
implements a `digamma` function, so we can use this one now that we
updated to Clad 2.3.
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.

4 participants