Extended Monty Hall problem

As I was going through the pymc 4.0 tutorial, I thought I could extend the Monty Hall problem to having multiple doors and really observe the addition of the probabilities.
I started by defineing this helper function that report array of probabilities of left over doors at all scenario:

def left_over_door(num_of_doors: int = doors, chosen: int = 0) -> np.ndarray:
    res = np.zeros(shape=(num_of_doors, num_of_doors))
    np.fill_diagonal(res, val=1)
    res[chosen] = np.full(shape=(1, num_of_doors), fill_value = 1./(num_of_doors-1))
    res[chosen, chosen] = 0
    return res

then I proceed to the model inference, by using at.take instead of at.switch in the example.

doors = 3
with pm.Model() as monty_multiple_doors_model:
    # prior setup
    prize = pm.DiscreteUniform("prize", 0, doors-1, initval = 0)
    p_not_open = at.take(left_over_door(doors, chosen=0), indices=prize, axis=0)
    
    # likelihood
    not_opened = pm.Categorical('not_opened', p_not_open, observed=2)

however, the model failed at sampling step. Here’s the error:

IndexError                                Traceback (most recent call last)
IndexError: index out of bounds
Apply node that caused the error: Subtensor{int64}(TensorConstant{[[0.  0.5 .. 0.  1. ]]}, ScalarFromTensor.0)
Toposort index: 8
Inputs types: [TensorType(float64, matrix), Scalar(int64)]
Inputs shapes: [(3, 3), ()]
Inputs strides: [(24, 8), ()]
Inputs values: ['not shown', 4]
Outputs clients: [[Elemwise{ge,no_inplace}(Subtensor{int64}.0, TensorConstant{(1,) of 0}), Sum{acc_dtype=float64}(Subtensor{int64}.0), Elemwise{true_div,no_inplace}(Subtensor{int64}.0, InplaceDimShuffle{x}.0)]]
...
RuntimeError: Chain 0 failed.

I find it stange, 'cause the way I specify my model shouldn’t lead to any index error. Could it be the way I call the aesara API which lead to this? If it is, how should I fix/war my code to make the simulation work?

thanks.

The reason it failed during sample is that, PyMC assign Metropolis as sampler to the random variable prize, which can generate proposal out of the range [0, 2], which cause the index error.
Changing prize to

    ...
    prize = pm.Categorical("prize", np.ones(3)/3)

should work

2 Likes

thanks.
after implementing the solution, the sampler changed to CategoricalGibbsMetropolis. I guess, from what the name suggests, is a sampler that out-of-range proposals are never proposed.
and from the API, I think that at.switch (used in the example) can accept out-of-range proposals while the at.take I’ve used does not. so I think this concludes my problem.

1 Like