簡體   English   中英

當每個循環讀取最后一個循環的結果時優化Python循環

[英]Optimizing Python loop when each loop reads the result of last loop

應該優化由兩個循環(外部和內部)組成的函數-理想情況下是用N​​umpy函數替換Python循環。 可以輕松優化內部循環(變量inner_loop ),但是也可以更改外部循環嗎?

問題是inner_loop讀取向量U ,在每個外部循環中都更改了它的一個元素。 如果我使用匹配的Numpy函數優化外循環,則會丟失“遞歸”元素(更新U[i] )。

for i in (y for y in xrange(0, n)):
    inner_loop = -np.sum(self.Y[i, :] * U) + self.Y[i, i] * U[i] + np.conjugate(self.shares[i] / U[i])
    U[i] = U_last[i] + accelerator * (1/self.Y[i,i] * inner_loop - U_last[i])

U是向量(n個維), U_lastself.sharesYself.shares矩陣U。對於那些想知道的人來說,它是高斯-賽德爾功率流算法的一部分。

因為您是遞歸地構建數組,所以沒有。 您必須找出另一種非遞歸算法,或者排除遞歸部分。


讓我們盡力而為。

for i in (y for y in xrange(0, n)):等同for i in xrange(n) y沒有任何用途,因為它沒有作為名稱公開。

使用U更改值的唯一地方是傳遞給np.sum ,因此我們可以通過進行一些預計算來進行一些簡化。

  • self.Y[i, i] * U[i]可以為Ydiag_times_U[i] ,其中Ydiag_times_U = np.diag(Y) * U
  • np.conjugate(self.shares[i] / U[i])可以是conjugate_shares_over_U[i] ,其中conjugate_shares_over_U = np.conjugate(self.shares/U)
  • U_last[i] + accelerator * (1/self.Y[i,i] * inner_loop - U_last[i])可以類似地重新排列並制作為U_last_minus_accelerator_times_U_last[i] + accelerator_over_Ydiag[i] * inner_loop ,其中U_last_minus_accelerator_times_U_last[i] + accelerator_over_Ydiag[i] * inner_loop

    U_last_minus_accelerator_times_U_last[i] = U_last - accelerator * U_last accelerator_over_Ydiag = accelerator/np.diag(self.Y)

進行更改:

Ydiag_times_U = np.diag(Y) * U
conjugate_shares_over_U = np.conjugate(self.shares / U)
inner_silliness = Ydiag_times_U + conjugate_shares_over_U
U_last_minus_accelerator_times_U_last[i] = U_last - accelerator * U_last
accelerator_over_Ydiag = accelerator/np.diag(self.Y)

for i in xrange(n):
    inner_loop = inner_silliness[i] - np.sum(self.Y[i, :] * U)
    U[i] = U_last_minus_accelerator_times_U_last[i] + accelerator_over_Ydiag[i] * inner_loop

這些是較低級別的更改。 除此之外,您可以嘗試做一些代數運算以消除遞歸性。 如果您擔心效率,請嘗試使用C進行循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM