Numpy:通过相对舍入克服机器不精确
Numpy: Overcoming machine imprecision by relative rounding
目标
我想对 numpy
数组的元素应用 "relative" 舍入。相对舍入在这里意味着我舍入到给定的数字有效数字,因此我不关心这是十进制还是二进制数字。
假设我们有两个数组 a
和 b
,这样一些元素彼此靠近。也就是说,
np.isclose(a, b, tolerance)
有一些 True
给定亲戚 tolerance
的条目。假设我们知道所有在容差范围内不相等的条目相差至少 100*tolerance
的相对差异。我想获得一些数组 a2
和 b2
以便
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%以内。)
给出 x
、y
和 z
的上述 isclose
关系,请求的 属性 将要求 x2 == y2
和y2 == z2
为真,但 x2 == z2
为假。但是,==
是可传递的,因此 x2 == y2
和 y2 == z2
意味着 x2 == z2
。因此,请求的函数要求 x2 == z2
既为真又为假,因此这是不可能的。
目标
我想对 numpy
数组的元素应用 "relative" 舍入。相对舍入在这里意味着我舍入到给定的数字有效数字,因此我不关心这是十进制还是二进制数字。
假设我们有两个数组 a
和 b
,这样一些元素彼此靠近。也就是说,
np.isclose(a, b, tolerance)
有一些 True
给定亲戚 tolerance
的条目。假设我们知道所有在容差范围内不相等的条目相差至少 100*tolerance
的相对差异。我想获得一些数组 a2
和 b2
以便
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%以内。)
给出 x
、y
和 z
的上述 isclose
关系,请求的 属性 将要求 x2 == y2
和y2 == z2
为真,但 x2 == z2
为假。但是,==
是可传递的,因此 x2 == y2
和 y2 == z2
意味着 x2 == z2
。因此,请求的函数要求 x2 == z2
既为真又为假,因此这是不可能的。