|
1 | 1 | import aesara
|
2 | 2 | import numpy as np
|
3 | 3 | import pytest
|
| 4 | +import scipy.stats as st |
4 | 5 |
|
5 | 6 | from aesara import tensor as at
|
6 | 7 | from scipy import special
|
7 | 8 |
|
8 | 9 | import pymc as pm
|
9 | 10 |
|
| 11 | +from pymc import Simulator |
10 | 12 | from pymc.distributions import (
|
11 | 13 | AsymmetricLaplace,
|
12 | 14 | Bernoulli,
|
@@ -1074,3 +1076,41 @@ def test_zero_inflated_negative_binomial_moment(psi, mu, alpha, size, expected):
|
1074 | 1076 | with Model() as model:
|
1075 | 1077 | ZeroInflatedNegativeBinomial("x", psi=psi, mu=mu, alpha=alpha, size=size)
|
1076 | 1078 | assert_moment_is_expected(model, expected)
|
| 1079 | + |
| 1080 | + |
| 1081 | +@pytest.mark.parametrize("mu", [0, np.arange(3)], ids=str) |
| 1082 | +@pytest.mark.parametrize("sigma", [1, np.array([1, 2, 5])], ids=str) |
| 1083 | +@pytest.mark.parametrize("size", [None, 3, (5, 3)], ids=str) |
| 1084 | +def test_simulator_moment(mu, sigma, size): |
| 1085 | + def normal_sim(rng, mu, sigma, size): |
| 1086 | + return rng.normal(mu, sigma, size=size) |
| 1087 | + |
| 1088 | + with Model() as model: |
| 1089 | + x = Simulator("x", normal_sim, mu, sigma, size=size) |
| 1090 | + |
| 1091 | + fn = make_initial_point_fn( |
| 1092 | + model=model, |
| 1093 | + return_transformed=False, |
| 1094 | + default_strategy="moment", |
| 1095 | + ) |
| 1096 | + |
| 1097 | + random_draw = model["x"].eval() |
| 1098 | + result = fn(0)["x"] |
| 1099 | + assert result.shape == random_draw.shape |
| 1100 | + |
| 1101 | + # We perform a z-test between the moment and expected mean from a sample of 10 draws |
| 1102 | + # This test fails if the number of samples averaged in get_moment(Simulator) |
| 1103 | + # is much smaller than 10, but would not catch the case where the number of samples |
| 1104 | + # is higher than the expected 10 |
| 1105 | + |
| 1106 | + n = 10 # samples |
| 1107 | + expected_sample_mean = mu |
| 1108 | + expected_sample_mean_std = np.sqrt(sigma ** 2 / n) |
| 1109 | + |
| 1110 | + # Multiple test adjustment for z-test to maintain alpha=0.01 |
| 1111 | + alpha = 0.01 |
| 1112 | + alpha /= 2 * 2 * 3 # Correct for number of test permutations |
| 1113 | + alpha /= random_draw.size # Correct for distribution size |
| 1114 | + cutoff = st.norm().ppf(1 - (alpha / 2)) |
| 1115 | + |
| 1116 | + assert np.all(np.abs((result - expected_sample_mean) / expected_sample_mean_std) < cutoff) |
0 commit comments