Numerically stable logarithm of the standard normal CDF.
Computes without losing precision in the deep
left tail, where the direct composition log(ndtr(x)) underflows.
Essential for log-likelihood evaluation of probit / Tobit / censored
models that need to handle cleanly.
Parameters
Returns
Tensor element-wise, same shape and dtype as
x; values lie in .
Notes
The implementation has three branches; with in the lower tail and in the upper one,
Between the cuts , so the
direct log(ndtr(x)) is safe. Below the identity
is used: erfc(t)
itself underflows to zero near in float32 (and loses
its relative precision well before that), while erfcx stays
bounded and the Gaussian factor comes out exactly as .
The upper tail fails the other way round. There
with small, and
forming first leaves to rounding: float32
answered -2.98e-7 at for -2.867e-7, and 0
from on. Computing
directly and
taking log1p of its negative keeps the relative precision until
itself underflows.
Examples
>>> import lucid
>>> from lucid.special import log_ndtr
>>> log_ndtr(lucid.tensor([-10.0, -1.0, 0.0, 1.0]))
tensor([-53.23, -1.841, -0.6931, -0.1728])