Skip to contents

Data Generation Using the SimSSMOUFixed Function from the simStateSpace Package

n
#> [1] 100
time
#> [1] 1000
delta_t
#> [1] 0.1
mu0
#> [1] 0 0 0
sigma0
#>      [,1] [,2] [,3]
#> [1,]  1.0  0.2  0.2
#> [2,]  0.2  1.0  0.2
#> [3,]  0.2  0.2  1.0
sigma0_l # sigma0_l <- t(chol(sigma0))
#>      [,1]      [,2]      [,3]
#> [1,]  1.0 0.0000000 0.0000000
#> [2,]  0.2 0.9797959 0.0000000
#> [3,]  0.2 0.1632993 0.9660918
mu
#> [1] 0 0 0
phi
#>        [,1]   [,2]   [,3]
#> [1,] -0.357  0.000  0.000
#> [2,]  0.771 -0.511  0.000
#> [3,] -0.450  0.729 -0.693
sigma
#>             [,1]       [,2]        [,3]
#> [1,]  0.24455556 0.02201587 -0.05004762
#> [2,]  0.02201587 0.07067800  0.01539456
#> [3,] -0.05004762 0.01539456  0.07553061
sigma_l # sigma_l <- t(chol(sigma))
#>             [,1]      [,2]     [,3]
#> [1,]  0.49452559 0.0000000 0.000000
#> [2,]  0.04451917 0.2620993 0.000000
#> [3,] -0.10120330 0.0759256 0.243975
nu
#> [1] 0 0 0
lambda
#>      [,1] [,2] [,3]
#> [1,]    1    0    0
#> [2,]    0    1    0
#> [3,]    0    0    1
theta
#>      [,1] [,2] [,3]
#> [1,]  0.2  0.0  0.0
#> [2,]  0.0  0.2  0.0
#> [3,]  0.0  0.0  0.2
theta_l # theta_l <- t(chol(theta))
#>           [,1]      [,2]      [,3]
#> [1,] 0.4472136 0.0000000 0.0000000
#> [2,] 0.0000000 0.4472136 0.0000000
#> [3,] 0.0000000 0.0000000 0.4472136
library(simStateSpace)
sim <- SimSSMOUFixed(
  n = n,
  time = time,
  delta_t = delta_t,
  mu0 = mu0,
  sigma0_l = sigma0_l,
  mu = mu,
  phi = phi,
  sigma_l = sigma_l,
  nu = nu,
  lambda = lambda,
  theta_l = theta_l,
  type = 0
)
data <- as.data.frame(sim)
colnames(data) <- c("id", "time", "x", "m", "y")
head(data)
#>   id time          x          m        y
#> 1  1  0.0 -0.3504435 0.41877429 2.611996
#> 2  1  0.1 -0.5920330 1.07433208 1.669272
#> 3  1  0.2 -0.7619855 1.21483834 2.369837
#> 4  1  0.3 -1.6964652 0.21209722 2.128531
#> 5  1  0.4 -1.2282686 0.09950326 1.891140
#> 6  1  0.5  0.1433985 0.66784226 2.036033

Model Fitting

We use the dynr package to fit the continuous-time vector autoregressive model.

Prepare the Data

dynr_data <- dynr.data(
  dataframe = data,
  id = "id",
  time = "time",
  observed = c("x", "m", "y")
)

Prepare the Initial Condition

dynr_initial <- prep.initial(
  values.inistate = c(
    0, 0, 0
  ),
  params.inistate = c(
    "mu0_1_1", "mu0_2_1", "mu0_3_1"
  ),
  values.inicov = matrix(
    data = c(
      1.0, 0.2, 0.2,
      0.2, 1.0, 0.2,
      0.2, 0.2, 1.0
    ),
    nrow = 3
  ),
  params.inicov = matrix(
    data = c(
      "sigma0_1_1", "sigma0_2_1", "sigma0_3_1",
      "sigma0_2_1", "sigma0_2_2", "sigma0_3_2",
      "sigma0_3_1", "sigma0_3_2", "sigma0_3_3"
    ),
    nrow = 3
  )
)

Prepare the Measurement Model

