2016-05-25 51 views
0

我想使用表查找來加速一些而不是其他計算。例如,對於正態分佈的CDF:R:使用ifelse矢量化的快速表查找

cdf <- pnorm 

BINS <- 10 
MINZ <- (-5) 
MAXZ <- 5 

cdftbl <- rep(NA, BINS+2) 

xi <- 0; SSZ <- (MAXZ-MINZ)/BINS 
while (xi<=BINS+2) { 
    x <- MINZ+xi*SSZ 
    cdftbl[xi+1] <- pnorm(x, log=TRUE) 
    xi <- xi+1 
} 

fastlogcdf <- function(x, m=0, sd=1) { 
    z <- (x-m)/sd 
    zi <- (z-MINZ)/(MAXZ-MINZ) * BINS 
    zi.whole <- as.integer(zi) 
    zi.frac <- zi-zi.whole 
    zi.index <- zi.whole+1 
    zi.tindex <- pmax(1,zi.index) ## will not throw an array index error! 
    ifelse((zi.index <= 0) | ((zi.index+1) >= BINS), 
     pnorm(x,m,sd,log=TRUE), 
     cdftbl[ zi.index ]+zi.frac*(cdftbl[ zi.index+1 ]-cdftbl[ zi.index ])) } 

這工作(不好),以及與

fastlogcdf(seq(-2,2,0.5)) 

但與

fastlogcdf(seq(-8,8,0.5)) 

因爲ifelse要完全評估這兩個結果根據條件分配之前。通常,我可以忽略這一點,但是這會產生一箇中間錯誤,即只有0可能與負下標混合在一起。當然,沒有cdftable[-8+1]

一種方法是使用我已經定義的tindex,但映射到矢量中的一些隨機無用數字然後丟棄它似乎很奇怪。

唉,即使這個解決方案仍然沒有解決問題,因爲整個觀點是爲了避免表查找時會執行緩慢的pnorm()調用!所以我確實需要一個真正的條件ifelse,它只評估每個向量元素的真實聲明方。

解決這個小難題的R方式是什麼?建議感激。

問候,/ IAW

回答

0

不是一個答案,但我不覺得我能在註釋中符合這一,抱歉:

根據您的功能,你怎麼稱呼它,男= 0和sd = 1,這意味着z總是等於x。因此,只要x是MINZ外MAXZ範圍內,你的表達:

(z<=MINZ)|(z>=MAXZ) returns TRUE 

在你的第一個序列(-2:2),你從來沒有遇到這樣的(它總是等於FALSE),但在你的第二個(-8 :8)你這樣做。所以這是你唯一的一次打電話

cdf(x,m,sd,log=TRUE) 

你的問題很可能存在。我不知道這個功能是什麼,你自己定義了它嗎?

+0

是的,它超出了數組。解決這個問題的一種方法是將另一個ifelse放入數組索引中,但這是另一個條件並且很醜陋。我澄清了cdf是什麼(即,pnorm)。 –