Skip to content

Commit fbf5cb9

Browse files
bwengalsJunpeng Lao
authored and
Junpeng Lao
committed
Adds documentation for Bound'ed variables (#2391)
* add doc for bounded variables * adds Usage, Caveats sections, fixes in response to comments * remove example definition of boundeddist from outside context * clarification of vector * moved to source/api/ and added to api.rst
1 parent df15a62 commit fbf5cb9

File tree

3 files changed

+63
-8
lines changed

3 files changed

+63
-8
lines changed

docs/source/api.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ API Reference
88
:maxdepth: 2
99

1010
api/distributions
11+
api/bounds
1112
api/inference
1213
api/glm
1314
api/gp
@@ -16,4 +17,4 @@ API Reference
1617
api/diagnostics
1718
api/backends
1819
api/math
19-
api/data
20+
api/data

docs/source/api/bounds.rst

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=================
2+
Bounded Variables
3+
=================
4+
5+
PyMC3 includes the construct ``Bound`` for placing constraints on existing
6+
probability distributions. It modifies a given distribution to take values
7+
only within a specified interval.
8+
9+
Some types of variables require constraints. For instance, it doesn't make
10+
sense for a standard deviation to have a negative value, so something like a
11+
Normal prior on a parameter that represents a standard deviation would be
12+
inappropriate. PyMC3 includes distributions that have positive support, such
13+
as ``Gamma`` or ``Exponential``. PyMC3 also includes several bounded
14+
distributions, such as ``Uniform``, ``HalfNormal``, and ``HalfCauchy``, that
15+
are restricted to a specific domain.
16+
17+
All univariate distributions in PyMC3 can be given bounds. The distribution of
18+
a continuous variable that has been bounded is automatically transformed into
19+
an unnormalized distribution whose domain is unconstrained. The transformation
20+
improves the efficiency of sampling and variational inference algorithms.
21+
22+
Usage
23+
#####
24+
25+
For example, one may have prior information that suggests that the value of a
26+
parameter representing a standard deviation is near one. One could use a
27+
Normal distribution while constraining the support to be positive. The
28+
specification of a bounded distribution should go within the model block::
29+
30+
import pymc3 as pm
31+
32+
with pm.Model() as model:
33+
BoundedNormal = pm.Bound(pm.Normal, lower=0.0)
34+
x = BoundedNormal('x', mu=1.0, sd=3.0)
35+
36+
If the bound will be applied to a single variable in the model, it may be
37+
cleaner notationally to define both the bound and variable together. ::
38+
39+
with model:
40+
x = pm.Bound(pm.Normal, lower=0.0)('x', mu=1.0, sd=3.0)
41+
42+
Bounds can also be applied to a vector of random variables. With the same
43+
``BoundedNormal`` object we created previously we can write::
44+
45+
with model:
46+
x_vector = BoundedNormal('x_vector', mu=1.0, sd=3.0, shape=3)
47+
48+
Caveats
49+
#######
50+
51+
* Bounds cannot be given to variables that are ``observed``. To model
52+
truncated data, use a ``Potential`` in combination with a cumulative
53+
probability function. See `this example <https://github.com/pymc-devs/pymc3/blob/master/pymc3/examples/censored_data.py>`_.
54+
55+
* The automatic transformation applied to continuous distributions results in
56+
an unnormalized probability distribution. This doesn't effect inference
57+
algorithms but may complicate some model comparison procedures.
58+

pymc3/distributions/bound.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,13 @@ class Bound(object):
176176
177177
Example
178178
-------
179-
# Bounded distribution can be defined before the model context
180-
PositiveNormal = pm.Bound(pm.Normal, lower=0.0)
181179
with pm.Model():
182-
par1 = PositiveNormal('par1', mu=0.0, sd=1.0, testval=1.0)
183-
# or within the model context
184180
NegativeNormal = pm.Bound(pm.Normal, upper=0.0)
185-
par2 = NegativeNormal('par2', mu=0.0, sd=1.0, testval=1.0)
181+
par1 = NegativeNormal('par2', mu=0.0, sd=1.0, testval=1.0)
186182
187183
# or you can define it implicitly within the model context
188-
par3 = pm.Bound(pm.Normal, lower=-1.0, upper=1.0)(
189-
'par3', mu=0.0, sd=1.0, testval=1.0)
184+
par2 = pm.Bound(pm.Normal, lower=-1.0, upper=1.0)(
185+
'par2', mu=0.0, sd=1.0, testval=1.0)
190186
"""
191187

192188
def __init__(self, distribution, lower=None, upper=None):

0 commit comments

Comments
 (0)