dynr_measurement <- prep.measurement(
  values.load = diag(3),
  params.load = matrix(
    data = "fixed",
    nrow = 3,
    ncol = 3
  ),
  state.names = c("eta_x", "eta_m", "eta_y"),
  obs.names = c("x", "m", "y")
)

Prepare the Dynamic Model

dynr_dynamics <- prep.formulaDynamics(
  formula = list(
    eta_x ~ phi_1_1 * eta_x + phi_1_2 * eta_m + phi_1_3 * eta_y,
    eta_m ~ phi_2_1 * eta_x + phi_2_2 * eta_m + phi_2_3 * eta_y,
    eta_y ~ phi_3_1 * eta_x + phi_3_2 * eta_m + phi_3_3 * eta_y
  ),
  startval = c(
    phi_1_1 = -0.2, phi_2_1 = 0.0, phi_3_1 = 0.0,
    phi_1_2 = 0.0, phi_2_2 = -0.2, phi_3_2 = 0.0,
    phi_1_3 = 0.0, phi_2_3 = 0.0, phi_3_3 = -0.2
  ),
  isContinuousTime = TRUE
)

Prepare the Noise Matrices

dynr_noise <- prep.noise(
  values.latent = matrix(
    data = 0.2 * diag(3),
    nrow = 3
  ),
  params.latent = matrix(
    data = c(
      "sigma_1_1", "sigma_2_1", "sigma_3_1",
      "sigma_2_1", "sigma_2_2", "sigma_3_2",
      "sigma_3_1", "sigma_3_2", "sigma_3_3"
    ),
    nrow = 3
  ),
  values.observed = 0.2 * diag(3),
  params.observed = matrix(
    data = c(
      "theta_1_1", "fixed", "fixed",
      "fixed", "theta_2_2", "fixed",
      "fixed", "fixed", "theta_3_3"
    ),
    nrow = 3
  )
)

Prepare the Model

In this example, we increase the maximum evaluations in the optimization process and constrain the lower and upper bounds of the parameters for the drift matrix.

dynr_model <- dynr.model(
  data = dynr_data,
  initial = dynr_initial,
  measurement = dynr_measurement,
  dynamics = dynr_dynamics,
  noise = dynr_noise,
  outfile = tempfile(
    paste0(
      "src-",
      format(
        Sys.time(),
        "%Y-%m-%d-%H-%M-%OS3"
      )
    ),
    fileext = ".c"
  )
)
dynr_model@options$maxeval <- 100000
lb <- ub <- rep(NA, times = length(dynr_model$xstart))
names(ub) <- names(lb) <- names(dynr_model$xstart)
lb[
  c(
    "phi_1_1", "phi_2_1", "phi_3_1",
    "phi_1_2", "phi_2_2", "phi_3_2",
    "phi_1_3", "phi_2_3", "phi_3_3"
  )
] <- -1.5
ub[
  c(
    "phi_1_1", "phi_2_1", "phi_3_1",
    "phi_1_2", "phi_2_2", "phi_3_2",
    "phi_1_3", "phi_2_3", "phi_3_3"
  )
] <- 1.5
dynr_model$lb <- lb
dynr_model$ub <- ub

Fit the Model

