Skip to content

Commit

Permalink
Merge 807c82f into 3b49770
Browse files Browse the repository at this point in the history
  • Loading branch information
eigenfoo committed Dec 5, 2019
2 parents 3b49770 + 807c82f commit 6e3263a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Currently Implemented
- Leapfrog integrator
- Hamiltonian Monte Carlo
- Some log probabilities (normal, multivariate normal, mixtures, funnel)
- Divergences

Roadmap
-------

- Divergences
- Mass matrix adaptation
- Diagnostics
- [NUTS](https://arxiv.org/abs/1111.4246)
Expand Down
23 changes: 17 additions & 6 deletions minimc/minimc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def hamiltonian_monte_carlo(
path_len=1,
initial_step_size=0.1,
integrator=leapfrog,
max_energy_change=1000.0,
):
"""Run Hamiltonian Monte Carlo sampling.
Expand All @@ -35,6 +36,9 @@ def hamiltonian_monte_carlo(
How long each integration path is. Smaller is faster and more correlated.
initial_step_size : float
How long each integration step is. This will be tuned automatically.
max_energy_change : float
The largest tolerable integration error. Transitions with energy changes
larger than this will be declared divergences.
Returns
-------
Expand Down Expand Up @@ -69,16 +73,23 @@ def hamiltonian_monte_carlo(
step_size=step_size,
)

# Check Metropolis acceptance criterion
start_log_p = np.sum(momentum.logpdf(p0)) - initial_potential
new_log_p = np.sum(momentum.logpdf(p_new)) - final_V
p_accept = min(1, np.exp(new_log_p - start_log_p))
if np.random.rand() < p_accept:
samples.append(q_new)
initial_potential = final_V
initial_potential_grad = final_dVdq
energy_change = new_log_p - start_log_p
p_accept = min(1, np.exp(energy_change))

if abs(energy_change) < max_energy_change:
# Check Metropolis acceptance criterion
if np.random.rand() < p_accept:
samples.append(q_new)
initial_potential = final_V
initial_potential_grad = final_dVdq
else:
samples.append(np.copy(samples[-1]))
else:
# Divergence encountered
samples.append(np.copy(samples[-1]))

if idx < tune - 1:
step_size, _ = step_size_tuning.update(p_accept)
elif idx == tune - 1:
Expand Down
23 changes: 15 additions & 8 deletions minimc/minimc_slow.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def hamiltonian_monte_carlo(
path_len=1,
step_size=0.1,
integrator=leapfrog,
max_energy_change=1000.0,
do_reject=True,
):
"""Run Hamiltonian Monte Carlo sampling.
Expand Down Expand Up @@ -72,15 +73,21 @@ def hamiltonian_monte_carlo(
momentum.logpdf(p0)
)
new_log_p = negative_log_prob(q_new) - np.sum(momentum.logpdf(p_new))
p_accept = np.exp(start_log_p - new_log_p)
if np.random.rand() < p_accept:
samples.append(q_new)
accepted.append(True)
else:
if do_reject:
samples.append(np.copy(samples[-1]))
else:
energy_change = start_log_p - new_log_p
p_accept = np.exp(energy_change)

if abs(energy_change) < max_energy_change:
if np.random.rand() < p_accept:
samples.append(q_new)
accepted.append(True)
else:
if do_reject:
samples.append(np.copy(samples[-1]))
else:
samples.append(q_new)
accepted.append(False)
else:
samples.append(np.copy(samples[-1]))
accepted.append(False)
p_accepts.append(p_accept)

Expand Down
8 changes: 4 additions & 4 deletions test/test_minimc.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def test_hamiltonian_monte_carlo(integrator):
100, neg_log_p, np.array(0.0), integrator=integrator
)
assert samples.shape[0] == 100
assert_allclose(2.0, np.mean(samples), atol=0.022)
assert_allclose(0.1, np.std(samples), atol=0.007)
assert_allclose(2.0, np.mean(samples), atol=0.1)
assert_allclose(0.1, np.std(samples), atol=0.1)


def test_hamiltonian_monte_carlo_mv():
Expand All @@ -78,5 +78,5 @@ def test_hamiltonian_monte_carlo_mv():
100, neg_log_p, np.zeros(mu.shape), path_len=2.0
)
assert samples.shape[0] == 100
assert_allclose(mu, np.mean(samples, axis=0), atol=0.13)
assert_allclose(cov, np.cov(samples.T), atol=0.17)
assert_allclose(mu, np.mean(samples, axis=0), atol=0.3)
assert_allclose(cov, np.cov(samples.T), atol=0.3)

0 comments on commit 6e3263a

Please sign in to comment.