Skip to contents

Data Generation Using the SimSSMOUFixed Function from the simStateSpace Package

n
#> [1] 50
time
#> [1] 100
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.2938068 0.8243958 -0.4543161 -0.07191554 
#> -0.5689988 0.707647 0.02579061 0.08266777 -0.6875018 -1.444748 0.07916771 
#> -0.2743246 -2.582169 0.1772108 -2.804538 -1.604288 -1.652135 -1.622277 
#> -0.06854665 0.08457349 0.1157207 -0.05902917 0.1716259 0.1095353 0.379774 
#> -0.08084045 -0.07765938 
#> 
#> Transformed fitted parameters:  -0.2938068 0.8243958 -0.4543161 -0.07191554 
#> -0.5689988 0.707647 0.02579061 0.08266777 -0.6875018 0.2358056 0.01866819 
#> -0.06468727 0.07708775 0.008277734 0.08065449 0.2010327 0.1916402 0.1974485 
#> -0.06854665 0.08457349 0.1157207 0.9426793 0.1617881 0.1032567 1.489721 
#> -0.1004635 0.9461439 
#> 
#> Doing end processing
#> Successful trial
#> Total Time: 6.042105 
#> Backend Time: 6.031054
summary(fit)
#> Coefficients:
#>             Estimate Std. Error t value  ci.lower  ci.upper Pr(>|t|)    
#> phi_1_1    -0.293807   0.082574  -3.558 -0.455648 -0.131966   0.0002 ***
#> phi_2_1     0.824396   0.056914  14.485  0.712846  0.935946   <2e-16 ***
#> phi_3_1    -0.454316   0.057647  -7.881 -0.567303 -0.341329   <2e-16 ***
#> phi_1_2    -0.071916   0.068787  -1.045 -0.206735  0.062904   0.1479    
#> phi_2_2    -0.568999   0.048532 -11.724 -0.664119 -0.473878   <2e-16 ***
#> phi_3_2     0.707647   0.048636  14.550  0.612322  0.802972   <2e-16 ***
#> phi_1_3     0.025791   0.062589   0.412 -0.096882  0.148463   0.3402    
#> phi_2_3     0.082668   0.043529   1.899 -0.002647  0.167983   0.0288 *  
#> phi_3_3    -0.687502   0.044092 -15.593 -0.773920 -0.601084   <2e-16 ***
#> sigma_1_1   0.235806   0.022759  10.361  0.191198  0.280413   <2e-16 ***
#> sigma_2_1   0.018668   0.010045   1.858 -0.001020  0.038356   0.0316 *  
#> sigma_3_1  -0.064687   0.010768  -6.007 -0.085793 -0.043582   <2e-16 ***
#> sigma_2_2   0.077088   0.009447   8.160  0.058572  0.095603   <2e-16 ***
#> sigma_3_2   0.008278   0.006655   1.244 -0.004765  0.021321   0.1068    
#> sigma_3_3   0.080654   0.010196   7.910  0.060670  0.100639   <2e-16 ***
#> theta_1_1   0.201033   0.005107  39.363  0.191023  0.211043   <2e-16 ***
#> theta_2_2   0.191640   0.004373  43.823  0.183069  0.200211   <2e-16 ***
#> theta_3_3   0.197449   0.004521  43.677  0.188588  0.206309   <2e-16 ***
#> mu0_1_1    -0.068547   0.142210  -0.482 -0.347273  0.210180   0.3149    
#> mu0_2_1     0.084573   0.176685   0.479 -0.261722  0.430869   0.3161    
#> mu0_3_1     0.115721   0.141485   0.818 -0.161585  0.393026   0.2067    
#> sigma0_1_1  0.942679   0.205369   4.590  0.540164  1.345195   <2e-16 ***
#> sigma0_2_1  0.161788   0.179880   0.899 -0.190769  0.514346   0.1842    
#> sigma0_3_1  0.103257   0.143856   0.718 -0.178696  0.385209   0.2365    
#> sigma0_2_2  1.489721   0.311204   4.787  0.879772  2.099670   <2e-16 ***
#> sigma0_3_2 -0.100464   0.178078  -0.564 -0.449491  0.248563   0.2863    
#> sigma0_3_3  0.946144   0.204219   4.633  0.545882  1.346406   <2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> -2 log-likelihood value at convergence = 21626.57
#> AIC = 21680.57
#> BIC = 21856.53
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.2938068 -0.07191554  0.02579061
#> [2,]  0.8243958 -0.56899879  0.08266777
#> [3,] -0.4543161  0.70764697 -0.68750180
vcov_phi_vec
#>               phi_1_1       phi_2_1       phi_3_1       phi_1_2       phi_2_2
#> phi_1_1  0.0068183887  3.328110e-04 -0.0014352362 -0.0049087319 -2.786146e-04
#> phi_2_1  0.0003328110  3.239243e-03 -0.0001186669 -0.0001298602 -2.425089e-03
#> phi_3_1 -0.0014352362 -1.186669e-04  0.0033232239  0.0009753620  1.079346e-04
#> phi_1_2 -0.0049087319 -1.298602e-04  0.0009753620  0.0047316027  1.927033e-04
#> phi_2_2 -0.0002786146 -2.425089e-03  0.0001079346  0.0001927033  2.355321e-03
#> phi_3_2  0.0010343753  3.893230e-05 -0.0024481377 -0.0009945998 -8.261422e-05
#> phi_1_3  0.0033608473  4.732055e-05 -0.0006083507 -0.0034296101 -8.603025e-05
#> phi_2_3  0.0002256333  1.691774e-03 -0.0001006453 -0.0001924514 -1.731951e-03
#> phi_3_3 -0.0007319213 -7.091233e-06  0.0016871746  0.0007482711  3.091309e-05
#>               phi_3_2       phi_1_3       phi_2_3       phi_3_3
#> phi_1_1  1.034375e-03  3.360847e-03  2.256333e-04 -7.319213e-04
#> phi_2_1  3.893230e-05  4.732055e-05  1.691774e-03 -7.091233e-06
#> phi_3_1 -2.448138e-03 -6.083507e-04 -1.006453e-04  1.687175e-03
#> phi_1_2 -9.945998e-04 -3.429610e-03 -1.924514e-04  7.482711e-04
#> phi_2_2 -8.261422e-05 -8.603025e-05 -1.731951e-03  3.091309e-05
#> phi_3_2  2.365471e-03  6.672321e-04  1.034336e-04 -1.733689e-03
#> phi_1_3  6.672321e-04  3.917403e-03  1.804875e-04 -8.681116e-04
#> phi_2_3  1.034336e-04  1.804875e-04  1.894760e-03 -9.774066e-05
#> phi_3_3 -1.733689e-03 -8.681116e-04 -9.774066e-05  1.944073e-03

