0

我正在尝试lgamma使用递归进行计算。但它没有按预期工作并给出Nanand -Inf。这可能是什么原因?

sum = 0
log_gamma_recursive <- function(n) {
  if(n == 1){
    return(1)
  }else{
    sum = sum + log(log_gamma_recursive(n-1))
    print(sum)
    return(sum)
  }
}#log 4  + log 3 + log 2 + log 1
log_gamma_recursive(5)
4

2 回答 2

1

代码有三处错误:

  1. sum不应该是全局变量,因为连续的“外部”调用将返回一个累积值
  2. 您将log返回值添加到sum. 这将给出一系列嵌套日志:
    • 你明白log 4 + log(log 3 + log(log 2 + log (log 1))))了,这显然是错误的
    • log(log 1) = log 0从数学上讲,它趋于负无穷大,但是库可能会将其归类为有效输入,也可能不归类为有效输入
  3. log_gamma(1)是 0,不是 1

考虑到这一点,试试这个:

log_gamma_recursive <- function(n) {
  if (n <= 1) {
    return (0)
  }else{
    sum = (log(n-1) + log_gamma_recursive(n-1))
    print(sum)
    return(sum)
  }
}
于 2018-01-21T20:52:33.317 回答
1

由于 R 可以进行向量化计算,因此对结果向量和求和执行对数是安全的。

 ll=function(x)sum(log(1:(x-1)))

这有什么好处?这可以计算无法计算的值log_gamma_recursive。召回log_gamma_recursive是一个嵌套函数,因此在某些时候会失败,具体取决于机器容量。例如:

log_gamma_recursive(3476)
[1] 24862.89
ll(3476)
[1] 24862.89

在这台机器上,log_gamma_recursive不适用于任何大于 3476 的数字:

log_gamma_recursive(3477)
Error: C stack usage  7970456 is too close to the limit

另一方面,该ll功能有效:

ll(3477)
[1] 24871.04

同时,ll函数比函数快得多log_recursive

system.time(for(i in 1:10000)ll(3000))
   user  system elapsed 
  0.313   0.036   0.350 
system.time(for(i in 1:10000)log_gamma_recursive(3000))
   user  system elapsed 
 20.569   0.100  20.794 

这些单位以秒为单位!!

于 2018-01-21T23:21:21.237 回答