Skip to content

Commit 1ad526a

Browse files
committed
MAINT Add back bound_elemwise. Port DiscreteUniform and Uniform to use it.
1 parent 7584b3b commit 1ad526a

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

pymc3/distributions/continuous.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import warnings
1414

1515
from . import transforms
16-
from .dist_math import bound, logpow, gammaln, betaln, std_cdf, i0, i1
16+
from .dist_math import bound, bound_elemwise, logpow, gammaln, betaln, std_cdf, i0, i1
1717
from .distribution import Continuous, draw_values, generate_samples
1818

1919
__all__ = ['Uniform', 'Flat', 'Normal', 'Beta', 'Exponential', 'Laplace',
@@ -146,8 +146,8 @@ def random(self, point=None, size=None, repeat=None):
146146
def logp(self, value):
147147
lower = self.lower
148148
upper = self.upper
149-
return bound(-tt.log(upper - lower),
150-
value >= lower, value <= upper)
149+
return bound_elemwise(-tt.log(upper - lower),
150+
value >= lower, value <= upper)
151151

152152

153153
class Flat(Continuous):

pymc3/distributions/discrete.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import theano.tensor as tt
66
from scipy import stats
77

8-
from .dist_math import bound, factln, binomln, betaln, logpow
8+
from .dist_math import bound, bound_elemwise, factln, binomln, betaln, logpow
99
from .distribution import Discrete, draw_values, generate_samples
1010

1111
__all__ = ['Binomial', 'BetaBinomial', 'Bernoulli', 'Poisson',
@@ -348,8 +348,8 @@ def random(self, point=None, size=None, repeat=None):
348348
def logp(self, value):
349349
upper = self.upper
350350
lower = self.lower
351-
return bound(-tt.log(upper - lower + 1),
352-
lower <= value, value <= upper)
351+
return bound_elemwise(-tt.log(upper - lower + 1) * tt.ones_like(value),
352+
lower <= value, value <= upper)
353353

354354

355355
class Categorical(Discrete):
@@ -454,7 +454,7 @@ class ZeroInflatedPoisson(Discrete):
454454
Often used to model the number of events occurring in a fixed period
455455
of time when the times at which events occur are independent.
456456
457-
.. math::
457+
.. math::
458458
459459
f(x \mid \theta, \psi) = \left\{ \begin{array}{l}
460460
(1-\psi) + \psi e^{-\theta}, \text{if } x = 0 \\
@@ -503,7 +503,7 @@ class ZeroInflatedNegativeBinomial(Discrete):
503503
504504
The Zero-inflated version of the Negative Binomial (NB).
505505
The NB distribution describes a Poisson random variable
506-
whose rate parameter is gamma distributed.
506+
whose rate parameter is gamma distributed.
507507
508508
.. math::
509509

pymc3/distributions/dist_math.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,32 @@
1111
from .special import gammaln, multigammaln
1212

1313

14+
def bound_elemwise(logp, *conditions):
15+
"""
16+
Bounds a log probability density with several conditions.
17+
18+
Respects shape of logp and performs broadcasting when
19+
conditions.shape > logp.shape.
20+
21+
Parameters
22+
----------
23+
logp : float
24+
*conditions : booleans
25+
26+
Returns
27+
-------
28+
logp with elements set to -inf where any condition is False
29+
"""
30+
return tt.switch(alltrue_elemwise(conditions), logp, -np.inf)
31+
32+
33+
def alltrue_elemwise(vals):
34+
ret = 1
35+
for c in vals:
36+
ret = ret * (1 * c)
37+
return ret
38+
39+
1440
def bound(logp, *conditions):
1541
"""
1642
Bounds a log probability density with several conditions
@@ -27,7 +53,6 @@ def bound(logp, *conditions):
2753
"""
2854
return tt.switch(alltrue(conditions), logp, -np.inf)
2955

30-
3156
def alltrue(vals):
3257
return tt.all([tt.all(1 * val) for val in vals])
3358

0 commit comments

Comments
 (0)