我一直在MCMC算法中使用deSolve包来估计ODE中的参数,并在C中编写求解器中使用的函数来加速算法。有时,但并非总是在运行Error in .C("unlock solver")
函数时出现错误ode
。我能够使用命令
system("R CMD SHLIB [insert-file-path]")
dyn.load("[dll-file-path]")
但是当我尝试使用dll文件解决ODE时,会抛出错误。然后,即使运行如下所示的简单脚本,我也会得到同样的错误。我认为这个问题与使用已编译的代码有关,但我不知道如何找不到任何关于此错误的引用。
> require(deSolve)
> initVal <- c(y=1)
> times <- seq(0, 1, 0.001)
> parms <- c(k=1)
> model1 <- function(t, y, parms){
+ with(as.list(c(y, parms)),{
+ dy <- -k*y;
+ list(c(dy))
+ })
+ }
> out <- ode(y=initVal, times=times, parms=parms, func=model1)
Error in .C("unlock_solver") :
"unlock_solver" not resolved from current namespace (deSolve)
部分解决方案
如果我重新启动R并仅使用dyn.load
函数加载DLL,但不编译代码,ode
函数运行时没有错误。这解决了我的问题,但我仍然不知道为什么。
答案 0 :(得分:5)
编辑: Thomas Petzoldt在R帮助列表中的真正解决方案:
“[错误]发生,如果在编译模型之后加载了包deSolve ...解决方案是在加载DLL之前加载deSolve,理想情况是在脚本的最开始,至少在加载之前加载/卸载DLL / .so“
如果这不起作用,下面也可以(旧回答):
我找到了一个不太优雅的解决方案。
问题似乎是deSolve中的“unlock_solver”函数以某种方式无法正确访问。您可以卸载并重新加载整个deSolve.so文件,而不是重新启动R。
为此,您可以使用以下内容:
require(deSolve)
# encounter error
library.dynam.unload("deSolve", libpath=paste(.libPaths()[1], "//deSolve", sep=""))
library.dynam("deSolve", package="deSolve", lib.loc=.libPaths()[1])
如果它位于.libPaths变量的第一个元素中,则需要将“.libPaths()[1]”替换为已安装deSolve的位置。
但是,这是一把大锤。我已经向r-help列表发出了一个请求,询问是否有某种方法可以更改R查找“unlock_solver”的位置,或者只是卸载/重新加载deSolve的一部分。答案 1 :(得分:1)
确保(在脚本的开头)安装了以下软件包来编译.dll文件。
packages <- c("deSolve","coda", "adaptMCMC")
if(require(packages)){
install.packages(packages,dependencies = T)
}
ppp <- lapply(packages,require,character.only=T)
首先在您的wdir中删除当前的.dll文件
c_compile <- "your_c_file"
dyn.unload(paste0(c_compile,".dll")) # unload dll (Windows only)
然后编译C文件和.dll
system(paste0("R CMD SHLIB ",c_compile,".c"))
dyn.load(paste0(c_compile,".dll"))# Load dll (Windows only)