Skip to content

Commit 86194a7

Browse files
committed
update tests, add __all__
1 parent 8818b71 commit 86194a7

File tree

2 files changed

+87
-92
lines changed

2 files changed

+87
-92
lines changed

pymc3/printing.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424

2525
from pymc3.model import Model
2626

27+
__all__ = [
28+
"str_for_dist",
29+
"str_for_model",
30+
"str_for_potential_or_deterministic",
31+
]
32+
2733

2834
def str_for_dist(rv: TensorVariable, formatting: str = "plain", include_params: bool = True) -> str:
2935
"""Make a human-readable string representation of a RandomVariable in a model, either
@@ -82,8 +88,13 @@ def str_for_model(model: Model, formatting: str = "plain", include_params: bool
8288

8389

8490
def str_for_potential_or_deterministic(
85-
var: TensorVariable, dist_name: str, formatting: str = "plain", include_params: bool = True
91+
var: TensorVariable,
92+
formatting: str = "plain",
93+
include_params: bool = True,
94+
dist_name: str = "Deterministic",
8695
) -> str:
96+
"""Make a human-readable string representation of a Deterministic or Potential in a model, either
97+
LaTeX or plain, optionally with distribution parameter values included."""
8798
print_name = var.name if var.name is not None else "<unnamed>"
8899
if "latex" in formatting:
89100
print_name = r"\text{" + _latex_escape(print_name) + "}"

pymc3/tests/test_distributions.py

Lines changed: 75 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
logpt_sum,
105105
)
106106
from pymc3.math import kronecker
107-
from pymc3.model import Deterministic, Model, Point
107+
from pymc3.model import Deterministic, Model, Point, Potential
108108
from pymc3.tests.helpers import select_by_precision
109109
from pymc3.vartypes import continuous_types
110110

@@ -2786,7 +2786,6 @@ def test_lower_bounded_broadcasted(self):
27862786
assert upper_interval is None
27872787

27882788

2789-
@pytest.mark.xfail(reason="LaTeX repr and str no longer applicable")
27902789
class TestStrAndLatexRepr:
27912790
def setup_class(self):
27922791
# True parameter values
@@ -2802,6 +2801,9 @@ def setup_class(self):
28022801
# Simulate outcome variable
28032802
Y = alpha + X.dot(beta) + np.random.randn(size) * sigma
28042803
with Model() as self.model:
2804+
# TODO: some variables commented out here as they're not working properly
2805+
# in v4 yet (9-jul-2021), so doesn't make sense to test str/latex for them
2806+
28052807
# Priors for unknown model parameters
28062808
alpha = Normal("alpha", mu=0, sigma=10)
28072809
b = Normal("beta", mu=0, sigma=10, size=(2,), observed=beta)
@@ -2811,128 +2813,110 @@ def setup_class(self):
28112813
Z = MvNormal("Z", mu=np.zeros(2), chol=np.eye(2), size=(2,))
28122814

28132815
# NegativeBinomial representations to test issue 4186
2814-
nb1 = pm.NegativeBinomial(
2815-
"nb_with_mu_alpha", mu=pm.Normal("nbmu"), alpha=pm.Gamma("nbalpha", mu=6, sigma=1)
2816-
)
2816+
# nb1 = pm.NegativeBinomial(
2817+
# "nb_with_mu_alpha", mu=pm.Normal("nbmu"), alpha=pm.Gamma("nbalpha", mu=6, sigma=1)
2818+
# )
28172819
nb2 = pm.NegativeBinomial("nb_with_p_n", p=pm.Uniform("nbp"), n=10)
28182820

28192821
# Expected value of outcome
28202822
mu = Deterministic("mu", floatX(alpha + at.dot(X, b)))
28212823

28222824
# add a bounded variable as well
2823-
bound_var = Bound(Normal, lower=1.0)("bound_var", mu=0, sigma=10)
2825+
# bound_var = Bound(Normal, lower=1.0)("bound_var", mu=0, sigma=10)
28242826

28252827
# KroneckerNormal
28262828
n, m = 3, 4
28272829
covs = [np.eye(n), np.eye(m)]
28282830
kron_normal = KroneckerNormal("kron_normal", mu=np.zeros(n * m), covs=covs, size=n * m)
28292831

28302832
# MatrixNormal
2831-
matrix_normal = MatrixNormal(
2832-
"mat_normal",
2833-
mu=np.random.normal(size=n),
2834-
rowcov=np.eye(n),
2835-
colchol=np.linalg.cholesky(np.eye(n)),
2836-
size=(n, n),
2837-
)
2833+
# matrix_normal = MatrixNormal(
2834+
# "mat_normal",
2835+
# mu=np.random.normal(size=n),
2836+
# rowcov=np.eye(n),
2837+
# colchol=np.linalg.cholesky(np.eye(n)),
2838+
# size=(n, n),
2839+
# )
28382840

28392841
# DirichletMultinomial
28402842
dm = DirichletMultinomial("dm", n=5, a=[1, 1, 1], size=(2, 3))
28412843

28422844
# Likelihood (sampling distribution) of observations
28432845
Y_obs = Normal("Y_obs", mu=mu, sigma=sigma, observed=Y)
28442846

2845-
self.distributions = [alpha, sigma, mu, b, Z, nb1, nb2, Y_obs, bound_var]
2847+
# add a potential as well
2848+
pot = Potential("pot", mu ** 2)
2849+
2850+
self.distributions = [alpha, sigma, mu, b, Z, nb2, Y_obs, pot]
2851+
self.deterministics_or_potentials = [mu, pot]
2852+
# tuples of (formatting, include_params
2853+
self.formats = [("plain", True), ("plain", False), ("latex", True), ("latex", False)]
28462854
self.expected = {
2847-
"latex": (
2848-
r"$\text{alpha} \sim \text{Normal}$",
2849-
r"$\text{sigma} \sim \text{HalfNormal}$",
2850-
r"$\text{mu} \sim \text{Deterministic}$",
2851-
r"$\text{beta} \sim \text{Normal}$",
2852-
r"$\text{Z} \sim \text{MvNormal}$",
2853-
r"$\text{nb_with_mu_alpha} \sim \text{NegativeBinomial}$",
2854-
r"$\text{nb_with_p_n} \sim \text{NegativeBinomial}$",
2855-
r"$\text{Y_obs} \sim \text{Normal}$",
2856-
r"$\text{bound_var} \sim \text{Bound}$ -- \text{Normal}$",
2857-
r"$\text{kron_normal} \sim \text{KroneckerNormal}$",
2858-
r"$\text{mat_normal} \sim \text{MatrixNormal}$",
2859-
r"$\text{dm} \sim \text{DirichletMultinomial}$",
2860-
),
2861-
"plain": (
2862-
r"alpha ~ Normal",
2863-
r"sigma ~ HalfNormal",
2855+
("plain", True): [
2856+
r"alpha ~ N(0, 10)",
2857+
r"sigma ~ N**+(0, 1)",
2858+
r"mu ~ Deterministic(f(beta, alpha))",
2859+
r"beta ~ N(0, 10)",
2860+
r"Z ~ N(<constant>, f())",
2861+
r"nb_with_p_n ~ NB(10, nbp)",
2862+
r"Y_obs ~ N(mu, sigma)",
2863+
r"pot ~ Potential(f(beta, alpha))",
2864+
],
2865+
("plain", False): [
2866+
r"alpha ~ N",
2867+
r"sigma ~ N**+",
28642868
r"mu ~ Deterministic",
2865-
r"beta ~ Normal",
2866-
r"Z ~ MvNormal",
2867-
r"nb_with_mu_alpha ~ NegativeBinomial",
2868-
r"nb_with_p_n ~ NegativeBinomial",
2869-
r"Y_obs ~ Normal",
2870-
r"bound_var ~ Bound-Normal",
2871-
r"kron_normal ~ KroneckerNormal",
2872-
r"mat_normal ~ MatrixNormal",
2873-
r"dm ~ DirichletMultinomial",
2874-
),
2875-
"latex_with_params": (
2876-
r"$\text{alpha} \sim \text{Normal}(\mathit{mu}=0.0,~\mathit{sigma}=10.0)$",
2877-
r"$\text{sigma} \sim \text{HalfNormal}(\mathit{sigma}=1.0)$",
2878-
r"$\text{mu} \sim \text{Deterministic}(\text{alpha},~\text{Constant},~\text{beta})$",
2879-
r"$\text{beta} \sim \text{Normal}(\mathit{mu}=0.0,~\mathit{sigma}=10.0)$",
2880-
r"$\text{Z} \sim \text{MvNormal}(\mathit{mu}=array,~\mathit{chol_cov}=array)$",
2881-
r"$\text{nb_with_mu_alpha} \sim \text{NegativeBinomial}(\mathit{mu}=\text{nbmu},~\mathit{alpha}=\text{nbalpha})$",
2882-
r"$\text{nb_with_p_n} \sim \text{NegativeBinomial}(\mathit{p}=\text{nbp},~\mathit{n}=10)$",
2883-
r"$\text{Y_obs} \sim \text{Normal}(\mathit{mu}=\text{mu},~\mathit{sigma}=f(\text{sigma}))$",
2884-
r"$\text{bound_var} \sim \text{Bound}(\mathit{lower}=1.0,~\mathit{upper}=\text{None})$ -- \text{Normal}(\mathit{mu}=0.0,~\mathit{sigma}=10.0)$",
2885-
r"$\text{kron_normal} \sim \text{KroneckerNormal}(\mathit{mu}=array)$",
2886-
r"$\text{mat_normal} \sim \text{MatrixNormal}(\mathit{mu}=array,~\mathit{rowcov}=array,~\mathit{colchol_cov}=array)$",
2887-
r"$\text{dm} \sim \text{DirichletMultinomial}(\mathit{n}=5,~\mathit{a}=array)$",
2888-
),
2889-
"plain_with_params": (
2890-
r"alpha ~ Normal(mu=0.0, sigma=10.0)",
2891-
r"sigma ~ HalfNormal(sigma=1.0)",
2892-
r"mu ~ Deterministic(alpha, Constant, beta)",
2893-
r"beta ~ Normal(mu=0.0, sigma=10.0)",
2894-
r"Z ~ MvNormal(mu=array, chol_cov=array)",
2895-
r"nb_with_mu_alpha ~ NegativeBinomial(mu=nbmu, alpha=nbalpha)",
2896-
r"nb_with_p_n ~ NegativeBinomial(p=nbp, n=10)",
2897-
r"Y_obs ~ Normal(mu=mu, sigma=f(sigma))",
2898-
r"bound_var ~ Bound(lower=1.0, upper=None)-Normal(mu=0.0, sigma=10.0)",
2899-
r"kron_normal ~ KroneckerNormal(mu=array)",
2900-
r"mat_normal ~ MatrixNormal(mu=array, rowcov=array, colchol_cov=array)",
2901-
r"dm∼DirichletMultinomial(n=5, a=array)",
2902-
),
2869+
r"beta ~ N",
2870+
r"Z ~ N",
2871+
r"nb_with_p_n ~ NB",
2872+
r"Y_obs ~ N",
2873+
r"pot ~ Potential",
2874+
],
2875+
("latex", True): [
2876+
r"$\text{alpha} \sim \operatorname{N}(0,~10)$",
2877+
r"$\text{sigma} \sim \operatorname{N^{+}}(0,~1)$",
2878+
r"$\text{mu} \sim \operatorname{Deterministic}(f(\text{beta},~\text{alpha}))$",
2879+
r"$\text{beta} \sim \operatorname{N}(0,~10)$",
2880+
r"$\text{Z} \sim \operatorname{N}(\text{<constant>},~f())$",
2881+
r"$\text{nb_with_p_n} \sim \operatorname{NB}(10,~\text{nbp})$",
2882+
r"$\text{Y_obs} \sim \operatorname{N}(\text{mu},~\text{sigma})$",
2883+
r"$\text{pot} \sim \operatorname{Potential}(f(\text{beta},~\text{alpha}))$",
2884+
],
2885+
("latex", False): [
2886+
r"$\text{alpha} \sim \operatorname{N}$",
2887+
r"$\text{sigma} \sim \operatorname{N^{+}}$",
2888+
r"$\text{mu} \sim \operatorname{Deterministic}$",
2889+
r"$\text{beta} \sim \operatorname{N}$",
2890+
r"$\text{Z} \sim \operatorname{N}$",
2891+
r"$\text{nb_with_p_n} \sim \operatorname{NB}$",
2892+
r"$\text{Y_obs} \sim \operatorname{N}$",
2893+
r"$\text{pot} \sim \operatorname{Potential}$",
2894+
],
29032895
}
29042896

29052897
def test__repr_latex_(self):
2906-
for distribution, tex in zip(self.distributions, self.expected["latex_with_params"]):
2898+
for distribution, tex in zip(self.distributions, self.expected[("latex", True)]):
29072899
assert distribution._repr_latex_() == tex
29082900

29092901
model_tex = self.model._repr_latex_()
29102902

29112903
# make sure each variable is in the model
2912-
for tex in self.expected["latex"]:
2904+
for tex in self.expected[("latex", True)]:
29132905
for segment in tex.strip("$").split(r"\sim"):
29142906
assert segment in model_tex
29152907

2916-
def test___latex__(self):
2917-
for distribution, tex in zip(self.distributions, self.expected["latex_with_params"]):
2918-
assert distribution._repr_latex_() == distribution.__latex__()
2919-
assert self.model._repr_latex_() == self.model.__latex__()
2920-
2921-
def test___str__(self):
2922-
for distribution, str_repr in zip(self.distributions, self.expected["plain"]):
2923-
assert distribution.__str__() == str_repr
2924-
2925-
model_str = self.model.__str__()
2926-
for str_repr in self.expected["plain"]:
2927-
assert str_repr in model_str
2928-
2929-
def test_str(self):
2930-
for distribution, str_repr in zip(self.distributions, self.expected["plain"]):
2931-
assert str(distribution) == str_repr
2932-
2933-
model_str = str(self.model)
2934-
for str_repr in self.expected["plain"]:
2935-
assert str_repr in model_str
2908+
def test_str_repr(self):
2909+
for str_format in self.formats:
2910+
for dist, text in zip(self.distributions, self.expected[str_format]):
2911+
assert dist.str_repr(*str_format) == text
2912+
2913+
model_text = self.model.str_repr(*str_format)
2914+
for text in self.expected[str_format]:
2915+
if str_format[0] == "latex":
2916+
for segment in text.strip("$").split(r"\sim"):
2917+
assert segment in model_text
2918+
else:
2919+
assert text in model_text
29362920

29372921

29382922
def test_discrete_trafo():

0 commit comments

Comments
 (0)