我正在处理一些编程问题,在这些问题中,我必须在标准空间和日志空间之间转换概率。为此,我试图找出最大绝对误差,用于计算log(exp(...))的R中的浮点误差,其中输入是日志概率(即非正数)。
目前,我已经使用网格搜索计算了答案(请参阅下面的代码和图表),但我不确定我计算的值是否正确。(我检查了其他一些范围,但图中显示的范围似乎得到了最大的绝对误差。)
#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)。我不知道这是否有理论上的原因,或者我是否得到了错误的答案。
问题:有任何方法来确定这是否是这个计算的最大浮点误差?是否有任何理论方法来计算最大值,或者这种网格搜索方法是否足够?
发布于 2021-06-21 08:43:50
我想你得到了正确的答案。在这里,我细化了像sqrt(.Machine$double.eps)这样小的步骤,您将看到
> x <- seq(0, 2, by = sqrt(.Machine$double.eps))
> max(abs(log(exp(x)) - x))
[1] 1.110725e-16但是,一旦您的x非常大,您就会出现Inf错误,例如,
> (x <- .Machine$double.xmax)
[1] 1.797693e+308
> max(abs(log(exp(x)) - x))
[1] Inf发布于 2021-06-21 10:22:46
log(exp(x))的误差取决于x的值。如果使用浮点数,x也有一个精度,这取决于它的值。裂变可以用nextafter从C中计算。
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
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
}还可以看看:检查差异是否小于机器精度的正确/标准方法是什么?。
发布于 2021-06-21 13:30:10
通常,我建议使用随机方法生成更多的x,例如:
x <- runif(10000000, 0, 2)您的定期间隔的值可能会碰巧被“只起作用”的模式绊倒。
此外,这取决于您是否关心绝对错误或相对误差。绝对误差应接近.Machine$double.xmax,而相对误差则随着x接近于零而增加。例如,log(exp(1e-16))被截断为零。
https://stackoverflow.com/questions/68063995
复制相似问题