python中的有效符号函数用于周期边界条件的情况

时间:2015-06-26 15:22:23

标签: python performance numpy cython

我正在使用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 个答案:

答案 0 :(得分:1)

首先,

-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.这会返回错误的值。

但是还没有计时。