查找numpy数组的成对行差(具有perdioic边界)

mcdcgff0  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(119)

我有一个(N,3)维的numpy数组来保存3-dim. N个粒子在其行中的位置。我想用周期性边界获得这些粒子的成对距离(后者意味着如果粒子的x、y或z距离d大于L/2,那么我们取距离abs(d-L)而不是d本身)。
我的类C原型看起来像这样:

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

我如何才能使它更有效和Python的?

kgsdhlau

kgsdhlau1#

你确定你提供的伪代码是正确的?特别是,线rs += [np.sqrt(rx*rx + ry*ry + rz*rz)]在外部循环中,因此它将仅使用在内部循环的最后一次迭代中计算的rx, ry, rz
以下是一些你可能会发现对你的问题有用的小技巧:

import numpy as np

N, L = 10, 1
arr = np.random.rand(N, 3)

# You can use broadcasting to do an operation between
# each pair of elements within an array:
r = np.abs(arr[:, None, :] - arr[None, :, :])
# `r.shape == (N, N, 3)`; the absolute difference
# between each pair of shape (3,) subvectors in `arr`.

# if-else logic is solved using `np.where`:
s = np.where(r < L/2, r, np.abs(r - L))

# np.sqrt(x**2 + y**2 + ...) is done with `np.linalg.norm`:
out = np.linalg.norm(s, axis=2)

这就给你留下了一个(N, N)形状的数组!

相关问题