Repository navigation
Conversation
avehtari
marked this pull request as draft
October 22, 2026 06:46
9 tasks done
SteveBronder
added this pull request to stack #3478
October 22, 2026 20:33
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
poisson_logcdfs, so that apoisson_loglikelihood can be truncated (is this the record for the oldest issue to be closed?).cdf/lcdf/lccdffunctions for distributions #2657 (thepoisson_logentry of its list).This PR depends on #3408, which adds the internal function that it uses.
An earlier attempt, #471 (2016), computed
poisson_cdf(n, exp(alpha))and was closed by its author before review.This PR was Claude assisted
Summary
poisson_loghad onlylpmfandrng. Withoutlcdfandlccdf, Stan cannot truncate it, and users who model with the log rate had to writepoisson_lcdf(n | exp(alpha)), which loses digits and gradients whenexp(alpha)is large or small. This PR adds the three functions:poisson_log_lcdf(n | alpha) = log Q(n + 1, exp(alpha))poisson_log_lccdf(n | alpha) = log P(n + 1, exp(alpha))poisson_log_cdf(n | alpha) = Q(n + 1, exp(alpha))Here
PandQare the regularized lower and upper incomplete gamma functions. Each function evaluateslog Porlog Qwithinternal::log_gamma_tailfrom #3408, which works in log space, so the value and the gradient stay finite where the probability underflows. The derivative with respect toalphais the derivative with respect to the rate timesexp(alpha). The probability-scalecdfsums the logs and multiplies byexp(sum)at the end, as the other cdfs in #3408 do.The argument checks follow
poisson_log_lpmf:alphamust not be NaN, andalpha = -infandalpha = +infare allowed.Values at the edges of the support, element by element (an element with probability 0 makes the whole result
-infor 0; an element with probability 1 contributes nothing):lcdflccdfcdfn < 0-infn = INT_MAX(an infinite count, as inneg_binomial)-infexp(alpha) = 0(alpha = -inf, or below about -745)-infexp(alpha) = inf(alpha = +inf, or above about 709.8)-infAccuracy
Against mpmath at 60 digits at 54 points (the three functions at 18 points
(n + 1, exp(alpha))of the incomplete gamma function, from the deep lower tail to the deep upper tail and with counts up to 999), computed by two routes that agree to 1e-25: the worst relative error is 1.1e-12 for values and 1.5e-12 for gradients. Most of the value error comes from the rounding ofexp(alpha): near the mean of a large count the value changes by thousands of times the relative change of the rate. The functions agree withpoisson_*(n, exp(alpha))to all printed digits, also infvar<fvar<double>>.Testing
test/unit/math/rev/prob/poisson_log_cdfs_reference.hppandpoisson_log_cdfs_test.cpp: the 54 reference rows withvar(value to 1e-11, gradient to 1e-9 relative).test/unit/math/prim/prob/poisson_log_cdfs_test.cpp: agreement withpoisson_lcdf,poisson_lccdfandpoisson_cdfatexp(alpha)for vectors, the edge values of the table above, and the NaN check.test/unit/math/mix/prob/poisson_log_cdfs_test.cpp:expect_adfor the three functions at two points each.test/prob/poisson/poisson_log_{cdf,cdf_log,ccdf_log}_test.hpp: the generated distribution tests, with the points of thepoissoncdf tests atalpha = log(lambda). In theccdf_logtest the pointn = 82, lambda = 42is replaced byn = 40: the test's reference function computeslog(1 - cdf), which keeps only about 8 digits where the ccdf is 1.5e-8, and its third derivative then differed from the exact value by more than the test tolerance (this PR agrees with mpmath there to 11 digits).The new and existing
poissonunit suites pass, and all 18 generatedtest/prob/poissoncdf programs pass. Header checks,make test-math-dependencies, cpplint and clang-format 10 pass, andmake doxygenwith doxygen 1.9.7 gives 0 warnings. Tested ondevelopate50e79f188with #3408 applied, g++ 11.5.The stanc3 PR stan-dev/stanc3#TBD adds the signatures.
Release notes
Add
poisson_log_cdf,poisson_log_lcdfandpoisson_log_lccdf.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