我试图找到参数为 (theta_1,...,theta_n) 的时间点 (t_1,...,t_n) 的常微分方程的数值解,其中 n 的数量级为数万。事实上,这可以看作是n个“独立”的ODE。然后,我需要重复这个M次,其中M的量级为数万。也就是说,每个时间点有一个不同参数的 ODE,并且只有前 n 个步骤是可并行的。
有没有有效的方法来做到这一点?我应该将其并行化为 t 和 theta 的函数吗?我目前正在使用 for 循环,但我感兴趣的方程比下面的示例稍微复杂一些,并且 n 约为数万。因此,我想有效地实现这个求解器。我还尝试了
foreach
的简单并行实现,但生成的代码甚至更慢。
下面是一个可重现的示例,对于 M = 1,使用逻辑常微分方程(我知道这个有一个解析解,只是试图呈现一个可重现的玩具示例)
library(deSolve)
# Logistic ODE
logisode <- function(t, y, par) {
# state variables
N <- y[1]
# parameters
lambda <- par[1]
kappa <- par[2]
# model equations
dN <- lambda*N*(1 - N/kappa)
# result
return( list(dN) )
}
lambdas = seq(0.1,1,by=0.1)
kappas = seq(0.1,1,by=0.1) + 1
ttimes <- seq(0.1, 25, length.out = 10)
out <- matrix(0, ncol = 2, nrow = length(lambdas))
for(i in 1:length(lambdas)){
params <- c(lambda = lambdas[i], kappa = kappas[i], h0 = 0.1)
init <- c(N = params[3])
times <- c(0,ttimes[i])
out[i,] <- ode(init, times, logisode, params, method = "lsode")[-1,]
}
plot(out, type = "l")
这里是带有
parApply
的 Windows 示例。 Windows 的困难在于,必须将完整的数据传递到每个核心。这就是为什么包和数据需要在runModel
内定义或加载。这对于 Linux 来说更容易,因为内核可以访问全局变量。mcapply
还有其他可能性,例如未来
套餐。