Como dice Dirk, el código compilado puede ser mucho más rápido. Tuve que hacer esto para uno de mis proyectos y me sorprendió la aceleración: ~ 40 veces más rápido que la solución de 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
Me hicieron varios intentos para acelerar este proceso en I antes de que decidiera que el uso de código C no podía ser tan malo (nota: en realidad no lo era). Todos los míos fueron más lentos que los de Andrie, y fueron variantes al sumar el producto cruzado de manera apropiada. Una versión rudimentaria se puede hacer en solo tres líneas.
convolveNotAsSlow <- function(x, y) {
xyt <- x %*% t(y)
ds <- row(xyt)+col(xyt)-1
tapply(xyt, ds, sum)
}
Esta versión solo ayuda un poco.
> 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
Mi mejor versión era la siguiente:
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)
}
Este fue un poco mejor, pero todavía no es tan rápido como de
> system.time(convolveFaster(a, b))
user system elapsed
0.280 0.038 0.319
Parece que está utilizando listas de vectores de elementos individuales en lugar de vectores. – mbq