使用R foreach进行高音循环

时间:2013-10-10 15:07:33

标签: r parallel-foreach

我尝试使用并行R包foreach进行高音循环。 out应该是一个三维数组,我不断得到一个二维矩阵。一个简单的例子:

library(foreach)
library(doParallel)

aa <-  seq(1,10, length=4)
bb <- seq(0,1, length=4)
cc <- seq(0,1, length=4)

fun <- function(a,b,c){return(a+b-c)}
out <- array(NaN, dim=c(4,4,4))

registerDoParallel()
out <- foreach(i = aa, .combine='cbind', .multicombine=TRUE) %dopar% {
  foreach(j = bb, .combine='cbind', .multicombine=TRUE) %:%
    foreach(k = cc, .combine='c') %dopar% { fun(i, j,k) }
}

2 个答案:

答案 0 :(得分:1)

您拥有所有正确的数据,只需更改尺寸:

dim(out)<-c(4,4,4)

如果您希望尺寸为out[i,j,k] == fun(aa[i],bb[k],cc[k]),那么您需要像这样对它们进行置换:

out<-aperm(out,c(3,2,1))

这可以验证:

out2<-array(0,dim(out))
for(i in 1:4)
  for(j in 1:4)
    for(k in 1:4)
      out2[i,j,k]<-fun(aa[i],bb[j],cc[k])

identical(out,out2)
## [1] TRUE

答案 1 :(得分:1)

问题在于cbind正在将矩阵逐列组合成更大的矩阵。您需要的是一个将矩阵组合成3-D数组的函数,例如abind包中的abind函数。由于它需要一个额外的参数,我将combine函数定义为:

mbind <- function(...) abind(..., along=3)

以下是我将如何将其用于您的示例:

library(abind)
library(doParallel)
registerDoParallel()
aa <- seq(1,10, length=4)
bb <- seq(0,1, length=4)
cc <- seq(0,1, length=4)

fun <- function(a,b,c) {return(a+b-c)}
mbind <- function(...) abind(..., along=3)

out <-
  foreach(i=aa, .combine='mbind', .multicombine=TRUE) %:%
    foreach(j=bb, .combine='cbind') %:%
      foreach(k=cc, .combine='c') %dopar% {
        fun(i, j, k)
      }

在Linux和Mac OS X上,整个嵌套循环将变为对mclapply的单个调用。如果组合结果需要花费太多时间,那么仅按照mrip的建议并行化外循环可能会更好,这样工作人员就可以执行大部分组合。