代码之家  ›  专栏  ›  技术社区  ›  Frank

我们知道对数加,但怎样做对数减?

  •  13
  • Frank  · 技术社区  · 16 年前

    乘法 日志空间中的两个数字意味着将它们相加:

    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) {
        // ?
      }
    
    2 回复  |  直到 11 年前
        1
  •  11
  •   David Z    16 年前

    怎么样

    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));
    }
    

    这只是我做的一些简单的数学计算…

        2
  •  3
  •   Paul Chernoch    13 年前

    exp和log的库函数会失去极值的精度。 log1p可以让您到达一半,但您需要的是一个函数,它可以同时处理日志和exp部分的错误。

    请参阅本文: http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf

    标题是“精确计算日志(1-exp(-a))”。

    本文讨论了如何无缝合并不同的算法,为更大范围的输入创建良好的误差边界。

    推荐文章