Skip to content

Commit 1f42835

Browse files
committed
Put tests for constrained priors into their own file
1 parent d53154a commit 1f42835

File tree

2 files changed

+120
-101
lines changed

2 files changed

+120
-101
lines changed

pymc/tests/test_func_utils.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Copyright 2020 The PyMC Developers
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import numpy as np
16+
import pytest
17+
18+
import pymc as pm
19+
20+
21+
@pytest.mark.parametrize(
22+
"distribution, lower, upper, init_guess, fixed_params",
23+
[
24+
(pm.Gamma, 0.1, 0.4, {"alpha": 1, "beta": 10}, {}),
25+
(pm.Normal, 155, 180, {"mu": 170, "sigma": 3}, {}),
26+
(pm.StudentT, 0.1, 0.4, {"mu": 10, "sigma": 3}, {"nu": 7}),
27+
(pm.StudentT, 0, 1, {"mu": 5, "sigma": 2, "nu": 7}, {}),
28+
# (pm.Exponential, 0, 1, {"lam": 1}, {}), PyMC Exponential gradient is failing miserably,
29+
# need to figure out why
30+
(pm.HalfNormal, 0, 1, {"sigma": 1}, {}),
31+
(pm.Binomial, 0, 8, {"p": 0.5}, {"n": 10}),
32+
(pm.Poisson, 1, 15, {"mu": 10}, {}),
33+
(pm.Poisson, 19, 41, {"mu": 30}, {}),
34+
],
35+
)
36+
@pytest.mark.parametrize("mass", [0.5, 0.75, 0.95])
37+
def test_find_constrained_prior(distribution, lower, upper, init_guess, fixed_params, mass):
38+
with pytest.warns(None) as record:
39+
opt_params = pm.find_constrained_prior(
40+
distribution,
41+
lower=lower,
42+
upper=upper,
43+
mass=mass,
44+
init_guess=init_guess,
45+
fixed_params=fixed_params,
46+
)
47+
assert len(record) == 0
48+
49+
opt_distribution = distribution.dist(**opt_params)
50+
mass_in_interval = (
51+
pm.math.exp(pm.logcdf(opt_distribution, upper))
52+
- pm.math.exp(pm.logcdf(opt_distribution, lower))
53+
).eval()
54+
assert np.abs(mass_in_interval - mass) <= 1e-5
55+
56+
57+
@pytest.mark.parametrize(
58+
"distribution, lower, upper, init_guess, fixed_params",
59+
[
60+
(pm.Gamma, 0.1, 0.4, {"alpha": 1}, {"beta": 10}),
61+
(pm.Exponential, 0.1, 1, {"lam": 1}, {}),
62+
(pm.Binomial, 0, 2, {"p": 0.8}, {"n": 10}),
63+
],
64+
)
65+
def test_find_constrained_prior_error_too_large(
66+
distribution, lower, upper, init_guess, fixed_params
67+
):
68+
with pytest.warns(UserWarning, match="instead of the requested 95%"):
69+
pm.find_constrained_prior(
70+
distribution,
71+
lower=lower,
72+
upper=upper,
73+
mass=0.95,
74+
init_guess=init_guess,
75+
fixed_params=fixed_params,
76+
)
77+
78+
79+
def test_find_constrained_prior_input_errors():
80+
# missing param
81+
with pytest.raises(TypeError, match="required positional argument"):
82+
pm.find_constrained_prior(
83+
pm.StudentT,
84+
lower=0.1,
85+
upper=0.4,
86+
mass=0.95,
87+
init_guess={"mu": 170, "sigma": 3},
88+
)
89+
90+
# mass too high
91+
with pytest.raises(AssertionError, match="has to be between 0.01 and 0.99"):
92+
pm.find_constrained_prior(
93+
pm.StudentT,
94+
lower=0.1,
95+
upper=0.4,
96+
mass=0.995,
97+
init_guess={"mu": 170, "sigma": 3},
98+
fixed_params={"nu": 7},
99+
)
100+
101+
# mass too low
102+
with pytest.raises(AssertionError, match="has to be between 0.01 and 0.99"):
103+
pm.find_constrained_prior(
104+
pm.StudentT,
105+
lower=0.1,
106+
upper=0.4,
107+
mass=0.005,
108+
init_guess={"mu": 170, "sigma": 3},
109+
fixed_params={"nu": 7},
110+
)
111+
112+
# non-scalar params
113+
with pytest.raises(NotImplementedError, match="does not work with non-scalar parameters yet"):
114+
pm.find_constrained_prior(
115+
pm.MvNormal,
116+
lower=0,
117+
upper=1,
118+
mass=0.95,
119+
init_guess={"mu": 5, "cov": np.asarray([[1, 0.2], [0.2, 1]])},
120+
)

pymc/tests/test_util.py

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -142,104 +142,3 @@ def fn(a=UNSET):
142142
help(fn)
143143
captured = capsys.readouterr()
144144
assert "a=UNSET" in captured.out
145-
146-
147-
@pytest.mark.parametrize(
148-
"distribution, lower, upper, init_guess, fixed_params",
149-
[
150-
(pm.Gamma, 0.1, 0.4, {"alpha": 1, "beta": 10}, {}),
151-
(pm.Normal, 155, 180, {"mu": 170, "sigma": 3}, {}),
152-
(pm.StudentT, 0.1, 0.4, {"mu": 10, "sigma": 3}, {"nu": 7}),
153-
(pm.StudentT, 0, 1, {"mu": 5, "sigma": 2, "nu": 7}, {}),
154-
# (pm.Exponential, 0, 1, {"lam": 1}, {}), PyMC Exponential gradient is failing miserably, need to figure out why
155-
(pm.HalfNormal, 0, 1, {"sigma": 1}, {}),
156-
(pm.Binomial, 0, 8, {"p": 0.5}, {"n": 10}),
157-
(pm.Poisson, 1, 15, {"mu": 10}, {}),
158-
(pm.Poisson, 19, 41, {"mu": 30}, {}),
159-
],
160-
)
161-
@pytest.mark.parametrize("mass", [0.5, 0.75, 0.95])
162-
def test_find_constrained_prior(distribution, lower, upper, init_guess, fixed_params, mass):
163-
with pytest.warns(None) as record:
164-
opt_params = pm.find_constrained_prior(
165-
distribution,
166-
lower=lower,
167-
upper=upper,
168-
mass=mass,
169-
init_guess=init_guess,
170-
fixed_params=fixed_params,
171-
)
172-
assert len(record) == 0
173-
174-
opt_distribution = distribution.dist(**opt_params)
175-
mass_in_interval = (
176-
pm.math.exp(pm.logcdf(opt_distribution, upper))
177-
- pm.math.exp(pm.logcdf(opt_distribution, lower))
178-
).eval()
179-
assert np.abs(mass_in_interval - mass) <= 1e-5
180-
181-
182-
@pytest.mark.parametrize(
183-
"distribution, lower, upper, init_guess, fixed_params",
184-
[
185-
(pm.Gamma, 0.1, 0.4, {"alpha": 1}, {"beta": 10}),
186-
(pm.Exponential, 0.1, 1, {"lam": 1}, {}),
187-
(pm.Binomial, 0, 2, {"p": 0.8}, {"n": 10}),
188-
],
189-
)
190-
def test_find_constrained_prior_error_too_large(
191-
distribution, lower, upper, init_guess, fixed_params
192-
):
193-
with pytest.warns(UserWarning, match="instead of the requested 95%"):
194-
pm.find_constrained_prior(
195-
distribution,
196-
lower=lower,
197-
upper=upper,
198-
mass=0.95,
199-
init_guess=init_guess,
200-
fixed_params=fixed_params,
201-
)
202-
203-
204-
def test_find_constrained_prior_input_errors():
205-
# missing param
206-
with pytest.raises(TypeError, match="required positional argument"):
207-
pm.find_constrained_prior(
208-
pm.StudentT,
209-
lower=0.1,
210-
upper=0.4,
211-
mass=0.95,
212-
init_guess={"mu": 170, "sigma": 3},
213-
)
214-
215-
# mass too high
216-
with pytest.raises(AssertionError, match="has to be between 0.01 and 0.99"):
217-
pm.find_constrained_prior(
218-
pm.StudentT,
219-
lower=0.1,
220-
upper=0.4,
221-
mass=0.995,
222-
init_guess={"mu": 170, "sigma": 3},
223-
fixed_params={"nu": 7},
224-
)
225-
226-
# mass too low
227-
with pytest.raises(AssertionError, match="has to be between 0.01 and 0.99"):
228-
pm.find_constrained_prior(
229-
pm.StudentT,
230-
lower=0.1,
231-
upper=0.4,
232-
mass=0.005,
233-
init_guess={"mu": 170, "sigma": 3},
234-
fixed_params={"nu": 7},
235-
)
236-
237-
# non-scalar params
238-
with pytest.raises(NotImplementedError, match="does not work with non-scalar parameters yet"):
239-
pm.find_constrained_prior(
240-
pm.MvNormal,
241-
lower=0,
242-
upper=1,
243-
mass=0.95,
244-
init_guess={"mu": 5, "cov": np.asarray([[1, 0.2], [0.2, 1]])},
245-
)

0 commit comments

Comments
 (0)