5

実行速度が遅い Python / Numpy コードがいくつかありますが、これは double for ループを使用しているためだと思います。これがコードです。

def heat(D,u0,q,tdim):
    xdim = np.size(u0)
    Z = np.zeros([xdim,tdim])
    Z[:,0]=u0;
    for i in range(1,tdim):
        for j in range (1,xdim-1):
            Z[j,i]=Z[j,i-1]+D*q*(Z[j-1,i-1]-2*Z[j,i-1]+Z[j+1,i-1])
    return Z

double for ループを削除して Z をベクトル化しようとしています。これが私の試みです。

def heat(D,u0,q,tdim):
    xdim = np.size(u0)
    Z = np.zeros([xdim,tdim])
    Z[:,0]=u0;
    Z[1:,1:-1]=Z[1:-1,:-1]+D*q*(Z[:-2,:-1]-2*Z[1:-1,:-1]+Z[2:,:-1])
    return Z

これは機能しません。次のエラーが表示されます。

operands could not be broadcast together with shapes (24,73) (23,74)

そのため、Z をベクトル化しようとしてどこかで失敗しました。私のエラーを見つけるのを手伝ってもらえますか?

4

2 に答える 2

2

問題の時間次元でその拡散計算をベクトル化することはできず、それでもループが必要です。ここでの唯一の明らかな最適化は、ラプラシアン計算をnumpy.diff関数 (プリコンパイル済み C) の呼び出しに置き換えることです。したがって、熱方程式ソルバーは次のようになります。

def heat(D,u0,q,tdim): 
    xdim = np.size(u0) 
    Z = np.zeros([xdim,tdim]) 
    Z[:,0]=u0; 

    for i in range(1,tdim): 
        Z[1:-1,i]=Z[1:-1,i-1] + D*q*np.diff(Z[:,i-1], 2)

    return Z

自明でない空間サイズの場合、かなりの速度向上が見られるはずです。

于 2012-10-19T07:55:59.867 に答える
1

列 i の計算は列 i-1 に依存するため、両方の for ループを削除することはできません。列 i-1 は (コードの 2 番目のビットでは) 最初の列を除いてゼロです。

あなたができることは次のとおりです。

def heat(D,u0,q,tdim):
    xdim = np.size(u0)
    Z = np.zeros([xdim,tdim])
    Z[:,0]=u0;
    for i in range(1,tdim):
        Z[1:-1,i] = Z[1:-1,i-1] + D*q*(Z[:-2,i-1] - 2*Z[1:-1,i-1] + Z[2:,i-1])
    return Z

コードに戻るには: Z[1,1:-1] に (最初の項のみ) Z[1:-1,:-1] を入力しています。形状の不一致は、ここですぐにわかります。

2 番目のインデックスを無視して (とにかくループする必要があるため)、ベクトル化されたソリューションは、ベクトル化されていないアプローチとは異なる仮定を使用します: 最初のバージョンでは、1 つの辺 u0 (Z[:,0]) と 2 つの辺 0 ( Z[0,:] および Z[-1,:]) ベクトル化されたソリューションでは、Z[1:,i] を埋めることによって Z[-1,:] を 0 以外に設定しようとします。どの状況をシミュレートしようとしていますか?!

于 2012-10-19T07:59:29.163 に答える