as.integer(8952)=8951?

我不小心发现了R base 中的as.integerdet函数的一个奇怪的错误。有谁知道这里发生了什么以及如何防止它?

我正在计算以下 3×3 矩阵的行列式:

mat <- matrix(c(15, 6, 116, 10, 13, 16, 14, 23, 56), ncol = 3)

看起来像这样:

     [,1] [,2] [,3]
[1,]   15   10   14
[2,]    6   13   23
[3,]  116   16   56

两件事很容易看出:所有条目都是整数,并且六组三个条目中的每一个都包含至少一个偶数. 因此行列式必须是偶数。

通过键入det(mat)它来询问 R 这个行列式的实际值,它返回一个看起来像偶数的东西:8952。但是瞧瞧:在 R 的内心深处,它实际上是一个非整数或奇数整数,因为在键入时as.integer(det(mat))我们会得到8951.

这里发生了什么?8951显然是错误的。此外,不太明显的是,值 8952 是正确的,如用笔和纸所见。

所以我的问题是:

  1. 这里发生了什么?

  2. 当被要求计算整数矩阵的行列式时,如何强制 R 给我正确的整数值?

回答

根本原因:截断is.integer而不是四舍五入和浮点数学对记录的中间值进行解释以解释第二个结果,结合print控制台 REPL 部分中显示的默认数字级别 来解释以下初始结果det(mat)

print( det(mat), digits =16)
[1] 8951.999999999993

理论上的答案很可能是 8952,但 R 不是符号数学引擎。

您可以使用 Rmpfr 包(如@BenBolker 所建议的)来提高精度水平:

 library(Rmpfr)
 mat <- mpfr(mat, 64)
 as.integer( det(mat) )
[1] 8952

as.integer截断而不是舍入。见?as.integer。R 将能够在不损失精度的情况下处理整数的加法或乘法,但一旦发生除法,可能会出现浮点错误。(实际上出现问题是因为默认为det使用determinantwithlog=TRUE然后对复数结果的模取幂。)从帮助页面的值部分:

非整数数值被截断为零(即as.integer(x)等于trunc(x)那里),并丢弃复数的虚部(带有警告)。

  • `as.integer` truncates rather than rounds. See `?as.integer`
  • From the `det` help page: "The determinant function uses an LU decomposition and the `det` function is simply a wrapper around a call to `determinant`.

    Often, computing the determinant is not what you should be doing to solve a given problem."


以上是as.integer(8952)=8951?的全部内容。
THE END
分享
二维码
< <上一篇

)">
下一篇>>