Skip to content
/ pymc Public

changed default values for TruncatedNormal lower and upper from None to -np.inf… #3250

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 35 commits into from
Mar 26, 2019
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
42ffa0d
changed default values for TruncatedNormal lower and upper to -np.inf…
gilliss Nov 13, 2018
51fd1fb
inserted an idea for testing in test_distributions_random.py
gilliss Nov 13, 2018
2e6444b
included a standalone test test_truncated_normal_sample_random_variab…
gilliss Nov 14, 2018
5271433
minor
gilliss Nov 14, 2018
893414f
minor
gilliss Nov 14, 2018
2835086
changed _default value cases in continuous.TruncatedNormal to avoid n…
gilliss Nov 14, 2018
ff5826c
minor
gilliss Nov 14, 2018
590ed88
removed test_truncated_normal_lower from TestScalarParameterSamples s…
gilliss Nov 14, 2018
e9d892c
added TestTruncatedNormalUpper and addressed TruncatedNormal _normali…
gilliss Nov 14, 2018
05b5c4c
changed TruncatedNormal.logp to check for infs instead of Nones
gilliss Nov 15, 2018
68dae58
debugging
gilliss Nov 15, 2018
7d03359
debugging
gilliss Nov 15, 2018
a58e8cb
debugging
gilliss Nov 15, 2018
ae90f8f
debugging
gilliss Nov 15, 2018
8ea31bf
debugging
gilliss Nov 15, 2018
77a0e8c
debugging
gilliss Nov 15, 2018
af89cba
tried np.isinf and put in the requested test_truncated_normal_lower t…
gilliss Nov 30, 2018
3febdd3
added extra members self.lower_np self.upper_np for checking values
gilliss Jan 4, 2019
343b6d0
changed to upper_check and lower_check members, with None checks
gilliss Jan 4, 2019
f08299f
minor
gilliss Jan 4, 2019
2d60f58
merged upstream/master
gilliss Jan 4, 2019
d68a640
merged from my own dev branch
gilliss Jan 4, 2019
def32d3
minor
gilliss Jan 4, 2019
8016105
minor
gilliss Jan 4, 2019
1e0c6aa
minor
gilliss Jan 4, 2019
b18623b
removed corresponding paramdomains from upper and lower tests
gilliss Jan 5, 2019
3e1dcf6
Merge branch 'master' of https://github.com/pymc-devs/pymc3
Mar 25, 2019
2cd14ab
removed upper positional arg from test_truncated_normal_lower and vic…
Mar 25, 2019
303843f
Update pymc3/tests/test_distributions_random.py
twiecki Mar 26, 2019
dd9d2f6
Update pymc3/tests/test_distributions_random.py
twiecki Mar 26, 2019
ae73bc0
Update pymc3/tests/test_distributions_random.py
twiecki Mar 26, 2019
2146664
Update pymc3/tests/test_distributions_random.py
twiecki Mar 26, 2019
2c3d1e2
minor syntax
Mar 26, 2019
a63961f
added line to docs/release-notes/pymc3-3.0.md
Mar 26, 2019
a60bbd0
moved release notes line to RELEASE-NOTES.md
Mar 26, 2019
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
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
- Changed initialization of `Categorical.p`. `p` is now normalized to sum to `1` inside `logp` and `random`, but not during initialization. This could hide negative values supplied to `p` as mentioned in #2082.
- `Categorical` now accepts elements of `p` equal to `0`. `logp` will return `-inf` if there are `values` that index to the zero probability categories.
- Add `sigma`, `tau`, and `sd` to signature of `NormalMixture`.
- Resolved issue #3248. Set default lower and upper values of -inf and inf for pm.distributions.continuous.TruncatedNormal. This avoids errors caused by their previous values of None.

### Deprecations

1 change: 1 addition & 0 deletions docs/release-notes/pymc3-3.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

