pymc
pymc copied to clipboard
Correct derivation for CDF of monotonically decreasing transforms of discrete variables
This is not an issue yet, because transforms of discrete variables aren't supported, but would be after we start allowing them (e.g., in #6836 and after https://github.com/pymc-devs/pymc/issues/6360)
import pymc as pm
import numpy as np
p = 0.7
rv = -pm.Bernoulli.dist(p=p)
# A negated Bernoulli has pmf {p if x == -1; 1-p if x == 0; 0 otherwise}
assert pm.logp(rv, -2).eval() == -np.inf # Correct
assert pm.logp(rv, -1).eval() == np.log(p) # Correct
assert pm.logp(rv, 0).eval() == np.log(1-p) # Correct
assert pm.logp(rv, 1).eval() == -np.inf # Correct
The logic here works correctly for continuous variables, but for discrete variables we need the survival function (logccdf) evaluated at backward_value-1 and not backward_value. Otherwise the following checks would fail:
assert pm.logcdf(rv, -2).eval() == -np.inf # Correct
assert pm.logcdf(rv, -1).eval() == np.log(p) # Incorrect
assert pm.logcdf(rv, 0).eval() == 0 # Incorrect
assert pm.logcdf(rv, 1).eval() == 0 # Correct
https://github.com/pymc-devs/pymc/blob/f5c5c9c637303a45afd184efb3c636a9053acd21/pymc/logprob/transforms.py#L466-L499
Some care must also be taken for the negative odd powers
Likewise, the logic may be wrong for icdf, but I haven't checked:
https://github.com/pymc-devs/pymc/blob/f5c5c9c637303a45afd184efb3c636a9053acd21/pymc/logprob/transforms.py#L510-L522