我有一个N体模拟脚本,可以处理数千个粒子。它输出粒子位置的最终2D投影,我希望在给定轴周围以不同的旋转角度多次运行,以便能够从不同的视角看到最终的2D结果。为此,我在开头添加了一些代码:
# Euler-Rodrigues formula definition for arbitrary 3D rotation
def rotation_matrix(axis,angle):
axis = axis/math.sqrt(dot(axis,axis))
a = math.cos(angle/2)
b,c,d = -axis*math.sin(angle/2)
return array([[a*a+b*b-c*c-d*d, 2*(b*c-a*d), 2*(b*d+a*c)],
[2*(b*c+a*d), a*a+c*c-b*b-d*d, 2*(c*d-a*b)],
[2*(b*d-a*c), 2*(c*d+a*b), a*a+d*d-b*b-c*c]])
然后:
# 3D rotation
angle = float(sys.argv[7])*math.pi/180.0
axis = array([0,0,1])
xAr,yAr,zAr=[],[],[] #arrays for rotated particles
for xi,yi,zi in zip(xA,yA,zA): #cycle to rotate every particle
ci = array([xi,yi,zi])
cr = dot(rotation_matrix(axis,angle),ci)
xAr.append(cr[0])
yAr.append(cr[1])
zAr.append(cr[2])
xA,yA,zA = array(xAr), array(yAr), array(zAr)
脚本的核心部分在此之后开始。总之,最初脚本执行此操作:
我现在添加了我的部分:
但我发现旋转过程花费了太多时间。在Python中是否有一种方法或不同的方法来加速这个? (如果它有帮助,我只希望最终的2D投影沿给定轴旋转)。
答案 0 :(得分:2)
您需要对操作进行矢量化,即在整个粒子集上运行它而不是在它们上面循环。假设xA
等是1-d数组,那就像:
particles = np.vstack([xA, xB, xC])
rot = rotation_matrix(axis, angle)
rotated = np.dot(rot, particles)
xA, yA, zA = rotated
这应该会给你几个数量级的加速。更一般地说,您在循环的每次迭代中构造相同的旋转矩阵。这太浪费了。
答案 1 :(得分:1)
如何将旋转矩阵(轴,角度)放出紧密循环