mhunter1 / dynr

Dynamic Modeling in R
5 stars 6 forks source link

Error in prep.noise #250

Open NathanUCP opened 4 years ago

NathanUCP commented 4 years ago

Problem I am setting a Toeplizt variance-covariance as initial. But getting error : Found multiple (transformed) start values for parameter ...

Expected : Before throwing this message, the program should check if the values with the same names have the same values.

mhunter1 commented 4 years ago

@NathanUCP I think I understand the issue you're having, but to assure me can you post a minimal example that demonstrates the error? Something like

prep.initial(...)
# Found multiple (transformed) start values for parameter ...
NathanUCP commented 4 years ago

Here is a minimal example:

y1 = pracma::randn(100,1)
y2 = abs(pracma::randn(100,1)) + .2*y1
y3 = abs(pracma::randn(100,1)) + .1*y2
times=1:100
id=rep(1,100)
y = as.data.frame(cbind(y1, y2, y3))
colnames(y) <- paste0("V",1:3)
builddata  = cbind(id, y, times)
data <- dynr::dynr.data(builddata, 
                   id="id", time="times", 
                   observed=paste0("V",1:3))

C0 = matrix(c(1:3, (1:3)^2), ncol = 2)

meas <- dynr::prep.measurement(values.load= C0,
                          params.load= matrix('fixed', 3, 2), 
                          state.names = c("x1","x2"),
                          obs.names = paste0("V",1:3) )
A0 = diag(2)
EC = matrix(0, nrow=2, ncol=1)
dynamics <- dynr::prep.matrixDynamics(values.dyn = A0,
                                 params.dyn = matrix(paste0('theta',1:4), 2, 2),
                                 values.int = EC,
                                 params.int = matrix(paste0('ec',1:4), 2, 1),
                                 isContinuousTime = FALSE)

my.matrixa <- pracma::Toeplitz(paste0('va',1:3))
W = diag(2)
V = pracma::Toeplitz(c(1,.75,.5))
W
     [,1] [,2]
[1,]    1    0
[2,]    0    1
V
     [,1] [,2] [,3]
[1,] 1.00 0.75 0.50
[2,] 0.75 1.00 0.75
[3,] 0.50 0.75 1.00
my.matrixa
     [,1]  [,2]  [,3] 
[1,] "va1" "va2" "va3"
[2,] "va2" "va1" "va2"
[3,] "va3" "va2" "va1"
ecov <- dynr::prep.noise(values.latent = W,
                   params.latent = diag(c('w1','w2')),
                   values.observed = V,
                   params.observed = my.matrixa)

Error: Found multiple (transformed) start values for parameter 'va1': 0, -0.826678573184468, -0.847297860387204

minimal-example.pdf

mhunter1 commented 4 years ago

Thanks, @NathanUCP ! I would say the following is the minimal working example.

require(pracma)
require(dynr)
my.matrixa <- Toeplitz(paste0('va',1:3))
W = diag(2)
V = Toeplitz(c(1,.75,.5))

ecov <- prep.noise(values.latent = W,
                   params.latent = diag(c('w1','w2')),
                   values.observed = V,
                   params.observed = my.matrixa)
# Error: Found multiple (transformed) start values for parameter 'va1': 0, -0.826678573184468, -0.847297860387204

If you change the off-diagonal elements of V to zero, then you will not get the error. However, I'm not sure the parameters will be estimated correctly in your desired model.

ecov <- prep.noise(values.latent = W,
                   params.latent = diag(c('w1','w2')),
                   values.observed = diag(1, 3),
                   params.observed = my.matrixa)

In general, dynr doesn't have a lot of flexibility for specifying structured covariance matrices. This is because of the LDL' transformation we make to keep covariance matrices positive definite. One thing the dynr team could do is add the ability for the user to turn off the LDL' transformation. This would give you more control over how you structure the covariance matrices without being bound by the LDL' transformation.

Here are two things you could provide feedback on:

  1. Let me know if fitting the model using zero off-diagonal elements works correctly.
  2. Let me know if having the ability to remove the LDL' transformation would be appealing.
NathanUCP commented 4 years ago

Thanks @mhunter1 for your answer. Regarding your questions:

  1. Yes, fitting the model using zero off-diagonal elements works correctly
  2. I think, giving the ability to choose the LDL or not is a good idea. For example, it could facilitate nested initialization strategy and It would also help to be sure on the initial values use in the Kalman filter.