简体   繁体   English

as.integer(8952) = 8951?

[英]as.integer(8952) = 8951?

I accidentally discovered a weird bug with either the as.integer or the det function in R base.我无意中发现了一个奇怪的错误,其中as.integer或 R 基础中的det function 。 Does anyone know what is going on here and how to prevent it?有谁知道这里发生了什么以及如何防止它?

I was computing the determinant of the following 3-by-3 matrix:我正在计算以下 3×3 矩阵的行列式:

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

Which looks like this:看起来像这样:

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

Two things are easy to see: all entries are integers, and each of the six sets of three-entries-no-two-of-which-lie-in-the-same-row-or-column contains at least one even integer.有两件事很容易看出:所有条目都是整数,并且六组三条目中的每一个都包含至少一个偶数 integer . Hence the determinant must be an even integer.因此行列式必须是偶数 integer。

Asking R the actual value of this determinant by typing det(mat) it returns something that looks like an even integer: 8952 .通过键入det(mat)询问 R 这个行列式的实际值,它返回的东西看起来像一个偶数 integer: 8952 But lo and behold: deep down inside R's mind it actually is either a non-integer or an odd integer, since when typing as.integer(det(mat)) we get 8951 .但是你瞧:在 R 的内心深处,它实际上要么是一个非整数,要么是一个奇怪的 integer,因为当键入as.integer(det(mat))时,我们得到8951

What is going on here?这里发生了什么? The 8951 is obviously wrong. 8951显然是错误的。 Also, less obviously, the value 8952 is correct as can be seen with pen and paper.此外,不太明显的是,值 8952 是正确的,可以用笔和纸看出。

So my questions are:所以我的问题是:

  1. what is going on here?这里发生了什么?

  2. How do I force R to give me the correct integer values when asked to compute the determinant of an integer matrix?当被要求计算 integer 矩阵的行列式时,如何强制 R 给我正确的 integer 值?

Underlying causes: Truncation by is.integer rather than rounding and floating point math on logged intermediate values to explain the second result, combined with the default digit level of display in the print portion of the console REPL to explain the initial result of det(mat) :根本原因:被is.integer截断而不是对记录的中间值进行舍入和浮点数学来解释第二个结果,结合控制台 REPL 的print部分中显示的默认数字级别来解释det(mat) :

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

It's quite possible that the theoretic answer is 8952 but R is not a symbolic math engine.理论答案很可能是 8952,但 R 不是符号数学引擎。

在此处输入图像描述

You can use the Rmpfr package (as suggested by @BenBolker) to increase the level of precision:您可以使用 Rmpfr package(如@BenBolker 建议的那样)来提高精度:

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

as.integer truncates rather than rounds. as.integer截断而不是舍入。 See ?as.integer .参见?as.integer R would be able to handle addition or multiplication of integers without loss of precision but as soon as division occurs there is likely to be floating point error. R 能够在不损失精度的情况下处理整数的加法或乘法,但一旦发生除法,就可能出现浮点错误。 (Actually the problem arises because the default for det is to use determinant with log=TRUE and then exponentiate the modulus of the complex result.) From the Values section of the help page: (实际上出现问题是因为det的默认值是使用log=TRUEdeterminant ,然后对复数结果的模取幂。)从帮助页面的 Values 部分:

Non-integral numeric values are truncated towards zero (ie, as.integer(x) equals trunc(x) there), and imaginary parts of complex numbers are discarded (with a warning).非整数数值被截断为零(即, as.integer(x) ) 在那里等于trunc(x) ),并且复数的虚部被丢弃(带有警告)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM