python中周期边界条件下的有效符号函数

python中周期边界条件下的有效符号函数,python,performance,numpy,cython,Python,Performance,Numpy,Cython,我用cython代码来加速纯python计算中的瓶颈。我在一个长度为Lbox的周期框中有一对点(对于这个问题,1d的情况可以)。我需要计算y-x的符号,当周期边界条件有效时,我需要翻转这个符号 在没有PBC的情况下,以下问题提供了解决方案:。这个解决方案就是我用来计算sgn函数的 def sgn(x, y): """ If x > y, returns 1. If x < y, returns -1. If x == y, returns 0.

我用cython代码来加速纯python计算中的瓶颈。我在一个长度为Lbox的周期框中有一对点(对于这个问题,1d的情况可以)。我需要计算y-x的符号,当周期边界条件有效时,我需要翻转这个符号

在没有PBC的情况下,以下问题提供了解决方案:。这个解决方案就是我用来计算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)
def sgn(x,y):
“”“如果x>y,则返回1。
如果x
下面编写的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)
def sgn_pbc(x、y、Lbox):
d=绝对值(x-y)
如果d首先

那么

但是,
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)
def sgn_pbc(x、y、Lbox):
d=绝对值(x-y)
w=sgn(磅/平方英寸,d)
返回w*(y
我之所以这么说,主要是因为在
d==Lbox/2的情况下。
这返回了一个错误的值


但是还没有计时。

sgn
中,为什么不使用
np.符号(y-x)
?对于一对浮点数,上面的sgn函数比np快约400%。符号您用
numpy
标记了它。通常,加快速度的最佳方法是对代码进行矢量化,这就是numpy的全部内容。您是否对矢量化解决方案感兴趣,其中
x
y
是浮点数组,还是希望坚持使用“浮点对”?这些是
python
还是
cython
函数?我看到了
def
,但没有看到
cdef
?这正是我遇到的问题:这种方法仍然需要一个控制流来正确处理d==Lbox/2的情况,因此根本没有加速。这些是浮点值吗?因为你可以加上+eps,这个等式为真的概率很低(1/2**53)。除非我误解了什么,否则无论加了什么epsilon,当距离正好等于Lbox/2+epsilon时,返回的结果都是不正确的。是的。这种可能性有多大?
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)
def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    w = sgn(Lbox/2., d)
    return  w * sgn(x, y)
def sgn_pbc(x, y, Lbox):
    d = abs(x-y)
    w = sgn(Lbox/2., d)
    return  w * (y < x) - (x < y)