From 5f976068e2223060cfae3ff83dc8f748bc6b32a9 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Fri, 27 Feb 2026 01:29:17 +0100 Subject: [PATCH 1/2] [Math] Add custom derivative for `digamma` function The `digamma` function is important because it's the derivative of the log of the gamma function, which is widely used in likelihood fits because it appears in the Poisson distribution. If we want analytical Hessians, we also need to provide the analytical derivative of the digamma function, which is the trigamma function. Fortunately, we can find it in the GNU scientific library: https://www.gnu.org/software/gsl/doc/html/specfunc.html#trigamma-function --- math/mathcore/inc/Math/CladDerivator.h | 17 +++++++++-------- math/mathmore/inc/Math/SpecFuncMathMore.h | 1 + math/mathmore/src/SpecFuncMathMore.cxx | 5 +++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/math/mathcore/inc/Math/CladDerivator.h b/math/mathcore/inc/Math/CladDerivator.h index 1c33e7cd3f1ca..b57722bb86242 100644 --- a/math/mathcore/inc/Math/CladDerivator.h +++ b/math/mathcore/inc/Math/CladDerivator.h @@ -34,8 +34,7 @@ #include -namespace clad { -namespace custom_derivatives { +namespace clad::custom_derivatives { namespace TMath { template ValueAndPushforward Abs_pushforward(T x, T d_x) @@ -222,8 +221,7 @@ ValueAndPushforward Ln10_pushforward() #endif } // namespace TMath -namespace ROOT { -namespace Math { +namespace ROOT::Math { inline void landau_pdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0) { @@ -1092,13 +1090,16 @@ inline void inc_gamma_c_pullback(double a, double x, double _d_y, double *_d_a, } } +inline ValueAndPushforward digamma_pushforward(double x, double d_x) +{ + return {::ROOT::Math::digamma(x), ::ROOT::Math::trigamma(x) * d_x}; +} + #endif // R__HAS_MATHMORE -} // namespace Math -} // namespace ROOT +} // namespace ROOT::Math -} // namespace custom_derivatives -} // namespace clad +} // namespace clad::custom_derivatives // Forward declare BLAS functions. extern "C" void sgemm_(const char *transa, const char *transb, const int *m, const int *n, const int *k, diff --git a/math/mathmore/inc/Math/SpecFuncMathMore.h b/math/mathmore/inc/Math/SpecFuncMathMore.h index 564729efbb39f..897c637ac53bd 100644 --- a/math/mathmore/inc/Math/SpecFuncMathMore.h +++ b/math/mathmore/inc/Math/SpecFuncMathMore.h @@ -874,6 +874,7 @@ namespace Math { double wigner_9j(int two_ja, int two_jb, int two_jc, int two_jd, int two_je, int two_jf, int two_jg, int two_jh, int two_ji); double digamma(double x); + double trigamma(double x); } // namespace Math diff --git a/math/mathmore/src/SpecFuncMathMore.cxx b/math/mathmore/src/SpecFuncMathMore.cxx index 73ed6c98149fe..8d29b10cca3d2 100644 --- a/math/mathmore/src/SpecFuncMathMore.cxx +++ b/math/mathmore/src/SpecFuncMathMore.cxx @@ -482,5 +482,10 @@ double digamma(double x) return gsl_sf_psi(x); } +double trigamma(double x) +{ + return gsl_sf_psi_1(x); +} + } // namespace Math } // namespace ROOT From cdd7d1700c8431bcc373ffe545939b7dcb959c83 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Fri, 27 Feb 2026 01:32:55 +0100 Subject: [PATCH 2/2] [Math] Remove unneeded code from CladDerivator.h --- math/mathcore/inc/Math/CladDerivator.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/math/mathcore/inc/Math/CladDerivator.h b/math/mathcore/inc/Math/CladDerivator.h index b57722bb86242..1d5cdcf2f9a60 100644 --- a/math/mathcore/inc/Math/CladDerivator.h +++ b/math/mathcore/inc/Math/CladDerivator.h @@ -205,20 +205,6 @@ ValueAndPushforward TanH_pushforward(T x, T d_x) return {::TMath::TanH(x), (1. / ::TMath::Sq(::TMath::CosH(x))) * d_x}; } -#ifdef WIN32 -// Additional custom derivatives that can be removed -// after Issue #12108 in ROOT is resolved -// constexpr is removed -ValueAndPushforward Pi_pushforward() -{ - return {3.1415926535897931, 0.}; -} -// constexpr is removed -ValueAndPushforward Ln10_pushforward() -{ - return {2.3025850929940459, 0.}; -} -#endif } // namespace TMath namespace ROOT::Math {