2016-05-25 2 views
0

Я хочу использовать таблицу-поиск, чтобы ускорить некоторые, но не другие вычисления. Например, для нормального распределения КОР: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

ответ

0

Не ответ, но я не чувствую, что я мог бы соответствовать это в комментарии, извините:

на основе вашей функции, и, как вы назвали, м = 0 и sd = 1, что означает, что z всегда будет равно x. Таким образом, всякий раз, когда х находится вне Минца в MaxZ диапазон, ваше выражение:

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

В вашей первой последовательности (-2: 2), вы никогда не столкнётесь с этим (он всегда равен FALSE), но в вашей второй (-8 : 8) вы делаете. Так что это единственный раз, когда вы звоните

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

Ваша проблема, скорее всего, там. Я не знаю, что это за функция, вы сами определили ее?

+0

Да, это то, что оно превышает массив. одним из способов решения этой проблемы было бы поставить еще один ifelse в индекс массива, но это другое условие и уродливое. Я уточнил, что такое cdf (т. Е. Pnorm). –

Смежные вопросы