简体   繁体   English

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

[英]solving compiled ODE in desolve package in R

I am solving ODE's in R using the deSolve package. 我正在使用deSolve包解决R中的ODE问题。 In order to speed up the calculations I want to use compiled code, using the instructions here 为了加快计算,我想使用编译代码,使用这里的说明

I am showing below an example of ODE system - which I am coding using Rcpp below. 我将在下面展示一个ODE系统的例子 - 我正在使用下面的Rcpp编码。 The details of the ODE system are taken from an example MATLAB code (can be found here ). ODE系统的细节取自示例MATLAB代码(可在此处找到)。 I wanted to simulate a non-trivial set of ODE in order to see a difference in only R and compile code. 我想模拟一组非平凡的ODE,以便只看到R和编译代码的区别。 The following is my drive file, where I calculated the mass-balances in two different ways (only R and compiled code) 以下是我的驱动文件,我用两种不同的方式计算了质量平衡(只有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))

My question is since vode call is made in R . 我的问题是因为vode调用是在R Does that mean the equations are solved in compiled code if the mass balances are formed in cpp and the speed gains are realized, or do I have to also make the vode call in cpp file. 这是否意味着如果在cpp中形成质量平衡并且实现速度增益,则在编译的代码中求解方程式,或者我是否还必须在cpp文件中进行vode调用。

Certainly, the microbenchmarking results show that there is a speed gain when using odes_gprotein.cpp 当然, 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

Thanks 谢谢

Reproducible example 可重复的例子

In the future, please link to / provide all written code that the question is based on. 将来,请链接到/提供问题所依据的所有书面代码。

Comparisons 比较

When writing a comparison of R and Rcpp function code you should append to the end of the c++ function name _cpp so that the call to different implementations is clear. 在编写R和Rcpp函数代码的比较时,您应该附加到c ++函数名_cpp以便清楚地调用不同的实现。 eg is ODE_gprotein() or odes_gprotein() the C++ implementation? 例如, ODE_gprotein()odes_gprotein()是C ++实现吗?

In the case of the benchmark, it appears as if odes_gprotein() is the cpp() call since the microbenchmark is lower. 在基准测试的情况下,似乎odes_gprotein()cpp()调用,因为odes_gprotein()基准测试较低。 This means that the vode() function is calling the Rcpp wrapper introduced into the namespace via the Rcpp::sourceCpp . 这意味着vode()函数通过Rcpp::sourceCpp调用引入命名空间的Rcpp包装器。

Gaining Speed 获得速度

If it is possible, all code should be embedded within cpp for the greatest gain. 如果可能,所有代码都应嵌入cpp以获得最大收益。 This means you may have to do an implementation from scratch if speed is a huge factor (eg working with very large data or performing computationally intensive simulations). 这意味着如果速度是一个重要因素(例如,处理非常大的数据或执行计算密集型模拟),您可能必须从头开始实施。 The recommendation comes as a result of decreasing the relay between the R code front and the C++ code. 该建议是由于减少了R代码前端和C ++代码之间的中继。 In essence, when the C++ code is called from R the objects must sometimes be copied and reformatted into different objects behind the scenes before they can be worked upon. 本质上,当从R调用C ++代码时,有时必须将对象复制并重新格式化为幕后的不同对象,然后才能对其进行处理。 This is particularly the case if you are using objects outside of the default Rcpp types (eg RcppArmadillo , RcppGSL , et cetera) as a copy must happen from R's object structure to the importing structure. 如果您使用默认Rcpp类型之外的对象(例如RcppArmadilloRcppGSL等),则情况尤其如此 ,因为副本必须从R的对象结构发生到导入结构。

What's Happening in Rcpp::sourceCpp (Behind the Scenes) Rcpp::sourceCpp发生了Rcpp::sourceCpp (幕后花絮)

Let's dive a little bit deeper into what is actually happening behind Rcpp::sourceCpp() . 让我们更深入地了解Rcpp::sourceCpp()背后的实际情况。 Specifically, when the method is called the different attributes are extracted (eg the // [[Rcpp::]] tags) and their options are enabled. 具体来说,当调用该方法时,提取不同的属性(例如// [[Rcpp::]]标签)并启用它们的选项。

The most common tag is // [[Rcpp::export] which creates a wrapper or an abstraction layer around the C++ code so that it can easily work with R objects. 最常见的标记是// [[Rcpp::export] ,它在C ++代码周围创建一个包装器或一个抽象层,以便它可以轻松地使用R对象。 This behavior is important for three reasons: 1. You do not need to worry about SEXP types and memory protection, 2. Automatic creation of an R level function with a default .Call("fname") , and 3. code caches that enable compiled code to only be recompiled on change. 此行为很重要有三个原因:1。您不必担心SEXP类型和内存保护,2。使用默认.Call("fname")自动创建R级函数,以及3.启用的代码缓存编译后的代码只能在更改时重新编译。

Thus, when you call odes_gprotein() you are actually calling a C++ function. 因此,当您调用odes_gprotein()时,实际上是在调用C ++函数。

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

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