我最近发现了 TMB 的神奇之处,并且正在开发一个包,最好在其中包含 TMB c++ 模板,以用于计算成本相当高的模型。
我假设有可能:
但我在 TMB 文档中找不到与此相关的任何明确指南。到目前为止,我的替代方案是编写在第一次调用使用未编译类的函数时编译 TMB 代码的函数……但我感觉有更好的方法可以做到这一点。
有没有人成功地将 TMB 函数包含在另一个包中,并且可以为我指出相关文档或示例的方向?
经过更多搜索,我终于在这个帖子中找到了答案。我想我错过了它,因为它详细说明的解决方案已移至名为development的 wiki 页面,其中内容专门针对希望为 TMB 的开发做出贡献的用户,而我只想分发包含 TMB 的代码。
总而言之,该线程建议我采用这样的一些更改(myPkg应该是您的包的名称):
.cpp模板放入mypkg/src. 当您构建包时,R 将自动编译它。将这些行添加到您的描述文件中,以便 R 拥有编译模型模板所需的所有工具。
Depends: TMB, RcppEigen
LinkingTo: TMB, RcppEigen
Run Code Online (Sandbox Code Playgroud)
现在我们需要将 TMB 模板添加到命名空间文件中。我们可以通过 roxygen 制作一个虚拟文件,如下所示轻松完成此操作:
#' Roxygen commands
#'
#' @useDynLib myPkg
#'
dummy <- function(){
return(NULL)
}
Run Code Online (Sandbox Code Playgroud)
虚拟函数只是将标签放在@useDynLib myPkg我的源代码中的某个地方的借口,这样我就不会弄乱它。该标签将用...填充您的命名空间useDynLib(myPkg),据我了解,这会在为您加载包时加载共享库。
最后,调用时MakeADFun,设置DLL="myPkg"。通过此设置,您可以将单个TMB 模型编译到您的包中。这是因为您文件夹中编译的内容./src/将根据您的包名称自动重命名,因此您无法创建唯一命名的模型。
经过更多搜索(与上面引用的相同线程)...我意识到官方 wiki 中描述的解决方案(以及上面详细介绍的)仅与分发单个 dll(即单个 TMB 模型)相关。
如果您想在一个包中分发多个 TMB 模型,则必须使用您自己的 makefile。我在我的博客中给出了更详细的描述,因此我将仅简要描述此处的步骤,了解它们与我之前描述的步骤有何不同。
您必须定义自己的Makefile(或Makefile.win针对 Windows 用户)并将其放入您的src/目录中。这是一个对我有用的例子:
all: template1.so template2.so
# Comment here preserves the prior tab
template1.so: template1.cpp
Rscript --vanilla -e "TMB::compile('template1.cpp','-O0 -g')"
template2.so: template2.cpp
Rscript --vanilla -e "TMB::compile('template2.cpp','-O0 -g')"
clean:
rm -rf *o
Run Code Online (Sandbox Code Playgroud)
对于 Windows,将so、 替换为dll,并使用相关编译器标志(用于调试)。?TMB::compile有关调试编译器标志的信息,请参阅参考资料。
这与上面略有不同:
#' Roxygen commands
#'
#' This is a dummy function who's purpose is to hold the useDynLib roxygen tag.
#' This tag will populate the namespace with compiled c++ functions upon package install.
#'
#' @useDynLib template1
#' @useDynLib template2
#'
dummy <- function(){
return(NULL)
}
Run Code Online (Sandbox Code Playgroud)
最后,上述更改将编译多个唯一命名的 TMB 模板并将它们加载到命名空间中。要在包中调用这些模型,下面是一个示例:
obj <- MakeADFun(data = data,
parameters = params,
DLL="template1",
inner.control = list(maxit = 10000),
silent=F)
Run Code Online (Sandbox Code Playgroud)
当我尝试在 Windows 机器上编译此文件时,我遇到了问题...结果证明与未正确清理 src 文件夹有关,并且我将旧的 linux 编译文件卡在了那里。如果您遇到编译问题,值得手动清除src/目录中以前版本中的残留文件...或者也许有人可以提供一些关于编写更好的 make 文件的好建议!
| 归档时间: |
|
| 查看次数: |
1378 次 |
| 最近记录: |