22#error "This file must not be included by compiled programs."
25#include <plugins/include/clad/Differentiator/Differentiator.h>
34namespace custom_derivatives {
105 return {
::TMath::LnGamma(z), ::clad::custom_derivatives::std::clad_digamma(z) * d_z};
120template <
typename T,
typename U>
146template <
typename T,
typename U>
156template <
typename T,
typename U,
typename V>
159 auto t = pow_pushforward(
x,
y, 1, 0);
160 *d_x += t.pushforward *
p;
161 t = pow_pushforward(
x,
y, 0, 1);
162 *d_y += t.pushforward *
p;
212 for (
unsigned i =
N - 1; i > 0; --i)
213 r =
c[i - 1] +
r *
x;
221 double r = (
N - 1) *
c[
N - 1];
222 for (
unsigned i =
N - 1; i > 1; --i)
223 r = (i - 1) *
c[i - 1] +
r *
x;
229template <
unsigned N,
unsigned M>
245 static constexpr double p1[5] = {0.4259894875,-0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253};
246 static constexpr double q1[5] = {1.0 ,-0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063};
248 static constexpr double p2[5] = {0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211};
249 static constexpr double q2[5] = {1.0 , 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714};
251 static constexpr double p3[5] = {0.1788544503, 0.09359161662,0.006325387654, 0.00006611667319,-0.000002031049101};
252 static constexpr double q3[5] = {1.0 , 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675};
254 static constexpr double p4[5] = {0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186};
255 static constexpr double q4[5] = {1.0 , 106.8615961, 337.6496214, 2016.712389, 1597.063511};
257 static constexpr double p5[5] = {1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910};
258 static constexpr double q5[5] = {1.0 , 156.9424537, 3745.310488, 9834.698876, 66924.28357};
260 static constexpr double p6[5] = {1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109};
261 static constexpr double q6[5] = {1.0 , 651.4101098, 56974.73333, 165917.4725, -2815759.939};
263 static constexpr double a1[3] = {0.04166666667,-0.01996527778, 0.02709538966};
265 static constexpr double a2[2] = {-1.845568670,-4.284640743};
268 const double u = ::std::exp(
v + 1.);
273 const double eu = 0.3989422803 * ::std::exp(-1. / u);
274 const double val = eu / ::std::sqrt(u) * (1 + (a1[0] + (a1[1] + a1[2] * u) * u) * u);
275 const double dA = a1[0] + (2 * a1[1] + 3 * a1[2] * u) * u;
276 return val * (1. / u - 0.5) + eu * ::std::sqrt(u) * dA;
281 const double u = ::std::exp(-
v - 1);
282 const double eu = ::std::exp(-u) * ::std::sqrt(u);
292 const double u = 1 /
v;
295 const double u = 1 /
v;
297 }
else if (
v < 300) {
298 const double u = 1 /
v;
302 const double lv = ::std::log(
v);
303 const double u = 1 / (
v -
v *
lv / (
v + 1));
304 const double dw = 1 -
lv / (
v + 1) - 1 / (
v + 1) +
v *
lv / ((
v + 1) * (
v + 1));
305 const double dB = a2[0] + 2 * a2[1] * u;
306 return -u * u * dw * (2 * u * (1 + (a2[0] + a2[1] * u) * u) + u * u * dB);
310inline void landau_pdf_pullback(
double x,
double xi,
double x0,
double d_out,
double *d_x,
double *d_xi,
double *d_x0)
316 const double v = (
x - x0) / xi;
319 *d_x += d_out * dp / (xi * xi);
320 *d_x0 += -d_out * dp / (xi * xi);
321 *d_xi += -d_out * (
v * dp +
p) / (xi * xi);
333 static constexpr double p1[5] = {0.2514091491e+0,-0.6250580444e-1, 0.1458381230e-1,-0.2108817737e-2, 0.7411247290e-3};
334 static constexpr double q1[5] = {1.0 ,-0.5571175625e-2, 0.6225310236e-1,-0.3137378427e-2, 0.1931496439e-2};
336 static constexpr double p2[4] = {0.2868328584e+0, 0.3564363231e+0, 0.1523518695e+0, 0.2251304883e-1};
337 static constexpr double q2[4] = {1.0 , 0.6191136137e+0, 0.1720721448e+0, 0.2278594771e-1};
339 static constexpr double p3[4] = {0.2868329066e+0, 0.3003828436e+0, 0.9950951941e-1, 0.8733827185e-2};
340 static constexpr double q3[4] = {1.0 , 0.4237190502e+0, 0.1095631512e+0, 0.8693851567e-2};
342 static constexpr double p4[4] = {0.1000351630e+1, 0.4503592498e+1, 0.1085883880e+2, 0.7536052269e+1};
343 static constexpr double q4[4] = {1.0 , 0.5539969678e+1, 0.1933581111e+2, 0.2721321508e+2};
345 static constexpr double p5[4] = {0.1000006517e+1, 0.4909414111e+2, 0.8505544753e+2, 0.1532153455e+3};
346 static constexpr double q5[4] = {1.0 , 0.5009928881e+2, 0.1399819104e+3, 0.4200002909e+3};
348 static constexpr double p6[4] = {0.1000000983e+1, 0.1329868456e+3, 0.9162149244e+3,-0.9605054274e+3};
349 static constexpr double q6[4] = {1.0 , 0.1339887843e+3, 0.1055990413e+4, 0.5532224619e+3};
351 static constexpr double a1[4] = {0 ,-0.4583333333e+0, 0.6675347222e+0,-0.1641741416e+1};
352 static constexpr double a2[4] = {0 , 1.0 ,-0.4227843351e+0,-0.2043403138e+1};
357 const double u = ::std::exp(
v + 1);
358 const double eu = 0.3989422803 * ::std::exp(-1. / u) * ::std::sqrt(u);
359 const double val = eu * (1 + (a1[1] + (a1[2] + a1[3] * u) * u) * u);
360 const double dA = a1[1] + (2 * a1[2] + 3 * a1[3] * u) * u;
361 return val * (1. / u + 0.5) + eu * u * dA;
366 const double u = ::std::exp(-
v - 1);
367 const double eu = ::std::exp(-u) / ::std::sqrt(u);
377 const double u = 1. /
v;
380 const double u = 1. /
v;
382 }
else if (
v < 300) {
383 const double u = 1. /
v;
387 const double lv = ::std::log(
v);
388 const double u = 1. / (
v -
v *
lv / (
v + 1));
389 const double dw = 1 -
lv / (
v + 1) - 1 / (
v + 1) +
v *
lv / ((
v + 1) * (
v + 1));
394inline void landau_cdf_pullback(
double x,
double xi,
double x0,
double d_out,
double *d_x,
double *d_xi,
double *d_x0)
397 const double v = (
x - x0) / xi;
399 *d_x += d_out * dcdf / xi;
400 *d_x0 += -d_out * dcdf / xi;
401 *d_xi += -d_out * dcdf *
v / xi;
409 constexpr double kMACHEP = 1.11022302462515654042363166809e-16;
410 constexpr double kMAXLOG = 709.782712893383973096206318587;
412 double _d_ans = 0, _d_ax = 0, _d_c = 0, _d_r = 0;
418 clad::tape<double> _t7 = {};
419 clad::tape<double> _t8 = {};
420 clad::tape<double> _t9 = {};
421 double ans, ax,
c,
r;
426 if ((
x > 1.) && (
x >
a)) {
435 ax =
a * _t1 -
x - ::std::lgamma(
a);
437 *_d_x += (
a * _d_ax /
x) - _d_ax;
438 *_d_a += _d_ax * (_t1 - ::clad::custom_derivatives::std::clad_digamma(
451 unsigned long _t6 = 0;
458 clad::push(_t9, ans);
462 _d_ans += _d_y /
a * ax;
463 _d_ax += ans * _d_y /
a;
464 double _r6 = _d_y * -(ans * ax / (
a *
a));
470 ans = clad::pop(_t9);
471 double _r_d7 = _d_ans;
478 _d_c += _r_d6 *
x /
r;
479 *_d_x +=
c * _r_d6 /
r;
480 double _r5 =
c * _r_d6 * -(
x / (
r *
r));
492 double _r_d4 = _d_ans;
508 double _r_d1 = _d_ax;
511 _r4 += _r_d1 * ::std::exp(ax);
515 *_d_x += (
a * _d_ax /
x) - _d_ax;
516 *_d_a += _d_ax * (_t1 - ::clad::custom_derivatives::std::clad_digamma(
525 constexpr double kMACHEP = 1.11022302462515654042363166809e-16;
526 constexpr double kMAXLOG = 709.782712893383973096206318587;
527 constexpr double kBig = 4.503599627370496e15;
528 constexpr double kBiginv = 2.22044604925031308085e-16;
530 double _d_ans = 0, _d_ax = 0, _d_c = 0, _d_yc = 0, _d_r = 0, _d_y0 = 0, _d_z = 0;
531 double _d_pk = 0, _d_pkm1 = 0, _d_pkm2 = 0, _d_qk = 0, _d_qkm1 = 0, _d_qkm2 = 0;
543 clad::tape<double> _t12 = {};
544 clad::tape<double> _t13 = {};
545 clad::tape<double> _t14 = {};
546 clad::tape<double> _t15 = {};
547 clad::tape<double> _t16 = {};
548 clad::tape<double> _t17 = {};
549 clad::tape<double> _t19 = {};
550 clad::tape<double> _t20 = {};
551 clad::tape<double> _t22 = {};
552 clad::tape<double> _t24 = {};
553 clad::tape<double> _t25 = {};
554 clad::tape<double> _t26 = {};
555 clad::tape<double> _t27 = {};
556 clad::tape<bool> _t29 = {};
557 clad::tape<double> _t30 = {};
558 clad::tape<double> _t31 = {};
559 clad::tape<double> _t32 = {};
560 clad::tape<double> _t33 = {};
561 double ans, ax,
c, yc,
r, t,
y, z;
562 double pk, pkm1, pkm2, qk, qkm1, qkm2;
567 if ((
x < 1.) || (
x <
a)) {
576 ax =
a * _t1 -
x - ::std::lgamma(
a);
578 *_d_x +=
a * _d_ax /
x - _d_ax;
579 *_d_a += _d_ax * (_t1 - ::clad::custom_derivatives::std::clad_digamma(
611 clad::push(_t15, yc);
613 clad::push(_t16, pk);
614 pk = pkm1 * z - pkm2 * yc;
615 clad::push(_t17, qk);
616 qk = qkm1 * z - qkm2 * yc;
622 t = ::std::abs((ans -
r) /
r);
623 clad::push(_t22, ans);
628 clad::push(_t19, _t18);
630 clad::push(_t24, pkm2);
632 clad::push(_t25, pkm1);
634 clad::push(_t26, qkm2);
636 clad::push(_t27, qkm1);
638 bool _t28 = ::std::abs(pk) > kBig;
641 clad::push(_t30, pkm2);
643 clad::push(_t31, pkm1);
645 clad::push(_t32, qkm2);
647 clad::push(_t33, qkm1);
650 clad::push(_t29, _t28);
659 if (clad::pop(_t29)) {
661 qkm1 = clad::pop(_t33);
662 double _r_d27 = _d_qkm1;
664 _d_qkm1 += _r_d27 * kBiginv;
667 qkm2 = clad::pop(_t32);
668 double _r_d26 = _d_qkm2;
670 _d_qkm2 += _r_d26 * kBiginv;
673 pkm1 = clad::pop(_t31);
674 double _r_d25 = _d_pkm1;
676 _d_pkm1 += _r_d25 * kBiginv;
679 pkm2 = clad::pop(_t30);
680 double _r_d24 = _d_pkm2;
682 _d_pkm2 += _r_d24 * kBiginv;
686 qkm1 = clad::pop(_t27);
687 double _r_d23 = _d_qkm1;
692 qkm2 = clad::pop(_t26);
693 double _r_d22 = _d_qkm2;
698 pkm1 = clad::pop(_t25);
699 double _r_d21 = _d_pkm1;
704 pkm2 = clad::pop(_t24);
705 double _r_d20 = _d_pkm2;
711 if (clad::pop(_t19)) {
713 ans = clad::pop(_t22);
714 double _r_d18 = _d_ans;
720 double _r_d16 = _d_r;
722 _d_pk += _r_d16 / qk;
723 double _r6 = _r_d16 * -(pk / (qk * qk));
728 qk = clad::pop(_t17);
729 double _r_d15 = _d_qk;
731 _d_qkm1 += _r_d15 * z;
732 _d_z += qkm1 * _r_d15;
733 _d_qkm2 += -_r_d15 * yc;
734 _d_yc += qkm2 * -_r_d15;
737 pk = clad::pop(_t16);
738 double _r_d14 = _d_pk;
740 _d_pkm1 += _r_d14 * z;
741 _d_z += pkm1 * _r_d14;
742 _d_pkm2 += -_r_d14 * yc;
743 _d_yc += pkm2 * -_r_d14;
746 yc = clad::pop(_t15);
747 double _r_d13 = _d_yc;
754 double _r_d12 = _d_z;
758 double _r_d11 = _d_y0;
762 double _r_d10 = _d_c;
769 double _r_d9 = _d_ans;
771 _d_pkm1 += _r_d9 / qkm1;
772 double _r5 = _r_d9 * -(pkm1 / (qkm1 * qkm1));
777 double _r_d8 = _d_qkm1;
784 double _r_d7 = _d_pkm1;
790 double _r_d6 = _d_qkm2;
796 double _r_d5 = _d_pkm2;
813 double _r_d2 = _d_y0;
819 double _r_d1 = _d_ax;
821 double _r4 = _r_d1 * ::std::exp(ax);
825 *_d_x +=
a * _d_ax /
x - _d_ax;
826 *_d_a += _d_ax * (_t1 - ::clad::custom_derivatives::std::clad_digamma(
837 if (
a <= 0 ||
x <= 0)
839 return ::std::exp((
a - 1.) * ::std::log(
x) -
x - ::std::lgamma(
a));
849 if (
a <= 0 ||
x <= 0)
852 *_d_a += _d_y *
g * (::std::log(
x) - ::clad::custom_derivatives::std::clad_digamma(
a));
853 *_d_x += _d_y *
g * ((
a - 1.) /
x - 1.);
878 if (
a <= 0 ||
x <= 0)
880 *_d_x += _d_y *
inc_gamma_dx(
a,
x) * (::std::log(
x) - ::clad::custom_derivatives::std::clad_digamma(
a));
885 const double h = 6
e-6 * ::std::max(1., ::std::abs(
a));
918 const double h = 6
e-6 * ::std::max(1., ::std::abs(
v));
922 constexpr double seams[] = {-5.5, -1., 1., 5., 12., 50., 300.};
923 for (
double seam : seams) {
924 if (lo < seam && seam <=
hi) {
948 const double v = (
x - x0) / xi;
950 const double vDot = (d_x - d_x0 -
v * d_xi) / xi;
968 const double v = (
x - x0) / xi;
969 const double vDot = (d_x - d_x0 -
v * d_xi) / xi;
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
double landau_pdf(double x, double xi=1, double x0=0)
Probability density function of the Landau distribution:
double landau_cdf(double x, double xi=1, double x0=0)
Cumulative distribution function of the Landau distribution (lower tail).
double inc_gamma_c(double a, double x)
Calculates the normalized (regularized) upper incomplete gamma function (upper integral)
double inc_gamma(double a, double x)
Calculates the normalized (regularized) lower incomplete gamma function (lower integral)
Namespace for new Math classes and functions.
Double_t CosH(Double_t)
Returns the hyperbolic cosine of x.
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Double_t Log2(Double_t x)
Returns the binary (base-2) logarithm of x.
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Double_t Erf(Double_t x)
Computation of the error function erf(x).
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Double_t ASinH(Double_t)
Returns the area hyperbolic sine of x.
Double_t TanH(Double_t)
Returns the hyperbolic tangent of x.
Double_t ACosH(Double_t)
Returns the nonnegative area hyperbolic cosine of x.
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Double_t Erfc(Double_t x)
Computes the complementary error function erfc(x).
Double_t Sq(Double_t x)
Returns x*x.
Double_t Sqrt(Double_t x)
Returns the square root of x.
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
constexpr Double_t Ln10()
Natural log of 10 (to convert log to ln)
Double_t Hypot(Double_t x, Double_t y)
Returns sqrt(x*x + y*y)
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Double_t ATanH(Double_t)
Returns the area hyperbolic tangent of x.
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Double_t SinH(Double_t)
Returns the hyperbolic sine of x.
double landau_pdf_dv(double v)
First derivative of the standardized Landau density p(v) = ROOT::Math::landau_pdf(v) with respect to ...
clad::ValueAndPushforward< double, double > inc_gamma_c_pushforward(double a, double x, double d_a, double d_x)
Pushforward of ROOT::Math::inc_gamma_c, which is 1 - inc_gamma.
void landau_pdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0)
double inc_gamma_da(double a, double x)
Derivative of the normalized lower incomplete gamma function P(a, x) with respect to a.
double landau_cdf_dv(double v)
Derivative with respect to v of the CERNLIB DISLAN rational approximation of the standardized Landau ...
clad::ValueAndPushforward< double, double > landau_cdf_pushforward(double x, double xi, double x0, double d_x, double d_xi, double d_x0)
Pushforward of ROOT::Math::landau_cdf, which is the cumulative distribution function of the standardi...
double horner(const double(&c)[N], double x)
Evaluate the polynomial c[0] + c[1]*x + c[2]*x^2 + ... in Horner form, matching the evaluation order ...
clad::ValueAndPushforward< double, double > inc_gamma_pushforward(double a, double x, double d_a, double d_x)
Pushforward of ROOT::Math::inc_gamma.
void inc_gamma_c_pullback(double a, double x, double _d_y, double *_d_a, double *_d_x)
clad::ValueAndPushforward< double, double > landau_pdf_pushforward(double x, double xi, double x0, double d_x, double d_xi, double d_x0)
Pushforward of ROOT::Math::landau_pdf, which is p((x - x0) / xi) / xi in terms of the standardized La...
void inc_gamma_da_pullback(double a, double x, double _d_y, double *_d_a, double *_d_x)
Pullback of inc_gamma_da().
void landau_cdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0)
void inc_gamma_dx_pullback(double a, double x, double _d_y, double *_d_a, double *_d_x)
Pullback of inc_gamma_dx(), using the closed forms of the second derivatives of P(a,...
double horner_deriv(const double(&c)[N], double x)
Derivative of horner(c, x) with respect to x.
double inc_gamma_dx(double a, double x)
Derivative of the normalized lower incomplete gamma function P(a, x) with respect to x.
void inc_gamma_pullback(double a, double x, double _d_y, double *_d_a, double *_d_x)
void landau_pdf_dv_pullback(double v, double _d_y, double *_d_v)
Pullback of landau_pdf_dv().
double rational_deriv(const double(&p)[N], const double(&q)[M], double x)
Derivative of the rational function horner(p, x) / horner(q, x) with respect to x.
ValueAndPushforward< T, T > CosH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Abs_pushforward(T x, T d_x)
void Power_pullback(T x, U y, V p, T *d_x, U *d_y)
ValueAndPushforward< T, T > Sq_pushforward(T x, T d_x)
void Hypot_pullback(T x, T y, U p, T *d_x, T *d_y)
ValueAndPushforward< T, T > Erf_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Erfc_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Sin_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Hypot_pushforward(T x, T y, T d_x, T d_y)
ValueAndPushforward< T, T > ASinH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > LnGamma_pushforward(T z, T d_z)
ValueAndPushforward< T, T > ACosH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ASin_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Power_pushforward(T x, U y, T d_x, U d_y)
ValueAndPushforward< T, T > Cos_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Sqrt_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Tan_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Log_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Log10_pushforward(T x, T d_x)
ValueAndPushforward< T, T > TanH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ACos_pushforward(T x, T d_x)
ValueAndPushforward< T, T > SinH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Exp_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Log2_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ATanH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ATan_pushforward(T x, T d_x)