优化嵌套for循环
我试图避免使用for循环来运行我的计算。但我不知道该怎么做。我有一个矩阵w
形状(40,100)
。每条线在t
时间内持有波浪位置。例如,第一行w[0]
是初始条件(因为我将显示的原因,也是w[1]
)。优化嵌套for循环
要计算下一行的元素我用,为每一位t
和x
的形状范围:
w[t+1,x] = a * w[t,x] + b * (w[t,x-1] + w[t,x+1]) - w[t-1,x]
凡a
和b
是基于方程解的一些常量(它其实并不重要),a = 2(1-r)
,b=r
,r=(c*(dt/dx))**2
。其中c
是波速和dt
,dx
与x
和t
方向上的增量有关。
有什么办法避免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]
nt
和nx
是w
矩阵的形状。
我假设你事先设置了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]
不是。如果你想为矩阵中的每个元素(你所做的)做一些事情,你将不得不以某种方式对每个元素进行操作(最明显的方法就是使用for循环,不太明显的方法要么执行相同或更差)。
如果你想避免循环,因为循环速度慢,知道有时循环是需要来解决某种问题。但是,有很多方法可以使循环更有效率。
通常在这样的矩阵问题中,您在查看相邻元素时,一个很好的解决方案是使用某种动态编程或记忆(保存工作以便不必频繁重复计算)。就像,假设每一个元素你都想要取其平均值及其周围的所有东西(这就是模糊图像的工作原理)。每个像素有8个邻居,所以平均值将是总和/ 9。那么,假设您保存列的总和(保存NW + W + SW,N + me + S,NE + E + SE)。那么当你进入下一个右边时,只需将前一个中间列的值,前一个最后一列和新列的值(右边的新值)相加即可。你只需要添加9个数字加上5就可以了。在比加法更复杂的操作中,将9减少到5可能意味着巨大的性能提升。
我看着你要做的事情,我想不出有什么办法像我刚刚描述的那样。但看看你能否想到类似的东西。
此外,请记住乘法比加法昂贵得多。所以,如果你有一个循环,例如,你必须乘以循环变量的一些数字,而不是做1x,2x,3x,...,你可以做(上次+ x值)。
'numpy'的特点之一是它的运算符和函数按照数组的元素进行操作。这使得这些任务更容易编写。在引擎盖下,这是作为一个循环来实现的,但是在C而不是Python *中,使它快了很多。 –
我会建议你看看[本教程(https://开头github上。com/barbagroup/CFDPython)用于在Python中实现偏微分方程(在本例中为Navier-Stokes)。 –
非常感谢@RolandSmith。 – Lin