FIXED: siehe aktualisierten Code unten.Cython-Programm mit numpy Arrays erlaubt keine vektorisierten Eingaben (akzeptiert nur Länge 1 Arrays), wie zu beheben?
Dies ist meine erste Cython-Versuch und haben einen funktionierenden Build, aber es erlaubt keine numpy Array (Vektoren) als Eingaben, das ist mein wirklicher Zweck hier. Es ist das Black-Modell (Black Scholes für europäische Optionspreise ohne Dividende). Es wird nur Arrays der Länge 1 als Eingaben akzeptieren (wenn ich versuche, mit Arrays der Länge 2 zu berechnen, sind es Fehler: TypeError: CyBlack() takes exactly 7 positional arguments (14 given)
, wenn ich Arrays der Länge 10 übergebe, (70 given)
, etc.). Ich bin nicht sicher, warum, wie ich im Cython-Code numpy Arrays definiert habe. Als Referenz Sie es mit dem folgenden Code kompilieren kann sie dann als solche verwendet werden: from CyBlack.CyBlack import CyBlack
dann CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput)
Also hier ist der Code der Rufnummer (speichern als CyBlack.pyx
Datei zu kompilieren):
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
Hier ist die setup.py
so andere können diese Typisierung bauen : python setup.py build_ext --inplace
mit VS2015 für Python 3.5 64bit Windows gebaut.
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)
Die oben kompiliert und funktioniert nach dem Update auf den Variablentyp mit (Black_callput war eigentlich ein int64
) und Sie haben die numpy Arrays zu übergeben, da sie (kein Stern) sind und es funktioniert einwandfrei.
* "Es wird immer nur 1 Wert berechnet" * - was genau meinst du damit? –
"Sie müssen die Nummernfelder mit einem Stern an die Funktion übergeben" - was? warum machen Sie das? Das ist entweder Ihr gesamtes Problem oder ein sehr großer Teil Ihres Problems. Zeigen Sie uns, welche Argumente Sie weitergeben und wie. – user2357112
* "Sie müssen die Nummernfelder an die Funktion mit einem Stern übergeben, * Black_PnL als Beispiel" * - uh, nein, Sie nicht! Übergeben Sie sie als separate Argumente. –