2016-11-29 19 views
6

Hesaplamalarımı hızlandırmak ve m işlevinde döngü kullanmadan sonuç almak istiyorum. Tekrar üretilebilir örnek:R: döngüden kurtulmak ve hız kodu

N <- 2500 
n <- 500 
r <- replicate(1000, sample(N, n)) 

m <- function(r, N) { 
    ic <- matrix(0, nrow = N, ncol = N) 
    for (i in 1:ncol(r)) { 
    p <- r[, i] 
    ic[p, p] <- ic[p, p] + 1 
    } 
    ic 
} 

system.time(ic <- m(r, N)) 
# user system elapsed 
# 6.25 0.51 6.76 
isSymmetric(ic) 
# [1] TRUE 
biz matriks değil vektörü ile ilgileniyor for döngünün her tekrarında

, bu nedenle bu nasıl Vektörize olabilir?

@ joel.wilson Bu işlevin amacı, elemanların ikili frekanslarını hesaplamaktır. Bundan sonra, çift taraflı eklenme olasılıklarını tahmin edebiliriz.

@Khashaa ve @alexis_laz'a teşekkürler. Deneyler: Bu çifte endeksleme işlemleri ortadan kaldırdığı

> require(rbenchmark) 
> benchmark(m(r, N), 
+   m1(r, N), 
+   mvec(r, N), 
+   alexis(r, N), 
+   replications = 10, order = "elapsed") 
      test replications elapsed relative user.self sys.self user.child sys.child 
4 alexis(r, N)   10 4.73 1.000  4.63  0.11   NA  NA 
3 mvec(r, N)   10 5.36 1.133  5.18  0.18   NA  NA 
2  m1(r, N)   10 5.48 1.159  5.29  0.19   NA  NA 
1  m(r, N)   10 61.41 12.983  60.43  0.90   NA  NA 
+1

vectorized edilebilir fonksiyonun amacı? Bunu açıklayabilir misin? –

+0

Bir matris sadece boyutları ile vektördür. – Tensibai

+0

Hız endişeniz varsa, o zaman uygulama işlevlerini kullanmayı düşünmelisiniz. – Ansjovis86

cevap

6

Bu daha hızlı belirgin olmalıdır

m1 <- function(r, N) { 
    ic <- matrix(0, nrow = N, ncol=ncol(r)) 
    for (i in 1:ncol(r)) { 
    p <- r[, i] 
    ic[, i][p] <- 1 
    } 
    tcrossprod(ic) 
} 

system.time(ic1 <- m1(r, N)) 
# user system elapsed 
# 0.53 0.01 0.55 

all.equal(ic, ic1) 
# [1] TRUE 

Basit "sayma ekleme /" operasyonları hemen hemen her zaman çekirdek ne

mvec <- function(r, N) { 
    ic <- matrix(0, nrow = N, ncol=ncol(r)) 
    i <- rep(1:ncol(r), each=nrow(r)) 
    ic[cbind(as.vector(r), i)] <- 1 
    tcrossprod(ic) 
} 
+0

Harika, 10 kat daha hızlı! Teşekkür ederim. Ama hala merak ediyorum, bunu döngü olmadan yapabilir miyiz? – minem

+0

Evet, bunu döngü olmadan yapabiliriz. Güncelleştirmeye bakın – Khashaa

+0

Teşekkür ederiz! Eşek cevaplamak için ilk işlevinizi (döngü ile) ekleyebilir misiniz, böylece 3 işlev için bazı kriterler ekleyebilirim. – minem