I have some Python / Numpy code that is running slow and I think it is because of the use of a double for loop. Here is the code.
def heat(D,u0,q,tdim):
xdim = np.size(u0)
Z = np.zeros([xdim,tdim])
Z[:,0]=u0;
for i in range(1,tdim):
for j in range (1,xdim-1):
Z[j,i]=Z[j,i-1]+D*q*(Z[j-1,i-1]-2*Z[j,i-1]+Z[j+1,i-1])
return Z
I am trying to remove the double for loop and vectorize Z. Here is my attempt.
def heat(D,u0,q,tdim):
xdim = np.size(u0)
Z = np.zeros([xdim,tdim])
Z[:,0]=u0;
Z[1:,1:-1]=Z[1:-1,:-1]+D*q*(Z[:-2,:-1]-2*Z[1:-1,:-1]+Z[2:,:-1])
return Z
This doesn’t work – I get the following error:
operands could not be broadcast together with shapes (24,73) (23,74)
So somewhere in trying to vectorize Z, I messed up. Can you please help me spot my error?
You cannot vectorize that diffusion calculation in the time dimension of the problem, that still requires a loop. The only obvious optimization here is to replace the Laplacian calculation with a call to the
numpy.difffunction (which is precompiled C), so your heat equation solver becomes:For non-trivial spatial sizes you should see considerable speed up.