Process Noise Covariance Matrix with Corresponding Sampling Covariance Matrix

sigma
#>             [,1]        [,2]         [,3]
#> [1,]  0.23580555 0.018668186 -0.064687273
#> [2,]  0.01866819 0.077087752  0.008277734
#> [3,] -0.06468727 0.008277734  0.080654489
vcov_sigma_vech
#>               sigma_1_1     sigma_2_1     sigma_3_1     sigma_2_2     sigma_3_2
#> sigma_1_1  5.179936e-04  1.286404e-05 -9.425124e-05  9.869593e-07 -5.327209e-06
#> sigma_2_1  1.286404e-05  1.009005e-04 -3.493273e-06  4.327901e-06 -2.213247e-05
#> sigma_3_1 -9.425124e-05 -3.493273e-06  1.159554e-04 -4.600131e-07  3.190146e-06
#> sigma_2_2  9.869593e-07  4.327901e-06 -4.600131e-07  8.924541e-05 -2.785630e-06
#> sigma_3_2 -5.327209e-06 -2.213247e-05  3.190146e-06 -2.785630e-06  4.428372e-05
#> sigma_3_3  1.933227e-05  1.524740e-06 -4.759391e-05 -1.091407e-07 -2.565877e-06
#>               sigma_3_3
#> sigma_1_1  1.933227e-05
#> sigma_2_1  1.524740e-06
#> sigma_3_1 -4.759391e-05
#> sigma_2_2 -1.091407e-07
#> sigma_3_2 -2.565877e-06
#> sigma_3_3  1.039638e-04

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.293806753  0.824395779 -0.454316070 -0.071915544 -0.568998789  0.707646969 
#>      phi_1_3      phi_2_3      phi_3_3    sigma_1_1    sigma_2_1    sigma_3_1 
#>  0.025790607  0.082667770 -0.687501801  0.235805550  0.018668186 -0.064687273 
#>    sigma_2_2    sigma_3_2    sigma_3_3 
#>  0.077087752  0.008277734  0.080654489
vcov_theta
#>                 phi_1_1       phi_2_1       phi_3_1       phi_1_2       phi_2_2
#> phi_1_1    6.818389e-03  3.328110e-04 -1.435236e-03 -4.908732e-03 -2.786146e-04
#> phi_2_1    3.328110e-04  3.239243e-03 -1.186669e-04 -1.298602e-04 -2.425089e-03
#> phi_3_1   -1.435236e-03 -1.186669e-04  3.323224e-03  9.753620e-04  1.079346e-04
#> phi_1_2   -4.908732e-03 -1.298602e-04  9.753620e-04  4.731603e-03  1.927033e-04
#> phi_2_2   -2.786146e-04 -2.425089e-03  1.079346e-04  1.927033e-04  2.355321e-03
#> phi_3_2    1.034375e-03  3.893230e-05 -2.448138e-03 -9.945998e-04 -8.261422e-05
#> phi_1_3    3.360847e-03  4.732055e-05 -6.083507e-04 -3.429610e-03 -8.603025e-05
#> phi_2_3    2.256333e-04  1.691774e-03 -1.006453e-04 -1.924514e-04 -1.731951e-03
#> phi_3_3   -7.319213e-04 -7.091233e-06  1.687175e-03  7.482711e-04  3.091309e-05
#> sigma_1_1 -1.106468e-03 -1.398287e-04  2.517698e-04  6.261763e-04  8.119764e-05
#> sigma_2_1  1.010203e-04 -2.425122e-04 -3.718890e-05 -1.273680e-04  1.291759e-04
#> sigma_3_1  1.334626e-04  2.947566e-05 -2.751090e-04 -3.525638e-05 -1.042500e-05
#> sigma_2_2 -4.057314e-06  1.151342e-04  1.195059e-05  5.574693e-06 -1.403873e-04
#> sigma_3_2 -5.525374e-06  2.791248e-05  5.403340e-05  1.195423e-05  8.511003e-06
#> sigma_3_3 -2.843026e-05 -1.384687e-05  5.809073e-05  7.685408e-06  5.321714e-06
#>                 phi_3_2       phi_1_3       phi_2_3       phi_3_3     sigma_1_1
#> phi_1_1    1.034375e-03  3.360847e-03  2.256333e-04 -7.319213e-04 -1.106468e-03
#> phi_2_1    3.893230e-05  4.732055e-05  1.691774e-03 -7.091233e-06 -1.398287e-04
#> phi_3_1   -2.448138e-03 -6.083507e-04 -1.006453e-04  1.687175e-03  2.517698e-04
#> phi_1_2   -9.945998e-04 -3.429610e-03 -1.924514e-04  7.482711e-04  6.261763e-04
#> phi_2_2   -8.261422e-05 -8.603025e-05 -1.731951e-03  3.091309e-05  8.119764e-05
#> phi_3_2    2.365471e-03  6.672321e-04  1.034336e-04 -1.733689e-03 -1.438765e-04
#> phi_1_3    6.672321e-04  3.917403e-03  1.804875e-04 -8.681116e-04 -2.973809e-04
#> phi_2_3    1.034336e-04  1.804875e-04  1.894760e-03 -9.774066e-05 -4.129221e-05
#> phi_3_3   -1.733689e-03 -8.681116e-04 -9.774066e-05  1.944073e-03  7.127045e-05
#> sigma_1_1 -1.438765e-04 -2.973809e-04 -4.129221e-05  7.127045e-05  5.179936e-04
#> sigma_2_1  3.881781e-05  7.657799e-05 -5.873909e-05 -2.257847e-05  1.286404e-05
#> sigma_3_1  1.436551e-04 -6.840144e-05 -7.334321e-06 -4.241756e-05 -9.425124e-05
#> sigma_2_2 -1.299325e-05 -3.273776e-06  8.554974e-05  8.082729e-06  9.869593e-07
#> sigma_3_2 -6.474756e-05 -4.432167e-06 -4.542482e-05  3.582377e-05 -5.327209e-06
#> sigma_3_3  1.565448e-05  2.001541e-05  5.982094e-06 -1.016672e-04  1.933227e-05
#>               sigma_2_1     sigma_3_1     sigma_2_2     sigma_3_2     sigma_3_3
#> phi_1_1    1.010203e-04  1.334626e-04 -4.057314e-06 -5.525374e-06 -2.843026e-05
#> phi_2_1   -2.425122e-04  2.947566e-05  1.151342e-04  2.791248e-05 -1.384687e-05
#> phi_3_1   -3.718890e-05 -2.751090e-04  1.195059e-05  5.403340e-05  5.809073e-05
#> phi_1_2   -1.273680e-04 -3.525638e-05  5.574693e-06  1.195423e-05  7.685408e-06
#> phi_2_2    1.291759e-04 -1.042500e-05 -1.403873e-04  8.511003e-06  5.321714e-06
#> phi_3_2    3.881781e-05  1.436551e-04 -1.299325e-05 -6.474756e-05  1.565448e-05
#> phi_1_3    7.657799e-05 -6.840144e-05 -3.273776e-06 -4.432167e-06  2.001541e-05
#> phi_2_3   -5.873909e-05 -7.334321e-06  8.554974e-05 -4.542482e-05  5.982094e-06
#> phi_3_3   -2.257847e-05 -4.241756e-05  8.082729e-06  3.582377e-05 -1.016672e-04
#> sigma_1_1  1.286404e-05 -9.425124e-05  9.869593e-07 -5.327209e-06  1.933227e-05
#> sigma_2_1  1.009005e-04 -3.493273e-06  4.327901e-06 -2.213247e-05  1.524740e-06
#> sigma_3_1 -3.493273e-06  1.159554e-04 -4.600131e-07  3.190146e-06 -4.759391e-05
#> sigma_2_2  4.327901e-06 -4.600131e-07  8.924541e-05 -2.785630e-06 -1.091407e-07
#> sigma_3_2 -2.213247e-05  3.190146e-06 -2.785630e-06  4.428372e-05 -2.565877e-06
#> sigma_3_3  1.524740e-06 -4.759391e-05 -1.091407e-07 -2.565877e-06  1.039638e-04

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/