我正在开发一个需要大量矩阵的大型矩阵的项目。不幸的是,由于这些矩阵中的一些可能具有超过1e10个元素,因此使用"标准"由于RAM限制,R矩阵不是一种选择。此外,我需要处理多个核心,因为计算可能需要很长时间,而且真的不应该。
到目前为止,我一直在使用foreach
包,然后将结果(标准矩阵中的结果)转换为稀疏矩阵。我不能帮助,但认为必须有一个更聪明的方法。
以下是我迄今为止所做的最简单的例子:
cl <- makeSOCKcluster(8)
registerDoSNOW(cl)
Mat <- foreach(j=1:length(lambda), .combine='cbind') %dopar% {
replicate(iter, rpois(n=1, lambda[j]))
}
Mat <- Matrix(Mat, sparse=TRUE)
stopCluster(cl)
lambda都非常小,因此只有每5个元素左右不同,因此将结果存储在稀疏矩阵中是明智的。
不幸的是,现在有必要将迭代次数从1e6增加到至少1e7,这样foreach
循环产生的矩阵太大而无法存储在8GB的RAM上。我现在想要做的是将任务分成每个都有1e6次迭代的步骤,并将它们组合成一个稀疏的矩阵。
我现在有以下想法:
library(Matrix)
library(snow)
cl <- makeSOCKcluster(8)
iter <- 1e6
steps <- 1e5
numsteps <- iter / steps
draws <- function(x, lambda, steps){
replicate(n=steps, rpois(n=1, lambda=lambda))
}
for(i in 1:numsteps){
Mat <- Matrix(0, nrow=steps, ncol=96, sparse=TRUE)
Mat <- Matrix(
parApply(cl=cl, X=Mat, MARGIN=2, FUN=draws, lambda=0.2, steps=steps)
, sparse = TRUE)
if(!exists("fullmat")) fullmat <- Mat else fullmat <- rBind(fullmat, Mat)
rm(Mat)
}
stopCluster(cl)
它运行正常,但我必须将lambda修复为某个值。对于我的应用程序,我需要第i行中的值来自泊松分布,其均值等于lambda向量的第i个元素。这在foreach
循环中显然工作正常。但是我还没有找到一种方法使它在apply循环中工作。
我的问题是:
答案 0 :(得分:1)
我能够找到解决问题的方法。
就我而言,我能够为每个列定义一个唯一的ID,并可以通过它来寻址参数。以下代码应说明我的意思:
library(snow)
library(Matrix)
iter <- 1e6
steps <- 1e5
# define a unique id
SZid <- seq(from=1, to=10, by=1)
# in order to have reproducible code, generate random parameters
SZlambda <- replicate(runif(n=1, min=0, max=.5))
SZmu <- replicate(runif(n=1, min=10, max=15))
SZsigma <- replicate(runif(n=1, min=1, max=3))
cl <- makeSOCKcluster(8)
clusterExport(cl, list=c("SZlambda", "SZmu", "SZsigma"))
numsteps <- iter / steps
MCSZ <- function(SZid, steps){ # Monte Carlo Simulation
lambda <- SZlambda[SZid]; mu <- SZmu[SZid]; sigma <- SZsigma[SZid];
replicate(steps, sum(rlnorm(meanlog=mu, sdlog=sigma,
n = rpois(n=1, lambda))
))
}
for (i in 1:numsteps){
Mat <- Matrix(
parSapply(cl, X=SZid, FUN=MCSZ, steps=steps), sparse=TRUE)
if(!exists("LossSZ")) LossSZ <- Mat else LossSZ <- rBind(LossSZ, Mat)
rm(Mat)
}
stopCluster(cl)
诀窍是将函数应用于矩阵之上,而不是应用于与参数索引对齐的唯一ID的向量。