简体   繁体   English

已编译 C ODE 使用 deSolve 为 R 提供不同的结果

[英]Compiled C ODE gives different results to R's using deSolve

I have an ODE which I would like to solve using compiled C code called from R's deSolve package. The ODE in question is I an exponential decay model (y'=-d* exp(g* time)*y): But running the compiled code from within R gives different results to R's native deSolve.我有一个 ODE,我想使用从 R 的 deSolve package 调用的已编译代码 C 来解决。有问题的 ODE 是指数衰减 model (y'=-d* exp(g* time)*y):但是运行R 中的编译代码给出了与 R 的原生 deSolve 不同的结果。 It's as is there they are flipped 180º.就好像它们被翻转了 180º。 What's going on?这是怎么回事?

C code implementation C代码实现

/* file testODE.c */
#include <R.h>
static double parms[4];
#define C parms[0] /* left here on purpose */
#define d parms[1]
#define g parms[2]

/* initializer  */
void initmod(void (* odeparms)(int *, double *))
{
  int N=3;
  odeparms(&N, parms);
}

/* Derivatives and 1 output variable */
void derivs (int *neq, double t, double *y, double *ydot,
             double *yout, int *ip)
{
  // if (ip[0] <1) error("nout should be at least 1");
  ydot[0] = -d*exp(-g*t)*y[0];
}
/* END file testODEod.c */

R implementation - Native deSolve R 实现 - Native deSolve

  testODE <- function(time_space, initial_contamination, parameters){
  with(
    as.list(c(initial_contamination, parameters)),{
      dContamination <- -d*exp(-g*time_space)*Contamination
      return(list(dContamination))
    }
  )
}

parameters <- c(C = -8/3, d = -10, g =  28)
Y=c(y=1200)
times <- seq(0, 6, by = 0.01)
initial_contamination=c(Contamination=1200) 
out <- ode(initial_contamination, times, testODE, parameters, method = "radau",atol = 1e-4, rtol = 1e-4)

plot(out)

R implementation - Run compiled code from deSolve R 实现 - 从 deSolve 运行编译代码

library(deSolve)
library(scatterplot3d)
dyn.load("Code/testODE.so")

Y <-c(y1=initial_contamination) ;
out <- ode(Y, times, func = "derivs", parms = parameters,
           dllname = "testODE", initfunc = "initmod")


plot(out)

Compiled code does not give different results to deSolve models implemented in R , except potential rounding errors within the limits of atol and rtol .编译代码不会给R中实现的deSolve模型带来不同的结果,除了atolrtol限制内的潜在舍入误差。

The reasons of the differences in the original post where two errors in the code.差异的原因在原帖中代码中有两处错误 One can correct it as follows:可以按如下方式更正它:

  1. Declare static double as parms[3]; static double声明为parms[3]; instead of parms[4]而不是parms[4]
  2. Time t in derivs is a pointer, ie *t derivs中的时间t是一个指针,即*t

so that the code reads as:这样代码就变成了:

/* file testODE.c */
#include <R.h>
#include <math.h>

static double parms[3];
#define C parms[0] /* left here on purpose */
#define d parms[1]
#define g parms[2]

/* initializer  */
void initmod(void (* odeparms)(int *, double *)) {
  int N=3;
  odeparms(&N, parms);
}

/* Derivatives and 1 output variable */
void derivs (int *neq, double *t, double *y, double *ydot,
             double *yout, int *ip) {
  ydot[0] = -d * exp(-g * *t) * y[0];
}

Here the comparison between the two simulations, somewhat adapted and generalized:这里是两个模拟之间的比较,经过一定程度的改编和概括:

library(deSolve)

testODE <- function(t, y, parameters){
  with(
    as.list(c(y, parameters)),{
      dContamination <- -d * exp(-g * t) * contamination
      return(list(dContamination))
    }
  )
}

system("R CMD SHLIB testODE.c")
dyn.load("testODE.dll")

parameters <- c(c = -8/3, d = -10, g =  28)
Y          <- c(contamination = 1200)
times      <- seq(0, 6, by = 0.01)

out1 <- ode(Y, times, testODE,
            parms = parameters, method = "radau", atol = 1e-4, rtol = 1e-4)
out2 <- ode(Y, times, func = "derivs", dllname = "testODE", initfunc = "initmod",
            parms = parameters, method = "radau", atol = 1e-4, rtol = 1e-4)

plot(out1, out2)          # no visible difference
summary(out1 - out2)      # differences should be (close to) zero

dyn.unload("testODE.dll") # always unload before editing .c file !!

R和C代码的比较

Note: set .dll or .so according to your OS, or detect it with .Platform$dynlib.ext .注意:根据您的操作系统设置.dll.so ,或者使用.Platform$dynlib.ext检测它。

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

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