2016-04-16 167 views
3

我試圖避免使用for循環來運行我的計算。但我不知道該怎麼做。我有一個矩陣w形狀(40,100)。每條線在t時間內持有波浪位置。例如,第一行w[0]是初始條件(因爲我將顯示的原因,也是w[1])。優化嵌套for循環

要計算下一行的元素我用,爲每一位tx的形狀範圍:

w[t+1,x] = a * w[t,x] + b * (w[t,x-1] + w[t,x+1]) - w[t-1,x] 

ab是基於方程解的一些常量(它其實並不重要),a = 2(1-r)b=rr=(c*(dt/dx))**2。其中c是波速和dt,dxxt方向上的增量有關。

有什麼辦法避免for循環,如:

for t in range(1,nt-1): 
    for x in range(1,nx-1): 
     w[t+1,x] = a * w[t,x] + b * (w[t,x-1] + w[t,x+1]) - w[t-1,x] 

ntnxw矩陣的形狀。

+1

我會建議你看看[本教程(https://開頭github上。com/barbagroup/CFDPython)用於在Python中實現偏微分方程(在本例中爲Navier-Stokes)。 –

+0

非常感謝@RolandSmith。 – Lin

回答

5

我假設你事先設置了w[:,0]w[:-1](對於某些常量?),因爲我沒有在循環中看到它。 如果是這樣,就可以消除for x循環矢量化的這部分代碼:

for t in range(1,nt-1): 
    w[t+1,1:-1] = a*w[t,1:-1] + b*(w[t,:-2] + w[t,2:]) - w[t-1,1:-1] 
0

不是。如果你想爲矩陣中的每個元素(你所做的)做一些事情,你將不得不以某種方式對每個元素進行操作(最明顯的方法就是使用for循環,不太明顯的方法要麼執行相同或更差)。

如果你想避免循環,因爲循環速度慢,知道有時循環是需要來解決某種問題。但是,有很多方法可以使循環更有效率。

通常在這樣的矩陣問題中,您在查看相鄰元素時,一個很好的解決方案是使用某種動態編程或記憶(保存工作以便不必頻繁重複計算)。就像,假設每一個元素你都想要取其平均值及其周圍的所有東西(這就是模糊圖像的工作原理)。每個像素有8個鄰居,所以平均值將是總和/ 9。那麼,假設您保存列的總和(保存NW + W + SW,N + me + S,NE + E + SE)。那麼當你進入下一個右邊時,只需將前一箇中間列的值,前一個最後一列和新列的值(右邊的新值)相加即可。你只需要添加9個數字加上5就可以了。在比加法更復雜的操作中,將9減少到5可能意味着巨大的性能提升。

我看着你要做的事情,我想不出有什麼辦法像我剛剛描述的那樣。但看看你能否想到類似的東西。

此外,請記住乘法比加法昂貴得多。所以,如果你有一個循環,例如,你必須乘以循環變量的一些數字,而不是做1x,2x,3x,...,你可以做(​​上次+ x值)。

+1

'numpy'的特點之一是它的運算符和函數按照數組的元素進行操作。這使得這些任務更容易編寫。在引擎蓋下,這是作爲一個循環來實現的,但是在C而不是Python *中,使它快了很多。 –