22 changes: 12 additions & 10 deletions pymc3/distributions/continuous.py
Original file line number Diff line number Diff line change
@@ -571,15 +571,17 @@ def __init__(self, mu=0, sigma=None, tau=None, lower=None, upper=None,
tau, sigma = get_tau_sigma(tau=tau, sigma=sigma)
self.sigma = self.sd = tt.as_tensor_variable(sigma)
self.tau = tt.as_tensor_variable(tau)
self.lower = tt.as_tensor_variable(floatX(lower)) if lower is not None else lower
self.upper = tt.as_tensor_variable(floatX(upper)) if upper is not None else upper
self.lower_check = tt.as_tensor_variable(floatX(lower)) if lower is not None else lower
self.upper_check = tt.as_tensor_variable(floatX(upper)) if upper is not None else upper
self.lower = tt.as_tensor_variable(floatX(lower)) if lower is not None else tt.as_tensor_variable(-np.inf)
self.upper = tt.as_tensor_variable(floatX(upper)) if upper is not None else tt.as_tensor_variable(np.inf)
self.mu = tt.as_tensor_variable(floatX(mu))

if self.lower is None and self.upper is None:
if self.lower_check is None and self.upper_check is None:
self._defaultval = mu
elif self.lower is None and self.upper is not None:
elif self.lower_check is None and self.upper_check is not None:
self._defaultval = self.upper - 1.
elif self.lower is not None and self.upper is None:
elif self.lower_check is not None and self.upper_check is None:
self._defaultval = self.lower + 1.
else:
self._defaultval = (self.lower + self.upper) / 2
@@ -639,19 +641,19 @@ def logp(self, value):
logp = Normal.dist(mu=mu, sigma=sigma).logp(value) - norm

bounds = [sigma > 0]
if self.lower is not None:
if self.lower_check is not None:
bounds.append(value >= self.lower)
if self.upper is not None:
if self.upper_check is not None:
bounds.append(value <= self.upper)
return bound(logp, *bounds)

def _normalization(self):
mu, sigma = self.mu, self.sigma

if self.lower is None and self.upper is None:
if self.lower_check is None and self.upper_check is None:
return 0.

if self.lower is not None and self.upper is not None:
if self.lower_check is not None and self.upper_check is not None:
lcdf_a = normal_lcdf(mu, sigma, self.lower)
lcdf_b = normal_lcdf(mu, sigma, self.upper)
lsf_a = normal_lccdf(mu, sigma, self.lower)
@@ -663,7 +665,7 @@ def _normalization(self):
logdiffexp(lcdf_b, lcdf_a),
)

if self.lower is not None:
if self.lower_check is not None:
return normal_lccdf(mu, sigma, self.lower)
else:
return normal_lcdf(mu, sigma, self.upper)
27 changes: 23 additions & 4 deletions pymc3/tests/test_distributions_random.py
Original file line number Diff line number Diff line change
@@ -257,7 +257,15 @@ class TestNormal(BaseTestCases.BaseTestCase):

class TestTruncatedNormal(BaseTestCases.BaseTestCase):
distribution = pm.TruncatedNormal
params = {'mu': 0., 'tau': 1., 'lower':-0.5, 'upper':0.5}
params = {'mu': 0., 'tau': 1., 'lower': -0.5, 'upper': 0.5}

class TestTruncatedNormalLower(BaseTestCases.BaseTestCase):
distribution = pm.TruncatedNormal
params = {'mu': 0., 'tau': 1., 'lower': -0.5}

class TestTruncatedNormalUpper(BaseTestCases.BaseTestCase):
distribution = pm.TruncatedNormal
params = {'mu': 0., 'tau': 1., 'upper': 0.5}

class TestSkewNormal(BaseTestCases.BaseTestCase):
distribution = pm.SkewNormal
@@ -461,7 +469,6 @@ def ref_rand(size, tau):
def test_uniform(self):
def ref_rand(size, lower, upper):
return st.uniform.rvs(size=size, loc=lower, scale=upper - lower)

pymc3_random(pm.Uniform, {'lower': -Rplus, 'upper': Rplus}, ref_rand=ref_rand)

def test_normal(self):
@@ -471,8 +478,20 @@ def ref_rand(size, mu, sigma):

def test_truncated_normal(self):
def ref_rand(size, mu, sigma, lower, upper):
return st.truncnorm.rvs((lower-mu)/sigma, (upper-mu)/sigma, size=size, loc=mu, scale=sigma)
pymc3_random(pm.TruncatedNormal, {'mu': R, 'sigma': Rplusbig, 'lower':-Rplusbig, 'upper':Rplusbig},
return st.truncnorm.rvs((lower - mu) / sigma, (upper - mu) / sigma, size=size, loc=mu, scale=sigma)
pymc3_random(pm.TruncatedNormal, {'mu': R, 'sigma': Rplusbig, 'lower': -Rplusbig, 'upper': Rplusbig},
ref_rand=ref_rand)

def test_truncated_normal_lower(self):
def ref_rand(size, mu, sigma, lower):
return st.truncnorm.rvs((lower - mu) / sigma, np.inf, size=size, loc=mu, scale=sigma)
pymc3_random(pm.TruncatedNormal, {'mu': R, 'sigma': Rplusbig, 'lower': -Rplusbig},
ref_rand=ref_rand)

def test_truncated_normal_upper(self):
def ref_rand(size, mu, sigma, upper):
return st.truncnorm.rvs(-np.inf, (upper - mu) / sigma, size=size, loc=mu, scale=sigma)
pymc3_random(pm.TruncatedNormal, {'mu': R, 'sigma': Rplusbig, 'upper': Rplusbig},
ref_rand=ref_rand)

def test_skew_normal(self):