Skip to content

Commit e164f29

Browse files
aloctavodiaricardoV94
authored andcommitted
SMC: use non isometric proposal distribution in MH kernel
1 parent a16afa7 commit e164f29

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

pymc3/smc/smc.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,6 @@ def setup_kernel(self):
460460
Dimension specific scaling is provided by self.proposal_scales and set in self.tune()
461461
"""
462462
ndim = self.tempered_posterior.shape[1]
463-
self.proposal_dist = MultivariateNormalProposal(np.eye(ndim))
464463
self.proposal_scales = np.full(self.draws, min(1, 2.38 ** 2 / ndim))
465464

466465
def resample(self):
@@ -475,7 +474,7 @@ def tune(self):
475474
# Rescale based on distance to 0.234 acceptance rate
476475
chain_scales = np.exp(np.log(self.proposal_scales) + (self.chain_acc_rate - 0.234))
477476
# Interpolate between individual and population scales
478-
self.proposal_scales = 0.5 * chain_scales + 0.5 * chain_scales.mean()
477+
self.proposal_scales = 0.5 * (chain_scales + chain_scales.mean())
479478

480479
if self.tune_steps:
481480
acc_rate = max(1.0 / self.proposed, self.chain_acc_rate.mean())
@@ -485,6 +484,14 @@ def tune(self):
485484
)
486485
self.proposed = self.draws * self.n_steps
487486

487+
# Update MVNormal proposal based on the covariance of the tempered posterior.
488+
cov = np.cov(self.tempered_posterior, ddof=0, rowvar=0)
489+
cov = np.atleast_2d(cov)
490+
cov += 1e-6 * np.eye(cov.shape[0])
491+
if np.isnan(cov).any() or np.isinf(cov).any():
492+
raise ValueError('Sample covariances not valid! Likely "draws" is too small!')
493+
self.proposal_dist = MultivariateNormalProposal(cov)
494+
488495
def mutate(self):
489496
"""Metropolis-Hastings perturbation."""
490497
ac_ = np.empty((self.n_steps, self.draws))

0 commit comments

Comments
 (0)