@@ -460,7 +460,6 @@ def setup_kernel(self):
460
460
Dimension specific scaling is provided by self.proposal_scales and set in self.tune()
461
461
"""
462
462
ndim = self .tempered_posterior .shape [1 ]
463
- self .proposal_dist = MultivariateNormalProposal (np .eye (ndim ))
464
463
self .proposal_scales = np .full (self .draws , min (1 , 2.38 ** 2 / ndim ))
465
464
466
465
def resample (self ):
@@ -475,7 +474,7 @@ def tune(self):
475
474
# Rescale based on distance to 0.234 acceptance rate
476
475
chain_scales = np .exp (np .log (self .proposal_scales ) + (self .chain_acc_rate - 0.234 ))
477
476
# 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 () )
479
478
480
479
if self .tune_steps :
481
480
acc_rate = max (1.0 / self .proposed , self .chain_acc_rate .mean ())
@@ -485,6 +484,14 @@ def tune(self):
485
484
)
486
485
self .proposed = self .draws * self .n_steps
487
486
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
+
488
495
def mutate (self ):
489
496
"""Metropolis-Hastings perturbation."""
490
497
ac_ = np .empty ((self .n_steps , self .draws ))
0 commit comments