1function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,decomp,trend_addition,state_uncertainty,M_,oo_,options_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_)
2% Estimation of the smoothed variables and innovations.
3%
4% INPUTS
5%   o xparam1       [double]   (p*1) vector of (estimated) parameters.
6%   o gend          [integer]  scalar specifying the number of observations ==> varargin{1}.
7%   o data          [double]   (n*T) matrix of data.
8%   o data_index    [cell]      1*smpl cell of column vectors of indices.
9%   o missing_value 1 if missing values, 0 otherwise
10%   o M_            [structure] decribing the model
11%   o oo_           [structure] storing the results
12%   o options_      [structure] describing the options
13%   o bayestopt_    [structure] describing the priors
14%   o estim_params_ [structure] characterizing parameters to be estimated
15%
16% OUTPUTS
17%   o alphahat      [double]  (m*T) matrix, smoothed endogenous variables (a_{t|T})  (decision-rule order)
18%   o etahat        [double]  (r*T) matrix, smoothed structural shocks (r>=n is the number of shocks).
19%   o epsilonhat    [double]  (n*T) matrix, smoothed measurement errors.
20%   o ahat          [double]  (m*T) matrix, updated (endogenous) variables (a_{t|t}) (decision-rule order)
21%   o SteadyState   [double]  (m*1) vector specifying the steady state level of each endogenous variable (declaration order)
22%   o trend_coeff   [double]  (n*1) vector, parameters specifying the slope of the trend associated to each observed variable.
23%   o aK            [double]  (K,n,T+K) array, k (k=1,...,K) steps ahead
24%                                   filtered (endogenous) variables  (decision-rule order)
25%   o T and R       [double]  Matrices defining the state equation (T is the (m*m) transition matrix).
26%   o P:            (m*m*(T+1)) 3D array of one-step ahead forecast error variance
27%                       matrices (decision-rule order)
28%   o PK:           (K*m*m*(T+K)) 4D array of k-step ahead forecast error variance
29%                       matrices (meaningless for periods 1:d) (decision-rule order)
30%   o decomp        (K*m*r*(T+K)) 4D array of shock decomposition of k-step ahead
31%                       filtered variables (decision-rule order)
32%   o trend_addition [double] (n*T) pure trend component; stored in options_.varobs order
33%   o state_uncertainty [double] (K,K,T) array, storing the uncertainty
34%                                   about the smoothed state (decision-rule order)
35%   o M_            [structure] decribing the model
36%   o oo_           [structure] storing the results
37%   o options_      [structure] describing the options
38%   o bayestopt_    [structure] describing the priors
39%
40% Notes:
41%   m:  number of endogenous variables (M_.endo_nbr)
42%   T:  number of Time periods (options_.nobs)
43%   r:  number of strucural shocks (M_.exo_nbr)
44%   n:  number of observables (length(options_.varobs))
45%   K:  maximum forecast horizon (max(options_.nk))
46%
47%   To get variables that are stored in decision rule order in order of declaration
48%   as in M_.endo_names, ones needs code along the lines of:
49%   variables_declaration_order(dr.order_var,:) = alphahat
50%
51%   Defines bayestopt_.mf = bayestopt_.smoother_mf (positions of observed variables
52%   and requested smoothed variables in decision rules (decision rule order)) and
53%   passes it back via global variable
54%
55% ALGORITHM
56%   Diffuse Kalman filter (Durbin and Koopman)
57%
58% SPECIAL REQUIREMENTS
59%   None
60
61% Copyright (C) 2006-2018 Dynare Team
62%
63% This file is part of Dynare.
64%
65% Dynare is free software: you can redistribute it and/or modify
66% it under the terms of the GNU General Public License as published by
67% the Free Software Foundation, either version 3 of the License, or
68% (at your option) any later version.
69%
70% Dynare is distributed in the hope that it will be useful,
71% but WITHOUT ANY WARRANTY; without even the implied warranty of
72% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73% GNU General Public License for more details.
74%
75% You should have received a copy of the GNU General Public License
76% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
77
78alphahat        = [];
79etahat  = [];
80epsilonhat      = [];
81ahat          = [];
82SteadyState   = [];
83trend_coeff   = [];
84aK            = [];
85T             = [];
86R             = [];
87P             = [];
88PK            = [];
89decomp        = [];
90vobs            = length(options_.varobs);
91smpl          = size(Y,2);
92
93if ~isempty(xparam1) %not calibrated model
94    M_ = set_all_parameters(xparam1,estim_params_,M_);
95end
96
97%------------------------------------------------------------------------------
98% 2. call model setup & reduction program
99%------------------------------------------------------------------------------
100oldoo.restrict_var_list = oo_.dr.restrict_var_list;
101oldoo.restrict_columns = oo_.dr.restrict_columns;
102oo_.dr.restrict_var_list = bayestopt_.smoother_var_list;
103oo_.dr.restrict_columns = bayestopt_.smoother_restrict_columns;
104
105[T,R,SteadyState,info,M_,options_,oo_] = dynare_resolve(M_,options_,oo_);
106
107if info~=0
108    print_info(info,options_.noprint, options_);
109    return
110end
111oo_.dr.restrict_var_list = oldoo.restrict_var_list;
112oo_.dr.restrict_columns = oldoo.restrict_columns;
113
114%get location of observed variables and requested smoothed variables in
115%decision rules
116bayestopt_.mf = bayestopt_.smoother_var_list(bayestopt_.smoother_mf);
117if options_.noconstant
118    constant = zeros(vobs,1);
119else
120    if options_.loglinear
121        constant = log(SteadyState(bayestopt_.mfys));
122    else
123        constant = SteadyState(bayestopt_.mfys);
124    end
125end
126trend_coeff = zeros(vobs,1);
127if bayestopt_.with_trend == 1
128    [trend_addition, trend_coeff] =compute_trend_coefficients(M_,options_,vobs,gend);
129    trend = constant*ones(1,gend)+trend_addition;
130else
131    trend_addition=zeros(size(constant,1),gend);
132    trend = constant*ones(1,gend);
133end
134start = options_.presample+1;
135np    = size(T,1);
136mf    = bayestopt_.mf;
137% ------------------------------------------------------------------------------
138%  3. Initial condition of the Kalman filter
139% ------------------------------------------------------------------------------
140%
141%  Here, Pinf and Pstar are determined. If the model is stationary, determine
142%  Pstar as the solution of the Lyapunov equation and set Pinf=[] (Notation follows
143%  Koopman/Durbin (2003), Journal of Time Series Analysis 24(1))
144%
145Q = M_.Sigma_e;
146H = M_.H;
147
148if isequal(H,0)
149    H = zeros(vobs,vobs);
150end
151
152Z = zeros(vobs,size(T,2));
153for i=1:vobs
154    Z(i,mf(i)) = 1;
155end
156
157expanded_state_vector_for_univariate_filter=0;
158kalman_algo = options_.kalman_algo;
159if options_.lik_init == 1               % Kalman filter
160    if kalman_algo ~= 2
161        kalman_algo = 1;
162    end
163    Pstar=lyapunov_solver(T,R,Q,options_);
164    Pinf        = [];
165elseif options_.lik_init == 2           % Old Diffuse Kalman filter
166    if kalman_algo ~= 2
167        kalman_algo = 1;
168    end
169    Pstar = options_.Harvey_scale_factor*eye(np);
170    Pinf        = [];
171elseif options_.lik_init == 3           % Diffuse Kalman filter
172    if kalman_algo ~= 4
173        kalman_algo = 3;
174    else
175        if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
176                                                %Augment state vector (follows Section 6.4.3 of DK (2012))
177            expanded_state_vector_for_univariate_filter=1;
178            T  = blkdiag(T,zeros(vobs));
179            np    = size(T,1);
180            Q   = blkdiag(Q,H);
181            R  = blkdiag(R,eye(vobs));
182            H   = zeros(vobs,vobs);
183            Z   = [Z, eye(vobs)];
184        end
185    end
186    [Pstar,Pinf] = compute_Pinf_Pstar(mf,T,R,Q,options_.qz_criterium);
187elseif options_.lik_init == 4           % Start from the solution of the Riccati equation.
188    [err, Pstar] = kalman_steady_state(transpose(T),R*Q*transpose(R),transpose(build_selection_matrix(mf,np,vobs)),H);
189    mexErrCheck('kalman_steady_state',err);
190    Pinf  = [];
191    if kalman_algo~=2
192        kalman_algo = 1;
193    end
194elseif options_.lik_init == 5            % Old diffuse Kalman filter only for the non stationary variables
195    [eigenvect, eigenv] = eig(T);
196    eigenv = diag(eigenv);
197    nstable = length(find(abs(abs(eigenv)-1) > 1e-7));
198    unstable = find(abs(abs(eigenv)-1) < 1e-7);
199    V = eigenvect(:,unstable);
200    indx_unstable = find(sum(abs(V),2)>1e-5);
201    stable = find(sum(abs(V),2)<1e-5);
202    nunit = length(eigenv) - nstable;
203    Pstar = options_.Harvey_scale_factor*eye(np);
204    if kalman_algo ~= 2
205        kalman_algo = 1;
206    end
207    R_tmp = R(stable, :);
208    T_tmp = T(stable,stable);
209    Pstar_tmp=lyapunov_solver(T_tmp,R_tmp,Q,DynareOptions);
210    Pstar(stable, stable) = Pstar_tmp;
211    Pinf  = [];
212end
213kalman_tol = options_.kalman_tol;
214diffuse_kalman_tol = options_.diffuse_kalman_tol;
215riccati_tol = options_.riccati_tol;
216data1 = Y-trend;
217% -----------------------------------------------------------------------------
218%  4. Kalman smoother
219% -----------------------------------------------------------------------------
220
221if ~missing_value
222    for i=1:smpl
223        data_index{i}=(1:vobs)';
224    end
225end
226
227ST = T;
228R1 = R;
229
230if kalman_algo == 1 || kalman_algo == 3
231    [alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty] = missing_DiffuseKalmanSmootherH1_Z(ST, ...
232                                                      Z,R1,Q,H,Pinf,Pstar, ...
233                                                      data1,vobs,np,smpl,data_index, ...
234                                                      options_.nk,kalman_tol,diffuse_kalman_tol,options_.filter_decomposition,options_.smoothed_state_uncertainty);
235    if isinf(alphahat)
236        if kalman_algo == 1
237            kalman_algo = 2;
238        elseif kalman_algo == 3
239            kalman_algo = 4;
240        else
241            error('This case shouldn''t happen')
242        end
243    end
244end
245
246if kalman_algo == 2 || kalman_algo == 4
247    if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
248        if ~expanded_state_vector_for_univariate_filter
249            %Augment state vector (follows Section 6.4.3 of DK (2012))
250            expanded_state_vector_for_univariate_filter=1;
251            Z   = [Z, eye(vobs)];
252            ST  = blkdiag(ST,zeros(vobs));
253            np  = size(ST,1);
254            Q   = blkdiag(Q,H);
255            R1  = blkdiag(R,eye(vobs));
256            if kalman_algo == 4
257                %recompute Schur state space transformation with
258                %expanded state space
259                [Pstar,Pinf] = compute_Pinf_Pstar(mf,ST,R1,Q,options_.qz_criterium);
260            else
261                Pstar = blkdiag(Pstar,H);
262                if ~isempty(Pinf)
263                    Pinf  = blkdiag(Pinf,zeros(vobs));
264                end
265            end
266            %now reset H to 0
267            H   = zeros(vobs,vobs);
268        else
269            %do nothing, state vector was already expanded
270        end
271    end
272
273    [alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty] = missing_DiffuseKalmanSmootherH3_Z(ST, ...
274                                                      Z,R1,Q,diag(H), ...
275                                                      Pinf,Pstar,data1,vobs,np,smpl,data_index, ...
276                                                      options_.nk,kalman_tol,diffuse_kalman_tol, ...
277                                                      options_.filter_decomposition,options_.smoothed_state_uncertainty);
278end
279
280
281if expanded_state_vector_for_univariate_filter && (kalman_algo == 2 || kalman_algo == 4)
282    % extracting measurement errors
283    % removing observed variables from the state vector
284    k = (1:np-vobs);
285    alphahat = alphahat(k,:);
286    ahat = ahat(k,:);
287    aK = aK(:,k,:,:);
288    epsilonhat=etahat(end-vobs+1:end,:);
289    etahat=etahat(1:end-vobs,:);
290    if ~isempty(PK)
291        PK = PK(:,k,k,:);
292    end
293    if ~isempty(decomp)
294        decomp = decomp(:,k,:,:);
295    end
296    if ~isempty(P)
297        P = P(k,k,:);
298    end
299    if ~isempty(state_uncertainty)
300        state_uncertainty = state_uncertainty(k,k,:);
301    end
302end
303