python - 机器 epsilon 的倍数是什么意思?
问题描述
我正在尝试调查矩阵方程问题(Ax=b)残差的来源。为了验证我的答案,我减去Ax-b,期望0。我不是“纯”零,而是获得与机器 epsilon 相同数量级的值,这很好。问题是这些残差似乎是彼此的倍数,所以我不确定如何解释它们。
我在这里找到了一些细节:机器 epsilon 计算问题,这并没有说明为什么会出现 epsilon 的倍数而不仅仅是一个或另一个。
我检查了我的系统,使用np.finfo(float).eps
which 生成2.220446049250313e-16
. 我在解x中得到的残差之一与该值相同,但是,另一个似乎是 epsilon 的一半。
这是我使用的代码:
# Arbitrary Matrix A and Vector b
A = np.array([[2,-1,0],[1,-2,1],[0,-1,2]])
b = np.array([[1],[0],[1]])
# Solve for Vector x
x = np.linalg.solve(A,b)
# Calculate difference, expected to be column of zeros
diff = A.dot(x) - b
print(diff)
这是输出:
Output:
[[ 0.00000000e+00]
[-1.11022302e-16] #-------> Is this machine epsilon...
[-2.22044605e-16]] #-------> ...or this?
对此有何解释/解释?我知道仍然可以表示小于 epsilon 的值,但在这种情况下,为什么不是两个残差-1.11022302e-16
?
提前致谢!
解决方案
所谓机器epsilon,就是1处的最小精度单位(ULP),即1的表示中最低位的位置值。有效位有53位时,表示1由二进制数字 1.000…000 2,其中二进制点后有 52 个零。所以最低位的位置值为 2 −52,而 2 −52是 1 的 ULP。
通常,让 ULP( x ) 代表 x 的最小精度单位。通常,浮点格式将数字表示为 (-1) s • f • b e,其中b是固定基数(二进制格式为 2,十进制格式为 10,十六进制格式为 16),s是符号位 ( 0 表示 +,1 表示 -),e是指数,f是具有p位数字的有效数,其中p是格式的固定数量。对于 IEEE-754 binary32,p是 53,对于 53 位。ULP 是由指数缩放的有效数字中最低精度的位置值,因此,如果某个数字x用符号位s、有效数字f和指数e以浮点格式表示,则其 ULP 为b 1 −<em>p • b e。(我假设有效数字的格式是小数点之前的一个基数b数字和小数点之后的p -1 位数字,这就是为什么它的最低数字的位置值为b 1−<em>p。这样有效数在区间 [1, b)。有时有效数字的缩放比例不同,并且调整指数以进行补偿。例如,在证明有效数为整数时可能很有用。)
在二进制格式中,ULP(2) = 2•ULP(1)、ULP(½) = ½•ULP(1)、ULP(¼) = ¼•ULP(1) 等等。
假设您计算了区间 [1, 2) 中的两个值,如果使用实数算术计算,它们将相等,但它们是使用浮点算术计算的,并且碰巧略有不同。由于表示的格式,它们只能相差 ULP(1) 的倍数。当您减去这些数字时,您通常会得到 0、ULP(1)、2•ULP(1) 或 ULP(1) 的其他倍数,具体取决于具体情况。如果使用实数算法计算两个相同的数字,但使用浮点算法计算它们时,它们可能会在计算的各个部分遇到不同的舍入误差。
如果您计算区间 [½, 1) 中的两个值,它们只能相差 ULP(½) 的倍数。
这就是为什么您会看到 ULP(1) 的各种倍数或二进制分数。它只是浮点格式量化的产物。
推荐阅读
- python - 正则表达式在关键字上方两行提取部分日志文件
- reactjs - InputProps min 和 max 没有被强制执行
- r - 在 R 中运行 GUI 的错误
- vba - 添加名为当前日期的列
- java - 在 Spring Boot 应用程序中使用 Docker 保护密钥的最佳方法是什么
- python - 在 tox 部分自动选择平台(或其他)条件
- oracle - 无法将 weblogic 12.2.1.4 服务器添加到 eclipse
- jmeter - Jmeter - 如何使用阈值比较两个数字
- javascript - 如何更改悬停时的图标颜色?
- json - 使用 JSON_MODIFY(),当名称未知或未指定时,如何将字符串附加到根路径?