Skip to content

Commit

Permalink
Replace custom incomplete_beta with aesara.tensor.betainc
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardoV94 committed Jul 12, 2021
1 parent a3ee747 commit 49cda54
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 220 deletions.
4 changes: 3 additions & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- The `Distribution` keyword argument `testval` has been deprecated in favor of `initval`.
- `pm.sample` now returns results as `InferenceData` instead of `MultiTrace` by default (see [#4744](https://github.com/pymc-devs/pymc3/pull/4744)).
- `pm.sample_prior_predictive` no longer returns transformed variable values by default. Pass them by name in `var_names` if you want to obtain these draws (see [4769](https://github.com/pymc-devs/pymc3/pull/4769)).
...
- ...

### New Features
- The `CAR` distribution has been added to allow for use of conditional autoregressions which often are used in spatial and network models.
Expand All @@ -20,12 +20,14 @@
- Add `logcdf` method to Kumaraswamy distribution (see [#4706](https://github.com/pymc-devs/pymc3/pull/4706)).
- The `OrderedMultinomial` distribution has been added for use on ordinal data which are _aggregated_ by trial, like multinomial observations, whereas `OrderedLogistic` only accepts ordinal data in a _disaggregated_ format, like categorical
observations (see [#4773](https://github.com/pymc-devs/pymc3/pull/4773)).
- ...

### Maintenance
- Remove float128 dtype support (see [#4514](https://github.com/pymc-devs/pymc3/pull/4514)).
- Logp method of `Uniform` and `DiscreteUniform` no longer depends on `pymc3.distributions.dist_math.bound` for proper evaluation (see [#4541](https://github.com/pymc-devs/pymc3/pull/4541)).
- `Model.RV_dims` and `Model.coords` are now read-only properties. To modify the `coords` dictionary use `Model.add_coord`. Also `dims` or coordinate values that are `None` will be auto-completed (see [#4625](https://github.com/pymc-devs/pymc3/pull/4625)).
- The length of `dims` in the model is now tracked symbolically through `Model.dim_lengths` (see [#4625](https://github.com/pymc-devs/pymc3/pull/4625)).
- The `incomplete_beta` function in `pymc3.distributions.dist_math` was replaced by `aesara.tensor.betainc` (see [4736](https://github.com/pymc-devs/pymc3/pull/4857)).
- ...

## PyMC3 3.11.2 (14 March 2021)
Expand Down
26 changes: 8 additions & 18 deletions pymc3/distributions/continuous.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
bound,
clipped_beta_rvs,
i0e,
incomplete_beta,
log_i0,
log_normal,
logpow,
Expand Down Expand Up @@ -1246,23 +1245,19 @@ def logcdf(value, alpha, beta):
Parameters
----------
value: numeric
Value(s) for which log CDF is calculated.
value: numeric or np.ndarray or aesara.tensor
Value(s) for which log CDF is calculated. If the log CDF for multiple
values are desired the values must be provided in a numpy array or Aesara tensor.
Returns
-------
TensorVariable
"""
# incomplete_beta function can only handle scalar values (see #4342)
if np.ndim(value):
raise TypeError(
f"Beta.logcdf expects a scalar value but received a {np.ndim(value)}-dimensional object."
)

return bound(
at.switch(
at.lt(value, 1),
at.log(incomplete_beta(alpha, beta, value)),
at.log(at.betainc(alpha, beta, value)),
0,
),
0 <= value,
Expand Down Expand Up @@ -1915,27 +1910,22 @@ def logcdf(value, nu, mu, sigma):
Parameters
----------
value: numeric
Value(s) for which log CDF is calculated.
value: numeric or np.ndarray or aesara.tensor
Value(s) for which log CDF is calculated. If the log CDF for multiple
values are desired the values must be provided in a numpy array or Aesara tensor.
Returns
-------
TensorVariable
"""
# incomplete_beta function can only handle scalar values (see #4342)
if np.ndim(value):
raise TypeError(
f"StudentT.logcdf expects a scalar value but received a {np.ndim(value)}-dimensional object."
)

lam, sigma = get_tau_sigma(sigma=sigma)

t = (value - mu) / sigma
sqrt_t2_nu = at.sqrt(t ** 2 + nu)
x = (t + sqrt_t2_nu) / (2.0 * sqrt_t2_nu)

return bound(
at.log(incomplete_beta(nu / 2.0, nu / 2.0, x)),
at.log(at.betainc(nu / 2.0, nu / 2.0, x)),
0 < nu,
0 < sigma,
0 < lam,
Expand Down
49 changes: 14 additions & 35 deletions pymc3/distributions/discrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
binomln,
bound,
factln,
incomplete_beta,
log_diff_normal_cdf,
logpow,
normal_lccdf,
Expand Down Expand Up @@ -145,25 +144,20 @@ def logcdf(value, n, p):
Parameters
----------
value: numeric
Value for which log CDF is calculated.
value: numeric or np.ndarray or aesara.tensor
Value(s) for which log CDF is calculated. If the log CDF for multiple
values are desired the values must be provided in a numpy array or Aesara tensor.
Returns
-------
TensorVariable
"""
# incomplete_beta function can only handle scalar values (see #4342)
if np.ndim(value):
raise TypeError(
f"Binomial.logcdf expects a scalar value but received a {np.ndim(value)}-dimensional object."
)

value = at.floor(value)

return bound(
at.switch(
at.lt(value, n),
at.log(incomplete_beta(n - value, value + 1, 1 - p)),
at.log(at.betainc(n - value, value + 1, 1 - p)),
0,
),
0 <= value,
Expand Down Expand Up @@ -732,21 +726,16 @@ def logcdf(value, n, p):
Parameters
----------
value: numeric
Value for which log CDF is calculated.
value: numeric or np.ndarray or aesara.tensor
Value(s) for which log CDF is calculated. If the log CDF for multiple
values are desired the values must be provided in a numpy array or Aesara tensor.
Returns
-------
TensorVariable
"""
# incomplete_beta function can only handle scalar values (see #4342)
if np.ndim(value):
raise TypeError(
f"NegativeBinomial.logcdf expects a scalar value but received a {np.ndim(value)}-dimensional object."
)

return bound(
at.log(incomplete_beta(n, at.floor(value) + 1, p)),
at.log(at.betainc(n, at.floor(value) + 1, p)),
0 <= value,
0 < n,
0 <= p,
Expand Down Expand Up @@ -1461,20 +1450,15 @@ def logcdf(value, psi, n, p):
Parameters
----------
value: numeric
Value for which log CDF is calculated.
value: numeric or np.ndarray or aesara.tensor
Value(s) for which log CDF is calculated. If the log CDF for multiple
values are desired the values must be provided in a numpy array or Aesara tensor.
Returns
-------
TensorVariable
"""

# logcdf can only handle scalar values due to limitation in Binomial.logcdf
if np.ndim(value):
raise TypeError(
f"ZeroInflatedBinomial.logcdf expects a scalar value but received a {np.ndim(value)}-dimensional object."
)

return bound(
logaddexp(at.log1p(-psi), at.log(psi) + _logcdf(binomial, value, {}, n, p)),
0 <= value,
Expand Down Expand Up @@ -1616,19 +1600,14 @@ def logcdf(value, psi, n, p):
Parameters
----------
value: numeric
Value for which log CDF is calculated.
value: numeric or np.ndarray or aesara.tensor
Value(s) for which log CDF is calculated. If the log CDF for multiple
values are desired the values must be provided in a numpy array or Aesara tensor.
Returns
-------
TensorVariable
"""
# logcdf can only handle scalar values due to limitation in NegativeBinomial.logcdf
if np.ndim(value):
raise TypeError(
f"ZeroInflatedNegativeBinomial.logcdf expects a scalar value but received a {np.ndim(value)}-dimensional object."
)

return bound(
logaddexp(at.log1p(-psi), at.log(psi) + _logcdf(nbinom, value, {}, n, p)),
0 <= value,
Expand Down
Loading

0 comments on commit 49cda54

Please sign in to comment.