1

我正在实现一个带有 Metropolis 和 barkes alpha 的 Markov Chain Montecarlo 用于数值积分。我创建了一个名为MCMCIntegrator(). 我已经为它加载了一些属性,其中之一是我们试图集成的函数(一个 lambda)的 pdf g

import numpy as np
import scipy.stats as st


class MCMCIntegrator:

    def __init__(self):

        self.g = lambda x: st.gamma.pdf(x, 0, 1, scale=1 / 1.23452676)*np.abs(np.cos(1.123454156))
        self.size = 10000
        self.std = 0.6
        self.real_int = 0.06496359

这个类中还有其他方法,size是类必须生成的样本大小,std是 Normal Kernel 的标准差,您将在几秒钟内看到。是我们正在积分的real_int函数从 1 到 2 的积分值。我用 R 脚本生成了它。现在,问题。

 def _chain(self, method=None):

        """
            Markov chain heat-up with burn-in

        :param method: Metrpolis or barker alpha
        :return: np.array containing the sample
        """
        old = 0
        sample = np.zeros(int(self.size * 1.5))
        i = 0

        if method:
            def alpha(a, b): return min(1, self.g(b) / self.g(a))

        else:
            def alpha(a, b): return self.g(b) / (self.g(a) + self.g(b))

        while i != len(sample):
            if new < 0:
                new = st.norm(loc=old, scale=self.std).rvs()
            alpha = alpha(old, new)
            u = st.uniform.rvs()

            if alpha > u:
                sample[i] = new
                old = new
                i += 1

        return np.array(sample)

当我调用该_chain()方法时,这是以下错误:


     44         while i != len(sample):
     45             new = st.norm(loc=old, scale=self.std).rvs()
---> 46             alpha = alpha(old, new)
     47             u = st.uniform.rvs()
     48 

TypeError: 'numpy.float64' object is not callable


alpha 返回一个 nnumpy.float,但我不知道为什么它说它不可调用。

4

1 回答 1

1

alpha您在代码的“早期”部分定义了一个基于某些条件命名的方法:

if method:
    def alpha(a, b): return min(1, self.g(b) / self.g(a))

else:
    def alpha(a, b): return self.g(b) / (self.g(a) + self.g(b))

然后在while循环中(代码的“稍后”部分),将此函数的返回分配给名为alpha.

由于这两个对象的名称相同,并且该变量已在代码中稍后声明,因此在创建此变量后没有在任何地方重新声明该函数,因此该变量替换了命名空间中的函数,现在您无法进行调用不再alpha,因为它已不再是一种功能。

如果它不是您的程序逻辑的障碍(似乎不是),那么将变量重命名为其他一些好听的名称就可以了。

于 2020-05-13T06:08:51.567 回答