Как говорит Дирк, скомпилированный код может быть намного быстрее.Я должен был сделать это для одного из моих проектов и был удивлен ускорением: ~ в 40 раз быстрее, чем решение Andrie.
> a <- runif(10000)
> b <- runif(10000)
> system.time(convolveFast(a, b))
user system elapsed
7.814 0.001 7.818
> system.time(convolveC(a, b))
user system elapsed
0.188 0.000 0.188
Я сделал несколько попыток ускорить это в R, прежде чем решил, что с помощью кода на Cне может быть так плохо (примечание: это действительно не было).Все мои были медленнее, чем у Андри, и были вариантами правильного сложения перекрестного продукта.Элементарная версия может быть сделана всего за три строки.
convolveNotAsSlow <- function(x, y) {
xyt <- x %*% t(y)
ds <- row(xyt)+col(xyt)-1
tapply(xyt, ds, sum)
}
Эта версия только немного помогает.
> a <- runif(1000)
> b <- runif(1000)
> system.time(convolveSlow(a, b))
user system elapsed
6.167 0.000 6.170
> system.time(convolveNotAsSlow(a, b))
user system elapsed
5.800 0.018 5.820
Моя лучшая версия была такой:
convolveFaster <- function(x,y) {
foo <- if (length(x)<length(y)) {y %*% t(x)} else { x %*% t(y) }
foo.d <- dim(foo)
bar <- matrix(0, sum(foo.d)-1, foo.d[2])
bar.rc <- row(bar)-col(bar)
bar[bar.rc>=0 & bar.rc<foo.d[1]]<-foo
rowSums(bar)
}
Это было немного лучше, но все же не так быстро, как у Андри
> system.time(convolveFaster(a, b))
user system elapsed
0.280 0.038 0.319