在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()
的比较应该产生==
?
但问题的最后一部分仍然存在:为什么浮点数的工作方式如果在二进制中它们基本上都用整数表示?
答案 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}}适合您的问题集。)