Numpy:通过相对舍入克服机器不精确

Numpy: Overcoming machine imprecision by relative rounding

目标

我想对 numpy 数组的元素应用 "relative" 舍入。相对舍入在这里意味着我舍入到给定的数字有效数字,因此我不关心这是十进制还是二进制数字。

假设我们有两个数组 ab,这样一些元素彼此靠近。也就是说,

np.isclose(a, b, tolerance) 

有一些 True 给定亲戚 tolerance 的条目。假设我们知道所有在容差范围内不相等的条目相差至少 100*tolerance 的相对差异。我想获得一些数组 a2b2 以便

np.all(np.isclose(a, b, tolerance) == (a2 == b2))

我的想法是将数组舍入到适当的有效数字:

a2 = relative_rounding(a, precision)
b2 = relative_rounding(b, precision)

但是,只要达到目标,数字是否四舍五入或应用底限都没有关系。

一个例子:

a = np.array([1.234567891234, 2234.56789123, 32.3456789123])
b = np.array([1.234567895678, 2234.56789456, 42.3456789456])

# desired output
a2 = np.array([1.2345679, 2234.5679, 3.2345679])
b2 = np.array([1.2345679, 2234.5679, 4.2345679])

动机

这个练习的目的是让我能够处理二元运算的明确定义的结果,这样小的错误就无关紧要了。例如,我希望 np.unique 的结果不受浮点运算不精确的影响。

您可能认为浮点运算引入的错误是known/can有界的。

问题

我知道 similar questions concerning rounding up to given significant figures with numpy and respective solutions。虽然各自的答案可能足以满足我的目的,但我认为应该有一个更简单、更有效的解决方案来解决这个问题:因为浮点数有内置的 "relative precision",所以应该可以只设置 n 尾数中的最低有效二进制值为 0。这应该比通常的舍入过程更有效。但是,我不知道如何用 numpy 实现它。至关重要的是,解决方案是矢量化的,并且比简单的方法更有效。有直接操作 numpy 数组二进制文件的直接方法吗?

这是不可能的,除了特殊情况,例如精度为零(isclose 等同于 ==)或无穷大(所有数字彼此接近)。

numpy.isclose 不可传递。我们可能有 np.isclose(x, y, precision)np.isclose(y, z, precision) 但没有 np.isclose(x, z, precision)。 (比如10和11的误差在10%以内,11和12的误差在10%以内,但是10和12的误差不在10%以内。)

给出 xyz 的上述 isclose 关系,请求的 属性 将要求 x2 == y2y2 == z2 为真,但 x2 == z2 为假。但是,== 是可传递的,因此 x2 == y2y2 == z2 意味着 x2 == z2。因此,请求的函数要求 x2 == z2 既为真又为假,因此这是不可能的。