I have a (N,3)-dimensional numpy array holding the 3-dim. positions of N particles in its rows. I want to obtain the pairwise distances of these particles using periodic boundaries (the latter means that if particles have a x-, y-, or z-distance d that is larger than a value L/2, then we take the distance abs(d-L) rather than d itself).
My C-like prototype looks like this:
def get_distances(positions, L):
"""Compute distances from positions using periodic boundaries"""
rs = []
L_half = 0.5*L
for pos_i in positions:
for pos_j in positions:
rx = np.abs(pos_i[0] - pos_j[0])
rx = rx if rx < L_half else np.abs(rx-L)
ry = np.abs(pos_i[1] - pos_j[1])
ry = ry if ry < L_half else np.abs(ry-L)
rz = np.abs(pos_i[2] - pos_j[2])
rz = rz if rz < L_half else np.abs(rz-L)
rs += [np.sqrt(rx*rx + ry*ry + rz*rz)]
return rs
How can I make this more efficient and Pythonic?
Are you sure your provided pseudocode is correct? In particular, the line
rs += [np.sqrt(rx*rx + ry*ry + rz*rz)]is in the outer loop, so it would only use therx, ry, rzcomputed in the last iteration of the inner loop.These are some numpy tricks that you might find useful for your problem:
Which leaves you with a shape
(N, N)array!