关于比较浮点数的公差和公式的原则性推理?

Principled reasoning about tolerances and formulas for comparing floating-point numbers?

提问人:shadowtalker 提问时间:2/14/2023 最后编辑:shadowtalker 更新时间:2/16/2023 访问量:109

问:

Python 标准库包含函数 math.isclose,它等效于:

abs(a - b) <= max(rtol * max(abs(a), abs(b)), atol)

Numpy 库同样包含 numpy.isclose 和 numpy.allclose,它们等效于:

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

这两个文档页面都没有解释为什么您希望使用其中一个公式而不是另一个公式,也没有提供任何选择合理的绝对公差和相对公差的原则标准,分别写在上面。atolrtol

我经常不得不在代码测试中使用这些函数,但我从未学到在这两个公式之间进行选择或选择可能适合我的用例的容差的任何原则基础。

我通常只是保持默认值不变,除非我碰巧知道我正在做一些可能导致数值精度损失的事情,此时我会手动调整公差,直到结果看起来正确,主要基于直觉和手动检查示例。这是乏味的、不完美的,并且似乎与软件测试的目的背道而驰,尤其是基于属性的测试

例如,我可能想断言同一算法的两个不同实现会产生“相同”的结果,并承认精确的相等性比较没有意义。

我可以使用哪些原则性技术来选择合理的公式和公差来比较浮点数?为了这个问题,我很高兴专注于测试使用浮点数的代码的情况。

测试 数学 浮点 精度 数值方法

评论

4赞 Eric Postpischil 2/15/2023
这是数值分析,这是一个完整的研究领域。确定最终结果中可能有多少误差通常是中间数据和运算的函数,通常不仅仅是最终结果的函数,因此您显示的公式都不可能在所有情况下都是正确的。严格确定误差范围通常很困难。、 和 是粗略的启发式方法......math.isclosenumpy.isclosenumpy.allclose
1赞 Eric Postpischil 2/15/2023
...它们可能有益于检测程序中的错误——如果存在一些错误,那么计算结果可能与理想结果大不相同,因此测试“接近性”可能会揭示错误。除此之外,测试“亲密关系”几乎没有用处。
0赞 shadowtalker 2/15/2023
@EricPostpischil谢谢你。为了回答这个问题,我很高兴地将重点放在测试使用浮点数的代码的案例上。而选择对任何特定应用程序有意义的启发式方法的主题正是这个问题的主题!
1赞 user14717 2/15/2023
@shadowtalker:搜索“函数求值的条件数”——它提供了一种测试函数调用错误的原则性方法。还有许多矩阵条件数,具体取决于您要实现的目标以及正在考虑的扰动。书籍:Higham's Accuracy and Stability of Numerical Algorithms,Corless's Graduate Introduction to Numerical Methods。
1赞 aka.nice 2/17/2023
为什么将使用限制在单独的数值分析中?难道它不符合特定领域的亲密关系概念吗?公差可以由物理考虑因素/工程决策来指导。无人机到达航点了吗?我们应该在什么温度差下关闭加热器?这种容差应比由于潜在的浮点伪影而产生的额外不确定性大几个数量级,这是带来这种保证的数值分析点。否则精度加倍。或者找到一个更健壮/稳定的算法。或者放宽要求。我想没有通用的食谱......

答:

1赞 chux - Reinstate Monica 2/15/2023 #1

例如,我可能想断言同一算法的两个不同实现会产生“相同”的结果,并承认精确的相等性比较没有意义。

不要考虑对“相同”结果进行单一的真/假评估,而是尝试对算法在各种属性上的相同性进行评分。

如果评估在您的容差/限制范围内,则功能是“相同的”。


给定 和 (引用函数)。g(x)r(x)

  • 绝对差异:尝试各种(如果不是全部)。最大的是什么?y = abs(g(x) - r(x))xy

  • 相对差:尝试各种正态(非零)。最大的是什么?y = abs((g(x) - r(x))/r(x))r(x)y

  • 相对差异:如上所述,结果低于正常水平。这里的相对差异可能比正常值大得多,因此需要单独处理。 值得特别评估。r(x)r(x) == +/-0.0

  • 范围测试/边缘情况:什么是最大/最小最大/最不“有效”。例如 并且可能在不同的位置返回无穷大或 0.0,但在其他方面几乎是“相同”。xy = my_exp(x)exp(x)x

  • 总订购差异:(收藏)。使用名为 的辅助函数将所有非 NAN 浮点值 -inf 到 +inf 映射到整数:[-ORDER_N to ORDER_N] 是 0。找到最大差异并使用该指标来确定“相同”度。total order()total order(+/-0.0)abs(total_order(g(x)) - total_order(r(x)))

  • 各种功能值得特殊处理。该研究领域还有许多进一步的考虑。

1赞 D Stanley 2/15/2023 #2

使用相对公差时的一个问题是 - 相对于什么?如果你想知道 90 和 100 是否“相等”,公差为 10%,如果你取 90 的 10% 和 100 的 10%,你会得到不同的答案。

在该方案中定义“什么”时,标准库使用较大的 或,因此它将使用 100 的 10% 作为容差。它还使用相对公差或绝对公差中的较大者作为“最终”公差。ab

numpy 方法简单地用于“相对”公差,并将相对公差和绝对公差的总和作为“最终”公差。b

哪个更好?两者都没有好坏之分——它们是建立宽容的不同方式。您可以根据要如何定义“足够接近”来选择要使用哪一个。

您选择的公差也与上下文相关 - 您是在比较木材的长度还是微处理器中电路路径之间的距离?1%的公差是“足够好”还是需要超精密公差?容差过低可能会产生过多的“误报”,具体取决于应用程序,而过高的容差会产生过多的“漏报”,这可能会让一些问题“从裂缝中溜走”。

请注意,标准函数不是矢量化的,所以如果你想在数组上使用它,你要么必须使用 numpy 函数,要么构建标准函数的垂直化版本。

0赞 user1196549 2/16/2023 #3

没有人可以为您选择公差,它们取决于问题。因为在现实生活中,您处理的输入数据的精度(非常)有限,无论是实验测量的结果还是引入截断误差的数值计算的结果。因此,您需要了解您的数据并了解误差演算的概念和方法才能对其进行调整。

至于公式,它们被设计为通用的,即不知道要比较的量是否可以严格相等(当它们严格相等时,相对误差不起作用)。同样,这不应该是一个盲目的选择。

评论

0赞 shadowtalker 2/16/2023
谢谢你。不幸的是,它并没有真正回答这个问题,只是证实了我已经知道的事情:我需要一些有原则的方法来比较这些数字!这个问题旨在询问这些原则性的方式实际上是什么。