Come dice Dirk, il codice compilato può essere molto più veloce. Ho dovuto farlo per uno dei miei progetti e sono rimasto sorpreso dall'accelerazione: ~ 40 volte più veloce della soluzione di 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
ho fatto diversi tentativi per accelerare questo in R prima ho deciso che utilizzando il codice C non poteva essere così male (nota: in realtà non era). Tutti i miei erano più lenti di quelli di Andrie, e c'erano varianti per aggiungere il prodotto incrociato in modo appropriato. Una versione rudimentale può essere fatta in sole tre righe.
convolveNotAsSlow <- function(x, y) {
xyt <- x %*% t(y)
ds <- row(xyt)+col(xyt)-1
tapply(xyt, ds, sum)
}
Questa versione aiuta solo un po '.
> 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
La mia migliore versione è stata questa:
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)
}
Questo è stato un po 'meglio, ma ancora non così veloce come di
> system.time(convolveFaster(a, b))
user system elapsed
0.280 0.038 0.319
Sembra che si stiano utilizzando elenchi di vettori di elementi singoli anziché di vettori. – mbq