2012-04-02 6 views
3

Numpyにはcインターフェースをcythonに宣言する基本的なpxdがあります。 scipyコンポーネント(特にscipy.integrate.quadpack)用のpxdはありますか?scipy.integrate.quadpack(またはscipyの他のc/fortran)をcythonからcとして直接使用する

また、誰かがcythonからscipyに含まれるc/fortran関数と直接リンクする方法の例を挙げることができますか?これまで私はいつもpyximportを使っています...それはここで働くのでしょうか、あるいはdistutilsを使ってリンクする必要がありますか?

ありがとうございます!

----更新日----

下記のcythonコードがコンパイルされます。しかし、私は、だから私は、私が実際にscipy.integrateで_quadpack.soにFORTRAN QDAGSEの私の参照を「ポインティング」に私の問題に焦点を当てたと思う

ImportError: Building module failed: ['ImportError: dlopen(/Users/shauncutts/.pyxbld/lib.macosx-10.7-intel-2.7/factfiber/stat/pmodel/c/meer.so, 2): Symbol not found: _DQAGSE\n Referenced from: /Users/shauncutts/.pyxbld/lib.macosx-10.7-intel-2.7/factfiber/stat/pmodel/c/meer.so\n Expected in: flat namespace\n in /Users/shauncutts/.pyxbld/lib.macosx-10.7-intel-2.7/factfiber/stat/pmodel/c/meer.so\n']

を取得します。 (N.B.は小文字版も試しました)...そこにpxdを置くことによってscipyをハックする必要はありません。私はこれを行うことができる方法はありますか?おそらく動的に? (私はおそらく、動的にする.soをロードして、グローバル変数に適切な関数ポインタをバインドすることはできますか?)に

cdef extern from "stdlib.h": 
    void free(void* ptr) 
    void* malloc(size_t size) 
    void* realloc(void* ptr, size_t size) 


ctypedef double (*qagfunc)(double*) 

cdef extern: 
    # in scipy.integrate._quadpack 
    cdef void dqagse(
     qagfunc f, double *a, double *b, double *epsabs, double *epsrel, 
     int *limit, 
     double *result, double *abserr, int *neval, int *ier, 
     double *alist, double *blist, double *rlist, double *elist, 
     int *iord, int *last 
     ) 

class QAGError(ValueError): 
    code = None 

cdef double qags( 
    qagfunc quad_function, double a, double b, 
    double epsabs=1.49e-8, double epsrel=1.49e-8, 
    int limit = 50 
    ): 

    ''' 
    wrapper for QUADPACK quags/quagse 
    ''' 
    cdef double result, abserr 
    cdef int neval = 0, ier = 0, last = 0 
    cdef int *iord = <int *>malloc(limit * sizeof(double)) 
    cdef double *alist = <double *>malloc(limit * sizeof(double)) 
    cdef double *blist = <double *>malloc(limit * sizeof(double)) 
    cdef double *rlist = <double *>malloc(limit * sizeof(double)) 
    cdef double *elist = <double *>malloc(limit * sizeof(double)) 

    try: 
     DQAGSE(
      quad_function, &a, &b, &epsabs, &epsrel, &limit, 
      &result, &abserr, &neval, &ier, 
      alist, blist, rlist, elist, iord, &last); 

    finally: 
     free(iord) 
     free(alist) 
     free(blist) 
     free(rlist) 
     free(elist) 

    if ier > 0: 
     raise QAGError(QUAGS_IER_MAP[ ier ]) 
    return result 
+0

私はscipyディストリビューションで__quadpack.hを見つけました。 ...私は(私が避けたいPython関数のラッピングを除いて)、作業配列などを設定しています。これを行う例は必要ありません(もちろん書かれていればいいと思いますが) 。私が理解できない基本的なことは、_quadpack.so内のシンボルを参照するだけでリンクできるようにすることです。言い換えれば、私の本質的な質問はより一般的です:pxdやその他の参照がない場合、Python拡張モジュールでc関数を使う方法は?私は "cdef extern"を使用しようとしましたが、正しい形式を見つけられませんでした。 – shaunc

答えて

3

ありがとう:http://codespeak.net/pipermail/cython-dev/2009-October/007239.html

の適応を、以下では動作しているようです。この先頭に追加して

from os import path 
import ctypes 

from scipy.integrate import quadpack 

ctypedef double (*qagfunc)(double*) 

ctypedef void (*quadpack_qagse_fp)( 
    qagfunc f, double *a, double *b, double *epsabs, double *epsrel, 
    int *limit, 
    double *result, double *abserr, int *neval, int *ier, 
    double *alist, double *blist, double *rlist, double *elist, 
    int *iord, int *last 
    ) 

quadpack_path = path.dirname(quadpack.__file__) 
quadpack_ext_path = path.join(quadpack_path, '_quadpack.so') 
quadpack_lib = ctypes.CDLL(quadpack_ext_path) 

cdef quadpack_qagse_fp quadpack_qagse 
quadpack_qagse = ( 
    <quadpack_qagse_fp*><size_t> ctypes.addressof(quadpack_lib.dqagse_))[ 0 ] 

、上記のコードが動作しているようです...よくことを除いて、うるさく十分、答えはPythonのクワッドよりも少し異なっている、ともQUADPACK dblquad(私は二重積分を評価しています)。私はさらに解像度が必要か、またはデフォルト以外の値でパラメータを指定する必要があると思います。 (でも、おそらくWindowsには移植されませんが、それは単に ".so"を ".dll"に変更することを意味します)

これはPythonコールバックを使用した以前のコードから5倍のスピードです。私が得ることができるように最適化された。

余分なクレジットについて...私はどのようにしてCのコールバックに余分なパラメータを混入しますか?グローバル変数なしでは不可能だと私は想定していますか?または私は織りを使用することができますか?

いずれにしても、あなたの注意に感謝します。これはあいまいな例ですが、拡張モジュールの宣言されていないc関数をcythonから呼び出す方が一般的です。もし誰かがもっと優雅なやり方をしていれば、私は聞くことを熱望しています。

関連する問題