2016-04-16 168 views
3

我试图避免使用for循环来运行我的计算。但我不知道该怎么做。我有一个矩阵w形状(40,100)。每条线在t时间内持有波浪位置。例如,第一行w[0]是初始条件(因为我将显示的原因,也是w[1])。优化嵌套for循环

要计算下一行的元素我用,为每一位tx的形状范围:

w[t+1,x] = a * w[t,x] + b * (w[t,x-1] + w[t,x+1]) - w[t-1,x] 

ab是基于方程解的一些常量(它其实并不重要),a = 2(1-r)b=rr=(c*(dt/dx))**2。其中c是波速和dt,dxxt方向上的增量有关。

有什么办法避免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] 

ntnxw矩阵的形状。

+1

我会建议你看看[本教程(https://开头github上。com/barbagroup/CFDPython)用于在Python中实现偏微分方程(在本例中为Navier-Stokes)。 –

+0

非常感谢@RolandSmith。 – Lin

回答

5

我假设你事先设置了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] 
0

不是。如果你想为矩阵中的每个元素(你所做的)做一些事情,你将不得不以某种方式对每个元素进行操作(最明显的方法就是使用for循环,不太明显的方法要么执行相同或更差)。

如果你想避免循环,因为循环速度慢,知道有时循环是需要来解决某种问题。但是,有很多方法可以使循环更有效率。

通常在这样的矩阵问题中,您在查看相邻元素时,一个很好的解决方案是使用某种动态编程或记忆(保存工作以便不必频繁重复计算)。就像,假设每一个元素你都想要取其平均值及其周围的所有东西(这就是模糊图像的工作原理)。每个像素有8个邻居,所以平均值将是总和/ 9。那么,假设您保存列的总和(保存NW + W + SW,N + me + S,NE + E + SE)。那么当你进入下一个右边时,只需将前一个中间列的值,前一个最后一列和新列的值(右边的新值)相加即可。你只需要添加9个数字加上5就可以了。在比加法更复杂的操作中,将9减少到5可能意味着巨大的性能提升。

我看着你要做的事情,我想不出有什么办法像我刚刚描述的那样。但看看你能否想到类似的东西。

此外,请记住乘法比加法昂贵得多。所以,如果你有一个循环,例如,你必须乘以循环变量的一些数字,而不是做1x,2x,3x,...,你可以做(​​上次+ x值)。

+1

'numpy'的特点之一是它的运算符和函数按照数组的元素进行操作。这使得这些任务更容易编写。在引擎盖下,这是作为一个循环来实现的,但是在C而不是Python *中,使它快了很多。 –