我需要优化这个函数,因为我正试图使我的OpenGL模拟运行得更快。我想使用Parakeet,但我不太明白需要以什么方式修改下面的代码。你知道我该怎么做吗?在
def distanceMatrix(self,x,y,z):
" ""Computes distances between all particles and places the result in a matrix such that the ij th matrix entry corresponds to the distance between particle i and j"" "
xtemp = tile(x,(self.N,1))
dx = xtemp - xtemp.T
ytemp = tile(y,(self.N,1))
dy = ytemp - ytemp.T
ztemp = tile(z,(self.N,1))
dz = ztemp - ztemp.T
# Particles 'feel' each other across the periodic boundaries
if self.periodicX:
dx[dx>self.L/2]=dx[dx > self.L/2]-self.L
dx[dx<-self.L/2]=dx[dx < -self.L/2]+self.L
if self.periodicY:
dy[dy>self.L/2]=dy[dy>self.L/2]-self.L
dy[dy<-self.L/2]=dy[dy<-self.L/2]+self.L
if self.periodicZ:
dz[dz>self.L/2]=dz[dz>self.L/2]-self.L
dz[dz<-self.L/2]=dz[dz<-self.L/2]+self.L
# Total Distances
d = sqrt(dx**2+dy**2+dz**2)
# Mark zero entries with negative 1 to avoid divergences
d[d==0] = -1
return d, dx, dy, dz
据我所知,长尾鹦鹉应该可以使用上面的函数而不做任何修改——它只使用Numpy和math。但是,当我从Paraket jit包装器调用函数时,总是出现以下错误:
^{pr2}$
鹦鹉还很年轻,它对NumPy的支持还不完整,并且您的代码涉及到一些还不起作用的特性。在
1)你在包装一个方法,而鹦鹉到目前为止只知道如何处理函数。常见的解决方法是生成一个@jit包装的helper函数,并使用所有必需的成员数据调用该函数。方法不起作用的原因是将有意义的类型赋给“self”是非常重要的。这不是不可能的,但足够棘手的是,在摘下悬挂较低的水果之前,这些方法是不会进入长尾鹦鹉的。说到低垂的水果。。。在
2)布尔索引。尚未实现,但将在下一个版本中提供。在
3)np.瓷砖:同样不起作用,也可能在下一个版本中。如果您想知道哪些内置函数和NumPy库函数可以工作,请看一下鹦鹉的mappings模块。在
我重写了你的代码,让它对鹦鹉更友好一点:
在我的机器上,如果N=2000,这个速度只比NumPy快3倍(NumPy为0.39s,而Parakeet为0.14s)。如果我重写数组遍历以更明确地使用循环,那么性能将比NumPy快约6倍(鹦鹉在~0.06s内运行):
^{pr2}$通过一些创造性的重写,您也可以让上面的代码在Numba中运行,但它只比NumPy快1.5倍(0.25秒)。编译时间是带理解的鹦鹉:1秒,带循环的鹦鹉:.5秒,带循环的Numba:0.9秒。在
希望接下来的几个发行版将支持对NumPy库函数的更多惯用用法,但目前理解或循环通常是最好的方法。在
相关问题 更多 >
编程相关推荐