问题:我想加速我的python循环,其中包含很多产品和总结,但我也对任何其他解决方案持开放态度。np.einsum
我的函数采用形状为 (n,n,3) 的向量配置 S(我的情况:n=72),并对 N*N 点的相关函数进行傅里叶变换。相关函数定义为每个向量与其他向量的乘积。这乘以向量位置乘以 kx 和 ky 值的余弦函数。每个位置在最终求和得到k空间中的一个点:i,jp,m
def spin_spin(S,N):
n= len(S)
conf = np.reshape(S,(n**2,3))
chi = np.zeros((N,N))
kx = np.linspace(-5*np.pi/3,5*np.pi/3,N)
ky = np.linspace(-3*np.pi/np.sqrt(3),3*np.pi/np.sqrt(3),N)
x=np.reshape(triangular(n)[0],(n**2))
y=np.reshape(triangular(n)[1],(n**2))
for p in range(N):
for m in range(N):
for i in range(n**2):
for j in range(n**2):
chi[p,m] += 2/(n**2)*np.dot(conf[i],conf[j])*np.cos(kx[p]*(x[i]-x[j])+ ky[m]*(y[i]-y[j]))
return(chi,kx,ky)
我的问题是我需要大约100 * 100个点,这些点由kx * ky表示,并且循环需要几个小时才能完成具有72 * 72个向量的格的工作。计算次数:72 * 72 * 72 * 72 * 100 * 100 我不能使用内置的FFT,因为我的三角形网格,所以我需要一些其他选项来降低这里的计算成本。numpy
我的想法:首先,我意识到将配置重新塑造为向量列表而不是矩阵可以降低计算成本。此外,我使用了numba包,这也降低了成本,但它仍然太慢了。我发现计算这些对象的一个好方法是函数。计算每个向量与每个向量的乘积是通过以下方式完成的:np.einsum
np.einsum('ij,kj -> ik',np.reshape(S,(72**2,3)),np.reshape(S,(72**2,3)))
棘手的部分是计算 .在这里,我想将产品与向量的位置(例如)的形状列表(100,1)连接起来。特别是我真的不知道如何用来实现x方向和y方向的距离。np.cosnp.shape(x)=(72**2,1)np.einsum
要重现代码(可能不需要这样):首先,您需要一个矢量配置。你可以简单地用它来做,或者你用随机向量作为例子:np.ones((72,72,3)
def spherical_to_cartesian(r, theta, phi):
'''Convert spherical coordinates (physics convention) to cartesian coordinates'''
sin_theta = np.sin(theta)
x = r * sin_theta * np.cos(phi)
y = r * sin_theta * np.sin(phi)
z = r * np.cos(theta)
return x, y, z # return a tuple
def random_directions(n, r):
'''Return ``n`` 3-vectors in random directions with radius ``r``'''
out = np.empty(shape=(n,3), dtype=np.float64)
for i in range(n):
# Pick directions randomly in solid angle
phi = random.uniform(0, 2*np.pi)
theta = np.arccos(random.uniform(-1, 1))
# unpack a tuple
x, y, z = spherical_to_cartesian(r, theta, phi)
out[i] = x, y, z
宝慕林4294392
翻翻过去那场雪
胡子哥哥
随时随地看视频慕课网APP
相关分类