【问题标题】:Numpy , OOP and callablesNumpy、OOP 和可调用对象
【发布时间】:2020-08-29 01:17:58
【问题描述】:

我正在实现一个带有 Metropolis 和 barkes alpha 的马尔可夫链 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,但我不知道为什么它说它不可调用。

【问题讨论】:

  • 可调用对象类似于函数或方法,可使用foo(...) 语法。你认为alpha 应该是什么,你打算用这个表达什么?
  • alpha 被重新分配,调用函数的结果......
  • @juanpa.arrivillaga,我把变量名改成了al,我也想过,但我不知道为什么没有成功

标签: numpy oop scipy scipy.stats


【解决方案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 循环(代码的“稍后”部分)中,将此函数的返回值分配给名为@987654324的变量 @。

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

如果它不会妨碍您的程序逻辑(似乎没有),则可以将变量重命名为其他好听的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多