为什么numpy.allclose使用非对称比较?

时间:2018-08-20 13:23:29

标签: python numpy comparison

numpy.allclose被声明为numpy.allclose(a, b, rtol=1e-05, atol=1e-08, ...),并使用以下方法实现非对称比较:

absolute(a - b) <= (atol + rtol * absolute(b))

非对称比较的结果是,在极少数情况下,allclose(a, b)allclose(b, a)可能不同,因此使allclosecommutative,这令人惊讶比较运算符的属性。

进行非对称比较的原因是什么?

1 个答案:

答案 0 :(得分:2)

除了我的评论外,math.isclose使用abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)是可交换的,但以额外的操作为代价(对于需要堆叠以查找数组的numpy数组,这可能会很昂贵。最大值)。如果确实需要此属性,则实现自己的并不难:

def isclose_comm(a, b, rtol=1e-5, atol=1e-8):
   ab = np.stack((a, b))
   return np.abs(a - b) <= (atol + rtol * ab.max(axis=0))

x = np.random.random(5)

x
Out[94]: array([0.36007049, 0.86934972, 0.05827216, 0.60794612, 0.24539454])

y = x + np.random.random(5)/1e6

y
Out[96]: array([0.36007072, 0.86934976, 0.05827312, 0.6079464 , 0.24539492])

np.isclose(x, y)
Out[97]: array([ True,  True,  False,  True,  True])

isclose_comm(x, y)
Out[98]: array([ True,  True,  True,  True,  True])

z = np.zeros(5)

isclose_comm(x, z)
Out[100]: array([False, False, False, False, False])

allclose等价物:

def allclose_comm(a, b, rtol=1e-5, atol=1e-8):
    return isclose_comm(a, b, rtol, atol).all()