微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从嵌套并行foreach 循环中取回矩阵数组?

如何解决如何从嵌套并行foreach 循环中取回矩阵数组?

具有唯一对象的列表,其中身份很重要(因此排序...但仅用于跟踪身份):

fakeDataList <- list(one = 1,two = 2,three = 3,four = 4)

一个执行成对计算的函数...

fakeInnerFxn <- function(l){
  x <- l[[1]]
  y <- l[[2]]
  low <- x + y - 1
  mid <- x + y
  high <- x + y + 1
  out <- c(low,mid,high)
  return(out)
}

... 并且每对 id 返回三个值

fakeInnerFxn(fakeDataList[c(1,2)])
#> [1] 2 3 4

内部函数嵌套在外部函数中,外部函数对完整列表执行每个成对操作...

fakeOuterFxn <- function(d){
  n <- length(d)
  out <- array(0,dim = c(n,n,3))
  colnames(out) <- names(d)
  rownames(out) <- names(d)
  for(i in 1:n){
    for(j in (i+1):n){
      if (j <= n) {
        out[i,j,] <- fakeInnerFxn(d[c(i,j)])
      }
    }
  }
 diag(out[,1]) <- 0  # not sure how to do this succinctly 
 diag(out[,2]) <- 0   
 diag(out[,3]) <- 0   
 
 return(out)
}

... 并返回一个由三个矩阵组成的数组,分别代表“低”、“中”和“高”

fakeOuterFxn(fakeDataList)
#>,1
#> 
#>       one two three four
#> one     0   2     3    4
#> two     0   0     4    5
#> three   0   0     0    6
#> four    0   0     0    0
#> 
#>,2
#> 
#>       one two three four
#> one     0   3     4    5
#> two     0   0     5    6
#> three   0   0     0    7
#> four    0   0     0    0
#> 
#>,3
#> 
#>       one two three four
#> one     0   4     5    6
#> two     0   0     6    7
#> three   0   0     0    8
#> four    0   0     0    0

实际数据是一个很长的列表,计算速度很慢。

如何使用 foreach 和 doParallel 并行化此代码,以保留数组并保留行/列顺序(或至少能够跟踪并在最后重新排序)?

library(foreach)
library(doParallel)
#> Loading required package: iterators
#> Loading required package: parallel

registerDoParallel(detectCores()-2)  

for 循环不需要在函数内部,但如果在函数内部就很好了。

d <- fakeDataList
n <- length(d)

这真的是我所能做到的:

out <- foreach(i=1:n,.combine = 'c') %:%
  foreach(j=(i+1):n,.combine = 'c') %dopar% {
    if (j <= n) {
      fakeInnerFxn(d[c(i,j)])
    }
  }

答案都在这里,但我如何取回数组?

out
#>  [1] 2 3 4 3 4 5 4 5 6 4 5 6 5 6 7 6 7 8 7 8 9

reprex package (v1.0.0) 于 2021 年 6 月 22 日创建

解决方法

您始终可以返回带有结果的索引,并在以后重建您的数组。

res <- foreach(i=1:(n-1),.combine = 'c') %:%
  foreach(j=(i+1):n) %dopar% {
    list(i,j,fakeInnerFxn(d[c(i,j)]))
  }

n <- length(d)
out <- array(0,dim = c(n,n,3))
for (res_k in res) out[res_k[[1]],res_k[[2]],] <- res_k[[3]]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。