Cython编译模块不允许访问定义为'module'的函数不可调用

时间:2016-05-10 23:39:53

标签: python cython

发现原始错误 - > from CyBlack.CyBlack import CyBlack然后传递*numpy_value作为输入。出现了一个新问题,因此为此创建了一个新职位。 Cython program with numpy arrays does not allow vectorized inputs (only accepts length 1 arrays), how to fix?

我是Cython的新手,并尝试将Black(Black Scholes没有股票红利)从Python转换为Cython。在编译之后,它不会让我实际使用该函数。我相信拥有更多经验的人可以轻松地看到这一点并找出原因。编译和导入函数from CyBlack import CyBlack并调用CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput)后得到的错误是TypeError: 'module' object is not callable:所以这是代码:

from numpy cimport ndarray
cimport numpy as np
cimport cython

cdef extern from "math.h":
    double exp(double)
    double sqrt(double)
    double pow(double)
    double log(double)
    double erf(double)

cdef double std_norm_cdf(double x):
    return 0.5*(1+erf(x/sqrt(2.0)))

@cython.boundscheck(False)
cdef CyBlack(ndarray[np.float64_t, ndim=1] BlackPnL, ndarray[np.float64_t, ndim=1] Black_S, ndarray[np.float64_t, ndim=1] Black_Texpiry, ndarray[np.float64_t, ndim=1] Black_strike, ndarray [np.float64_t, ndim=1] Black_volatility, ndarray[np.float64_t, ndim=1] Black_IR, ndarray[np.float64_t, ndim=1] Black_callput):

    cdef Py_ssize_t i
    cdef Py_ssize_t N = BlackPnL.shape[0]
    cdef double d1, d2


    for i in range(N):
        d1 = ((log(Black_S[i] / Black_strike[i]) + Black_Texpiry[i] * Black_volatility[i] **2 / 2)) / (Black_volatility[i] * sqrt(Black_Texpiry[i]))
        d2 = d1 - Black_volatility[i] * sqrt(Black_Texpiry[i])
        BlackPnL[i] = exp(-Black_IR[i] * Black_Texpiry[i]) * (Black_callput[i] * Black_S[i] * std_norm_cdf(Black_callput[i] * d1) - Black_callput[i] * Black_strike[i] * std_norm_cdf(Black_callput[i] * d2)) 

    return BlackPnL

感谢您的帮助!如果你需要测试一些内容,我可以发布python假数据 - 虽然只是用任何数据调用它都会暴露错误......有些东西指向我没有从C代码中暴露给Python的变量。

在此处添加setup.py,以便其他人可以构建此类型:python setup.py build_ext --inplace使用VS2015构建,适用于Python 3.5 64位Windows。

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize("CyBlack.pyx"), include_dirs =["C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//include", "C://Program Files (x86)//Windows Kits//10//Include//10.0.1.0240.0//ucrt", "C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//lib//amd64", "C://Anaconda3//Lib//site-packages//numpy//core//include", "C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//lib//amd64"])

2 个答案:

答案 0 :(得分:2)

我设法得到(类似的东西)以下列方式工作:

C:/dev/tmp/CyBlack/
                   __init__.py
                   setup.py
                   CyBlack.pyx

CyBlack.pyx与您的CyBlack一样,cpdef函数除外setup.py' d。 from distutils.core import setup import numpy from Cython.Build import cythonize extra_compile_args = ['/EHsc', '/openmp', '/favor:INTEL64'] setup( ext_modules=cythonize("CyBlack.pyx"), include_dirs=['.', numpy.get_include()], extra_compile_args=extra_compile_args ) 包含:

C:\dev\tmp\CyBlack> python .\setup.py build_ext --compiler=msvc --inplace

然后跑:

C:/dev/tmp/CyBlack/CyBlack.pyd

将生成>>> from sys import path >>> path.insert(0, "C:/dev/tmp") >>> from CyBlack.CyBlack import CyBlack >>> CyBlack(*[np.array([1.0]) for _ in xrange(7)]) # I'm too lazy to put proper values here... array([ 0.14087021]) ,然后我设法从Python运行代码:

function normalizer() {
list=$(grep -n "STRING" $1 |cut -f1 -d:|wc -l)
coso=1
while [ $coso -le $list ];
    do
    direc=$(grep -n "STRING" $1 |cut -f1 -d:|head -$coso|tail -1)
    str=$(perl -wne "print if $. == ($direc - 6)" $1)
    if  [ "$str" == "STING 2" ]; then
            sed -i "${direc}s/STRING/DORSOC CARATR/" $1
        else if     [ "$str" == "STRING 3" ]; then
                sed -i "${direc}s/STRING/DORSOC CARATU/" $1
            else
                echo dont match
            fi
    fi
  let coso=$coso+1
 done
}

这是通过 Python 2.7 完成的,整体设置可能略有不同,但希望这可能有助于您获得最小的工作示例并追溯如何使您的正确运行。

答案 1 :(得分:-1)

而不是

from CyBlack import CyBlack

你为什么不这样做

import CyBlack