与(绝对)容差的传递浮点比较

计算科学 C++ 浮点
2021-12-10 15:08:36

我想比较两个浮点数相对于已知绝对容差的相等性。然而,这是我很久以前写的一个算法,我相信如果等式关系不是传递的,那么该算法的逻辑就会被破坏。

一些假阴性是没有问题的,即如果两个“相等”的数字比较不相等,那么会发生的只是算法将使用更多的时间和内存。但是,我现在得到了由另一种算法预处理的输入数据(以平滑角落),但是该算法在每条直线上都添加了噪声,这导致我的算法过程中出现内存消耗问题(> 4GB)。

我基本上看到了两个选项,我该如何解决这个问题:

  • 我可以尝试从预处理算法的结果中去除“噪音”。
  • 我可以尝试找到一种以传递方式进行基于容差的相等比较的方法。

第一种方法对我来说看起来更容易。我基本上会有一组固定的双打,并且需要选择一组代表,以便该组中的每个双打都在代表的 epsilon 内。我对第二种方法的唯一想法是将值捕捉到网格以进行比较。但是,我依稀记得以前实现过这样的网格捕捉方法,但是一旦 (c++) 编译器开始内联相应的代码,它就崩溃了。我通过将捕捉代码移动到不同的翻译单元来解决此问题,但后来重写了代码以使捕捉过时。

问题

  1. 是否可以在不违反传递性的情况下进行基于容差的相等比较(在 C++ 中)?

  2. 什么是实现“去噪”算法的好方法?我的方法可能是保留一个排序的代表列表,并在该列表中通过二等分查找每个新的双精度值,从而导致O(nlogn)运行时和O(n)“去噪”算法的(附加)内存消耗。

2个回答

如果您预先准备好所有数字,则可以使用union-find 结构有效地计算基于容差的比较的传递闭包。首先循环遍历所有成对的附近点(例如,使用边界框层次结构),并为您的容差范围内的每一对将它们标记为合并到并集查找中。稍后,通过检查它们是否在同一个 union-find 组件中来比较点是否相等。

您不能使用容差进行等式比较。过去,我使用过将点转换为浮点数并返回为双精度数的方法,将点捕捉到网格上。这不是故障保险,但它通常会摆脱一些更烦人的情况。