fit <- dynr.cook(
  dynr_model,
  verbose = FALSE
)
#> [1] "Get ready!!!!"
#> using C compiler: ‘gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0’
#> Optimization function called.
#> Starting Hessian calculation ...
#> Finished Hessian calculation.
#> Original exit flag:  3 
#> Modified exit flag:  3 
#> Optimization terminated successfully: ftol_rel or ftol_abs was reached. 
#> Original fitted parameters:  -0.3518368 0.7442809 -0.4586826 0.01729864 
#> -0.4888158 0.726799 -0.02382471 -0.00979981 -0.6883465 -1.418096 0.096098 
#> -0.2088241 -2.681141 0.2898495 -2.881284 -1.615145 -1.611841 -1.603598 
#> 0.006364943 -0.04257927 0.1301567 0.1400115 0.3596348 0.1963933 0.07053978 
#> 0.1436827 -0.1098101 
#> 
#> Transformed fitted parameters:  -0.3518368 0.7442809 -0.4586826 0.01729864 
#> -0.4888158 0.726799 -0.02382471 -0.00979981 -0.6883465 0.2421747 0.0232725 
#> -0.05057192 0.0707214 0.01499047 0.07237695 0.1988618 0.1995199 0.2011713 
#> 0.006364943 -0.04257927 0.1301567 1.150287 0.4136832 0.2259086 1.221862 
#> 0.2354286 0.9625248 
#> 
#> Doing end processing
#> Successful trial
#> Total Time: 2.68385 
#> Backend Time: 2.68365
summary(fit)
#> Coefficients:
#>             Estimate Std. Error t value  ci.lower  ci.upper Pr(>|t|)    
#> phi_1_1    -0.351837   0.040477  -8.692 -0.431170 -0.272503   <2e-16 ***
#> phi_2_1     0.744281   0.022684  32.810  0.699821  0.788741   <2e-16 ***
#> phi_3_1    -0.458683   0.023307 -19.680 -0.504364 -0.413001   <2e-16 ***
#> phi_1_2     0.017299   0.035160   0.492 -0.051614  0.086211   0.3114    
#> phi_2_2    -0.488816   0.019999 -24.442 -0.528013 -0.449619   <2e-16 ***
#> phi_3_2     0.726799   0.020673  35.157  0.686280  0.767318   <2e-16 ***
#> phi_1_3    -0.023825   0.026208  -0.909 -0.075191  0.027542   0.1817    
#> phi_2_3    -0.009800   0.015134  -0.648 -0.039463  0.019863   0.2586    
#> phi_3_3    -0.688346   0.015868 -43.379 -0.719448 -0.657245   <2e-16 ***
#> sigma_1_1   0.242175   0.007291  33.216  0.227885  0.256465   <2e-16 ***
#> sigma_2_1   0.023273   0.002647   8.792  0.018084  0.028461   <2e-16 ***
#> sigma_3_1  -0.050572   0.002740 -18.459 -0.055941 -0.045202   <2e-16 ***
#> sigma_2_2   0.070721   0.001916  36.921  0.066967  0.074476   <2e-16 ***
#> sigma_3_2   0.014990   0.001380  10.865  0.012286  0.017695   <2e-16 ***
#> sigma_3_3   0.072377   0.002106  34.361  0.068249  0.076505   <2e-16 ***
#> theta_1_1   0.198862   0.001189 167.270  0.196532  0.201192   <2e-16 ***
#> theta_2_2   0.199520   0.001001 199.355  0.197558  0.201481   <2e-16 ***
#> theta_3_3   0.201171   0.001017 197.798  0.199178  0.203165   <2e-16 ***
#> mu0_1_1     0.006365   0.118695   0.054 -0.226274  0.239004   0.4786    
#> mu0_2_1    -0.042579   0.113165  -0.376 -0.264378  0.179220   0.3534    
#> mu0_3_1     0.130157   0.102344   1.272 -0.070434  0.330747   0.1017    
#> sigma0_1_1  1.150287   0.205378   5.601  0.747754  1.552820   <2e-16 ***
#> sigma0_2_1  0.413683   0.134865   3.067  0.149352  0.678015   0.0011 ** 
#> sigma0_3_1  0.225909   0.118800   1.902 -0.006935  0.458753   0.0286 *  
#> sigma0_2_2  1.221862   0.198459   6.157  0.832890  1.610835   <2e-16 ***
#> sigma0_3_2  0.235429   0.125869   1.870 -0.011271  0.482128   0.0307 *  
#> sigma0_3_3  0.962525   0.150708   6.387  0.667142  1.257908   <2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> -2 log-likelihood value at convergence = 429365.49
#> AIC = 429419.49
#> BIC = 429676.34
coefs <- coef(fit)
vcovs <- vcov(fit)

Extract Matrices from the Fitted Model to use in cTMed

