Skip to content

Commit e79504a

Browse files
committed
Add regression test for batched time_varying_P
1 parent 7f51e71 commit e79504a

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

tests/model/marginal/test_discrete_markov_chain.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,43 @@ def test_marginalized_discrete_markov_chain_time_varying_P():
273273
np.testing.assert_allclose(marginal_m.compile_logp()({}), expected)
274274

275275

276+
def test_marginalized_discrete_markov_chain_batched_time_varying_P():
277+
"""Batched chains sharing one time-varying P. The batch axes of the chain must not collide
278+
with P's core (time, from, to) axes in the forward filter."""
279+
pi0 = np.array([0.6, 0.4])
280+
sigma = 0.8
281+
obs = np.array([[0.1, 1.2, 0.8, -0.2], [0.9, -0.1, 0.2, 1.1], [0.5, 0.7, 1.0, 0.3]])
282+
n_chains, T, k = *obs.shape, 2
283+
A_t = np.array(
284+
[
285+
[[0.9, 0.1], [0.2, 0.8]],
286+
[[0.4, 0.6], [0.3, 0.7]],
287+
[[0.1, 0.9], [0.5, 0.5]],
288+
]
289+
) # (T - 1, k, k), no batch axis: every chain shares the same per-step kernels
290+
291+
with pm.Model() as m:
292+
init = pm.Categorical.dist(p=pi0, shape=(n_chains,))
293+
states = DiscreteMarkovChain(
294+
"states", P=A_t, init_dist=init, time_varying_P=True, shape=(n_chains, T)
295+
)
296+
pm.Normal("emission", mu=states, sigma=sigma, observed=obs)
297+
298+
marginal_m = marginalize(m, [states])
299+
300+
# The chains are independent, so brute force each one over its k**T paths and sum.
301+
expected = 0.0
302+
for b in range(n_chains):
303+
log_joint = []
304+
for s in itertools.product(range(k), repeat=T):
305+
lp = np.log(pi0[s[0]]) + sum(np.log(A_t[t - 1, s[t - 1], s[t]]) for t in range(1, T))
306+
lp += norm.logpdf(obs[b], loc=np.array(s), scale=sigma).sum()
307+
log_joint.append(lp)
308+
expected += logsumexp(log_joint)
309+
310+
np.testing.assert_allclose(marginal_m.compile_logp()({}), expected)
311+
312+
276313
# The higher-order (n_lags > 1) forward scan currently OOMs under the default numba backend
277314
# (a numba fast_run scan-lowering bug, not a logic issue; see numba_nlags2_repro.py). Compile the
278315
# logp under the C VM so these still verify correctness; drop the override once numba is fixed.

0 commit comments

Comments
 (0)