1C ----------------------------------------------------------------------
2C HF computes the loglikelihood, the innovations, and the Hamilton (1989)
3C Smoother for a Markov Switching VAR(1)
4C Developed by A.Rossi, C.Planas and G.Fiorentini
5C
6C OUTPUT: LLILIKE:  log-likelihood
7C         INN:      innovations
8C         SSMOOTH:  P(s(t)|y^T), t=1,2,...,T
9C
10C Copyright (C) 2010-2014 European Commission
11C
12C This file is part of Program DMM
13C
14C DMM is free software developed at the Joint Research Centre of the
15C European Commission: you can redistribute it and/or modify it under
16C the terms of the GNU General Public License as published by
17C the Free Software Foundation, either version 3 of the License, or
18C (at your option) any later version.
19C
20C DMM is distributed in the hope that it will be useful,
21C but WITHOUT ANY WARRANTY; without even the implied warranty of
22C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23C GNU General Public License for more details.
24C
25C You should have received a copy of the GNU General Public License
26C along with DMM.  If not, see <http://www.gnu.org/licenses/>.
27C ----------------------------------------------------------------------
28	SUBROUTINE HF(nobs,nx,nk,nz,nu,ns,nv,np,psi,ismoo,yk,IYK,INFOS,
29     1              c,a,F,R,SSMOOTH,INN,LLIKE)
30
31C INPUT
32	INTEGER nobs,nx,nk,nz,nu,nv,np,ns(6),ismoo,IYK(nobs,nx+1),INFOS(9,6)
33	DOUBLE PRECISION yk(nobs,nx+nz),c(nx,max(1,nz),ns(1)),
34     1 a(nx,ns(4)),F(nx,nx,ns(5)),R(nx,nu,ns(6)),psi(max(1,np))
35
36C OUTPUT
37	DOUBLE PRECISION SSMOOTH(nobs,nk),INN(nobs,nx),LLIKE(nobs)
38
39C LOCALS
40	INTEGER inobs,inx,I,J,K,IMAX(1),IS(6),SEQ(1)
41	DOUBLE PRECISION,ALLOCATABLE:: ZZ(:),gam(:),mu(:),SIG(:,:),FILT(:,:),
42     1 P(:,:),PE(:),PP1(:,:),PP2(:,:),PP3(:,:),PP4(:,:),PP5(:,:),
43     1 PP6(:,:)
44
45      DOUBLE PRECISION logmvnpdf,mvnpdf,norm,Lmax
46      ALLOCATE(PP1(INFOS(8,1),INFOS(8,1)),PP2(INFOS(8,2),INFOS(8,2)),
47     1 PP3(INFOS(8,3),INFOS(8,3)),PP4(INFOS(8,4),INFOS(8,4)),
48     1 PP5(INFOS(8,5),INFOS(8,5)),PP6(INFOS(8,6),INFOS(8,6)))
49	ALLOCATE(ZZ(nk),gam(nk),mu(nx),SIG(nx,nx),FILT(nobs,nk),
50     1 P(nk,nk),PE(nk))
51
52      FILT(:,:) = 0.D0
53	LLIKE(:)  = 0.D0
54      CALL designz(nv,np,psi,INFOS,PP1,PP2,PP3,PP4,PP5,PP6)
55      CALL pprod(nv,nk,INFOS,PP1,PP2,PP3,PP4,PP5,PP6,P)
56C Initial condition (stationary MS-VAR(1))
57      CALL ergodic(nk,P,PE)
58      inx = IYK(1,nx+1)
59      DO J = 1,inx
60	 mu(J) = a(IYK(1,J),IS(4))+
61     #       + SUM(F(IYK(1,J),IYK(1,1:inx),IS(5))
62     #       * yk(1,IYK(1,1:inx)))
63     #       + SUM(c(IYK(1,J),1:nz,IS(1))*yk(1,nx+1:nx+nz))
64      ENDDO
65C SIG = R*R'
66      DO  K=1,inx
67       SIG(K,K) = SUM(R(IYK(1,K),1:nu,IS(6))
68     #          *     R(IYK(1,K),1:nu,IS(6)))
69	 DO  J=1,K-1
70        SIG(K,J) = SUM(R(IYK(1,K),1:nu,IS(6))
71     #           *     R(IYK(1,J),1:nu,IS(6)))
72        SIG(J,K) = SIG(K,J)
73       ENDDO
74      ENDDO
75      DO I = 1,nk
76       gam(I) = PE(I)*mvnpdf(yk(1,IYK(1,1:inx)),mu(1:inx),
77     #                       SIG(1:inx,1:inx),inx)
78      ENDDO
79      LLIKE(1) = dlog(sum(gam(1:nk)))
80      FILT(1,1:nk-1) = gam(1:nk-1)/sum(gam(1:nk))
81      FILT(1,nk) = 1.D0-sum(FILT(1,1:nk-1))
82
83C ----------------------------------------------------------
84C Filtering Z(t|t)=P*Z(t-1|t-1) (.*) F(j) / SUM of numerator
85C ----------------------------------------------------------
86	DO 100 inobs = 2,nobs
87       inx = IYK(inobs,nx+1)
88	 DO I =1,nk
89        CALL int2seq(I,nv,INFOS,SEQ,IS)
90	  ZZ(I) = SUM(P(I,1:nk)*FILT(inobs-1,1:nk))
91c y(t) = c(t)z(t) + x(t)
92C x(t) = a(t)     + F(t)x(t-1) + R(t)u(t)
93        DO J = 1,inx
94	   mu(J) = a(IYK(inobs,J),IS(4))+
95     #         + SUM(F(IYK(inobs,J),IYK(inobs,1:inx),IS(5))
96     #         * yk(inobs-1,IYK(inobs-1,1:inx)))
97     #         + SUM(c(IYK(inobs,J),1:nz,IS(1))*yk(inobs,nx+1:nx+nz))
98        ENDDO
99C SIG = R*R'
100        DO  K=1,inx
101         SIG(K,K) = SUM(R(IYK(inobs,K),1:nu,IS(6))
102     #            *     R(IYK(inobs,K),1:nu,IS(6)))
103	   DO  J=1,K-1
104          SIG(K,J) = SUM(R(IYK(inobs,K),1:nu,IS(6))
105     #             *     R(IYK(inobs,J),1:nu,IS(6)))
106          SIG(J,K) = SIG(K,J)
107         ENDDO
108        ENDDO
109        gam(I) = logmvnpdf(yk(inobs,IYK(inobs,1:inx)),mu(1:inx),
110     #                     SIG(1:inx,1:inx),inx) ! log
111       ENDDO
112C ---------------------------------------------------
113C Compute the log-likelihood and Normalise the filter
114C ---------------------------------------------------
115	 IMAX = MAXLOC(gam(1:nk))
116	 Lmax = gam(IMAX(1))
117       gam(:) = dexp(gam(:)-Lmax)
118       FILT(inobs,1:nk) = ZZ(1:nk)*gam(1:nk)
119	 norm = SUM(FILT(inobs,:))
120       FILT(inobs,:) = FILT(inobs,:)/norm
121	 LLIKE(inobs)  = DLOG(norm) + Lmax
122100   CONTINUE
123
124C ------------------------------------------------------------------------------------
125C Hamilton smoother for a MS-VAR(1)
126C Z(t|T): Hamilton (94), pp 694
127C Innovations:
128C INN(t) = y(y)-SUM(S(t),S(t-1)) P(S(t)|S(t-1)*P(S(t-1)|x^(t-1))*E(x(t)|S(t),x^(t-1))
129C ------------------------------------------------------------------------------------
130      IF (ismoo.EQ.1) THEN
131       SSMOOTH(nobs,:) = FILT(nobs,:)
132	 DO inobs = nobs-1,1,-1
133	  DO J=1,nk
134	   gam(J) = SUM(P(J,1:nk)*FILT(inobs,1:nk))
135        ENDDO
136	  DO J=1,nk
137	   ZZ(J) = 1.D0
138	   IF (gam(J).GT.1.D-13) ZZ(J) = SSMOOTH(inobs+1,J)/gam(J)
139        ENDDO
140	  DO J=1,nk
141	   gam(J) = SUM(P(1:nk,J)*ZZ(1:nk))
142        ENDDO
143	  SSMOOTH(inobs,1:nk) = FILT(inobs,1:nk)*gam(1:nk)
144       ENDDO
145       INN(:,:) = 0.D0
146       DO inobs = 2,nobs
147        inx = IYK(inobs,nx+1)
148	  DO I=1,nk
149         CALL int2seq(I,nv,INFOS,SEQ,IS)
150         DO K = 1,inx
151	    mu(K) = a(IYK(inobs,K),IS(4))+
152     #          + SUM(F(IYK(inobs,K),IYK(inobs,1:inx),IS(5))
153     #          * yk(inobs-1,IYK(inobs-1,1:inx)))
154     #          + SUM(c(IYK(inobs,K),1:nz,IS(1))*yk(inobs,nx+1:nx+nz))
155         ENDDO
156         DO J=1,nk
157          INN(inobs,IYK(inobs,1:inx)) = INN(inobs,IYK(inobs,1:inx))
158     1                                + mu(1:inx)*P(I,J)*FILT(inobs-1,J)
159         ENDDO
160        ENDDO
161        INN(inobs,IYK(inobs,1:inx)) = yk(inobs,IYK(inobs,1:inx))
162     1                              - INN(inobs,IYK(inobs,1:inx))
163       ENDDO
164      ENDIF
165
166      DEALLOCATE(gam,mu,SIG)
167	RETURN
168	END
169