简体   繁体   English

是否可以在Python / Numpy中向量化这个三重for循环?

[英]Is vectorizing this triple for loop in Python / Numpy possible?

I am trying to speed up my code which currently takes a little over an hour to run in Python / Numpy. 我正在尝试加速我的代码,目前需要花费一个多小时才能在Python / Numpy中运行。 The majority of computation time occurs in the function pasted below. 大部分计算时间发生在下面粘贴的函数中。

I'm trying to vectorize Z, but I'm finding it rather difficult for a triple for loop. 我正在尝试对Z进行矢量化,但我发现三重for循环相当困难。 Could I possible implement the numpy.diff function somewhere? 我可以在某处实现numpy.diff功能吗? Take a look: 看一看:

def MyFESolver(KK,D,r,Z):
    global tdim
    global xdim
    global q1
    global q2
    for k in range(1,tdim):
        for i in range(1,xdim-1):
            for j in range (1,xdim-1):
                Z[k,i,j]=Z[k-1,i,j]+r*q1*Z[k-1,i,j]*(KK-Z[k-1,i,j])+D*q2*(Z[k-1,i-1,j]-4*Z[k-1,i,j]+Z[k-1,i+1,j]+Z[k-1,i,j-1]+Z[k-1,i,j+1])
    return Z

tdim = 75 xdim = 25 tdim = 75 xdim = 25

I agree, it's tricky because the BCs on all four sides, ruin the simple structure of the Stiffness matrix. 我同意,这很棘手,因为所有四个方面的BC都破坏了刚度矩阵的简单结构。 You can get rid of the space loops as such: 您可以删除空间循环:

from pylab import *
from scipy.sparse.lil import lil_matrix
tdim = 3;     xdim = 4;  r = 1.0;  q1, q2 = .05, .05; KK= 1.0; D = .5  #random values
Z = ones((tdim, xdim, xdim))
#Iterate in time
for k in range(1,tdim):
    Z_prev = Z[k-1,:,:] #may need to flatten
    Z_up = Z_prev[1:-1,2:]
    Z_down = Z_prev[1:-1,:-2]

    Z_left = Z_prev[:-2,1:-1]
    Z_right = Z_prev[2:,1:-1]

    centre_term  = (q1*r*(Z_prev[1:-1,1:-1] + KK) - 4*D*q2)* Z_prev[1:-1,1:-1] 

    Z[k,1:-1,1:-1]= Z_prev[1:-1,1:-1]+ centre_term + q2*(Z_up+Z_left+Z_right+Z_down)

But I don't think you can get rid of the time loop... 但我不认为你可以摆脱时间循环......

I think the expression: 我认为这个表达方式:

Z_up = Z_prev[1:-1,2:]

makes a copy in numpy, whereas what you want is a view - if you can figure out how to do this - it should be even faster (how much?) 在numpy中制作副本,而你想要的是一个视图 - 如果你能弄清楚如何做到这一点 - 它应该更快(多少?)

Finally, I agree with the rest of the answerers - from experience, this kind of loops are better done in C and then wrapped into numpy. 最后,我同意其余的回答者 - 从经验来看,这种循环在C中做得更好,然后包裹成numpy。 But the above should be faster than the original... 但上面应该比原来快......

This looks like an ideal case for Cython. 这看起来像Cython的理想情况。 I'd suggest writing that function in Cython, it'll probably be hundreds of times faster. 我建议在Cython中编写该函数,它可能会快几百倍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM