Code Monkey home page Code Monkey logo

r2sundials's Introduction

Introduction

Package r2sundials is an RcppArmadillo wrapper for a well known and wide spread library SUNDIALS/CVODES from LLNL written in C. It provides an access from R to some basic features of cvodes module from this library which include:

  • solving real valued, user defined ODE via user provided functions calculating ODE’s right hand side (rhs);
  • calculating first order forward sensitivities to parameters on which ODE solution depends ;
  • setting key parameters for ODE solving method like explicit or implicit time scheme, minimal or maximal steps, error order etc.

Note that user has to install SUNDIALS/CVODES by his own means (cf. Install section)

Why another ODE solver for R?

The question is legitimate as there is already very furnished package deSolve. It was also published Rsundials package but it is archived now since 2017-03-26. There is a fresh wrapper to the same library sundialr. You can find even more packages dedicated to ODE solving in this task view. So why a new wrapper? Let see what are the novelties brought by r2sundials compared to most close alternatives: deSolve and sundialr.

deSolve

Compared to deSolve, r2sundials provides possibilities:

  • to do forward sensitivity calculations for all or selected parameters;
  • to write users callback functions (rhs, Jacobian, …) in RcppArmadillo where calculated values are stored “in-place” thus avoiding frequent memory reallocation;
  • to pass a parameter of any R type (vector, list, environment, …) directly to Rcpp functions ;
  • to use rmumps package for solving underlying sparse linear systems;
  • to have much more flexible root finding and handling based on user callback functions.
  • to get statistics on ODE method used (call number for rhs routines, number of Jacobian calculations and so on).

sundialr

Compared to sundialr, r2sundials provides:

  • more complete access to fine tuning of cvodes methods;
  • more complete parameter infrastructure. In r2sundials, parameters passed to callback functions can be of any R type (vector, list, environment, …), not only numeric vector as in sundialr;
  • sensitivity calculations possibly done with the help of user provided functions (and not only with internal sundials procedure);
  • sensitivity calculations can be done on a selection of parameters, not necessarily on the totality of parameters.
  • Jacobian (dense or sparse) calculated with possibly user provided functions;
  • sparse system solving is made with rmumps package;
  • root finding and handling;
  • some statistics of ODE methods (call number for rhs routines, number of Jacobian calculations and so on).
  • (as of time of this writing, 2019-11-25) more thorough memory management which ensures that sundials’ allocated memory is freed in due way, no matter what C++ exception and in what moment could happen. This avoids potential memory leaking problem in case of frequent package use during the same session.

Install

The package can be installed as any other CRAN or github package:

install.packages("r2sundials")

or

devtools::install_github("sgsokol/r2sundials")

Version note

r2sundials was developed and tested with CVODES version 5.0.0 released in October 2019. It can happen that r2sundials works with other versions of CVODES but it was not tested. The versioning scheme of r2sundials is based on the version of CVODES used during developments extended with one number proper to r2sundials. For example, r2sundials can have a version 5.0.0-2.

Example

Let solve a very simple ODE (y'(t)=-ν(y(t)-a)), with (ν=2), (a=1) and (y(0)=0) on a time interval ([0, 3]). This equation describes an exponential transition between two states 0 and (a) with a rate (ν).

With rhs written in R, we can do:

library(r2sundials)
## Loading required package: rmumps

## 
## Attaching package: 'r2sundials'

## The following object is masked from 'package:rmumps':
## 
##     get_cnst
ti=seq(0, 3, length.out=101) # set time grid
p=c(nu=2, a=1) # set parameter vector
y0=0 # set initial condition
frhs=function(t, y, p, psens) -p["nu"]*(y-p["a"]) # set rhs functions
res=r2sundials::r2cvodes(y0, ti, frhs, param=p) # solve ODE
# compare with analytical solution
stopifnot(diff(range(p["a"]-exp(-p["nu"]*ti) - res)) < 1.e-6)
# see stats
print(attr(res, "stats"))
##                   NumSteps                NumRhsEvals 
##                        112                        136 
##           NumLinSolvSetups            NumErrTestFails 
##                         23                          3 
##         NumNonlinSolvIters     NumNonlinSolvConvFails 
##                        133                          0 
##                NumJacEvals             NumLinRhsEvals 
##                          2                          2 
##                  NumGEvals            SensNumRhsEvals 
##                          0                          0 
##            NumRhsEvalsSens       SensNumLinSolvSetups 
##                          0                          0 
##        SensNumErrTestFails     SensNumNonlinSolvIters 
##                          0                          0 
## SensNumNonlinSolvConvFails 
##                          0

The same problem solved with RcppArmadillo rhs can look like:

library(RcppXPtrUtils)
Sys.setenv(PKG_CXXFLAGS=paste0("-I ", gsub("\\", "/", readLines(system.file("cvodes.txt", package="r2sundials"))[1L], fixed=TRUE)))
ti=seq(0, 3, length.out=101)
p=c(nu=2, a=1)
y0=0
# next step can take few seconds at the first execution as it will compile C++ code.
ptr_exp=cppXPtr(code='
int rhs_exp(double t, const vec &y, vec &ydot, RObject &param, NumericVector &psens) {
  NumericVector p(param);
  ydot[0] = -p["nu"]*(y[0]-p["a"]);
  return(CV_SUCCESS);
}
', depends=c("RcppArmadillo","r2sundials","rmumps"),
 includes="using namespace arma;\n#include <r2sundials.h>", cacheDir="lib", verbose=FALSE)

res2=r2sundials::r2cvodes(y0, ti, ptr_exp, param=p)
stopifnot(diff(range(res2 - res)) < 1.e-14)

For more examples, see ?r2sundials::r2cvodes.

r2sundials's People

Contributors

eddelbuettel avatar sgsokol avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.