Repository navigation
Conversation
|
I'll be away for two weeks, but did create this PR to avoid overlap in work. Similar PR should be made for incomplete beta gradient roots (mentioned in PR text) |
Jenkins Console Log Machine informationDistributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focal CPU: Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 43 bits physical, 48 bits virtual CPU(s): 256 On-line CPU(s) list: 0-255 Thread(s) per core: 2 Core(s) per socket: 64 Socket(s): 2 NUMA node(s): 2 Vendor ID: AuthenticAMD CPU family: 23 Model: 49 Model name: AMD EPYC 7742 64-Core Processor Stepping: 0 Frequency boost: enabled CPU MHz: 1494.753 CPU max MHz: 3416.0681 CPU min MHz: 1500.0000 BogoMIPS: 4491.85 Virtualization: AMD-V L1d cache: 4 MiB L1i cache: 4 MiB L2 cache: 64 MiB L3 cache: 512 MiB NUMA node0 CPU(s): 0-63,128-191 NUMA node1 CPU(s): 64-127,192-255 Vulnerability Gather data sampling: Not affected Vulnerability Indirect target selection: Not affected Vulnerability Itlb multihit: Not affected Vulnerability L1tf: Not affected Vulnerability Mds: Not affected Vulnerability Meltdown: Not affected Vulnerability Mmio stale data: Not affected Vulnerability Old microcode: Not affected Vulnerability Reg file data sampling: Not affected Vulnerability Retbleed: Mitigation; untrained return thunk; SMT enabled with STIBP protection Vulnerability Spec rstack overflow: Mitigation; Safe RET Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization Vulnerability Spectre v2: Mitigation; Retpolines; IBPB conditional; STIBP always-on; RSB filling; PBRSB-eIBRS Not affected; BHI Not affected Vulnerability Srbds: Not affected Vulnerability Tsa: Not affected Vulnerability Tsx async abort: Not affected Vulnerability Vmscape: Mitigation; IBPB before exit to userspace Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd amd_ppin arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip rdpid overflow_recov succor smca sev sev_es G++: g++ (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Clang: clang version 10.0.0-4ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
|
@avehtari A colleague of mine noticed instability in the gradient of Stan's
|
@mjcarter95 There was no plan before your comment! Thanks for testing and reporting, I'll investigate a possible fix |
Thank you, Aki. Claude helped me to identify that the issue arises because Stan computes the shape gradient as dQ/dα divided by exp(log Q), and once log Q falls below about −745, both terms underflow to zero and the result is 0/0 = NaN. Are there guidelines for how to submit an AI-assisted PR? If so, I'd be happy to supervise Claude in coming up with a fix and submitting a PR that piggybacks off this one. |
|
I'm already fixing this and what you mentioned is only part of the problem. It's just that running the accuracy, speed and unit tests takes some time and also checking which other functions can be improved, so please wait a few hours. |
|
@mjcarter95 Just an intermediate report that I'm making fixes for 17 other functions in addition to |
Brilliant, thank you for following up so quickly! |
igamma_der_a for the incomplete gamma gradient roots|
@mjcarter95 The Here's my version of the figure (with probably more accurate reference as when using the same color scale as you used, it is very boring) |
|
Re-ran the tests my end, all looks good! I am comparing against mpmath. Thank you for fixing this @avehtari
|
I guess you are using lower accuracy in mpmath, as you report worst relative error 4.1e-6 and I have worst relative error 3.4e-12 (I used 40 to 80 digits accuracy) |
I used precision 60 for all cells. |
…ther elements of poisson_lccdf for negative counts
|
@avehtari can you split this PR into smaller batches? There's a bit too much to review properly, and doesn't all need to land in the one PR |
OK. I have worried that I have too many PRs, but I can do more. |
|
@andrjohns how many PRs would you prefer? There are 5 logical parts and thus it would be possible to split this in 5 PRs
G2 and G3 are independent of each other; G4 and G5 are independent of each other. Instead of 5 PRs it would possible to combine G1 and G2 in one PR and/or G3, G4 and G5 to one PR Let me know what you prefer, and I'll do the split |



EDIT: This PR text was updated 2026-10-21
This PR was Claude assisted
Issues
In addition of great accuracy, stability and speed improvement
gamma_qwithfvarandgamma_pwithvarreturn wrong derivatives (Part 2).poisson_lccdfno longer drops the other elements of a vector when one count is negative. The same defect remains in other discrete cdfs; see "Not included".tgamma_lowerandtgamma(a,z)functions #2769:log Pandlog Qare now computed in log space inside the library, but no public function is added.gamma_lccdfshape-gradient failures that @mjcarter95 reported in this thread (Part 3).Summary
This PR repairs the derivatives of the regularized incomplete gamma functions and the 18 distribution functions that are built on them: the
cdf,lcdfandlccdfofchi_square,gamma,inv_chi_square,inv_gamma,scaled_inv_chi_squareandpoisson. It has three parts.grad_reg_inc_gammaandgrad_reg_lower_inc_gamma(the derivatives ofQ(a, z)andP(a, z)with respect toa) are replaced byEigen::numext::igamma_der_a, which is already vendored inlib/eigen_5.0.1. The old roots were wrong by tens of percent, or NaN, in regions that ordinary models reach.gamma_qhad its own copy of the old series, which did not terminate forzabove about 700. The copy is removed. The reverse-modegamma_preturned zero derivatives forz / a > 10; it now returns the derivatives. Closes gamma_p and gamma_q gradient problems #2006.log Porlog Qand their derivatives in log space, through one internal function. Before, they returned-infvalues or NaN gradients where the probability underflows, and 13 of them returned NaN gradients in the bulk once the shape is above about 150.The values of the distributions change only where they were
-infor lost digits; elsewhere only the gradients change.developa ≈ z ≈ 1e4gamma_q,z ≳ 700doublerootsvar)Part 1: the gradient roots
The defects on
developAll numbers in this part were measured against an mpmath reference at 80 digits, built through two independent routes that agree to at least 13 digits, with the real
developheaders at5252d51d47compiled and run.grad_reg_inc_gammatakes an invalid branch whenzis neara. The testz >= a && z >= 8selects a fixed 10-term asymptotic expansion (DLMF 8.11.2), which needsz >> a. In the whole banda <= z < 2athe terms do not decay. The relative error atz = ais 4.4e-02 ata = 20, 5.8e-01 ata = 100and 7.2e-01 ata = 171.grad_reg_inc_gammareturns NaN foraabove about 171.6. Every call site passesg = tgamma(a), which isinfthere, so the correction termexp(-z + (a-1) log z) * S / gisinf / inf. The series branch fails the same way throughexp(a * log z)whena log z > 709, for example at(a, z) = (150, 150).grad_reg_lower_inc_gammaloses all accuracy forzwell abovea. Its delegation test sends every point withz > 42anda >= 12to the Gautschi branch, whereemz * (log_z * sum_a - sum_b)is a difference of two large, nearly equal sums. It returns about 1e-14 of rounding noise with arbitrary sign: at(50, 150)the reference is -8.29e-22 anddevelopreturns -4.70e-15; at(50, 500)the reference is -5.34e-148 anddevelopreturns +1.47e-14.precisionof 1e-6 sets the error of the plain series branch: 9.2e-08 ata = 0.5and 9.0e-05 ata = 8. It is the smallest of the four problems.The defects reach the distribution functions. Measured with
varagainst the same reference (the cdf values are correct; only the gradients are wrong):developchi_square_lccdfchi_square_lccdfchi_square_lcdfgamma_cdfinv_gamma_lccdfThe gradients are NaN for
chi_square_lccdfandchi_square_lcdfat nu = 360,gamma_cdfandinv_gamma_lccdfat alpha = 180, andscaled_inv_chi_square_lcdfat nu = 360. With this PR, every row of the table agrees with the reference to all 12 printed digits.The change
Eigen::internal::igamma_generic_impldifferentiates the Cephes power series and continued fraction term by term, stops at machine epsilon, and branches onx > 1 && x > a, which is the well-conditioned split. It is generic in the scalar type except for three helpers,lgamma_impl,digamma_implandcephes_helper. This PR supplies those three for Stan's autodiff scalars in two new headers,stan/math/fwd/fun/Eigen_SpecialFunctions.hppandstan/math/rev/fun/Eigen_SpecialFunctions.hpp. Both roots then become thin wrappers, and the hand-written series, the asymptotic branch and the Gautschi branch are deleted.One algorithm now serves every scalar type and every autodiff order, so reverse mode, forward mode,
fvar<fvar<double>>,fvar<var>andhessian()agree. I tried thedoublepath alone first and rejected it:hessian()stayed on the old code, andgradient()andhessian()then returned first derivatives that differed by 5.8e-01 atalpha = 100and by NaN atalpha = 180.The signatures do not change.
g,dig,precisionandmax_stepsare accepted and ignored.Accuracy
A sweep of 1 800 points in nine regions chosen by the branch structure; worst relative error per region (200 points each):
developgrad_reg_inc_gammadevelopgrad_reg_lower_inc_gammaA second sweep compared 49 990 points with
aandzboth in [1e-3, 1e4], dense onz ≈ a, thez = 8seam,a = 171.62anda log z = 709.developreturns NaN or inf at 6 379 of them forgrad_reg_inc_gamma; this PR is finite at every one, with median relative errors between 1e-16 and 1e-14 in every region.One known limit: near
z = athe error grows witha, to 3e-11 fora < 1 000, 2.9e-7 fora < 10 000, and 5.2e-6 ata = z = 1e4, where Eigen's Cephes recurrence loses digits near the mode. Three independent references agree to 17 digits there, so this is the algorithm, not the measurement. In the far upper tail ata ≳ 1e4the reference is certified to 11 digits only.Speed
Function level, net ns per call, Xeon E5-2680 v3,
performancegovernor, two rounds (spread under 3 %), onain [0.5, 60] andzin [0.1, 40], wheredevelopterminates and is finite:developgrad_reg_inc_gamma, double, withtgammaanddigammagrad_reg_inc_gamma, fvargrad_reg_inc_gamma, fvar<fvar>grad_reg_lower_inc_gamma, doublegrad_reg_lower_inc_gamma, fvargrad_reg_lower_inc_gamma, fvar<fvar>grad_reg_inc_gamma, var, value + gradgrad_reg_lower_inc_gamma, var, value + gradThe
varinstantiation of the upper root is slower: Eigen's series and continued fraction take more operations than the 10-term asymptotic branch where that branch runs, and withvarevery operation is a tape node. Reverse-mode code in the library calls the roots withdoublevalues; only thefvar<var>path of the cdfs passesvar.Part 2: the derivatives of
gamma_qandgamma_p#2006 shows both problems at
(a, z) = (3, 36):gamma_qwithfvar<double>returns -6.7e+12 for a derivative of -11.5, andgamma_pwithvarreturns zero derivatives.The reverse-mode
gamma_pinrev/fun/gamma_p.hppreturned without derivatives whenz / a > 10, with the comment thatgamma_pis flat to machine precision there. Its derivatives there are small but not zero (about 1e-13 at(3, 36)), andlog1m(gamma_p(...)), the case of #2006, divides them by1 - P, so its whole gradient was lost. With the new roots the derivatives are accurate in that region, and this PR removes the short-cut from all three overloads.stan/math/fwd/fun/gamma_q.hppondevelopheld its own copy of the series ingrad_reg_inc_gamma, withwhile (fabs(delta) > 1e-6)and no iteration cap. Forzabove about 700 the alternating terms(-z)^k / k!overflow before they decay,deltastaysinf, and the loop never exits; a call ata = 0.168, z = 4 748did not return in 15 minutes. The asymptotic branch of the old root callsgamma_qwithfvararguments, sograd_reg_inc_gammareached the loop too. The existing mix test forgamma_qcarries a commented-out case with the note "this still fails forward mode", which is the same defect.This PR replaces the copy with a call to
grad_reg_inc_gamma, asfwd/fun/gamma_p.hppalready callsgrad_reg_lower_inc_gamma. It also evaluates the derivative with respect toz,-z^(a-1) e^(-z) / Γ(a), in log space; it was NaN at(a, z) = (200, 150)becausepowandtgammaoverflow.The copy had been hiding the defect. The generated third-order case in
test/prob/chi_squarecompares the analytic partials against autodiff throughlog(gamma_q(nu * 0.5, y * 0.5)). Both routes used the same inaccurate series, so the errors cancelled. With an accurate root and the stale copy, the case fails by 2.4e-03; with the copy removed, it passes.Part 3: the cdf functions in log space
What failed
gamma_lccdfcomputedlog Qin log space, but the shape derivative asdQ/dalpha / exp(log Q). That is NaN or 0 wherelog Q < -708, for example at(alpha, y) = (10, 1000)and(200, 1600)(NaN) and(150, 1200)(0). @mjcarter95 shows this region in the plot in this thread. The same plot shows thatgamma_lccdfinherits defects 1 and 2 of Part 1 foralpha + 1 < y <= 2 alpha. Withfvar<fvar<double>>andfvar<fvar<var>>, the second derivative with respect toalphawas exactly 0 at every point: the code seeded a copy ofalphaand kept only a plain number as the partial. Withfvar<var>, ashessian()uses it, the second derivative was NaN at the tested pointsalpha = 700and1e4.The other 17 functions had three defects, measured at 18 points
(a, z)of the incomplete gamma function against mpmath, with the roots of Part 1 already in place:log(gamma_p(...))orlog(gamma_q(...)). Where the probability is below 1e-308, the value is-infand the gradient NaN; where it is subnormal, the value has relative error 1.5e-4 and the gradient 0.1 to 1. Example:chi_square_lccdf(2000 | 20)is-inf; the true value is -950.6.yand scale partials overflows. 13 functions wrote it asexp(-z) pow(z, a - 1) / tgamma(a).tgammaoverflows above 171.6 andpowonce(a - 1) log z > 709, so the partial is NaN also in the bulk, for example theygradient ofchi_square_cdf,chi_square_lccdfandgamma_cdfat the median fornu = 400.The change
One internal function,
log_gamma_tail(a, z)inlog_gamma_q_dgamma.hpp, returnslog Porlog Qwith its derivatives with respect toaandz, all /in log space and generic in the scalar type:z > a + 1, the continued fraction giveslog Q, and with the derivative carried through the recurrence alsod/da log Q. It stops only when the value and the derivative have converged.log P = log1m_exp(log Q).gamma_pgivesP, andgrad_reg_lower_inc_gammaits derivative. WherePis belowDBL_MIN / EPSILON, a power series in log space giveslog Pand its derivative; it stops on a bound of the remaining terms.d/dzis the density divided by the probability,exp(log density - log prob).Each of the 18 functions keeps its argument checks and applies its own chain rule. The probability-scale
cdfsums the logs and partials and multiplies byexp(sum)at the end, so it has neither the density overflow nor the 0/0. A derivative that is differentiated again is computed in the autodiff type, so nested forward mode andhessian()get correct second derivatives.Two behavior changes at the edges of the support:
gamma_lcdfandchi_square_lcdfaty = inf, and thelccdfofchi_square,inv_gamma,inv_chi_squareandscaled_inv_chi_squareaty = 0, returned 0 for the whole vector when one element had probability 1, so the other elements were lost. Such an element now contributes 0.poisson_lccdfreturned 0 for the whole vector when one count was negative (Incorrect behaviour of CCDFs when there is a negative random variable #56). Such an element has probability 1 and now contributes 0.n = INT_MAXas an infinite count, asneg_binomial,beta_neg_binomialandyule_simonalready do. Before,poisson_lccdfreturned-infthere only becausegamma_punderflowed.Accuracy
At the 324 test points (the 18 functions at 18 points), no value or gradient is non-finite. The worst relative error is 2e-13 for values and 8e-13 for gradients, with one exception: the
nupartial ofscaled_inv_chi_squarenear the mode has a relative error up to 2.7e-10. Thereaandzboth grow withnu, and the two terms of the chain rule nearly cancel; the absolute error is of rounding size. Forgamma_lccdfin all autodiff modes, first derivatives are within 5.6e-12 and second derivatives within 1.9e-10 (7e-9 neary = alpha + 1atalpha = 5). On the grid of the plot by @mjcarter95, all 266 cells are finite and the worst relative error of the shape derivative is 3.4e-12.Speed
Value plus all gradients with
vararguments, ns per call, AMD EPYC 9965, g++ 11.5,-O3, medians of 4 alternating runs. Points witha = 5anda = 50andzfrom0.2 ato3 a, mapped to each function's arguments:develop, a = 5develop, a = 50gamma_cdfgamma_lcdfgamma_lccdfchi_square_cdfchi_square_lccdfinv_gamma_cdfinv_gamma_lcdfscaled_inv_chi_square_lcdfpoisson_lcdfMost of the gain comes from no longer calling
tgamma,powand a root withtgammaanddigammaper element.gamma_lccdfalone, shape derivative only, withalphafrom 5 to 1000 (ns per call):developvary > alpha + 1, normalQvarQunderflowsvary <= alpha + 1fvar<double>y > alpha + 1, normalQfvar<var>y > alpha + 1, normalQfvar<var>Qunderflowsfvar<var>y <= alpha + 1Where
Qunderflows,developreturns NaN or 0, so its time there is no baseline. One of the four runs of this PR was about 35 % slower in three rows of the cdf table; the medians do not depend on it.Testing
New tests, all with fixed references from mpmath;
expect_adcompares against finite differences and cannot see errors of this size:test/unit/math/prim/fun/grad_reg_inc_gamma_accuracy_test.cpp: the roots at the points of Part 1, references at 80 digits.ProbInternalMath.gradRegIncGamma_gradient_matches_hessian: the first derivative ofgamma_cdfis the same from reverse mode and fromhessian().gammaQ_fwd_shape_derivative_large_zandgammaQ_fwd_z_derivative_large_aintest/unit/math/mix/fun/gamma_q_test.cpp: the forward-modegamma_qderivatives. A test that hangs is not usable in CI, so the first one uses(a, z) = (1.5, 300), where the old series terminates but returns1.2e+112for a derivative of5.7e-129.test/unit/math/rev/prob/incomplete_gamma_cdfs_reference.hppwithincomplete_gamma_cdfs_reference_test.cpp: 324 rows, the value and gradient of the 18 functions at 18 points, at 60 digits by two routes (the incomplete gamma function with numerical differentiation, and a quadrature of the scaled density with the chain rule), which agree to 1e-25. Value to 1e-12, gradient to 1e-9 relative.test/unit/math/rev/prob/gamma_lccdf_tail_reference.hpp: 13 rows forgamma_lccdfwith second derivatives, used by avarcase inrev/prob/gamma_lccdf_test.cppand byfvar<double>,fvar<var>,fvar<fvar<double>>andfvar<fvar<var>>cases inmix/prob/gamma_lccdf_test.cpp.mix/prob/incomplete_gamma_cdfs_test.cppandmix/prob/inv_incomplete_gamma_cdfs_test.cpp:expect_adfor all 18 functions at two points each, one on each branch.gammaP_rev_far_upper_tailintest/unit/math/mix/fun/gamma_p_test.cpp: the reverse-mode derivatives ofgamma_p(3, 36)in all three overloads, and the gradient oflog1m(gamma_p(alpha, beta * y))from gamma_p and gamma_q gradient problems #2006.lccdf_negative_count_contributes_zerointest/unit/math/prim/prob/poisson_ccdf_log_test.cpp: the example of Incorrect behaviour of CCDFs when there is a negative random variable #56.Changed tests:
test/unit/math/mix/fun/grad_reg_inc_gamma_test.cppexpected 0.38984156 ford/da Q(0.5, 1.0); the true value is 0.38983726432851057. The old constants combined the roundedg = 1.77245that the test passes in and the 1e-6 series truncation. The two second- and third-derivative cases of that file were not changed and still pass.lccdf_log1m_exp_lcdf_rounds_to_inf(prim and rev) asserted thatgamma_lcdf(20000 | 800, 0.1)rounds to exactly 0.gamma_lcdfnow returns its true value, about -1e-204, so the case checks thatlog1m_exp(gamma_lcdf)equalsgamma_lccdfthere, and is renamed tolccdf_far_tail_matches_log1m_exp_lcdf.The new tests fail without the changes. I installed the old headers, kept the new tests, and restored afterwards; the header checksums after the restore equal those before:
gamma_qofdevelopgamma_lccdfbefore its commitsvarcases fails (8 rows); both mix cases fail (162 expectations)rev/fun/gamma_p.hppandpoisson_lccdfbefore their commitgammaP_rev_far_upper_tailfails 7 expectations (all three overloads and the case of #2006);lccdf_negative_count_contributes_zerofails both vector cases of #56The existing unit suites of the roots,
gamma_p,gamma_qand all 18 functions pass, and so do the 90 generatedtest/probcdf programs of the six families. The existinggrad_reg_lower_inc_gamma_testchecks 9 600 values from Mathematica with a 1e-10 absolute tolerance; Eigen satisfies all of them, but that grid (aup to 19.75,zup to 29.75) contains no point of defect 3. Tested ondevelopate50e79f188with this PR applied, with g++ 11.5 and g++ 14.3.Dependency on Eigen
The two new headers specialize
lgamma_impl,digamma_implandcephes_helperinsideEigen::internal. Stan Math already specializes inside that namespace, instan/math/rev/core/Eigen_NumTraits.hpp. An Eigen upgrade that renames those three helpers breaks the build; that failure is immediate, and the alternative was to copy about 300 lines of the Cephes algorithm into Stan Math. The headers belong to thefunlayer, notcore, because they needdigammaandlgamma; incorethey break the include order of every mix target.Not included
OpenCL is unaffected: no OpenCL code calls these functions, and the six families have OpenCL implementations only for their
lpdforlpmf.The incomplete beta gradient roots have their own defects; they are in #3409.
#2769 asks for log-scale incomplete gamma functions, because
gamma_lcdflost resolution at the boundaries. This PR computeslog Pandlog Qin log space inside the library (internal::log_gamma_tail), which meets that motivation for the cdfs, but it adds no public function such aslog_gamma_porlog_gamma_q.Other discrete cdfs have the defect of #56: one element with probability 1 decides the result for the whole vector.
bernoulli_lccdf,binomial_lccdf,beta_binomial_lccdf,neg_binomial_lccdf(and soneg_binomial_2_lccdf),beta_neg_binomial_lccdfandyule_simon_lccdfreturn 0 when one count is below the support;neg_binomial_lcdf,beta_neg_binomial_lcdfandyule_simon_lcdfreturn 0, andneg_binomial_cdf,neg_binomial_2_cdf,beta_neg_binomial_cdfandyule_simon_cdfreturn 1, when one count isINT_MAX. Most of these files are changed by other open PRs, so the repair is left for a separate PR.The missing
poisson_log_cdf,poisson_log_lcdfandpoisson_log_lccdf(#90, #2657) are now short wrappers of the same log-space function,log Q(n + 1, exp(eta)); they need new signatures in stanc3 and are left for a separate PR.g,dig,precisionandmax_stepsof the roots are now unused. Removing them changes the remaining call sites (gamma_qinrevandfwd, andlog_gamma_q_dgamma) and the public signature, so it is left for a separate PR.log_gamma_q_dgammaitself is no longer called by the library and is kept for compatibility.Release notes
Use Eigen's
igamma_der_afor the incomplete gamma gradient roots, and compute the cdf, lcdf and lccdf of chi_square, gamma, inv_chi_square, inv_gamma, scaled_inv_chi_square and poisson in log space, so that their values and gradients stay finite in the tails and for large shapes.Checklist
Copyright holder: Aalto University
The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
- Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
the basic tests are passing
./runTests.py test/unit)make test-headers)make test-math-dependencies)make doxygen)make cpplint)the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested