Before
# LogNormal currently falls back to the generic helper:
# logccdf(dist, value) internally computes log1mexp(logcdf(dist, value))
import pymc as pm
from pymc.logprob.basic import logccdf
dist = pm.LogNormal.dist(mu=0, sigma=1)
logccdf(dist, 2.0) # goes through _logccdf_helper -> log1mexp(normal_lcdf(...))
After
# LogNormal uses direct closed-form log survival function:
# normal_lccdf(mu, sigma, log(t))
import pymc as pm
from pymc.logprob.basic import logccdf
dist = pm.LogNormal.dist(mu=0, sigma=1)
logccdf(dist, 2.0) # directly calls normal_lccdf(mu, sigma, log(t))
Context for the issue:
LogNormal currently falls back to the generic _logccdf_helper which computes log1mexp(logcdf). While log1mexp is numerically stable (Mächler two-branch formula), LogNormal has a direct closed-form log survival function:
log S(t) = normal_lccdf(mu, sigma, log(t))
This reuses the existing normal_lccdf from dist_math.py, consistent with how Normal.logccdf already works. It is a genuinely different function call, not just the logcdf intermediate minus a log1mexp wrapper.
Context
Refer to the related discussion on Discourse:
https://discourse.pymc.io/t/consider-adding-numerically-stable-logccdf-log-survival-function-to-exponential-weibull-and-other-distro/17603
The log-likelihood for survival models with right-censored observations includes a log S(t_i) term for every censored observation. pymc/logprob/censoring.py calls _logccdf_helper for this.
Before
After
Context for the issue:
LogNormal currently falls back to the generic
_logccdf_helperwhich computeslog1mexp(logcdf). Whilelog1mexpis numerically stable (Mächler two-branch formula), LogNormal has a direct closed-form log survival function:log S(t) = normal_lccdf(mu, sigma, log(t))This reuses the existing
normal_lccdffromdist_math.py, consistent with howNormal.logccdfalready works. It is a genuinely different function call, not just thelogcdfintermediate minus alog1mexpwrapper.Context
Refer to the related discussion on Discourse:
https://discourse.pymc.io/t/consider-adding-numerically-stable-logccdf-log-survival-function-to-exponential-weibull-and-other-distro/17603
The log-likelihood for survival models with right-censored observations includes a
log S(t_i)term for every censored observation.pymc/logprob/censoring.pycalls_logccdf_helperfor this.