繁体   English   中英

使用foreach的R并行计算可通过不同的操作进行多个输出

[英]R parallel computation with foreach for multiple output by different operation

我想使用foreach来提高计算速度。 我想做的是从单个foreach循环中输出两个结果。

以下是原始想法的简化版本:

output <- list(matrix_addition = matrix(0, nrow = 2, ncol = 2), process_list = list())

for(i in c(1:10)){
  # value_1 indicates some calculation to get the matrix
  value_1 <- i * 2

  # value_2 indicates some calculation to process_list for each i
  value_2 <- i / 2

  output$matrix_addition <- output$matrix_addition + matrix(value_1, nrow = 2, ncol = 2)
  output$process_list <- append(output$process_list, value_2)
}

预期的output将如下所示:

$matrix_addition
     [,1] [,2]
[1,]  110  110
[2,]  110  110

$process_list
$process_list[[1]]
[1] 0.5

$process_list[[2]]
[1] 1

...

$process_list[[10]]
[1] 5

我尝试将foreach.combine = "+"用于矩阵加法部分,但是当涉及到多个输出时, mapply似乎无法与"+"结合使用。 我通过使用.combine = "cbind", .multicombine=TRUE联机找到了两个对两个输出具有相同操作的代码。 当涉及到两个输出的不同操作时,有什么方法可做?

谢谢您的帮助!

编辑:

我的仅矩阵加法的foreach代码是

library(foreach)
library(doParallel)

cl <- makeCluster(2)
registerDoParallel(cl)

output <- foreach(i = 1:10, .combine = "+") %dopar% {
  value_1 <- i * 2
  matrix <- matrix(value_1, nrow = 2, ncol = 2)
}

stopCluster(cl)

我对这两个输出的第一次尝试是

output <- foreach(i = 1:10) %dopar% {
  if(exists("temp") == FALSE) {
    output <- list(matrix_addition = matrix(0, nrow = 2, ncol = 2), process_list = list())
  }

  value_1 <- i * 2
  value_2 <- i / 2

  output$matrix_addition <- output$matrix_addition + matrix(value_1, nrow = 2, ncol = 2)
  output$process_list <- append(output$process_list, value_2)
  output
}

似乎原始的for循环想法无法直接在foreach使用。

接下来,我在网上找到了这些代码,看起来像:

comb <- function(...) {
  mapply("cbind", ..., SIMPLIFY=FALSE)
}

output <- foreach(i = 1:10, .combine="comb", .multicombine = TRUE) %dopar% {
  value_1 <- i * 2
  value_2 <- i / 2

  matrix_addition_part  <- matrix(value_1, nrow = 2, ncol = 2)
  process_list_part     <- value_2
  list(matrix_addition_part, process_list_part)
}

comb <- function(x, ...) {
  lapply(seq_along(x),
         function(i){c(x[[i]], lapply(list(...), function(y) y[[i]]))})
}

output <- foreach(i=1:10, .combine="comb", .multicombine=TRUE, .init=list(list(), list())) %dopar% {
  value_1 <- i * 2
  value_2 <- i / 2

  list(matrix(value_1, nrow = 2, ncol = 2), value_2)
}

这两个是相似的,这里的想法是将所有矩阵保存在矩阵加法部分中,并且在foreach之后,可以将矩阵相加。 但是对我来说,问题是我的代码中的每个矩阵太大,这需要巨大的存储空间,因此我无法保存所有矩阵。 我想我需要将矩阵加法部分中的"cbind"替换为"+"类的东西,但是在mapplymapply

我的猜测是,我需要使函数comp既包含"+"又包含"append" ,但仍然无法通过applyapply适当的解决方案。

只要弄清楚怎么做:

library(foreach)
library(doParallel)
cl <- makeCluster(2)
registerDoParallel(cl)

comb <- function(List1, List2) {
  output_a <- apply(abind(List1[[1]], List2[[1]], along = 3), 1:2, sum)
  output_b <- c(List1[[2]], List2[[2]])
  return(list(matrix_addition = output_a, process_list = output_b))
}

output <- foreach(i = 1:10, .combine = "comb", .init=list(matrix(0, 2, 2), list())) %dopar% {
  value_1 <- i * 2
  value_2 <- i / 2

  list(matrix_addition = matrix(value_1, nrow = 2, ncol = 2), process_list = value_2)
}

stopCluster(cl)

在这里,通过自定义.combine函数comb ,分离矩阵加法部分和处理列表部分,并将它们合并为一个列表。 同样, comp函数的第一个输入(此处为List1 )将是.init或先前的循环迭代(i-1)结果,第二个输入(此处为List2 )将为当前循环迭代(i)结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM