3

Cython を学習して、計算の一部を高速化しようとしています。これは、私がやろうとしていることのサブセットです。これは、NumPy 配列を利用しながら、再帰式を使用して微分方程式を単純に統合することです。私はすでに、純粋な python バージョンよりも約 100 倍の速度向上を達成しています。-aただし、 cython コマンドによってコード用に生成された HTML ファイルを見ると、速度が向上するようです。私のコードは次のとおりです(HTMLファイルで黄色になり、白にしたい行にラベルが付けられています):

%%cython
import numpy as np
cimport numpy as np
cimport cython
from libc.math cimport exp,sqrt

@cython.boundscheck(False)
cdef double riccati_int(double j, double w, double h, double an, double d):
    cdef:
        double W
        double an1
    W = sqrt(w**2 + d**2)
    #dark_yellow
    an1 = ((d - (W + w) * an) * exp(-2 * W * h / j ) - d - (W - w) * an) / 
          ((d * an - W + w) * exp(-2 * W * h / j) - d * an - W - w) 
    return an1


def acalc(double j, double w):
    cdef:
        int xpos, i, n
        np.ndarray[np.int_t, ndim=1] xvals
        np.ndarray[np.double_t, ndim=1] h, a
    xpos = 74
    xvals = np.array([0, 8, 23, 123, 218], dtype=np.int)     #dark_yellow
    h = np.array([1, .1, .01, .1], dtype=np.double)          #dark_yellow
    a = np.empty(219, dtype=np.double)                       #dark_yellow
    a[0] = 1 / (w + sqrt(w**2 + 1))                          #light_yellow

    for i in range(h.size):                                  #dark_yellow
        for n in range(xvals[i], xvals[i + 1]):              #light_yellow
            if n < xpos:
                a[n+1] = riccati_int(j, w, h[i], a[n], 1.)   #light_yellow
            else:
                a[n+1] = riccati_int(j, w, h[i], a[n], 0.)   #light_yellow
    return a  

上記でラベル付けした 9 行すべてを適切な調整で白くできるように思えます。1 つの問題は、NumPy 配列を適切な方法で定義する機能です。しかし、おそらくもっと重要なのは、ラベル付けされた最初の行を効率的に機能させる能力です。これは、計算の大部分が行われる場所だからです。黄色い線をクリックした後に HTML ファイルが表示する、生成された C コードを読んでみましたが、正直、そのコードの読み方がわかりません。誰かが私を助けてくれれば、それは大歓迎です。

4

2 に答える 2

0

それが違いを生むかどうかはわかりませんが、配列にメモリビューを使用できます。

cdef double [:] h = np.array([1, .1, .01, .1], dtype=np.double) #dark_yellow
cdef double [:] a = np.empty(219, dtype=np.double)              #dark_yellow

また、4 つの静的な値に対して numpy 配列を作成するのは少しやり過ぎです。これは、静的 C 配列に置き換えることができます

cdef double *h = [1, .1, .01, .1]

ただし、前述のように、ループの内容が最も重要です。ライン プロファイラーは cython (afaik) では機能しないため、timeモジュールを使用して関数内でベンチマークを実行しますcProfile。cython ログの線の色の強度は、コンテキストで評価する必要があるという考えが得られるかもしれません。

私が学んだように、インデックス作成には python 型を使用することをお勧めします

size_t i, n
Py_ssize_t i, n

2枚目はサイン入りバージョン

于 2014-01-08T20:37:56.943 に答える