Skip to content

Latest commit

 

History

History
139 lines (109 loc) · 5.7 KB

File metadata and controls

139 lines (109 loc) · 5.7 KB

cppDE

R-CMD-check

C++ code generation for ODEs with sensitivity propagation.

cppDE writes, compiles and runs a C++ solver for a system of ordinary differential equations, or C++ code for algebraic functions, given as equations in R. Derivatives with respect to the parameters are propagated forward on dual numbers or backward by a discrete adjoint, to first and second order.

Features

  • Solvers: variable-order BDF/NDF and Adams multistep in Nordsieck form, adapted from SUNDIALS/CVODE; Rosenbrock4 extended from Boost.Odeint; the Tsitouras 5(4) pair, an explicit Runge-Kutta method with dense output
  • Sensitivities in both directions: forward mode carries one tangent per parameter through the solve; reverse mode returns the gradient of a functional in one backward sweep, at a cost independent of the parameter count
  • Second order: exact Hessians, forward over forward or forward over reverse
  • Events: time-based and root-triggered, with the saltation correction of first- and second-order sensitivities across a jump
  • Code generation on an expression graph: Jacobians and derivative contractions by automatic differentiation, emitted as straight-line C++, with automatic sparsity detection and KLU factorisation for large systems
  • cvode(): the same models on SUNDIALS CVODES, with its forward sensitivities and adjoint
  • cppFUN(): the same code generation for algebraic functions, with Jacobian, Hessian and vector-Jacobian products
  • Batched solving: solveODEBatch() integrates many conditions in one .Call over OpenMP threads, without the fork and serialisation of parallel::mclapply()

Installation

# install.packages("devtools")
devtools::install_github("dModverse/cppDE")

Model code is generated and compiled at run time, so a C++17 compiler and Python with SymPy are required. Windows users need Rtools.

Optional system dependencies

The package installs and runs without any system library. Three features are gated on one, detected by ./configure at install time:

Feature Needs Without it
cvode() backend SUNDIALS (>= 6.0) the native solvers are unaffected
sparse Jacobian path SuiteSparse / KLU sparse = TRUE says how to enable it
parallel solveODEBatch() a toolchain with OpenMP correct results, conditions run serially

The three are independent; cppODE() uses KLU without SUNDIALS. OpenMP needs nothing installed on Linux or with Rtools; on macOS, Apple’s clang needs libomp (brew install libomp).

Either install the libraries as system packages,

Platform SUNDIALS SuiteSparse / KLU
Debian/Ubuntu sudo apt install libsundials-dev sudo apt install libsuitesparse-dev
Fedora sudo dnf install sundials-devel sudo dnf install suitesparse-devel
Arch sudo pacman -S sundials sudo pacman -S suitesparse
macOS (Homebrew) brew install sundials brew install suite-sparse

or let cppDE build pinned releases into a per-user cache, which needs no administrator rights:

cppDE::install_libs("sundials")        # or "suitesparse"

./configure finds the cache on every install, so the build is needed once. See ?install_libs for building during the install, build options, and removing the cache. CPPDE_EXTRA_CXXFLAGS is appended to the flags of every model compile().

To see what was detected:

writeLines(readLines(system.file("cvodeConfig.dcf", package = "cppDE")))

Example

  • Fitting measured magnetisation dynamics: a Landau-Lifshitz-Gilbert model fitted to pump-probe measurements by Gauss-Newton on forward sensitivities, with a moving-average noise model and a multistart.

License

cppDE is distributed under the MIT License; see LICENSE / LICENSE.md for the full text.

Portions of the C++ solver core in inst/include/cppde/ are derived from third-party projects and remain subject to their upstream licenses:

  • The Nordsieck multistep stepper (BDF/NDF and Adams-Moulton) in cppde_multistepper.hpp, cppde_multistepper_controller.hpp and cppde_newton.hpp is a port of the corresponding routines in SUNDIALS/CVODE(S) (Copyright © 2002-2024 Lawrence Livermore National Security and Southern Methodist University), distributed under the BSD-3-Clause license.
  • The Rosenbrock4 stepper architecture in cppde_rosenbrock4.hpp (and the surrounding stage-matrix, dense-output and stepper-protocol infrastructure) is derived from Boost.Numeric.Odeint by Karsten Ahnert, Mario Mulansky and Christoph Koke, distributed under the Boost Software License 1.0.

Full upstream copyright notices and license texts are reproduced in inst/COPYRIGHTS. Both upstream licenses are permissive and compatible with MIT; using or redistributing cppDE requires preserving the notices in inst/COPYRIGHTS and the relevant header attribution blocks.

The optional system libraries linked at run time are not vendored: SUNDIALS (BSD-3-Clause) for the cvode() backend and SuiteSparse-KLU (LGPL-2.1+) for the sparse-Jacobian path. Their own licenses govern the libraries at the user’s installation site.