pymc icon indicating copy to clipboard operation
pymc copied to clipboard

Correct derivation for CDF of monotonically decreasing transforms of discrete variables

Open ricardoV94 opened this issue 2 years ago • 0 comments

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

ricardoV94 avatar Nov 02 '23 09:11 ricardoV94