有一种方法来做并行在这个R代码?



我正在尝试学习r中的并行性。我写了一个代码,其中我有一个50*50的矩阵,从值1到250000。对于矩阵中的每一个元素,我都在寻找它的邻居值最小的元素。邻居也可以在对角线上。然后我把元素本身替换成最小的邻居。在我的计算机上运行这段代码所需的时间大约是4.5秒。如果可能的话,谁能帮我把for循环平行?下面是代码片段

start_time <- Sys.time()

myMatrix <- matrix(1:250000, nrow=500) # a 500 * 500 matrix from 1 to 250000

indexBound <- function(row,col) { # this function is to check if the indexes are out of bound
if(row<0 || col <0 || row > 500 || col >500){
return (FALSE)
}
else{
return (TRUE)
}
}

for(row in 1:nrow(myMatrix)){

for(col in 1:ncol(myMatrix)){
li <- list()
if(indexBound(row-1,col-1)){
li <- c(li,myMatrix[row-1,col-1])

}
if(indexBound(row-1,col)){
li <- c(li,myMatrix[row-1,col])

}
if(indexBound(row-1,col+1)){
li <- c(li,myMatrix[row-1,col+1])

}
if(indexBound(row,col-1)){
li <- c(li,myMatrix[row,col-1])
}
if(indexBound(row-1,col+1)){
li <- c(li,myMatrix[row,col+1])

}
if(indexBound(row+1,col-1)){
li <- c(li,myMatrix[row+1,col-1])

}
if(indexBound(row+1,col)){
li <- c(li,myMatrix[row+1,col])

}
if(indexBound(row+1,col+1)){
li <- c(li, myMatrix[row+1,col+1])

}
min = Reduce(min,li) #find the lowest value from the list
myMatrix[row,col] = min
}
}
end_time <- Sys.time()
end_time - start_time

感谢您的回复。

您的脚本将产生一个所有元素都等于2的矩阵。如果这不是目的,您应该创建myMatrix的副本,以便在构建li时使用(在if语句中)。

我意识到这可能是一个探索并行化的人为例子,但使用R通常最好首先关注向量化。当向量化时,此操作可能足够快,而并行化实际上可能由于开销而变慢。例如,以下是使用填充矩阵的矢量化解决方案(这不会给出所有2,并且它仍然不包括min计算中的当前单元格):

library(matrixStats)
system.time({
idxShift <- expand.grid(rep(list(-1:1), 2))[-5,] # don't include the current cell (0, 0)
myMatrix <- matrix(nrow = 502, ncol = 502)
myMatrix[2:501, 2:501] <- matrix(1:250000, nrow = 500)
myMatrix <- matrix(rowMins(mapply(function(i,j) c(myMatrix[2:501 + i, 2:501 + j]), idxShift$Var1, idxShift$Var2), na.rm = TRUE), nrow = 500)
})
user  system elapsed 
0.03    0.00    0.03 

将其与使用future.apply的相同矢量化代码的并行版本进行比较:

library(future.apply)
plan(multisession)
system.time({
idxShift <- expand.grid(rep(list(-1:1), 2))[-5,]
myMatrix <- matrix(nrow = 502, ncol = 502)
myMatrix[2:501, 2:501] <- matrix(1:250000, nrow = 500)
myMatrix <- matrix(rowMins(future_mapply(function(i,j) c(myMatrix[2:501 + i, 2:501 + j]), idxShift$Var1, idxShift$Var2), na.rm = TRUE), nrow = 500)
})
future:::ClusterRegistry("stop")
user  system elapsed 
0.10    0.05    2.11 

如果我没有搞砸什么,并行解决方案会更慢,这甚至不包括plan(multisession)在计时。

最新更新