[英]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"
替换为"+"
类的东西,但是在mapply
中mapply
。
我的猜测是,我需要使函数comp
既包含"+"
又包含"append"
,但仍然无法通过apply
来apply
适当的解决方案。
只要弄清楚怎么做:
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.