脾气暴躁:通过相对舍入来克服机器不精确度

时间:2019-07-08 23:51:20

标签: numpy floating-point binary rounding relative

目标

我想对numpy数组的元素应用“相对”舍入。相对舍入在这里意味着我将有效数字四舍五入到给定的数字,因此我不在乎这是十进制还是二进制数字。

假设给定两个数组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的结果不受浮点运算的不精确性影响。

您可能会认为由浮点运算引起的错误是已知的/可以限制的。

问题

我知道similar questions concerning rounding up to given significant figures with numpyrespective solutions。尽管各自的答案可能足以满足我的目的,但我认为应该有一个更简单,更有效的解决方案:由于浮点数具有内置的“相对精度”,因此应该可以只设置{{1} }将尾数中的最低有效二进制值设为0。这应该比通常的舍入过程更有效。但是,我不知道如何用numpy实现它。至关重要的是,解决方案必须是矢量化的,并且比朴素的方式更有效。是否有直接方法可以直接在numpy中操作数组的二进制文件?

1 个答案:

答案 0 :(得分:3)

这是不可能的,除非有特殊情况,例如精度为零(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%之内。)

鉴于isclosexy的上述z关系,所请求的属性将要求x2 == y2y2 == z2为正确,但x2 == z2为假。但是,==是可传递的,因此x2 == y2y2 == z2意味着x2 == z2。因此,请求的函数要求x2 == z2为真和为假,因此这是不可能的。