我需要用相同的尺寸(例如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我试图与循环,使这个,但计算时间太伟大了,留下的代码未优化。
嵌套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
迭代从i
到n
,并使用.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机器上。
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