的foreach和迭代器的非平行变化(foreach and non-parallel change

2019-10-29 04:24发布

我需要用相同的尺寸(例如1:N)两种迭代变量来执行的foreach,但编写的功能改变它们并联这里 :

我们称之为a和b的迭代变量,因为那些是被在多个执行改变的变量。 请注意,我们遍历它们并行,也就是说,它们都在同一时间发生变化。

我需要的是做的foreach独立地改变他们,所以我将不得不长度为n ^ 2,不是n的列表。

例:

X = foreach(i=1:n, j=1:n) %do% (sum(M[i,]*M[j,]))

在最后,我得到长度为n的矢量,其仅仅是一个对角矩阵X,不完整的基质。

PS我试图循环,使这个,但计算时间太伟大了,留下的代码未优化。

Answer 1:

嵌套foreach循环中,使用嵌套操作者,“%:%”:

library(foreach)
n <- 4
M <- matrix(rnorm(n*n), n)
X <- foreach(i=1:n, .combine='cbind') %:%
       foreach(j=1:n, .combine='c') %do% {
         sum(M[i,]*M[j,])
       }

为了避免重复计算,可以有j迭代从in ,并使用.final函数来垫用所得载体NA

pad <- function(x) c(rep(NA, n - length(x)), x)
Y <- foreach(i=1:n, .combine='cbind') %:%
       foreach(j=i:n, .combine='c', .final=pad) %do% {
         sum(M[i,]*M[j,])
       }

但是,这些解决方案是唯一的学术兴趣。 为了简化和速度,我怀疑tcrossprod是迄今为止最好的解决办法:

Z <- tcrossprod(M)

对于4000 X 4000矩阵,这在执行下8秒我的Linux机器上。



Answer 2:

foreach不大于有效for 。 认准%:%由@BenBarnes作为评价运营商使用它。 并行可能有点帮助,但数量不多。

尝试,而不是下面的一个明确的循环:

M <- matrix(1:8,4)

prodsums <- combn(seq_len(nrow(M)), 2, FUN=function(ind) {
  res <- sum(M[ind[1],]*M[ind[2],])
  names(res) <- paste(ind, collapse="*")
  res
}, simplify=F)

unlist(prodsums)
#1*2 1*3 1*4 2*3 2*4 3*4 
# 32  38  44  48  56  68 

resmat <- matrix(ncol=nrow(M),nrow=nrow(M))
resmat[lower.tri(resmat)] <- unlist(prodsums)
#       [,1] [,2] [,3] [,4]
# [1,]   NA   NA   NA   NA
# [2,]   32   NA   NA   NA
# [3,]   38   48   NA   NA
# [4,]   44   56   68   NA

resmat[upper.tri(resmat)] <- t(resmat)[upper.tri(resmat)]

diag(resmat) <- rowSums(M^2)
#     [,1] [,2] [,3] [,4]
#[1,]   26   32   38   44
#[2,]   32   40   48   56
#[3,]   38   48   58   68
#[4,]   44   56   68   80


文章来源: foreach and non-parallel change of iterators