This example illustrates how to fit a linear Stochastic differential equation (SDE) model in the dynr
package.
A damped linear oscillator model is estimated. Details of the model set up is as follows:
\(\frac{d^2x}{dt^2} = -kx - c\frac{dx}{dt} + \zeta\)
This model can also be written in the form of a vector of first-order systems:
The dynamic model is :
\[\begin{pmatrix} \frac{dx}{dt}\\ \frac{d^2x}{dt^2} \end{pmatrix} = \begin{pmatrix} 0 & 1\\ -k & -c \end{pmatrix}\begin{pmatrix} x\\ \frac{dx}{dt} \end{pmatrix} + \begin{pmatrix} 0\\ \zeta \end{pmatrix}\]
The measurement model is:
\[y = \begin{pmatrix} 1 & 0 \end{pmatrix}\begin{pmatrix} x\\ \frac{dx}{dt} \end{pmatrix} + \epsilon\]
We first load dynr package.
The dynr.data command is used to create a dynr data object. Here the observed variable we are modeling is “y1” . (The simulated data are loaded as part of the package.)
## Loading required package: dynr
## Loading required package: ggplot2
The prep.measurement command is used to specify the factor loadings matrix. The values.load
argument specifies that the factor loadings are fixed at 1 and 0. In this model, all parameters are fixed, which is indicated by the params.load
argument. The *.names
argument gives names to the latent and observed variables.
The prep.noise command is used to specify dynamic (values.latent
) and observation (values.observed
) noise components. The latent noise is the dynamic noise. The observed noise is the measurement noise.
The prep.matrixDynamics command is used to define the differental equation. In this model, the first row of the parameter matrix is fixed at 0 and 1 and the starting values for the second row of the matrix is set at -0.1 and -0.2.
ecov <- prep.noise(
values.latent=diag(c(0, 1), 2), params.latent=diag(c('fixed', 'dnoise'), 2),
values.observed=diag(1.5, 1), params.observed=diag('mnoise', 1))
dynamics <- prep.matrixDynamics(
values.dyn=matrix(c(0, -0.1, 1, -0.2), 2, 2),
params.dyn=matrix(c('fixed', 'spring', 'fixed', 'friction'), 2, 2),
isContinuousTime=TRUE)
This step specifies the covariances and latent state values at t=0. These initialize the recursive algorithm (extended Kalman filter) that dynr uses.
Now we put together everything we’ve previously specified in dynr.model. This code connects the recipes we’ve written up with our data and writes a c file in our working directory. We can inspect c functions that go with each recipe in the c file.
We can check our model specifications in a neatly printed pdf file using the following code.
The printex command is used to write the model into a Latex file, with a name given by the outFile
argument. Then, the tools::texi2pdf command generates a pdf file from the latex file we just created. The system command prints out the pdf file:
We can also print out the model in R, instead of generating a Latex file, using the command plotFormula.
Now the model is specified and we are ready to cook dynr! The summary command gives the model fitting results.
## Coefficients:
## Estimate Std. Error t value ci.lower ci.upper Pr(>|t|)
## spring -0.25072 0.03247 -7.721 -0.31437 -0.18708 <2e-16 ***
## friction -0.62364 0.11617 -5.368 -0.85133 -0.39595 <2e-16 ***
## dnoise 1.53092 0.44174 3.466 0.66513 2.39671 0.0003 ***
## mnoise 1.62361 0.10465 15.514 1.41850 1.82873 <2e-16 ***
## inipos 0.13306 1.41682 0.094 -2.64385 2.90997 0.4626
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## -2 log-likelihood value at convergence = 4067.88
## AIC = 4077.88
## BIC = 4102.41