Skip to content

Commit 63e5d16

Browse files
committed
Merge branch 'main' into gpv4update
2 parents 196e702 + 310a6b9 commit 63e5d16

40 files changed

+1031
-403
lines changed

.github/workflows/pytest.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ jobs:
155155
- |
156156
pymc/tests/test_initial_point.py
157157
pymc/tests/test_distributions_random.py
158+
pymc/tests/test_distributions_moments.py
158159
pymc/tests/test_distributions_timeseries.py
159160
- |
160161
pymc/tests/test_parallel_sampling.py

RELEASE-NOTES.md

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,109 @@
11
# Release Notes
22

3-
## PyMC vNext (4.0.0)
4-
### Breaking Changes
5-
- ⚠ Theano-PyMC has been replaced with Aesara, so all external references to `theano`, `tt`, and `pymc.theanof` need to be replaced with `aesara`, `at`, and `pymc.aesaraf` (see [4471](https://github.com/pymc-devs/pymc/pull/4471)).
6-
- ⚠ PyMC now requires Scipy version `>= 1.4.1` (see [4857](https://github.com/pymc-devs/pymc/pull/4857)).
7-
- ArviZ `plots` and `stats` *wrappers* were removed. The functions are now just available by their original names (see [#4549](https://github.com/pymc-devs/pymc/pull/4471) and `3.11.2` release notes).
8-
- The GLM submodule has been removed, please use [Bambi](https://bambinos.github.io/bambi/) instead.
9-
- The `Distribution` keyword argument `testval` has been deprecated in favor of `initval`. Furthermore `initval` no longer assigns a `tag.test_value` on tensors since the initial values are now kept track of by the model object ([see #4913](https://github.com/pymc-devs/pymc/pull/4913)).
10-
- `pm.sample` now returns results as `InferenceData` instead of `MultiTrace` by default (see [#4744](https://github.com/pymc-devs/pymc/pull/4744)).
11-
- `pm.sample_prior_predictive`, `pm.sample_posterior_predictive` and `pm.sample_posterior_predictive_w` now return an `InferenceData` object
12-
by default, instead of a dictionary (see [#5073](https://github.com/pymc-devs/pymc/pull/5073)).
3+
<!--
4+
⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
5+
Do not create individual sections for the beta releases.
6+
Instead update the vNext section until 4.0.0 is out.
7+
⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
8+
-->
9+
10+
## PyMC vNext (4.0.0-beta1 → 4.0.0-beta2 → 4.0.0)
11+
⚠ The changes below are the delta between the upcoming releases `v3.11.5` →...→ `v4.0.0`.
12+
13+
### Unexpected breaking changes (action needed)
14+
+ New API is not available in `v3.11.5`.
15+
+ Old API does not work in `v4.0.0`.
16+
17+
All of the above apply to:
18+
19+
- ⚠ The library is now named, installed and imported as "pymc".
20+
- ⚠ Theano-PyMC has been replaced with Aesara, so all external references to `theano`, `tt`, and `pymc3.theanof` need to be replaced with `aesara`, `at`, and `pymc.aesaraf` (see [4471](https://github.com/pymc-devs/pymc/pull/4471)).
21+
- `pm.Distribution(...).logp(x)` is now `pm.logp(pm.Distribution(...), x)`
22+
- `pm.Distribution(...).logcdf(x)` is now `pm.logcdf(pm.Distribution(...), x)`
23+
- `pm.Distribution(...).random()` is now `pm.Distribution(...).eval()`
24+
- `pm.draw_values(...)` and `pm.generate_samples(...)` were removed. The tensors can now be evaluated with `.eval()`.
25+
- `pm.fast_sample_posterior_predictive` was removed.
26+
- `pm.sample_prior_predictive`, `pm.sample_posterior_predictive` and `pm.sample_posterior_predictive_w` now return an `InferenceData` object by default, instead of a dictionary (see [#5073](https://github.com/pymc-devs/pymc/pull/5073)).
1327
- `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/pymc/pull/4769)).
14-
-`pm.Bound` interface no longer accepts a callable class as argument, instead it requires an instantiated distribution (created via the `.dist()` API) to be passed as an argument. In addition, Bound no longer returns a class instance but works as a normal PyMC distribution. Finally, it is no longer possible to do predictive random sampling from Bounded variables. Please, consult the new documentation for details on how to use Bounded variables (see [4815](https://github.com/pymc-devs/pymc/pull/4815)).
15-
- `pm.DensityDist` no longer accepts the `logp` as its first position argument. It is now an optional keyword argument. If you pass a callable as the first positional argument, a `TypeError` will be raised (see [5026](https://github.com/pymc-devs/pymc3/pull/5026)).
16-
- `pm.DensityDist` now accepts distribution parameters as positional arguments. Passing them as a dictionary in the `observed` keyword argument is no longer supported and will raise an error (see [5026](https://github.com/pymc-devs/pymc3/pull/5026)).
17-
- The signature of the `logp` and `random` functions that can be passed into a `pm.DensityDist` has been changed (see [5026](https://github.com/pymc-devs/pymc3/pull/5026)).
28+
- `pm.sample(trace=...)` no longer accepts `MultiTrace` or `len(.) > 0` traces ([see 5019#](https://github.com/pymc-devs/pymc/pull/5019)).
29+
- The GLM submodule was removed, please use [Bambi](https://bambinos.github.io/bambi/) instead.
30+
- `pm.Bound` interface no longer accepts a callable class as argument, instead it requires an instantiated distribution (created via the `.dist()` API) to be passed as an argument. In addition, Bound no longer returns a class instance but works as a normal PyMC distribution. Finally, it is no longer possible to do predictive random sampling from Bounded variables. Please, consult the new documentation for details on how to use Bounded variables (see [4815](https://github.com/pymc-devs/pymc/pull/4815)).
31+
- `pm.logpt(transformed=...)` kwarg was removed (816b5f).
32+
- `Model(model=...)` kwarg was removed
33+
- `Model(theano_config=...)` kwarg was removed
34+
- `Model.size` property was removed (use `Model.ndim` instead).
35+
- `dims` and `coords` handling:
36+
- `Model.RV_dims` and `Model.coords` are now read-only properties. To modify the `coords` dictionary use `Model.add_coord`.
37+
- `dims` or coordinate values that are `None` will be auto-completed (see [#4625](https://github.com/pymc-devs/pymc/pull/4625)).
38+
- Coordinate values passed to `Model.add_coord` are always converted to tuples (see [#5061](https://github.com/pymc-devs/pymc/pull/5061)).
39+
- `Model.update_start_values(...)` was removed. Initial values can be set in the `Model.initial_values` dictionary directly.
40+
- Test values can no longer be set through `pm.Distribution(testval=...)` and must be assigned manually.
41+
- `Transform.forward` and `Transform.backward` signatures changed.
42+
- `pm.DensityDist` no longer accepts the `logp` as its first position argument. It is now an optional keyword argument. If you pass a callable as the first positional argument, a `TypeError` will be raised (see [5026](https://github.com/pymc-devs/pymc/pull/5026)).
43+
- `pm.DensityDist` now accepts distribution parameters as positional arguments. Passing them as a dictionary in the `observed` keyword argument is no longer supported and will raise an error (see [5026](https://github.com/pymc-devs/pymc/pull/5026)).
44+
- The signature of the `logp` and `random` functions that can be passed into a `pm.DensityDist` has been changed (see [5026](https://github.com/pymc-devs/pymc/pull/5026)).
45+
- Changes to the BART implementation:
46+
- A BART variable can be combined with other random variables. The `inv_link` argument has been removed (see [4914](https://github.com/pymc-devs/pymc3/pull/4914)).
47+
- Moved BART to its own module (see [5058](https://github.com/pymc-devs/pymc3/pull/5058)).
1848
- ...
1949

20-
### New Features
50+
51+
### Expected breaks
52+
+ New API was already available in `v3`.
53+
+ Old API had deprecation warnings since at least `3.11.0` (2021-01).
54+
+ Old API stops working in `v4` (preferably with informative errors).
55+
56+
All of the above apply to:
57+
58+
- `pm.sample(return_inferencedata=True)` is now the default (see [#4744](https://github.com/pymc-devs/pymc/pull/4744)).
59+
- ArviZ `plots` and `stats` *wrappers* were removed. The functions are now just available by their original names (see [#4549](https://github.com/pymc-devs/pymc/pull/4471) and `3.11.2` release notes).
60+
- `pm.sample_posterior_predictive(vars=...)` kwarg was removed in favor of `var_names` (see [#4343](https://github.com/pymc-devs/pymc/pull/4343)).
61+
- `ElemwiseCategorical` step method was removed (see [#4701](https://github.com/pymc-devs/pymc/pull/4701))
62+
63+
### Ongoing deprecations
64+
- Old API still works in `v4` and has a deprecation warning.
65+
- Prefereably the new API should be available in `v3` already.
66+
67+
This includes API changes we did not warn about since at least `3.11.0` (2021-01).
68+
69+
- Setting initial values through `pm.Distribution(testval=...)` is now `pm.Distribution(initval=...)`.
70+
71+
72+
### New features
73+
- The length of `dims` in the model is now tracked symbolically through `Model.dim_lengths` (see [#4625](https://github.com/pymc-devs/pymc/pull/4625)).
2174
- The `CAR` distribution has been added to allow for use of conditional autoregressions which often are used in spatial and network models.
2275
- The dimensionality of model variables can now be parametrized through either of `shape`, `dims` or `size` (see [#4696](https://github.com/pymc-devs/pymc/pull/4696)):
2376
- With `shape` the length of dimensions must be given numerically or as scalar Aesara `Variables`. Numeric entries in `shape` restrict the model variable to the exact length and re-sizing is no longer possible.
2477
- `dims` keeps model variables re-sizeable (for example through `pm.Data`) and leads to well defined coordinates in `InferenceData` objects.
2578
- The `size` kwarg behaves like it does in Aesara/NumPy. For univariate RVs it is the same as `shape`, but for multivariate RVs it depends on how the RV implements broadcasting to dimensionality greater than `RVOp.ndim_supp`.
2679
- An `Ellipsis` (`...`) in the last position of `shape` or `dims` can be used as short-hand notation for implied dimensions.
27-
- Add `logcdf` method to Kumaraswamy distribution (see [#4706](https://github.com/pymc-devs/pymc/pull/4706)).
80+
- Added a `logcdf` implementation for the Kumaraswamy distribution (see [#4706](https://github.com/pymc-devs/pymc/pull/4706)).
2881
- 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
2982
observations (see [#4773](https://github.com/pymc-devs/pymc/pull/4773)).
3083
- The `Polya-Gamma` distribution has been added (see [#4531](https://github.com/pymc-devs/pymc/pull/4531)). To make use of this distribution, the [`polyagamma>=1.3.1`](https://pypi.org/project/polyagamma/) library must be installed and available in the user's environment.
3184
- A small change to the mass matrix tuning methods jitter+adapt_diag (the default) and adapt_diag improves performance early on during tuning for some models. [#5004](https://github.com/pymc-devs/pymc/pull/5004)
3285
- New experimental mass matrix tuning method jitter+adapt_diag_grad. [#5004](https://github.com/pymc-devs/pymc/pull/5004)
33-
- `pm.DensityDist` can now accept an optional `logcdf` keyword argument to pass in a function to compute the cummulative density function of the distribution (see [5026](https://github.com/pymc-devs/pymc3/pull/5026)).
34-
- `pm.DensityDist` can now accept an optional `get_moment` keyword argument to pass in a function to compute the moment of the distribution (see [5026](https://github.com/pymc-devs/pymc3/pull/5026)).
86+
- `pm.DensityDist` can now accept an optional `logcdf` keyword argument to pass in a function to compute the cummulative density function of the distribution (see [5026](https://github.com/pymc-devs/pymc/pull/5026)).
87+
- `pm.DensityDist` can now accept an optional `get_moment` keyword argument to pass in a function to compute the moment of the distribution (see [5026](https://github.com/pymc-devs/pymc/pull/5026)).
88+
- New features for BART:
89+
- Added linear response, increased number of trees fitted per step [5044](https://github.com/pymc-devs/pymc3/pull/5044).
90+
- Added partial dependence plots and individual conditional expectation plots [5091](https://github.com/pymc-devs/pymc3/pull/5091).
91+
- `pm.Data` now passes additional kwargs to `aesara.shared`. [#5098](https://github.com/pymc-devs/pymc/pull/5098)
3592
- ...
3693

37-
### Maintenance
38-
- Remove float128 dtype support (see [#4514](https://github.com/pymc-devs/pymc/pull/4514)).
94+
95+
### Internal changes
96+
- ⚠ PyMC now requires Scipy version `>= 1.4.1` (see [4857](https://github.com/pymc-devs/pymc/pull/4857)).
97+
- Removed float128 dtype support (see [#4514](https://github.com/pymc-devs/pymc/pull/4514)).
3998
- Logp method of `Uniform` and `DiscreteUniform` no longer depends on `pymc.distributions.dist_math.bound` for proper evaluation (see [#4541](https://github.com/pymc-devs/pymc/pull/4541)).
40-
- `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/pymc/pull/4625)).
41-
- The length of `dims` in the model is now tracked symbolically through `Model.dim_lengths` (see [#4625](https://github.com/pymc-devs/pymc/pull/4625)).
4299
- We now include `cloudpickle` as a required dependency, and no longer depend on `dill` (see [#4858](https://github.com/pymc-devs/pymc/pull/4858)).
43100
- The `incomplete_beta` function in `pymc.distributions.dist_math` was replaced by `aesara.tensor.betainc` (see [4857](https://github.com/pymc-devs/pymc/pull/4857)).
44101
- `math.log1mexp` and `math.log1mexp_numpy` will expect negative inputs in the future. A `FutureWarning` is now raised unless `negative_input=True` is set (see [#4860](https://github.com/pymc-devs/pymc/pull/4860)).
45-
- Change name of `Lognormal` distribution to `LogNormal` to harmonize CamelCase usage for distribution names.
46-
- Attempt to iterate over MultiTrace will raise NotImplementedError
102+
- Changed name of `Lognormal` distribution to `LogNormal` to harmonize CamelCase usage for distribution names.
103+
- Attempt to iterate over MultiTrace will raise NotImplementedError.
47104
- ...
48105

106+
49107
## PyMC 3.11.2 (14 March 2021)
50108

51109
### New Features

conda-envs/environment-dev-py37.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- defaults
66
dependencies:
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools>=4.2.1
1111
- cloudpickle

conda-envs/environment-dev-py38.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- defaults
66
dependencies:
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools>=4.2.1
1111
- cloudpickle

conda-envs/environment-dev-py39.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- defaults
66
dependencies:
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools>=4.2.1
1111
- cloudpickle

conda-envs/environment-test-py37.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- defaults
66
dependencies:
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools>=4.2.1
1111
- cloudpickle

conda-envs/environment-test-py38.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- defaults
66
dependencies:
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools>=4.2.1
1111
- cloudpickle

conda-envs/environment-test-py39.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- defaults
66
dependencies:
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools
1111
- cloudpickle

conda-envs/windows-environment-dev-py38.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
dependencies:
66
# base dependencies (see install guide for Windows)
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.4
1010
- cachetools>=4.2.1
1111
- cloudpickle

conda-envs/windows-environment-test-py38.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
dependencies:
66
# base dependencies (see install guide for Windows)
77
- aeppl>=0.0.13
8-
- aesara>=2.2.2
8+
- aesara>=2.2.6
99
- arviz>=0.11.2
1010
- cachetools
1111
- cloudpickle

docs/source/developer_guide_implementing_distribution.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ If it is, it should be added to the [Aesara library](https://github.com/aesara-d
2727

2828
In addition, it might not always be necessary to implement a new `RandomVariable`.
2929
For example if the new `Distribution` is just a special parametrization of an existing `Distribution`.
30-
This is the case of the `OrderedLogistic` and `OrderedProbit`, which are just special parametrizations of the `Categorial` distribution.
30+
This is the case of the `OrderedLogistic` and `OrderedProbit`, which are just special parametrizations of the `Categorical` distribution.
3131

3232
The following snippet illustrates how to create a new `RandomVariable`:
3333

@@ -67,7 +67,7 @@ class BlahRV(RandomVariable):
6767
# start with a NumPy `RandomState` object, then the distribution
6868
# parameters, and, finally, the size.
6969
#
70-
# This is effectively the v4 replacement for `Distribution.random`.
70+
# This is effectively the PyMC v4.x replacement for `Distribution.random`.
7171
@classmethod
7272
def rng_fn(
7373
cls,
@@ -115,7 +115,7 @@ blah([0, 0], [1, 2], size=(10, 2)).eval()
115115
## 2. Inheriting from a PyMC base `Distribution` class
116116

117117
After implementing the new `RandomVariable` `Op`, it's time to make use of it in a new PyMC {class}`pymc.distributions.Distribution`.
118-
PyMC works in a very {term}`functional <Functional Programming>` way, and the `distribution` classes are there mostly to facilitate porting the `v3` code to the new `v4` version, add PyMC API features and keep related methods organized together.
118+
PyMC 4.x works in a very {term}`functional <Functional Programming>` way, and the `distribution` classes are there mostly to facilitate porting the `PyMC3` v3.x code to the new `PyMC` v4.x version, add PyMC API features and keep related methods organized together.
119119
In practice, they take care of:
120120

121121
1. Linking ({term}`Dispatching`) a rv_op class with the corresponding logp and logcdf methods.
@@ -186,7 +186,7 @@ Some notes:
186186
1. A distribution should at the very least inherit from {class}`~pymc.distributions.Discrete` or {class}`~pymc.distributions.Continuous`. For the latter, more specific subclasses exist: `PositiveContinuous`, `UnitContinuous`, `BoundedContinuous`, `CircularContinuous`, which specify default transformations for the variables. If you need to specify a one-time custom transform you can also override the `__new__` method, as is done for the {class}`~pymc.distributions.multivariate.Dirichlet`.
187187
1. If a distribution does not have a corresponding `random` implementation, a `RandomVariable` should still be created that raises a `NotImplementedError`. This is the case for the {class}`~pymc.distributions.continuous.Flat`. In this case it will be necessary to provide a standard `initval` by
188188
overriding `__new__`.
189-
1. As mentioned above, `v4` works in a very {term}`functional <Functional Programming>` way, and all the information that is needed in the `logp` and `logcdf` 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 `logp` and `logcdf` methods. Just keep in mind whether this affects the correct shape inference behavior of the `RandomVariable`. If specialized non-numeric information is needed you might need to define your custom`_logp` and `_logcdf` {term}`Dispatching` functions, but this should be done as a last resort.
189+
1. As mentioned above, `PyMC` v4.x works in a very {term}`functional <Functional Programming>` way, and all the information that is needed in the `logp` and `logcdf` 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 `logp` and `logcdf` methods. Just keep in mind whether this affects the correct shape inference behavior of the `RandomVariable`. If specialized non-numeric information is needed you might need to define your custom`_logp` and `_logcdf` {term}`Dispatching` functions, but this should be done as a last resort.
190190
1. The `logcdf` method is not a requirement, but it's a nice plus!
191191

192192
For a quick check that things are working you can try the following:

0 commit comments

Comments
 (0)