R - 矢量化哪个操作

时间:2012-06-26 09:31:40

标签: r loops vectorization which

嗨我在R中有一个功能,我正在尝试优化性能。我需要向量化循环。我的问题是稍微复杂的数据结构以及我需要使用'which'命令执行查找的方式。

假设我们正在处理5个元素(1,2,3,4,5),10x2矩阵对是5个元素的所有唯一对的组合(即(1,2),(1,3) ,(1,4)....(4,5))。 all_prods是一个10x1矩阵,我需要在迭代所有5个元素时使用这些对查找。

因此对于1,我需要从all_prods索引1,2,3,4(1,2,3,4和1,5对)行,依此类推1,2,3,4,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 个答案:

答案 0 :(得分: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是该对中的第一个元素,而第二个元素是第二个元素。后来这导致摆脱这种区别相当麻烦。拥有完整的对称矩阵,您不必担心顺序,并且事物可以顺利地进行矢量化。