由两个循环(外循环和内循环)组成的函数应该进行优化 - 最好用 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 潮流算法的一部分。
最佳答案
因为您正在递归地构建数组,所以不会。您必须找出另一种非递归算法,或者分解出递归部分。
<小时/>不过,我们还是尽力而为吧。
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] * inside_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 - 加速器 * 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 中执行循环。
关于python - 当每个循环读取上一个循环的结果时优化Python循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30773623/