Я хочу использовать таблицу-поиск, чтобы ускорить некоторые, но не другие вычисления. Например, для нормального распределения КОР: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, которое только проверяет истинную сторону оператора для каждого векторного элемента.
Каков путь к решению этой маленькой дилеммы? совет приветствуется.
С уважением,/IAW
Да, это то, что оно превышает массив. одним из способов решения этой проблемы было бы поставить еще один ifelse в индекс массива, но это другое условие и уродливое. Я уточнил, что такое cdf (т. Е. Pnorm). –