phi_names <- c(
  "phi_1_1", "phi_2_1", "phi_3_1",
  "phi_1_2", "phi_2_2", "phi_3_2",
  "phi_1_3", "phi_2_3", "phi_3_3"
)
sigma_names <- c(
  "sigma_1_1", "sigma_2_1", "sigma_3_1",
  "sigma_2_1", "sigma_2_2", "sigma_3_2",
  "sigma_3_1", "sigma_3_2", "sigma_3_3"
)
sigma_vech_names <- c(
  "sigma_1_1", "sigma_2_1", "sigma_3_1",
  "sigma_2_2", "sigma_3_2",
  "sigma_3_3"
)
theta_names <- c(
  "phi_1_1", "phi_2_1", "phi_3_1",
  "phi_1_2", "phi_2_2", "phi_3_2",
  "phi_1_3", "phi_2_3", "phi_3_3",
  "sigma_1_1", "sigma_2_1", "sigma_3_1",
  "sigma_2_2", "sigma_3_2",
  "sigma_3_3"
)
phi <- matrix(
  data = coefs[phi_names],
  nrow = 3,
  ncol = 3
)
sigma <- matrix(
  data = coefs[sigma_names],
  nrow = 3,
  ncol = 3
)
theta <- coefs[theta_names]
vcov_phi_vec <- vcovs[phi_names, phi_names]
vcov_sigma_vech <- vcovs[sigma_vech_names, sigma_vech_names]
vcov_theta <- vcovs[theta_names, theta_names]

Estimated Drift Matrix with Corresponding Sampling Covariance Matrix

phi
#>            [,1]        [,2]        [,3]
#> [1,] -0.3518368  0.01729864 -0.02382471
#> [2,]  0.7442809 -0.48881584 -0.00979981
#> [3,] -0.4586826  0.72679902 -0.68834647
vcov_phi_vec
#>               phi_1_1       phi_2_1       phi_3_1       phi_1_2       phi_2_2
#> phi_1_1  1.638395e-03  4.205720e-05 -2.365513e-04 -1.376185e-03 -4.400313e-05
#> phi_2_1  4.205720e-05  5.145749e-04  1.901381e-05 -2.143907e-05 -4.359631e-04
#> phi_3_1 -2.365513e-04  1.901381e-05  5.432299e-04  1.936645e-04 -9.386709e-06
#> phi_1_2 -1.376185e-03 -2.143907e-05  1.936645e-04  1.236241e-03  3.126359e-05
#> phi_2_2 -4.400313e-05 -4.359631e-04 -9.386709e-06  3.126359e-05  3.999593e-04
#> phi_3_2  2.074921e-04 -2.517298e-05 -4.623548e-04 -1.848726e-04  1.576373e-05
#> phi_1_3  9.257184e-04  8.251254e-06 -1.204207e-04 -8.555641e-04 -1.597444e-05
#> phi_2_3  3.762530e-05  2.928343e-04  7.109899e-07 -3.090243e-05 -2.783699e-04
#> phi_3_3 -1.487146e-04  2.380476e-05  3.133472e-04  1.369958e-04 -1.775455e-05
#>               phi_3_2       phi_1_3       phi_2_3       phi_3_3
#> phi_1_1  2.074921e-04  9.257184e-04  3.762530e-05 -1.487146e-04
#> phi_2_1 -2.517298e-05  8.251254e-06  2.928343e-04  2.380476e-05
#> phi_3_1 -4.623548e-04 -1.204207e-04  7.109899e-07  3.133472e-04
#> phi_1_2 -1.848726e-04 -8.555641e-04 -3.090243e-05  1.369958e-04
#> phi_2_2  1.576373e-05 -1.597444e-05 -2.783699e-04 -1.775455e-05
#> phi_3_2  4.273789e-04  1.199960e-04 -4.260080e-06 -3.007907e-04
#> phi_1_3  1.199960e-04  6.868542e-04  2.386256e-05 -1.071758e-04
#> phi_2_3 -4.260080e-06  2.386256e-05  2.290520e-04  8.181839e-06
#> phi_3_3 -3.007907e-04 -1.071758e-04  8.181839e-06  2.518045e-04

Process Noise Covariance Matrix with Corresponding Sampling Covariance Matrix

