/* Version: 7/9/2008 made by Wen-Jen Tsay, The Institute of Economics, Academia Sinica, Taiwan */
/* Please acknowledge the copyright of this code */

new;

library maxlik, pgraph;
graphset;

#include maxlik.ext;
maxset;

t_begin=hsec;


re = 1;
num = re;




//fname1 = "elec_bernd_sea.xls"; 
fname1 = "elec_bernd.xls";
rname1 = "a1:e3776"; 
shname1 = 1;   vls1 = reshape(error(0),9,1);
residuals = xlsReadM(fname1, rname1, shname1, vls1[1]);  residuals = packr(residuals);

jj = 1; do while jj <= 5; 

dataa = residuals[.,jj]; 
    
aah = 1402|1508|1503|1402|1574;

t1 = rows(dataa);
t2 = t1-aah[jj]+1;
t3 = t1-t2+1;
hh = 20;

MSresid = zeros(t3,t2-hh); 

tt = 1; do while tt <= t2-hh; 
    
data = dataa[tt:(t1-t2+tt)];

d1 = 0.45;
d2 = 0.33;
p11 = 0.93;
p22 = 0.8;
sigmasq1 = (.2)^2;
sigmasq2 = (1.64)^2;
mu1 = 0.5;
mu2 = 1.4;



rho1 = 0.2;
theta1 = -0.3;


wdata = data;



estvi = {};
stateest = {};


k=1;do until k>re;


_max_Algorithm = 2; /* algorithm BFGS = 2 */
_max_CovPar = 1; /* 1 for Hessian, 2 for Outer Product */
_max_LineSearch = 2; /* 2 is much faster than 1 */
_max_GrdTol = 1e-6;
_max_MaxIters = 5;
__output = 0;


nrep = 0 $+ " rep=" $+ ftocv(k,1,0);




truevi =d1|d2|p11|p22|
sqrt(sigmasq1)|
sqrt(sigmasq2)|
mu1|mu2|
rho1|theta1
;


startvi =


d1|d2|
ln(p11/(1-p11))|ln(p22/(1-p22))|
ln(sqrt(sigmasq1))|
ln(sqrt(sigmasq2))|
mu1|mu2|
rho1|theta1
;



output file = msarfima.out reset;
output on;
screen on;
format /rd 8,4;


__title= "MS ARFIMA(1,d,1) Model  "$+nrep;
{bh,fmin,g,cov,retcode } = maxlik(wdata[.,k],0,&lnvi,startvi);
call maxprt(bh,fmin,g,cov,retcode);


estvi1 =

bh[1:2]|
exp(bh[3])/(exp(bh[3])+1)|
exp(bh[4])/(exp(bh[4])+1)|
exp(bh[5])|
exp(bh[6])|
bh[7]|bh[8]|
bh[9]|bh[10]

;








estvi = estvi|estvi1';

print k;

k=k+1;endo;




output file = msarfima.out on;
output on;
screen on;
format /rd 8,4;


_max_MaxIters = 0;

__title= "MS ARFIMA(1,d,1) Model  "$+nrep;
{bh,fmin,g,cov,retcode } = maxlik(wdata,0,&lnviest1,estvi);
call maxprt(bh,fmin,g,cov,retcode);
out1 = bh;






output file = msarfima.out on;
output on;
screen off;
format /rd 8,4;



date1 = seqa(1,1,rows(wdata));
date2 = lnviest(out1,wdata);
date3 = date1~date2;
date3;


output file = state11 reset;
output on;
screen off;
format /rd 8,4;

date3;



output file = msarfima.res reset;
output on;
screen off;
format /rd 8,4;


residu = lnviest2(out1,wdata);

MSresid[.,tt] = residu;

tt = tt + 1;
 
endo;

vls = reshape(error(0),9,1);
      

oret = xlsWriteM(MSresid,"MSARFIMA_residual.xlsx","a1",jj,vls[4]);
   
jj = jj + 1;
 
endo;


output off;

t_used=hsec-t_begin;
;
"Time used";;t_used/100;
;




proc lnvi(b,w);
local size,d1hat,d2hat,sigma1hat,sigma2hat,
mu1hat,mu2hat,mu,
sigma,coefd1,coefd2,coeff,
p11hat,p22hat,
rho1hat,
theta1hat,
tranmax,
eta1,eta,xihat,ehat,zhat,zsigmahat,den1,den2,
path1,path2,lnlk1,lnlk2,
j,lnlipath1,lnlipath2,lnlk;



size = rows(w);


d1hat = b[1];
d2hat = b[2];
p11hat = exp(b[3])/(exp(b[3])+1);
p22hat = exp(b[4])/(exp(b[4])+1);

sigma1hat =  exp(b[5]);
sigma2hat =  exp(b[6]);


mu1hat = b[7];
mu2hat = b[8];
rho1hat = b[9];
theta1hat = b[10];

tranmax =
(p11hat~(1-p22hat))|
((1-p11hat)~p22hat);



mu = mu1hat|mu2hat;
sigma = sigma1hat|sigma2hat;


coefd1 = cumprodc(seqa(d1hat,1,size-1)./seqa(1,1,size-1));
coefd2 = cumprodc(seqa(d2hat,1,size-1)./seqa(1,1,size-1));
coeff = coefd1~coefd2;



/* muhat is to store the selected path of state: from date 2 */

eta1 = zeros(4,size); /* row 1:2 for path1, 3:4 for path2 */

eta = zeros(4,size);  /* same as above */
xihat = zeros(4,size);/* same as above */
ehat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
/* to keep the long memory part, not iid */
zsigmahat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
zhat = zeros(2,size); /* row 1, for path1, row 2 for path2 */




lnlk1 = zeros(1,size); /* likelihood for date t for path1*/
lnlk2 = zeros(1,size);

path1 = zeros(size,2*size); /* so save the path arriving 1, at time t */
path2 = zeros(size,2*size);


eta1[.,1] = 0|0|0|0;
eta[.,1] = 0|0|0|0;
xihat[.,1] = 0|0|0|0;

path1[1,1:2] = 1~0;
path2[1,1:2] = 0~1;


zsigmahat[.,1] = (w[1] - path1[1,1:2]*mu)|
                 (w[1] - path2[1,1:2]*mu);


zhat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);

ehat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);


den1 = exp(-( (ehat[1,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));
den2 = exp(-( (ehat[2,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));


lnlk1[1,1] = ln(den1 * ((1-p22hat)/(2-p11hat-p22hat))+1e-50);
lnlk2[1,1] = ln(den2 * ((1-p11hat)/(2-p11hat-p22hat))+1e-50);






j = 2;do until j>size;


eta1[.,j] =


exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1] 
            - theta1hat*sigma1hat*ehat[1,j-1]
            
      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]
 


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))

;


xihat[.,j] =
         ( (tranmax')* path1[j-1,1+(j-2)*2:(j-1)*2]')|
         ( (tranmax')* path2[j-1,1+(j-2)*2:(j-1)*2]')

;


eta[.,j] = eta1[.,j] .* xihat[.,j];


if ln(eta[1,j]+1e-50) +lnlk1[1,j-1] > ln(eta[2,j]+1e-50) + lnlk2[1,j-1];
lnlk1[1,j] = ln(eta[1,j]+1e-50)+lnlk1[1,j-1];

path1[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);

zsigmahat[1,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1]
            - theta1hat*sigma1hat*ehat[1,j-1]

        )/sigma1hat
;


else;
lnlk1[1,j] = ln(eta[2,j]+1e-50)+lnlk2[1,j-1];


path1[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);



zsigmahat[1,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

        )/sigma1hat
;



endif;



if ln(eta[3,j]+1e-50) +lnlk1[1,j-1] > ln(eta[4,j]+1e-50) + lnlk2[1,j-1];
lnlk2[1,j] = ln(eta[3,j]+1e-50)+lnlk1[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);



zsigmahat[2,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]



        )/sigma2hat
;




else;

lnlk2[1,j] = ln(eta[4,j]+1e-50)+lnlk2[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);




zsigmahat[2,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]





        )/sigma2hat
;




endif;




j=j+1;endo;





lnlipath1 = lnlk1';
lnlipath2 = lnlk2';


if (lnlipath1[size,1]) > (lnlipath2[size,1]);
lnlk = lnlipath1[size,1];

else;
lnlk = lnlipath2[size,1];
endif;


retp(lnlk);
endp;





proc lnviest1(b,w);
local size,d1hat,d2hat,sigma1hat,sigma2hat,
mu1hat,mu2hat,mu,
sigma,coefd1,coefd2,coeff,
p11hat,p22hat,
rho1hat,
theta1hat,
tranmax,
eta1,eta,xihat,ehat,zhat,zsigmahat,den1,den2,
path1,path2,lnlk1,lnlk2,
j,lnlipath1,lnlipath2,lnlk;



size = rows(w);


d1hat = b[1];
d2hat = b[2];
p11hat = b[3];
p22hat = b[4];

sigma1hat =  b[5];
sigma2hat =  b[6];


mu1hat = b[7];
mu2hat = b[8];
rho1hat = b[9];
theta1hat = b[10];


tranmax =
(p11hat~(1-p22hat))|
((1-p11hat)~p22hat);



mu = mu1hat|mu2hat;
sigma = sigma1hat|sigma2hat;


coefd1 = cumprodc(seqa(d1hat,1,size-1)./seqa(1,1,size-1));
coefd2 = cumprodc(seqa(d2hat,1,size-1)./seqa(1,1,size-1));
coeff = coefd1~coefd2;







/* muhat is to store the selected path of state: from date 2 */

eta1 = zeros(4,size); /* row 1:2 for path1, 3:4 for path2 */

eta = zeros(4,size);  /* same as above */
xihat = zeros(4,size);/* same as above */
ehat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
/* to keep the long memory part, not iid */
zsigmahat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
zhat = zeros(2,size); /* row 1, for path1, row 2 for path2 */




lnlk1 = zeros(1,size); /* likelihood for date t for path1*/
lnlk2 = zeros(1,size);

path1 = zeros(size,2*size); /* so save the path arriving 1, at time t */
path2 = zeros(size,2*size);


eta1[.,1] = 0|0|0|0;
eta[.,1] = 0|0|0|0;
xihat[.,1] = 0|0|0|0;

path1[1,1:2] = 1~0;
path2[1,1:2] = 0~1;


zsigmahat[.,1] = (w[1] - path1[1,1:2]*mu)|
                 (w[1] - path2[1,1:2]*mu);


zhat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);

ehat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);


den1 = exp(-( (ehat[1,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));
den2 = exp(-( (ehat[2,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));


lnlk1[1,1] = ln(den1 * ((1-p22hat)/(2-p11hat-p22hat))+1e-50);
lnlk2[1,1] = ln(den2 * ((1-p11hat)/(2-p11hat-p22hat))+1e-50);






j = 2;do until j>size;



eta1[.,j] =


exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1] 
            - theta1hat*sigma1hat*ehat[1,j-1]
            
      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]
 


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))

;


xihat[.,j] =
         ( (tranmax')* path1[j-1,1+(j-2)*2:(j-1)*2]')|
         ( (tranmax')* path2[j-1,1+(j-2)*2:(j-1)*2]')

;


eta[.,j] = eta1[.,j] .* xihat[.,j];


if ln(eta[1,j]+1e-50) +lnlk1[1,j-1] > ln(eta[2,j]+1e-50) + lnlk2[1,j-1];
lnlk1[1,j] = ln(eta[1,j]+1e-50)+lnlk1[1,j-1];

path1[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);

zsigmahat[1,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1]
            - theta1hat*sigma1hat*ehat[1,j-1]

        )/sigma1hat
;


else;
lnlk1[1,j] = ln(eta[2,j]+1e-50)+lnlk2[1,j-1];


path1[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);



zsigmahat[1,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

        )/sigma1hat
;



endif;



if ln(eta[3,j]+1e-50) +lnlk1[1,j-1] > ln(eta[4,j]+1e-50) + lnlk2[1,j-1];
lnlk2[1,j] = ln(eta[3,j]+1e-50)+lnlk1[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);



zsigmahat[2,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]



        )/sigma2hat
;




else;

lnlk2[1,j] = ln(eta[4,j]+1e-50)+lnlk2[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);




zsigmahat[2,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]





        )/sigma2hat
;




endif;




j=j+1;endo;





lnlipath1 = lnlk1';
lnlipath2 = lnlk2';


if (lnlipath1[size,1]) > (lnlipath2[size,1]);
lnlk = lnlipath1[size,1];

else;
lnlk = lnlipath2[size,1];
endif;


retp(lnlk);
endp;












proc lnviest(b,w);
local size,d1hat,d2hat,sigma1hat,sigma2hat,
mu1hat,mu2hat,mu,
sigma,coefd1,coefd2,coeff,
p11hat,p22hat,
rho1hat,
theta1hat,
tranmax,
eta1,eta,xihat,ehat,zhat,zsigmahat,den1,den2,
path1,path2,lnlk1,lnlk2,
j,lnlipath1,lnlipath2,lnlk;



size = rows(w);


d1hat = b[1];
d2hat = b[2];
p11hat = b[3];
p22hat = b[4];

sigma1hat =  b[5];
sigma2hat =  b[6];


mu1hat = b[7];
mu2hat = b[8];
rho1hat = b[9];
theta1hat = b[10];


tranmax =
(p11hat~(1-p22hat))|
((1-p11hat)~p22hat);



mu = mu1hat|mu2hat;
sigma = sigma1hat|sigma2hat;


coefd1 = cumprodc(seqa(d1hat,1,size-1)./seqa(1,1,size-1));
coefd2 = cumprodc(seqa(d2hat,1,size-1)./seqa(1,1,size-1));
coeff = coefd1~coefd2;







/* muhat is to store the selected path of state: from date 2 */

eta1 = zeros(4,size); /* row 1:2 for path1, 3:4 for path2 */

eta = zeros(4,size);  /* same as above */
xihat = zeros(4,size);/* same as above */
ehat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
/* to keep the long memory part, not iid */
zsigmahat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
zhat = zeros(2,size); /* row 1, for path1, row 2 for path2 */




lnlk1 = zeros(1,size); /* likelihood for date t for path1*/
lnlk2 = zeros(1,size);

path1 = zeros(size,2*size); /* so save the path arriving 1, at time t */
path2 = zeros(size,2*size);


eta1[.,1] = 0|0|0|0;
eta[.,1] = 0|0|0|0;
xihat[.,1] = 0|0|0|0;

path1[1,1:2] = 1~0;
path2[1,1:2] = 0~1;


zsigmahat[.,1] = (w[1] - path1[1,1:2]*mu)|
                 (w[1] - path2[1,1:2]*mu);


zhat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);

ehat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);


den1 = exp(-( (ehat[1,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));
den2 = exp(-( (ehat[2,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));


lnlk1[1,1] = ln(den1 * ((1-p22hat)/(2-p11hat-p22hat))+1e-50);
lnlk2[1,1] = ln(den2 * ((1-p11hat)/(2-p11hat-p22hat))+1e-50);






j = 2;do until j>size;


eta1[.,j] =


exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1] 
            - theta1hat*sigma1hat*ehat[1,j-1]
            
      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]
 


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))

;


xihat[.,j] =
         ( (tranmax')* path1[j-1,1+(j-2)*2:(j-1)*2]')|
         ( (tranmax')* path2[j-1,1+(j-2)*2:(j-1)*2]')

;


eta[.,j] = eta1[.,j] .* xihat[.,j];


if ln(eta[1,j]+1e-50) +lnlk1[1,j-1] > ln(eta[2,j]+1e-50) + lnlk2[1,j-1];
lnlk1[1,j] = ln(eta[1,j]+1e-50)+lnlk1[1,j-1];

path1[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);

zsigmahat[1,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1]
            - theta1hat*sigma1hat*ehat[1,j-1]

        )/sigma1hat
;


else;
lnlk1[1,j] = ln(eta[2,j]+1e-50)+lnlk2[1,j-1];


path1[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);



zsigmahat[1,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

        )/sigma1hat
;



endif;



if ln(eta[3,j]+1e-50) +lnlk1[1,j-1] > ln(eta[4,j]+1e-50) + lnlk2[1,j-1];
lnlk2[1,j] = ln(eta[3,j]+1e-50)+lnlk1[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);



zsigmahat[2,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]



        )/sigma2hat
;




else;

lnlk2[1,j] = ln(eta[4,j]+1e-50)+lnlk2[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);




zsigmahat[2,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]





        )/sigma2hat
;




endif;




j=j+1;endo;







lnlipath1 = lnlk1';
lnlipath2 = lnlk2';




if (lnlipath1[size,1]) > (lnlipath2[size,1]);
lnlk = path1[.,1+(size-1)*2:(size)*2];



else;

lnlk = path2[.,1+(size-1)*2:(size)*2];

endif;


retp(lnlk);
endp;






proc lnviest2(b,w);
local size,d1hat,d2hat,sigma1hat,sigma2hat,
mu1hat,mu2hat,mu,
sigma,coefd1,coefd2,coeff,
p11hat,p22hat,
rho1hat,
theta1hat,
tranmax,
eta1,eta,xihat,ehat,zhat,zsigmahat,den1,den2,
path1,path2,lnlk1,lnlk2,
j,lnlipath1,lnlipath2,lnlk;



size = rows(w);


d1hat = b[1];
d2hat = b[2];
p11hat = b[3];
p22hat = b[4];

sigma1hat =  b[5];
sigma2hat =  b[6];


mu1hat = b[7];
mu2hat = b[8];
rho1hat = b[9];
theta1hat = b[10];

tranmax =
(p11hat~(1-p22hat))|
((1-p11hat)~p22hat);



mu = mu1hat|mu2hat;
sigma = sigma1hat|sigma2hat;


coefd1 = cumprodc(seqa(d1hat,1,size-1)./seqa(1,1,size-1));
coefd2 = cumprodc(seqa(d2hat,1,size-1)./seqa(1,1,size-1));
coeff = coefd1~coefd2;







/* muhat is to store the selected path of state: from date 2 */

eta1 = zeros(4,size); /* row 1:2 for path1, 3:4 for path2 */

eta = zeros(4,size);  /* same as above */
xihat = zeros(4,size);/* same as above */
ehat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
/* to keep the long memory part, not iid */
zsigmahat = zeros(2,size); /* row 1, for path1, row 2 for path2 */
zhat = zeros(2,size); /* row 1, for path1, row 2 for path2 */




lnlk1 = zeros(1,size); /* likelihood for date t for path1*/
lnlk2 = zeros(1,size);

path1 = zeros(size,2*size); /* so save the path arriving 1, at time t */
path2 = zeros(size,2*size);


eta1[.,1] = 0|0|0|0;
eta[.,1] = 0|0|0|0;
xihat[.,1] = 0|0|0|0;

path1[1,1:2] = 1~0;
path2[1,1:2] = 0~1;


zsigmahat[.,1] = (w[1] - path1[1,1:2]*mu)|
                 (w[1] - path2[1,1:2]*mu);


zhat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);

ehat[.,1] = (w[1] - path1[1,1:2]*mu)/(sigma1hat)|
            (w[1] - path2[1,1:2]*mu)/(sigma2hat);


den1 = exp(-( (ehat[1,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));
den2 = exp(-( (ehat[2,1])^(2) )/(2+1e-50)
          )/(sqrt(2*pi));


lnlk1[1,1] = ln(den1 * ((1-p22hat)/(2-p11hat-p22hat))+1e-50);
lnlk2[1,1] = ln(den2 * ((1-p11hat)/(2-p11hat-p22hat))+1e-50);






j = 2;do until j>size;


eta1[.,j] =


exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1] 
            - theta1hat*sigma1hat*ehat[1,j-1]
            
      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

      )^(2))/(2*sigma1hat*sigma1hat+1e-50)
   )/(sqrt(2*pi*sigma1hat*sigma1hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]
 


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))|
exp(-((
         w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]


      )^(2))/(2*sigma2hat*sigma2hat+1e-50)
   )/(sqrt(2*pi*sigma2hat*sigma2hat))

;


xihat[.,j] =
         ( (tranmax')* path1[j-1,1+(j-2)*2:(j-1)*2]')|
         ( (tranmax')* path2[j-1,1+(j-2)*2:(j-1)*2]')

;


eta[.,j] = eta1[.,j] .* xihat[.,j];


if ln(eta[1,j]+1e-50) +lnlk1[1,j-1] > ln(eta[2,j]+1e-50) + lnlk2[1,j-1];
lnlk1[1,j] = ln(eta[1,j]+1e-50)+lnlk1[1,j-1];

path1[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);

zsigmahat[1,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma1hat*zhat[1,j-1]
            - theta1hat*sigma1hat*ehat[1,j-1]

        )/sigma1hat
;


else;
lnlk1[1,j] = ln(eta[2,j]+1e-50)+lnlk2[1,j-1];


path1[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(1~0);



zsigmahat[1,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[1,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[1,j]/(sigma1hat));

ehat[1,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path1[1,1:2]*mu -
               (coeff[1:j-1,.]*(path1[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma1hat*zhat[2,j-1]
            - theta1hat*sigma1hat*ehat[2,j-1]

        )/sigma1hat
;



endif;



if ln(eta[3,j]+1e-50) +lnlk1[1,j-1] > ln(eta[4,j]+1e-50) + lnlk2[1,j-1];
lnlk2[1,j] = ln(eta[3,j]+1e-50)+lnlk1[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path1[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);



zsigmahat[2,1:j] =



                 zsigmahat[1,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[1,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[1,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[1,1:j-1]')
            - rho1hat*sigma2hat*zhat[1,j-1]
            - theta1hat*sigma2hat*ehat[1,j-1]



        )/sigma2hat
;




else;

lnlk2[1,j] = ln(eta[4,j]+1e-50)+lnlk2[1,j-1];


path2[1:j,1+(j-1)*2:(j)*2] =
path2[1:j-1,1+(j-2)*2:(j-1)*2]|(0~1);




zsigmahat[2,1:j] =



                 zsigmahat[2,1:j-1]~
                     ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
          )
          ;

zhat[2,1:j] =
                 zhat[2,1:j-1]~(zsigmahat[2,j]/(sigma2hat));

ehat[2,1:j] =


                 ehat[2,1:j-1]~
        ( w[j] - path2[1,1:2]*mu -
               (coeff[1:j-1,.]*(path2[1,1:2]'))'*rev(zsigmahat[2,1:j-1]')
            - rho1hat*sigma2hat*zhat[2,j-1]
            - theta1hat*sigma2hat*ehat[2,j-1]





        )/sigma2hat
;




endif;




j=j+1;endo;







lnlipath1 = lnlk1';
lnlipath2 = lnlk2';








if (lnlipath1[size,1]) > (lnlipath2[size,1]);
lnlk = ehat[1,.]';



else;

lnlk = ehat[2,.]';

endif;


retp(lnlk);
endp;







end;
