应该优化由两个循环(外部和内部)组成的函数 - 理想情况下,用Numpy函数替换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_last
和self.shares
,Y
是一个nxn矩阵,U。
对于那些想知道的人来说,它是Gauss-Seidel潮流算法的一部分。
答案 0 :(得分:1)
因为你以递归方式构建数组,所以没有。您必须找出另一种不递归的算法,或者将递归部分算出来。
尽管如此,让我们尽力而为。
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] = 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中进行循环。