在日志空间中乘以两个数字意味着添加它们:
log_multiply(x, y) = log( exp(x) * exp(y) )
= x + y
在日志空间中添加两个数字意味着您执行了特殊的日志添加操作:
log_add(x, y) = log( exp(x) + exp(y) )
在以下代码中实现,其方式不需要我们采用两个指数(并且失去运行时速度和精度):
double log_add(double x, double y) {
if(x == neginf)
return y;
if(y == neginf)
return x;
return max(x, y) + log1p(exp( -fabs(x - y) ));
}
(Here是另一个。)
但问题是:
还有一个技巧可以用于减法吗?
log_subtract(x, y) = log( exp(x) - exp(y) )
不必拿指数而失去精确度?
double log_subtract(double x, double y) {
// ?
}
答案 0 :(得分:11)
怎么样
double log_subtract(double x, double y) {
if(x <= y)
// error!! computing the log of a negative number
if(y == neginf)
return x;
return x + log1p(-exp(y-x));
}
这只是基于我做的一些快速数学......
答案 1 :(得分:3)
exp和log的库函数会丢失极值的精度。 log1p让你到了一半,但你需要的是一个处理日志和exp部分错误的函数。
请参阅此文章:http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf
标题是“准确计算日志(1 - exp( - | a |))”。
本文讨论了如何无缝合并不同的算法,为更大范围的输入创建良好的误差范围。