sigma
#>             [,1]       [,2]        [,3]
#> [1,]  0.24217468 0.02327250 -0.05057192
#> [2,]  0.02327250 0.07072140  0.01499047
#> [3,] -0.05057192 0.01499047  0.07237695
vcov_sigma_vech
#>               sigma_1_1     sigma_2_1     sigma_3_1     sigma_2_2     sigma_3_2
#> sigma_1_1  5.315788e-05 -1.473938e-06 -5.848017e-06  4.039293e-07 -2.565611e-08
#> sigma_2_1 -1.473938e-06  7.006599e-06  1.438703e-07 -6.227217e-07 -9.558368e-07
#> sigma_3_1 -5.848017e-06  1.438703e-07  7.505554e-06  7.860849e-09 -2.941660e-07
#> sigma_2_2  4.039293e-07 -6.227217e-07  7.860849e-09  3.669146e-06  6.984348e-08
#> sigma_3_2 -2.565611e-08 -9.558368e-07 -2.941660e-07  6.984348e-08  1.903497e-06
#> sigma_3_3  7.654383e-07  2.524688e-08 -2.011280e-06 -4.218391e-08  5.149938e-08
#>               sigma_3_3
#> sigma_1_1  7.654383e-07
#> sigma_2_1  2.524688e-08
#> sigma_3_1 -2.011280e-06
#> sigma_2_2 -4.218391e-08
#> sigma_3_2  5.149938e-08
#> sigma_3_3  4.436798e-06

Estimated Drift Matrix and Process Noise Covariance Matrix with Corresponding Sampling Covariance Matrix

