优化循环的 Python 实现当每个循环读取上一个循环的结果时

2024-05-13 21:24:21 发布

您现在位置:Python中文网/ 问答频道 /正文

一个包含两个循环(外部循环和内部循环)的函数应该得到优化——理想的方法是用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_lastself.shares,也是一个nxn矩阵,U。 对于那些好奇的人来说,这是高斯-赛德尔潮流算法的一部分。你知道吗


Tags: 方法函数inselfnumpyloop元素for
1条回答
网友
1楼 · 发布于 2024-05-13 21:24:21

因为您是递归地构建数组,所以不需要。您必须找出另一个不是递归的算法,或者考虑递归部分。你知道吗


不过,让我们尽我们所能吧。你知道吗

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_lastaccelerator_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来做循环

相关问题 更多 >