2016-05-10 7 views
1

ORIGINAL FEHLER GEFUNDEN ->from CyBlack.CyBlack import CyBlack dann pass *numpy_value als Eingänge. Ein neues Problem ist entstanden, indem ein neuer Beitrag dafür erstellt wird. Cython program with numpy arrays does not allow vectorized inputs (only accepts length 1 arrays), how to fix?Cython kompilierte Modul erlaubt keinen Zugriff auf die Funktion definiert "Modul" nicht aufrufbar

Ich bin neu bei Cython und habe versucht, die Black (Black Scholes ohne eine Aktiendividende) von Python nach Cython zu konvertieren. Nachdem ich es kompiliert habe, kann ich die Funktion nicht benutzen. Ich bin mir sicher, dass jemand mit mehr Erfahrung dies leicht sehen und herausfinden kann warum. Der Fehler ich nach dem Kompilieren und dem Import die Funktion from CyBlack import CyBlack und CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput) Aufruf ist TypeError: 'module' object is not callable: So, hier ist der Code:

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 

Vielen Dank für jede Hilfe hier! Ich kann gefälschte Python-Daten posten, wenn Sie etwas zum Testen benötigen - obwohl das Aufrufen von Daten den Fehler aufdeckt ... Etwas deutet darauf hin, dass die Variablen nicht von C-Code Python ausgesetzt sind.

Hinzufügen meiner setup.py hier, damit andere diese Typisierung erstellen können: 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 

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"]) 
+0

Es klingt, als ob dieses 'CyBlack'-Modul tatsächlich in ein' CyBlack'-Paket eingebettet sein könnte. Ihre 'CyBlack'-Funktion wird anstelle von cpdef 'angegeben, so dass sie durch keinen Python-Import zugänglich ist. – user2357112

+0

Ich cpdef es und immer noch das gleiche Problem ... – Matt

+0

Könnten Sie das Ergebnis von 'von CyBlack import CyBlack; Drucken (CyBlack .__ Datei __) '? Dies sollte den Pfad zu dem Modul ausgeben, das den Fehler verursacht. –

Antwort

2

konnte ich (so etwas wie es) in der folgenden Art und Weise arbeiten erhalten:

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

Wo CyBlack.pyx sind Sie gerade gefällt, außer mit CyBlack Funktion cpdef ‚d sein. setup.py enthält:

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 
) 

Lauf dann:

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

C:/dev/tmp/CyBlack/CyBlack.pyd produzieren, und ich schaffte es dann den Code aus Python ausführen:

>>> 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]) 

Das mit Python 2.7 getan wurde und das Setup könnte etwas anders sein, aber hoffentlich hilft das, ein funktionierendes Beispiel zu bekommen Verfolgen Sie, wie Sie Ihren Computer richtig laufen lassen.

+0

danke für die Veröffentlichung des laufenden Beispiels. Ich habe das vergrabene Modul zur gleichen Zeit wie zufällig gefunden. Das einzige Problem ist jetzt, dass die Funktion nicht erlaubt, dass numpy Vektoren verarbeitet werden (eine Art, die den Zweck einer internen Schleife zunichte macht), da ich dachte, dass dies der Punkt war, in dem numpy Array-Typen im Cython-Block deklariert wurden. – Matt

+0

Ich hatte Probleme, in 'nd' Vektoren auch zu gehen, die ich von der Verwendung der C' log' und 'sqrt' eher als der (vektorisierten) numpy kommen; nicht sicher, ob dies das ist, was es verursacht – val

+0

Ich habe die [i] Indexierung dem obigen Code hinzugefügt, der es erlauben sollte, dass jeweils 1 Wert an 'log' und' sqrt' übergeben wird, aber keine Hilfe. Ich denke, ich habe das in eine andere Frage geändert und sollte einfach deine Antwort akzeptieren und Teil 2 neu posten ... – Matt

-1

Statt

from CyBlack import CyBlack 

Warum gehst du nicht einfach tun

import CyBlack 

?

+0

Das ist tatsächlich, was ich zuerst versuchte ... funktioniert nicht. – Matt

+0

Ich vermute, es gibt wahrscheinlich ein Submodul/Funktion namens CyBlack im CyBlack-Modul. Wenn Sie also 'CyBlack' nur importiert haben, müssten Sie' CyBlack.CyBlack() 'wahrscheinlich immer dann verwenden, wenn Sie es im Code verwenden möchten, wenn es sich tatsächlich um eine Funktion handelt. – mjp

+0

Nein ... habe das auch probiert :) – Matt