如何将正常循环转换为带有 foreach 包的并行循环?
我尝试从 vrtest 包
转换此代码CvMexpb <- matrix(0,nrow=B,ncol=2)
for(k in 1:B)
{
eb <- e * Mammen2(n)
eb <- eb - mean(eb)
tem <- 0
for( j in 1:(n-1) )
{
aux2 <- 1/((j*pi)*(j*pi))
aux2 <- aux2/(n-j+1)
tem <- tem+aux2* t(eb[(1+j):n]) %*% weiexp[1:(n-j),1:(n-j)] %*% eb[(1+j):n]
}
CvMexpb[k,] <- cbind(tem/v > CvMexp,tem/v)
}
pboot <- mean(CvMexpb[,1])
Critboot <- quantile(CvMexpb[,2],c(0.9,0.95,0.99))
return(pboot)
到
CvMexpb <- foreach(k = 1:B, .combine='cbind') %:%
{
eb <- e * Mammen2(n)
eb <- eb - mean(eb)
tem <- 0
foreach(j = 1:(n-1), .combine='c') %dopar%
{
aux2 <- 1/((j*pi)*(j*pi))
aux2 <- aux2/(n-j+1)
tem <- tem+aux2* t(eb[(1+j):n]) %*% weiexp[1:(n-j),1:(n-j)] %*% eb[(1+j):n]
}
CvMexpb[k,] <- cbind(tem/v > CvMexp,tem/v)
}
pboot <- mean(CvMexpb[,1])
Critboot <- quantile(CvMexpb[,2],c(0.9,0.95,0.99))
return(pboot)
但返回错误
foreach中的错误(k = 1:B,.combine =“cbind”)%:%{: “%:%”被传递为非法的右操作数
原始完整代码是
compweexp <-
function(inf)
{
n <- length(inf)
weiexp <- matrix(1,nrow=n,ncol=n)
for(i in 1:n)
{
for(j in (i+1):n)
{
if(j > n) break
aux1 <- (inf[i]-inf[j]) %*% t(inf[i]-inf[j])
weiexp[i,j] <- exp(-0.5*aux1)
weiexp[j,i] <- weiexp[i,j]
}
}
return(weiexp)
}
Mammen <-
function(n)
{
p <- (sqrt(5)+1)/(2*sqrt(5))
zmat <- rep(1,n)*(-(sqrt(5)-1)/2);
u <- runif(n,0,1)
zmat[u > p] <- (sqrt(5)+1)/2
return(zmat)
}
Gen.Spec <-
function(y,B=300)
{
set.seed(12345)
n<- length(y)
e <- y - mean(y)
v <- var(e)
y1 <- y[1:(n-1)]
weiexp <- compweexp(y1)
CvMexp <- 0
for(j in 1:(n-1)) {
aux2 <- 1/((j*pi)^2)
aux2 <- aux2/(n-j+1)
CvMexp <- CvMexp+ aux2* t(e[(1+j):n]) %*% weiexp[1:(n-j),1:(n-j)] %*% e[(1+j):n]
}
CvMexp <- CvMexp/v
CvMexpb <- matrix(0,nrow=B,ncol=2)
for(k in 1:B)
{
eb <- e * Mammen(n)
eb <- eb - mean(eb)
tem <- 0
for( j in 1:(n-1) ){
aux2 <- 1/((j*pi)^2)
aux2 <- aux2/(n-j+1)
tem <- tem+aux2* t(eb[(1+j):n]) %*% weiexp[1:(n-j),1:(n-j)] %*% eb[(1+j):n]
}
CvMexpb[k,] <- cbind(tem/v > CvMexp,tem/v)
}
pboot <- mean(CvMexpb[,1])
Critboot <- quantile(CvMexpb[,2],c(0.9,0.95,0.99))
return(pboot)
}
答案 0 :(得分:0)
您收到错误消息,因为'%:%'运算符的右参数必须是另一个foreach表达式。没有标准方法来包含内部foreach循环的初始化代码。 doMPI包确实提供了这样的机制。
但另一个问题是你的内部for循环不能以这种方式并行化,因为你是从循环的前一次迭代中计算的值设置“tem”变量。您只需使用foreach作为外循环就可以解决这两个问题:
CvMexpb <- foreach(k=1:B, .combine='rbind', .export='Mammen2') %dopar% {
eb <- e * Mammen2(n)
eb <- eb - mean(eb)
tem <- 0
for( j in 1:(n-1) )
{
aux2 <- 1/((j*pi)*(j*pi))
aux2 <- aux2/(n-j+1)
tem <- tem+aux2* t(eb[(1+j):n]) %*% weiexp[1:(n-j),1:(n-j)] %*% eb[(1+j):n]
}
cbind(tem/v > CvMexp,tem/v)
}
这将导致计算时间更长的任务减少,这可能是也可能不是好事。