theta
#>     phi_1_1     phi_2_1     phi_3_1     phi_1_2     phi_2_2     phi_3_2 
#> -0.35183681  0.74428086 -0.45868259  0.01729864 -0.48881584  0.72679902 
#>     phi_1_3     phi_2_3     phi_3_3   sigma_1_1   sigma_2_1   sigma_3_1 
#> -0.02382471 -0.00979981 -0.68834647  0.24217468  0.02327250 -0.05057192 
#>   sigma_2_2   sigma_3_2   sigma_3_3 
#>  0.07072140  0.01499047  0.07237695
vcov_theta
#>                 phi_1_1       phi_2_1       phi_3_1       phi_1_2       phi_2_2
#> phi_1_1    1.638395e-03  4.205720e-05 -2.365513e-04 -1.376185e-03 -4.400313e-05
#> phi_2_1    4.205720e-05  5.145749e-04  1.901381e-05 -2.143907e-05 -4.359631e-04
#> phi_3_1   -2.365513e-04  1.901381e-05  5.432299e-04  1.936645e-04 -9.386709e-06
#> phi_1_2   -1.376185e-03 -2.143907e-05  1.936645e-04  1.236241e-03  3.126359e-05
#> phi_2_2   -4.400313e-05 -4.359631e-04 -9.386709e-06  3.126359e-05  3.999593e-04
#> phi_3_2    2.074921e-04 -2.517298e-05 -4.623548e-04 -1.848726e-04  1.576373e-05
#> phi_1_3    9.257184e-04  8.251254e-06 -1.204207e-04 -8.555641e-04 -1.597444e-05
#> phi_2_3    3.762530e-05  2.928343e-04  7.109899e-07 -3.090243e-05 -2.783699e-04
#> phi_3_3   -1.487146e-04  2.380476e-05  3.133472e-04  1.369958e-04 -1.775455e-05
#> sigma_1_1 -2.442013e-04 -1.579694e-05  3.757720e-05  1.933901e-04  1.302756e-05
#> sigma_2_1  2.297497e-05 -3.896357e-05 -7.962854e-06 -2.294436e-05  2.962651e-05
#> sigma_3_1  1.863072e-05  3.619382e-06 -4.198918e-05 -1.170724e-05 -2.840243e-06
#> sigma_2_2 -3.578211e-06  1.541868e-05  2.332149e-06  3.281239e-06 -1.545537e-05
#> sigma_3_2 -1.431835e-06  1.927127e-06  8.322808e-06  1.615242e-06  1.176296e-07
#> sigma_3_3 -2.203611e-06 -1.270215e-06  4.429654e-06  1.092348e-06  8.732957e-07
#>                 phi_3_2       phi_1_3       phi_2_3       phi_3_3     sigma_1_1
#> phi_1_1    2.074921e-04  9.257184e-04  3.762530e-05 -1.487146e-04 -2.442013e-04
#> phi_2_1   -2.517298e-05  8.251254e-06  2.928343e-04  2.380476e-05 -1.579694e-05
#> phi_3_1   -4.623548e-04 -1.204207e-04  7.109899e-07  3.133472e-04  3.757720e-05
#> phi_1_2   -1.848726e-04 -8.555641e-04 -3.090243e-05  1.369958e-04  1.933901e-04
#> phi_2_2    1.576373e-05 -1.597444e-05 -2.783699e-04 -1.775455e-05  1.302756e-05
#> phi_3_2    4.273789e-04  1.199960e-04 -4.260080e-06 -3.007907e-04 -3.085525e-05
#> phi_1_3    1.199960e-04  6.868542e-04  2.386256e-05 -1.071758e-04 -1.210257e-04
#> phi_2_3   -4.260080e-06  2.386256e-05  2.290520e-04  8.181839e-06 -8.695992e-06
#> phi_3_3   -3.007907e-04 -1.071758e-04  8.181839e-06  2.518045e-04  2.042787e-05
#> sigma_1_1 -3.085525e-05 -1.210257e-04 -8.695992e-06  2.042787e-05  5.315788e-05
#> sigma_2_1  7.563860e-06  1.524066e-05 -1.770462e-05 -5.242933e-06 -1.473938e-06
#> sigma_3_1  3.205242e-05  1.735962e-06  1.379332e-06 -1.843388e-05 -5.848017e-06
#> sigma_2_2 -2.613218e-06 -2.319797e-06  9.763319e-06  1.906244e-06  4.039293e-07
#> sigma_3_2 -8.237631e-06 -9.189074e-07 -2.405728e-06  4.981899e-06 -2.565611e-08
#> sigma_3_3 -2.240050e-07  5.646350e-07 -1.197923e-07 -5.157492e-06  7.654383e-07
#>               sigma_2_1     sigma_3_1     sigma_2_2     sigma_3_2     sigma_3_3
#> phi_1_1    2.297497e-05  1.863072e-05 -3.578211e-06 -1.431835e-06 -2.203611e-06
#> phi_2_1   -3.896357e-05  3.619382e-06  1.541868e-05  1.927127e-06 -1.270215e-06
#> phi_3_1   -7.962854e-06 -4.198918e-05  2.332149e-06  8.322808e-06  4.429654e-06
#> phi_1_2   -2.294436e-05 -1.170724e-05  3.281239e-06  1.615242e-06  1.092348e-06
#> phi_2_2    2.962651e-05 -2.840243e-06 -1.545537e-05  1.176296e-07  8.732957e-07
#> phi_3_2    7.563860e-06  3.205242e-05 -2.613218e-06 -8.237631e-06 -2.240050e-07
#> phi_1_3    1.524066e-05  1.735962e-06 -2.319797e-06 -9.189074e-07  5.646350e-07
#> phi_2_3   -1.770462e-05  1.379332e-06  9.763319e-06 -2.405728e-06 -1.197923e-07
#> phi_3_3   -5.242933e-06 -1.843388e-05  1.906244e-06  4.981899e-06 -5.157492e-06
#> sigma_1_1 -1.473938e-06 -5.848017e-06  4.039293e-07 -2.565611e-08  7.654383e-07
#> sigma_2_1  7.006599e-06  1.438703e-07 -6.227217e-07 -9.558368e-07  2.524688e-08
#> sigma_3_1  1.438703e-07  7.505554e-06  7.860849e-09 -2.941660e-07 -2.011280e-06
#> sigma_2_2 -6.227217e-07  7.860849e-09  3.669146e-06  6.984348e-08 -4.218391e-08
#> sigma_3_2 -9.558368e-07 -2.941660e-07  6.984348e-08  1.903497e-06  5.149938e-08
#> sigma_3_3  2.524688e-08 -2.011280e-06 -4.218391e-08  5.149938e-08  4.436798e-06

References

Ou, L., Hunter, M. D., & Chow, S.-M. (2019). What’s for dynr: A package for linear and nonlinear dynamic modeling in R. The R Journal, 11(1), 91. https://doi.org/10.32614/rj-2019-012
R Core Team. (2024). R: A language and environment for statistical computing. R Foundation for Statistical Computing. https://www.R-project.org/