The ECctmc package is a lightweight C++ implementation of the modified rejection sampling and uniformization algorithms detailed in Hobolth and Stone (2009). These algorithms allow users to efficiently simulate sample paths for continuous time Markov chains (CTMC) with discrete state spaces conditional on the state of the chain at the endpoints of the sampling interval. This implementation assumes that state sojourn times are exponentially distributed, and that the process is time-homogeneous. In this vignette we will briefly outline the two algorithms and demonstrate how to call the sampling functions to obtain a collection of paths. This vignette is not intended to be a completely describe the mathematical details of the algorithms or their relative efficiency. For details on the modified rejection sampling and uniformization algorithms, we suggest the Hobolth and Stone (2009) paper, which is really quite excellent.
We are interested in sample paths for a finite state CTMC, \(X(t)\), over the time interval [0, T], conditional on \(X(0) = a\) and \(X(T) = b\). We suppose that the chain has rate matrix \(Q\), where \(Q_{i,j}\) denotes the instantaneous rate of change from state \(i\) to state \(j\), and \(Q_i = Q_{i,i} = -\sum_{j\neq i} Q_{i,j} > 0\) is the rate of exit out of state \(i\). We will use \(\tau\) to denote waiting times.
Simple rejection sampling retains only the paths where \(X(T)=b\).
If \(a=b\),
If \(a\neq b\),
Modified rejection sampling improves upon simple rejection sampling by avoiding sampling constant paths. It will be efficient when the time interval is small and the path is non-constant. However, when transitions into the final state are unlikely, many paths will be rejected.
We begin by defining an auxilliary stochastic process, \(Y(t)\), for which we construct a transition matrix \[ R = I + Q/\mu \] where \(\mu = \max_i Q_i\). Let \(R^n_{i,j}\) denote the \(i,j\) element of the \(n^{th}\) power of \(R\). Let \(P_(T)=e^{QT}\) be the discrete transition probability matrix of \(X(t)\) over the interval, and \(P_{a,b}(T)\) be it’s \(a,b\) element. We proceed as follows:
We may simulate sample paths by calling the sample_path()
function, which returns either a matrix containing the CTMC path, or a list of matrices each containing a path. This function has only a few argments that must be specified. There are:
The default number of paths is 1, although the user can request any number of paths to be returned in a list. We can optionally specify a method, either “mr”, or “unif”, though the default is modified rejection sampling. If uniformization is specified, the user can optionally provide a vector of eigen values, the matrix of corresponding eigen vectors, and the inverse eigen vector matrix. This may help speed up computations if the eigen decomposition has been computed beforehand. When multiple paths are requested, the eigen decomposition is computed once and cached for re-use, so there is no need to supply a pre-computed eigen decomposition.
set.seed(183427)
require(ECctmc)
## Loading required package: ECctmc
# rates
r1 <- 1 # 1->2
r2 <- 0.75 # 2->3
r3 <- 0.5 # 3->1
r4 <- 0.5 # 3-> 2
Q <- matrix(c(-r1, r1, 0, 0, -r2, r2, r3, r4, -(r3+r4)), nrow = 3, byrow = TRUE)
# sample path
path <- sample_path(a=1, b=3, t0=0, t1=5, Q=Q)
path
## time state
## [1,] 0.0000000 1
## [2,] 0.1631161 2
## [3,] 1.1726034 3
## [4,] 1.7334418 1
## [5,] 2.7399563 2
## [6,] 4.7602188 3
## [7,] 5.0000000 3
plot(stepfun(x=path[1:(nrow(path)-1),"time"], y = path[,"state"]), xlim = c(0,5), xlab = "Time", ylab = "State", main = "Sample path")
Asger Hobolth and Eric A Stone. Simulation from endpoint-conditioned, continuous-time Markov chains on a finite state space, with applications to molecular evolution. The Annals of Applied Statistics, 3(3):1204, 2009.
Daniel T Gillespie. A general method for numerically simulating the stochastic time evolution of coupled chemical reactions. Journal of computational physics, 22(4):403–434, 1976