簡體   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