Skip to content

Cap the values that Beta.random can generate. #3924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
FIX: use scipy.stats and change ref_rand to point to clipped_beta_rvs
  • Loading branch information
lucianopaz committed May 15, 2020
commit 12e30f1bbc0c383885503f5fe873b26745ce35ee
13 changes: 7 additions & 6 deletions pymc3/distributions/dist_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
'''
import numpy as np
import scipy.linalg
import scipy.stats
import theano.tensor as tt
import theano
from theano.scalar import UnaryScalarOp, upgrade_to_float_no_complex
Expand Down Expand Up @@ -558,17 +559,17 @@ def incomplete_beta(a, b, value):
def clipped_beta_rvs(a, b, size=None, dtype="float64"):
"""Draw beta distributed random samples in the open :math:`(0, 1)` interval.

The samples are generated with ``numpy.random.beta``, but any value that
The samples are generated with ``scipy.stats.beta.rvs``, but any value that
is equal to 0 or 1 will be shifted towards the next floating point in the
interval :math:`[0, 1]`, depending on the floating point precision that is
given by ``dtype``.

Parameters
----------
a : float or array_like of floats
Alpha, positive (>0).
Alpha, strictly positive (>0).
b : float or array_like of floats
Beta, positive (>0).
Beta, strictly positive (>0).
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. If size is ``None`` (default),
Expand All @@ -582,15 +583,15 @@ def clipped_beta_rvs(a, b, size=None, dtype="float64"):
Returns
-------
out : ndarray or scalar
Drawn samples from the parameterized beta distribution. The numpy
Drawn samples from the parameterized beta distribution. The scipy
implementation can yield values that are equal to zero or one. We
assume the support of the Beta distribution to be in the open interval
:math:`(0, 1)`, so we shift any sample that is equal to 0 to
``np.nextafter(0, 1, dtype=dtype)`` and any sample that is equal to 1
if shifted to ``np.nextafter(1, 0, dtype=dtype)``.
is shifted to ``np.nextafter(1, 0, dtype=dtype)``.

"""
out = np.random.beta(a, b, size=size).astype(dtype)
out = scipy.stats.beta.rvs(a, b, size=size).astype(dtype)
lower, upper = _beta_clip_values[dtype]
out[out == 0] = lower
out[out == 1] = upper
Expand Down
3 changes: 2 additions & 1 deletion pymc3/tests/test_distributions_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import theano

import pymc3 as pm
from pymc3.distributions.dist_math import clipped_beta_rvs
from pymc3.distributions.distribution import (draw_values,
_DrawValuesContext,
_DrawValuesContextBlocker)
Expand Down Expand Up @@ -548,7 +549,7 @@ def ref_rand(size, mu, lam, alpha):

def test_beta(self):
def ref_rand(size, alpha, beta):
return st.beta.rvs(a=alpha, b=beta, size=size)
return clipped_beta_rvs(a=alpha, b=beta, size=size)
pymc3_random(pm.Beta, {'alpha': Rplus, 'beta': Rplus}, ref_rand=ref_rand)

def test_exponential(self):
Expand Down