2016-01-26 60 views
0

我想知道如何計算R中的大數值乘法。 R返回Inf!R中的大數乘法

例如:

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 for nv我檢查了部分代碼段,我發現這些n值返回的結果poch(r,k)是Inf。(w lam)^ k poch(r,k)我還檢查我的代碼在數學等效代碼這一切都OK了:

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} 

現在請讓我知道如何解決這個問題,因爲簡單,因爲它是在數學。問候。你必須在基礎R,它不需要專門的庫中可用

+2

嘗試'GMP :: mul.bigz(6.350218e + 277,+ 2.218789e 215)' – Khashaa

+0

或用[大人國(https://cran.r-project.org/web/ packages/Brobdingnag/index.html)庫 –

+0

感謝Khashaa 2,但它返回:錯誤mul.bigz(6.350218e + 277 * 2.218789e + 215): 參數「e2」丟失,沒有默認 –

回答

4

對於第一,我建議兩個有用的記載:logarithmshow floating values are handled by a computer。這些都是相關的,因爲用一些「技巧」你可以處理比你想象的更大的價值。例如,您對poch函數的定義非常糟糕。這是因爲分數可以被簡化很多,但計算機會首先評估分子,如果它溢出,結果將是無用的。這就是爲什麼R提供旁邊gammalgamma功能:它只是計算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 
+2

還有'lfactorial'。 – Roland

+0

@Roland是的,當然,因爲'factorial'只是'gamma'(和'lgamma'的'lfactorial')的包裝。 – nicola

+0

非常感謝nicola,現在需要更多的新方程式。 –

6

一種選擇,是將兩個數字轉換爲一個共同的基礎,然後添加指數合力得到最終結果:

> 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

也許值得指出的是,浮點精確度起着一定的作用,但通常與此數量級無關 – Roland

+0

從我童年時代起,無限加上一個仍然是無窮大:-) –

+0

親愛的Tim Biegeleisen,但R中10^493.1489的結果仍然是Inf並且有問題沒有解決!!!!!! –

4
> library(gmp) 
> x<- pow.bigz(6.350218,277) 
> y<- pow.bigz(2.218789,215) 
> x*y 

Big Integer ('bigz') : 
[1] 18592826814872791919942226542714580401488894909642693257011204682802122918146288728149155739011270579948954646130492024596687919148494136290260248656581476275790189359808616520170359345612068099238508437236172770752199936303947098513476300142414338199993261924467166943683593371648