如何将Cython与PyMC3结合使用?

时间:2019-06-25 03:53:33

标签: python python-3.x cython pymc3 pymc

对于我正在编写的某些PyMC3代码,我定义了一个DensityDist,并使用自定义函数来评估点x处的概率密度。

此自定义函数是用Cython编写的,因为它可以将速度提高100倍。但是,当我尝试运行代码时,我看到了令人恐惧的...

    TypeError: must be real number, not TensorVariable

我制作了该功能的非Cython版本(可以很好地与PyMC3配合使用),但它大约是Cython版本的1/100。

简而言之,我希望函数的运行速度不低于Cython速度的50%。完全不能接受以Cython速度的1%运行。

我已经在Google上搜索了“带有pymc3的cython”,但发现有用的材料很少。我不确定如何实现这种速度提升。请帮忙。

以下是相关功能的Cython实现:

   cdef double singlePrecompVcdfe(double x, double h, int n, double *data_array, double *lambdaArray):
       cdef double tmp
       cdef double sumTerm = 0.
       for k in range(n):
           x_k = data_array[k]
           tmp = (x - x_k) / (h * lambdaArray[k])
           sumTerm += 0.5 * erfc(-tmp * M_SQRT1_2);

       # Compute F_Hat
       cdef double F_Hat = (1. / (<double>n)) * sumTerm

       # Return F_Hat
       return(F_Hat)

这是该函数的Python实现:

    def singlePrecompVcdfe(self, x, h, data_list, lambdaList):
        n = len(data_list)
        sumTerm = 0.
        for k in range(n):
            x_k = data_list[k]
            tmp = (x - x_k) / (h * lambdaList[k])
            # erfc = 1 - erf
            sumTerm += 0.5 * (1. - pymc3.math.erf(-tmp * self.sqrt1_2))

        # Compute F_Hat
        F_Hat = (1. / float(n)) * sumTerm

        # Return F_Hat
        return(F_Hat)

该函数的用法如下...

   def helperFunc(X):
       h = 0.5
       data = <DATA>
       lambdas = <LAMBDAS>
       return(myObj.singlePrecompVcdfe(X, h, data, lambdas))

    with pymc3.Model() as model:
        # Create likelihood
        like = pymc3.DensityDist('X', helperFunc, shape=1)

        # Make samples
        step = pymc3.NUTS()
        trace = pymc3.sample(2000, tune=1000, init=None, step=step, cores=2)

以下是某些情况下的错误:

    File "vkde.pyx", line 635, in vkde.vkdEstimator.VCDFE
    return(singlePrecompVcdfe(x, self.__h, self.__n, myCopy(self.__data_list), 
    TypeError: must be real number, not TensorVariable

如果不清楚,我正在运行Python3(3.7.2)。

0 个答案:

没有答案