Hi!
This is from the documentation (slightly changed) and works perfectly:
with pm.Model() as model:
x0 = pm.Categorical.dist(np.ones(2) / 2, size=(size,))
P = pm.Dirichlet("P", a=[1, 1], size=(2,))
discrete_mc = DiscreteMarkovChain("MarkovChain", P=P, init_dist=x0, observed=chains)
idata = pm.sample()
However, this does not work:
with pm.Model() as model:
x0 = pm.Categorical.dist(np.ones(2) / 2, size=(size,))
P = pm.Dirichlet("P", a=[1, 1], size=(2,))
discrete_mc = DiscreteMarkovChain("MarkovChain", P=P, init_dist=x0, steps=steps-1)
obs = pm.Normal('obs', mu=pm.math.switch(pm.math.eq(discrete_mc, 0), 0, 1), sigma=0.1, observed=chains)
idata = pm.sample()
Can anybody help me explain why this does not work? What can I do to fix it? Thank you!
Hopefully this is the correct place to ask this, I’m sorry if that is not the case.
The following are less important details:
The important part of the error is
ParallelSamplingError Traceback (most recent call last)
Cell In[31], line 7
5 obs = pm.Normal('obs', mu=pm.math.switch(pm.math.eq(discrete_mc, 0), 0, 1), sigma=0.1, observed=chains)
6 # discrete_mc = DiscreteMarkovChain("MarkovChain", P=P, init_dist=x0, observed=chains)
----> 7 idata = pm.sample()
File c:\Users\pasca\anaconda3\envs\tno\Lib\site-packages\pymc\sampling\mcmc.py:846, in sample(draws, tune, chains, cores, random_seed, progressbar, progressbar_theme, step, var_names, nuts_sampler, initvals, init, jitter_max_retries, n_init, trace, discard_tuned_samples, compute_convergence_checks, keep_warning_stat, return_inferencedata, idata_kwargs, nuts_sampler_kwargs, callback, mp_ctx, blas_cores, model, **kwargs)
844 _print_step_hierarchy(step)
845 try:
--> 846 _mp_sample(**sample_args, **parallel_args)
847 except pickle.PickleError:
848 _log.warning("Could not pickle model, sampling singlethreaded.")
File c:\Users\pasca\anaconda3\envs\tno\Lib\site-packages\pymc\sampling\mcmc.py:1259, in _mp_sample(draws, tune, step, chains, cores, random_seed, start, progressbar, progressbar_theme, traces, model, callback, blas_cores, mp_ctx, **kwargs)
1257 try:
1258 with sampler:
-> 1259 for draw in sampler:
1260 strace = traces[draw.chain]
1261 strace.record(draw.point, draw.stats)
File c:\Users\pasca\anaconda3\envs\tno\Lib\site-packages\pymc\sampling\parallel.py:471, in ParallelSampler.__iter__(self)
464 task = progress.add_task(
465 self._desc.format(self),
466 completed=self._completed_draws,
467 total=self._total_draws,
468 )
470 while self._active:
--> 471 draw = ProcessAdapter.recv_draw(self._active)
472 proc, is_last, draw, tuning, stats = draw
473 self._completed_draws += 1
File c:\Users\pasca\anaconda3\envs\tno\Lib\site-packages\pymc\sampling\parallel.py:338, in ProcessAdapter.recv_draw(processes, timeout)
336 else:
337 error = RuntimeError(f"Chain {proc.chain} failed.")
--> 338 raise error from old_error
339 elif msg[0] == "writing_done":
340 proc._readable = True
IndexError: index 2 is out of bounds for axis 0 with size 2
Apply node that caused the error: AdvancedSubtensor(LogSoftmax{axis=1}.0, Subtensor{start:stop}.0, Subtensor{start:}.0)
Toposort index: 34
Inputs types: [TensorType(float64, shape=(2, 2)), TensorType(int64, shape=(99,)), TensorType(int64, shape=(99,))]
Inputs shapes: [(2, 2), (99,), (99,)]
Inputs strides: [(16, 8), (8,), (8,)]
Inputs values: [array([[-0.01639124, -4.11919274],
[-0.77331141, -0.61893506]]), 'not shown', 'not shown']
Outputs clients: [[Sum{axes=None}(AdvancedSubtensor.0)]]
The code for initialization is
import arviz as az
import numpy as np
import pymc as pm
import pytensor
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
from matplotlib import ticker as mtick
from pymc_experimental.distributions.timeseries import DiscreteMarkovChain
true_P = np.array([[0.6, 0.4], [0.4, 0.6]])
def generate_chains(P, steps, n_chains=1):
output = np.empty((n_chains, steps), dtype="int64")
x0 = pm.draw(pm.Categorical.dist(p=[0.5, 0.5], shape=(n_chains,)))
output[:, 0] = x0
for t in range(1, steps):
output[:, t] = [
np.random.choice(range(P.shape[0]), p=P[output[i, t - 1]].ravel()).astype(int)
for i in range(n_chains)
]
return output.squeeze()
steps = 100
chains = generate_chains(true_P, steps, n_chains=100)