我正在尝试使用递归来计算lgamma
。但它没有按预期工作,而是发出Nan
和-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)
答案 0 :(得分:1)
代码有三个问题:
sum
不应该是全局变量,因为连续的“外部”调用将返回累计值log
添加到sum
。这将提供一系列嵌套日志:
log 4 + log(log 3 + log(log 2 + log (log 1))))
,这显然是错误的log(log 1) = log 0
在数学上倾向于负无穷大,但图书馆可能会也可能不会将此归类为有效输入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)
}
}
答案 1 :(得分:1)
由于R可以执行向量化计算,因此可以安全地对结果向量和总和进行记录。
ll=function(x)sum(log(1:(x-1)))
这有什么好处?这可以计算log_gamma_recursive
无法计算的值。 Recall 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
这些单位在几秒钟内!!