繁体   English   中英

在R中的desolve包中解决已编译的ODE

[英]solving compiled ODE in desolve package in R

我正在使用deSolve包解决R中的ODE问题。 为了加快计算,我想使用编译代码,使用这里的说明

我将在下面展示一个ODE系统的例子 - 我正在使用下面的Rcpp编码。 ODE系统的细节取自示例MATLAB代码(可在此处找到)。 我想模拟一组非平凡的ODE,以便只看到R和编译代码的区别。 以下是我的驱动文件,我用两种不同的方式计算了质量平衡(只有R和编译的代码)

library(deSolve)
library(ggplot2)
library(microbenchmark)

source('parameters_gprotein.R')
p   <- parameters()

source('IC_gprotein.R')
IC  <- Initial_conditions()

TIME = seq(from = 0, to = 600)

source('odes_gprotein.R')
sim.data.df  <- as.data.frame(vode(IC,TIME,ODE_gprotein,p,
                                    mf = 22, rtol=1e-3,atol=1e-6,maxord = 5,
                                    verbose = F))

Rcpp::sourceCpp("odes_gprotein.cpp")
sim.data.df <- as.data.frame(vode(IC,TIME,odes_gprotein,p,
                                      mf = 22, rtol = 1e-3, atol = 1e-6, maxord = 5,
                                      verbose = F))

我的问题是因为vode调用是在R 这是否意味着如果在cpp中形成质量平衡并且实现速度增益,则在编译的代码中求解方程式,或者我是否还必须在cpp文件中进行vode调用。

当然, odes_gprotein.cpp结果表明使用odes_gprotein.cpp时速度odes_gprotein.cpp

Unit: milliseconds
                                                                                                                               expr
  sim.data.df1 <- as.data.frame(vode(IC, TIME, ODE_gprotein, p,      mf = 22, rtol = 0.001, atol = 1e-06, maxord = 5, verbose = F))
 sim.data.df2 <- as.data.frame(vode(IC, TIME, odes_gprotein, p,      mf = 22, rtol = 0.001, atol = 1e-06, maxord = 5, verbose = F))


       min        lq      mean    median        uq      max neval
 27.801954 29.543624 31.213758 30.565434 31.399140 86.28537   100
  8.188846  8.577824  9.177491  8.817025  9.437214 18.94304   100

谢谢

可重复的例子

将来,请链接到/提供问题所依据的所有书面代码。

比较

在编写R和Rcpp函数代码的比较时,您应该附加到c ++函数名_cpp以便清楚地调用不同的实现。 例如, ODE_gprotein()odes_gprotein()是C ++实现吗?

在基准测试的情况下,似乎odes_gprotein()cpp()调用,因为odes_gprotein()基准测试较低。 这意味着vode()函数通过Rcpp::sourceCpp调用引入命名空间的Rcpp包装器。

获得速度

如果可能,所有代码都应嵌入cpp以获得最大收益。 这意味着如果速度是一个重要因素(例如,处理非常大的数据或执行计算密集型模拟),您可能必须从头开始实施。 该建议是由于减少了R代码前端和C ++代码之间的中继。 本质上,当从R调用C ++代码时,有时必须将对象复制并重新格式化为幕后的不同对象,然后才能对其进行处理。 如果您使用默认Rcpp类型之外的对象(例如RcppArmadilloRcppGSL等),则情况尤其如此 ,因为副本必须从R的对象结构发生到导入结构。

Rcpp::sourceCpp发生了Rcpp::sourceCpp (幕后花絮)

让我们更深入地了解Rcpp::sourceCpp()背后的实际情况。 具体来说,当调用该方法时,提取不同的属性(例如// [[Rcpp::]]标签)并启用它们的选项。

最常见的标记是// [[Rcpp::export] ,它在C ++代码周围创建一个包装器或一个抽象层,以便它可以轻松地使用R对象。 此行为很重要有三个原因:1。您不必担心SEXP类型和内存保护,2。使用默认.Call("fname")自动创建R级函数,以及3.启用的代码缓存编译后的代码只能在更改时重新编译。

因此,当您调用odes_gprotein()时,实际上是在调用C ++函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM