2

我尝试将并行 R 包foreach用于高音 for 循环。out应该是一个 3-d 数组,我不断得到一个 2-d 矩阵。一个简单的例子:

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) }
}
4

2 回答 2

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
于 2013-10-10T15:47:47.103 回答
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 建议的那样,以便工作人员执行大部分合并。

于 2013-10-10T22:50:42.627 回答