2013-10-10 81 views
2

我試圖使用並行R包foreach高音for循環。 out應該是一個三維陣列,我不斷得到一個二維矩陣。一個簡單的例子:高音循環使用R foreach

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

回答

1

問題是cbind正在將矩陣逐列組合成更大的矩陣。您需要的是將矩陣組合爲3-D陣列的功能,例如abind軟件包中的abind功能。因爲它需要一個額外的參數,我定義組合函數爲:

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的建議平行化外環,以便工作人員執行大部分組合。

+0

將你的答案擴展到四重循環並不是那麼明顯,或者我只是在緩慢。如果您/其他人可以再次幫忙,我會很感激 –

1

你擁有所有正確的數據,你只需要更改尺寸:如果你想在尺寸使得out[i,j,k] == fun(aa[i],bb[k],cc[k]),那麼你需要置換他們像

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

這樣的:

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 
+0

謝謝,這有幫助!有關foreach函數的任何提示也將非常棒!無論哪種方式,您的答案是有幫助的! –

+1

您可能不需要第三個循環中的'%dopar%'。嘗試用'%do%'代替,它可能會更快。通常情況下,最好儘可能粗略地進行並行處理,這樣可以減少在線程中分配任務的時間,並減少實際執行工作的時間。 – mrip