foreach与迭代器的非并行变换

foreach与迭代器的非并行变换,r,foreach,parallel-processing,iteration,R,Foreach,Parallel Processing,Iteration,我需要使用两个大小相同的迭代变量(例如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的对角线,而不是整个矩阵 另外,

我需要使用两个大小相同的迭代变量(例如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的对角线,而不是整个矩阵


另外,我试图用进行循环,但计算时间太长,无法使代码保持最佳状态。

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

M要嵌套
foreach
循环,请使用嵌套运算符“%:%”:

但这些解决方案只具有学术意义。为了简单和快速,我怀疑到目前为止,
tcrossprod
是最好的解决方案:

Z <- tcrossprod(M)

Z您有哪种数据结构?阅读以下关于处理表的内容:
vignette(“嵌套”)
help?它使用
%:%
运算符处理嵌套的
foreach
循环。非常感谢,计算时间缩短了50倍!最后一个问题-如何填充示例中resmat的上部三角形,使其与下部三角形对称?@Seva请参阅我的编辑。虽然如果矩阵很大,最好使用稀疏矩阵,因为这是冗余信息。顺便说一句,如果你省略了
names(res)+1,那么有时候想到显而易见的解决方案是多么的困难,这真是令人惊讶。但是,
combn
解决方案可以用于其他功能。@Roland同意。看过你的例子后,我会记住
combn
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,])
       }
Z <- tcrossprod(M)