You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/contributing/implementing_distribution.md
+20-20Lines changed: 20 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ This guide provides an overview on how to implement a distribution for PyMC.
5
5
It is designed for developers who wish to add a new distribution to the library.
6
6
Users will not be aware of all this complexity and should instead make use of helper methods such as `~pymc.CustomDist`.
7
7
8
-
PyMC {class}`~pymc.Distribution` builds on top of PyTensor's {class}`~pytensor.tensor.random.op.RandomVariable`, and implements `logp`, `logcdf`, `icdf` and `moment` methods as well as other initialization and validation helpers.
8
+
PyMC {class}`~pymc.Distribution` builds on top of PyTensor's {class}`~pytensor.tensor.random.op.RandomVariable`, and implements `logp`, `logcdf`, `icdf` and `support_point` methods as well as other initialization and validation helpers.
9
9
Most notably `shape/dims/observed` kwargs, alternative parametrizations, and default `transform`.
10
10
11
11
Here is a summary check-list of the steps needed to implement a new distribution.
@@ -14,7 +14,7 @@ Each section will be expanded below:
14
14
1. Creating a new `RandomVariable``Op`
15
15
1. Implementing the corresponding `Distribution` class
16
16
1. Adding tests for the new `RandomVariable`
17
-
1. Adding tests for `logp` / `logcdf` / `icdf` and `moment` methods
17
+
1. Adding tests for `logp` / `logcdf` / `icdf` and `support_point` methods
18
18
1. Documenting the new `Distribution`.
19
19
20
20
This guide does not attempt to explain the rationale behind the `Distributions` current implementation, and details are provided only insofar as they help to implement new "standard" distributions.
@@ -120,7 +120,7 @@ After implementing the new `RandomVariable` `Op`, it's time to make use of it in
120
120
PyMC works in a very {term}`functional <Functional Programming>` way, and the `distribution` classes are there mostly to add PyMC API features and keep related methods organized together.
121
121
In practice, they take care of:
122
122
123
-
1. Linking ({term}`Dispatching`) an `rv_op` class with the corresponding `moment`, `logp`, `logcdf` and `icdf` methods.
123
+
1. Linking ({term}`Dispatching`) an `rv_op` class with the corresponding `support_point`, `logp`, `logcdf` and `icdf` methods.
124
124
1. Defining a standard transformation (for continuous distributions) that converts a bounded variable domain (e.g., positive line) to an unbounded domain (i.e., the real line), which many samplers prefer.
125
125
1. Validating the parametrization of a distribution and converting non-symbolic inputs (i.e., numeric literals or NumPy arrays) to symbolic variables.
126
126
1. Converting multiple alternative parametrizations to the standard parametrization that the `RandomVariable` is defined in terms of.
@@ -156,14 +156,14 @@ class Blah(PositiveContinuous):
156
156
# the rv_op needs in order to be instantiated
157
157
returnsuper().dist([param1, param2], **kwargs)
158
158
159
-
#moment returns a symbolic expression for the stable moment from which to start sampling
159
+
#support_point returns a symbolic expression for the stable point from which to start sampling
160
160
# the variable, given the implicit `rv`, `size` and `param1` ... `paramN`.
161
161
# This is typically a "representative" point such as the the mean or mode.
# Logp returns a symbolic expression for the elementwise log-pdf or log-pmf evaluation
169
169
# of the variable given the `value` of the variable and the parameters `param1` ... `paramN`.
@@ -200,18 +200,18 @@ class Blah(PositiveContinuous):
200
200
Some notes:
201
201
202
202
1. A distribution should at the very least inherit from {class}`~pymc.Discrete` or {class}`~pymc.Continuous`. For the latter, more specific subclasses exist: `PositiveContinuous`, `UnitContinuous`, `BoundedContinuous`, `CircularContinuous`, `SimplexContinuous`, which specify default transformations for the variables. If you need to specify a one-time custom transform you can also create a `_default_transform` dispatch function as is done for the {class}`~pymc.distributions.multivariate.LKJCholeskyCov`.
203
-
1. If a distribution does not have a corresponding `rng_fn` implementation, a `RandomVariable` should still be created to raise a `NotImplementedError`. This is, for example, the case in {class}`~pymc.distributions.continuous.Flat`. In this case it will be necessary to provide a `moment` method, because without a `rng_fn`, PyMC can't fall back to a random draw to use as an initial point for MCMC.
204
-
1. As mentioned above, PyMC works in a very {term}`functional <Functional Programming>` way, and all the information that is needed in the `logp`, `logcdf`, `icdf` and `moment` methods is expected to be "carried" via the `RandomVariable` inputs. You may pass numerical arguments that are not strictly needed for the `rng_fn` method but are used in the those methods. Just keep in mind whether this affects the correct shape inference behavior of the `RandomVariable`.
203
+
1. If a distribution does not have a corresponding `rng_fn` implementation, a `RandomVariable` should still be created to raise a `NotImplementedError`. This is, for example, the case in {class}`~pymc.distributions.continuous.Flat`. In this case it will be necessary to provide a `support_point` method, because without a `rng_fn`, PyMC can't fall back to a random draw to use as an initial point for MCMC.
204
+
1. As mentioned above, PyMC works in a very {term}`functional <Functional Programming>` way, and all the information that is needed in the `logp`, `logcdf`, `icdf` and `support_point` methods is expected to be "carried" via the `RandomVariable` inputs. You may pass numerical arguments that are not strictly needed for the `rng_fn` method but are used in the those methods. Just keep in mind whether this affects the correct shape inference behavior of the `RandomVariable`.
205
205
1. The `logcdf`, and `icdf` methods is not a requirement, but it's a nice plus!
206
-
1. Currently, only one moment is supported in the `moment` method, and probably the "higher-order" one is the most useful (that is `mean` > `median` > `mode`)... You might need to truncate the moment if you are dealing with a discrete distribution. `moment` should return a valid point for the random variable (i.e., it always has non-zero probability when evaluated at that point)
207
-
1. When creating the `moment` method, be careful with `size != None` and broadcast properly also based on parameters that are not necessarily used to calculate the moment. For example, the `sigma` in `pm.Normal.dist(mu=0, sigma=np.arange(1, 6))` is irrelevant for the moment, but may nevertheless inform about the shape. In this case, the `moment` should return `[mu, mu, mu, mu, mu]`.
206
+
1. Currently, only one moment is supported in the `support_point` method, and probably the "higher-order" one is the most useful (that is `mean` > `median` > `mode`)... You might need to truncate the moment if you are dealing with a discrete distribution. `support_point` should return a valid point for the random variable (i.e., it always has non-zero probability when evaluated at that point)
207
+
1. When creating the `support_point` method, be careful with `size != None` and broadcast properly also based on parameters that are not necessarily used to calculate the moment. For example, the `sigma` in `pm.Normal.dist(mu=0, sigma=np.arange(1, 6))` is irrelevant for the moment, but may nevertheless inform about the shape. In this case, the `support_point` should return `[mu, mu, mu, mu, mu]`.
208
208
209
209
For a quick check that things are working you can try the following:
210
210
211
211
```python
212
212
213
213
import pymc as pm
214
-
from pymc.distributions.distribution importmoment
214
+
from pymc.distributions.distribution importsupport_point
0 commit comments