| Title: | MAnifold-Constrained Gaussian Process Inference |
|---|---|
| Description: | Provides fast and accurate inference for the parameter estimation problem in Ordinary Differential Equations, including the case when there are unobserved system components. Implements the MAGI method (MAnifold-constrained Gaussian process Inference) of Yang, Wong, and Kou (2021) <doi:10.1073/pnas.2020397118>. A user guide is provided by the accompanying software paper Wong, Yang, and Kou (2024) <doi:10.18637/jss.v109.i04>. |
| Authors: | Shihao Yang [aut, cre] (ORCID: <https://orcid.org/0000-0003-3910-4969>), Samuel W.K. Wong [aut] (ORCID: <https://orcid.org/0000-0002-7325-7267>), S.C. Kou [ctb, cph] (role: Contributor of MAGI method development) |
| Maintainer: | Shihao Yang <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.2.5 |
| Built: | 2026-05-20 09:01:55 UTC |
| Source: | https://github.com/cran/magi |
Covariance calculations for Gaussian process kernels. Currently supports matern, rbf, compact1, periodicMatern, generalMatern, and rationalQuadratic kernels. Can also return m_phi and other additional quantities useful for ODE inference.
calCov( phi, rInput, signrInput, bandsize = NULL, complexity = 3, kerneltype = "matern", df, noiseInjection = 1e-07 )calCov( phi, rInput, signrInput, bandsize = NULL, complexity = 3, kerneltype = "matern", df, noiseInjection = 1e-07 )
phi |
the kernel hyper-parameters. See details for hyper-parameter specification for each |
rInput |
the distance matrix between all time points s and t, i.e., |s - t| |
signrInput |
the sign matrix of the time differences, i.e., sign(s - t) |
bandsize |
size for band matrix approximation. See details. |
complexity |
integer value for the complexity of the kernel calculations desired:
See details for their definitions. |
kerneltype |
must be one of |
df |
degrees of freedom, for |
noiseInjection |
a small value added to the diagonal elements of C and Kphi for numerical stability |
The covariance formulae and the hyper-parameters phi for the supported kernels are as follows. Stationary kernels have where is the distance between the two time points. Generally, the hyper-parameter phi[1] controls the overall variance level while phi[2] controls the bandwidth.
matern This is the simplified Matern covariance with df = 5/2:
rbf
compact1
periodicMaternDefine . Then the covariance is given by using the Matern formula.
generalMatern
where besselK is the modified Bessel function of the second kind.
rationalQuadratic
The kernel calculations available and their definitions are as follows:
The covariance matrix corresponding to the distance matrix rInput.
The cross-covariance matrix .
The cross-covariance matrix .
A list with the matrices for each element of phi.
The reciprocals of the eigenvalues of C.
Matrix of eigenvectors of C.
The inverse of C.
The matrix Cprime * Cinv.
The matrix Cdoubleprime - Cprime * Kinv * t(Cprime).
The reciprocals of the eigenvalues of Kphi.
The inverse of Kphi.
The matrix Cprime * CeigenVec.
as a 3-D array, with the third dimension corresponding to the elements of phi.
If bandsize is a positive integer, additionally CinvBand, mphiBand, and KinvBand are provided in the return list, which are
band matrix approximations to Cinv, mphi, and Kinv with the specified bandsize.
A list containing the kernel calculations included by the value of complexity.
foo <- outer(0:40, t(0:40), '-')[, 1, ] r <- abs(foo) signr <- -sign(foo) calCov(c(0.2, 2), r, signr, bandsize = 20, kerneltype = "generalMatern", df = 2.01)foo <- outer(0:40, t(0:40), '-')[, 1, ] r <- abs(foo) signr <- -sign(foo) calCov(c(0.2, 2), r, signr, bandsize = 20, kerneltype = "generalMatern", df = 2.01)
The classic FN equations model the spike potentials of neurons, where system components and are the voltage and recovery variables, respectively.
and are governed by the following differential equations:
where are system parameters.
This dataset was generated by first numerically solving these ODEs from to , with initial conditions and and parameters .
The system components were taken to be measured at 28 observation time points (as indicated in time column) with additive Gaussian noise (standard deviation 0.2).
data(FNdat)data(FNdat)
A data frame with 28 rows and 3 columns (time, , ).
FitzHugh, R (1961). Impulses and Physiological States in Theoretical Models of Nerve Membrane. Biophysical Journal, 1(6), 445–466.
The classic FN equations model the spike potentials of neurons, where system components represent the voltage and recovery variables, respectively.
and are governed by the following differential equations:
where are system parameters.
fnmodelODE(theta, x, tvec) fnmodelDx(theta, x, tvec) fnmodelDtheta(theta, x, tvec)fnmodelODE(theta, x, tvec) fnmodelDx(theta, x, tvec) fnmodelDtheta(theta, x, tvec)
theta |
vector of parameters. |
x |
matrix of system states (one per column) at the time points in |
tvec |
vector of time points |
fnmodelODE returns an array with the values of the derivatives .
fnmodelDx returns a 3-D array with the values of the gradients with respect to .
fnmodelDtheta returns a 3-D array with the values of the gradients with respect to .
FitzHugh, R (1961). Impulses and Physiological States in Theoretical Models of Nerve Membrane. Biophysical Journal, 1(6), 445–466.
theta <- c(0.2, 0.2, 3) x <- matrix(1:10, nrow = 5, ncol = 2) tvec <- 1:5 fnmodelODE(theta, x, tvec)theta <- c(0.2, 0.2, 3) x <- matrix(1:10, nrow = 5, ncol = 2) tvec <- 1:5 fnmodelODE(theta, x, tvec)
Compute the conditional covariance of a Gaussian process, given a vector of observations, hyper-parameters phi, and noise standard deviation sigma.
gpcov(yobs, tvec, tnew, phi, sigma, kerneltype = "generalMatern")gpcov(yobs, tvec, tnew, phi, sigma, kerneltype = "generalMatern")
yobs |
vector of observations |
tvec |
vector of time points corresponding to observations |
tnew |
vector of time points at which the conditional covariance should be computed |
phi |
vector of hyper-parameters for the covariance kernel ( |
sigma |
the noise level (if known). By default, both |
kerneltype |
the covariance kernel, types |
The conditional covariance matrix for the GP evaluated at the time points in tnew.
# Load Fitzhugh-Nagumo dataset data(FNdat) tnew <- seq(15, 20, by = 0.5) # GP covariance of V component at time points in tnew given observations gpcov(FNdat$V, FNdat$time, tnew, c(2.3, 1.2), 0.2)# Load Fitzhugh-Nagumo dataset data(FNdat) tnew <- seq(15, 20, by = 0.5) # GP covariance of V component at time points in tnew given observations gpcov(FNdat$V, FNdat$time, tnew, c(2.3, 1.2), 0.2)
Compute the conditional mean of a Gaussian process (and optionally, its derivative), given a vector of observations, hyper-parameters phi, and noise standard deviation sigma.
gpmean( yobs, tvec, tnew, phi, sigma, kerneltype = "generalMatern", deriv = FALSE )gpmean( yobs, tvec, tnew, phi, sigma, kerneltype = "generalMatern", deriv = FALSE )
yobs |
vector of observations |
tvec |
vector of time points corresponding to observations |
tnew |
vector of time points at which the conditional mean should be computed |
phi |
vector of hyper-parameters for the covariance kernel ( |
sigma |
the noise level (if known). By default, both |
kerneltype |
the covariance kernel, types |
deriv |
logical; if true, the conditional mean of the GP's derivative is also computed |
A vector with the values of the conditional mean function evaluated at the time points in tnew. If deriv = TRUE, returned with an additional attribute deriv that contains the values of the conditional mean of the GP derivative evaluated at the time points in tnew.
# Load Fitzhugh-Nagumo dataset data(FNdat) tnew <- seq(0, 20, by = 0.5) # GP mean of V component at time points in tnew given observations gpmean(FNdat$V, FNdat$time, tnew, c(2.3, 1.2), 0.2)# Load Fitzhugh-Nagumo dataset data(FNdat) tnew <- seq(0, 20, by = 0.5) # GP mean of V component at time points in tnew given observations gpmean(FNdat$V, FNdat$time, tnew, c(2.3, 1.2), 0.2)
Estimate hyper-parameters phi and noise standard deviation sigma for a vector of observations using Gaussian process smoothing.
gpsmoothing(yobs, tvec, kerneltype = "generalMatern", sigma = NULL)gpsmoothing(yobs, tvec, kerneltype = "generalMatern", sigma = NULL)
yobs |
vector of observations |
tvec |
vector of time points corresponding to observations |
kerneltype |
the covariance kernel, types |
sigma |
the noise level (if known). By default, both |
A list containing the elements phi and sigma with their estimated values.
# Sample data and observation times tvec <- seq(0, 20, by = 0.5) y <- c(-1.16, -0.18, 1.57, 1.99, 1.95, 1.85, 1.49, 1.58, 1.47, 0.96, 0.75, 0.22, -1.34, -1.72, -2.11, -1.56, -1.51, -1.29, -1.22, -0.36, 1.78, 2.36, 1.78, 1.8, 1.76, 1.4, 1.02, 1.28, 1.21, 0.04, -1.35, -2.1, -1.9, -1.49, -1.55, -1.35, -0.98, -0.34, 1.9, 1.99, 1.84) gpsmoothing(y, tvec)# Sample data and observation times tvec <- seq(0, 20, by = 0.5) y <- c(-1.16, -0.18, 1.57, 1.99, 1.95, 1.85, 1.49, 1.58, 1.47, 0.96, 0.75, 0.22, -1.34, -1.72, -2.11, -1.56, -1.51, -1.29, -1.22, -0.36, 1.78, 2.36, 1.78, 1.8, 1.76, 1.4, 1.02, 1.28, 1.21, 0.04, -1.35, -2.1, -1.9, -1.49, -1.55, -1.35, -0.98, -0.34, 1.9, 1.99, 1.84) gpsmoothing(y, tvec)
Marginal log-likelihood and gradient as a function of GP hyper-parameters phi and observation noise standard deviation sigma. For use in Gaussian process smoothing where values of phi and sigma may be optimized.
gpsmoothllik(phisig, yobs, rInput, kerneltype = "generalMatern")gpsmoothllik(phisig, yobs, rInput, kerneltype = "generalMatern")
phisig |
vector containing GP hyper-parameters phi and observation noise SD sigma. See |
yobs |
vector of observations |
rInput |
distance matrix between all time points of |
kerneltype |
the covariance kernel, types |
A list with elements value and grad, which are the log-likelihood value and gradient with respect to phisig, respectively.
# Suppose phi[1] = 0.5, phi[2] = 3, sigma = 0.1 gpsmoothllik(c(0.5, 3, 0.1), rnorm(10), abs(outer(0:9, t(0:9), '-')[, 1, ]))# Suppose phi[1] = 0.5, phi[2] = 3, sigma = 0.1 gpsmoothllik(c(0.5, 3, 0.1), rnorm(10), abs(outer(0:9, t(0:9), '-')[, 1, ]))
The Hes1 equations model the oscillatory cycles of protein and messenger ribonucleic acid (mRNA) levels in cultured cells. The system components represent the concentrations of protein, mRNA, and the Hes1-interacting factor that provides a negative feedback loop.
, , and are governed by the following differential equations:
where are system parameters.
hes1modelODE(theta, x, tvec) hes1modelDx(theta, x, tvec) hes1modelDtheta(theta, x, tvec) hes1logmodelODE(theta, x, tvec) hes1logmodelDx(theta, x, tvec) hes1logmodelDtheta(theta, x, tvec)hes1modelODE(theta, x, tvec) hes1modelDx(theta, x, tvec) hes1modelDtheta(theta, x, tvec) hes1logmodelODE(theta, x, tvec) hes1logmodelDx(theta, x, tvec) hes1logmodelDtheta(theta, x, tvec)
theta |
vector of parameters. |
x |
matrix of system states (one per column) at the time points in |
tvec |
vector of time points |
hes1modelODE returns an array with the values of the derivatives .
hes1modelDx returns a 3-D array with the values of the gradients with respect to .
hes1modelDtheta returns a 3-D array with the values of the gradients with respect to .
hes1logmodelODE, hes1logmodelDx, and hes1logmodelDtheta are the log-transformed versions of hes1modelODE, hes1modelDx, and hes1modelDtheta, respectively.
Hirata H, Yoshiura S, Ohtsuka T, Bessho Y, Harada T, Yoshikawa K, Kageyama R (2002). Oscillatory Expression of the bHLH Factor Hes1 Regulated by a Negative Feedback Loop. Science, 298(5594), 840–843.
theta <- c(0.022, 0.3, 0.031, 0.028, 0.5, 20, 0.3) x <- matrix(1:15, nrow = 5, ncol = 3) tvec <- 1:5 hes1modelODE(theta, x, tvec)theta <- c(0.022, 0.3, 0.031, 0.028, 0.5, 20, 0.3) x <- matrix(1:15, nrow = 5, ncol = 3) tvec <- 1:5 hes1modelODE(theta, x, tvec)
magioutput) objectCheck for and create a magioutput object
is.magioutput(object) magioutput(...)is.magioutput(object) magioutput(...)
object |
an R object |
... |
arguments required to create a magioutput object. See details. |
Using the core MagiSolver function returns a magioutput object as output, which is a list that contains the following elements:
thetamatrix of MCMC samples for the system parameters , after burn-in.
xsampledarray of MCMC samples for the system trajectories at each discretization time point, after burn-in.
sigmamatrix of MCMC samples for the observation noise SDs , after burn-in.
phimatrix of estimated GP hyper-parameters, one column for each system component.
lpvector of log-posterior values at each MCMC iteration, after burn-in.
y, tvec, odeModelfrom the inputs to MagiSolver.
Printing a magioutput object displays a brief summary of the settings used for the MagiSolver run.
The summary method for a magioutput object prints a table of parameter estimates, see summary.magioutput for more details.
Plotting a magioutput object by default shows the inferred trajectories for each component, see plot.magioutput for more details.
logical. Is the input a magioutput object?
# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example FN data data(FNdat) # Create magioutput from a short MagiSolver run (demo only, more iterations needed for convergence) result <- MagiSolver(FNdat, fnmodel, control = list(nstepsHmc = 5, niterHmc = 50)) is.magioutput(result)# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example FN data data(FNdat) # Create magioutput from a short MagiSolver run (demo only, more iterations needed for convergence) result <- MagiSolver(FNdat, fnmodel, control = list(nstepsHmc = 5, niterHmc = 50)) is.magioutput(result)
magi: MAnifold-Constrained Gaussian Process Inferencemagi is a package that provides fast and accurate inference for the parameter estimation problem in Ordinary Differential Equations, including the case when there are unobserved system components.
In the references below, please see our software paper Wong, Yang, and Kou (2024) for a detailed user guide and Yang, Wong, and Kou (2021) for details of the MAGI method (MAnifold-constrained Gaussian process Inference).
Wong, S. W. K., Yang, S., & Kou, S. C. (2024). magi: A Package for Inference of Dynamic Systems from Noisy and Sparse Data via Manifold-Constrained Gaussian Processes. Journal of Statistical Software, 109 (4), 1-47. doi:10.18637/jss.v109.i04
Yang, S., Wong, S. W. K., & Kou, S. C. (2021). Inference of Dynamic Systems from Noisy and Sparse Data via Manifold-constrained Gaussian Processes. Proceedings of the National Academy of Sciences, 118 (15), e2020397118. doi:10.1073/pnas.2020397118
Computes the MAGI log-posterior value and gradient for an ODE model with the given inputs: the observations , the latent system trajectories ,
the parameters , the noise standard deviations , and covariance kernels.
MagiPosterior( y, xlatent, theta, sigma, covAllDimInput, odeModel, priorTemperatureInput = 1, useBand = FALSE )MagiPosterior( y, xlatent, theta, sigma, covAllDimInput, odeModel, priorTemperatureInput = 1, useBand = FALSE )
y |
data matrix of observations |
xlatent |
matrix of system trajectory values |
theta |
vector of parameter values |
sigma |
vector of observation noise for each system component |
covAllDimInput |
list of covariance kernel objects for each system component. Covariance calculations may be carried out with |
odeModel |
list of ODE functions and inputs. See details. |
priorTemperatureInput |
vector of tempering factors for the GP prior, derivatives, and observations, in that order. Controls the influence of the GP prior relative to the likelihood. Recommended values: the total number of observations divided by the total number of discretization points for the GP prior and derivatives, and 1 for the observations. |
useBand |
logical: should the band matrix approximation be used? If |
A list with elements value for the value of the log-posterior density and grad for its gradient.
# Trajectories from the Fitzhugh-Nagumo equations tvec <- seq(0, 20, 2) Vtrue <- c(-1, 1.91, 1.38, -1.32, -1.5, 1.73, 1.66, 0.89, -1.82, -0.93, 1.89) Rtrue <- c(1, 0.33, -0.62, -0.82, 0.5, 0.94, -0.22, -0.9, -0.08, 0.95, 0.3) # Noisy observations Vobs <- Vtrue + rnorm(length(tvec), sd = 0.05) Robs <- Rtrue + rnorm(length(tvec), sd = 0.1) # Prepare distance matrix for covariance kernel calculation foo <- outer(tvec, t(tvec), '-')[, 1, ] r <- abs(foo) r2 <- r^2 signr <- -sign(foo) # Choose some hyperparameter values to illustrate rphi <- c(0.95, 3.27) vphi <- c(1.98, 1.12) phiTest <- cbind(vphi, rphi) # Covariance computations curCovV <- calCov(phiTest[,1], r, signr, kerneltype = "generalMatern") curCovR <- calCov(phiTest[,2], r, signr, kerneltype = "generalMatern") # Y and X inputs to MagiPosterior yInput <- data.matrix(cbind(Vobs, Robs)) xlatentTest <- data.matrix(cbind(Vtrue, Rtrue)) # Create odeModel list for FN equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) MagiPosterior(yInput, xlatentTest, theta = c(0.2, 0.2, 3), sigma = c(0.05, 0.1), list(curCovV, curCovR), fnmodel)# Trajectories from the Fitzhugh-Nagumo equations tvec <- seq(0, 20, 2) Vtrue <- c(-1, 1.91, 1.38, -1.32, -1.5, 1.73, 1.66, 0.89, -1.82, -0.93, 1.89) Rtrue <- c(1, 0.33, -0.62, -0.82, 0.5, 0.94, -0.22, -0.9, -0.08, 0.95, 0.3) # Noisy observations Vobs <- Vtrue + rnorm(length(tvec), sd = 0.05) Robs <- Rtrue + rnorm(length(tvec), sd = 0.1) # Prepare distance matrix for covariance kernel calculation foo <- outer(tvec, t(tvec), '-')[, 1, ] r <- abs(foo) r2 <- r^2 signr <- -sign(foo) # Choose some hyperparameter values to illustrate rphi <- c(0.95, 3.27) vphi <- c(1.98, 1.12) phiTest <- cbind(vphi, rphi) # Covariance computations curCovV <- calCov(phiTest[,1], r, signr, kerneltype = "generalMatern") curCovR <- calCov(phiTest[,2], r, signr, kerneltype = "generalMatern") # Y and X inputs to MagiPosterior yInput <- data.matrix(cbind(Vobs, Robs)) xlatentTest <- data.matrix(cbind(Vtrue, Rtrue)) # Create odeModel list for FN equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) MagiPosterior(yInput, xlatentTest, theta = c(0.2, 0.2, 3), sigma = c(0.05, 0.1), list(curCovV, curCovR), fnmodel)
Core function of the MAGI method for inferring the parameters and trajectories of dynamic systems governed by ordinary differential equations.
MagiSolver(y, odeModel, tvec, control = list())MagiSolver(y, odeModel, tvec, control = list())
y |
data matrix of observations |
odeModel |
list of ODE functions and inputs. See details. |
tvec |
vector of discretization time points corresponding to rows of |
control |
list of control variables, which may include 'sigma', 'phi', 'theta', 'xInit', 'mu', 'dotmu', 'priorTemperature', 'niterHmc', 'nstepsHmc', 'burninRatio', 'stepSizeFactor', 'bandSize', 'useFixedSigma', 'kerneltype', 'skipMissingComponentOptimization', 'positiveSystem', 'verbose'. See details. |
The data matrix y has a column for each system component, and optionally a column 'time' with the discretization time points. If the column 'time' is not provided in y, a vector of time points must be provided via the tvec argument. The rows of y correspond to the discretization set at which the GP is constrained to the derivatives of the ODE system. To set the desired discretization level for inference, use setDiscretization to prepare the data matrix for input into MagiSolver. Missing observations are indicated with NA or NaN.
The list odeModel is used for specification of the ODE system and its parameters. It must include five elements:
fOdefunction that computes the ODEs, specified with the form f(theta, x, tvec). fOde should return a matrix where columns correspond to the system components of x, see examples.
fOdeDxfunction that computes the gradients of the ODEs with respect to the system components. fOdeDx should return a 3-D array, where the slice [, i, j] is the partial derivative of the ODE for the j-th system component with respect to the i-th system component, see examples.
fOdeDthetafunction that computes the gradients of the ODEs with respect to the parameters . fOdeDtheta should return a 3-D array, where the slice [, i, j] is the partial derivative of the ODE for the j-th system component with respect to the i-th parameter in , see examples.
thetaLowerBounda vector indicating the lower bounds of each parameter in .
thetaUpperBounda vector indicating the upper bounds of each parameter in .
Additional control variables can be supplied to MagiSolver via the optional list control, which may include the following:
sigmaa vector of noise levels (observation noise standard deviations) for each component, at which to initialize MCMC sampling. By default, MagiSolver computes starting values for sigma via Gaussian process (GP) smoothing. If the noise levels are known, specify sigma together with useFixedSigma = TRUE.
phia matrix of GP hyper-parameters for each component, with rows for the kernel hyper-parameters and columns for the system components. By default, MagiSolver estimates phi via an optimization routine.
thetaa vector of starting values for the parameters , at which to initialize MCMC sampling. By default, MagiSolver uses an optimization routine to obtain starting values.
xInita matrix of values for the system trajectories of the same dimension as y, at which to initialize MCMC sampling. Default is linear interpolation between the observed (non-missing) values of y and an optimization routine for entirely unobserved components of y.
mua matrix of values for the mean function of the GP prior, of the same dimension as y. Default is a zero mean function.
dotmua matrix of values for the derivatives of the GP prior mean function, of the same dimension as y. Default is zero.
priorTemperaturethe tempering factor by which to divide the contribution of the GP prior, to control the influence of the GP prior relative to the likelihood. Default is the total number of observations divided by the total number of discretization points.
niterHmcMCMC sampling from the posterior is carried out via the Hamiltonian Monte Carlo (HMC) algorithm. niterHmc specifies the number of HMC iterations to run. Default is 20000 HMC iterations.
nstepsHmcthe number of leapfrog steps per HMC iteration. Default is 200.
burninRatiothe proportion of HMC iterations to be discarded as burn-in. Default is 0.5, which discards the first half of the MCMC samples.
stepSizeFactorinitial leapfrog step size factor for HMC. Can be a specified as a scalar (applied to all posterior dimensions) or a vector (with length corresponding to the dimension of the posterior). Default is 0.01, and the leapfrog step size is automatically tuned during burn-in to achieve an acceptance rate between 60-90%.
bandSizea band matrix approximation is used to speed up matrix operations, with default band size 20. Can be increased if MagiSolver returns an error indicating numerical instability.
useFixedSigmalogical, set to TRUE if sigma is known. If useFixedSigma = TRUE, the known values of must be supplied via the sigma control variable. Default is FALSE.
kerneltypethe GP covariance kernel, generalMatern is the default and recommended choice. Other available choices are matern, rbf, compact1, periodicMatern. See calCov for their definitions.
skipMissingComponentOptimizationlogical, set to TRUE to skip automatic optimization for missing components. If skipMissingComponentOptimization = TRUE, values for xInit and phi must be supplied for all system components. Default is FALSE.
positiveSystemlogical, set to TRUE if the system cannot be negative. Default is FALSE.
verboselogical, set to TRUE to output diagnostic and progress messages to the console. Default is FALSE.
MagiSolver returns an object of class magioutput which contains the following elements:
thetamatrix of MCMC samples for the system parameters , after burn-in.
xsampledarray of MCMC samples for the system trajectories at each discretization time point, after burn-in.
sigmamatrix of MCMC samples for the observation noise SDs , after burn-in.
phimatrix of estimated GP hyper-parameters, one column for each system component.
lpvector of log-posterior values at each MCMC iteration, after burn-in.
y, tvec, odeModelfrom the inputs to MagiSolver.
Wong, S. W. K., Yang, S., & Kou, S. C. (2024). 'magi': A Package for Inference of Dynamic Systems from Noisy and Sparse Data via Manifold-Constrained Gaussian Processes. *Journal of Statistical Software*, 109 (4), 1-47. doi:10.18637/jss.v109.i04
Yang, S., Wong, S. W. K., & Kou, S. C. (2021). Inference of Dynamic Systems from Noisy and Sparse Data via Manifold-constrained Gaussian Processes. *Proceedings of the National Academy of Sciences*, 118 (15), e2020397118. doi:10.1073/pnas.2020397118
# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example noisy data observed from the FN system data(FNdat) # Set discretization for a total of 81 equally-spaced time points from 0 to 20 yinput <- setDiscretization(FNdat, by = 0.25) # Run MagiSolver # Short sampler run for demo only, more iterations needed for convergence MagiSolver(yinput, fnmodel, control = list(nstepsHmc = 5, niterHmc = 101)) # Use 3000 HMC iterations with 100 leapfrog steps per iteration FNres <- MagiSolver(yinput, fnmodel, control = list(nstepsHmc = 100, niterHmc = 3000)) # Summary of parameter estimates summary(FNres) # Plot of inferred trajectories plot(FNres, comp.names = c("V", "R"), xlab = "Time", ylab = "Level")# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example noisy data observed from the FN system data(FNdat) # Set discretization for a total of 81 equally-spaced time points from 0 to 20 yinput <- setDiscretization(FNdat, by = 0.25) # Run MagiSolver # Short sampler run for demo only, more iterations needed for convergence MagiSolver(yinput, fnmodel, control = list(nstepsHmc = 5, niterHmc = 101)) # Use 3000 HMC iterations with 100 leapfrog steps per iteration FNres <- MagiSolver(yinput, fnmodel, control = list(nstepsHmc = 100, niterHmc = 3000)) # Summary of parameter estimates summary(FNres) # Plot of inferred trajectories plot(FNres, comp.names = c("V", "R"), xlab = "Time", ylab = "Level")
magioutput objectPlots inferred system trajectories or diagnostic traceplots from the output of MagiSolver
## S3 method for class 'magioutput' plot( x, type = "traj", obs = TRUE, ci = TRUE, ci.col = "skyblue", comp.names, par.names, est = "mean", lower = 0.025, upper = 0.975, sigma = FALSE, lp = TRUE, nplotcol = 3, ... )## S3 method for class 'magioutput' plot( x, type = "traj", obs = TRUE, ci = TRUE, ci.col = "skyblue", comp.names, par.names, est = "mean", lower = 0.025, upper = 0.975, sigma = FALSE, lp = TRUE, nplotcol = 3, ... )
x |
a |
type |
string; the default |
obs |
logical; if true, points will be added on the plots for the observations when |
ci |
logical; if true, credible bands/intervals will be added to the plots. |
ci.col |
string; color to use for credible bands. |
comp.names |
vector of system component names, when |
par.names |
vector of parameter names, when |
est |
string specifying the posterior quantity to plot as the estimate. Can be "mean", "median", "mode", or "none". Default is "mean", which plots the posterior mean of the MCMC samples. |
lower |
the lower quantile of the credible band/interval, default is 0.025. Only used if |
upper |
the upper quantile of the credible band/interval, default is 0.975. Only used if |
sigma |
logical; if true, the noise levels |
lp |
logical; if true, the values of the log-posterior will be included in the traceplots when |
nplotcol |
the number of subplots per row. |
... |
additional arguments to |
Plots the inferred system trajectories (when type = "traj") or diagnostic traceplots of the parameters and log-posterior (when type = "trace") from the MCMC samples.
By default, the posterior mean is treated as the estimate of the trajectories and parameters (est = "mean").
Alternatives are the posterior median (est = "median", taken component-wise) and the posterior mode (est = "mode", approximated by the MCMC sample with the highest log-posterior value).
The default type = "traj" produces plots of the inferred trajectories and credible bands from the MCMC samples, one subplot for each system component.
By default, lower = 0.025 and upper = 0.975 produces a central 95% credible band when ci = TRUE.
Adding the observed data points (obs = TRUE) can provide a visual assessment of the inferred trajectories.
Setting type = "trace" generates diagnostic traceplots for the MCMC samples of the system parameters and the values of the log-posterior, which is a useful tool for informally assessing convergence.
In this case, the est and ci options add horizontal lines to the plots that indicate the estimate (in red) and credible interval (in green) for each parameter.
# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example FN data data(FNdat) y <- setDiscretization(FNdat, by = 0.25) # Create magioutput from a short MagiSolver run (demo only, more iterations needed for convergence) result <- MagiSolver(y, fnmodel, control = list(nstepsHmc = 20, niterHmc = 500)) # Inferred trajectories plot(result, comp.names = c("V", "R"), xlab = "Time", ylab = "Level") # Parameter trace plots plot(result, type = "trace", par.names = c("a", "b", "c", "sigmaV", "sigmaR"), sigma = TRUE)# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example FN data data(FNdat) y <- setDiscretization(FNdat, by = 0.25) # Create magioutput from a short MagiSolver run (demo only, more iterations needed for convergence) result <- MagiSolver(y, fnmodel, control = list(nstepsHmc = 20, niterHmc = 500)) # Inferred trajectories plot(result, comp.names = c("V", "R"), xlab = "Time", ylab = "Level") # Parameter trace plots plot(result, type = "trace", par.names = c("a", "b", "c", "sigmaV", "sigmaR"), sigma = TRUE)
The protein transduction equations model a biochemical reaction involving a signaling protein that degrades over time. The system components represent the levels of signaling protein, its degraded form, inactive state of , complex, and activated state of .
, , , and are governed by the following differential equations:
where are system parameters.
ptransmodelODE(theta, x, tvec) ptransmodelDx(theta, x, tvec) ptransmodelDtheta(theta, x, tvec)ptransmodelODE(theta, x, tvec) ptransmodelDx(theta, x, tvec) ptransmodelDtheta(theta, x, tvec)
theta |
vector of parameters. |
x |
matrix of system states (one per column) at the time points in |
tvec |
vector of time points |
ptransmodelODE returns an array with the values of the derivatives .
ptransmodelDx returns a 3-D array with the values of the gradients with respect to .
ptransmodelDtheta returns a 3-D array with the values of the gradients with respect to .
Vyshemirsky, V., & Girolami, M. A. (2008). Bayesian Ranking of Biochemical System Models. Bioinformatics, 24(6), 833-839.
theta <- c(0.07, 0.6, 0.05, 0.3, 0.017, 0.3) x <- matrix(1:25, nrow = 5, ncol = 5) tvec <- 1:5 ptransmodelODE(theta, x, tvec)theta <- c(0.07, 0.6, 0.05, 0.3, 0.017, 0.3) x <- matrix(1:25, nrow = 5, ncol = 5) tvec <- 1:5 ptransmodelODE(theta, x, tvec)
Set the discretization level of a data matrix for input to MagiSolver, by inserting time points where the GP is constrained to the derivatives of the ODE system.
setDiscretization(dat, level, by)setDiscretization(dat, level, by)
dat |
data matrix. Must include a column with name 'time'. |
level |
discretization level (a positive integer). |
by |
discretization interval. As an alternative to |
Specify the desired discretization using level or by.
Returns a data matrix with the same columns as dat, with rows added for the inserted discretization time points.
dat <- data.frame(time = 0:10, x = rnorm(11)) setDiscretization(dat, level = 2) setDiscretization(dat, by = 0.2)dat <- data.frame(time = 0:10, x = rnorm(11)) setDiscretization(dat, level = 2) setDiscretization(dat, by = 0.2)
magioutput objectComputes a summary table of parameter estimates from the output of MagiSolver
## S3 method for class 'magioutput' summary( object, sigma = FALSE, par.names, est = "mean", lower = 0.025, upper = 0.975, digits = 3, ... )## S3 method for class 'magioutput' summary( object, sigma = FALSE, par.names, est = "mean", lower = 0.025, upper = 0.975, digits = 3, ... )
object |
a |
sigma |
logical; if true, the noise levels |
par.names |
vector of parameter names for the summary table. If provided, should be the same length as the number of parameters in |
est |
string specifying the posterior quantity to treat as the estimate. Default is |
lower |
the lower quantile of the credible interval, default is 0.025. |
upper |
the upper quantile of the credible interval, default is 0.975. |
digits |
integer; the number of significant digits to print. |
... |
additional arguments affecting the summary produced. |
Computes parameter estimates and credible intervals from the MCMC samples. By default, the posterior mean is treated as the parameter estimate, and lower = 0.025 and upper = 0.975 produces a central 95% credible interval.
Returns a matrix where rows display the estimate, lower credible limit, and upper credible limit of each parameter.
# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example FN data data(FNdat) # Create magioutput from a short MagiSolver run (demo only, more iterations needed for convergence) result <- MagiSolver(FNdat, fnmodel, control = list(nstepsHmc = 5, niterHmc = 100)) summary(result, sigma = TRUE, par.names = c("a", "b", "c", "sigmaV", "sigmaR"))# Set up odeModel list for the Fitzhugh-Nagumo equations fnmodel <- list( fOde = fnmodelODE, fOdeDx = fnmodelDx, fOdeDtheta = fnmodelDtheta, thetaLowerBound = c(0, 0, 0), thetaUpperBound = c(Inf, Inf, Inf) ) # Example FN data data(FNdat) # Create magioutput from a short MagiSolver run (demo only, more iterations needed for convergence) result <- MagiSolver(FNdat, fnmodel, control = list(nstepsHmc = 5, niterHmc = 100)) summary(result, sigma = TRUE, par.names = c("a", "b", "c", "sigmaV", "sigmaR"))
Given functions for the ODE and its gradients (with respect to the system components and parameters), verify the correctness of the gradients using numerical differentiation.
testDynamicalModel(modelODE, modelDx, modelDtheta, modelName, x, theta, tvec)testDynamicalModel(modelODE, modelDx, modelDtheta, modelName, x, theta, tvec)
modelODE |
function that computes the ODEs, specified with the form |
modelDx |
function that computes the gradients of the ODEs with respect to the system components. See examples. |
modelDtheta |
function that computes the gradients of the ODEs with respect to the parameters |
modelName |
string giving a name for the model |
x |
data matrix of system values, one column for each component, at which to test the gradients |
theta |
vector of parameter values for |
tvec |
vector of time points corresponding to the rows of |
Calls test_that to test equality of the analytic and numeric gradients.
A list with elements testDx and testDtheta, each with value TRUE if the corresponding gradient check passed and FALSE if not.
# ODE system and gradients for Fitzhugh-Nagumo equations: fnmodelODE, fnmodelDx, fnmodelDtheta # Example of incorrect gradient with respect to parameters theta fnmodelDthetaWrong <- function(theta, x, tvec) { resultDtheta <- array(0, c(nrow(x), length(theta), ncol(x))) V = x[, 1] R = x[, 2] resultDtheta[, 3, 1] = V - V^3 / 3.0 - R resultDtheta[, 1, 2] = 1.0 / theta[3] resultDtheta[, 2, 2] = -R / theta[3] resultDtheta[, 3, 2] = 1.0 / (theta[3]^2) * (V - theta[1] + theta[2] * R) resultDtheta } # Sample data for testing gradient correctness data(FNdat) # Correct gradients testDynamicalModel(fnmodelODE, fnmodelDx, fnmodelDtheta, "FN equations", FNdat[, c("V", "R")], c(.5, .6, 2), FNdat$time) # Incorrect theta gradient (test fails) testDynamicalModel(fnmodelODE, fnmodelDx, fnmodelDthetaWrong, "FN equations", FNdat[, c("V", "R")], c(.5, .6, 2), FNdat$time)# ODE system and gradients for Fitzhugh-Nagumo equations: fnmodelODE, fnmodelDx, fnmodelDtheta # Example of incorrect gradient with respect to parameters theta fnmodelDthetaWrong <- function(theta, x, tvec) { resultDtheta <- array(0, c(nrow(x), length(theta), ncol(x))) V = x[, 1] R = x[, 2] resultDtheta[, 3, 1] = V - V^3 / 3.0 - R resultDtheta[, 1, 2] = 1.0 / theta[3] resultDtheta[, 2, 2] = -R / theta[3] resultDtheta[, 3, 2] = 1.0 / (theta[3]^2) * (V - theta[1] + theta[2] * R) resultDtheta } # Sample data for testing gradient correctness data(FNdat) # Correct gradients testDynamicalModel(fnmodelODE, fnmodelDx, fnmodelDtheta, "FN equations", FNdat[, c("V", "R")], c(.5, .6, 2), FNdat$time) # Incorrect theta gradient (test fails) testDynamicalModel(fnmodelODE, fnmodelDx, fnmodelDthetaWrong, "FN equations", FNdat[, c("V", "R")], c(.5, .6, 2), FNdat$time)