Векторизация функции: cumsum с параметром затухания

Я написал вариант из cumsum функция, где я умножаю предыдущую сумму на коэффициент убывания перед добавлением текущего значения:

decay <- function(x, decay=0.5){
  for (i in 2:length(x)){
    x[i] <- x[i] + decay*x[(i-1)]
  }
  return(x)
}

Вот демонстрация, использующая двоичную переменную, чтобы прояснить эффект:

set.seed(42)
Events <- sample(0:1, 50, replace=TRUE, prob=c(.7, .3))
plot(decay(Events), type='l')
points(Events)

Rplot

Компиляция этой функции значительно ускоряет:

#Benchmark
library(compiler)
library(rbenchmark)
cumsum_decayCOMP <- cmpfun(cumsum_decay)
Events <- sample(0:1, 10000, replace=TRUE, prob=c(.7, .3))
benchmark(replications=rep(100, 1),
          cumsum_decay(Events),
          cumsum_decayCOMP(Events),
          columns=c('test', 'elapsed', 'replications', 'relative'))

                      test elapsed replications relative
1     cumsum_decay(Events)    3.28          100    6.979
2 cumsum_decayCOMP(Events)    0.47          100    1.000

Но я подозреваю, что векторизация улучшит это еще больше. Есть идеи?

1 ответ

Решение

Попробуйте filter функция:

filter.decay <- function(x, decay=0.5) filter(x, decay, method = "recursive")

Это очень быстро:

#                       test elapsed replications relative
# 1     cumsum_decay(Events)    4.83          100    19.32
# 2 cumsum_decayCOMP(Events)    1.00          100     4.00
# 3     filter.decay(Events)    0.25          100     1.00
Другие вопросы по тегам