Page 1 of 1

Understanding the difference between Sspace and R's DLM

Posted: Mon Jan 04, 2021 12:53 pm
by Elderfield.A
Hi,

I am trying to convert a model I had put together using R's DLM (Dynamic Linear Model) into Eviews Sspace framework. The model is a Nelson Siegal style latent factor model, using inflation expectations rather than bond yields. I can't seem to get estimates anywhere near what I get with R. I've provided the same starting parameters, using the same data, but I get an error "Near singular matrix in "DLM_INFE.ML" on line 525." I suspect the issue is coming in with how I am specifying my error variances, currently I am imposing non-negativity by

Code: Select all

dlm_infe.append @evar var(g1) = (infe_dlm(18)^2)
When I change this to the exponential

Code: Select all

exp(infe_dlm(18))
I don't get the error, but I do get junk results.

As you are probably aware, the state space representation of the NS model popularised by Diebold and Li, has a VAR(1) process for the state. In R, I parameterise the state VCV matrix directly by setting the matrix Q = to a 3x3 lower triangular matrix of parameters to be estimated (see code below), which then multiply by it's transpose to impose non-negativity and symmetry. So I suspect this is where I am going wrong with my Eviews model, as everything else seems to be the same, however, I am directly imposing the constraints in Eviews.

My Eviews code is below:

Code: Select all

if @isobject("dlm_infe") =1 then delete dlm_infe endif vector(6) mprior = 0 sym(6,6) vprior = 0 vprior(1,1) = 0.1 vprior(2,2) = 0.1 vprior(3,3) = 0.1 vprior(4,4) = 0.1 vprior(5,5) = 0.1 vprior(6,6) = 0.1 param infe_dlm(1) 0.06 for !i = 2 to 10 param infe_dlm(!i) 0.5 next for !i = 11 to 17 param infe_dlm(!i) -1.5 next for !i = 18 to 23 param infe_dlm(!i) -1 next ' sspace dlm_infe dlm_infe.append @vprior vprior dlm_infe.append @mprior mprior ' Measurment errors dlm_infe.append @ename e1 dlm_infe.append @ename e2 dlm_infe.append @ename e3 dlm_infe.append @ename e4 dlm_infe.append @ename e5 dlm_infe.append @ename e6 dlm_infe.append @ename e7 'State errors dlm_infe.append @ename g1 dlm_infe.append @ename g2 dlm_infe.append @ename g3 ' Measurment equations dlm_infe.append @signal infe_1 = level + ((1-exp(-infe_dlm(1)*40 ))/(infe_dlm(1)*40))*slope+(((1-exp(-infe_dlm(1)*40))/(infe_dlm(1)*40)-exp(infe_dlm(1)*40)))*curv + e1 dlm_infe.append @signal infe_2 = level + ((1-exp(-infe_dlm(1)*1))/(infe_dlm(1)*1))*slope+(((1-exp(-infe_dlm(1)*1))/(infe_dlm(1)*1)-exp(infe_dlm(1)*1)))*curv +e2 dlm_infe.append @signal infe_3 = level + ((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4))*slope+(((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4)-exp(infe_dlm(1)*4)))*curv +e3 dlm_infe.append @signal infe_4 = level + ((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4))*slope+(((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4)-exp(infe_dlm(1)*4)))*curv +e4 dlm_infe.append @signal infe_5 = level + ((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8))*slope+(((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8)-exp(infe_dlm(1)*8)))*curv +e5 dlm_infe.append @signal infe_6 = level + ((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4))*slope+(((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4)-exp(infe_dlm(1)*4)))*curv +e6 dlm_infe.append @signal infe_7 = level + ((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8))*slope+(((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8)-exp(infe_dlm(1)*8)))*curv +e7 ' State equations dlm_infe.append @state level = infe_dlm(2)*level(-1)+infe_dlm(3)*slope(-1)+infe_dlm(4)*curv(-1)+(1-infe_dlm(2))*mean_level(-1)-infe_dlm(3)*mean_slope(-1)-infe_dlm(4)*mean_curv(-1) +g1 dlm_infe.append @state slope = infe_dlm(5)*level(-1)+infe_dlm(6)*slope(-1)+infe_dlm(7)*curv(-1)-infe_dlm(5)*mean_level(-1)+(1-infe_dlm(6))*mean_slope(-1)-infe_dlm(7)*mean_curv(-1) +g2 dlm_infe.append @state curv = infe_dlm(8)*level(-1)+infe_dlm(9)*slope(-1)+infe_dlm(10)*curv(-1)-infe_dlm(8)*mean_level(-1)-infe_dlm(9)*mean_slope(-1)+(1-infe_dlm(10))*mean_curv(-1) +g3 dlm_infe.append @state mean_level = mean_level(-1) dlm_infe.append @state mean_slope = mean_slope(-1) dlm_infe.append @state mean_curv = mean_curv(-1) dlm_infe.append @evar var(e1) = (infe_dlm(11)^2) 'exp(infe_dlm(11)) ' dlm_infe.append @evar var(e2) = (infe_dlm(12)^2) 'exp(infe_dlm(12)) ' dlm_infe.append @evar var(e3) = (infe_dlm(13)^2) 'exp(infe_dlm(13)) ' dlm_infe.append @evar var(e4) = (infe_dlm(14)^2) 'exp(infe_dlm(14))' dlm_infe.append @evar var(e5) = (infe_dlm(15)^2) 'exp(infe_dlm(15)) ' dlm_infe.append @evar var(e6) = (infe_dlm(16)^2) 'exp(infe_dlm(16)) ' dlm_infe.append @evar var(e7) = (infe_dlm(17)^2) 'exp(infe_dlm(17)) ' ' State error variances dlm_infe.append @evar var(g1) = (infe_dlm(18)^2) 'exp(infe_dlm(18)) ' dlm_infe.append @evar var(g2) = (infe_dlm(19)^2) 'exp(infe_dlm(19)) ' dlm_infe.append @evar var(g3) = (infe_dlm(20)^2) 'exp(infe_dlm(20)) ' dlm_infe.append @evar cov(g1,g2) = infe_dlm(21) dlm_infe.append @evar cov(g1,g3) = infe_dlm(22) dlm_infe.append @evar cov(g2,g3) = infe_dlm(23) smpl 1989:3 2020:1 dlm_infe.ml
And my R code (relevant sections, the matrix qq and W). Note, the exph[] vector simply contains the following, c(40, 1,4,4,8,4,8) which I have hard entered above in the eviews code.

