我想知道如何在R中计算大值乘法。 R返回Inf!
例如:
6.350218e+277*2.218789e+215
[1] Inf
让我更多地澄清问题: 考虑以下代码和outFunc函数的结果:
library(hypergeo)
poch <-function(a,b) gamma(a+b)/gamma(a)
n<-c(37 , 41 , 4 , 9 , 12 , 13 , 2 , 5 , 23 , 73 , 129 , 22 , 121 )
v<-c(90.2, 199.3, 61, 38, 176.3, 293.6, 318.6, 328.7, 328.1, 313.3, 142.4, 92.9, 95.5)
DF<-data.frame(n,v)
outFunc<-function(k,w,r,lam,a,b) {
((((w*lam)^k) * poch(r,k) * poch(a,b) ) * hypergeo(r+k,a+k,a+b+k,-(w*lam)) )/(poch(a+k,b)*factorial(k))
}
并且函数返回:
outFunc(DF$n,DF$v,0.2, 1, 3, 1)
[1] 0.002911330+ 0i 0.003047594+ 0i 0.029886646+ 0i 0.013560599+ 0i 0.010160073+ 0i
[6] 0.008928524+ 0i 0.040165795+ 0i 0.019402318+ 0i 0.005336008+ 0i 0.001689114+ 0i
[11] Inf+NaNi 0.005577985+ 0i Inf+NaNi
如上所示,outFunc返回Inf + NaNi,其n值为129和121。 我逐个检查了代码部分,发现这些n值的(w lam)^ k poch(r,k)的返回结果是Inf。我还用Mathematica中的等效代码检查我的代码,一切正常:
in: out[indata[[All, 1]], indata[[All, 2]], 0.2, 1, 3, 1]
out: {0.00291133, 0.00304759, 0.0298866, 0.0135606, 0.0101601, 0.00892852, \
0.0401658, 0.0194023, 0.00533601, 0.00168911, 0.000506457, \
0.00557798, 0.000365445}
现在请让我知道如何解决这个问题,就像在Mathematica中一样简单。问候。
答案 0 :(得分:6)
您在基础R中可用的一个选项(不需要特殊的库)是将两个数字转换为公共基数,然后将指数一起添加以获得最终结果:
> x <- log(6.350218e+277, 10)
> x
[1] 277.8028
> y <- log(2.218789e+215, 10)
> y
[1] 215.3461
> x + y
[1] 493.1489
自10^x * 10^y = 10^(x+y)
起,您的最终答案为10^493.1489
请注意,此解决方案不允许实际存储R通常视为INF
的数字。因此,在此示例中,您仍然无法计算10^493
,但您可以梳理出该产品的内容。
答案 1 :(得分:4)
> library(gmp)
> x<- pow.bigz(6.350218,277)
> y<- pow.bigz(2.218789,215)
> x*y
Big Integer ('bigz') :
[1] 18592826814872791919942226542714580401488894909642693257011204682802122918146288728149155739011270579948954646130492024596687919148494136290260248656581476275790189359808616520170359345612068099238508437236172770752199936303947098513476300142414338199993261924467166943683593371648
答案 2 :(得分:4)
首先,我建议使用两个有用的读物:logarithms和how floating values are handled by a computer。这些是相关的,因为有了一些“技巧”,你可以处理比你想象的更大的价值。例如,您对poch
函数的定义很糟糕。这是因为分数可以简化很多,但是计算机会首先评估分子,如果它溢出,结果将是无用的。这就是R
在gamma
lgamma
函数旁边提供的原因:它只计算gamma
的对数,并且可以处理更大的值。因此,我们计算函数中每个因子的log
,然后我们使用exp
来恢复预期值。试试这个:
#redefine poch properly
poch<-function(a,b) lgamma(a+b) - lgamma(a)
#redefine outFunc
outFunc<-function(k,w,r,lam,a,b) {
exp((k*(log(w)+log(lam))+ poch(r,k) + poch(a,b) ) +
log(hypergeo(r+k,a+k,a+b+k,-(w*lam)))- poch(a+k,b)-lgamma(k+1))
}
#Now we go
outFunc(DF$n,DF$v,0.2, 1, 3, 1)
#[1] 0.0029113299+0i 0.0030475939+0i 0.0298866458+0i 0.0135605995+0i
#[5] 0.0101600732+0i 0.0089285243+0i 0.0401657947+0i 0.0194023182+0i
#[9] 0.0053360084+0i 0.0016891144+0i 0.0005064566+0i 0.0055779850+0i
#[13] 0.0003654449+0i