【发布时间】:2016-05-11 15:29:28
【问题描述】:
已修复:请参阅下面的更新代码。
这是我第一次尝试 Cython 并且有一个有效的构建,但它不允许 numpy 数组(向量)作为输入,这是我在这里的真正目的。它是 Black 模型(Black Scholes 用于没有股息的欧洲期权定价)。它只接受长度为 1 的数组作为输入(如果我尝试使用长度为 2 的数组进行计算,则会出错:TypeError: CyBlack() takes exactly 7 positional arguments (14 given),如果我传递长度为 10 的数组,(70 given) 等)。我不确定为什么我在 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,因此其他人可以构建此类型:python setup.py build_ext --inplace 为 Python 3.5 64 位 Windows 使用 VS2015 构建。
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 个值” - 你到底是什么意思?
-
“您必须将 numpy 数组传递给带有星号的函数” - 什么?你为什么这样做?那要么是你的全部问题,要么是你问题的很大一部分。向我们展示您传递的参数以及方法。
-
“您必须将 numpy 数组传递给带有星号的函数,以 *Black_PnL 为例” - 嗯,不!尝试将它们作为单独的参数传递。
-
ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long long'如果您只是在没有星号的情况下传递值,则结果。 -
好的,现在
ValueError表示您传递的是一个 int64 数组,而不是输入类型声明中指定的 float64