什么是检查python中两个复数是否相同的更好方法?

时间:2016-03-07 14:43:22

标签: python python-2.7 numpy

在python 2.7.3中测试mpi4py的comm.reduce()comm.Reduce()方法时遇到以下行为:

  • 有时会减去两个复数(类型'numpy.complex128',它们是某些并行计算的输出),在屏幕上打印时看起来相同会产生非零结果

  • 将它们与==进行比较,偶尔会产生False

示例:

print z1, z2, z1-z2
(0.268870295763-0.268490433604j) (0.268870295763-0.268490433604j) 0j
print z1 == z2
True

但是

print z1, z2, z1-z2
(0.226804302192-0.242683516175j) (0.226804302192-0.242683516175j) (-2.77555756156e-17+5.55111512313e-17j)
print z1 == z2
False

我认为这与浮动的有限精度有关,所以我只是检查差异abs(z1-z2)是否大于1e-16(它从来没有 - 这是人们所期望的{{ {1}}和reduce()相同)。 (编辑:这实际上不是检查平等的好方法。见:What is the best way to compare floats for almost-equality in Python?

我想知道是否有更简单的方法来比较python中的复数。

此外,为什么会出现这种情况?毕竟,浮点数(据我所知,复数基本上是两个浮点数的元组)以二进制形式存储在机器上,作为一系列位。难道如果两个数字由二进制中的相同序列表示,那么差异应该为零,与Reduce()的比较应该产生==

编辑:好的,我发现了What is the best way to compare floats for almost-equality in Python?,这基本上归结为同样的事情。

但问题的最后一部分仍然存在:为什么浮点数的工作方式如果在二进制中它们基本上都用整数表示?

1 个答案:

答案 0 :(得分:1)

以产生相同逻辑结果的方式派生的

float值在二进制中始终具有相同的表示,因为float不是无限精度,并且其表示存在限制。不同顺序中相同的逻辑等效步骤有时会出现精确错误,导致结果略有不同。

通常,检查"关闭"当您知道值很小或范围很窄时,与float s的平等就是这样做:

if abs(a - b) < 1e-9:  # Substitute your own threshold for equality

是否适合您的complex值是特定于问题的;您可能需要独立检查实部和虚部的接近程度。

如果你可以使用Python 3.5,它提供cmath.isclose来简化这个(并允许缩放&#34;亲密度&#34;,而不仅仅是绝对接近),但是在2.7,它可能是正如我在上面演示的那样,更容易捏造它,或者你可以借用等同的&#34; cmath.isclose文档提供的代码:

 abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

该等效代码会根据相对容差进行缩放,因此,如果您的值可以涵盖complex类型的整个范围,那么您将希望使用类似的内容(其中rel_tol和{您选择的{1}}适合您的问题集。)