Code: Select all

buildNSInf <- function(p){ exph <- exph # Deibold and Li Loadings ff <- c(1,(1-exp(-p[1]*exph[1]))/(p[1]*exph[1]),((1-exp(-p[1]*exph[1]))/(p[1]*exph[1])-exp(-p[1]*exph[1])),0,0,0, 1,(1-exp(-p[1]*exph[2]))/(p[1]*exph[2]),((1-exp(-p[1]*exph[2]))/(p[1]*exph[2])-exp(-p[1]*exph[2])),0,0,0, 1,(1-exp(-p[1]*exph[3]))/(p[1]*exph[3]),((1-exp(-p[1]*exph[3]))/(p[1]*exph[3])-exp(-p[1]*exph[3])),0,0,0, 1,(1-exp(-p[1]*exph[4]))/(p[1]*exph[4]),((1-exp(-p[1]*exph[4]))/(p[1]*exph[4])-exp(-p[1]*exph[4])),0,0,0, 1,(1-exp(-p[1]*exph[5]))/(p[1]*exph[5]),((1-exp(-p[1]*exph[5]))/(p[1]*exph[5])-exp(-p[1]*exph[5])),0,0,0, 1,(1-exp(-p[1]*exph[6]))/(p[1]*exph[6]),((1-exp(-p[1]*exph[6]))/(p[1]*exph[6])-exp(-p[1]*exph[6])),0,0,0, 1,(1-exp(-p[1]*exph[7]))/(p[1]*exph[7]),((1-exp(-p[1]*exph[7]))/(p[1]*exph[7])-exp(-p[1]*exph[7])),0,0,0 ) gg <- c(p[2],p[3],p[4],(1-p[2]),-p[3],-p[4], p[5],p[6],p[7],-p[5],(1-p[6]),-p[7], p[8],p[9],p[10],-p[8],-p[9],(1-p[10]), 0, 0,0,1,0,0, 0, 0,0,0,1,0, 0, 0,0,0,0,1 ) qq <- c(p[11],0,0,0,0,0, p[12],p[13],0,0,0,0, p[14],p[15],p[16],0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0) hh <- c( p[17],0,0,0,0,0,0, 0,p[18],0,0,0,0,0, 0,0,p[19],0,0,0,0, 0,0,0,p[20],0,0,0, 0,0,0,0,p[21],0,0, 0,0,0,0,0,p[22],0, 0,0,0,0,0,0,p[23]) FF1 <- matrix(ff,7,6, byrow = TRUE) GG1 <- matrix(gg, 6, 6, byrow = TRUE) W1 <- matrix(qq,6,6, byrow = TRUE) V1 <- matrix(hh,7,7, byrow = TRUE) return(list( m0 = c(0,0,0,0,0,0), C0 = bdiag(diag(0.1,3),diag(0.1,3)), FF = FF1, GG = GG1, W = W1%*%t(W1), V = V1%*%t(V1) )) } ggp <- rep(0.5,9) wp <- rep(-1,6) vp <- rep(-1.5,7) dat1 <- matrix(as.numeric(unlist(RBA1[,-c(1:2)])),nrow=nrow(RBA1)) LC <- rep(exp(-8),25) UC <- rep(exp(12),25) LC[2:10] <- -Inf UC[2:10] <- Inf NSml <- dlmMLE(dat1, parm =c(lam,ggp,wp,vp) , build = buildNSInf, lower=LC , upper=UC , control = list(trace = 6, REPORT = 5, maxit = 500))
Of course, I can call R from Eviews to run this code (which, by the way is a fantastic application) but I would really like to understand why R's DLM produces something sensible and why I can't recreate this with Eviews. By sensible, my model converges and the the states look reasonable.

I'm not saying DLM is correct, the error here is no-doubt my own, I just want to understand it so I know for next time :)

Thanks

Adam

I am using Eviews 12 and have updated for the latest patch

More details on R's DLM can be found here:
https://cran.r-project.org/web/packages ... es/dlm.pdf

Re: Understanding the difference between Sspace and R's DLM

Posted: Mon Feb 01, 2021 12:39 am
by Elderfield.A
Hi,

I've attached a workfile if it helps - any guidance would be appreciated.

Adam

Re: Understanding the difference between Sspace and R's DLM

Posted: Mon Feb 01, 2021 4:43 pm
by EViews Glenn
Been down a few rabbit holes trying to track this down, but I just noticed that the signal equation specifications in your sspace object don't match the Diebold and Li paper and that they differ from the R specifications. I'm not sure that this is the sole reason for the issues you are seeing, but I believe that the last exponential term should have a negative sign inside the exp function.

For example, you have,

Code: Select all

dlm_infe.append @signal infe_1 = level + ((1-exp(-infe_dlm(1)*40 ))/(infe_dlm(1)*40))*slope+(((1-exp(-infe_dlm(1)*40))/(infe_dlm(1)*40)-exp(infe_dlm(1)*40)))*curv + e1
That specification should, I believe, be

Code: Select all

dlm_infe.append @signal infe_1 = level + ((1-exp(-infe_dlm(1)*40 ))/(infe_dlm(1)*40))*slope+(((1-exp(-infe_dlm(1)*40))/(infe_dlm(1)*40)-exp(-infe_dlm(1)*40)))*curv + e1
Haven't done any additional testing yet, but I thought I'd point this out before I went too much further. Note also that I haven't looked carefully at your state equation specifications yet.

Re: Understanding the difference between Sspace and R's DLM

Posted: Tue Feb 02, 2021 3:03 am
by Elderfield.A
Thanks Glenn, indeed an error. In regards to the state equations, I have specified this model a little differently to how I have seen others on this forum specify this model. This is because I originally estimated the model using R's DLM package, which doesn't allow an intercept in the state equation, so I have moved the intercepts into the state vector - hopefully I've done this correctly.

Re: Understanding the difference between Sspace and R's DLM

Posted: Tue Feb 02, 2021 12:30 pm
by EViews Glenn
Took a quick look at the state specs. Just double checking that you did want to extend Diebold and Li by specifying the states as a VAR(2).

Re: Understanding the difference between Sspace and R's DLM

Posted: Tue Feb 02, 2021 2:02 pm
by Elderfield.A
I don't think that is the intention, no.

The original specification was:

Y = F*X(t) + E(t)
(X(t)-U) = G*(X(t-1)-U) + W(t)

In R, the state space model doesn't allow for an intercept in the state equation (which the above has) so to get around that I have moved the intercept into the state vector:

X(t) = U +G*X(t) -G*U +W(t)
X(t) = (I-G)*U + G*X(t-1) +W(t)

So now the state vector becomes

[level, slope, curv, U(level) , U(slope), U(curv)]


The the first three state variables follow an AR(1) process and the intercepts (what I have called U) are non-time varying state variables.


That was the intention anyway, maybe it is not the correct way to approach the problem?

Re: Understanding the difference between Sspace and R's DLM

Posted: Wed Feb 03, 2021 1:43 pm
by EViews Glenn
Yes, what you are doing makes perfect sense. I wasn't quite sure what the "mean_" variables were doing since I hadn't really looked at the original specification, and think I just mushed all of the variables together in my mind. Sorry to worry you.

Re: Understanding the difference between Sspace and R's DLM

Posted: Fri May 28, 2021 10:59 pm
by Elderfield.A
Hi,

Just wondering if there has been any further developments on this? I have been playing about with thing, trying alternative measurement equations for instance, I still get the singular matrix error.

I also noticed that if I comment out the state covariance commands, the singular matrix error doesn't appear, but unsurprisingly the model is junk.

Be good to know what is happening here.

Thanks

Adam

Re: Understanding the difference between Sspace and R's DLM

Posted: Mon May 31, 2021 3:08 pm
by Elderfield.A
I've made a bit of progress on this, my starting parameters were the causing the issue. When I change these, I can get the model to estimate, not converge but at least estimate. So I think that is a good start!

I guess that puts this one to bed.