首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用doMC进行并行仿真研究中的组合功能需要帮助

利用doMC进行并行仿真研究中的组合功能需要帮助
EN

Stack Overflow用户
提问于 2014-05-05 05:57:29
回答 1查看 231关注 0票数 1

我想在为foreach()编写一个组合函数时寻求一些帮助。考虑以下职能:

代码语言:javascript
复制
library(mvtnorm)
library(doMC)

mySimFunc <- function(){
  myNum <- runif(1)
  myVec <- rnorm(10)
  myMat <- rmvnorm(5, rep(0, 3), diag(3))
  myListRslt <- list("myNum" = myNum, "myVec" = myVec, "myMat" = myMat)
return (myListRslt)
}

现在,我想使用foreach() %dopar%运行上面的代码1000次,并且在每次迭代中我想:

  1. 按原样返回myNum
  2. 获取myVec的平均值并返回它
  3. 获取myMat的myMat()并返回它。

我希望foreach() %dopar%返回一个最终列表,包括:

  1. 长度为1000 myNum的向量,每个向量对应于一个迭代
  2. 长度为1000的向量,包括每次迭代中myVec的平均1000次
  3. 一个有1000行的矩阵,其中每一行在迭代中都包含colMeans of myMat。

我的理想解决方案

我的理想解决方案是o找到一种与foreach()完全相同的方式,这样我就可以简单地定义:

代码语言:javascript
复制
myNumRslt <- NULL
myVecRslt <- NULL
myMatRslt <- NULL

# and then simply aggregate result of each iteration to the variables above as:
foreach(i = 1:1000) %dopar%{
   rslt <- mySimFunc()
   myNumRslt <- c(myNumRslt, rslt$myNum)
   myVecRslt <- c(myVecRslt, mean(rslt$myVec))
   myMatRslt.tmp <- colMeans(rslt$myMat)
   myMatRslt <- rbind(myMatRslt, myMatRslt.tmp)
}

但是,不幸的是,使用foreach()似乎不可能做到这一点,所以我认为唯一的解决方案是编写一个与上面的结果聚合类似的组合函数。

挑战

1)如何编写返回我前面解释过的内容的组合函数?

2)当我们使用%dopar% (假设使用doMC包)时,doMC是将每个迭代分发给一个CPU,还是进一步将每个迭代分割成更多的片段并进行分发?

3)是否有比使用doMC和foreach()更好(更有效)的方法?idea的question Brian中提到了处理列表(包括数值)的一种很好的方法。在我的例子中,我有数值以及向量和矩阵。我不知道怎么在我的案子里推广布莱恩的想法。

非常感谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-05 08:45:42

编辑

使用.combine清理、通用的解决方案

代码语言:javascript
复制
#modify function to include aggregation
mySimFunc2 <- function(){
myNum <- runif(1)
myVec <- mean(rnorm(10))
myMat <- colMeans(rmvnorm(5, rep(0, 3), diag(3)))
myListRslt <- list("myNum" = myNum, "myVec" = myVec, "myMat" = myMat)
return (myListRslt)
}

#.combine function
MyComb1 <- function(...) {
lst=list(...)
vec<-sapply(1:length(lst), function (i) return(lst[[i]][[1]] ))
vecavg<-sapply(1:length(lst),function (i) return(lst[[i]][[2]] ))
colmeans<-t(sapply(1:length(lst), function (i) return(lst[[i]][[3]])))
final<-list(vec,vecavg,colmeans)
names(final)<-c("vec","vecavg","colmeans")
return(final)
}

library(doParallel)
cl <- makeCluster(3) #set cores
registerDoParallel(cl)

foreach(i=1:1000,.export=c("mySimFunc2","MyComb1"),.combine=MyComb1,
.multicombine=TRUE,.maxcombine=1000, .packages=c("mvtnorm"))%dopar%{mySimFunc2()}

现在您应该有一个列表输出,它包含所需的三个对象,我将其分别命名为vecvecavgcolmeans。注意,如果迭代次数大于100,则必须将.maxcombine设置为迭代次数。

顺便提一句,对这个示例任务进行并行化是没有意义的,尽管我猜真正的任务可能更复杂。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23465741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档