diff --git a/CFiles/Copy of kalman.c b/CFiles/Copy of kalman.c deleted file mode 100755 index b53d44e67f6162fcc07843849c030ab5e2c0751f..0000000000000000000000000000000000000000 --- a/CFiles/Copy of kalman.c +++ /dev/null @@ -1,2751 +0,0 @@ -/*=============================================================================================================== - * Check $$$ for important notes. - * Check <<>> for updating DW's new switch code or questions for DW. - * - * kalcvf_urw(): the Kalman filter forward prediction specialized for only a univariate random walk (urw) process. - * - * State space model is defined as follows: - * z(t+1) = z(t)+eta(t) (state or transition equation) - * y(t) = x(t)'*z(t)+eps(t) (observation or measurement equation) - * where for this function, eta and eps must be uncorrelated; y(t) must be 1-by-1. Note that - * x(t): k-by-1; - * z(t): k-by-1; - * eps(t): 1-by-1 and ~ N(0, sigma^2); - * eta(t): ~ N(0, V) where V is a k-by-k covariance matrix. - * - * - * Written by Tao Zha, May 2004. - * Revised, May 2008; -=================================================================================================================*/ - -/** -//=== For debugging purpose. -if (1) -{ - double t_loglht; - - t_loglht = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, " %10.5f\n", t_loglht); - - fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - - fprintf(FPTR_DEBUG, "\n wP0_dv:\n"); - WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "\n Vt_dc->C[sti_v=%d]:\n", sti_v); - WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - - fflush(FPTR_DEBUG); -} -/**/ - - -#include "kalman.h" - - -static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); -static int Updatekalfilms_1stapp(int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - -TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv) //, int storeZ, int storeV) -{ - int _i; - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - //--- - TSkalcvfurw *kalcvfurw_ps = tzMalloc(1, TSkalcvfurw); - - - kalcvfurw_ps->indx_tvsigmasq = tv; - kalcvfurw_ps->fss = T; - kalcvfurw_ps->kx = k; - - //=== - kalcvfurw_ps->V_dm = CreateMatrix_lf(k, k); - kalcvfurw_ps->ylhtran_dv = CreateVector_lf(T); - kalcvfurw_ps->Xrhtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->z10_dv = CreateVector_lf(k); - kalcvfurw_ps->P10_dm = CreateMatrix_lf(k, k); - - kalcvfurw_ps->zupdate_dv = CreateVector_lf(k); - kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->ylhtranpred_dv = CreateVector_lf(T); - // - rows_iv = CreateVector_int(T); - cols_iv = CreateVector_int(T); - for (_i=T-1; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // if (!storeZ) kalcvfurw_ps->Zpredtran_dm = (TSdmatrix *)NULL; - // else kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - // if (!storeV) kalcvfurw_ps->Ppred_dc = (TSdcell *)NULL; - // else { - // rows_iv = CreateVector_int(T); - // cols_iv = CreateVector_int(T); - // for (_i=T; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - // kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // } - - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - return (kalcvfurw_ps); -} - -TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps) -{ - if (kalcvfurw_ps) { - DestroyMatrix_lf(kalcvfurw_ps->V_dm); - DestroyVector_lf(kalcvfurw_ps->ylhtran_dv); - DestroyMatrix_lf(kalcvfurw_ps->Xrhtran_dm); - DestroyVector_lf(kalcvfurw_ps->z10_dv); - DestroyMatrix_lf(kalcvfurw_ps->P10_dm); - - DestroyVector_lf(kalcvfurw_ps->zupdate_dv); - DestroyMatrix_lf(kalcvfurw_ps->Zpredtran_dm); - DestroyCell_lf(kalcvfurw_ps->Ppred_dc); - DestroyVector_lf(kalcvfurw_ps->ylhtranpred_dv); - - free(kalcvfurw_ps); - return ((TSkalcvfurw *)NULL); - } - else return (kalcvfurw_ps); -} - - -void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps) -{ - //See the notes of SWZ regarding the government's updating of the parameters in their Phillips-curve equation. - //NOTE: make sure that the value of kalcvfurw_ps->sigmasq and other input values are given. - int ti; - double workd, workdenominv; - //--- - int fss, kx; - double sigmasq_fix = kalcvfurw_ps->sigmasq; -// double sigmasq; - TSdmatrix *V_dm; - TSdmatrix *Zpredtran_dm; - TSdcell *Ppred_dc; - TSdvector *ylhtran_dv; - TSdmatrix *Xrhtran_dm; - //=== - TSdvector *workkxby1_dv = NULL; //kx-by-1. -// TSdvector *work1kxby1_dv = NULL; //kx-by-1. - TSdmatrix *workkxbykx_dm = NULL; //kx-by-kx symmetric and positive positive. -// //=== -// TSdvector *zbefore_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vbefore_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); -// TSdvector *zafter_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vafter_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); - //******* WARNING: Some dangerous pointer movement to gain efficiency ******* -// double *yt_p; -// double *Vbefore_p; -// double *Vafter_p; - TSdvector xt_sdv; - TSdvector zbefore_sdv; - //TSdmatrix Vbefore_sdm; - TSdvector zafter_sdv; - //TSdmatrix Vafter_sdm; - - - if (!kalcvfurw_ps) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps must be created"); - if (!kalcvfurw_ps->V_dm || !kalcvfurw_ps->ylhtran_dv || !kalcvfurw_ps->Xrhtran_dm || !kalcvfurw_ps->z10_dv || !kalcvfurw_ps->P10_dm) - fn_DisplayError(".../kalcvf_urw(): input arguments kalcvfurw_ps->V_dm, kalcvfurw_ps->ylhtran_dv, kalcvfurw_ps->Xrhtran_dm, kalcvfurw_ps->z10_dv, kalcvfurw_ps->P10_dm must be given legal values"); - if (!(kalcvfurw_ps->P10_dm->flag & (M_SU | M_SL))) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps->P10_dm must be symmetric"); - fss = kalcvfurw_ps->fss; - kx = kalcvfurw_ps->kx; - V_dm = kalcvfurw_ps->V_dm; - Zpredtran_dm = kalcvfurw_ps->Zpredtran_dm; - Ppred_dc = kalcvfurw_ps->Ppred_dc; - ylhtran_dv = kalcvfurw_ps->ylhtran_dv; - Xrhtran_dm = kalcvfurw_ps->Xrhtran_dm; - //--- - xt_sdv.n = kx; - xt_sdv.flag = V_DEF; - zbefore_sdv.n = kx; - zbefore_sdv.flag = V_DEF; - zafter_sdv.n = kx; - zafter_sdv.flag = V_DEF; - - //=== Memory allocation. - workkxby1_dv = CreateVector_lf(kx); - workkxbykx_dm = CreateMatrix_lf(kx, kx); - - - //------- The first period (ti=0). ------- - zbefore_sdv.v = kalcvfurw_ps->z10_dv->v; - zafter_sdv.v = Zpredtran_dm->M; - xt_sdv.v = Xrhtran_dm->M; - //--- - - workd = ylhtran_dv->v[0] - (kalcvfurw_ps->ylhtranpred_dv->v[0]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, kalcvfurw_ps->P10_dm, &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(kalcvfurw_ps->z10_dv->v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t]; - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - - - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[0], kalcvfurw_ps->P10_dm, workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[0]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - - //------- The rest of the periods (ti=1:T-1). ------- - for (ti=1; ti<fss; ti++) { - //NOTE: ti=0 has been taken care of outside of this loop. - zbefore_sdv.v = Zpredtran_dm->M + (ti-1)*kx; - zafter_sdv.v = Zpredtran_dm->M + ti*kx; - xt_sdv.v = Xrhtran_dm->M + ti*kx; - //--- - workd = ylhtran_dv->v[ti] - (kalcvfurw_ps->ylhtranpred_dv->v[ti]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, Ppred_dc->C[ti-1], &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(zbefore_sdv.v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[ti], Ppred_dc->C[ti-1], workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[ti]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - } - CopyVector0(kalcvfurw_ps->zupdate_dv, &zafter_sdv); - Zpredtran_dm->flag = M_GE; - kalcvfurw_ps->ylhtranpred_dv->flag = V_DEF; - -// DestroyVector_lf(zbefore_dv); -// DestroyMatrix_lf(Vbefore_dm); -// DestroyVector_lf(zafter_dv); -// DestroyMatrix_lf(Vafter_dm); - - DestroyVector_lf(workkxby1_dv); -// DestroyVector_lf(work1kxby1_dv); - DestroyMatrix_lf(workkxbykx_dm); -} - - - -//----------------------------------------------------------------------------------------------------------------------- -//-- General constant (known-time-varying) Kalman filter for DSGE models. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T) -{ - int _i; - //=== - TSivector *rows_iv = CreateVector_int(T); - TSivector *cols_iv = CreateVector_int(T); - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfiltv_tag *kalfiltv_ps = tzMalloc(1, struct TSkalfiltv_tag); - - - //--- Default value. - kalfiltv_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfiltv_ps->ny = ny; - kalfiltv_ps->nz = nz; - kalfiltv_ps->T = T; - - - - //--------- Creates memory and assigns values. The order matters. - kalfiltv_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfiltv_ps->at_dm = CreateMatrix_lf(ny, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = nz; - } - rows_iv->flag = cols_iv->flag = V_DEF; - kalfiltv_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->bt_dm = CreateMatrix_lf(nz, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - kalfiltv_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->z0_dv = CreateVector_lf(nz); - kalfiltv_ps->P0_dm = CreateMatrix_lf(nz, nz); - - - //--- - kalfiltv_ps->zt_tm1_dm = CreateMatrix_lf(nz, T); - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Pt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfiltv_ps); - -} -//--- -struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - if (kalfiltv_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfiltv_ps->yt_dm); - DestroyMatrix_lf(kalfiltv_ps->at_dm); - DestroyCell_lf(kalfiltv_ps->Ht_dc); - DestroyCell_lf(kalfiltv_ps->Rt_dc); - DestroyCell_lf(kalfiltv_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfiltv_ps->bt_dm); - DestroyCell_lf(kalfiltv_ps->Ft_dc); - DestroyCell_lf(kalfiltv_ps->Vt_dc); - //--- - DestroyVector_lf(kalfiltv_ps->z0_dv); - DestroyMatrix_lf(kalfiltv_ps->P0_dm); - //--- - DestroyMatrix_lf(kalfiltv_ps->zt_tm1_dm); - DestroyCell_lf(kalfiltv_ps->Pt_tm1_dc); - - - //--- - tzDestroy(kalfiltv_ps); //Must be freed last! - - return ((struct TSkalfiltv_tag *)NULL); - } - else return (kalfiltv_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //=== Default value. - kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; - kalfilmsinputs_1stapp_ps->ztm1_track = -1; - kalfilmsinputs_1stapp_ps->dtm1_track = -1; - - //--- Other key assignments. - kalfilmsinputs_1stapp_ps->ny = ny; - kalfilmsinputs_1stapp_ps->nz = nz; - kalfilmsinputs_1stapp_ps->nst = nst; - kalfilmsinputs_1stapp_ps->T = T; - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - //--- For output arguments. - rows_iv = CreateConstantVector_int(T+1, nz); - cols_iv = CreateConstantVector_int(T+1, nst); - kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - return (kalfilmsinputs_1stapp_ps); -} -//--- -struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - if (kalfilmsinputs_1stapp_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); - //--- - tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); - } - else return (kalfilmsinputs_1stapp_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_tag *kalfilmsinputs_ps = tzMalloc(1, struct TSkalfilmsinputs_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //--- Default value. - kalfilmsinputs_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfilmsinputs_ps->ny = ny; - kalfilmsinputs_ps->nz = nz; - kalfilmsinputs_ps->nRc = nRc; - kalfilmsinputs_ps->nRstc = nRstc; - kalfilmsinputs_ps->nRv = nRv; - kalfilmsinputs_ps->indxIndRegimes = indxIndRegimes; - kalfilmsinputs_ps->T = T; - - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_ps->at_dm = CreateMatrix_lf(ny, nRc); - // - rows_iv = CreateConstantVector_int(nRc, ny); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, ny); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_ps->bt_dm = CreateMatrix_lf(nz, nRc); - // - rows_iv = CreateConstantVector_int(nRc, nz); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - if (indxIndRegimes) - { - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRc*nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - //--- For output arguments. - if (indxIndRegimes) - { - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRc*nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfilmsinputs_ps); - -} -//--- -struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps) -{ - if (kalfilmsinputs_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->z0_dm); - DestroyCell_lf(kalfilmsinputs_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_ps->Pt_tm1_d4); - //--- - tzDestroy(kalfilmsinputs_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_tag *)NULL); - } - else return (kalfilmsinputs_ps); -}; - - -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//-- Constant-parameters (known-time-varying) Kalman filter -//----------------------------------------------------- -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //General constant (known-time-varying) Kalman filter for DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - int T = kalfiltv_ps->T; - int Tp1 = T + 1; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - int indx_badlh = 0; //1: bad likelihood with, say, -infinity of the LH value. - int tdata, ti; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; //double loglh_tdata; //logdetDtdata. - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - //--- Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - - - - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "Fatal error: tz_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[0], P0_dm); - - //====== See p.002 in LiuWZ. ====== - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - loglh = 0.0; - for (tdata=0; tdata<T; tdata++ ) - { - //Base-0 timing. - ti = tdata + 1; //Next period. - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (kalfiltv_ps->loglh = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh += -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //loglh += -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (ti<T) - { - //Updating only up to tdata=T-2. The values at ti=T or tdata=T-1 will not be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[ti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + ti*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[ti], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + ti*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[ti], Vt_dc->C[ti]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[ti], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[ti], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[ti], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[ti], W2nzbynz_dm); - //Done with all W*_dm. - } - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (kalfiltv_ps->loglh = loglh); -} -/** -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //This function is used to test tz_logTimetCondLH_kalfiltv(). - int T = kalfiltv_ps->T; - int tdata; - double loglh; - - loglh = 0.0; - for (tdata=0; tdata<T; tdata++) loglh += tz_logTimetCondLH_kalfiltv(0, tdata+1, kalfiltv_ps); - - return (loglh); -} -/**/ -//----------------------------------------------------- -//-- Updating Kalman filter at time t for constant-parameters (or known-time-varying) Kalman filter. -//----------------------------------------------------- -double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps) -{ - //st: base-0 grand regime at time t, which is just a dummy for this constant-parameter function in order to use - // Waggoner's automatic functions. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - // - //log LH at time t for constant (known-time-varying) Kalman-filter DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood at time t. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // April 2008, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //--- Output arguments. - double loglh_timet; //log likelihood at time t. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - //--- Input arguments. - int tdata, tp1; - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - int T = kalfiltv_ps->T; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - - - tdata = (tp1=inpt) - 1; //Base-0 time. - - //======= Initial condition. ======= - if (tdata==0) - { - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_logTimetCondLH_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(FPTR_DEBUG, "Fatal error: tz_logTimetCondLH_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and thus the initial conditions must be supplied by, say, input arguments"); - fflush(FPTR_DEBUG); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[tdata], P0_dm); - } - - - //======= Liklihood at time t (see p.002 in LiuWZ). ======= - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //======= Updating for the next period. ======= - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (tp1<T) - { - //Updating only up to tdata=T-2, because the values at tp1=T or tdata=T-1 will NOT be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[tp1], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + tp1*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[tp1], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + tp1*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[tp1], Vt_dc->C[tp1]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[tp1], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[tp1], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[tp1], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[tp1], W2nzbynz_dm); - //Done with all W*_dm. - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (loglh_timet); -} - - - - -//----------------------------------------------------- -//- WARNING: bedore using this function, make sure to call the following functions -// Only once in creating lwzmodel_ps: Refresh_kalfilms_*(lwzmodel_ps); -// Everytime when parameters are changed: RefreshEverything(); RefreRunningGensys_allcases(lwzmodel_ps) in particular. -//----------------------------------------------------- -double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //st: base-0 grand regime -- deals with the cross-section values at time t. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - //-- Output arguments - double loglh_timet; - //--- Input arguments - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- Local variables - int tbase0; - double logdet_Dtdata; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - TSdvector etdata_sdv; - //=== Work arguments. - TSdvector *wny_dv = CreateVector_lf(ny); - - - - //--- Critical checking. - if (inpt > kalfilmsinputs_1stapp_ps->T) - fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): The time exceeds the\n" - " data sample size allocated the structure TSkalfilmsinputs_1stapp_tag"); - - //--- The following is for safe guard. InitializeKalman_z10_P10() should be called in, say, RefreshEverything(). - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - if (!InitializeKalman_z10_P10(kalfilmsinputs_1stapp_ps, (TSdmatrix *)NULL, (TSdcell *)NULL)) - fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): the system is non-stationary when calling" - " InitializeKalman_z10_P10(). Please call this function in RefreshEverthing() and" - " set the likehood to be -infty for early exit"); - - tbase0=inpt-1; - - //------------------- The order matters. Updatekalfilms_1stapp() must be called before Update_et_Dt_1stapp(). ----------------- - //--- $$$ Critical updating where we MUSt have inpt-1. If inpt, Updatekalfilms_1stapp() will call this function again - //--- $$$ because DW function ProbabilityStateConditionalCurrent() need to access this function at time inpt, - //--- $$$ which has not computed before Updatekalfilms_1stapp(). Thus, we'll have an infinite loop. - Updatekalfilms_1stapp(tbase0, kalfilmsinputs_1stapp_ps, smodel_ps); -// //--- $$$ Critical updating. -// Update_et_Dt_1stapp(tbase0, kalfilmsinputs_1stapp_ps); -// //This function will give Dtdata_d4->F[tbase0], etdata_dc->C[tbase0], and PHtran_tdata_d4->F[tbase0]. - - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - //--- Forming the log conditional likelihood at t. - etdata_sdv.n = ny; - etdata_sdv.v = etdata_dc->C[tbase0]->M + ny*st; - etdata_sdv.flag = V_DEF; - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_d4->F[tbase0]->C[st]))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, &etdata_sdv, '/', Dtdata_d4->F[tbase0]->C[st]); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, &etdata_sdv); - //Done with all w*_dv. - - //=== - DestroyVector_lf(wny_dv); - - return (loglh_timet); -} -//====================================================== -//= Computing z_{1|0} and P_{1|0} for each new parameter values. -//====================================================== -int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc) -{ - //See p.001 and p.004 in LWZ Model II. - //Outputs: - // return 1: success in initializing; 0: initializing fails, so the likelihood must be set to -infty outside this function. - // ztm1_track to track the time up to which Kalman filter have been updated. - // z0_dm, zt_tm1_dc->C[0] - // P0_dc, Pt_tm1_d4->F[0] - - //--- Output arguments - TSdmatrix *z0_0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdmatrix *z0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdcell *P0_dc = kalfilmsinputs_1stapp_ps->P0_dc; //nz-by-nz-by-nst. - //+ Used to get zt_tm1_dc->C[0] and Pt_tm1_d4->F[0] only. - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Input arguments - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //--- Local variables - int sti; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv, z0_0_sdv, bt_sdv; - TSdvector yt_sdv, at_sdv; - //--- For the initial conditions: eigenvalue decompositions - int ki; - int errflag; - double eigmax; - //=== - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - // - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - - - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - { - z0_sdv.n = z0_0_sdv.n = bt_sdv.n = nz; - z0_sdv.flag = z0_0_sdv.flag = bt_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (!kalfilmsinputs_1stapp_ps->indxIni) - { - z0_0_dm->flag = z0_dm->flag = M_GE; - for (sti=nst-1; sti>=0; sti--) - { - if (kalfilmsinputs_1stapp_ps->DiffuseScale) //Diffuse initial conditions are used. - { - //--- Diffuse condition for z0_dv. - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; - bt_sdv.v = bt_dm->M + bt_sdv.n*sti; - InitializeConstantVector_lf(&z0_0_sdv, 0.0); - MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); - VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); - //--- Diffuse condition for P0_dm. - InitializeDiagonalMatrix_lf(Wnzbynz_dm, kalfilmsinputs_1stapp_ps->DiffuseScale); //To be used for DiffuseScale*I(nz) - CopyMatrix0(P0_dc->C[sti], Wnzbynz_dm); - //Done with W*_dm. - } - else //Unconditional moments for initial conditions are used. - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti]); - if (errflag) fn_DisplayError("kalman.c/InitializeKalman_z10_P10(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0-SQRTEPSILON)) //(1.0+EPSILON)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,sti))\b(:,sti); - z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti]); - CopySubmatrix2vector(&z0_0_sdv, 0, bt_dm, 0, sti, bt_dm->nrows); - bdivA_rgens(&z0_0_sdv, &z0_0_sdv, '\\', Wnzbynz_dm); - //- Under the assumption s_0 = s_1 (this is a short-cut). - MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); - VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,sti),F(:,:,sti)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti], Ft_dc->C[sti]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - if (0) //0: no printing. - { - #if defined (USE_DEBUG_FILE) - fprintf(FPTR_DEBUG, "\n-------WARNING: ----------\n"); - fprintf(FPTR_DEBUG, "\nIn grand regime sti=%d\n", sti); - fprintf(FPTR_DEBUG, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #else - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn grand regime sti=%d\n", sti); - fprintf(stdout, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #endif - } - //=== See p.000.3 in LWZ Model II. - //=== Do NOT use the following option. It turns out that this will often generate explosive conditional liklihood - //=== at the end of the sample, because Pt_tm1 shrinks to zero overtime due to the sigularity of - //=== the initila condition P_{1|0}. - //--- Letting z0_dv = 0.0 - // z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - // InitializeConstantVector_lf(&z0_sdv, 0.0); - // //--- Letting P0_dm = V - // CopyMatrix0(P0_dc->C[sti], Vt_dc->C[sti]); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (0); //Early exit with kalfilmsinputs_1stapp_ps->ztm1_track continues to be -1. - } - } - } - } - else - { - if (!z10_dm) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition z_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyMatrix0(z0_dm, z10_dm); - - if (!P10_dc) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition P_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyCell0(P0_dc, P10_dc); - } - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t-1 = 1. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t-1 = 1. - - - kalfilmsinputs_1stapp_ps->ztm1_track = 0; //Must reset to 0, meaning initial setting is done and ready for computing LH at t = 1. - - Update_et_Dt_1stapp(0, kalfilmsinputs_1stapp_ps); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (1); - } - else - { - fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): calling this function makes sense only if" - " kalfilmsinputs_1stapp_ps->ztm1_track is -1. Please check this value."); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (0); - } -} -//====================================================== -//= Integrating out the lagged regimes in order to -//= updating zt_tm1 and Pt_tm1 for next perid tp1 through Kim-Nelson filter. -//= tdata representing base-0 t timing, while inpt represents base-1 t timing. -// -//= Purpose: for each inpt, we integrate out grand regimes st -//= only ONCE to prevent the dimension of updated zt_tm1 and Pt_tm1 through Kim-Nelson filter. -//====================================================== -static int Updatekalfilms_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //Output: - // tm1update - // z_{t_1+1|t_1} - // P_{t_1+1|t_1} - //Input: - // t-1: base-1 t timing. Thus t-1=inpt-1. - - //--- Local variables - int stp1i, sti, t_2, t_2p1; - double prob_previous_regimes; - //-- Output arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Input arguments - TSdcell *Gt_dc = kalfilmsinputs_1stapp_ps->Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //+ - TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - int T = kalfilmsinputs_1stapp_ps->T; - TSdvector z0_sdv; - TSdvector btp1_sdv; - TSdvector etdata_sdv; - //=== Work arguments. - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - //+ - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //=== For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - //--- Critical checking. - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - fn_DisplayError(".../kalman.c/Updatekalfilms_1stapp(): Make sure InitializeKalman_z10_P10() is called in the function RefreshEverthing()"); - - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - btp1_sdv.n = nz; - btp1_sdv.flag = V_DEF; - //+ - etdata_sdv.n = ny; - etdata_sdv.flag = V_DEF; - - for (t_2=kalfilmsinputs_1stapp_ps->ztm1_track; t_2<t_1; t_2++) - { - //If t_1 <= ztm1_track, no updating. - //If t_1 > ztm1_track, updating z_{t|t-1} and P_{t|t-1} up to t-1 = t_1. - - zt_tm1_dc->C[t_2p1=t_2+1]->flag = M_GE; - for (stp1i=nst-1; stp1i>=0; stp1i--) - { - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=nst-1; sti>=0; sti--) - { - //=== Updating for next period by integrating out sti.. - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i], PHtran_tdata_d4->F[t_2]->C[sti], 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_d4->F[t_2]->C[sti]); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - etdata_sdv.v = etdata_dc->C[t_2]->M + ny*sti; - z0_sdv.v = zt_tm1_dc->C[t_2]->M + nz*sti; //sti: regime at time t_2. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, &etdata_sdv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i], Pt_tm1_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - - //--- Integrating out the state at t_2 using - //--- P(s_t_2|Y_{t_2}, theta) = ProbabilityStateConditionalCurrent(sti, t_2, smodel_ps); - //--- One can also access to P(s_t_2|Y_{t_2}, theta) by using ElementV(smodel_ps->V[t_2],s_{t_2}i), - //--- but this access will not call my function logTimetCondLH(), thus no updating for - //--- P(s_t_2|Y_{t_2}, and thus leading to incorrect results. - prob_previous_regimes = ProbabilityStateConditionalCurrent(sti, t_2, smodel_ps); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - //--- Filling zt_tm1 and Pt_tm1 for next period. - z0_sdv.v = zt_tm1_dc->C[t_2p1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[t_2p1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - //--- $$$ The following is important because it tells ProbabilityStateConditionalCurrent(), which calls - //--- $$$ logTimetCondLH_kalfilms_1stapp(), which calls recursively this function again, that there is no - //--- $$$ need to update Kalman filter for the period before kalfilmsinputs_1stapp_ps->ztm1_track. - kalfilmsinputs_1stapp_ps->ztm1_track = t_2p1; //Means that z_{t_2p1+1|t_2p1} and P_{t_2p1+1|t_2p1} are done. - - //--- $$$ This function must be called after all the above computations are done. - Update_et_Dt_1stapp(t_2p1, kalfilmsinputs_1stapp_ps); - } - - - //=== - DestroyMatrix_lf(Wnzbynz_dm); - // - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (kalfilmsinputs_1stapp_ps->ztm1_track); -} -//====================================================== -//= Computes etdata and Dtdata for all grand regimes st at tbase0=inpt-1 or dtm1_track -//= to prevent recomputing this object for different st at given tbase0. -//====================================================== -static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - //Output: - // dtm1_track is updated in this function. - // PHtran_tdata_d4->F[t-1] - // etdata_dc->C[t-1] - // Dtdata_d4->F[t-1] - //Input: - // t_1=inpt-1: base-0 timing for et and Dt before the likelihood at time inpt is computed. - - //--- Local variables - int sti, tbase0; - //-- Output arguments - TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdcell *yt_tm1_dc = kalfilmsinputs_1stapp_ps->yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- input arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-T. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-T. - //+ - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv; - TSdvector yt_sdv, at_sdv; - TSdvector etdata_sdv, yt_tm1_sdv; - //=== Work arguments. - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - etdata_sdv.n = yt_tm1_sdv.n = ny; - etdata_sdv.flag = yt_tm1_sdv.flag = V_DEF; - - for (tbase0=(kalfilmsinputs_1stapp_ps->dtm1_track+1); tbase0<=t_1; tbase0++) - { - //Note tbase0<=t_1, NOT tbase0<t_1. - //If t_1 < (dtm1_track+1), no updating. - //If t_1 >= (dtm1_track+1), updating etdata_dc->C[t-1] and Dtdata_d4->F[t-1] up to t-1=t_1. - - for (sti=nst-1; sti>=0; sti--) - { - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti], 1.0, 0.0, 'N', 'T'); - CopyMatrix0(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4->F[tbase0]->C[sti], PHtran_tdata_dm); - - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti*at_dm->nrows; //grand regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - etdata_sdv.v = etdata_dc->C[tbase0]->M + etdata_sdv.n*sti; - yt_tm1_sdv.v = etdata_dc->C[tbase0]->M + yt_tm1_sdv.n*sti; - CopyVector0(&yt_tm1_sdv, &at_sdv); - MatrixTimesVector(&yt_tm1_sdv, Ht_dc->C[sti], &z0_sdv, 1.0, 1.0, 'N'); //a + H*z_{t|t-1}. - VectorMinusVector(&etdata_sdv, &yt_sdv, &yt_tm1_sdv); //y_t - a - H*z_{t|t-1}. - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - CopyMatrix0(Dtdata_d4->F[tbase0]->C[sti], Dtdata_dm); //Saved to be used for logTimetCondLH_kalfilms_1stapp(). - } - - //--- $$$ This tracker functions the same way as kalfilmsinputs_1stapp_ps->ztm1_track. - kalfilmsinputs_1stapp_ps->dtm1_track = tbase0; - } - - //=== - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyMatrix_lf(Dtdata_dm); - - return (kalfilmsinputs_1stapp_ps->dtm1_track); -} - - - - - - -//----------------------------------------------------- -//------------ OLD Code -------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -// -//- IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that -//- the coefficient regime is the 1st state variable, and -//- the volatility regime is the 2nd state variable. -//----------------------------------------------------- -#if defined (NEWVERSIONofDW_SWITCH) -double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int comst_c; //composite (s_tc, s_{t-1}c) - int st_c, stm1_c, st_v; - int comsti_c; //composite (s_tc, s_{t-1}c) - int sti, sti_c, stm1i_c, sti_v; - int comstp1i_c; //composite (s_{t+1}c, s_tc) - int stp1i, stp1i_c, stp1i_v; - int tbase0, tp1; - double logdet_Dtdata, loglh_timet; - static int record_tbase1_or_inpt_or_tp1 = 0; - static int passonce; - double prob_previous_regimes; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRstc = kalfilmsinputs_ps->nRstc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - int **Index = smodel_ps->sv->index; //Regime-switching states. - //smodel_ps->sv->index is for our new code. - // For old code (before 9 April 08 and before dsge_switch is created), use smodel_ps->sv->Index; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_logTimetLH_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - tbase0 = (tp1=inpt) - 1; - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (tbase0==0) - { - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[comsti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[comsti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, comsti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[comsti_c], Ft_dc->C[comsti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); -//=== ???????? For debugging purpose. -//if ((inpt<2) && (st==0)) -//{ -// fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - -// fprintf(FPTR_DEBUG, "wP0_dv:\n"); -// WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Vt_dc->C[sti_v=%d]:\n", sti_v); -// WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - -// fflush(FPTR_DEBUG); - -//} - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime comsti_c=%d and sti_v=%d and at time=%d\n", comsti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - } - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - if (indxIndRegimes ) - { - if (nRc==1) //Volatility. - { - comst_c = st_c = 0; - st_v = st; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_v = Index[st][1]; //volatility state s_tv - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comst_c = st_c = st; - st_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = st_c = Index[st][0]; - st_v = Index[st][1]; - } - } - else //Syncronized regimes - { - if (nRc>nRstc) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = st_c; - } - else - comst_c = st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[comst_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comst_c*at_dm->nrows; //comst_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comst_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comst_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //--- Forming the log conditional likelihood at t. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); -//if ((inpt>82) && (inpt<86) ) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %.16e "); - -// fflush(FPTR_DEBUG); -//} - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - - -//=== ???????? For debugging purpose. -if (inpt==1) -{ - double wk1, wk2; - - wk1 = logdet_Dtdata; - wk2 = VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, "logdet_Dtdata = %10.5f\n", wk1); - fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f\n", wk2); - fprintf(FPTR_DEBUG, "----- etdata_dv: \n"); - WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- yt_dv: \n"); - WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- at_dv: \n"); - WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- z0_dv: \n"); - WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- Ht_dc->C[comst_c=%d]:\n", comst_c); - WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); - - fprintf(FPTR_DEBUG, "\n\n"); - -} -// -fprintf(FPTR_DEBUG, " %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//fprintf(FPTR_DEBUG, "------------------------\n"); -//fprintf(FPTR_DEBUG, "st=%d and inpt=%d\n", st, inpt); -//fprintf(FPTR_DEBUG, "loglh_timet = %10.5f\n", loglh_timet); -//fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -//WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -////WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -////fprintf(FPTR_DEBUG, "\n"); -////WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//if ((inpt>82) && (inpt<86) ) -//if (inpt<2) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// tmp_Dtdata = logdeterminant(Dtdata_dm); -// tmp_expterm = VectorDotVector(wny_dv, etdata_dv); -// fprintf(FPTR_DEBUG, "logdeterminant(Dtdata_dm) = %10.5f;\n", tmp_Dtdata); -// fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f;\n", tmp_expterm); -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&at_sdv:\n"); -// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&z0_sdv:\n"); -// WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Ht_dc->C[comst_c=%d]:\n",comst_c); -// WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); -// fprintf(FPTR_DEBUG, "Rt_dc->C[st_v=%d]:\n", st_v); -// WriteMatrix(FPTR_DEBUG, Rt_dc->C[st_v], " %10.5f "); -// fprintf(FPTR_DEBUG, "Pt_tm1_d4->F[tbase0]->C[st = %d]:\n",st); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[st], " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); - - - - -//// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "zt_tm1_dc->C[tbase0]:\n"); -//// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -//// //WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -//// //fprintf(FPTR_DEBUG, "\n"); -//// fprintf(FPTR_DEBUG, "bt_dm = [\n"); -//// WriteMatrix(FPTR_DEBUG, bt_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); - -//// fprintf(FPTR_DEBUG, "et:\n"); -//// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "yt_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - -//// fprintf(FPTR_DEBUG, "at_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - - -//// for (ki=0; ki<Ht_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ht_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ht_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Ft_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ft_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ft_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Vt_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Vt_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Vt_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -// fflush(FPTR_DEBUG); -//} - - - //====================================================== - //= Updating zt_tm1 and Pt_tm1 for next perid tp1. - //= tdata = tbase0 is base-0 timing. - //====================================================== - if (inpt > record_tbase1_or_inpt_or_tp1) //This condition always satisfies at the 1st period (which is inpt=1). - { - passonce = 0; - record_tbase1_or_inpt_or_tp1 = inpt; - } - if (!passonce) - { - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comstp1i_c = stp1i_c = 0; - stp1i_v = stp1i; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_v = Index[stp1i][1]; //volatility state s_tv - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comstp1i_c = stp1i_c = stp1i; - stp1i_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comstp1i_c = stp1i_c = Index[stp1i][0]; - stp1i_v = Index[stp1i][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = stp1i_c; - } - else - comstp1i_c = stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[comsti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comsti_c*at_dm->nrows; //comsti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comsti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comsti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i_v]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_{t-1}, theta) = ElementV(smodel_ps->Z[inpt],s_{inpt}_i). - //--- Note tbase0 = inpt-1 because the data in DW code (ElementV) is base-1. - //--- Note at this point, we cannot access to P(s_t|Y_t, theta) = ElementV(smodel_ps->V[inpt],s_{inpt}_i) - //--- through DW's code. But we can modify my own code to do this later. - prob_previous_regimes = ElementV(smodel_ps->Z[inpt],sti); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - } - - -//=== ???????? For debugging purpose. -//if ((inpt>60) && (inpt<65) ) //if (inpt<5) -//{ -// int kip1; //Must be declared at the top of this "if" block. - -// fprintf(FPTR_DEBUG, "zt_tm1t=[\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); - -// for (ki=0; ki<Pt_tm1_d4->F[tbase0]->ncells; ki++) -// { -// kip1 = ki+1; -// fprintf(FPTR_DEBUG, "Pt_tm1_d4t(:,:,%d)=[\n", kip1); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[ki], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); -// } - -// fflush(FPTR_DEBUG); -//} - - -//=== ???????? For debugging purpose. -fprintf(FPTR_DEBUG, " loglh_timet = %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (loglh_timet); -} -#undef LOG2PI -#endif - - -/** -//---------------------------------------------------------------- -//-- Tested OK, but has not use because tz_Refresh_z_T7P_T_in_kalfilms_1st_approx() -//-- cannot access to ElementV(smodel_ps->V[tp1],sti) or ElementV(smodel_ps->V[tbase0],sti) -//-- because no likelihood has been formed at all before this function is called. -//---------------------------------------------------------------- -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -//----------------------------------------------------- -void tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - double debug1; - //--- Local variables - int stp1i, stp1i_c, stp1i_v, sti, sti_c, sti_v, tbase0, tp1; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, sti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti_c], Ft_dc->C[sti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime sti_c=%d and sti_v=%d and at time=%d\n", sti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - - -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[0]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[0]->C[0], " %.16e "); - - - //============== Updating zt_tm1 and Pt_tm1. ================== - for (tbase0=0; tbase0<T; tbase0++ ) - { - //tdata = tbase0 is base-0 timing. - tp1 = tbase0 + 1; //Next period. - - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes && (nRc==1)) - { - stp1i_c = 0; - stp1i_v = stp1i; - } - else if (indxIndRegimes && (nRv==1)) - { - stp1i_c = stp1i; - stp1i_v = 0; - } - else if (indxIndRegimes) - { - stp1i_c = smodel_ps->sv->Index[stp1i][0]; - stp1i_v = smodel_ps->sv->Index[stp1i][1]; - } - else - { - stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti_c*at_dm->nrows; //sti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[sti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_t, theta) = ElementV(smodel_ps->V[t+1],s_{t+1}_i). - //--- Note because the data in DW code (ElementV) is base-1, t+1 is actually tbase0. - debug1 = ElementV(smodel_ps->V[tp1],sti); //?????? Debug. - //ScalarTimesVectorUpdate(ztp1_dv, ElementV(smodel_ps->V[tp1],sti), ztp1_t_dv); - //ScalarTimesMatrix(Ptp1_dm, ElementV(smodel_ps->V[tp1],sti), Ptp1_t_dm, 1.0); - ScalarTimesVectorUpdate(ztp1_dv, 0.5, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, 0.5, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - -// fprintf(FPTR_DEBUG, "\n &yt_sdv:\n"); -// WriteMatrix(FPTR_DEBUG, &yt_sdv, " %.16e "); -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[tp1]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tp1], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[tp1]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tp1]->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fflush(FPTR_DEBUG); - - - } - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); -} -//----------------------------------------------------- -//- Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// (1) RunningGensys_const7varionly(lwzmodel_ps); -// (2) Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -// (3) tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(); -//- before using kalfilms_timet_1st_approx(). -//----------------------------------------------------- -double tz_kalfilms_timet_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0. The same for (T+1)-by-1 gbeta_dv and nlcoefs-by-(T+1) galpha_dm. - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int st_c, st_v, tbase0; - double loglh_timet; - //--- Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - TSdvector yt_sdv, at_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - if (smodel_ps->sv->nstates != zt_tm1_dc->C[0]->ncols) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Make sure that the column dimension of zt_tm1_dc->C is the same as smodel_ps->sv->nstates"); - - tbase0 = inpt - 1; //base-0 time t. - - if (indxIndRegimes && (nRc==1)) - { - st_c = 0; - st_v = st; - } - else if (indxIndRegimes && (nRv==1)) - { - st_c = st; - st_v = 0; - } - else if (indxIndRegimes) - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - st_c = smodel_ps->sv->Index[st][0]; - st_v = smodel_ps->sv->Index[st][1]; - } - else - { - st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + st_c*at_dm->nrows; //st_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[st_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - - //--- Forming the log conditional likelihood at t. - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //=== - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - - return (loglh_timet); -} -#undef LOG2PI -/**/ - - - - diff --git a/CFiles/Copy of kalman.h b/CFiles/Copy of kalman.h deleted file mode 100755 index 7e869dd7d9575d1f274640b3615a7d77c82ec6cd..0000000000000000000000000000000000000000 --- a/CFiles/Copy of kalman.h +++ /dev/null @@ -1,300 +0,0 @@ -#ifndef __KALMAN_H__ - #define __KALMAN_H__ - - #include "tzmatlab.h" - #include "mathlib.h" - #include "switch.h" - #include "fn_filesetup.h" //Used to call WriteMatrix(FPTR_DEBUG,....). - - - typedef struct TSkalcvfurw_tag { - //urw: univariate random walk kalman filter. Desigend specially for the 2006 AER SWZ paper. - - //=== Input arguments. - int indx_tvsigmasq; //0: constant siqmasq in Kalman updating (default); - //1: Keyensian (project-specific) type of time-varying sigmasq in Kalman updating; See pp.37 and 37a in SWZ Learning NOTES; - //2: project-specific type; - //3: another project-specific type. - double sigmasq; //Variance for the residual eps(t) of the measurement equation. - int fss; //T: effective sample size (excluding lags). - int kx; //dimension for x(t). - TSdmatrix *V_dm; //kx-by-kx. Covariance (symmetric and positive definite) matrix for the residual eta(t) of the transition equation. - TSdvector *ylhtran_dv; //1-by-T of y(t). The term lh means lelf hand side and tran means transpose. - TSdmatrix *Xrhtran_dm; //kx-by-T of x(t). The term rh means right hand side and tran means transpose. - TSdvector *z10_dv; //kx-by-1. Initial condition for prediction: z_{1|0}. - TSdmatrix *P10_dm; //kx-by-kx symmetric matrix. Initial condition for the variance of the prediction: P_{1|0}. - - //=== Output arguments. - TSdvector *zupdate_dv; //kx-by-1. z_{T+1|T}. - TSdmatrix *Zpredtran_dm; //kx-by-T matrix of one-step predicted values of z(t). [z_{2|1}, ..., z_{t+1|t}, ..., z_{T+1|T}]. - //Set to NULL (no output) if storeZ = 0; - TSdcell *Ppred_dc; //T cells and kx-by-kx symmetric and positive definite matrix for each cell. Mean square errors of predicted state variables. - //{P_{2|1}, ..., P{t+1|t}, ..., P{T+1|T}. Set to NULL (no output if storeV = 0). - TSdvector *ylhtranpred_dv; //1-by-T one-step prediction of y(t) or ylhtran_dv. Added 03/17/05. - - //=== Function itself. - void (*learning_fnc)(struct TSkalcvfurw_tag *, void *); - } TSkalcvfurw; //urw: univariate random walk. - // - typedef void TFlearninguni(struct TSkalcvfurw_tag *, void *); //For linear rational expectations models. - - - //=== Better version is TSkalfilmsinputs_1stapp_tag. Kalman filter for constant or known-time-varying DSGE models. - typedef struct TSkalfiltv_tag - { - //General (known-time-varying) Kalman filter for DSGE models. - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Not used if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as a initial condition - // and with z_{t+1|t} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as a initial condition - // and with P_{t+1|t} as the last element. Thus, we can use it as a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-T. - TSdcell *Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-T. - TSdcell *Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv; //nz-by-1; - TSdmatrix *P0_dm; //nz-by-nz. - - //=== Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc; //nz-by-nz-T. - } TSkalfiltv; - - - - //=== Inputs for filter for Markov-switching DSGE models at any time t. - typedef struct TSkalfilmsinputs_1stapp_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on the grand regime s_t that follows a Markov-chain process - // and is taken as given. - // - // Inputs at time t are as follows where nst is number of grand regimes (including lagged regime - // and coefficients and shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nst matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nst 3-D of Markov-switching matrices in the measurement equation. - // R is an n_y-by-n_y-by-nst 3-D of Markov-switching covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-nst 3-D of Markov-switching E(eta_t * eps_t'). - // ------ - // b is an n_z-by-nst matrix of Markov-switching input vectors in the state equation with b(:,st) as an initial condition. - // (alternatively, with the ergodic weighted b(:,st) as an initial condition). - // F is an n_z-by-n_z-by-nst 3-D of Markov-switching transition matrices in the state equation with F(:,:,st) - // as an initial condition (alternatively, with the ergodic weighted F(:,:,st) as an initial condition). - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation - // with V(:,:,st) as an initial condition (alternatively, with the ergodic weighted V(:,:,st) as an initial condition). - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nst matrix of initial condition (Not used if indxIni=0). - // P0 is an n_z-by-n_z-by-nst 3-D of initial condition (Not used if indxIni=0). - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,st))\b(:,st) - // vec(P0_0m1) = (I-kron(F(:,:,st),F(:,:,st)))\vec(V(:,:,st)) - // Note that all eigenvalues of the matrix F(:,:,st) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha. Revised, April 2008. - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nst; //number of grand composite regimes (current and past regimes, coefficient and volatility regimes). - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0, - //0: using the unconditional momnets for any given regime at time 0 (default when indxDiffuse = 0). - int indxDiffuse; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - double DiffuseScale; //A large (infinity) number when indxDiffuse = 1. - int ztm1_track; //t-1 = -1: no initial conditions z_{1|0} and P_{1|0} has been computed yet, but will be using InitializeKalman_z10_P10(), - //t-1 >= 0:T-1: z_{t|t-1} and P_{t|t-1} are updated up to t-1. - int dtm1_track; //t-1 = -1: no etdata_dc->C[0] or Dtdata_d4->F[0] has been computed yet. - //t-1 >= 0:T-1: etdata_dc->C[t-1] and Dtdata_d4->F[t-1] are updated up to t-1. - - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nst. - TSdcell *Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nst. - TSdcell *Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - // - TSdmatrix *z0_0_dm; //nz-by-nst. z_{0|0}. - TSdmatrix *z0_dm; //nz-by-nst. z_{1|0}. - TSdcell *P0_dc; //nz-by-nz-by-nst. P_{1|0} - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nst-by-(T+1), where z_{1|0} is an initial condition (1st element with t-1=0 or t=1 for base-1) and - // the terminal condition z_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, z_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1), where P_{1|0} is an initial condition (1st element with t-1=0) and - // the terminal condition P_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, P_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - //+ Will be save for updating likelihood and Kalman filter Updatekalfilms_1stapp(), so save time to recompute these objects again. - TSdfourth *PHtran_tdata_d4; //nz-by-ny-by-nst-T, P_{t|t-1}*H_t'. Saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc; //ny-by-nst-by-T (with base-0 T), forecast errors e_t in the likelihood. - TSdcell *yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). Incorrect now (Used to back out structural shocks). - TSdfourth *Dtdata_d4; //ny-by-ny-nst-by-T, forecast covariance D_t in the likelihood. Saved for updating Kalman filter Updatekalfilms_1stapp(). - } TSkalfilmsinputs_1stapp; - - - //=== OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. - typedef struct TSkalfilmsinputs_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs at time t are as follows where nRc is number of regimes for coefficients - // nRv is number of regimes for volatility (shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nRc matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nRc 3-D of Markov-switching matrices in the measurement equation. - // R is an n_y-by-n_y-by-nRv 3-D of Markov-switching covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-nRv 3-D of Markov-switching E(eta_t * eps_t'). - // ------ - // b is an n_z-by-nRc matrix of Markov-switching input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-nRc 3-D of Markov-switching transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIndRegimes: 1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nRc*nRv matrix of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // z0 is an n_z-by-nRv matrix of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRc*nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nRc; //number of composite regimes (current and past regimes) for coefficients. - int nRstc; //number of coefficient regimes at time t. - int nRv; //number of regimes for volatility (shock variances). - int indxIndRegimes; //1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nRc. - TSdcell *Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nRc. - TSdcell *Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm; //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - TSdcell *P0_dc; //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - } TSkalfilmsinputs; - - - - - //--- Functions for univariate random walk kalman filter. - TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv); //, int storeZ, int storeV); - TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps); - void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps); - - //--- New Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T); - struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); - int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc); - double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - - - //--- OLD Code: Functions for general constant Kalman filter. - struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T); - struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - //Used to test tz_logTimetCondLH_kalfiltv(). (Done April 08). double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps); - - //--- OLD Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T); - struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps); - double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps); - //IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that - // the coefficient regime is the 1st state variable, and - // the volatility regime is the 2nd state variable. -#endif - diff --git a/CFiles/congradmin.c b/CFiles/congradmin.c old mode 100755 new mode 100644 diff --git a/CFiles/congradmin.h b/CFiles/congradmin.h old mode 100755 new mode 100644 diff --git a/CFiles/congradminOrigWorks.c b/CFiles/congradminOrigWorks.c deleted file mode 100755 index e4cbb6e7d6e1f95f365b3e72d91b42a6da0c5588..0000000000000000000000000000000000000000 --- a/CFiles/congradminOrigWorks.c +++ /dev/null @@ -1,557 +0,0 @@ -/************************************************************* - * Conjugate Gradient Minimization Methods. See Numerical Recipes in C by Press, Flannery, Teukolsky, and Vetterling. - * (I) frprmn(): Plolak-Ribiere method with the line minimization without using the derivative information. - * (II) dlinmin(): Fletcher-Reeves method with the line minimization using the derivative information. - * - * Modified by Tao Zha, September 2003. -*************************************************************/ - -#include "congradmin.h" - -static void linmin(double p[], double xi[], int n, double *fret, double tol_brent, int itmax_brent, double (*func)(double [], int)); -static double brent(double ax, double bx, double cx, double (*f)(double), double tol_brent, double itmax_brent, double *xmin); -// -static void dlinmin(double p[], double xi[], int n, double *fret, double tol_dbrent, double itmax_dbrent, double *grdh_p, double (*func)(double [], int), void (*dfunc)(double [], double [], int, double (*func)(double [], int), double *, double)); -static double dbrent(double ax, double bx, double cx, double (*f)(double), double (*df)(double, double *), double *grdh_p, double tol_dbrent, double itmax_dbrent, double *xmin); -static double df1dim(double x, double *grdh_p); -// -static void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc, double (*func)(double)); -static double f1dim(double x); -// -static double ftd_norm2(double *vnew_p, double *vold_p, int _n); - - - -#define STRLEN 192 -static FILE *fptr_interesults = (FILE *)NULL; //Printing intermediate results to a file. -static char filename_sp3vecs[STRLEN]; //Three vectors. 1st row: line search direction; 2nd row: numerical gradient; 3rd row: vectorized parameters. -//static FILE *fptr_interesults_db = (FILE *)NULL; //Printing intermediate results to a file for debugging (db). -#define PRINTON //Added by TZ, September 2003. -#define EPS 1.0e-10 //Small number to rectify special case of converging to exactly zero function value. -#ifdef PRINTON //Added by TZ, September 2003. - #define FREEALL {tzDestroy(xi); tzDestroy(h); tzDestroy(g); tzDestroy(pold); tzDestroy(numgrad)} -#else - #define FREEALL {tzDestroy(xi); tzDestroy(h); tzDestroy(g);} -#endif -void frprmn(double p[], int n, int *iter, double *fret, - double (*func)(double [], int), void (*dfunc)(double [], double [], int, double (*func)(double [], int), double *, double), - double *ftol_p, int *itmax_p, double *tol_brent_p, int *itmax_brent_p, double *grdh_p) { - //Outputs: - // p[0, ..., n-1]: the location of the minimum if it converges, which replaces the starting value. - // iter: pointer to the number of iterations that were performed. - // fret: pointer to the minimum value of the function. - //Inputs: - // p[0, ..., n-1]: a starting point for the minimization. - // n: the dimension of p. - // ftol_p: pointer to the convergence tolerance on the objective function value. Default: 1.0e-4 if NULL. - // itmax_p: pointer to the maximum number of iterations in the main minimization program frprmn(). Default: 2000 if NULL. - // tol_brent_p: pointer to the convergence tolerance for the line minimization in brent(). Default: 2.0e-4 if NULL. - // itmax_brent_p: pointer to the maximum number of iterations for the line minimization in brent(). Default: 100 if NULL. - // grdh: pointer to the user's specified step size for a numerical gradient. If NULL, dfunc() (i.e., gradcd_gen()) will select grdh automatically. - // func(): the objective function. - // dfunc(): the gradient function computing the numerical gradient. In the form of gradcd_gen() in cstz.c. - int j, its, itmax, itmax_brent; - double gg, gam, fp, dgg, ftol, tol_brent; - double *g=NULL, *h=NULL, *xi=NULL; - #ifdef PRINTON //Added by TZ, September 2003. - time_t begtime, currentime; - double normforp, *pold = NULL, *numgrad = NULL; - #endif - - //=== Memory allocation. - g=tzMalloc(n, double); - h=tzMalloc(n, double); - xi=tzMalloc(n, double); - // - numgrad = tzMalloc(n, double); //Added by TZ, September 2003. - #ifdef PRINTON //Added by TZ, September 2003. - pold = tzMalloc(n, double); - #endif - - //=== Default values. - if (!ftol_p) ftol = 1.0e-4; else ftol = *ftol_p; - if (!itmax_p) itmax = 200; else itmax = *itmax_p; - if (!tol_brent_p) tol_brent = 2.0e-4; else tol_brent = *tol_brent_p; - if (!itmax_brent_p) itmax_brent = 100; else itmax_brent = *itmax_brent_p; - - fp=(*func)(p, n); - (*dfunc)(xi, p, n, func, grdh_p, fp); - for (j=n-1;j>=0;j--) { - g[j] = -xi[j]; - xi[j]=h[j]=g[j]; - } - memcpy(numgrad, xi, n*sizeof(double)); //Added by TZ, September 2003. Save the numerical gradient to be printed out at the right place. - for (its=0;its<itmax;its++) { - #ifdef PRINTON - time(&begtime); //Added by TZ, September 2003. - memcpy(pold, p, n*sizeof(double)); //Added by TZ, September 2003. - #endif - //====== Added by TZ, September 2003 ====== - if ( !(fptr_interesults = fopen(filename_sp3vecs,"w")) ) { - printf("\n\nUnable to create the starting point data file %s in congradmin.c!\n", filename_sp3vecs); - getchar(); - exit(EXIT_FAILURE); - } -// rewind(fptr_interesults); //Must put the pointer at the beginning of the file. - //=== Prints out the line search direction. - fprintf(fptr_interesults, "--------Line search direction---------\n"); - for (j=0; j<n; j++) fprintf(fptr_interesults, " %0.16e ", xi[j]); - fprintf(fptr_interesults, "\n"); -// fflush( fptr_interesults ); - - - *iter=its; - #if defined (CGI_OPTIMIZATION) - linmin(p,xi,n,fret, tol_brent, itmax_brent, func); - #elif defined (CGII_OPTIMIZATION) - dlinmin(p, xi, n, fret, tol_brent, itmax_brent, grdh_p, func, dfunc); - #else - fn_DisplayError("The minimization routine frprmn() requires activating CGI_OPTIMIZATION or CGII_OPTIMIZATION in tzmatlab.h"); - #endif - #ifdef PRINTON - normforp = ftd_norm2(p, pold, n); - //=== Prints out intermediate results. - printf("\n========================================\n"); - printf("Intermediate results for the conjugate gradient algorithm."); - printf("\n (1) Number of iterations so far (maximum number): %d (%d)\n (2) New value of log posterior kernal (old value, improvement): %0.9f (%0.9f, %0.9f)\n" - " (3) Norm-2 of dx: %0.9f\n", - its, itmax, -(*fret), -fp, fp-(*fret), normforp); - fflush(stdout); // Flush the buffer to get out this message without delay. - #endif - //====== The following statements print out intermediate results. Added by TZ, September 2003 ====== - //=== Prints out the gradient. - fprintf(fptr_interesults, "--------Numerical graident---------\n"); - for (j=0; j<n; j++) fprintf(fptr_interesults, " %0.16e ", numgrad[j]); - fprintf(fptr_interesults, "\n"); - // - fprintf(fptr_interesults, "--------Restarting point---------\n"); - for (j=0; j<n; j++) fprintf(fptr_interesults, " %0.16e ", p[j]); - fprintf(fptr_interesults, "\n\n"); -// fflush( fptr_interesults ); - tzFclose(fptr_interesults); - - - if (2.0*fabs(*fret-fp) <= ftol*(fabs(*fret)+fabs(fp)+EPS)) { - //This is a normal convergence. - printf("\n----- Normal convergence by the criterion of the objective function evaluation -----------\n"); - FREEALL - return; - } - fp=(*func)(p, n); - (*dfunc)(xi, p, n, func, grdh_p, fp); - memcpy(numgrad, xi, n*sizeof(double)); //Added by TZ, September 2003. Save the numerical gradient to be printed out at the right place. -// if (filename_sp3vecs) { -// //=== Prints out the gradient. -// fprintf(fptr_interesults, "--------Numerical graident---------\n"); -// for (j=0; j<n; j++) fprintf(fptr_interesults, " %0.16e ", xi[j]); -// fprintf(fptr_interesults, "\n\n"); -//// fflush( fptr_interesults ); - -// tzFclose(fptr_interesults); -// } - dgg=gg=0.0; - for (j=n-1;j>=0;j--) { - gg += g[j]*g[j]; - dgg += (xi[j]+g[j])*xi[j]; - } - if (gg == 0.0) { - FREEALL - return; - } - gam=dgg/gg; - for (j=n-1;j>=0;j--) { - g[j] = -xi[j]; - xi[j]=h[j]=g[j]+gam*h[j]; - } - - #ifdef PRINTON - time(¤time); - //=== Times the iterative progress. - printf(" (4) Seconds to complete one iteration: %0.4f\n (5) Current time of day: %s\n", difftime(currentime, begtime), ctime(¤time)); - fflush(stdout); // Flush the buffer to get out this message without delay. - #endif - } - fn_DisplayError("The maximum number of iterations in frprmn() is reached before convergence"); -} -#undef PRINTON -#undef EPS -#undef FREEALL - - -#if defined (CGI_OPTIMIZATION) - static int ncom; - static double *pcom=NULL, *xicom=NULL, (*nrfunc)(double [], int); //nrfunc(), pcom, ncom, and xicom will be used by f1dim(). - static void linmin(double p[], double xi[], int n, double *fret, double tol_brent, int itmax_brent, double (*func)(double [], int)) { - //Outputs: - // p[0, ..., n-1]: a returned and reset value. - // xi[0, ..., n-1]: a value repaced by the actual vector displacement that p was moved. - // fret: the value of func at the returned location p. - //Inputs: - // p[0, ..., n-1]: a given point. - // xi[0, ..., n-1]: a given multidimensional direction. - // n: the dimension of p and xi. - // func(): the objective function. - int j; - double xx,xmin,fx,fb,fa,bx,ax; - - ncom=n; - pcom = tzMalloc(n, double); - xicom = tzMalloc(n, double); - nrfunc=func; - for (j=n-1;j>=0;j--) { - pcom[j]=p[j]; - xicom[j]=xi[j]; - } - ax=0.0; - xx=1.0; - mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,f1dim); - *fret=brent(ax,xx,bx,f1dim, tol_brent, itmax_brent, &xmin); - for (j=n-1;j>=0;j--) { - xi[j] *= xmin; - p[j] += xi[j]; - } - tzDestroy(xicom); - tzDestroy(pcom); - } - - - //=== Used by linmin() only; - #define CGOLD 0.3819660 - #define ZEPS 1.0e-10 - #define SHFT(a,b,c,d) {(a)=(b);(b)=(c);(c)=(d);} - #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) - static double brent(double ax, double bx, double cx, double (*f)(double), double tol_brent, double itmax_brent, double *xmin) { - int iter; - double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; - double e=0.0; - - a=(ax < cx ? ax : cx); - b=(ax > cx ? ax : cx); - x=w=v=bx; - fw=fv=fx=(*f)(x); - for (iter=0;iter<itmax_brent;iter++) { - xm=0.5*(a+b); - tol2=2.0*(tol1=tol_brent*fabs(x)+ZEPS); - if (fabs(x-xm) <= (tol2-0.5*(b-a))) { - *xmin=x; - return fx; - } - if (fabs(e) > tol1) { - r=(x-w)*(fx-fv); - q=(x-v)*(fx-fw); - p=(x-v)*q-(x-w)*r; - q=2.0*(q-r); - if (q > 0.0) p = -p; - q=fabs(q); - etemp=e; - e=d; - if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) - d=CGOLD*(e=(x >= xm ? a-x : b-x)); - else { - d=p/q; - u=x+d; - if (u-a < tol2 || b-u < tol2) - d=SIGN(tol1,xm-x); - } - } else { - d=CGOLD*(e=(x >= xm ? a-x : b-x)); - } - u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); - fu=(*f)(u); - if (fu <= fx) { - if (u >= x) a=x; else b=x; - SHFT(v,w,x,u) - SHFT(fv,fw,fx,fu) - } else { - if (u < x) a=u; else b=u; - if (fu <= fw || w == x) { - v=w; - w=u; - fv=fw; - fw=fu; - } else if (fu <= fv || v == x || v == w) { - v=u; - fv=fu; - } - } - } - fn_DisplayError("The maximum number of iterations in brent() is reached before convergence"); - *xmin=x; - return fx; - } - #undef CGOLD - #undef ZEPS - #undef SHFT - #undef SIGN - -#else //Default to CGII_OPTIMIZATION - - static int ncom; - static double *pcom=NULL, *xicom=NULL, (*nrfunc)(double [], int); //nrfunc(), pcom, ncom, and xicom will be used by f1dim() and df1dim(). - static void (*nrdfun)(double [], double [], int, double (*func)(double [], int), double *, double); - static void dlinmin(double p[], double xi[], int n, double *fret, double tol_dbrent, double itmax_dbrent, double *grdh_p, double (*func)(double [], int), void (*dfunc)(double [], double [], int, double (*func)(double [], int), double *, double)) { - //Outputs: - // p[0, ..., n-1]: a returned and reset value. - // xi[0, ..., n-1]: a value repaced by the actual vector displacement that p was moved. - // fret: the value of func at the returned location p. - //Inputs: - // p[0, ..., n-1]: a given point. - // xi[0, ..., n-1]: a given multidimensional direction. - // n: the dimension of p and xi. - // func(): the objective function. - // dfunc(): the gradient function computing the numerical gradient. In the form of gradcd_gen() in cstz.c. - - int j; - double xx,xmin,fx,fb,fa,bx,ax; - - ncom=n; - pcom = tzMalloc(n, double); - xicom = tzMalloc(n, double); - nrfunc=func; - nrdfun=dfunc; - for (j=n-1;j>=0;j--) { - pcom[j]=p[j]; - xicom[j]=xi[j]; - } - ax=0.0; - xx=1.0; - mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,f1dim); - *fret=dbrent(ax,xx,bx,f1dim, df1dim, grdh_p, tol_dbrent, itmax_dbrent, &xmin); - for (j=n-1;j>=0;j--) { - xi[j] *= xmin; - p[j] += xi[j]; - } - tzDestroy(xicom); - tzDestroy(pcom); - } - - - //=== Used by dlinmin() only; - #define ZEPS 1.0e-10 - #define MOV3(a,b,c, d,e,f) {(a)=(d);(b)=(e);(c)=(f);} - #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) - static double dbrent(double ax, double bx, double cx, double (*f)(double), double (*df)(double, double *), double *grdh_p, double tol_dbrent, double itmax_dbrent, double *xmin) { - int iter,ok1,ok2; - double a,b,d,d1,d2,du,dv,dw,dx,e=0.0; - double fu,fv,fw,fx,olde,tol1,tol2,u,u1,u2,v,w,x,xm; - - a=(ax < cx ? ax : cx); - b=(ax > cx ? ax : cx); - x=w=v=bx; - fw=fv=fx=(*f)(x); - dw=dv=dx=(*df)(x, grdh_p); - for (iter=1;iter<=itmax_dbrent;iter++) { - xm=0.5*(a+b); - tol1=tol_dbrent*fabs(x)+ZEPS; - tol2=2.0*tol1; - if (fabs(x-xm) <= (tol2-0.5*(b-a))) { - *xmin=x; - return fx; - } - if (fabs(e) > tol1) { - d1=2.0*(b-a); - d2=d1; - if (dw != dx) d1=(w-x)*dx/(dx-dw); - if (dv != dx) d2=(v-x)*dx/(dx-dv); - u1=x+d1; - u2=x+d2; - ok1 = (a-u1)*(u1-b) > 0.0 && dx*d1 <= 0.0; - ok2 = (a-u2)*(u2-b) > 0.0 && dx*d2 <= 0.0; - olde=e; - e=d; - if (ok1 || ok2) { - if (ok1 && ok2) - d=(fabs(d1) < fabs(d2) ? d1 : d2); - else if (ok1) - d=d1; - else - d=d2; - if (fabs(d) <= fabs(0.5*olde)) { - u=x+d; - if (u-a < tol2 || b-u < tol2) - d=SIGN(tol1,xm-x); - } else { - d=0.5*(e=(dx >= 0.0 ? a-x : b-x)); - } - } else { - d=0.5*(e=(dx >= 0.0 ? a-x : b-x)); - } - } else { - d=0.5*(e=(dx >= 0.0 ? a-x : b-x)); - } - if (fabs(d) >= tol1) { - u=x+d; - fu=(*f)(u); - } else { - u=x+SIGN(tol1,d); - fu=(*f)(u); - if (fu > fx) { - *xmin=x; - return fx; - } - } - du=(*df)(u, grdh_p); - if (fu <= fx) { - if (u >= x) a=x; else b=x; - MOV3(v,fv,dv, w,fw,dw) - MOV3(w,fw,dw, x,fx,dx) - MOV3(x,fx,dx, u,fu,du) - } else { - if (u < x) a=u; else b=u; - if (fu <= fw || w == x) { - MOV3(v,fv,dv, w,fw,dw) - MOV3(w,fw,dw, u,fu,du) - } else if (fu < fv || v == x || v == w) { - MOV3(v,fv,dv, u,fu,du) - } - } - } - fn_DisplayError("The maximum number of iterations in dbrent() is reached before convergence"); - return 0.0; - } - #undef ZEPS - #undef MOV3 - #undef SIGN - - //=== Used by dlinmin() and dbrent() only; - static double df1dim(double x, double *grdh_p) { - int j; - double df1=0.0; - double *xt,*df; - - xt = tzMalloc(ncom, double); - df = tzMalloc(ncom, double); - for (j=ncom-1;j>=0;j--) xt[j]=pcom[j]+x*xicom[j]; - (*nrdfun)(df, xt, ncom, nrfunc, grdh_p, nrfunc(xt, ncom)); - //=================== WARNING ====================== - //We use 0.0 because the current gradient function gradcd_gen() in cstz.c do not use this function value. A more - // sophisticated central gradient method would require this function value, and therefore we must pass - // nrfunc(xt, ncom) instead of 0.0. TZ, September 2003. - //=================== WARNING ====================== - for (j=ncom-1;j>=0;j--) df1 += df[j]*xicom[j]; - tzDestroy(df); - tzDestroy(xt); - return df1; - } - -#endif - - - -static double f1dim(double x) { - //Collapsing to one dimension line search, used by limin() or dlimin(). - int j; - double f,*xt=NULL; - - xt = tzMalloc(ncom, double); - for (j=ncom-1;j>=0;j--) xt[j]=pcom[j]+x*xicom[j]; - f=(*nrfunc)(xt, ncom); - tzDestroy(xt); - return f; -} - - -#define GOLD 1.618034 -#define GLIMIT 100.0 -#define TINY 1.0e-20 -#define SHFT(a,b,c,d) {(a)=(b);(b)=(c);(c)=(d);} -#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) -static void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc, double (*func)(double)) { - double ulim,u,r,q,fu,dum, tmpd; - - *fa=(*func)(*ax); - *fb=(*func)(*bx); - if (*fb > *fa) { - SHFT(dum,*ax,*bx,dum) - SHFT(dum,*fb,*fa,dum) - } - *cx=(*bx)+GOLD*(*bx-*ax); - *fc=(*func)(*cx); - while (*fb > *fc) { - r=(*bx-*ax)*(*fb-*fc); - q=(*bx-*cx)*(*fb-*fa); - u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ - (2.0*SIGN((tmpd=fabs(q-r))>TINY ? tmpd : TINY,q-r)); //Original: (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r)); - ulim=(*bx)+GLIMIT*(*cx-*bx); - if ((*bx-u)*(u-*cx) > 0.0) { - fu=(*func)(u); - if (fu < *fc) { - *ax=(*bx); - *bx=u; - *fa=(*fb); - *fb=fu; - return; - } else if (fu > *fb) { - *cx=u; - *fc=fu; - return; - } - u=(*cx)+GOLD*(*cx-*bx); - fu=(*func)(u); - } else if ((*cx-u)*(u-ulim) > 0.0) { - fu=(*func)(u); - if (fu < *fc) { - SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx)) - SHFT(*fb,*fc,fu,(*func)(u)) - } - } else if ((u-ulim)*(ulim-*cx) >= 0.0) { - u=ulim; - fu=(*func)(u); - } else { - u=(*cx)+GOLD*(*cx-*bx); - fu=(*func)(u); - } - SHFT(*ax,*bx,*cx,u) - SHFT(*fa,*fb,*fc,fu) - } -} -#undef GOLD -#undef GLIMIT -#undef TINY -#undef SHFT -#undef SIGN - - - - - -//------------------- -// My own functions. -//------------------- -//=== Computing Norm2 of dx. -static double ftd_norm2(double *vnew_p, double *vold_p, int _n) { - int _i; - double dtheta=0.0, //Cumulative. - tmpd; - - for (_i=_n; _i>=0; _i--) { - tmpd = vnew_p[_i] - vold_p[_i]; - dtheta += square(tmpd); - } - - return ( sqrt(dtheta) ); -} - - - -//=== Extern function to be accessed by other C files. -void congradmin_SetPrintFile(char *filename) { - if (!filename) sprintf(filename_sp3vecs, "outdata5congradmin.prn"); //Default filename. - else { - strcpy(filename_sp3vecs, filename); - //filename_sp3vecs[STRLEN-1] = '\0'; //The end of the string is set to NUL to prevent it from be a non-string. - } -} - - - -//void congradmin_SetPrintFile(FILE *fptr_sp) { -// fptr_interesults = fptr_sp; -//} - -//void congradmin_SetPrintFile_db(FILE *fptr_sp) { -// fptr_interesults_db = fptr_sp; -//} - - -#undef STRLEN diff --git a/CFiles/congradminOrigWorks.h b/CFiles/congradminOrigWorks.h deleted file mode 100755 index 567c40aea4fad6287d6608d25812767cb005722e..0000000000000000000000000000000000000000 --- a/CFiles/congradminOrigWorks.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __CONGRADMIN_H__ -#define __CONGRADMIN_H__ - - #include <math.h> - #include <string.h> - - #include "tzmatlab.h" - - - void frprmn(double p[], int n, int *iter, double *fret, - double (*func)(double [], int), void (*dfunc)(double [], double [], int, double (*func)(double [], int), double *, double), - double *ftol_p, int *itmax_p, double *tol_brent_p, int *itmax_brent_p, double *grdh_p); - //Outputs: - // p[0, ..., n-1]: the location of the minimum if it converges, which replaces the starting value. - // iter: pointer to the number of iterations that were performed. - // fret: pointer to the minimum value of the function. - //Inputs: - // p[0, ..., n-1]: a starting point for the minimization. - // n: the dimension of p. - // ftol_p: pointer to the convergence tolerance on the objective function value. Default: 1.0e-4 if NULL. - // itmax_p: pointer to the maximum number of iterations in the main minimization program frprmn(). Default: 2000 if NULL. - // tol_brent_p: pointer to the convergence tolerance for the line minimization in brent(). Default: 2.0e-4 if NULL. - // itmax_brent_p: pointer to the maximum number of iterations for the line minimization in brent(). Default: 100 if NULL. - // grdh: pointer to the user's specified step size for a numerical gradient. If NULL, dfunc() (i.e., gradcd_gen()) will select grdh automatically. - // func(): the objective function. - // dfunc(): the gradient function computing the numerical gradient. In the form of gradcd_gen() in cstz.c. - - void congradmin_SetPrintFile(char *filename); - //If filename=NULL, no intermediate results will be printed out to a file. -// void congradmin_SetPrintFile(FILE *fptr_sp); - //If fptr_sp=NULL, no intermediate results will be printed out to a file. -// void congradmin_SetPrintFile_db(FILE *fptr_sp); -#endif diff --git a/CFiles/csminwel.c b/CFiles/csminwel.c old mode 100755 new mode 100644 diff --git a/CFiles/csminwel.h b/CFiles/csminwel.h old mode 100755 new mode 100644 diff --git a/CFiles/csminwelOrigWorks.c b/CFiles/csminwelOrigWorks.c deleted file mode 100755 index fc118aa7acfe4b99451ddd3642f1903ea5d6609c..0000000000000000000000000000000000000000 --- a/CFiles/csminwelOrigWorks.c +++ /dev/null @@ -1,706 +0,0 @@ -/*========================================================= - * csminwel.c - * - * Unconstrained minimization. Uses a quasi-Newton method with BFGS update of - * the estimated inverse hessian. It is robust against certain pathologies - * common on likelihood functions. It attempts to be robust against "cliffs", - * i.e. hyperplane discontinuities, though it is not really clear whether what - * it does in such cases succeeds reliably. - * - * function [fhat,xhat,ghat,Hhat,itct,fcount,retcodehat] = csminwelmex(fcn,x0,H0,grad,crit,nit,varargin) - * fcn: string naming the objective function to be minimized - * x0: initial value of the parameter vector - * H0: initial value for the inverse Hessian. Must be positive definite. - * grad: Either a string naming a function that calculates the gradient, or the null matrix. - * If it's null, the program calculates a numerical gradient. In this case fcn must - * be written so that it can take a matrix argument and produce a row vector of values. - * crit: Convergence criterion. Iteration will cease when it proves impossible to improve the - * function value by more than crit. - * nit: Maximum number of iterations. - * varargin: A list of optional length of additional parameters that get handed off to fcn each - * time it is called. - * Note that if the program ends abnormally, it is possible to retrieve the current x, - * f, and H from the files g1.mat and H.mat that are written at each iteration and at each - * hessian update, respectively. (When the routine hits certain kinds of difficulty, it - * write g2.mat and g3.mat as well. If all were written at about the same time, any of them - * may be a decent starting point. One can also start from the one with best function value.) - * - * Note: to set the level of display output, change preprocessor definitions in csminwel.h - * to display all output, uncomment both VERBOSE_WARNINGS and VERBOSE_DETOUTPUT - * to display only warnings without output, uncomment VERBOSE_WARNINGS - * to display no ouput, comment both VERBOSE_DETOUTPUT and VERBOSE_WARNINGS - * - * MATLAB algorithm by Christopher Sims - * C implementation by Iskander Karibzhanov - * Modified by Dan Waggoner and Tao Zha - * - * Copyright(c) 1996 Christopher Sims - * Copyright(c) 2003 Karibzhanov, Waggoner, and Zha - *======================================================= - * Revision history: - * - * 10/3/2002 - 1. corrected problem with memory corruption in C-MEX-file (csminwelmex.c) - * (needed to switch fcnRhs[0] back to x[0] before destroying it. - * If we don't do this, we will later clear previously destroyed array - * (one of x[1], x[2] or x[3]) which causes memory fault. - * The reason why fcnRhs[0] pointed to array other than x[0] is - * because we use mxSetPr in feval and gfeval. - * This was not a problem in C-file (csminwel.c). - * - * 10/11/2002 - 1. changed csminit function to avoid using fPeak without first initializing it - * 2. added two switches in csminit function to assign retcode to 7 for lambda>=4 - * 3. added one more verbose level to display only warnings or all output * - *=======================================================*/ - -#include "csminwel.h" -#define STRLEN 192 -static int numgrad(double *g, double *x, int n, - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims); -static void csminit(double *fhat, double *xhat, int *fcount, int *retcode, - double *x0, double f0, double *g, int badg, double *H0, int n, - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims); -static void bfgsi(double *H, double *dg, double *dx, int n, int nn); -static int peakwall(double *g, int retcode, double *x, int n, - int (*gfcn)(double *x, int n, double *g, double **args, int *dims), - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims); -static double times(double *x, double *y, int n); -static double *mtimes(double *x, double *y, int n, int nn); -static double *mminus(double *x, double *y, int n); - - -static FILE *fptr_interesults = (FILE *)NULL; //Printing intermediate results to a file. -static char filename_sp2vecs[STRLEN]; //Two vectors. 1st row: numerical gradient; 2nd row: vectorized parameters. - - -void csminwel(double (*fcn)(double *x, int n, double **args, int *dims), - double *xh, int n, double *H, double *gh, - int (*gfcn)(double *x, int n, double *g, double **args, - int *dims), double *fh, double crit, int *itct, int nit, - int *fcount, int *retcodeh, double **args, int *dims) { - - int done=0, badg[4], badgh, nogh=1, stuck=0; - double *x[4], *g[4], f[4], *dg, *dx; - int retcode[3], fc=0, ih, nn, i; - #ifdef VERBOSE_DETOUTPUT - time_t begtime, currentime; - #endif - - - nn = n*n; /* n: dimension size of x or xh */ - *itct = -1; /* itct: number of actual iterations */ - *fcount = -1; /* fcount: number of evaluations of the function */ - - for (i=0; i<4; i++) - x[i] = tzMalloc(n, double); //x[i] = calloc(n, sizeof(double)); Commented out by TZ. - memcpy(x[0],xh,n*sizeof(double)); - - for (i=0; i<4; i++) - g[i] = tzMalloc(n, double); //calloc(n, sizeof(double)); Commented out by TZ. - - f[0] = fcn(x[0],n,args,dims); - - if (f[0] > 1.0e+50) { - printf("Bad initial parameter.\n"); - return; - } - - if (gfcn) - /* if grad is a string, compute it */ - badg[0] = gfcn(x[0],n,g[0],args,dims); - else - /* if grad is not string, compute it */ - badg[0] = numgrad(g[0],x[0],n,fcn,args,dims); - retcode[2] = 101; - /* iterate until done is false */ - while (!done) { - #ifdef VERBOSE_DETOUTPUT - time(&begtime); - #endif - - for (i=0; i<n; i++) - g[1][i] = g[2][i] = g[3][i] = 0; - -// #ifdef VERBOSE_DETOUTPUT -// printf("-----------------\n-----------------\n"); -// printf("f at the beginning of new iteration, %.10f\nx = ",f[0]); -// for (i=0; i<n; i++) { -// printf("%15.8g ",x[0][i]); -// if (i%4==3) printf("\n"); -// } -// if (i%4>0) printf("\n"); -// #endif - - (*itct)++; - csminit(&f[1],x[1],&fc,&retcode[0],x[0],f[0],g[0],badg[0],H,n,fcn,args,dims); - *fcount += fc; - /* if retcode1=1 gradient is zero and you are at the peak */ - if (retcode[0]!=1) { - badg[1] = peakwall(g[1],retcode[0],x[1],n,gfcn,fcn,args,dims); - /* Bad gradient or back and forth on step length. - Possibly at cliff edge. Try perturbing search direction. */ - if (badg[1]) { - double *Hcliff = tzMalloc(nn, double); //calloc(nn,sizeof(double)); Commented out by TZ. - double randmax=1/RAND_MAX; - /* if stuck, give it another try by perturbing Hessian */ - memcpy(Hcliff,H,nn*sizeof(double)); - for (i=0; i<nn; i+=n+1) - Hcliff[i] *= 1+rand()*randmax; - - #ifdef VERBOSE_WARNINGS - printf("Cliff. Perturbing search direction.\n"); - #endif - - csminit(&f[2],x[2],&fc,&retcode[1],x[0],f[0],g[0],badg[0],Hcliff,n,fcn,args,dims); - *fcount += fc; - if (f[2] < f[0]) { - badg[2] = peakwall(g[2],retcode[1],x[2],n,gfcn,fcn,args,dims); - if (badg[2]) { - double *xx = tzMalloc(n, double), nx; //calloc(n,sizeof(double)), nx; Commented out by TZ. - - #ifdef VERBOSE_WARNINGS - printf("Cliff again. Try traversing.\n"); - #endif - - for (i=0; i<n; i++) - xx[i] = x[2][i]-x[1][i]; - nx = times(xx,xx,n); - if (sqrt(nx) < 1e-13) { - f[3] = f[0]; - memcpy(x[3],x[0],n*sizeof(double)); - badg[3] = 1; - retcode[2] = 101; - } else { - double *gcliff = tzMalloc(n, double), //calloc(n,sizeof(double)), Commented out by TZ. - *eye = tzMalloc(n, double); //calloc(n,sizeof(double)); Commented out by TZ. - double dfnx = (f[2]-f[1])/nx; - for (i=0; i<n; i++) { - gcliff[i] = dfnx*xx[i]; - eye[i*(n+1)] = 1; - } - csminit(&f[3],x[3],&fc,&retcode[2],x[0],f[0],gcliff,0,eye,n,fcn,args,dims); - *fcount += fc; - badg[3] = peakwall(g[3],retcode[2],x[3],n,gfcn,fcn,args,dims); - free(eye); - free(gcliff); - } - free(xx); - } else { - f[3] = f[0]; - memcpy(x[3],x[0],n*sizeof(double)); - badg[3] = 1; - retcode[2] = 101; - } - } else { - f[3] = f[0]; - memcpy(x[3],x[0],n*sizeof(double)); - badg[3] = 1; - retcode[2] = 101; - } - free(Hcliff); - } else { - /* normal iteration, no walls, or else we're finished here. */ - f[2] = f[0]; - f[3] = f[0]; - badg[2] = 1; - badg[3] = 1; - retcode[1] = 101; - retcode[2] = 101; - } - } - - - /* how to pick gh and xh */ - if (f[3]<f[0] && badg[3]==0) { - /* if 3 (transversing) was needed, it improved and gradient is good, take that */ - ih = 3; - *fh = f[3]; - memcpy(xh,x[3],n*sizeof(double)); - memcpy(gh,g[3],n*sizeof(double)); - badgh = badg[3]; - *retcodeh = retcode[2]; - } - else if (f[2]<f[0] && badg[2]==0) { - /* if 2 (perturbig) was needed, it improved and gradient is good, take that */ - ih = 2; - *fh = f[2]; - memcpy(xh,x[2],n*sizeof(double)); - memcpy(gh,g[2],n*sizeof(double)); - badgh = badg[2]; - *retcodeh = retcode[1]; - } - else if (f[1]<f[0] && badg[1]==0) { - /* if first try went fine, take that */ - ih = 1; - *fh = f[1]; - memcpy(xh,x[1],n*sizeof(double)); - memcpy(gh,g[1],n*sizeof(double)); - badgh = badg[1]; - *retcodeh = retcode[0]; - } - else { - /* if nothing worked, just take the min of your attempts and compute the gradient */ - if (f[1] <= f[2]) - if (f[1] <= f[3]) ih = 1; - else ih = 3; - else if (f[2] <= f[3]) ih = 2; - else ih = 3; - *fh = f[i]; - memcpy(xh,x[ih],n*sizeof(double)); - *retcodeh = retcode[ih-1]; - if (nogh) { - nogh = 0; - if (gfcn) - badgh = gfcn(xh,n,gh,args,dims); - else - badgh = numgrad(gh,xh,n,fcn,args,dims); - } - badgh = 1; - } - /* end of picking */ - stuck = fabs(*fh-f[0]) < crit; - /* if nothing REALLY worked, too bad, you're stuck */ - if (!badg[0] && !badgh && !stuck) { - /* if you are not stuck, update H0 matrix */ - dg = mminus(gh,g[0],n); - dx = mminus(xh,x[0],n); - bfgsi(H,dg,dx,n,nn); - free(dx); - free(dg); - } - - #ifdef VERBOSE_DETOUTPUT - //=== Prints out intermediate results. - printf("========================================\n"); - printf(" (1) New value of the obj. func. on iteration %d: %.9f\n (2) Old value: %.9f\n (3) Downhill improvement: %.9f\n", - (int)*itct, *fh, f[0], f[0]-(*fh)); - - time(¤time); - //=== Times the iterative progress. - printf(" (4) Seconds to complete one iteration: %0.4f\n (5) Current time of day: %s\n\n", difftime(currentime, begtime), ctime(¤time)); - fflush(stdout); // Flush the buffer to get out this message without delay. - #endif - - //--------- Prints outputs to a file. --------- - if ( !(fptr_interesults = fopen(filename_sp2vecs,"w")) ) { - printf("\n\nUnable to create the starting point data file %s in csminwel.c!\n", filename_sp2vecs); - getchar(); - exit(EXIT_FAILURE); - } - fprintf(fptr_interesults, "--------Numerical gradient---------\n"); - for (i=0; i<n; i++) fprintf(fptr_interesults, " %0.16e ", gh[i]); - fprintf(fptr_interesults, "\n"); - fprintf(fptr_interesults, "--------Restarting point---------\n"); - for (i=0; i<n; i++) fprintf(fptr_interesults, " %0.16e ", xh[i]); - fprintf(fptr_interesults, "\n\n"); - tzFclose(fptr_interesults); - - if ((int)*itct > nit) { - #ifdef VERBOSE_WARNINGS - printf("\nWarning: termination as the maximum number of iterations is reached.\n"); - #endif - done = 1; - } - else if (stuck) { - #ifdef VERBOSE_DETOUTPUT - printf("improvement < crit termination\n"); - #endif - - done = 1; - } - - #ifdef VERBOSE_WARNINGS - switch ((int)*retcodeh) { - case 1: - printf("\nWarning: Zero gradient.\n"); break; - case 2: - printf("\nWarning: Back adjustment of stepsize didn't finish.\n"); break; - case 3: - printf("\nWarning: Smallest stepsize still improving too slow.\n"); break; - case 4: - printf("\nWarning: Forth adjustment of stepsize didn't finish.\n"); break; - case 6: - printf("\nWarning: Smallest step still improving too slow, reversed gradient.\n"); break; - case 5: - printf("\nWarning: Largest stepsize still improving too fast.\n"); break; - case 7: - printf("\nWarning: Possible inaccuracy in Hessian matrix.\n"); break; - } - #endif - - f[0] = *fh; - memcpy(x[0],xh,n*sizeof(double)); - memcpy(g[0],gh,n*sizeof(double)); - badg[0] = badgh; - } - for (i=0; i<4; i++) { - free(g[i]); - free(x[i]); - } -} - -/**/ -#define SCALE 1.0 -static int numgrad(double *g, double *x, int n, - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims) { - //Forward difference gradient method. - double delta, deltai; - double f0, g0, ff, tmp, *xp; - int i; - int badg; - f0 = fcn(x,n,args,dims); - badg = 0; - for (i=0, xp=x; i<n; i++, xp++, g++) { - delta=SCALE*1.0e-5, deltai=1.0e+5/SCALE; - - tmp = *xp; - *xp += delta; - delta = *xp - tmp; // This increases the precision slightly. Added by TZ. - if ( (ff=fcn(x,n,args,dims)) < NEARINFINITY ) g0 = (ff-f0)*deltai; //Not over the boundary. - else { - //Switches to the other side of the boundary. - *xp = tmp - delta; - g0 = (f0-fcn(x,n,args,dims))*deltai; - } - - *xp = tmp; //Puts back to the original place. TZ, 9/03. - if (fabs(g0)<1.0e+15) - *g = g0; - else { - #ifdef VERBOSE_WARNINGS - printf("Bad gradient.\n"); - #endif - - *g = 0; - badg = 1; - } - } - return badg; -} -#undef SCALE - -/** -#define STPS 1.0e-04 // 6.0554544523933391e-6 step size = pow(DBL_EPSILON,1.0/3) -static int numgrad(double *g, double *x, int n, - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims) { - //Central difference gradient method. Added by TZ. - double dh; - double f0, fp, fm, tmp, *xp; - int i; - int badg; - - badg = 0; - for (i=0, xp=x; i<n; i++, xp++, g++) { - dh = fabs(*xp)<=1 ? STPS : STPS*(*xp); - - tmp = *xp; - *xp += dh; - dh = *xp - tmp; // This increases the precision slightly. - fp = fcn(x,n,args,dims); - *xp = tmp - dh; - fm = fcn(x,n,args,dims); - - //=== Checking the boundary condition for the minimization problem. - if (fp >= NEARINFINITY) { - *xp = tmp; //Puts back to the original place. TZ, 9/03. - f0 = fcn(x,n,args,dims); - *g = (f0-fm)/dh; - } - else if (fm >= NEARINFINITY) { - //Switches to the other side of the boundary. - *xp = tmp; //Puts back to the original place. TZ, 9/03. - f0 = fcn(x,n,args,dims); - *g = (fp-f0)/dh; - } - else { - *g = (fp-fm)/(2.0*dh); - *xp = tmp; //Puts back to the original place. TZ, 9/03. - } - - if (fabs(*g)>1.0e+15) { - #ifdef VERBOSE_WARNINGS - printf("Bad gradient.\n"); - #endif - *g = 0.0; - badg = 1; - } - } - return badg; -} -#undef STPS -/**/ - - -#define ANGLE 0.05 //When output of this variable becomes negative, we have a wrong analytical graident. - //.005 works for identified VARs and OLS. -#define THETA .4 //(0<THETA<.5) THETA near .5 makes long line searches, possibly fewer iterations. - //.1 works for OLS or other nonlinear functions. - //.3 works for identified VARs. -#define FCHANGE 1000 -#define MINLAMB 1e-9 -#define MINDFAC .01 -static void csminit(double *fhat, double *xhat, int *fcount, int *retcode, - double *x0, double f0, double *g, int badg, double *H0, int n, - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims) { - double lambda=1, gnorm=0, dxnorm=0, factor=3, lambdaPeak=0; - double f, dfhat, a, tmp, fPeak=f0, lambdaMax=DBL_MAX; - double *dx, *dxtest; - int done=0, shrink=1, shrinkSignal, growSignal; - int i; - - *fhat = f0; - *fcount = 0; - *retcode = 0; - gnorm = sqrt(times(g,g,n)); - if ((gnorm < 1.e-12) && !badg) - *retcode = 1; /* gradient convergence */ - else { - /* with badg 1, we don't try to match rate of improvement to directional - derivative. We're satisfied just to get some improvement in f. */ - dx = tzMalloc(n, double); //dx = calloc(n, sizeof(double)); Commented out by TZ. - //if (!dx) printf("Dynamic memory allocation error.\n"); Commnted out by TZ. - for (i=0; i<n; i++) - dx[i] = -times(&H0[i*n],g,n); - dxnorm = sqrt(times(dx,dx,n)); - if (dxnorm > 1e12) { - #ifdef VERBOSE_WARNINGS - printf("Near-singular H problem.\n"); - #endif - - for (i=0; i<n; i++) - dx[i] *= FCHANGE/dxnorm; - } - dfhat = times(dx,g,n); - if (!badg) { - /* test for alignment of dx with gradient and fix if necessary */ - a = -dfhat/(gnorm*dxnorm); - if (a<ANGLE) { - tmp = (ANGLE*dxnorm+dfhat/gnorm)/gnorm; - for (i=0; i<n; i++) - dx[i] -= tmp*g[i]; - dfhat = times(dx,g,n); - dxnorm = sqrt(times(dx,dx,n)); - - #ifdef VERBOSE_DETOUTPUT - printf("Correct for low angle: %g\n",a); - #endif - } - } - - #ifdef VERBOSE_DETOUTPUT - printf("Predicted improvement: %18.9f, Norm of gradient: %18.9f\n",-dfhat/2,gnorm); - #endif - - dxtest = tzMalloc(n, double); //calloc(n, sizeof(double)); Commented out by TZ. - while (!done) { - for (i=0; i<n; i++) - dxtest[i] = x0[i]+dx[i]*lambda; - f = fcn(dxtest,n,args,dims); - - #ifdef VERBOSE_DETOUTPUT - printf("lambda = %10.5g; f = %20.7f\n",lambda,f); - #endif - - if (f<*fhat) { - *fhat = f; - memcpy(xhat,dxtest,n*sizeof(double)); - } - (*fcount)++; - tmp = -THETA*dfhat*lambda; - - /* the optimal lambda should be such that f0-f > -THETA*dfhat*lambda (see Berndt et al.) - If that's not the case and grad is good, OR - if grad is bad and f is not going down, shrinkSignal = 1 */ - shrinkSignal = ( !badg && (f0-f <= (tmp>0?tmp:0)) ) || - ( badg && (f0-f < 0 ) ); - - /* the optimal lambda should also be such that f0-f<-(1-THETA)*dfhat*lambda - If that's not the case with lambda>0, AND grad is good, growthSignal = 1 */ - growSignal = !badg && ( (lambda > 0) && (f0-f >= -(1-THETA)*dfhat*lambda) ); - - /* If shrinkSignal=1 AND ( lambda>lambdaPeak or lambda negative ) - (note when lambdaPeak=0 the second part only excludes lambda=0) - try shrinking lambda */ - if ( shrinkSignal && ( (lambda>lambdaPeak) || (lambda<0) ) ) { - /* if shrink=0 OR lambda/factor is already smaller than lambdaPeak, increase factor */ - if ( (lambda>0) && ((!shrink) || (lambda/factor <= lambdaPeak)) ) { - shrink = 1; - factor = pow(factor,.6); - while (lambda/factor <= lambdaPeak) - factor = pow(factor,.6); - if (fabs(factor-1)<MINDFAC) { - if (fabs(lambda) < 4) - *retcode = 2; - else - *retcode = 7; - done = 1; - } - } - if ((lambda<lambdaMax) && (lambda>lambdaPeak)) - lambdaMax=lambda; - /* shrink lambda */ - lambda /= factor; - /* if lambda has already been shrunk as much as possible */ - if (fabs(lambda) < MINLAMB) - /* if lambda is positive AND you have not made any improvement - try going against gradient, which may be inaccurate */ - if ((lambda > 0) && (f0 <= *fhat)) - lambda = -lambda*pow(factor,6); - else { - /* if lambda is negative: let it be known and quit trying */ - if (lambda < 0) - *retcode = 6; - /* if you have not made any imporvement: - let it be known and quit trying */ - else - *retcode = 3; - done = 1; - } - } - /* If growSignal=1 and lambda positive OR ( lambda>lambdaPeak or lambda negative ) - (note when lambdaPeak=0 the second part only excludes lambda=0) - try increase lambda */ - else - if ( (growSignal && (lambda > 0) ) || - ( shrinkSignal && (lambda <= lambdaPeak) && (lambda > 0) ) ) { - if (shrink) { - shrink = 0; - factor = pow(factor,.6); - if (fabs(factor-1) < MINDFAC) { - if (fabs(lambda) < 4) - *retcode = 4; - else - *retcode = 7; - done = 1; - } - } - if ( (f<fPeak) && (lambda>0) ) { - fPeak = f; - lambdaPeak = lambda; - if (lambdaMax <= lambdaPeak) - lambdaMax = lambdaPeak*factor*factor; - } - /* increase lambda (up to 1e20) */ - lambda *= factor; - /* if lambda has been increased up to the limit and - you have not made any imporvement: - let it be known and quit trying */ - if (fabs(lambda) > 1e20) { - *retcode = 5; - done = 1; - } - } - /* If growthSignal=shrinkSignal=0 you found a good lambda, you are done */ - else { - done = 1; - *retcode = factor<1.2 ? 7 : 0; - } - } - free(dxtest); - free(dx); - } - #ifdef VERBOSE_DETOUTPUT - printf("Norm of dx %10.5g\n", dxnorm); - #endif -} -#undef ANGLE -#undef THETA -#undef FCHANGE -#undef MINLAMB -#undef MINDFAC - - -static double times(double *x, double *y, int n) { - double z = 0; - int i; - for (i=0; i<n; i++, x++, y++) - z += (*x)*(*y); - return z; -} - -static int peakwall(double *g, int retcode, double *x, int n, - int (*gfcn)(double *x, int n, double *g, double **args, int *dims), - double (*fcn)(double *x, int n, double **args, int *dims), - double **args, int *dims) { - /* if retcode=2 or 4 you have shrunk or increased lambda as much as you could: - exhausted search possibilities the csminit step has failed */ - if (retcode==2 || retcode==4) - return 1; - else - /* if you are not at the peak but the csminit has improved, - compute the gradient again to update H0 */ - if (gfcn) - return gfcn(x,n,g,args,dims); - else - return numgrad(g,x,n,fcn,args,dims); -} - -static void bfgsi(double *H, double *dg, double *dx, int n, int nn) { - double *Hdg, *dxdx, *dxHdg, *Hdgdx; - double dgdx, m; - int i; - - Hdg = tzMalloc(n, double); //calloc(n, sizeof(double)); Commented out by TZ. - //if (!Hdg) printf("Dynamic memory allocation error.\n"); Commented out by TZ. - - /* Hdg = H0*dg; */ - for (i=0; i<n; i++) - Hdg[i] = times(&H[i*n],dg,n); - /* dgdx = dg'*dx; */ - dgdx = 1/times(dg,dx,n); - if (fabs(dgdx)<1e12) { - dxdx = mtimes(dx,dx,n,nn); - dxHdg = mtimes(dx,Hdg,n,nn); - Hdgdx = mtimes(Hdg,dx,n,nn); - m = 1+times(dg,Hdg,n)*dgdx; - for (i=0; i<nn; i++, H++, dxdx++, dxHdg++, Hdgdx++) - *H += (m*(*dxdx)-(*dxHdg)-(*Hdgdx))*dgdx; - free(Hdgdx-nn); - free(dxHdg-nn); - free(dxdx-nn); - } - else { - #ifdef VERBOSE_WARNINGS - printf("BFGS update failed.\n"); - printf("|dg| = %f |dx| = %f\n",sqrt(times(dg,dg,n)),sqrt(times(dx,dx,n))); - printf("dg\'*dx = %f\n",dgdx); - printf("|H*dg| = %f\n",sqrt(times(Hdg,Hdg,n))); - #endif - } - free(Hdg); -} - -static double *mtimes(double *x, double *y, int n, int nn) { - double *x0; - double *z; - int i, j; - z = tzMalloc(nn, double); //calloc(nn, sizeof(double)); Commented out by TZ. - for (i=0, x0=x; i<n; i++, y++) - for (j=0, x=x0; j<n; j++, x++, z++) - *z = (*x)*(*y); - return z-nn; -} - -static double *mminus(double *x, double *y, int n) { - double *z; - int i; - z = tzMalloc(n, double); //calloc(n, sizeof(double)); Commented out by TZ. - for (i=0; i<n; i++, x++, y++, z++) - *z = (*x)-(*y); - return z-n; -} - - -//=== Extern function to be accessed by other C files. -void csminwel_SetPrintFile(char *filename) { - if (!filename) sprintf(filename_sp2vecs, "outdata5csminwel.prn"); //Default filename. - else if (STRLEN-1 < strlen(filename)) fn_DisplayError(".../csminwel.c: the allocated length STRLEN for filename_sp2vecs is too short. Must increase the string length"); - else strcpy(filename_sp2vecs, filename); -} - -#undef STRLEN diff --git a/CFiles/csminwelOrigWorks.h b/CFiles/csminwelOrigWorks.h deleted file mode 100755 index bb4e8daf5e8fe14e59f49d310003e5f0d43ae92c..0000000000000000000000000000000000000000 --- a/CFiles/csminwelOrigWorks.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __CSMINWEL_H__ -#define __CSMINWEL_H__ - - #define VERBOSE_WARNINGS // display warnings - #define VERBOSE_DETOUTPUT // display detailed output - - #include <math.h> - #include <string.h> - #include <stdio.h> - #include <float.h> - - #include "tzmatlab.h" - - void csminwel(double (*fcn)(double *x, int n, double **args, int *dims), - double *x, int n, double *H, double *gh, - int (*grad)(double *x, int n, double *g, double **args, - int *dims), double *fh, double crit, int *itct, int nit, - int *fcount, int *retcodeh, double **args, int *dims); - // Alternative but less clear way: ... (double (*fcn)(double *, int, double **, int *), ... - - void csminwel_SetPrintFile(char *filename); -#endif diff --git a/CFiles/cstz.c b/CFiles/cstz.c old mode 100755 new mode 100644 index 1ac3dfcfa810a8225d9a211c711fe58d304fcf20..f82821d7f7d42ce17846bd1e399c606a1d7308de --- a/CFiles/cstz.c +++ b/CFiles/cstz.c @@ -1615,104 +1615,121 @@ double fn_replace_logofsumsbt(double *yold, double _a, double ynew, double _b) } - - - //<<--------------- // Evaluating the inverse of the chi-square cumulative distribution function. //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double fn_chi2inv(double p, double df) { +#if defined( IMSL_STATISTICSTOOLBOX ) //Returns x where p = int_{0}^{x} chi2pdf(t, df) dt if (df<=0.0) fn_DisplayError("cstz.c/fn_chi2inv(): degrees of freedom df must be greater than 0.0"); if (p<=0.0) return (0.0); else if (p>=1.0) return (MACHINEINFINITY); else return (imsls_d_chi_squared_inverse_cdf(p, df)); -} +#elif defined( USE_GSL_LIBRARY ) + if (df<=0.0) fn_DisplayError("cstz.c/fn_chi2inv(): degrees of freedom df must be greater than 0.0"); + + if (p<=0.0) return (0.0); + else if (p>=1.0) return (MACHINEINFINITY); + else + return gsl_cdf_chisq_Pinv(p,df); #else ***No default routine yet; #endif +} //<<--------------- // Evaluating the standard normal cumulative distribution function. //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double fn_normalcdf(double x) { +#if defined( IMSL_STATISTICSTOOLBOX ) return (imsls_d_normal_cdf(x)); -} +#elif defined( USE_GSL_LIBRARY ) + return gsl_cdf_ugaussian_P(x); #else ***No default routine yet; #endif +} + //<<--------------- // Evaluating the inverse of the standard normal cumulative distribution function. //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double fn_normalinv(double p) { +#if defined( IMSL_STATISTICSTOOLBOX ) return (imsls_d_normal_inverse_cdf(p)); -} +#elif defined( USE_GSL_LIBRARY ) + return gsl_cdf_ugaussian_Pinv(p); #else ***No default routine yet; #endif +} //<<--------------- // Evaluating the inverse of the beta cumulative distribution function. //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double fn_betainv(double p, double _alpha, double _beta) { +#if defined( IMSL_STATISTICSTOOLBOX ) //p = int_{0}^{\infty} betapdf(t, _alpha, _beta) dt where betapdf(t,_alpha,_beta) \propt t^{_alpha-1}*(1-t)^(_beta-1}. return (imsls_d_beta_inverse_cdf(p, _alpha, _beta)); -} +#elif defined( USE_GSL_LIBRARY) + return gsl_cdf_beta_Pinv(p,_alpha,_beta); #else ***No default routine yet; #endif +} //<<--------------- // Computes log gamma (x) where gamma(n+1) = n! and gamma(x) = int_0^{\infty} e^{-t} t^{x-1} dt. //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double fn_gammalog(double x) { +#if defined( IMSL_STATISTICSTOOLBOX ) return (imsl_d_log_gamma(x)); -} +#elif defined( USE_GSL_LIBRARY ) + return gsl_sf_lngamma(x); #else -No default routine yet; + ***No default routine yet; #endif +} //<<--------------- // Computes log beta(x, y) where beta(x, y) = gamma(x)*gamm(y)/gamma(x+y). //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double fn_betalog(double x, double y) { +#if defined( IMSL_STATISTICSTOOLBOX ) return (imsl_d_log_beta(x, y)); -} +#elif defined( USE_GSL_LIBRARY ) + return gsl_sf_lnbeta(x,y); #else ***No default routine yet; #endif +} //<<--------------- // Computes log gamma (x) where gamma(n+1) = n! and gamma(x) = int_0^{\infty} e^{-t} t^{x-1} dt. //--------------->> -#if defined( IMSL_STATISTICSTOOLBOX ) double gammalog(double x) { +#if defined( IMSL_STATISTICSTOOLBOX ) return (imsl_d_log_gamma(x)); -} +#elif defined( USE_GSL_LIBRARY ) + return gsl_sf_lngamma(x); #else -**No default routine yet; + ***No default routine yet; #endif +} //----------------------------------------------------------------------------------- diff --git a/CFiles/cstz.h b/CFiles/cstz.h old mode 100755 new mode 100644 index e52a2bfe2c194269e888f9be33108d7574d6e8d0..c99c29ede23a04b3e343c113e0663566582c17b3 --- a/CFiles/cstz.h +++ b/CFiles/cstz.h @@ -1,7 +1,7 @@ #ifndef __CSTZ_H__ #define __CSTZ_H__ #include "tzmatlab.h" - #include "switch_opt.h" //DW's Markov-switching routines, only used by gradcd_timet() and ComputeCovarianceFromOuterProduct(). + #include "dw_switch_opt.h" //DW's Markov-switching routines, only used by gradcd_timet() and ComputeCovarianceFromOuterProduct(). typedef struct { @@ -67,8 +67,6 @@ void gradfd_gen(double *g, double *x, int n, double (*fcn)(double *x, int n), double *grdh, double f0); //=== For computing inverse Hessian. - TSdmatrix *ComputeHessianFrom2ndDerivative(TSdmatrix *Hessian_dm, struct TStateModel_tag *smodel_ps, TSdvector *xhat_dv); - //+ void gradcd_timet(TSdvector *g_dv, TSdvector *x_dv, int t, struct TStateModel_tag *smodel_ps, double (*fcn)(double *x, int t, struct TStateModel_tag *smodel_ps), double grdh, double f0); TSdmatrix *ComputeHessianFromOuterProduct(TSdmatrix *Hessian_dm, struct TStateModel_tag *smodel_ps, TSdvector *xhat_dv); TSdmatrix *ComputeCovarianceFromOuterProduct(TSdmatrix *Omega_dm, struct TStateModel_tag *smodel_ps, TSdvector *xhat_dv); diff --git a/CFiles/cstz_dw.c b/CFiles/cstz_dw.c old mode 100755 new mode 100644 diff --git a/CFiles/fn_filesetup.c b/CFiles/fn_filesetup.c old mode 100755 new mode 100644 index f756f5c6c9ee394d86d4cc98a97187eef5ad955a..f75c865663be4beee65409b85ed646116a7fb90f --- a/CFiles/fn_filesetup.c +++ b/CFiles/fn_filesetup.c @@ -14,7 +14,7 @@ int fn_ParseCommandLine(int n_arg, char **args, char ch) { int i; for (i=1; i<n_arg; i++) - if ( ((args[i][0] == '/') || (args[i][0] == '-')) && (args[i][1] == ch) && (args[i][2] == '\0')) return i; + if ((args[i][0] == '/') && (args[i][1] == ch)) return i; return 0; } @@ -30,12 +30,10 @@ int fn_ParseCommandLine(int n_arg, char **args, char ch) { char *fn_ParseCommandLine_String(int n_arg, char **args, char ch, char *default_return) { int i=fn_ParseCommandLine(n_arg,args,ch); if (i > 0) - //if (strlen(args[i]) > 2) return args[i]+2; - // // In case the user forgot typing a space between /ch and string following it, still returns a pointer to the string folloing /ch. - //else if ((i+1 < n_arg) && (args[i+1][0] != '/')) return args[i+1]; - // // Returns a pointer to the string that does NOT begin with / and there is a whitespace between /ch and the string. - if (i+1 < n_arg) return args[i+1]; - // Returns a pointer to the string that does NOT begin with / and there is a whitespace between /ch and the string. + if (strlen(args[i]) > 2) return args[i]+2; + // In case the user forgot typing a space between /ch and string following it, still returns a pointer to the string folloing /ch. + else if ((i+1 < n_arg) && (args[i+1][0] != '/')) return args[i+1]; + // Returns a pointer to the string that does NOT begin with / and there is a whitespace between /ch and the string. return default_return; } diff --git a/CFiles/fn_filesetup.h b/CFiles/fn_filesetup.h old mode 100755 new mode 100644 diff --git a/CFiles/gensys.c b/CFiles/gensys.c old mode 100755 new mode 100644 diff --git a/CFiles/gensys.h b/CFiles/gensys.h old mode 100755 new mode 100644 index ea1e2ac2f1ea3e3121606522becac2ba2588819b..9b6d3516d0522f1af9280517a4687130055d32ad --- a/CFiles/gensys.h +++ b/CFiles/gensys.h @@ -48,7 +48,7 @@ TSdzmatrix *Gev_dzm; //n-by-2 z matrix of possible complex numbers. TSivector *eu_iv; //2-by-1. //=== Function itself. - void (*gensys)(struct TSgensys_tag *, void *); + int (*gensys)(struct TSgensys_tag *, void *); //=== Input arguments, which are all intialized to 0.0 and whose flags are set to M_GE. TSdmatrix *G0_dm; //n-by-n. TSdmatrix *G1_dm; //n-by-n. diff --git a/CFiles/gensys01Mar06Works.c b/CFiles/gensys01Mar06Works.c deleted file mode 100755 index d185626bf99db49e7bdbe4212f4704f7d1464c03..0000000000000000000000000000000000000000 --- a/CFiles/gensys01Mar06Works.c +++ /dev/null @@ -1,1114 +0,0 @@ -/******************************************************************* - * [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensys(g0,g1,c,psi,pi,div) - * - * System given as - * g0*y(t)=g1*y(t-1)+c+psi*z(t)+pi*eta(t), - * with z an exogenous variable process and eta being endogenously determined - * one-step-ahead expectational errors. Returned system is - * y(t)=G1*y(t-1)+C+impact*z(t)+ywt*inv(I-fmat*inv(L))*fwt*z(t+1) . - * If z(t) is i.i.d., the last term drops out. - * If div or stake is omitted from argument list, a div>1 or stake>1 is calculated. - * eu(1)=1 for existence, eu(2)=1 for uniqueness. eu(1)=-1 for - * existence only with not-serially correlated z(t); eu=[-2,-2] for coincident zeros. - * - * g0, g1: n-by-n matrices. - * c: n-by-1 constant terms. - * z(t): m-by-1 vector of exogenous residuals where m < n. - * psi: n-by-m matrix. - * eta(t): h-by-1 vector of expectational (endogenous) errors. - * pi: n-by-h matrix. - * div: a real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - *------- - * G1 or Theta_dm: n-by-n matrices. - * C: n-by-1 vector of constant terms. - * impact: n-by-m matrix. - * gev: n-by-2 z vector of stacked generalized eigenvalues where gev(;,2) ./ gev(:,1) = eig(g0, g1). - * ywt: n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - * fmat: nunstab-by-nunstab z matrix where nunstab is the number of non-stable roots. - * fwt: nunstab-by-m z matrix. - * - * 1996 MATLAB algorithm by Christopher Sims - * 2002 Mex implementation by Iskander Karibzhanov - * 2004 Modified to C function by Tao Zha (April) - * - * Note: Iskander is transforming g0 and g1 to complex matrices and uses zgges() as a qz decomposition. - * This is really wasting efficiency. One should keep g0 and g1 as real matrices and use - * dgges() as a qz decomposition. I don't have time to overhaul this at this point. 04/20/04, T. Zha. - * Note: 02/22/06. I take the above note back. According to DW, it is easy to order the - * the generalized eigenvalues by using the complex g0 and g1. In principle, one could - * order the roots using the real qz decomposition on real matrices g0 and g1. But so far - * Dan has found it a pain to do it. Perhaps we should read the MKL Lapack manual more - * carefully at a later point. -********************************************************************/ - -#include "gensys.h" - - -//----- NOTE: We can't replace MKL_Complex16 with a different name because the Intel Lapack uses MKL_Complex16. -//----- The only way to do this is to overhaul the code and put a wrapper function on each Intel Lapack function. -static int selctg(MKL_Complex16 *alpha, MKL_Complex16 *beta); -static int qz(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *q, MKL_Complex16 *z, int n); -static MKL_Complex16* CreateComplexMatrix5RealMatrix(TSdmatrix *X_dm); -static MKL_Complex16* CreateComplexMatrix5RealVector(TSdvector *x_dv); -static void ComplexMatrix2RealMatrix(TSdmatrix *Y_dm, MKL_Complex16 *Z); -static void ComplexMatrix2RealVector(TSdvector *y_dv, MKL_Complex16 *Z); -static TSdzmatrix *SubComplexMatrix2Zmatrix(TSdzmatrix *X_dzm, MKL_Complex16 *Z, const int nrowsforZ, const int _m, const int _n); -static void copy_eigenvalues(TSdzmatrix *Gev_dzm, MKL_Complex16 *a, MKL_Complex16 *b); -static int compute_svd(MKL_Complex16 *a, MKL_Complex16 **u, double **d, MKL_Complex16 **v, int m, int n); -static int compute_norm(MKL_Complex16 *a, double **d, int m, int n); -// -static int compute_normx(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *zwt, MKL_Complex16 *ueta, double **normx, int nunstab, int psin, int n, int bigev); -static void cblas_zdupe(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdscali(int n, double *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdscale(int n, double *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdpsb(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb, MKL_Complex16 *c, int ldc); -// -static void InitializeConstantMLK_Complex16(MKL_Complex16 *x_clx, const int _n, const double c); -static void InitializeConstantDouble(double *x_p, const int _n, const double c); - - - -TSgensys *CreateTSgensys(TFlinratexp *func, const int _n, const int _m, const int _k, const double div) -{ - //_n is the number of stacked variables (endogenous, Lagurangian multiplier, expected multiplier, etc.). - //_m is the number of exogenous shocks. - //_k is the number of expectational errors. - //div is the dividing number to determine what constitutes an unstable root. If div<1.0, a div>1.0 is calculated mechanically. - TSgensys *gensys_ps = tzMalloc(1, TSgensys); - - //=== Output arguments. - gensys_ps->Theta_dm = CreateMatrix_lf(_n, _n); //n-by-n. - gensys_ps->c_dv = CreateVector_lf(_n); //n-by-1. - gensys_ps->Impact_dm = CreateMatrix_lf(_n, _m); //n-by-m. - gensys_ps->Fmat_dzm = (TSdzmatrix *)NULL; //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - gensys_ps->Fwt_dzm = (TSdzmatrix *)NULL; //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - gensys_ps->Ywt_dzm = (TSdzmatrix *)NULL; //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - gensys_ps->Gev_dzm = CreateMatrix_dz(_n, 2); //n-by-2 z matrix of possible complex numbers. - gensys_ps->eu_iv = CreateConstantVector_int(2, 0); //2-by-1. - - //=== Function itself. - gensys_ps->gensys = func; - - //=== Input arguments. - gensys_ps->G0_dm = CreateConstantMatrix_lf(_n, _n, 0.0); //n-by-n. - gensys_ps->G0_dm->flag = M_GE; - gensys_ps->G1_dm = CreateConstantMatrix_lf(_n, _n, 0.0); //n-by-n. - gensys_ps->G1_dm->flag = M_GE; - gensys_ps->c0_dv = CreateConstantVector_lf(_n, 0.0); //n-by-1. - gensys_ps->Psi_dm = CreateConstantMatrix_lf(_n, _m, 0.0); //n-by-m. - gensys_ps->Psi_dm->flag = M_GE; - gensys_ps->Pi_dm = CreateConstantMatrix_lf(_n, _k, 0.0); //n-by-k where k is the number of expectational errors. - gensys_ps->Pi_dm->flag = M_GE; - gensys_ps->div = div; - - return (gensys_ps); -} -//------- -TSgensys *DestroyTSgensys(TSgensys *gensys_ps) -{ - if (gensys_ps) { - //=== Output arguments. - DestroyMatrix_lf(gensys_ps->Theta_dm); //n-by-n. - DestroyVector_lf(gensys_ps->c_dv); //n-by-1. - DestroyMatrix_lf(gensys_ps->Impact_dm); //n-by-m. - DestroyMatrix_dz(gensys_ps->Fmat_dzm); //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - DestroyMatrix_dz(gensys_ps->Fwt_dzm); //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - DestroyMatrix_dz(gensys_ps->Ywt_dzm); //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - DestroyMatrix_dz(gensys_ps->Gev_dzm); //n-by-2 z matrix of possible complex numbers. - DestroyVector_int(gensys_ps->eu_iv); //2-by-1. - - //=== Input arguments. - DestroyMatrix_lf(gensys_ps->G0_dm); //n-by-n. - DestroyMatrix_lf(gensys_ps->G1_dm); //n-by-n. - DestroyVector_lf(gensys_ps->c0_dv); //n-by-1. - DestroyMatrix_lf(gensys_ps->Psi_dm); //n-by-m. - DestroyMatrix_lf(gensys_ps->Pi_dm); //n-by-k where k is the number of expectational errors. - - free(gensys_ps); - - return ((TSgensys *)NULL); - } - else return (gensys_ps); -} - - -//--------------------------- For the function gensys_sims() ------------------------------------ -static int fixdiv = 1, zxz = 0; -static double stake = 1.01; -static int nunstab = 0; -static MKL_Complex16 one, minusone, zero; - -/* [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensysmkl(g0,g1,c,psi,pi,stake) */ -//void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { -void gensys_sims(TSgensys *gensys_ps, void *dummy_ps) -{ - int tmpi; - int n, psin, pin, nsquare, md, mds, md1, i, bigev, bigevs, bigev1; - int *eu; - int exist = 0, existx = 0, unique = 0; - //=== Memory will be allocated to the following. - double *deta = NULL, *dz = NULL, *normx = NULL, *deta1 = NULL, *norm = NULL; - MKL_Complex16 *a = NULL, *b = NULL, *q = NULL, *z = NULL, *pi = NULL, *psi = NULL; - MKL_Complex16 *tmat = NULL, *g0 = NULL, *g1 = NULL, *dummy = NULL, *tmatq = NULL, *c = NULL, *impact = NULL, *ab = NULL; - MKL_Complex16 *fmat = NULL, *fwt = NULL, *ywt = NULL; - MKL_Complex16 *etawt = NULL, *ueta = NULL, *veta = NULL, *zwt = NULL, *uz = NULL, *vz = NULL, *etawt1 = NULL, *ueta1 = NULL, *veta1 = NULL; - -// /* Check for proper number of input and output arguments */ -// if (nrhs < 5 || nrhs > 6) -// mexErrMsgTxt("Five or six input arguments required.\n"); -// if (nlhs != 8) -// mexErrMsgTxt("Eight output arguments required.\n"); - -// /* Dimensions */ -// n = mxGetM(prhs[0]); -// psin = mxGetN(prhs[3]); -// pin = mxGetN(prhs[4]); - n = gensys_ps->G0_dm->nrows; - psin = gensys_ps->Psi_dm->ncols; - pin = gensys_ps->Pi_dm->ncols; - // - eu = gensys_ps->eu_iv->v; - //eu = mxGetPr(plhs[7]=mxCreateDoubleMatrix(2,1,mxREAL)); - -// /* Check for consistency of input matrix dimensions */ -// if (mxGetM(prhs[0])!=n || mxGetM(prhs[1])!=n) -// mexErrMsgTxt("g0 and g1 must be square matrices.\n"); - -// if (mxGetM(prhs[3])!=n || mxGetM(prhs[4])!=n) -// mexErrMsgTxt("psi and pi must have the same number of rows as g0.\n"); - -// eu = mxGetPr(plhs[7]=mxCreateDoubleMatrix(2,1,mxREAL)); - - //=== [a b q z]=qz(g0,g1); -// a = mat2mkl(prhs[0],n,n); -// b = mat2mkl(prhs[1],n,n); -// q = mxCalloc(n*n,sizeof(MKL_Complex16)); -// z = mxCalloc(n*n,sizeof(MKL_Complex16)); - a = CreateComplexMatrix5RealMatrix(gensys_ps->G0_dm); - b = CreateComplexMatrix5RealMatrix(gensys_ps->G1_dm); - q = tzMalloc(nsquare=square(n), MKL_Complex16); - z = tzMalloc(nsquare, MKL_Complex16); - InitializeConstantMLK_Complex16(q, nsquare, 0.0); - InitializeConstantMLK_Complex16(z, nsquare, 0.0); - -// fixdiv = nrhs != 6; -// stake = fixdiv ? 1.01 : mxGetScalar(prhs[5]); - fixdiv = (gensys_ps->div < 1.0); - stake = fixdiv ? 1.01 : gensys_ps->div; - nunstab = 0; - zxz = 0; - - if (qz(a, b, q, z, n)) { - printf("WARNING: QZ factorization failed.\n"); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - - nunstab /= 2; - - if (zxz) { - printf("WARNING: Coincident zeros. Indeterminacy and/or nonexistence.\n"); - eu[0] = eu[1] = -2; - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - -// plhs[6] = mxCreateDoubleMatrix(n, 2, mxCOMPLEX); //For Gev_dzm. -// copy_eigenvalues(plhs[6], a, b, n); - copy_eigenvalues(gensys_ps->Gev_dzm, a, b); - - one.real = 1.0; - one.imag = 0.0; - - minusone.real = -1.0; - minusone.imag = 0.0; - - zero.real = 0.0; - zero.imag = 0.0; - -// pi = mat2mkl(prhs[4],n,pin); -// etawt = mxCalloc(nunstab*pin,sizeof(MKL_Complex16)); - pi = CreateComplexMatrix5RealMatrix(gensys_ps->Pi_dm); - etawt = tzMalloc(tmpi=nunstab*pin, MKL_Complex16); - InitializeConstantMLK_Complex16(etawt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, pin, n, - &one, q+n*(n-nunstab), n, pi, n, &zero, etawt, nunstab); - if (compute_svd(etawt, &ueta, &deta, &veta, nunstab, pin)) { - //Memory is now allocated to ueta, deta, and veta. - printf("WARNING: SVD failed.\n"); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(etawt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(etawt); - md = nunstab<pin?nunstab:pin; - bigev = md; - for (i=0; i<md; i++) - if (deta[i]<=REALSMALL) { - bigev=i; - break; - } - -// psi = mat2mkl(prhs[3],n,psin); -// zwt = mxCalloc(nunstab*psin,sizeof(MKL_Complex16)); - psi = CreateComplexMatrix5RealMatrix(gensys_ps->Psi_dm); - zwt = tzMalloc(tmpi=nunstab*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(zwt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, psin, n, - &one, q+n*(n-nunstab), n, psi, n, &zero, zwt, nunstab); - if (compute_svd(zwt, &uz, &dz, &vz, nunstab, psin)) { - //Memory is now allocated to uz, dz, and vz. - printf("WARNING: SV decomposition failed.\n"); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(uz); - tzDestroy(dz); - tzDestroy(vz); - tzDestroy(zwt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(vz); - mds = nunstab<psin?nunstab:psin; - bigevs = mds; - for (i=0; i<mds; i++) - if (dz[i]<=REALSMALL) { - bigevs=i; - break; - } - tzDestroy(dz); - - - /* ueta = nunstab x bigev - deta = bigev x 1 - veta = bigev x pin, ldveta = md - uz = nunstab x bigevs - dz = bigevs x 1 - vz = bigevs x psin, ldvz = mds */ - - if (!bigevs) { - exist = 1; - existx = 1; - } else { - /* uz-ueta*ueta'*uz */ - MKL_Complex16 *tmp = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, nunstab, nunstab, - bigev, &one, ueta, nunstab, ueta, nunstab, &zero, tmp, nunstab); - cblas_zhemm(CblasColMajor, CblasLeft, CblasUpper, nunstab, - bigevs, &minusone, tmp, nunstab, uz, nunstab, &one, uz, nunstab); - tzDestroy(tmp); - if (compute_norm(uz, &norm, nunstab, bigevs)) { - //Memory is now allocated to norm. - printf("WARNING: SVD failed.\n"); - tzDestroy(norm); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(uz); - tzDestroy(zwt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - exist = *norm < REALSMALL*n; - tzDestroy(norm); - if (compute_normx(a, b, zwt, ueta, &normx, nunstab, psin, n, bigev)) { - //If 0, memory is now allocated to normx; otherwise, normx is destroyed within the function compute_normx(). - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(uz); - tzDestroy(zwt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - existx = *normx < REALSMALL*n; - tzDestroy(normx); - } - - tzDestroy(uz); - tzDestroy(zwt); - - -/* Note that existence and uniqueness are not just matters of comparing - numbers of roots and numbers of endogenous errors. These counts are - reported below because usually they point to the source of the problem. */ - - etawt1 = tzMalloc(tmpi=(n-nunstab)*pin, MKL_Complex16); - InitializeConstantMLK_Complex16(etawt1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, n-nunstab, pin, n, - &one, q, n, pi, n, &zero, etawt1, n-nunstab); - tzDestroy(pi); - if (compute_svd(etawt1, &ueta1, &deta1, &veta1, n-nunstab, pin)) { - //Memory is now allocated to ueta1, deta1, and veta1. - printf("WARNING: SVD failed for compute_svd().\n"); - tzDestroy(ueta1); - tzDestroy(deta1); - tzDestroy(veta1); - tzDestroy(etawt1); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(etawt1); - md1 = n-nunstab<pin?n-nunstab:pin; - bigev1 = md1; - for (i=0; i<md1; i++) - if (deta1[i]<=REALSMALL) { - bigev1=i; - break; - } - /* ueta1 = n-nunstab x bigev1 - deta1 = bigev1 x 1 - veta1 = bigev1 x pin, ldveta1 = md1 */ - - if (existx || !nunstab) { - //=== Solution exists. - eu[0] = 1; - } else { - if (exist) { - printf("WARNING: Solution exists for unforecastable z only\n"); - eu[0] = -1; - } /* else - mexPrintf("No solution. %d unstable roots. %d endog errors.\n",nunstab,bigev1); */ - /* mexPrintf("Generalized eigenvalues\n"); - mexCallMATLAB(0,NULL,1, &plhs[6], "disp"); */ - } - if (!bigev1) - unique = 1; - else { - /* veta1-veta1*veta*veta' */ - /* veta = bigev x pin, ldveta1 = md - veta1 = bigev1 x pin, ldveta1 = md1 */ - MKL_Complex16 *tmp = tzMalloc(pin*pin, MKL_Complex16); - MKL_Complex16 *veta1_copy = tzMalloc(pin*bigev1, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, pin*pin, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - InitializeConstantMLK_Complex16(veta1_copy, pin*bigev1, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, pin, pin, - bigev, &one, veta, md, veta, md, &zero, tmp, pin); - cblas_zdupe(bigev1,pin,veta1,md1,veta1_copy,bigev1); - cblas_zhemm(CblasColMajor, CblasRight, CblasUpper, bigev1, pin, - &minusone, tmp, pin, veta1_copy, bigev1, &one, veta1_copy, bigev1); - tzDestroy(tmp); - if (compute_norm(veta1_copy, &norm, bigev1, pin)) { - //Memory is now allocated to norm. - printf("WARNING: SVD failed.\n"); - tzDestroy(norm); - tzDestroy(ueta1); - tzDestroy(deta1); - tzDestroy(veta1); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(veta1_copy); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(veta1_copy); - unique = *norm < REALSMALL*n; - tzDestroy(norm); - } - if (unique) { - //=== Unique solution. - eu[1] = 1; - } else { - eu[1] = 0; - printf("WARNING: Indeterminacy. %d loose endog errors with eu being [%d, %d].\n",bigev1-bigev, eu[0], eu[1]); - //printf("WARNING: Indeterminacy. %d loose endog errors with eu being [%g, %g].\n",bigev1-bigev, gensys_ps->eu_dv->v[0], gensys_ps->eu_dv->v[1]); - //printf("WARNING: Indeterminacy. %d loose endog errors.\n",bigev1-bigev); - /* mexPrintf("Generalized eigenvalues\n"); - mexCallMATLAB(0,NULL,1, &plhs[6], "disp"); */ - } - - cblas_zdscali(pin,deta,bigev,veta,md); /* veta' = deta\veta' */ - tzDestroy(deta); - cblas_zdscale(pin,deta1,bigev1,veta1,md1); /* veta1' = deta1*veta1' */ - tzDestroy(deta1); - etawt = tzMalloc(tmpi=nunstab*pin, MKL_Complex16); /* etawt = ueta*veta' */ - InitializeConstantMLK_Complex16(etawt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, nunstab, pin, bigev, - &one, ueta, nunstab, veta, md, &zero, etawt, nunstab); - tzDestroy(ueta); - tzDestroy(veta); - etawt1 = tzMalloc(tmpi=(n-nunstab)*pin, MKL_Complex16); /* etawt1 = ueta1*veta1' */ - InitializeConstantMLK_Complex16(etawt1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, pin, bigev1, - &one, ueta1, n-nunstab, veta1, md1, &zero, etawt1, n-nunstab); - tzDestroy(ueta1); - tzDestroy(veta1); - tmat = tzMalloc(tmpi=(n-nunstab)*nunstab, MKL_Complex16); /* tmat = etawt1*etawt' */ - InitializeConstantMLK_Complex16(tmat, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n-nunstab, nunstab, pin, - &one, etawt1, n-nunstab, etawt, nunstab, &zero, tmat, n-nunstab); - tzDestroy(etawt1); - tzDestroy(etawt); - - g0 = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(g0, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdupe(n-nunstab, n, a, n, g0, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, nunstab, nunstab, - &minusone, tmat, n-nunstab, a+(n-nunstab)*(n+1), n, &one, g0+(n-nunstab)*n, n); - cblas_zcopy(nunstab, &one, 0, g0+(n-nunstab)*(n+1), n+1); - - g1 = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(g1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdupe(n-nunstab, n, b, n, g1, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, nunstab, nunstab, - &minusone, tmat, n-nunstab, b+(n-nunstab)*(n+1), n, &one, g1+(n-nunstab)*n, n); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, n, &one, g0, n, g1, n); - dummy = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, n, n, &one, z, n, g1, n, &zero, dummy, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n, n, n, &one, dummy, n, z, n, &zero, g1, n); - tzDestroy(dummy); - //plhs[0] = mkl2mat_real(g1, n, n, n); - ComplexMatrix2RealMatrix(gensys_ps->Theta_dm, g1); //Output. - tzDestroy(g1); - - tmatq = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(tmatq, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zcopy(n*n, q, 1, tmatq, 1); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n, n-nunstab, nunstab, - &minusone, tmatq+(n-nunstab)*n, n, tmat, n-nunstab, &one, tmatq, n); - tzDestroy(tmat); - - ab = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(ab, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdpsb(nunstab, nunstab, a+(n-nunstab)*(n+1), n, b+(n-nunstab)*(n+1), n, ab, nunstab); - cblas_ztrsm(CblasColMajor, CblasRight, CblasUpper, CblasConjTrans, CblasNonUnit, - n, nunstab, &one, ab, nunstab, tmatq+(n-nunstab)*n, n); - tzDestroy(ab); - - //c = mat2mkl(prhs[2],n,1); - c = CreateComplexMatrix5RealVector(gensys_ps->c0_dv); - dummy = tzMalloc(gensys_ps->c0_dv->n, MKL_Complex16); - //$$$$$$$ The following is Iskander's fatal code error. One cannot use c in the two different places; otherwise, it makes c be zero completely! - // cblas_zgemv(CblasColMajor, CblasConjTrans, n, n, &one, tmatq, n, c, 1, &zero, c, 1); - // cblas_ztrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, n, g0, n, c, 1); - // cblas_zgemv(CblasColMajor, CblasNoTrans, n, n, &one, z, n, c, 1, &zero, c, 1); - cblas_zgemv(CblasColMajor, CblasConjTrans, n, n, &one, tmatq, n, c, 1, &zero, dummy, 1); - cblas_ztrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, n, g0, n, dummy, 1); - cblas_zgemv(CblasColMajor, CblasNoTrans, n, n, &one, z, n, dummy, 1, &zero, c, 1); - //plhs[1] = mkl2mat_real(c, n, n, 1); - ComplexMatrix2RealVector(gensys_ps->c_dv, c); //Output. - tzDestroy(c); - tzDestroy(dummy); - - impact = tzMalloc(tmpi=n*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(impact, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, n-nunstab, psin, n, - &one, tmatq, n, psi, n, &zero, impact, n); - tzDestroy(tmatq); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, psin, &one, g0, n, impact, n); - dummy = tzMalloc(tmpi=n*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, psin, n, - &one, z, n, impact, n, &zero, dummy, n); - tzDestroy(impact); - //plhs[2] = mkl2mat_real(dummy, n, n, psin); - ComplexMatrix2RealMatrix(gensys_ps->Impact_dm, dummy); //Output. - tzDestroy(dummy); - - fmat = a+(n-nunstab)*(n+1); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, nunstab, &one, b+(n-nunstab)*(n+1), n, fmat, n); - //plhs[3] = mkl2mat(fmat, n, nunstab, nunstab); - gensys_ps->Fmat_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Fmat_dzm, fmat, n, nunstab, nunstab); - tzDestroy(a); - - fwt = tzMalloc(tmpi=nunstab*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(fwt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_ztrsm(CblasColMajor, CblasRight, CblasUpper, CblasConjTrans, CblasNonUnit, - n, nunstab, &one, b+(n-nunstab)*(n+1), n, q+(n-nunstab)*n, n); - tzDestroy(b); - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, psin, n, - &minusone, q+(n-nunstab)*n, n, psi, n, &zero, fwt, nunstab); - tzDestroy(q); - tzDestroy(psi); - //plhs[4] = mkl2mat(fwt, nunstab, nunstab, psin); - gensys_ps->Fwt_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Fwt_dzm, fwt, nunstab, nunstab, psin); - tzDestroy(fwt); - - ywt = tzMalloc(tmpi=n*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(ywt, tmpi, 0.0); - cblas_zcopy(nunstab, &one, 0, ywt+n-nunstab, n+1); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, nunstab, &one, g0, n, ywt, n); - tzDestroy(g0); - dummy = tzMalloc(tmpi=n*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, nunstab, n, - &one, z, n, ywt, n, &zero, dummy, n); - tzDestroy(z); - tzDestroy(ywt); - //plhs[5] = mkl2mat(dummy, n, n, nunstab); - gensys_ps->Ywt_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Ywt_dzm, dummy, n, n, nunstab); - tzDestroy(dummy); -} - - -/****************************************************************************** - * function selctg orders the eigenvalues so that a selected cluster of * - * eigenvalues appears in the leading diagonal blocks of the upper * - * quasi-triangular matrix S and the upper triangular matrix T. * - ******************************************************************************/ - -static int selctg(MKL_Complex16 *alpha, MKL_Complex16 *beta) -{ - double absA = sqrt(alpha->real*alpha->real+alpha->imag*alpha->imag), - absB = fabs(beta->real); - if (absA) { - double divhat = absB/absA; - //bug detected by Vasco Curdia and Daria Finocchiaro, 2/25/2004 CAS. A root of - //exactly 1.01 and no root between 1 and 1.02, led to div being stuck at 1.01 - //and the 1.01 root being misclassified as stable. Changing < to <= below fixes this. - if (fixdiv && 1+REALSMALL<divhat && divhat<=stake) - stake = (1+divhat)/2; - } - if (absA<REALSMALL && absB<REALSMALL) - zxz = 1; - if (absB>stake*absA) { - nunstab++; - return(0); - } else - return(1); -} - -/****************************************************************************** - * compute for a pair of N-by-N complex nonsymmetric matrices (A,B), * - * the generalized eigenvalues, the generalized complex Schur form (S, T), * - * and optionally left and/or right Schur vectors (VSL and VSR) * - ******************************************************************************/ - -static int qz(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *q, MKL_Complex16 *z, int n) -{ -// unsigned char msg[101]; - int sdim, lwork = -1, info = 0; - MKL_Complex16 *alpha = tzMalloc(n,MKL_Complex16), - *beta = tzMalloc(n,MKL_Complex16), - *work, work1; - double *rwork = tzMalloc(8*n, double); - int *bwork = tzMalloc(4*n, int); - - /* Query zgges on the value of lwork */ - zgges("V", "V", "S", &selctg, &n, a, &n, b, &n, &sdim, alpha, beta, q, - &n, z, &n, &work1, &lwork, rwork, bwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to the Intel MKL function zgges() has an illegal value",-info); - tzDestroy(bwork); - tzDestroy(rwork); - tzDestroy(alpha); - tzDestroy(beta); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgges("V", "V", "S", &selctg, &n, a, &n, b, &n, &sdim, alpha, beta, q, - &n, z, &n, work, &lwork, rwork, bwork, &info); - - tzDestroy(work); - tzDestroy(bwork); - tzDestroy(rwork); - tzDestroy(alpha); - tzDestroy(beta); - - if (info < 0) { - printf("WARNING: Input %d to the Intel MKL function zgges() has an illegal value",-info); - return(info); - } - - if (info > 0) - if (info < n) - printf("WARNING: The QZ iteration failed. (A,B) are not in Schur form,\n" - "but ALPHA(j) and BETA(j) should be correct for j=%d,...,N.",info+1); - else { - switch (info-n) { - case 1: - printf("WARNING: LAPACK problem: error return from ZGGBAL"); - break; - case 2: - printf("WARNING: LAPACK problem: error return from ZGEQRF"); - break; - case 3: - printf("WARNING: LAPACK problem: error return from ZUNMQR"); - break; - case 4: - printf("WARNING: LAPACK problem: error return from ZUNGQR"); - break; - case 5: - printf("WARNING: LAPACK problem: error return from ZGGHRD"); - break; - case 6: - printf("WARNING: LAPACK problem: error return from ZHGEQZ (other than failed iteration)"); - break; - case 7: - printf("WARNING: LAPACK problem: error return from ZGGBAK (computing VSL)"); - break; - case 8: - printf("WARNING: LAPACK problem: error return from ZGGBAK (computing VSR)"); - break; - case 9: - printf("WARNING: LAPACK problem: error return from ZLASCL (various places)"); - break; - default: - printf("WARNING: LAPACK problem: unknown error."); - break; - } - } - return(info); -} - -/* - * Convert MATLAB complex matrix to MKL complex storage. - * - * Z = mat2mkl(X,ldz,ndz) - * - * converts MATLAB's mxArray X to MKL_Complex16 Z(ldz,ndz). - * The parameters ldz and ndz determine the storage allocated for Z, - * while mxGetM(X) and mxGetN(X) determine the amount of data copied. - */ - -//MKL_Complex16* mat2mkl(const mxArray *X, int ldz, int ndz) { -// MKL_Complex16 *Z, *zp; -// int m, n, incz, cmplxflag; -// register int i, j; -// double *xr, *xi; - -// Z = mxCalloc(ldz*ndz, sizeof(MKL_Complex16)); -// xr = mxGetPr(X); -// xi = mxGetPi(X); -// m = mxGetM(X); -// n = mxGetN(X); -// zp = Z; -// incz = ldz-m; -// cmplxflag = (xi != NULL); -// for (j = 0; j < n; j++) { -// if (cmplxflag) { -// for (i = 0; i < m; i++) { -// zp->real = *xr++; -// zp->imag = *xi++; -// zp++; -// } -// } else { -// for (i = 0; i < m; i++) { -// zp->real = *xr++; -// zp++; -// } -// } -// zp += incz; -// } -// return(Z); -//} - - -/* - * Convert MKL complex storage to MATLAB real and imaginary parts. - * - * X = mkl2mat(Z,ldz,m,n) - * - * copies MKL_Complex16 Z to X, producing a complex mxArray - * with mxGetM(X) = m and mxGetN(X) = n. - */ - -//mxArray* mkl2mat(MKL_Complex16 *Z, int ldz, int m, int n) { -// int i, j, incz; -// double *xr, *xi; -// MKL_Complex16 *zp; -// mxArray *X; - -// X = mxCreateDoubleMatrix(m,n,mxCOMPLEX); -// xr = mxGetPr(X); -// xi = mxGetPi(X); -// zp = Z; -// incz = ldz-m; -// for (j = 0; j < n; j++) { -// for (i = 0; i < m; i++) { -// *xr++ = zp->real; -// *xi++ = zp->imag; -// zp++; -// } -// zp += incz; -// } -// return(X); -//} - -//plhs[3] = mkl2mat(fmat, n, nunstab, nunstab) - -/* - * Convert MKL complex storage to MATLAB real matrix ignoring imaginary part. - * - * X = mkl2mat(Z,ldz,m,n) - * - * copies MKL_Complex16 Z to X, producing a real mxArray - * with mxGetM(X) = m and mxGetN(X) = n. - */ - -//mxArray* mkl2mat_real(MKL_Complex16 *Z, int ldz, int m, int n) { -// int i, j, incz; -// double *xr; -// MKL_Complex16 *zp; -// mxArray *X; - -// X = mxCreateDoubleMatrix(m,n,mxREAL); -// xr = mxGetPr(X); -// zp = Z; -// incz = ldz-m; -// for (j = 0; j < n; j++) { -// for (i = 0; i < m; i++) { -// *xr++ = zp->real; -// zp++; -// } -// zp += incz; -// } -// return(X); -//} - -//void copy_eigenvalues(mxArray *gev, MKL_Complex16 *a, MKL_Complex16 *b, int n) { -// double *gevr = mxGetPr(gev), -// *gevi = mxGetPi(gev); -// int i; - -// for (i=0; i<n; i++, gevr++, gevi++, a+=n+1) { -// *gevr = a->real; -// *gevi = a->imag; -// } - -// for (i=0; i<n; i++, gevr++, gevi++, b+=n+1) { -// *gevr = b->real; -// *gevi = b->imag; -// } -//} - -static void copy_eigenvalues(TSdzmatrix *Gev_dzm, MKL_Complex16 *a, MKL_Complex16 *b) -{ - int n = Gev_dzm->real->nrows; - double *gevr = Gev_dzm->real->M, - *gevi = Gev_dzm->imag->M; - int i; - - for (i=0; i<n; i++, gevr++, gevi++, a+=n+1) { - *gevr = a->real; - *gevi = a->imag; - } - - for (i=0; i<n; i++, gevr++, gevi++, b+=n+1) { - *gevr = b->real; - *gevi = b->imag; - } -} - - -static int compute_svd(MKL_Complex16 *x, MKL_Complex16 **u, double **d, MKL_Complex16 **v, int m, int n) -{ - //$$$Memory allocated to u, d, and v will be destroyed outside this function.$$$ - int tmpi; - int md = m<n?m:n, lwork = -1, info = 0; - MKL_Complex16 *a, *work, work1; - double *rwork = tzMalloc(5*md>1?5*md:1, double); - - a = tzMalloc(m*n, MKL_Complex16); - cblas_zcopy(m*n, x, 1, a, 1); - - *u = tzMalloc(tmpi=m*md,MKL_Complex16); - InitializeConstantMLK_Complex16(*u, tmpi, 0.0); - *v = tzMalloc(tmpi=md*n, MKL_Complex16); - InitializeConstantMLK_Complex16(*v, tmpi, 0.0); - *d = tzMalloc(md, double); - InitializeConstantDouble(*d, md, 0.0); - - /* Query zgges on the value of lwork */ - zgesvd("S", "S", &m, &n, a, &m, *d, *u, &m, *v, &md, &work1, &lwork, rwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - tzDestroy(rwork); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgesvd("S", "S", &m, &n, a, &m, *d, *u, &m, *v, &md, work, &lwork, rwork, &info); - - tzDestroy(work); - tzDestroy(rwork); - tzDestroy(a); - - if (info < 0) - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - - if (info > 0) - printf("WARNING: ZBDSQR did not converge.\n%d superdiagonals of an intermediate " - "bidiagonal form B did not converge to zero.",info); - return(info); -} - -static int compute_norm(MKL_Complex16 *a, double **d, int m, int n) -{ - //Memory will be allocated to d, which will be destroyed outside this function. - int md = m<n?m:n, lwork = -1, info = 0; - MKL_Complex16 *work = NULL, work1; - double *rwork = tzMalloc(5*md>1?5*md:1, double); - - *d = tzMalloc(md, double); - - /* Query zgges on the value of lwork */ - zgesvd("N", "N", &m, &n, a, &m, *d, NULL, &m, NULL, &md, &work1, &lwork, rwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - tzDestroy(rwork); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgesvd("N", "N", &m, &n, a, &m, *d, NULL, &m, NULL, &md, work, &lwork, rwork, &info); - - tzDestroy(work); - tzDestroy(rwork); - - if (info < 0) - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - - if (info > 0) - printf("WARNING: ZBDSQR() in Intel MKL did not converge.\n%d superdiagonals of an intermediate " - "bidiagonal form B did not converge to zero.",info); - - return(info); -} - -static int compute_normx(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *zwt, MKL_Complex16 *ueta, double **normx, int nunstab, int psin, int n, int bigev) -{ - //Memory is allocated to normx, which will be freed outside this function. - int tmpi; - int info = 0, i, bigevs; - // - MKL_Complex16 *M = NULL, *zwtx = NULL, *ux = NULL, *vx = NULL, *tmp = NULL; - double *dx = NULL; - - - a += (n+1)*(n-nunstab); - b += (n+1)*(n-nunstab); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, psin, &one, b, n, zwt, nunstab); - M = tzMalloc(nunstab*nunstab, MKL_Complex16); - cblas_zdupe(nunstab, nunstab, a, n, M, nunstab); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, nunstab, &one, b, n, M, nunstab); - - zwtx = tzMalloc(nunstab*nunstab*psin, MKL_Complex16); - cblas_zcopy(nunstab*psin, zwt, 1, zwtx, 1); - for (i=1; i<nunstab; i++) { - cblas_ztrmm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, nunstab, psin*i, &one, M, nunstab, zwtx, nunstab); - cblas_zcopy(nunstab*psin, zwt, 1, zwtx+nunstab*psin*i, 1); - } - tzDestroy(M); - cblas_ztrmm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, nunstab, nunstab*psin, &one, b, n, zwtx, nunstab); - info = compute_svd(zwtx, &ux, &dx, &vx, nunstab, nunstab*psin); //Memory is allocated to ux, dx, and vx. - tzDestroy(vx); - tzDestroy(zwtx); - if (info) { - printf("WARNING: SVD failed.\n"); - tzDestroy(ux); - tzDestroy(dx); - return(info); - } - bigevs = nunstab; - for (i=0; i<nunstab; i++) - if (dx[i]<=REALSMALL) { - bigevs = i; - break; - } - tzDestroy(dx); - /* ux-ueta*ueta'*ux */ - tmp = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, nunstab, nunstab, - bigev, &one, ueta, nunstab, ueta, nunstab, &zero, tmp, nunstab); - cblas_zhemm(CblasColMajor, CblasLeft, CblasUpper, nunstab, - bigevs, &minusone, tmp, nunstab, ux, nunstab, &one, ux, nunstab); - tzDestroy(tmp); - info = compute_norm(ux, normx, nunstab, bigevs); //Memory is allocated to normx. - if (info) { - printf("WARNING: SVD failed.\n"); - tzDestroy(normx); - tzDestroy(ux); - return(info); - } - tzDestroy(ux); - return(info); -} - -static void cblas_zdupe(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<m; i++, a++, b++) - cblas_zcopy(n, a, lda, b, ldb); -} - -static void cblas_zdscali(int n, double *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<lda; i++, a++, b++) - cblas_zdscal(n, 1.0/(*a), b, ldb); -} - -static void cblas_zdscale(int n, double *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<lda; i++, a++, b++) - cblas_zdscal(n, *a, b, ldb); -} - -static void cblas_zdpsb(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb, MKL_Complex16 *c, int ldc) -{ - int i; - cblas_zdupe(m, n, a, lda, c, ldc); - for (i=0; i<m; i++, b++, c++) - cblas_zaxpy(n, &minusone, b, ldb, c, ldc); -} - - -static MKL_Complex16* CreateComplexMatrix5RealMatrix(TSdmatrix *X_dm) -{ - int mn, k; - double *M; - // - MKL_Complex16 *Z = NULL; - - if (!X_dm) fn_DisplayError("CreateComplexMatrix5RealMatrix(): Input matrix X_dm must be allocated memory"); - M = X_dm->M; - - Z = tzMalloc(mn=X_dm->nrows*X_dm->ncols, MKL_Complex16); - for (k=mn-1; k>=0; k--) { - Z[k].real = M[k]; - Z[k].imag = 0.0; - } - return(Z); -} - -static MKL_Complex16* CreateComplexMatrix5RealVector(TSdvector *x_dv) -{ - int n, k; - double *v; - // - MKL_Complex16 *Z = NULL; - - if (!x_dv) fn_DisplayError("CreateComplexMatrix5RealVector(): Input vector x_dv must be allocated memory"); - v = x_dv->v; - - Z = tzMalloc(n=x_dv->n, MKL_Complex16); - for (k=n-1; k>=0; k--) { - Z[k].real = v[k]; - Z[k].imag = 0.0; - } - return(Z); -} - - -static void ComplexMatrix2RealMatrix(TSdmatrix *Y_dm, MKL_Complex16 *Z) -{ - int _k; - double *M; - - if (!Y_dm) fn_DisplayError("ComplexMatrix2RealMatrix(): Output matrix Y_dm must be allocated memory"); - M = Y_dm->M; - - for (_k=Y_dm->nrows*Y_dm->ncols-1; _k>=0; _k--) M[_k] = Z[_k].real; - Y_dm->flag = M_GE; -} - - -static void ComplexMatrix2RealVector(TSdvector *y_dv, MKL_Complex16 *Z) -{ - int _k; - double *v; - - if (!y_dv) fn_DisplayError("ComplexMatrix2RealVector(): Output matrix y_dv must be allocated memory"); - v = y_dv->v; - - for (_k=y_dv->n-1; _k>=0; _k--) v[_k] = Z[_k].real; - y_dv->flag = V_DEF; -} - - -static TSdzmatrix *SubComplexMatrix2Zmatrix(TSdzmatrix *X_dzm, MKL_Complex16 *Z, const int nrowsforZ, const int _m, const int _n) -{ - //X_dzm is _m-by_n comlex types where nrowsforZ <= _m and Z is nrowsforZ-by-_n. - int _i, _j, incz; - double *Mreal, *Mimag; - MKL_Complex16 *zp; - // - TSdzmatrix *Y_dzm = NULL; - - if (!X_dzm || X_dzm->real->nrows != _m || X_dzm->real->ncols != _n) { - DestroyMatrix_dz(X_dzm); //Destroys Y_dzm if already allocated memory to accommodate a possbible change of its dimension. - Y_dzm = CreateMatrix_dz(_m, _n); - } - else Y_dzm = X_dzm; - - Mreal = Y_dzm->real->M; - Mimag = Y_dzm->imag->M; - zp = Z; - if ((incz=nrowsforZ-_m)<0) fn_DisplayError("SubComplexMatrix2ZMatrix(): Number of rows for the input complex matrix Z must be greater that of the output Z matrix Y_dzm"); - - for (_j=0; _j<_n; _j++) { - for (_i=0; _i<_m; _i++) { - *Mreal++ = zp->real; - *Mimag++ = zp->imag; - zp++; - } - zp += incz; - } - return (Y_dzm); -} - - -static void InitializeConstantMLK_Complex16(MKL_Complex16 *x_clx, const int _n, const double c) -{ - int _i; - - for (_i=_n-1; _i>=0; _i--) - x_clx[_i].real = x_clx[_i].imag = c; -} - -static void InitializeConstantDouble(double *x_p, const int _n, const double c) -{ - int _i; - - for (_i=_n-1; _i>=0; _i--) x_p[_i] = c; -} diff --git a/CFiles/gensys01Mar06Works.h b/CFiles/gensys01Mar06Works.h deleted file mode 100755 index e2a347772044ea29ed6f7b283448d74a7bb90c02..0000000000000000000000000000000000000000 --- a/CFiles/gensys01Mar06Works.h +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************* - * [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensys(g0,g1,c,psi,pi,div) - * - * System given as - * g0*y(t)=g1*y(t-1)+c+psi*z(t)+pi*eta(t), - * with z an exogenous variable process and eta being endogenously determined - * one-step-ahead expectational errors. Returned system is - * y(t)=G1*y(t-1)+C+impact*z(t)+ywt*inv(I-fmat*inv(L))*fwt*z(t+1) . - * If z(t) is i.i.d., the last term drops out. - * If div or stake is omitted from argument list, a div>1 or stake>1 is calculated. - * eu(1)=1 for existence, eu(2)=1 for uniqueness. eu(1)=-1 for - * existence only with not-serially correlated z(t); eu=[-2,-2] for coincident zeros. - * - * g0, g1: n-by-n matrices. - * c: n-by-1 constant terms. - * z(t): m-by-1 vector of exogenous residuals where m < n. - * psi: n-by-m matrix. - * eta(t): h-by-1 vector of expectational (endogenous) errors. - * pi: n-by-h matrix. - * div: a real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - *------- - * G1 or Theta_dm: n-by-n matrices. - * C: n-by-1 vector of constant terms. - * impact: n-by-m matrix. - * gev: n-by-2 z vector of stacked generalized eigenvalues where gev(;,2) ./ gev(:,1) = eig(g0, g1). - * ywt: n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - * fmat: nunstab-by-nunstab z matrix where nunstab is the number of non-stable roots. - * fwt: nunstab-by-m z matrix. -********************************************************************/ - -#ifndef __GENSYS_H__ - #define __GENSYS_H__ - - #include "tzmatlab.h" - - #define REALSMALL 1e-7 - - typedef struct TSgensys_tag { - //=== Output arguments. - TSdmatrix *Theta_dm; //n-by-n. - TSdvector *c_dv; //n-by-1. - TSdmatrix *Impact_dm; //n-by-m. - TSdzmatrix *Fmat_dzm; //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - TSdzmatrix *Fwt_dzm; //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - TSdzmatrix *Ywt_dzm; //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - TSdzmatrix *Gev_dzm; //n-by-2 z matrix of possible complex numbers. - TSivector *eu_iv; //2-by-1. - //=== Function itself. - void (*gensys)(struct TSgensys_tag *, void *); - //=== Input arguments, which are all intialized to 0.0 and whose flags are set to M_GE. - TSdmatrix *G0_dm; //n-by-n. - TSdmatrix *G1_dm; //n-by-n. - TSdvector *c0_dv; //n-by-1. - TSdmatrix *Psi_dm; //n-by-m. - TSdmatrix *Pi_dm; //n-by-k whtere k is the number of expectational errors. - double div; //A real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - } TSgensys; - // - typedef void TFlinratexp(struct TSgensys_tag *, void *); //For linear rational expectations models. - - struct TSgensys_tag *CreateTSgensys(TFlinratexp *func, const int _n, const int _m, const int _k, const double div); - struct TSgensys_tag *DestroyTSgensys(struct TSgensys_tag *gensys_ps); - void gensys_sims(struct TSgensys_tag *gensys_ps, void *dummy_ps); -#endif - diff --git a/CFiles/gensys08Mar06.c b/CFiles/gensys08Mar06.c deleted file mode 100755 index f51c7c689ed749c1e1006944c17f1cf84f301445..0000000000000000000000000000000000000000 --- a/CFiles/gensys08Mar06.c +++ /dev/null @@ -1,1113 +0,0 @@ -/******************************************************************* - * [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensys(g0,g1,c,psi,pi,div) - * - * System given as - * g0*y(t)=g1*y(t-1)+c+psi*z(t)+pi*eta(t), - * with z an exogenous variable process and eta being endogenously determined - * one-step-ahead expectational errors. Returned system is - * y(t)=G1*y(t-1)+C+impact*z(t)+ywt*inv(I-fmat*inv(L))*fwt*z(t+1) . - * If z(t) is i.i.d., the last term drops out. - * If div or stake is omitted from argument list, a div>1 or stake>1 is calculated. - * eu(1)=1 for existence, eu(2)=1 for uniqueness. eu(1)=-1 for - * existence only with not-serially correlated z(t); eu=[-2,-2] for coincident zeros. - * - * g0, g1: n-by-n matrices. - * c: n-by-1 constant terms. - * z(t): m-by-1 vector of exogenous residuals where m < n. - * psi: n-by-m matrix. - * eta(t): h-by-1 vector of expectational (endogenous) errors. - * pi: n-by-h matrix. - * div: a real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - *------- - * G1 or Theta_dm: n-by-n matrices. - * C: n-by-1 vector of constant terms. - * impact: n-by-m matrix. - * gev: n-by-2 z vector of stacked generalized eigenvalues where gev(;,2) ./ gev(:,1) = eig(g0, g1). - * ywt: n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - * fmat: nunstab-by-nunstab z matrix where nunstab is the number of non-stable roots. - * fwt: nunstab-by-m z matrix. - * - * 1996 MATLAB algorithm by Christopher Sims - * 2002 Mex implementation by Iskander Karibzhanov - * 2004 Modified to C function by Tao Zha (April), correcting a few bugs of Iskander. - * 03/01/06 Another modification by Tao Zha, to be consistent with the CAS 3/10/04 correction. - * - * Note: Iskander is transforming g0 and g1 to complex matrices and uses zgges() as a qz decomposition. - * This is really wasting efficiency. One should keep g0 and g1 as real matrices and use - * dgges() as a qz decomposition. I don't have time to overhaul this at this point. 04/20/04, T. Zha. - * Note: 02/22/06. I take the above note back. According to DW, it is easy to *order* the - * the generalized eigenvalues by using the complex g0 and g1. In principle, one could - * order the roots using the real qz decomposition on real matrices g0 and g1. But so far - * Dan has found it a pain to do it. Perhaps we should read the MKL Lapack manual more - * carefully at a later point. -********************************************************************/ -#include "gensys.h" - - -//----- NOTE: We can't replace MKL_Complex16 with a different name because the Intel Lapack uses MKL_Complex16. -//----- The only way to do this is to overhaul the code and put a wrapper function on each Intel Lapack function. -static int selctg(MKL_Complex16 *alpha, MKL_Complex16 *beta); -static int qz(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *q, MKL_Complex16 *z, int n); -static MKL_Complex16* CreateComplexMatrix5RealMatrix(TSdmatrix *X_dm); -static MKL_Complex16* CreateComplexMatrix5RealVector(TSdvector *x_dv); -static void ComplexMatrix2RealMatrix(TSdmatrix *Y_dm, MKL_Complex16 *Z); -static void ComplexMatrix2RealVector(TSdvector *y_dv, MKL_Complex16 *Z); -static TSdzmatrix *SubComplexMatrix2Zmatrix(TSdzmatrix *X_dzm, MKL_Complex16 *Z, const int nrowsforZ, const int _m, const int _n); -static void copy_eigenvalues(TSdzmatrix *Gev_dzm, MKL_Complex16 *a, MKL_Complex16 *b); -static int compute_svd(MKL_Complex16 *a, MKL_Complex16 **u, double **d, MKL_Complex16 **v, int m, int n); -static int compute_norm(MKL_Complex16 *a, double **d, int m, int n); -//--- 03/01/06 TZ. Commented out to be consistent with the CAS 3/10/04 correction. -// static int compute_normx(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *zwt, MKL_Complex16 *ueta, double **normx, int nunstab, int psin, int n, int bigev); -static void cblas_zdupe(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdscali(int n, double *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdscale(int n, double *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdpsb(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb, MKL_Complex16 *c, int ldc); -// -static void InitializeConstantMLK_Complex16(MKL_Complex16 *x_clx, const int _n, const double c); -static void InitializeConstantDouble(double *x_p, const int _n, const double c); - - - -TSgensys *CreateTSgensys(TFlinratexp *func, const int _n, const int _m, const int _k, const double div) -{ - //_n is the number of stacked variables (endogenous, Lagurangian multiplier, expected multiplier, etc.). - //_m is the number of exogenous shocks. - //_k is the number of expectational errors. - //div is the dividing number to determine what constitutes an unstable root. If div<1.0, a div>1.0 is calculated mechanically. - TSgensys *gensys_ps = tzMalloc(1, TSgensys); - - //=== Output arguments. - gensys_ps->Theta_dm = CreateMatrix_lf(_n, _n); //n-by-n. - gensys_ps->c_dv = CreateVector_lf(_n); //n-by-1. - gensys_ps->Impact_dm = CreateMatrix_lf(_n, _m); //n-by-m. - gensys_ps->Fmat_dzm = (TSdzmatrix *)NULL; //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - gensys_ps->Fwt_dzm = (TSdzmatrix *)NULL; //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - gensys_ps->Ywt_dzm = (TSdzmatrix *)NULL; //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - gensys_ps->Gev_dzm = CreateMatrix_dz(_n, 2); //n-by-2 z matrix of possible complex numbers. - gensys_ps->eu_iv = CreateConstantVector_int(2, 0); //2-by-1. - - //=== Function itself. - gensys_ps->gensys = func; - - //=== Input arguments. - gensys_ps->G0_dm = CreateConstantMatrix_lf(_n, _n, 0.0); //n-by-n. - gensys_ps->G0_dm->flag = M_GE; - gensys_ps->G1_dm = CreateConstantMatrix_lf(_n, _n, 0.0); //n-by-n. - gensys_ps->G1_dm->flag = M_GE; - gensys_ps->c0_dv = CreateConstantVector_lf(_n, 0.0); //n-by-1. - gensys_ps->Psi_dm = CreateConstantMatrix_lf(_n, _m, 0.0); //n-by-m. - gensys_ps->Psi_dm->flag = M_GE; - gensys_ps->Pi_dm = CreateConstantMatrix_lf(_n, _k, 0.0); //n-by-k where k is the number of expectational errors. - gensys_ps->Pi_dm->flag = M_GE; - gensys_ps->div = div; - - return (gensys_ps); -} -//------- -TSgensys *DestroyTSgensys(TSgensys *gensys_ps) -{ - if (gensys_ps) { - //=== Output arguments. - DestroyMatrix_lf(gensys_ps->Theta_dm); //n-by-n. - DestroyVector_lf(gensys_ps->c_dv); //n-by-1. - DestroyMatrix_lf(gensys_ps->Impact_dm); //n-by-m. - DestroyMatrix_dz(gensys_ps->Fmat_dzm); //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - DestroyMatrix_dz(gensys_ps->Fwt_dzm); //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - DestroyMatrix_dz(gensys_ps->Ywt_dzm); //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - DestroyMatrix_dz(gensys_ps->Gev_dzm); //n-by-2 z matrix of possible complex numbers. - DestroyVector_int(gensys_ps->eu_iv); //2-by-1. - - //=== Input arguments. - DestroyMatrix_lf(gensys_ps->G0_dm); //n-by-n. - DestroyMatrix_lf(gensys_ps->G1_dm); //n-by-n. - DestroyVector_lf(gensys_ps->c0_dv); //n-by-1. - DestroyMatrix_lf(gensys_ps->Psi_dm); //n-by-m. - DestroyMatrix_lf(gensys_ps->Pi_dm); //n-by-k where k is the number of expectational errors. - - free(gensys_ps); - - return ((TSgensys *)NULL); - } - else return (gensys_ps); -} - - -//--------------------------- For the function gensys_sims() ------------------------------------ -static int fixdiv = 1, zxz = 0; -static double stake = 1.01; -static int nunstab = 0; -static MKL_Complex16 one, minusone, zero; - -/* [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensysmkl(g0,g1,c,psi,pi,stake) */ -//void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { -void gensys_sims(TSgensys *gensys_ps, void *dummy_ps) -{ - int tmpi; - int n, psin, pin, nsquare, md, md1, i, bigev, bigev1; //mds, bigevs, //03/01/06 TZ. Commented out to be consistent with the CAS 3/10/04 correction. - int *eu; - int exist = 0, existx = 0, unique = 0; - //=== Memory will be allocated to the following. - double *deta = NULL, *deta1 = NULL, *norm = NULL; //*normx = NULL, *dz = NULL, //03/01/06 TZ. Commented out to be consistent with the CAS 3/10/04 correction. - MKL_Complex16 *a = NULL, *b = NULL, *q = NULL, *z = NULL, *pi = NULL, *psi = NULL; - MKL_Complex16 *tmat = NULL, *g0 = NULL, *g1 = NULL, *dummy = NULL, *tmatq = NULL, *c = NULL, *impact = NULL, *ab = NULL; - MKL_Complex16 *fmat = NULL, *fwt = NULL, *ywt = NULL; - MKL_Complex16 *etawt = NULL, *ueta = NULL, *veta = NULL, *etawt1 = NULL, *ueta1 = NULL, *veta1 = NULL; - // *uz = NULL, *vz = NULL, *zwt = NULL, //03/01/06 TZ. Commented out to be consistent with the CAS 3/10/04 correction. - //--- Dimensions. - n = gensys_ps->G0_dm->nrows; - psin = gensys_ps->Psi_dm->ncols; - pin = gensys_ps->Pi_dm->ncols; - //--- Pointer. - eu = gensys_ps->eu_iv->v; - - - //=== [a b q z]=qz(g0,g1); - a = CreateComplexMatrix5RealMatrix(gensys_ps->G0_dm); - b = CreateComplexMatrix5RealMatrix(gensys_ps->G1_dm); - q = tzMalloc(nsquare=square(n), MKL_Complex16); - z = tzMalloc(nsquare, MKL_Complex16); - InitializeConstantMLK_Complex16(q, nsquare, 0.0); - InitializeConstantMLK_Complex16(z, nsquare, 0.0); - - fixdiv = (gensys_ps->div < 1.0); - stake = fixdiv ? 1.01 : gensys_ps->div; - nunstab = 0; - zxz = 0; - - if (qz(a, b, q, z, n)) { - printf("WARNING: QZ factorization failed.\n"); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - - nunstab /= 2; - - if (zxz) { - printf("WARNING: Coincident zeros. Indeterminacy and/or nonexistence.\n"); - eu[0] = eu[1] = -2; - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - copy_eigenvalues(gensys_ps->Gev_dzm, a, b); - - one.real = 1.0; - one.imag = 0.0; - - minusone.real = -1.0; - minusone.imag = 0.0; - - zero.real = 0.0; - zero.imag = 0.0; - - pi = CreateComplexMatrix5RealMatrix(gensys_ps->Pi_dm); - etawt = tzMalloc(tmpi=nunstab*pin, MKL_Complex16); - InitializeConstantMLK_Complex16(etawt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, pin, n, - &one, q+n*(n-nunstab), n, pi, n, &zero, etawt, nunstab); - if (compute_svd(etawt, &ueta, &deta, &veta, nunstab, pin)) { - //Memory is now allocated to ueta, deta, and veta. - - //=== DDDDDebugging - fprintf(FPTR_DEBUG, "Aind=[\n"); - WriteMatrix(FPTR_DEBUG, gensys_ps->G0_dm, " %.16e "); - fprintf(FPTR_DEBUG, "];\n"); - fprintf(FPTR_DEBUG, "Bind=[\n"); - WriteMatrix(FPTR_DEBUG, gensys_ps->G1_dm, " %.16e "); - fprintf(FPTR_DEBUG, "];\n"); - fprintf(FPTR_DEBUG, "Consterm=[\n"); - WriteVector(FPTR_DEBUG, gensys_ps->c0_dv, " %.16e "); - fprintf(FPTR_DEBUG, "]';\n"); - fprintf(FPTR_DEBUG, "gUpsiloneind=[\n"); - WriteMatrix(FPTR_DEBUG, gensys_ps->Psi_dm, " %.16e "); - fprintf(FPTR_DEBUG, "];\n"); - fprintf(FPTR_DEBUG, "gUpsilonxind=[\n"); - WriteMatrix(FPTR_DEBUG, gensys_ps->Pi_dm, " %.16e "); - fprintf(FPTR_DEBUG, "];\n"); - fflush(FPTR_DEBUG); - - - printf("WARNING: SVD failed.\n"); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(etawt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(etawt); - md = nunstab<pin?nunstab:pin; - bigev = md; - for (i=0; i<md; i++) - if (deta[i]<=REALSMALL) { - bigev=i; - break; - } - //------ 03/01/06 TZ: corrected code by CAS, 3/10/04. - eu[0] = (bigev >= nunstab); - //--------------------------------- - // ueta = nunstab x bigev - // deta = bigev x 1 - // veta = bigev x pin, ldveta = md - // uz = nunstab x bigevs - // dz = bigevs x 1 - // vz = bigevs x psin, ldvz = mds - //--------------------------------- - - //====== 03/01/06 TZ: the following note is added by CAS 3/10/04. - //------ Code below allowed "existence" in cases where the initial lagged state was free to take on values - //------ inconsistent with existence, so long as the state could w.p.1 remain consistent with a stable solution - //------ if its initial lagged value was consistent with a stable solution. This is a mistake, though perhaps there - //------ are situations where we would like to know that this "existence for restricted initial state" situation holds. - // psi = CreateComplexMatrix5RealMatrix(gensys_ps->Psi_dm); - // zwt = tzMalloc(tmpi=nunstab*psin, MKL_Complex16); - // InitializeConstantMLK_Complex16(zwt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - // cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, psin, n, - // &one, q+n*(n-nunstab), n, psi, n, &zero, zwt, nunstab); - // if (compute_svd(zwt, &uz, &dz, &vz, nunstab, psin)) { - // //Memory is now allocated to uz, dz, and vz. - // printf("WARNING: SV decomposition failed.\n"); - // tzDestroy(ueta); - // tzDestroy(deta); - // tzDestroy(veta); - // tzDestroy(uz); - // tzDestroy(dz); - // tzDestroy(vz); - // tzDestroy(zwt); - // tzDestroy(a); - // tzDestroy(b); - // tzDestroy(q); - // tzDestroy(z); - // return; - // } - // tzDestroy(vz); - // mds = nunstab<psin?nunstab:psin; - // bigevs = mds; - // for (i=0; i<mds; i++) - // if (dz[i]<=REALSMALL) { - // bigevs=i; - // break; - // } - // tzDestroy(dz); - // - // if (!bigevs) { - // exist = 1; - // existx = 1; - // } else { - // /* uz-ueta*ueta'*uz */ - // MKL_Complex16 *tmp = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - // InitializeConstantMLK_Complex16(tmp, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - // cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, nunstab, nunstab, - // bigev, &one, ueta, nunstab, ueta, nunstab, &zero, tmp, nunstab); - // cblas_zhemm(CblasColMajor, CblasLeft, CblasUpper, nunstab, - // bigevs, &minusone, tmp, nunstab, uz, nunstab, &one, uz, nunstab); - // tzDestroy(tmp); - // if (compute_norm(uz, &norm, nunstab, bigevs)) { - // //Memory is now allocated to norm. - // printf("WARNING: SVD failed.\n"); - // tzDestroy(norm); - // tzDestroy(ueta); - // tzDestroy(deta); - // tzDestroy(veta); - // tzDestroy(uz); - // tzDestroy(zwt); - // tzDestroy(a); - // tzDestroy(b); - // tzDestroy(q); - // tzDestroy(z); - // return; - // } - // exist = *norm < REALSMALL*n; - // tzDestroy(norm); - // if (compute_normx(a, b, zwt, ueta, &normx, nunstab, psin, n, bigev)) { - // //If 0, memory is now allocated to normx; otherwise, normx is destroyed within the function compute_normx(). - // tzDestroy(ueta); - // tzDestroy(deta); - // tzDestroy(veta); - // tzDestroy(uz); - // tzDestroy(zwt); - // tzDestroy(a); - // tzDestroy(b); - // tzDestroy(q); - // tzDestroy(z); - // return; - // } - // existx = *normx < REALSMALL*n; - // tzDestroy(normx); - // } - // - // tzDestroy(uz); - // tzDestroy(zwt); - - //--------------------------------------------------------------------------- - // Note that existence and uniqueness are not just matters of comparing - // numbers of roots and numbers of endogenous errors. These counts are - // reported below because usually they point to the source of the problem. - //--------------------------------------------------------------------------- - etawt1 = tzMalloc(tmpi=(n-nunstab)*pin, MKL_Complex16); - InitializeConstantMLK_Complex16(etawt1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, n-nunstab, pin, n, - &one, q, n, pi, n, &zero, etawt1, n-nunstab); - tzDestroy(pi); - if (compute_svd(etawt1, &ueta1, &deta1, &veta1, n-nunstab, pin)) { - //Memory is now allocated to ueta1, deta1, and veta1. - printf("WARNING: SVD failed for compute_svd().\n"); - tzDestroy(ueta1); - tzDestroy(deta1); - tzDestroy(veta1); - tzDestroy(etawt1); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(etawt1); - md1 = n-nunstab<pin?n-nunstab:pin; - bigev1 = md1; - for (i=0; i<md1; i++) - if (deta1[i]<=REALSMALL) { - bigev1=i; - break; - } - - //====== 03/01/06 TZ: the following is commented out by CAS 3/10/04. - // if (existx || !nunstab) { - // //=== Solution exists. - // eu[0] = 1; - // } else { - // if (exist) { - // printf("WARNING: Solution exists for unforecastable z only\n"); - // eu[0] = -1; - // } /* else - // mexPrintf("No solution. %d unstable roots. %d endog errors.\n",nunstab,bigev1); */ - // /* mexPrintf("Generalized eigenvalues\n"); - // mexCallMATLAB(0,NULL,1, &plhs[6], "disp"); */ - // } - - - //------------------------------- - // ueta1 = n-nunstab x bigev1 - // deta1 = bigev1 x 1 - // veta1 = bigev1 x pin, ldveta1 = md1 - //------------------------------- - if (!bigev1) - unique = 1; - else { - // veta1-veta1*veta*veta' - // veta = bigev x pin, ldveta1 = md - // veta1 = bigev1 x pin, ldveta1 = md1 - MKL_Complex16 *tmp = tzMalloc(pin*pin, MKL_Complex16); - MKL_Complex16 *veta1_copy = tzMalloc(pin*bigev1, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, pin*pin, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - InitializeConstantMLK_Complex16(veta1_copy, pin*bigev1, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, pin, pin, - bigev, &one, veta, md, veta, md, &zero, tmp, pin); - cblas_zdupe(bigev1,pin,veta1,md1,veta1_copy,bigev1); - cblas_zhemm(CblasColMajor, CblasRight, CblasUpper, bigev1, pin, - &minusone, tmp, pin, veta1_copy, bigev1, &one, veta1_copy, bigev1); - tzDestroy(tmp); - if (compute_norm(veta1_copy, &norm, bigev1, pin)) { - //Memory is now allocated to norm. - printf("WARNING: SVD failed.\n"); - tzDestroy(norm); - tzDestroy(ueta1); - tzDestroy(deta1); - tzDestroy(veta1); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(veta1_copy); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(veta1_copy); - unique = *norm < REALSMALL*n; - tzDestroy(norm); - } - if (unique) { - //=== Unique solution. - eu[1] = 1; - } else { - eu[1] = 0; - printf("WARNING: Indeterminacy. %d loose endog errors with eu being [%d, %d].\n",bigev1-bigev, eu[0], eu[1]); - //printf("WARNING: Indeterminacy. %d loose endog errors with eu being [%g, %g].\n",bigev1-bigev, gensys_ps->eu_dv->v[0], gensys_ps->eu_dv->v[1]); - //printf("WARNING: Indeterminacy. %d loose endog errors.\n",bigev1-bigev); - } - - cblas_zdscali(pin,deta,bigev,veta,md); /* veta' = deta\veta' */ - tzDestroy(deta); - cblas_zdscale(pin,deta1,bigev1,veta1,md1); /* veta1' = deta1*veta1' */ - tzDestroy(deta1); - etawt = tzMalloc(tmpi=nunstab*pin, MKL_Complex16); /* etawt = ueta*veta' */ - InitializeConstantMLK_Complex16(etawt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, nunstab, pin, bigev, - &one, ueta, nunstab, veta, md, &zero, etawt, nunstab); - tzDestroy(ueta); - tzDestroy(veta); - etawt1 = tzMalloc(tmpi=(n-nunstab)*pin, MKL_Complex16); /* etawt1 = ueta1*veta1' */ - InitializeConstantMLK_Complex16(etawt1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, pin, bigev1, - &one, ueta1, n-nunstab, veta1, md1, &zero, etawt1, n-nunstab); - tzDestroy(ueta1); - tzDestroy(veta1); - tmat = tzMalloc(tmpi=(n-nunstab)*nunstab, MKL_Complex16); /* tmat = etawt1*etawt' */ - InitializeConstantMLK_Complex16(tmat, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n-nunstab, nunstab, pin, - &one, etawt1, n-nunstab, etawt, nunstab, &zero, tmat, n-nunstab); - tzDestroy(etawt1); - tzDestroy(etawt); - - g0 = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(g0, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdupe(n-nunstab, n, a, n, g0, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, nunstab, nunstab, - &minusone, tmat, n-nunstab, a+(n-nunstab)*(n+1), n, &one, g0+(n-nunstab)*n, n); - cblas_zcopy(nunstab, &one, 0, g0+(n-nunstab)*(n+1), n+1); - - g1 = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(g1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdupe(n-nunstab, n, b, n, g1, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, nunstab, nunstab, - &minusone, tmat, n-nunstab, b+(n-nunstab)*(n+1), n, &one, g1+(n-nunstab)*n, n); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, n, &one, g0, n, g1, n); - dummy = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, n, n, &one, z, n, g1, n, &zero, dummy, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n, n, n, &one, dummy, n, z, n, &zero, g1, n); - tzDestroy(dummy); - ComplexMatrix2RealMatrix(gensys_ps->Theta_dm, g1); //Output. - tzDestroy(g1); - - tmatq = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(tmatq, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zcopy(n*n, q, 1, tmatq, 1); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n, n-nunstab, nunstab, - &minusone, tmatq+(n-nunstab)*n, n, tmat, n-nunstab, &one, tmatq, n); - tzDestroy(tmat); - - ab = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(ab, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdpsb(nunstab, nunstab, a+(n-nunstab)*(n+1), n, b+(n-nunstab)*(n+1), n, ab, nunstab); - cblas_ztrsm(CblasColMajor, CblasRight, CblasUpper, CblasConjTrans, CblasNonUnit, - n, nunstab, &one, ab, nunstab, tmatq+(n-nunstab)*n, n); - tzDestroy(ab); - - //c = mat2mkl(prhs[2],n,1); - c = CreateComplexMatrix5RealVector(gensys_ps->c0_dv); - dummy = tzMalloc(gensys_ps->c0_dv->n, MKL_Complex16); - //$$$$$$$ The following is Iskander's fatal code error. One cannot use c in the two different places; otherwise, it makes c be zero completely! - // cblas_zgemv(CblasColMajor, CblasConjTrans, n, n, &one, tmatq, n, c, 1, &zero, c, 1); - // cblas_ztrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, n, g0, n, c, 1); - // cblas_zgemv(CblasColMajor, CblasNoTrans, n, n, &one, z, n, c, 1, &zero, c, 1); - cblas_zgemv(CblasColMajor, CblasConjTrans, n, n, &one, tmatq, n, c, 1, &zero, dummy, 1); - cblas_ztrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, n, g0, n, dummy, 1); - cblas_zgemv(CblasColMajor, CblasNoTrans, n, n, &one, z, n, dummy, 1, &zero, c, 1); - //plhs[1] = mkl2mat_real(c, n, n, 1); - ComplexMatrix2RealVector(gensys_ps->c_dv, c); //Output. - tzDestroy(c); - tzDestroy(dummy); - - impact = tzMalloc(tmpi=n*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(impact, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - psi = CreateComplexMatrix5RealMatrix(gensys_ps->Psi_dm); //03/01/06 TZ. Added to be consistent with the CAS 3/10/04 correction. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, n-nunstab, psin, n, - &one, tmatq, n, psi, n, &zero, impact, n); - tzDestroy(tmatq); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, psin, &one, g0, n, impact, n); - dummy = tzMalloc(tmpi=n*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, psin, n, - &one, z, n, impact, n, &zero, dummy, n); - tzDestroy(impact); - //plhs[2] = mkl2mat_real(dummy, n, n, psin); - ComplexMatrix2RealMatrix(gensys_ps->Impact_dm, dummy); //Output. - tzDestroy(dummy); - - fmat = a+(n-nunstab)*(n+1); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, nunstab, &one, b+(n-nunstab)*(n+1), n, fmat, n); - //plhs[3] = mkl2mat(fmat, n, nunstab, nunstab); - gensys_ps->Fmat_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Fmat_dzm, fmat, n, nunstab, nunstab); - tzDestroy(a); - - fwt = tzMalloc(tmpi=nunstab*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(fwt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_ztrsm(CblasColMajor, CblasRight, CblasUpper, CblasConjTrans, CblasNonUnit, - n, nunstab, &one, b+(n-nunstab)*(n+1), n, q+(n-nunstab)*n, n); - tzDestroy(b); - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, psin, n, - &minusone, q+(n-nunstab)*n, n, psi, n, &zero, fwt, nunstab); - tzDestroy(q); - tzDestroy(psi); - gensys_ps->Fwt_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Fwt_dzm, fwt, nunstab, nunstab, psin); - tzDestroy(fwt); - - ywt = tzMalloc(tmpi=n*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(ywt, tmpi, 0.0); - cblas_zcopy(nunstab, &one, 0, ywt+n-nunstab, n+1); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, nunstab, &one, g0, n, ywt, n); - tzDestroy(g0); - dummy = tzMalloc(tmpi=n*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, nunstab, n, - &one, z, n, ywt, n, &zero, dummy, n); - tzDestroy(z); - tzDestroy(ywt); - gensys_ps->Ywt_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Ywt_dzm, dummy, n, n, nunstab); - tzDestroy(dummy); -} - - -/****************************************************************************** - * function selctg orders the eigenvalues so that a selected cluster of * - * eigenvalues appears in the leading diagonal blocks of the upper * - * quasi-triangular matrix S and the upper triangular matrix T. * - ******************************************************************************/ - -static int selctg(MKL_Complex16 *alpha, MKL_Complex16 *beta) -{ - double absA = sqrt(alpha->real*alpha->real+alpha->imag*alpha->imag), - absB = fabs(beta->real); - if (absA) { - double divhat = absB/absA; - //bug detected by Vasco Curdia and Daria Finocchiaro, 2/25/2004 CAS. A root of - //exactly 1.01 and no root between 1 and 1.02, led to div being stuck at 1.01 - //and the 1.01 root being misclassified as stable. Changing < to <= below fixes this. - if (fixdiv && 1+REALSMALL<divhat && divhat<=stake) - stake = (1+divhat)/2; - } - if (absA<REALSMALL && absB<REALSMALL) - zxz = 1; - if (absB>stake*absA) { - nunstab++; - return(0); - } else - return(1); -} - -/****************************************************************************** - * compute for a pair of N-by-N complex nonsymmetric matrices (A,B), * - * the generalized eigenvalues, the generalized complex Schur form (S, T), * - * and optionally left and/or right Schur vectors (VSL and VSR) * - ******************************************************************************/ - -static int qz(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *q, MKL_Complex16 *z, int n) -{ -// unsigned char msg[101]; - int sdim, lwork = -1, info = 0; - MKL_Complex16 *alpha = tzMalloc(n,MKL_Complex16), - *beta = tzMalloc(n,MKL_Complex16), - *work, work1; - double *rwork = tzMalloc(8*n, double); - int *bwork = tzMalloc(4*n, int); - - /* Query zgges on the value of lwork */ - zgges("V", "V", "S", &selctg, &n, a, &n, b, &n, &sdim, alpha, beta, q, - &n, z, &n, &work1, &lwork, rwork, bwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to the Intel MKL function zgges() has an illegal value",-info); - tzDestroy(bwork); - tzDestroy(rwork); - tzDestroy(alpha); - tzDestroy(beta); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgges("V", "V", "S", &selctg, &n, a, &n, b, &n, &sdim, alpha, beta, q, - &n, z, &n, work, &lwork, rwork, bwork, &info); - - tzDestroy(work); - tzDestroy(bwork); - tzDestroy(rwork); - tzDestroy(alpha); - tzDestroy(beta); - - if (info < 0) { - printf("WARNING: Input %d to the Intel MKL function zgges() has an illegal value",-info); - return(info); - } - - if (info > 0) - if (info < n) - printf("WARNING: The QZ iteration failed. (A,B) are not in Schur form,\n" - "but ALPHA(j) and BETA(j) should be correct for j=%d,...,N.",info+1); - else { - switch (info-n) { - case 1: - printf("WARNING: LAPACK problem: error return from ZGGBAL"); - break; - case 2: - printf("WARNING: LAPACK problem: error return from ZGEQRF"); - break; - case 3: - printf("WARNING: LAPACK problem: error return from ZUNMQR"); - break; - case 4: - printf("WARNING: LAPACK problem: error return from ZUNGQR"); - break; - case 5: - printf("WARNING: LAPACK problem: error return from ZGGHRD"); - break; - case 6: - printf("WARNING: LAPACK problem: error return from ZHGEQZ (other than failed iteration)"); - break; - case 7: - printf("WARNING: LAPACK problem: error return from ZGGBAK (computing VSL)"); - break; - case 8: - printf("WARNING: LAPACK problem: error return from ZGGBAK (computing VSR)"); - break; - case 9: - printf("WARNING: LAPACK problem: error return from ZLASCL (various places)"); - break; - default: - printf("WARNING: LAPACK problem: unknown error."); - break; - } - } - return(info); -} - -/* - * Convert MATLAB complex matrix to MKL complex storage. - * - * Z = mat2mkl(X,ldz,ndz) - * - * converts MATLAB's mxArray X to MKL_Complex16 Z(ldz,ndz). - * The parameters ldz and ndz determine the storage allocated for Z, - * while mxGetM(X) and mxGetN(X) determine the amount of data copied. - */ - -//MKL_Complex16* mat2mkl(const mxArray *X, int ldz, int ndz) { -// MKL_Complex16 *Z, *zp; -// int m, n, incz, cmplxflag; -// register int i, j; -// double *xr, *xi; - -// Z = mxCalloc(ldz*ndz, sizeof(MKL_Complex16)); -// xr = mxGetPr(X); -// xi = mxGetPi(X); -// m = mxGetM(X); -// n = mxGetN(X); -// zp = Z; -// incz = ldz-m; -// cmplxflag = (xi != NULL); -// for (j = 0; j < n; j++) { -// if (cmplxflag) { -// for (i = 0; i < m; i++) { -// zp->real = *xr++; -// zp->imag = *xi++; -// zp++; -// } -// } else { -// for (i = 0; i < m; i++) { -// zp->real = *xr++; -// zp++; -// } -// } -// zp += incz; -// } -// return(Z); -//} - - -/* - * Convert MKL complex storage to MATLAB real and imaginary parts. - * - * X = mkl2mat(Z,ldz,m,n) - * - * copies MKL_Complex16 Z to X, producing a complex mxArray - * with mxGetM(X) = m and mxGetN(X) = n. - */ - -//mxArray* mkl2mat(MKL_Complex16 *Z, int ldz, int m, int n) { -// int i, j, incz; -// double *xr, *xi; -// MKL_Complex16 *zp; -// mxArray *X; - -// X = mxCreateDoubleMatrix(m,n,mxCOMPLEX); -// xr = mxGetPr(X); -// xi = mxGetPi(X); -// zp = Z; -// incz = ldz-m; -// for (j = 0; j < n; j++) { -// for (i = 0; i < m; i++) { -// *xr++ = zp->real; -// *xi++ = zp->imag; -// zp++; -// } -// zp += incz; -// } -// return(X); -//} - -//plhs[3] = mkl2mat(fmat, n, nunstab, nunstab) - -/* - * Convert MKL complex storage to MATLAB real matrix ignoring imaginary part. - * - * X = mkl2mat(Z,ldz,m,n) - * - * copies MKL_Complex16 Z to X, producing a real mxArray - * with mxGetM(X) = m and mxGetN(X) = n. - */ - -//mxArray* mkl2mat_real(MKL_Complex16 *Z, int ldz, int m, int n) { -// int i, j, incz; -// double *xr; -// MKL_Complex16 *zp; -// mxArray *X; - -// X = mxCreateDoubleMatrix(m,n,mxREAL); -// xr = mxGetPr(X); -// zp = Z; -// incz = ldz-m; -// for (j = 0; j < n; j++) { -// for (i = 0; i < m; i++) { -// *xr++ = zp->real; -// zp++; -// } -// zp += incz; -// } -// return(X); -//} - -//void copy_eigenvalues(mxArray *gev, MKL_Complex16 *a, MKL_Complex16 *b, int n) { -// double *gevr = mxGetPr(gev), -// *gevi = mxGetPi(gev); -// int i; - -// for (i=0; i<n; i++, gevr++, gevi++, a+=n+1) { -// *gevr = a->real; -// *gevi = a->imag; -// } - -// for (i=0; i<n; i++, gevr++, gevi++, b+=n+1) { -// *gevr = b->real; -// *gevi = b->imag; -// } -//} - -static void copy_eigenvalues(TSdzmatrix *Gev_dzm, MKL_Complex16 *a, MKL_Complex16 *b) -{ - int n = Gev_dzm->real->nrows; - double *gevr = Gev_dzm->real->M, - *gevi = Gev_dzm->imag->M; - int i; - - for (i=0; i<n; i++, gevr++, gevi++, a+=n+1) { - *gevr = a->real; - *gevi = a->imag; - } - - for (i=0; i<n; i++, gevr++, gevi++, b+=n+1) { - *gevr = b->real; - *gevi = b->imag; - } -} - - -static int compute_svd(MKL_Complex16 *x, MKL_Complex16 **u, double **d, MKL_Complex16 **v, int m, int n) -{ - //$$$Memory allocated to u, d, and v will be destroyed outside this function.$$$ - int tmpi; - int md = m<n?m:n, lwork = -1, info = 0; - MKL_Complex16 *a, *work, work1; - double *rwork = tzMalloc(5*md>1?5*md:1, double); - - a = tzMalloc(m*n, MKL_Complex16); - cblas_zcopy(m*n, x, 1, a, 1); - - *u = tzMalloc(tmpi=m*md,MKL_Complex16); - InitializeConstantMLK_Complex16(*u, tmpi, 0.0); - *v = tzMalloc(tmpi=md*n, MKL_Complex16); - InitializeConstantMLK_Complex16(*v, tmpi, 0.0); - *d = tzMalloc(md, double); - InitializeConstantDouble(*d, md, 0.0); - - /* Query zgges on the value of lwork */ - zgesvd("S", "S", &m, &n, a, &m, *d, *u, &m, *v, &md, &work1, &lwork, rwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - tzDestroy(rwork); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgesvd("S", "S", &m, &n, a, &m, *d, *u, &m, *v, &md, work, &lwork, rwork, &info); - - tzDestroy(work); - tzDestroy(rwork); - tzDestroy(a); - - if (info < 0) - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - - if (info > 0) - printf("WARNING: ZBDSQR did not converge.\n%d superdiagonals of an intermediate " - "bidiagonal form B did not converge to zero.",info); - return(info); -} - -static int compute_norm(MKL_Complex16 *a, double **d, int m, int n) -{ - //Memory will be allocated to d, which will be destroyed outside this function. - int md = m<n?m:n, lwork = -1, info = 0; - MKL_Complex16 *work = NULL, work1; - double *rwork = tzMalloc(5*md>1?5*md:1, double); - - *d = tzMalloc(md, double); - - /* Query zgges on the value of lwork */ - zgesvd("N", "N", &m, &n, a, &m, *d, NULL, &m, NULL, &md, &work1, &lwork, rwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - tzDestroy(rwork); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgesvd("N", "N", &m, &n, a, &m, *d, NULL, &m, NULL, &md, work, &lwork, rwork, &info); - - tzDestroy(work); - tzDestroy(rwork); - - if (info < 0) - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - - if (info > 0) - printf("WARNING: ZBDSQR() in Intel MKL did not converge.\n%d superdiagonals of an intermediate " - "bidiagonal form B did not converge to zero.",info); - - return(info); -} - - -//======= 03/01/06 TZ. Commented out to be consistent with the CAS 3/10/04 correction. =======// -//static int compute_normx(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *zwt, MKL_Complex16 *ueta, double **normx, int nunstab, int psin, int n, int bigev) -//{ -// //Memory is allocated to normx, which will be freed outside this function. -// int tmpi; -// int info = 0, i, bigevs; -// // -// MKL_Complex16 *M = NULL, *zwtx = NULL, *ux = NULL, *vx = NULL, *tmp = NULL; -// double *dx = NULL; - - -// a += (n+1)*(n-nunstab); -// b += (n+1)*(n-nunstab); -// cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, -// nunstab, psin, &one, b, n, zwt, nunstab); -// M = tzMalloc(nunstab*nunstab, MKL_Complex16); -// cblas_zdupe(nunstab, nunstab, a, n, M, nunstab); -// cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, -// nunstab, nunstab, &one, b, n, M, nunstab); - -// zwtx = tzMalloc(nunstab*nunstab*psin, MKL_Complex16); -// cblas_zcopy(nunstab*psin, zwt, 1, zwtx, 1); -// for (i=1; i<nunstab; i++) { -// cblas_ztrmm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, nunstab, psin*i, &one, M, nunstab, zwtx, nunstab); -// cblas_zcopy(nunstab*psin, zwt, 1, zwtx+nunstab*psin*i, 1); -// } -// tzDestroy(M); -// cblas_ztrmm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, nunstab, nunstab*psin, &one, b, n, zwtx, nunstab); -// info = compute_svd(zwtx, &ux, &dx, &vx, nunstab, nunstab*psin); //Memory is allocated to ux, dx, and vx. -// tzDestroy(vx); -// tzDestroy(zwtx); -// if (info) { -// printf("WARNING: SVD failed.\n"); -// tzDestroy(ux); -// tzDestroy(dx); -// return(info); -// } -// bigevs = nunstab; -// for (i=0; i<nunstab; i++) -// if (dx[i]<=REALSMALL) { -// bigevs = i; -// break; -// } -// tzDestroy(dx); -// /* ux-ueta*ueta'*ux */ -// tmp = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); -// InitializeConstantMLK_Complex16(tmp, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. -// cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, nunstab, nunstab, -// bigev, &one, ueta, nunstab, ueta, nunstab, &zero, tmp, nunstab); -// cblas_zhemm(CblasColMajor, CblasLeft, CblasUpper, nunstab, -// bigevs, &minusone, tmp, nunstab, ux, nunstab, &one, ux, nunstab); -// tzDestroy(tmp); -// info = compute_norm(ux, normx, nunstab, bigevs); //Memory is allocated to normx. -// if (info) { -// printf("WARNING: SVD failed.\n"); -// tzDestroy(normx); -// tzDestroy(ux); -// return(info); -// } -// tzDestroy(ux); -// return(info); -//} - -static void cblas_zdupe(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<m; i++, a++, b++) - cblas_zcopy(n, a, lda, b, ldb); -} - -static void cblas_zdscali(int n, double *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<lda; i++, a++, b++) - cblas_zdscal(n, 1.0/(*a), b, ldb); -} - -static void cblas_zdscale(int n, double *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<lda; i++, a++, b++) - cblas_zdscal(n, *a, b, ldb); -} - -static void cblas_zdpsb(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb, MKL_Complex16 *c, int ldc) -{ - int i; - cblas_zdupe(m, n, a, lda, c, ldc); - for (i=0; i<m; i++, b++, c++) - cblas_zaxpy(n, &minusone, b, ldb, c, ldc); -} - - -static MKL_Complex16* CreateComplexMatrix5RealMatrix(TSdmatrix *X_dm) -{ - int mn, k; - double *M; - // - MKL_Complex16 *Z = NULL; - - if (!X_dm) fn_DisplayError("CreateComplexMatrix5RealMatrix(): Input matrix X_dm must be allocated memory"); - M = X_dm->M; - - Z = tzMalloc(mn=X_dm->nrows*X_dm->ncols, MKL_Complex16); - for (k=mn-1; k>=0; k--) { - Z[k].real = M[k]; - Z[k].imag = 0.0; - } - return(Z); -} - -static MKL_Complex16* CreateComplexMatrix5RealVector(TSdvector *x_dv) -{ - int n, k; - double *v; - // - MKL_Complex16 *Z = NULL; - - if (!x_dv) fn_DisplayError("CreateComplexMatrix5RealVector(): Input vector x_dv must be allocated memory"); - v = x_dv->v; - - Z = tzMalloc(n=x_dv->n, MKL_Complex16); - for (k=n-1; k>=0; k--) { - Z[k].real = v[k]; - Z[k].imag = 0.0; - } - return(Z); -} - - -static void ComplexMatrix2RealMatrix(TSdmatrix *Y_dm, MKL_Complex16 *Z) -{ - int _k; - double *M; - - if (!Y_dm) fn_DisplayError("ComplexMatrix2RealMatrix(): Output matrix Y_dm must be allocated memory"); - M = Y_dm->M; - - for (_k=Y_dm->nrows*Y_dm->ncols-1; _k>=0; _k--) M[_k] = Z[_k].real; - Y_dm->flag = M_GE; -} - - -static void ComplexMatrix2RealVector(TSdvector *y_dv, MKL_Complex16 *Z) -{ - int _k; - double *v; - - if (!y_dv) fn_DisplayError("ComplexMatrix2RealVector(): Output matrix y_dv must be allocated memory"); - v = y_dv->v; - - for (_k=y_dv->n-1; _k>=0; _k--) v[_k] = Z[_k].real; - y_dv->flag = V_DEF; -} - - -static TSdzmatrix *SubComplexMatrix2Zmatrix(TSdzmatrix *X_dzm, MKL_Complex16 *Z, const int nrowsforZ, const int _m, const int _n) -{ - //X_dzm is _m-by_n comlex types where nrowsforZ <= _m and Z is nrowsforZ-by-_n. - int _i, _j, incz; - double *Mreal, *Mimag; - MKL_Complex16 *zp; - // - TSdzmatrix *Y_dzm = NULL; - - if (!X_dzm || X_dzm->real->nrows != _m || X_dzm->real->ncols != _n) { - DestroyMatrix_dz(X_dzm); //Destroys Y_dzm if already allocated memory to accommodate a possbible change of its dimension. - Y_dzm = CreateMatrix_dz(_m, _n); - } - else Y_dzm = X_dzm; - - Mreal = Y_dzm->real->M; - Mimag = Y_dzm->imag->M; - zp = Z; - if ((incz=nrowsforZ-_m)<0) fn_DisplayError("SubComplexMatrix2ZMatrix(): Number of rows for the input complex matrix Z must be greater that of the output Z matrix Y_dzm"); - - for (_j=0; _j<_n; _j++) { - for (_i=0; _i<_m; _i++) { - *Mreal++ = zp->real; - *Mimag++ = zp->imag; - zp++; - } - zp += incz; - } - return (Y_dzm); -} - - -static void InitializeConstantMLK_Complex16(MKL_Complex16 *x_clx, const int _n, const double c) -{ - int _i; - - for (_i=_n-1; _i>=0; _i--) - x_clx[_i].real = x_clx[_i].imag = c; -} - -static void InitializeConstantDouble(double *x_p, const int _n, const double c) -{ - int _i; - - for (_i=_n-1; _i>=0; _i--) x_p[_i] = c; -} diff --git a/CFiles/gensysOldVersionWorks.c b/CFiles/gensysOldVersionWorks.c deleted file mode 100755 index c78aa433f315a559198ce5943669d28beb5939b8..0000000000000000000000000000000000000000 --- a/CFiles/gensysOldVersionWorks.c +++ /dev/null @@ -1,1114 +0,0 @@ -/******************************************************************* - * [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensys(g0,g1,c,psi,pi,div) - * - * System given as - * g0*y(t)=g1*y(t-1)+c+psi*z(t)+pi*eta(t), - * with z an exogenous variable process and eta being endogenously determined - * one-step-ahead expectational errors. Returned system is - * y(t)=G1*y(t-1)+C+impact*z(t)+ywt*inv(I-fmat*inv(L))*fwt*z(t+1) . - * If z(t) is i.i.d., the last term drops out. - * If div or stake is omitted from argument list, a div>1 or stake>1 is calculated. - * eu(1)=1 for existence, eu(2)=1 for uniqueness. eu(1)=-1 for - * existence only with not-serially correlated z(t); eu=[-2,-2] for coincident zeros. - * - * g0, g1: n-by-n matrices. - * c: n-by-1 constant terms. - * z(t): m-by-1 vector of exogenous residuals where m < n. - * psi: n-by-m matrix. - * eta(t): h-by-1 vector of expectational (endogenous) errors. - * pi: n-by-h matrix. - * div: a real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - *------- - * G1 or Theta_dm: n-by-n matrices. - * C: n-by-1 vector of constant terms. - * impact: n-by-m matrix. - * gev: n-by-2 z vector of stacked generalized eigenvalues where gev(;,2) ./ gev(:,1) = eig(g0, g1). - * ywt: n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - * fmat: nunstab-by-nunstab z matrix where nunstab is the number of non-stable roots. - * fwt: nunstab-by-m z matrix. - * - * 1996 MATLAB algorithm by Christopher Sims - * 2002 Mex implementation by Iskander Karibzhanov - * 2004 Modified to C function by Tao Zha (April) - * - * Note: Iskander is transforming g0 and g1 to complex matrices and uses zgges() as a qz decomposition. - * This is really wasting efficiency. One should keep g0 and g1 as real matrices and use - * dgges() as a qz decomposition. I don't have time to overhaul this at this point. 04/20/04, T. Zha. - * Note: 02/22/06. I take the above note back. According to DW, it is easy to order the - * the generalized eigenvalues by using the complex g0 and g1. In principle, one could - * order the roots using the real qz decomposition on real matrices g0 and g1. But so far - * Dan has found it a pain to do it. Perhaps we should read the MKL Lapack manual more - * carefully at a later point. -********************************************************************/ - -#include "gensys.h" - - -//----- NOTE: We can't replace MKL_Complex16 with a different name because the Intel Lapack uses MKL_Complex16. -//----- The only way to do this is to overhaul the code and put a wrapper function on each Intel Lapack function. -static int selctg(MKL_Complex16 *alpha, MKL_Complex16 *beta); -static int qz(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *q, MKL_Complex16 *z, int n); -static MKL_Complex16* CreateComplexMatrix5RealMatrix(TSdmatrix *X_dm); -static MKL_Complex16* CreateComplexMatrix5RealVector(TSdvector *x_dv); -static void ComplexMatrix2RealMatrix(TSdmatrix *Y_dm, MKL_Complex16 *Z); -static void ComplexMatrix2RealVector(TSdvector *y_dv, MKL_Complex16 *Z); -static TSdzmatrix *SubComplexMatrix2Zmatrix(TSdzmatrix *X_dzm, MKL_Complex16 *Z, const int nrowsforZ, const int _m, const int _n); -static void copy_eigenvalues(TSdzmatrix *Gev_dzm, MKL_Complex16 *a, MKL_Complex16 *b); -static int compute_svd(MKL_Complex16 *a, MKL_Complex16 **u, double **d, MKL_Complex16 **v, int m, int n); -static int compute_norm(MKL_Complex16 *a, double **d, int m, int n); -// -static int compute_normx(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *zwt, MKL_Complex16 *ueta, double **normx, int nunstab, int psin, int n, int bigev); -static void cblas_zdupe(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdscali(int n, double *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdscale(int n, double *a, int lda, MKL_Complex16 *b, int ldb); -static void cblas_zdpsb(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb, MKL_Complex16 *c, int ldc); -// -static void InitializeConstantMLK_Complex16(MKL_Complex16 *x_clx, const int _n, const double c); -static void InitializeConstantDouble(double *x_p, const int _n, const double c); - - - -TSgensys *CreateTSgensys(TFlinratexp *func, const int _n, const int _m, const int _k, const double div) -{ - //_n is the number of stacked variables (endogenous, Lagurangian multiplier, expected multiplier, etc.). - //_m is the number of exogenous shocks. - //_k is the number of expectational errors. - //div is the dividing number to determine what constitutes an unstable root. If div<1.0, a div>1.0 is calculated mechanically. - TSgensys *gensys_ps = tzMalloc(1, TSgensys); - - //=== Output arguments. - gensys_ps->Theta_dm = CreateMatrix_lf(_n, _n); //n-by-n. - gensys_ps->c_dv = CreateVector_lf(_n); //n-by-1. - gensys_ps->Impact_dm = CreateMatrix_lf(_n, _m); //n-by-m. - gensys_ps->Fmat_dzm = (TSdzmatrix *)NULL; //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - gensys_ps->Fwt_dzm = (TSdzmatrix *)NULL; //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - gensys_ps->Ywt_dzm = (TSdzmatrix *)NULL; //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - gensys_ps->Gev_dzm = CreateMatrix_dz(_n, 2); //n-by-2 z matrix of possible complex numbers. - gensys_ps->eu_dv = CreateConstantVector_lf(2, 0.0); //2-by-1. - - //=== Function itself. - gensys_ps->gensys = func; - - //=== Input arguments. - gensys_ps->G0_dm = CreateConstantMatrix_lf(_n, _n, 0.0); //n-by-n. - gensys_ps->G0_dm->flag = M_GE; - gensys_ps->G1_dm = CreateConstantMatrix_lf(_n, _n, 0.0); //n-by-n. - gensys_ps->G1_dm->flag = M_GE; - gensys_ps->c0_dv = CreateConstantVector_lf(_n, 0.0); //n-by-1. - gensys_ps->Psi_dm = CreateConstantMatrix_lf(_n, _m, 0.0); //n-by-m. - gensys_ps->Psi_dm->flag = M_GE; - gensys_ps->Pi_dm = CreateConstantMatrix_lf(_n, _k, 0.0); //n-by-k where k is the number of expectational errors. - gensys_ps->Pi_dm->flag = M_GE; - gensys_ps->div = div; - - return (gensys_ps); -} -//------- -TSgensys *DestroyTSgensys(TSgensys *gensys_ps) -{ - if (gensys_ps) { - //=== Output arguments. - DestroyMatrix_lf(gensys_ps->Theta_dm); //n-by-n. - DestroyVector_lf(gensys_ps->c_dv); //n-by-1. - DestroyMatrix_lf(gensys_ps->Impact_dm); //n-by-m. - DestroyMatrix_dz(gensys_ps->Fmat_dzm); //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - DestroyMatrix_dz(gensys_ps->Fwt_dzm); //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - DestroyMatrix_dz(gensys_ps->Ywt_dzm); //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - DestroyMatrix_dz(gensys_ps->Gev_dzm); //n-by-2 z matrix of possible complex numbers. - DestroyVector_lf(gensys_ps->eu_dv); //2-by-1. - - //=== Input arguments. - DestroyMatrix_lf(gensys_ps->G0_dm); //n-by-n. - DestroyMatrix_lf(gensys_ps->G1_dm); //n-by-n. - DestroyVector_lf(gensys_ps->c0_dv); //n-by-1. - DestroyMatrix_lf(gensys_ps->Psi_dm); //n-by-m. - DestroyMatrix_lf(gensys_ps->Pi_dm); //n-by-k where k is the number of expectational errors. - - free(gensys_ps); - - return ((TSgensys *)NULL); - } - else return (gensys_ps); -} - - -//--------------------------- For the function gensys_sims() ------------------------------------ -static int fixdiv = 1, zxz = 0; -static double stake = 1.01; -static int nunstab = 0; -static MKL_Complex16 one, minusone, zero; - -/* [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensysmkl(g0,g1,c,psi,pi,stake) */ -//void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { -void gensys_sims(TSgensys *gensys_ps, void *dummy_ps) -{ - int tmpi; - int n, psin, pin, nsquare, md, mds, md1, i, bigev, bigevs, bigev1; - double *eu; - int exist = 0, existx = 0, unique = 0; - //=== Memory will be allocated to the following. - double *deta = NULL, *dz = NULL, *normx = NULL, *deta1 = NULL, *norm = NULL; - MKL_Complex16 *a = NULL, *b = NULL, *q = NULL, *z = NULL, *pi = NULL, *psi = NULL; - MKL_Complex16 *tmat = NULL, *g0 = NULL, *g1 = NULL, *dummy = NULL, *tmatq = NULL, *c = NULL, *impact = NULL, *ab = NULL; - MKL_Complex16 *fmat = NULL, *fwt = NULL, *ywt = NULL; - MKL_Complex16 *etawt = NULL, *ueta = NULL, *veta = NULL, *zwt = NULL, *uz = NULL, *vz = NULL, *etawt1 = NULL, *ueta1 = NULL, *veta1 = NULL; - -// /* Check for proper number of input and output arguments */ -// if (nrhs < 5 || nrhs > 6) -// mexErrMsgTxt("Five or six input arguments required.\n"); -// if (nlhs != 8) -// mexErrMsgTxt("Eight output arguments required.\n"); - -// /* Dimensions */ -// n = mxGetM(prhs[0]); -// psin = mxGetN(prhs[3]); -// pin = mxGetN(prhs[4]); - n = gensys_ps->G0_dm->nrows; - psin = gensys_ps->Psi_dm->ncols; - pin = gensys_ps->Pi_dm->ncols; - // - eu = gensys_ps->eu_dv->v; - //eu = mxGetPr(plhs[7]=mxCreateDoubleMatrix(2,1,mxREAL)); - -// /* Check for consistency of input matrix dimensions */ -// if (mxGetM(prhs[0])!=n || mxGetM(prhs[1])!=n) -// mexErrMsgTxt("g0 and g1 must be square matrices.\n"); - -// if (mxGetM(prhs[3])!=n || mxGetM(prhs[4])!=n) -// mexErrMsgTxt("psi and pi must have the same number of rows as g0.\n"); - -// eu = mxGetPr(plhs[7]=mxCreateDoubleMatrix(2,1,mxREAL)); - - //=== [a b q z]=qz(g0,g1); -// a = mat2mkl(prhs[0],n,n); -// b = mat2mkl(prhs[1],n,n); -// q = mxCalloc(n*n,sizeof(MKL_Complex16)); -// z = mxCalloc(n*n,sizeof(MKL_Complex16)); - a = CreateComplexMatrix5RealMatrix(gensys_ps->G0_dm); - b = CreateComplexMatrix5RealMatrix(gensys_ps->G1_dm); - q = tzMalloc(nsquare=square(n), MKL_Complex16); - z = tzMalloc(nsquare, MKL_Complex16); - InitializeConstantMLK_Complex16(q, nsquare, 0.0); - InitializeConstantMLK_Complex16(z, nsquare, 0.0); - -// fixdiv = nrhs != 6; -// stake = fixdiv ? 1.01 : mxGetScalar(prhs[5]); - fixdiv = (gensys_ps->div < 1.0); - stake = fixdiv ? 1.01 : gensys_ps->div; - nunstab = 0; - zxz = 0; - - if (qz(a, b, q, z, n)) { - printf("WARNING: QZ factorization failed.\n"); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - - nunstab /= 2; - - if (zxz) { - printf("WARNING: Coincident zeros. Indeterminacy and/or nonexistence.\n"); - eu[0] = eu[1] = -2.0; - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - -// plhs[6] = mxCreateDoubleMatrix(n, 2, mxCOMPLEX); //For Gev_dzm. -// copy_eigenvalues(plhs[6], a, b, n); - copy_eigenvalues(gensys_ps->Gev_dzm, a, b); - - one.real = 1.0; - one.imag = 0.0; - - minusone.real = -1.0; - minusone.imag = 0.0; - - zero.real = 0.0; - zero.imag = 0.0; - -// pi = mat2mkl(prhs[4],n,pin); -// etawt = mxCalloc(nunstab*pin,sizeof(MKL_Complex16)); - pi = CreateComplexMatrix5RealMatrix(gensys_ps->Pi_dm); - etawt = tzMalloc(tmpi=nunstab*pin, MKL_Complex16); - InitializeConstantMLK_Complex16(etawt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, pin, n, - &one, q+n*(n-nunstab), n, pi, n, &zero, etawt, nunstab); - if (compute_svd(etawt, &ueta, &deta, &veta, nunstab, pin)) { - //Memory is now allocated to ueta, deta, and veta. - printf("WARNING: SVD failed.\n"); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(etawt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(etawt); - md = nunstab<pin?nunstab:pin; - bigev = md; - for (i=0; i<md; i++) - if (deta[i]<=REALSMALL) { - bigev=i; - break; - } - -// psi = mat2mkl(prhs[3],n,psin); -// zwt = mxCalloc(nunstab*psin,sizeof(MKL_Complex16)); - psi = CreateComplexMatrix5RealMatrix(gensys_ps->Psi_dm); - zwt = tzMalloc(tmpi=nunstab*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(zwt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, psin, n, - &one, q+n*(n-nunstab), n, psi, n, &zero, zwt, nunstab); - if (compute_svd(zwt, &uz, &dz, &vz, nunstab, psin)) { - //Memory is now allocated to uz, dz, and vz. - printf("WARNING: SV decomposition failed.\n"); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(uz); - tzDestroy(dz); - tzDestroy(vz); - tzDestroy(zwt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(vz); - mds = nunstab<psin?nunstab:psin; - bigevs = mds; - for (i=0; i<mds; i++) - if (dz[i]<=REALSMALL) { - bigevs=i; - break; - } - tzDestroy(dz); - - - /* ueta = nunstab x bigev - deta = bigev x 1 - veta = bigev x pin, ldveta = md - uz = nunstab x bigevs - dz = bigevs x 1 - vz = bigevs x psin, ldvz = mds */ - - if (!bigevs) { - exist = 1; - existx = 1; - } else { - /* uz-ueta*ueta'*uz */ - MKL_Complex16 *tmp = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, nunstab, nunstab, - bigev, &one, ueta, nunstab, ueta, nunstab, &zero, tmp, nunstab); - cblas_zhemm(CblasColMajor, CblasLeft, CblasUpper, nunstab, - bigevs, &minusone, tmp, nunstab, uz, nunstab, &one, uz, nunstab); - tzDestroy(tmp); - if (compute_norm(uz, &norm, nunstab, bigevs)) { - //Memory is now allocated to norm. - printf("WARNING: SVD failed.\n"); - tzDestroy(norm); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(uz); - tzDestroy(zwt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - exist = *norm < REALSMALL*n; - tzDestroy(norm); - if (compute_normx(a, b, zwt, ueta, &normx, nunstab, psin, n, bigev)) { - //If 0, memory is now allocated to normx; otherwise, normx is destroyed within the function compute_normx(). - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(uz); - tzDestroy(zwt); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - existx = *normx < REALSMALL*n; - tzDestroy(normx); - } - - tzDestroy(uz); - tzDestroy(zwt); - - -/* Note that existence and uniqueness are not just matters of comparing - numbers of roots and numbers of endogenous errors. These counts are - reported below because usually they point to the source of the problem. */ - - etawt1 = tzMalloc(tmpi=(n-nunstab)*pin, MKL_Complex16); - InitializeConstantMLK_Complex16(etawt1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, n-nunstab, pin, n, - &one, q, n, pi, n, &zero, etawt1, n-nunstab); - tzDestroy(pi); - if (compute_svd(etawt1, &ueta1, &deta1, &veta1, n-nunstab, pin)) { - //Memory is now allocated to ueta1, deta1, and veta1. - printf("WARNING: SVD failed for compute_svd().\n"); - tzDestroy(ueta1); - tzDestroy(deta1); - tzDestroy(veta1); - tzDestroy(etawt1); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(etawt1); - md1 = n-nunstab<pin?n-nunstab:pin; - bigev1 = md1; - for (i=0; i<md1; i++) - if (deta1[i]<=REALSMALL) { - bigev1=i; - break; - } - /* ueta1 = n-nunstab x bigev1 - deta1 = bigev1 x 1 - veta1 = bigev1 x pin, ldveta1 = md1 */ - - if (existx || !nunstab) { - //=== Solution exists. - eu[0] = 1.0; - } else { - if (exist) { - printf("WARNING: Solution exists for unforecastable z only\n"); - eu[0] = -1.0; - } /* else - mexPrintf("No solution. %d unstable roots. %d endog errors.\n",nunstab,bigev1); */ - /* mexPrintf("Generalized eigenvalues\n"); - mexCallMATLAB(0,NULL,1, &plhs[6], "disp"); */ - } - if (!bigev1) - unique = 1; - else { - /* veta1-veta1*veta*veta' */ - /* veta = bigev x pin, ldveta1 = md - veta1 = bigev1 x pin, ldveta1 = md1 */ - MKL_Complex16 *tmp = tzMalloc(pin*pin, MKL_Complex16); - MKL_Complex16 *veta1_copy = tzMalloc(pin*bigev1, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, pin*pin, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - InitializeConstantMLK_Complex16(veta1_copy, pin*bigev1, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, pin, pin, - bigev, &one, veta, md, veta, md, &zero, tmp, pin); - cblas_zdupe(bigev1,pin,veta1,md1,veta1_copy,bigev1); - cblas_zhemm(CblasColMajor, CblasRight, CblasUpper, bigev1, pin, - &minusone, tmp, pin, veta1_copy, bigev1, &one, veta1_copy, bigev1); - tzDestroy(tmp); - if (compute_norm(veta1_copy, &norm, bigev1, pin)) { - //Memory is now allocated to norm. - printf("WARNING: SVD failed.\n"); - tzDestroy(norm); - tzDestroy(ueta1); - tzDestroy(deta1); - tzDestroy(veta1); - tzDestroy(ueta); - tzDestroy(deta); - tzDestroy(veta); - tzDestroy(veta1_copy); - tzDestroy(a); - tzDestroy(b); - tzDestroy(q); - tzDestroy(z); - return; - } - tzDestroy(veta1_copy); - unique = *norm < REALSMALL*n; - tzDestroy(norm); - } - if (unique) { - //=== Unique solution. - eu[1] = 1.0; - } else { - eu[1] = 0.0; - printf("WARNING: Indeterminacy. %d loose endog errors with eu being [%g, %g].\n",bigev1-bigev, eu[0], eu[1]); - //printf("WARNING: Indeterminacy. %d loose endog errors with eu being [%g, %g].\n",bigev1-bigev, gensys_ps->eu_dv->v[0], gensys_ps->eu_dv->v[1]); - //printf("WARNING: Indeterminacy. %d loose endog errors.\n",bigev1-bigev); - /* mexPrintf("Generalized eigenvalues\n"); - mexCallMATLAB(0,NULL,1, &plhs[6], "disp"); */ - } - - cblas_zdscali(pin,deta,bigev,veta,md); /* veta' = deta\veta' */ - tzDestroy(deta); - cblas_zdscale(pin,deta1,bigev1,veta1,md1); /* veta1' = deta1*veta1' */ - tzDestroy(deta1); - etawt = tzMalloc(tmpi=nunstab*pin, MKL_Complex16); /* etawt = ueta*veta' */ - InitializeConstantMLK_Complex16(etawt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, nunstab, pin, bigev, - &one, ueta, nunstab, veta, md, &zero, etawt, nunstab); - tzDestroy(ueta); - tzDestroy(veta); - etawt1 = tzMalloc(tmpi=(n-nunstab)*pin, MKL_Complex16); /* etawt1 = ueta1*veta1' */ - InitializeConstantMLK_Complex16(etawt1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, pin, bigev1, - &one, ueta1, n-nunstab, veta1, md1, &zero, etawt1, n-nunstab); - tzDestroy(ueta1); - tzDestroy(veta1); - tmat = tzMalloc(tmpi=(n-nunstab)*nunstab, MKL_Complex16); /* tmat = etawt1*etawt' */ - InitializeConstantMLK_Complex16(tmat, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n-nunstab, nunstab, pin, - &one, etawt1, n-nunstab, etawt, nunstab, &zero, tmat, n-nunstab); - tzDestroy(etawt1); - tzDestroy(etawt); - - g0 = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(g0, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdupe(n-nunstab, n, a, n, g0, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, nunstab, nunstab, - &minusone, tmat, n-nunstab, a+(n-nunstab)*(n+1), n, &one, g0+(n-nunstab)*n, n); - cblas_zcopy(nunstab, &one, 0, g0+(n-nunstab)*(n+1), n+1); - - g1 = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(g1, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdupe(n-nunstab, n, b, n, g1, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n-nunstab, nunstab, nunstab, - &minusone, tmat, n-nunstab, b+(n-nunstab)*(n+1), n, &one, g1+(n-nunstab)*n, n); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, n, &one, g0, n, g1, n); - dummy = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, n, n, &one, z, n, g1, n, &zero, dummy, n); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n, n, n, &one, dummy, n, z, n, &zero, g1, n); - tzDestroy(dummy); - //plhs[0] = mkl2mat_real(g1, n, n, n); - ComplexMatrix2RealMatrix(gensys_ps->Theta_dm, g1); //Output. - tzDestroy(g1); - - tmatq = tzMalloc(tmpi=n*n, MKL_Complex16); - InitializeConstantMLK_Complex16(tmatq, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zcopy(n*n, q, 1, tmatq, 1); - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, n, n-nunstab, nunstab, - &minusone, tmatq+(n-nunstab)*n, n, tmat, n-nunstab, &one, tmatq, n); - tzDestroy(tmat); - - ab = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(ab, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zdpsb(nunstab, nunstab, a+(n-nunstab)*(n+1), n, b+(n-nunstab)*(n+1), n, ab, nunstab); - cblas_ztrsm(CblasColMajor, CblasRight, CblasUpper, CblasConjTrans, CblasNonUnit, - n, nunstab, &one, ab, nunstab, tmatq+(n-nunstab)*n, n); - tzDestroy(ab); - - //c = mat2mkl(prhs[2],n,1); - c = CreateComplexMatrix5RealVector(gensys_ps->c0_dv); - dummy = tzMalloc(gensys_ps->c0_dv->n, MKL_Complex16); - //$$$$$$$ The following is Iskander's fatal code error. One cannot use c in the two different places; otherwise, it makes c be zero completely! - // cblas_zgemv(CblasColMajor, CblasConjTrans, n, n, &one, tmatq, n, c, 1, &zero, c, 1); - // cblas_ztrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, n, g0, n, c, 1); - // cblas_zgemv(CblasColMajor, CblasNoTrans, n, n, &one, z, n, c, 1, &zero, c, 1); - cblas_zgemv(CblasColMajor, CblasConjTrans, n, n, &one, tmatq, n, c, 1, &zero, dummy, 1); - cblas_ztrsv(CblasColMajor, CblasUpper, CblasNoTrans, CblasNonUnit, n, g0, n, dummy, 1); - cblas_zgemv(CblasColMajor, CblasNoTrans, n, n, &one, z, n, dummy, 1, &zero, c, 1); - //plhs[1] = mkl2mat_real(c, n, n, 1); - ComplexMatrix2RealVector(gensys_ps->c_dv, c); //Output. - tzDestroy(c); - tzDestroy(dummy); - - impact = tzMalloc(tmpi=n*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(impact, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, n-nunstab, psin, n, - &one, tmatq, n, psi, n, &zero, impact, n); - tzDestroy(tmatq); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, psin, &one, g0, n, impact, n); - dummy = tzMalloc(tmpi=n*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, psin, n, - &one, z, n, impact, n, &zero, dummy, n); - tzDestroy(impact); - //plhs[2] = mkl2mat_real(dummy, n, n, psin); - ComplexMatrix2RealMatrix(gensys_ps->Impact_dm, dummy); //Output. - tzDestroy(dummy); - - fmat = a+(n-nunstab)*(n+1); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, nunstab, &one, b+(n-nunstab)*(n+1), n, fmat, n); - //plhs[3] = mkl2mat(fmat, n, nunstab, nunstab); - gensys_ps->Fmat_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Fmat_dzm, fmat, n, nunstab, nunstab); - tzDestroy(a); - - fwt = tzMalloc(tmpi=nunstab*psin, MKL_Complex16); - InitializeConstantMLK_Complex16(fwt, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_ztrsm(CblasColMajor, CblasRight, CblasUpper, CblasConjTrans, CblasNonUnit, - n, nunstab, &one, b+(n-nunstab)*(n+1), n, q+(n-nunstab)*n, n); - tzDestroy(b); - cblas_zgemm(CblasColMajor, CblasConjTrans, CblasNoTrans, nunstab, psin, n, - &minusone, q+(n-nunstab)*n, n, psi, n, &zero, fwt, nunstab); - tzDestroy(q); - tzDestroy(psi); - //plhs[4] = mkl2mat(fwt, nunstab, nunstab, psin); - gensys_ps->Fwt_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Fwt_dzm, fwt, nunstab, nunstab, psin); - tzDestroy(fwt); - - ywt = tzMalloc(tmpi=n*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(ywt, tmpi, 0.0); - cblas_zcopy(nunstab, &one, 0, ywt+n-nunstab, n+1); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - n, nunstab, &one, g0, n, ywt, n); - tzDestroy(g0); - dummy = tzMalloc(tmpi=n*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(dummy, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, nunstab, n, - &one, z, n, ywt, n, &zero, dummy, n); - tzDestroy(z); - tzDestroy(ywt); - //plhs[5] = mkl2mat(dummy, n, n, nunstab); - gensys_ps->Ywt_dzm = SubComplexMatrix2Zmatrix(gensys_ps->Ywt_dzm, dummy, n, n, nunstab); - tzDestroy(dummy); -} - - -/****************************************************************************** - * function selctg orders the eigenvalues so that a selected cluster of * - * eigenvalues appears in the leading diagonal blocks of the upper * - * quasi-triangular matrix S and the upper triangular matrix T. * - ******************************************************************************/ - -static int selctg(MKL_Complex16 *alpha, MKL_Complex16 *beta) -{ - double absA = sqrt(alpha->real*alpha->real+alpha->imag*alpha->imag), - absB = fabs(beta->real); - if (absA) { - double divhat = absB/absA; - //bug detected by Vasco Curdia and Daria Finocchiaro, 2/25/2004 CAS. A root of - //exactly 1.01 and no root between 1 and 1.02, led to div being stuck at 1.01 - //and the 1.01 root being misclassified as stable. Changing < to <= below fixes this. - if (fixdiv && 1+REALSMALL<divhat && divhat<=stake) - stake = (1+divhat)/2; - } - if (absA<REALSMALL && absB<REALSMALL) - zxz = 1; - if (absB>stake*absA) { - nunstab++; - return(0); - } else - return(1); -} - -/****************************************************************************** - * compute for a pair of N-by-N complex nonsymmetric matrices (A,B), * - * the generalized eigenvalues, the generalized complex Schur form (S, T), * - * and optionally left and/or right Schur vectors (VSL and VSR) * - ******************************************************************************/ - -static int qz(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *q, MKL_Complex16 *z, int n) -{ -// unsigned char msg[101]; - int sdim, lwork = -1, info = 0; - MKL_Complex16 *alpha = tzMalloc(n,MKL_Complex16), - *beta = tzMalloc(n,MKL_Complex16), - *work, work1; - double *rwork = tzMalloc(8*n, double); - int *bwork = tzMalloc(4*n, int); - - /* Query zgges on the value of lwork */ - zgges("V", "V", "S", &selctg, &n, a, &n, b, &n, &sdim, alpha, beta, q, - &n, z, &n, &work1, &lwork, rwork, bwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to the Intel MKL function zgges() has an illegal value",-info); - tzDestroy(bwork); - tzDestroy(rwork); - tzDestroy(alpha); - tzDestroy(beta); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgges("V", "V", "S", &selctg, &n, a, &n, b, &n, &sdim, alpha, beta, q, - &n, z, &n, work, &lwork, rwork, bwork, &info); - - tzDestroy(work); - tzDestroy(bwork); - tzDestroy(rwork); - tzDestroy(alpha); - tzDestroy(beta); - - if (info < 0) { - printf("WARNING: Input %d to the Intel MKL function zgges() has an illegal value",-info); - return(info); - } - - if (info > 0) - if (info < n) - printf("WARNING: The QZ iteration failed. (A,B) are not in Schur form,\n" - "but ALPHA(j) and BETA(j) should be correct for j=%d,...,N.",info+1); - else { - switch (info-n) { - case 1: - printf("WARNING: LAPACK problem: error return from ZGGBAL"); - break; - case 2: - printf("WARNING: LAPACK problem: error return from ZGEQRF"); - break; - case 3: - printf("WARNING: LAPACK problem: error return from ZUNMQR"); - break; - case 4: - printf("WARNING: LAPACK problem: error return from ZUNGQR"); - break; - case 5: - printf("WARNING: LAPACK problem: error return from ZGGHRD"); - break; - case 6: - printf("WARNING: LAPACK problem: error return from ZHGEQZ (other than failed iteration)"); - break; - case 7: - printf("WARNING: LAPACK problem: error return from ZGGBAK (computing VSL)"); - break; - case 8: - printf("WARNING: LAPACK problem: error return from ZGGBAK (computing VSR)"); - break; - case 9: - printf("WARNING: LAPACK problem: error return from ZLASCL (various places)"); - break; - default: - printf("WARNING: LAPACK problem: unknown error."); - break; - } - } - return(info); -} - -/* - * Convert MATLAB complex matrix to MKL complex storage. - * - * Z = mat2mkl(X,ldz,ndz) - * - * converts MATLAB's mxArray X to MKL_Complex16 Z(ldz,ndz). - * The parameters ldz and ndz determine the storage allocated for Z, - * while mxGetM(X) and mxGetN(X) determine the amount of data copied. - */ - -//MKL_Complex16* mat2mkl(const mxArray *X, int ldz, int ndz) { -// MKL_Complex16 *Z, *zp; -// int m, n, incz, cmplxflag; -// register int i, j; -// double *xr, *xi; - -// Z = mxCalloc(ldz*ndz, sizeof(MKL_Complex16)); -// xr = mxGetPr(X); -// xi = mxGetPi(X); -// m = mxGetM(X); -// n = mxGetN(X); -// zp = Z; -// incz = ldz-m; -// cmplxflag = (xi != NULL); -// for (j = 0; j < n; j++) { -// if (cmplxflag) { -// for (i = 0; i < m; i++) { -// zp->real = *xr++; -// zp->imag = *xi++; -// zp++; -// } -// } else { -// for (i = 0; i < m; i++) { -// zp->real = *xr++; -// zp++; -// } -// } -// zp += incz; -// } -// return(Z); -//} - - -/* - * Convert MKL complex storage to MATLAB real and imaginary parts. - * - * X = mkl2mat(Z,ldz,m,n) - * - * copies MKL_Complex16 Z to X, producing a complex mxArray - * with mxGetM(X) = m and mxGetN(X) = n. - */ - -//mxArray* mkl2mat(MKL_Complex16 *Z, int ldz, int m, int n) { -// int i, j, incz; -// double *xr, *xi; -// MKL_Complex16 *zp; -// mxArray *X; - -// X = mxCreateDoubleMatrix(m,n,mxCOMPLEX); -// xr = mxGetPr(X); -// xi = mxGetPi(X); -// zp = Z; -// incz = ldz-m; -// for (j = 0; j < n; j++) { -// for (i = 0; i < m; i++) { -// *xr++ = zp->real; -// *xi++ = zp->imag; -// zp++; -// } -// zp += incz; -// } -// return(X); -//} - -//plhs[3] = mkl2mat(fmat, n, nunstab, nunstab) - -/* - * Convert MKL complex storage to MATLAB real matrix ignoring imaginary part. - * - * X = mkl2mat(Z,ldz,m,n) - * - * copies MKL_Complex16 Z to X, producing a real mxArray - * with mxGetM(X) = m and mxGetN(X) = n. - */ - -//mxArray* mkl2mat_real(MKL_Complex16 *Z, int ldz, int m, int n) { -// int i, j, incz; -// double *xr; -// MKL_Complex16 *zp; -// mxArray *X; - -// X = mxCreateDoubleMatrix(m,n,mxREAL); -// xr = mxGetPr(X); -// zp = Z; -// incz = ldz-m; -// for (j = 0; j < n; j++) { -// for (i = 0; i < m; i++) { -// *xr++ = zp->real; -// zp++; -// } -// zp += incz; -// } -// return(X); -//} - -//void copy_eigenvalues(mxArray *gev, MKL_Complex16 *a, MKL_Complex16 *b, int n) { -// double *gevr = mxGetPr(gev), -// *gevi = mxGetPi(gev); -// int i; - -// for (i=0; i<n; i++, gevr++, gevi++, a+=n+1) { -// *gevr = a->real; -// *gevi = a->imag; -// } - -// for (i=0; i<n; i++, gevr++, gevi++, b+=n+1) { -// *gevr = b->real; -// *gevi = b->imag; -// } -//} - -static void copy_eigenvalues(TSdzmatrix *Gev_dzm, MKL_Complex16 *a, MKL_Complex16 *b) -{ - int n = Gev_dzm->real->nrows; - double *gevr = Gev_dzm->real->M, - *gevi = Gev_dzm->imag->M; - int i; - - for (i=0; i<n; i++, gevr++, gevi++, a+=n+1) { - *gevr = a->real; - *gevi = a->imag; - } - - for (i=0; i<n; i++, gevr++, gevi++, b+=n+1) { - *gevr = b->real; - *gevi = b->imag; - } -} - - -static int compute_svd(MKL_Complex16 *x, MKL_Complex16 **u, double **d, MKL_Complex16 **v, int m, int n) -{ - //$$$Memory allocated to u, d, and v will be destroyed outside this function.$$$ - int tmpi; - int md = m<n?m:n, lwork = -1, info = 0; - MKL_Complex16 *a, *work, work1; - double *rwork = tzMalloc(5*md>1?5*md:1, double); - - a = tzMalloc(m*n, MKL_Complex16); - cblas_zcopy(m*n, x, 1, a, 1); - - *u = tzMalloc(tmpi=m*md,MKL_Complex16); - InitializeConstantMLK_Complex16(*u, tmpi, 0.0); - *v = tzMalloc(tmpi=md*n, MKL_Complex16); - InitializeConstantMLK_Complex16(*v, tmpi, 0.0); - *d = tzMalloc(md, double); - InitializeConstantDouble(*d, md, 0.0); - - /* Query zgges on the value of lwork */ - zgesvd("S", "S", &m, &n, a, &m, *d, *u, &m, *v, &md, &work1, &lwork, rwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - tzDestroy(rwork); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgesvd("S", "S", &m, &n, a, &m, *d, *u, &m, *v, &md, work, &lwork, rwork, &info); - - tzDestroy(work); - tzDestroy(rwork); - tzDestroy(a); - - if (info < 0) - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - - if (info > 0) - printf("WARNING: ZBDSQR did not converge.\n%d superdiagonals of an intermediate " - "bidiagonal form B did not converge to zero.",info); - return(info); -} - -static int compute_norm(MKL_Complex16 *a, double **d, int m, int n) -{ - //Memory will be allocated to d, which will be destroyed outside this function. - int md = m<n?m:n, lwork = -1, info = 0; - MKL_Complex16 *work = NULL, work1; - double *rwork = tzMalloc(5*md>1?5*md:1, double); - - *d = tzMalloc(md, double); - - /* Query zgges on the value of lwork */ - zgesvd("N", "N", &m, &n, a, &m, *d, NULL, &m, NULL, &md, &work1, &lwork, rwork, &info); - - if (info < 0) { - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - tzDestroy(rwork); - return(info); - } - - lwork = (int)(work1.real); - work = tzMalloc(lwork, MKL_Complex16); - zgesvd("N", "N", &m, &n, a, &m, *d, NULL, &m, NULL, &md, work, &lwork, rwork, &info); - - tzDestroy(work); - tzDestroy(rwork); - - if (info < 0) - printf("WARNING: Input %d to zgesvd had an illegal value",-info); - - if (info > 0) - printf("WARNING: ZBDSQR() in Intel MKL did not converge.\n%d superdiagonals of an intermediate " - "bidiagonal form B did not converge to zero.",info); - - return(info); -} - -static int compute_normx(MKL_Complex16 *a, MKL_Complex16 *b, MKL_Complex16 *zwt, MKL_Complex16 *ueta, double **normx, int nunstab, int psin, int n, int bigev) -{ - //Memory is allocated to normx, which will be freed outside this function. - int tmpi; - int info = 0, i, bigevs; - // - MKL_Complex16 *M = NULL, *zwtx = NULL, *ux = NULL, *vx = NULL, *tmp = NULL; - double *dx = NULL; - - - a += (n+1)*(n-nunstab); - b += (n+1)*(n-nunstab); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, psin, &one, b, n, zwt, nunstab); - M = tzMalloc(nunstab*nunstab, MKL_Complex16); - cblas_zdupe(nunstab, nunstab, a, n, M, nunstab); - cblas_ztrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, - nunstab, nunstab, &one, b, n, M, nunstab); - - zwtx = tzMalloc(nunstab*nunstab*psin, MKL_Complex16); - cblas_zcopy(nunstab*psin, zwt, 1, zwtx, 1); - for (i=1; i<nunstab; i++) { - cblas_ztrmm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, nunstab, psin*i, &one, M, nunstab, zwtx, nunstab); - cblas_zcopy(nunstab*psin, zwt, 1, zwtx+nunstab*psin*i, 1); - } - tzDestroy(M); - cblas_ztrmm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, nunstab, nunstab*psin, &one, b, n, zwtx, nunstab); - info = compute_svd(zwtx, &ux, &dx, &vx, nunstab, nunstab*psin); //Memory is allocated to ux, dx, and vx. - tzDestroy(vx); - tzDestroy(zwtx); - if (info) { - printf("WARNING: SVD failed.\n"); - tzDestroy(ux); - tzDestroy(dx); - return(info); - } - bigevs = nunstab; - for (i=0; i<nunstab; i++) - if (dx[i]<=REALSMALL) { - bigevs = i; - break; - } - tzDestroy(dx); - /* ux-ueta*ueta'*ux */ - tmp = tzMalloc(tmpi=nunstab*nunstab, MKL_Complex16); - InitializeConstantMLK_Complex16(tmp, tmpi, 0.0); //Must be initialized to 0.0 in order to have legal values of this pointer. - cblas_zgemm(CblasColMajor, CblasNoTrans, CblasConjTrans, nunstab, nunstab, - bigev, &one, ueta, nunstab, ueta, nunstab, &zero, tmp, nunstab); - cblas_zhemm(CblasColMajor, CblasLeft, CblasUpper, nunstab, - bigevs, &minusone, tmp, nunstab, ux, nunstab, &one, ux, nunstab); - tzDestroy(tmp); - info = compute_norm(ux, normx, nunstab, bigevs); //Memory is allocated to normx. - if (info) { - printf("WARNING: SVD failed.\n"); - tzDestroy(normx); - tzDestroy(ux); - return(info); - } - tzDestroy(ux); - return(info); -} - -static void cblas_zdupe(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<m; i++, a++, b++) - cblas_zcopy(n, a, lda, b, ldb); -} - -static void cblas_zdscali(int n, double *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<lda; i++, a++, b++) - cblas_zdscal(n, 1.0/(*a), b, ldb); -} - -static void cblas_zdscale(int n, double *a, int lda, MKL_Complex16 *b, int ldb) -{ - int i; - for (i=0; i<lda; i++, a++, b++) - cblas_zdscal(n, *a, b, ldb); -} - -static void cblas_zdpsb(int m, int n, MKL_Complex16 *a, int lda, MKL_Complex16 *b, int ldb, MKL_Complex16 *c, int ldc) -{ - int i; - cblas_zdupe(m, n, a, lda, c, ldc); - for (i=0; i<m; i++, b++, c++) - cblas_zaxpy(n, &minusone, b, ldb, c, ldc); -} - - -static MKL_Complex16* CreateComplexMatrix5RealMatrix(TSdmatrix *X_dm) -{ - int mn, k; - double *M; - // - MKL_Complex16 *Z = NULL; - - if (!X_dm) fn_DisplayError("CreateComplexMatrix5RealMatrix(): Input matrix X_dm must be allocated memory"); - M = X_dm->M; - - Z = tzMalloc(mn=X_dm->nrows*X_dm->ncols, MKL_Complex16); - for (k=mn-1; k>=0; k--) { - Z[k].real = M[k]; - Z[k].imag = 0.0; - } - return(Z); -} - -static MKL_Complex16* CreateComplexMatrix5RealVector(TSdvector *x_dv) -{ - int n, k; - double *v; - // - MKL_Complex16 *Z = NULL; - - if (!x_dv) fn_DisplayError("CreateComplexMatrix5RealVector(): Input vector x_dv must be allocated memory"); - v = x_dv->v; - - Z = tzMalloc(n=x_dv->n, MKL_Complex16); - for (k=n-1; k>=0; k--) { - Z[k].real = v[k]; - Z[k].imag = 0.0; - } - return(Z); -} - - -static void ComplexMatrix2RealMatrix(TSdmatrix *Y_dm, MKL_Complex16 *Z) -{ - int _k; - double *M; - - if (!Y_dm) fn_DisplayError("ComplexMatrix2RealMatrix(): Output matrix Y_dm must be allocated memory"); - M = Y_dm->M; - - for (_k=Y_dm->nrows*Y_dm->ncols-1; _k>=0; _k--) M[_k] = Z[_k].real; - Y_dm->flag = M_GE; -} - - -static void ComplexMatrix2RealVector(TSdvector *y_dv, MKL_Complex16 *Z) -{ - int _k; - double *v; - - if (!y_dv) fn_DisplayError("ComplexMatrix2RealVector(): Output matrix y_dv must be allocated memory"); - v = y_dv->v; - - for (_k=y_dv->n-1; _k>=0; _k--) v[_k] = Z[_k].real; - y_dv->flag = V_DEF; -} - - -static TSdzmatrix *SubComplexMatrix2Zmatrix(TSdzmatrix *X_dzm, MKL_Complex16 *Z, const int nrowsforZ, const int _m, const int _n) -{ - //X_dzm is _m-by_n comlex types where nrowsforZ <= _m and Z is nrowsforZ-by-_n. - int _i, _j, incz; - double *Mreal, *Mimag; - MKL_Complex16 *zp; - // - TSdzmatrix *Y_dzm = NULL; - - if (!X_dzm || X_dzm->real->nrows != _m || X_dzm->real->ncols != _n) { - DestroyMatrix_dz(X_dzm); //Destroys Y_dzm if already allocated memory to accommodate a possbible change of its dimension. - Y_dzm = CreateMatrix_dz(_m, _n); - } - else Y_dzm = X_dzm; - - Mreal = Y_dzm->real->M; - Mimag = Y_dzm->imag->M; - zp = Z; - if ((incz=nrowsforZ-_m)<0) fn_DisplayError("SubComplexMatrix2ZMatrix(): Number of rows for the input complex matrix Z must be greater that of the output Z matrix Y_dzm"); - - for (_j=0; _j<_n; _j++) { - for (_i=0; _i<_m; _i++) { - *Mreal++ = zp->real; - *Mimag++ = zp->imag; - zp++; - } - zp += incz; - } - return (Y_dzm); -} - - -static void InitializeConstantMLK_Complex16(MKL_Complex16 *x_clx, const int _n, const double c) -{ - int _i; - - for (_i=_n-1; _i>=0; _i--) - x_clx[_i].real = x_clx[_i].imag = c; -} - -static void InitializeConstantDouble(double *x_p, const int _n, const double c) -{ - int _i; - - for (_i=_n-1; _i>=0; _i--) x_p[_i] = c; -} diff --git a/CFiles/gensysOldVersionWorks.h b/CFiles/gensysOldVersionWorks.h deleted file mode 100755 index 9c6b23a98b82eb0a53168e6df96e500ff4db0044..0000000000000000000000000000000000000000 --- a/CFiles/gensysOldVersionWorks.h +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************* - * [G1,C,impact,fmat,fwt,ywt,gev,eu]=gensys(g0,g1,c,psi,pi,div) - * - * System given as - * g0*y(t)=g1*y(t-1)+c+psi*z(t)+pi*eta(t), - * with z an exogenous variable process and eta being endogenously determined - * one-step-ahead expectational errors. Returned system is - * y(t)=G1*y(t-1)+C+impact*z(t)+ywt*inv(I-fmat*inv(L))*fwt*z(t+1) . - * If z(t) is i.i.d., the last term drops out. - * If div or stake is omitted from argument list, a div>1 or stake>1 is calculated. - * eu(1)=1 for existence, eu(2)=1 for uniqueness. eu(1)=-1 for - * existence only with not-serially correlated z(t); eu=[-2,-2] for coincident zeros. - * - * g0, g1: n-by-n matrices. - * c: n-by-1 constant terms. - * z(t): m-by-1 vector of exogenous residuals where m < n. - * psi: n-by-m matrix. - * eta(t): h-by-1 vector of expectational (endogenous) errors. - * pi: n-by-h matrix. - * div: a real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - *------- - * G1 or Theta_dm: n-by-n matrices. - * C: n-by-1 vector of constant terms. - * impact: n-by-m matrix. - * gev: n-by-2 z vector of stacked generalized eigenvalues where gev(;,2) ./ gev(:,1) = eig(g0, g1). - * ywt: n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - * fmat: nunstab-by-nunstab z matrix where nunstab is the number of non-stable roots. - * fwt: nunstab-by-m z matrix. -********************************************************************/ - -#ifndef __GENSYS_H__ - #define __GENSYS_H__ - - #include "tzmatlab.h" - - #define REALSMALL 1e-7 - - typedef struct TSgensys_tag { - //=== Output arguments. - TSdmatrix *Theta_dm; //n-by-n. - TSdvector *c_dv; //n-by-1. - TSdmatrix *Impact_dm; //n-by-m. - TSdzmatrix *Fmat_dzm; //nunstab-by-nunstab z matrix. Initialized to NULL and will be dynamically allocated whenever gensys() is called. - TSdzmatrix *Fwt_dzm; //nunstab-by-m z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - TSdzmatrix *Ywt_dzm; //n-by-nunstab z matrix of possible complex numbers. Initialized to NULL and dynamically allocated. - TSdzmatrix *Gev_dzm; //n-by-2 z matrix of possible complex numbers. - TSdvector *eu_dv; //2-by-1. - //=== Function itself. - void (*gensys)(struct TSgensys_tag *, void *); - //=== Input arguments, which are all intialized to 0.0 and whose flags are set to M_GE. - TSdmatrix *G0_dm; //n-by-n. - TSdmatrix *G1_dm; //n-by-n. - TSdvector *c0_dv; //n-by-1. - TSdmatrix *Psi_dm; //n-by-m. - TSdmatrix *Pi_dm; //n-by-k whtere k is the number of expectational errors. - double div; //A real number dividing stable and unstable roots.. If < 1.0, a div>1.0 is calculated mechanically. - } TSgensys; - // - typedef void TFlinratexp(struct TSgensys_tag *, void *); //For linear rational expectations models. - - struct TSgensys_tag *CreateTSgensys(TFlinratexp *func, const int _n, const int _m, const int _k, const double div); - struct TSgensys_tag *DestroyTSgensys(struct TSgensys_tag *gensys_ps); - void gensys_sims(struct TSgensys_tag *gensys_ps, void *dummy_ps); -#endif - diff --git a/CFiles/gradcd_switch.c b/CFiles/gradcd_switch.c deleted file mode 100755 index 95c417940435d8ba6736e23b20306e98ef69bdc9..0000000000000000000000000000000000000000 --- a/CFiles/gradcd_switch.c +++ /dev/null @@ -1,202 +0,0 @@ - -#include "gradcd_switch.h" -//#include "dw_array.h" -//#include "m_array.h" -//#include "dw_error.h" -//#include "dw_rand.h" - -#include <math.h> -#include <string.h> - - -/* - Assumes: - model is a pointer to a properly initialized TStateModel. -*/ -double logTimetLHgivenparameters(TStateModel *model, TSdvector *x_dv, int nmodelpars, int endt_base1) -{ - //void *model is TStateModel *model - //endt_base1: base-1 t. - int s, t; - double logvalue; - PRECISION scale, u; - TMarkovStateVariable *sv=model->sv; - - //--- Added by Zha. - if (endt_base1 < 1 || endt_base1 > sv->nobs) - { - printf("gradcd_switch.c/logLHgivenparameters_time_t(): Input endt_base1 must be between 1 and T.\n"); - exit(EXIT_FAILURE); - } - if (nmodelpars > x_dv->n) - { - printf("gradcd_switch.c/logLHgivenparameters_time_t(): Number of model parameters, nmodelpars, must be <= x_dv->n.\n"); - exit(EXIT_FAILURE); - } - ConvertFreeParametersToQ(model, x_dv->v + nmodelpars); - ConvertFreeParametersToTheta(model,x_dv->v); - - - - //====== Initializes prior to forward recursion if necessary ====== - if (model->routines->pInitializeForwardRecursion) - model->routines->pInitializeForwardRecursion(model); - - //====== Get ergodic distribution if necessary ====== - if (sv->UseErgodic) - if (!Ergodic(model->V[0],sv->Q)) - { - printf("ForwardRecursion(): Ergodic distribution does not exist.\n"); - exit(0); - } - - //====== forward recursion ====== - for (t=1; t <= sv->nobs; t++) - { - //------ compute Z[t] ------ - ProductMV(model->Z[t],sv->Q,model->V[t-1]); - - //------ compute log conditional probabilities and scale ------ - scale=MINUS_INFINITY; - for (s=sv->nstates-1; s >= 0; s--) - { - if (ElementV(model->Z[t],s) > 0.0) - { - u=LogConditionalLikelihood(s,t,model); - scale=AddScaledLogs(1.0,scale,ElementV(model->Z[t],s),u); - ElementV(model->V[t],s)=log(ElementV(model->Z[t],s)) + u; - } - else - ElementV(model->V[t],s)=MINUS_INFINITY; - } - - //------ update L ------ - model->L+=scale; - - //--- Added by Zha. - if (t==endt_base1) logvalue = scale; - - //------ scale V[t] ------ - for (s=sv->nstates-1; s >= 0; s--) - if (ElementV(model->V[t],s) != MINUS_INFINITY) - ElementV(model->V[t],s)=exp(ElementV(model->V[t],s) - scale); - else - ElementV(model->V[t],s)=0.0; - } - - model->ValidForwardRecursion=1; - - return (logvalue); -} - - - - -//------------------------------- -//Modified from fn_gradcd() in cstz.c for the conjugate gradient method I or II -//------------------------------- -#define STPS 1.0e-04 // 6.0554544523933391e-6 step size = pow(DBL_EPSILON,1.0/3) -#define GRADMANUAL 0.0e+01 //Arbitrarily (manually) set gradient. -void gradcd_switch(TSdvector *g_dv, TStateModel *model, TSdvector *x_dv, int nmodelpars, int endt_base1, double (*fcn)(TStateModel *model, TSdvector *x_dv, int nmodelpars, int endt_base1), TSdvector *grdh_dv, double f0) -{ - //Outputs: - // g: the gradient n-by-1 g (no need to be initialized). - //Inputs: - // x: the vector point at which the gradient is evaluated. No change in the end although will be added or substracted by dh during the function (but in the end the original value will be put back). - // n: the dimension of g or x. - // fcn(): the function for which the gradient is evaluated - // grdh: step size. If NULL, then dh is set automatically; otherwise, grdh is taken as a step size, often set as 1.0e-004. - // f0: the value of (*fcn)(x). NOT used in this function except dealing with the boundary (NEARINFINITY) for the - // minimization problem, but to be compatible with a genral function call where, say, gradfw_gen() and cubic - // interpolation of central difference method will use f0. - - double *g, *x, *grdh; - double dh, dhi, dh2i, fp, fm, tmp, *xp; - int n, i; - - g = g_dv->v; - x = x_dv->v; - if (!grdh_dv) grdh = NULL; - else grdh = grdh_dv->v; - n = g_dv->n; - if (n != x_dv->n) - { - printf("gradcd_switch.c/gradcd_switch(): Input vectors g_dv and x_dv must have the same length.\n"); - exit(EXIT_FAILURE); - } - if (grdh_dv && n != grdh_dv->n) - { - printf("gradcd_switch.c/gradcd_switch(): Input vector grdh_dv mush have the same length as x_dv.\n"); - exit(EXIT_FAILURE); - } - - if (grdh) { - //=== If f0 >= NEARINFINITY, we're in a bad region and so we assume it's flat in this bad region. This assumption may or may not work for a third-party optimimization routine. - if (f0 >= NEARINFINITY) - { - for (i=n-1; i>=0; i--) - g[i] = GRADMANUAL; - return;; //Early exit. - } - - dh2i = (dhi=1.0/(dh=*grdh))/2.0; - for (i=0, xp=x; i<n; i++, xp++, g++) { - tmp = *xp; - *xp += dh; - //The following statement is bad because dh does not get reset at the beginning of the loop and thus may get changed continually within the loop. - // dh = *xp - tmp; // This increases the precision slightly. - fp = fcn(model, x_dv, nmodelpars, endt_base1); - //fp = fcn(n,x); // IMSL - //fcn(n,x,&fp,NULL,NULL); /* NAG */ - *xp = tmp - dh; - fm = fcn(model, x_dv, nmodelpars, endt_base1); - //fm = fcn(n,x); // IMSL - //fcn(n,x,&fm,NULL,NULL); - - //=== Checking the boundary condition for the minimization problem. - if ((fp < NEARINFINITY) && (fm < NEARINFINITY)) *g = (fp-fm)*dh2i; - else if (fp < NEARINFINITY) *g = (fp-f0)*dhi; - else if (fm < NEARINFINITY) *g = (f0-fm)*dhi; - else *g = GRADMANUAL; - - *xp = tmp; // Put the original value of x[i] back to x[i] so that the content x[i] is still unaltered. - } - - } - else { - //=== If f0 >= NEARINFINITY, we're in a bad region and so we assume it's flat in this bad region. This assumption may or may not work for a third-party optimimization routine. - if (f0 >= NEARINFINITY) - { - for (i=n-1; i>=0; i--) - g[i] = GRADMANUAL; - return;; //Early exit. - } - - for (i=0, xp=x; i<n; i++, xp++, g++) { - dh = fabs(*xp)<=1 ? STPS : STPS*(*xp); - tmp = *xp; - *xp += dh; - dh = *xp - tmp; // This increases the precision slightly. - fp = fcn(model, x_dv, nmodelpars, endt_base1); - //fp = fcn(n,x); // IMSL - //fcn(n,x,&fp,NULL,NULL); /* NAG */ - *xp = tmp - dh; - fm = fcn(model, x_dv, nmodelpars, endt_base1); - //fm = fcn(n,x); // IMSL - //fcn(n,x,&fm,NULL,NULL); - - //=== Checking the boundary condition for the minimization problem. - if ((fp < NEARINFINITY) && (fm < NEARINFINITY)) *g = (fp-fm)/(2.0*dh); - else if (fp < NEARINFINITY) *g = (fp-f0)/dh; - else if (fm < NEARINFINITY) *g = (f0-fm)/dh; - else *g = GRADMANUAL; - - *xp = tmp; // Put the original value of x[i] back to x[i] so that the content x[i] is still unaltered. - } - } - - g_dv->flag = V_DEF; -} -#undef STPS -#undef GRADMANUAL - diff --git a/CFiles/gradcd_switch.h b/CFiles/gradcd_switch.h deleted file mode 100755 index e6b7097286968bea7d7b822e3090c12b084d9942..0000000000000000000000000000000000000000 --- a/CFiles/gradcd_switch.h +++ /dev/null @@ -1,6 +0,0 @@ - -#include "switch.h" - - -double logTimetLHgivenparameters(TStateModel *model, TSdvector *x_dv, int nmodelpars, int endt_base1); -void gradcd_switch(TSdvector *g_dv, TStateModel *model, TSdvector *x_dv, int nmodelpars, int endt_base1, double (*fcn)(TStateModel *model, TSdvector *x_dv, int nmodelpars, int endt_base1), TSdvector *grdh_dv, double f0); diff --git a/CFiles/kalman.c b/CFiles/kalman.c old mode 100755 new mode 100644 index d9b4df9a68204ba7910c82c704588b878106f01e..dbeff14b363bd11f089876a8672873eb2d0903aa --- a/CFiles/kalman.c +++ b/CFiles/kalman.c @@ -1,2908 +1,2909 @@ -/*=============================================================================================================== - * Check $$$ for important notes. - * Check <<>> for updating DW's new switch code or questions for DW. - * - * kalcvf_urw(): the Kalman filter forward prediction specialized for only a univariate random walk (urw) process. - * - * State space model is defined as follows: - * z(t+1) = z(t)+eta(t) (state or transition equation) - * y(t) = x(t)'*z(t)+eps(t) (observation or measurement equation) - * where for this function, eta and eps must be uncorrelated; y(t) must be 1-by-1. Note that - * x(t): k-by-1; - * z(t): k-by-1; - * eps(t): 1-by-1 and ~ N(0, sigma^2); - * eta(t): ~ N(0, V) where V is a k-by-k covariance matrix. - * - * - * Written by Tao Zha, May 2004. - * Revised, May 2008; -=================================================================================================================*/ - -/** -//=== For debugging purpose. -if (1) -{ - double t_loglht; - - t_loglht = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, " %10.5f\n", t_loglht); - - fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - - fprintf(FPTR_DEBUG, "\n wP0_dv:\n"); - WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "\n Vt_dc->C[sti_v=%d]:\n", sti_v); - WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - - fflush(FPTR_DEBUG); -} -/**/ - - -#include "kalman.h" - - -static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); -static int Updatekalfilms_1stapp(int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - -TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv) //, int storeZ, int storeV) -{ - int _i; - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - //--- - TSkalcvfurw *kalcvfurw_ps = tzMalloc(1, TSkalcvfurw); - - - kalcvfurw_ps->indx_tvsigmasq = tv; - kalcvfurw_ps->fss = T; - kalcvfurw_ps->kx = k; - - //=== - kalcvfurw_ps->V_dm = CreateMatrix_lf(k, k); - kalcvfurw_ps->ylhtran_dv = CreateVector_lf(T); - kalcvfurw_ps->Xrhtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->z10_dv = CreateVector_lf(k); - kalcvfurw_ps->P10_dm = CreateMatrix_lf(k, k); - - kalcvfurw_ps->zupdate_dv = CreateVector_lf(k); - kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->ylhtranpred_dv = CreateVector_lf(T); - // - rows_iv = CreateVector_int(T); - cols_iv = CreateVector_int(T); - for (_i=T-1; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // if (!storeZ) kalcvfurw_ps->Zpredtran_dm = (TSdmatrix *)NULL; - // else kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - // if (!storeV) kalcvfurw_ps->Ppred_dc = (TSdcell *)NULL; - // else { - // rows_iv = CreateVector_int(T); - // cols_iv = CreateVector_int(T); - // for (_i=T; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - // kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // } - - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - return (kalcvfurw_ps); -} - -TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps) -{ - if (kalcvfurw_ps) { - DestroyMatrix_lf(kalcvfurw_ps->V_dm); - DestroyVector_lf(kalcvfurw_ps->ylhtran_dv); - DestroyMatrix_lf(kalcvfurw_ps->Xrhtran_dm); - DestroyVector_lf(kalcvfurw_ps->z10_dv); - DestroyMatrix_lf(kalcvfurw_ps->P10_dm); - - DestroyVector_lf(kalcvfurw_ps->zupdate_dv); - DestroyMatrix_lf(kalcvfurw_ps->Zpredtran_dm); - DestroyCell_lf(kalcvfurw_ps->Ppred_dc); - DestroyVector_lf(kalcvfurw_ps->ylhtranpred_dv); - - free(kalcvfurw_ps); - return ((TSkalcvfurw *)NULL); - } - else return (kalcvfurw_ps); -} - - -void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps) -{ - //See the notes of SWZ regarding the government's updating of the parameters in their Phillips-curve equation. - //NOTE: make sure that the value of kalcvfurw_ps->sigmasq and other input values are given. - int ti; - double workd, workdenominv; - //--- - int fss, kx; - double sigmasq_fix = kalcvfurw_ps->sigmasq; -// double sigmasq; - TSdmatrix *V_dm; - TSdmatrix *Zpredtran_dm; - TSdcell *Ppred_dc; - TSdvector *ylhtran_dv; - TSdmatrix *Xrhtran_dm; - //=== - TSdvector *workkxby1_dv = NULL; //kx-by-1. -// TSdvector *work1kxby1_dv = NULL; //kx-by-1. - TSdmatrix *workkxbykx_dm = NULL; //kx-by-kx symmetric and positive positive. -// //=== -// TSdvector *zbefore_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vbefore_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); -// TSdvector *zafter_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vafter_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); - //******* WARNING: Some dangerous pointer movement to gain efficiency ******* -// double *yt_p; -// double *Vbefore_p; -// double *Vafter_p; - TSdvector xt_sdv; - TSdvector zbefore_sdv; - //TSdmatrix Vbefore_sdm; - TSdvector zafter_sdv; - //TSdmatrix Vafter_sdm; - - - if (!kalcvfurw_ps) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps must be created"); - if (!kalcvfurw_ps->V_dm || !kalcvfurw_ps->ylhtran_dv || !kalcvfurw_ps->Xrhtran_dm || !kalcvfurw_ps->z10_dv || !kalcvfurw_ps->P10_dm) - fn_DisplayError(".../kalcvf_urw(): input arguments kalcvfurw_ps->V_dm, kalcvfurw_ps->ylhtran_dv, kalcvfurw_ps->Xrhtran_dm, kalcvfurw_ps->z10_dv, kalcvfurw_ps->P10_dm must be given legal values"); - if (!(kalcvfurw_ps->P10_dm->flag & (M_SU | M_SL))) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps->P10_dm must be symmetric"); - fss = kalcvfurw_ps->fss; - kx = kalcvfurw_ps->kx; - V_dm = kalcvfurw_ps->V_dm; - Zpredtran_dm = kalcvfurw_ps->Zpredtran_dm; - Ppred_dc = kalcvfurw_ps->Ppred_dc; - ylhtran_dv = kalcvfurw_ps->ylhtran_dv; - Xrhtran_dm = kalcvfurw_ps->Xrhtran_dm; - //--- - xt_sdv.n = kx; - xt_sdv.flag = V_DEF; - zbefore_sdv.n = kx; - zbefore_sdv.flag = V_DEF; - zafter_sdv.n = kx; - zafter_sdv.flag = V_DEF; - - //=== Memory allocation. - workkxby1_dv = CreateVector_lf(kx); - workkxbykx_dm = CreateMatrix_lf(kx, kx); - - - //------- The first period (ti=0). ------- - zbefore_sdv.v = kalcvfurw_ps->z10_dv->v; - zafter_sdv.v = Zpredtran_dm->M; - xt_sdv.v = Xrhtran_dm->M; - //--- - - workd = ylhtran_dv->v[0] - (kalcvfurw_ps->ylhtranpred_dv->v[0]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, kalcvfurw_ps->P10_dm, &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(kalcvfurw_ps->z10_dv->v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t]; - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - - - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[0], kalcvfurw_ps->P10_dm, workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[0]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - - //------- The rest of the periods (ti=1:T-1). ------- - for (ti=1; ti<fss; ti++) { - //NOTE: ti=0 has been taken care of outside of this loop. - zbefore_sdv.v = Zpredtran_dm->M + (ti-1)*kx; - zafter_sdv.v = Zpredtran_dm->M + ti*kx; - xt_sdv.v = Xrhtran_dm->M + ti*kx; - //--- - workd = ylhtran_dv->v[ti] - (kalcvfurw_ps->ylhtranpred_dv->v[ti]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, Ppred_dc->C[ti-1], &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(zbefore_sdv.v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[ti], Ppred_dc->C[ti-1], workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[ti]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - } - CopyVector0(kalcvfurw_ps->zupdate_dv, &zafter_sdv); - Zpredtran_dm->flag = M_GE; - kalcvfurw_ps->ylhtranpred_dv->flag = V_DEF; - -// DestroyVector_lf(zbefore_dv); -// DestroyMatrix_lf(Vbefore_dm); -// DestroyVector_lf(zafter_dv); -// DestroyMatrix_lf(Vafter_dm); - - DestroyVector_lf(workkxby1_dv); -// DestroyVector_lf(work1kxby1_dv); - DestroyMatrix_lf(workkxbykx_dm); -} - - - -//----------------------------------------------------------------------------------------------------------------------- -//-- General constant (known-time-varying) Kalman filter for DSGE models. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T) -{ - int _i; - //=== - TSivector *rows_iv = CreateVector_int(T); - TSivector *cols_iv = CreateVector_int(T); - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfiltv_tag *kalfiltv_ps = tzMalloc(1, struct TSkalfiltv_tag); - - - //--- Default value. - kalfiltv_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfiltv_ps->ny = ny; - kalfiltv_ps->nz = nz; - kalfiltv_ps->T = T; - - - - //--------- Creates memory and assigns values. The order matters. - kalfiltv_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfiltv_ps->at_dm = CreateMatrix_lf(ny, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = nz; - } - rows_iv->flag = cols_iv->flag = V_DEF; - kalfiltv_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->bt_dm = CreateMatrix_lf(nz, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - kalfiltv_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->z0_dv = CreateVector_lf(nz); - kalfiltv_ps->P0_dm = CreateMatrix_lf(nz, nz); - - - //--- - kalfiltv_ps->zt_tm1_dm = CreateMatrix_lf(nz, T); - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Pt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfiltv_ps); - -} -//--- -struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - if (kalfiltv_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfiltv_ps->yt_dm); - DestroyMatrix_lf(kalfiltv_ps->at_dm); - DestroyCell_lf(kalfiltv_ps->Ht_dc); - DestroyCell_lf(kalfiltv_ps->Rt_dc); - DestroyCell_lf(kalfiltv_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfiltv_ps->bt_dm); - DestroyCell_lf(kalfiltv_ps->Ft_dc); - DestroyCell_lf(kalfiltv_ps->Vt_dc); - //--- - DestroyVector_lf(kalfiltv_ps->z0_dv); - DestroyMatrix_lf(kalfiltv_ps->P0_dm); - //--- - DestroyMatrix_lf(kalfiltv_ps->zt_tm1_dm); - DestroyCell_lf(kalfiltv_ps->Pt_tm1_dc); - - - //--- - tzDestroy(kalfiltv_ps); //Must be freed last! - - return ((struct TSkalfiltv_tag *)NULL); - } - else return (kalfiltv_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- New code: Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp2(int ny, int nz, int nu, int ne, int nst, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //=== Default value. - kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; - kalfilmsinputs_1stapp_ps->ztm1_track = -1; - kalfilmsinputs_1stapp_ps->dtm1_track = -1; - - //--- Other key assignments. - kalfilmsinputs_1stapp_ps->ny = ny; - kalfilmsinputs_1stapp_ps->nz = nz; - kalfilmsinputs_1stapp_ps->nu = nu; - kalfilmsinputs_1stapp_ps->ne = ne; - kalfilmsinputs_1stapp_ps->nst = nst; - kalfilmsinputs_1stapp_ps->T = T; - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - if (nu) - { - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nu); - kalfilmsinputs_1stapp_ps->Psiut_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - kalfilmsinputs_1stapp_ps->Psiut_dc = NULL; - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ne); - kalfilmsinputs_1stapp_ps->Psiet_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - //--- For output arguments. - rows_iv = CreateConstantVector_int(T+1, nz); - cols_iv = CreateConstantVector_int(T+1, nst); - kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - return (kalfilmsinputs_1stapp_ps); -} -//--- -struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp2(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - if (kalfilmsinputs_1stapp_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Psiut_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Psiet_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); - //--- - tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); - } - else return (kalfilmsinputs_1stapp_ps); -}; - -struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //=== Default value. - kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; - kalfilmsinputs_1stapp_ps->ztm1_track = -1; - kalfilmsinputs_1stapp_ps->dtm1_track = -1; - - //--- Other key assignments. - kalfilmsinputs_1stapp_ps->ny = ny; - kalfilmsinputs_1stapp_ps->nz = nz; - kalfilmsinputs_1stapp_ps->nst = nst; - kalfilmsinputs_1stapp_ps->T = T; - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - //--- For output arguments. - rows_iv = CreateConstantVector_int(T+1, nz); - cols_iv = CreateConstantVector_int(T+1, nst); - kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - return (kalfilmsinputs_1stapp_ps); -} -//--- -struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - if (kalfilmsinputs_1stapp_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); - //--- - tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); - } - else return (kalfilmsinputs_1stapp_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_tag *kalfilmsinputs_ps = tzMalloc(1, struct TSkalfilmsinputs_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //--- Default value. - kalfilmsinputs_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfilmsinputs_ps->ny = ny; - kalfilmsinputs_ps->nz = nz; - kalfilmsinputs_ps->nRc = nRc; - kalfilmsinputs_ps->nRstc = nRstc; - kalfilmsinputs_ps->nRv = nRv; - kalfilmsinputs_ps->indxIndRegimes = indxIndRegimes; - kalfilmsinputs_ps->T = T; - - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_ps->at_dm = CreateMatrix_lf(ny, nRc); - // - rows_iv = CreateConstantVector_int(nRc, ny); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, ny); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_ps->bt_dm = CreateMatrix_lf(nz, nRc); - // - rows_iv = CreateConstantVector_int(nRc, nz); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - if (indxIndRegimes) - { - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRc*nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - //--- For output arguments. - if (indxIndRegimes) - { - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRc*nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfilmsinputs_ps); - -} -//--- -struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps) -{ - if (kalfilmsinputs_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->z0_dm); - DestroyCell_lf(kalfilmsinputs_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_ps->Pt_tm1_d4); - //--- - tzDestroy(kalfilmsinputs_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_tag *)NULL); - } - else return (kalfilmsinputs_ps); -}; - - -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//-- Constant-parameters (known-time-varying) Kalman filter -//----------------------------------------------------- -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //General constant (known-time-varying) Kalman filter for DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - int T = kalfiltv_ps->T; - int Tp1 = T + 1; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - int indx_badlh = 0; //1: bad likelihood with, say, -infinity of the LH value. - int tdata, ti; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; //double loglh_tdata; //logdetDtdata. - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - //--- Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - - - - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "Fatal error: tz_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[0], P0_dm); - - //====== See p.002 in LiuWZ. ====== - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - loglh = 0.0; - for (tdata=0; tdata<T; tdata++ ) - { - //Base-0 timing. - ti = tdata + 1; //Next period. - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (kalfiltv_ps->loglh = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh += -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //loglh += -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (ti<T) - { - //Updating only up to tdata=T-2. The values at ti=T or tdata=T-1 will not be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[ti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + ti*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[ti], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + ti*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[ti], Vt_dc->C[ti]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[ti], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[ti], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[ti], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[ti], W2nzbynz_dm); - //Done with all W*_dm. - } - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (kalfiltv_ps->loglh = loglh); -} -/** -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //This function is used to test tz_logTimetCondLH_kalfiltv(). - int T = kalfiltv_ps->T; - int tdata; - double loglh; - - loglh = 0.0; - for (tdata=0; tdata<T; tdata++) loglh += tz_logTimetCondLH_kalfiltv(0, tdata+1, kalfiltv_ps); - - return (loglh); -} -/**/ -//----------------------------------------------------- -//-- Updating Kalman filter at time t for constant-parameters (or known-time-varying) Kalman filter. -//----------------------------------------------------- -double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps) -{ - //st: base-0 grand regime at time t, which is just a dummy for this constant-parameter function in order to use - // Waggoner's automatic functions. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - // - //log LH at time t for constant (known-time-varying) Kalman-filter DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood at time t. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // April 2008, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //--- Output arguments. - double loglh_timet; //log likelihood at time t. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - //--- Input arguments. - int tdata, tp1; - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - int T = kalfiltv_ps->T; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - - - tdata = (tp1=inpt) - 1; //Base-0 time. - - //======= Initial condition. ======= - if (tdata==0) - { - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_logTimetCondLH_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(FPTR_DEBUG, "Fatal error: tz_logTimetCondLH_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and thus the initial conditions must be supplied by, say, input arguments"); - fflush(FPTR_DEBUG); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[tdata], P0_dm); - } - - - //======= Liklihood at time t (see p.002 in LiuWZ). ======= - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //======= Updating for the next period. ======= - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (tp1<T) - { - //Updating only up to tdata=T-2, because the values at tp1=T or tdata=T-1 will NOT be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[tp1], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + tp1*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[tp1], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + tp1*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[tp1], Vt_dc->C[tp1]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[tp1], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[tp1], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[tp1], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[tp1], W2nzbynz_dm); - //Done with all W*_dm. - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (loglh_timet); -} - - - - -//----------------------------------------------------- -//- WARNING: bedore using this function, make sure to call the following functions -// Only once in creating lwzmodel_ps: Refresh_kalfilms_*(lwzmodel_ps); -// Everytime when parameters are changed: RefreshEverything(); RefreRunningGensys_allcases(lwzmodel_ps) in particular. -//----------------------------------------------------- -double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //st: base-0 grand regime -- deals with the cross-section values at time t. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - //-- Output arguments - double loglh_timet; - //--- Input arguments - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- Local variables - int tbase0; - double logdet_Dtdata; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - TSdvector etdata_sdv; - //=== Work arguments. - TSdvector *wny_dv = CreateVector_lf(ny); - - - - //--- Critical checking. - if (inpt > kalfilmsinputs_1stapp_ps->T) - fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): The time exceeds the\n" - " data sample size allocated the structure TSkalfilmsinputs_1stapp_tag"); - - //--- The following is for safe guard. InitializeKalman_z10_P10() should be called in, say, RefreshEverything(). - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - if (!InitializeKalman_z10_P10(kalfilmsinputs_1stapp_ps, (TSdmatrix *)NULL, (TSdcell *)NULL)) - fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): the system is non-stationary when calling" - " InitializeKalman_z10_P10(). Please call this function in RefreshEverthing() and" - " set the likehood to be -infty for early exit"); - - tbase0=inpt-1; - - //------------------- The order matters. Updatekalfilms_1stapp() must be called before Update_et_Dt_1stapp(). ----------------- - //--- $$$ Critical updating where we MUSt have inpt-1. If inpt, Updatekalfilms_1stapp() will call this function again - //--- $$$ because DW function ProbabilityStateConditionalCurrent() need to access this function at time inpt, - //--- $$$ which has not computed before Updatekalfilms_1stapp(). Thus, we'll have an infinite loop. - Updatekalfilms_1stapp(tbase0, kalfilmsinputs_1stapp_ps, smodel_ps); -// //--- $$$ Critical updating. -// Update_et_Dt_1stapp(tbase0, kalfilmsinputs_1stapp_ps); -// //This function will give Dtdata_d4->F[tbase0], etdata_dc->C[tbase0], and PHtran_tdata_d4->F[tbase0]. - - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - //--- Forming the log conditional likelihood at t. - etdata_sdv.n = ny; - etdata_sdv.v = etdata_dc->C[tbase0]->M + ny*st; - etdata_sdv.flag = V_DEF; - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_d4->F[tbase0]->C[st]))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, &etdata_sdv, '/', Dtdata_d4->F[tbase0]->C[st]); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, &etdata_sdv); - //Done with all w*_dv. - - //=== - DestroyVector_lf(wny_dv); - - return (loglh_timet); -} -//====================================================== -//= Computing z_{1|0} and P_{1|0} for each new parameter values. -//====================================================== -int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc) -{ - //See p.001 and p.004 in LWZ Model II. - //Outputs: - // return 1: success in initializing; 0: initializing fails, so the likelihood must be set to -infty outside this function. - // ztm1_track to track the time up to which Kalman filter have been updated. - // z0_dm, zt_tm1_dc->C[0] - // P0_dc, Pt_tm1_d4->F[0] - - //--- Output arguments - TSdmatrix *z0_0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdmatrix *z0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdcell *P0_dc = kalfilmsinputs_1stapp_ps->P0_dc; //nz-by-nz-by-nst. - //+ Used to get zt_tm1_dc->C[0] and Pt_tm1_d4->F[0] only. - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Input arguments - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //--- Local variables - int sti; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv, z0_0_sdv, bt_sdv; - TSdvector yt_sdv, at_sdv; - //--- For the initial conditions: eigenvalue decompositions - int ki; - int errflag; - double eigmax; - //=== - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - // - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - - - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - { - z0_sdv.n = z0_0_sdv.n = bt_sdv.n = nz; - z0_sdv.flag = z0_0_sdv.flag = bt_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (!kalfilmsinputs_1stapp_ps->indxIni) - { - z0_0_dm->flag = z0_dm->flag = M_GE; - for (sti=nst-1; sti>=0; sti--) - { - if (kalfilmsinputs_1stapp_ps->DiffuseScale) //Diffuse initial conditions are used. - { - //--- Diffuse condition for z0_dv. - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; - bt_sdv.v = bt_dm->M + bt_sdv.n*sti; - InitializeConstantVector_lf(&z0_0_sdv, 0.0); - MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); - VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); - //--- Diffuse condition for P0_dm. - InitializeDiagonalMatrix_lf(Wnzbynz_dm, kalfilmsinputs_1stapp_ps->DiffuseScale); //To be used for DiffuseScale*I(nz) - CopyMatrix0(P0_dc->C[sti], Wnzbynz_dm); - //Done with W*_dm. - } - else //Unconditional moments for initial conditions are used. - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti]); - if (errflag) fn_DisplayError("kalman.c/InitializeKalman_z10_P10(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0-SQRTEPSILON)) //(1.0+EPSILON)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,sti))\b(:,sti); - z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti]); - CopySubmatrix2vector(&z0_0_sdv, 0, bt_dm, 0, sti, bt_dm->nrows); - bdivA_rgens(&z0_0_sdv, &z0_0_sdv, '\\', Wnzbynz_dm); - //- Under the assumption s_0 = s_1 (this is a short-cut). - MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); - VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,sti),F(:,:,sti)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti], Ft_dc->C[sti]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - if (0) //0: no printing. - { - #if defined (USE_DEBUG_FILE) - fprintf(FPTR_DEBUG, "\n-------WARNING: ----------\n"); - fprintf(FPTR_DEBUG, "\nIn grand regime sti=%d\n", sti); - fprintf(FPTR_DEBUG, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #else - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn grand regime sti=%d\n", sti); - fprintf(stdout, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #endif - } - //=== See p.000.3 in LWZ Model II. - //=== Do NOT use the following option. It turns out that this will often generate explosive conditional liklihood - //=== at the end of the sample, because Pt_tm1 shrinks to zero overtime due to the sigularity of - //=== the initila condition P_{1|0}. - //--- Letting z0_dv = 0.0 - // z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - // InitializeConstantVector_lf(&z0_sdv, 0.0); - // //--- Letting P0_dm = V - // CopyMatrix0(P0_dc->C[sti], Vt_dc->C[sti]); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (0); //Early exit with kalfilmsinputs_1stapp_ps->ztm1_track continues to be -1. - } - } - } - } - else - { - if (!z10_dm) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition z_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyMatrix0(z0_dm, z10_dm); - - if (!P10_dc) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition P_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyCell0(P0_dc, P10_dc); - } - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t-1 = 1. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t-1 = 1. - - - kalfilmsinputs_1stapp_ps->ztm1_track = 0; //Must reset to 0, meaning initial setting is done and ready for computing LH at t = 1. - - Update_et_Dt_1stapp(0, kalfilmsinputs_1stapp_ps); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (1); - } - else - { - fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): calling this function makes sense only if" - " kalfilmsinputs_1stapp_ps->ztm1_track is -1. Please check this value."); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (0); - } -} -//====================================================== -//= Integrating out the lagged regimes in order to -//= updating zt_tm1 and Pt_tm1 for next perid tp1 through Kim-Nelson filter. -//= tdata representing base-0 t timing, while inpt represents base-1 t timing. -// -//= Purpose: for each inpt, we integrate out grand regimes st -//= only ONCE to prevent the dimension of updated zt_tm1 and Pt_tm1 through Kim-Nelson filter. -//====================================================== -static int Updatekalfilms_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //Output: - // tm1update - // z_{t_1+1|t_1} - // P_{t_1+1|t_1} - //Input: - // t-1: base-1 t timing. Thus t-1=inpt-1. - - //--- Local variables - int stp1i, sti, t_2, t_2p1; - double prob_previous_regimes; - //-- Output arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Input arguments - TSdcell *Gt_dc = kalfilmsinputs_1stapp_ps->Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //+ - TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - int T = kalfilmsinputs_1stapp_ps->T; - TSdvector z0_sdv; - TSdvector btp1_sdv; - TSdvector etdata_sdv; - //=== Work arguments. - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - //+ - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //=== For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - //--- Critical checking. - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - fn_DisplayError(".../kalman.c/Updatekalfilms_1stapp(): Make sure InitializeKalman_z10_P10() is called in the function RefreshEverthing()"); - - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - btp1_sdv.n = nz; - btp1_sdv.flag = V_DEF; - //+ - etdata_sdv.n = ny; - etdata_sdv.flag = V_DEF; - - for (t_2=kalfilmsinputs_1stapp_ps->ztm1_track; t_2<t_1; t_2++) - { - //If t_1 <= ztm1_track, no updating. - //If t_1 > ztm1_track, updating z_{t|t-1} and P_{t|t-1} up to t-1 = t_1. - - zt_tm1_dc->C[t_2p1=t_2+1]->flag = M_GE; - for (stp1i=nst-1; stp1i>=0; stp1i--) - { - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=nst-1; sti>=0; sti--) - { - //=== Updating for next period by integrating out sti.. - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i], PHtran_tdata_d4->F[t_2]->C[sti], 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_d4->F[t_2]->C[sti]); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - etdata_sdv.v = etdata_dc->C[t_2]->M + ny*sti; - z0_sdv.v = zt_tm1_dc->C[t_2]->M + nz*sti; //sti: regime at time t_2. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, &etdata_sdv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i], Pt_tm1_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - - //--- Integrating out the state at t_2 using - //--- P(s_t_2|Y_{t_2}, theta) = ProbabilityStateConditionalCurrent(sti, t_2, smodel_ps); - //--- One can also access to P(s_t_2|Y_{t_2}, theta) by using ElementV(smodel_ps->V[t_2],s_{t_2}i), - //--- but this access will not call my function logTimetCondLH(), thus no updating for - //--- P(s_t_2|Y_{t_2}, and thus leading to incorrect results. - //--- we must pass t_2+1 as opposed to t_2. - prob_previous_regimes = ProbabilityStateConditionalCurrent(sti, t_2+1, smodel_ps); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - //--- Filling zt_tm1 and Pt_tm1 for next period. - z0_sdv.v = zt_tm1_dc->C[t_2p1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[t_2p1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - //--- $$$ The following is important because it tells ProbabilityStateConditionalCurrent(), which calls - //--- $$$ logTimetCondLH_kalfilms_1stapp(), which calls recursively this function again, that there is no - //--- $$$ need to update Kalman filter for the period before kalfilmsinputs_1stapp_ps->ztm1_track. - kalfilmsinputs_1stapp_ps->ztm1_track = t_2p1; //Means that z_{t_2p1+1|t_2p1} and P_{t_2p1+1|t_2p1} are done. - - //--- $$$ This function must be called after all the above computations are done. - Update_et_Dt_1stapp(t_2p1, kalfilmsinputs_1stapp_ps); - } - - - //=== - DestroyMatrix_lf(Wnzbynz_dm); - // - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (kalfilmsinputs_1stapp_ps->ztm1_track); -} -//====================================================== -//= Computes etdata and Dtdata for all grand regimes st at tbase0=inpt-1 or dtm1_track -//= to prevent recomputing this object for different st at given tbase0. -//====================================================== -static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - //Output: - // dtm1_track is updated in this function. - // PHtran_tdata_d4->F[t-1] - // etdata_dc->C[t-1] - // Dtdata_d4->F[t-1] - //Input: - // t_1=inpt-1: base-0 timing for et and Dt before the likelihood at time inpt is computed. - - //--- Local variables - int sti, tbase0; - //-- Output arguments - TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdcell *yt_tm1_dc = kalfilmsinputs_1stapp_ps->yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- input arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-T. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-T. - //+ - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv; - TSdvector yt_sdv, at_sdv; - TSdvector etdata_sdv, yt_tm1_sdv; - //=== Work arguments. - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - etdata_sdv.n = yt_tm1_sdv.n = ny; - etdata_sdv.flag = yt_tm1_sdv.flag = V_DEF; - - for (tbase0=(kalfilmsinputs_1stapp_ps->dtm1_track+1); tbase0<=t_1; tbase0++) - { - //Note tbase0<=t_1, NOT tbase0<t_1. - //If t_1 < (dtm1_track+1), no updating. - //If t_1 >= (dtm1_track+1), updating etdata_dc->C[t-1] and Dtdata_d4->F[t-1] up to t-1=t_1. - - for (sti=nst-1; sti>=0; sti--) - { - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti], 1.0, 0.0, 'N', 'T'); - CopyMatrix0(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4->F[tbase0]->C[sti], PHtran_tdata_dm); - - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti*at_dm->nrows; //grand regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - etdata_sdv.v = etdata_dc->C[tbase0]->M + etdata_sdv.n*sti; - yt_tm1_sdv.v = etdata_dc->C[tbase0]->M + yt_tm1_sdv.n*sti; - CopyVector0(&yt_tm1_sdv, &at_sdv); - MatrixTimesVector(&yt_tm1_sdv, Ht_dc->C[sti], &z0_sdv, 1.0, 1.0, 'N'); //a + H*z_{t|t-1}. - VectorMinusVector(&etdata_sdv, &yt_sdv, &yt_tm1_sdv); //y_t - a - H*z_{t|t-1}. - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - CopyMatrix0(Dtdata_d4->F[tbase0]->C[sti], Dtdata_dm); //Saved to be used for logTimetCondLH_kalfilms_1stapp(). - } - - //--- $$$ This tracker functions the same way as kalfilmsinputs_1stapp_ps->ztm1_track. - kalfilmsinputs_1stapp_ps->dtm1_track = tbase0; - } - - //=== - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyMatrix_lf(Dtdata_dm); - - return (kalfilmsinputs_1stapp_ps->dtm1_track); -} - - - - - - -//----------------------------------------------------- -//------------ OLD Code -------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -// -//- IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that -//- the coefficient regime is the 1st state variable, and -//- the volatility regime is the 2nd state variable. -//----------------------------------------------------- -#if defined (NEWVERSIONofDW_SWITCH) -double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int comst_c; //composite (s_tc, s_{t-1}c) - int st_c, stm1_c, st_v; - int comsti_c; //composite (s_tc, s_{t-1}c) - int sti, sti_c, stm1i_c, sti_v; - int comstp1i_c; //composite (s_{t+1}c, s_tc) - int stp1i, stp1i_c, stp1i_v; - int tbase0, tp1; - double logdet_Dtdata, loglh_timet; - static int record_tbase1_or_inpt_or_tp1 = 0; - static int passonce; - double prob_previous_regimes; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRstc = kalfilmsinputs_ps->nRstc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - int **Index = smodel_ps->sv->index; //Regime-switching states. - //smodel_ps->sv->index is for our new code. - // For old code (before 9 April 08 and before dsge_switch is created), use smodel_ps->sv->Index; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_logTimetLH_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - tbase0 = (tp1=inpt) - 1; - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (tbase0==0) - { - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[comsti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[comsti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, comsti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[comsti_c], Ft_dc->C[comsti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); -//=== ???????? For debugging purpose. -//if ((inpt<2) && (st==0)) -//{ -// fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - -// fprintf(FPTR_DEBUG, "wP0_dv:\n"); -// WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Vt_dc->C[sti_v=%d]:\n", sti_v); -// WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - -// fflush(FPTR_DEBUG); - -//} - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime comsti_c=%d and sti_v=%d and at time=%d\n", comsti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - } - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - if (indxIndRegimes ) - { - if (nRc==1) //Volatility. - { - comst_c = st_c = 0; - st_v = st; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_v = Index[st][1]; //volatility state s_tv - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comst_c = st_c = st; - st_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = st_c = Index[st][0]; - st_v = Index[st][1]; - } - } - else //Syncronized regimes - { - if (nRc>nRstc) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = st_c; - } - else - comst_c = st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[comst_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comst_c*at_dm->nrows; //comst_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comst_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comst_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //--- Forming the log conditional likelihood at t. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); -//if ((inpt>82) && (inpt<86) ) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %.16e "); - -// fflush(FPTR_DEBUG); -//} - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - - -//=== ???????? For debugging purpose. -if (inpt==1) -{ - double wk1, wk2; - - wk1 = logdet_Dtdata; - wk2 = VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, "logdet_Dtdata = %10.5f\n", wk1); - fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f\n", wk2); - fprintf(FPTR_DEBUG, "----- etdata_dv: \n"); - WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- yt_dv: \n"); - WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- at_dv: \n"); - WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- z0_dv: \n"); - WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- Ht_dc->C[comst_c=%d]:\n", comst_c); - WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); - - fprintf(FPTR_DEBUG, "\n\n"); - -} -// -fprintf(FPTR_DEBUG, " %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//fprintf(FPTR_DEBUG, "------------------------\n"); -//fprintf(FPTR_DEBUG, "st=%d and inpt=%d\n", st, inpt); -//fprintf(FPTR_DEBUG, "loglh_timet = %10.5f\n", loglh_timet); -//fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -//WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -////WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -////fprintf(FPTR_DEBUG, "\n"); -////WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//if ((inpt>82) && (inpt<86) ) -//if (inpt<2) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// tmp_Dtdata = logdeterminant(Dtdata_dm); -// tmp_expterm = VectorDotVector(wny_dv, etdata_dv); -// fprintf(FPTR_DEBUG, "logdeterminant(Dtdata_dm) = %10.5f;\n", tmp_Dtdata); -// fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f;\n", tmp_expterm); -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&at_sdv:\n"); -// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&z0_sdv:\n"); -// WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Ht_dc->C[comst_c=%d]:\n",comst_c); -// WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); -// fprintf(FPTR_DEBUG, "Rt_dc->C[st_v=%d]:\n", st_v); -// WriteMatrix(FPTR_DEBUG, Rt_dc->C[st_v], " %10.5f "); -// fprintf(FPTR_DEBUG, "Pt_tm1_d4->F[tbase0]->C[st = %d]:\n",st); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[st], " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); - - - - -//// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "zt_tm1_dc->C[tbase0]:\n"); -//// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -//// //WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -//// //fprintf(FPTR_DEBUG, "\n"); -//// fprintf(FPTR_DEBUG, "bt_dm = [\n"); -//// WriteMatrix(FPTR_DEBUG, bt_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); - -//// fprintf(FPTR_DEBUG, "et:\n"); -//// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "yt_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - -//// fprintf(FPTR_DEBUG, "at_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - - -//// for (ki=0; ki<Ht_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ht_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ht_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Ft_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ft_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ft_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Vt_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Vt_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Vt_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -// fflush(FPTR_DEBUG); -//} - - - //====================================================== - //= Updating zt_tm1 and Pt_tm1 for next perid tp1. - //= tdata = tbase0 is base-0 timing. - //====================================================== - if (inpt > record_tbase1_or_inpt_or_tp1) //This condition always satisfies at the 1st period (which is inpt=1). - { - passonce = 0; - record_tbase1_or_inpt_or_tp1 = inpt; - } - if (!passonce) - { - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comstp1i_c = stp1i_c = 0; - stp1i_v = stp1i; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_v = Index[stp1i][1]; //volatility state s_tv - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comstp1i_c = stp1i_c = stp1i; - stp1i_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comstp1i_c = stp1i_c = Index[stp1i][0]; - stp1i_v = Index[stp1i][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = stp1i_c; - } - else - comstp1i_c = stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[comsti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comsti_c*at_dm->nrows; //comsti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comsti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comsti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i_v]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_{t-1}, theta) = ElementV(smodel_ps->Z[inpt],s_{inpt}_i). - //--- Note tbase0 = inpt-1 because the data in DW code (ElementV) is base-1. - //--- Note at this point, we cannot access to P(s_t|Y_t, theta) = ElementV(smodel_ps->V[inpt],s_{inpt}_i) - //--- through DW's code. But we can modify my own code to do this later. - prob_previous_regimes = ElementV(smodel_ps->Z[inpt],sti); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - } - - -//=== ???????? For debugging purpose. -//if ((inpt>60) && (inpt<65) ) //if (inpt<5) -//{ -// int kip1; //Must be declared at the top of this "if" block. - -// fprintf(FPTR_DEBUG, "zt_tm1t=[\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); - -// for (ki=0; ki<Pt_tm1_d4->F[tbase0]->ncells; ki++) -// { -// kip1 = ki+1; -// fprintf(FPTR_DEBUG, "Pt_tm1_d4t(:,:,%d)=[\n", kip1); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[ki], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); -// } - -// fflush(FPTR_DEBUG); -//} - - -//=== ???????? For debugging purpose. -fprintf(FPTR_DEBUG, " loglh_timet = %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (loglh_timet); -} -#undef LOG2PI -#endif - - -/** -//---------------------------------------------------------------- -//-- Tested OK, but has not use because tz_Refresh_z_T7P_T_in_kalfilms_1st_approx() -//-- cannot access to ElementV(smodel_ps->V[tp1],sti) or ElementV(smodel_ps->V[tbase0],sti) -//-- because no likelihood has been formed at all before this function is called. -//---------------------------------------------------------------- -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -//----------------------------------------------------- -void tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - double debug1; - //--- Local variables - int stp1i, stp1i_c, stp1i_v, sti, sti_c, sti_v, tbase0, tp1; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, sti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti_c], Ft_dc->C[sti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime sti_c=%d and sti_v=%d and at time=%d\n", sti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - - -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[0]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[0]->C[0], " %.16e "); - - - //============== Updating zt_tm1 and Pt_tm1. ================== - for (tbase0=0; tbase0<T; tbase0++ ) - { - //tdata = tbase0 is base-0 timing. - tp1 = tbase0 + 1; //Next period. - - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes && (nRc==1)) - { - stp1i_c = 0; - stp1i_v = stp1i; - } - else if (indxIndRegimes && (nRv==1)) - { - stp1i_c = stp1i; - stp1i_v = 0; - } - else if (indxIndRegimes) - { - stp1i_c = smodel_ps->sv->Index[stp1i][0]; - stp1i_v = smodel_ps->sv->Index[stp1i][1]; - } - else - { - stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti_c*at_dm->nrows; //sti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[sti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_t, theta) = ElementV(smodel_ps->V[t+1],s_{t+1}_i). - //--- Note because the data in DW code (ElementV) is base-1, t+1 is actually tbase0. - debug1 = ElementV(smodel_ps->V[tp1],sti); //?????? Debug. - //ScalarTimesVectorUpdate(ztp1_dv, ElementV(smodel_ps->V[tp1],sti), ztp1_t_dv); - //ScalarTimesMatrix(Ptp1_dm, ElementV(smodel_ps->V[tp1],sti), Ptp1_t_dm, 1.0); - ScalarTimesVectorUpdate(ztp1_dv, 0.5, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, 0.5, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - -// fprintf(FPTR_DEBUG, "\n &yt_sdv:\n"); -// WriteMatrix(FPTR_DEBUG, &yt_sdv, " %.16e "); -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[tp1]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tp1], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[tp1]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tp1]->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fflush(FPTR_DEBUG); - - - } - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); -} -//----------------------------------------------------- -//- Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// (1) RunningGensys_const7varionly(lwzmodel_ps); -// (2) Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -// (3) tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(); -//- before using kalfilms_timet_1st_approx(). -//----------------------------------------------------- -double tz_kalfilms_timet_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0. The same for (T+1)-by-1 gbeta_dv and nlcoefs-by-(T+1) galpha_dm. - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int st_c, st_v, tbase0; - double loglh_timet; - //--- Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - TSdvector yt_sdv, at_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - if (smodel_ps->sv->nstates != zt_tm1_dc->C[0]->ncols) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Make sure that the column dimension of zt_tm1_dc->C is the same as smodel_ps->sv->nstates"); - - tbase0 = inpt - 1; //base-0 time t. - - if (indxIndRegimes && (nRc==1)) - { - st_c = 0; - st_v = st; - } - else if (indxIndRegimes && (nRv==1)) - { - st_c = st; - st_v = 0; - } - else if (indxIndRegimes) - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - st_c = smodel_ps->sv->Index[st][0]; - st_v = smodel_ps->sv->Index[st][1]; - } - else - { - st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + st_c*at_dm->nrows; //st_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[st_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - - //--- Forming the log conditional likelihood at t. - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //=== - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - - return (loglh_timet); -} -#undef LOG2PI -/**/ - - - - +/*=============================================================================================================== + * Check $$$ for important notes. + * Check <<>> for updating DW's new switch code or questions for DW. + * + * kalcvf_urw(): the Kalman filter forward prediction specialized for only a univariate random walk (urw) process. + * + * State space model is defined as follows: + * z(t+1) = z(t)+eta(t) (state or transition equation) + * y(t) = x(t)'*z(t)+eps(t) (observation or measurement equation) + * where for this function, eta and eps must be uncorrelated; y(t) must be 1-by-1. Note that + * x(t): k-by-1; + * z(t): k-by-1; + * eps(t): 1-by-1 and ~ N(0, sigma^2); + * eta(t): ~ N(0, V) where V is a k-by-k covariance matrix. + * + * + * Written by Tao Zha, May 2004. + * Revised, May 2008; +=================================================================================================================*/ + +/** +//=== For debugging purpose. +if (1) +{ + double t_loglht; + + t_loglht = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); + fprintf(FPTR_DEBUG, " %10.5f\n", t_loglht); + + fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); + + fprintf(FPTR_DEBUG, "\n wP0_dv:\n"); + WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); + fprintf(FPTR_DEBUG, "\n Vt_dc->C[sti_v=%d]:\n", sti_v); + WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); + + fflush(FPTR_DEBUG); +} +/**/ + + +#include "kalman.h" + + +static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); +int Updatekalfilms_1stapp(int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); + + +TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv) //, int storeZ, int storeV) +{ + int _i; + //=== + TSivector *rows_iv = NULL; + TSivector *cols_iv = NULL; + //--- + TSkalcvfurw *kalcvfurw_ps = tzMalloc(1, TSkalcvfurw); + + + kalcvfurw_ps->indx_tvsigmasq = tv; + kalcvfurw_ps->fss = T; + kalcvfurw_ps->kx = k; + + //=== + kalcvfurw_ps->V_dm = CreateMatrix_lf(k, k); + kalcvfurw_ps->ylhtran_dv = CreateVector_lf(T); + kalcvfurw_ps->Xrhtran_dm = CreateMatrix_lf(k, T); + kalcvfurw_ps->z10_dv = CreateVector_lf(k); + kalcvfurw_ps->P10_dm = CreateMatrix_lf(k, k); + + kalcvfurw_ps->zupdate_dv = CreateVector_lf(k); + kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); + kalcvfurw_ps->ylhtranpred_dv = CreateVector_lf(T); + // + rows_iv = CreateVector_int(T); + cols_iv = CreateVector_int(T); + for (_i=T-1; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; + kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); + // if (!storeZ) kalcvfurw_ps->Zpredtran_dm = (TSdmatrix *)NULL; + // else kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); + // if (!storeV) kalcvfurw_ps->Ppred_dc = (TSdcell *)NULL; + // else { + // rows_iv = CreateVector_int(T); + // cols_iv = CreateVector_int(T); + // for (_i=T; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; + // kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); + // } + + DestroyVector_int(rows_iv); + DestroyVector_int(cols_iv); + return (kalcvfurw_ps); +} + +TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps) +{ + if (kalcvfurw_ps) { + DestroyMatrix_lf(kalcvfurw_ps->V_dm); + DestroyVector_lf(kalcvfurw_ps->ylhtran_dv); + DestroyMatrix_lf(kalcvfurw_ps->Xrhtran_dm); + DestroyVector_lf(kalcvfurw_ps->z10_dv); + DestroyMatrix_lf(kalcvfurw_ps->P10_dm); + + DestroyVector_lf(kalcvfurw_ps->zupdate_dv); + DestroyMatrix_lf(kalcvfurw_ps->Zpredtran_dm); + DestroyCell_lf(kalcvfurw_ps->Ppred_dc); + DestroyVector_lf(kalcvfurw_ps->ylhtranpred_dv); + + free(kalcvfurw_ps); + return ((TSkalcvfurw *)NULL); + } + else return (kalcvfurw_ps); +} + + +void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps) +{ + //See the notes of SWZ regarding the government's updating of the parameters in their Phillips-curve equation. + //NOTE: make sure that the value of kalcvfurw_ps->sigmasq and other input values are given. + int ti; + double workd, workdenominv; + //--- + int fss, kx; + double sigmasq_fix = kalcvfurw_ps->sigmasq; +// double sigmasq; + TSdmatrix *V_dm; + TSdmatrix *Zpredtran_dm; + TSdcell *Ppred_dc; + TSdvector *ylhtran_dv; + TSdmatrix *Xrhtran_dm; + //=== + TSdvector *workkxby1_dv = NULL; //kx-by-1. +// TSdvector *work1kxby1_dv = NULL; //kx-by-1. + TSdmatrix *workkxbykx_dm = NULL; //kx-by-kx symmetric and positive positive. +// //=== +// TSdvector *zbefore_dv = CreateVector_lf(kalcvfurw_ps->kx); +// TSdmatrix *Vbefore_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); +// TSdvector *zafter_dv = CreateVector_lf(kalcvfurw_ps->kx); +// TSdmatrix *Vafter_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); + //******* WARNING: Some dangerous pointer movement to gain efficiency ******* +// double *yt_p; +// double *Vbefore_p; +// double *Vafter_p; + TSdvector xt_sdv; + TSdvector zbefore_sdv; + //TSdmatrix Vbefore_sdm; + TSdvector zafter_sdv; + //TSdmatrix Vafter_sdm; + + + if (!kalcvfurw_ps) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps must be created"); + if (!kalcvfurw_ps->V_dm || !kalcvfurw_ps->ylhtran_dv || !kalcvfurw_ps->Xrhtran_dm || !kalcvfurw_ps->z10_dv || !kalcvfurw_ps->P10_dm) + fn_DisplayError(".../kalcvf_urw(): input arguments kalcvfurw_ps->V_dm, kalcvfurw_ps->ylhtran_dv, kalcvfurw_ps->Xrhtran_dm, kalcvfurw_ps->z10_dv, kalcvfurw_ps->P10_dm must be given legal values"); + if (!(kalcvfurw_ps->P10_dm->flag & (M_SU | M_SL))) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps->P10_dm must be symmetric"); + fss = kalcvfurw_ps->fss; + kx = kalcvfurw_ps->kx; + V_dm = kalcvfurw_ps->V_dm; + Zpredtran_dm = kalcvfurw_ps->Zpredtran_dm; + Ppred_dc = kalcvfurw_ps->Ppred_dc; + ylhtran_dv = kalcvfurw_ps->ylhtran_dv; + Xrhtran_dm = kalcvfurw_ps->Xrhtran_dm; + //--- + xt_sdv.n = kx; + xt_sdv.flag = V_DEF; + zbefore_sdv.n = kx; + zbefore_sdv.flag = V_DEF; + zafter_sdv.n = kx; + zafter_sdv.flag = V_DEF; + + //=== Memory allocation. + workkxby1_dv = CreateVector_lf(kx); + workkxbykx_dm = CreateMatrix_lf(kx, kx); + + + //------- The first period (ti=0). ------- + zbefore_sdv.v = kalcvfurw_ps->z10_dv->v; + zafter_sdv.v = Zpredtran_dm->M; + xt_sdv.v = Xrhtran_dm->M; + //--- + + workd = ylhtran_dv->v[0] - (kalcvfurw_ps->ylhtranpred_dv->v[0]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. + SymmatrixTimesVector(workkxby1_dv, kalcvfurw_ps->P10_dm, &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; + + if (!kalcvfurw_ps->indx_tvsigmasq) + workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] + else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. + workdenominv = 1.0/(sigmasq_fix*square(kalcvfurw_ps->z10_dv->v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t]; + else { + printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); + exit(EXIT_FAILURE); + } + + + //--- Updating z_{t+1|t}. + CopyVector0(&zafter_sdv, &zbefore_sdv); + VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; + //--- Updating P_{t+1|t}. + CopyMatrix0(workkxbykx_dm, V_dm); + VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); + // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; + MatrixPlusMatrix(Ppred_dc->C[0], kalcvfurw_ps->P10_dm, workkxbykx_dm); + //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; + Ppred_dc->C[0]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, + // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). + //Done with all work* arrays. + + //------- The rest of the periods (ti=1:T-1). ------- + for (ti=1; ti<fss; ti++) { + //NOTE: ti=0 has been taken care of outside of this loop. + zbefore_sdv.v = Zpredtran_dm->M + (ti-1)*kx; + zafter_sdv.v = Zpredtran_dm->M + ti*kx; + xt_sdv.v = Xrhtran_dm->M + ti*kx; + //--- + workd = ylhtran_dv->v[ti] - (kalcvfurw_ps->ylhtranpred_dv->v[ti]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. + SymmatrixTimesVector(workkxby1_dv, Ppred_dc->C[ti-1], &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; + if (!kalcvfurw_ps->indx_tvsigmasq) + workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] + else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. + workdenominv = 1.0/(sigmasq_fix*square(zbefore_sdv.v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] + else { + printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); + exit(EXIT_FAILURE); + } + //--- Updating z_{t+1|t}. + CopyVector0(&zafter_sdv, &zbefore_sdv); + VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; + //--- Updating P_{t+1|t}. + CopyMatrix0(workkxbykx_dm, V_dm); + VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); + // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; + MatrixPlusMatrix(Ppred_dc->C[ti], Ppred_dc->C[ti-1], workkxbykx_dm); + //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; + Ppred_dc->C[ti]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, + // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). + //Done with all work* arrays. + } + CopyVector0(kalcvfurw_ps->zupdate_dv, &zafter_sdv); + Zpredtran_dm->flag = M_GE; + kalcvfurw_ps->ylhtranpred_dv->flag = V_DEF; + +// DestroyVector_lf(zbefore_dv); +// DestroyMatrix_lf(Vbefore_dm); +// DestroyVector_lf(zafter_dv); +// DestroyMatrix_lf(Vafter_dm); + + DestroyVector_lf(workkxby1_dv); +// DestroyVector_lf(work1kxby1_dv); + DestroyMatrix_lf(workkxbykx_dm); +} + + + +//----------------------------------------------------------------------------------------------------------------------- +//-- General constant (known-time-varying) Kalman filter for DSGE models. +//----------------------------------------------------------------------------------------------------------------------- +struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T) +{ + int _i; + //=== + TSivector *rows_iv = CreateVector_int(T); + TSivector *cols_iv = CreateVector_int(T); + //~~~ Creating the structure and initializing the NULL pointers. + struct TSkalfiltv_tag *kalfiltv_ps = tzMalloc(1, struct TSkalfiltv_tag); + + + //--- Default value. + kalfiltv_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + //0: using the unconditional mean for any given regime at time 0. + //--- Other assignments. + kalfiltv_ps->ny = ny; + kalfiltv_ps->nz = nz; + kalfiltv_ps->T = T; + + + + //--------- Creates memory and assigns values. The order matters. + kalfiltv_ps->yt_dm = CreateMatrix_lf(ny, T); + kalfiltv_ps->at_dm = CreateMatrix_lf(ny, T); + // + for (_i=T-1; _i>=0; _i--) + { + rows_iv->v[_i] = ny; + cols_iv->v[_i] = nz; + } + rows_iv->flag = cols_iv->flag = V_DEF; + kalfiltv_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); + // + for (_i=T-1; _i>=0; _i--) + { + rows_iv->v[_i] = ny; + cols_iv->v[_i] = ny; + } + kalfiltv_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); + // + for (_i=T-1; _i>=0; _i--) + { + rows_iv->v[_i] = nz; + cols_iv->v[_i] = ny; + } + kalfiltv_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); + // + kalfiltv_ps->bt_dm = CreateMatrix_lf(nz, T); + // + for (_i=T-1; _i>=0; _i--) + { + rows_iv->v[_i] = nz; + cols_iv->v[_i] = nz; + } + kalfiltv_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); + kalfiltv_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); + // + kalfiltv_ps->z0_dv = CreateVector_lf(nz); + kalfiltv_ps->P0_dm = CreateMatrix_lf(nz, nz); + + + //--- + kalfiltv_ps->zt_tm1_dm = CreateMatrix_lf(nz, T); + for (_i=T-1; _i>=0; _i--) + { + rows_iv->v[_i] = nz; + cols_iv->v[_i] = nz; + } + kalfiltv_ps->Pt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); + + + //=== + DestroyVector_int(rows_iv); + DestroyVector_int(cols_iv); + + return (kalfiltv_ps); + +} +//--- +struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) +{ + if (kalfiltv_ps) + { + //=== The order matters! + DestroyMatrix_lf(kalfiltv_ps->yt_dm); + DestroyMatrix_lf(kalfiltv_ps->at_dm); + DestroyCell_lf(kalfiltv_ps->Ht_dc); + DestroyCell_lf(kalfiltv_ps->Rt_dc); + DestroyCell_lf(kalfiltv_ps->Gt_dc); + //--- + DestroyMatrix_lf(kalfiltv_ps->bt_dm); + DestroyCell_lf(kalfiltv_ps->Ft_dc); + DestroyCell_lf(kalfiltv_ps->Vt_dc); + //--- + DestroyVector_lf(kalfiltv_ps->z0_dv); + DestroyMatrix_lf(kalfiltv_ps->P0_dm); + //--- + DestroyMatrix_lf(kalfiltv_ps->zt_tm1_dm); + DestroyCell_lf(kalfiltv_ps->Pt_tm1_dc); + + + //--- + tzDestroy(kalfiltv_ps); //Must be freed last! + + return ((struct TSkalfiltv_tag *)NULL); + } + else return (kalfiltv_ps); +}; + + +//----------------------------------------------------------------------------------------------------------------------- +//-- New code: Inputs for filter for Markov-switching DSGE models at any time t. +//----------------------------------------------------------------------------------------------------------------------- +struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp2(int ny, int nz, int nu, int ne, int nst, int T) +{ + //~~~ Creating the structure and initializing the NULL pointers. + struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); + + //=== + TSivector *rows_iv = NULL; + TSivector *cols_iv = NULL; + + //=== Default value. + kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + //0: using the unconditional mean for any given regime at time 0. + kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. + //0: using the unconditional moments. + kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; + kalfilmsinputs_1stapp_ps->ztm1_track = -1; + kalfilmsinputs_1stapp_ps->dtm1_track = -1; + + //--- Other key assignments. + kalfilmsinputs_1stapp_ps->ny = ny; + kalfilmsinputs_1stapp_ps->nz = nz; + kalfilmsinputs_1stapp_ps->nu = nu; + kalfilmsinputs_1stapp_ps->ne = ne; + kalfilmsinputs_1stapp_ps->nst = nst; + kalfilmsinputs_1stapp_ps->T = T; + + //--------- Creates memory and assigns values. The order matters. + kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); + kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); + // + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + if (nu) + { + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, nu); + kalfilmsinputs_1stapp_ps->Psiut_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + } + else + kalfilmsinputs_1stapp_ps->Psiut_dc = NULL; + // + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, ne); + kalfilmsinputs_1stapp_ps->Psiet_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. + kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + + //--- For output arguments. + rows_iv = CreateConstantVector_int(T+1, nz); + cols_iv = CreateConstantVector_int(T+1, nst); + kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(T, ny); + cols_iv = CreateConstantVector_int(T, nst); + kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). + rows_iv = CreateConstantVector_int(T, ny); + cols_iv = CreateConstantVector_int(T, nst); + // + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + + return (kalfilmsinputs_1stapp_ps); +} +//--- +struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp2(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) +{ + if (kalfilmsinputs_1stapp_ps) + { + //=== The order matters! + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Psiut_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); + //--- + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Psiet_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); + //--- + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); + //--- + DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); + DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); + DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); + DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); + //--- + tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! + + return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); + } + else return (kalfilmsinputs_1stapp_ps); +}; + +struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T) +{ + //~~~ Creating the structure and initializing the NULL pointers. + struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); + + //=== + TSivector *rows_iv = NULL; + TSivector *cols_iv = NULL; + + //=== Default value. + kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + //0: using the unconditional mean for any given regime at time 0. + kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. + //0: using the unconditional moments. + kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; + kalfilmsinputs_1stapp_ps->ztm1_track = -1; + kalfilmsinputs_1stapp_ps->dtm1_track = -1; + + //--- Other key assignments. + kalfilmsinputs_1stapp_ps->ny = ny; + kalfilmsinputs_1stapp_ps->nz = nz; + kalfilmsinputs_1stapp_ps->nst = nst; + kalfilmsinputs_1stapp_ps->T = T; + + //--------- Creates memory and assigns values. The order matters. + kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); + kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); + // + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. + kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + + //--- For output arguments. + rows_iv = CreateConstantVector_int(T+1, nz); + cols_iv = CreateConstantVector_int(T+1, nst); + kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, nz); + kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nst, nz); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(T, ny); + cols_iv = CreateConstantVector_int(T, nst); + kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). + rows_iv = CreateConstantVector_int(T, ny); + cols_iv = CreateConstantVector_int(T, nst); + // + rows_iv = CreateConstantVector_int(nst, ny); + cols_iv = CreateConstantVector_int(nst, ny); + kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + + return (kalfilmsinputs_1stapp_ps); +} +//--- +struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) +{ + if (kalfilmsinputs_1stapp_ps) + { + //=== The order matters! + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); + //--- + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); + //--- + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); + DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); + //--- + DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); + DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); + DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); + DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); + DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); + //--- + tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! + + return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); + } + else return (kalfilmsinputs_1stapp_ps); +}; + + +//----------------------------------------------------------------------------------------------------------------------- +//-- OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. +//----------------------------------------------------------------------------------------------------------------------- +struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T) +{ + //~~~ Creating the structure and initializing the NULL pointers. + struct TSkalfilmsinputs_tag *kalfilmsinputs_ps = tzMalloc(1, struct TSkalfilmsinputs_tag); + + //=== + TSivector *rows_iv = NULL; + TSivector *cols_iv = NULL; + + //--- Default value. + kalfilmsinputs_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + //0: using the unconditional mean for any given regime at time 0. + //--- Other assignments. + kalfilmsinputs_ps->ny = ny; + kalfilmsinputs_ps->nz = nz; + kalfilmsinputs_ps->nRc = nRc; + kalfilmsinputs_ps->nRstc = nRstc; + kalfilmsinputs_ps->nRv = nRv; + kalfilmsinputs_ps->indxIndRegimes = indxIndRegimes; + kalfilmsinputs_ps->T = T; + + + //--------- Creates memory and assigns values. The order matters. + kalfilmsinputs_ps->yt_dm = CreateMatrix_lf(ny, T); + kalfilmsinputs_ps->at_dm = CreateMatrix_lf(ny, nRc); + // + rows_iv = CreateConstantVector_int(nRc, ny); + cols_iv = CreateConstantVector_int(nRc, nz); + kalfilmsinputs_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nRv, ny); + cols_iv = CreateConstantVector_int(nRv, ny); + kalfilmsinputs_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nRv, nz); + cols_iv = CreateConstantVector_int(nRv, ny); + kalfilmsinputs_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + kalfilmsinputs_ps->bt_dm = CreateMatrix_lf(nz, nRc); + // + rows_iv = CreateConstantVector_int(nRc, nz); + cols_iv = CreateConstantVector_int(nRc, nz); + kalfilmsinputs_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nRv, nz); + cols_iv = CreateConstantVector_int(nRv, nz); + kalfilmsinputs_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + if (indxIndRegimes) + { + kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRc*nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. + // + rows_iv = CreateConstantVector_int(nRc*nRv, nz); + cols_iv = CreateConstantVector_int(nRc*nRv, nz); + kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + } + else + { + if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); + kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. + // + rows_iv = CreateConstantVector_int(nRv, nz); + cols_iv = CreateConstantVector_int(nRv, nz); + kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + } + //--- For output arguments. + if (indxIndRegimes) + { + rows_iv = CreateConstantVector_int(T, nz); + cols_iv = CreateConstantVector_int(T, nRc*nRv); + kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nRc*nRv, nz); + cols_iv = CreateConstantVector_int(nRc*nRv, nz); + kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + } + else + { + if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); + rows_iv = CreateConstantVector_int(T, nz); + cols_iv = CreateConstantVector_int(T, nRv); + kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + // + rows_iv = CreateConstantVector_int(nRv, nz); + cols_iv = CreateConstantVector_int(nRv, nz); + kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + rows_iv = DestroyVector_int(rows_iv); + cols_iv = DestroyVector_int(cols_iv); + } + + + //=== + DestroyVector_int(rows_iv); + DestroyVector_int(cols_iv); + + return (kalfilmsinputs_ps); + +} +//--- +struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps) +{ + if (kalfilmsinputs_ps) + { + //=== The order matters! + DestroyMatrix_lf(kalfilmsinputs_ps->yt_dm); + DestroyMatrix_lf(kalfilmsinputs_ps->at_dm); + DestroyCell_lf(kalfilmsinputs_ps->Ht_dc); + DestroyCell_lf(kalfilmsinputs_ps->Rt_dc); + DestroyCell_lf(kalfilmsinputs_ps->Gt_dc); + //--- + DestroyMatrix_lf(kalfilmsinputs_ps->bt_dm); + DestroyCell_lf(kalfilmsinputs_ps->Ft_dc); + DestroyCell_lf(kalfilmsinputs_ps->Vt_dc); + //--- + DestroyMatrix_lf(kalfilmsinputs_ps->z0_dm); + DestroyCell_lf(kalfilmsinputs_ps->P0_dc); + //--- + DestroyCell_lf(kalfilmsinputs_ps->zt_tm1_dc); + DestroyFourth_lf(kalfilmsinputs_ps->Pt_tm1_d4); + //--- + tzDestroy(kalfilmsinputs_ps); //Must be freed last! + + return ((struct TSkalfilmsinputs_tag *)NULL); + } + else return (kalfilmsinputs_ps); +}; + + +#define LOG2PI (1.837877066409345e+000) //log(2*pi) +//----------------------------------------------------- +//-- Constant-parameters (known-time-varying) Kalman filter +//----------------------------------------------------- +double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) +{ + //General constant (known-time-varying) Kalman filter for DSGE models (conditional on all the parameters). + // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. + // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m + // + // State space model is defined as follows: + // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) + // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) + // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. + // + // Inputs are as follows: + // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. + // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. + // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. + // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. + // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). + // ------ + // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. + // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. + // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. + // ------ + // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + // 0: using the unconditional mean for any given regime at time 0. + // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Do not enter if indxIni=0.) + // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Do not enter if indxIni=0.) + // + // Outputs are as follows: + // loglh is a value of the log likelihood function of the state-space model + // under the assumption that errors are multivariate Gaussian. + // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) + // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. + // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition + // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. + // + // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: + // z0_0m1 = (I-F(:,:,1))\b(:,1) + // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) + // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). + // + // March 2007, written by Tao Zha + // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. + + int T = kalfiltv_ps->T; + int Tp1 = T + 1; + int ny = kalfiltv_ps->ny; + int nz = kalfiltv_ps->nz; + int indx_badlh = 0; //1: bad likelihood with, say, -infinity of the LH value. + int tdata, ti; + //--- Work arguments. + int nz2 = square(nz); + TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdvector *wP0_dv = CreateVector_lf(nz2); + //+ + TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; //double loglh_tdata; //logdetDtdata. + TSdvector *wny_dv = CreateVector_lf(ny); + TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); + TSdvector *etdata_dv = CreateVector_lf(ny); + TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); + TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); + //--- For eigenvalue decompositions + int ki; + int errflag; + double eigmax, logdet_Dtdata; + TSdzvector *evals_dzv = NULL; + TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. + //--- Input arguments. + TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. + TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. + TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. + TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. + // + TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. + TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. + TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. + // + TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; + TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. + //--- Output arguments. + double loglh; //log likelihood. + TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. + TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. + + + + //=== Initializing. + if (!kalfiltv_ps->indxIni) + { + InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - + InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - + + //=== Eigenanalysis to determine the roots to ensure boundedness. + evals_dzv = CreateVector_dz(nz); + evals_abs_dv = CreateVector_lf(nz); + errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); + if (errflag) fn_DisplayError("tz_kalfiltv() in kalman.c: eigen decomposition failed"); + for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); + evals_abs_dv->flag = V_DEF; + eigmax = MaxVector(evals_abs_dv); + if (eigmax < (1.0+1.0e-14)) + { + //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); + MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); + CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); + bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); + //Done with Wnzbynz_dm. + //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); + tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); + MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); + CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); + bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); + CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); + //Done with all w*_dv and W*_dm. + } + else + { + fprintf(stdout, "Fatal error: tz_kalfiltv() in kalman.c: the system is non-stationary solutions\n" + " and the initial conditions must be supplied by, say, input arguments"); + fflush(stdout); + exit( EXIT_FAILURE ); + } + } + CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); + CopyMatrix0(Pt_tm1_dc->C[0], P0_dm); + + //====== See p.002 in LiuWZ. ====== + at_sdv.n = yt_sdv.n = yt_dm->nrows; + at_sdv.flag = yt_sdv.flag = V_DEF; + zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; + zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; + btp1_sdv.n = bt_dm->nrows; + btp1_sdv.flag = V_DEF; + loglh = 0.0; + for (tdata=0; tdata<T; tdata++ ) + { + //Base-0 timing. + ti = tdata + 1; //Next period. + + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; + yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; + at_sdv.v = at_dm->M + tdata*at_dm->nrows; + zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; + VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); + MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); + CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. + //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message + // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either + // a bad number or a complex number. + Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; + + //--- Forming the log likelihood. + if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (kalfiltv_ps->loglh = -NEARINFINITY); + bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); + loglh += -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); + //loglh += -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); + //Done with all w*_dv. + + + //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. + if (ti<T) + { + //Updating only up to tdata=T-2. The values at ti=T or tdata=T-1 will not be used in the likelihood function. + + //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; + CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); + MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[ti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); + //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; + ztp1_t_sdv.v = zt_tm1_dm->M + ti*zt_tm1_dm->nrows; + MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[ti], &zt_tm1_sdv, 1.0, 0.0, 'N'); + MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); + btp1_sdv.v = bt_dm->M + ti*btp1_sdv.n; + VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); + //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); + CopyMatrix0(Pt_tm1_dc->C[ti], Vt_dc->C[ti]); + MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); + MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[ti], Wnzbynz_dm, -1.0); + //Done with all W*_dm. + MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[ti], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[ti], 1.0, 0.0, 'N', 'T'); + MatrixPlusMatrixUpdate(Pt_tm1_dc->C[ti], W2nzbynz_dm); + //Done with all W*_dm. + } + } + zt_tm1_dm->flag = M_GE; + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + // + DestroyVector_lf(wny_dv); + DestroyMatrix_lf(Wnzbyny_dm); + DestroyMatrix_lf(W2nzbynz_dm); + DestroyMatrix_lf(PHtran_tdata_dm); + DestroyVector_lf(etdata_dv); + DestroyMatrix_lf(Dtdata_dm); + DestroyMatrix_lf(Kt_tdata0_dm); + DestroyMatrix_lf(Kt_tdata_dm); + + return (kalfiltv_ps->loglh = loglh); +} +/** +double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) +{ + //This function is used to test tz_logTimetCondLH_kalfiltv(). + int T = kalfiltv_ps->T; + int tdata; + double loglh; + + loglh = 0.0; + for (tdata=0; tdata<T; tdata++) loglh += tz_logTimetCondLH_kalfiltv(0, tdata+1, kalfiltv_ps); + + return (loglh); +} +/**/ +//----------------------------------------------------- +//-- Updating Kalman filter at time t for constant-parameters (or known-time-varying) Kalman filter. +//----------------------------------------------------- +double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps) +{ + //st: base-0 grand regime at time t, which is just a dummy for this constant-parameter function in order to use + // Waggoner's automatic functions. + //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. + // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). + // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. + //See (42.3) on p.42 in the SWZII NOTES. + // + //log LH at time t for constant (known-time-varying) Kalman-filter DSGE models (conditional on all the parameters). + // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood at time t. + // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m + // + // State space model is defined as follows: + // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) + // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) + // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. + // + // Inputs are as follows: + // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. + // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. + // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. + // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. + // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). + // ------ + // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. + // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. + // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. + // ------ + // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + // 0: using the unconditional mean for any given regime at time 0. + // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) + // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) + // + // Outputs are as follows: + // loglh is a value of the log likelihood function of the state-space model + // under the assumption that errors are multivariate Gaussian. + // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) + // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. + // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition + // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. + // + // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: + // z0_0m1 = (I-F(:,:,1))\b(:,1) + // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) + // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). + // + // April 2008, written by Tao Zha + // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. + + //--- Output arguments. + double loglh_timet; //log likelihood at time t. + TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. + TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. + //--- Input arguments. + int tdata, tp1; + TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; + TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. + int T = kalfiltv_ps->T; + int ny = kalfiltv_ps->ny; + int nz = kalfiltv_ps->nz; + //--- Work arguments. + int nz2 = square(nz); + TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdvector *wP0_dv = CreateVector_lf(nz2); + //+ + TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; + TSdvector *wny_dv = CreateVector_lf(ny); + TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); + TSdvector *etdata_dv = CreateVector_lf(ny); + TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); + TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); + //--- For eigenvalue decompositions + int ki; + int errflag; + double eigmax, logdet_Dtdata; + TSdzvector *evals_dzv = NULL; + TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. + //--- Input arguments. + TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. + TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. + TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. + TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. + // + TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. + TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. + TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. + // + + + tdata = (tp1=inpt) - 1; //Base-0 time. + + //======= Initial condition. ======= + if (tdata==0) + { + //=== Initializing. + if (!kalfiltv_ps->indxIni) + { + InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - + InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - + + //=== Eigenanalysis to determine the roots to ensure boundedness. + evals_dzv = CreateVector_dz(nz); + evals_abs_dv = CreateVector_lf(nz); + errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); + if (errflag) fn_DisplayError("tz_logTimetCondLH_kalfiltv() in kalman.c: eigen decomposition failed"); + for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); + evals_abs_dv->flag = V_DEF; + eigmax = MaxVector(evals_abs_dv); + if (eigmax < (1.0+1.0e-14)) + { + //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); + MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); + CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); + bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); + //Done with Wnzbynz_dm. + //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); + tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); + MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); + CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); + bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); + CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); + //Done with all w*_dv and W*_dm. + } + else + { + fprintf(FPTR_DEBUG, "Fatal error: tz_logTimetCondLH_kalfiltv() in kalman.c: the system is non-stationary solutions\n" + " and thus the initial conditions must be supplied by, say, input arguments"); + fflush(FPTR_DEBUG); + exit( EXIT_FAILURE ); + } + } + CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); + CopyMatrix0(Pt_tm1_dc->C[tdata], P0_dm); + } + + + //======= Liklihood at time t (see p.002 in LiuWZ). ======= + at_sdv.n = yt_sdv.n = yt_dm->nrows; + at_sdv.flag = yt_sdv.flag = V_DEF; + zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; + zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; + btp1_sdv.n = bt_dm->nrows; + btp1_sdv.flag = V_DEF; + + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; + yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; + at_sdv.v = at_dm->M + tdata*at_dm->nrows; + zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; + VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); + MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); + CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. + //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message + // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either + // a bad number or a complex number. + Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; + + //--- Forming the log likelihood. + if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); + bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); + loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); + //Done with all w*_dv. + + + //======= Updating for the next period. ======= + //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. + if (tp1<T) + { + //Updating only up to tdata=T-2, because the values at tp1=T or tdata=T-1 will NOT be used in the likelihood function. + + //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; + CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); + MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[tp1], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); + //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; + ztp1_t_sdv.v = zt_tm1_dm->M + tp1*zt_tm1_dm->nrows; + MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[tp1], &zt_tm1_sdv, 1.0, 0.0, 'N'); + MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); + btp1_sdv.v = bt_dm->M + tp1*btp1_sdv.n; + VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); + //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); + CopyMatrix0(Pt_tm1_dc->C[tp1], Vt_dc->C[tp1]); + MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); + MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[tp1], Wnzbynz_dm, -1.0); + //Done with all W*_dm. + MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[tp1], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[tp1], 1.0, 0.0, 'N', 'T'); + MatrixPlusMatrixUpdate(Pt_tm1_dc->C[tp1], W2nzbynz_dm); + //Done with all W*_dm. + } + zt_tm1_dm->flag = M_GE; + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + // + DestroyVector_lf(wny_dv); + DestroyMatrix_lf(Wnzbyny_dm); + DestroyMatrix_lf(W2nzbynz_dm); + DestroyMatrix_lf(PHtran_tdata_dm); + DestroyVector_lf(etdata_dv); + DestroyMatrix_lf(Dtdata_dm); + DestroyMatrix_lf(Kt_tdata0_dm); + DestroyMatrix_lf(Kt_tdata_dm); + + return (loglh_timet); +} + + + + +//----------------------------------------------------- +//- WARNING: bedore using this function, make sure to call the following functions +// Only once in creating lwzmodel_ps: Refresh_kalfilms_*(lwzmodel_ps); +// Everytime when parameters are changed: RefreshEverything(); RefreRunningGensys_allcases(lwzmodel_ps) in particular. +//----------------------------------------------------- +double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) +{ + //st: base-0 grand regime -- deals with the cross-section values at time t. + //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. + // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). + // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. + //See (42.3) on p.42 in the SWZII NOTES. + + //-- Output arguments + double loglh_timet; + //--- Input arguments + TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. + TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). + //--- Local variables + int tbase0; + double logdet_Dtdata; + //--- Accessible variables + int ny = kalfilmsinputs_1stapp_ps->ny; + TSdvector etdata_sdv; + //=== Work arguments. + TSdvector *wny_dv = CreateVector_lf(ny); + + + + //--- Critical checking. + if (inpt > kalfilmsinputs_1stapp_ps->T) + fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): The time exceeds the\n" + " data sample size allocated the structure TSkalfilmsinputs_1stapp_tag"); + + //--- The following is for safe guard. InitializeKalman_z10_P10() should be called in, say, RefreshEverything(). + if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) + if (!InitializeKalman_z10_P10(kalfilmsinputs_1stapp_ps, (TSdmatrix *)NULL, (TSdcell *)NULL)) + fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): the system is non-stationary when calling" + " InitializeKalman_z10_P10(). Please call this function in RefreshEverthing() and" + " set the likehood to be -infty for early exit"); + + tbase0=inpt-1; + + //------------------- The order matters. Updatekalfilms_1stapp() must be called before Update_et_Dt_1stapp(). ----------------- + //--- $$$ Critical updating where we MUSt have inpt-1. If inpt, Updatekalfilms_1stapp() will call this function again + //--- $$$ because DW function ProbabilityStateConditionalCurrent() need to access this function at time inpt, + //--- $$$ which has not computed before Updatekalfilms_1stapp(). Thus, we'll have an infinite loop. + Updatekalfilms_1stapp(tbase0, kalfilmsinputs_1stapp_ps, smodel_ps); +// //--- $$$ Critical updating. +// Update_et_Dt_1stapp(tbase0, kalfilmsinputs_1stapp_ps); +// //This function will give Dtdata_d4->F[tbase0], etdata_dc->C[tbase0], and PHtran_tdata_d4->F[tbase0]. + + + + //====================================================== + //= Getting the logLH at time tbase0 or time inpt. + //====================================================== + //--- Forming the log conditional likelihood at t. + etdata_sdv.n = ny; + etdata_sdv.v = etdata_dc->C[tbase0]->M + ny*st; + etdata_sdv.flag = V_DEF; + if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_d4->F[tbase0]->C[st]))) return (loglh_timet = -NEARINFINITY); + bdivA_rgens(wny_dv, &etdata_sdv, '/', Dtdata_d4->F[tbase0]->C[st]); + loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, &etdata_sdv); + //Done with all w*_dv. + + //=== + DestroyVector_lf(wny_dv); + + return (loglh_timet); +} +//====================================================== +//= Computing z_{1|0} and P_{1|0} for each new parameter values. +//====================================================== +int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc) +{ + //See p.001 and p.004 in LWZ Model II. + //Outputs: + // return 1: success in initializing; 0: initializing fails, so the likelihood must be set to -infty outside this function. + // ztm1_track to track the time up to which Kalman filter have been updated. + // z0_dm, zt_tm1_dc->C[0] + // P0_dc, Pt_tm1_d4->F[0] + + //--- Output arguments + TSdmatrix *z0_0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. + TSdmatrix *z0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. + TSdcell *P0_dc = kalfilmsinputs_1stapp_ps->P0_dc; //nz-by-nz-by-nst. + //+ Used to get zt_tm1_dc->C[0] and Pt_tm1_d4->F[0] only. + TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). + TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). + //--- Input arguments + TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. + TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. + TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. + //+ + TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. + TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. + TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. + //--- Local variables + int sti; + //--- Accessible variables + int ny = kalfilmsinputs_1stapp_ps->ny; + int nz = kalfilmsinputs_1stapp_ps->nz; + int nst = kalfilmsinputs_1stapp_ps->nst; + TSdvector z0_sdv, z0_0_sdv, bt_sdv; + TSdvector yt_sdv, at_sdv; + //--- For the initial conditions: eigenvalue decompositions + int ki; + int errflag; + double eigmax; + //=== + int nz2 = square(nz); + TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdvector *wP0_dv = CreateVector_lf(nz2); + // + TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); + TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. + + + if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) + { + z0_sdv.n = z0_0_sdv.n = bt_sdv.n = nz; + z0_sdv.flag = z0_0_sdv.flag = bt_sdv.flag = V_DEF; + at_sdv.n = yt_sdv.n = ny; + at_sdv.flag = yt_sdv.flag = V_DEF; + + + //======= Initial condition. ======= + if (!kalfilmsinputs_1stapp_ps->indxIni) + { + z0_0_dm->flag = z0_dm->flag = M_GE; + for (sti=nst-1; sti>=0; sti--) + { + if (kalfilmsinputs_1stapp_ps->DiffuseScale) //Diffuse initial conditions are used. + { + //--- Diffuse condition for z0_dv. + z0_sdv.v = z0_dm->M + z0_sdv.n*sti; + z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; + bt_sdv.v = bt_dm->M + bt_sdv.n*sti; + InitializeConstantVector_lf(&z0_0_sdv, 0.0); + MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); + VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); + //--- Diffuse condition for P0_dm. + InitializeDiagonalMatrix_lf(Wnzbynz_dm, kalfilmsinputs_1stapp_ps->DiffuseScale); //To be used for DiffuseScale*I(nz) + CopyMatrix0(P0_dc->C[sti], Wnzbynz_dm); + //Done with W*_dm. + } + else //Unconditional moments for initial conditions are used. + { + InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - + InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - + + //=== Eigenanalysis to determine the roots to ensure boundedness. + errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti]); + if (errflag) fn_DisplayError("kalman.c/InitializeKalman_z10_P10(): eigen decomposition failed"); + for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); + evals_abs_dv->flag = V_DEF; + eigmax = MaxVector(evals_abs_dv); + if (eigmax < (1.0-SQRTEPSILON)) //(1.0+EPSILON)) + { + //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,sti))\b(:,sti); + z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; + z0_sdv.v = z0_dm->M + z0_sdv.n*sti; + MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti]); + CopySubmatrix2vector(&z0_0_sdv, 0, bt_dm, 0, sti, bt_dm->nrows); + bdivA_rgens(&z0_0_sdv, &z0_0_sdv, '\\', Wnzbynz_dm); + //- Under the assumption s_0 = s_1 (this is a short-cut). + MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); + VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); + //Done with Wnzbynz_dm. + //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,sti),F(:,:,sti)))\V1(:),n_z,n_z); + tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti], Ft_dc->C[sti]); + MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); + CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti], 0, 0, nz2); + bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); + CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); + //Done with all w*_dv and W*_dm. + } + else + { + if (0) //0: no printing. + { + #if defined (USE_DEBUG_FILE) + fprintf(FPTR_DEBUG, "\n-------WARNING: ----------\n"); + fprintf(FPTR_DEBUG, "\nIn grand regime sti=%d\n", sti); + fprintf(FPTR_DEBUG, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" + " and see p.003 in LWZ Model II"); + #else + fprintf(stdout, "\n-----------------\n"); + fprintf(stdout, "\nIn grand regime sti=%d\n", sti); + fprintf(stdout, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" + " and see p.003 in LWZ Model II"); + #endif + } + //=== See p.000.3 in LWZ Model II. + //=== Do NOT use the following option. It turns out that this will often generate explosive conditional liklihood + //=== at the end of the sample, because Pt_tm1 shrinks to zero overtime due to the sigularity of + //=== the initila condition P_{1|0}. + //--- Letting z0_dv = 0.0 + // z0_sdv.v = z0_dm->M + z0_sdv.n*sti; + // InitializeConstantVector_lf(&z0_sdv, 0.0); + // //--- Letting P0_dm = V + // CopyMatrix0(P0_dc->C[sti], Vt_dc->C[sti]); + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + + return (0); //Early exit with kalfilmsinputs_1stapp_ps->ztm1_track continues to be -1. + } + } + } + } + else + { + if (!z10_dm) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition z_{1|0}\n" + " must be supplied as valid input arguments for when indxIni == 1"); + else + CopyMatrix0(z0_dm, z10_dm); + + if (!P10_dc) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition P_{1|0}\n" + " must be supplied as valid input arguments for when indxIni == 1"); + else + CopyCell0(P0_dc, P10_dc); + } + CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t-1 = 1. + CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t-1 = 1. + + + kalfilmsinputs_1stapp_ps->ztm1_track = 0; //Must reset to 0, meaning initial setting is done and ready for computing LH at t = 1. + + Update_et_Dt_1stapp(0, kalfilmsinputs_1stapp_ps); + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + + return (1); + } + else + { + fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): calling this function makes sense only if" + " kalfilmsinputs_1stapp_ps->ztm1_track is -1. Please check this value."); + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + + return (0); + } +} +//====================================================== +//= Integrating out the lagged regimes in order to +//= updating zt_tm1 and Pt_tm1 for next perid tp1 through Kim-Nelson filter. +//= tdata representing base-0 t timing, while inpt represents base-1 t timing. +// +//= Purpose: for each inpt, we integrate out grand regimes st +//= only ONCE to prevent the dimension of updated zt_tm1 and Pt_tm1 through Kim-Nelson filter. +//====================================================== +int Updatekalfilms_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) +{ + //Output: + // tm1update + // z_{t_1+1|t_1} + // P_{t_1+1|t_1} + //Input: + // t-1: base-1 t timing. Thus t-1=inpt-1. + + //--- Local variables + int stp1i, sti, t_2, t_2p1; + double prob_previous_regimes; + //-- Output arguments + TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). + TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). + //--- Input arguments + TSdcell *Gt_dc = kalfilmsinputs_1stapp_ps->Gt_dc; //nz-by-ny-by-nst. Cross-covariance. + //+ + TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. + TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. + TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. + //+ + TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). + TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. + TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). + //--- Accessible variables + int ny = kalfilmsinputs_1stapp_ps->ny; + int nz = kalfilmsinputs_1stapp_ps->nz; + int nst = kalfilmsinputs_1stapp_ps->nst; + int T = kalfilmsinputs_1stapp_ps->T; + TSdvector z0_sdv; + TSdvector btp1_sdv; + TSdvector etdata_sdv; + //=== Work arguments. + TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); + //+ + TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); + //=== For updating zt_tm1_dm and Pt_tm1. + TSdvector *ztp1_t_dv = CreateVector_lf(nz); + TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); + TSdvector *ztp1_dv = CreateVector_lf(nz); + TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); + + + //--- Critical checking. + if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) + fn_DisplayError(".../kalman.c/Updatekalfilms_1stapp(): Make sure InitializeKalman_z10_P10() is called in the function RefreshEverthing()"); + + + z0_sdv.n = nz; + z0_sdv.flag = V_DEF; + btp1_sdv.n = nz; + btp1_sdv.flag = V_DEF; + //+ + etdata_sdv.n = ny; + etdata_sdv.flag = V_DEF; + + for (t_2=kalfilmsinputs_1stapp_ps->ztm1_track; t_2<t_1; t_2++) + { + //If t_1 <= ztm1_track, no updating. + //If t_1 > ztm1_track, updating z_{t|t-1} and P_{t|t-1} up to t-1 = t_1. + + zt_tm1_dc->C[t_2p1=t_2+1]->flag = M_GE; + for (stp1i=nst-1; stp1i>=0; stp1i--) + { + InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. + InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. + + for (sti=nst-1; sti>=0; sti--) + { + //=== Updating for next period by integrating out sti.. + //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; + //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. + CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti]); + MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i], PHtran_tdata_d4->F[t_2]->C[sti], 1.0, 1.0, 'N', 'N'); + BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_d4->F[t_2]->C[sti]); + //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. + etdata_sdv.v = etdata_dc->C[t_2]->M + ny*sti; + z0_sdv.v = zt_tm1_dc->C[t_2]->M + nz*sti; //sti: regime at time t_2. + MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i], &z0_sdv, 1.0, 0.0, 'N'); + MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, &etdata_sdv, 1.0, 1.0, 'N'); + btp1_sdv.v = bt_dm->M + stp1i*btp1_sdv.n; + VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); + //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); + CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); + MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); + MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); + //Done with all W*_dm. + MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i], Pt_tm1_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i], 1.0, 0.0, 'N', 'T'); + MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); + //Done with all W*_dm. + + + //--- Integrating out the state at t_2 using + //--- P(s_t_2|Y_{t_2}, theta) = ProbabilityStateConditionalCurrent(sti, t_2, smodel_ps); + //--- One can also access to P(s_t_2|Y_{t_2}, theta) by using ElementV(smodel_ps->V[t_2],s_{t_2}i), + //--- but this access will not call my function logTimetCondLH(), thus no updating for + //--- P(s_t_2|Y_{t_2}, and thus leading to incorrect results. + //--- ProbabilityStateConditionalCurrent() assumes first data starts at time 1, not 0. Thus + //--- we must pass t_2+1 as opposed to t_2. + prob_previous_regimes = ProbabilityStateConditionalCurrent(sti, t_2+1, smodel_ps); + ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); + ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); + Ptp1_dm->flag = M_GE | M_SU | M_SL; + //Done with ztp1_t_dv and Ptp1_t_dm. + } + //--- Filling zt_tm1 and Pt_tm1 for next period. + z0_sdv.v = zt_tm1_dc->C[t_2p1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. + CopyVector0(&z0_sdv, ztp1_dv); + CopyMatrix0(Pt_tm1_d4->F[t_2p1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. + //Done with ztp1_dv, z0_sdv, Ptp1_dm. + } + //--- $$$ The following is important because it tells ProbabilityStateConditionalCurrent(), which calls + //--- $$$ logTimetCondLH_kalfilms_1stapp(), which calls recursively this function again, that there is no + //--- $$$ need to update Kalman filter for the period before kalfilmsinputs_1stapp_ps->ztm1_track. + kalfilmsinputs_1stapp_ps->ztm1_track = t_2p1; //Means that z_{t_2p1+1|t_2p1} and P_{t_2p1+1|t_2p1} are done. + + //--- $$$ This function must be called after all the above computations are done. + Update_et_Dt_1stapp(t_2p1, kalfilmsinputs_1stapp_ps); + } + + + //=== + DestroyMatrix_lf(Wnzbynz_dm); + // + DestroyMatrix_lf(Wnzbyny_dm); + DestroyMatrix_lf(W2nzbynz_dm); + DestroyMatrix_lf(Kt_tdata0_dm); + DestroyMatrix_lf(Kt_tdata_dm); + // + DestroyVector_lf(ztp1_t_dv); + DestroyMatrix_lf(Ptp1_t_dm); + DestroyVector_lf(ztp1_dv); + DestroyMatrix_lf(Ptp1_dm); + + return (kalfilmsinputs_1stapp_ps->ztm1_track); +} +//====================================================== +//= Computes etdata and Dtdata for all grand regimes st at tbase0=inpt-1 or dtm1_track +//= to prevent recomputing this object for different st at given tbase0. +//====================================================== +static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) +{ + //Output: + // dtm1_track is updated in this function. + // PHtran_tdata_d4->F[t-1] + // etdata_dc->C[t-1] + // Dtdata_d4->F[t-1] + //Input: + // t_1=inpt-1: base-0 timing for et and Dt before the likelihood at time inpt is computed. + + //--- Local variables + int sti, tbase0; + //-- Output arguments + TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). + TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. + TSdcell *yt_tm1_dc = kalfilmsinputs_1stapp_ps->yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). + TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). + //--- input arguments + TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-T. + TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-T. + //+ + TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. + TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. + TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. + //--- Accessible variables + int ny = kalfilmsinputs_1stapp_ps->ny; + int nz = kalfilmsinputs_1stapp_ps->nz; + int nst = kalfilmsinputs_1stapp_ps->nst; + TSdvector z0_sdv; + TSdvector yt_sdv, at_sdv; + TSdvector etdata_sdv, yt_tm1_sdv; + //=== Work arguments. + TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); + + + z0_sdv.n = nz; + z0_sdv.flag = V_DEF; + at_sdv.n = yt_sdv.n = ny; + at_sdv.flag = yt_sdv.flag = V_DEF; + etdata_sdv.n = yt_tm1_sdv.n = ny; + etdata_sdv.flag = yt_tm1_sdv.flag = V_DEF; + + for (tbase0=(kalfilmsinputs_1stapp_ps->dtm1_track+1); tbase0<=t_1; tbase0++) + { + //Note tbase0<=t_1, NOT tbase0<t_1. + //If t_1 < (dtm1_track+1), no updating. + //If t_1 >= (dtm1_track+1), updating etdata_dc->C[t-1] and Dtdata_d4->F[t-1] up to t-1=t_1. + + for (sti=nst-1; sti>=0; sti--) + { + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti], 1.0, 0.0, 'N', 'T'); + CopyMatrix0(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4->F[tbase0]->C[sti], PHtran_tdata_dm); + + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. + yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; + at_sdv.v = at_dm->M + sti*at_dm->nrows; //grand regime at time tbase0. + z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. + etdata_sdv.v = etdata_dc->C[tbase0]->M + etdata_sdv.n*sti; + yt_tm1_sdv.v = etdata_dc->C[tbase0]->M + yt_tm1_sdv.n*sti; + CopyVector0(&yt_tm1_sdv, &at_sdv); + MatrixTimesVector(&yt_tm1_sdv, Ht_dc->C[sti], &z0_sdv, 1.0, 1.0, 'N'); //a + H*z_{t|t-1}. + VectorMinusVector(&etdata_sdv, &yt_sdv, &yt_tm1_sdv); //y_t - a - H*z_{t|t-1}. + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); + CopyMatrix0(Dtdata_dm, Rt_dc->C[sti]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + //Done with z0_sdv.v. + ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. + //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message + // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either + // a bad number or a complex number. + Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; + CopyMatrix0(Dtdata_d4->F[tbase0]->C[sti], Dtdata_dm); //Saved to be used for logTimetCondLH_kalfilms_1stapp(). + } + + //--- $$$ This tracker functions the same way as kalfilmsinputs_1stapp_ps->ztm1_track. + kalfilmsinputs_1stapp_ps->dtm1_track = tbase0; + } + + //=== + DestroyMatrix_lf(PHtran_tdata_dm); + DestroyMatrix_lf(Dtdata_dm); + + return (kalfilmsinputs_1stapp_ps->dtm1_track); +} + + + + + + +//----------------------------------------------------- +//------------ OLD Code -------------------------- +//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. +//- WARNING: make sure to call the following functions +// RunningGensys_const7varionly(lwzmodel_ps); +// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. +//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). +// +//- IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that +//- the coefficient regime is the 1st state variable, and +//- the volatility regime is the 2nd state variable. +//----------------------------------------------------- +#if defined (NEWVERSIONofDW_SWITCH) +double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) +{ + //st, st_c, and st_v: base-0: deals with the cross-section values at time t where + // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. + //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. + // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). + // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. + //See (42.3) on p.42 in the SWZII NOTES. + + + //--- Local variables + int comst_c; //composite (s_tc, s_{t-1}c) + int st_c, stm1_c, st_v; + int comsti_c; //composite (s_tc, s_{t-1}c) + int sti, sti_c, stm1i_c, sti_v; + int comstp1i_c; //composite (s_{t+1}c, s_tc) + int stp1i, stp1i_c, stp1i_v; + int tbase0, tp1; + double logdet_Dtdata, loglh_timet; + static int record_tbase1_or_inpt_or_tp1 = 0; + static int passonce; + double prob_previous_regimes; + //=== Accessible variables + int ny = kalfilmsinputs_ps->ny; + int nz = kalfilmsinputs_ps->nz; + int nRc = kalfilmsinputs_ps->nRc; + int nRstc = kalfilmsinputs_ps->nRstc; + int nRv = kalfilmsinputs_ps->nRv; + int T = kalfilmsinputs_ps->T; + int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; + int **Index = smodel_ps->sv->index; //Regime-switching states. + //smodel_ps->sv->index is for our new code. + // For old code (before 9 April 08 and before dsge_switch is created), use smodel_ps->sv->Index; + TSdvector z0_sdv; + //+ input arguments. + TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. + TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. + TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. + TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. + // + TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. + TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. + TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. + // + TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. + TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. + //+ Output arguments. + TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + //=== Work arguments. + int nz2 = square(nz); + TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdvector *wP0_dv = CreateVector_lf(nz2); + //+ + TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, + TSdvector *wny_dv = CreateVector_lf(ny); + TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); + TSdvector *etdata_dv = CreateVector_lf(ny); + TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); + TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); + //--- For eigenvalue decompositions + int ki; + int errflag; + double eigmax; + TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); + TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. + //--- For updating zt_tm1_dm and Pt_tm1. + TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); + TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); + TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); + TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); + + + + if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_logTimetLH_kalfilms_1st_approx():\n" + " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); + if (indxIndRegimes && (nRc>1) && (nRv>1)) + if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" + " Number of state variables must be coincide with indxIndRegimes"); + + tbase0 = (tp1=inpt) - 1; + + z0_sdv.n = z0_dm->nrows; + z0_sdv.flag = V_DEF; + // + at_sdv.n = yt_sdv.n = yt_dm->nrows; + at_sdv.flag = yt_sdv.flag = V_DEF; + btp1_sdv.n = bt_dm->nrows; + btp1_sdv.flag = V_DEF; + + + //======= Initial condition. ======= + if (tbase0==0) + { + for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) + { + if (indxIndRegimes) + { + if (nRc==1) //Volatility. + { + comsti_c = sti_c = 0; + sti_v = sti; + } + else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. + { + comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) + sti_v = Index[sti][1]; //volatility state s_tv + sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. + stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; + } + else if ((nRv==1) && (nRc>nRstc)) + { + comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) + sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. + stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; + sti_v = 0; + } + else if ((nRv==1) && (nRc==nRstc)) + { + comsti_c = sti_c = sti; + sti_v = 0; + } + else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. + { + comsti_c = sti_c = Index[sti][0]; + sti_v = Index[sti][1]; + } + } + else //Syncronized regimes. + { + if (nRc>nRstc) + { + comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) + sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. + stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; + sti_v = sti_c; + } + else + comsti_c = sti_c = sti_v = sti; + } + + + if (!kalfilmsinputs_ps->indxIni) + { + InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - + InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - + + //=== Eigenanalysis to determine the roots to ensure boundedness. + errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[comsti_c]); + if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); + for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); + evals_abs_dv->flag = V_DEF; + eigmax = MaxVector(evals_abs_dv); + if (eigmax < (1.0+1.0e-14)) + { + //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); + MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[comsti_c]); + z0_sdv.v = z0_dm->M + z0_sdv.n*sti; + CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, comsti_c, bt_dm->nrows); + bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); + //Done with Wnzbynz_dm. + //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); + tz_kron(W2nz2bynz2_dm, Ft_dc->C[comsti_c], Ft_dc->C[comsti_c]); + MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); + CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); +//=== ???????? For debugging purpose. +//if ((inpt<2) && (st==0)) +//{ +// fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); + +// fprintf(FPTR_DEBUG, "wP0_dv:\n"); +// WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); +// fprintf(FPTR_DEBUG, "Vt_dc->C[sti_v=%d]:\n", sti_v); +// WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); + +// fflush(FPTR_DEBUG); + +//} + bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); + CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); + //Done with all w*_dv and W*_dm. + } + else + { + fprintf(stdout, "\n-----------------\n"); + fprintf(stdout, "\nIn regime comsti_c=%d and sti_v=%d and at time=%d\n", comsti_c, sti_v, 0); + fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" + " and the initial conditions must be supplied by, say, input arguments"); + fflush(stdout); + } + } + } + z0_dm->flag = M_GE; + CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. + CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. + } + + + //====================================================== + //= Getting the logLH at time tbase0 or time inpt. + //====================================================== + if (indxIndRegimes ) + { + if (nRc==1) //Volatility. + { + comst_c = st_c = 0; + st_v = st; + } + else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. + { + if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" + " Number of state variables must be coincide with indxIndRegimes"); + + comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) + st_v = Index[st][1]; //volatility state s_tv + st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. + stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; + } + else if ((nRv==1) && (nRc>nRstc)) + { + comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) + st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. + stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; + st_v = 0; + } + else if ((nRv==1) && (nRc==nRstc)) + { + comst_c = st_c = st; + st_v = 0; + } + else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. + { + if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" + " Number of state variables must be coincide with indxIndRegimes"); + + comst_c = st_c = Index[st][0]; + st_v = Index[st][1]; + } + } + else //Syncronized regimes + { + if (nRc>nRstc) + { + comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) + st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. + stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; + st_v = st_c; + } + else + comst_c = st_c = st_v = st; + } + + + z0_sdv.n = zt_tm1_dc->C[0]->nrows; + z0_sdv.flag = V_DEF; + // + at_sdv.n = yt_sdv.n = yt_dm->nrows; + at_sdv.flag = yt_sdv.flag = V_DEF; + + //====== Computing the conditional LH at time t. ====== + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[comst_c], 1.0, 0.0, 'N', 'T'); + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. + yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; + at_sdv.v = at_dm->M + comst_c*at_dm->nrows; //comst_c: coefficient regime at time tbase0. + z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. + VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); + MatrixTimesVector(etdata_dv, Ht_dc->C[comst_c], &z0_sdv, -1.0, 1.0, 'N'); + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); + CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comst_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. + //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message + // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either + // a bad number or a complex number. + Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; + + + //--- Forming the log conditional likelihood at t. + if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); + bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); +//if ((inpt>82) && (inpt<86) ) +//{ +// //Must be declared at the top of this "if" block. +// int kip1; +// double tmp_Dtdata; +// double tmp_expterm; + +// fprintf(FPTR_DEBUG, "%%------------------------\n"); +// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); +// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); + + +// fprintf(FPTR_DEBUG, "wny_dv:\n"); +// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); +// fprintf(FPTR_DEBUG, "etdata_dv:\n"); +// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); +// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); +// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %.16e "); + +// fflush(FPTR_DEBUG); +//} + loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); + //Done with all w*_dv. + + + + +//=== ???????? For debugging purpose. +if (inpt==1) +{ + double wk1, wk2; + + wk1 = logdet_Dtdata; + wk2 = VectorDotVector(wny_dv, etdata_dv); + fprintf(FPTR_DEBUG, "logdet_Dtdata = %10.5f\n", wk1); + fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f\n", wk2); + fprintf(FPTR_DEBUG, "----- etdata_dv: \n"); + WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); + fprintf(FPTR_DEBUG, "----- yt_dv: \n"); + WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); + fprintf(FPTR_DEBUG, "----- at_dv: \n"); + WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); + fprintf(FPTR_DEBUG, "----- z0_dv: \n"); + WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); + fprintf(FPTR_DEBUG, "----- Ht_dc->C[comst_c=%d]:\n", comst_c); + WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); + + fprintf(FPTR_DEBUG, "\n\n"); + +} +// +fprintf(FPTR_DEBUG, " %10.5f\n", loglh_timet); +fflush(FPTR_DEBUG); + + +//=== ???????? For debugging purpose. +//fprintf(FPTR_DEBUG, "------------------------\n"); +//fprintf(FPTR_DEBUG, "st=%d and inpt=%d\n", st, inpt); +//fprintf(FPTR_DEBUG, "loglh_timet = %10.5f\n", loglh_timet); +//fprintf(FPTR_DEBUG, "&yt_sdv:\n"); +//WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); +////WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); +////fprintf(FPTR_DEBUG, "\n"); +////WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); +//fflush(FPTR_DEBUG); + + +//=== ???????? For debugging purpose. +//if ((inpt>82) && (inpt<86) ) +//if (inpt<2) +//{ +// //Must be declared at the top of this "if" block. +// int kip1; +// double tmp_Dtdata; +// double tmp_expterm; + +// fprintf(FPTR_DEBUG, "%%------------------------\n"); +// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); +// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); + + +// tmp_Dtdata = logdeterminant(Dtdata_dm); +// tmp_expterm = VectorDotVector(wny_dv, etdata_dv); +// fprintf(FPTR_DEBUG, "logdeterminant(Dtdata_dm) = %10.5f;\n", tmp_Dtdata); +// fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f;\n", tmp_expterm); +// fprintf(FPTR_DEBUG, "wny_dv:\n"); +// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); +// fprintf(FPTR_DEBUG, "etdata_dv:\n"); +// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); +// fprintf(FPTR_DEBUG, "&yt_sdv:\n"); +// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); +// fprintf(FPTR_DEBUG, "&at_sdv:\n"); +// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); +// fprintf(FPTR_DEBUG, "&z0_sdv:\n"); +// WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); +// fprintf(FPTR_DEBUG, "Ht_dc->C[comst_c=%d]:\n",comst_c); +// WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); +// fprintf(FPTR_DEBUG, "Rt_dc->C[st_v=%d]:\n", st_v); +// WriteMatrix(FPTR_DEBUG, Rt_dc->C[st_v], " %10.5f "); +// fprintf(FPTR_DEBUG, "Pt_tm1_d4->F[tbase0]->C[st = %d]:\n",st); +// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[st], " %10.5f "); +// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); +// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); + + + + +//// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); +//// fprintf(FPTR_DEBUG, "zt_tm1_dc->C[tbase0]:\n"); +//// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); +//// //WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); +//// //fprintf(FPTR_DEBUG, "\n"); +//// fprintf(FPTR_DEBUG, "bt_dm = [\n"); +//// WriteMatrix(FPTR_DEBUG, bt_dm, " %10.5f "); +//// fprintf(FPTR_DEBUG, "];\n"); + +//// fprintf(FPTR_DEBUG, "et:\n"); +//// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); +//// fprintf(FPTR_DEBUG, "yt_dv=[\n"); +//// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); +//// fprintf(FPTR_DEBUG, "]';\n"); + +//// fprintf(FPTR_DEBUG, "at_dv=[\n"); +//// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); +//// fprintf(FPTR_DEBUG, "]';\n"); + + +//// for (ki=0; ki<Ht_dc->ncells; ki++) +//// { +//// kip1 = ki+1; +//// fprintf(FPTR_DEBUG, "Ht_dc(:,:,%d)=[\n", kip1); +//// WriteMatrix(FPTR_DEBUG, Ht_dc->C[ki], " %10.5f "); +//// fprintf(FPTR_DEBUG, "];\n"); +//// } +//// for (ki=0; ki<Ft_dc->ncells; ki++) +//// { +//// kip1 = ki+1; +//// fprintf(FPTR_DEBUG, "Ft_dc(:,:,%d)=[\n", kip1); +//// WriteMatrix(FPTR_DEBUG, Ft_dc->C[ki], " %10.5f "); +//// fprintf(FPTR_DEBUG, "];\n"); +//// } +//// for (ki=0; ki<Vt_dc->ncells; ki++) +//// { +//// kip1 = ki+1; +//// fprintf(FPTR_DEBUG, "Vt_dc(:,:,%d)=[\n", kip1); +//// WriteMatrix(FPTR_DEBUG, Vt_dc->C[ki], " %10.5f "); +//// fprintf(FPTR_DEBUG, "];\n"); +//// } +// fflush(FPTR_DEBUG); +//} + + + //====================================================== + //= Updating zt_tm1 and Pt_tm1 for next perid tp1. + //= tdata = tbase0 is base-0 timing. + //====================================================== + if (inpt > record_tbase1_or_inpt_or_tp1) //This condition always satisfies at the 1st period (which is inpt=1). + { + passonce = 0; + record_tbase1_or_inpt_or_tp1 = inpt; + } + if (!passonce) + { + for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) + { + if (indxIndRegimes) + { + if (nRc==1) //Volatility. + { + comstp1i_c = stp1i_c = 0; + stp1i_v = stp1i; + } + else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. + { + comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) + stp1i_v = Index[stp1i][1]; //volatility state s_tv + stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. + //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; + } + else if ((nRv==1) && (nRc>nRstc)) + { + comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) + stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. + //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; + stp1i_v = 0; + } + else if ((nRv==1) && (nRc==nRstc)) + { + comstp1i_c = stp1i_c = stp1i; + stp1i_v = 0; + } + else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. + { + comstp1i_c = stp1i_c = Index[stp1i][0]; + stp1i_v = Index[stp1i][1]; + } + } + else //Syncronized regimes. + { + if (nRc>nRstc) + { + comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) + stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. + //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; + stp1i_v = stp1i_c; + } + else + comstp1i_c = stp1i_c = stp1i_v = stp1i; + } + + + InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. + InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. + + for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) + { + if (indxIndRegimes) + { + if (nRc==1) //Volatility. + { + comsti_c = sti_c = 0; + sti_v = sti; + } + else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. + { + comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) + sti_v = Index[sti][1]; //volatility state s_tv + sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. + stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; + } + else if ((nRv==1) && (nRc>nRstc)) + { + comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) + sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. + stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; + sti_v = 0; + } + else if ((nRv==1) && (nRc==nRstc)) + { + comsti_c = sti_c = sti; + sti_v = 0; + } + else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. + { + comsti_c = sti_c = Index[sti][0]; + sti_v = Index[sti][1]; + } + } + else //Syncronized regimes. + { + if (nRc>nRstc) + { + comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) + sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. + stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; + sti_v = sti_c; + } + else + comsti_c = sti_c = sti_v = sti; + } + + + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[comsti_c], 1.0, 0.0, 'N', 'T'); + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. + yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; + at_sdv.v = at_dm->M + comsti_c*at_dm->nrows; //comsti_c: coefficient regime at time tbase0. + z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. + VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); + MatrixTimesVector(etdata_dv, Ht_dc->C[comsti_c], &z0_sdv, -1.0, 1.0, 'N'); + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); + CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comsti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + //Done with z0_sdv.v. + ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. + //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message + // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either + // a bad number or a complex number. + Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; + + + //=== Updating for next period by integrating out sti.. + if (tp1<T) + { + //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. + + //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; + //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. + CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); + MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); + //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. + MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); + MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); + btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; + VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); + //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); + CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i_v]); + MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); + MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); + //Done with all W*_dm. + MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); + MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); + //Done with all W*_dm. + + //--- Integrating out the state at tbase0 using P(s_t|Y_{t-1}, theta) = ElementV(smodel_ps->Z[inpt],s_{inpt}_i). + //--- Note tbase0 = inpt-1 because the data in DW code (ElementV) is base-1. + //--- Note at this point, we cannot access to P(s_t|Y_t, theta) = ElementV(smodel_ps->V[inpt],s_{inpt}_i) + //--- through DW's code. But we can modify my own code to do this later. + prob_previous_regimes = ElementV(smodel_ps->Z[inpt],sti); + ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); + ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); + Ptp1_dm->flag = M_GE | M_SU | M_SL; + //Done with ztp1_t_dv and Ptp1_t_dm. + } + } + //--- Filling zt_tm1 and Pt_tm1 for next period + if (tp1<T) + { + z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. + CopyVector0(&z0_sdv, ztp1_dv); + CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. + //Done with ztp1_dv, z0_sdv, Ptp1_dm. + } + } + if (tp1<T) + zt_tm1_dc->C[tp1]->flag = M_GE; + } + + +//=== ???????? For debugging purpose. +//if ((inpt>60) && (inpt<65) ) //if (inpt<5) +//{ +// int kip1; //Must be declared at the top of this "if" block. + +// fprintf(FPTR_DEBUG, "zt_tm1t=[\n"); +// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); +// fprintf(FPTR_DEBUG, "];\n"); + +// for (ki=0; ki<Pt_tm1_d4->F[tbase0]->ncells; ki++) +// { +// kip1 = ki+1; +// fprintf(FPTR_DEBUG, "Pt_tm1_d4t(:,:,%d)=[\n", kip1); +// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[ki], " %10.5f "); +// fprintf(FPTR_DEBUG, "];\n"); +// } + +// fflush(FPTR_DEBUG); +//} + + +//=== ???????? For debugging purpose. +fprintf(FPTR_DEBUG, " loglh_timet = %10.5f\n", loglh_timet); +fflush(FPTR_DEBUG); + + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + // + DestroyVector_lf(wny_dv); + DestroyMatrix_lf(Wnzbyny_dm); + DestroyMatrix_lf(W2nzbynz_dm); + DestroyMatrix_lf(PHtran_tdata_dm); + DestroyVector_lf(etdata_dv); + DestroyMatrix_lf(Dtdata_dm); + DestroyMatrix_lf(Kt_tdata0_dm); + DestroyMatrix_lf(Kt_tdata_dm); + // + DestroyVector_lf(ztp1_t_dv); + DestroyMatrix_lf(Ptp1_t_dm); + DestroyVector_lf(ztp1_dv); + DestroyMatrix_lf(Ptp1_dm); + + return (loglh_timet); +} +#undef LOG2PI +#endif + + +/** +//---------------------------------------------------------------- +//-- Tested OK, but has not use because tz_Refresh_z_T7P_T_in_kalfilms_1st_approx() +//-- cannot access to ElementV(smodel_ps->V[tp1],sti) or ElementV(smodel_ps->V[tbase0],sti) +//-- because no likelihood has been formed at all before this function is called. +//---------------------------------------------------------------- +#define LOG2PI (1.837877066409345e+000) //log(2*pi) +//----------------------------------------------------- +//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. +//- WARNING: make sure to call the following functions +// RunningGensys_const7varionly(lwzmodel_ps); +// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. +//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). +//----------------------------------------------------- +void tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) +{ + double debug1; + //--- Local variables + int stp1i, stp1i_c, stp1i_v, sti, sti_c, sti_v, tbase0, tp1; + //=== Accessible variables + int ny = kalfilmsinputs_ps->ny; + int nz = kalfilmsinputs_ps->nz; + int nRc = kalfilmsinputs_ps->nRc; + int nRv = kalfilmsinputs_ps->nRv; + int T = kalfilmsinputs_ps->T; + int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; + TSdvector z0_sdv; + //+ input arguments. + TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. + TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. + TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. + TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. + // + TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. + TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. + TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. + // + TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. + TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. + //+ Output arguments. + TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + //=== Work arguments. + int nz2 = square(nz); + TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); + TSdvector *wP0_dv = CreateVector_lf(nz2); + //+ + TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, + TSdvector *wny_dv = CreateVector_lf(ny); + TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); + TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); + TSdvector *etdata_dv = CreateVector_lf(ny); + TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); + TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); + TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); + //--- For eigenvalue decompositions + int ki; + int errflag; + double eigmax; + TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); + TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. + //--- For updating zt_tm1_dm and Pt_tm1. + TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); + TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); + TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); + TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); + + + if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" + " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); + if (indxIndRegimes && (nRc>1) && (nRv>1)) + if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" + " Number of state variables must be coincide with indxIndRegimes"); + + + z0_sdv.n = z0_dm->nrows; + z0_sdv.flag = V_DEF; + // + at_sdv.n = yt_sdv.n = yt_dm->nrows; + at_sdv.flag = yt_sdv.flag = V_DEF; + btp1_sdv.n = bt_dm->nrows; + btp1_sdv.flag = V_DEF; + + + //======= Initial condition. ======= + for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) + { + if (indxIndRegimes && (nRc==1)) + { + sti_c = 0; + sti_v = sti; + } + else if (indxIndRegimes && (nRv==1)) + { + sti_c = sti; + sti_v = 0; + } + else if (indxIndRegimes) + { + sti_c = smodel_ps->sv->Index[sti][0]; + sti_v = smodel_ps->sv->Index[sti][1]; + } + else + { + sti_c = sti_v = sti; + } + + + if (!kalfilmsinputs_ps->indxIni) + { + InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - + InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - + + //=== Eigenanalysis to determine the roots to ensure boundedness. + errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti_c]); + if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); + for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); + evals_abs_dv->flag = V_DEF; + eigmax = MaxVector(evals_abs_dv); + if (eigmax < (1.0+1.0e-14)) + { + //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); + MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti_c]); + z0_sdv.v = z0_dm->M + z0_sdv.n*sti; + CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, sti_c, bt_dm->nrows); + bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); + //Done with Wnzbynz_dm. + //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); + tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti_c], Ft_dc->C[sti_c]); + MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); + CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); + bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); + CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); + //Done with all w*_dv and W*_dm. + } + else + { + fprintf(stdout, "\n-----------------\n"); + fprintf(stdout, "\nIn regime sti_c=%d and sti_v=%d and at time=%d\n", sti_c, sti_v, 0); + fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" + " and the initial conditions must be supplied by, say, input arguments"); + fflush(stdout); + } + } + } + z0_dm->flag = M_GE; + CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. + CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. + + +// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[0]:\n"); +// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[0], " %.16e "); +// fprintf(FPTR_DEBUG, "\n"); +// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[0]->C[0]:\n"); +// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[0]->C[0], " %.16e "); + + + //============== Updating zt_tm1 and Pt_tm1. ================== + for (tbase0=0; tbase0<T; tbase0++ ) + { + //tdata = tbase0 is base-0 timing. + tp1 = tbase0 + 1; //Next period. + + for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) + { + if (indxIndRegimes && (nRc==1)) + { + stp1i_c = 0; + stp1i_v = stp1i; + } + else if (indxIndRegimes && (nRv==1)) + { + stp1i_c = stp1i; + stp1i_v = 0; + } + else if (indxIndRegimes) + { + stp1i_c = smodel_ps->sv->Index[stp1i][0]; + stp1i_v = smodel_ps->sv->Index[stp1i][1]; + } + else + { + stp1i_c = stp1i_v = stp1i; + } + + + InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. + InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. + for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) + { + if (indxIndRegimes && (nRc==1)) + { + sti_c = 0; + sti_v = sti; + } + else if (indxIndRegimes && (nRv==1)) + { + sti_c = sti; + sti_v = 0; + } + else if (indxIndRegimes) + { + sti_c = smodel_ps->sv->Index[sti][0]; + sti_v = smodel_ps->sv->Index[sti][1]; + } + else + { + sti_c = sti_v = sti; + } + + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti_c], 1.0, 0.0, 'N', 'T'); + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. + yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; + at_sdv.v = at_dm->M + sti_c*at_dm->nrows; //sti_c: coefficient regime at time tbase0. + z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. + VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); + MatrixTimesVector(etdata_dv, Ht_dc->C[sti_c], &z0_sdv, -1.0, 1.0, 'N'); + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); + CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + //Done with z0_sdv.v. + + + //=== Updating for next period by integrating out sti.. + if (tp1<T) + { + //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. + + //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; + //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. + CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); + MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); + //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. + MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); + MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); + btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; + VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); + //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); + CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); + MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); + MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); + //Done with all W*_dm. + MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); + MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); + MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); + //Done with all W*_dm. + + //--- Integrating out the state at tbase0 using P(s_t|Y_t, theta) = ElementV(smodel_ps->V[t+1],s_{t+1}_i). + //--- Note because the data in DW code (ElementV) is base-1, t+1 is actually tbase0. + debug1 = ElementV(smodel_ps->V[tp1],sti); //?????? Debug. + //ScalarTimesVectorUpdate(ztp1_dv, ElementV(smodel_ps->V[tp1],sti), ztp1_t_dv); + //ScalarTimesMatrix(Ptp1_dm, ElementV(smodel_ps->V[tp1],sti), Ptp1_t_dm, 1.0); + ScalarTimesVectorUpdate(ztp1_dv, 0.5, ztp1_t_dv); + ScalarTimesMatrix(Ptp1_dm, 0.5, Ptp1_t_dm, 1.0); + Ptp1_dm->flag = M_GE | M_SU | M_SL; + //Done with ztp1_t_dv and Ptp1_t_dm. + } + } + //--- Filling zt_tm1 and Pt_tm1 for next period + if (tp1<T) + { + z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. + CopyVector0(&z0_sdv, ztp1_dv); + CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. + //Done with ztp1_dv, z0_sdv, Ptp1_dm. + } + } + if (tp1<T) + zt_tm1_dc->C[tp1]->flag = M_GE; + +// fprintf(FPTR_DEBUG, "\n &yt_sdv:\n"); +// WriteMatrix(FPTR_DEBUG, &yt_sdv, " %.16e "); +// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[tp1]:\n"); +// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tp1], " %.16e "); +// fprintf(FPTR_DEBUG, "\n"); +// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[tp1]->C[0]:\n"); +// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tp1]->C[0], " %.16e "); +// fprintf(FPTR_DEBUG, "\n"); +// fflush(FPTR_DEBUG); + + + } + + //=== + DestroyVector_dz(evals_dzv); + DestroyVector_lf(evals_abs_dv); + DestroyMatrix_lf(Wnzbynz_dm); + DestroyMatrix_lf(Wnz2bynz2_dm); + DestroyMatrix_lf(W2nz2bynz2_dm); + DestroyVector_lf(wP0_dv); + // + DestroyVector_lf(wny_dv); + DestroyMatrix_lf(Wnzbyny_dm); + DestroyMatrix_lf(W2nzbynz_dm); + DestroyMatrix_lf(PHtran_tdata_dm); + DestroyVector_lf(etdata_dv); + DestroyMatrix_lf(Dtdata_dm); + DestroyMatrix_lf(Kt_tdata0_dm); + DestroyMatrix_lf(Kt_tdata_dm); + // + DestroyVector_lf(ztp1_t_dv); + DestroyMatrix_lf(Ptp1_t_dm); + DestroyVector_lf(ztp1_dv); + DestroyMatrix_lf(Ptp1_dm); +} +//----------------------------------------------------- +//- Kalman filter at time t for Markov-switching DSGE model. +//- WARNING: make sure to call the following functions +// (1) RunningGensys_const7varionly(lwzmodel_ps); +// (2) Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. +// (3) tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(); +//- before using kalfilms_timet_1st_approx(). +//----------------------------------------------------- +double tz_kalfilms_timet_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) +{ + //st, st_c, and st_v: base-0: deals with the cross-section values at time t where + // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. + //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. + // The 1st element for S_T is S_T[1] while S_T[0] is s_0. The same for (T+1)-by-1 gbeta_dv and nlcoefs-by-(T+1) galpha_dm. + // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. + //See (42.3) on p.42 in the SWZII NOTES. + + + //--- Local variables + int st_c, st_v, tbase0; + double loglh_timet; + //--- Accessible variables + int ny = kalfilmsinputs_ps->ny; + int nz = kalfilmsinputs_ps->nz; + int nRc = kalfilmsinputs_ps->nRc; + int nRv = kalfilmsinputs_ps->nRv; + int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; + TSdvector z0_sdv; + //+ input arguments. + TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. + TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. + TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. + TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. + //+ Output arguments. + TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + //=== Work arguments. + TSdvector yt_sdv, at_sdv; + TSdvector *wny_dv = CreateVector_lf(ny); + TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); + TSdvector *etdata_dv = CreateVector_lf(ny); + TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); + + + if (smodel_ps->sv->nstates != zt_tm1_dc->C[0]->ncols) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" + " Make sure that the column dimension of zt_tm1_dc->C is the same as smodel_ps->sv->nstates"); + + tbase0 = inpt - 1; //base-0 time t. + + if (indxIndRegimes && (nRc==1)) + { + st_c = 0; + st_v = st; + } + else if (indxIndRegimes && (nRv==1)) + { + st_c = st; + st_v = 0; + } + else if (indxIndRegimes) + { + if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" + " Number of state variables must be coincide with indxIndRegimes"); + st_c = smodel_ps->sv->Index[st][0]; + st_v = smodel_ps->sv->Index[st][1]; + } + else + { + st_c = st_v = st; + } + + + z0_sdv.n = zt_tm1_dc->C[0]->nrows; + z0_sdv.flag = V_DEF; + // + at_sdv.n = yt_sdv.n = yt_dm->nrows; + at_sdv.flag = yt_sdv.flag = V_DEF; + + //====== Computing the conditional LH at time t. ====== + //--- Setup. + MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st_c], 1.0, 0.0, 'N', 'T'); + + //--- Data. + //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. + yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; + at_sdv.v = at_dm->M + st_c*at_dm->nrows; //st_c: coefficient regime at time tbase0. + z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. + VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); + MatrixTimesVector(etdata_dv, Ht_dc->C[st_c], &z0_sdv, -1.0, 1.0, 'N'); + //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); + CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); + MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); + + //--- Forming the log conditional likelihood at t. + bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); + loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); + //Done with all w*_dv. + + + //=== + DestroyVector_lf(wny_dv); + DestroyMatrix_lf(PHtran_tdata_dm); + DestroyVector_lf(etdata_dv); + DestroyMatrix_lf(Dtdata_dm); + + return (loglh_timet); +} +#undef LOG2PI +/**/ + + + + diff --git a/CFiles/kalman.h b/CFiles/kalman.h old mode 100755 new mode 100644 index df661b5160ecd1be8c733931ddfc94fb29d2f7dd..3733a3007fb5262e0973c974f3d4b22a0e48ee9a --- a/CFiles/kalman.h +++ b/CFiles/kalman.h @@ -1,314 +1,314 @@ -#ifndef __KALMAN_H__ - #define __KALMAN_H__ - - #include "tzmatlab.h" - #include "mathlib.h" - #include "switch.h" - #include "fn_filesetup.h" //Used to call WriteMatrix(FPTR_DEBUG,....). - - - typedef struct TSkalcvfurw_tag { - //urw: univariate random walk kalman filter. Desigend specially for the 2006 AER SWZ paper. - - //=== Input arguments. - int indx_tvsigmasq; //0: constant siqmasq in Kalman updating (default); - //1: Keyensian (project-specific) type of time-varying sigmasq in Kalman updating; See pp.37 and 37a in SWZ Learning NOTES; - //2: project-specific type; - //3: another project-specific type. - double sigmasq; //Variance for the residual eps(t) of the measurement equation. - int fss; //T: effective sample size (excluding lags). - int kx; //dimension for x(t). - TSdmatrix *V_dm; //kx-by-kx. Covariance (symmetric and positive definite) matrix for the residual eta(t) of the transition equation. - TSdvector *ylhtran_dv; //1-by-T of y(t). The term lh means lelf hand side and tran means transpose. - TSdmatrix *Xrhtran_dm; //kx-by-T of x(t). The term rh means right hand side and tran means transpose. - TSdvector *z10_dv; //kx-by-1. Initial condition for prediction: z_{1|0}. - TSdmatrix *P10_dm; //kx-by-kx symmetric matrix. Initial condition for the variance of the prediction: P_{1|0}. - - //=== Output arguments. - TSdvector *zupdate_dv; //kx-by-1. z_{T+1|T}. - TSdmatrix *Zpredtran_dm; //kx-by-T matrix of one-step predicted values of z(t). [z_{2|1}, ..., z_{t+1|t}, ..., z_{T+1|T}]. - //Set to NULL (no output) if storeZ = 0; - TSdcell *Ppred_dc; //T cells and kx-by-kx symmetric and positive definite matrix for each cell. Mean square errors of predicted state variables. - //{P_{2|1}, ..., P{t+1|t}, ..., P{T+1|T}. Set to NULL (no output if storeV = 0). - TSdvector *ylhtranpred_dv; //1-by-T one-step prediction of y(t) or ylhtran_dv. Added 03/17/05. - - //=== Function itself. - void (*learning_fnc)(struct TSkalcvfurw_tag *, void *); - } TSkalcvfurw; //urw: univariate random walk. - // - typedef void TFlearninguni(struct TSkalcvfurw_tag *, void *); //For linear rational expectations models. - - - //=== Better version is TSkalfilmsinputs_1stapp_tag. Kalman filter for constant or known-time-varying DSGE models. - typedef struct TSkalfiltv_tag - { - //General (known-time-varying) Kalman filter for DSGE models. - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Not used if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as a initial condition - // and with z_{t+1|t} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as a initial condition - // and with P_{t+1|t} as the last element. Thus, we can use it as a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-T. - TSdcell *Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-T. - TSdcell *Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv; //nz-by-1; - TSdmatrix *P0_dm; //nz-by-nz. - - //=== Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc; //nz-by-nz-T. - } TSkalfiltv; - - - - //=== Inputs for filter for Markov-switching DSGE models at any time t. - typedef struct TSkalfilmsinputs_1stapp_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on the grand regime s_t that follows a Markov-chain process - // and is taken as given, and - // eps(t) = Psi_u(t)*u(t), where Psi_u(t) is n_y-by-n_u and u(t) is n_u-by-1; - // eta(t) = Psi_e(t)*e(t), where Psi_e(t) is n_z-by-n_e and e(t) is n_e-by-1. - // - // Inputs at time t are as follows where nst is number of grand regimes (including lagged regime - // and coefficients and shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nst matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nst 3-D of Markov-switching matrices in the measurement equation. - // Psi_u is an n_y-by-n_u-by-nst 3-D Markov-switching matrices. - // R is an n_y-by-n_y-by-nst 3-D of Markov-switching covariance matrices, - // E(eps(t) * eps(t)') = Psi_u(t)*Psi_u(t)', for the error in the measurement equation. - // G is an n_z-by-n_y-by-nst 3-D of Markov-switching E(eta_t * eps_t') = Psi_e(t)*Psi_u(t)'. - // ------ - // b is an n_z-by-nst matrix of Markov-switching input vectors in the state equation with b(:,st) as an initial condition. - // (alternatively, with the ergodic weighted b(:,st) as an initial condition). - // F is an n_z-by-n_z-by-nst 3-D of Markov-switching transition matrices in the state equation with F(:,:,st) - // as an initial condition (alternatively, with the ergodic weighted F(:,:,st) as an initial condition). - // Psi_e is an n_z-by-n_e-by-nst 3-D Markov-switching matrices. - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices, - // E(eta(t)*eta(t)') = Psi_e(t)*Psi_e(t)', for the error in the state equation - // with V(:,:,st) as an initial condition (alternatively, with the ergodic weighted V(:,:,st) as an initial condition). - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nst matrix of initial condition (Not used if indxIni=0). - // P0 is an n_z-by-n_z-by-nst 3-D of initial condition (Not used if indxIni=0). - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,st))\b(:,st) - // vec(P0_0m1) = (I-kron(F(:,:,st),F(:,:,st)))\vec(V(:,:,st)) - // Note that all eigenvalues of the matrix F(:,:,st) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha. Revised, April 2008. - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nu; //number of measurement errors. - int ne; //number of fundamental errors. - int nst; //number of grand composite regimes (current and past regimes, coefficient and volatility regimes). - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0, - //0: using the unconditional momnets for any given regime at time 0 (default when indxDiffuse = 0). - int indxDiffuse; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - double DiffuseScale; //A large (infinity) number when indxDiffuse = 1. - int ztm1_track; //t-1 = -1: no initial conditions z_{1|0} and P_{1|0} has been computed yet, but will be using InitializeKalman_z10_P10(), - //t-1 >= 0:T-1: z_{t|t-1} and P_{t|t-1} are updated up to t-1. - int dtm1_track; //t-1 = -1: no etdata_dc->C[0] or Dtdata_d4->F[0] has been computed yet. - //t-1 >= 0:T-1: etdata_dc->C[t-1] and Dtdata_d4->F[t-1] are updated up to t-1. - - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nst. - TSdcell *Ht_dc; //ny-by-nz-by-nst. - TSdcell *Psiut_dc; //ny-by-nu-by-nst. Measurement error coefficient matrix. - TSdcell *Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nst. - TSdcell *Ft_dc; //nz-by-nz-by-nst. - TSdcell *Psiet_dc; //nz-by-ne-by-nst. Impact matrix in the state equation. - TSdcell *Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - // - TSdmatrix *z0_0_dm; //nz-by-nst. z_{0|0}. - TSdmatrix *z0_dm; //nz-by-nst. z_{1|0}. - TSdcell *P0_dc; //nz-by-nz-by-nst. P_{1|0} - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nst-by-(T+1), where z_{1|0} is an initial condition (1st element with t-1=0 or t=1 for base-1) and - // the terminal condition z_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, z_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1), where P_{1|0} is an initial condition (1st element with t-1=0) and - // the terminal condition P_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, P_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - //+ Will be save for updating likelihood and Kalman filter Updatekalfilms_1stapp(), so save time to recompute these objects again. - TSdfourth *PHtran_tdata_d4; //nz-by-ny-by-nst-T, P_{t|t-1}*H_t'. Saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc; //ny-by-nst-by-T (with base-0 T), forecast errors e_t in the likelihood. - TSdcell *yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). Incorrect now (Used to back out structural shocks). - TSdfourth *Dtdata_d4; //ny-by-ny-nst-by-T, forecast covariance D_t in the likelihood. Saved for updating Kalman filter Updatekalfilms_1stapp(). - } TSkalfilmsinputs_1stapp; - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - //~~~ OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - typedef struct TSkalfilmsinputs_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs at time t are as follows where nRc is number of regimes for coefficients - // nRv is number of regimes for volatility (shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nRc matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nRc 3-D of Markov-switching matrices in the measurement equation. - // R is an n_y-by-n_y-by-nRv 3-D of Markov-switching covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-nRv 3-D of Markov-switching E(eta_t * eps_t'). - // ------ - // b is an n_z-by-nRc matrix of Markov-switching input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-nRc 3-D of Markov-switching transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIndRegimes: 1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nRc*nRv matrix of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // z0 is an n_z-by-nRv matrix of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRc*nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nRc; //number of composite regimes (current and past regimes) for coefficients. - int nRstc; //number of coefficient regimes at time t. - int nRv; //number of regimes for volatility (shock variances). - int indxIndRegimes; //1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nRc. - TSdcell *Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nRc. - TSdcell *Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm; //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - TSdcell *P0_dc; //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - } TSkalfilmsinputs; - - - - - //--- Functions for univariate random walk kalman filter. - TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv); //, int storeZ, int storeV); - TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps); - void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps); - - //--- New Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp2(int ny, int nz, int nu, int ne, int nst, int T); - struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp2(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); - struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T); - struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); - int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc); - double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - - - //--- OLD Code: Functions for general constant Kalman filter. - struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T); - struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - //Used to test tz_logTimetCondLH_kalfiltv(). (Done April 08). double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps); - - //--- OLD Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T); - struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps); - double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps); - //IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that - // the coefficient regime is the 1st state variable, and - // the volatility regime is the 2nd state variable. -#endif - +#ifndef __KALMAN_H__ + #define __KALMAN_H__ + + #include "tzmatlab.h" + #include "mathlib.h" + #include "dw_switch.h" + #include "fn_filesetup.h" //Used to call WriteMatrix(FPTR_DEBUG,....). + + + typedef struct TSkalcvfurw_tag { + //urw: univariate random walk kalman filter. Desigend specially for the 2006 AER SWZ paper. + + //=== Input arguments. + int indx_tvsigmasq; //0: constant siqmasq in Kalman updating (default); + //1: Keyensian (project-specific) type of time-varying sigmasq in Kalman updating; See pp.37 and 37a in SWZ Learning NOTES; + //2: project-specific type; + //3: another project-specific type. + double sigmasq; //Variance for the residual eps(t) of the measurement equation. + int fss; //T: effective sample size (excluding lags). + int kx; //dimension for x(t). + TSdmatrix *V_dm; //kx-by-kx. Covariance (symmetric and positive definite) matrix for the residual eta(t) of the transition equation. + TSdvector *ylhtran_dv; //1-by-T of y(t). The term lh means lelf hand side and tran means transpose. + TSdmatrix *Xrhtran_dm; //kx-by-T of x(t). The term rh means right hand side and tran means transpose. + TSdvector *z10_dv; //kx-by-1. Initial condition for prediction: z_{1|0}. + TSdmatrix *P10_dm; //kx-by-kx symmetric matrix. Initial condition for the variance of the prediction: P_{1|0}. + + //=== Output arguments. + TSdvector *zupdate_dv; //kx-by-1. z_{T+1|T}. + TSdmatrix *Zpredtran_dm; //kx-by-T matrix of one-step predicted values of z(t). [z_{2|1}, ..., z_{t+1|t}, ..., z_{T+1|T}]. + //Set to NULL (no output) if storeZ = 0; + TSdcell *Ppred_dc; //T cells and kx-by-kx symmetric and positive definite matrix for each cell. Mean square errors of predicted state variables. + //{P_{2|1}, ..., P{t+1|t}, ..., P{T+1|T}. Set to NULL (no output if storeV = 0). + TSdvector *ylhtranpred_dv; //1-by-T one-step prediction of y(t) or ylhtran_dv. Added 03/17/05. + + //=== Function itself. + void (*learning_fnc)(struct TSkalcvfurw_tag *, void *); + } TSkalcvfurw; //urw: univariate random walk. + // + typedef void TFlearninguni(struct TSkalcvfurw_tag *, void *); //For linear rational expectations models. + + + //=== Better version is TSkalfilmsinputs_1stapp_tag. Kalman filter for constant or known-time-varying DSGE models. + typedef struct TSkalfiltv_tag + { + //General (known-time-varying) Kalman filter for DSGE models. + // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. + // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m + // + // State space model is defined as follows: + // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) + // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) + // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. + // + // Inputs are as follows: + // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. + // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. + // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. + // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. + // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). + // ------ + // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. + // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. + // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. + // ------ + // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + // 0: using the unconditional mean for any given regime at time 0. + // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Not used if indxIni=0.) + // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Not used if indxIni=0.) + // + // Outputs are as follows: + // loglh is a value of the log likelihood function of the state-space model + // under the assumption that errors are multivariate Gaussian. + // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as a initial condition + // and with z_{t+1|t} as the last element. Thus, we can use it as a base-1 vector. + // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as a initial condition + // and with P_{t+1|t} as the last element. Thus, we can use it as a base-1 cell. + // + // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: + // z0_0m1 = (I-F(:,:,1))\b(:,1) + // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) + // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). + // + // March 2007, written by Tao Zha + // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. + + //=== Input arguments. + int ny; //number of observables. + int nz; //number of state variables. + int T; //sample size. + int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + //0: using the unconditional mean for any given regime at time 0. (Default value) + TSdmatrix *yt_dm; //ny-by-T. + TSdmatrix *at_dm; //ny-by-T. + TSdcell *Ht_dc; //ny-by-nz-by-T. + TSdcell *Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. + TSdcell *Gt_dc; //nz-by-ny-by-T. Cross-covariance. + // + TSdmatrix *bt_dm; //nz-by-T. + TSdcell *Ft_dc; //nz-by-nz-by-T. + TSdcell *Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. + // + TSdvector *z0_dv; //nz-by-1; + TSdmatrix *P0_dm; //nz-by-nz. + + //=== Output arguments. + double loglh; //log likelihood. + TSdmatrix *zt_tm1_dm; //nz-by-T. + TSdcell *Pt_tm1_dc; //nz-by-nz-T. + } TSkalfiltv; + + + + //=== Inputs for filter for Markov-switching DSGE models at any time t. + typedef struct TSkalfilmsinputs_1stapp_tag + { + //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). + // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. + // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m + // + // State space model is defined as follows: + // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) + // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) + // where a(t), H(t), b(t), and F(t) depend on the grand regime s_t that follows a Markov-chain process + // and is taken as given, and + // eps(t) = Psi_u(t)*u(t), where Psi_u(t) is n_y-by-n_u and u(t) is n_u-by-1; + // eta(t) = Psi_e(t)*e(t), where Psi_e(t) is n_z-by-n_e and e(t) is n_e-by-1. + // + // Inputs at time t are as follows where nst is number of grand regimes (including lagged regime + // and coefficients and shock variances): + // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. + // a is an n_y-by-nst matrix of Markov-switching input vectors in the measurement equation. + // H is an n_y-by-n_z-by-nst 3-D of Markov-switching matrices in the measurement equation. + // Psi_u is an n_y-by-n_u-by-nst 3-D Markov-switching matrices. + // R is an n_y-by-n_y-by-nst 3-D of Markov-switching covariance matrices, + // E(eps(t) * eps(t)') = Psi_u(t)*Psi_u(t)', for the error in the measurement equation. + // G is an n_z-by-n_y-by-nst 3-D of Markov-switching E(eta_t * eps_t') = Psi_e(t)*Psi_u(t)'. + // ------ + // b is an n_z-by-nst matrix of Markov-switching input vectors in the state equation with b(:,st) as an initial condition. + // (alternatively, with the ergodic weighted b(:,st) as an initial condition). + // F is an n_z-by-n_z-by-nst 3-D of Markov-switching transition matrices in the state equation with F(:,:,st) + // as an initial condition (alternatively, with the ergodic weighted F(:,:,st) as an initial condition). + // Psi_e is an n_z-by-n_e-by-nst 3-D Markov-switching matrices. + // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices, + // E(eta(t)*eta(t)') = Psi_e(t)*Psi_e(t)', for the error in the state equation + // with V(:,:,st) as an initial condition (alternatively, with the ergodic weighted V(:,:,st) as an initial condition). + // ------ + // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + // 0: using the unconditional mean for any given regime at time 0. + // z0 is an n_z-by-nst matrix of initial condition (Not used if indxIni=0). + // P0 is an n_z-by-n_z-by-nst 3-D of initial condition (Not used if indxIni=0). + // + // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: + // z0_0m1 = (I-F(:,:,st))\b(:,st) + // vec(P0_0m1) = (I-kron(F(:,:,st),F(:,:,st)))\vec(V(:,:,st)) + // Note that all eigenvalues of the matrix F(:,:,st) are inside the unit circle when the state-space model is bounded (stationary). + // + // November 2007, written by Tao Zha. Revised, April 2008. + // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. + + //=== Input arguments. + int ny; //number of observables. + int nz; //number of state variables. + int nu; //number of measurement errors. + int ne; //number of fundamental errors. + int nst; //number of grand composite regimes (current and past regimes, coefficient and volatility regimes). + int T; //sample size. + int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0, + //0: using the unconditional momnets for any given regime at time 0 (default when indxDiffuse = 0). + int indxDiffuse; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. + //0: using the unconditional moments. + double DiffuseScale; //A large (infinity) number when indxDiffuse = 1. + int ztm1_track; //t-1 = -1: no initial conditions z_{1|0} and P_{1|0} has been computed yet, but will be using InitializeKalman_z10_P10(), + //t-1 >= 0:T-1: z_{t|t-1} and P_{t|t-1} are updated up to t-1. + int dtm1_track; //t-1 = -1: no etdata_dc->C[0] or Dtdata_d4->F[0] has been computed yet. + //t-1 >= 0:T-1: etdata_dc->C[t-1] and Dtdata_d4->F[t-1] are updated up to t-1. + + TSdmatrix *yt_dm; //ny-by-T. + TSdmatrix *at_dm; //ny-by-nst. + TSdcell *Ht_dc; //ny-by-nz-by-nst. + TSdcell *Psiut_dc; //ny-by-nu-by-nst. Measurement error coefficient matrix. + TSdcell *Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. + TSdcell *Gt_dc; //nz-by-ny-by-nst. Cross-covariance. + // + TSdmatrix *bt_dm; //nz-by-nst. + TSdcell *Ft_dc; //nz-by-nz-by-nst. + TSdcell *Psiet_dc; //nz-by-ne-by-nst. Impact matrix in the state equation. + TSdcell *Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. + // + TSdmatrix *z0_0_dm; //nz-by-nst. z_{0|0}. + TSdmatrix *z0_dm; //nz-by-nst. z_{1|0}. + TSdcell *P0_dc; //nz-by-nz-by-nst. P_{1|0} + + + //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. + TSdcell *zt_tm1_dc; //nz-by-nst-by-(T+1), where z_{1|0} is an initial condition (1st element with t-1=0 or t=1 for base-1) and + // the terminal condition z_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed + // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, z_{T+1|T} + // has not legal value computed in most applications unless in out-of-sample forecasting problems. + TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1), where P_{1|0} is an initial condition (1st element with t-1=0) and + // the terminal condition P_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed + // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, P_{T+1|T} + // has not legal value computed in most applications unless in out-of-sample forecasting problems. + //+ Will be save for updating likelihood and Kalman filter Updatekalfilms_1stapp(), so save time to recompute these objects again. + TSdfourth *PHtran_tdata_d4; //nz-by-ny-by-nst-T, P_{t|t-1}*H_t'. Saved only for updating Kalman filter Updatekalfilms_1stapp(). + TSdcell *etdata_dc; //ny-by-nst-by-T (with base-0 T), forecast errors e_t in the likelihood. + TSdcell *yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). Incorrect now (Used to back out structural shocks). + TSdfourth *Dtdata_d4; //ny-by-ny-nst-by-T, forecast covariance D_t in the likelihood. Saved for updating Kalman filter Updatekalfilms_1stapp(). + } TSkalfilmsinputs_1stapp; + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + //~~~ OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + typedef struct TSkalfilmsinputs_tag + { + //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). + // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. + // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m + // + // State space model is defined as follows: + // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) + // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) + // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. + // + // Inputs at time t are as follows where nRc is number of regimes for coefficients + // nRv is number of regimes for volatility (shock variances): + // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. + // a is an n_y-by-nRc matrix of Markov-switching input vectors in the measurement equation. + // H is an n_y-by-n_z-by-nRc 3-D of Markov-switching matrices in the measurement equation. + // R is an n_y-by-n_y-by-nRv 3-D of Markov-switching covariance matrices for the error in the measurement equation. + // G is an n_z-by-n_y-by-nRv 3-D of Markov-switching E(eta_t * eps_t'). + // ------ + // b is an n_z-by-nRc matrix of Markov-switching input vectors in the state equation with b(:,1) as an initial condition. + // F is an n_z-by-n_z-by-nRc 3-D of Markov-switching transition matrices in the state equation with F(:,:,1) as an initial condition. + // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. + // ------ + // indxIndRegimes: 1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. + // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + // 0: using the unconditional mean for any given regime at time 0. + // z0 is an n_z-by-nRc*nRv matrix of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) + // z0 is an n_z-by-nRv matrix of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) + // P0 is an n_z-by-n_z-by-nRc*nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) + // P0 is an n_z-by-n_z-by-nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) + // + // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: + // z0_0m1 = (I-F(:,:,1))\b(:,1) + // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) + // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). + // + // November 2007, written by Tao Zha + // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. + + //=== Input arguments. + int ny; //number of observables. + int nz; //number of state variables. + int nRc; //number of composite regimes (current and past regimes) for coefficients. + int nRstc; //number of coefficient regimes at time t. + int nRv; //number of regimes for volatility (shock variances). + int indxIndRegimes; //1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. + int T; //sample size. + int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; + //0: using the unconditional mean for any given regime at time 0. (Default value) + TSdmatrix *yt_dm; //ny-by-T. + TSdmatrix *at_dm; //ny-by-nRc. + TSdcell *Ht_dc; //ny-by-nz-by-nRc. + TSdcell *Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. + TSdcell *Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. + // + TSdmatrix *bt_dm; //nz-by-nRc. + TSdcell *Ft_dc; //nz-by-nz-by-nRc. + TSdcell *Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. + // + TSdmatrix *z0_dm; //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. + TSdcell *P0_dc; //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. + + + //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. + TSdcell *zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. + } TSkalfilmsinputs; + + + + + //--- Functions for univariate random walk kalman filter. + TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv); //, int storeZ, int storeV); + TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps); + void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps); + + //--- New Code: Functions for Markov-switching Kalman filter. + struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp2(int ny, int nz, int nu, int ne, int nst, int T); + struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp2(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); + struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T); + struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); + int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc); + double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); + + + + //--- OLD Code: Functions for general constant Kalman filter. + struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T); + struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); + //Used to test tz_logTimetCondLH_kalfiltv(). (Done April 08). double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); + double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps); + + //--- OLD Code: Functions for Markov-switching Kalman filter. + struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T); + struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps); + double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps); + //IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that + // the coefficient regime is the 1st state variable, and + // the volatility regime is the 2nd state variable. +#endif + diff --git a/CFiles/kalmanOldWorks.c b/CFiles/kalmanOldWorks.c deleted file mode 100755 index 0918ed169d82cba2c4a99e8f920645ac955172fc..0000000000000000000000000000000000000000 --- a/CFiles/kalmanOldWorks.c +++ /dev/null @@ -1,2634 +0,0 @@ -/*=============================================================================================================== - * Check $$$ for important notes. - * Check <<>> for updating DW's new switch code or questions for DW. - * - * kalcvf_urw(): the Kalman filter forward prediction specialized for only a univariate random walk (urw) process. - * - * State space model is defined as follows: - * z(t+1) = z(t)+eta(t) (state or transition equation) - * y(t) = x(t)'*z(t)+eps(t) (observation or measurement equation) - * where for this function, eta and eps must be uncorrelated; y(t) must be 1-by-1. Note that - * x(t): k-by-1; - * z(t): k-by-1; - * eps(t): 1-by-1 and ~ N(0, sigma^2); - * eta(t): ~ N(0, V) where V is a k-by-k covariance matrix. - * - * - * Written by Tao Zha, May 2004. - * Revised, May 2008; -=================================================================================================================*/ - -/** -//=== For debugging purpose. -if (1) -{ - double t_loglht; - - t_loglht = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, " %10.5f\n", t_loglht); - - fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - - fprintf(FPTR_DEBUG, "\n wP0_dv:\n"); - WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "\n Vt_dc->C[sti_v=%d]:\n", sti_v); - WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - - fflush(FPTR_DEBUG); -} -/**/ - - -#include "kalman.h" - - -static int Updatekalfilms_1stapp(int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - -TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv) //, int storeZ, int storeV) -{ - int _i; - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - //--- - TSkalcvfurw *kalcvfurw_ps = tzMalloc(1, TSkalcvfurw); - - - kalcvfurw_ps->indx_tvsigmasq = tv; - kalcvfurw_ps->fss = T; - kalcvfurw_ps->kx = k; - - //=== - kalcvfurw_ps->V_dm = CreateMatrix_lf(k, k); - kalcvfurw_ps->ylhtran_dv = CreateVector_lf(T); - kalcvfurw_ps->Xrhtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->z10_dv = CreateVector_lf(k); - kalcvfurw_ps->P10_dm = CreateMatrix_lf(k, k); - - kalcvfurw_ps->zupdate_dv = CreateVector_lf(k); - kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->ylhtranpred_dv = CreateVector_lf(T); - // - rows_iv = CreateVector_int(T); - cols_iv = CreateVector_int(T); - for (_i=T-1; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // if (!storeZ) kalcvfurw_ps->Zpredtran_dm = (TSdmatrix *)NULL; - // else kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - // if (!storeV) kalcvfurw_ps->Ppred_dc = (TSdcell *)NULL; - // else { - // rows_iv = CreateVector_int(T); - // cols_iv = CreateVector_int(T); - // for (_i=T; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - // kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // } - - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - return (kalcvfurw_ps); -} - -TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps) -{ - if (kalcvfurw_ps) { - DestroyMatrix_lf(kalcvfurw_ps->V_dm); - DestroyVector_lf(kalcvfurw_ps->ylhtran_dv); - DestroyMatrix_lf(kalcvfurw_ps->Xrhtran_dm); - DestroyVector_lf(kalcvfurw_ps->z10_dv); - DestroyMatrix_lf(kalcvfurw_ps->P10_dm); - - DestroyVector_lf(kalcvfurw_ps->zupdate_dv); - DestroyMatrix_lf(kalcvfurw_ps->Zpredtran_dm); - DestroyCell_lf(kalcvfurw_ps->Ppred_dc); - DestroyVector_lf(kalcvfurw_ps->ylhtranpred_dv); - - free(kalcvfurw_ps); - return ((TSkalcvfurw *)NULL); - } - else return (kalcvfurw_ps); -} - - -void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps) -{ - //See the notes of SWZ regarding the government's updating of the parameters in their Phillips-curve equation. - //NOTE: make sure that the value of kalcvfurw_ps->sigmasq and other input values are given. - int ti; - double workd, workdenominv; - //--- - int fss, kx; - double sigmasq_fix = kalcvfurw_ps->sigmasq; -// double sigmasq; - TSdmatrix *V_dm; - TSdmatrix *Zpredtran_dm; - TSdcell *Ppred_dc; - TSdvector *ylhtran_dv; - TSdmatrix *Xrhtran_dm; - //=== - TSdvector *workkxby1_dv = NULL; //kx-by-1. -// TSdvector *work1kxby1_dv = NULL; //kx-by-1. - TSdmatrix *workkxbykx_dm = NULL; //kx-by-kx symmetric and positive positive. -// //=== -// TSdvector *zbefore_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vbefore_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); -// TSdvector *zafter_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vafter_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); - //******* WARNING: Some dangerous pointer movement to gain efficiency ******* -// double *yt_p; -// double *Vbefore_p; -// double *Vafter_p; - TSdvector xt_sdv; - TSdvector zbefore_sdv; - //TSdmatrix Vbefore_sdm; - TSdvector zafter_sdv; - //TSdmatrix Vafter_sdm; - - - if (!kalcvfurw_ps) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps must be created"); - if (!kalcvfurw_ps->V_dm || !kalcvfurw_ps->ylhtran_dv || !kalcvfurw_ps->Xrhtran_dm || !kalcvfurw_ps->z10_dv || !kalcvfurw_ps->P10_dm) - fn_DisplayError(".../kalcvf_urw(): input arguments kalcvfurw_ps->V_dm, kalcvfurw_ps->ylhtran_dv, kalcvfurw_ps->Xrhtran_dm, kalcvfurw_ps->z10_dv, kalcvfurw_ps->P10_dm must be given legal values"); - if (!(kalcvfurw_ps->P10_dm->flag & (M_SU | M_SL))) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps->P10_dm must be symmetric"); - fss = kalcvfurw_ps->fss; - kx = kalcvfurw_ps->kx; - V_dm = kalcvfurw_ps->V_dm; - Zpredtran_dm = kalcvfurw_ps->Zpredtran_dm; - Ppred_dc = kalcvfurw_ps->Ppred_dc; - ylhtran_dv = kalcvfurw_ps->ylhtran_dv; - Xrhtran_dm = kalcvfurw_ps->Xrhtran_dm; - //--- - xt_sdv.n = kx; - xt_sdv.flag = V_DEF; - zbefore_sdv.n = kx; - zbefore_sdv.flag = V_DEF; - zafter_sdv.n = kx; - zafter_sdv.flag = V_DEF; - - //=== Memory allocation. - workkxby1_dv = CreateVector_lf(kx); - workkxbykx_dm = CreateMatrix_lf(kx, kx); - - - //------- The first period (ti=0). ------- - zbefore_sdv.v = kalcvfurw_ps->z10_dv->v; - zafter_sdv.v = Zpredtran_dm->M; - xt_sdv.v = Xrhtran_dm->M; - //--- - - workd = ylhtran_dv->v[0] - (kalcvfurw_ps->ylhtranpred_dv->v[0]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, kalcvfurw_ps->P10_dm, &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(kalcvfurw_ps->z10_dv->v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t]; - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - - - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[0], kalcvfurw_ps->P10_dm, workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[0]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - - //------- The rest of the periods (ti=1:T-1). ------- - for (ti=1; ti<fss; ti++) { - //NOTE: ti=0 has been taken care of outside of this loop. - zbefore_sdv.v = Zpredtran_dm->M + (ti-1)*kx; - zafter_sdv.v = Zpredtran_dm->M + ti*kx; - xt_sdv.v = Xrhtran_dm->M + ti*kx; - //--- - workd = ylhtran_dv->v[ti] - (kalcvfurw_ps->ylhtranpred_dv->v[ti]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, Ppred_dc->C[ti-1], &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(zbefore_sdv.v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[ti], Ppred_dc->C[ti-1], workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[ti]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - } - CopyVector0(kalcvfurw_ps->zupdate_dv, &zafter_sdv); - Zpredtran_dm->flag = M_GE; - kalcvfurw_ps->ylhtranpred_dv->flag = V_DEF; - -// DestroyVector_lf(zbefore_dv); -// DestroyMatrix_lf(Vbefore_dm); -// DestroyVector_lf(zafter_dv); -// DestroyMatrix_lf(Vafter_dm); - - DestroyVector_lf(workkxby1_dv); -// DestroyVector_lf(work1kxby1_dv); - DestroyMatrix_lf(workkxbykx_dm); -} - - - -//----------------------------------------------------------------------------------------------------------------------- -//-- General constant (known-time-varying) Kalman filter for DSGE models. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T) -{ - int _i; - //=== - TSivector *rows_iv = CreateVector_int(T); - TSivector *cols_iv = CreateVector_int(T); - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfiltv_tag *kalfiltv_ps = tzMalloc(1, struct TSkalfiltv_tag); - - - //--- Default value. - kalfiltv_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfiltv_ps->ny = ny; - kalfiltv_ps->nz = nz; - kalfiltv_ps->T = T; - - - - //--------- Creates memory and assigns values. The order matters. - kalfiltv_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfiltv_ps->at_dm = CreateMatrix_lf(ny, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = nz; - } - rows_iv->flag = cols_iv->flag = V_DEF; - kalfiltv_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->bt_dm = CreateMatrix_lf(nz, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - kalfiltv_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->z0_dv = CreateVector_lf(nz); - kalfiltv_ps->P0_dm = CreateMatrix_lf(nz, nz); - - - //--- - kalfiltv_ps->zt_tm1_dm = CreateMatrix_lf(nz, T); - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Pt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfiltv_ps); - -} -//--- -struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - if (kalfiltv_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfiltv_ps->yt_dm); - DestroyMatrix_lf(kalfiltv_ps->at_dm); - DestroyCell_lf(kalfiltv_ps->Ht_dc); - DestroyCell_lf(kalfiltv_ps->Rt_dc); - DestroyCell_lf(kalfiltv_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfiltv_ps->bt_dm); - DestroyCell_lf(kalfiltv_ps->Ft_dc); - DestroyCell_lf(kalfiltv_ps->Vt_dc); - //--- - DestroyVector_lf(kalfiltv_ps->z0_dv); - DestroyMatrix_lf(kalfiltv_ps->P0_dm); - //--- - DestroyMatrix_lf(kalfiltv_ps->zt_tm1_dm); - DestroyCell_lf(kalfiltv_ps->Pt_tm1_dc); - - - //--- - tzDestroy(kalfiltv_ps); //Must be freed last! - - return ((struct TSkalfiltv_tag *)NULL); - } - else return (kalfiltv_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //--- Default value. - kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - kalfilmsinputs_1stapp_ps->tm1_track = -1; - //t-1 = -1: the initial conditions z_{1|0} and P_{1|0} are yet to be computed using InitializeKalman_z10_P10(). - //t-1 >= 0: z_{t|t-1} and P_{t|t-1} are updated up to t where t-1 = 1 to T. - //--- Other assignments. - kalfilmsinputs_1stapp_ps->ny = ny; - kalfilmsinputs_1stapp_ps->nz = nz; - kalfilmsinputs_1stapp_ps->nst = nst; - kalfilmsinputs_1stapp_ps->T = T; - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - //--- For output arguments. - rows_iv = CreateConstantVector_int(T+1, nz); - cols_iv = CreateConstantVector_int(T+1, nst); - kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - return (kalfilmsinputs_1stapp_ps); -} -//--- -struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - if (kalfilmsinputs_1stapp_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); - //--- - tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); - } - else return (kalfilmsinputs_1stapp_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_tag *kalfilmsinputs_ps = tzMalloc(1, struct TSkalfilmsinputs_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //--- Default value. - kalfilmsinputs_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfilmsinputs_ps->ny = ny; - kalfilmsinputs_ps->nz = nz; - kalfilmsinputs_ps->nRc = nRc; - kalfilmsinputs_ps->nRstc = nRstc; - kalfilmsinputs_ps->nRv = nRv; - kalfilmsinputs_ps->indxIndRegimes = indxIndRegimes; - kalfilmsinputs_ps->T = T; - - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_ps->at_dm = CreateMatrix_lf(ny, nRc); - // - rows_iv = CreateConstantVector_int(nRc, ny); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, ny); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_ps->bt_dm = CreateMatrix_lf(nz, nRc); - // - rows_iv = CreateConstantVector_int(nRc, nz); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - if (indxIndRegimes) - { - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRc*nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - //--- For output arguments. - if (indxIndRegimes) - { - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRc*nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfilmsinputs_ps); - -} -//--- -struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps) -{ - if (kalfilmsinputs_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->z0_dm); - DestroyCell_lf(kalfilmsinputs_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_ps->Pt_tm1_d4); - //--- - tzDestroy(kalfilmsinputs_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_tag *)NULL); - } - else return (kalfilmsinputs_ps); -}; - - -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//-- Constant-parameters (known-time-varying) Kalman filter -//----------------------------------------------------- -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //General constant (known-time-varying) Kalman filter for DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - int T = kalfiltv_ps->T; - int Tp1 = T + 1; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - int indx_badlh = 0; //1: bad likelihood with, say, -infinity of the LH value. - int tdata, ti; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; //double loglh_tdata; //logdetDtdata. - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - //--- Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - - - - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "Fatal error: tz_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[0], P0_dm); - - //====== See p.002 in LiuWZ. ====== - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - loglh = 0.0; - for (tdata=0; tdata<T; tdata++ ) - { - //Base-0 timing. - ti = tdata + 1; //Next period. - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (kalfiltv_ps->loglh = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh += -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //loglh += -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (ti<T) - { - //Updating only up to tdata=T-2. The values at ti=T or tdata=T-1 will not be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[ti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + ti*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[ti], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + ti*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[ti], Vt_dc->C[ti]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[ti], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[ti], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[ti], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[ti], W2nzbynz_dm); - //Done with all W*_dm. - } - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (kalfiltv_ps->loglh = loglh); -} -/** -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //This function is used to test tz_logTimetCondLH_kalfiltv(). - int T = kalfiltv_ps->T; - int tdata; - double loglh; - - loglh = 0.0; - for (tdata=0; tdata<T; tdata++) loglh += tz_logTimetCondLH_kalfiltv(0, tdata+1, kalfiltv_ps); - - return (loglh); -} -/**/ -//----------------------------------------------------- -//-- Updating Kalman filter at time t for constant-parameters (or known-time-varying) Kalman filter. -//----------------------------------------------------- -double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps) -{ - //st: base-0 grand regime at time t, which is just a dummy for this constant-parameter function in order to use - // Waggoner's automatic functions. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - // - //log LH at time t for constant (known-time-varying) Kalman-filter DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood at time t. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // April 2008, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //--- Output arguments. - double loglh_timet; //log likelihood at time t. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - //--- Input arguments. - int tdata, tp1; - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - int T = kalfiltv_ps->T; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - - - tdata = (tp1=inpt) - 1; //Base-0 time. - - //======= Initial condition. ======= - if (tdata==0) - { - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_logTimetCondLH_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(FPTR_DEBUG, "Fatal error: tz_logTimetCondLH_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and thus the initial conditions must be supplied by, say, input arguments"); - fflush(FPTR_DEBUG); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[tdata], P0_dm); - } - - - //======= Liklihood at time t (see p.002 in LiuWZ). ======= - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //======= Updating for the next period. ======= - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (tp1<T) - { - //Updating only up to tdata=T-2, because the values at tp1=T or tdata=T-1 will NOT be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[tp1], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + tp1*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[tp1], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + tp1*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[tp1], Vt_dc->C[tp1]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[tp1], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[tp1], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[tp1], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[tp1], W2nzbynz_dm); - //Done with all W*_dm. - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (loglh_timet); -} - - -//----------------------------------------------------- -//- WARNING: bedore using this function, make sure to call the following functions -// Only once in creating lwzmodel_ps: Refresh_kalfilms_*(lwzmodel_ps); -// Everytime when parameters are changed: RefreshEverything(); RefreRunningGensys_allcases(lwzmodel_ps) in particular. -//----------------------------------------------------- -double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //st: base-0 grand regime -- deals with the cross-section values at time t. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - //-- Output arguments - double loglh_timet; - //--- input arguments - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_1stapp_ps->Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //+ - TSdmatrix *z0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdcell *P0_dc = kalfilmsinputs_1stapp_ps->P0_dc; //nz-by-nz-by-nst. - //--- Used to get zt_tm1_dc->C[0] and Pt_tm1_d4->F[0] only. - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Local variables - int tbase0; - double logdet_Dtdata; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - int T = kalfilmsinputs_1stapp_ps->T; - TSdvector z0_sdv; - TSdvector yt_sdv, at_sdv; - //=== Work arguments. - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - //--- Critical checking. - if (inpt > T) fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): The time exceeds the\n" - " data sample size allocated the structure TSkalfilmsinputs_1stapp_tag"); - - //--- $$$ Critical updating where we MUSt have inpt-1. If inpt, Updatekalfilms_1stapp() will call this function again - //--- $$$ because DW function ProbabilityStateConditionalCurrent() need to access this function at time inpt, - //--- $$$ which has not computed before Updatekalfilms_1stapp(). Thus, we'll have an infinite loop. - Updatekalfilms_1stapp(tbase0=inpt-1, kalfilmsinputs_1stapp_ps, smodel_ps); - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + st*at_dm->nrows; //comst_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[st], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag |= M_SU | M_SL; - - - //--- Forming the log conditional likelihood at t. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - //=== - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - - - return (loglh_timet); -} -//====================================================== -//= Computing z_{1|0} and P_{1|0} for each new parameter values. -//====================================================== -int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc) -{ - //See p.001 in LWZ Model II. - //Outputs: - // return 1: success in initializing; 0: initializing fails, so the likelihood must be set to -infty outside this function. - // tm1_track to track the time up to which Kalman filter have been updated. - // z0_dm, zt_tm1_dc->C[0] - // P0_dc, Pt_tm1_d4->F[0] - - //--- input arguments - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //+ - TSdmatrix *z0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdcell *P0_dc = kalfilmsinputs_1stapp_ps->P0_dc; //nz-by-nz-by-nst. - //--- Used to get zt_tm1_dc->C[0] and Pt_tm1_d4->F[0] only. - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Local variables - int sti; - //--- Accessible variables - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv; - //--- For the initial conditions: eigenvalue decompositions - int ki; - int errflag; - double eigmax; - //=== - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - // - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - - - if (kalfilmsinputs_1stapp_ps->tm1_track < 0) - { - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - //======= Initial condition. ======= - if (!kalfilmsinputs_1stapp_ps->indxIni) - { - z0_dm->flag = M_GE; - for (sti=nst-1; sti>=0; sti--) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti]); - if (errflag) fn_DisplayError("kalman.c/InitializeKalman_z10_P10(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < 1.0) //(1.0+EPSILON)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,sti))\b(:,sti); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, sti, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,sti),F(:,:,sti)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti], Ft_dc->C[sti]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - if (0) //0: no printing. - { - #if defined (USE_DEBUG_FILE) - fprintf(FPTR_DEBUG, "\n-------WARNING: ----------\n"); - fprintf(FPTR_DEBUG, "\nIn grand regime sti=%d\n", sti); - fprintf(FPTR_DEBUG, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #else - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn grand regime sti=%d\n", sti); - fprintf(stdout, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #endif - } - //=== See p.000.3 in LWZ Model II. - //=== Do NOT use the following option. It turns out that this will often generate explosive conditional liklihood - //=== at the end of the sample, because Pt_tm1 shrinks to zero overtime due to the sigularity of - //=== the initila condition P_{1|0}. - //--- Letting z0_dv = 0.0 - // z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - // InitializeConstantVector_lf(&z0_sdv, 0.0); - // //--- Letting P0_dm = V - // CopyMatrix0(P0_dc->C[sti], Vt_dc->C[sti]); - return (0); //Early exit with kalfilmsinputs_1stapp_ps->tm1_track continues to be -1. - } - -// //====== Getting etdata_dv and Dtdata_dm for the likelihood function. -// //--- Setup. -// MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st], 1.0, 0.0, 'N', 'T'); - -// //--- Data. -// //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. -// yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; -// at_sdv.v = at_dm->M + st*at_dm->nrows; //comst_c: coefficient regime at time tbase0. -// z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. -// VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); -// MatrixTimesVector(etdata_dv, Ht_dc->C[st], &z0_sdv, -1.0, 1.0, 'N'); -// //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); -// CopyMatrix0(Dtdata_dm, Rt_dc->C[st]); -// MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); -// ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. -// //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message -// // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either -// // a bad number or a complex number. -// Dtdata_dm->flag |= M_SU | M_SL; - - } - } - else - { - if (!z10_dm) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition z_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyMatrix0(z0_dm, z10_dm); - - if (!P10_dc) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition P_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyCell0(P0_dc, P10_dc); - } - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t-1 = 1. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t-1 = 1. - - kalfilmsinputs_1stapp_ps->tm1_track = 0; //Must reset to 0, meaning initial setting is done and ready for computing LH at t = 1. - - return (1); - } - else fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): calling this function makes sense only if" - " kalfilmsinputs_1stapp_ps->tm1_track is -1. Please check this value."); -} - - -//====================================================== -//= Integrating out the lagged regimes in order to -//= updating zt_tm1 and Pt_tm1 for next perid tp1 through Kim-Nelson filter. -//= tdata representing base-0 t timing, while inpt represents base-1 t timing. -// -//= Purpose: for each inpt, we integrate out grand regimes st -//= only ONCE to prevent the dimension of updated zt_tm1 and Pt_tm1 through Kim-Nelson filter. -//====================================================== -static int Updatekalfilms_1stapp(int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //Output: - // tm1update - // z_{inpt+1|inpt} - // P_{inpt+1|inpt} - //Input: - // inpt: base-1 t timing. Thus inpt=1 is the first period. - - //--- Local variables - int stp1i, sti, tbase0, tbase0p1; - double prob_previous_regimes; - //-- Output arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-T. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-T. - //--- input arguments - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_1stapp_ps->Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - int T = kalfilmsinputs_1stapp_ps->T; - TSdvector z0_sdv; - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - //=== Work arguments. - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - //+ - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //=== For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - //--- The following is for safe guard. InitializeKalman_z10_P10() should be called in, say, RefreshEverthing(). - if (kalfilmsinputs_1stapp_ps->tm1_track < 0) - if (!InitializeKalman_z10_P10(kalfilmsinputs_1stapp_ps, (TSdmatrix *)NULL, (TSdcell *)NULL)) - fn_DisplayError(".../kalman.c/Updatekalfilms_1stapp(): the system is non-stationary when calling" - " InitializeKalman_z10_P10(). Please call this function in RefreshEverthing() and" - " set the likehood to be -infty for early exit"); - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = nz; - btp1_sdv.flag = V_DEF; - - for (tbase0=kalfilmsinputs_1stapp_ps->tm1_track; tbase0<inpt; tbase0++) - { - //If inpt <= tm1_track, no updating. - //If inpt > tm1_track, updating z_{t|t-1} and P_{t|t-1} up to t-1 = inpt. - - zt_tm1_dc->C[tbase0p1=tbase0+1]->flag = M_GE; - for (stp1i=nst-1; stp1i>=0; stp1i--) - { - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=nst-1; sti>=0; sti--) - { - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti*at_dm->nrows; //grand regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[sti], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //=== Updating for next period by integrating out sti.. - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - - //--- Integrating out the state at tbase0 using - //--- P(s_tbase0|Y_{tbase0}, theta) = ProbabilityStateConditionalCurrent(sti, tbase0, smodel_ps); - //--- One can also access to P(s_tbase0|Y_{tbase0}, theta) by using ElementV(smodel_ps->V[tbase0],s_{tbase0}i), - //--- but this access will not call my function logTimetCondLH(), thus no updating for - //--- P(s_tbase0|Y_{tbase0}, and thus leading to incorrect results. - prob_previous_regimes = ProbabilityStateConditionalCurrent(sti, tbase0, smodel_ps); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - //--- Filling zt_tm1 and Pt_tm1 for next period. - z0_sdv.v = zt_tm1_dc->C[tbase0p1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tbase0p1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - - //--- $$$ This following is important because it tells ProbabilityStateConditionalCurrent(), which calls - //--- $$$ logTimetCondLH_kalfilms_1stapp(), which calls recursively this function again, that there is no - //--- $$$ need to update Kalman filter for the period before kalfilmsinputs_1stapp_ps->tm1_track. - kalfilmsinputs_1stapp_ps->tm1_track = tbase0p1; //Means that z_{tbase0p1+1|tbase0p1} and P_{tbase0p1+1|tbase0p1} are done. - } - } - - - //=== - DestroyMatrix_lf(Wnzbynz_dm); - // - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (kalfilmsinputs_1stapp_ps->tm1_track); -} - - - - -//----------------------------------------------------- -//------------ OLD Code -------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -// -//- IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that -//- the coefficient regime is the 1st state variable, and -//- the volatility regime is the 2nd state variable. -//----------------------------------------------------- -double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int comst_c; //composite (s_tc, s_{t-1}c) - int st_c, stm1_c, st_v; - int comsti_c; //composite (s_tc, s_{t-1}c) - int sti, sti_c, stm1i_c, sti_v; - int comstp1i_c; //composite (s_{t+1}c, s_tc) - int stp1i, stp1i_c, stp1i_v; - int tbase0, tp1; - double logdet_Dtdata, loglh_timet; - static int record_tbase1_or_inpt_or_tp1 = 0; - static int passonce; - double prob_previous_regimes; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRstc = kalfilmsinputs_ps->nRstc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - int **Index = smodel_ps->sv->index; //Regime-switching states. - //smodel_ps->sv->index is for our new code. - // For old code (before 9 April 08 and before dsge_switch is created), use smodel_ps->sv->Index; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_logTimetLH_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - tbase0 = (tp1=inpt) - 1; - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (tbase0==0) - { - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[comsti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[comsti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, comsti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[comsti_c], Ft_dc->C[comsti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); -//=== ???????? For debugging purpose. -//if ((inpt<2) && (st==0)) -//{ -// fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - -// fprintf(FPTR_DEBUG, "wP0_dv:\n"); -// WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Vt_dc->C[sti_v=%d]:\n", sti_v); -// WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - -// fflush(FPTR_DEBUG); - -//} - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime comsti_c=%d and sti_v=%d and at time=%d\n", comsti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - } - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - if (indxIndRegimes ) - { - if (nRc==1) //Volatility. - { - comst_c = st_c = 0; - st_v = st; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_v = Index[st][1]; //volatility state s_tv - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comst_c = st_c = st; - st_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = st_c = Index[st][0]; - st_v = Index[st][1]; - } - } - else //Syncronized regimes - { - if (nRc>nRstc) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = st_c; - } - else - comst_c = st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[comst_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comst_c*at_dm->nrows; //comst_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comst_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comst_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //--- Forming the log conditional likelihood at t. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); -//if ((inpt>82) && (inpt<86) ) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %.16e "); - -// fflush(FPTR_DEBUG); -//} - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - - -//=== ???????? For debugging purpose. -if (inpt==1) -{ - double wk1, wk2; - - wk1 = logdet_Dtdata; - wk2 = VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, "logdet_Dtdata = %10.5f\n", wk1); - fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f\n", wk2); - fprintf(FPTR_DEBUG, "----- etdata_dv: \n"); - WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- yt_dv: \n"); - WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- at_dv: \n"); - WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- z0_dv: \n"); - WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- Ht_dc->C[comst_c=%d]:\n", comst_c); - WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); - - fprintf(FPTR_DEBUG, "\n\n"); - -} -// -fprintf(FPTR_DEBUG, " %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//fprintf(FPTR_DEBUG, "------------------------\n"); -//fprintf(FPTR_DEBUG, "st=%d and inpt=%d\n", st, inpt); -//fprintf(FPTR_DEBUG, "loglh_timet = %10.5f\n", loglh_timet); -//fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -//WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -////WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -////fprintf(FPTR_DEBUG, "\n"); -////WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//if ((inpt>82) && (inpt<86) ) -//if (inpt<2) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// tmp_Dtdata = logdeterminant(Dtdata_dm); -// tmp_expterm = VectorDotVector(wny_dv, etdata_dv); -// fprintf(FPTR_DEBUG, "logdeterminant(Dtdata_dm) = %10.5f;\n", tmp_Dtdata); -// fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f;\n", tmp_expterm); -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&at_sdv:\n"); -// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&z0_sdv:\n"); -// WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Ht_dc->C[comst_c=%d]:\n",comst_c); -// WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); -// fprintf(FPTR_DEBUG, "Rt_dc->C[st_v=%d]:\n", st_v); -// WriteMatrix(FPTR_DEBUG, Rt_dc->C[st_v], " %10.5f "); -// fprintf(FPTR_DEBUG, "Pt_tm1_d4->F[tbase0]->C[st = %d]:\n",st); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[st], " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); - - - - -//// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "zt_tm1_dc->C[tbase0]:\n"); -//// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -//// //WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -//// //fprintf(FPTR_DEBUG, "\n"); -//// fprintf(FPTR_DEBUG, "bt_dm = [\n"); -//// WriteMatrix(FPTR_DEBUG, bt_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); - -//// fprintf(FPTR_DEBUG, "et:\n"); -//// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "yt_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - -//// fprintf(FPTR_DEBUG, "at_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - - -//// for (ki=0; ki<Ht_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ht_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ht_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Ft_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ft_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ft_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Vt_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Vt_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Vt_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -// fflush(FPTR_DEBUG); -//} - - - //====================================================== - //= Updating zt_tm1 and Pt_tm1 for next perid tp1. - //= tdata = tbase0 is base-0 timing. - //====================================================== - if (inpt > record_tbase1_or_inpt_or_tp1) //This condition always satisfies at the 1st period (which is inpt=1). - { - passonce = 0; - record_tbase1_or_inpt_or_tp1 = inpt; - } - if (!passonce) - { - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comstp1i_c = stp1i_c = 0; - stp1i_v = stp1i; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_v = Index[stp1i][1]; //volatility state s_tv - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comstp1i_c = stp1i_c = stp1i; - stp1i_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comstp1i_c = stp1i_c = Index[stp1i][0]; - stp1i_v = Index[stp1i][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = stp1i_c; - } - else - comstp1i_c = stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[comsti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comsti_c*at_dm->nrows; //comsti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comsti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comsti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i_v]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_{t-1}, theta) = ElementV(smodel_ps->Z[inpt],s_{inpt}_i). - //--- Note tbase0 = inpt-1 because the data in DW code (ElementV) is base-1. - //--- Note at this point, we cannot access to P(s_t|Y_t, theta) = ElementV(smodel_ps->V[inpt],s_{inpt}_i) - //--- through DW's code. But we can modify my own code to do this later. - prob_previous_regimes = ElementV(smodel_ps->Z[inpt],sti); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - } - - -//=== ???????? For debugging purpose. -//if ((inpt>60) && (inpt<65) ) //if (inpt<5) -//{ -// int kip1; //Must be declared at the top of this "if" block. - -// fprintf(FPTR_DEBUG, "zt_tm1t=[\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); - -// for (ki=0; ki<Pt_tm1_d4->F[tbase0]->ncells; ki++) -// { -// kip1 = ki+1; -// fprintf(FPTR_DEBUG, "Pt_tm1_d4t(:,:,%d)=[\n", kip1); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[ki], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); -// } - -// fflush(FPTR_DEBUG); -//} - - -//=== ???????? For debugging purpose. -fprintf(FPTR_DEBUG, " loglh_timet = %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (loglh_timet); -} -#undef LOG2PI - - - -/** -//---------------------------------------------------------------- -//-- Tested OK, but has not use because tz_Refresh_z_T7P_T_in_kalfilms_1st_approx() -//-- cannot access to ElementV(smodel_ps->V[tp1],sti) or ElementV(smodel_ps->V[tbase0],sti) -//-- because no likelihood has been formed at all before this function is called. -//---------------------------------------------------------------- -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -//----------------------------------------------------- -void tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - double debug1; - //--- Local variables - int stp1i, stp1i_c, stp1i_v, sti, sti_c, sti_v, tbase0, tp1; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, sti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti_c], Ft_dc->C[sti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime sti_c=%d and sti_v=%d and at time=%d\n", sti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - - -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[0]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[0]->C[0], " %.16e "); - - - //============== Updating zt_tm1 and Pt_tm1. ================== - for (tbase0=0; tbase0<T; tbase0++ ) - { - //tdata = tbase0 is base-0 timing. - tp1 = tbase0 + 1; //Next period. - - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes && (nRc==1)) - { - stp1i_c = 0; - stp1i_v = stp1i; - } - else if (indxIndRegimes && (nRv==1)) - { - stp1i_c = stp1i; - stp1i_v = 0; - } - else if (indxIndRegimes) - { - stp1i_c = smodel_ps->sv->Index[stp1i][0]; - stp1i_v = smodel_ps->sv->Index[stp1i][1]; - } - else - { - stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti_c*at_dm->nrows; //sti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[sti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_t, theta) = ElementV(smodel_ps->V[t+1],s_{t+1}_i). - //--- Note because the data in DW code (ElementV) is base-1, t+1 is actually tbase0. - debug1 = ElementV(smodel_ps->V[tp1],sti); //?????? Debug. - //ScalarTimesVectorUpdate(ztp1_dv, ElementV(smodel_ps->V[tp1],sti), ztp1_t_dv); - //ScalarTimesMatrix(Ptp1_dm, ElementV(smodel_ps->V[tp1],sti), Ptp1_t_dm, 1.0); - ScalarTimesVectorUpdate(ztp1_dv, 0.5, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, 0.5, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - -// fprintf(FPTR_DEBUG, "\n &yt_sdv:\n"); -// WriteMatrix(FPTR_DEBUG, &yt_sdv, " %.16e "); -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[tp1]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tp1], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[tp1]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tp1]->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fflush(FPTR_DEBUG); - - - } - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); -} -//----------------------------------------------------- -//- Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// (1) RunningGensys_const7varionly(lwzmodel_ps); -// (2) Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -// (3) tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(); -//- before using kalfilms_timet_1st_approx(). -//----------------------------------------------------- -double tz_kalfilms_timet_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0. The same for (T+1)-by-1 gbeta_dv and nlcoefs-by-(T+1) galpha_dm. - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int st_c, st_v, tbase0; - double loglh_timet; - //--- Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - TSdvector yt_sdv, at_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - if (smodel_ps->sv->nstates != zt_tm1_dc->C[0]->ncols) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Make sure that the column dimension of zt_tm1_dc->C is the same as smodel_ps->sv->nstates"); - - tbase0 = inpt - 1; //base-0 time t. - - if (indxIndRegimes && (nRc==1)) - { - st_c = 0; - st_v = st; - } - else if (indxIndRegimes && (nRv==1)) - { - st_c = st; - st_v = 0; - } - else if (indxIndRegimes) - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - st_c = smodel_ps->sv->Index[st][0]; - st_v = smodel_ps->sv->Index[st][1]; - } - else - { - st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + st_c*at_dm->nrows; //st_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[st_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - - //--- Forming the log conditional likelihood at t. - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //=== - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - - return (loglh_timet); -} -#undef LOG2PI -/**/ - - - - diff --git a/CFiles/kalmanOldWorks.h b/CFiles/kalmanOldWorks.h deleted file mode 100755 index 17523384085b06a3878ec22e1e9853ae4c213485..0000000000000000000000000000000000000000 --- a/CFiles/kalmanOldWorks.h +++ /dev/null @@ -1,290 +0,0 @@ -#ifndef __KALMAN_H__ - #define __KALMAN_H__ - - #include "tzmatlab.h" - #include "mathlib.h" - #include "switch.h" - #include "fn_filesetup.h" //Used to call WriteMatrix(FPTR_DEBUG,....). - - - typedef struct TSkalcvfurw_tag { - //urw: univariate random walk kalman filter. Desigend specially for the 2006 AER SWZ paper. - - //=== Input arguments. - int indx_tvsigmasq; //0: constant siqmasq in Kalman updating (default); - //1: Keyensian (project-specific) type of time-varying sigmasq in Kalman updating; See pp.37 and 37a in SWZ Learning NOTES; - //2: project-specific type; - //3: another project-specific type. - double sigmasq; //Variance for the residual eps(t) of the measurement equation. - int fss; //T: effective sample size (excluding lags). - int kx; //dimension for x(t). - TSdmatrix *V_dm; //kx-by-kx. Covariance (symmetric and positive definite) matrix for the residual eta(t) of the transition equation. - TSdvector *ylhtran_dv; //1-by-T of y(t). The term lh means lelf hand side and tran means transpose. - TSdmatrix *Xrhtran_dm; //kx-by-T of x(t). The term rh means right hand side and tran means transpose. - TSdvector *z10_dv; //kx-by-1. Initial condition for prediction: z_{1|0}. - TSdmatrix *P10_dm; //kx-by-kx symmetric matrix. Initial condition for the variance of the prediction: P_{1|0}. - - //=== Output arguments. - TSdvector *zupdate_dv; //kx-by-1. z_{T+1|T}. - TSdmatrix *Zpredtran_dm; //kx-by-T matrix of one-step predicted values of z(t). [z_{2|1}, ..., z_{t+1|t}, ..., z_{T+1|T}]. - //Set to NULL (no output) if storeZ = 0; - TSdcell *Ppred_dc; //T cells and kx-by-kx symmetric and positive definite matrix for each cell. Mean square errors of predicted state variables. - //{P_{2|1}, ..., P{t+1|t}, ..., P{T+1|T}. Set to NULL (no output if storeV = 0). - TSdvector *ylhtranpred_dv; //1-by-T one-step prediction of y(t) or ylhtran_dv. Added 03/17/05. - - //=== Function itself. - void (*learning_fnc)(struct TSkalcvfurw_tag *, void *); - } TSkalcvfurw; //urw: univariate random walk. - // - typedef void TFlearninguni(struct TSkalcvfurw_tag *, void *); //For linear rational expectations models. - - - //=== General Kalman filter for constant or known-time-varying DSGE models. - typedef struct TSkalfiltv_tag - { - //General (known-time-varying) Kalman filter for DSGE models. - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Not used if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as a initial condition - // and with z_{t+1|t} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as a initial condition - // and with P_{t+1|t} as the last element. Thus, we can use it as a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-T. - TSdcell *Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-T. - TSdcell *Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv; //nz-by-1; - TSdmatrix *P0_dm; //nz-by-nz. - - //=== Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc; //nz-by-nz-T. - - } TSkalfiltv; - - - - //=== Inputs for filter for Markov-switching DSGE models at any time t. - typedef struct TSkalfilmsinputs_1stapp_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on the grand regime s_t that follows a Markov-chain process - // and is taken as given. - // - // Inputs at time t are as follows where nst is number of grand regimes (including lagged regime - // and coefficients and shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nst matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nst 3-D of Markov-switching matrices in the measurement equation. - // R is an n_y-by-n_y-by-nst 3-D of Markov-switching covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-nst 3-D of Markov-switching E(eta_t * eps_t'). - // ------ - // b is an n_z-by-nst matrix of Markov-switching input vectors in the state equation with b(:,st) as an initial condition. - // (alternatively, with the ergodic weighted b(:,st) as an initial condition). - // F is an n_z-by-n_z-by-nst 3-D of Markov-switching transition matrices in the state equation with F(:,:,st) - // as an initial condition (alternatively, with the ergodic weighted F(:,:,st) as an initial condition). - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation - // with V(:,:,st) as an initial condition (alternatively, with the ergodic weighted V(:,:,st) as an initial condition). - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nst matrix of initial condition (Not used if indxIni=0). - // P0 is an n_z-by-n_z-by-nst 3-D of initial condition (Not used if indxIni=0). - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,st))\b(:,st) - // vec(P0_0m1) = (I-kron(F(:,:,st),F(:,:,st)))\vec(V(:,:,st)) - // Note that all eigenvalues of the matrix F(:,:,st) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha. Revised, April 2008. - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nst; //number of grand composite regimes (current and past regimes, coefficient and volatility regimes). - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - int tm1_track; //t-1 = -1: the initial conditions z_{1|0} and P_{1|0} are yet to be computed using InitializeKalman_z10_P10(). - //t-1 >= 0: z_{t|t-1} and P_{t|t-1} are updated up to t where t-1 = 1 to T. - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nst. - TSdcell *Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nst. - TSdcell *Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm; //nz-by-nst. - TSdcell *P0_dc; //nz-by-nz-by-nst. - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nst-by-(T+1), where z_{1|0} is an initial condition (1st element with t-1=0) and - // the terminal condition z_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, z_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1), where P_{1|0} is an initial condition (1st element with t-1=0) and - // the terminal condition P_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, P_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - } TSkalfilmsinputs_1stapp; - - - //=== OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. - typedef struct TSkalfilmsinputs_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs at time t are as follows where nRc is number of regimes for coefficients - // nRv is number of regimes for volatility (shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nRc matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nRc 3-D of Markov-switching matrices in the measurement equation. - // R is an n_y-by-n_y-by-nRv 3-D of Markov-switching covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-nRv 3-D of Markov-switching E(eta_t * eps_t'). - // ------ - // b is an n_z-by-nRc matrix of Markov-switching input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-nRc 3-D of Markov-switching transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIndRegimes: 1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nRc*nRv matrix of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // z0 is an n_z-by-nRv matrix of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRc*nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nRc; //number of composite regimes (current and past regimes) for coefficients. - int nRstc; //number of coefficient regimes at time t. - int nRv; //number of regimes for volatility (shock variances). - int indxIndRegimes; //1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nRc. - TSdcell *Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nRc. - TSdcell *Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm; //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - TSdcell *P0_dc; //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - - } TSkalfilmsinputs; - - - - - //--- Functions for univariate random walk kalman filter. - TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv); //, int storeZ, int storeV); - TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps); - void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps); - - //--- New Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T); - struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); - int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc); - double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - - - //--- OLD Code: Functions for general constant Kalman filter. - struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T); - struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - //Used to test tz_logTimetCondLH_kalfiltv(). (Done April 08). double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps); - - //--- OLD Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T); - struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps); - double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps); - //IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that - // the coefficient regime is the 1st state variable, and - // the volatility regime is the 2nd state variable. -#endif - diff --git a/CFiles/kalmanOldWorks2.c b/CFiles/kalmanOldWorks2.c deleted file mode 100755 index 3a66f3e2f0b70eb94b987c85cb86926570badac9..0000000000000000000000000000000000000000 --- a/CFiles/kalmanOldWorks2.c +++ /dev/null @@ -1,2907 +0,0 @@ -/*=============================================================================================================== - * Check $$$ for important notes. - * Check <<>> for updating DW's new switch code or questions for DW. - * - * kalcvf_urw(): the Kalman filter forward prediction specialized for only a univariate random walk (urw) process. - * - * State space model is defined as follows: - * z(t+1) = z(t)+eta(t) (state or transition equation) - * y(t) = x(t)'*z(t)+eps(t) (observation or measurement equation) - * where for this function, eta and eps must be uncorrelated; y(t) must be 1-by-1. Note that - * x(t): k-by-1; - * z(t): k-by-1; - * eps(t): 1-by-1 and ~ N(0, sigma^2); - * eta(t): ~ N(0, V) where V is a k-by-k covariance matrix. - * - * - * Written by Tao Zha, May 2004. - * Revised, May 2008; -=================================================================================================================*/ - -/** -//=== For debugging purpose. -if (1) -{ - double t_loglht; - - t_loglht = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, " %10.5f\n", t_loglht); - - fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - - fprintf(FPTR_DEBUG, "\n wP0_dv:\n"); - WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "\n Vt_dc->C[sti_v=%d]:\n", sti_v); - WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - - fflush(FPTR_DEBUG); -} -/**/ - - -#include "kalman.h" - - -static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); -static int Updatekalfilms_1stapp(int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - -TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv) //, int storeZ, int storeV) -{ - int _i; - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - //--- - TSkalcvfurw *kalcvfurw_ps = tzMalloc(1, TSkalcvfurw); - - - kalcvfurw_ps->indx_tvsigmasq = tv; - kalcvfurw_ps->fss = T; - kalcvfurw_ps->kx = k; - - //=== - kalcvfurw_ps->V_dm = CreateMatrix_lf(k, k); - kalcvfurw_ps->ylhtran_dv = CreateVector_lf(T); - kalcvfurw_ps->Xrhtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->z10_dv = CreateVector_lf(k); - kalcvfurw_ps->P10_dm = CreateMatrix_lf(k, k); - - kalcvfurw_ps->zupdate_dv = CreateVector_lf(k); - kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - kalcvfurw_ps->ylhtranpred_dv = CreateVector_lf(T); - // - rows_iv = CreateVector_int(T); - cols_iv = CreateVector_int(T); - for (_i=T-1; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // if (!storeZ) kalcvfurw_ps->Zpredtran_dm = (TSdmatrix *)NULL; - // else kalcvfurw_ps->Zpredtran_dm = CreateMatrix_lf(k, T); - // if (!storeV) kalcvfurw_ps->Ppred_dc = (TSdcell *)NULL; - // else { - // rows_iv = CreateVector_int(T); - // cols_iv = CreateVector_int(T); - // for (_i=T; _i>=0; _i--) rows_iv->v[_i] = cols_iv->v[_i] = k; - // kalcvfurw_ps->Ppred_dc = CreateCell_lf(rows_iv, cols_iv); - // } - - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - return (kalcvfurw_ps); -} - -TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps) -{ - if (kalcvfurw_ps) { - DestroyMatrix_lf(kalcvfurw_ps->V_dm); - DestroyVector_lf(kalcvfurw_ps->ylhtran_dv); - DestroyMatrix_lf(kalcvfurw_ps->Xrhtran_dm); - DestroyVector_lf(kalcvfurw_ps->z10_dv); - DestroyMatrix_lf(kalcvfurw_ps->P10_dm); - - DestroyVector_lf(kalcvfurw_ps->zupdate_dv); - DestroyMatrix_lf(kalcvfurw_ps->Zpredtran_dm); - DestroyCell_lf(kalcvfurw_ps->Ppred_dc); - DestroyVector_lf(kalcvfurw_ps->ylhtranpred_dv); - - free(kalcvfurw_ps); - return ((TSkalcvfurw *)NULL); - } - else return (kalcvfurw_ps); -} - - -void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps) -{ - //See the notes of SWZ regarding the government's updating of the parameters in their Phillips-curve equation. - //NOTE: make sure that the value of kalcvfurw_ps->sigmasq and other input values are given. - int ti; - double workd, workdenominv; - //--- - int fss, kx; - double sigmasq_fix = kalcvfurw_ps->sigmasq; -// double sigmasq; - TSdmatrix *V_dm; - TSdmatrix *Zpredtran_dm; - TSdcell *Ppred_dc; - TSdvector *ylhtran_dv; - TSdmatrix *Xrhtran_dm; - //=== - TSdvector *workkxby1_dv = NULL; //kx-by-1. -// TSdvector *work1kxby1_dv = NULL; //kx-by-1. - TSdmatrix *workkxbykx_dm = NULL; //kx-by-kx symmetric and positive positive. -// //=== -// TSdvector *zbefore_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vbefore_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); -// TSdvector *zafter_dv = CreateVector_lf(kalcvfurw_ps->kx); -// TSdmatrix *Vafter_dm = CreateMatrix_lf(kalcvfurw_ps->kx, kalcvfurw_ps->kx); - //******* WARNING: Some dangerous pointer movement to gain efficiency ******* -// double *yt_p; -// double *Vbefore_p; -// double *Vafter_p; - TSdvector xt_sdv; - TSdvector zbefore_sdv; - //TSdmatrix Vbefore_sdm; - TSdvector zafter_sdv; - //TSdmatrix Vafter_sdm; - - - if (!kalcvfurw_ps) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps must be created"); - if (!kalcvfurw_ps->V_dm || !kalcvfurw_ps->ylhtran_dv || !kalcvfurw_ps->Xrhtran_dm || !kalcvfurw_ps->z10_dv || !kalcvfurw_ps->P10_dm) - fn_DisplayError(".../kalcvf_urw(): input arguments kalcvfurw_ps->V_dm, kalcvfurw_ps->ylhtran_dv, kalcvfurw_ps->Xrhtran_dm, kalcvfurw_ps->z10_dv, kalcvfurw_ps->P10_dm must be given legal values"); - if (!(kalcvfurw_ps->P10_dm->flag & (M_SU | M_SL))) fn_DisplayError(".../kalcvf_urw(): the input argument kalcvfurw_ps->P10_dm must be symmetric"); - fss = kalcvfurw_ps->fss; - kx = kalcvfurw_ps->kx; - V_dm = kalcvfurw_ps->V_dm; - Zpredtran_dm = kalcvfurw_ps->Zpredtran_dm; - Ppred_dc = kalcvfurw_ps->Ppred_dc; - ylhtran_dv = kalcvfurw_ps->ylhtran_dv; - Xrhtran_dm = kalcvfurw_ps->Xrhtran_dm; - //--- - xt_sdv.n = kx; - xt_sdv.flag = V_DEF; - zbefore_sdv.n = kx; - zbefore_sdv.flag = V_DEF; - zafter_sdv.n = kx; - zafter_sdv.flag = V_DEF; - - //=== Memory allocation. - workkxby1_dv = CreateVector_lf(kx); - workkxbykx_dm = CreateMatrix_lf(kx, kx); - - - //------- The first period (ti=0). ------- - zbefore_sdv.v = kalcvfurw_ps->z10_dv->v; - zafter_sdv.v = Zpredtran_dm->M; - xt_sdv.v = Xrhtran_dm->M; - //--- - - workd = ylhtran_dv->v[0] - (kalcvfurw_ps->ylhtranpred_dv->v[0]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, kalcvfurw_ps->P10_dm, &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(kalcvfurw_ps->z10_dv->v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t]; - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - - - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[0], kalcvfurw_ps->P10_dm, workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[0]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - - //------- The rest of the periods (ti=1:T-1). ------- - for (ti=1; ti<fss; ti++) { - //NOTE: ti=0 has been taken care of outside of this loop. - zbefore_sdv.v = Zpredtran_dm->M + (ti-1)*kx; - zafter_sdv.v = Zpredtran_dm->M + ti*kx; - xt_sdv.v = Xrhtran_dm->M + ti*kx; - //--- - workd = ylhtran_dv->v[ti] - (kalcvfurw_ps->ylhtranpred_dv->v[ti]=VectorDotVector(&xt_sdv, &zbefore_sdv)); //y_t - x_t'*z_{t-1}. - SymmatrixTimesVector(workkxby1_dv, Ppred_dc->C[ti-1], &xt_sdv, 1.0, 0.0); //P_{t|t-1} x_t; - if (!kalcvfurw_ps->indx_tvsigmasq) - workdenominv = 1.0/(sigmasq_fix + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else if (kalcvfurw_ps->indx_tvsigmasq == 1) //See pp.37 and 37a in SWZ Learning NOTES. - workdenominv = 1.0/(sigmasq_fix*square(zbefore_sdv.v[0]) + VectorDotVector(&xt_sdv, workkxby1_dv)); //1/[sigma^2 + x_t' P_{t|t-1} x_t] - else { - printf(".../kalman.c/kalcvf_urw(): Have not got time to deal with kalcvfurw_ps->indx_tvsigmasq defined in kalman.h other than 0 or 1"); - exit(EXIT_FAILURE); - } - //--- Updating z_{t+1|t}. - CopyVector0(&zafter_sdv, &zbefore_sdv); - VectorPlusMinusVectorUpdate(&zafter_sdv, workkxby1_dv, workd*workdenominv); //z_{t+1|t} = z_{t|t-1} + P_{t|t-1} x_t [y_t - x_t'*z_{t-1}] / [sigma^2 + x_t' P_{t|t-1} x_t]; - //--- Updating P_{t+1|t}. - CopyMatrix0(workkxbykx_dm, V_dm); - VectorTimesSelf(workkxbykx_dm, workkxby1_dv, -workdenominv, 1.0, (V_dm->flag & M_SU) ? 'U' : 'L'); - // - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - MatrixPlusMatrix(Ppred_dc->C[ti], Ppred_dc->C[ti-1], workkxbykx_dm); - //P_{t|t-1} - P_{t|t-1}*x_t * xt'*P_{t|t-1} / [sigma^2 + x_t' P_{t|t-1} x_t] + V; - Ppred_dc->C[ti]->flag = M_GE | M_SU | M_SL; //This is necessary because if P10_dm is initialized as diagonal, it will have M_GE | M_SU | M_SL | M_UT | M_LT, - // which is no longer true for workkxbykx_dm and therefore gives Ppred_dc->C[0] with M_GE only as a result of MatrixPlusMatrix(). - //Done with all work* arrays. - } - CopyVector0(kalcvfurw_ps->zupdate_dv, &zafter_sdv); - Zpredtran_dm->flag = M_GE; - kalcvfurw_ps->ylhtranpred_dv->flag = V_DEF; - -// DestroyVector_lf(zbefore_dv); -// DestroyMatrix_lf(Vbefore_dm); -// DestroyVector_lf(zafter_dv); -// DestroyMatrix_lf(Vafter_dm); - - DestroyVector_lf(workkxby1_dv); -// DestroyVector_lf(work1kxby1_dv); - DestroyMatrix_lf(workkxbykx_dm); -} - - - -//----------------------------------------------------------------------------------------------------------------------- -//-- General constant (known-time-varying) Kalman filter for DSGE models. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T) -{ - int _i; - //=== - TSivector *rows_iv = CreateVector_int(T); - TSivector *cols_iv = CreateVector_int(T); - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfiltv_tag *kalfiltv_ps = tzMalloc(1, struct TSkalfiltv_tag); - - - //--- Default value. - kalfiltv_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfiltv_ps->ny = ny; - kalfiltv_ps->nz = nz; - kalfiltv_ps->T = T; - - - - //--------- Creates memory and assigns values. The order matters. - kalfiltv_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfiltv_ps->at_dm = CreateMatrix_lf(ny, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = nz; - } - rows_iv->flag = cols_iv->flag = V_DEF; - kalfiltv_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = ny; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = ny; - } - kalfiltv_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->bt_dm = CreateMatrix_lf(nz, T); - // - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - kalfiltv_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - // - kalfiltv_ps->z0_dv = CreateVector_lf(nz); - kalfiltv_ps->P0_dm = CreateMatrix_lf(nz, nz); - - - //--- - kalfiltv_ps->zt_tm1_dm = CreateMatrix_lf(nz, T); - for (_i=T-1; _i>=0; _i--) - { - rows_iv->v[_i] = nz; - cols_iv->v[_i] = nz; - } - kalfiltv_ps->Pt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfiltv_ps); - -} -//--- -struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - if (kalfiltv_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfiltv_ps->yt_dm); - DestroyMatrix_lf(kalfiltv_ps->at_dm); - DestroyCell_lf(kalfiltv_ps->Ht_dc); - DestroyCell_lf(kalfiltv_ps->Rt_dc); - DestroyCell_lf(kalfiltv_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfiltv_ps->bt_dm); - DestroyCell_lf(kalfiltv_ps->Ft_dc); - DestroyCell_lf(kalfiltv_ps->Vt_dc); - //--- - DestroyVector_lf(kalfiltv_ps->z0_dv); - DestroyMatrix_lf(kalfiltv_ps->P0_dm); - //--- - DestroyMatrix_lf(kalfiltv_ps->zt_tm1_dm); - DestroyCell_lf(kalfiltv_ps->Pt_tm1_dc); - - - //--- - tzDestroy(kalfiltv_ps); //Must be freed last! - - return ((struct TSkalfiltv_tag *)NULL); - } - else return (kalfiltv_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- New code: Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp2(int ny, int nz, int nu, int ne, int nst, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //=== Default value. - kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; - kalfilmsinputs_1stapp_ps->ztm1_track = -1; - kalfilmsinputs_1stapp_ps->dtm1_track = -1; - - //--- Other key assignments. - kalfilmsinputs_1stapp_ps->ny = ny; - kalfilmsinputs_1stapp_ps->nz = nz; - kalfilmsinputs_1stapp_ps->nu = nu; - kalfilmsinputs_1stapp_ps->ne = ne; - kalfilmsinputs_1stapp_ps->nst = nst; - kalfilmsinputs_1stapp_ps->T = T; - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - if (nu) - { - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nu); - kalfilmsinputs_1stapp_ps->Psiut_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - kalfilmsinputs_1stapp_ps->Psiut_dc = NULL; - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ne); - kalfilmsinputs_1stapp_ps->Psiet_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - //--- For output arguments. - rows_iv = CreateConstantVector_int(T+1, nz); - cols_iv = CreateConstantVector_int(T+1, nst); - kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - return (kalfilmsinputs_1stapp_ps); -} -//--- -struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp2(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - if (kalfilmsinputs_1stapp_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Psiut_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Psiet_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); - //--- - tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); - } - else return (kalfilmsinputs_1stapp_ps); -}; - -struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps = tzMalloc(1, struct TSkalfilmsinputs_1stapp_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //=== Default value. - kalfilmsinputs_1stapp_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - kalfilmsinputs_1stapp_ps->indxDiffuse = 1; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - kalfilmsinputs_1stapp_ps->DiffuseScale = 100.0; - kalfilmsinputs_1stapp_ps->ztm1_track = -1; - kalfilmsinputs_1stapp_ps->dtm1_track = -1; - - //--- Other key assignments. - kalfilmsinputs_1stapp_ps->ny = ny; - kalfilmsinputs_1stapp_ps->nz = nz; - kalfilmsinputs_1stapp_ps->nst = nst; - kalfilmsinputs_1stapp_ps->T = T; - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_1stapp_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_1stapp_ps->at_dm = CreateMatrix_lf(ny, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->bt_dm = CreateMatrix_lf(nz, nst); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_1stapp_ps->z0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - kalfilmsinputs_1stapp_ps->z0_0_dm = CreateMatrix_lf(nz, nst); //nz-by-nst. - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nst. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - //--- For output arguments. - rows_iv = CreateConstantVector_int(T+1, nz); - cols_iv = CreateConstantVector_int(T+1, nst); - kalfilmsinputs_1stapp_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, nz); - kalfilmsinputs_1stapp_ps->Pt_tm1_d4 = CreateFourth_lf(T+1, rows_iv, cols_iv); //nz-by-nz-by-nst-by-(T+1). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nst, nz); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->PHtran_tdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - kalfilmsinputs_1stapp_ps->etdata_dc = CreateCell_lf(rows_iv, cols_iv); //ny-by-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = CreateConstantVector_int(T, ny); - cols_iv = CreateConstantVector_int(T, nst); - // - rows_iv = CreateConstantVector_int(nst, ny); - cols_iv = CreateConstantVector_int(nst, ny); - kalfilmsinputs_1stapp_ps->Dtdata_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //ny-by-ny-nst-by-T, used for updating Kalman filter Updatekalfilms_1stapp(). - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - - return (kalfilmsinputs_1stapp_ps); -} -//--- -struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - if (kalfilmsinputs_1stapp_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_dm); - DestroyMatrix_lf(kalfilmsinputs_1stapp_ps->z0_0_dm); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_1stapp_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Pt_tm1_d4); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4); - DestroyCell_lf(kalfilmsinputs_1stapp_ps->etdata_dc); - DestroyFourth_lf(kalfilmsinputs_1stapp_ps->Dtdata_d4); - //--- - tzDestroy(kalfilmsinputs_1stapp_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_1stapp_tag *)NULL); - } - else return (kalfilmsinputs_1stapp_ps); -}; - - -//----------------------------------------------------------------------------------------------------------------------- -//-- OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. -//----------------------------------------------------------------------------------------------------------------------- -struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T) -{ - //~~~ Creating the structure and initializing the NULL pointers. - struct TSkalfilmsinputs_tag *kalfilmsinputs_ps = tzMalloc(1, struct TSkalfilmsinputs_tag); - - //=== - TSivector *rows_iv = NULL; - TSivector *cols_iv = NULL; - - //--- Default value. - kalfilmsinputs_ps->indxIni = 0; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. - //--- Other assignments. - kalfilmsinputs_ps->ny = ny; - kalfilmsinputs_ps->nz = nz; - kalfilmsinputs_ps->nRc = nRc; - kalfilmsinputs_ps->nRstc = nRstc; - kalfilmsinputs_ps->nRv = nRv; - kalfilmsinputs_ps->indxIndRegimes = indxIndRegimes; - kalfilmsinputs_ps->T = T; - - - //--------- Creates memory and assigns values. The order matters. - kalfilmsinputs_ps->yt_dm = CreateMatrix_lf(ny, T); - kalfilmsinputs_ps->at_dm = CreateMatrix_lf(ny, nRc); - // - rows_iv = CreateConstantVector_int(nRc, ny); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ht_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, ny); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Rt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, ny); - kalfilmsinputs_ps->Gt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - kalfilmsinputs_ps->bt_dm = CreateMatrix_lf(nz, nRc); - // - rows_iv = CreateConstantVector_int(nRc, nz); - cols_iv = CreateConstantVector_int(nRc, nz); - kalfilmsinputs_ps->Ft_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Vt_dc = CreateCell_lf(rows_iv, cols_iv); - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - if (indxIndRegimes) - { - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRc*nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - kalfilmsinputs_ps->z0_dm = CreateMatrix_lf(nz, nRv); //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->P0_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - //--- For output arguments. - if (indxIndRegimes) - { - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRc*nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRc*nRv, nz); - cols_iv = CreateConstantVector_int(nRc*nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - else - { - if (nRstc != nRv) fn_DisplayError("kalman.c/CreateTSkalfilmsinputs(): nRstc must equal to nRv when indxIndRegimes==0"); - rows_iv = CreateConstantVector_int(T, nz); - cols_iv = CreateConstantVector_int(T, nRv); - kalfilmsinputs_ps->zt_tm1_dc = CreateCell_lf(rows_iv, cols_iv); //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - // - rows_iv = CreateConstantVector_int(nRv, nz); - cols_iv = CreateConstantVector_int(nRv, nz); - kalfilmsinputs_ps->Pt_tm1_d4 = CreateFourth_lf(T, rows_iv, cols_iv); //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - rows_iv = DestroyVector_int(rows_iv); - cols_iv = DestroyVector_int(cols_iv); - } - - - //=== - DestroyVector_int(rows_iv); - DestroyVector_int(cols_iv); - - return (kalfilmsinputs_ps); - -} -//--- -struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps) -{ - if (kalfilmsinputs_ps) - { - //=== The order matters! - DestroyMatrix_lf(kalfilmsinputs_ps->yt_dm); - DestroyMatrix_lf(kalfilmsinputs_ps->at_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ht_dc); - DestroyCell_lf(kalfilmsinputs_ps->Rt_dc); - DestroyCell_lf(kalfilmsinputs_ps->Gt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->bt_dm); - DestroyCell_lf(kalfilmsinputs_ps->Ft_dc); - DestroyCell_lf(kalfilmsinputs_ps->Vt_dc); - //--- - DestroyMatrix_lf(kalfilmsinputs_ps->z0_dm); - DestroyCell_lf(kalfilmsinputs_ps->P0_dc); - //--- - DestroyCell_lf(kalfilmsinputs_ps->zt_tm1_dc); - DestroyFourth_lf(kalfilmsinputs_ps->Pt_tm1_d4); - //--- - tzDestroy(kalfilmsinputs_ps); //Must be freed last! - - return ((struct TSkalfilmsinputs_tag *)NULL); - } - else return (kalfilmsinputs_ps); -}; - - -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//-- Constant-parameters (known-time-varying) Kalman filter -//----------------------------------------------------- -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //General constant (known-time-varying) Kalman filter for DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Do not enter if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - int T = kalfiltv_ps->T; - int Tp1 = T + 1; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - int indx_badlh = 0; //1: bad likelihood with, say, -infinity of the LH value. - int tdata, ti; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; //double loglh_tdata; //logdetDtdata. - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - //--- Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - - - - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "Fatal error: tz_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[0], P0_dm); - - //====== See p.002 in LiuWZ. ====== - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - loglh = 0.0; - for (tdata=0; tdata<T; tdata++ ) - { - //Base-0 timing. - ti = tdata + 1; //Next period. - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (kalfiltv_ps->loglh = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh += -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //loglh += -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (ti<T) - { - //Updating only up to tdata=T-2. The values at ti=T or tdata=T-1 will not be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[ti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + ti*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[ti], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + ti*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[ti], Vt_dc->C[ti]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[ti], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[ti], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[ti], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[ti], W2nzbynz_dm); - //Done with all W*_dm. - } - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (kalfiltv_ps->loglh = loglh); -} -/** -double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps) -{ - //This function is used to test tz_logTimetCondLH_kalfiltv(). - int T = kalfiltv_ps->T; - int tdata; - double loglh; - - loglh = 0.0; - for (tdata=0; tdata<T; tdata++) loglh += tz_logTimetCondLH_kalfiltv(0, tdata+1, kalfiltv_ps); - - return (loglh); -} -/**/ -//----------------------------------------------------- -//-- Updating Kalman filter at time t for constant-parameters (or known-time-varying) Kalman filter. -//----------------------------------------------------- -double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps) -{ - //st: base-0 grand regime at time t, which is just a dummy for this constant-parameter function in order to use - // Waggoner's automatic functions. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - // - //log LH at time t for constant (known-time-varying) Kalman-filter DSGE models (conditional on all the parameters). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood at time t. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Value to be assigned if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as an initial condition (base-0 first element) - // and with z_{T|T-1} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as though it were a initial condition - // and with P_{T|T-1} as the last element. Thus, we can use it as though it were a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // April 2008, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //--- Output arguments. - double loglh_timet; //log likelihood at time t. - TSdmatrix *zt_tm1_dm = kalfiltv_ps->zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc = kalfiltv_ps->Pt_tm1_dc; //nz-by-nz-T. - //--- Input arguments. - int tdata, tp1; - TSdvector *z0_dv = kalfiltv_ps->z0_dv; //nz-by-1; - TSdmatrix *P0_dm = kalfiltv_ps->P0_dm; //nz-by-nz. - int T = kalfiltv_ps->T; - int ny = kalfiltv_ps->ny; - int nz = kalfiltv_ps->nz; - //--- Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, zt_tm1_sdv, ztp1_t_sdv, btp1_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax, logdet_Dtdata; - TSdzvector *evals_dzv = NULL; - TSdvector *evals_abs_dv = NULL; //Absolute eigenvalues. - //--- Input arguments. - TSdmatrix *yt_dm = kalfiltv_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfiltv_ps->at_dm; //ny-by-T. - TSdcell *Ht_dc = kalfiltv_ps->Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc = kalfiltv_ps->Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfiltv_ps->Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm = kalfiltv_ps->bt_dm; //nz-by-T. - TSdcell *Ft_dc = kalfiltv_ps->Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc = kalfiltv_ps->Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - - - tdata = (tp1=inpt) - 1; //Base-0 time. - - //======= Initial condition. ======= - if (tdata==0) - { - //=== Initializing. - if (!kalfiltv_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - evals_dzv = CreateVector_dz(nz); - evals_abs_dv = CreateVector_lf(nz); - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[0]); - if (errflag) fn_DisplayError("tz_logTimetCondLH_kalfiltv() in kalman.c: eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[0]); - CopySubmatrix2vector(z0_dv, 0, bt_dm, 0, 0, bt_dm->nrows); - bdivA_rgens(z0_dv, z0_dv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[0], Ft_dc->C[0]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[0], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dm, 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(FPTR_DEBUG, "Fatal error: tz_logTimetCondLH_kalfiltv() in kalman.c: the system is non-stationary solutions\n" - " and thus the initial conditions must be supplied by, say, input arguments"); - fflush(FPTR_DEBUG); - exit( EXIT_FAILURE ); - } - } - CopySubvector2matrix(zt_tm1_dm, 0, 0, z0_dv, 0, z0_dv->n); - CopyMatrix0(Pt_tm1_dc->C[tdata], P0_dm); - } - - - //======= Liklihood at time t (see p.002 in LiuWZ). ======= - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - zt_tm1_sdv.n = ztp1_t_sdv.n = zt_tm1_dm->nrows; - zt_tm1_sdv.flag = ztp1_t_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_dc->C[tdata], Ht_dc->C[tdata], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata; - yt_sdv.v = yt_dm->M + tdata*yt_dm->nrows; - at_sdv.v = at_dm->M + tdata*at_dm->nrows; - zt_tm1_sdv.v = zt_tm1_dm->M + tdata*zt_tm1_dm->nrows; - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[tdata], &zt_tm1_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tdata); - CopyMatrix0(Dtdata_dm, Rt_dc->C[tdata]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[tdata], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - //--- Forming the log likelihood. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //======= Updating for the next period. ======= - //--- Updating zt_tm1_dm and Pt_tm1_dc by ztp1_t_sdv and Pt_tm1_dc->C[ti]. - if (tp1<T) - { - //Updating only up to tdata=T-2, because the values at tp1=T or tdata=T-1 will NOT be used in the likelihood function. - - //- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata; - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[tdata]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[tp1], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata; - ztp1_t_sdv.v = zt_tm1_dm->M + tp1*zt_tm1_dm->nrows; - MatrixTimesVector(&ztp1_t_sdv, Ft_dc->C[tp1], &zt_tm1_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(&ztp1_t_sdv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + tp1*btp1_sdv.n; - VectorPlusMinusVectorUpdate(&ztp1_t_sdv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Pt_tm1_dc->C[tp1], Vt_dc->C[tp1]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Pt_tm1_dc->C[tp1], Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[tp1], Pt_tm1_dc->C[tdata], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[tp1], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Pt_tm1_dc->C[tp1], W2nzbynz_dm); - //Done with all W*_dm. - } - zt_tm1_dm->flag = M_GE; - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - - return (loglh_timet); -} - - - - -//----------------------------------------------------- -//- WARNING: bedore using this function, make sure to call the following functions -// Only once in creating lwzmodel_ps: Refresh_kalfilms_*(lwzmodel_ps); -// Everytime when parameters are changed: RefreshEverything(); RefreRunningGensys_allcases(lwzmodel_ps) in particular. -//----------------------------------------------------- -double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //st: base-0 grand regime -- deals with the cross-section values at time t. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - //-- Output arguments - double loglh_timet; - //--- Input arguments - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- Local variables - int tbase0; - double logdet_Dtdata; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - TSdvector etdata_sdv; - //=== Work arguments. - TSdvector *wny_dv = CreateVector_lf(ny); - - - - //--- Critical checking. - if (inpt > kalfilmsinputs_1stapp_ps->T) - fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): The time exceeds the\n" - " data sample size allocated the structure TSkalfilmsinputs_1stapp_tag"); - - //--- The following is for safe guard. InitializeKalman_z10_P10() should be called in, say, RefreshEverything(). - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - if (!InitializeKalman_z10_P10(kalfilmsinputs_1stapp_ps, (TSdmatrix *)NULL, (TSdcell *)NULL)) - fn_DisplayError(".../kalman.c/logTimetCondLH_kalfilms_1stapp(): the system is non-stationary when calling" - " InitializeKalman_z10_P10(). Please call this function in RefreshEverthing() and" - " set the likehood to be -infty for early exit"); - - tbase0=inpt-1; - - //------------------- The order matters. Updatekalfilms_1stapp() must be called before Update_et_Dt_1stapp(). ----------------- - //--- $$$ Critical updating where we MUSt have inpt-1. If inpt, Updatekalfilms_1stapp() will call this function again - //--- $$$ because DW function ProbabilityStateConditionalCurrent() need to access this function at time inpt, - //--- $$$ which has not computed before Updatekalfilms_1stapp(). Thus, we'll have an infinite loop. - Updatekalfilms_1stapp(tbase0, kalfilmsinputs_1stapp_ps, smodel_ps); -// //--- $$$ Critical updating. -// Update_et_Dt_1stapp(tbase0, kalfilmsinputs_1stapp_ps); -// //This function will give Dtdata_d4->F[tbase0], etdata_dc->C[tbase0], and PHtran_tdata_d4->F[tbase0]. - - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - //--- Forming the log conditional likelihood at t. - etdata_sdv.n = ny; - etdata_sdv.v = etdata_dc->C[tbase0]->M + ny*st; - etdata_sdv.flag = V_DEF; - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_d4->F[tbase0]->C[st]))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, &etdata_sdv, '/', Dtdata_d4->F[tbase0]->C[st]); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, &etdata_sdv); - //Done with all w*_dv. - - //=== - DestroyVector_lf(wny_dv); - - return (loglh_timet); -} -//====================================================== -//= Computing z_{1|0} and P_{1|0} for each new parameter values. -//====================================================== -int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc) -{ - //See p.001 and p.004 in LWZ Model II. - //Outputs: - // return 1: success in initializing; 0: initializing fails, so the likelihood must be set to -infty outside this function. - // ztm1_track to track the time up to which Kalman filter have been updated. - // z0_dm, zt_tm1_dc->C[0] - // P0_dc, Pt_tm1_d4->F[0] - - //--- Output arguments - TSdmatrix *z0_0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdmatrix *z0_dm = kalfilmsinputs_1stapp_ps->z0_dm; //nz-by-nst. - TSdcell *P0_dc = kalfilmsinputs_1stapp_ps->P0_dc; //nz-by-nz-by-nst. - //+ Used to get zt_tm1_dc->C[0] and Pt_tm1_d4->F[0] only. - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Input arguments - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //--- Local variables - int sti; - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv, z0_0_sdv, bt_sdv; - TSdvector yt_sdv, at_sdv; - //--- For the initial conditions: eigenvalue decompositions - int ki; - int errflag; - double eigmax; - //=== - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - // - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - - - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - { - z0_sdv.n = z0_0_sdv.n = bt_sdv.n = nz; - z0_sdv.flag = z0_0_sdv.flag = bt_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (!kalfilmsinputs_1stapp_ps->indxIni) - { - z0_0_dm->flag = z0_dm->flag = M_GE; - for (sti=nst-1; sti>=0; sti--) - { - if (kalfilmsinputs_1stapp_ps->DiffuseScale) //Diffuse initial conditions are used. - { - //--- Diffuse condition for z0_dv. - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; - bt_sdv.v = bt_dm->M + bt_sdv.n*sti; - InitializeConstantVector_lf(&z0_0_sdv, 0.0); - MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); - VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); - //--- Diffuse condition for P0_dm. - InitializeDiagonalMatrix_lf(Wnzbynz_dm, kalfilmsinputs_1stapp_ps->DiffuseScale); //To be used for DiffuseScale*I(nz) - CopyMatrix0(P0_dc->C[sti], Wnzbynz_dm); - //Done with W*_dm. - } - else //Unconditional moments for initial conditions are used. - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti]); - if (errflag) fn_DisplayError("kalman.c/InitializeKalman_z10_P10(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0-SQRTEPSILON)) //(1.0+EPSILON)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,sti))\b(:,sti); - z0_0_sdv.v = z0_0_dm->M + z0_0_sdv.n*sti; - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti]); - CopySubmatrix2vector(&z0_0_sdv, 0, bt_dm, 0, sti, bt_dm->nrows); - bdivA_rgens(&z0_0_sdv, &z0_0_sdv, '\\', Wnzbynz_dm); - //- Under the assumption s_0 = s_1 (this is a short-cut). - MatrixTimesVector(&z0_sdv, Ft_dc->C[sti], &z0_0_sdv, 1.0, 0.0, 'N'); - VectorPlusVector(&z0_sdv, &z0_sdv, &bt_sdv); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,sti),F(:,:,sti)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti], Ft_dc->C[sti]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - if (0) //0: no printing. - { - #if defined (USE_DEBUG_FILE) - fprintf(FPTR_DEBUG, "\n-------WARNING: ----------\n"); - fprintf(FPTR_DEBUG, "\nIn grand regime sti=%d\n", sti); - fprintf(FPTR_DEBUG, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #else - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn grand regime sti=%d\n", sti); - fprintf(stdout, ".../kalman.c/InitializeKalman_z10_P10(): the system is non-stationary solutions\n" - " and see p.003 in LWZ Model II"); - #endif - } - //=== See p.000.3 in LWZ Model II. - //=== Do NOT use the following option. It turns out that this will often generate explosive conditional liklihood - //=== at the end of the sample, because Pt_tm1 shrinks to zero overtime due to the sigularity of - //=== the initila condition P_{1|0}. - //--- Letting z0_dv = 0.0 - // z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - // InitializeConstantVector_lf(&z0_sdv, 0.0); - // //--- Letting P0_dm = V - // CopyMatrix0(P0_dc->C[sti], Vt_dc->C[sti]); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (0); //Early exit with kalfilmsinputs_1stapp_ps->ztm1_track continues to be -1. - } - } - } - } - else - { - if (!z10_dm) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition z_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyMatrix0(z0_dm, z10_dm); - - if (!P10_dc) fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): The initial condition P_{1|0}\n" - " must be supplied as valid input arguments for when indxIni == 1"); - else - CopyCell0(P0_dc, P10_dc); - } - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t-1 = 1. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t-1 = 1. - - - kalfilmsinputs_1stapp_ps->ztm1_track = 0; //Must reset to 0, meaning initial setting is done and ready for computing LH at t = 1. - - Update_et_Dt_1stapp(0, kalfilmsinputs_1stapp_ps); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (1); - } - else - { - fn_DisplayError(".../kalman.c/InitializeKalman_z10_P10(): calling this function makes sense only if" - " kalfilmsinputs_1stapp_ps->ztm1_track is -1. Please check this value."); - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - - return (0); - } -} -//====================================================== -//= Integrating out the lagged regimes in order to -//= updating zt_tm1 and Pt_tm1 for next perid tp1 through Kim-Nelson filter. -//= tdata representing base-0 t timing, while inpt represents base-1 t timing. -// -//= Purpose: for each inpt, we integrate out grand regimes st -//= only ONCE to prevent the dimension of updated zt_tm1 and Pt_tm1 through Kim-Nelson filter. -//====================================================== -static int Updatekalfilms_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps) -{ - //Output: - // tm1update - // z_{t_1+1|t_1} - // P_{t_1+1|t_1} - //Input: - // t-1: base-1 t timing. Thus t-1=inpt-1. - - //--- Local variables - int stp1i, sti, t_2, t_2p1; - double prob_previous_regimes; - //-- Output arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-(T+1). - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1). - //--- Input arguments - TSdcell *Gt_dc = kalfilmsinputs_1stapp_ps->Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - //+ - TSdmatrix *bt_dm = kalfilmsinputs_1stapp_ps->bt_dm; //nz-by-nst. - TSdcell *Ft_dc = kalfilmsinputs_1stapp_ps->Ft_dc; //nz-by-nz-by-nst. - TSdcell *Vt_dc = kalfilmsinputs_1stapp_ps->Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - //+ - TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - int T = kalfilmsinputs_1stapp_ps->T; - TSdvector z0_sdv; - TSdvector btp1_sdv; - TSdvector etdata_sdv; - //=== Work arguments. - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - //+ - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //=== For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(nz); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - //--- Critical checking. - if (kalfilmsinputs_1stapp_ps->ztm1_track < 0) - fn_DisplayError(".../kalman.c/Updatekalfilms_1stapp(): Make sure InitializeKalman_z10_P10() is called in the function RefreshEverthing()"); - - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - btp1_sdv.n = nz; - btp1_sdv.flag = V_DEF; - //+ - etdata_sdv.n = ny; - etdata_sdv.flag = V_DEF; - - for (t_2=kalfilmsinputs_1stapp_ps->ztm1_track; t_2<t_1; t_2++) - { - //If t_1 <= ztm1_track, no updating. - //If t_1 > ztm1_track, updating z_{t|t-1} and P_{t|t-1} up to t-1 = t_1. - - zt_tm1_dc->C[t_2p1=t_2+1]->flag = M_GE; - for (stp1i=nst-1; stp1i>=0; stp1i--) - { - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=nst-1; sti>=0; sti--) - { - //=== Updating for next period by integrating out sti.. - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i], PHtran_tdata_d4->F[t_2]->C[sti], 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_d4->F[t_2]->C[sti]); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - etdata_sdv.v = etdata_dc->C[t_2]->M + ny*sti; - z0_sdv.v = zt_tm1_dc->C[t_2]->M + nz*sti; //sti: regime at time t_2. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, &etdata_sdv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i], Pt_tm1_d4->F[t_2]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - - //--- Integrating out the state at t_2 using - //--- P(s_t_2|Y_{t_2}, theta) = ProbabilityStateConditionalCurrent(sti, t_2, smodel_ps); - //--- One can also access to P(s_t_2|Y_{t_2}, theta) by using ElementV(smodel_ps->V[t_2],s_{t_2}i), - //--- but this access will not call my function logTimetCondLH(), thus no updating for - //--- P(s_t_2|Y_{t_2}, and thus leading to incorrect results. - prob_previous_regimes = ProbabilityStateConditionalCurrent(sti, t_2, smodel_ps); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - //--- Filling zt_tm1 and Pt_tm1 for next period. - z0_sdv.v = zt_tm1_dc->C[t_2p1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[t_2p1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - //--- $$$ The following is important because it tells ProbabilityStateConditionalCurrent(), which calls - //--- $$$ logTimetCondLH_kalfilms_1stapp(), which calls recursively this function again, that there is no - //--- $$$ need to update Kalman filter for the period before kalfilmsinputs_1stapp_ps->ztm1_track. - kalfilmsinputs_1stapp_ps->ztm1_track = t_2p1; //Means that z_{t_2p1+1|t_2p1} and P_{t_2p1+1|t_2p1} are done. - - //--- $$$ This function must be called after all the above computations are done. - Update_et_Dt_1stapp(t_2p1, kalfilmsinputs_1stapp_ps); - } - - - //=== - DestroyMatrix_lf(Wnzbynz_dm); - // - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (kalfilmsinputs_1stapp_ps->ztm1_track); -} -//====================================================== -//= Computes etdata and Dtdata for all grand regimes st at tbase0=inpt-1 or dtm1_track -//= to prevent recomputing this object for different st at given tbase0. -//====================================================== -static int Update_et_Dt_1stapp(int t_1, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps) -{ - //Output: - // dtm1_track is updated in this function. - // PHtran_tdata_d4->F[t-1] - // etdata_dc->C[t-1] - // Dtdata_d4->F[t-1] - //Input: - // t_1=inpt-1: base-0 timing for et and Dt before the likelihood at time inpt is computed. - - //--- Local variables - int sti, tbase0; - //-- Output arguments - TSdfourth *PHtran_tdata_d4 = kalfilmsinputs_1stapp_ps->PHtran_tdata_d4; //nz-by-ny-by-nst-T, saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc = kalfilmsinputs_1stapp_ps->etdata_dc; //ny-by-nst-by-T, save for computing the likelihood. - TSdcell *yt_tm1_dc = kalfilmsinputs_1stapp_ps->yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). - TSdfourth *Dtdata_d4 = kalfilmsinputs_1stapp_ps->Dtdata_d4; //ny-by-ny-nst-by-T, save for computing the likelihood and updating Kalman filter Updatekalfilms_1stapp(). - //--- input arguments - TSdcell *zt_tm1_dc = kalfilmsinputs_1stapp_ps->zt_tm1_dc; //nz-by-nst-by-T. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_1stapp_ps->Pt_tm1_d4; //nz-by-nz-by-nst-by-T. - //+ - TSdmatrix *yt_dm = kalfilmsinputs_1stapp_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_1stapp_ps->at_dm; //ny-by-nst. - TSdcell *Ht_dc = kalfilmsinputs_1stapp_ps->Ht_dc; //ny-by-nz-by-nst. - TSdcell *Rt_dc = kalfilmsinputs_1stapp_ps->Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - //--- Accessible variables - int ny = kalfilmsinputs_1stapp_ps->ny; - int nz = kalfilmsinputs_1stapp_ps->nz; - int nst = kalfilmsinputs_1stapp_ps->nst; - TSdvector z0_sdv; - TSdvector yt_sdv, at_sdv; - TSdvector etdata_sdv, yt_tm1_sdv; - //=== Work arguments. - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - z0_sdv.n = nz; - z0_sdv.flag = V_DEF; - at_sdv.n = yt_sdv.n = ny; - at_sdv.flag = yt_sdv.flag = V_DEF; - etdata_sdv.n = yt_tm1_sdv.n = ny; - etdata_sdv.flag = yt_tm1_sdv.flag = V_DEF; - - for (tbase0=(kalfilmsinputs_1stapp_ps->dtm1_track+1); tbase0<=t_1; tbase0++) - { - //Note tbase0<=t_1, NOT tbase0<t_1. - //If t_1 < (dtm1_track+1), no updating. - //If t_1 >= (dtm1_track+1), updating etdata_dc->C[t-1] and Dtdata_d4->F[t-1] up to t-1=t_1. - - for (sti=nst-1; sti>=0; sti--) - { - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti], 1.0, 0.0, 'N', 'T'); - CopyMatrix0(kalfilmsinputs_1stapp_ps->PHtran_tdata_d4->F[tbase0]->C[sti], PHtran_tdata_dm); - - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti*at_dm->nrows; //grand regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - etdata_sdv.v = etdata_dc->C[tbase0]->M + etdata_sdv.n*sti; - yt_tm1_sdv.v = etdata_dc->C[tbase0]->M + yt_tm1_sdv.n*sti; - CopyVector0(&yt_tm1_sdv, &at_sdv); - MatrixTimesVector(&yt_tm1_sdv, Ht_dc->C[sti], &z0_sdv, 1.0, 1.0, 'N'); //a + H*z_{t|t-1}. - VectorMinusVector(&etdata_sdv, &yt_sdv, &yt_tm1_sdv); //y_t - a - H*z_{t|t-1}. - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - CopyMatrix0(Dtdata_d4->F[tbase0]->C[sti], Dtdata_dm); //Saved to be used for logTimetCondLH_kalfilms_1stapp(). - } - - //--- $$$ This tracker functions the same way as kalfilmsinputs_1stapp_ps->ztm1_track. - kalfilmsinputs_1stapp_ps->dtm1_track = tbase0; - } - - //=== - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyMatrix_lf(Dtdata_dm); - - return (kalfilmsinputs_1stapp_ps->dtm1_track); -} - - - - - - -//----------------------------------------------------- -//------------ OLD Code -------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -// -//- IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that -//- the coefficient regime is the 1st state variable, and -//- the volatility regime is the 2nd state variable. -//----------------------------------------------------- -#if defined (NEWVERSIONofDW_SWITCH) -double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0 (initial condition). - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int comst_c; //composite (s_tc, s_{t-1}c) - int st_c, stm1_c, st_v; - int comsti_c; //composite (s_tc, s_{t-1}c) - int sti, sti_c, stm1i_c, sti_v; - int comstp1i_c; //composite (s_{t+1}c, s_tc) - int stp1i, stp1i_c, stp1i_v; - int tbase0, tp1; - double logdet_Dtdata, loglh_timet; - static int record_tbase1_or_inpt_or_tp1 = 0; - static int passonce; - double prob_previous_regimes; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRstc = kalfilmsinputs_ps->nRstc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - int **Index = smodel_ps->sv->index; //Regime-switching states. - //smodel_ps->sv->index is for our new code. - // For old code (before 9 April 08 and before dsge_switch is created), use smodel_ps->sv->Index; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_logTimetLH_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - tbase0 = (tp1=inpt) - 1; - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - if (tbase0==0) - { - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[comsti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[comsti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, comsti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[comsti_c], Ft_dc->C[comsti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); -//=== ???????? For debugging purpose. -//if ((inpt<2) && (st==0)) -//{ -// fprintf(FPTR_DEBUG, "%%st=%d, inpt=%d, and sti=%d\n", st, inpt, sti); - -// fprintf(FPTR_DEBUG, "wP0_dv:\n"); -// WriteVector(FPTR_DEBUG, wP0_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Vt_dc->C[sti_v=%d]:\n", sti_v); -// WriteMatrix(FPTR_DEBUG, Vt_dc->C[sti_v], " %10.5f "); - -// fflush(FPTR_DEBUG); - -//} - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime comsti_c=%d and sti_v=%d and at time=%d\n", comsti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - } - - - //====================================================== - //= Getting the logLH at time tbase0 or time inpt. - //====================================================== - if (indxIndRegimes ) - { - if (nRc==1) //Volatility. - { - comst_c = st_c = 0; - st_v = st; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_v = Index[st][1]; //volatility state s_tv - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comst_c = st_c = st; - st_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - comst_c = st_c = Index[st][0]; - st_v = Index[st][1]; - } - } - else //Syncronized regimes - { - if (nRc>nRstc) - { - comst_c = Index[st][0]; //composite (s_tc, s_{t-1}c) - st_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][0]; //coefficient regime at t. - stm1_c = smodel_ps->sv->state_variable[0]->lag_index[comst_c][1]; //coefficient regime at t-1: tm1: t-1; - st_v = st_c; - } - else - comst_c = st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[comst_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comst_c*at_dm->nrows; //comst_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comst_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comst_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //--- Forming the log conditional likelihood at t. - if (!isfinite(logdet_Dtdata=logdetspd(Dtdata_dm))) return (loglh_timet = -NEARINFINITY); - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); -//if ((inpt>82) && (inpt<86) ) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %.16e "); - -// fflush(FPTR_DEBUG); -//} - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdet_Dtdata - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - - -//=== ???????? For debugging purpose. -if (inpt==1) -{ - double wk1, wk2; - - wk1 = logdet_Dtdata; - wk2 = VectorDotVector(wny_dv, etdata_dv); - fprintf(FPTR_DEBUG, "logdet_Dtdata = %10.5f\n", wk1); - fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f\n", wk2); - fprintf(FPTR_DEBUG, "----- etdata_dv: \n"); - WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- yt_dv: \n"); - WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- at_dv: \n"); - WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- z0_dv: \n"); - WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); - fprintf(FPTR_DEBUG, "----- Ht_dc->C[comst_c=%d]:\n", comst_c); - WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); - - fprintf(FPTR_DEBUG, "\n\n"); - -} -// -fprintf(FPTR_DEBUG, " %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//fprintf(FPTR_DEBUG, "------------------------\n"); -//fprintf(FPTR_DEBUG, "st=%d and inpt=%d\n", st, inpt); -//fprintf(FPTR_DEBUG, "loglh_timet = %10.5f\n", loglh_timet); -//fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -//WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -////WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -////fprintf(FPTR_DEBUG, "\n"); -////WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//fflush(FPTR_DEBUG); - - -//=== ???????? For debugging purpose. -//if ((inpt>82) && (inpt<86) ) -//if (inpt<2) -//{ -// //Must be declared at the top of this "if" block. -// int kip1; -// double tmp_Dtdata; -// double tmp_expterm; - -// fprintf(FPTR_DEBUG, "%%------------------------\n"); -// fprintf(FPTR_DEBUG, "%%st=%d and inpt=%d\n", st, inpt); -// fprintf(FPTR_DEBUG, "loglh_timet = %10.5f;\n", loglh_timet); - - -// tmp_Dtdata = logdeterminant(Dtdata_dm); -// tmp_expterm = VectorDotVector(wny_dv, etdata_dv); -// fprintf(FPTR_DEBUG, "logdeterminant(Dtdata_dm) = %10.5f;\n", tmp_Dtdata); -// fprintf(FPTR_DEBUG, "VectorDotVector(wny_dv, etdata_dv) = %10.5f;\n", tmp_expterm); -// fprintf(FPTR_DEBUG, "wny_dv:\n"); -// WriteVector(FPTR_DEBUG, wny_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "etdata_dv:\n"); -// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&yt_sdv:\n"); -// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&at_sdv:\n"); -// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "&z0_sdv:\n"); -// WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -// fprintf(FPTR_DEBUG, "Ht_dc->C[comst_c=%d]:\n",comst_c); -// WriteMatrix(FPTR_DEBUG, Ht_dc->C[comst_c], " %10.5f "); -// fprintf(FPTR_DEBUG, "Rt_dc->C[st_v=%d]:\n", st_v); -// WriteMatrix(FPTR_DEBUG, Rt_dc->C[st_v], " %10.5f "); -// fprintf(FPTR_DEBUG, "Pt_tm1_d4->F[tbase0]->C[st = %d]:\n",st); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[st], " %10.5f "); -// fprintf(FPTR_DEBUG, "Dtdata_dm:\n"); -// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); - - - - -//// WriteMatrix(FPTR_DEBUG, Dtdata_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "zt_tm1_dc->C[tbase0]:\n"); -//// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -//// //WriteVector(FPTR_DEBUG, &z0_sdv, " %10.5f "); -//// //fprintf(FPTR_DEBUG, "\n"); -//// fprintf(FPTR_DEBUG, "bt_dm = [\n"); -//// WriteMatrix(FPTR_DEBUG, bt_dm, " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); - -//// fprintf(FPTR_DEBUG, "et:\n"); -//// WriteVector(FPTR_DEBUG, etdata_dv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "yt_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &yt_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - -//// fprintf(FPTR_DEBUG, "at_dv=[\n"); -//// WriteVector(FPTR_DEBUG, &at_sdv, " %10.5f "); -//// fprintf(FPTR_DEBUG, "]';\n"); - - -//// for (ki=0; ki<Ht_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ht_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ht_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Ft_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Ft_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Ft_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -//// for (ki=0; ki<Vt_dc->ncells; ki++) -//// { -//// kip1 = ki+1; -//// fprintf(FPTR_DEBUG, "Vt_dc(:,:,%d)=[\n", kip1); -//// WriteMatrix(FPTR_DEBUG, Vt_dc->C[ki], " %10.5f "); -//// fprintf(FPTR_DEBUG, "];\n"); -//// } -// fflush(FPTR_DEBUG); -//} - - - //====================================================== - //= Updating zt_tm1 and Pt_tm1 for next perid tp1. - //= tdata = tbase0 is base-0 timing. - //====================================================== - if (inpt > record_tbase1_or_inpt_or_tp1) //This condition always satisfies at the 1st period (which is inpt=1). - { - passonce = 0; - record_tbase1_or_inpt_or_tp1 = inpt; - } - if (!passonce) - { - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comstp1i_c = stp1i_c = 0; - stp1i_v = stp1i; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_v = Index[stp1i][1]; //volatility state s_tv - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comstp1i_c = stp1i_c = stp1i; - stp1i_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comstp1i_c = stp1i_c = Index[stp1i][0]; - stp1i_v = Index[stp1i][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comstp1i_c = Index[stp1i][0]; //composite (s_tc, s_{t-1}c) - stp1i_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][0]; //coefficient regime at t. - //sti_c = smodel_ps->sv->state_variable[0]->lag_index[comstp1i_c][1]; //coefficient regime at t-1: tm1: t-1; - stp1i_v = stp1i_c; - } - else - comstp1i_c = stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes) - { - if (nRc==1) //Volatility. - { - comsti_c = sti_c = 0; - sti_v = sti; - } - else if ((nRv>1) && (nRc>nRstc)) //Trend inflation, both sc_t and sc_{t-1} enters coefficient regime. - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_v = Index[sti][1]; //volatility state s_tv - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - } - else if ((nRv==1) && (nRc>nRstc)) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = 0; - } - else if ((nRv==1) && (nRc==nRstc)) - { - comsti_c = sti_c = sti; - sti_v = 0; - } - else if ((nRv>1) && (nRc==nRstc)) //only sc_t enters coefficient regime. - { - comsti_c = sti_c = Index[sti][0]; - sti_v = Index[sti][1]; - } - } - else //Syncronized regimes. - { - if (nRc>nRstc) - { - comsti_c = Index[sti][0]; //composite (s_tc, s_{t-1}c) - sti_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][0]; //coefficient regime at t. - stm1i_c = smodel_ps->sv->state_variable[0]->lag_index[comsti_c][1]; //coefficient regime at t-1: tm1: t-1; - sti_v = sti_c; - } - else - comsti_c = sti_c = sti_v = sti; - } - - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[comsti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + comsti_c*at_dm->nrows; //comsti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[comsti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[comsti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - ScalarTimesMatrixSquare(Dtdata_dm, 0.5, Dtdata_dm, 'T', 0.5); //Making it symmetric against some rounding errors. - //This making-symmetric is very IMPORTANT; otherwise, we will get the matrix being singular message - // and eigenvalues being negative for the SPD matrix, etc. Then the likelihood becomes either - // a bad number or a complex number. - Dtdata_dm->flag = Dtdata_dm->flag | M_SU | M_SL; - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i_v]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_{t-1}, theta) = ElementV(smodel_ps->Z[inpt],s_{inpt}_i). - //--- Note tbase0 = inpt-1 because the data in DW code (ElementV) is base-1. - //--- Note at this point, we cannot access to P(s_t|Y_t, theta) = ElementV(smodel_ps->V[inpt],s_{inpt}_i) - //--- through DW's code. But we can modify my own code to do this later. - prob_previous_regimes = ElementV(smodel_ps->Z[inpt],sti); - ScalarTimesVectorUpdate(ztp1_dv, prob_previous_regimes, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, prob_previous_regimes, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - } - - -//=== ???????? For debugging purpose. -//if ((inpt>60) && (inpt<65) ) //if (inpt<5) -//{ -// int kip1; //Must be declared at the top of this "if" block. - -// fprintf(FPTR_DEBUG, "zt_tm1t=[\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tbase0], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); - -// for (ki=0; ki<Pt_tm1_d4->F[tbase0]->ncells; ki++) -// { -// kip1 = ki+1; -// fprintf(FPTR_DEBUG, "Pt_tm1_d4t(:,:,%d)=[\n", kip1); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tbase0]->C[ki], " %10.5f "); -// fprintf(FPTR_DEBUG, "];\n"); -// } - -// fflush(FPTR_DEBUG); -//} - - -//=== ???????? For debugging purpose. -fprintf(FPTR_DEBUG, " loglh_timet = %10.5f\n", loglh_timet); -fflush(FPTR_DEBUG); - - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); - - return (loglh_timet); -} -#undef LOG2PI -#endif - - -/** -//---------------------------------------------------------------- -//-- Tested OK, but has not use because tz_Refresh_z_T7P_T_in_kalfilms_1st_approx() -//-- cannot access to ElementV(smodel_ps->V[tp1],sti) or ElementV(smodel_ps->V[tbase0],sti) -//-- because no likelihood has been formed at all before this function is called. -//---------------------------------------------------------------- -#define LOG2PI (1.837877066409345e+000) //log(2*pi) -//----------------------------------------------------- -//- Updating or refreshing all Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// RunningGensys_const7varionly(lwzmodel_ps); -// Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -//- before using tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(). -//----------------------------------------------------- -void tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - double debug1; - //--- Local variables - int stp1i, stp1i_c, stp1i_v, sti, sti_c, sti_v, tbase0, tp1; - //=== Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int T = kalfilmsinputs_ps->T; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc = kalfilmsinputs_ps->Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm = kalfilmsinputs_ps->bt_dm; //nz-by-nRc. - TSdcell *Ft_dc = kalfilmsinputs_ps->Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc = kalfilmsinputs_ps->Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm = kalfilmsinputs_ps->z0_dm; //nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - TSdcell *P0_dc = kalfilmsinputs_ps->P0_dc; //nz-by-nz-by-nRc*nRv or nz-by-nRv, depending on indxIndRegimes. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - int nz2 = square(nz); - TSdmatrix *Wnzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *Wnz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdmatrix *W2nz2bynz2_dm = CreateMatrix_lf(nz2,nz2); - TSdvector *wP0_dv = CreateVector_lf(nz2); - //+ - TSdvector yt_sdv, at_sdv, btp1_sdv; //zt_tm1_sdv, ztp1_t_sdv, - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *Wnzbyny_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *W2nzbynz_dm = CreateMatrix_lf(nz,nz); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - TSdmatrix *Kt_tdata0_dm = CreateMatrix_lf(nz,ny); - TSdmatrix *Kt_tdata_dm = CreateMatrix_lf(nz,ny); - //--- For eigenvalue decompositions - int ki; - int errflag; - double eigmax; - TSdzvector *evals_dzv = evals_dzv = CreateVector_dz(nz); - TSdvector *evals_abs_dv = CreateVector_lf(nz); //Absolute eigenvalues. - //--- For updating zt_tm1_dm and Pt_tm1. - TSdvector *ztp1_t_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_t_dm = CreateMatrix_lf(nz, nz); - TSdvector *ztp1_dv = CreateVector_lf(z0_dm->nrows); - TSdmatrix *Ptp1_dm = CreateMatrix_lf(nz, nz); - - - if (smodel_ps->sv->nstates != z0_dm->ncols) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Make sure that the column dimension of z0_dm is the same as smodel_ps->sv->nstates"); - if (indxIndRegimes && (nRc>1) && (nRv>1)) - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - - - z0_sdv.n = z0_dm->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - btp1_sdv.n = bt_dm->nrows; - btp1_sdv.flag = V_DEF; - - - //======= Initial condition. ======= - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - - if (!kalfilmsinputs_ps->indxIni) - { - InitializeDiagonalMatrix_lf(Wnzbynz_dm, 1.0); //To be used for I(nz) - - InitializeDiagonalMatrix_lf(Wnz2bynz2_dm, 1.0); //To be used for I(nz2) - - - //=== Eigenanalysis to determine the roots to ensure boundedness. - errflag = eigrgen(evals_dzv, (TSdzmatrix *)NULL, (TSdzmatrix *)NULL, Ft_dc->C[sti_c]); - if (errflag) fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): eigen decomposition failed"); - for (ki=nz-1; ki>=0; ki--) evals_abs_dv->v[ki] = sqrt(square(evals_dzv->real->v[ki]) + square(evals_dzv->imag->v[ki])); - evals_abs_dv->flag = V_DEF; - eigmax = MaxVector(evals_abs_dv); - if (eigmax < (1.0+1.0e-14)) - { - //--- Getting z0_dv: zt_tm1(:,1) = (eye(n_z)-F(:,:,1))\b(:,1); - MatrixMinusMatrix(Wnzbynz_dm, Wnzbynz_dm, Ft_dc->C[sti_c]); - z0_sdv.v = z0_dm->M + z0_sdv.n*sti; - CopySubmatrix2vector(&z0_sdv, 0, bt_dm, 0, sti_c, bt_dm->nrows); - bdivA_rgens(&z0_sdv, &z0_sdv, '\\', Wnzbynz_dm); - //Done with Wnzbynz_dm. - //--- Getting P0_dm: Pt_tm1(:,:,1) = reshape((eye(n_z^2)-kron(F(:,:,1),F(:,:,1)))\V1(:),n_z,n_z); - tz_kron(W2nz2bynz2_dm, Ft_dc->C[sti_c], Ft_dc->C[sti_c]); - MatrixMinusMatrix(Wnz2bynz2_dm, Wnz2bynz2_dm, W2nz2bynz2_dm); - CopySubmatrix2vector(wP0_dv, 0, Vt_dc->C[sti_v], 0, 0, nz2); - bdivA_rgens(wP0_dv, wP0_dv, '\\', Wnz2bynz2_dm); - CopySubvector2matrix_unr(P0_dc->C[sti], 0, 0, wP0_dv, 0, nz2); - //Done with all w*_dv and W*_dm. - } - else - { - fprintf(stdout, "\n-----------------\n"); - fprintf(stdout, "\nIn regime sti_c=%d and sti_v=%d and at time=%d\n", sti_c, sti_v, 0); - fn_DisplayError("kalman.c/tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(): the system is non-stationary solutions\n" - " and the initial conditions must be supplied by, say, input arguments"); - fflush(stdout); - } - } - } - z0_dm->flag = M_GE; - CopyMatrix0(zt_tm1_dc->C[0], z0_dm); //At time t=0. - CopyCell0(Pt_tm1_d4->F[0], P0_dc); //At time t=0. - - -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[0]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[0]->C[0], " %.16e "); - - - //============== Updating zt_tm1 and Pt_tm1. ================== - for (tbase0=0; tbase0<T; tbase0++ ) - { - //tdata = tbase0 is base-0 timing. - tp1 = tbase0 + 1; //Next period. - - for (stp1i=smodel_ps->sv->nstates-1; stp1i>=0; stp1i--) - { - if (indxIndRegimes && (nRc==1)) - { - stp1i_c = 0; - stp1i_v = stp1i; - } - else if (indxIndRegimes && (nRv==1)) - { - stp1i_c = stp1i; - stp1i_v = 0; - } - else if (indxIndRegimes) - { - stp1i_c = smodel_ps->sv->Index[stp1i][0]; - stp1i_v = smodel_ps->sv->Index[stp1i][1]; - } - else - { - stp1i_c = stp1i_v = stp1i; - } - - - InitializeConstantVector_lf(ztp1_dv, 0.0); //To be summed over sti. - InitializeConstantMatrix_lf(Ptp1_dm, 0.0); //To be summed over sti. - for (sti=smodel_ps->sv->nstates-1; sti>=0; sti--) - { - if (indxIndRegimes && (nRc==1)) - { - sti_c = 0; - sti_v = sti; - } - else if (indxIndRegimes && (nRv==1)) - { - sti_c = sti; - sti_v = 0; - } - else if (indxIndRegimes) - { - sti_c = smodel_ps->sv->Index[sti][0]; - sti_v = smodel_ps->sv->Index[sti][1]; - } - else - { - sti_c = sti_v = sti; - } - - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[sti], Ht_dc->C[sti_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + sti_c*at_dm->nrows; //sti_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*sti; //sti: regime at time tbase0. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[sti_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[sti_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[sti_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - //Done with z0_sdv.v. - - - //=== Updating for next period by integrating out sti.. - if (tp1<T) - { - //Updating only up to tbase0=T-2. The values at tp1=T or tbase0=T-1 will not be used in the likelihood function. - - //--- Ktp1_t = (F_tp1*PHtran_t+G(:,:,t))/Dt; - //--- Kt_tdata = (Ft*PHtran_tdata+G(:,:,tdata))/Dtdata where t=tp1 and tdata=t. - CopyMatrix0(Kt_tdata0_dm, Gt_dc->C[sti_v]); - MatrixTimesMatrix(Kt_tdata0_dm, Ft_dc->C[stp1i_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - BdivA_rrect(Kt_tdata_dm, Kt_tdata0_dm, '/', Dtdata_dm); - //+ zt_tm1(:,t) = b(:,t) + Ft*zt_tm1(:,tdata) + Kt_tdata*etdata where t=tp1 and tm1=t. - MatrixTimesVector(ztp1_t_dv, Ft_dc->C[stp1i_c], &z0_sdv, 1.0, 0.0, 'N'); - MatrixTimesVector(ztp1_t_dv, Kt_tdata_dm, etdata_dv, 1.0, 1.0, 'N'); - btp1_sdv.v = bt_dm->M + stp1i_c*btp1_sdv.n; - VectorPlusMinusVectorUpdate(ztp1_t_dv, &btp1_sdv, 1.0); - //+ Pt_tm1(:,:,t) = Ft*Ptdata*Fttran - Kt_tdata*Dtdata*Kt_tdatatran + V(:,:,t); - CopyMatrix0(Ptp1_t_dm, Vt_dc->C[stp1i]); - MatrixTimesMatrix(Wnzbyny_dm, Kt_tdata_dm, Dtdata_dm, 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(Wnzbynz_dm, Wnzbyny_dm, Kt_tdata_dm, 1.0, 0.0, 'N', 'T'); - MatrixPlusMinusMatrixUpdate(Ptp1_t_dm, Wnzbynz_dm, -1.0); - //Done with all W*_dm. - MatrixTimesMatrix(Wnzbynz_dm, Ft_dc->C[stp1i_c], Pt_tm1_d4->F[tbase0]->C[sti], 1.0, 0.0, 'N', 'N'); - MatrixTimesMatrix(W2nzbynz_dm, Wnzbynz_dm, Ft_dc->C[stp1i_c], 1.0, 0.0, 'N', 'T'); - MatrixPlusMatrixUpdate(Ptp1_t_dm, W2nzbynz_dm); - //Done with all W*_dm. - - //--- Integrating out the state at tbase0 using P(s_t|Y_t, theta) = ElementV(smodel_ps->V[t+1],s_{t+1}_i). - //--- Note because the data in DW code (ElementV) is base-1, t+1 is actually tbase0. - debug1 = ElementV(smodel_ps->V[tp1],sti); //?????? Debug. - //ScalarTimesVectorUpdate(ztp1_dv, ElementV(smodel_ps->V[tp1],sti), ztp1_t_dv); - //ScalarTimesMatrix(Ptp1_dm, ElementV(smodel_ps->V[tp1],sti), Ptp1_t_dm, 1.0); - ScalarTimesVectorUpdate(ztp1_dv, 0.5, ztp1_t_dv); - ScalarTimesMatrix(Ptp1_dm, 0.5, Ptp1_t_dm, 1.0); - Ptp1_dm->flag = M_GE | M_SU | M_SL; - //Done with ztp1_t_dv and Ptp1_t_dm. - } - } - //--- Filling zt_tm1 and Pt_tm1 for next period - if (tp1<T) - { - z0_sdv.v = zt_tm1_dc->C[tp1]->M + z0_sdv.n*stp1i; //stp1i: regime at time tp1. - CopyVector0(&z0_sdv, ztp1_dv); - CopyMatrix0(Pt_tm1_d4->F[tp1]->C[stp1i], Ptp1_dm); //stp1i: regime at time tp1. - //Done with ztp1_dv, z0_sdv, Ptp1_dm. - } - } - if (tp1<T) - zt_tm1_dc->C[tp1]->flag = M_GE; - -// fprintf(FPTR_DEBUG, "\n &yt_sdv:\n"); -// WriteMatrix(FPTR_DEBUG, &yt_sdv, " %.16e "); -// fprintf(FPTR_DEBUG, "\n zt_tm1_dc->C[tp1]:\n"); -// WriteMatrix(FPTR_DEBUG, zt_tm1_dc->C[tp1], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fprintf(FPTR_DEBUG, "\n Pt_tm1_d4->F[tp1]->C[0]:\n"); -// WriteMatrix(FPTR_DEBUG, Pt_tm1_d4->F[tp1]->C[0], " %.16e "); -// fprintf(FPTR_DEBUG, "\n"); -// fflush(FPTR_DEBUG); - - - } - - //=== - DestroyVector_dz(evals_dzv); - DestroyVector_lf(evals_abs_dv); - DestroyMatrix_lf(Wnzbynz_dm); - DestroyMatrix_lf(Wnz2bynz2_dm); - DestroyMatrix_lf(W2nz2bynz2_dm); - DestroyVector_lf(wP0_dv); - // - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(Wnzbyny_dm); - DestroyMatrix_lf(W2nzbynz_dm); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - DestroyMatrix_lf(Kt_tdata0_dm); - DestroyMatrix_lf(Kt_tdata_dm); - // - DestroyVector_lf(ztp1_t_dv); - DestroyMatrix_lf(Ptp1_t_dm); - DestroyVector_lf(ztp1_dv); - DestroyMatrix_lf(Ptp1_dm); -} -//----------------------------------------------------- -//- Kalman filter at time t for Markov-switching DSGE model. -//- WARNING: make sure to call the following functions -// (1) RunningGensys_const7varionly(lwzmodel_ps); -// (2) Refresh_kalfilms_*(lwzmodel_ps); //Creates or refreshes kalfilmsinputs_ps at new parameter values. -// (3) tz_Refresh_z_T7P_T_in_kalfilms_1st_approx(); -//- before using kalfilms_timet_1st_approx(). -//----------------------------------------------------- -double tz_kalfilms_timet_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps) -{ - //st, st_c, and st_v: base-0: deals with the cross-section values at time t where - // st is a grand regime, st_c is an encoded coefficient regime, and st_c is an encoded volatility regime. - //inpt: base-1 in the sense that inpt>=1 to deal with the time series situation where S_T is (T+1)-by-1 and Y_T is T+nlags_max-by-1. - // The 1st element for S_T is S_T[1] while S_T[0] is s_0. The same for (T+1)-by-1 gbeta_dv and nlcoefs-by-(T+1) galpha_dm. - // The 1st element for Y_T, however, is Y_T[nlags_max+1-1]. - //See (42.3) on p.42 in the SWZII NOTES. - - - //--- Local variables - int st_c, st_v, tbase0; - double loglh_timet; - //--- Accessible variables - int ny = kalfilmsinputs_ps->ny; - int nz = kalfilmsinputs_ps->nz; - int nRc = kalfilmsinputs_ps->nRc; - int nRv = kalfilmsinputs_ps->nRv; - int indxIndRegimes = kalfilmsinputs_ps->indxIndRegimes; - TSdvector z0_sdv; - //+ input arguments. - TSdmatrix *yt_dm = kalfilmsinputs_ps->yt_dm; //ny-by-T. - TSdmatrix *at_dm = kalfilmsinputs_ps->at_dm; //ny-by-nRc. - TSdcell *Ht_dc = kalfilmsinputs_ps->Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc = kalfilmsinputs_ps->Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - //+ Output arguments. - TSdcell *zt_tm1_dc = kalfilmsinputs_ps->zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4 = kalfilmsinputs_ps->Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - //=== Work arguments. - TSdvector yt_sdv, at_sdv; - TSdvector *wny_dv = CreateVector_lf(ny); - TSdmatrix *PHtran_tdata_dm = CreateMatrix_lf(nz,ny); - TSdvector *etdata_dv = CreateVector_lf(ny); - TSdmatrix *Dtdata_dm = CreateMatrix_lf(ny,ny); - - - if (smodel_ps->sv->nstates != zt_tm1_dc->C[0]->ncols) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Make sure that the column dimension of zt_tm1_dc->C is the same as smodel_ps->sv->nstates"); - - tbase0 = inpt - 1; //base-0 time t. - - if (indxIndRegimes && (nRc==1)) - { - st_c = 0; - st_v = st; - } - else if (indxIndRegimes && (nRv==1)) - { - st_c = st; - st_v = 0; - } - else if (indxIndRegimes) - { - if (smodel_ps->sv->n_state_variables != 2) fn_DisplayError("kalman.c/kalfilms_timet_1st_approx():\n" - " Number of state variables must be coincide with indxIndRegimes"); - st_c = smodel_ps->sv->Index[st][0]; - st_v = smodel_ps->sv->Index[st][1]; - } - else - { - st_c = st_v = st; - } - - - z0_sdv.n = zt_tm1_dc->C[0]->nrows; - z0_sdv.flag = V_DEF; - // - at_sdv.n = yt_sdv.n = yt_dm->nrows; - at_sdv.flag = yt_sdv.flag = V_DEF; - - //====== Computing the conditional LH at time t. ====== - //--- Setup. - MatrixTimesMatrix(PHtran_tdata_dm, Pt_tm1_d4->F[tbase0]->C[st], Ht_dc->C[st_c], 1.0, 0.0, 'N', 'T'); - - //--- Data. - //- etdata = Y_T(:,tdata) - a(:,tdata) - Htdata*ztdata where tdata = tbase0 = inpt-1. - yt_sdv.v = yt_dm->M + tbase0*yt_dm->nrows; - at_sdv.v = at_dm->M + st_c*at_dm->nrows; //st_c: coefficient regime at time tbase0. - z0_sdv.v = zt_tm1_dc->C[tbase0]->M + z0_sdv.n*st; //st: regime at time tbase0 for zt_tm1. - VectorMinusVector(etdata_dv, &yt_sdv, &at_sdv); - MatrixTimesVector(etdata_dv, Ht_dc->C[st_c], &z0_sdv, -1.0, 1.0, 'N'); - //+ Dtdata = Htdata*PHtran_tdata + R(:,:,tbase0); - CopyMatrix0(Dtdata_dm, Rt_dc->C[st_v]); - MatrixTimesMatrix(Dtdata_dm, Ht_dc->C[st_c], PHtran_tdata_dm, 1.0, 1.0, 'N', 'N'); - - //--- Forming the log conditional likelihood at t. - bdivA_rgens(wny_dv, etdata_dv, '/', Dtdata_dm); - loglh_timet = -(0.5*ny)*LOG2PI - 0.5*logdeterminant(Dtdata_dm) - 0.5*VectorDotVector(wny_dv, etdata_dv); - //Done with all w*_dv. - - - //=== - DestroyVector_lf(wny_dv); - DestroyMatrix_lf(PHtran_tdata_dm); - DestroyVector_lf(etdata_dv); - DestroyMatrix_lf(Dtdata_dm); - - return (loglh_timet); -} -#undef LOG2PI -/**/ - - - - diff --git a/CFiles/kalmanOldWorks2.h b/CFiles/kalmanOldWorks2.h deleted file mode 100755 index df661b5160ecd1be8c733931ddfc94fb29d2f7dd..0000000000000000000000000000000000000000 --- a/CFiles/kalmanOldWorks2.h +++ /dev/null @@ -1,314 +0,0 @@ -#ifndef __KALMAN_H__ - #define __KALMAN_H__ - - #include "tzmatlab.h" - #include "mathlib.h" - #include "switch.h" - #include "fn_filesetup.h" //Used to call WriteMatrix(FPTR_DEBUG,....). - - - typedef struct TSkalcvfurw_tag { - //urw: univariate random walk kalman filter. Desigend specially for the 2006 AER SWZ paper. - - //=== Input arguments. - int indx_tvsigmasq; //0: constant siqmasq in Kalman updating (default); - //1: Keyensian (project-specific) type of time-varying sigmasq in Kalman updating; See pp.37 and 37a in SWZ Learning NOTES; - //2: project-specific type; - //3: another project-specific type. - double sigmasq; //Variance for the residual eps(t) of the measurement equation. - int fss; //T: effective sample size (excluding lags). - int kx; //dimension for x(t). - TSdmatrix *V_dm; //kx-by-kx. Covariance (symmetric and positive definite) matrix for the residual eta(t) of the transition equation. - TSdvector *ylhtran_dv; //1-by-T of y(t). The term lh means lelf hand side and tran means transpose. - TSdmatrix *Xrhtran_dm; //kx-by-T of x(t). The term rh means right hand side and tran means transpose. - TSdvector *z10_dv; //kx-by-1. Initial condition for prediction: z_{1|0}. - TSdmatrix *P10_dm; //kx-by-kx symmetric matrix. Initial condition for the variance of the prediction: P_{1|0}. - - //=== Output arguments. - TSdvector *zupdate_dv; //kx-by-1. z_{T+1|T}. - TSdmatrix *Zpredtran_dm; //kx-by-T matrix of one-step predicted values of z(t). [z_{2|1}, ..., z_{t+1|t}, ..., z_{T+1|T}]. - //Set to NULL (no output) if storeZ = 0; - TSdcell *Ppred_dc; //T cells and kx-by-kx symmetric and positive definite matrix for each cell. Mean square errors of predicted state variables. - //{P_{2|1}, ..., P{t+1|t}, ..., P{T+1|T}. Set to NULL (no output if storeV = 0). - TSdvector *ylhtranpred_dv; //1-by-T one-step prediction of y(t) or ylhtran_dv. Added 03/17/05. - - //=== Function itself. - void (*learning_fnc)(struct TSkalcvfurw_tag *, void *); - } TSkalcvfurw; //urw: univariate random walk. - // - typedef void TFlearninguni(struct TSkalcvfurw_tag *, void *); //For linear rational expectations models. - - - //=== Better version is TSkalfilmsinputs_1stapp_tag. Kalman filter for constant or known-time-varying DSGE models. - typedef struct TSkalfiltv_tag - { - //General (known-time-varying) Kalman filter for DSGE models. - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs are as follows: - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-T matrix of time-varying input vectors in the measurement equation. - // H is an n_y-by-n_z-by-T 3-D of time-varying matrices in the measurement equation. - // R is an n_y-by-n_y-by-T 3-D of time-varying covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-T 3-D of time-varying E(eta_t * eps_t'). - // ------ - // b is an n_z-by-T matrix of time-varying input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-T 3-D of time-varying transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-T 3-D of time-varying covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-1 vector of initial condition when indxIni=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z matrix of initial condition when indxIni=1. (Not used if indxIni=0.) - // - // Outputs are as follows: - // loglh is a value of the log likelihood function of the state-space model - // under the assumption that errors are multivariate Gaussian. - // zt_tm1 is an n_z-by-T matrices of one-step predicted state vectors with z0_0m1 as a initial condition - // and with z_{t+1|t} as the last element. Thus, we can use it as a base-1 vector. - // Pt_tm1 is an n_z-by-n_z-by-T 3-D of covariance matrices of zt_tm1 with P0_0m1 as a initial condition - // and with P_{t+1|t} as the last element. Thus, we can use it as a base-1 cell. - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // March 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-T. - TSdcell *Ht_dc; //ny-by-nz-by-T. - TSdcell *Rt_dc; //ny-by-ny-by-T. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-T. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-T. - TSdcell *Ft_dc; //nz-by-nz-by-T. - TSdcell *Vt_dc; //nz-by-nz-by-T. Covariance matrix for the state equation. - // - TSdvector *z0_dv; //nz-by-1; - TSdmatrix *P0_dm; //nz-by-nz. - - //=== Output arguments. - double loglh; //log likelihood. - TSdmatrix *zt_tm1_dm; //nz-by-T. - TSdcell *Pt_tm1_dc; //nz-by-nz-T. - } TSkalfiltv; - - - - //=== Inputs for filter for Markov-switching DSGE models at any time t. - typedef struct TSkalfilmsinputs_1stapp_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on the grand regime s_t that follows a Markov-chain process - // and is taken as given, and - // eps(t) = Psi_u(t)*u(t), where Psi_u(t) is n_y-by-n_u and u(t) is n_u-by-1; - // eta(t) = Psi_e(t)*e(t), where Psi_e(t) is n_z-by-n_e and e(t) is n_e-by-1. - // - // Inputs at time t are as follows where nst is number of grand regimes (including lagged regime - // and coefficients and shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nst matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nst 3-D of Markov-switching matrices in the measurement equation. - // Psi_u is an n_y-by-n_u-by-nst 3-D Markov-switching matrices. - // R is an n_y-by-n_y-by-nst 3-D of Markov-switching covariance matrices, - // E(eps(t) * eps(t)') = Psi_u(t)*Psi_u(t)', for the error in the measurement equation. - // G is an n_z-by-n_y-by-nst 3-D of Markov-switching E(eta_t * eps_t') = Psi_e(t)*Psi_u(t)'. - // ------ - // b is an n_z-by-nst matrix of Markov-switching input vectors in the state equation with b(:,st) as an initial condition. - // (alternatively, with the ergodic weighted b(:,st) as an initial condition). - // F is an n_z-by-n_z-by-nst 3-D of Markov-switching transition matrices in the state equation with F(:,:,st) - // as an initial condition (alternatively, with the ergodic weighted F(:,:,st) as an initial condition). - // Psi_e is an n_z-by-n_e-by-nst 3-D Markov-switching matrices. - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices, - // E(eta(t)*eta(t)') = Psi_e(t)*Psi_e(t)', for the error in the state equation - // with V(:,:,st) as an initial condition (alternatively, with the ergodic weighted V(:,:,st) as an initial condition). - // ------ - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nst matrix of initial condition (Not used if indxIni=0). - // P0 is an n_z-by-n_z-by-nst 3-D of initial condition (Not used if indxIni=0). - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,st))\b(:,st) - // vec(P0_0m1) = (I-kron(F(:,:,st),F(:,:,st)))\vec(V(:,:,st)) - // Note that all eigenvalues of the matrix F(:,:,st) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha. Revised, April 2008. - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nu; //number of measurement errors. - int ne; //number of fundamental errors. - int nst; //number of grand composite regimes (current and past regimes, coefficient and volatility regimes). - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0, - //0: using the unconditional momnets for any given regime at time 0 (default when indxDiffuse = 0). - int indxDiffuse; //1: using the diffuse condition for z_{1|0} and P_{1|0} (default option), according to Koopman and Durbin, "Filtering and Smoothing of State Vector for Diffuse State-Space Models," J. of Time Series Analysis, Vol 24(1), pp.85-99. - //0: using the unconditional moments. - double DiffuseScale; //A large (infinity) number when indxDiffuse = 1. - int ztm1_track; //t-1 = -1: no initial conditions z_{1|0} and P_{1|0} has been computed yet, but will be using InitializeKalman_z10_P10(), - //t-1 >= 0:T-1: z_{t|t-1} and P_{t|t-1} are updated up to t-1. - int dtm1_track; //t-1 = -1: no etdata_dc->C[0] or Dtdata_d4->F[0] has been computed yet. - //t-1 >= 0:T-1: etdata_dc->C[t-1] and Dtdata_d4->F[t-1] are updated up to t-1. - - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nst. - TSdcell *Ht_dc; //ny-by-nz-by-nst. - TSdcell *Psiut_dc; //ny-by-nu-by-nst. Measurement error coefficient matrix. - TSdcell *Rt_dc; //ny-by-ny-by-nst. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nst. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nst. - TSdcell *Ft_dc; //nz-by-nz-by-nst. - TSdcell *Psiet_dc; //nz-by-ne-by-nst. Impact matrix in the state equation. - TSdcell *Vt_dc; //nz-by-nz-by-nst. Covariance matrix for the state equation. - // - TSdmatrix *z0_0_dm; //nz-by-nst. z_{0|0}. - TSdmatrix *z0_dm; //nz-by-nst. z_{1|0}. - TSdcell *P0_dc; //nz-by-nz-by-nst. P_{1|0} - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nst-by-(T+1), where z_{1|0} is an initial condition (1st element with t-1=0 or t=1 for base-1) and - // the terminal condition z_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, z_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nst-by-(T+1), where P_{1|0} is an initial condition (1st element with t-1=0) and - // the terminal condition P_{T+1|T} using Updatekalfilms_1stapp(T, ...) is not computed - // when the likelihood logTimetCondLH_kalfilms_1stapp() is computed. Thus, P_{T+1|T} - // has not legal value computed in most applications unless in out-of-sample forecasting problems. - //+ Will be save for updating likelihood and Kalman filter Updatekalfilms_1stapp(), so save time to recompute these objects again. - TSdfourth *PHtran_tdata_d4; //nz-by-ny-by-nst-T, P_{t|t-1}*H_t'. Saved only for updating Kalman filter Updatekalfilms_1stapp(). - TSdcell *etdata_dc; //ny-by-nst-by-T (with base-0 T), forecast errors e_t in the likelihood. - TSdcell *yt_tm1_dc; //ny-by-nst-by-T, one-step forecast y_{t|t-1} for t=0 to T-1 (base-0). Incorrect now (Used to back out structural shocks). - TSdfourth *Dtdata_d4; //ny-by-ny-nst-by-T, forecast covariance D_t in the likelihood. Saved for updating Kalman filter Updatekalfilms_1stapp(). - } TSkalfilmsinputs_1stapp; - - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - //~~~ OLD Code: Inputs for filter for Markov-switching DSGE models at any time t. - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - typedef struct TSkalfilmsinputs_tag - { - //Inputs Markov-switching Kalman filter for DSGE models (conditional on all the regimes at time t). - // It computes a sequence of one-step predictions and their covariance matrices, and the log likelihood. - // The function uses a forward recursion algorithm. See also the Matlab function fn_kalfil_tv.m - // - // State space model is defined as follows: - // y(t) = a(t) + H(t)*z(t) + eps(t) (observation or measurement equation) - // z(t) = b(t) + F(t)*z(t) + eta(t) (state or transition equation) - // where a(t), H(t), b(t), and F(t) depend on s_t that follows a Markov-chain process and are taken as given. - // - // Inputs at time t are as follows where nRc is number of regimes for coefficients - // nRv is number of regimes for volatility (shock variances): - // Y_T is a n_y-by-T matrix containing data [y(1), ... , y(T)]. - // a is an n_y-by-nRc matrix of Markov-switching input vectors in the measurement equation. - // H is an n_y-by-n_z-by-nRc 3-D of Markov-switching matrices in the measurement equation. - // R is an n_y-by-n_y-by-nRv 3-D of Markov-switching covariance matrices for the error in the measurement equation. - // G is an n_z-by-n_y-by-nRv 3-D of Markov-switching E(eta_t * eps_t'). - // ------ - // b is an n_z-by-nRc matrix of Markov-switching input vectors in the state equation with b(:,1) as an initial condition. - // F is an n_z-by-n_z-by-nRc 3-D of Markov-switching transition matrices in the state equation with F(:,:,1) as an initial condition. - // V is an n_z-by-n_z-by-nRv 3-D of Markov-switching covariance matrices for the error in the state equation with V(:,:,1) as an initial condition. - // ------ - // indxIndRegimes: 1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - // indxIni: 1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - // 0: using the unconditional mean for any given regime at time 0. - // z0 is an n_z-by-nRc*nRv matrix of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // z0 is an n_z-by-nRv matrix of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRc*nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=1. (Not used if indxIni=0.) - // P0 is an n_z-by-n_z-by-nRv 3-D of initial condition when indxIni=1 and indxIndRegimes=0. (Not used if indxIni=0.) - // - // The initial state vector and its covariance matrix are computed under the bounded (stationary) condition: - // z0_0m1 = (I-F(:,:,1))\b(:,1) - // vec(P0_0m1) = (I-kron(F(:,:,1),F(:,:,1)))\vec(V(:,:,1)) - // Note that all eigenvalues of the matrix F(:,:,1) are inside the unit circle when the state-space model is bounded (stationary). - // - // November 2007, written by Tao Zha - // See Hamilton's book ([13.2.13] -- [13.2.22]), Harvey (pp.100-106), and LiuWZ Model I NOTES pp.001-003. - - //=== Input arguments. - int ny; //number of observables. - int nz; //number of state variables. - int nRc; //number of composite regimes (current and past regimes) for coefficients. - int nRstc; //number of coefficient regimes at time t. - int nRv; //number of regimes for volatility (shock variances). - int indxIndRegimes; //1: coefficient regime and volatility regime are independent; 0: these two regimes are synchronized completely. - int T; //sample size. - int indxIni; //1: using the initial condition with zt_tm1(:,1)=z0 and Pt_tm1(:,:,1)=P0; - //0: using the unconditional mean for any given regime at time 0. (Default value) - TSdmatrix *yt_dm; //ny-by-T. - TSdmatrix *at_dm; //ny-by-nRc. - TSdcell *Ht_dc; //ny-by-nz-by-nRc. - TSdcell *Rt_dc; //ny-by-ny-by-nRv. Covariance matrix for the measurement equation. - TSdcell *Gt_dc; //nz-by-ny-by-nRv. Cross-covariance. - // - TSdmatrix *bt_dm; //nz-by-nRc. - TSdcell *Ft_dc; //nz-by-nz-by-nRc. - TSdcell *Vt_dc; //nz-by-nz-by-nRv. Covariance matrix for the state equation. - // - TSdmatrix *z0_dm; //nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nRv if indxIndRegimes == 0. - TSdcell *P0_dc; //nz-by-nz-by-nRc*nRv if indxIndRegimes == 1 or nz-by-nz-by-nRv if indxIndRegimes == 0. - - - //=== Output arguments only used for 1st order approximation to zt and Pt depending on infinite past regimes. - TSdcell *zt_tm1_dc; //nz-by-nRc*nRv-by-T if indxIndRegimes==1, nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - TSdfourth *Pt_tm1_d4; //nz-by-nz-by-nRc*nRv-T if indxIndRegimes==1, nz-by-nz-by-nRv-by-T if indxIndRegimes==0 where nRc=nRv. - } TSkalfilmsinputs; - - - - - //--- Functions for univariate random walk kalman filter. - TSkalcvfurw *CreateTSkalcvfurw(TFlearninguni *func, int T, int k, int tv); //, int storeZ, int storeV); - TSkalcvfurw *DestroyTSkalcvfurw(TSkalcvfurw *kalcvfurw_ps); - void kalcvf_urw(TSkalcvfurw *kalcvfurw_ps, void *dummy_ps); - - //--- New Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp2(int ny, int nz, int nu, int ne, int nst, int T); - struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp2(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); - struct TSkalfilmsinputs_1stapp_tag *CreateTSkalfilmsinputs_1stapp(int ny, int nz, int nst, int T); - struct TSkalfilmsinputs_1stapp_tag *DestroyTSkalfilmsinputs_1stapp(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps); - int InitializeKalman_z10_P10(struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, TSdmatrix *z10_dm, TSdcell *P10_dc); - double logTimetCondLH_kalfilms_1stapp(int st, int inpt, struct TSkalfilmsinputs_1stapp_tag *kalfilmsinputs_1stapp_ps, struct TStateModel_tag *smodel_ps); - - - - //--- OLD Code: Functions for general constant Kalman filter. - struct TSkalfiltv_tag *CreateTSkalfiltv(int ny, int nz, int T); - struct TSkalfiltv_tag *DestroyTSkalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - //Used to test tz_logTimetCondLH_kalfiltv(). (Done April 08). double tz_kalfiltv(struct TSkalfiltv_tag *kalfiltv_ps); - double tz_logTimetCondLH_kalfiltv(int st, int inpt, struct TSkalfiltv_tag *kalfiltv_ps); - - //--- OLD Code: Functions for Markov-switching Kalman filter. - struct TSkalfilmsinputs_tag *CreateTSkalfilmsinputs(int ny, int nz, int nRc, int nRstc, int nRv, int indxIndRegimes, int T); - struct TSkalfilmsinputs_tag *DestroyTSkalfilmsinputs(struct TSkalfilmsinputs_tag *kalfilmsinputs_ps); - double tz_logTimetCondLH_kalfilms_1st_approx(int st, int inpt, struct TSkalfilmsinputs_tag *kalfilmsinputs_ps, struct TStateModel_tag *smodel_ps); - //IMPORTANT NOTE: in the Markov-switching input file datainp_markov*.prn, it MUST be that - // the coefficient regime is the 1st state variable, and - // the volatility regime is the 2nd state variable. -#endif - diff --git a/CFiles/mathlib.c b/CFiles/mathlib.c old mode 100755 new mode 100644 index 8bf1c40cdd0ae6052d2e6bb73070b00171462171..2dafff104d4b1c1183ddabc7f853a772bc41652f --- a/CFiles/mathlib.c +++ b/CFiles/mathlib.c @@ -1,5 +1,8 @@ #include "mathlib.h" +// Undefine to see all MKL error messages +#define MKL_QUIET MKL_QUIET + //======================================================= // LAPACK routines -- all based on Intel MKL (or IMSL C Math library) //======================================================= @@ -628,8 +631,12 @@ int BdivA_rrect(TSdmatrix *X_dm, const TSdmatrix *B_dm, const char lr, const TSd //=== Multiplies a real matrix by the orthogonal matrix Q of the QR factorization formed by dgeqp3. work_p = tzMalloc(lwork=_r*BLOCKSIZE_FOR_INTEL_MKL, double); dormqr("L","T",&_m,&_r,&_n,qra_p,&_m,tau_p,qrb_p,&_m,work_p,&lwork,&info); + +#ifndef MKL_QUIET if (work_p[0]>lwork) printf("Warning for /mathlib.c/BdivA_rrect(); when calling MKL dormqr(), we need at least %d workspace for good performance " "but lwork is allocated with only %d space!\n", (int)work_p[0], lwork); +#endif + //dormqr("L","T",&_m,&_r,&mn_min,qra_p,&_m,tau_p,qrb_p,&mn_max,work_p,&lwork,&info); tzDestroy(work_p) if (info) return (info); //If info==0, the execution is successful; if info == -i, the ith parameter has an illegal value. @@ -979,12 +986,11 @@ double logdetspd(TSdmatrix *S_dm) else if (S_dm->flag & M_SL) errflag=chol(Work_dm, S_dm, 'L'); else fn_DisplayError(".../mathlib.c/logdetspd(): Input matrix S_dm must be either M_SU or M_SL"); - if (errflag) { //printf("\nFatal Error in .../mathlib.c/logdetspd() when calling chol() with error flag %d\n", errflag); //exit(EXIT_FAILURE); DestroyMatrix_lf(Work_dm); - printf("\n----- errflag for chol() when calling logdetspd() in mathlib.c = %d -----\n", errflag); + printf("----- errflag for chol() when calling logdetspd() in mathlib.c = %d -----", errflag); return (log(-1.0)); } else @@ -1637,8 +1643,7 @@ void MatrixPlusMinusMatrixUpdate(TSdmatrix *X_dm, TSdmatrix *A_dm, double _alpha void MatrixTimesVector(TSdvector *x_dv, TSdmatrix *A_dm, const TSdvector *b_dv, const double _alpha, const double _beta, const char tn) { - //WARNING: x_dv must NOT be the same as b_dv! - // + //????? This is NOT checked yet: If x_dv = b_dv, x_dv or b_dv will be relaced by alpha*A*x + beta*x. //Output: x_dv = _alpha*A_dm'*b_dv + _beta*x_dv for tn=='T'; x_dv = _alpha*A_dm*b_dv + _beta*x_dv for tn=='N' // where x_dv->v is ncols-by-1 or nrows-by-1 and needs not be initialized outside this function if _beta is set to 0.0. //Inputs: @@ -2342,7 +2347,7 @@ void ElementwiseInverseofMatrix(TSdmatrix *Y_dm, TSdmatrix *X_dm) if ( ((nrows=X_dm->nrows) != Y_dm->nrows) || ((ncols=X_dm->ncols) != Y_dm->ncols) ) fn_DisplayError(".../mathlib.c/ElementwiseInverseofMatrix(): Dimensions of both input and output matrices must be same"); X = X_dm->M; Y = Y_dm->M; - for (_i=_nrows*ncols-1; _i>=0; _i--) Y[_i] = 1.0/X[_i]; + for (_i=nrows*ncols-1; _i>=0; _i--) Y[_i] = 1.0/X[_i]; Y_dm->flag = M_GE; } #endif @@ -3895,7 +3900,7 @@ void CopySubrowmatrix(TSdmatrix *x1_dm, const int br1, const int bc1, TSdmatrix else fn_DisplayError(".../mathlib.c/CopySubrowmatrix(): the submatrix of x2_dm must be within the range of itself as well as x1_dm"); } #else - Haven't got time to code up the default using Linux BLAS. +printf("Have not got time to code up the default using Linux BLAS."); exit(0); #endif @@ -3929,7 +3934,7 @@ void CopySubmatrix2rowmatrix(TSdmatrix *x1_dm, const int br1, const int bc1, TSd else fn_DisplayError(".../mathlib.c/CopySubmatrix2rowmatrix(): the submatrix of x2_dm must be within the range of x2_dm and its transpose must be within the range of x1_dm"); } #else - Haven't got time to code up the default using Linux BLAS. +printf("Have not got time to code up the default using Linux BLAS."); exit(0); #endif @@ -3964,7 +3969,7 @@ void CopySubrowmatrix2matrix(TSdmatrix *x1_dm, const int br1, const int bc1, TSd else fn_DisplayError(".../mathlib.c/CopySubrowmatrix2matrix(): the submatrix of x2_dm must be within the range of itself as well as x1_dm"); } #else - Haven't got time to code up the default using Linux BLAS. +printf("Have not got time to code up the default using Linux BLAS."); exit(0); #endif @@ -4207,7 +4212,7 @@ void CopySubvector2rowmatrix(TSdmatrix *x1_dm, const int br, const int bc, const else fn_DisplayError(".../mathlib.c/CopySubvector2rowmatrix(): Copying (copied) elements are outside the (row) dimension of the copying vector x2_dv (the copied matrix x1_dm)"); } #else - Haven't got time to code up the default using Linux BLAS. +printf("Have not got time to code up the default using Linux BLAS."); exit(0); #endif diff --git a/CFiles/mathlib.h b/CFiles/mathlib.h old mode 100755 new mode 100644 index fc5371872d9194965cfded5414a9e124ca28430c..4db819580b18d7fe7dce0d5fe5b0af34776f54c5 --- a/CFiles/mathlib.h +++ b/CFiles/mathlib.h @@ -102,7 +102,7 @@ // A_dm: m-by-n general or symmetric matrix. // _alpha: double scalar. void MatrixTimesVector(TSdvector *x_dv, TSdmatrix *A_dm, const TSdvector *b_dv, const double _alpha, const double _beta, const char tn); - //WARNING: x_dv must NOT be the same as b_dv! + //????? This is NOT checked yet: If x_dv = b_dv, x_dv or b_dv will be relaced by alpha*A*x + beta*x. //Output: x_dv->v = _alpha*A_dm'*b_dv + _beta*x_dv for tn=='T'; x_dv = _alpha*A_dm*b_dv + _beta*x_dv for tn=='N' // where x_dv->v is ncols-by-1 or nrows-by-1 and needs not be initialized if _beta is set to 0.0. //Inputs: diff --git a/CFiles/numgradgenTemplate.c b/CFiles/numgradgenTemplate.c deleted file mode 100755 index 31130c371f6b98b0fdcdb4e9ece11b99c71642bd..0000000000000000000000000000000000000000 --- a/CFiles/numgradgenTemplate.c +++ /dev/null @@ -1,83 +0,0 @@ -/* For the general purpose numerical gradient.This source file (function) must be *manually* copied to a specific subdirectory (another source file). - * Before copying this file, there are a few lines that must be *manually* changed, marked by CCCCCCCCC: - * (1) The .h file to be included. - * (2) T_tag in the typedef. - * (3) T_tag in the declaration of the structure. -*/ -#include "swz_comfuns.h" //CCCCCCCCC. - - -typedef double TFgradfcn(struct T_tag *); //CCCCCCCCC. -//------------------------------- -// Modified from gradcd_gen() in cstz.c for the general purpose. -//------------------------------- -#define STPS 1.0e-04 // 6.0554544523933391e-6 step size = pow(DBL_EPSILON,1.0/3) -void numgrad_cd(void *Snotype_ps) -{ - /* The no-type structure Snotype_ps must contain the output and input arguments with the *exact* names. */ - //Outputs: - // grad_dv: the gradient n-by-1 g (no need to be initialized). - //Inputs: - // xg_dv: the n-by-1 vector point at which the gradient is evaluated. No change in the end although will be added or substracted by dh during the function (but in the end the original value will be put back). - // fcn_grad(struct T_tag *): the function for which the gradient is evaluated - // grdh: step size. If 0.0, then dh is set automatically; otherwise, grdh is taken as a step size, often set as 1.0e-004. - // fatx: the value of (*fcn_grad)(xg_dv). NOT used in this function except dealing with the boundary (NEARINFINITY) for the - // minimization problem, but to be compatible with a genral function call where, say, a forward-difference method or cubic - // interpolation of central difference method will use f0. - - //double *g, double *x, int n, double (*fcn)(double *x, int n), double *grdh, double f0) - - //--- Essential elments from the structure S_ps. - struct T_tag *S_ps = (T_tag *)Snotype_ps; //CCCCCCCCC. - int n = S_ps->grad_dv->n; - double *g = S_ps->grad_dv->v; - double *x = S_ps->xg_dv->v; - TFgradfcn *fcn = S_ps->fcn_grad; - double grdh = S_ps->grdh; - double f0 = S_ps->fatx; //At the original point x. - //--- Local to this function only. - int i; - double dh, dhi, dh2i, fp, fm, tmp, *xp; - - - if (grdh != 0.0) { - dh2i = (dhi=1.0/(dh=grdh))/2.0; - for (i=0, xp=x; i<n; i++, xp++, g++) { - tmp = *xp; - *xp += dh; - //The following statement is bad because dh does not get reset at the beginning of the loop and thus may get changed continually within the loop. - // dh = *xp - tmp; // This increases the precision slightly. - fp = fcn(S_ps); //At the point x+dh. - *xp = tmp - dh; - fm = fcn(S_ps); //At the point x-dh. - - //=== Checking the boundary condition for the minimization problem. - if (fp >= NEARINFINITY) *g = (f0-fm)*dhi; - else if (fm >= NEARINFINITY) *g = (fp-f0)*dhi; - else *g = (fp-fm)*dh2i; - - *xp = tmp; // Put the original value of x[i] back to x[i] so that the content x[i] is still unaltered. - } - - } - else { - for (i=0, xp=x; i<n; i++, xp++, g++) { - dh = fabs(*xp)<=1 ? STPS : STPS*(*xp); - tmp = *xp; - *xp += dh; - dh = *xp - tmp; // This increases the precision slightly. - fp = fcn(S_ps); //At the point x+dh. - *xp = tmp - dh; - fm = fcn(S_ps); //At the point x-dh. - - //=== Checking the boundary condition for the minimization problem. - if (fp >= NEARINFINITY) *g = (f0-fm)/dh; - else if (fm >= NEARINFINITY) *g = (fp-f0)/dh; - else *g = (fp-fm)/(2.0*dh); - - *xp = tmp; // Put the original value of x[i] back to x[i] so that the content x[i] is still unaltered. - } - } -} -#undef STPS - diff --git a/CFiles/optpackage.c b/CFiles/optpackage.c old mode 100755 new mode 100644 index e52975edd0cbdae066e4ec4a242eb149671ac724..efd85215c5c576f37b43e4eb495ba75f3c9fdb54 --- a/CFiles/optpackage.c +++ b/CFiles/optpackage.c @@ -108,6 +108,7 @@ TSminpack *DestroyTSminpack(TSminpack *minpack_ps) static TSetc_csminwel *CreateTSetc_csminwel(FILE *fptr_input1, const int n, const int q, const int k) { //If fptr_input1==NULL or no no values supplied when fptr_input1 != NULL, default values are taken. + int _i; //=== TSetc_csminwel *etc_csminwel_ps = tzMalloc(1, TSetc_csminwel); @@ -401,7 +402,6 @@ void InitializeForMinproblem(struct TSminpack_tag *minpack_ps, char *filename_sp } /**/ //------- Step 3. ------- -#if defined (NEWVERSIONofDW_SWITCH) void minfinder_blockcsminwel(struct TSminpack_tag *minpack_ps, int indx_findMLE) { //Better version (November 2007) @@ -462,8 +462,7 @@ void minfinder_blockcsminwel(struct TSminpack_tag *minpack_ps, int indx_findMLE) //---- Refreshing the parameters outside this function. TZ October 2007. SetupObjectiveFunction(smodel_ps, x1_pd, x2_pd, x_dv->v); - //--- minpack_ps->fret0 has to be initialized using InitializeForMinproblem() in the main function. - logvalue = -( minpack_ps->fret = PosteriorObjectiveFunction(x_dv->v, x_dv->n) ); //Refreshing. logPosterirPdf. DW function. + logvalue = -( minpack_ps->fret0 = minpack_ps->fret = PosteriorObjectiveFunction(x_dv->v, x_dv->n) ); //Refreshing. logPosterirPdf. DW function. fprintf(FPTR_OPT, "\n=========== Beginning Blockwise and Overall csminwel Minimizations =======================\nLog Peak Value: %.16e\n", logvalue); fflush(FPTR_OPT); @@ -598,7 +597,7 @@ void minfinder_blockcsminwel(struct TSminpack_tag *minpack_ps, int indx_findMLE) DestroyMatrix_lf(H2_dm); DestroyMatrix_lf(H_dm); } -#endif + //----------------------------------------------------- // Minimization csminwel for the constant parameter model only. 5/24/04. @@ -801,17 +800,22 @@ void minfinder_noblockimslconlin(struct TSpackage_imslconlin_tag *package_imslco CopyVector0(package_imslconlin_ps->xsaved_dv, XIMSL_DV); //+ SetModelGlobalForIMSLconlin(smodel_ps); - if (imsl_d_min_con_gen_lin(ObjFuncForModel_imslconlin, x_dv->n, package_imslconlin_ps->ncons, package_imslconlin_ps->neqs, - package_imslconlin_ps->ncons ? package_imslconlin_ps->lh_coefs_dv->v : NULL, - package_imslconlin_ps->ncons ? package_imslconlin_ps->rh_constraints_dv->v : NULL, - package_imslconlin_ps->lowbounds_dv->v, package_imslconlin_ps->upperbounds_dv->v, - IMSL_XGUESS, xguess_dv->v, IMSL_GRADIENT, gradcd_imslconlin, - IMSL_MAX_FCN, package_imslconlin_ps->itmax, IMSL_OBJ, &minpack_ps->fret, - IMSL_TOLERANCE, package_imslconlin_ps->crit, IMSL_RETURN_USER, x_dv->v, 0)) - { - printf("\nFinished: IMSL linearly-constrained optimization is successfully finished with the value of obj. fun.: %.16e\n", minpack_ps->fret); - } - else printf("\nWarning: IMSL linearly-constrained optimization fails, so the results from csminwel and congramin are used.\n"); + + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + //if (imsl_d_min_con_gen_lin(ObjFuncForModel_imslconlin, x_dv->n, package_imslconlin_ps->ncons, package_imslconlin_ps->neqs, + // package_imslconlin_ps->lh_coefs_dv->v, + // package_imslconlin_ps->rh_constraints_dv->v, + // package_imslconlin_ps->lowbounds_dv->v, package_imslconlin_ps->upperbounds_dv->v, + // IMSL_XGUESS, xguess_dv->v, IMSL_GRADIENT, gradcd_imslconlin, + // IMSL_MAX_FCN, package_imslconlin_ps->itmax, IMSL_OBJ, &minpack_ps->fret, + // IMSL_TOLERANCE, package_imslconlin_ps->crit, IMSL_RETURN_USER, x_dv->v, 0)) + //{ + // printf("\nFinished: IMSL linearly-constrained optimization is successfully finished with the value of obj. fun.: %.16e\n", minpack_ps->fret); + //} + //else printf("\nWarning: IMSL linearly-constrained optimization fails, so the results from csminwel and congramin are used.\n"); printf("\n===Ending the IMSL constrained optimization===\n"); //=== Printing out messages indicating that IMSL has bugs. diff --git a/CFiles/optpackage.h b/CFiles/optpackage.h old mode 100755 new mode 100644 index 5215390889707fd8a04ca50061050a93a4113a11..088d99cb0e2fca42f3e916924993bf151ecec580 --- a/CFiles/optpackage.h +++ b/CFiles/optpackage.h @@ -20,7 +20,7 @@ #include "congradmin.h" #include "fn_filesetup.h" //fn_SetFilePosition(), etc. #include "mathlib.h" //CopyVector0(), etc. -#include "switch_opt.h" //DW's optimization routines for Markov-switching models. +#include "dw_switch_opt.h" //DW's optimization routines for Markov-switching models. #include "cstz.h" //Used for gradcd_gen() only in the IMSL linear constrainted problem. //-------------- Attributes for selecting optimization packages. -------------- @@ -242,10 +242,9 @@ struct TSetc_minproj_tag *DestroyTSetc_minproj(struct TSetc_minproj_tag *); //--- //void InitializeForMinproblem(struct TSminpack_tag *minpack_ps, char *filename_sp, TSdvector *gphi_dv, int indxStartValuesForMin); //=== Step 3. -#if defined (NEWVERSIONofDW_SWITCH) void minfinder_blockcsminwel(struct TSminpack_tag *minpack_ps, int indx_findMLE); //Blockwise minimization. //indx_findMLE: 1: find MLE without a prior, 0: find posterior (with a prior). -#endif + diff --git a/CFiles/rand.c b/CFiles/rand.c old mode 100755 new mode 100644 index 397fbbe9f1667149aa6f3bf40d411c100c185af7..1c7306aad935c17c3c81fb96062a0524b88849ef --- a/CFiles/rand.c +++ b/CFiles/rand.c @@ -276,7 +276,8 @@ double StandardNormalDouble(void) { double x; imsls_d_random_normal(1, IMSLS_RETURN_USER, &x, 0); return x; - #else CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. + #else + // CASE2_RANDOMNUMBERGENERATOR Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. return gaussrnd(); #endif } @@ -289,7 +290,8 @@ double LogNormalDouble(double mean, double std) double x; imsls_d_random_lognormal(1, mean, std, IMSLS_RETURN_USER, &x, 0); return x; - #else CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. + #else + // CASE2_RANDOMNUMBERGENERATOR Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. fn_DisplayError(".../rand.c/LogNormalDouble(): NO defaul available for log normal draws"); return (0); #endif @@ -305,7 +307,8 @@ double GammaDouble(const double a, const double b) { imsls_d_random_gamma(1, a, IMSLS_RETURN_USER, &x, 0); if (b != 1.0) x *= b; return x; - #else CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. + #else + // CASE2_RANDOMNUMBERGENERATOR Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. return ( (b==1.0) ? gammrnd(a) : b*gammrnd(a) ); #endif } @@ -416,7 +419,8 @@ void GammaMatrix(TSdmatrix *X_dm, TSdmatrix *A_dm, TSdmatrix *B_dm) { } X_dm->flag = M_GE; - #else CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. + #else + //CASE2_RANDOMNUMBERGENERATOR Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. int _i, nels, nrows, ncols; double *X, *A, *B; @@ -452,7 +456,8 @@ double ChisquareDouble(const double v) { double x; imsls_d_random_chi_squared(1, v, IMSLS_RETURN_USER, &x, 0); return x; - #else CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. + #else + // CASE2_RANDOMNUMBERGENERATOR Imported from the C recipe book -- Case 2 and my own (Iskander) code for generating a gamma distribution. return ( 2.0*gammrnd(0.5*v) ); #endif } diff --git a/CFiles/rand.h b/CFiles/rand.h old mode 100755 new mode 100644 diff --git a/CFiles/template_proj.vcproj b/CFiles/template_proj.vcproj deleted file mode 100755 index ab4cb30ae2fedebea4bdd82ab1d6cc9e2633fa67..0000000000000000000000000000000000000000 --- a/CFiles/template_proj.vcproj +++ /dev/null @@ -1,376 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="template_proj" - ProjectGUID="{30EA1610-6051-4681-A29C-9D29389FE60F}" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="Debug" - IntermediateDirectory="Debug" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="1" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="4" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="2" - IgnoreAllDefaultLibraries="false" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib;libcmtd.lib" - GenerateDebugInformation="true" - SubSystem="1" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="Release" - IntermediateDirectory="Release" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - InlineFunctionExpansion="2" - EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" - OmitFramePointers="true" - EnableFiberSafeOptimizations="false" - WholeProgramOptimization="false" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" - StringPooling="true" - RuntimeLibrary="0" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="1" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib" - GenerateDebugInformation="false" - SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" - > - <File - RelativePath="..\..\..\TZCcode\csminwel.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\..\TZCcode\cstz.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\..\TZCcode\DWMatrixCode\switch\estimate.c" - > - </File> - <File - RelativePath="..\..\..\TZCcode\DWMatrixCode\extern_dw_switch_var_est.c" - > - </File> - <File - RelativePath="..\..\..\TZCcode\fn_filesetup.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\..\TZCcode\mathlib.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\..\TZCcode\rand.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\..\TZCcode\tzmatlab.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)/$(InputName)1.obj" - /> - </FileConfiguration> - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc" - > - <File - RelativePath=".\resource.h" - > - </File> - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" - > - </Filter> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_iblas.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_scalar.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat_iblas.lib" - > - </File> - <File - RelativePath="..\..\..\..\Program Files\Microsoft Visual Studio 8\VC\lib\libcmt.lib" - > - </File> - <File - RelativePath="..\..\Program Files\Microsoft Visual Studio 8\VC\lib\libcmtd.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\8.1\ia32\lib\libguide40.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\8.1\ia32\lib\mkl_c.lib" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/CFiles/template_proj2.vcproj b/CFiles/template_proj2.vcproj deleted file mode 100755 index 4f4a33c93c4104784ee6ed71de382be5d61b9d52..0000000000000000000000000000000000000000 --- a/CFiles/template_proj2.vcproj +++ /dev/null @@ -1,291 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="9.00" - Name="template_proj2" - ProjectGUID="{30EA1610-6051-4681-A29C-9D29389FE60F}" - Keyword="Win32Proj" - TargetFrameworkVersion="131072" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="Debug" - IntermediateDirectory="Debug" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="1" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="false" - DebugInformationFormat="4" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="2" - IgnoreAllDefaultLibraries="false" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib;libcmtd.lib" - GenerateDebugInformation="true" - SubSystem="1" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="Release" - IntermediateDirectory="Release" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - InlineFunctionExpansion="2" - EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" - OmitFramePointers="true" - EnableFiberSafeOptimizations="true" - WholeProgramOptimization="false" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" - StringPooling="true" - RuntimeLibrary="0" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="false" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="1" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib" - GenerateDebugInformation="false" - SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" - > - <File - RelativePath="D:\ZhaData\TZCcode\congradmin.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\csminwel.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\cstz.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\DWMatrixCode\extern_dw_switch.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\fn_filesetup.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\gensys.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\gradcd_switch.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\kalman.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\mathlib.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\optpackage.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\rand.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\tzmatlab.c" - > - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc" - > - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" - > - </Filter> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_iblas.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_scalar.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat_iblas.lib" - > - </File> - <File - RelativePath="C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\libcmt.lib" - > - </File> - <File - RelativePath="C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\libcmtd.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\9.0\ia32\lib\libguide.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\9.0\ia32\lib\mkl_c.lib" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/CFiles/template_proj2_MKL8.0.vcproj b/CFiles/template_proj2_MKL8.0.vcproj deleted file mode 100755 index 14d59cce04c151f7b13b1042d4733e3e01b29e29..0000000000000000000000000000000000000000 --- a/CFiles/template_proj2_MKL8.0.vcproj +++ /dev/null @@ -1,296 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="template_proj2" - ProjectGUID="{30EA1610-6051-4681-A29C-9D29389FE60F}" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="Debug" - IntermediateDirectory="Debug" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="1" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="4" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="2" - IgnoreAllDefaultLibraries="false" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib;libcmtd.lib" - GenerateDebugInformation="true" - SubSystem="1" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="Release" - IntermediateDirectory="Release" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - InlineFunctionExpansion="2" - EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" - OmitFramePointers="true" - EnableFiberSafeOptimizations="false" - WholeProgramOptimization="false" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" - StringPooling="true" - RuntimeLibrary="0" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="1" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib" - GenerateDebugInformation="false" - SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" - > - <File - RelativePath="D:\ZhaData\TZCcode\congradmin.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\csminwel.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\cstz.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\DWMatrixCode\extern_dw_switch.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\fn_filesetup.c" - > - </File> - <File - RelativePath="D:\ZhaData\\TZCcode\gradcd_switch.c" - > - </File> - <File - RelativePath=".\hyper_est.c" - > - </File> - <File - RelativePath="D:\ZhaData\\TZCcode\kalman.c" - > - </File> - <File - RelativePath="D:\ZhaData\\TZCcode\mathlib.c" - > - </File> - <File - RelativePath="D:\ZhaData\\TZCcode\optpackage.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\rand.c" - > - </File> - <File - RelativePath="..\swz2_comfuns.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\tzmatlab.c" - > - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc" - > - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" - > - </Filter> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_iblas.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_scalar.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat_iblas.lib" - > - </File> - <File - RelativePath="D:\Program Files\Microsoft Visual Studio 8\VC\lib\libcmt.lib" - > - </File> - <File - RelativePath="D:\Program Files\Microsoft Visual Studio 8\VC\lib\libcmtd.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\8.1\ia32\lib\libguide40.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\8.1\ia32\lib\mkl_c.lib" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/CFiles/template_proj2_MSV2005_MKL9.0.vcproj b/CFiles/template_proj2_MSV2005_MKL9.0.vcproj deleted file mode 100755 index 3b7f01c6aeb3a00a4450efb885627006a68f0c1e..0000000000000000000000000000000000000000 --- a/CFiles/template_proj2_MSV2005_MKL9.0.vcproj +++ /dev/null @@ -1,292 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="template_proj2" - ProjectGUID="{30EA1610-6051-4681-A29C-9D29389FE60F}" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="Debug" - IntermediateDirectory="Debug" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="1" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="4" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="2" - IgnoreAllDefaultLibraries="false" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib;libcmtd.lib" - GenerateDebugInformation="true" - SubSystem="1" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="Release" - IntermediateDirectory="Release" - ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops" - CharacterSet="2" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - InlineFunctionExpansion="2" - EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" - OmitFramePointers="true" - EnableFiberSafeOptimizations="false" - WholeProgramOptimization="false" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" - StringPooling="true" - RuntimeLibrary="0" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="3" - CompileAs="1" - DisableSpecificWarnings="4996" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib" - LinkIncremental="1" - IgnoreDefaultLibraryNames="libcd.lib;libc.lib" - GenerateDebugInformation="false" - SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" - > - <File - RelativePath="D:\ZhaData\TZCcode\congradmin.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\csminwel.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\cstz.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\DWMatrixCode\extern_dw_switch.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\fn_filesetup.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\gradcd_switch.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\gensys.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\kalman.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\mathlib.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\optpackage.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\rand.c" - > - </File> - <File - RelativePath="D:\ZhaData\TZCcode\tzmatlab.c" - > - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc" - > - </Filter> - <Filter - Name="Resource Files" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" - > - </Filter> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_iblas.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcmath_scalar.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat.lib" - > - </File> - <File - RelativePath="C:\Program Files\VNI\imsl\cnl600\vs05pc\lib\imslcstat_iblas.lib" - > - </File> - <File - RelativePath="D:\Program Files\Microsoft Visual Studio 8\VC\lib\libcmt.lib" - > - </File> - <File - RelativePath="D:\Program Files\Microsoft Visual Studio 8\VC\lib\libcmtd.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\9.0\ia32\lib\libguide40.lib" - > - </File> - <File - RelativePath="C:\Program Files\Intel\MKL\9.0\ia32\lib\mkl_c.lib" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/CFiles/tzmatlab.c b/CFiles/tzmatlab.c old mode 100755 new mode 100644 diff --git a/CFiles/tzmatlab.h b/CFiles/tzmatlab.h old mode 100755 new mode 100644 index 5c7c2d285027289e91d09afecbd27804f93633eb..6171e53ad56cff29f566b4fbcbba76efcec54c6f --- a/CFiles/tzmatlab.h +++ b/CFiles/tzmatlab.h @@ -1,326 +1,7 @@ -/********* - * _cv: Pointer to TScvector (character vector). - * _iv: Pointer to TSivector (integer vector). - * _im: Pointer to TSimatrix (integer matrix). - * _dv: Pointer to TSdvector (double vector). - * _dm: Pointer to TSdmatrix (double matrix). - * _dc: Pointer to TSdcell (double cell -- pointer to pointer to a matrix). - * _dcv: Pointer to TSdcellvec (double cell -- pointer to pointer to a vector). - * _d4: Pointer to TSdfourth (double fourth dimension -- pointer to pointer to pointer to a matrix). - * _dzv: Pointer to TSdzvector (double complex vector). - * _dzm: Pointer to TSdzmatrix (double complex matrix). - * - * _s: structure variable. - * _ps: pointer to a structure. - * _sv: an array of structures. - * - * _sdv: structure (NOT pointer to structure) that contains TSdvector. - * _sdm: structure (NOT pointer to structure) that contains TSdmatrix. - * - * ???????? OLD NOTATIONS ?????????? - * _v: C row or column vector pointer. - * _vint: C row or column vector pointer to integer. - * _m: C matrix pointer. - * _mint: C matrix pointer to integer. - * _m3: C 3-D matrix pointer. - * _ppm: C pointer to pointer to a matrix. - * d_???_ppm: the number of pointers that are pointed to by _ppm. - * rv_???_ppm: a vector (with dimension d_???_ppm) pointer of numbers of rows, each of the numbers coresponding to a pointed matrix. - * cv_???_ppm: a vector (with dimension d_???_ppm) pointer of numbers of columns, each of the numbers coresponding to a pointed matrix. - * d_???_v: dimension size. - * r_???_m: numbers of rows. - * c_???_m: number of columns. - * r_???_m3: number of rows. - * c_???_m3: number of columns. - * t_???_m3: number of a third dimension. -*********/ - - -#ifndef __TZMATLAB__ -#define __TZMATLAB__ - #define _ISOC99_SOURCE //Using C99 features for gcc or icc on Linux. Must be placed as the first line above all #include lines. - - #include <stdio.h> - #include <stdlib.h> // For rand(), size_t, exit, malloc, free, qsort, EXIT_FAILURE. - #include <memory.h> //For memcpy, etc. Alternative: string.h - #include <math.h> //For isfinite. - #include <float.h> //For DBL_MIN, etc. - #include <time.h> //For time(), etc. - - - - //#include "mkl_cblas.h" // Intel MKL C Blas library. - #include "mkl.h" //This includes mkl_cblas.h and mkl_lapack.h. - #include <imsl.h> //IMSL math package. - #include <imsls.h> //IMSL statistical package. - - #define USE_DEBUG_FILE //When defined, one must use tzFopen to give the file name in the main .c file. - extern FILE *FPTR_DEBUG; //For debugging. Applied to all functions and all .c files that call tzmatlab.h. - //Initiated to NULL in tzmatlab.c. - //Must use tzFopen to give the file name in the main .c file. - extern FILE *FPTR_OPT; //For recording the optimization intermediate results. - //Applied to minfinder_blockcsminwel() in optpackage.c. - //Initiated to NULL in tzmatlab.c. - //Must use tzFopen to give the file name in the main .c file. - - #define NEWVERSIONofDW_SWITCH //If defined, using DW's new switch program (implemented in 2008), - // which may be incompatible with previous programs, such as ...\SargentWZ2\EstProbModel\EstimationJuly07USED - //If undef, using the old, working switch program for, say, ...\SargentWZ2\EstProbModel\EstimationJuly07USED. - //Files that are affected are: cstz.c, kalman.c, optpackage.c, - - - #define SWITCHTOIMSLCMATH // define: use IMSL special functions like gammlog; undef: use my own default code if it exists. - - //-------Only one of the following for math library.-------- - #define INTELCMATHLIBRARY // define: use Intel MKL LAPACK library; undef: use others. - //#define IMSLCMATHLIBRARY // define: use IMSL C Math library; undef: use others. - //#define MATLABCMATHLIBRARY // define: use Matlab C math library; undef: use others. - - //-------Only one of the following for math library.-------- - #define SWITCHTOINTELCMATH // define: use Intel MKL LAPACK library; undef: use others. - //#define SWITCHTOTZCMATH // define: use my own C math library; undef: use others. - - //-------Only one of the following for optimization routines except that CG?_ and CSMINWEL_ can be chosen together.-------- - //#define IMSL_OPTIMIZATION // IMSL optimization routines. - #define CSMINWEL_OPTIMIZATION //Sims's optimization routine. - #define CGI_OPTIMIZATION //Polak-Ribiere conjugate gradient method without using derivative information in performing the line minimization. - //NOT available yet! #define CGII_OPTIMIZATION //NOT available yet! Pletcher-Reeves conjugate gradient method using derivative information in performing the line minimization. - - //-------Only one of the following for random number generating routines.-------- - #define IMSL_RANDOMNUMBERGENERATOR // IMSL random number generator. - //#define CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- case 2 and my own (Iskander) code for generating a gamma distribution. - - //-------Only one of the following statistical packages.-------- - #define IMSL_STATISTICSTOOLBOX // IMSL statistical package. - - - - //-------If define: use matlab API interface; otherwise (undef), use C console. - #undef WIN_MATLABAPI // define: use matlab API interface; undef: use C dos console. - - - //--------------- - #ifdef MATLABCMATHLIBRARY - #include "matlab.h" // For all mlf???? functions. - #include "matrix.h" // For mxGetM, mxCreatDoubleMatrix, etc. - #endif - #ifdef WIN_MATLABAPI // define: use matlab API interface; undef: use C dos console. - #include "mex.h" // For all mex??? calls. Matlab API (application program interface or external interface). - #define printf mexPrintf - #define malloc mxMalloc - #define calloc mxCalloc - #define free mxFree - #endif - - - //-------------- Attributes for the real double matrix type TSdmatrix. -------------- - //-------------- Whenever a matrix is initialized, the default is M_GE, but nothing else. -------------- - #define M_UNDEF 0 //0 or NULL: No attribute will be given when memory is allocated but no values are initialized. - #define M_GE 0x0001 //1: A general matrix. - #define M_SU 0x0002 //2: A symmetric (must be square) matrix but only the upper triangular part is referenced. - #define M_SL 0x0004 //4: A symmetric (must be square) matrix but only the lower triangular part is referenced. - #define M_UT 0x0008 //8: A upper triangular (trapezoidal if nrows < ncols) matrix but only the upper triangular part is referenced. - #define M_LT 0x0010 //16: A lower triangular (trapezoidal if nrows > ncols) matrix but only the lower triangular part is referenced. - #define M_CN 0x0020 //32: A constant (CN) matrix (All elements are the same or no (N) change from one to another). -// #define M_UTU 0x0040 //2^6: An unit upper triangular matrix. -// #define M_LTU 0x0080 //2^7: An unit lower triangular matrix. - //-------------- Attributes for the real double vector type TSdvector or the character vector type TScvector. -------------- - #define V_UNDEF 0 //Zero or NULL: No values have been assigned to the double vector. - #define V_DEF 1 //True: Values have been assigned to the double vector. - - - //-------------- Other macro definitions. -------------- - #define BLOCKSIZE_FOR_INTEL_MKL 128 //A machine-dependent value (typically, 16 to 64) required for optimum performance of the blocked algorithm in Intel MKL. - #define NEARINFINITY 1.0E+300 - #define BIGREALNUMBER 1.0E+30 - #define MACHINEZERO DBL_MIN - #define EPSILON DBL_EPSILON //1.0E-015. In Standard C, DBL_EPSILON = 2.2204460492503131 - #define SQRTEPSILON 1.490116119384766E-008 //1.0E-15. In Standard C, DBL_EPSILON = 2.2204460492503131E-016 - #define SQRTMACHINEZERO 1.490116119384766E-008 - //This is really not correct, because this number is sqrt(epsion), where DBL_MIN is around 1.0e-300. - #define MACHINEINFINITY DBL_MAX - #define MACHINE_EXP_INFINITY DBL_MAX_EXP - #define EXP_NEARINFINITY 1000 - //=== - #define TZ_TRUE 1 - #define TZ_FALSE 0 - - - - //--------------- - #define tzMalloc(elt_count, type) (type *)m_alloc((elt_count)*sizeof(type)) - #define tzCalloc(elt_count, type) (type *)c_alloc((elt_count), sizeof(type)) - #define tzDestroy(x) {if ((x)) { \ - free((x)); \ - (x) = NULL; \ - }} - #define tzFclose(x) {if ((x)) { \ - fclose((x)); \ - (x) = (FILE *)NULL; \ - }} - #define mos(i, j, nrows) ((j)*(nrows)+(i)) //i: ith row; j: jth column; nrows: number of rows for the matrix. - //Offset(os) for a matrix(m) in column major order and with base 0. See Reek pp.241-242. - #define square(x) ((x) * (x)) //Must be careful to avoid using, say, square(tmpd=2) or square(++x). - #define _max(a, b) ((a)>(b) ? (a) : (b)) // Macro max or __max is already defined in stdlib.h in MS visual C++, but mex.h may overwrite the max macro so we use _max. - #define _min(a, b) ((a)>(b) ? (b) : (a)) - #define swap(a, b, stemp) {(stemp)=(a); (a)=(b); (b)=(stemp);} - // - #ifndef isfinite - #define isfinite(x) _finite(x) //_finite is for Microsoft C++ compiler only (in float.h, which strangely is not ANSI compible), - // All these Microsoft functions are not yet C99 compatible. - #endif - //--- The following does not work. - // #ifndef FP_NAN - // #define FP_NAN _FPCLASS_SNAN //_FPCLASS_SNAN is for Microsoft C++ compiler only (in float.h, which strangely is not ANSI compible), - // // All these Microsoft functions are not yet C99 compatible. - // #endif - #define isdiagonalmatrix(x) (((x)->flag & (M_UT | M_LT)) == (M_UT | M_LT)) //x is the tz type of matrix. - // - #define DestroyDatesVector_lf(x) DestroyVector_lf(x) - - - //--------------- - typedef struct TScvector_tag - { - char *v; //v: vector. - int n; - int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. - } TScvector; - typedef struct TSvoidvector_tag - { - void *v; //v: vector. - int n; - int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. - } TSvoidvector; - typedef struct { - int *v; //v: vector. - int n; - int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. - } TSivector; - typedef struct { - int *M; //M: matrix. - int nrows, ncols; - int flag; //flag: Refers to M_GE, M_SU, M_SL, M_UT, and M_LT in tzmatlab.h. - } TSimatrix; - typedef struct { - TSivector **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. - int ncells; //Number of pointers (cells) to pointer. - } TSicellvec; - typedef struct { - TSimatrix **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. - int ncells; //Number of pointers (cells) to pointer. - } TSicell; - //=== Real types. - typedef struct { - double *v; //v: vector. - int n; - int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. - } TSdvector; - typedef struct { - double *M; //M: matrix. - int nrows, ncols; - int flag; //flag: Refers to M_GE, M_SU, M_SL, M_UT, and M_LT in tzmatlab.h. - } TSdmatrix; - typedef struct { - TSdmatrix **C; //ncells-by-1 cells (C) and a pointer to matrix in each cell. - int ncells; //Number of pointers (cells) to pointer. - } TSdcell; - typedef struct { - TSdvector **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. - int ncells; //Number of pointers (cells) to pointer. - } TSdcellvec; - typedef struct { - TSdcell **F; //ndims-by-1 fourths (F) and a pointer to cell in each fourth. - int ndims; //Number of pointers (fourth dimensions) to pointer. - } TSdfourth; - typedef struct { - TSdcellvec **F; //ndims-by-1 fourths (F) and a pointer to cellvec in each fourth. - int ndims; //Number of pointers (fourth dimensions) to pointer. - } TSdfourthvec; - //=== Complex types. - typedef struct { - TSdvector *real; //Real part. - TSdvector *imag; //Imaginary part. - } TSdzvector; - typedef struct { - TSdmatrix *real; //Real part. - TSdmatrix *imag; //Imaginary part. - } TSdzmatrix; - - - - //----------------- Some high-level functions. ----------------- - int fn_locofyearqm(int q_m, int yrstart, int qmstart, int yrend, int qmend); - - - - - //--------------- - void fn_DisplayError(char *msg_s); - void *m_alloc(size_t size); - void *c_alloc(size_t elt_count, size_t elt_size); - - /** - TSvoidvector *CreateVector_void(int _n); - TSvoidvector *DestroyVector_void(TSvoidvector *x_voidv); - /**/ - - TScvector *CreateVector_c(int _n); - TScvector *DestroyVector_c(TScvector *x_s); - TSivector *CreateVector_int(int _n); - TSivector *DestroyVector_int(TSivector *x_iv); - TSimatrix *CreateMatrix_int(int nrows, int ncols); - TSimatrix *DestroyMatrix_int(TSimatrix *x_im); - TSicellvec *CreateCellvec_int(TSivector *n_iv); - TSicellvec *DestroyCellvec_int(TSicellvec *x_icv); - TSicell *CreateCell_int(TSivector *row_iv, TSivector *col_iv); - TSicell *DestroyCell_int(TSicell *x_ic); - - TSdvector *CreateVector_lf(int _n); - TSdvector *DestroyVector_lf(TSdvector *x_iv); - TSdmatrix *CreateMatrix_lf(int nrows, int ncols); - TSdmatrix *DestroyMatrix_lf(TSdmatrix *x_im); - TSdcell *CreateCell_lf(TSivector *row_iv, TSivector *col_iv); - TSdcell *DestroyCell_lf(TSdcell *x_dc); - TSdcellvec *CreateCellvec_lf(TSivector *n_iv); - TSdcellvec *DestroyCellvec_lf(TSdcellvec *x_dcv); - TSdfourth *CreateFourth_lf(int ndims, TSivector *row_iv, TSivector *col_iv); - TSdfourth *DestroyFourth_lf(TSdfourth *x_d4); - TSdfourthvec *CreateFourthvec_lf(int ndims, TSivector *n_iv); - TSdfourthvec *DestroyFourthvec_lf(TSdfourthvec *x_d4v); - - TSdzvector *CreateVector_dz(int _n); - TSdzvector *DestroyVector_dz(TSdzvector *x_dzv); - TSdzmatrix *CreateMatrix_dz(int nrows, int ncols); - TSdzmatrix *DestroyMatrix_dz(TSdzmatrix *x_dzm); - - //+ - TSdmatrix *CreateZeroMatrix_lf(const int nrows, const int ncols); - TSdmatrix *CreateIdentityMatrix_lf(const int nrows, const int ncols); - //TSdvector *CreateZerosVector_lf(int _n); - TSivector *CreateConstantVector_int( const int _n, const int _k); - TSimatrix *CreateConstantMatrix_int(const int nrows, const int ncols, const int _n); - TSicellvec *CreateConstantCellvec_int(TSivector *n_iv, const int _n); - TSicell *CreateConstantCell_int(TSivector *row_iv, TSivector *col_iv, const int _n); - TSdvector *CreateConstantVector_lf(const int _n, const double _alpha); - TSdmatrix *CreateConstantMatrix_lf(const int nrows, const int ncols, const double _alpha); - TSdcellvec *CreateConstantCellvec_lf(TSivector *n_iv, const double _alpha); - TSdcell *CreateConstantCell_lf(TSivector *row_iv, TSivector *col_iv, const double _alpha); - TSdvector *CreateDatesVector_lf(int nq_m, int yrstart, int qmstart, int yrend, int qmend); - //+ - void InitializeConstantVector_lf(TSdvector *x_dv, const double _alpha); - void InitializeConstantVector_int(TSivector *x_iv, const int _k); - void InitializeConstantMatrix_lf(TSdmatrix *x_dm, const double _alpha); - void InitializeDiagonalMatrix_lf(TSdmatrix *x_dm, const double _alpha); - void InitializeConstantMatrix_int(TSimatrix *x_dm, const int _alpha); - void InitializeConstantCellvec_lf(TSdcellvec *x_dcv, const double _alpha); - void InitializeConstantCell_lf(TSdcell *x_dc, const double _alpha); - void InitializeConstantFourthvec_lf(TSdfourthvec *x_d4v, const double _alpha); - void InitializeConstantFourth_lf(TSdfourth *x_d4, const double _alpha); - - - void NegateColofMatrix_lf(TSdvector *y_dv, TSdmatrix *x_dm, int _j); - void InitializeConstantColofMatrix_lf(TSdmatrix *X_dm, int jx, double _alpha); - - FILE *tzFopen(char *filename, char *mode); -#endif + +// Use this for tao's orginal code +#include "tzmatlab_tao.h" + + +// Use this for dan's version of the code +//#include "tzmatlab_dw.h" diff --git a/CFiles/tzmatlab_dw.h b/CFiles/tzmatlab_dw.h new file mode 100644 index 0000000000000000000000000000000000000000..0d2449ae007127c9da3503d1bf202a61c322ffea --- /dev/null +++ b/CFiles/tzmatlab_dw.h @@ -0,0 +1,363 @@ +/********* + * _cv: Pointer to TScvector (character vector). + * _iv: Pointer to TSivector (integer vector). + * _im: Pointer to TSimatrix (integer matrix). + * _dv: Pointer to TSdvector (double vector). + * _dm: Pointer to TSdmatrix (double matrix). + * _dc: Pointer to TSdcell (double cell -- pointer to pointer to a matrix). + * _dcv: Pointer to TSdcellvec (double cell -- pointer to pointer to a vector). + * _d4: Pointer to TSdfourth (double fourth dimension -- pointer to pointer to pointer to a matrix). + * _dzv: Pointer to TSdzvector (double complex vector). + * _dzm: Pointer to TSdzmatrix (double complex matrix). + * + * _s: structure variable. + * _ps: pointer to a structure. + * _sv: an array of structures. + * + * _sdv: structure (NOT pointer to structure) that contains TSdvector. + * _sdm: structure (NOT pointer to structure) that contains TSdmatrix. + * + * ???????? OLD NOTATIONS ?????????? + * _v: C row or column vector pointer. + * _vint: C row or column vector pointer to integer. + * _m: C matrix pointer. + * _mint: C matrix pointer to integer. + * _m3: C 3-D matrix pointer. + * _ppm: C pointer to pointer to a matrix. + * d_???_ppm: the number of pointers that are pointed to by _ppm. + * rv_???_ppm: a vector (with dimension d_???_ppm) pointer of numbers of rows, each of the numbers coresponding to a pointed matrix. + * cv_???_ppm: a vector (with dimension d_???_ppm) pointer of numbers of columns, each of the numbers coresponding to a pointed matrix. + * d_???_v: dimension size. + * r_???_m: numbers of rows. + * c_???_m: number of columns. + * r_???_m3: number of rows. + * c_???_m3: number of columns. + * t_???_m3: number of a third dimension. +*********/ + + +#ifndef __TZMATLAB__ +#define __TZMATLAB__ + #define _ISOC99_SOURCE //Using C99 features for gcc or icc on Linux. Must be placed as the first line above all #include lines. + + #include <stdio.h> + #include <stdlib.h> // For rand(), size_t, exit, malloc, free, qsort, EXIT_FAILURE. + #include <memory.h> //For memcpy, etc. Alternative: string.h + #include <math.h> //For isfinite. + #include <float.h> //For DBL_MIN, etc. + #include <time.h> //For time(), etc. + + + #define USE_DEBUG_FILE //When defined, one must use tzFopen to give the file name in the main .c file. + extern FILE *FPTR_DEBUG; //For debugging. Applied to all functions and all .c files that call tzmatlab.h. + //Initiated to NULL in tzmatlab.c. + //Must use tzFopen to give the file name in the main .c file. + extern FILE *FPTR_OPT; //For recording the optimization intermediate results. + //Applied to minfinder_blockcsminwel() in optpackage.c. + //Initiated to NULL in tzmatlab.c. + //Must use tzFopen to give the file name in the main .c file. + +/*******************************************************************************/ +/* Added by DW 9/1/08 */ +/*******************************************************************************/ +//#define USE_IMSL_MATH_LIBRARY +//#define USE_IMSL_STAT_LIBRARY +#define USE_GSL_LIBRARY +#define USE_MKL_LIBRARY +/*******************************************************************************/ + +// #define NEWVERSIONofDW_SWITCH //If defined, using DW's new switch program (implemented in 2008), + // which may be incompatible with previous programs, such as ...\SargentWZ2\EstProbModel\EstimationJuly07USED + //If undef, using the old, working switch program for, say, ...\SargentWZ2\EstProbModel\EstimationJuly07USED. + //Files that are affected are: cstz.c, kalman.c, optpackage.c, + + + #define SWITCHTOIMSLCMATH // define: use IMSL special functions like gammlog; undef: use my own default code if it exists. + + //-------Only one of the following for math library.-------- + #define INTELCMATHLIBRARY // define: use Intel MKL LAPACK library; undef: use others. + //#define IMSLCMATHLIBRARY // define: use IMSL C Math library; undef: use others. + //#define MATLABCMATHLIBRARY // define: use Matlab C math library; undef: use others. + + //-------Only one of the following for math library.-------- + #define SWITCHTOINTELCMATH // define: use Intel MKL LAPACK library; undef: use others. + //#define SWITCHTOTZCMATH // define: use my own C math library; undef: use others. + + //-------Only one of the following for optimization routines except that CG?_ and CSMINWEL_ can be chosen together.-------- + //#define IMSL_OPTIMIZATION // IMSL optimization routines. + #define CSMINWEL_OPTIMIZATION //Sims's optimization routine. + #define CGI_OPTIMIZATION //Polak-Ribiere conjugate gradient method without using derivative information in performing the line minimization. + //NOT available yet! #define CGII_OPTIMIZATION //NOT available yet! Pletcher-Reeves conjugate gradient method using derivative information in performing the line minimization. + + //-------Only one of the following for random number generating routines.-------- + #define IMSL_RANDOMNUMBERGENERATOR // IMSL random number generator. + //#define CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- case 2 and my own (Iskander) code for generating a gamma distribution. + + //-------Only one of the following statistical packages.-------- + #define IMSL_STATISTICSTOOLBOX // IMSL statistical package. + +/*******************************************************************************/ +/* Added by DW 9/1/08 */ +/*******************************************************************************/ +#if defined(USE_MKL_LIBRARY) + #include "mkl.h" +#else + #if defined (USE_GSL_LIBRARY) + #include "gsl_cblas.h" + #endif + #include "blas_lapack.h" + #undef SWITCHTOINTELCMATH + #undef INTELCMATHLIBRARY +#endif + +#if defined(USE_GSL_LIBRARY) + #include "gsl_sf_gamma.h" + #include "gsl_cdf.h" +#endif + +#if defined(USE_IMSL_MATH_LIBRARY) + #include <imsl.h> //IMSL math package. + #include <imsls.h> //IMSL statistical package. +#else + #undef IMSL_OPTIMIZATION + #undef SWITCHTOIMSLCMATH + #undef IMSL_OPTIMIZATION + #undef IMSL_RANDOMNUMBERGENERATOR +#endif + +#if defined(USE_IMSL_STAT_LIBRARY) + #include <imsls.h> //IMSL statistical package. +#else + #undef IMSL_STATISTICSTOOLBOX +#endif +/*******************************************************************************/ + + //-------If define: use matlab API interface; otherwise (undef), use C console. + #undef WIN_MATLABAPI // define: use matlab API interface; undef: use C dos console. + + + //--------------- + #ifdef MATLABCMATHLIBRARY + #include "matlab.h" // For all mlf???? functions. + #include "matrix.h" // For mxGetM, mxCreatDoubleMatrix, etc. + #endif + #ifdef WIN_MATLABAPI // define: use matlab API interface; undef: use C dos console. + #include "mex.h" // For all mex??? calls. Matlab API (application program interface or external interface). + #define printf mexPrintf + #define malloc mxMalloc + #define calloc mxCalloc + #define free mxFree + #endif + + + //-------------- Attributes for the real double matrix type TSdmatrix. -------------- + //-------------- Whenever a matrix is initialized, the default is M_GE, but nothing else. -------------- + #define M_UNDEF 0 //0 or NULL: No attribute will be given when memory is allocated but no values are initialized. + #define M_GE 0x0001 //1: A general matrix. + #define M_SU 0x0002 //2: A symmetric (must be square) matrix but only the upper triangular part is referenced. + #define M_SL 0x0004 //4: A symmetric (must be square) matrix but only the lower triangular part is referenced. + #define M_UT 0x0008 //8: A upper triangular (trapezoidal if nrows < ncols) matrix but only the upper triangular part is referenced. + #define M_LT 0x0010 //16: A lower triangular (trapezoidal if nrows > ncols) matrix but only the lower triangular part is referenced. + #define M_CN 0x0020 //32: A constant (CN) matrix (All elements are the same or no (N) change from one to another). +// #define M_UTU 0x0040 //2^6: An unit upper triangular matrix. +// #define M_LTU 0x0080 //2^7: An unit lower triangular matrix. + //-------------- Attributes for the real double vector type TSdvector or the character vector type TScvector. -------------- + #define V_UNDEF 0 //Zero or NULL: No values have been assigned to the double vector. + #define V_DEF 1 //True: Values have been assigned to the double vector. + + + //-------------- Other macro definitions. -------------- + #define BLOCKSIZE_FOR_INTEL_MKL 128 //A machine-dependent value (typically, 16 to 64) required for optimum performance of the blocked algorithm in Intel MKL. + #define NEARINFINITY 1.0E+300 + #define BIGREALNUMBER 1.0E+30 + #define MACHINEZERO DBL_MIN + #define EPSILON DBL_EPSILON //1.0E-015. In Standard C, DBL_EPSILON = 2.2204460492503131 + #define SQRTEPSILON 1.490116119384766E-008 //1.0E-15. In Standard C, DBL_EPSILON = 2.2204460492503131E-016 + #define SQRTMACHINEZERO 1.490116119384766E-008 + //This is really not correct, because this number is sqrt(epsion), where DBL_MIN is around 1.0e-300. + #define MACHINEINFINITY DBL_MAX + #define MACHINE_EXP_INFINITY DBL_MAX_EXP + #define EXP_NEARINFINITY 1000 + //=== + #define TZ_TRUE 1 + #define TZ_FALSE 0 + + + + //--------------- + #define tzMalloc(elt_count, type) (type *)m_alloc((elt_count)*sizeof(type)) + #define tzCalloc(elt_count, type) (type *)c_alloc((elt_count), sizeof(type)) + #define tzDestroy(x) {if ((x)) { \ + free((x)); \ + (x) = NULL; \ + }} + #define tzFclose(x) {if ((x)) { \ + fclose((x)); \ + (x) = (FILE *)NULL; \ + }} + #define mos(i, j, nrows) ((j)*(nrows)+(i)) //i: ith row; j: jth column; nrows: number of rows for the matrix. + //Offset(os) for a matrix(m) in column major order and with base 0. See Reek pp.241-242. + #define square(x) ((x) * (x)) //Must be careful to avoid using, say, square(tmpd=2) or square(++x). + #define _max(a, b) ((a)>(b) ? (a) : (b)) // Macro max or __max is already defined in stdlib.h in MS visual C++, but mex.h may overwrite the max macro so we use _max. + #define _min(a, b) ((a)>(b) ? (b) : (a)) + #define swap(a, b, stemp) {(stemp)=(a); (a)=(b); (b)=(stemp);} + // + #ifndef isfinite + #define isfinite(x) _finite(x) //_finite is for Microsoft C++ compiler only (in float.h, which strangely is not ANSI compible), + // All these Microsoft functions are not yet C99 compatible. + #endif + //--- The following does not work. + // #ifndef FP_NAN + // #define FP_NAN _FPCLASS_SNAN //_FPCLASS_SNAN is for Microsoft C++ compiler only (in float.h, which strangely is not ANSI compible), + // // All these Microsoft functions are not yet C99 compatible. + // #endif + #define isdiagonalmatrix(x) (((x)->flag & (M_UT | M_LT)) == (M_UT | M_LT)) //x is the tz type of matrix. + // + #define DestroyDatesVector_lf(x) DestroyVector_lf(x) + + + //--------------- + typedef struct TScvector_tag + { + char *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TScvector; + typedef struct TSvoidvector_tag + { + void *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TSvoidvector; + typedef struct { + int *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TSivector; + typedef struct { + int *M; //M: matrix. + int nrows, ncols; + int flag; //flag: Refers to M_GE, M_SU, M_SL, M_UT, and M_LT in tzmatlab.h. + } TSimatrix; + typedef struct { + TSivector **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSicellvec; + typedef struct { + TSimatrix **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSicell; + //=== Real types. + typedef struct { + double *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TSdvector; + typedef struct { + double *M; //M: matrix. + int nrows, ncols; + int flag; //flag: Refers to M_GE, M_SU, M_SL, M_UT, and M_LT in tzmatlab.h. + } TSdmatrix; + typedef struct { + TSdmatrix **C; //ncells-by-1 cells (C) and a pointer to matrix in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSdcell; + typedef struct { + TSdvector **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSdcellvec; + typedef struct { + TSdcell **F; //ndims-by-1 fourths (F) and a pointer to cell in each fourth. + int ndims; //Number of pointers (fourth dimensions) to pointer. + } TSdfourth; + typedef struct { + TSdcellvec **F; //ndims-by-1 fourths (F) and a pointer to cellvec in each fourth. + int ndims; //Number of pointers (fourth dimensions) to pointer. + } TSdfourthvec; + //=== Complex types. + typedef struct { + TSdvector *real; //Real part. + TSdvector *imag; //Imaginary part. + } TSdzvector; + typedef struct { + TSdmatrix *real; //Real part. + TSdmatrix *imag; //Imaginary part. + } TSdzmatrix; + + + + //----------------- Some high-level functions. ----------------- + int fn_locofyearqm(int q_m, int yrstart, int qmstart, int yrend, int qmend); + + + + + //--------------- + void fn_DisplayError(char *msg_s); + void *m_alloc(size_t size); + void *c_alloc(size_t elt_count, size_t elt_size); + + /** + TSvoidvector *CreateVector_void(int _n); + TSvoidvector *DestroyVector_void(TSvoidvector *x_voidv); + /**/ + + TScvector *CreateVector_c(int _n); + TScvector *DestroyVector_c(TScvector *x_s); + TSivector *CreateVector_int(int _n); + TSivector *DestroyVector_int(TSivector *x_iv); + TSimatrix *CreateMatrix_int(int nrows, int ncols); + TSimatrix *DestroyMatrix_int(TSimatrix *x_im); + TSicellvec *CreateCellvec_int(TSivector *n_iv); + TSicellvec *DestroyCellvec_int(TSicellvec *x_icv); + TSicell *CreateCell_int(TSivector *row_iv, TSivector *col_iv); + TSicell *DestroyCell_int(TSicell *x_ic); + + TSdvector *CreateVector_lf(int _n); + TSdvector *DestroyVector_lf(TSdvector *x_iv); + TSdmatrix *CreateMatrix_lf(int nrows, int ncols); + TSdmatrix *DestroyMatrix_lf(TSdmatrix *x_im); + TSdcell *CreateCell_lf(TSivector *row_iv, TSivector *col_iv); + TSdcell *DestroyCell_lf(TSdcell *x_dc); + TSdcellvec *CreateCellvec_lf(TSivector *n_iv); + TSdcellvec *DestroyCellvec_lf(TSdcellvec *x_dcv); + TSdfourth *CreateFourth_lf(int ndims, TSivector *row_iv, TSivector *col_iv); + TSdfourth *DestroyFourth_lf(TSdfourth *x_d4); + TSdfourthvec *CreateFourthvec_lf(int ndims, TSivector *n_iv); + TSdfourthvec *DestroyFourthvec_lf(TSdfourthvec *x_d4v); + + TSdzvector *CreateVector_dz(int _n); + TSdzvector *DestroyVector_dz(TSdzvector *x_dzv); + TSdzmatrix *CreateMatrix_dz(int nrows, int ncols); + TSdzmatrix *DestroyMatrix_dz(TSdzmatrix *x_dzm); + + //+ + TSdmatrix *CreateZeroMatrix_lf(const int nrows, const int ncols); + TSdmatrix *CreateIdentityMatrix_lf(const int nrows, const int ncols); + //TSdvector *CreateZerosVector_lf(int _n); + TSivector *CreateConstantVector_int( const int _n, const int _k); + TSimatrix *CreateConstantMatrix_int(const int nrows, const int ncols, const int _n); + TSicellvec *CreateConstantCellvec_int(TSivector *n_iv, const int _n); + TSicell *CreateConstantCell_int(TSivector *row_iv, TSivector *col_iv, const int _n); + TSdvector *CreateConstantVector_lf(const int _n, const double _alpha); + TSdmatrix *CreateConstantMatrix_lf(const int nrows, const int ncols, const double _alpha); + TSdcellvec *CreateConstantCellvec_lf(TSivector *n_iv, const double _alpha); + TSdcell *CreateConstantCell_lf(TSivector *row_iv, TSivector *col_iv, const double _alpha); + TSdvector *CreateDatesVector_lf(int nq_m, int yrstart, int qmstart, int yrend, int qmend); + //+ + void InitializeConstantVector_lf(TSdvector *x_dv, const double _alpha); + void InitializeConstantVector_int(TSivector *x_iv, const int _k); + void InitializeConstantMatrix_lf(TSdmatrix *x_dm, const double _alpha); + void InitializeDiagonalMatrix_lf(TSdmatrix *x_dm, const double _alpha); + void InitializeConstantMatrix_int(TSimatrix *x_dm, const int _alpha); + void InitializeConstantCellvec_lf(TSdcellvec *x_dcv, const double _alpha); + void InitializeConstantCell_lf(TSdcell *x_dc, const double _alpha); + void InitializeConstantFourthvec_lf(TSdfourthvec *x_d4v, const double _alpha); + void InitializeConstantFourth_lf(TSdfourth *x_d4, const double _alpha); + + + void NegateColofMatrix_lf(TSdvector *y_dv, TSdmatrix *x_dm, int _j); + void InitializeConstantColofMatrix_lf(TSdmatrix *X_dm, int jx, double _alpha); + + FILE *tzFopen(char *filename, char *mode); +#endif diff --git a/CFiles/tzmatlab_tao.h b/CFiles/tzmatlab_tao.h new file mode 100644 index 0000000000000000000000000000000000000000..e8da1ac75ec89f031c686cafa8fdd03968c0ebaf --- /dev/null +++ b/CFiles/tzmatlab_tao.h @@ -0,0 +1,359 @@ +/********* + * _cv: Pointer to TScvector (character vector). + * _iv: Pointer to TSivector (integer vector). + * _im: Pointer to TSimatrix (integer matrix). + * _dv: Pointer to TSdvector (double vector). + * _dm: Pointer to TSdmatrix (double matrix). + * _dc: Pointer to TSdcell (double cell -- pointer to pointer to a matrix). + * _dcv: Pointer to TSdcellvec (double cell -- pointer to pointer to a vector). + * _d4: Pointer to TSdfourth (double fourth dimension -- pointer to pointer to pointer to a matrix). + * _dzv: Pointer to TSdzvector (double complex vector). + * _dzm: Pointer to TSdzmatrix (double complex matrix). + * + * _s: structure variable. + * _ps: pointer to a structure. + * _sv: an array of structures. + * + * _sdv: structure (NOT pointer to structure) that contains TSdvector. + * _sdm: structure (NOT pointer to structure) that contains TSdmatrix. + * + * ???????? OLD NOTATIONS ?????????? + * _v: C row or column vector pointer. + * _vint: C row or column vector pointer to integer. + * _m: C matrix pointer. + * _mint: C matrix pointer to integer. + * _m3: C 3-D matrix pointer. + * _ppm: C pointer to pointer to a matrix. + * d_???_ppm: the number of pointers that are pointed to by _ppm. + * rv_???_ppm: a vector (with dimension d_???_ppm) pointer of numbers of rows, each of the numbers coresponding to a pointed matrix. + * cv_???_ppm: a vector (with dimension d_???_ppm) pointer of numbers of columns, each of the numbers coresponding to a pointed matrix. + * d_???_v: dimension size. + * r_???_m: numbers of rows. + * c_???_m: number of columns. + * r_???_m3: number of rows. + * c_???_m3: number of columns. + * t_???_m3: number of a third dimension. +*********/ + + +#ifndef __TZMATLAB__ +#define __TZMATLAB__ + #define _ISOC99_SOURCE //Using C99 features for gcc or icc on Linux. Must be placed as the first line above all #include lines. + + #include <stdio.h> + #include <stdlib.h> // For rand(), size_t, exit, malloc, free, qsort, EXIT_FAILURE. + #include <memory.h> //For memcpy, etc. Alternative: string.h + #include <math.h> //For isfinite. + #include <float.h> //For DBL_MIN, etc. + #include <time.h> //For time(), etc. + + + #define USE_DEBUG_FILE //When defined, one must use tzFopen to give the file name in the main .c file. + extern FILE *FPTR_DEBUG; //For debugging. Applied to all functions and all .c files that call tzmatlab.h. + //Initiated to NULL in tzmatlab.c. + //Must use tzFopen to give the file name in the main .c file. + extern FILE *FPTR_OPT; //For recording the optimization intermediate results. + //Applied to minfinder_blockcsminwel() in optpackage.c. + //Initiated to NULL in tzmatlab.c. + //Must use tzFopen to give the file name in the main .c file. + +/*******************************************************************************/ +/* Added by DW 9/1/08 */ +/*******************************************************************************/ +//#define USE_IMSL_MATH_LIBRARY +//#define USE_IMSL_STAT_LIBRARY +#define USE_GSL_LIBRARY +#define USE_MKL_LIBRARY +/*******************************************************************************/ + + #define NEWVERSIONofDW_SWITCH //If defined, using DW's new switch program (implemented in 2008), + // which may be incompatible with previous programs, such as ...\SargentWZ2\EstProbModel\EstimationJuly07USED + //If undef, using the old, working switch program for, say, ...\SargentWZ2\EstProbModel\EstimationJuly07USED. + //Files that are affected are: cstz.c, kalman.c, optpackage.c, + + + #define SWITCHTOIMSLCMATH // define: use IMSL special functions like gammlog; undef: use my own default code if it exists. + + //-------Only one of the following for math library.-------- + #define INTELCMATHLIBRARY // define: use Intel MKL LAPACK library; undef: use others. + //#define IMSLCMATHLIBRARY // define: use IMSL C Math library; undef: use others. + //#define MATLABCMATHLIBRARY // define: use Matlab C math library; undef: use others. + + //-------Only one of the following for math library.-------- + #define SWITCHTOINTELCMATH // define: use Intel MKL LAPACK library; undef: use others. + //#define SWITCHTOTZCMATH // define: use my own C math library; undef: use others. + + //-------Only one of the following for optimization routines except that CG?_ and CSMINWEL_ can be chosen together.-------- + //#define IMSL_OPTIMIZATION // IMSL optimization routines. + #define CSMINWEL_OPTIMIZATION //Sims's optimization routine. + #define CGI_OPTIMIZATION //Polak-Ribiere conjugate gradient method without using derivative information in performing the line minimization. + //NOT available yet! #define CGII_OPTIMIZATION //NOT available yet! Pletcher-Reeves conjugate gradient method using derivative information in performing the line minimization. + + //-------Only one of the following for random number generating routines.-------- + #define IMSL_RANDOMNUMBERGENERATOR // IMSL random number generator. + //#define CASE2_RANDOMNUMBERGENERATOR //Imported from the C recipe book -- case 2 and my own (Iskander) code for generating a gamma distribution. + + //-------Only one of the following statistical packages.-------- + #define IMSL_STATISTICSTOOLBOX // IMSL statistical package. + +/*******************************************************************************/ +/* Added by DW 9/1/08 */ +/*******************************************************************************/ +#if defined(USE_MKL_LIBRARY) + #include "mkl.h" +#else + #include "blas_lapack.h" + #undef SWITCHTOINTELCMATH +#endif + +#if defined(USE_GSL_LIBRARY) + #include "gsl_sf_gamma.h" + #include "gsl_cdf.h" +#endif + +#if defined(USE_IMSL_MATH_LIBRARY) + #include <imsl.h> //IMSL math package. + #include <imsls.h> //IMSL statistical package. +#else + #undef IMSL_OPTIMIZATION + #undef SWITCHTOIMSLCMATH + #undef IMSL_OPTIMIZATION + #undef IMSL_RANDOMNUMBERGENERATOR +#endif + +#if defined(USE_IMSL_STAT_LIBRARY) + #include <imsls.h> //IMSL statistical package. +#else + #undef IMSL_STATISTICSTOOLBOX +#endif +/*******************************************************************************/ + + //-------If define: use matlab API interface; otherwise (undef), use C console. + #undef WIN_MATLABAPI // define: use matlab API interface; undef: use C dos console. + + + //--------------- + #ifdef MATLABCMATHLIBRARY + #include "matlab.h" // For all mlf???? functions. + #include "matrix.h" // For mxGetM, mxCreatDoubleMatrix, etc. + #endif + #ifdef WIN_MATLABAPI // define: use matlab API interface; undef: use C dos console. + #include "mex.h" // For all mex??? calls. Matlab API (application program interface or external interface). + #define printf mexPrintf + #define malloc mxMalloc + #define calloc mxCalloc + #define free mxFree + #endif + + + //-------------- Attributes for the real double matrix type TSdmatrix. -------------- + //-------------- Whenever a matrix is initialized, the default is M_GE, but nothing else. -------------- + #define M_UNDEF 0 //0 or NULL: No attribute will be given when memory is allocated but no values are initialized. + #define M_GE 0x0001 //1: A general matrix. + #define M_SU 0x0002 //2: A symmetric (must be square) matrix but only the upper triangular part is referenced. + #define M_SL 0x0004 //4: A symmetric (must be square) matrix but only the lower triangular part is referenced. + #define M_UT 0x0008 //8: A upper triangular (trapezoidal if nrows < ncols) matrix but only the upper triangular part is referenced. + #define M_LT 0x0010 //16: A lower triangular (trapezoidal if nrows > ncols) matrix but only the lower triangular part is referenced. + #define M_CN 0x0020 //32: A constant (CN) matrix (All elements are the same or no (N) change from one to another). +// #define M_UTU 0x0040 //2^6: An unit upper triangular matrix. +// #define M_LTU 0x0080 //2^7: An unit lower triangular matrix. + //-------------- Attributes for the real double vector type TSdvector or the character vector type TScvector. -------------- + #define V_UNDEF 0 //Zero or NULL: No values have been assigned to the double vector. + #define V_DEF 1 //True: Values have been assigned to the double vector. + + + //-------------- Other macro definitions. -------------- + #define BLOCKSIZE_FOR_INTEL_MKL 128 //A machine-dependent value (typically, 16 to 64) required for optimum performance of the blocked algorithm in Intel MKL. + #define NEARINFINITY 1.0E+300 + #define BIGREALNUMBER 1.0E+30 + #define MACHINEZERO DBL_MIN + #define EPSILON DBL_EPSILON //1.0E-015. In Standard C, DBL_EPSILON = 2.2204460492503131 + #define SQRTEPSILON 1.490116119384766E-008 //1.0E-15. In Standard C, DBL_EPSILON = 2.2204460492503131E-016 + #define SQRTMACHINEZERO 1.490116119384766E-008 + //This is really not correct, because this number is sqrt(epsion), where DBL_MIN is around 1.0e-300. + #define MACHINEINFINITY DBL_MAX + #define MACHINE_EXP_INFINITY DBL_MAX_EXP + #define EXP_NEARINFINITY 1000 + //=== + #define TZ_TRUE 1 + #define TZ_FALSE 0 + + + + //--------------- + #define tzMalloc(elt_count, type) (type *)m_alloc((elt_count)*sizeof(type)) + #define tzCalloc(elt_count, type) (type *)c_alloc((elt_count), sizeof(type)) + #define tzDestroy(x) {if ((x)) { \ + free((x)); \ + (x) = NULL; \ + }} + #define tzFclose(x) {if ((x)) { \ + fclose((x)); \ + (x) = (FILE *)NULL; \ + }} + #define mos(i, j, nrows) ((j)*(nrows)+(i)) //i: ith row; j: jth column; nrows: number of rows for the matrix. + //Offset(os) for a matrix(m) in column major order and with base 0. See Reek pp.241-242. + #define square(x) ((x) * (x)) //Must be careful to avoid using, say, square(tmpd=2) or square(++x). + #define _max(a, b) ((a)>(b) ? (a) : (b)) // Macro max or __max is already defined in stdlib.h in MS visual C++, but mex.h may overwrite the max macro so we use _max. + #define _min(a, b) ((a)>(b) ? (b) : (a)) + #define swap(a, b, stemp) {(stemp)=(a); (a)=(b); (b)=(stemp);} + // + #ifndef isfinite + #define isfinite(x) _finite(x) //_finite is for Microsoft C++ compiler only (in float.h, which strangely is not ANSI compible), + // All these Microsoft functions are not yet C99 compatible. + #endif + //--- The following does not work. + // #ifndef FP_NAN + // #define FP_NAN _FPCLASS_SNAN //_FPCLASS_SNAN is for Microsoft C++ compiler only (in float.h, which strangely is not ANSI compible), + // // All these Microsoft functions are not yet C99 compatible. + // #endif + #define isdiagonalmatrix(x) (((x)->flag & (M_UT | M_LT)) == (M_UT | M_LT)) //x is the tz type of matrix. + // + #define DestroyDatesVector_lf(x) DestroyVector_lf(x) + + + //--------------- + typedef struct TScvector_tag + { + char *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TScvector; + typedef struct TSvoidvector_tag + { + void *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TSvoidvector; + typedef struct { + int *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TSivector; + typedef struct { + int *M; //M: matrix. + int nrows, ncols; + int flag; //flag: Refers to M_GE, M_SU, M_SL, M_UT, and M_LT in tzmatlab.h. + } TSimatrix; + typedef struct { + TSivector **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSicellvec; + typedef struct { + TSimatrix **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSicell; + //=== Real types. + typedef struct { + double *v; //v: vector. + int n; + int flag; //flag: no legal values are assigned if 0 and legal values are assigned if 1. + } TSdvector; + typedef struct { + double *M; //M: matrix. + int nrows, ncols; + int flag; //flag: Refers to M_GE, M_SU, M_SL, M_UT, and M_LT in tzmatlab.h. + } TSdmatrix; + typedef struct { + TSdmatrix **C; //ncells-by-1 cells (C) and a pointer to matrix in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSdcell; + typedef struct { + TSdvector **C; //ncells-by-1 cells (C) and a ponter to vector in each cell. + int ncells; //Number of pointers (cells) to pointer. + } TSdcellvec; + typedef struct { + TSdcell **F; //ndims-by-1 fourths (F) and a pointer to cell in each fourth. + int ndims; //Number of pointers (fourth dimensions) to pointer. + } TSdfourth; + typedef struct { + TSdcellvec **F; //ndims-by-1 fourths (F) and a pointer to cellvec in each fourth. + int ndims; //Number of pointers (fourth dimensions) to pointer. + } TSdfourthvec; + //=== Complex types. + typedef struct { + TSdvector *real; //Real part. + TSdvector *imag; //Imaginary part. + } TSdzvector; + typedef struct { + TSdmatrix *real; //Real part. + TSdmatrix *imag; //Imaginary part. + } TSdzmatrix; + + + + //----------------- Some high-level functions. ----------------- + int fn_locofyearqm(int q_m, int yrstart, int qmstart, int yrend, int qmend); + + + + + //--------------- + void fn_DisplayError(char *msg_s); + void *m_alloc(size_t size); + void *c_alloc(size_t elt_count, size_t elt_size); + + /** + TSvoidvector *CreateVector_void(int _n); + TSvoidvector *DestroyVector_void(TSvoidvector *x_voidv); + /**/ + + TScvector *CreateVector_c(int _n); + TScvector *DestroyVector_c(TScvector *x_s); + TSivector *CreateVector_int(int _n); + TSivector *DestroyVector_int(TSivector *x_iv); + TSimatrix *CreateMatrix_int(int nrows, int ncols); + TSimatrix *DestroyMatrix_int(TSimatrix *x_im); + TSicellvec *CreateCellvec_int(TSivector *n_iv); + TSicellvec *DestroyCellvec_int(TSicellvec *x_icv); + TSicell *CreateCell_int(TSivector *row_iv, TSivector *col_iv); + TSicell *DestroyCell_int(TSicell *x_ic); + + TSdvector *CreateVector_lf(int _n); + TSdvector *DestroyVector_lf(TSdvector *x_iv); + TSdmatrix *CreateMatrix_lf(int nrows, int ncols); + TSdmatrix *DestroyMatrix_lf(TSdmatrix *x_im); + TSdcell *CreateCell_lf(TSivector *row_iv, TSivector *col_iv); + TSdcell *DestroyCell_lf(TSdcell *x_dc); + TSdcellvec *CreateCellvec_lf(TSivector *n_iv); + TSdcellvec *DestroyCellvec_lf(TSdcellvec *x_dcv); + TSdfourth *CreateFourth_lf(int ndims, TSivector *row_iv, TSivector *col_iv); + TSdfourth *DestroyFourth_lf(TSdfourth *x_d4); + TSdfourthvec *CreateFourthvec_lf(int ndims, TSivector *n_iv); + TSdfourthvec *DestroyFourthvec_lf(TSdfourthvec *x_d4v); + + TSdzvector *CreateVector_dz(int _n); + TSdzvector *DestroyVector_dz(TSdzvector *x_dzv); + TSdzmatrix *CreateMatrix_dz(int nrows, int ncols); + TSdzmatrix *DestroyMatrix_dz(TSdzmatrix *x_dzm); + + //+ + TSdmatrix *CreateZeroMatrix_lf(const int nrows, const int ncols); + TSdmatrix *CreateIdentityMatrix_lf(const int nrows, const int ncols); + //TSdvector *CreateZerosVector_lf(int _n); + TSivector *CreateConstantVector_int( const int _n, const int _k); + TSimatrix *CreateConstantMatrix_int(const int nrows, const int ncols, const int _n); + TSicellvec *CreateConstantCellvec_int(TSivector *n_iv, const int _n); + TSicell *CreateConstantCell_int(TSivector *row_iv, TSivector *col_iv, const int _n); + TSdvector *CreateConstantVector_lf(const int _n, const double _alpha); + TSdmatrix *CreateConstantMatrix_lf(const int nrows, const int ncols, const double _alpha); + TSdcellvec *CreateConstantCellvec_lf(TSivector *n_iv, const double _alpha); + TSdcell *CreateConstantCell_lf(TSivector *row_iv, TSivector *col_iv, const double _alpha); + TSdvector *CreateDatesVector_lf(int nq_m, int yrstart, int qmstart, int yrend, int qmend); + //+ + void InitializeConstantVector_lf(TSdvector *x_dv, const double _alpha); + void InitializeConstantVector_int(TSivector *x_iv, const int _k); + void InitializeConstantMatrix_lf(TSdmatrix *x_dm, const double _alpha); + void InitializeDiagonalMatrix_lf(TSdmatrix *x_dm, const double _alpha); + void InitializeConstantMatrix_int(TSimatrix *x_dm, const int _alpha); + void InitializeConstantCellvec_lf(TSdcellvec *x_dcv, const double _alpha); + void InitializeConstantCell_lf(TSdcell *x_dc, const double _alpha); + void InitializeConstantFourthvec_lf(TSdfourthvec *x_d4v, const double _alpha); + void InitializeConstantFourth_lf(TSdfourth *x_d4, const double _alpha); + + + void NegateColofMatrix_lf(TSdvector *y_dv, TSdmatrix *x_dm, int _j); + void InitializeConstantColofMatrix_lf(TSdmatrix *X_dm, int jx, double _alpha); + + FILE *tzFopen(char *filename, char *mode); +#endif