13.3 Solving a System of Linear ODEs using a Matrix Exponential
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. Because we are performing matrix
operations, we declare y0
and y_hat
as vectors, instead of using arrays,
as in the previous example code.
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 ODEs.
data {
int<lower=1> T;
vector[2] y0;
real ts[T];
real theta[1];
}
model {
}
generated quantities {
vector[2] y_hat[T];
matrix[2, 2] A = [[ 0, 1],
[-1, -theta[1]]]
for (t in 1:T)
y_hat[t] = matrix_exp((t - 1) * A) * y0;
// add measurement error
for (t in 1:T) {
y_hat[t, 1] += normal_rng(0, 0.1);
y_hat[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_hat
. Because the
ODEs are linear, we can use the matrix_exp
function to solve the
system.