gpt4 book ai didi

python - 具有 numpy 数组的 Cython 程序不允许矢量化输入(仅接受长度为 1 的数组),如何修复?

转载 作者:行者123 更新时间:2023-11-30 22:56:00 25 4
gpt4 key购买 nike

已修复:请参阅下面更新的代码。

这是我的第一次 Cython 尝试,并且有一个工作构建,但它不允许 numpy 数组(向量)作为输入,这是我在这里的真正目的。这就是布莱克模型(Black Scholes,用于无股息的欧洲期权定价)。它只接受长度为 1 的数组作为输入(如果我尝试使用长度为 2 的数组进行计算,则会出错:TypeError: CyBlack() 恰好需要 7 个位置参数(给定 14 个),如果我传递长度为 10 的数组、(给定 70 个) 等)。我不确定为什么,因为我在 Cython 代码中定义了 numpy 数组。作为引用,您可以使用以下代码对其进行编译,然后按如下方式使用:from CyBlack.CyBlack import CyBlack 然后调用 CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput) 这是代码(保存为 CyBlack.pyx 文件进行编译):

from numpy cimport ndarray
cimport numpy as np
cimport cython

cdef extern from "math.h":
double exp(double)
double sqrt(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)
cpdef 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.int64_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

这里是 setup.py,以便其他人可以构建此类型:使用 VS2015 为 Python 3.5 64 位 Windows 构建的 python setup.py build_ext --inplace

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

extra_compile_args = ['/EHsc', '/openmp', '/favor:INTEL64']

setup(
ext_modules=cythonize("CyBlack.pyx"),
include_dirs=['.', numpy.get_include()],
extra_compile_args=extra_compile_args)

上面的代码在使用变量类型修复后编译并工作(Black_callput 实际上是一个 int64),并且您必须按原样传递 numpy 数组(无星号)并且它可以正常工作。

最佳答案

这里有两个问题:

  1. TypeError:CyBlack() 恰好需要 7 个位置参数(给定 14 个)

    这是由于您使用 *(“splat”)运算符解压输入数组而导致的。您需要将它们作为 7 个单独的参数传递。

  2. ValueError:缓冲区数据类型不匹配,预期为“float64_t”,但得到“long long”:

    此错误告诉您输入数组之一的 C 类型为 long long(这是一个 64 位整数),而不是中指定的 float64_t您的输入类型声明。您需要将所有输入数组转换为 np.float64

关于python - 具有 numpy 数组的 Cython 程序不允许矢量化输入(仅接受长度为 1 的数组),如何修复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37167147/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com