13.8 Solving a system of linear ODEs using a matrix exponential
Linear systems of ODEs can be solved using a matrix exponential. This can be considerably faster than using one of the ODE solvers.
The solution to ddty=ay is y=y0eat, where the constant y0 is determined by boundary conditions. We can extend this solution to the vector case: ddty=Ay where y is now a vector of length n and A is an n by n matrix. The solution is then given by: y=etAy0 where the matrix exponential is formally defined by the convergent power series: etA=∞∑n=0tAnn!=I+tA+t2A22!+⋯
We can apply this technique to the simple harmonic oscillator example, by setting y=[y1y2]A=[01−1−θ]
The Stan model to simulate noisy observations using a matrix exponential function is given below.
In general, computing a matrix exponential will be more efficient than using a numerical solver. We can however only apply this technique to systems of linear ODEs.
data {
int<lower=1> T;
vector[2] y0;
array[T] real ts;
array[1] real theta;
}
model {
}
generated quantities {
array[T] vector[2] y_sim;
matrix[2, 2] A = [[ 0, 1],
[-1, -theta[1]]]
for (t in 1:T) {
y_sim[t] = matrix_exp((t - 1) * A) * y0;
}
// add measurement error
for (t in 1:T) {
y_sim[t, 1] += normal_rng(0, 0.1);
y_sim[t, 2] += normal_rng(0, 0.1);
}
}
This Stan program simulates noisy measurements from a simple harmonic
oscillator. The system of linear differential equations is coded as a
matrix. The system parameters theta
and initial state y0
are read
in as data along observation times ts
. The generated quantities
block is used to solve the ODE for the specified times and then add
random measurement error, producing observations y_sim
. Because the
ODEs are linear, we can use the matrix_exp
function to solve the
system.