python的新手,并不确定这里的效率问题。对于表示n个粒子坐标的向量x,y和z,我可以进行以下计算
import numpy as np
X=np.subtract.outer(x,x)
Y=np.subtract.outer(y,y)
Z=np.subtract.outer(z,z)
R=np.sqrt(X**2+Y**2+Z**2)
A=X/R
np.fill_diagonal(A,0)
a=np.sum(A,axis=0)
通过这种计算,冗余度约为2倍,因为乘法和除法不需要对角线,而下对角线只是上对角线的负值。我计划在odeint使用的函数调用中使用这种计算 - 即它将被调用很多,向量将很大 - 与我的计算机将处理的一样大。为了删除它,天真地我最终会做一个for循环,这可能是一个愚蠢的事情。我能以矢量化的方式摆脱这种冗余,还是值得努力?
更新:根据以下建议,我唯一能看到改进的方法是
ut=np.triu_indices(n,1)
X=x[ut[0]]-x[ut[1]]
使用类似的Y和Z表达式并使用pdist查找R.此结构仅计算上三角形部分。看一下pdist的源代码,我不相信它做了什么特别聪明的事情,所以我认为上面的表达同样会很好。方形的使用仅产生对称形式。对于反对称也可以使用
B=np.zeros((n,n),dtype=np.float64)
B(ut[0],ut[1])=A
B=B-B.T
这不能比方形慢,因为这正是方形所做的。由于函数经常被调用,在我看来,ut应该是静态的,同时存储其他的(X,Y,Z,A,B)。然而,对于python来说,我不知道如何做到这一点。