From 6ae7f20054e9f83ea4d641a34125a467ac932afb Mon Sep 17 00:00:00 2001 From: Ahan M R Date: Thu, 19 Mar 2020 00:11:31 +0530 Subject: [PATCH 1/9] Closes #3051 - logp numpy array input- fixed Converts 'int' type to to parse value to `astype` and allows arguments to `logp(self,value)` when called with numpy array. --- pymc3/distributions/multivariate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymc3/distributions/multivariate.py b/pymc3/distributions/multivariate.py index bff2bf1c2c..3add98293f 100755 --- a/pymc3/distributions/multivariate.py +++ b/pymc3/distributions/multivariate.py @@ -327,7 +327,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = value.shape[-1].astype(theano.config.floatX) + k = theano.shared(value).shape[-1].astype(theano.config.floatX) norm = - 0.5 * k * pm.floatX(np.log(2 * np.pi)) return bound(norm - 0.5 * quaddist - logdet, ok) @@ -441,7 +441,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = value.shape[-1].astype(theano.config.floatX) + k = theano.shared(value).shape[-1].astype(theano.config.floatX) norm = (gammaln((self.nu + k) / 2.) - gammaln(self.nu / 2.) From 742049543ee596900186f9783725bb22e734a93a Mon Sep 17 00:00:00 2001 From: Ahan M R Date: Thu, 19 Mar 2020 01:27:37 +0530 Subject: [PATCH 2/9] Closes #3051 - Allows numpy array input to logp Allows `logp(self,value)` to take `value` input of type numpy array without errors --- pymc3/distributions/multivariate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymc3/distributions/multivariate.py b/pymc3/distributions/multivariate.py index 3add98293f..ece8eaf807 100755 --- a/pymc3/distributions/multivariate.py +++ b/pymc3/distributions/multivariate.py @@ -27,7 +27,7 @@ from theano.tensor.slinalg import Cholesky import pymc3 as pm -from pymc3.theanof import floatX +from pymc3.theanof import floatX, intX from . import transforms from pymc3.util import get_variable_name from .distribution import (Continuous, Discrete, draw_values, generate_samples, @@ -327,7 +327,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = theano.shared(value).shape[-1].astype(theano.config.floatX) + k = intX(value.shape[-1]).astype(theano.config.floatX) norm = - 0.5 * k * pm.floatX(np.log(2 * np.pi)) return bound(norm - 0.5 * quaddist - logdet, ok) @@ -441,7 +441,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = theano.shared(value).shape[-1].astype(theano.config.floatX) + k = intX(value.shape[-1]).astype(theano.config.floatX) norm = (gammaln((self.nu + k) / 2.) - gammaln(self.nu / 2.) From 9df27b35c859d4b0bb754a6bfdec0216369c5f60 Mon Sep 17 00:00:00 2001 From: Ahan M R Date: Thu, 19 Mar 2020 03:16:27 +0530 Subject: [PATCH 3/9] fixes #3051 --- pymc3/distributions/multivariate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymc3/distributions/multivariate.py b/pymc3/distributions/multivariate.py index ece8eaf807..0a7ab8774a 100755 --- a/pymc3/distributions/multivariate.py +++ b/pymc3/distributions/multivariate.py @@ -327,7 +327,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = intX(value.shape[-1]).astype(theano.config.floatX) + k = floatX(value.shape[-1]) norm = - 0.5 * k * pm.floatX(np.log(2 * np.pi)) return bound(norm - 0.5 * quaddist - logdet, ok) @@ -441,7 +441,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = intX(value.shape[-1]).astype(theano.config.floatX) + k = floatX(value.shape[-1]) norm = (gammaln((self.nu + k) / 2.) - gammaln(self.nu / 2.) From 1d53dcfdc86b4573f5bbc49185a9fc2f9aabaaba Mon Sep 17 00:00:00 2001 From: Ahan M R Date: Thu, 19 Mar 2020 03:59:03 +0530 Subject: [PATCH 4/9] Fixes #3051 --- pymc3/distributions/multivariate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymc3/distributions/multivariate.py b/pymc3/distributions/multivariate.py index 0a7ab8774a..ece8eaf807 100755 --- a/pymc3/distributions/multivariate.py +++ b/pymc3/distributions/multivariate.py @@ -327,7 +327,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = floatX(value.shape[-1]) + k = intX(value.shape[-1]).astype(theano.config.floatX) norm = - 0.5 * k * pm.floatX(np.log(2 * np.pi)) return bound(norm - 0.5 * quaddist - logdet, ok) @@ -441,7 +441,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = floatX(value.shape[-1]) + k = intX(value.shape[-1]).astype(theano.config.floatX) norm = (gammaln((self.nu + k) / 2.) - gammaln(self.nu / 2.) From 4a8eb5e32db7acfc4ae864f0bf167cf6f872d017 Mon Sep 17 00:00:00 2001 From: Ahan M R Date: Thu, 19 Mar 2020 15:41:26 +0530 Subject: [PATCH 5/9] updated RELEASE-NOTES.md Added the deprecation of `sd` with `sigma` in newer version with DeprecationWarning on usage of `sd`. --- RELEASE-NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 3010f150ac..a5306a5622 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -14,6 +14,9 @@ - Remove `sample_ppc` and `sample_ppc_w` that were deprecated in 3.6. - Tuning results no longer leak into sequentially sampled `Metropolis` chains (see #3733 and #3796). +### Deprecation +- Deprecated `sd` in version 3.7 has been replaced by `sigma` now raises DepreciationWarning on using `sg` in continuous, mixed and timeseries distributions. (see #3837 and #3688). + ## PyMC3 3.8 (November 29 2019) ### New features From 9002e41c3dad0ee38c08ef9f49541c6b2f0e3371 Mon Sep 17 00:00:00 2001 From: Michael Osthege Date: Mon, 4 May 2020 21:56:15 +0200 Subject: [PATCH 6/9] directly use floatX --- pymc3/distributions/multivariate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymc3/distributions/multivariate.py b/pymc3/distributions/multivariate.py index 94134fd5cc..3b7196682d 100755 --- a/pymc3/distributions/multivariate.py +++ b/pymc3/distributions/multivariate.py @@ -27,7 +27,7 @@ from theano.tensor.slinalg import Cholesky import pymc3 as pm -from pymc3.theanof import floatX, intX +from pymc3.theanof import floatX from . import transforms from pymc3.util import get_variable_name from .distribution import (Continuous, Discrete, draw_values, generate_samples, @@ -325,7 +325,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = intX(value.shape[-1]).astype(theano.config.floatX) + k = floatX(value.shape[-1]) norm = - 0.5 * k * pm.floatX(np.log(2 * np.pi)) return bound(norm - 0.5 * quaddist - logdet, ok) @@ -439,7 +439,7 @@ def logp(self, value): TensorVariable """ quaddist, logdet, ok = self._quaddist(value) - k = intX(value.shape[-1]).astype(theano.config.floatX) + k = floatX(value.shape[-1]) norm = (gammaln((self.nu + k) / 2.) - gammaln(self.nu / 2.) From 7f3b59650a2690109f8b3a2a4decda8eb6ee0237 Mon Sep 17 00:00:00 2001 From: Michael Osthege Date: Mon, 4 May 2020 21:58:39 +0200 Subject: [PATCH 7/9] mention #3836 --- RELEASE-NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 7bfd08ddf0..5aaeb5e6e5 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -26,6 +26,7 @@ - Dropped the outdated 'nuts' initialization method for `pm.sample` (see [#3863](https://github.com/pymc-devs/pymc3/pull/3863)). - Moved argument division out of `NegativeBinomial` `random` method. Fixes [#3864](https://github.com/pymc-devs/pymc3/issues/3864) in the style of [#3509](https://github.com/pymc-devs/pymc3/pull/3509). - The Dirichlet distribution now raises a ValueError when it's initialized with <= 0 values (see [#3853](https://github.com/pymc-devs/pymc3/pull/3853)). +- Dtype bugfix in `MvNormal` and `MvStudentT` (see [3836](https://github.com/pymc-devs/pymc3/pull/3836)) - End of sampling report now uses `arviz.InferenceData` internally and avoids storing pointwise log likelihood (see [#3883](https://github.com/pymc-devs/pymc3/pull/3883)) From 27da5c758ed754c2c183b5db6f4f77d98e7a99c9 Mon Sep 17 00:00:00 2001 From: Michael Osthege Date: Mon, 4 May 2020 22:09:15 +0200 Subject: [PATCH 8/9] move all deprecations into their own chapter, as done in previous releases --- RELEASE-NOTES.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 5aaeb5e6e5..d141236602 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -16,22 +16,22 @@ - `pm.LKJCholeskyCov` now automatically computes and returns the unpacked Cholesky decomposition, the correlations and the standard deviations of the covariance matrix (see [#3881](https://github.com/pymc-devs/pymc3/pull/3881)). ### Maintenance -- Remove `sample_ppc` and `sample_ppc_w` that were deprecated in 3.6. - Tuning results no longer leak into sequentially sampled `Metropolis` chains (see #3733 and #3796). -- Deprecated `sd` in version 3.7 has been replaced by `sigma` now raises `DeprecationWarning` on using `sd` in continuous, mixed and timeseries distributions. (see #3837 and #3688). -- We'll deprecate the `Text` and `SQLite` backends and the `save_trace`/`load_trace` functions, since this is now done with ArviZ. (see [#3902](https://github.com/pymc-devs/pymc3/pull/3902)) - In named models, `pm.Data` objects now get model-relative names (see [#3843](https://github.com/pymc-devs/pymc3/pull/3843)). - `pm.sample` now takes 1000 draws and 1000 tuning samples by default, instead of 500 previously (see [#3855](https://github.com/pymc-devs/pymc3/pull/3855)). -- Dropped some deprecated kwargs and functions (see [#3906](https://github.com/pymc-devs/pymc3/pull/3906)) -- Dropped the outdated 'nuts' initialization method for `pm.sample` (see [#3863](https://github.com/pymc-devs/pymc3/pull/3863)). - Moved argument division out of `NegativeBinomial` `random` method. Fixes [#3864](https://github.com/pymc-devs/pymc3/issues/3864) in the style of [#3509](https://github.com/pymc-devs/pymc3/pull/3509). - The Dirichlet distribution now raises a ValueError when it's initialized with <= 0 values (see [#3853](https://github.com/pymc-devs/pymc3/pull/3853)). - Dtype bugfix in `MvNormal` and `MvStudentT` (see [3836](https://github.com/pymc-devs/pymc3/pull/3836)) - End of sampling report now uses `arviz.InferenceData` internally and avoids storing pointwise log likelihood (see [#3883](https://github.com/pymc-devs/pymc3/pull/3883)) -### Deprecation -- Deprecated `sd` in version 3.7 has been replaced by `sigma` now raises DepreciationWarning on using `sg` in continuous, mixed and timeseries distributions. (see #3837 and #3688). +### Deprecations +- Remove `sample_ppc` and `sample_ppc_w` that were deprecated in 3.6. +- Deprecated `sd` in version 3.7 has been replaced by `sigma` now raises `DeprecationWarning` on using `sd` in continuous, mixed and timeseries distributions. (see [#3837](https://github.com/pymc-devs/pymc3/pull/3837) and [#3688](https://github.com/pymc-devs/pymc3/issues/3688)). +- We'll deprecate the `Text` and `SQLite` backends and the `save_trace`/`load_trace` functions, since this is now done with ArviZ. (see [#3902](https://github.com/pymc-devs/pymc3/pull/3902)) +- Dropped some deprecated kwargs and functions (see [#3906](https://github.com/pymc-devs/pymc3/pull/3906)) +- Dropped the outdated 'nuts' initialization method for `pm.sample` (see [#3863](https://github.com/pymc-devs/pymc3/pull/3863)). + ## PyMC3 3.8 (November 29 2019) From 46f0fb03518dda5e321ce000ce7aa58bfa926b11 Mon Sep 17 00:00:00 2001 From: Michael Osthege Date: Tue, 5 May 2020 11:36:38 +0200 Subject: [PATCH 9/9] add regression test --- pymc3/tests/test_distributions.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pymc3/tests/test_distributions.py b/pymc3/tests/test_distributions.py index d8586d421c..8c1a6a2dd7 100644 --- a/pymc3/tests/test_distributions.py +++ b/pymc3/tests/test_distributions.py @@ -1414,3 +1414,21 @@ def test_orderedlogistic_dimensions(shape): assert np.allclose(clogp, expected) assert ol.distribution.p.ndim == (len(shape) + 1) assert np.allclose(ologp, expected) + + +class TestBugfixes: + @pytest.mark.parametrize('dist_cls,kwargs', [ + (MvNormal, dict(mu=0)), + (MvStudentT, dict(mu=0, nu=2)) + ]) + @pytest.mark.parametrize('dims', [1,2,4]) + def test_issue_3051(self, dims, dist_cls, kwargs): + d = dist_cls.dist(**kwargs, cov=np.eye(dims), shape=(dims,)) + + X = np.random.normal(size=(20,dims)) + actual_t = d.logp(X) + assert isinstance(actual_t, tt.TensorVariable) + actual_a = actual_t.eval() + assert isinstance(actual_a, np.ndarray) + assert actual_a.shape == (X.shape[0],) + pass