2012-06-26 51 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