Skip to content

Commit

Permalink
Explain difference between BinaryMetropolis and BinaryGibbsMetropolis
Browse files Browse the repository at this point in the history
Also test assignment of variables in BinaryMetropolis
  • Loading branch information
ricardoV94 committed Nov 25, 2024
1 parent 0082409 commit 725b5de
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
15 changes: 15 additions & 0 deletions pymc/step_methods/metropolis.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,13 @@ class BinaryMetropolisState(StepMethodState):
class BinaryMetropolis(ArrayStep):
"""Metropolis-Hastings optimized for binary variables.
Unlike BinaryGibbsMetropolis, this step sampler proposes changes for all variable dimensions at once.
This will perform a single logp evaluation per step, at the expense of a lower acceptance rate when
the posterior of the binary variable dimensions is very correlated.
The BinaryGibbsMetropolis (not this one) in the default step sampler for binary variables
Parameters
----------
vars: list
Expand Down Expand Up @@ -489,6 +496,14 @@ class BinaryGibbsMetropolisState(StepMethodState):
class BinaryGibbsMetropolis(ArrayStep):
"""A Metropolis-within-Gibbs step method optimized for binary variables.
Unlike BinaryMetropolis, this step sampler proposes a variable dimension change at a time.
This will increase acceptance rate when the posterior of the binary variable demensions is very correlated,
at the expense of doing more logp evaluations per step.
This is the default step sampler for binary variables.
Parameters
----------
vars: list
Expand Down
15 changes: 7 additions & 8 deletions tests/step_methods/test_metropolis.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,22 +356,21 @@ def test_step_continuous(self, step_fn, draws):

class TestRVsAssignmentMetropolis(RVsAssignmentStepsTester):
@pytest.mark.parametrize(
"step, step_kwargs",
"step",
[
(BinaryGibbsMetropolis, {}),
(CategoricalGibbsMetropolis, {}),
BinaryMetropolis,
BinaryGibbsMetropolis,
CategoricalGibbsMetropolis,
],
)
def test_discrete_steps(self, step, step_kwargs):
def test_discrete_steps(self, step):
with pm.Model() as m:
d1 = pm.Bernoulli("d1", p=0.5)
d2 = pm.Bernoulli("d2", p=0.5)

with pytensor.config.change_flags(mode=fast_unstable_sampling_mode):
assert [m.rvs_to_values[d1]] == step([d1], **step_kwargs).vars
assert {m.rvs_to_values[d1], m.rvs_to_values[d2]} == set(
step([d1, d2], **step_kwargs).vars
)
assert [m.rvs_to_values[d1]] == step([d1]).vars
assert {m.rvs_to_values[d1], m.rvs_to_values[d2]} == set(step([d1, d2]).vars)

@pytest.mark.parametrize(
"step, step_kwargs", [(Metropolis, {}), (DEMetropolis, {}), (DEMetropolisZ, {})]
Expand Down

0 comments on commit 725b5de

Please sign in to comment.