我回答了similar question previously。我在这里提到的很多东西(不计算每次迭代的当前可能性,预先计算随机创新等等)都可以在这里使用。在
实现的其他改进是不使用列表来存储示例。相反,您应该为样本预先分配内存,并将它们存储为数组。类似samples = np.zeros(n_samples)的方法比在每次迭代时追加到列表中更有效。在
你已经提到你试图通过不记录老化样本来提高效率。这是个好主意。您也可以通过只记录每m个样本来完成类似的细化操作,因为无论如何,您在return语句中使用np.array(sample_list)[::m]丢弃这些样本。你可以通过改变:# do not add burn-in samples
if n_sampled > burn_in:
sample_list.append(z)
到
^{pr2}$
还值得注意的是,您不需要计算min(1, p(cand) / p(z)),只需计算p(cand) / p(z),就可以逃脱惩罚。我意识到形式上min是必要的(以确保概率在0和1之间有界)。但是,计算上,我们不需要最小值,因为如果p(cand) / p(z) > 1,那么{}总是大于u。在
把这一切放在一起,并预先计算随机创新,接受概率u,只有在你真的需要我想出的时候才计算可能性:def my_Metropolis_Gaussian(p, z0, sigma, n_samples=100, burn_in=0, m=1):
# Pre-allocate memory for samples (much more efficient than using append)
samples = np.