最初にデータを補間してサーフェスを作成することにより、二重積分を実行しようとしています。numba を使用してこのプロセスを高速化しようとしていますが、時間がかかりすぎます。
これが私のコードで、コードを実行するために必要な画像はhereとhereにあります。
最初にデータを補間してサーフェスを作成することにより、二重積分を実行しようとしています。numba を使用してこのプロセスを高速化しようとしていますが、時間がかかりすぎます。
これが私のコードで、コードを実行するために必要な画像はhereとhereにあります。
あなたのコードには 4 重にネストされた一連の for ループがあることに注意して、内側のペアの最適化に焦点を当てました。古いコードは次のとおりです。
for i in xrange(K.shape[0]):
for j in xrange(K.shape[1]):
print(i,j)
'''create an r vector '''
r=(i*distX,j*distY,z)
for x in xrange(img.shape[0]):
for y in xrange(img.shape[1]):
'''create an ksi vector, then calculate
it's norm, and the dot product of r and ksi'''
ksi=(x*distX,y*distY,z)
ksiNorm=np.linalg.norm(ksi)
ksiDotR=float(np.dot(ksi,r))
'''calculate the integrand'''
temp[x,y]=img[x,y]*np.exp(1j*k*ksiDotR/ksiNorm)
'''interpolate so that we can do the integral and take the integral'''
temp2=rbs(a,b,temp.real)
K[i,j]=temp2.integral(0,n,0,m)
K と img はそれぞれ約 2000x2000 であるため、最も内側のステートメントを 16 兆回実行する必要があります。これは Python を使用して単純に実用的ではありませんが、NumPy を使用してベクトル化する C や Fortran に作業を移すことができます。結果が一致することを確認するために、この手順を一度に 1 つずつ慎重に実行しました。これが私が最終的に得たものです:
'''create all r vectors'''
R = np.empty((K.shape[0], K.shape[1], 3))
R[:,:,0] = np.repeat(np.arange(K.shape[0]), K.shape[1]).reshape(K.shape) * distX
R[:,:,1] = np.arange(K.shape[1]) * distY
R[:,:,2] = z
'''create all ksi vectors'''
KSI = np.empty((img.shape[0], img.shape[1], 3))
KSI[:,:,0] = np.repeat(np.arange(img.shape[0]), img.shape[1]).reshape(img.shape) * distX
KSI[:,:,1] = np.arange(img.shape[1]) * distY
KSI[:,:,2] = z
# vectorized 2-norm; see http://stackoverflow.com/a/7741976/4323
KSInorm = np.sum(np.abs(KSI)**2,axis=-1)**(1./2)
# loop over entire K, which is same shape as img, rows first
# this loop populates K, one pixel at a time (so can be parallelized)
for i in xrange(K.shape[0]):
for j in xrange(K.shape[1]):
print(i, j)
KSIdotR = np.dot(KSI, R[i,j])
temp = img * np.exp(1j * k * KSIdotR / KSInorm)
'''interpolate so that we can do the integral and take the integral'''
temp2 = rbs(a, b, temp.real)
K[i,j] = temp2.integral(0, n, 0, m)
ループの内側のペアは完全になくなり、前もって実行されたベクトル化された演算に置き換えられました (スペース コストは入力のサイズに比例します)。
これにより、 Numba を使用せずに、Macbook Air 1.6 GHz i5 で外側の 2 つのループの反復あたりの時間が 340 秒から 1.3 秒に短縮されます。反復あたり 1.3 秒のうち、0.68 秒がrbs
関数に費やされscipy.interpolate.RectBivariateSpline
ます。おそらく、さらに最適化する余地があります。いくつかのアイデアを次に示します。
今のところは以上です。これはあなたをどこに置きますか?わずかに優れたコンピューターで、それ以上の最適化作業がないと仮定すると、最適化されたコードでさえ、テスト画像を処理するのに約 1 か月かかります。これを一度だけ行う必要がある場合は、おそらくそれで問題ありません。より頻繁に実行する必要がある場合、またはさまざまなことを試すときにコードを反復する必要がある場合は、最適化を続ける必要があります。現在半分以上の時間を消費している RBS 関数から始めます。
k
おまけのヒント:とのようなほぼ同一の変数名がなく、変数名としても複素数接尾辞 ( ) としてK
も使用されていない場合、コードははるかに扱いやすくなります。j
0j