首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >R:计算日志的最大浮点误差(exp(.))

R:计算日志的最大浮点误差(exp(.))
EN

Stack Overflow用户
提问于 2021-06-21 07:32:14
回答 3查看 164关注 0票数 4

我正在处理一些编程问题,在这些问题中,我必须在标准空间和日志空间之间转换概率。为此,我试图找出最大绝对误差,用于计算log(exp(...))R中的浮点误差,其中输入是日志概率(即非正数)。

目前,我已经使用网格搜索计算了答案(请参阅下面的代码和图表),但我不确定我计算的值是否正确。(我检查了其他一些范围,但图中显示的范围似乎得到了最大的绝对误差。)

代码语言:javascript
运行
复制
#Set function for computing floating-point error of log(exp(...))
fp.error <- function(x) { abs(log(exp(x)) - x) }

#Compute and plot floating-point error over a grid of non-negative values
xx <- -(0:20000/10000)
ff <- fp.error(xx)
plot(xx, ff, col = '#0000FF10',
     main = 'Error in computation of log(exp(...))', 
     xlab = 'x', ylab = 'Floating-Point Error')

#Compute maximum floating-point error
fp.error.max <- max(ff)
fp.error.max
[1] 1.110223e-16

根据这一分析,我估计的最大绝对误差是.Machine$double.eps大小的一半(即2.220446e-16)。我不知道这是否有理论上的原因,或者我是否得到了错误的答案。

问题:有任何方法来确定这是否是这个计算的最大浮点误差?是否有任何理论方法来计算最大值,或者这种网格搜索方法是否足够?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-06-21 08:43:50

我想你得到了正确的答案。在这里,我细化了像sqrt(.Machine$double.eps)这样小的步骤,您将看到

代码语言:javascript
运行
复制
> x <- seq(0, 2, by = sqrt(.Machine$double.eps))

> max(abs(log(exp(x)) - x))
[1] 1.110725e-16

但是,一旦您的x非常大,您就会出现Inf错误,例如,

代码语言:javascript
运行
复制
> (x <- .Machine$double.xmax)
[1] 1.797693e+308

> max(abs(log(exp(x)) - x))
[1] Inf
票数 2
EN

Stack Overflow用户

发布于 2021-06-21 10:22:46

log(exp(x))的误差取决于x的值。如果使用浮点数,x也有一个精度,这取决于它的值。裂变可以用nextafterC中计算。

代码语言:javascript
运行
复制
library(Rcpp)
cppFunction("double getPrec(double x) {
  return nextafter(x, std::numeric_limits<double>::infinity()) - x;}")

getPrec(2)
#[1] 4.440892e-16

getPrec(exp(2))
#[1] 8.881784e-16

或者不使用Rcpp

代码语言:javascript
运行
复制
getPrecR <- function(x) {
  y <- log2(pmax(.Machine$double.xmin, abs(x)))
  ifelse(x < 0 & floor(y) == y, 2^(y-1), 2^floor(y)) * .Machine$double.eps
}

还可以看看:检查差异是否小于机器精度的正确/标准方法是什么?

票数 2
EN

Stack Overflow用户

发布于 2021-06-21 13:30:10

通常,我建议使用随机方法生成更多的x,例如:

代码语言:javascript
运行
复制
x <- runif(10000000, 0, 2)

您的定期间隔的值可能会碰巧被“只起作用”的模式绊倒。

此外,这取决于您是否关心绝对错误或相对误差。绝对误差应接近.Machine$double.xmax,而相对误差则随着x接近于零而增加。例如,log(exp(1e-16))被截断为零。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68063995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档