我有cython代码,可用来加速原本纯Python计算中的瓶颈。我在长度为Lbox的周期框中有一对点(此问题适合1d情况)。我需要计算y-x的符号,并且当周期性边界条件有效时,需要翻转该符号。

在没有PBC的情况下,以下问题提供了解决方案:Is there a standard sign function (signum, sgn) in C/C++?。该解决方案是我用来计算sgn函数的方法。

def sgn(x, y):
    """ If x > y, returns 1.
    If x < y, returns -1.
    If x == y, returns 0.
    """
    return (y < x) - (x < y)


如下所示,sgn_pbc函数返回正确的结果,但编写效率低下:sgn_pbc内的控制流是降低PBC版本速度的元凶。如何以类似于sgn函数的方式编写sgn_pbc,从而避免笨拙的控制流程?

def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    if d <= Lbox/2.:
        return sgn(x, y)
    else:
        return -1*sgn(x, y)

最佳答案

第一,

-1*sgn(x, y) == sgn(y, x)


然后,

def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    if d <= Lbox/2.:
        return sgn(x, y)
    else:
        return sgn(y, x)


同样在Python中,函数调用是最昂贵的操作。您可以内联sgn

def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    if d <= Lbox/2.:
        return (y < x) - (x < y)
    else:
        return (x < y) - (y < x)


但是随后if可以(大部分)重写为:

def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    w = sgn(Lbox/2., d)
    return  w * sgn(x, y)


再次,内联sgn

def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    w = sgn(Lbox/2., d)
    return  w * (y < x) - (x < y)


我之所以这么说,主要是因为d == Lbox/2.返回错误值的情况。

尚未计时。

关于python - python中的高效符号函数,用于周期性边界条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31076878/

10-11 07:03