function [oo_, yf]=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,P,PK,decomp,Trend,state_uncertainty) % oo_=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,P,PK,decomp,Trend) % Writes the smoother results into respective fields in oo_ % % Inputs: % M_ [structure] storing the model information % oo_ [structure] storing the results % options_ [structure] storing the options % bayestopt_ [structure] storing information about priors % dataset_ [structure] storing the dataset % atT [double] (m*T) matrix, smoothed endogenous variables (a_{t|T}) (decision-rule order) % innov [double] (r*T) matrix, smoothed structural shocks (r>n is the umber of shocks). % measurement_error [double] (n*T) matrix, smoothed measurement errors. % updated_variables [double] (m*T) matrix, updated (endogenous) variables (a_{t|t}) (decision-rule order) % ys [double] (m*1) vector specifying the steady state % level of each endogenous variable (declaration order) % trend_coeff [double] (n*1) vector, parameters specifying the slope of the trend associated to each observed variable. % aK [double] (K,n,T+K) array, k (k=1,...,K) steps ahead % filtered (endogenous) variables (decision-rule order) % P [3D array] (m*m*(T+1)) array of one-step ahead forecast error variance % matrices (decision-rule order) % PK [4D array] (K*m*m*(T+K)) 4D array of k-step ahead forecast error variance % matrices (meaningless for periods 1:d) (decision-rule order) % decomp [4D array] (K*m*r*(T+K)) 4D array of shock decomposition of k-step ahead % filtered variables (decision-rule order) % Trend [double] [nvarobs*T] matrix of trends in observables % state_uncertainty [double] (K,K,T) array, storing the uncertainty % about the smoothed state (decision-rule order) % % Outputs: % oo_ [structure] storing the results: % oo_.Smoother.SteadyState: Steady states (declaration order) % oo_.Smoother.TrendCoeffs: trend coefficients, with zeros where no trend applies (declaration order) % oo_.Smoother.Variance: one-step ahead forecast error variance (declaration order) % oo_.Smoother.Constant: structure storing the constant term of the smoother % oo_.Smoother.Trend: structure storing the trend term of the smoother % oo_.FilteredVariablesKStepAhead: k-step ahead filtered variables (declaration order) % oo_.FilteredVariablesKStepAheadVariances: k-step ahead forecast error variance matrices (declaration order) % oo_.FilteredVariablesShockDecomposition: shock decomposition of k-step ahead filtered variables (declaration order) % oo_.FilteredVariables: structure storing the filtered variables % oo_.UpdatedVariables: structure storing the updated variables % oo_.SmoothedShocks: structure storing the smoothed shocks % oo_.SmoothedMeasurementErrors: structure storing the smoothed measurement errors % oo_.Smoother.State_uncertainty: smoothed state uncertainty (declaration order) % yf [double] (nvarobs*T) matrix storing the smoothed observed variables (order of options_.varobs) % % Notes: % m: number of endogenous variables (M_.endo_nbr) % T: number of Time periods (options_.nobs) % r: number of strucural shocks (M_.exo_nbr) % n: number of observables (length(options_.varobs)) % K: maximum forecast horizon (max(options_.nk)) % % First all smoothed variables are saved without trend and constant. % Then trend and constant are added for the observed variables. % % Copyright © 2014-2018 Dynare Team % % This file is part of Dynare. % % Dynare is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Dynare is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . if nargin<15 PK=[]; end if nargin<16 decomp=[]; end gend=dataset_.nobs; if nargin<17 Trend=zeros(options_.number_of_observed_variables,gend); end %make sure there are no stale results field_names={'Smoother','SmoothedVariables','UpdatedVariables','FilteredVariables','FilteredVariablesKStepAhead','FilteredVariablesShockDecomposition','FilteredVariablesKStepAheadVariances','SmoothedShocks','SmoothedMeasurementErrors'}; for field_iter=1:length(field_names) if isfield(oo_,field_names(field_iter)) oo_=rmfield(oo_,field_names(field_iter)); end end if options_.occbin.smoother.status oo_.Smoother.occbin = true; else oo_.Smoother.occbin = false; end if options_.loglinear oo_.Smoother.loglinear = true; if ~isempty(M_.aux_vars) % deal with lead/lag of exogenous variables exo_lead_lag_index = M_.orig_endo_nbr + find(([M_.aux_vars.type] == 2) | ([M_.aux_vars.type] == 3)); else exo_lead_lag_index =[]; end else oo_.Smoother.loglinear = false; end %% write variable steady state oo_.Smoother.SteadyState = ys; %% write trend coefficients and trend oo_.Smoother.TrendCoeffs = zeros(size(ys)); oo_.Smoother.TrendCoeffs(options_.varobs_id)=trend_coeff; %are in order of options_.varobs if ~isempty(Trend) for var_iter=1:M_.endo_nbr if isempty(strmatch(M_.endo_names{var_iter}, options_.varobs, 'exact')) oo_.Smoother.Trend.(M_.endo_names{var_iter}) = zeros(gend,1); end end for var_iter=1:length(options_.varobs) oo_.Smoother.Trend.(options_.varobs{var_iter}) = Trend(var_iter,:)'; end end %% Compute constant for observables if options_.prefilter == 1 %as mean is taken after log transformation, no distinction is needed here constant_part=repmat(dataset_info.descriptive.mean',1,gend); elseif options_.prefilter == 0 && options_.loglinear %logged steady state must be used constant_part=repmat(log(ys(bayestopt_.mfys)),1,gend); elseif options_.prefilter == 0 && ~options_.loglinear %unlogged steady state must be used constant_part=repmat(ys(bayestopt_.mfys),1,gend); end %% get observed variables including trend and constant trend_constant_observables=constant_part+Trend; yf = atT(bayestopt_.mf,:)+trend_constant_observables; if options_.nk > 0 %filtered variable E_t(y_t+k) requires to shift trend by k periods filter_steps_required=union(1,options_.filter_step_ahead); % 1 is required for standard filtered variables for filter_iter=1:length(filter_steps_required) filter_step=filter_steps_required(filter_iter); trend_constant_observables_filtered.(['filter_ahead_' num2str(filter_step)])=constant_part+[Trend+repmat(filter_step*trend_coeff,1,gend)]; end end %% write smoother variance if options_.filter_covariance oo_.Smoother.Variance = P; end if options_.smoothed_state_uncertainty oo_.Smoother.State_uncertainty=state_uncertainty; end %get indices of smoothed variables i_endo_in_bayestopt_smoother_varlist = bayestopt_.smoother_saved_var_list; i_endo_in_dr_matrices=bayestopt_.smoother_var_list(i_endo_in_bayestopt_smoother_varlist); if ~isempty(options_.nk) && options_.nk ~= 0 %% Compute constant i_endo_declaration_order = oo_.dr.order_var(i_endo_in_dr_matrices); %get indices of smoothed variables in name vector if options_.loglinear %logged steady state must be used constant_all_variables=repmat(log(ys(i_endo_declaration_order))',[length(options_.filter_step_ahead),1,gend+max(options_.filter_step_ahead)]); if ~isempty(exo_lead_lag_index) && any(ismember(i_endo_declaration_order,exo_lead_lag_index)) % deal with lead/lag of exogenous variables constant_all_variables(:,ismember(i_endo_declaration_order,exo_lead_lag_index),:)=repmat(ys(i_endo_declaration_order(ismember(i_endo_declaration_order,exo_lead_lag_index)))',[length(options_.filter_step_ahead),1,gend+max(options_.filter_step_ahead)]); end elseif ~options_.loglinear %unlogged steady state must be used constant_all_variables=repmat((ys(i_endo_declaration_order))',[length(options_.filter_step_ahead),1,gend+max(options_.filter_step_ahead)]); end % add constant oo_.FilteredVariablesKStepAhead = aK(options_.filter_step_ahead,i_endo_in_dr_matrices,:)+constant_all_variables; if ~isempty(PK) && options_.filter_covariance %get K-step ahead variances oo_.FilteredVariablesKStepAheadVariances = ... PK(options_.filter_step_ahead,i_endo_in_dr_matrices,i_endo_in_dr_matrices,:); end if ~isempty(decomp) %get decomposition oo_.FilteredVariablesShockDecomposition = ... decomp(options_.filter_step_ahead,i_endo_in_dr_matrices,:,:); end end for i_endo_in_bayestopt_smoother_varlist=bayestopt_.smoother_saved_var_list' i_endo_in_dr=bayestopt_.smoother_var_list(i_endo_in_bayestopt_smoother_varlist); i_endo_declaration_order = oo_.dr.order_var(i_endo_in_dr); %get indices of smoothed variables in name vector %% Compute constant if options_.loglinear == 1 %logged steady state must be used if ~isempty(exo_lead_lag_index) && ismember(i_endo_declaration_order,exo_lead_lag_index)% deal with lead/lag of exogenous variables constant_current_variable=repmat(ys(i_endo_declaration_order),gend,1); else constant_current_variable=repmat(log(ys(i_endo_declaration_order)),gend,1); end elseif options_.loglinear == 0 %unlogged steady state must be used constant_current_variable=repmat((ys(i_endo_declaration_order)),gend,1); end oo_.Smoother.Constant.(M_.endo_names{i_endo_declaration_order})=constant_current_variable; oo_.SmoothedVariables.(M_.endo_names{i_endo_declaration_order})=atT(i_endo_in_dr,:)'+constant_current_variable; if ~isempty(options_.nk) && options_.nk > 0 % && ~((any(bayestopt_.pshape > 0) && options_.mh_replic) || (any(bayestopt_.pshape> 0) && options_.load_mh_file)) oo_.FilteredVariables.(M_.endo_names{i_endo_declaration_order})=squeeze(aK(1,i_endo_in_dr,2:end-(options_.nk-1)))+constant_current_variable; end oo_.UpdatedVariables.(M_.endo_names{i_endo_declaration_order})=updated_variables(i_endo_in_dr,:)'+constant_current_variable; end %% Add trend and constant for observed variables for pos_iter=1:length(bayestopt_.mf) oo_.Smoother.Constant.(M_.endo_names{bayestopt_.mfys(pos_iter)})=constant_part(pos_iter,:)'; if ismember(bayestopt_.mf(pos_iter),bayestopt_.smoother_var_list(bayestopt_.smoother_saved_var_list)) oo_.SmoothedVariables.(M_.endo_names{bayestopt_.mfys(pos_iter)})=yf(pos_iter,:)'; if ~isempty(options_.nk) && options_.nk > 0 %filtered variable E_t(y_t+1) requires to shift trend by 1 period oo_.FilteredVariables.(M_.endo_names{bayestopt_.mfys(pos_iter)})=... squeeze(aK(1,bayestopt_.mf(pos_iter),2:end-(options_.nk-1)))... +trend_constant_observables_filtered.filter_ahead_1(pos_iter,:)'; for filter_iter=1:length(options_.filter_step_ahead) filter_step=options_.filter_step_ahead(filter_iter); oo_.FilteredVariablesKStepAhead(filter_iter,find(i_endo_in_dr_matrices==bayestopt_.mf(pos_iter)),1+filter_step:end-(max(options_.filter_step_ahead)-filter_step)) = ... squeeze(aK(filter_step,bayestopt_.mf(pos_iter),1+filter_step:end-(max(options_.filter_step_ahead)-filter_step)))... +trend_constant_observables_filtered.(['filter_ahead_' num2str(filter_step)])(pos_iter,:)'; end end %updated variables are E_t(y_t) so no trend shift is required oo_.UpdatedVariables.(M_.endo_names{bayestopt_.mfys(pos_iter)})=... updated_variables(bayestopt_.mf(pos_iter),:)'+trend_constant_observables(pos_iter,:)'; end end %% resort fields that are in decision rule order to declaration order if ~isempty(options_.nk) && options_.nk ~= 0 positions_in_declaration_order=oo_.dr.order_var(bayestopt_.smoother_var_list(bayestopt_.smoother_saved_var_list)); if ~(options_.selected_variables_only && ~(options_.forecast > 0)) %happens only when selected_variables_only is not used oo_.FilteredVariablesKStepAhead(:,positions_in_declaration_order,:)=oo_.FilteredVariablesKStepAhead; if ~isempty(PK) && options_.filter_covariance %get K-step ahead variances oo_.FilteredVariablesKStepAheadVariances(:,positions_in_declaration_order,positions_in_declaration_order,:)=oo_.FilteredVariablesKStepAheadVariances; end if ~isempty(decomp) oo_.FilteredVariablesShockDecomposition(:,positions_in_declaration_order,:,:)=oo_.FilteredVariablesShockDecomposition; end else positions_in_declaration_order=oo_.dr.order_var(bayestopt_.smoother_var_list(bayestopt_.smoother_saved_var_list)); [~,sorted_index_declaration_order]=sort(positions_in_declaration_order); oo_.FilteredVariablesKStepAhead(:,sorted_index_declaration_order,:)=oo_.FilteredVariablesKStepAhead; if ~isempty(PK) && options_.filter_covariance %get K-step ahead variances oo_.FilteredVariablesKStepAheadVariances(:,sorted_index_declaration_order,sorted_index_declaration_order,:)=oo_.FilteredVariablesKStepAheadVariances; end if ~isempty(decomp) oo_.FilteredVariablesShockDecomposition(:,sorted_index_declaration_order,:,:)=oo_.FilteredVariablesShockDecomposition; end end end if options_.filter_covariance oo_.Smoother.Variance(oo_.dr.order_var,oo_.dr.order_var,:)=oo_.Smoother.Variance; end if options_.smoothed_state_uncertainty oo_.Smoother.State_uncertainty(oo_.dr.order_var,oo_.dr.order_var,:)=state_uncertainty; end %% get smoothed shocks for exo_iter=1:M_.exo_nbr oo_.SmoothedShocks.(M_.exo_names{exo_iter})=innov(exo_iter,:)'; end %% Smoothed measurement errors if ~isequal(M_.H,0) % measurement_error_indices=find(diag(M_.H)~=0); for meas_error_iter=1:length(options_.varobs) oo_.SmoothedMeasurementErrors.(options_.varobs{meas_error_iter})= measurement_error(meas_error_iter,:)'; end end