2012-06-26 53 views
3

嗨我有一個R函數,我試圖優化性能。我需要矢量化for循環。我的問題是稍微複雜的數據結構以及我需要使用'which'命令執行查找的方式。假設我們處理5個元素(1,2,3,4,5),10x2矩陣對是所有唯一對的組合,即5個元素(即(1,2),(1,3) ),(1,4)....(4,5))。 all_prods是一個10x1的矩陣,我需要使用這些對來查找,同時遍歷所有5個元素。R - 矢量化哪一個操作

因此,對於1,我需要從all_prods等1,2,3,4,4(1,2,3,4和1,5對)中索引1,2,3,4和1,2,3行, 5.

我最近才從matlab切換到R,所以非常感謝任何幫助。

foo <- function(AA , BB , CC){ 
    pa <- AA*CC; 
    pairs <- t(combn(seq_len(length(AA)),2)); 

    all_prods <- pa[pairs[,1]] * pa[pairs[,2]]; 

    result <- matrix(0,1,length(AA)); 

    # WANT TO VECTORIZE THIS BLOCK 
    for(st in seq(from=1,to=length(AA))){ 
     result[st] <- sum(all_prods[c(which(pairs[,1]==st), which(pairs[,2]==st))])*BB[st]; 
    } 
    return(result); 
} 
AA <- seq(from=1,to=5); BB<-seq(from=11,to=15); CC<-seq(from=21,to=25); 
results <- foo(AA,BB,CC); 

#final results is [7715 164208 256542 348096 431250] 

我想將for循環轉換爲矢量化版本。我不想循環遍歷每一個元素st,我想在一個命令中給出結果向量(而不是逐個元素地構建它)。

在此先感謝。

+1

我建議你提供一些樣本數據來玩。看到http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example –

+0

我不知道這是你的瓶頸。你預先分配一個好的矩陣,但combn和t很貪婪。你有沒有嘗試分析你的代碼? –

+0

我想將for循環轉換爲矢量化版本。我不想循環遍歷每個元素st,而是希望在一個命令中完成它,這個命令爲我提供了一個結果向量(而不是逐個構建它)。我沒有做出更明確的道歉。我已更新該帖子。 – user1480926

回答

8

你可以寫你的函數是這樣的:

foo <- function(AA, BB, CC) { 
    pa <- AA*CC 
    x <- outer(pa, pa) 
    diag(x) <- 0 
    res <- colSums(x)*BB 
    return(res) 
} 

的核心思想是打破對稱。您使用訂購的pairs對應於我的矩陣x的右上角三角形。儘管這似乎只是計算值的一半,但句法和計算開銷卻變得相當大。你區分st是第一個元素與第二個元素的區別。後來這會導致擺脫這種區別的困難。擁有完全對稱矩陣,您不必擔心順序,並且順利矢量化。

+0

謝謝MvG這是一個很棒的概念課! – user1480926