Add Occbin routines
Syntax is not yet finalized (see preprocessor#68). Documentation still to be done. Ref. #569var-model-with-constant
parent
54f80e88d2
commit
02072dde39
26
license.txt
26
license.txt
|
@ -25,6 +25,32 @@ Files: *
|
|||
Copyright: 1996-2021 Dynare Team
|
||||
License: GPL-3+
|
||||
|
||||
Files: matlab/+occbin/IVF_core.m
|
||||
matlab/+occbin/make_chart.m
|
||||
matlab/+occbin/map_regime.m
|
||||
matlab/+occbin/match_function.m
|
||||
matlab/+occbin/mkdata.m
|
||||
matlab/+occbin/mkdatap_anticipated_2constraints_dyn.m
|
||||
matlab/+occbin/mkdatap_anticipated_dyn.m
|
||||
matlab/+occbin/process_constraint.m
|
||||
matlab/+occbin/solve_one_constraint.m
|
||||
matlab/+occbin/solve_two_constraints.m
|
||||
matlab/+occbin/tokenize.m
|
||||
Copyright: none
|
||||
License: public-domain-occbin
|
||||
Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
Original file downloaded from:
|
||||
https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
Adapted for Dynare by Dynare Team.
|
||||
.
|
||||
This code is in the public domain and may be used freely.
|
||||
However the authors would appreciate acknowledgement of the source by
|
||||
citation of any of the following papers:
|
||||
.
|
||||
Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
dynamic models with occasionally binding constraints easily"
|
||||
Journal of Monetary Economics 70, 22-38
|
||||
|
||||
Files: matlab/AIM/SP*
|
||||
Copyright: none
|
||||
License: public-domain-aim
|
||||
|
|
|
@ -0,0 +1,391 @@
|
|||
function [alphahat,etahat,epsilonhat,ahat0,SteadyState,trend_coeff,aKK,T0,R0,P,PKK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DSGE_smoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,dataset_, dataset_info)
|
||||
%function [alphahat,etahat,epsilonhat,ahat0,SteadyState,trend_coeff,aKK,T0,R0,P,PKK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DSGE_smoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,dataset_, dataset_info)
|
||||
% Runs a DSGE smoother with occasionally binding constraints
|
||||
%
|
||||
% INPUTS
|
||||
% - xparam1 [double] (p*1) vector of (estimated) parameters.
|
||||
% - gend [integer] scalar specifying the number of observations
|
||||
% - Y [double] (n*T) matrix of data.
|
||||
% - data_index [cell] 1*smpl cell of column vectors of indices.
|
||||
% - missing_value [boolean] 1 if missing values, 0 otherwise
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
% - options_ [structure] Matlab's structure describing the current options (options_).
|
||||
% - bayestopt_ [structure] describing the priors
|
||||
% - estim_params_ [structure] characterizing parameters to be estimated
|
||||
% - dataset_ [structure] the dataset after required transformation
|
||||
% - dataset_info [structure] Various informations about the dataset (descriptive statistics and missing observations)
|
||||
%
|
||||
% OUTPUTS
|
||||
% - alphahat [double] (m*T) matrix, smoothed endogenous variables (a_{t|T}) (decision-rule order)
|
||||
% - etahat [double] (r*T) matrix, smoothed structural shocks (r>=n is the number of shocks).
|
||||
% - epsilonhat [double] (n*T) matrix, smoothed measurement errors.
|
||||
% - ahat0 [double] (m*T) matrix, updated (endogenous) variables (a_{t|t}) (decision-rule order)
|
||||
% - SteadyState [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.
|
||||
% - aKK [double] (K,n,T+K) array, k (k=1,...,K) steps ahead
|
||||
% filtered (endogenous) variables (decision-rule order)
|
||||
% - T0 and R0 [double] Matrices defining the state equation (T is the (m*m) transition matrix).
|
||||
% - P: (m*m*(T+1)) 3D array of one-step ahead forecast error variance
|
||||
% matrices (decision-rule order)
|
||||
% - PKK (K*m*m*(T+K)) 4D array of k-step ahead forecast error variance
|
||||
% matrices (meaningless for periods 1:d) (decision-rule order)
|
||||
% - decomp (K*m*r*(T+K)) 4D array of shock decomposition of k-step ahead
|
||||
% filtered variables (decision-rule order)
|
||||
% - Trend [double] (n*T) pure trend component; stored in options_.varobs order
|
||||
% - state_uncertainty [double] (K,K,T) array, storing the uncertainty
|
||||
% about the smoothed state (decision-rule order)
|
||||
% - M_ [structure] decribing the model
|
||||
% - oo_ [structure] storing the results
|
||||
% - options_ [structure] describing the options
|
||||
% - bayestopt_ [structure] describing the priors
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
smoother_field_list = {'SmoothedVariables', 'UpdatedVariables', 'SmoothedShocks'};
|
||||
|
||||
regime_history=[];
|
||||
if options_.occbin.smoother.linear_smoother && nargin==12
|
||||
%% linear smoother
|
||||
options_.occbin.smoother.status=false;
|
||||
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
tmp_smoother=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,P,PK,decomp,Trend,state_uncertainty);
|
||||
for jf=1:length(smoother_field_list)
|
||||
oo_.occbin.linear_smoother.(smoother_field_list{jf}) = tmp_smoother.(smoother_field_list{jf});
|
||||
end
|
||||
oo_.occbin.linear_smoother.alphahat=alphahat;
|
||||
oo_.occbin.linear_smoother.etahat=etahat;
|
||||
oo_.occbin.linear_smoother.epsilonhat=epsilonhat;
|
||||
oo_.occbin.linear_smoother.ahat=ahat;
|
||||
oo_.occbin.linear_smoother.SteadyState=SteadyState;
|
||||
oo_.occbin.linear_smoother.trend_coeff=trend_coeff;
|
||||
oo_.occbin.linear_smoother.aK=aK;
|
||||
oo_.occbin.linear_smoother.T0=T0;
|
||||
oo_.occbin.linear_smoother.R0=R0;
|
||||
oo_.occbin.linear_smoother.decomp=decomp;
|
||||
|
||||
fprintf('\nOccbin: linear smoother done.\n')
|
||||
options_.occbin.smoother.status=true;
|
||||
end
|
||||
% if init_mode
|
||||
%% keep these commented lines for the moment, should some nasty problem in the future call back for this option
|
||||
% shocks1 = etahat(:,2:end)';
|
||||
% clear regime_history ;
|
||||
%
|
||||
% for ii = 1:gend-1
|
||||
%
|
||||
% fprintf('Period number %d out of %d \n',ii,gend-1)
|
||||
% opts_simul.SHOCKS = shocks1(ii,:);
|
||||
% opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,ii);
|
||||
% out = occbin.runsim_fn(opts_simul, M_, oo_, options_);
|
||||
% regime_history(ii) = out.regime_history;
|
||||
% end
|
||||
%
|
||||
% [TT,RR] = dynare_resolve(M_,options_,oo_);
|
||||
% CC = zeros([size(RR,1),gend ]);
|
||||
% else
|
||||
|
||||
opts_simul = options_.occbin.simul;
|
||||
opts_simul.curb_retrench = options_.occbin.smoother.curb_retrench;
|
||||
opts_simul.maxit = options_.occbin.smoother.maxit;
|
||||
opts_simul.waitbar = options_.occbin.smoother.waitbar;
|
||||
opts_simul.periods = options_.occbin.smoother.periods;
|
||||
opts_simul.check_ahead_periods = options_.occbin.smoother.check_ahead_periods;
|
||||
opts_simul.full_output = options_.occbin.smoother.full_output;
|
||||
opts_simul.piecewise_only = options_.occbin.smoother.piecewise_only;
|
||||
constraints = M_.occbin.constraint;
|
||||
% init_mode = options_.occbin.smoother.init_mode; % 0 = standard; 1 = unconditional frcsts zero shocks+smoothed states in each period
|
||||
% init_mode = 0;
|
||||
occbin_options = struct();
|
||||
|
||||
occbin_options.constraints = constraints;
|
||||
occbin_options.first_period_occbin_update = options_.occbin.smoother.first_period_occbin_update;
|
||||
occbin_options.opts_regime = opts_simul; % this builds the opts_simul options field needed by occbin.solver
|
||||
occbin_options.opts_regime.binding_indicator = options_.occbin.likelihood.init_binding_indicator;
|
||||
occbin_options.opts_regime.regime_history=options_.occbin.likelihood.init_regime_history;
|
||||
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,occbin_options);% T1=TT;
|
||||
|
||||
oo_.occbin.smoother.realtime_regime_history = oo_.occbin.smoother.regime_history;
|
||||
regime_history = oo_.occbin.smoother.regime_history;
|
||||
opts_regime.regime_history = oo_.occbin.smoother.regime_history;
|
||||
|
||||
ahat0 = ahat;
|
||||
aKK=aK;
|
||||
PKK=PK;
|
||||
clear aK PK;
|
||||
|
||||
occbin_options.first_period_occbin_update = inf;
|
||||
|
||||
opts_regime.binding_indicator=[];
|
||||
regime_history0 = regime_history;
|
||||
|
||||
fprintf('Occbin smoother iteration 1.\n')
|
||||
opts_simul.SHOCKS = [etahat(:,2:end)'; zeros(1,M_.exo_nbr)];
|
||||
opts_simul.exo_pos = 1:M_.exo_nbr;
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
opts_simul.init_regime=regime_history; % use realtime regime for guess, to avoid multiple solution issues!
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
regime_history = out.regime_history;
|
||||
if options_.smoother_redux
|
||||
occbin_options.opts_simul.restrict_state_space =1;
|
||||
oo_.occbin.linear_smoother.T0=ss.T(oo_.dr.order_var,oo_.dr.order_var,1);
|
||||
oo_.occbin.linear_smoother.R0=ss.R(oo_.dr.order_var,:,1);
|
||||
end
|
||||
TT = ss.T(oo_.dr.order_var,oo_.dr.order_var,:);
|
||||
RR = ss.R(oo_.dr.order_var,:,:);
|
||||
CC = ss.C(oo_.dr.order_var,:);
|
||||
TT = cat(3,TT(:,:,1),TT);
|
||||
RR = cat(3,RR(:,:,1),RR);
|
||||
CC = cat(2,CC(:,1),CC);
|
||||
|
||||
opts_regime.regime_history = regime_history;
|
||||
opts_regime.binding_indicator = [];
|
||||
[TT, RR, CC, regime_history] = occbin.check_regimes(TT, RR, CC, opts_regime, M_, oo_, options_);
|
||||
is_changed = ~isequal(regime_history0,regime_history);
|
||||
if isempty(regime_history0)
|
||||
regime_history0 = regime_history;
|
||||
end
|
||||
iter=1;
|
||||
|
||||
is_periodic = 0;
|
||||
is_changed_start = 0;
|
||||
maxiter = options_.occbin.smoother.max_number_of_iterations;
|
||||
occbin_smoother_fast = options_.occbin.smoother.fast;
|
||||
occbin_smoother_debug=options_.occbin.smoother.debug;
|
||||
|
||||
sto_alphahat=alphahat;
|
||||
sto_etahat={etahat};
|
||||
sto_CC = CC;
|
||||
sto_RR = RR;
|
||||
sto_TT = TT;
|
||||
for k=1:size(TT,3)
|
||||
sto_eee(:,k) = eig(TT(:,:,k));
|
||||
end
|
||||
|
||||
|
||||
while is_changed && maxiter>iter && ~is_periodic
|
||||
iter=iter+1;
|
||||
fprintf('Occbin smoother iteration %u.\n', iter)
|
||||
occbin_options.opts_regime.regime_history=regime_history;
|
||||
[alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T0,R0,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,occbin_options,TT,RR,CC);% T1=TT;
|
||||
sto_etahat(iter)={etahat};
|
||||
regime_history0(iter,:) = regime_history;
|
||||
save('info1','regime_history0');
|
||||
|
||||
sto_CC = CC;
|
||||
sto_RR = RR;
|
||||
sto_TT = TT;
|
||||
|
||||
opts_simul.SHOCKS = [etahat(:,2:end)'; zeros(1,M_.exo_nbr)];
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
regime_history = out.regime_history;
|
||||
TT = ss.T(oo_.dr.order_var,oo_.dr.order_var,:);
|
||||
RR = ss.R(oo_.dr.order_var,:,:);
|
||||
CC = ss.C(oo_.dr.order_var,:);
|
||||
TT = cat(3,TT(:,:,1),TT);
|
||||
RR = cat(3,RR(:,:,1),RR);
|
||||
CC = cat(2,CC(:,1),CC);
|
||||
|
||||
opts_regime.regime_history = regime_history;
|
||||
[TT, RR, CC, regime_history] = occbin.check_regimes(TT, RR, CC, opts_regime, M_, oo_, options_);
|
||||
is_changed = ~isequal(regime_history0(iter,:),regime_history);
|
||||
if length(constraints)==2
|
||||
for k=1:size(regime_history0,2)
|
||||
isdiff_regime(k,1) = ~isequal(regime_history0(end,k).regime1,regime_history(k).regime1);
|
||||
isdiff_start(k,1) = ~isequal(regime_history0(end,k).regimestart1,regime_history(k).regimestart1);
|
||||
isdiff_(k,1) = isdiff_regime(k,1) || isdiff_start(k,1);
|
||||
isdiff_regime(k,2) = ~isequal(regime_history0(end,k).regime2,regime_history(k).regime2);
|
||||
isdiff_start(k,2) = ~isequal(regime_history0(end,k).regimestart2,regime_history(k).regimestart2);
|
||||
isdiff_(k,2) = isdiff_regime(k,2) || isdiff_start(k,2);
|
||||
end
|
||||
is_changed_regime = ~isempty(find(isdiff_regime(:,1))) || ~isempty(find(isdiff_regime(:,2)));
|
||||
is_changed_start = ~isempty(find(isdiff_start(:,1))) || ~isempty(find(isdiff_start(:,2)));
|
||||
else
|
||||
for k=1:size(regime_history0,2)
|
||||
isdiff_regime(k,1) = ~isequal(regime_history0(end,k).regime,regime_history(k).regime);
|
||||
isdiff_start(k,1) = ~isequal(regime_history0(end,k).regimestart,regime_history(k).regimestart);
|
||||
isdiff_(k,1) = isdiff_regime(k,1) || isdiff_start(k,1);
|
||||
end
|
||||
is_changed_regime = ~isempty(find(isdiff_regime(:,1)));
|
||||
is_changed_start = ~isempty(find(isdiff_start(:,1)));
|
||||
end
|
||||
if occbin_smoother_fast
|
||||
is_changed = is_changed_regime;
|
||||
end
|
||||
if iter>1
|
||||
for kiter=1:iter-1
|
||||
is_tmp = isequal(regime_history0(kiter,:),regime_history);
|
||||
if is_tmp
|
||||
break
|
||||
end
|
||||
end
|
||||
is_periodic = (is_changed && is_tmp);
|
||||
end
|
||||
|
||||
if is_changed
|
||||
for k=1:size(TT,3)
|
||||
eee(:,k) = eig(TT(:,:,k));
|
||||
end
|
||||
err_eig(iter-1) = max(max(abs(sort(eee)-sort(sto_eee))));
|
||||
err_alphahat(iter-1) = max(max(max(abs(alphahat-sto_alphahat))));
|
||||
err_etahat(iter-1) = max(max(max(abs(etahat-sto_etahat{iter-1}))));
|
||||
err_CC(iter-1) = max(max(max(abs(CC-sto_CC))));
|
||||
err_RR(iter-1) = max(max(max(abs(RR-sto_RR))));
|
||||
err_TT(iter-1) = max(max(max(abs(TT-sto_TT))));
|
||||
end
|
||||
|
||||
if occbin_smoother_debug
|
||||
regime_ = cell(0);
|
||||
regime_new = regime_;
|
||||
start_ = regime_;
|
||||
start_new = regime_;
|
||||
if length(constraints)==2
|
||||
indx_init_1 = find(isdiff_(:,1));
|
||||
if ~isempty(indx_init_1)
|
||||
qq={regime_history0(end,indx_init_1).regime1}';
|
||||
for j=1:length(qq), regime_(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history0(end,indx_init_1).regimestart1}';
|
||||
for j=1:length(qq), start_(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history(indx_init_1).regime1}';
|
||||
for j=1:length(qq), regime_new(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history(indx_init_1).regimestart1}';
|
||||
for j=1:length(qq), start_new(j,1) = {int2str(qq{j})}; end
|
||||
disp('Time points where regime 1 differs')
|
||||
disp(table(indx_init_1, regime_, start_, regime_new, start_new))
|
||||
end
|
||||
|
||||
indx_init_2 = find(isdiff_(:,2));
|
||||
if ~isempty(indx_init_2)
|
||||
regime_ = cell(0);
|
||||
regime_new = regime_;
|
||||
start_ = regime_;
|
||||
start_new = regime_;
|
||||
qq={regime_history0(end,indx_init_2).regime2}';
|
||||
for j=1:length(qq), regime_(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history0(end,indx_init_2).regimestart2}';
|
||||
for j=1:length(qq), start_(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history(indx_init_2).regime2}';
|
||||
for j=1:length(qq), regime_new(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history(indx_init_2).regimestart2}';
|
||||
for j=1:length(qq), start_new(j,1) = {int2str(qq{j})}; end
|
||||
disp('Time points where regime 2 differs ')
|
||||
disp(table(indx_init_2, regime_, start_, regime_new, start_new))
|
||||
end
|
||||
else
|
||||
indx_init_1 = find(isdiff_(:,1));
|
||||
if ~isempty(indx_init_1)
|
||||
qq={regime_history0(end,indx_init_1).regime}';
|
||||
for j=1:length(qq), regime_(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history0(end,indx_init_1).regimestart}';
|
||||
for j=1:length(qq), start_(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history(indx_init_1).regime}';
|
||||
for j=1:length(qq), regime_new(j,1) = {int2str(qq{j})}; end
|
||||
qq={regime_history(indx_init_1).regimestart}';
|
||||
for j=1:length(qq), start_new(j,1) = {int2str(qq{j})}; end
|
||||
disp('Time points where regime differs')
|
||||
disp(table(indx_init_1, regime_, start_, regime_new, start_new))
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
if is_changed
|
||||
sto_alphahat=alphahat;
|
||||
sto_eee = eee;
|
||||
end
|
||||
end
|
||||
regime_history0(max(iter+1,1),:) = regime_history;
|
||||
oo_.occbin.smoother.regime_history=regime_history0(end,:);
|
||||
oo_.occbin.smoother.regime_history_iter=regime_history0;
|
||||
save('info1','regime_history0')
|
||||
|
||||
if (maxiter==iter && is_changed) || is_periodic
|
||||
disp(['Occbin smoother did not converge.'])
|
||||
if is_periodic
|
||||
disp(['Occbin smoother algo loops between two solutions.'])
|
||||
end
|
||||
else
|
||||
disp(['Occbin smoother converged.'])
|
||||
if occbin_smoother_fast && is_changed_start
|
||||
disp('WARNING: fast algo is used, regime(s) duration(s) was not forced to converge')
|
||||
end
|
||||
end
|
||||
if (~is_changed || occbin_smoother_debug) && nargin==12
|
||||
if is_changed
|
||||
CC = sto_CC;
|
||||
RR = sto_RR;
|
||||
TT = sto_TT;
|
||||
oo_.occbin.smoother.regime_history=regime_history0(end-1,:);
|
||||
end
|
||||
tmp_smoother=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,alphahat,etahat,epsilonhat,ahat0,SteadyState,trend_coeff,aKK,P,PKK,decomp,Trend,state_uncertainty);
|
||||
for jf=1:length(smoother_field_list)
|
||||
oo_.occbin.smoother.(smoother_field_list{jf}) = tmp_smoother.(smoother_field_list{jf});
|
||||
end
|
||||
oo_.occbin.smoother.alphahat=alphahat;
|
||||
oo_.occbin.smoother.etahat=etahat;
|
||||
oo_.occbin.smoother.epsilonhat=epsilonhat;
|
||||
oo_.occbin.smoother.ahat=ahat0;
|
||||
oo_.occbin.smoother.SteadyState=SteadyState;
|
||||
oo_.occbin.smoother.trend_coeff=trend_coeff;
|
||||
oo_.occbin.smoother.aK=aKK;
|
||||
oo_.occbin.smoother.T0=TT;
|
||||
oo_.occbin.smoother.R0=RR;
|
||||
oo_.occbin.smoother.C0=CC;
|
||||
if options_.occbin.smoother.plot
|
||||
GraphDirectoryName = CheckPath('graphs',M_.fname);
|
||||
j1=0;
|
||||
ifig=0;
|
||||
for j=1:M_.exo_nbr
|
||||
if M_.Sigma_e(j,j)
|
||||
j1=j1+1;
|
||||
if mod(j1,9)==1
|
||||
hfig = dyn_figure(options_.nodisplay,'name','Occbin smoothed shocks');
|
||||
ifig=ifig+1;
|
||||
isub=0;
|
||||
end
|
||||
isub=isub+1;
|
||||
subplot(3,3,isub)
|
||||
if options_.occbin.smoother.linear_smoother
|
||||
plot(oo_.occbin.linear_smoother.etahat(j,:)','linewidth',2)
|
||||
hold on,
|
||||
end
|
||||
plot(oo_.occbin.smoother.etahat(j,:)','r--','linewidth',2)
|
||||
hold on, plot([0 options_.nobs],[0 0],'k--')
|
||||
set(gca,'xlim',[0 options_.nobs])
|
||||
title(deblank(M_.exo_names(j,:)),'interpreter','none')
|
||||
if mod(j1,9)==0
|
||||
if options_.occbin.smoother.linear_smoother
|
||||
annotation('textbox', [0.1,0,0.35,0.05],'String', 'Linear','Color','Blue','horizontalalignment','center','interpreter','none');
|
||||
end
|
||||
annotation('textbox', [0.55,0,0.35,0.05],'String', 'Piecewise','Color','Red','horizontalalignment','center','interpreter','none');
|
||||
dyn_saveas(gcf,[GraphDirectoryName filesep M_.fname,'_smoothedshocks_occbin',int2str(ifig)],options_.nodisplay,options_.graph_format);
|
||||
end
|
||||
end
|
||||
|
||||
if mod(j1,9)~=0 && j==M_.exo_nbr
|
||||
annotation('textbox', [0.1,0,0.35,0.05],'String', 'Linear','Color','Blue','horizontalalignment','center','interpreter','none');
|
||||
annotation('textbox', [0.55,0,0.35,0.05],'String', 'Piecewise','Color','Red','horizontalalignment','center','interpreter','none');
|
||||
dyn_saveas(hfig,[GraphDirectoryName filesep M_.fname,'_smoothedshocks_occbin',int2str(ifig)],options_.nodisplay,options_.graph_format);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
function [filtered_errs, resids, Emat, stateval, error_code] = IVF_core(M_,oo_,options_,err_index,filtered_errs_init,my_obs_list,obs,init_val)
|
||||
% function [filtered_errs, resids, Emat, stateval] = IVF_core(M_,oo_,options_,err_index,filtered_errs_init,my_obs_list,obs,init_val)
|
||||
% Computes thre
|
||||
%
|
||||
% Outputs:
|
||||
% - filtered_errs [T by N_obs] filtered shocks
|
||||
% - resids [T by N_obs] residuals
|
||||
% - Emat [N by N_obs by T] response matrix of endogenous variables to shocks at each point in time
|
||||
% - stateval [T by N] vector of endogenous variables
|
||||
% - error_code [4 by 1] error code
|
||||
%
|
||||
% Inputs
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
% - options_ [structure] Matlab's structure describing the current options (options_).
|
||||
% - err_index [double] index of shocks with strictly positive variance in M_.exo_names
|
||||
% - filtered_errs_init [T by N_obs] initial values for the shocks
|
||||
% - my_obs_list [cell] names of observables
|
||||
% - obs [T by N_obs] observed data
|
||||
% - init_val [N by 1] initial value of endogenous variables
|
||||
|
||||
% Original authors: Pablo Cuba-Borda, Luca Guerrieri, Matteo Iacoviello and Molin Zhong
|
||||
% Original file downloaded from:
|
||||
% http://www.lguerrieri.com/jae-replication.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Pablo Cuba-Borda, Luca Guerrieri, and Matteo Iacoviello (2019): "Likelihood evaluation of models
|
||||
% with occasionally binding constraints", Journal of Applied Econometrics,
|
||||
% 34(7), 1073-1085
|
||||
|
||||
|
||||
%-------------------------------------
|
||||
% Filter shocks
|
||||
%-------------------------------------
|
||||
|
||||
[sample_length, n_obs]= size(obs);
|
||||
nerrs = size(err_index,1);
|
||||
if nargin<8
|
||||
init_val = zeros(M_.endo_nbr,1);
|
||||
end
|
||||
|
||||
resids = zeros(sample_length,nerrs);
|
||||
stateval = zeros(sample_length,M_.endo_nbr);
|
||||
Emat = zeros(M_.endo_nbr,nerrs,sample_length);
|
||||
error_code = zeros(4,1);
|
||||
%solver options (set locally)
|
||||
options_.solve_algo = options_.occbin.solver.solve_algo;
|
||||
options_.solve_tolf = options_.occbin.solver.solve_tolf;
|
||||
options_.solve_tolx = options_.occbin.solver.solve_tolx;
|
||||
options_.options.steady.maxit = options_.occbin.solver.maxit;
|
||||
options_.jacobian_flag=1;
|
||||
|
||||
opts_simul = options_.occbin.simul;
|
||||
opts_simul.curb_retrench = options_.occbin.likelihood.curb_retrench;
|
||||
opts_simul.maxit = options_.occbin.likelihood.maxit;
|
||||
opts_simul.waitbar = false;
|
||||
opts_simul.periods = options_.occbin.likelihood.periods;
|
||||
opts_simul.check_ahead_periods = options_.occbin.likelihood.check_ahead_periods;
|
||||
opts_simul.periodic_solution = options_.occbin.likelihood.periodic_solution;
|
||||
opts_simul.restrict_state_space = options_.occbin.likelihood.restrict_state_space;
|
||||
opts_simul.piecewise_only = 1;
|
||||
|
||||
filtered_errs=zeros(sample_length,n_obs);
|
||||
|
||||
if options_.occbin.likelihood.waitbar
|
||||
hh = dyn_waitbar(0,'IVF_core: Filtering the shocks');
|
||||
set(hh,'Name','IVF_core: Filtering the shocks.');
|
||||
end
|
||||
|
||||
for this_period=1:sample_length
|
||||
if options_.occbin.likelihood.waitbar
|
||||
dyn_waitbar(this_period/sample_length, hh, sprintf('Period %u of %u', this_period,sample_length));
|
||||
end
|
||||
current_obs = obs(this_period,:);
|
||||
init_val_old = init_val;
|
||||
|
||||
inan = ~isnan(current_obs);
|
||||
current_obs = current_obs(inan);
|
||||
obs_list = my_obs_list(inan);
|
||||
opts_simul.varobs_id=options_.varobs_id(inan)';
|
||||
opts_simul.exo_pos=err_index(inan); %err_index is predefined mapping from observables to shocks
|
||||
opts_simul.endo_init = init_val_old;
|
||||
opts_simul.SHOCKS = filtered_errs_init(this_period,inan);
|
||||
% [ err_vals_out, exitflag ] = csolve(@(err_vals) occbin.match_function(...
|
||||
% err_vals, obs_list,current_obs, opts_simul, M_,oo_,options_),...
|
||||
% err0',@(err_vals) occbin.match_function(...
|
||||
% err_vals, obs_list,current_obs, opts_simul, M_,oo_,options_),options_.solve_tolf,options_.occbin.solver.maxit);
|
||||
[err_vals_out, exitflag] = dynare_solve(@occbin.match_function, filtered_errs_init(this_period,inan)', options_, obs_list,current_obs, opts_simul, M_,oo_,options_);
|
||||
|
||||
if exitflag
|
||||
filtered_errs=NaN;
|
||||
error_code(1) = 304;
|
||||
error_code(4) = 1000;
|
||||
if options_.occbin.likelihood.waitbar; dyn_waitbar_close(hh); end
|
||||
return
|
||||
end
|
||||
filtered_errs(this_period,inan)=err_vals_out';
|
||||
|
||||
opts_simul.SHOCKS = err_vals_out;
|
||||
|
||||
[ resids(this_period,inan), ~, stateval(this_period,:), Emat(:,inan,this_period), M_] = occbin.match_function(...
|
||||
err_vals_out,obs_list,current_obs,opts_simul, M_,oo_,options_);
|
||||
init_val = stateval(this_period,:); %update
|
||||
if max(abs(err_vals_out))>1e8
|
||||
error_code(1) = 306;
|
||||
error_code(4) = max(abs(err_vals_out))/1000;
|
||||
filtered_errs=NaN;
|
||||
if options_.occbin.likelihood.waitbar; dyn_waitbar_close(hh); end
|
||||
return
|
||||
end
|
||||
if max(abs(resids(this_period,:)))>0.001
|
||||
disp_verbose('IVF_core: I am stopping because match_function could not find the shocks that',options_.verbosity)
|
||||
disp_verbose('IVF_core: solve for the model''s observed variables',options_.verbosity)
|
||||
filtered_errs=NaN;
|
||||
error_code(1) = 303;
|
||||
error_code(4) = max(abs(resids(this_period,:)))*100;
|
||||
if options_.occbin.likelihood.waitbar; dyn_waitbar_close(hh); end
|
||||
return
|
||||
end
|
||||
end
|
||||
if options_.occbin.likelihood.waitbar
|
||||
dyn_waitbar_close(hh);
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,198 @@
|
|||
function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,Model,DynareOptions,BayesInfo,DynareResults, atT, innov] = IVF_posterior(xparam1,...
|
||||
dataset_,obs_info,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults)
|
||||
% function [fval,info,exit_flag,DLIK,Hess,SteadyState,trend_coeff,Model,DynareOptions,BayesInfo,DynareResults, atT, innov] = IVF_posterior(xparam1,...
|
||||
% dataset_,obs_info,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults)
|
||||
% Computes Likelihood with inversion filter
|
||||
%
|
||||
% INPUTS
|
||||
% - xparam1 [double] current values for the estimated parameters.
|
||||
% - dataset_ [structure] dataset after transformations
|
||||
% - DynareOptions [structure] Matlab's structure describing the current options (options_).
|
||||
% - Model [structure] Matlab's structure describing the model (M_).
|
||||
% - EstimatedParameters [structure] characterizing parameters to be estimated
|
||||
% - BayesInfo [structure] describing the priors
|
||||
% - BoundsInfo [structure] containing prior bounds
|
||||
% - DynareResults [structure] Matlab's structure containing the results (oo_).
|
||||
%
|
||||
% OUTPUTS
|
||||
% - fval [double] scalar, value of the likelihood or posterior kernel.
|
||||
% - info [integer] 4×1 vector, informations resolution of the model and evaluation of the likelihood.
|
||||
% - exit_flag [integer] scalar, equal to 1 (no issues when evaluating the likelihood) or 0 (not able to evaluate the likelihood).
|
||||
% - DLIK [double] Empty array.
|
||||
% - Hess [double] Empty array.
|
||||
% - SteadyState [double] Empty array.
|
||||
% - trend [double] Empty array.
|
||||
% - Model [struct] Updated Model structure described in INPUTS section.
|
||||
% - DynareOptions [struct] Updated DynareOptions structure described in INPUTS section.
|
||||
% - BayesInfo [struct] See INPUTS section.
|
||||
% - DynareResults [struct] Updated DynareResults structure described in INPUTS section.
|
||||
% - 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).
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
DLIK=[];
|
||||
Hess=[];
|
||||
trend_coeff = [];
|
||||
obs = obs_info.rawdata;
|
||||
obs_list = DynareOptions.varobs(:);
|
||||
exit_flag = 1;
|
||||
|
||||
|
||||
if size(xparam1,1)<size(xparam1,2)
|
||||
xparam1=xparam1';
|
||||
end
|
||||
|
||||
|
||||
%------------------------------------------------------------------------------
|
||||
% 1. Get the structural parameters & define penalties
|
||||
%------------------------------------------------------------------------------
|
||||
|
||||
if ~isempty(xparam1)
|
||||
Model = set_all_parameters(xparam1,EstimatedParameters,Model);
|
||||
[fval,info,exit_flag,Q,H]=check_bounds_and_definiteness_estimation(xparam1, Model, EstimatedParameters, BoundsInfo);
|
||||
if info(1)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
err_index=DynareOptions.occbin.likelihood.IVF_shock_observable_mapping; % err_index= find(diag(Model.Sigma_e)~=0);
|
||||
COVMAT1 = Model.Sigma_e(err_index,err_index);
|
||||
|
||||
% Linearize the model around the deterministic steady state and extract the matrices of the state equation (T and R).
|
||||
[T,R,SteadyState,info,Model,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict');
|
||||
|
||||
% Return, with endogenous penalty when possible, if dynare_resolve issues an error code (defined in resol).
|
||||
if info(1)
|
||||
if info(1) == 3 || info(1) == 4 || info(1) == 5 || info(1)==6 ||info(1) == 19 ||...
|
||||
info(1) == 20 || info(1) == 21 || info(1) == 23 || info(1) == 26 || ...
|
||||
info(1) == 81 || info(1) == 84 || info(1) == 85 || info(1) == 86
|
||||
%meaningful second entry of output that can be used
|
||||
fval = Inf;
|
||||
info(4) = info(2);
|
||||
exit_flag = 0;
|
||||
return
|
||||
else
|
||||
fval = Inf;
|
||||
info(4) = 0.1;
|
||||
exit_flag = 0;
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
%---------------------------------------------
|
||||
% Calculate likelihood
|
||||
%---------------------------------------------
|
||||
sample_length = size(obs,1);
|
||||
filtered_errs_init = zeros(sample_length,sum(err_index));
|
||||
|
||||
[filtered_errs, resids, Emat, stateval, info] = occbin.IVF_core(Model,DynareResults,DynareOptions,err_index,filtered_errs_init,obs_list,obs);
|
||||
if info(1)
|
||||
fval = Inf;
|
||||
exit_flag = 0;
|
||||
return
|
||||
end
|
||||
nobs=size(filtered_errs,1);
|
||||
|
||||
|
||||
%-------------------------------------
|
||||
% Calculate the selection matrix
|
||||
%-------------------------------------
|
||||
|
||||
iobs=DynareOptions.varobs_id';
|
||||
|
||||
likei=NaN(nobs,1);
|
||||
if ~any(any(isnan(obs)))
|
||||
log_det_COV=log(det(COVMAT1));
|
||||
for t = 1:nobs
|
||||
Gmat1 = Emat(iobs,:,t);
|
||||
log_det_jacobian = log_det_COV + 2*log(abs(det(Gmat1)));
|
||||
trace_term = filtered_errs(t,:)/(COVMAT1)*filtered_errs(t,:)';
|
||||
|
||||
likei(t,1) = log_det_jacobian + trace_term;
|
||||
end
|
||||
likei=likei+length(iobs)*log(2*pi);
|
||||
else
|
||||
for t = 1:nobs
|
||||
inan=~isnan(obs(t,:));
|
||||
Gmat1 = Emat(iobs(inan),inan,t);
|
||||
log_det_jacobian = log(det(COVMAT1(inan,inan))) + 2*log(abs(det(Gmat1)));
|
||||
trace_term = filtered_errs(t,inan)/(COVMAT1(inan,inan))*filtered_errs(t,inan)';
|
||||
|
||||
likei(t,1) = log_det_jacobian + trace_term + length(iobs(inan))*log(2*pi);
|
||||
end
|
||||
end
|
||||
|
||||
like = 0.5*sum(likei(DynareOptions.presample+1:end));
|
||||
|
||||
if isinf(like)
|
||||
fval = Inf;
|
||||
info(1) = 301;
|
||||
info(4) = 1000;
|
||||
exit_flag = 0;
|
||||
return
|
||||
elseif isnan(like)
|
||||
fval = Inf;
|
||||
info(1) = 302;
|
||||
info(4) = 1000;
|
||||
exit_flag = 0;
|
||||
return
|
||||
end
|
||||
|
||||
maxresid = max(abs(resids(:)));
|
||||
if maxresid>1e-3
|
||||
disp_verbose('Penalize failure of residuals to be zero',options_.verbosity)
|
||||
fval = Inf;
|
||||
info(1) = 303;
|
||||
info(4) = sum(resids(:).^2);
|
||||
exit_flag = 0;
|
||||
return
|
||||
end
|
||||
|
||||
if ~isempty(xparam1)
|
||||
prior = -priordens(xparam1,BayesInfo.pshape,BayesInfo.p6,BayesInfo.p7,BayesInfo.p3,BayesInfo.p4);
|
||||
else
|
||||
prior = 0;
|
||||
end
|
||||
if prior == Inf
|
||||
% If parameters outside prior bound, minus prior density is very large
|
||||
fval = Inf;
|
||||
info(4) = 1000;
|
||||
exit_flag = 0;
|
||||
return
|
||||
end
|
||||
|
||||
%---------------------------------------------
|
||||
% Calculate posterior
|
||||
%---------------------------------------------
|
||||
|
||||
% remember that the likelihood has already been multiplied by -1
|
||||
% hence, posterior is -1 times the log of the prior
|
||||
fval = like+prior;
|
||||
atT = stateval(:,DynareResults.dr.order_var)';
|
||||
innov = zeros(Model.exo_nbr,sample_length);
|
||||
innov(diag(Model.Sigma_e)~=0,:)=filtered_errs';
|
||||
updated_variables = atT*nan;
|
||||
BayesInfo.mf = BayesInfo.smoother_var_list(BayesInfo.smoother_mf);
|
||||
|
||||
|
||||
initDynareOptions=DynareOptions;
|
||||
DynareOptions.nk=[]; %unset options_.nk and reset it later
|
||||
[DynareResults]=store_smoother_results(Model,DynareResults,DynareOptions,BayesInfo,dataset_,obs_info,atT,innov,[],updated_variables,DynareResults.dr.ys,zeros(length(DynareOptions.varobs_id),1));
|
||||
DynareOptions=initDynareOptions;
|
|
@ -0,0 +1,146 @@
|
|||
function [TT, RR, CC, regime_history] = check_regimes(TT, RR, CC, opts_regime, M_, oo_, options_)
|
||||
%-function function [TT, RR, CC, regime_history] = check_regimes(TT, RR, CC, opts_regime, M_, oo_, options_)
|
||||
%
|
||||
% INPUTS
|
||||
% - TT [N by N] transition matrix of state space
|
||||
% - RR [N by N_exo] shock impact matrix of state space
|
||||
% - CC [N by 1] constant of state space
|
||||
% - opts_regime_ [structure] structure describing the regime
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - options_ [structure] Matlab's structure describing the current options
|
||||
%
|
||||
% OUTPUTS
|
||||
% - TT [N by N] transition matrix of state space for each period
|
||||
% - RR [N by N_exo by T] shock impact matrix of state space for each period
|
||||
% - CC [N by N_exo by T] constant of state space for each period
|
||||
% - regime_history [structure] contains the regime history
|
||||
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
binding_indicator = opts_regime.binding_indicator;
|
||||
regime_history = opts_regime.regime_history;
|
||||
gend = size(binding_indicator,1);
|
||||
if gend ==0
|
||||
gend = length(regime_history)+1;
|
||||
end
|
||||
number_of_constraints = length(M_.occbin.constraint);
|
||||
|
||||
if number_of_constraints==1
|
||||
base_regime.regime = 0;
|
||||
base_regime.regimestart = 1;
|
||||
else
|
||||
base_regime.regime1 = 0;
|
||||
base_regime.regimestart1 = 1;
|
||||
base_regime.regime2 = 0;
|
||||
base_regime.regimestart2 = 1;
|
||||
end
|
||||
|
||||
if isempty(regime_history)
|
||||
% set default unconstrained regimes
|
||||
regime_history = base_regime;
|
||||
regime_history(2:gend-1) = base_regime;
|
||||
end
|
||||
init_=0;
|
||||
if ndim(TT)==2
|
||||
CC = zeros([size(RR,1),gend ]);
|
||||
TT = repmat(TT, [1 1 gend]);
|
||||
RR = repmat(RR, [1 1 gend]);
|
||||
init_=1;
|
||||
end
|
||||
opts_simul = options_.occbin.simul;
|
||||
opts_simul.full_output=0;
|
||||
opts_simul.piecewise_only=1;
|
||||
|
||||
for tp=1:gend-1
|
||||
change_it = 0;
|
||||
if ~isempty(binding_indicator)
|
||||
if number_of_constraints==1
|
||||
if regime_history(tp).regime(1) > binding_indicator(tp+1,1)
|
||||
regime_history(tp).regime = [0 regime_history(tp).regime];
|
||||
regime_history(tp).regimestart = [1 regime_history(tp).regimestart+1];
|
||||
change_it = 1;
|
||||
end
|
||||
if regime_history(tp).regime(1) < binding_indicator(tp+1,1)
|
||||
regime_history(tp).regime = [1 regime_history(tp).regime];
|
||||
regime_history(tp).regimestart = [1 regime_history(tp).regimestart+1];
|
||||
change_it = 1;
|
||||
end
|
||||
|
||||
else
|
||||
if regime_history(tp).regime1(1) > binding_indicator(tp+1,1)
|
||||
regime_history(tp).regime1 = [0 regime_history(tp).regime1];
|
||||
regime_history(tp).regimestart1 = [1 regime_history(tp).regimestart1+1];
|
||||
change_it = 1;
|
||||
end
|
||||
if regime_history(tp).regime1(1) < binding_indicator(tp+1,1)
|
||||
regime_history(tp).regime1 = [1 regime_history(tp).regime1];
|
||||
regime_history(tp).regimestart1 = [1 regime_history(tp).regimestart1+1];
|
||||
change_it = 1;
|
||||
end
|
||||
if regime_history(tp).regime2(1) > binding_indicator(tp+1,2)
|
||||
regime_history(tp).regime2 = [0 regime_history(tp).regime2];
|
||||
regime_history(tp).regimestart2 = [1 regime_history(tp).regimestart2+1];
|
||||
change_it = 1;
|
||||
end
|
||||
if regime_history(tp).regime2(1) < binding_indicator(tp+1,2)
|
||||
regime_history(tp).regime2 = [1 regime_history(tp).regime2];
|
||||
regime_history(tp).regimestart2 = [1 regime_history(tp).regimestart2+1];
|
||||
change_it = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if change_it || init_
|
||||
check_it = 0;
|
||||
jt=1;
|
||||
while jt<=tp-1 && check_it==0
|
||||
check_it = isequal(regime_history(tp),regime_history(jt));
|
||||
jt = jt+1;
|
||||
end
|
||||
if ~check_it && isequal(regime_history(tp),base_regime) && init_
|
||||
check_it = true;
|
||||
jt=1;
|
||||
end
|
||||
|
||||
if check_it %|| tp==1 % the matrices for regime have been already computed
|
||||
TT(:,:,tp+1) = TT(:,:,jt);
|
||||
RR(:,:,tp+1) = RR(:,:,jt);
|
||||
CC(:,tp+1) = CC(:,jt);
|
||||
else
|
||||
if number_of_constraints==1
|
||||
nperi = max(regime_history(tp).regimestart);
|
||||
else
|
||||
nperi = max([regime_history(tp).regimestart1 regime_history(tp).regimestart2]);
|
||||
end
|
||||
|
||||
opts_simul.endo_init_=zeros(size(RR,1),1);
|
||||
opts_simul.init_binding_indicator=[];
|
||||
opts_simul.init_regime=regime_history(tp);
|
||||
opts_simul.SHOCKS=zeros(1,size(RR,2));
|
||||
opts_simul.maxit=1;
|
||||
opts_simul.periods=nperi;
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, ~, ss] = occbin.solver(M_,oo_,options_);
|
||||
TT(:,:,tp+1) = ss.T(oo_.dr.order_var,oo_.dr.order_var);
|
||||
RR(:,:,tp+1) = ss.R(oo_.dr.order_var,:);
|
||||
CC(:,tp+1) = ss.C(oo_.dr.order_var);
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,72 @@
|
|||
function [A,B,ys,info,M_,oo_,TT, RR, CC, A0, B0] ...
|
||||
= dynare_resolve(M_,options_,oo_,regime_history, reduced_state_space, A, B)
|
||||
% function [A,B,ys,info,M_,options_,oo_,TT, RR, CC, A0, B0] ...
|
||||
% = dynare_resolve(M_,options_,oo_,regime_history, reduced_state_space, A, B)
|
||||
% Computes the linear approximation and the matrices A and B of the
|
||||
% transition equation. Mirrors dynare_resolve
|
||||
%
|
||||
% Inputs:
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - reduced_state_space [string]
|
||||
% - A [double] State transition matrix
|
||||
% - B [double] shock impact matrix
|
||||
% Outputs:
|
||||
% - A [double] State transition matrix (potentially for restricted state space)
|
||||
% - B [double] shock impact matrix (potentially for restricted state space)
|
||||
% - ys [double] vector of steady state values
|
||||
% - info [double] 4 by 1 vector with exit flag and information
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - TT [N by N] transition matrix of state space for each period
|
||||
% - RR [N by N_exo by T] shock impact matrix of state space for each period
|
||||
% - CC [N by N_exo by T] constant of state space for each period
|
||||
% - A0 [double] State transition matrix (unrestricted state space)
|
||||
% - B0 [double] shock impact matrix (unrestricted state space)
|
||||
|
||||
% Copyright (C) 2001-2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
if nargin<6
|
||||
[A,B,ys,info,M_,oo_] = dynare_resolve(M_,options_,oo_);
|
||||
else
|
||||
ys = oo_.dr.ys;
|
||||
info = 0;
|
||||
end
|
||||
if ~info(1) && nargin>4 && ~isempty(regime_history)
|
||||
opts_regime.regime_history=regime_history;
|
||||
opts_regime.binding_indicator=[];
|
||||
[TT, RR, CC] = ...
|
||||
occbin.check_regimes(A, B, [], opts_regime, M_,oo_,options_);
|
||||
else
|
||||
TT=A;
|
||||
RR=B;
|
||||
CC=zeros(size(A,1),1);
|
||||
end
|
||||
|
||||
A0=A;
|
||||
B0=B;
|
||||
if ~info(1) && nargin>4 && ischar(reduced_state_space) && ~isempty(reduced_state_space)
|
||||
iv = oo_.dr.restrict_var_list;
|
||||
A=A(iv,iv);
|
||||
B=B(iv,:);
|
||||
TT=TT(iv,iv,:);
|
||||
RR=RR(iv,:,:);
|
||||
CC=CC(iv,:);
|
||||
end
|
|
@ -0,0 +1,69 @@
|
|||
function [h_minus_1, h, h_plus_1, h_exo, resid] = get_deriv(M_, ys_)
|
||||
% function [h_minus_1, h, h_plus_1, h_exo, resid] = get_deriv(M_, ys_)
|
||||
% Computes dynamic Jacobian and writes it to conformable matrices
|
||||
%
|
||||
% INPUTS
|
||||
% - M_ [struct] Definition of the model.
|
||||
% - ys vector steady state
|
||||
%
|
||||
% OUTPUTS
|
||||
% - h_minus_1 [N by N] derivative matrix with respect to lagged endogenous variables
|
||||
% - h [N by N] derivative matrix with respect to contemporanous endogenous variables
|
||||
% - h_plus_1 [N by N] derivative matrix with respect to leaded endogenous variables
|
||||
% - h_exo [N by N_exo] derivative matrix with respect to exogenous variables
|
||||
% - resid [N by 1] vector of residuals
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
x = zeros(M_.maximum_lag + M_.maximum_lead + 1,M_.exo_nbr);
|
||||
|
||||
iyv = M_.lead_lag_incidence';
|
||||
iyr0 = find(iyv(:)) ;
|
||||
z=repmat(ys_,1,M_.maximum_lag + M_.maximum_lead + 1);
|
||||
|
||||
[resid,g1]=feval([M_.fname,'.dynamic'],z(iyr0),x, M_.params, ys_, M_.maximum_exo_lag+1);
|
||||
|
||||
% Initialize matrices
|
||||
h_minus_1=zeros(M_.endo_nbr);
|
||||
h = h_minus_1;
|
||||
h_plus_1 = h_minus_1;
|
||||
|
||||
% build h_minus_1
|
||||
if M_.maximum_lag
|
||||
lag_columns=find(iyv(:,1));
|
||||
n_lag_columns=length(lag_columns);
|
||||
h_minus_1(:,lag_columns) = g1(:,1:n_lag_columns);
|
||||
else
|
||||
n_lag_columns=0;
|
||||
end
|
||||
|
||||
% build h
|
||||
contemporaneous_columns=find(iyv(:,M_.maximum_lag+1));
|
||||
n_contemporaneous_columns = length(contemporaneous_columns);
|
||||
h(:,contemporaneous_columns) = g1(:,1+n_lag_columns:n_lag_columns+n_contemporaneous_columns);
|
||||
|
||||
%build h_plus_1
|
||||
if M_.maximum_lead
|
||||
lead_columns=find(iyv(:,end));
|
||||
n_lead_columns = length(lead_columns);
|
||||
h_plus_1(:,lead_columns) = g1(:,n_lag_columns+n_contemporaneous_columns+1:n_lag_columns+n_contemporaneous_columns+n_lead_columns);
|
||||
else
|
||||
n_lead_columns=0;
|
||||
end
|
||||
|
||||
h_exo =g1(:,n_lag_columns+n_contemporaneous_columns+n_lead_columns+1:end);
|
|
@ -0,0 +1,57 @@
|
|||
function M_ = get_info(M_)
|
||||
%function M_ = get_info(M_)
|
||||
% Parses constraint to clean spaces and provide information on endogenous variables
|
||||
% involved in constraints
|
||||
%
|
||||
% INPUTS
|
||||
% - M_ [struct] Definition of the model.
|
||||
%
|
||||
% OUTPUTS
|
||||
% - M_ [struct] Definition of the model.
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
delimiters = char(',',';','(',')','+','-','^','*','/','>','<','=');
|
||||
iwish=0;
|
||||
indx_=[];
|
||||
wish_list='';
|
||||
M_.occbin.constraint_nbr=length(M_.occbin.constraint);
|
||||
for k=1:M_.occbin.constraint_nbr
|
||||
%get rid of redundant spaces;
|
||||
M_.occbin.constraint(k).bind=strrep(M_.occbin.constraint(k).bind,' ','');
|
||||
M_.occbin.constraint(k).relax=strrep(M_.occbin.constraint(k).relax,' ','');
|
||||
bind_clean = occbin.tokenize(M_.occbin.constraint(k).bind,delimiters);
|
||||
relax_clean = occbin.tokenize(M_.occbin.constraint(k).relax,delimiters);
|
||||
for j=1:M_.endo_nbr
|
||||
tmp=ismember(M_.endo_names{j},bind_clean);
|
||||
tmp1=ismember(M_.endo_names{j},relax_clean);
|
||||
if tmp || tmp1
|
||||
iwish = iwish+1;
|
||||
indx_(iwish)=j;
|
||||
if iwish>1
|
||||
wish_list = char(wish_list,M_.endo_names{j});
|
||||
else
|
||||
wish_list = M_.endo_names{j};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
M_.occbin.wish_list.endo = wish_list;
|
||||
M_.occbin.wish_list.iendo = indx_;
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
function [p,q]=get_pq(dr)
|
||||
% function [p,q]=get_pq(dr)
|
||||
% Output decision rule matrices p and q in declaration order
|
||||
%
|
||||
% INPUTS
|
||||
% - dr [struct] decision rules
|
||||
%
|
||||
% OUTPUTS
|
||||
% - p [N by N] transition matrix ghu in declaration order
|
||||
% - q [N by N_exo] shock response matrix ghx in declaration order
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
nvars = size(dr.ghx,1);
|
||||
p = zeros(nvars);
|
||||
p(dr.order_var,dr.state_var) = dr.ghx;
|
||||
q = dr.ghu(dr.inv_order_var,:);
|
|
@ -0,0 +1,156 @@
|
|||
function graph(M_, options_, options_occbin_, oo_, var_list)
|
||||
% function graph(M_, options_, options_occbin_, oo_, var_list)
|
||||
%
|
||||
% Inputs:
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
% - options_occbin_ [structure] Matlab's structure containing Occbin options
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - var_list [char] list of the variables to plot
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
options_ = occbin.set_option(options_,options_occbin_,'graph.steady_state');
|
||||
|
||||
if ~exist([M_.dname '/graphs'],'dir')
|
||||
mkdir(M_.dname,'graphs');
|
||||
end
|
||||
|
||||
fidTeX=write_latex_header(M_,options_);
|
||||
|
||||
if isempty(var_list)
|
||||
var_list = M_.endo_names(1:M_.orig_endo_nbr);
|
||||
end
|
||||
|
||||
%get endogenous variables
|
||||
[i_var, number_of_plots_to_draw_endo, index_uniques] = varlist_indices(var_list, M_.endo_names, 1);
|
||||
var_list_plots=var_list(index_uniques);
|
||||
var_list_TeX = M_.endo_names_tex(i_var);
|
||||
|
||||
data_to_plot(:,:,1)=oo_.occbin.piecewise(:,i_var);
|
||||
if isfield(oo_.occbin,'linear')
|
||||
data_to_plot(:,:,2)=oo_.occbin.linear(:,i_var);
|
||||
legend_list = {'Piecewise Linear','Linear'};
|
||||
else
|
||||
legend_list = {'Piecewise Linear'};
|
||||
end
|
||||
|
||||
nperiods=size(data_to_plot,1);
|
||||
ndim=size(data_to_plot,3);
|
||||
|
||||
if ~options_.occbin.graph.steady_state
|
||||
data_to_plot=data_to_plot-repmat(oo_.occbin.ys(i_var)',nperiods,1,ndim);
|
||||
end
|
||||
|
||||
%get exogenous variables
|
||||
[i_var_exo, number_of_plots_to_draw_exo, index_uniques] = varlist_indices(var_list, M_.exo_names, 1);
|
||||
var_list_plots=[var_list_plots; var_list(index_uniques)];
|
||||
var_list_TeX = [var_list_TeX; M_.exo_names_tex(i_var_exo)];
|
||||
|
||||
if number_of_plots_to_draw_exo>0
|
||||
exo_index=NaN(number_of_plots_to_draw_exo);
|
||||
for ii=1:length(i_var_exo)
|
||||
temp_index=find(oo_.occbin.exo_pos==i_var_exo(ii));
|
||||
if ~isempty(temp_index)
|
||||
exo_index(ii)=temp_index;
|
||||
else
|
||||
error('%s was not part of the shocks for Occbin.', var_list{i_var_exo(ii)});
|
||||
end
|
||||
end
|
||||
data_to_plot(:,end+1:end+number_of_plots_to_draw_exo,1)=[oo_.occbin.shocks_sequence(:,exo_index); zeros(nperiods-size(oo_.occbin.shocks_sequence,1),number_of_plots_to_draw_exo)];
|
||||
data_to_plot(:,end+1:end+number_of_plots_to_draw_exo,2)=NaN;
|
||||
end
|
||||
|
||||
[nbplt,nr,nc,lr,lc,nstar] = pltorg(number_of_plots_to_draw_endo+number_of_plots_to_draw_exo);
|
||||
|
||||
for fig = 1:nbplt
|
||||
hh = dyn_figure(options_.nodisplay,'Name',['Occbin simulated paths, figure ' int2str(fig)]);
|
||||
for plt = 1:nstar
|
||||
if fig==nbplt && ~lr==0
|
||||
subplot(lr,lc,plt);
|
||||
else
|
||||
subplot(nr,nc,plt);
|
||||
end
|
||||
h_zero=plot([1 nperiods],[0 0],'--k','linewidth',0.5);
|
||||
hold on
|
||||
h1=plot(1:nperiods,data_to_plot(:,(fig-1)*nstar+plt,1),'b-','linewidth',2);
|
||||
if ndim==2 && (fig-1)*nstar+plt<=number_of_plots_to_draw_endo
|
||||
h2=plot(1:nperiods,data_to_plot(:,(fig-1)*nstar+plt,2),'r--','linewidth',2); hold on
|
||||
end
|
||||
hold off
|
||||
|
||||
max_y = max(max(data_to_plot(:,(fig-1)*nstar+plt,:)));
|
||||
min_y = min(min(data_to_plot(:,(fig-1)*nstar+plt,:)));
|
||||
|
||||
y_bottom = min_y - .01*abs(min_y);
|
||||
|
||||
y_top = max_y + 0.01*abs(max_y);
|
||||
if y_bottom==y_top
|
||||
y_top=y_bottom+1;
|
||||
end
|
||||
axis([1 nperiods y_bottom y_top])
|
||||
remove_fractional_xticks
|
||||
if plt==1
|
||||
if ndim==2
|
||||
legend([h1,h2],legend_list,'box','off')
|
||||
else
|
||||
legend([h1],legend_list,'box','off')
|
||||
end
|
||||
end
|
||||
if options_.TeX
|
||||
title(['$' var_list_TeX{(fig-1)*nstar+plt,:} '$'],'Interpreter','latex');
|
||||
else
|
||||
title(deblank(var_list_plots((fig-1)*nstar+plt,:)),'Interpreter','none');
|
||||
end
|
||||
if number_of_plots_to_draw_endo+number_of_plots_to_draw_exo==(fig-1)*nstar+plt
|
||||
break
|
||||
end
|
||||
end
|
||||
dyn_saveas(hh,[M_.dname, '/graphs/' M_.fname '_occbin_' int2str(fig)],options_.nodisplay,options_.graph_format);
|
||||
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fprintf(fidTeX,'\\begin{figure}[H]\n');
|
||||
fprintf(fidTeX,'\\centering \n');
|
||||
if fig==nbplt
|
||||
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s_occbin_%s}\n',options_.figures.textwidth*min(plt/nc,1),[M_.dname, '/graphs/' M_.fname],int2str(fig));
|
||||
else
|
||||
fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s_occbin_%s}\n',options_.figures.textwidth*min(plt/lc,1),[M_.dname, '/graphs/' M_.fname],int2str(fig));
|
||||
end
|
||||
fprintf(fidTeX,'\\caption{Simulated time paths over time. Blue solid line: taking occasionally binding constraint into account. Red dashed line: ignoring constraint.}\n');
|
||||
fprintf(fidTeX,'\\label{Fig:occbin:%s}\n', int2str(fig));
|
||||
fprintf(fidTeX,'\\end{figure}\n');
|
||||
fprintf(fidTeX,' \n');
|
||||
end
|
||||
end
|
||||
|
||||
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fprintf(fidTeX,' \n');
|
||||
fprintf(fidTeX,'%% End Of TeX file. \n');
|
||||
fclose(fidTeX);
|
||||
end
|
||||
|
||||
|
||||
function fidTeX=write_latex_header(M_,options_)
|
||||
|
||||
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
|
||||
fidTeX = fopen([M_.dname, '/graphs/' M_.fname '_occbin.tex'],'w');
|
||||
fprintf(fidTeX,'%% TeX eps-loader file generated by occbin.make_chart.m (Dynare).\n');
|
||||
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
|
||||
fprintf(fidTeX,' \n');
|
||||
else
|
||||
fidTeX =[];
|
||||
end
|
|
@ -0,0 +1,75 @@
|
|||
function [M_, oo_, options_] = initialize(M_,oo_,options_)
|
||||
% function [M_, oo_, options_] = initialize(M_,oo_,options_)
|
||||
% Initializes run of Occbin: sets default options, parses constraints, creates
|
||||
% eval_difference-file
|
||||
%
|
||||
% INPUT:
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
%
|
||||
% OUTPUT:
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
options_.occbin = struct();
|
||||
options_.occbin = occbin.set_default_options(options_.occbin, M_);
|
||||
|
||||
oo_.dr=set_state_space(oo_.dr,M_,options_);
|
||||
|
||||
M_ = occbin.get_info(M_);
|
||||
|
||||
if M_.occbin.constraint_nbr>2
|
||||
error('Occbin: Only up to two constraints are supported')
|
||||
end
|
||||
for k=1:M_.occbin.constraint_nbr
|
||||
M_.occbin.constraint(k).bind_difference = occbin.process_constraint(M_.occbin.constraint(k).bind,'_difference',M_.endo_names,false,M_.param_names);
|
||||
M_.occbin.constraint(k).bind_error = occbin.process_error_constraint(M_.occbin.constraint(k).bind_difference);
|
||||
if isempty(M_.occbin.constraint(k).relax)
|
||||
M_.occbin.constraint(k).relax_difference = ['~binding.constraint_',int2str(k)];
|
||||
else
|
||||
M_.occbin.constraint(k).relax_difference = occbin.process_constraint(M_.occbin.constraint(k).relax,'_difference',M_.endo_names,false,M_.param_names);
|
||||
end
|
||||
M_.occbin.constraint(k).relax_error = occbin.process_error_constraint(M_.occbin.constraint(k).relax_difference);
|
||||
M_.occbin.constraint(k).pswitch_index = strmatch(M_.occbin.constraint(k).pswitch,M_.param_names);
|
||||
end
|
||||
nwishes_ = size(M_.occbin.wish_list.endo,1);
|
||||
fid = fopen(['+' M_.fname '/eval_difference.m'],'w+');
|
||||
fprintf(fid,'function [binding, relax, err]=eval_difference(zdatalinear_,M_,ys);\n');
|
||||
for i_indx_=1:nwishes_
|
||||
fprintf(fid,'%s_difference=zdatalinear_(:,%i);\r\n',deblank(M_.occbin.wish_list.endo(i_indx_,:)),M_.occbin.wish_list.iendo(i_indx_));
|
||||
end
|
||||
for k=1:M_.occbin.constraint_nbr
|
||||
fprintf(fid,'binding.constraint_%i = %s;\r\n',k,M_.occbin.constraint(k).bind_difference);
|
||||
fprintf(fid,'relax.constraint_%i = %s;\r\n',k,M_.occbin.constraint(k).relax_difference);
|
||||
% fprintf(fid,'try\r\n');
|
||||
|
||||
fprintf(fid,' err.binding_constraint_%i = abs(%s);\r\n',k,M_.occbin.constraint(k).bind_error);
|
||||
fprintf(fid,' err.relax_constraint_%i = abs(%s);\r\n',k,M_.occbin.constraint(k).relax_error);
|
||||
|
||||
% fprintf(fid,'catch\r\n');
|
||||
%
|
||||
% fprintf(fid,' err.newviolvecbool_%i = nan(size(err.newviolvecbool_%i));\r\n',k,k);
|
||||
% fprintf(fid,' err.relaxconstraint_%i = nan(size(err.relaxconstraint_%i));\r\n',k,k);
|
||||
|
||||
% fprintf(fid,'end\r\n');
|
||||
end
|
||||
fclose(fid);
|
|
@ -0,0 +1,427 @@
|
|||
function [a, a1, P, P1, v, T, R, C, regimes_, error_flag, M_, lik, etahat] = kalman_update_algo_1(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,oo_,options_,occbin_options)
|
||||
% function [a, a1, P, P1, v, T, R, C, regimes_, info, M_, lik, etahat] = kalman_update_algo_1(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,oo_,options_,occbin_options)
|
||||
% INPUTS
|
||||
% - a [N by 1] t-1's state estimate
|
||||
% - a1 [N by 2] state predictions made at t-1:t
|
||||
% - P [N by N] t-1's covariance of states
|
||||
% - P1 [N by N by 2] one-step ahead forecast error variance at t-1:t
|
||||
% - data_index: [cell] 1*2 cell of column vectors of indices.
|
||||
% - Z [N_obs ny N] Selector matrix
|
||||
% - v [N_obs by 2] prediction error on observables at t-1:t
|
||||
% - Y: [N_obs by 2] observations at t-1:t
|
||||
% - H [N_obs by 1] vector of measurement error
|
||||
% - QQQ [N_exo by N_exo by 3] covariance matrix of shocks at t-1:t+1
|
||||
% - T0 [N by N] initial state transition matrix
|
||||
% - R0 [N by N_exo] initial shock impact transition matrix
|
||||
% - TT [N by N by 2] state transition matrix at t-1:t
|
||||
% - RR [N by N_exo by 2] shock impact matrix at t-1:t
|
||||
% - CC [N by 2] state space constant state transition matrix at t-1:t
|
||||
% - regimes0 [structure] regime info at t-1:t
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
% - options_ [structure] Matlab's structure describing the current options (options_).
|
||||
% - occbin_options_ [structure] Matlab's structure describing the Occbin options.
|
||||
% - kalman_tol [double] tolerance for reciprocal condition number
|
||||
%
|
||||
% Outputs
|
||||
% - a [N by 2] t-1's state estimate
|
||||
% - a1 [N by 2] state predictions made at t-1:t
|
||||
% - P [N by N by 2] t-1's covariance of states
|
||||
% - P1 [N by N by 2] one-step ahead forecast error variance at t-1:t
|
||||
% - v [N_obs by 2] prediction error on observables at t-1:t
|
||||
% - T [N by N by 2] state transition matrix at t-1:t
|
||||
% - R [N by N_exo by 2] shock impact matrix at t-1:t
|
||||
% - C [N by 2] state space constant state transition matrix at t-1:t
|
||||
% - regimes_ [structure] regime info at t-1:t
|
||||
% - error_flag [integer] error code
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - lik [double] likelihood
|
||||
% - etahat: smoothed shocks
|
||||
%
|
||||
% Notes: The algorithm and implementation is based on Massimo Giovannini,
|
||||
% Philipp Pfeiffer, Marco Ratto (2021), Efficient and robust inference of models with occasionally binding
|
||||
% constraints, Working Papers 2021-03, Joint Research Centre, European Commission
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
warning off
|
||||
|
||||
sto.a=a;
|
||||
sto.a1=a1;
|
||||
sto.P=P;
|
||||
sto.P1=P1;
|
||||
|
||||
number_constr = length(M_.occbin.constraint);
|
||||
base_regime = struct();
|
||||
if number_constr==1
|
||||
base_regime.regime = 0;
|
||||
base_regime.regimestart = 1;
|
||||
else
|
||||
base_regime.regime1 = 0;
|
||||
base_regime.regimestart1 = 1;
|
||||
base_regime.regime2 = 0;
|
||||
base_regime.regimestart2 = 1;
|
||||
end
|
||||
|
||||
mm=size(a,1);
|
||||
%% store info in t=1
|
||||
t=1;
|
||||
di = data_index{t};
|
||||
T = TT(:,:,t);
|
||||
ZZ = Z(di,:);
|
||||
di = data_index{t};
|
||||
F = ZZ*P1(:,:,t)*ZZ' + H(di,di);
|
||||
Fi(di,di,t)=F;
|
||||
sig=sqrt(diag(F));
|
||||
iF(di,di,t) = inv(F./(sig*sig'))./(sig*sig');
|
||||
PZI = P1(:,:,t)*ZZ'*iF(di,di,t);
|
||||
% K(:,di,t) = T*PZI;
|
||||
% L(:,:,t) = T-K(:,di,t)*ZZ;
|
||||
L(:,:,t) = eye(mm)-PZI*ZZ;
|
||||
|
||||
if ~options_.occbin.filter.use_relaxation
|
||||
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
|
||||
else
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, base_regime,'reduced_state_space',T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
|
||||
regimes0(1)=base_regime;
|
||||
end
|
||||
|
||||
|
||||
%% run here the occbin simul
|
||||
opts_simul = occbin_options.opts_simul;
|
||||
opts_simul.SHOCKS = zeros(3,M_.exo_nbr);
|
||||
opts_simul.exo_pos=1:M_.exo_nbr;
|
||||
opts_simul.SHOCKS(1,:) = etahat(:,2)';
|
||||
if opts_simul.restrict_state_space
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=alphahat(:,1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
my_order_var = oo_.dr.order_var(oo_.dr.restrict_var_list);
|
||||
else
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
my_order_var = oo_.dr.order_var;
|
||||
end
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
|
||||
regimes_ = out.regime_history;
|
||||
if number_constr==1
|
||||
myregime = [regimes_.regime];
|
||||
else
|
||||
myregime = [regimes_.regime1 regimes_.regime2];
|
||||
end
|
||||
etahat_hist = {etahat};
|
||||
regime_hist = {regimes0(1)};
|
||||
if number_constr==1
|
||||
regime_end = regimes0(1).regimestart(end);
|
||||
end
|
||||
lik_hist=lik;
|
||||
niter=1;
|
||||
is_periodic=0;
|
||||
if options_.occbin.filter.use_relaxation || isequal(regimes0(1),base_regime)
|
||||
nguess=1;
|
||||
else
|
||||
nguess=0;
|
||||
end
|
||||
newguess=0;
|
||||
|
||||
if any(myregime) || ~isequal(regimes_(1),regimes0(1))
|
||||
while ~isequal(regimes_(1),regimes0(1)) && ~is_periodic && ~out.error_flag && niter<=options_.occbin.likelihood.max_number_of_iterations
|
||||
niter=niter+1;
|
||||
oldstart=1;
|
||||
if number_constr==1 && length(regimes0(1).regimestart)>1
|
||||
oldstart = regimes0(1).regimestart(end);
|
||||
end
|
||||
newstart=1;
|
||||
if number_constr==1 && length(regimes_(1).regimestart)>1
|
||||
newstart = regimes_(1).regimestart(end);
|
||||
end
|
||||
if number_constr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
|
||||
regimestart = max(oldstart+2,round(0.5*(newstart+oldstart)));
|
||||
regimestart = min(regimestart,oldstart+4);
|
||||
if regimestart<=regimes_(1).regimestart(end-1)
|
||||
if length(regimes_(1).regimestart)<=3
|
||||
regimestart = max(regimestart, min(regimes_(1).regimestart(end-1)+2,newstart));
|
||||
else
|
||||
regimes_(1).regime = regimes_(1).regime(1:end-2);
|
||||
regimes_(1).regimestart = regimes_(1).regimestart(1:end-2);
|
||||
regimestart = max(regimestart, regimes_(1).regimestart(end-1)+1);
|
||||
end
|
||||
end
|
||||
regimes_(1).regimestart(end)=regimestart;
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, [base_regime regimes_(1)],'reduced_state_space', T0, R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
elseif newguess==0
|
||||
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
|
||||
RR(:,:,2)=ss.R(my_order_var,:,1);
|
||||
CC(:,2)=ss.C(my_order_var,1);
|
||||
end
|
||||
newguess=0;
|
||||
regime_hist(niter) = {regimes_(1)};
|
||||
if number_constr==1
|
||||
regime_end(niter) = regimes_(1).regimestart(end);
|
||||
end
|
||||
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
|
||||
etahat_hist(niter) = {etahat};
|
||||
lik_hist(niter) = lik;
|
||||
opts_simul.SHOCKS(1,:) = etahat(:,2)';
|
||||
if opts_simul.restrict_state_space
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=alphahat(:,1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
else
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
end
|
||||
% opts_simul.init_regime=regimes_(1);
|
||||
if number_constr==1
|
||||
myregimestart = [regimes_.regimestart];
|
||||
else
|
||||
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
|
||||
end
|
||||
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
regimes0=regimes_;
|
||||
regimes_ = out.regime_history;
|
||||
if niter>1
|
||||
for kiter=1:niter-1
|
||||
is_periodic(kiter) = isequal(regime_hist{kiter}, regimes_(1));
|
||||
end
|
||||
is_periodic = any(is_periodic);
|
||||
if is_periodic
|
||||
if nguess<3 && number_constr==1
|
||||
newguess=1;
|
||||
is_periodic=0;
|
||||
nguess=nguess+1;
|
||||
if nguess==1
|
||||
% change starting regime
|
||||
regimes_(1).regime=0;
|
||||
regimes_(1).regimestart=1;
|
||||
elseif nguess==2
|
||||
% change starting regime
|
||||
regimes_(1).regime=[0 1 0];
|
||||
regimes_(1).regimestart=[1 2 3];
|
||||
else
|
||||
regimes_(1).regime=[1 0];
|
||||
regimes_(1).regimestart=[1 2];
|
||||
end
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, [base_regime regimes_(1)],'reduced_state_space',T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
regime_hist = regime_hist(1);
|
||||
niter=1;
|
||||
else
|
||||
% re-set to previous regime
|
||||
regimes_ = regimes0;
|
||||
% force projection conditional on previous regime
|
||||
opts_simul.init_regime=regimes0(1);
|
||||
if number_constr==1
|
||||
myregimestart = [regimes0.regimestart];
|
||||
else
|
||||
myregimestart = [regimes0.regimestart1 regimes0.regimestart2];
|
||||
end
|
||||
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
|
||||
opts_simul.maxit=1;
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
error_flag = out.error_flag;
|
||||
if ~error_flag && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1))
|
||||
error_flag = 1;
|
||||
if number_constr==1 % try some other regime
|
||||
[ll, il]=sort(lik_hist);
|
||||
[ll, il]=sort(regime_end);
|
||||
rr=regime_hist(il(2:3));
|
||||
newstart=1;
|
||||
if length(rr{1}.regimestart)>1
|
||||
newstart = rr{1}.regimestart(end)-rr{1}.regimestart(end-1)+1;
|
||||
end
|
||||
oldstart=1;
|
||||
if length(rr{2}.regimestart)>1
|
||||
oldstart = rr{2}.regimestart(end)-rr{2}.regimestart(end-1)+1;
|
||||
end
|
||||
nstart=sort([newstart oldstart]);
|
||||
regimes_=rr{1}(1);
|
||||
for k=(nstart(1)+1):(nstart(2)-1)
|
||||
niter=niter+1;
|
||||
regimes_(1).regimestart(end)=k;
|
||||
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, [base_regime regimes_(1)],'reduced_state_space',T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
[a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, options_.rescale_prediction_error_covariance, options_.occbin.likelihood.IF_likelihood);
|
||||
etahat_hist(niter) = {etahat};
|
||||
lik_hist(niter) = lik;
|
||||
regime_hist(niter) = {regimes_(1)};
|
||||
opts_simul.SHOCKS(1,:) = etahat(:,2)';
|
||||
if opts_simul.restrict_state_space
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=alphahat(:,1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
else
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
end
|
||||
% opts_simul.init_regime=regimes_(1);
|
||||
if number_constr==1
|
||||
myregimestart = [regimes_.regimestart];
|
||||
else
|
||||
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
|
||||
end
|
||||
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
if isequal(out.regime_history(1),regimes_(1))
|
||||
error_flag=0;
|
||||
break
|
||||
end
|
||||
end
|
||||
regimes_ = out.regime_history;
|
||||
end
|
||||
end
|
||||
|
||||
a = out.piecewise(1:2,my_order_var)' - repmat(out.ys(my_order_var),1,2);
|
||||
T = ss.T(my_order_var,my_order_var,1:2);
|
||||
R = ss.R(my_order_var,:,1:2);
|
||||
C = ss.C(my_order_var,1:2);
|
||||
QQ = R(:,:,2)*QQQ(:,:,3)*transpose(R(:,:,2));
|
||||
P(:,:,1) = P(:,:,2);
|
||||
P(:,:,2) = T(:,:,2)*P(:,:,1)*transpose(T(:,:,2))+QQ;
|
||||
% P = cat(3,P(:,:,2),P2);
|
||||
regimes_=regimes_(1:3);
|
||||
etahat=etahat(:,2);
|
||||
|
||||
warning on
|
||||
end
|
||||
|
||||
function [a, a1, P, P1, v, alphahat, etahat, lik] = occbin_kalman_update0(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,iF,L,mm, rescale_prediction_error_covariance, IF_likelihood)
|
||||
warning off
|
||||
if nargin<18
|
||||
IF_likelihood=0;
|
||||
end
|
||||
t=2;
|
||||
%% forward pass
|
||||
% given updated variables and covarnace in t=1, we make the step to t=2
|
||||
T = TT(:,:,t);
|
||||
R = RR(:,:,t);
|
||||
C = CC(:,t);
|
||||
Q=QQQ(:,:,t);
|
||||
QQ = R*Q*transpose(R);
|
||||
a1(:,t) = T*a(:,t-1)+C;
|
||||
a(:,t) = a1(:,t);
|
||||
P1(:,:,t) = T*P(:,:,t-1)*T' + QQ; %transition according to (6.14) in DK (2012)
|
||||
P(:,:,t) = P1(:,:,t);
|
||||
|
||||
di = data_index{t};
|
||||
if isempty(di)
|
||||
a(:,t) = a1(:,t);
|
||||
L(:,:,t) = eye(mm);
|
||||
P1(:,:,t+1) = T*P(:,:,t)*T' + QQ; %p. 111, DK(2012)
|
||||
else
|
||||
ZZ = Z(di,:);
|
||||
v(di,t) = Y(di,t) - ZZ*a(:,t);
|
||||
F = ZZ*P(:,:,t)*ZZ' + H(di,di);
|
||||
sig=sqrt(diag(F));
|
||||
if rank(F)<size(F,1)
|
||||
% here we trap cases when some OBC regime triggers singularity
|
||||
% e.g. no shock to interest rate at ZLB
|
||||
di=di(find(sig));
|
||||
ZZ = Z(di,:);
|
||||
v(di,t) = Y(di,t) - ZZ*a(:,t);
|
||||
F = ZZ*P(:,:,t)*ZZ' + H(di,di);
|
||||
sig=sqrt(diag(F));
|
||||
data_index{t}=di;
|
||||
end
|
||||
|
||||
if rescale_prediction_error_covariance
|
||||
if IF_likelihood == 0
|
||||
log_dF = log(det(F./(sig*sig')))+2*sum(log(sig));
|
||||
end
|
||||
iF(di,di,t) = inv(F./(sig*sig'))./(sig*sig');
|
||||
else
|
||||
if IF_likelihood == 0
|
||||
log_dF = log(det(F));
|
||||
end
|
||||
iF(di,di,t) = inv(F);
|
||||
end
|
||||
if IF_likelihood == 0
|
||||
lik = log_dF + transpose(v(di,t))*iF(di,di,t)*v(di,t) + length(di)*log(2*pi);
|
||||
end
|
||||
|
||||
PZI = P(:,:,t)*ZZ'*iF(di,di,t);
|
||||
a(:,t) = a(:,t) + PZI*v(di,t);
|
||||
K = PZI*ZZ;
|
||||
L(:,:,t) = (eye(mm) - K);
|
||||
P(:,:,t) = P(:,:,t) - K*P(:,:,t);
|
||||
|
||||
end
|
||||
|
||||
%% do backward pass
|
||||
r=zeros(mm,3);
|
||||
t = t+1;
|
||||
while t > 1
|
||||
t = t-1;
|
||||
di = data_index{t};
|
||||
if isempty(di)
|
||||
% in this case, L is simply T due to Z=0, so that DK (2012), eq. 4.93 obtains
|
||||
r(:,t) = L(:,:,t)'*r(:,t+1); %compute r_{t-1}, DK (2012), eq. 4.38 with Z=0
|
||||
else
|
||||
ZZ = Z(di,:);
|
||||
r(:,t) = ZZ'*iF(di,di,t)*v(di,t) + L(:,:,t)'*r(:,t+1); %compute r_{t-1}, DK (2012), eq. 4.38
|
||||
end
|
||||
Q=QQQ(:,:,t);
|
||||
QRt = Q*transpose(RR(:,:,t));
|
||||
T = TT(:,:,t);
|
||||
alphahat(:,t) = a1(:,t) + P1(:,:,t)*r(:,t); %DK (2012), eq. 4.35
|
||||
etahat(:,t) = QRt*r(:,t); %DK (2012), eq. 4.63
|
||||
r(:,t) = T'*r(:,t); % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
|
||||
|
||||
if IF_likelihood && t==2 && not(isempty(di))
|
||||
ishocks = any(ZZ*RR(:,:,t));
|
||||
ishocks(find(etahat(ishocks,t)==0))=false;
|
||||
Gmat1 = ZZ*RR(:,ishocks,t);
|
||||
if size(Gmat1,1) == size(Gmat1,2)
|
||||
log_det_jacobian = log(det(Q(ishocks,ishocks))) + 2*log(abs(det(Gmat1)));
|
||||
trace_term = etahat(ishocks,t)'*(Q(ishocks,ishocks)\etahat(ishocks,t));
|
||||
|
||||
lik = log_det_jacobian + trace_term + length(di)*log(2*pi);
|
||||
else
|
||||
lik = inf;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
warning on
|
||||
end
|
|
@ -0,0 +1,392 @@
|
|||
function [a, a1, P, P1, v, Fi, Ki, T, R, C, regimes_, error_flag, M_, alphahat, etahat, TT, RR, CC] = kalman_update_algo_3(a,a1,P,P1,data_index,Z,v,Fi,Ki,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,oo_,options_,occbin_options,kalman_tol,nk)
|
||||
% function [a, a1, P, P1, v, Fi, Ki, T, R, C, regimes_, error_flag, M_, alphahat, etahat, TT, RR, CC] = kalman_update_algo_3(a,a1,P,P1,data_index,Z,v,Fi,Ki,Y,H,QQQ,T0,R0,TT,RR,CC,regimes0,M_,oo_,options_,occbin_options,kalman_tol,nk)
|
||||
%
|
||||
% INPUTS
|
||||
% - a [N by 1] t-1's state estimate
|
||||
% - a1 [N by N by 2] state predictions made at t-1:t
|
||||
% - P [N by N] t-1's covariance of states
|
||||
% - P1 [N by N by 2] one-step ahead forecast error variance at t-1:t
|
||||
% - data_index: [cell] 1*2 cell of column vectors of indices.
|
||||
% - Z [N_obs ny N] Selector matrix
|
||||
% - v [N_obs by 2] prediction error on observables at t-1:t
|
||||
% - Fi [N_obs by 1] F_i matrix
|
||||
% - Ki [N by N_obs] Kalman gain matrix
|
||||
% - Y: [N_obs by 2] observations at t-1:t
|
||||
% - H [N_obs by 1] vector of measurement error
|
||||
% - QQQ [N_exo by N_exo by 3] covariance matrix of shocks at t-1:t+1
|
||||
% - T0 [N by N] initial state transition matrix
|
||||
% - R0 [N by N_exo] initial shock impact transition matrix
|
||||
% - TT [N by N by 2] state transition matrix at t-1:t
|
||||
% - RR [N by N_exo by 2] shock impact matrix at t-1:t
|
||||
% - CC [N by 2] state space constant state transition matrix at t-1:t
|
||||
% - regimes0 [structure] regime info at t-1:t
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - options_ [structure] Matlab's structure describing the current options (options_).
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
% - occbin_options_ [structure] Matlab's structure describing the Occbin options.
|
||||
% - kalman_tol [double] tolerance for reciprocal condition number
|
||||
% - nk [double] number of forecasting periods
|
||||
%
|
||||
% Outputs
|
||||
% - a [N by 2] t-1's state estimate
|
||||
% - a1 [N by N by 2] state predictions made at t-1:t
|
||||
% - P [N by N by 2] t-1's covariance of states
|
||||
% - P1 [N by N by 2] one-step ahead forecast error variance at t-1:t
|
||||
% - v [N_obs by 2] prediction error on observables at t-1:t
|
||||
% - Fi [N_obs by 2] F_i matrix
|
||||
% - Ki [N by N_obs by 2] Kalman gain matrix
|
||||
% - TT [N by N by 2] state transition matrix at t-1:t
|
||||
% - RR [N by N_exo by 2] shock impact matrix at t-1:t
|
||||
% - CC [N by 2] state space constant state transition matrix at t-1:t
|
||||
% - regimes_ [structure] regime info at t-1:t
|
||||
% - error_flag [structure] error flag
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - alphahat: smoothed variables (a_{t|T})
|
||||
% - etahat: smoothed shocks
|
||||
% - TT [N by N by 2] state transition matrix at t-1:t
|
||||
% - RR [N by N_exo by 2] shock impact matrix at t-1:t
|
||||
% - CC [N by 2] state space constant state transition matrix at t-1:t
|
||||
%
|
||||
% Notes: The algorithm and implementation is based on Massimo Giovannini,
|
||||
% Philipp Pfeiffer, Marco Ratto (2021), Efficient and robust inference of models with occasionally binding
|
||||
% constraints, Working Papers 2021-03, Joint Research Centre, European Commission
|
||||
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
if isempty(nk)
|
||||
nk=1;
|
||||
end
|
||||
nk=max(nk,1);
|
||||
|
||||
number_constr = length(M_.occbin.constraint);
|
||||
opts_simul = occbin_options.opts_regime;base_regime = struct();
|
||||
if number_constr==1
|
||||
base_regime.regime = 0;
|
||||
base_regime.regimestart = 1;
|
||||
else
|
||||
base_regime.regime1 = 0;
|
||||
base_regime.regimestart1 = 1;
|
||||
base_regime.regime2 = 0;
|
||||
base_regime.regimestart2 = 1;
|
||||
end
|
||||
myrestrict=[];
|
||||
if options_.smoother_redux
|
||||
opts_simul.restrict_state_space =1;
|
||||
myrestrict='restrict';
|
||||
end
|
||||
|
||||
mm=size(a,1);
|
||||
if ~options_.occbin.filter.use_relaxation
|
||||
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
|
||||
else
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, base_regime,myrestrict,T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
|
||||
regimes0(1)=base_regime;
|
||||
end
|
||||
|
||||
|
||||
%% run here the occbin simul
|
||||
opts_simul.SHOCKS = zeros(max(3,1+nk),M_.exo_nbr);
|
||||
opts_simul.SHOCKS(1,:) = etahat(:,2)';
|
||||
opts_simul.exo_pos=1:M_.exo_nbr;
|
||||
|
||||
if opts_simul.restrict_state_space
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=alphahat(:,1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
my_order_var = oo_.dr.order_var(oo_.dr.restrict_var_list);
|
||||
else
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
my_order_var = oo_.dr.order_var;
|
||||
end
|
||||
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
|
||||
regimes_ = out.regime_history;
|
||||
if number_constr==1
|
||||
myregime = [regimes_.regime];
|
||||
else
|
||||
myregime = [regimes_.regime1 regimes_.regime2];
|
||||
end
|
||||
regime_hist = {regimes0};
|
||||
if number_constr==1
|
||||
regime_end = regimes0(1).regimestart(end);
|
||||
end
|
||||
niter=1;
|
||||
is_periodic=0;
|
||||
if options_.occbin.filter.use_relaxation || isequal(regimes0(1),base_regime)
|
||||
nguess=1;
|
||||
else
|
||||
nguess=0;
|
||||
end
|
||||
newguess=0;
|
||||
|
||||
if any(myregime) || ~isequal(regimes_(1),regimes0(1))
|
||||
while ~isequal(regimes_(1),regimes0(1)) && ~is_periodic && ~out.error_flag && niter<=options_.occbin.likelihood.max_number_of_iterations
|
||||
niter=niter+1;
|
||||
newstart=1;
|
||||
if number_constr==1 && length(regimes_(1).regimestart)>1
|
||||
newstart = regimes_(1).regimestart(end);
|
||||
end
|
||||
oldstart=1;
|
||||
if number_constr==1 && length(regimes0(1).regimestart)>1
|
||||
oldstart = regimes0(1).regimestart(end);
|
||||
end
|
||||
if number_constr==1 && (newstart-oldstart)>2 && options_.occbin.filter.use_relaxation
|
||||
regimestart = max(oldstart+2,round(0.5*(newstart+oldstart)));
|
||||
regimestart = min(regimestart,oldstart+4);
|
||||
if regimestart<=regimes_(1).regimestart(end-1)
|
||||
if length(regimes_(1).regimestart)<=3
|
||||
regimestart = max(regimestart, min(regimes_(1).regimestart(end-1)+2,newstart));
|
||||
else
|
||||
regimes_(1).regime = regimes_(1).regime(1:end-2);
|
||||
regimes_(1).regimestart = regimes_(1).regimestart(1:end-2);
|
||||
regimestart = max(regimestart, regimes_(1).regimestart(end-1)+1);
|
||||
end
|
||||
end
|
||||
|
||||
% % if (newstart-oldstart)>3
|
||||
% % regimestart = regimes_(1).regimestart(end-1)+oldstart+2;
|
||||
% % % regimestart = regimes_(1).regimestart(end-1)+round(0.5*(newstart+oldstart))-1;
|
||||
regimes_(1).regimestart(end)=regimestart;
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, [base_regime regimes_(1)],myrestrict,T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
elseif newguess==0
|
||||
TT(:,:,2)=ss.T(my_order_var,my_order_var,1);
|
||||
RR(:,:,2)=ss.R(my_order_var,:,1);
|
||||
CC(:,2)=ss.C(my_order_var,1);
|
||||
end
|
||||
newguess=0;
|
||||
regime_hist(niter) = {regimes_};
|
||||
if number_constr==1
|
||||
regime_end(niter) = regimes_(1).regimestart(end);
|
||||
end
|
||||
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
|
||||
opts_simul.SHOCKS(1,:) = etahat(:,2)';
|
||||
% if opts_simul.restrict_state_space
|
||||
% tmp=zeros(M_.endo_nbr,1);
|
||||
% tmp(oo_.dr.restrict_var_list,1)=alphahat(:,1);
|
||||
% opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
% else
|
||||
if opts_simul.restrict_state_space
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=alphahat(:,1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
else
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
end
|
||||
% end
|
||||
% opts_simul.init_regime=regimes_(1); %% why don't we use this ???
|
||||
if number_constr==1
|
||||
myregimestart = [regimes_.regimestart];
|
||||
else
|
||||
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
|
||||
end
|
||||
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
regimes0=regimes_;
|
||||
regimes_ = out.regime_history;
|
||||
if niter>1
|
||||
for kiter=1:niter-1
|
||||
is_periodic(kiter) = isequal(regime_hist{kiter}, regimes_);
|
||||
end
|
||||
is_periodic = any(is_periodic);
|
||||
if is_periodic
|
||||
if nguess<3 && number_constr==1
|
||||
newguess=1;
|
||||
is_periodic=0;
|
||||
nguess=nguess+1;
|
||||
if nguess==1
|
||||
% change starting regime
|
||||
regimes_(1).regime=0;
|
||||
regimes_(1).regimestart=1;
|
||||
elseif nguess==2
|
||||
% change starting regime
|
||||
regimes_(1).regime=[0 1 0];
|
||||
regimes_(1).regimestart=[1 2 3];
|
||||
else
|
||||
regimes_(1).regime=[1 0];
|
||||
regimes_(1).regimestart=[1 2];
|
||||
end
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, [base_regime regimes_(1)],myrestrict,T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
regime_hist = regime_hist(1);
|
||||
niter=1;
|
||||
else
|
||||
% re-set to previous regime
|
||||
regimes_ = regimes0;
|
||||
% force projection conditional on previous regime
|
||||
opts_simul.init_regime=regimes0(1);
|
||||
if number_constr==1
|
||||
myregimestart = [regimes0.regimestart];
|
||||
else
|
||||
myregimestart = [regimes0.regimestart1 regimes0.regimestart2];
|
||||
end
|
||||
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
|
||||
opts_simul.maxit=1;
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
error_flag = out.error_flag;
|
||||
if error_flag==0 && niter>options_.occbin.likelihood.max_number_of_iterations && ~isequal(regimes_(1),regimes0(1)) %fixed point algorithm did not converge
|
||||
error_flag = 1;
|
||||
|
||||
if number_constr==1
|
||||
% try some other regime before giving up
|
||||
[ll, il]=sort(regime_end);
|
||||
rr=regime_hist(il(2:3));
|
||||
newstart=1;
|
||||
if length(rr{1}(1).regimestart)>1
|
||||
newstart = rr{1}(1).regimestart(end)-rr{1}(1).regimestart(end-1)+1;
|
||||
end
|
||||
oldstart=1;
|
||||
if length(rr{2}(1).regimestart)>1
|
||||
oldstart = rr{2}(1).regimestart(end)-rr{2}(1).regimestart(end-1)+1;
|
||||
end
|
||||
nstart=sort([newstart oldstart]);
|
||||
regimes_=rr{1}(1);
|
||||
for k=(nstart(1)+1):(nstart(2)-1)
|
||||
niter=niter+1;
|
||||
regimes_(1).regimestart(end)=k;
|
||||
|
||||
[~,~,~,~,~,~, TTx, RRx, CCx] ...
|
||||
= occbin.dynare_resolve(M_,options_,oo_, [base_regime regimes_(1)],myrestrict,T0,R0);
|
||||
TT(:,:,2) = TTx(:,:,end);
|
||||
RR(:,:,2) = RRx(:,:,end);
|
||||
CC(:,2) = CCx(:,end);
|
||||
[a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol);
|
||||
opts_simul.SHOCKS(1,:) = etahat(:,2)';
|
||||
opts_simul.endo_init = alphahat(oo_.dr.inv_order_var,1);
|
||||
if number_constr==1
|
||||
myregimestart = [regimes_.regimestart];
|
||||
else
|
||||
myregimestart = [regimes_.regimestart1 regimes_.regimestart2];
|
||||
end
|
||||
opts_simul.periods = max(opts_simul.periods,max(myregimestart));
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
if isequal(out.regime_history(1),regimes_(1))
|
||||
error_flag=0;
|
||||
break
|
||||
end
|
||||
end
|
||||
regimes_ = out.regime_history;
|
||||
end
|
||||
end
|
||||
|
||||
regimes_=regimes_(1:3);
|
||||
a = out.piecewise(1:nk+1,my_order_var)' - repmat(out.ys(my_order_var),1,nk+1);
|
||||
T = ss.T(my_order_var,my_order_var,:);
|
||||
R = ss.R(my_order_var,:,:);
|
||||
C = ss.C(my_order_var,:);
|
||||
TT = ss.T(oo_.dr.order_var,oo_.dr.order_var,1);
|
||||
RR = ss.R(oo_.dr.order_var,:,1);
|
||||
CC = ss.C(oo_.dr.order_var,1);
|
||||
QQ = R(:,:,2)*QQQ(:,:,3)*transpose(R(:,:,2));
|
||||
P(:,:,1) = P(:,:,2);
|
||||
for j=1:nk
|
||||
P(:,:,j+1) = T(:,:,j+1)*P(:,:,j)*transpose(T(:,:,j+1))+QQ;
|
||||
end
|
||||
% P = cat(3,P(:,:,2),P2);
|
||||
|
||||
|
||||
end
|
||||
|
||||
function [a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol)
|
||||
% [a, a1, P, P1, v, Fi, Ki, alphahat, etahat] = occbin_kalman_update(a,a1,P,P1,data_index,Z,v,Y,H,QQQ,TT,RR,CC,Ki,Fi,mm,kalman_tol)
|
||||
% - a
|
||||
% - a1
|
||||
% - P
|
||||
% - P1
|
||||
% - v
|
||||
% - Fi
|
||||
% - Ki
|
||||
|
||||
|
||||
t=2;
|
||||
|
||||
%% forward pass
|
||||
% given updated variables and covariance in t=1, we make the step to t=2
|
||||
T = TT(:,:,t);
|
||||
R = RR(:,:,t);
|
||||
C = CC(:,t);
|
||||
Q=QQQ(:,:,t);
|
||||
QQ = R*Q*transpose(R);
|
||||
a1(:,t) = T*a(:,t-1)+C;
|
||||
a(:,t) = a1(:,t);
|
||||
P1(:,:,t) = T*P(:,:,t-1)*T' + QQ; %transition according to (6.14) in DK (2012)
|
||||
P(:,:,t) = P1(:,:,t);
|
||||
di = data_index{t}';
|
||||
if isempty(di)
|
||||
Fi(:,t) = 0;
|
||||
Ki(:,:,t) = 0;
|
||||
end
|
||||
for i=di
|
||||
Zi = Z(i,:);
|
||||
v(i,t) = Y(i,t) - Zi*a(:,t); % nu_{t,i} in 6.13 in DK (2012)
|
||||
Fi(i,t) = Zi*P(:,:,t)*Zi' + H(i); % F_{t,i} in 6.13 in DK (2012), relies on H being diagonal
|
||||
Ki(:,i,t) = P(:,:,t)*Zi'; % K_{t,i}*F_(i,t) in 6.13 in DK (2012)
|
||||
if Fi(i,t) > kalman_tol
|
||||
a(:,t) = a(:,t) + Ki(:,i,t)*v(i,t)/Fi(i,t); %filtering according to (6.13) in DK (2012)
|
||||
P(:,:,t) = P(:,:,t) - Ki(:,i,t)*Ki(:,i,t)'/Fi(i,t); %filtering according to (6.13) in DK (2012)
|
||||
else
|
||||
% do nothing as a_{t,i+1}=a_{t,i} and P_{t,i+1}=P_{t,i}, see
|
||||
% p. 157, DK (2012)
|
||||
end
|
||||
end
|
||||
|
||||
%% do backward pass
|
||||
ri=zeros(mm,1);
|
||||
t = t+1;
|
||||
while t > 1
|
||||
t = t-1;
|
||||
di = flipud(data_index{t})';
|
||||
for i = di
|
||||
if Fi(i,t) > kalman_tol
|
||||
Li = eye(mm)-Ki(:,i,t)*Z(i,:)/Fi(i,t);
|
||||
ri = Z(i,:)'/Fi(i,t)*v(i,t)+Li'*ri; % DK (2012), 6.15, equation for r_{t,i-1}
|
||||
end
|
||||
end
|
||||
r(:,t) = ri; % DK (2012), below 6.15, r_{t-1}=r_{t,0}
|
||||
alphahat(:,t) = a1(:,t) + P1(:,:,t)*r(:,t);
|
||||
Q=QQQ(:,:,t);
|
||||
QRt = Q*transpose(RR(:,:,t));
|
||||
T = TT(:,:,t);
|
||||
etahat(:,t) = QRt*r(:,t);
|
||||
ri = T'*ri; % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
function make_chart(titlelist,legendlist,figlabel,ylabels,data_series)
|
||||
% function make_chart(titlelist,legendlist,figlabel,ylabels,zdata)
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
titlelist = char(strrep(cellstr(titlelist),'_','.'));
|
||||
|
||||
ndsets=size(data_series,3); % default, changed below as applicable
|
||||
nperiods = size(data_series,1);
|
||||
|
||||
xvalues = (1:nperiods)';
|
||||
nvars = size(titlelist,1);
|
||||
|
||||
[nbplt,nr,nc,lr,lc,nstar] = pltorg(nvars);
|
||||
|
||||
style_cell={'k','r','b','g','c','y'};
|
||||
|
||||
for fig = 1:nbplt
|
||||
figure('Name',[figlabel, ', Figure ' int2str(fig)]);
|
||||
for plt = 1:nstar
|
||||
h1=NaN(ndsets);
|
||||
if fig==nbplt && ~lr==0
|
||||
subplot(lr,lc,plt);
|
||||
else
|
||||
subplot(nr,nc,plt);
|
||||
end
|
||||
for data_set_iter=1:ndsets
|
||||
h1(data_set_iter)=plot(xvalues,data_series(:,(fig-1)*nstar+plt,data_set_iter),style_cell{1+mod(data_set_iter-1,length(style_cell))},'linewidth',2);
|
||||
hold on
|
||||
end
|
||||
grid on
|
||||
|
||||
max_y = max(max(data_series(:,(fig-1)*nstar+plt,:)));
|
||||
min_y = min(min(data_series(:,(fig-1)*nstar+plt,:)));
|
||||
|
||||
y_bottom = min_y - .01*abs(min_y);
|
||||
|
||||
y_top = max_y + 0.01*abs(max_y);
|
||||
if y_bottom==y_top
|
||||
y_top=y_bottom+1;
|
||||
end
|
||||
|
||||
axis([1 nperiods y_bottom y_top])
|
||||
if plt==1
|
||||
if numel(strvcat(legendlist(1,:)))
|
||||
h=legend(legendlist,'Location','Northwest','Fontsize',8);
|
||||
end
|
||||
end
|
||||
|
||||
title(titlelist(plt,:),'Fontsize',11);
|
||||
ylabel(ylabels(plt,:))
|
||||
if nvars==(fig-1)*nstar+plt
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
function [regime, regime_start, error_flag]=map_regime(binding_indicator,debug_switch)
|
||||
% function [regime, regime_start, error_flag]=map_regime(binding_indicator)
|
||||
% Map regime indicator into information
|
||||
%
|
||||
% Inputs:
|
||||
% - binding_indicator [integer] [nperiods by 1] vector of regime indices
|
||||
% - debug_switch [boolean] indicator for printing warnings
|
||||
%
|
||||
% Outputs:
|
||||
% - regime [integer] [1 by n_transitions] vector of regime number indices
|
||||
% - regime_start [integer] [1 by n_transitions] vectors with period numbers in which regime starts
|
||||
% - error_flag [boolean] 1 if regime never leaves 1 or is still there at the end of nperiods
|
||||
% 0 otherwise
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
error_flag=0;
|
||||
% analyse violvec and isolate contiguous periods in the other regime.
|
||||
regime(1) = binding_indicator(1);
|
||||
regime_index = 1;
|
||||
regime_start(1) = 1;
|
||||
for i=2:length(binding_indicator)
|
||||
if binding_indicator(i)~=regime(regime_index)
|
||||
regime_index=regime_index+1;
|
||||
regime(regime_index) = binding_indicator(i);
|
||||
regime_start(regime_index)=i;
|
||||
end
|
||||
end
|
||||
|
||||
if (regime(1) == 1 && length(regime_start)==1)
|
||||
disp_verbose('map_regime: Binding regime was never left. nperiods needs to be increased.',debug_switch);
|
||||
error_flag=1;
|
||||
end
|
||||
|
||||
if (regime(end)==1)
|
||||
disp_verbose('map_regime: Constraint(s) are binding at the end of the sample. nperiods needs to be increased.',debug_switch);
|
||||
error_flag=1;
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
function [resids, grad, state_out, E, M_, out] = match_function(err_0, obs_list,current_obs, opts_simul,...
|
||||
M_, oo_, options_)
|
||||
% function [resids, grad, stateout, E, M_, out] = match_function(err_0, obs_list,current_obs, opts_simul,...
|
||||
% M_, oo_, options_)
|
||||
% Outputs:
|
||||
% - resids [double] [n_exo by 1] vector of residuals
|
||||
% - grad [double] [n by n_exo] gradient (response of observables to shocks)
|
||||
% - state_out [double] [ny by 1] value of endogenous variables
|
||||
% - E [double] response of endogenous variables to shocks
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - out [structure] Occbin's results structure
|
||||
%
|
||||
% Inputs
|
||||
% - err_ [double] value of shocks
|
||||
% - obs_list [cell] names of observables
|
||||
% - current_obs [double] [1 by n_obs] current value of observables
|
||||
% - opts_simul [structure] Structure with simulation options
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
% - options_ [structure] Matlab's structure describing the current options (options_).
|
||||
|
||||
% Original authors: Pablo Cuba-Borda, Luca Guerrieri, Matteo Iacoviello, and Molin Zhong
|
||||
% Original file downloaded from:
|
||||
% http://www.lguerrieri.com/jae-replication.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Pablo Cuba-Borda, Luca Guerrieri, and Matteo Iacoviello (2019): "Likelihood evaluation of models
|
||||
% with occasionally binding constraints", Journal of Applied Econometrics,
|
||||
% 34(7), 1073-1085
|
||||
|
||||
opts_simul.SHOCKS = err_0';
|
||||
options_.occbin.simul=opts_simul;
|
||||
options_.occbin.simul.full_output=1;
|
||||
options_.noprint = 1;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
state_out= out.piecewise(1,:)' - out.ys;
|
||||
|
||||
E = ss.R(:,opts_simul.exo_pos);
|
||||
grad = ss.R(opts_simul.varobs_id,opts_simul.exo_pos);
|
||||
|
||||
nobs = size(obs_list,1);
|
||||
resids = zeros(nobs,1);
|
||||
|
||||
if ~out.error_flag
|
||||
% -- add observation block in model ---%
|
||||
% % put in model file
|
||||
resids = (out.piecewise(1,opts_simul.varobs_id)-current_obs)'; %-out.endo_ss.(obs_list{this_obs});
|
||||
else
|
||||
resids = resids+100;
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
function [data_mat]=make_linear_model_data(n_periods,dr_A,dr_B,endo_names,exo_names,wish_list,shock_pos,shock_size_vec,var_init)
|
||||
% function [data_mat]=make_linear_model_data(n_periods,dr_A,dr_B,endo_names,exo_names,wish_list,shock_pos,shock_size_vec,var_init)
|
||||
% Inputs:
|
||||
% - n_periods [integer] number of simulation periods
|
||||
% - dr_A [double] [n by n] transition matrix
|
||||
% - dr_B [double] [n by nexo] shock response matrix
|
||||
% - endo_names [cell] name of endogenous variables
|
||||
% - exo_names [cell] name of exogenous variables
|
||||
% - wish_list [cell] name of requested variables for output
|
||||
% - shock_pos [integer] index of shocks
|
||||
% - shock_size_vec [double] [shock periods by 1] vector of
|
||||
% - var_init [double] [n by 1] vector of initial values (incl. states)
|
||||
%
|
||||
% Outputs:
|
||||
% - data_mat [double] [n_periods by n] vector of regime number indices
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
% given decision rule
|
||||
neqs = size(endo_names,1);
|
||||
|
||||
if nargin<9
|
||||
var_init = zeros(neqs,1);
|
||||
end
|
||||
|
||||
if nargin<8
|
||||
shock_size_vec=1;
|
||||
end
|
||||
|
||||
if nargin<7
|
||||
error('Not enough inputs')
|
||||
end
|
||||
|
||||
history = zeros(neqs,n_periods+1);
|
||||
|
||||
% generate data
|
||||
% history will contain data, the state vector at each period in time will
|
||||
% be stored columnwise.
|
||||
history(:,1)= var_init;
|
||||
|
||||
lengthshock = size(shock_size_vec,1);
|
||||
|
||||
err_vec = zeros(size(exo_names,1),1);
|
||||
|
||||
for i = 2:n_periods+1
|
||||
if i<=(lengthshock+1)
|
||||
err_vec(shock_pos) = shock_size_vec(i-1,:);
|
||||
history(:,i) = dr_A * history(:,i-1)+dr_B*err_vec;
|
||||
else
|
||||
% update endogenous variables
|
||||
history(:,i) = dr_A * history(:,i-1);
|
||||
end
|
||||
end
|
||||
|
||||
% extract desired variables
|
||||
if ~isempty(wish_list)
|
||||
n_wish=size(wish_list,1);
|
||||
wish_pos = zeros(n_wish,1);
|
||||
for i=1:n_wish
|
||||
wish_pos(i) = strmatch(wish_list(i,:),endo_names,'exact');
|
||||
end
|
||||
data_mat = history(wish_pos,2:end)';
|
||||
else
|
||||
data_mat = history(:,2:end)';
|
||||
end
|
|
@ -0,0 +1,169 @@
|
|||
function [zdata, T, R, CONST, ss, update_flag]=mkdatap_anticipated_2constraints_dyn(n_periods,DM,T_max,...
|
||||
binding_indicator,irfshock_pos,scalefactor_mod,init,update_flag)
|
||||
% function [zdata, T, R, CONST, ss, update_flag]=mkdatap_anticipated_2constraints_dyn(n_periods,DM,T_max,...
|
||||
% binding_indicator,irfshock_pos,scalefactor_mod,init,update_flag)
|
||||
%
|
||||
% Inputs:
|
||||
% - n_periods [double] number for periods for simulation
|
||||
% - DM [structure] Dynamic model
|
||||
% - T_max [Tmax] last period where constraints bind
|
||||
% - binding_indicator [T+1] indicator for constraint violations
|
||||
% - irfshock_pos [double] shock position
|
||||
% - scalefactor_mod [double] shock values
|
||||
% - init [double] [N by 1] initial value of endogenous variables
|
||||
% - update_flag [boolean] flag whether to update results
|
||||
%
|
||||
% Output:
|
||||
% - zdata [double] T+1 by N matrix of simulated data
|
||||
% - T [N by N] transition matrix of state space
|
||||
% - R [N by N_exo] shock impact matrix of state space
|
||||
% - CONST [N by 1] constant of state space
|
||||
% - ss [structure] state space system
|
||||
% - update_flag [boolean] flag that results have been updated
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
persistent dictionary
|
||||
|
||||
if update_flag
|
||||
dictionary=[];
|
||||
update_flag=false;
|
||||
end
|
||||
|
||||
n_vars = DM.n_vars;
|
||||
T = DM.decrulea;
|
||||
CONST = zeros(n_vars,1);
|
||||
R = DM.decruleb;
|
||||
|
||||
if nargin<7
|
||||
init=zeros(n_vars,1);
|
||||
end
|
||||
|
||||
if nargin<6
|
||||
scalefactor_mod=1;
|
||||
end
|
||||
|
||||
n_exo=DM.n_exo;
|
||||
|
||||
% Tmax = max([regimestart1(nregimes1) regimestart2(nregimes2)])-1; % Tmax is the position of the last period
|
||||
% when the constraint binds
|
||||
|
||||
if ~isempty(dictionary)
|
||||
if (length(binding_indicator(:))>size(dictionary.binding_indicator,1))
|
||||
nviol_old = size(dictionary.binding_indicator,1)/2;
|
||||
tmp = zeros(length(binding_indicator)-nviol_old,size(dictionary.binding_indicator,2));
|
||||
dictionary.binding_indicator = [dictionary.binding_indicator(1:nviol_old,:); tmp; dictionary.binding_indicator(1+nviol_old:2*nviol_old,:); tmp];
|
||||
end
|
||||
if (length(binding_indicator(:))<size(dictionary.binding_indicator,1))
|
||||
binding_indicator = [binding_indicator; zeros(size(dictionary.binding_indicator,1)/2-size(binding_indicator,1),2) ];
|
||||
end
|
||||
end
|
||||
|
||||
if T_max > 0
|
||||
|
||||
if isempty(dictionary)
|
||||
tmp = [binding_indicator(T_max,:); zeros(n_periods,2)];
|
||||
dictionary.binding_indicator(:,1) = tmp(:);
|
||||
if (binding_indicator(T_max,1) && ~binding_indicator(T_max,2))
|
||||
temp = -(DM.Abarmat10*DM.decrulea+DM.Bbarmat10)\[DM.Cbarmat10 DM.Jbarmat10 DM.Dbarmat10];
|
||||
dictionary.ss(1).T = temp(:,1:n_vars);
|
||||
dictionary.ss(1).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(1).C = temp(:,n_vars+n_exo+1:end);
|
||||
elseif (binding_indicator(T_max,1) && binding_indicator(T_max,2))
|
||||
temp = -(DM.Abarmat11*DM.decrulea+DM.Bbarmat11)\[DM.Cbarmat11 DM.Jbarmat11 DM.Dbarmat11];
|
||||
dictionary.ss(1).T = temp(:,1:n_vars);
|
||||
dictionary.ss(1).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(1).C = temp(:,n_vars+n_exo+1:end);
|
||||
else
|
||||
temp = -(DM.Abarmat01*DM.decrulea+DM.Bbarmat01)\[DM.Cbarmat01 DM.Jbarmat01 DM.Dbarmat01];
|
||||
dictionary.ss(1).T = temp(:,1:n_vars);
|
||||
dictionary.ss(1).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(1).C = temp(:,n_vars+n_exo+1:end);
|
||||
end
|
||||
end
|
||||
ireg(T_max)=1;
|
||||
|
||||
icount=length(dictionary.ss);
|
||||
|
||||
for i = T_max-1:-1:1
|
||||
tmp = 0*binding_indicator;
|
||||
tmp(1:end-i+1,:) = binding_indicator(i:end,:);
|
||||
itmp = find(~any(dictionary.binding_indicator(1:length(tmp)*2,:)-tmp(:)));
|
||||
if ~isempty(itmp)
|
||||
ireg(i) = itmp;
|
||||
else
|
||||
icount=icount+1;
|
||||
ireg(i) = icount;
|
||||
dictionary.binding_indicator(1:length(tmp)*2,icount) = tmp(:);
|
||||
if (binding_indicator(i,1) && ~binding_indicator(i,2))
|
||||
temp = -(DM.Bbarmat10+DM.Abarmat10*dictionary.ss(ireg(i+1)).T)\[DM.Cbarmat10 DM.Jbarmat10 DM.Abarmat10*dictionary.ss(ireg(i+1)).C+DM.Dbarmat10];
|
||||
dictionary.ss(icount).T = temp(:,1:n_vars);
|
||||
dictionary.ss(icount).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(icount).C = temp(:,n_vars+n_exo+1:end);
|
||||
elseif (~binding_indicator(i,1) && binding_indicator(i,2))
|
||||
temp = -(DM.Bbarmat01+DM.Abarmat01*dictionary.ss(ireg(i+1)).T)\[DM.Cbarmat01 DM.Jbarmat01 DM.Abarmat01*dictionary.ss(ireg(i+1)).C+DM.Dbarmat01];
|
||||
dictionary.ss(icount).T = temp(:,1:n_vars);
|
||||
dictionary.ss(icount).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(icount).C = temp(:,n_vars+n_exo+1:end);
|
||||
elseif (binding_indicator(i,1) && binding_indicator(i,2))
|
||||
temp = -(DM.Bbarmat11+DM.Abarmat11*dictionary.ss(ireg(i+1)).T)\[DM.Cbarmat11 DM.Jbarmat11 DM.Abarmat11*dictionary.ss(ireg(i+1)).C+DM.Dbarmat11];
|
||||
dictionary.ss(icount).T = temp(:,1:n_vars);
|
||||
dictionary.ss(icount).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(icount).C = temp(:,n_vars+n_exo+1:end);
|
||||
else
|
||||
temp = -(DM.Bbarmat+DM.Abarmat*dictionary.ss(ireg(i+1)).T)\[DM.Cbarmat DM.Jbarmat DM.Abarmat*dictionary.ss(ireg(i+1)).C];
|
||||
dictionary.ss(icount).T = temp(:,1:n_vars);
|
||||
dictionary.ss(icount).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(icount).C = temp(:,n_vars+n_exo+1:end);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
E = dictionary.ss(ireg(1)).R;
|
||||
ss = dictionary.ss(ireg(1:T_max));
|
||||
else
|
||||
ss = [];
|
||||
end
|
||||
|
||||
% generate data
|
||||
% history will contain data, the state vector at each period in time will
|
||||
% be stored columnwise.
|
||||
history = zeros(n_vars,n_periods+1);
|
||||
history(:,1) = init;
|
||||
errvec = zeros(n_exo,1);
|
||||
|
||||
errvec(irfshock_pos) = scalefactor_mod;
|
||||
|
||||
% deal with shocks
|
||||
irfpos =1;
|
||||
if irfpos <=T_max
|
||||
history(:,irfpos+1) = dictionary.ss(ireg(irfpos)).T* history(:,irfpos)+...
|
||||
dictionary.ss(ireg(irfpos)).C + E*errvec;
|
||||
T = dictionary.ss(ireg(irfpos)).T;
|
||||
CONST = dictionary.ss(ireg(irfpos)).C;
|
||||
R = E;
|
||||
else
|
||||
history(:,irfpos+1) = DM.decrulea*history(:,irfpos)+DM.decruleb*errvec;
|
||||
end
|
||||
|
||||
% all other periods
|
||||
for irfpos=2:n_periods+1
|
||||
if irfpos <=T_max
|
||||
history(:,irfpos+1) = dictionary.ss(ireg(irfpos)).T* history(:,irfpos)+...
|
||||
dictionary.ss(ireg(irfpos)).C;
|
||||
else
|
||||
history(:,irfpos+1) = DM.decrulea*history(:,irfpos);
|
||||
end
|
||||
end
|
||||
|
||||
zdata = history(:,2:end)';
|
|
@ -0,0 +1,151 @@
|
|||
function [zdata, T, R, CONST, ss, update_flag]=mkdatap_anticipated_dyn(n_periods,DM,...
|
||||
T_max,binding_indicator,irfshock_pos,scalefactor_mod,init,update_flag)
|
||||
% function [zdata, T, R, CONST, ss]=mkdatap_anticipated_dyn(nperiods,DM,...
|
||||
% Tmax,binding_indicator,irfshockpos,scalefactormod,init,update_flag)
|
||||
%
|
||||
% Inputs:
|
||||
% - n_periods [double] number for periods for simulation
|
||||
% - DM [structure] Dynamic model
|
||||
% - T_max [Tmax] last period where constraints bind
|
||||
% - binding_indicator [T+1] indicator for constraint violations
|
||||
% - irfshock_pos [double] shock position
|
||||
% - scalefactor_mod [double] shock values
|
||||
% - init [double] [N by 1] initial value of endogenous variables
|
||||
% - update_flag [boolean] flag whether to update results
|
||||
%
|
||||
% Output:
|
||||
% - zdata [double] T+1 by N matrix of simulated data
|
||||
% - T [N by N] transition matrix of state space
|
||||
% - R [N by N_exo] shock impact matrix of state space
|
||||
% - CONST [N by 1] constant of state space
|
||||
% - ss [structure] state space system
|
||||
% - update_flag [boolean] flag that results have been updated
|
||||
%
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
persistent dictionary
|
||||
|
||||
if update_flag
|
||||
dictionary=[];
|
||||
update_flag=false;
|
||||
end
|
||||
|
||||
%Initialize outputs
|
||||
n_vars = DM.n_vars;
|
||||
n_exo = DM.n_exo;
|
||||
T = DM.decrulea;
|
||||
CONST = zeros(n_vars,1);
|
||||
R = DM.decruleb;
|
||||
|
||||
if nargin<7
|
||||
init=zeros(n_vars,1);
|
||||
end
|
||||
|
||||
if nargin<6
|
||||
scalefactor_mod=1;
|
||||
end
|
||||
|
||||
|
||||
% % get the time-dependent decision rules
|
||||
|
||||
if ~isempty(dictionary)
|
||||
if (length(binding_indicator)>size(dictionary.binding_indicator,1))
|
||||
dictionary.binding_indicator = [dictionary.binding_indicator; zeros(length(binding_indicator)-size(dictionary.binding_indicator,1),size(dictionary.binding_indicator,2))];
|
||||
end
|
||||
if (length(binding_indicator(:))<size(dictionary.binding_indicator,1))
|
||||
binding_indicator = [binding_indicator; zeros(size(dictionary.binding_indicator,1)-size(binding_indicator,1),1) ];
|
||||
end
|
||||
end
|
||||
|
||||
if T_max > 0
|
||||
if isempty(dictionary)
|
||||
temp = -(DM.Astarbarmat*DM.decrulea+DM.Bstarbarmat)\[DM.Cstarbarmat DM.Jstarbarmat DM.Dstarbarmat];
|
||||
dictionary.binding_indicator(:,1) = [1; zeros(n_periods,1)];
|
||||
dictionary.ss(1).T = temp(:,1:n_vars);
|
||||
dictionary.ss(1).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(1).C = temp(:,n_vars+n_exo+1:end);
|
||||
end
|
||||
ireg(T_max)=1;
|
||||
|
||||
% equivalent to pre-multiplying by the inverse above if the target
|
||||
% matrix is invertible. Otherwise it yields the minimum state solution
|
||||
%P(:,:,Tmax) = -(Astarbarmat*decrulea+Bstarbarmat)\Cstarbarmat;
|
||||
%D(:,Tmax) = -(Astarbarmat*decrulea+Bstarbarmat)\Dstarbarmat;
|
||||
|
||||
icount=length(dictionary.ss);
|
||||
|
||||
for i = T_max-1:-1:1
|
||||
|
||||
tmp = 0*binding_indicator;
|
||||
tmp(1:end-i+1) = binding_indicator(i:end);
|
||||
itmp = find(~any(dictionary.binding_indicator-tmp));
|
||||
if ~isempty(itmp)
|
||||
ireg(i) = itmp;
|
||||
else
|
||||
icount=icount+1;
|
||||
ireg(i) = icount;
|
||||
dictionary.binding_indicator(1:length(tmp),icount) = tmp;
|
||||
if binding_indicator(i)
|
||||
temp = -(DM.Bstarbarmat+DM.Astarbarmat*dictionary.ss(ireg(i+1)).T)\[DM.Cstarbarmat DM.Jstarbarmat DM.Astarbarmat*dictionary.ss(ireg(i+1)).C+DM.Dstarbarmat];
|
||||
dictionary.ss(icount).T = temp(:,1:n_vars);
|
||||
dictionary.ss(icount).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(icount).C = temp(:,n_vars+n_exo+1:end);
|
||||
else
|
||||
temp = -(DM.Bbarmat+DM.Abarmat*dictionary.ss(ireg(i+1)).T)\[DM.Cbarmat DM.Jbarmat (DM.Abarmat*dictionary.ss(ireg(i+1)).C)];
|
||||
dictionary.ss(icount).T = temp(:,1:n_vars);
|
||||
dictionary.ss(icount).R = temp(:,n_vars+1:n_vars+n_exo);
|
||||
dictionary.ss(icount).C = temp(:,n_vars+n_exo+1:end);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
E = dictionary.ss(ireg(1)).R;
|
||||
ss = dictionary.ss(ireg(1:T_max));
|
||||
else
|
||||
ss = [];
|
||||
end
|
||||
|
||||
% generate data
|
||||
% history will contain data, the state vector at each period in time will
|
||||
% be stored columnwise.
|
||||
history = zeros(n_vars,n_periods+1);
|
||||
history(:,1) = init;
|
||||
errvec = zeros(n_exo,1);
|
||||
|
||||
% deal with predetermined conditions
|
||||
errvec(irfshock_pos) = scalefactor_mod;
|
||||
|
||||
% deal with shocks
|
||||
irfpos =1;
|
||||
if irfpos <=T_max
|
||||
history(:,irfpos+1) = dictionary.ss(ireg(irfpos)).T* history(:,irfpos)+...
|
||||
dictionary.ss(ireg(irfpos)).C + E*errvec;
|
||||
T = dictionary.ss(ireg(irfpos)).T;
|
||||
CONST = dictionary.ss(ireg(irfpos)).C;
|
||||
R = E;
|
||||
else
|
||||
history(:,irfpos+1) = DM.decrulea*history(:,irfpos)+DM.decruleb*errvec;
|
||||
end
|
||||
|
||||
% all other periods
|
||||
for irfpos=2:n_periods+1
|
||||
if irfpos <=T_max
|
||||
history(:,irfpos+1) = dictionary.ss(ireg(irfpos)).T* history(:,irfpos)+...
|
||||
dictionary.ss(ireg(irfpos)).C;
|
||||
else
|
||||
history(:,irfpos+1) = DM.decrulea*history(:,irfpos);
|
||||
end
|
||||
end
|
||||
|
||||
zdata = history(:,2:end)';
|
|
@ -0,0 +1,81 @@
|
|||
function constraint_parsed = process_constraint(constraint,suffix,endo_names,invert_switch,param_names)
|
||||
%function constraint_parsed = process_constraint(constraint,suffix,endo_names,invert_switch,param_names)
|
||||
% Processes constraints for use in Occbin, appending endogenous variables
|
||||
% with suffix and replacing parameters by their value in M_.params
|
||||
%
|
||||
% INPUTS
|
||||
% - constraint [char] constraint to be parsed
|
||||
% - suffix [char] suffix to be appended
|
||||
% - endo_names [cell] names of endogenous variables
|
||||
% - invert_switch [bool] if true, invert direction of the inequality constraint
|
||||
% - param_names [cell] names of parameters
|
||||
%
|
||||
% OUTPUTS
|
||||
% - constraint_parsed [char] parsed constraint
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
% create a list of delimiters that can separate parameters and endogenoous
|
||||
% variables in the string that expresses the constraint
|
||||
delimiters = char(',',';','(',')','+','-','^','*','/','>','<','=');
|
||||
|
||||
% split the string that holds the constraint into tokens
|
||||
tokens = occbin.tokenize(constraint,delimiters);
|
||||
|
||||
ntokens = length(tokens);
|
||||
|
||||
endo_ss=strcat(endo_names,repmat('_ss',length(endo_names),1));
|
||||
|
||||
% search for tokens that match the list of endogenous variables
|
||||
for i=1:ntokens
|
||||
valid_token=0;
|
||||
if ~isempty(find(strcmp(tokens(i),delimiters)))
|
||||
% if the invert_switch is true
|
||||
% reverse the direction of the inequality
|
||||
if invert_switch
|
||||
if strcmp(tokens(i),cellstr('>'))
|
||||
tokens(i) = cellstr('<');
|
||||
elseif strcmp(tokens(i),cellstr('<'))
|
||||
tokens(i) = cellstr('>');
|
||||
end
|
||||
end
|
||||
valid_token=1;
|
||||
continue;
|
||||
end
|
||||
|
||||
if ~isempty(find(strcmp(tokens(i),endo_names)))
|
||||
% when there is a match with an endogenous variable append the suffix
|
||||
tokens(i) = cellstr([char(tokens(i)),suffix]);
|
||||
valid_token=1;
|
||||
continue;
|
||||
end
|
||||
par_index=find(strcmp(tokens(i),param_names));
|
||||
if ~isempty(par_index)
|
||||
tokens(i) = {['M_.params(',num2str(par_index),')']};
|
||||
valid_token=1;
|
||||
continue;
|
||||
end
|
||||
ss_index=find(strcmp(tokens(i),endo_ss));
|
||||
if ~isempty(ss_index)
|
||||
tokens(i) = {['ys(',num2str(ss_index),')']};
|
||||
valid_token=1;
|
||||
continue;
|
||||
end
|
||||
if isnan(str2double(tokens(i)))
|
||||
error('Occbin: Constraint %s contains the uninterpretable token %s', constraint, tokens{i});
|
||||
end
|
||||
end
|
||||
|
||||
% reassemble the tokens to create a string that expresses the constraint
|
||||
constraint_parsed = regexprep(strjoin(tokens),' ','');
|
|
@ -0,0 +1,35 @@
|
|||
function error_parsed = process_error_constraint(constraint)
|
||||
% function constraint1 = process_error_constraint(constraint)
|
||||
% Constructs a string with the constraint error, i.e. by how much it is violated
|
||||
% INPUTS
|
||||
% - constraint [char] constraint to be parsed
|
||||
%
|
||||
% OUTPUTS
|
||||
% - error_parsed [char] parsed constraint
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
error_parsed = constraint;
|
||||
error_parsed=regexprep(error_parsed,'=','');
|
||||
num = length(regexp(error_parsed,'>'))+length(regexp(error_parsed,'<'));
|
||||
error_parsed=regexprep(error_parsed,'>','-(');
|
||||
error_parsed=regexprep(error_parsed,'<','-(');
|
||||
for k=1:num
|
||||
error_parsed=[error_parsed ')'];
|
||||
end
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
function options_occbin_ = set_default_options(options_occbin_,M_,flag)
|
||||
% function options_occbin_ = set_default_options(options_occbin_,M_,flag)
|
||||
% Sets default options for Occbin
|
||||
%
|
||||
% INPUTS
|
||||
% - options_occbin_ [structure] Matlab's structure describing the current options
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - flag [cell] govern what/how much to initialize
|
||||
%
|
||||
% OUTPUTS
|
||||
% - options_occbin_ [structure] Matlab's structure describing the current options
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
if nargin<3
|
||||
flag='all';
|
||||
end
|
||||
|
||||
if ismember(flag,{'all'})
|
||||
options_occbin_.solver.solve_algo=3; %solver for match_function: csolve
|
||||
options_occbin_.solver.solve_tolx=1e-10;
|
||||
options_occbin_.solver.solve_tolf=1e-5;
|
||||
options_occbin_.solver.maxit=10;
|
||||
options_occbin_.write_regimes.periods=[];
|
||||
options_occbin_.write_regimes.filename=[M_.fname '_occbin_regimes'];
|
||||
end
|
||||
|
||||
if ismember(flag,{'filter','all'})
|
||||
options_occbin_.filter.use_relaxation = false;
|
||||
end
|
||||
|
||||
if ismember(flag,{'forecast','all'})
|
||||
options_occbin_.forecast.debug_flag=false;
|
||||
options_occbin_.forecast.frcst_regimes=[];
|
||||
options_occbin_.forecast.maxit=30;
|
||||
options_occbin_.forecast.periods=30;
|
||||
options_occbin_.forecast.qmc=0;
|
||||
options_occbin_.forecast.replic=0;
|
||||
options_occbin_.forecast.SHOCKS0=[];
|
||||
options_occbin_.forecast.treepath=1; % number of branches
|
||||
end
|
||||
|
||||
if ismember(flag,{'irf','all'})
|
||||
options_occbin_.irf.init_regime=[];
|
||||
options_occbin_.irf.maxit=30;
|
||||
options_occbin_.irf.threshold = 10^-6;
|
||||
% options_occbin_.irf.periods=options_.irf;
|
||||
options_occbin_.irf.shocksize=[];
|
||||
options_occbin_.irf.shocksigns = {'1','_1'};
|
||||
end
|
||||
|
||||
if ismember(flag,{'likelihood','all'})
|
||||
options_occbin_.likelihood.curb_retrench = false;
|
||||
options_occbin_.likelihood.first_period_occbin_update = true;
|
||||
options_occbin_.likelihood.full_output = false;
|
||||
options_occbin_.likelihood.IF_likelihood = false;
|
||||
options_occbin_.likelihood.init_regime_history = [];
|
||||
options_occbin_.likelihood.init_binding_indicator = false(0);
|
||||
options_occbin_.likelihood.inversion_filter = false;
|
||||
options_occbin_.likelihood.IVF_shock_observable_mapping = [];
|
||||
options_occbin_.likelihood.maxit = 50; % this is for occbin solver algo
|
||||
options_occbin_.likelihood.max_number_of_iterations = 10; % this is for occbin_kalman_update loop
|
||||
options_occbin_.likelihood.periods = 100;
|
||||
options_occbin_.likelihood.check_ahead_periods=200;
|
||||
options_occbin_.likelihood.periodic_solution=true;
|
||||
options_occbin_.likelihood.piecewise_only = true;
|
||||
options_occbin_.likelihood.restrict_state_space = true;
|
||||
options_occbin_.likelihood.status=true;
|
||||
options_occbin_.likelihood.use_updated_regime = true;
|
||||
options_occbin_.likelihood.waitbar=false;
|
||||
end
|
||||
|
||||
if ismember(flag,{'plot_shock_decomp','all'})
|
||||
options_occbin_.plot_shock_decomp.add_steadystate = false;
|
||||
options_occbin_.plot_shock_decomp.add_zero_line = false;
|
||||
options_occbin_.plot_shock_decomp.decomp_type='qoq';
|
||||
options_occbin_.plot_shock_decomp.figure_size = [200 100 650 850];
|
||||
options_occbin_.plot_shock_decomp.grid = false;
|
||||
options_occbin_.plot_shock_decomp.graph_line=false;
|
||||
options_occbin_.plot_shock_decomp.graph_regime=false;
|
||||
options_occbin_.plot_shock_decomp.graph_simul=char('total','linear');
|
||||
options_occbin_.plot_shock_decomp.graph_simul_zoom=char('total','piecewise','linear');
|
||||
options_occbin_.plot_shock_decomp.graph_zoom=false;
|
||||
options_occbin_.plot_shock_decomp.init_names_=[];
|
||||
options_occbin_.plot_shock_decomp.lw=2;
|
||||
options_occbin_.plot_shock_decomp.mystyles = {':','--',':','-.'};
|
||||
options_occbin_.plot_shock_decomp.ncol = 3;
|
||||
options_occbin_.plot_shock_decomp.no_legend = false;
|
||||
options_occbin_.plot_shock_decomp.no_others = false;
|
||||
options_occbin_.plot_shock_decomp.T0 = []; % initial date in plot (must be >= TINIT)
|
||||
options_occbin_.plot_shock_decomp.TINIT = dates(); % date of initialized states for shock decomp
|
||||
% options_occbin_.plot_shock_decomp.use_shock_groups=options_.plot_shock_decomp.use_shock_groups;
|
||||
end
|
||||
|
||||
if ismember(flag,{'plot_simul','all'})
|
||||
options_occbin_.plot_simul.add_steadystate = false;
|
||||
options_occbin_.plot_simul.add_vertical_line = false;
|
||||
options_occbin_.plot_simul.cutoff = false;
|
||||
options_occbin_.plot_simul.figure_size = [50 50 850 850];
|
||||
options_occbin_.plot_simul.labels = {'Linear','Piecewise','Simulation 3','Simulation 4'};
|
||||
options_occbin_.plot_simul.legend = true;
|
||||
options_occbin_.plot_simul.length_simul = [];
|
||||
options_occbin_.plot_simul.linewidth = 2;
|
||||
options_occbin_.plot_simul.log_normalize_graph = false;
|
||||
options_occbin_.plot_simul.marg_h(1) = 0.08;
|
||||
options_occbin_.plot_simul.marg_h(2) = 0.055;
|
||||
options_occbin_.plot_simul.mycolors = get(groot,'DefaultAxesColorOrder');
|
||||
options_occbin_.plot_simul.my_dir = 'OccBinSimul';
|
||||
options_occbin_.plot_simul.mystyles = {'-','--',':','-.'};
|
||||
options_occbin_.plot_simul.mystst_simul_pos = false;
|
||||
options_occbin_.plot_simul.ncols = 3;
|
||||
options_occbin_.plot_simul.normalization_point = 1;
|
||||
options_occbin_.plot_simul.nrows = 3;
|
||||
options_occbin_.plot_simul.print_emf = false;
|
||||
options_occbin_.plot_simul.scale_y = false;
|
||||
options_occbin_.plot_simul.scale_y1 = true;
|
||||
options_occbin_.plot_simul.scale_y2 = true;
|
||||
options_occbin_.plot_simul.simulname = 'occbin_simul';
|
||||
options_occbin_.plot_simul.subplot_gap = 0.07;
|
||||
options_occbin_.plot_simul.threshold = 10^-6;
|
||||
options_occbin_.plot_simul.timeaxis = [];
|
||||
options_occbin_.plot_simul.use_grid = true;
|
||||
|
||||
end
|
||||
|
||||
if ismember(flag,{'shock_decomp','all'})
|
||||
options_occbin_.shock_decomp.additive=false;
|
||||
options_occbin_.shock_decomp.curb_retrench=false;
|
||||
options_occbin_.shock_decomp.debug=false;
|
||||
options_occbin_.shock_decomp.init_in_others=false;
|
||||
options_occbin_.shock_decomp.init_names_=[];
|
||||
options_occbin_.shock_decomp.init_total=false;
|
||||
options_occbin_.shock_decomp.init2shocks= false;
|
||||
options_occbin_.shock_decomp.main_effect=false;
|
||||
options_occbin_.shock_decomp.main_effect_init=false;
|
||||
options_occbin_.shock_decomp.maxit = 100;
|
||||
options_occbin_.shock_decomp.nfrcst=0;
|
||||
options_occbin_.shock_decomp.periods = 60;
|
||||
options_occbin_.shock_decomp.check_ahead_periods=200;
|
||||
options_occbin_.shock_decomp.shocks_only=false;
|
||||
options_occbin_.shock_decomp.total_effect=false;
|
||||
options_occbin_.shock_decomp.conditional_only=true;
|
||||
options_occbin_.shock_decomp.TINIT = dates(); % date to initialize states for shock decomp
|
||||
% options_occbin_.shock_decomp.use_shock_groups=options_.plot_shock_decomp.use_shock_groups;
|
||||
end
|
||||
|
||||
if ismember(flag,{'simul','all'})
|
||||
options_occbin_.simul.debug = false;
|
||||
options_occbin_.simul.curb_retrench=false;
|
||||
options_occbin_.simul.endo_init=zeros(M_.endo_nbr,1);
|
||||
options_occbin_.simul.full_output=true;
|
||||
options_occbin_.simul.init_regime=[];
|
||||
options_occbin_.simul.init_binding_indicator=false(0);
|
||||
options_occbin_.simul.exo_pos=1:M_.exo_nbr;
|
||||
options_occbin_.simul.local=true;
|
||||
options_occbin_.simul.maxit=10;
|
||||
options_occbin_.simul.max_periods=inf;
|
||||
options_occbin_.simul.periods=30;
|
||||
options_occbin_.simul.check_ahead_periods=200;
|
||||
options_occbin_.simul.periodic_solution=true;
|
||||
options_occbin_.simul.piecewise_only = false;
|
||||
options_occbin_.simul.restrict_state_space=false;
|
||||
options_occbin_.simul.SHOCKS=zeros(1,M_.exo_nbr);
|
||||
options_occbin_.simul.waitbar=true;
|
||||
end
|
||||
|
||||
if ismember(flag,{'smoother','all'})
|
||||
options_occbin_.smoother.curb_retrench = false;
|
||||
options_occbin_.smoother.debug = false;
|
||||
options_occbin_.smoother.fast = false;
|
||||
options_occbin_.smoother.first_period_occbin_update = true;
|
||||
options_occbin_.smoother.full_output = false;
|
||||
% options.occbin.smoother.init_mode = 1; % 0 = standard; 1 = unconditional frcsts zero shocks+smoothed states in each period
|
||||
options_occbin_.smoother.init_regime_history = [];
|
||||
options_occbin_.smoother.init_binding_indicator = false(0);
|
||||
options_occbin_.smoother.inversion_filter = false;
|
||||
options_occbin_.smoother.linear_smoother = true;
|
||||
options_occbin_.smoother.maxit = 30; % this is for occbin solver algo
|
||||
options_occbin_.smoother.max_number_of_iterations = 10; % this is for smoother loop
|
||||
options_occbin_.smoother.periods = 100;
|
||||
options_occbin_.smoother.check_ahead_periods=200;
|
||||
options_occbin_.smoother.piecewise_only = true;
|
||||
options_occbin_.smoother.plot = true;
|
||||
options_occbin_.smoother.status=true;
|
||||
options_occbin_.smoother.waitbar=true;
|
||||
% options.occbin.smoother.restrict_state_space = 1;
|
||||
end
|
||||
|
||||
if ismember(flag,{'graph','all'})
|
||||
options_occbin_.graph.steady_state=true;
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
function options_=set_option(options_,options_occbin_,fieldname)
|
||||
% function options_=set_option(options_,options_occbin_,fieldname)
|
||||
% Set local option for Occbin
|
||||
%
|
||||
% Inputs:
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
% - options_occbin_ [structure] Matlab's structure containing Occbin options
|
||||
% - fieldname [string] name of the options field to set
|
||||
%
|
||||
% Outputs:
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
dot_pos = strfind(fieldname,'.');
|
||||
|
||||
if isfield(options_occbin_,fieldname(1:dot_pos-1)) && isfield(options_occbin_.(fieldname(1:dot_pos-1)),fieldname(dot_pos+1:end))
|
||||
options_.occbin.(fieldname(1:dot_pos-1)).(fieldname(dot_pos+1:end)) = options_occbin_.(fieldname(1:dot_pos-1)).(fieldname(dot_pos+1:end));
|
||||
end
|
|
@ -0,0 +1,52 @@
|
|||
function [M_, options_] = setup(M_,options_, options_occbin_)
|
||||
% function [M_, options_] = setup(M_, options_, options_occbin_)
|
||||
% Sets up run of Occbin: creates shock matrix, sets options
|
||||
%
|
||||
% INPUT:
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
% - options_occbin_ [structure] Matlab's structure containing Occbin options
|
||||
%
|
||||
% OUTPUT:
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - options_occbin_ [structure] Matlab's structure containing Occbin options
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
options_ = occbin.set_option(options_,options_occbin_,'simul.periods');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'simul.curb_retrench');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'simul.maxit');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'simul.check_ahead_periods');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'smoother.periods');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'smoother.curb_retrench');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'smoother.maxit');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'smoother.check_ahead_periods');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'filter.use_relaxation');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'likelihood.inversion_filter');
|
||||
options_ = occbin.set_option(options_,options_occbin_,'smoother.inversion_filter');
|
||||
|
||||
if isfield(M_,'surprise_shocks') && ~isempty(M_.surprise_shocks)
|
||||
temp=zeros(max(cat(2,M_.surprise_shocks.periods)),M_.exo_nbr);
|
||||
for ii = 1:length(M_.surprise_shocks)
|
||||
ivar = M_.surprise_shocks(ii).exo_id;
|
||||
temp(M_.surprise_shocks(ii).periods,ivar) = M_.surprise_shocks(ii).value;
|
||||
end
|
||||
shock_index=~all(temp==0);
|
||||
options_.occbin.simul.SHOCKS=temp(:,shock_index);
|
||||
options_.occbin.simul.exo_pos=find(shock_index);
|
||||
end
|
|
@ -0,0 +1,266 @@
|
|||
function oo_ = shock_decomposition(oo_, M_, options_, vname)
|
||||
% function oo_ = shock_decomposition(oo_, M_, options_, vname)
|
||||
%
|
||||
% INPUTS
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - options_ [structure] Matlab's structure describing the current options (options_).
|
||||
% - vname [cell] array of variable names
|
||||
% OUTPUT
|
||||
% - oo_ [structure] Matlab's structure containing the results (oo_).
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
% list of options
|
||||
% T0, use_shock_groups, vname, file_name, nfrcst, init_names_
|
||||
|
||||
shock_decomp_options = options_.occbin.shock_decomp;
|
||||
|
||||
if nargin<4 || isempty(vname)
|
||||
vname=cellstr(M_.endo_names(1:M_.orig_endo_nbr,:));
|
||||
end
|
||||
|
||||
opts_simul = options_.occbin.simul;
|
||||
opts_simul.periods = shock_decomp_options.periods;
|
||||
opts_simul.check_ahead_periods = shock_decomp_options.check_ahead_periods;
|
||||
opts_simul.maxit = shock_decomp_options.maxit;
|
||||
use_shock_groups = shock_decomp_options.use_shock_groups;
|
||||
|
||||
init_names_ = shock_decomp_options.init_names_;
|
||||
nfrcst = shock_decomp_options.nfrcst;
|
||||
|
||||
%% new dynare grouping
|
||||
if isempty(use_shock_groups)
|
||||
use_shock_groups = 'ALL';
|
||||
ngroups = M_.exo_nbr;
|
||||
ex_names_ = cell(ngroups,1);
|
||||
for i=1:ngroups
|
||||
ex_names_{i} = M_.exo_names(i);
|
||||
end
|
||||
shock_decomp_options.main_effect=0;
|
||||
shock_decomp_options.additive = 0;
|
||||
else
|
||||
shock_groups = M_.shock_groups.(use_shock_groups);
|
||||
shock_ind = fieldnames(shock_groups);
|
||||
ngroups = length(shock_ind);
|
||||
ex_names_ = shock_ind;
|
||||
for i=1:ngroups
|
||||
ex_names_{i} = shock_groups.(shock_ind{i}).shocks;
|
||||
end
|
||||
end
|
||||
%%
|
||||
|
||||
if iscell(vname{1})
|
||||
vname0=vname;
|
||||
clear vname
|
||||
vname = cell(1,length(vname0));
|
||||
decomp_type = cell(1,length(vname0));
|
||||
gtrend = cell(1,length(vname0));
|
||||
var_type = nan(1,length(vname0));
|
||||
for j=1:length(vname0)
|
||||
vname{j}=vname0{j}{1};
|
||||
decomp_type{j}=vname0{j}{2};
|
||||
if strcmpi(decomp_type{j},'aoa')
|
||||
gtrend{j}=vname0{j}{3};
|
||||
if strcmpi(vname0{j}{4},'flow')
|
||||
var_type(j)=1;
|
||||
elseif strcmpi(vname0{j}{4},'deflator')
|
||||
var_type(j)=2;
|
||||
elseif strcmpi(vname0{j}{4},'stock')
|
||||
var_type(j)=0;
|
||||
else
|
||||
error('wrong var type for aoa decomp')
|
||||
end
|
||||
end
|
||||
end
|
||||
clear vname0
|
||||
else
|
||||
decomp_type = cell(1,length(vname));
|
||||
for j=1:length(vname)
|
||||
decomp_type{j}='qoq';
|
||||
end
|
||||
end
|
||||
|
||||
% set time-varying state space matrices
|
||||
TT = oo_.occbin.smoother.T0;
|
||||
RR = oo_.occbin.smoother.R0;
|
||||
CC = oo_.occbin.smoother.C0;
|
||||
|
||||
load (options_.datafile, 'T');
|
||||
|
||||
indx_init=zeros(length(init_names_),1);
|
||||
for j=1:length(init_names_)
|
||||
indx_init(j)=strmatch(init_names_{j},M_.endo_names(oo_.dr.order_var,:),'exact');
|
||||
end
|
||||
|
||||
if shock_decomp_options.debug
|
||||
% re-compute smoothed variables from T, R and smoothed shocks etahat
|
||||
a1=oo_.occbin.smoother.alphahat(:,1);
|
||||
as=a1;
|
||||
as0=zeros(length(a1),1);
|
||||
as0(indx_init)=a1(indx_init);
|
||||
etahat=[oo_.occbin.smoother.etahat zeros(size(oo_.occbin.smoother.etahat,1),nfrcst)];
|
||||
for j=1:size(etahat,2)-1
|
||||
TM = TT(:,:,j+1);
|
||||
RM = RR(:,:,j+1);
|
||||
CONST = CC(:,j+1);
|
||||
as(:,j+1)=TM*as(:,j)+RM*etahat(:,j+1)+CONST;
|
||||
as0(:,j+1)=TM*as0(:,j)+CONST;
|
||||
end
|
||||
err = max(max(abs(oo_.occbin.smoother.alphahat-as)));
|
||||
if err>1e-8
|
||||
disp('WARNING CHECK SMOOTHER:')
|
||||
disp(['simulated model with smoothed shocks differs from stored smoother by ' num2str(err)])
|
||||
else
|
||||
disp('CHECK SMOOTHER OK:')
|
||||
disp(['simulated model with smoothed shocks differs from stored smoother by less than 1e-8 (err=' num2str(err) ')'])
|
||||
end
|
||||
else
|
||||
etahat=[oo_.occbin.smoother.etahat zeros(size(oo_.occbin.smoother.etahat,1),nfrcst)];
|
||||
as = oo_.occbin.smoother.alphahat;
|
||||
end
|
||||
gend=size(etahat,2);
|
||||
|
||||
%%
|
||||
TT= 0:0.25:ceil(gend/4+1);
|
||||
TT=TT(1:gend);
|
||||
TT1= dates('0Q1'):(dates('0Q1')+gend-1);
|
||||
if exist('T','var')
|
||||
TT=T(options_.first_obs)+TT;
|
||||
TT1=TT1+T(options_.first_obs)*4;
|
||||
end
|
||||
|
||||
shock_decomp_options = set_default_option(shock_decomp_options,'TINIT',TT1(1));
|
||||
tinit = max([1,find(TT1==shock_decomp_options.TINIT)]);
|
||||
TINIT = char(TT1(tinit));
|
||||
shock_decomp_options = set_default_option(shock_decomp_options,'file_name',['_' use_shock_groups '_' TINIT]);
|
||||
file_name = shock_decomp_options.file_name;
|
||||
|
||||
%%
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%% LINEAR shock decomp
|
||||
as_lin=zeros(M_.endo_nbr,length(tinit:gend)); % linear smoother reconstructed
|
||||
att=zeros(M_.endo_nbr,length(tinit:gend)); % linear initial condition effect
|
||||
inn=zeros(M_.endo_nbr,length(tinit:gend)); % linear aggreage shocks effect without att, i.e. as_lin = inn+att;
|
||||
deco=zeros(M_.endo_nbr,M_.exo_nbr,length(tinit:gend)); % full decomposition into individual shocks
|
||||
|
||||
att(:,1)=oo_.occbin.linear_smoother.alphahat(:,tinit);
|
||||
as_lin(:,1)=oo_.occbin.linear_smoother.alphahat(:,tinit);
|
||||
TM = oo_.occbin.linear_smoother.T0;
|
||||
RM= oo_.occbin.linear_smoother.R0;
|
||||
for j=2:length(tinit:gend)
|
||||
as_lin(:,j) = TM*as_lin(:,j-1)+RM*oo_.occbin.linear_smoother.etahat(:,j+tinit-1);
|
||||
att(:,j) = TM*att(:,j-1);
|
||||
inn(:,j) = RM*oo_.occbin.linear_smoother.etahat(:,j+tinit-1);
|
||||
if j>1
|
||||
inn(:,j) = inn(:,j) + TM*inn(:,j-1);
|
||||
end
|
||||
for iexo=1:M_.exo_nbr
|
||||
deco(:,iexo,j) = RM(:,iexo)*oo_.occbin.linear_smoother.etahat(iexo,j+tinit-1);
|
||||
if j>1
|
||||
deco(:,iexo,j) = deco(:,iexo,j) + TM*deco(:,iexo,j-1);
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
as_lin=as_lin(oo_.dr.inv_order_var,:); % linear smoother reconstructed
|
||||
att=att(oo_.dr.inv_order_var,:); % linear initial condition effect
|
||||
inn=inn(oo_.dr.inv_order_var,:); % linear aggreage shocks effect without att
|
||||
deco=deco(oo_.dr.inv_order_var,:,:); % full decomposition into individual shocks
|
||||
deco(:,M_.exo_nbr+1,:)=att;
|
||||
deco(:,M_.exo_nbr+2,:)=as_lin;
|
||||
oo_.occbin.linear_smoother.decomp=deco;
|
||||
%%%%%%%%%%%%%%%%%%%% END LINEAR shock decomp
|
||||
|
||||
%%
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%% piecewise COONDITIONAL shock decomp
|
||||
as_p=zeros(M_.endo_nbr,length(tinit:gend)); % smoother reconstructed
|
||||
att_p=zeros(M_.endo_nbr,length(tinit:gend)); % initial condition effect
|
||||
inn_p=zeros(M_.endo_nbr,length(tinit:gend)); % aggreage shocks effect without att, i.e. as_lin = inn+att;
|
||||
deco_p=zeros(M_.endo_nbr,M_.exo_nbr,length(tinit:gend)); % full decomposition into individual shocks
|
||||
reg_p=zeros(M_.endo_nbr,length(tinit:gend)); % pure regime effect (CONST 'shocks')
|
||||
|
||||
att_p(:,1)=oo_.occbin.smoother.alphahat(:,tinit);
|
||||
as_p(:,1)=oo_.occbin.smoother.alphahat(:,tinit);
|
||||
TT = oo_.occbin.smoother.T0;
|
||||
RR= oo_.occbin.smoother.R0;
|
||||
CC= oo_.occbin.smoother.C0;
|
||||
|
||||
for j=2:length(tinit:gend)
|
||||
TM = TT(:,:,j+tinit-1);
|
||||
RM = RR(:,:,j+tinit-1);
|
||||
CONST = CC(:,j+tinit-1);
|
||||
as_p(:,j) = TM*as_p(:,j-1)+RM*oo_.occbin.smoother.etahat(:,j+tinit-1)+CONST;
|
||||
att_p(:,j) = TM*att_p(:,j-1);
|
||||
inn_p(:,j) = RM*oo_.occbin.smoother.etahat(:,j+tinit-1);
|
||||
reg_p(:,j) = TM*reg_p(:,j-1)+CONST;
|
||||
if j>1
|
||||
inn_p(:,j) = inn_p(:,j) + TM*inn_p(:,j-1) ;
|
||||
end
|
||||
for iexo=1:M_.exo_nbr
|
||||
deco_p(:,iexo,j) = RM(:,iexo)*oo_.occbin.smoother.etahat(iexo,j+tinit-1);
|
||||
if j>1
|
||||
deco_p(:,iexo,j) = deco_p(:,iexo,j) + TM*deco_p(:,iexo,j-1);
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
as_p=as_p(oo_.dr.inv_order_var,:); % occbin smoother reconstructed
|
||||
att_p=att_p(oo_.dr.inv_order_var,:); % occbin initial condition effect
|
||||
inn_p=inn_p(oo_.dr.inv_order_var,:); % occbin aggregage shocks effect without att
|
||||
deco_p=deco_p(oo_.dr.inv_order_var,:,:); % occbin full decomposition into individual shocks
|
||||
reg_p=reg_p(oo_.dr.inv_order_var,:); % occbin pure regime effect (CONST 'shocks')
|
||||
i_reg=strmatch('EPS_REGIME',M_.exo_names,'exact');
|
||||
if ~isempty(i_reg)
|
||||
deco_p(:,i_reg,:)=reg_p;
|
||||
end
|
||||
deco_p(:,M_.exo_nbr+1,:)=att_p;
|
||||
deco_p(:,M_.exo_nbr+2,:)=as_p;
|
||||
%deco_p(:,M_.exo_nbr+3,:)=as_p-reg_p;
|
||||
oo_.occbin.smoother.decomp=deco_p;
|
||||
rr=abs(deco_p(:,1:end-1,:));
|
||||
if isequal(use_shock_groups,'ALL') && ~isempty(i_reg)
|
||||
rr(:,i_reg,:)=0;
|
||||
end
|
||||
ww=zeros(size(rr));
|
||||
for k=1:size(rr,3)
|
||||
tmp=sum(rr(:,:,k),2);
|
||||
tmp(tmp<1.e-10)=1;
|
||||
for g=1:size(rr,2)
|
||||
ww(:,g,k) = rr(:,g,k)./tmp;
|
||||
end
|
||||
end
|
||||
wdeco_p=deco_p;
|
||||
if ~isempty(i_reg)
|
||||
wdeco_p(:,i_reg,:)=0;
|
||||
end
|
||||
for k=1:size(rr,3)
|
||||
if any(any(reg_p(:,k)))
|
||||
for g=1:size(rr,2)
|
||||
wdeco_p(:,g,k) = wdeco_p(:,g,k)+reg_p(:,k).*ww(:,g,k);
|
||||
end
|
||||
end
|
||||
end
|
||||
oo_.occbin.smoother.wdecomp=wdeco_p;
|
||||
%%%%%%%%%%%%%%%%%%%% END CONDITIONAL shock decomp
|
||||
%% add here other fetures when ready
|
||||
% if shock_decomp_options.conditional_only ==1
|
||||
% return
|
||||
% end
|
|
@ -0,0 +1,297 @@
|
|||
function [data, SS_out, error_flag ] = solve_one_constraint(M_,dr, opts_simul_, solve_DM)
|
||||
%function [data, SS_out, error_flag ] = solve_one_constraint(M_,dr, opts_simul_, solve_DM)
|
||||
%
|
||||
% INPUT:
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - dr [structure] decision rules for the model
|
||||
% - opts_simul [structure] Matlab's structure containing the Occbin options (opts_simul).
|
||||
% - solve_DM [double] indicator on whether to recompute decision rules
|
||||
%
|
||||
% OUTPUT:
|
||||
% - data [structure] simulation result containing fields:
|
||||
% - linear: paths for endogenous variables ignoring OBC (linear solution)
|
||||
% - piecewise: paths for endogenous variables satisfying the OBC (occbin/piecewise solution)
|
||||
% - ys: vector of steady state values
|
||||
% - regime_history: information on number and time of regime transitions
|
||||
% - SS_out [structure] State space solution
|
||||
% - T: [n_vars by n_vars by n_shock_period] array of transition matrices
|
||||
% - R: [n_vars by n_exo by n_shock_period] array of shock response matrices
|
||||
% - C: [n_vars by n_shock_period] array of constants
|
||||
% - error_flag [integer] 1 if a problem was encoutered, 0 otherwise
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
persistent DM
|
||||
|
||||
if isempty(DM)
|
||||
solve_DM=true;
|
||||
end
|
||||
|
||||
data.shocks_sequence = opts_simul_.SHOCKS; % sequence of unforeseen shocks under which one wants to solve the model
|
||||
n_periods = opts_simul_.periods; % simulation horizon (can be longer than the sequence of shocks defined in shockssequence; must be long enough to ensure convergence back to the reference model at the end of the simulation horizon and may need to be varied depending on the sequence of shocks).
|
||||
curb_retrench = opts_simul_.curb_retrench; % 0: updates guess based on previous iteration; 1: updates similar to Gauss-Jacobi scheme, slowing iterations down by updating guess only one period at a time
|
||||
max_iter = opts_simul_.maxit; % maximum number of iterations allowed for the solution algorithm
|
||||
endo_init = opts_simul_.endo_init; % initial condition for state variables, in deviation from steady state in declaration order
|
||||
binding_indicator = opts_simul_.init_binding_indicator; % initial guess for constraint violations
|
||||
regime_history_guess = opts_simul_.init_regime; % initial guess for constraint violations
|
||||
periodic_solution = opts_simul_.periodic_solution;
|
||||
|
||||
data.exo_pos = opts_simul_.exo_pos;
|
||||
|
||||
n_shocks_periods = size(data.shocks_sequence,1);
|
||||
|
||||
if n_periods < n_shocks_periods
|
||||
n_periods = n_shocks_periods;
|
||||
end
|
||||
nperiods_0 = max(opts_simul_.check_ahead_periods,n_periods-n_shocks_periods);
|
||||
|
||||
error_flag=0;
|
||||
|
||||
M_base = M_;
|
||||
dr_base = dr;
|
||||
|
||||
% ensure that the two models have the same parameters
|
||||
% use the parameters for the base model.
|
||||
%Mstar_.params = Mbase_.params;
|
||||
|
||||
data.ys = dr_base.ys;
|
||||
|
||||
if solve_DM
|
||||
DM.n_vars = M_base.endo_nbr;
|
||||
DM.n_exo = M_base.exo_nbr;
|
||||
|
||||
% get the matrices holding the first derivatives for the model
|
||||
% each regime is treated separately
|
||||
[DM.Cbarmat, DM.Bbarmat, DM.Abarmat, DM.Jbarmat] = occbin.get_deriv(M_base,data.ys);
|
||||
|
||||
Mstar_= M_base;
|
||||
Mstar_.params(M_.occbin.constraint(1).pswitch_index)= 1;
|
||||
[DM.Cstarbarmat, DM.Bstarbarmat, DM.Astarbarmat, DM.Jstarbarmat, DM.Dstarbarmat] = occbin.get_deriv(Mstar_,data.ys);
|
||||
|
||||
[DM.decrulea,DM.decruleb]=occbin.get_pq(dr_base);
|
||||
|
||||
update_flag=true;
|
||||
else
|
||||
update_flag=false;
|
||||
end
|
||||
|
||||
endo_names = M_base.endo_names;
|
||||
exo_names = M_base.exo_names;
|
||||
|
||||
|
||||
% set some initial conditions and loop through the shocks
|
||||
% period by period
|
||||
init_orig_ = endo_init;
|
||||
zdatapiecewise_ = zeros(n_periods,DM.n_vars);
|
||||
% nwishes_ = size(wishlist_,1);
|
||||
if ~exist('binding_indicator','var')
|
||||
binding_indicator = false(nperiods_0+1,1);
|
||||
else
|
||||
if length(binding_indicator)<(nperiods_0+1)
|
||||
binding_indicator = [binding_indicator; false(nperiods_0+1-length(binding_indicator),1)];
|
||||
end
|
||||
end
|
||||
SS_out.T = NaN(DM.n_vars,DM.n_vars,n_shocks_periods);
|
||||
SS_out.R = NaN(DM.n_vars,DM.n_exo,n_shocks_periods);
|
||||
SS_out.C = nan(DM.n_vars,n_shocks_periods);
|
||||
if ~exist('regime_history_','var') || isempty(regime_history_guess)
|
||||
regime_history = struct();
|
||||
guess_history = false;
|
||||
else
|
||||
guess_history = true;
|
||||
regime_history = regime_history_guess;
|
||||
end
|
||||
|
||||
if opts_simul_.waitbar
|
||||
hh = dyn_waitbar(0,'Occbin: Solving the model');
|
||||
set(hh,'Name','Occbin: Solving the model.');
|
||||
end
|
||||
|
||||
for shock_period = 1:n_shocks_periods
|
||||
if opts_simul_.waitbar
|
||||
dyn_waitbar(shock_period/n_shocks_periods, hh, sprintf('Period %u of %u', shock_period,n_shocks_periods));
|
||||
end
|
||||
|
||||
regime_change_this_iteration=true;
|
||||
iter = 0;
|
||||
guess_history_it = false;
|
||||
if guess_history && (shock_period<=length(regime_history_guess)) %beyond guess regime history
|
||||
guess_history_it = true;
|
||||
end
|
||||
|
||||
is_periodic=false;
|
||||
binding_indicator_history={};
|
||||
max_err = NaN(max_iter,1);
|
||||
|
||||
while (regime_change_this_iteration && iter<max_iter && ~is_periodic)
|
||||
iter = iter +1;
|
||||
if binding_indicator(end) && nperiods_0<opts_simul_.max_periods
|
||||
binding_indicator = [binding_indicator; false ];
|
||||
nperiods_0 = nperiods_0 + 1;
|
||||
disp_verbose(['nperiods has been endogenously increased up to ' int2str(nperiods_0) '.'],opts_simul_.debug)
|
||||
end
|
||||
if length(binding_indicator)<(nperiods_0 + 1)
|
||||
binding_indicator=[binding_indicator; false(nperiods_0 + 1-length(binding_indicator),1)];
|
||||
end
|
||||
|
||||
binding_indicator_history{iter}=binding_indicator;
|
||||
|
||||
if iter==1 && guess_history_it
|
||||
regime = regime_history_guess(shock_period).regime;
|
||||
regime_start = regime_history_guess(shock_period).regimestart;
|
||||
binding_indicator(:,1) = regime(end);
|
||||
for ir=1:length(regime)-1
|
||||
binding_indicator(regime_start(ir):regime_start(ir+1)-1,1) = regime(ir);
|
||||
end
|
||||
nperiods_0 = size(binding_indicator,1)-1; %if history is present, update may be required
|
||||
end
|
||||
% analyze when each regime starts based on current guess
|
||||
[regime, regime_start, error_code_period]=occbin.map_regime(binding_indicator,opts_simul_.debug);
|
||||
regime_history(shock_period).regime = regime;
|
||||
regime_history(shock_period).regimestart = regime_start;
|
||||
|
||||
% get the hypothesized piece wise linear solution
|
||||
if shock_period==1 || shock_period>1 && any(data.shocks_sequence(shock_period,:))
|
||||
[zdatalinear_, SS_out.T(:,:,shock_period), SS_out.R(:,:,shock_period), SS_out.C(:,shock_period), SS, update_flag]=occbin.mkdatap_anticipated_dyn(nperiods_0,DM,...
|
||||
regime_start(end)-1,binding_indicator,...
|
||||
data.exo_pos,data.shocks_sequence(shock_period,:),endo_init,update_flag);
|
||||
|
||||
[binding, relax, err]=feval([M_.fname,'.eval_difference'],zdatalinear_,M_,dr_base.ys);
|
||||
|
||||
% check if changes to the hypothesis of the duration for each
|
||||
% regime
|
||||
if any(binding.constraint_1 & ~binding_indicator) || any(relax.constraint_1 & binding_indicator)
|
||||
err_viol = err.binding_constraint_1(binding.constraint_1 & ~binding_indicator);
|
||||
err_relax = err.relax_constraint_1(relax.constraint_1 & binding_indicator);
|
||||
max_err(iter) = max(abs([err_viol;err_relax]));
|
||||
regime_change_this_iteration = true;
|
||||
else
|
||||
regime_change_this_iteration = false;
|
||||
max_err(iter) = 0;
|
||||
end
|
||||
|
||||
if curb_retrench % apply Gauss-Seidel idea of slowing down the change in the guess
|
||||
% for the constraint -- only relax one
|
||||
% period at a time starting from the last
|
||||
% one when each of the constraints is true.
|
||||
retrench = false(numel(binding_indicator),1);
|
||||
max_relax_constraint_1=find(relax.constraint_1 & binding_indicator,1,'last');
|
||||
if ~isempty(max_relax_constraint_1) && find(relax.constraint_1,1,'last')>=find(binding_indicator,1,'last')
|
||||
retrench(max_relax_constraint_1) = true;
|
||||
end
|
||||
binding_indicator = (binding_indicator | binding.constraint_1) & ~ retrench;
|
||||
else
|
||||
binding_indicator= (binding_indicator | binding.constraint_1) & ~(binding_indicator & relax.constraint_1);
|
||||
end
|
||||
|
||||
if iter>1 && regime_change_this_iteration
|
||||
for kiter=1:iter-1
|
||||
vvv = [binding_indicator_history{kiter}; false(size(binding_indicator,1)- size(binding_indicator_history{kiter},1), 1)];
|
||||
is_periodic(kiter) = isequal(vvv, binding_indicator);
|
||||
end
|
||||
is_periodic_all =is_periodic;
|
||||
is_periodic = any(is_periodic);
|
||||
if is_periodic && periodic_solution
|
||||
[merr,imerr]=min(max_err(find(is_periodic_all,1):end));
|
||||
inx = find(is_periodic_all,1):iter;
|
||||
inx = inx(imerr);
|
||||
binding_indicator=binding_indicator_history{inx};
|
||||
if inx<iter
|
||||
[regime, regime_start, error_code_period]=occbin.map_regime(binding_indicator,opts_simul_.debug);
|
||||
regime_history(shock_period).regime = regime;
|
||||
regime_history(shock_period).regimestart = regime_start;
|
||||
|
||||
% get the hypothesized piece wise linear solution
|
||||
[zdatalinear_, SS_out.T(:,:,shock_period), SS_out.R(:,:,shock_period), SS_out.C(:,shock_period), SS, update_flag]=occbin.mkdatap_anticipated_dyn(nperiods_0,DM,...
|
||||
regime_start(end)-1,binding_indicator,...
|
||||
data.exo_pos,data.shocks_sequence(shock_period,:),endo_init,update_flag);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
regime_change_this_iteration=false;
|
||||
zdatalinear_(1:end-1,:)=zdatalinear_(2:end,:);
|
||||
zdatalinear_(end,:) = DM.decrulea*zdatalinear_(end-1,:)';
|
||||
if length(SS)>1
|
||||
SS=SS(2:end);
|
||||
else
|
||||
SS=[];
|
||||
end
|
||||
if isempty(SS)
|
||||
SS_out.T(:,:,shock_period)= DM.decrulea;
|
||||
SS_out.R(:,:,shock_period)= DM.decruleb;
|
||||
SS_out.C(:,shock_period)= 0;
|
||||
else
|
||||
SS_out.T(:,:,shock_period)= SS(1).T;
|
||||
SS_out.R(:,:,shock_period)= SS(1).R;
|
||||
SS_out.C(:,shock_period)= SS(1).C;
|
||||
end
|
||||
binding_indicator_history{iter}=binding_indicator;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if regime_change_this_iteration ==1 && max_iter>1
|
||||
disp_verbose(['occbin solver:: period ' int2str(shock_period) '::'],opts_simul_.debug)
|
||||
if is_periodic
|
||||
disp_verbose('Occbin solver loops between two regimes.',opts_simul_.debug)
|
||||
if periodic_solution
|
||||
disp_verbose(['Max error:' num2str(merr) '.'],opts_simul_.debug)
|
||||
else
|
||||
if opts_simul_.waitbar; dyn_waitbar_close(hh); end
|
||||
error_flag = 310;
|
||||
return
|
||||
end
|
||||
else
|
||||
disp_verbose('Did not converge -- increase maxit.',opts_simul_.debug)
|
||||
if opts_simul_.waitbar; dyn_waitbar_close(hh); end
|
||||
error_flag = 311;
|
||||
return
|
||||
end
|
||||
end
|
||||
if any(error_code_period)
|
||||
disp_verbose('Increase nperiods.',opts_simul_.debug)
|
||||
if opts_simul_.waitbar; dyn_waitbar_close(hh); end
|
||||
error_flag = 312;
|
||||
return
|
||||
end
|
||||
|
||||
endo_init = zdatalinear_(1,:);
|
||||
zdatapiecewise_(shock_period,:)=endo_init;
|
||||
endo_init= endo_init';
|
||||
|
||||
% reset binding_indicator for next period's shock -- this resetting is
|
||||
% consistent with expecting no additional shocks
|
||||
binding_indicator=[binding_indicator(2:end); false];
|
||||
|
||||
end
|
||||
|
||||
% if necessary, fill in the rest of the path with the remainder of the
|
||||
% last IRF computed.
|
||||
zdatapiecewise_(n_shocks_periods+1:end,:)=zdatalinear_(2:n_periods-n_shocks_periods+1,:);
|
||||
|
||||
data.piecewise=zdatapiecewise_;
|
||||
data.regime_history=regime_history;
|
||||
|
||||
if ~opts_simul_.piecewise_only
|
||||
% get the linear responses
|
||||
data.linear = occbin.mkdata(max(n_periods,size(data.shocks_sequence,1)),...
|
||||
DM.decrulea,DM.decruleb,endo_names,exo_names,...
|
||||
[],data.exo_pos,data.shocks_sequence,init_orig_);
|
||||
end
|
||||
|
||||
if opts_simul_.waitbar
|
||||
dyn_waitbar_close(hh);
|
||||
end
|
|
@ -0,0 +1,321 @@
|
|||
function [ data, SS_out, error_flag] = solve_two_constraints(M_,dr, opts_simul_, solve_DM)
|
||||
% function [ data, SS_out, error_flag] = solve_two_constraints(M_,dr, opts_simul_, solve_DM)
|
||||
%
|
||||
% INPUT:
|
||||
% - M_ [structure] Matlab's structure describing the model (M_).
|
||||
% - dr [structure] decision rules for the model
|
||||
% - opts_simul [structure] Matlab's structure containing the Occbin options (opts_simul).
|
||||
% - solve_DM [double] indicator on whether to recompute decision rules
|
||||
%
|
||||
% OUTPUT:
|
||||
% - data [structure] simulation result containing fields:
|
||||
% - linear: paths for endogenous variables ignoring OBC (linear solution)
|
||||
% - piecewise: paths for endogenous variables satisfying the OBC (occbin/piecewise solution)
|
||||
% - ys: vector of steady state values
|
||||
% - regime_history: information on number and time of regime transitions
|
||||
% - SS_out [structure] State space solution
|
||||
% - T: [n_vars by n_vars by n_shock_period] array of transition matrices
|
||||
% - R: [n_vars by n_exo by n_shock_period] array of shock response matrices
|
||||
% - C: [n_vars by n_shock_period] array of constants
|
||||
% - error_flag [integer] 1 if a problem was encoutered, 0 otherwise
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
persistent DM
|
||||
|
||||
if isempty(DM)
|
||||
solve_DM=true;
|
||||
end
|
||||
|
||||
data.shocks_sequence= opts_simul_.SHOCKS; % sequence of unforeseen shocks under which one wants to solve the model
|
||||
n_periods = opts_simul_.periods; % simulation horizon (can be longer than the sequence of shocks defined in shockssequence; must be long enough to ensure convergence back to the reference model at the end of the simulation horizon and may need to be varied depending on the sequence of shocks).
|
||||
curb_retrench = opts_simul_.curb_retrench; % 0: updates guess based on previous iteration; 1: updates similar to Gauss-Jacobi scheme, slowing iterations down by updating guess only one period at a time
|
||||
max_iter = opts_simul_.maxit; % maximum number of iterations allowed for the solution algorithm
|
||||
endo_init = opts_simul_.endo_init; % initial condition for state variables, in deviation from steady state in declaration order
|
||||
binding_indicator = opts_simul_.init_binding_indicator; % initial guess for constraint violations
|
||||
regime_history_guess = opts_simul_.init_regime; % initial guess for constraint violations
|
||||
periodic_solution = opts_simul_.periodic_solution;
|
||||
data.exo_pos = opts_simul_.exo_pos;
|
||||
|
||||
n_shocks_periods = size(data.shocks_sequence,1);
|
||||
|
||||
if n_periods < n_shocks_periods
|
||||
n_periods = n_shocks_periods;
|
||||
end
|
||||
nperiods_0 = max(opts_simul_.check_ahead_periods,n_periods-n_shocks_periods);
|
||||
|
||||
error_flag=0;
|
||||
|
||||
M00_ = M_;
|
||||
|
||||
% ensure that all models have the same parameters
|
||||
% use the parameters for the base model.
|
||||
|
||||
%keep the correct auxiliary regime specific parameter values
|
||||
|
||||
data.ys = dr.ys;
|
||||
|
||||
if solve_DM %recompute solution matrices
|
||||
[DM.Cbarmat ,DM.Bbarmat, DM.Abarmat, DM.Jbarmat] = occbin.get_deriv(M00_,data.ys);
|
||||
|
||||
M10_ = M00_;
|
||||
M10_.params(strmatch(M_.occbin.constraint(1).pswitch,M00_.param_names,'exact'))= 1;
|
||||
[DM.Cbarmat10, DM.Bbarmat10, DM.Abarmat10, DM.Jbarmat10, DM.Dbarmat10] = occbin.get_deriv(M10_,data.ys);
|
||||
|
||||
M01_ = M00_;
|
||||
M01_.params(strmatch(M_.occbin.constraint(2).pswitch,M00_.param_names,'exact'))= 1;
|
||||
[DM.Cbarmat01, DM.Bbarmat01, DM.Abarmat01, DM.Jbarmat01, DM.Dbarmat01] = occbin.get_deriv(M01_,data.ys);
|
||||
|
||||
M11_ = M00_;
|
||||
M11_.params(M_.occbin.constraint(1).pswitch_index)= 1;
|
||||
M11_.params(M_.occbin.constraint(2).pswitch_index)= 1;
|
||||
[DM.Cbarmat11, DM.Bbarmat11, DM.Abarmat11, DM.Jbarmat11, DM.Dbarmat11] = occbin.get_deriv(M11_,data.ys);
|
||||
|
||||
[DM.decrulea,DM.decruleb]=occbin.get_pq(dr);
|
||||
update_flag=true;
|
||||
DM.n_vars = M00_.endo_nbr;
|
||||
DM.n_exo = M00_.exo_nbr;
|
||||
else
|
||||
update_flag=false;
|
||||
end
|
||||
|
||||
endo_names = M00_.endo_names;
|
||||
exo_names = M00_.exo_names;
|
||||
|
||||
init_orig_ = endo_init;
|
||||
|
||||
zdatapiecewise_ = zeros(n_periods,DM.n_vars);
|
||||
|
||||
if ~exist('binding_indicator','var')
|
||||
binding_indicator = false(nperiods_0+1,2); % This sets the first guess for when
|
||||
% the constraints are going to hold.
|
||||
% The variable is a boolean with two columns. The first column refers to
|
||||
% constrain1_; the second to constrain2_.
|
||||
% Each row is a period in time.
|
||||
% If the boolean is true it indicates the relevant constraint is expected
|
||||
% to evaluate to true.
|
||||
% The default initial guess is consistent with the base model always
|
||||
% holding -- equivalent to the linear solution.
|
||||
else
|
||||
if size(binding_indicator,1)<(nperiods_0+1)
|
||||
binding_indicator = [binding_indicator; false(nperiods_0+1-size(binding_indicator,1),2)];
|
||||
end
|
||||
end
|
||||
SS_out.T = NaN(DM.n_vars,DM.n_vars,n_shocks_periods);
|
||||
SS_out.R = NaN(DM.n_vars,DM.n_exo,n_shocks_periods);
|
||||
SS_out.C = NaN(DM.n_vars,n_shocks_periods);
|
||||
if ~exist('regime_history_','var') || isempty(regime_history_guess)
|
||||
regime_history = struct();
|
||||
guess_history = false;
|
||||
else
|
||||
guess_history = true; %previous information exists
|
||||
regime_history = regime_history_guess;
|
||||
end
|
||||
|
||||
if opts_simul_.waitbar
|
||||
hh = dyn_waitbar(0,'Occbin: Solving the model');
|
||||
set(hh,'Name','Occbin: Solving the model.');
|
||||
end
|
||||
|
||||
for shock_period = 1:n_shocks_periods
|
||||
if opts_simul_.waitbar
|
||||
dyn_waitbar(shock_period/n_shocks_periods, hh, sprintf('Period %u of %u', shock_period,n_shocks_periods));
|
||||
end
|
||||
regime_change_this_iteration=true;
|
||||
iter = 0;
|
||||
guess_history_it = false;
|
||||
if guess_history && (shock_period<=length(regime_history_guess)) %beyond guess regime history
|
||||
guess_history_it = true;
|
||||
end
|
||||
is_periodic=false;
|
||||
binding_indicator_history={};
|
||||
max_err = NaN(max_iter,1);
|
||||
|
||||
while (regime_change_this_iteration && iter<max_iter && ~is_periodic)
|
||||
iter = iter +1;
|
||||
if any(binding_indicator(end,:)) && nperiods_0<opts_simul_.max_periods
|
||||
binding_indicator = [binding_indicator; false(2,1)];
|
||||
nperiods_0 = nperiods_0 + 1;
|
||||
disp_verbose(['nperiods has been endogenously increased up to ' int2str(nperiods_0) '.'],opts_simul_.debug)
|
||||
end
|
||||
if size(binding_indicator,1)<(nperiods_0 + 1)
|
||||
binding_indicator=[binding_indicator; false(nperiods_0 + 1-size(binding_indicator,1),2)];
|
||||
end
|
||||
binding_indicator_history{iter}=binding_indicator;
|
||||
|
||||
if iter==1 && guess_history_it
|
||||
regime_1 = regime_history_guess(shock_period).regime1;
|
||||
regime_start_1 = regime_history_guess(shock_period).regimestart1;
|
||||
binding_indicator(:,1) = regime_1(end);
|
||||
for ir=1:length(regime_1)-1
|
||||
binding_indicator(regime_start_1(ir):regime_start_1(ir+1)-1,1) = regime_1(ir);
|
||||
end
|
||||
regime_2 = regime_history_guess(shock_period).regime2;
|
||||
regime_start_2 = regime_history_guess(shock_period).regimestart2;
|
||||
binding_indicator(:,2) = regime_2(end);
|
||||
for ir=1:length(regime_2)-1
|
||||
binding_indicator(regime_start_2(ir):regime_start_2(ir+1)-1,2) = regime_2(ir);
|
||||
end
|
||||
nperiods_0 = size(binding_indicator,1)-1; %if history is present, update may be required
|
||||
end
|
||||
% analyse violvec and isolate contiguous periods in the other regime.
|
||||
[regime_1, regime_start_1, error_code_period(1)]=occbin.map_regime(binding_indicator(:,1),opts_simul_.debug);
|
||||
regime_history(shock_period).regime1 = regime_1;
|
||||
regime_history(shock_period).regimestart1 = regime_start_1;
|
||||
[regime_2, regime_start_2, error_code_period(2)]=occbin.map_regime(binding_indicator(:,2),opts_simul_.debug);
|
||||
regime_history(shock_period).regime2 = regime_2;
|
||||
regime_history(shock_period).regimestart2 = regime_start_2;
|
||||
if shock_period==1 || shock_period>1 && any(data.shocks_sequence(shock_period,:)) % first period or shock happening
|
||||
Tmax=max([regime_start_1(end) regime_start_2(end)])-1;
|
||||
[zdatalinear_, SS_out.T(:,:,shock_period), SS_out.R(:,:,shock_period), SS_out.C(:,shock_period), SS, update_flag]=occbin.mkdatap_anticipated_2constraints_dyn(nperiods_0,...
|
||||
DM,Tmax,...
|
||||
binding_indicator,...
|
||||
data.exo_pos,data.shocks_sequence(shock_period,:),endo_init, update_flag);
|
||||
|
||||
[binding, relax, err]=feval([M_.fname,'.eval_difference'],zdatalinear_,M_,dr.ys);
|
||||
binding_constraint_new=[binding.constraint_1;binding.constraint_2];
|
||||
relaxed_constraint_new = [relax.constraint_1;relax.constraint_2];
|
||||
|
||||
err_binding_constraint_new = [err.binding_constraint_1; err.binding_constraint_2];
|
||||
err_relaxed_constraint_new = [err.relax_constraint_1; err.relax_constraint_2];
|
||||
|
||||
% check if changes_
|
||||
if any(binding_constraint_new & ~binding_indicator(:)) || any(relaxed_constraint_new & binding_indicator(:))
|
||||
err_violation = err_binding_constraint_new(binding_constraint_new & ~binding_indicator(:));
|
||||
err_relax = err_relaxed_constraint_new(relaxed_constraint_new & binding_indicator(:));
|
||||
max_err(iter) = max(abs([err_violation;err_relax]));
|
||||
regime_change_this_iteration = true;
|
||||
else
|
||||
regime_change_this_iteration = false;
|
||||
max_err(iter) = 0;
|
||||
end
|
||||
|
||||
if curb_retrench % apply Gauss-Seidel idea of slowing down the change in the guess
|
||||
% for the constraint -- only relax one
|
||||
% period at a time starting from the last
|
||||
% one when each of the constraints is true.
|
||||
retrench = false(numel(binding_indicator),1);
|
||||
max_relax_constraint_1=find(relax.constraint_1 & binding_indicator(:,1),1,'last');
|
||||
if ~isempty(max_relax_constraint_1) && find(relax.constraint_1,1,'last')>=find(binding_indicator(:,1),1,'last')
|
||||
retrench(max_relax_constraint_1) = true;
|
||||
end
|
||||
max_relax_constraint_2=find(relax.constraint_2 & binding_indicator(:,2),1,'last');
|
||||
if ~isempty(max_relax_constraint_2) && find(relax.constraint_2,1,'last')>=find(binding_indicator(:,2),1,'last')
|
||||
retrench(max_relax_constraint_2+nperiods_0+1) = true;
|
||||
end
|
||||
binding_indicator = (binding_indicator(:) | binding_constraint_new) & ~ retrench;
|
||||
else
|
||||
binding_indicator= (binding_indicator(:) | binding_constraint_new) & ~(binding_indicator(:) & relaxed_constraint_new);
|
||||
end
|
||||
binding_indicator = reshape(binding_indicator,nperiods_0+1,2);
|
||||
|
||||
if iter>1 && regime_change_this_iteration
|
||||
is_periodic=false(1,iter-1);
|
||||
for kiter=1:iter-1
|
||||
vvv = [binding_indicator_history{kiter}; false(size(binding_indicator,1)- size(binding_indicator_history{kiter},1), 2)];
|
||||
is_periodic(kiter) = isequal(vvv, binding_indicator);
|
||||
end
|
||||
is_periodic_all = is_periodic;
|
||||
is_periodic = any(is_periodic);
|
||||
if is_periodic && periodic_solution
|
||||
[min_err,index_min_err]=min(max_err(find(is_periodic_all,1):end));
|
||||
inx = find(is_periodic_all,1):iter;
|
||||
inx = inx(index_min_err);
|
||||
binding_indicator=binding_indicator_history{inx}; %select regime history with same result, but smallest error
|
||||
if inx<iter %update if needed
|
||||
[regime_1, regime_start_1, error_code_period(1)]=occbin.map_regime(binding_indicator(:,1),opts_simul_.debug);
|
||||
regime_history(shock_period).regime1 = regime_1;
|
||||
regime_history(shock_period).regimestart1 = regime_start_1;
|
||||
[regime_2, regime_start_2, error_code_period(2)]=occbin.map_regime(binding_indicator(:,2),opts_simul_.debug);
|
||||
regime_history(shock_period).regime2 = regime_2;
|
||||
regime_history(shock_period).regimestart2 = regime_start_2;
|
||||
Tmax=max([regime_start_1(end) regime_start_2(end)])-1;
|
||||
% get the hypothesized piece wise linear solution
|
||||
[zdatalinear_, SS_out.T(:,:,shock_period), SS_out.R(:,:,shock_period), SS_out.C(:,shock_period), SS, update_flag]=occbin.mkdatap_anticipated_2constraints_dyn(nperiods_0,DM,...
|
||||
Tmax,...
|
||||
binding_indicator,...
|
||||
data.exo_pos,data.shocks_sequence(shock_period,:),endo_init,update_flag);
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
regime_change_this_iteration= false;
|
||||
zdatalinear_(1:end-1,:)=zdatalinear_(2:end,:);
|
||||
zdatalinear_(end,:) = DM.decrulea*zdatalinear_(end-1,:)';
|
||||
if length(SS)>1
|
||||
SS=SS(2:end);
|
||||
else
|
||||
SS=[];
|
||||
end
|
||||
if isempty(SS)
|
||||
SS_out.T(:,:,shock_period)= DM.decrulea;
|
||||
SS_out.R(:,:,shock_period)= DM.decruleb;
|
||||
SS_out.C(:,shock_period)= 0;
|
||||
else
|
||||
SS_out.T(:,:,shock_period)= SS(1).T;
|
||||
SS_out.R(:,:,shock_period)= SS(1).R;
|
||||
SS_out.C(:,shock_period)= SS(1).C;
|
||||
end
|
||||
binding_indicator_history{iter}=binding_indicator;
|
||||
end
|
||||
end
|
||||
if regime_change_this_iteration && max_iter>1
|
||||
disp_verbose(['occbin solver: period ' int2str(shock_period) ':'],opts_simul_.debug)
|
||||
if is_periodic
|
||||
disp_verbose('Occbin solver loops between two regimes.',opts_simul_.debug)
|
||||
if periodic_solution
|
||||
disp_verbose(['Max error:' num2str(min_err) '.'],opts_simul_.debug)
|
||||
else
|
||||
error_flag = 310;
|
||||
if opts_simul_.waitbar; dyn_waitbar_close(hh); end
|
||||
return;
|
||||
end
|
||||
else
|
||||
disp_verbose('Did not converge -- increase maxit.',opts_simul_.debug)
|
||||
error_flag = 311;
|
||||
if opts_simul_.waitbar; dyn_waitbar_close(hh); end
|
||||
return;
|
||||
end
|
||||
end
|
||||
if any(error_code_period)
|
||||
disp_verbose('Increase nperiods.',opts_simul_.debug)
|
||||
error_flag = 312;
|
||||
if opts_simul_.waitbar; dyn_waitbar_close(hh); end
|
||||
return;
|
||||
end
|
||||
|
||||
endo_init = zdatalinear_(1,:);
|
||||
zdatapiecewise_(shock_period,:)=endo_init;
|
||||
endo_init= endo_init';
|
||||
|
||||
% update the guess for constraint violations for next period
|
||||
% update is consistent with expecting no additional shocks next period
|
||||
binding_indicator=[binding_indicator(2:end,:); false(1,2)];
|
||||
|
||||
end
|
||||
|
||||
zdatapiecewise_(shock_period+1:end,:)=zdatalinear_(2:n_periods-shock_period+1,:);
|
||||
|
||||
data.piecewise=zdatapiecewise_;
|
||||
data.regime_history=regime_history;
|
||||
|
||||
if ~opts_simul_.piecewise_only
|
||||
% get the linear responses
|
||||
data.linear = occbin.mkdata(n_periods,DM.decrulea,DM.decruleb,endo_names,exo_names,[],data.exo_pos,data.shocks_sequence,init_orig_);
|
||||
end
|
||||
|
||||
if opts_simul_.waitbar
|
||||
dyn_waitbar_close(hh);
|
||||
end
|
|
@ -0,0 +1,83 @@
|
|||
function [oo_, out, ss] = solver(M_,oo_,options_)
|
||||
% function [oo_, out, ss] = solver(M_,oo_,options_,opts_simul)
|
||||
% Solves the model with an OBC and produces simulations/IRFs
|
||||
%
|
||||
% INPUT:
|
||||
% - opts_simul [structure] Occbin simulation options
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
%
|
||||
% OUTPUT:
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - out [structure] simulation result containing fields:
|
||||
% - linear: paths for endogenous variables ignoring OBC (linear solution)
|
||||
% - piecewise: paths for endogenous variables satisfying the OBC (occbin/piecewise solution)
|
||||
% - ys: vector of steady state values
|
||||
% - regime_history: information on number and time of regime transitions
|
||||
% - ss [structure] State space solution
|
||||
% - T: [n_vars by n_vars by n_shock_period] array of transition matrices
|
||||
% - R: [n_vars by n_exo by n_shock_period] array of shock response matrices
|
||||
% - C: [n_vars by n_shock_period] array of constants
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
persistent sto_M sto_dr
|
||||
|
||||
% check dr
|
||||
solve_dr=0;
|
||||
if isempty(sto_M) || isempty(sto_dr)
|
||||
solve_dr=1;
|
||||
else
|
||||
inan = find(~isnan(M_.params));
|
||||
inan0 = find(~isnan(sto_M.params));
|
||||
if ~isequal(inan,inan0) || ~isequal(sto_M.params(inan),M_.params(inan))
|
||||
solve_dr=1;
|
||||
end
|
||||
end
|
||||
|
||||
if solve_dr
|
||||
[dr,error_flag,M_,oo_] = resol(0,M_,options_,oo_);
|
||||
oo_.dr = dr;
|
||||
sto_dr=dr;
|
||||
sto_M=M_;
|
||||
else
|
||||
oo_.dr=sto_dr;
|
||||
end
|
||||
|
||||
if M_.occbin.constraint_nbr==1
|
||||
[out, ss, error_flag ] = occbin.solve_one_constraint(M_,oo_.dr,options_.occbin.simul,solve_dr);
|
||||
elseif M_.occbin.constraint_nbr==2
|
||||
[out, ss, error_flag ] = occbin.solve_two_constraints(M_,oo_.dr,options_.occbin.simul,solve_dr);
|
||||
end
|
||||
|
||||
out.error_flag=error_flag;
|
||||
if error_flag
|
||||
print_info(error_flag, options_.noprint, options_)
|
||||
out=[];
|
||||
return;
|
||||
end
|
||||
|
||||
% add back steady state
|
||||
if ~options_.occbin.simul.piecewise_only
|
||||
out.linear = out.linear + out.ys';
|
||||
end
|
||||
out.piecewise = out.piecewise+ out.ys';
|
||||
out.exo_simul = options_.occbin.simul.SHOCKS;
|
||||
out.exo_pos = options_.occbin.simul.exo_pos;
|
||||
|
||||
oo_.occbin=out;
|
|
@ -0,0 +1,66 @@
|
|||
function tokens = tokenize(source,delimiter)
|
||||
%function tokens = tokenize(source,delimiter)
|
||||
% Breaks down strings into its components (tokens)
|
||||
% INPUTS
|
||||
% - source [string] string to be broken into tokens
|
||||
% - delimiter [char array] single character delimiters
|
||||
%
|
||||
% OUTPUTS:
|
||||
% -tokens [cell] array containing the tokens
|
||||
|
||||
% Original authors: Luca Guerrieri and Matteo Iacoviello
|
||||
% Original file downloaded from:
|
||||
% https://www.matteoiacoviello.com/research_files/occbin_20140630.zip
|
||||
% Adapted for Dynare by Dynare Team.
|
||||
%
|
||||
% This code is in the public domain and may be used freely.
|
||||
% However the authors would appreciate acknowledgement of the source by
|
||||
% citation of any of the following papers:
|
||||
%
|
||||
% Luca Guerrieri and Matteo Iacoviello (2015): "OccBin: A toolkit for solving
|
||||
% dynamic models with occasionally binding constraints easily"
|
||||
% Journal of Monetary Economics 70, 22-38
|
||||
|
||||
posdelims = [];
|
||||
|
||||
% assumes that delimiter cannot be in the first position or the last position
|
||||
ndelimiters = size(delimiter,1);
|
||||
for i=1:ndelimiters
|
||||
newpositions = strfind(source,delimiter(i,:));
|
||||
if ~isempty(newpositions)
|
||||
posdelims =[posdelims, newpositions];
|
||||
end
|
||||
end
|
||||
|
||||
% reorder posdelims in ascending order
|
||||
posdelims = sort(posdelims);
|
||||
|
||||
if isempty(posdelims)
|
||||
tokens = cellstr(source);
|
||||
else
|
||||
ndelims = length(posdelims);
|
||||
% build positions for substrings
|
||||
delims = zeros(ndelims+1,2);
|
||||
for i=1:ndelims+1
|
||||
if i==1
|
||||
if posdelims(1) == 1
|
||||
tokens = cellstr(source(1));
|
||||
else
|
||||
delims(i,:) = [1,posdelims(i)-1];
|
||||
tokens = cellstr(source([delims(i,1):delims(i,2)]));
|
||||
tokens = [tokens, source(posdelims(i))];
|
||||
end
|
||||
elseif i==ndelims+1
|
||||
if (posdelims(i-1) < length(source))
|
||||
delims(i,:) = [posdelims(i-1)+1,length(source)];
|
||||
tokens = [tokens, cellstr(source([delims(i,1):delims(i,2)]))];
|
||||
end
|
||||
else
|
||||
if posdelims(i)>posdelims(i-1)+1
|
||||
delims(i,:) = [posdelims(i-1)+1,posdelims(i)-1];
|
||||
tokens = [tokens, cellstr(source([delims(i,1):delims(i,2)]))];
|
||||
end
|
||||
tokens = [tokens, source(posdelims(i))];
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
function oo_=unpack_simulations(M_,oo_,options_)
|
||||
% function oo_=unpack_simulations(M_,oo_,options_)
|
||||
% Writes Occbin simulations from matrix to structure
|
||||
%
|
||||
% Inputs
|
||||
% - M_ [structure] Matlab's structure describing the model
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
% - options_ [structure] Matlab's structure containing the options
|
||||
%
|
||||
% Outputs
|
||||
% - oo_ [structure] Matlab's structure containing the results
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
for i=1:M_.endo_nbr
|
||||
% unpack the IRFs
|
||||
oo_.occbin.endo_linear.(M_.endo_names{i})= oo_.occbin.linear(:,i);
|
||||
oo_.occbin.endo_piecewise.(M_.endo_names{i})=oo_.occbin.piecewise(:,i);
|
||||
oo_.occbin.endo_ss.(M_.endo_names{i})=oo_.occbin.ys(i);
|
||||
end
|
||||
for i=1:length(oo_.occbin.exo_pos)
|
||||
oo_.occbin.exo.(M_.exo_names{i})=options_.occbin.simul.SHOCKS(:,i);
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
function write_regimes_to_xls(regime_history,M_,options_)
|
||||
% function write_regimes_to_xls(regime_history,M_,options_)
|
||||
% writes regime results to Excel-file
|
||||
%
|
||||
% INPUTS
|
||||
% - regime_history [struct] information on the regimes
|
||||
% - M_ [struct] Matlab's structure describing the model
|
||||
% - options_ [struct] Matlab's structure describing the current options
|
||||
|
||||
% Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
OutputDirectoryName = CheckPath('Output',M_.dname);
|
||||
|
||||
if isempty(options_.occbin.write_regimes.periods)
|
||||
T=1:length(regime_history);
|
||||
else
|
||||
T=options_.occbin.write_regimes.periods;
|
||||
end
|
||||
|
||||
xls_filename = options_.occbin.write_regimes.filename;
|
||||
|
||||
if isfield(regime_history,'regime')
|
||||
Header = {'time', 'regime sequence', 'starting period of regime'};
|
||||
for tp=1:length(T)
|
||||
xlsmat{tp,1}=T(tp);
|
||||
xlsmat{tp,2}=int2str(regime_history(tp).regime);
|
||||
xlsmat{tp,3}=int2str(regime_history(tp).regimestart);
|
||||
end
|
||||
else
|
||||
Header = {'time', 'regime sequence 1', 'starting period of regime 1', 'regime sequence 2', 'starting period of regime 2'};
|
||||
for tp=1:length(T)
|
||||
xlsmat{tp,1}=T(tp);
|
||||
xlsmat{tp,2}=int2str(regime_history(tp).regime1);
|
||||
xlsmat{tp,3}=int2str(regime_history(tp).regimestart1);
|
||||
xlsmat{tp,4}=int2str(regime_history(tp).regime2);
|
||||
xlsmat{tp,5}=int2str(regime_history(tp).regimestart2);
|
||||
end
|
||||
end
|
||||
filename=[OutputDirectoryName filesep xls_filename '.xls'];
|
||||
if matlab_ver_less_than('9.3')
|
||||
if exist(filename,'file')
|
||||
delete(filename)
|
||||
end
|
||||
else
|
||||
if isfile(filename)
|
||||
delete(filename)
|
||||
end
|
||||
end
|
||||
writetable(array2table(xlsmat,'VariableNames',Header), filename, 'Sheet', 'Regimes');
|
|
@ -1,4 +1,4 @@
|
|||
function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,decomp,trend_addition,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_)
|
||||
function [alphahat,etahat,epsilonhat,ahat,SteadyState,trend_coeff,aK,T,R,P,PK,decomp,trend_addition,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,Y,data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,varargin)
|
||||
% Estimation of the smoothed variables and innovations.
|
||||
%
|
||||
% INPUTS
|
||||
|
@ -96,6 +96,7 @@ end
|
|||
%------------------------------------------------------------------------------
|
||||
% 2. call model setup & reduction program
|
||||
%------------------------------------------------------------------------------
|
||||
length_varargin=length(varargin);
|
||||
if ~options_.smoother_redux
|
||||
|
||||
%store old setting of restricted var_list
|
||||
|
@ -111,9 +112,22 @@ if ~options_.smoother_redux
|
|||
bayestopt_.mf = bayestopt_.smoother_var_list(bayestopt_.smoother_mf);
|
||||
|
||||
else
|
||||
[T,R,SteadyState,info,M_,oo_] = dynare_resolve(M_,options_,oo_,'restrict');
|
||||
if ~options_.occbin.smoother.status
|
||||
[T,R,SteadyState,info,M_,oo_] = dynare_resolve(M_,options_,oo_,'restrict');
|
||||
else
|
||||
[T,R,SteadyState,info,M_,oo_,~,~,~, T0, R0] = ...
|
||||
occbin.dynare_resolve(M_,options_,oo_,[],'restrict');
|
||||
varargin{length_varargin+1}=T0;
|
||||
varargin{length_varargin+2}=R0;
|
||||
end
|
||||
bayestopt_.mf = bayestopt_.mf1;
|
||||
end
|
||||
if options_.occbin.smoother.status
|
||||
occbin_info.status = true;
|
||||
occbin_info.info= [{options_,oo_,M_} varargin];
|
||||
else
|
||||
occbin_info.status = false;
|
||||
end
|
||||
|
||||
if info~=0
|
||||
print_info(info,options_.noprint, options_);
|
||||
|
@ -179,7 +193,7 @@ elseif options_.lik_init == 3 % Diffuse Kalman filter
|
|||
kalman_algo = 3;
|
||||
else
|
||||
if ~all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is not diagonal...
|
||||
%Augment state vector (follows Section 6.4.3 of DK (2012))
|
||||
%Augment state vector (follows Section 6.4.3 of DK (2012))
|
||||
expanded_state_vector_for_univariate_filter=1;
|
||||
T = blkdiag(T,zeros(vobs));
|
||||
np = size(T,1);
|
||||
|
@ -236,14 +250,23 @@ if options_.heteroskedastic_filter
|
|||
Q=get_Qvec_heteroskedastic_filter(Q,smpl,M_);
|
||||
end
|
||||
|
||||
if options_.occbin.smoother.status
|
||||
if kalman_algo == 1
|
||||
kalman_algo = 2;
|
||||
end
|
||||
if kalman_algo == 3
|
||||
kalman_algo = 4;
|
||||
end
|
||||
end
|
||||
|
||||
if kalman_algo == 1 || kalman_algo == 3
|
||||
a_initial = zeros(np,1);
|
||||
a_initial=set_Kalman_smoother_starting_values(a_initial,M_,oo_,options_);
|
||||
a_initial=T*a_initial; %set state prediction for first Kalman step;
|
||||
a_initial=T*a_initial; %set state prediction for first Kalman step;
|
||||
[alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty, aahat, eehat, d] = missing_DiffuseKalmanSmootherH1_Z(a_initial,ST, ...
|
||||
Z,R1,Q,H,Pinf,Pstar, ...
|
||||
data1,vobs,np,smpl,data_index, ...
|
||||
options_.nk,kalman_tol,diffuse_kalman_tol,options_.filter_decomposition,options_.smoothed_state_uncertainty,options_.filter_covariance,options_.smoother_redux);
|
||||
Z,R1,Q,H,Pinf,Pstar, ...
|
||||
data1,vobs,np,smpl,data_index, ...
|
||||
options_.nk,kalman_tol,diffuse_kalman_tol,options_.filter_decomposition,options_.smoothed_state_uncertainty,options_.filter_covariance,options_.smoother_redux);
|
||||
if isinf(alphahat)
|
||||
if kalman_algo == 1
|
||||
fprintf('\nDsgeSmoother: Switching to univariate filter. This may be a sign of stochastic singularity.\n')
|
||||
|
@ -292,16 +315,18 @@ if kalman_algo == 2 || kalman_algo == 4
|
|||
%do nothing, state vector was already expanded
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
a_initial = zeros(np,1);
|
||||
a_initial=set_Kalman_smoother_starting_values(a_initial,M_,oo_,options_);
|
||||
a_initial=ST*a_initial; %set state prediction for first Kalman step;
|
||||
[alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty, aahat, eehat, d] = missing_DiffuseKalmanSmootherH3_Z(a_initial,ST, ...
|
||||
Z,R1,Q,diag(H), ...
|
||||
Pinf,Pstar,data1,vobs,np,smpl,data_index, ...
|
||||
options_.nk,kalman_tol,diffuse_kalman_tol, ...
|
||||
options_.filter_decomposition,options_.smoothed_state_uncertainty,options_.filter_covariance,options_.smoother_redux);
|
||||
|
||||
[alphahat,epsilonhat,etahat,ahat,P,aK,PK,decomp,state_uncertainty, aahat, eehat, d, regimes_,TT,RR,CC] = missing_DiffuseKalmanSmootherH3_Z(a_initial,ST, ...
|
||||
Z,R1,Q,diag(H), ...
|
||||
Pinf,Pstar,data1,vobs,np,smpl,data_index, ...
|
||||
options_.nk,kalman_tol,diffuse_kalman_tol, ...
|
||||
options_.filter_decomposition,options_.smoothed_state_uncertainty,options_.filter_covariance,options_.smoother_redux,occbin_info);
|
||||
if options_.occbin.smoother.status
|
||||
oo_.occbin.smoother.regime_history = regimes_;
|
||||
end
|
||||
end
|
||||
|
||||
if expanded_state_vector_for_univariate_filter && (kalman_algo == 2 || kalman_algo == 4)
|
||||
|
@ -327,7 +352,7 @@ if expanded_state_vector_for_univariate_filter && (kalman_algo == 2 || kalman_al
|
|||
end
|
||||
end
|
||||
|
||||
if ~options_.smoother_redux
|
||||
if ~options_.smoother_redux
|
||||
%reset old setting of restricted var_list
|
||||
oo_.dr.restrict_var_list = oldoo.restrict_var_list;
|
||||
oo_.dr.restrict_columns = oldoo.restrict_columns;
|
||||
|
@ -338,107 +363,238 @@ else
|
|||
ic = oo_.dr.restrict_columns;
|
||||
end
|
||||
|
||||
[A,B] = kalman_transition_matrix(oo_.dr,(1:M_.endo_nbr)',ic,M_.exo_nbr);
|
||||
iT = pinv(T);
|
||||
Tstar = A(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),oo_.dr.restrict_var_list);
|
||||
Rstar = B(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),:);
|
||||
C = Tstar*iT;
|
||||
D = Rstar-C*R;
|
||||
static_var_list = ~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list);
|
||||
ilagged = any(abs(C*T-Tstar)'>1.e-12);
|
||||
static_var_list0 = static_var_list;
|
||||
static_var_list0(static_var_list) = ilagged;
|
||||
static_var_list(static_var_list) = ~ilagged;
|
||||
% reconstruct smoothed variables
|
||||
aaa=zeros(M_.endo_nbr,gend);
|
||||
aaa(oo_.dr.restrict_var_list,:)=alphahat;
|
||||
for k=1:gend
|
||||
aaa(static_var_list,k) = C(~ilagged,:)*alphahat(:,k)+D(~ilagged,:)*etahat(:,k);
|
||||
end
|
||||
if any(ilagged)
|
||||
if options_.occbin.smoother.status
|
||||
% reconstruct occbin smoother
|
||||
if length_varargin>0
|
||||
isoccbin=1;
|
||||
else
|
||||
isoccbin=0;
|
||||
end
|
||||
if length_varargin>1
|
||||
TT=varargin{2};
|
||||
RR=varargin{3};
|
||||
CC=varargin{4};
|
||||
if size(TT,3)<(smpl+1)
|
||||
TT=repmat(T,1,1,smpl+1);
|
||||
RR=repmat(R,1,1,smpl+1);
|
||||
CC=repmat(zeros(mm,1),1,smpl+1);
|
||||
end
|
||||
end
|
||||
if isoccbin==0
|
||||
[A,B] = kalman_transition_matrix(oo_.dr,(1:M_.endo_nbr)',ic,M_.exo_nbr);
|
||||
else
|
||||
opts_simul = options_.occbin.simul;
|
||||
end
|
||||
aaa=zeros(M_.endo_nbr,gend);
|
||||
aaa(oo_.dr.restrict_var_list,:)=alphahat;
|
||||
for k=2:gend
|
||||
aaa(static_var_list0,k) = Tstar(ilagged,:)*alphahat(:,k-1)+Rstar(ilagged,:)*etahat(:,k);
|
||||
if isoccbin
|
||||
A = TT(:,:,k);
|
||||
B = RR(:,:,k);
|
||||
C = CC(:,k);
|
||||
else
|
||||
C=0;
|
||||
end
|
||||
aaa(:,k) = C+A*aaa(:,k-1)+B*etahat(:,k);
|
||||
end
|
||||
end
|
||||
alphahat=aaa;
|
||||
|
||||
% reconstruct updated variables
|
||||
aaa=zeros(M_.endo_nbr,gend);
|
||||
aaa(oo_.dr.restrict_var_list,:)=ahat;
|
||||
for k=1:gend
|
||||
aaa(static_var_list,k) = C(~ilagged,:)*ahat(:,k)+D(~ilagged,:)*eehat(:,k);
|
||||
end
|
||||
if any(ilagged)
|
||||
alphahat=aaa;
|
||||
aaa=zeros(M_.endo_nbr,gend);
|
||||
bbb=zeros(M_.endo_nbr,gend);
|
||||
bbb(oo_.dr.restrict_var_list,:)=ahat;
|
||||
aaa(oo_.dr.restrict_var_list,:)=aahat;
|
||||
for k=d+2:gend
|
||||
aaa(static_var_list0,k) = Tstar(ilagged,:)*aahat(:,k-1)+Rstar(ilagged,:)*eehat(:,k);
|
||||
end
|
||||
end
|
||||
ahat1=aaa;
|
||||
% reconstruct aK
|
||||
aaa = zeros(options_.nk,M_.endo_nbr,gend+options_.nk);
|
||||
aaa(:,oo_.dr.restrict_var_list,:)=aK;
|
||||
for k=1:gend
|
||||
for jnk=1:options_.nk
|
||||
aaa(jnk,static_var_list,k+jnk) = C(~ilagged,:)*dynare_squeeze(aK(jnk,:,k+jnk));
|
||||
end
|
||||
end
|
||||
if any(ilagged)
|
||||
for k=1:gend
|
||||
aaa(1,static_var_list0,k+1) = Tstar(ilagged,:)*ahat(:,k);
|
||||
for jnk=2:options_.nk
|
||||
aaa(jnk,static_var_list0,k+jnk) = Tstar(ilagged,:)*dynare_squeeze(aK(jnk-1,:,k+jnk-1));
|
||||
if isoccbin
|
||||
A = TT(:,:,k);
|
||||
B = RR(:,:,k);
|
||||
C = CC(:,k);
|
||||
bbb(:,k) = C+A*aaa(:,k-1)+B*eehat(:,k);
|
||||
else
|
||||
opts_simul.curb_retrench = options_.occbin.smoother.curb_retrench;
|
||||
opts_simul.waitbar = options_.occbin.smoother.waitbar;
|
||||
opts_simul.maxit = options_.occbin.smoother.maxit;
|
||||
opts_simul.periods = options_.occbin.smoother.periods;
|
||||
opts_simul.check_ahead_periods = options_.occbin.smoother.check_ahead_periods;
|
||||
opts_simul.full_output = options_.occbin.smoother.full_output;
|
||||
opts_simul.piecewise_only = options_.occbin.smoother.piecewise_only;
|
||||
opts_simul.SHOCKS = zeros(options_.nk,M_.exo_nbr);
|
||||
opts_simul.SHOCKS(1,:) = eehat(:,k);
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=aahat(:,k-1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
opts_simul.init_regime = []; %regimes_(k);
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out] = occbin.solver(M_,oo_,options_);
|
||||
% regime in out should be identical to regimes_(k-2) moved one
|
||||
% period ahead (so if regimestart was [1 5] it should be [1 4]
|
||||
% in out
|
||||
% end
|
||||
bbb(oo_.dr.inv_order_var,k) = out.zpiece(1,:);
|
||||
end
|
||||
end
|
||||
end
|
||||
aK=aaa;
|
||||
ahat=ahat1;
|
||||
|
||||
% reconstruct P
|
||||
if ~isempty(P)
|
||||
PP=zeros(M_.endo_nbr,M_.endo_nbr,gend+1);
|
||||
PP(oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:)=P;
|
||||
DQD=D(~ilagged,:)*Q*transpose(D(~ilagged,:))+C(~ilagged,:)*R*Q*transpose(D(~ilagged,:))+D(~ilagged,:)*Q*transpose(C(~ilagged,:)*R);
|
||||
DQR=D(~ilagged,:)*Q*transpose(R);
|
||||
for k=1:gend+1
|
||||
PP(static_var_list,static_var_list,k)=C(~ilagged,:)*P(:,:,k)*C(~ilagged,:)'+DQD;
|
||||
PP(static_var_list,oo_.dr.restrict_var_list,k)=C(~ilagged,:)*P(:,:,k)+DQR;
|
||||
PP(oo_.dr.restrict_var_list,static_var_list,k)=transpose(PP(static_var_list,oo_.dr.restrict_var_list,k));
|
||||
ahat0=ahat;
|
||||
ahat=bbb;
|
||||
if ~isempty(P)
|
||||
PP=zeros(M_.endo_nbr,M_.endo_nbr,gend+1);
|
||||
PP(oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:)=P;
|
||||
P=PP;
|
||||
clear PP
|
||||
end
|
||||
P=PP;
|
||||
clear('PP');
|
||||
end
|
||||
|
||||
% reconstruct state_uncertainty
|
||||
if ~isempty(state_uncertainty)
|
||||
mm=size(T,1);
|
||||
ss=length(find(static_var_list));
|
||||
sstate_uncertainty=zeros(M_.endo_nbr,M_.endo_nbr,gend);
|
||||
sstate_uncertainty(oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:)=state_uncertainty(1:mm,1:mm,:);
|
||||
for k=1:gend
|
||||
sstate_uncertainty(static_var_list,static_var_list,k)=[C(~ilagged,:) D(~ilagged,:)]*state_uncertainty(:,:,k)*[C(~ilagged,:) D(~ilagged,:)]';
|
||||
tmp = [C(~ilagged,:) D(~ilagged,:)]*state_uncertainty(:,:,k);
|
||||
sstate_uncertainty(static_var_list,oo_.dr.restrict_var_list,k)=tmp(1:ss,1:mm);
|
||||
sstate_uncertainty(oo_.dr.restrict_var_list,static_var_list,k)=transpose(sstate_uncertainty(static_var_list,oo_.dr.restrict_var_list,k));
|
||||
end
|
||||
state_uncertainty=sstate_uncertainty;
|
||||
clear('sstate_uncertainty');
|
||||
end
|
||||
|
||||
% reconstruct PK TO DO!!
|
||||
if ~isempty(PK)
|
||||
PP = zeros(options_.nk,M_.endo_nbr,M_.endo_nbr,gend+options_.nk);
|
||||
PP(:,oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:) = PK;
|
||||
DQD=D(~ilagged,:)*Q*transpose(D(~ilagged,:))+C(~ilagged,:)*R*Q*transpose(D(~ilagged,:))+D(~ilagged,:)*Q*transpose(C(~ilagged,:)*R);
|
||||
DQR=D(~ilagged,:)*Q*transpose(R);
|
||||
for f=1:options_.nk
|
||||
for k=1:gend
|
||||
PP(f,static_var_list,static_var_list,k+f)=C(~ilagged,:)*squeeze(PK(f,:,:,k+f))*C(~ilagged,:)'+DQD;
|
||||
PP(f,static_var_list,oo_.dr.restrict_var_list,k+f)=C(~ilagged,:)*squeeze(PK(f,:,:,k+f))+DQR;
|
||||
PP(f,oo_.dr.restrict_var_list,static_var_list,k+f)=transpose(squeeze(PP(f,static_var_list,oo_.dr.restrict_var_list,k+f)));
|
||||
if ~isempty(state_uncertainty)
|
||||
sstate_uncertainty=zeros(M_.endo_nbr,M_.endo_nbr,gend);
|
||||
sstate_uncertainty(oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:)=state_uncertainty;
|
||||
state_uncertainty=sstate_uncertainty;
|
||||
clear sstate_uncertainty
|
||||
end
|
||||
|
||||
aaa = zeros(options_.nk,M_.endo_nbr,gend+options_.nk);
|
||||
aaa(:,oo_.dr.restrict_var_list,:)=aK;
|
||||
|
||||
for k=2:gend+1
|
||||
opts_simul.curb_retrench = options_.occbin.smoother.curb_retrench;
|
||||
opts_simul.waitbar = options_.occbin.smoother.waitbar;
|
||||
opts_simul.maxit = options_.occbin.smoother.maxit;
|
||||
opts_simul.periods = options_.occbin.smoother.periods;
|
||||
opts_simul.check_ahead_periods = options_.occbin.smoother.check_ahead_periods;
|
||||
opts_simul.full_output = options_.occbin.smoother.full_output;
|
||||
opts_simul.piecewise_only = options_.occbin.smoother.piecewise_only;
|
||||
opts_simul.SHOCKS = zeros(options_.nk,M_.exo_nbr);
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list,1)=ahat0(:,k-1);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var,1);
|
||||
opts_simul.init_regime = []; %regimes_(k);
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out] = occbin.solver(M_,oo_,options_);
|
||||
% regime in out should be identical to regimes_(k-2) moved one
|
||||
% period ahead (so if regimestart was [1 5] it should be [1 4]
|
||||
% in out
|
||||
% end
|
||||
for jnk=1:options_.nk
|
||||
aaa(jnk,oo_.dr.inv_order_var,k+jnk-1) = out.zpiece(jnk,:);
|
||||
end
|
||||
end
|
||||
PK=PP;
|
||||
clear('PP');
|
||||
aK=aaa;
|
||||
|
||||
if ~isempty(PK)
|
||||
PP = zeros(options_.nk,M_.endo_nbr,M_.endo_nbr,gend+options_.nk);
|
||||
PP(:,oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:) = PK;
|
||||
PK=PP;
|
||||
clear PP
|
||||
end
|
||||
else
|
||||
% reconstruct smoother
|
||||
[A,B] = kalman_transition_matrix(oo_.dr,(1:M_.endo_nbr)',ic,M_.exo_nbr);
|
||||
iT = pinv(T);
|
||||
Tstar = A(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),oo_.dr.restrict_var_list);
|
||||
Rstar = B(~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list),:);
|
||||
C = Tstar*iT;
|
||||
D = Rstar-C*R;
|
||||
static_var_list = ~ismember(1:M_.endo_nbr,oo_.dr.restrict_var_list);
|
||||
ilagged = any(abs(C*T-Tstar)'>1.e-12);
|
||||
static_var_list0 = static_var_list;
|
||||
static_var_list0(static_var_list) = ilagged;
|
||||
static_var_list(static_var_list) = ~ilagged;
|
||||
% reconstruct smoothed variables
|
||||
aaa=zeros(M_.endo_nbr,gend);
|
||||
aaa(oo_.dr.restrict_var_list,:)=alphahat;
|
||||
for k=1:gend
|
||||
aaa(static_var_list,k) = C(~ilagged,:)*alphahat(:,k)+D(~ilagged,:)*etahat(:,k);
|
||||
end
|
||||
if any(ilagged)
|
||||
for k=2:gend
|
||||
aaa(static_var_list0,k) = Tstar(ilagged,:)*alphahat(:,k-1)+Rstar(ilagged,:)*etahat(:,k);
|
||||
end
|
||||
end
|
||||
alphahat=aaa;
|
||||
|
||||
% reconstruct updated variables
|
||||
aaa=zeros(M_.endo_nbr,gend);
|
||||
aaa(oo_.dr.restrict_var_list,:)=ahat;
|
||||
for k=1:gend
|
||||
aaa(static_var_list,k) = C(~ilagged,:)*ahat(:,k)+D(~ilagged,:)*eehat(:,k);
|
||||
end
|
||||
if any(ilagged)
|
||||
% bbb=zeros(M_.endo_nbr,gend);
|
||||
% bbb(oo_.dr.restrict_var_list,:)=aahat;
|
||||
for k=d+2:gend
|
||||
aaa(static_var_list0,k) = Tstar(ilagged,:)*aahat(:,k-1)+Rstar(ilagged,:)*eehat(:,k);
|
||||
end
|
||||
end
|
||||
ahat1=aaa;
|
||||
% reconstruct aK
|
||||
aaa = zeros(options_.nk,M_.endo_nbr,gend+options_.nk);
|
||||
aaa(:,oo_.dr.restrict_var_list,:)=aK;
|
||||
for k=1:gend
|
||||
for jnk=1:options_.nk
|
||||
aaa(jnk,static_var_list,k+jnk) = C(~ilagged,:)*dynare_squeeze(aK(jnk,:,k+jnk));
|
||||
end
|
||||
end
|
||||
if any(ilagged)
|
||||
for k=1:gend
|
||||
aaa(1,static_var_list0,k+1) = Tstar(ilagged,:)*ahat(:,k);
|
||||
for jnk=2:options_.nk
|
||||
aaa(jnk,static_var_list0,k+jnk) = Tstar(ilagged,:)*dynare_squeeze(aK(jnk-1,:,k+jnk-1));
|
||||
end
|
||||
end
|
||||
end
|
||||
aK=aaa;
|
||||
ahat=ahat1;
|
||||
|
||||
% reconstruct P
|
||||
if ~isempty(P)
|
||||
PP=zeros(M_.endo_nbr,M_.endo_nbr,gend+1);
|
||||
PP(oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:)=P;
|
||||
if ~options_.heteroskedastic_filter
|
||||
DQD=D(~ilagged,:)*Q*transpose(D(~ilagged,:))+C(~ilagged,:)*R*Q*transpose(D(~ilagged,:))+D(~ilagged,:)*Q*transpose(C(~ilagged,:)*R);
|
||||
DQR=D(~ilagged,:)*Q*transpose(R);
|
||||
end
|
||||
for k=1:gend+1
|
||||
if options_.heteroskedastic_filter
|
||||
DQD=D(~ilagged,:)*Q(:,:,k)*transpose(D(~ilagged,:))+C(~ilagged,:)*R*Q(:,:,k)*transpose(D(~ilagged,:))+D(~ilagged,:)*Q(:,:,k)*transpose(C(~ilagged,:)*R);
|
||||
DQR=D(~ilagged,:)*Q(:,:,k)*transpose(R);
|
||||
end
|
||||
PP(static_var_list,static_var_list,k)=C(~ilagged,:)*P(:,:,k)*C(~ilagged,:)'+DQD;
|
||||
PP(static_var_list,oo_.dr.restrict_var_list,k)=C(~ilagged,:)*P(:,:,k)+DQR;
|
||||
PP(oo_.dr.restrict_var_list,static_var_list,k)=transpose(PP(static_var_list,oo_.dr.restrict_var_list,k));
|
||||
end
|
||||
P=PP;
|
||||
clear PP
|
||||
end
|
||||
|
||||
% reconstruct state_uncertainty
|
||||
if ~isempty(state_uncertainty)
|
||||
mm=size(T,1);
|
||||
ss=length(find(static_var_list));
|
||||
sstate_uncertainty=zeros(M_.endo_nbr,M_.endo_nbr,gend);
|
||||
sstate_uncertainty(oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:)=state_uncertainty(1:mm,1:mm,:);
|
||||
for k=1:gend
|
||||
sstate_uncertainty(static_var_list,static_var_list,k)=[C(~ilagged,:) D(~ilagged,:)]*state_uncertainty(:,:,k)*[C(~ilagged,:) D(~ilagged,:)]';
|
||||
tmp = [C(~ilagged,:) D(~ilagged,:)]*state_uncertainty(:,:,k);
|
||||
sstate_uncertainty(static_var_list,oo_.dr.restrict_var_list,k)=tmp(1:ss,1:mm);
|
||||
sstate_uncertainty(oo_.dr.restrict_var_list,static_var_list,k)=transpose(sstate_uncertainty(static_var_list,oo_.dr.restrict_var_list,k));
|
||||
end
|
||||
state_uncertainty=sstate_uncertainty;
|
||||
clear sstate_uncertainty
|
||||
end
|
||||
|
||||
% reconstruct PK
|
||||
if ~isempty(PK)
|
||||
PP = zeros(options_.nk,M_.endo_nbr,M_.endo_nbr,gend+options_.nk);
|
||||
PP(:,oo_.dr.restrict_var_list,oo_.dr.restrict_var_list,:) = PK;
|
||||
if ~options_.heteroskedastic_filter
|
||||
DQD=D(~ilagged,:)*Q*transpose(D(~ilagged,:))+C(~ilagged,:)*R*Q*transpose(D(~ilagged,:))+D(~ilagged,:)*Q*transpose(C(~ilagged,:)*R);
|
||||
DQR=D(~ilagged,:)*Q*transpose(R);
|
||||
for f=1:options_.nk
|
||||
for k=1:gend
|
||||
PP(f,static_var_list,static_var_list,k+f)=C(~ilagged,:)*squeeze(PK(f,:,:,k+f))*C(~ilagged,:)'+DQD;
|
||||
PP(f,static_var_list,oo_.dr.restrict_var_list,k+f)=C(~ilagged,:)*squeeze(PK(f,:,:,k+f))+DQR;
|
||||
PP(f,oo_.dr.restrict_var_list,static_var_list,k+f)=transpose(squeeze(PP(f,static_var_list,oo_.dr.restrict_var_list,k+f)));
|
||||
end
|
||||
end
|
||||
end
|
||||
PK=PP;
|
||||
clear PP
|
||||
end
|
||||
end
|
||||
|
||||
bayestopt_.mf = bayestopt_.smoother_var_list(bayestopt_.smoother_mf);
|
||||
|
@ -446,14 +602,14 @@ end
|
|||
|
||||
function a=set_Kalman_smoother_starting_values(a,M_,oo_,options_)
|
||||
% function a=set_Kalman_smoother_starting_values(a,M_,oo_,options_)
|
||||
% Sets initial states guess for Kalman filter/smoother based on M_.filter_initial_state
|
||||
%
|
||||
% INPUTS
|
||||
% Sets initial states guess for Kalman filter/smoother based on M_.filter_initial_state
|
||||
%
|
||||
% INPUTS
|
||||
% o a [double] (p*1) vector of states
|
||||
% o M_ [structure] decribing the model
|
||||
% o oo_ [structure] storing the results
|
||||
% o options_ [structure] describing the options
|
||||
%
|
||||
%
|
||||
% OUTPUTS
|
||||
% o a [double] (p*1) vector of set initial states
|
||||
|
||||
|
|
|
@ -412,6 +412,9 @@ options_.recursive_estimation_restart = 0;
|
|||
options_.MCMC_jumping_covariance='hessian';
|
||||
options_.use_calibration_initialization = 0;
|
||||
options_.endo_vars_for_moment_computations_in_estimation=[];
|
||||
% occbin options
|
||||
options_.occbin.likelihood.status=false;
|
||||
options_.occbin.smoother.status=false;
|
||||
|
||||
% Run optimizer silently
|
||||
options_.silent_optimizer = false;
|
||||
|
|
|
@ -183,9 +183,34 @@ end
|
|||
%------------------------------------------------------------------------------
|
||||
% 2. call model setup & reduction program
|
||||
%------------------------------------------------------------------------------
|
||||
is_restrict_state_space = true;
|
||||
if DynareOptions.occbin.likelihood.status
|
||||
occbin_options = set_occbin_options(DynareOptions, Model);
|
||||
if occbin_options.opts_simul.restrict_state_space
|
||||
[T,R,SteadyState,info,Model,DynareResults,TTx,RRx,CCx, T0, R0] = ...
|
||||
occbin.dynare_resolve(Model,DynareOptions,DynareResults,[],'restrict');
|
||||
else
|
||||
is_restrict_state_space = false;
|
||||
oldoo.restrict_var_list = DynareResults.dr.restrict_var_list;
|
||||
oldoo.restrict_columns = DynareResults.dr.restrict_columns;
|
||||
DynareResults.dr.restrict_var_list = BayesInfo.smoother_var_list;
|
||||
DynareResults.dr.restrict_columns = BayesInfo.smoother_restrict_columns;
|
||||
|
||||
% Linearize the model around the deterministic steady state and extract the matrices of the state equation (T and R).
|
||||
[T,R,SteadyState,info,Model,DynareOptions,DynareResults,TTx,RRx,CCx, T0, R0] = ...
|
||||
occbin.dynare_resolve(Model,DynareOptions,DynareResults);
|
||||
|
||||
% Linearize the model around the deterministic steady state and extract the matrices of the state equation (T and R).
|
||||
[T,R,SteadyState,info,Model,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict');
|
||||
DynareResults.dr.restrict_var_list = oldoo.restrict_var_list;
|
||||
DynareResults.dr.restrict_columns = oldoo.restrict_columns;
|
||||
|
||||
end
|
||||
occbin_.status = true;
|
||||
occbin_.info= {DynareOptions, DynareResults, Model, occbin_options, TTx, RRx, CCx,T0,R0};
|
||||
else
|
||||
% Linearize the model around the deterministic steady state and extract the matrices of the state equation (T and R).
|
||||
[T,R,SteadyState,info,Model,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict');
|
||||
occbin_.status = false;
|
||||
end
|
||||
|
||||
% Return, with endogenous penalty when possible, if dynare_resolve issues an error code (defined in resol).
|
||||
if info(1)
|
||||
|
@ -223,8 +248,14 @@ if info(1)
|
|||
return
|
||||
end
|
||||
|
||||
% Define a vector of indices for the observed variables. Is this really usefull?...
|
||||
BayesInfo.mf = BayesInfo.mf1;
|
||||
if is_restrict_state_space
|
||||
%% Define a vector of indices for the observed variables. Is this really usefull?...
|
||||
BayesInfo.mf = BayesInfo.mf1;
|
||||
else
|
||||
%get location of observed variables and requested smoothed variables in
|
||||
%decision rules
|
||||
BayesInfo.mf = BayesInfo.smoother_var_list(BayesInfo.smoother_mf);
|
||||
end
|
||||
|
||||
% Define the constant vector of the measurement equation.
|
||||
if DynareOptions.noconstant
|
||||
|
@ -283,7 +314,16 @@ switch DynareOptions.lik_init
|
|||
a = zeros(mm,1);
|
||||
a=set_Kalman_starting_values(a,Model,DynareResults,DynareOptions,BayesInfo);
|
||||
a_0_given_tm1=T*a; %set state prediction for first Kalman step;
|
||||
Zflag = 0;
|
||||
|
||||
if DynareOptions.occbin.likelihood.status
|
||||
Z =zeros(length(BayesInfo.mf),size(T,1));
|
||||
for i = 1:length(BayesInfo.mf)
|
||||
Z(i,BayesInfo.mf(i))=1;
|
||||
end
|
||||
Zflag = 1;
|
||||
else
|
||||
Zflag = 0;
|
||||
end
|
||||
case 2% Initialization with large numbers on the diagonal of the covariance matrix if the states (for non stationary models).
|
||||
if kalman_algo ~= 2
|
||||
% Use standard kalman filter except if the univariate filter is explicitely choosen.
|
||||
|
@ -294,7 +334,15 @@ switch DynareOptions.lik_init
|
|||
a = zeros(mm,1);
|
||||
a = set_Kalman_starting_values(a,Model,DynareResults,DynareOptions,BayesInfo);
|
||||
a_0_given_tm1 = T*a; %set state prediction for first Kalman step;
|
||||
Zflag = 0;
|
||||
if DynareOptions.occbin.likelihood.status
|
||||
Z =zeros(length(BayesInfo.mf),size(T,1));
|
||||
for i = 1:length(BayesInfo.mf)
|
||||
Z(i,BayesInfo.mf(i))=1;
|
||||
end
|
||||
Zflag = 1;
|
||||
else
|
||||
Zflag = 0;
|
||||
end
|
||||
case 3% Diffuse Kalman filter (Durbin and Koopman)
|
||||
% Use standard kalman filter except if the univariate filter is explicitely choosen.
|
||||
if kalman_algo == 0
|
||||
|
@ -421,7 +469,15 @@ switch DynareOptions.lik_init
|
|||
a = zeros(mm,1);
|
||||
a = set_Kalman_starting_values(a,Model,DynareResults,DynareOptions,BayesInfo);
|
||||
a_0_given_tm1 = T*a;
|
||||
Zflag = 0;
|
||||
if DynareOptions.occbin.likelihood.status
|
||||
Z =zeros(length(BayesInfo.mf),size(T,1));
|
||||
for i = 1:length(BayesInfo.mf)
|
||||
Z(i,BayesInfo.mf(i))=1;
|
||||
end
|
||||
Zflag = 1;
|
||||
else
|
||||
Zflag = 0;
|
||||
end
|
||||
case 5 % Old diffuse Kalman filter only for the non stationary variables
|
||||
[eigenvect, eigenv] = eig(T);
|
||||
eigenv = diag(eigenv);
|
||||
|
@ -443,7 +499,15 @@ switch DynareOptions.lik_init
|
|||
a = zeros(mm,1);
|
||||
a = set_Kalman_starting_values(a,Model,DynareResults,DynareOptions,BayesInfo);
|
||||
a_0_given_tm1 = T*a;
|
||||
Zflag = 0;
|
||||
if DynareOptions.occbin.likelihood.status
|
||||
Z =zeros(length(BayesInfo.mf),size(T,1));
|
||||
for i = 1:length(BayesInfo.mf)
|
||||
Z(i,BayesInfo.mf(i))=1;
|
||||
end
|
||||
Zflag = 1;
|
||||
else
|
||||
Zflag = 0;
|
||||
end
|
||||
otherwise
|
||||
error('dsge_likelihood:: Unknown initialization approach for the Kalman filter!')
|
||||
end
|
||||
|
@ -604,7 +668,7 @@ end
|
|||
singularity_has_been_detected = false;
|
||||
% First test multivariate filter if specified; potentially abort and use univariate filter instead
|
||||
if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter
|
||||
if no_missing_data_flag
|
||||
if no_missing_data_flag && ~DynareOptions.occbin.likelihood.status
|
||||
if DynareOptions.block
|
||||
LIK = block_kalman_filter(T,R,Q,H,Pstar,Y,start,Z,kalman_tol,riccati_tol, Model.nz_state_var, Model.n_diag, Model.nobs_non_statevar);
|
||||
elseif DynareOptions.fast_kalman_filter
|
||||
|
@ -643,7 +707,7 @@ if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter
|
|||
kalman_tol, DynareOptions.riccati_tol, ...
|
||||
DynareOptions.rescale_prediction_error_covariance, ...
|
||||
DynareOptions.presample, ...
|
||||
T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods);
|
||||
T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods, occbin_);
|
||||
end
|
||||
end
|
||||
if analytic_derivation
|
||||
|
@ -895,3 +959,21 @@ if isfield(M_,'filter_initial_state') && ~isempty(M_.filter_initial_state)
|
|||
end
|
||||
end
|
||||
|
||||
function occbin_options = set_occbin_options(DynareOptions, Model)
|
||||
|
||||
% this builds the opts_simul options field needed by occbin.solver
|
||||
occbin_options.opts_simul = DynareOptions.occbin.simul;
|
||||
occbin_options.opts_simul.curb_retrench = DynareOptions.occbin.likelihood.curb_retrench;
|
||||
occbin_options.opts_simul.maxit = DynareOptions.occbin.likelihood.maxit;
|
||||
occbin_options.opts_simul.periods = DynareOptions.occbin.likelihood.periods;
|
||||
occbin_options.opts_simul.check_ahead_periods = DynareOptions.occbin.likelihood.check_ahead_periods;
|
||||
occbin_options.opts_simul.periodic_solution = DynareOptions.occbin.likelihood.periodic_solution;
|
||||
occbin_options.opts_simul.restrict_state_space = DynareOptions.occbin.likelihood.restrict_state_space;
|
||||
occbin_options.constraints = Model.occbin.constraint;
|
||||
|
||||
occbin_options.opts_simul.full_output = DynareOptions.occbin.likelihood.full_output;
|
||||
occbin_options.opts_simul.piecewise_only = DynareOptions.occbin.likelihood.piecewise_only;
|
||||
if ~isempty(DynareOptions.occbin.smoother.init_binding_indicator)
|
||||
occbin_options.opts_simul.init_binding_indicator = DynareOptions.occbin.likelihood.init_binding_indicator;
|
||||
occbin_options.opts_simul.init_regime_history=DynareOptions.occbin.likelihood.init_regime_history;
|
||||
end
|
||||
|
|
|
@ -41,7 +41,6 @@ else
|
|||
reset_options_related_to_estimation = false;
|
||||
end
|
||||
|
||||
|
||||
%store qz_criterium
|
||||
qz_criterium_old=options_.qz_criterium;
|
||||
if isnan(options_.first_obs)
|
||||
|
@ -102,7 +101,11 @@ if ~options_.dsge_var
|
|||
error(['Estimation: Unknown filter ' options_.particle.filter_algorithm])
|
||||
end
|
||||
else
|
||||
objective_function = str2func('dsge_likelihood');
|
||||
if options_.occbin.likelihood.status && options_.occbin.likelihood.inversion_filter
|
||||
objective_function = str2func('occbin.IVF_posterior');
|
||||
else
|
||||
objective_function = str2func('dsge_likelihood');
|
||||
end
|
||||
end
|
||||
else
|
||||
objective_function = str2func('dsge_var_likelihood');
|
||||
|
@ -176,8 +179,22 @@ end
|
|||
if isequal(options_.mode_compute,0) && isempty(options_.mode_file) && options_.mh_posterior_mode_estimation==0
|
||||
if options_.order==1 && ~options_.particle.status
|
||||
if options_.smoother
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,transpose(data),data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
[oo_]=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);
|
||||
if options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter
|
||||
[~, ~, ~, ~, ~, ~, ~, ~, ~, ~, oo_, atT, innov] = occbin.IVF_posterior(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,prior_bounds(bayestopt_,options_.prior_trunc),oo_);
|
||||
updated_variables = atT*nan;
|
||||
measurement_error=[];
|
||||
ys = oo_.dr.ys;
|
||||
trend_coeff = zeros(length(options_.varobs_id),1);
|
||||
bayestopt_.mf = bayestopt_.smoother_var_list(bayestopt_.smoother_mf);
|
||||
[oo_]=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,atT,innov,measurement_error,updated_variables,ys,trend_coeff);
|
||||
else
|
||||
if options_.occbin.smoother.status
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = occbin.DSGE_smoother(xparam1,gend,transpose(data),data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_,dataset_,dataset_info);
|
||||
else
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,gend,transpose(data),data_index,missing_value,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
end
|
||||
[oo_]=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);
|
||||
end
|
||||
if options_.forecast > 0
|
||||
oo_.forecast = dyn_forecast(var_list_,M_,options_,oo_,'smoother',dataset_info);
|
||||
end
|
||||
|
@ -554,9 +571,22 @@ end
|
|||
if (~((any(bayestopt_.pshape > 0) && options_.mh_replic) || (any(bayestopt_.pshape> 0) && options_.load_mh_file)) ...
|
||||
|| ~options_.smoother ) && ~options_.partial_information % to be fixed
|
||||
%% ML estimation, or posterior mode without Metropolis-Hastings or Metropolis without Bayesian smoothes variables
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
[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);
|
||||
|
||||
if options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter
|
||||
[~, ~, ~, ~, ~, ~, ~, ~, ~, ~, oo_, atT, innov] = occbin.IVF_posterior(xparam1,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,prior_bounds(bayestopt_,options_.prior_trunc),oo_);
|
||||
updated_variables = atT*nan;
|
||||
measurement_error=[];
|
||||
ys = oo_.dr.ys;
|
||||
trend_coeff = zeros(length(options_.varobs_id),1);
|
||||
bayestopt_.mf = bayestopt_.smoother_var_list(bayestopt_.smoother_mf);
|
||||
[oo_, yf]=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,atT,innov,measurement_error,updated_variables,ys,trend_coeff);
|
||||
else
|
||||
if options_.occbin.smoother.status
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = occbin.DSGE_smoother(xparam1,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state,M_,oo_,options_,bayestopt_,estim_params_,dataset_,dataset_info);
|
||||
else
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = DsgeSmoother(xparam1,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
end
|
||||
[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);
|
||||
end
|
||||
if ~options_.nograph
|
||||
[nbplt,nr,nc,lr,lc,nstar] = pltorg(M_.exo_nbr);
|
||||
if ~exist([M_.dname '/graphs'],'dir')
|
||||
|
|
|
@ -685,3 +685,14 @@ if options_.heteroskedastic_filter
|
|||
error('Scale and value defined for the same shock in the same period with "heteroskedastic_shocks".')
|
||||
end
|
||||
end
|
||||
|
||||
if options_.occbin.likelihood.status && options_.occbin.likelihood.inversion_filter
|
||||
if isempty(options_.occbin.likelihood.IVF_shock_observable_mapping)
|
||||
options_.occbin.likelihood.IVF_shock_observable_mapping=find(diag(M.Sigma_e)~=0);
|
||||
else
|
||||
zero_var_shocks=find(diag(M.Sigma_e)==0);
|
||||
if any(ismember(options_.occbin.likelihood.IVF_shock_observable_mapping,zero_var_shocks))
|
||||
error('IVF-filter: an observable is mapped to a zero variance shock.')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -73,6 +73,10 @@ if isempty(dataset)
|
|||
end
|
||||
options_=select_qz_criterium_value(options_);
|
||||
|
||||
llik = -dsge_likelihood(parameters,dataset,dataset_info,options_,M_,estim_params_,bayestopt_,prior_bounds(bayestopt_,options_.prior_trunc),oo_);
|
||||
if options_.occbin.likelihood.status && options_.occbin.likelihood.inversion_filter
|
||||
llik = -occbin.IVF_posterior(parameters,dataset,dataset_info,options_,M_,estim_params_,bayestopt_,prior_bounds(bayestopt_,options_.prior_trunc),oo_);
|
||||
else
|
||||
llik = -dsge_likelihood(parameters,dataset,dataset_info,options_,M_,estim_params_,bayestopt_,prior_bounds(bayestopt_,options_.prior_trunc),oo_);
|
||||
end
|
||||
ldens = evaluate_prior(parameters,M_,estim_params_,oo_,options_,bayestopt_);
|
||||
llik = llik - ldens;
|
|
@ -101,10 +101,27 @@ if ischar(parameters)
|
|||
end
|
||||
end
|
||||
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = ...
|
||||
DsgeSmoother(parameters,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
[oo_]=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);
|
||||
|
||||
if options_.occbin.smoother.status
|
||||
if options_.occbin.smoother.inversion_filter
|
||||
[~, ~, ~, ~, ~, ~, ~, ~, ~, ~, oo_, atT, innov] = occbin.IVF_posterior(parameters,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,prior_bounds(bayestopt_,options_.prior_trunc),oo_);
|
||||
updated_variables = atT*nan;
|
||||
measurement_error=[];
|
||||
ys = oo_.dr.ys;
|
||||
trend_coeff = zeros(length(options_.varobs_id),1);
|
||||
bayestopt_.mf = bayestopt_.smoother_var_list(bayestopt_.smoother_mf);
|
||||
else
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = ...
|
||||
occbin.DSGE_smoother(parameters,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state,M_,oo_,options_,bayestopt_,estim_params_,dataset_,dataset_info);
|
||||
end
|
||||
else
|
||||
[atT,innov,measurement_error,updated_variables,ys,trend_coeff,aK,T,R,P,PK,decomp,Trend,state_uncertainty,M_,oo_,bayestopt_] = ...
|
||||
DsgeSmoother(parameters,dataset_.nobs,transpose(dataset_.data),dataset_info.missing.aindex,dataset_info.missing.state,M_,oo_,options_,bayestopt_,estim_params_);
|
||||
end
|
||||
if ~(options_.occbin.smoother.status && options_.occbin.smoother.inversion_filter)
|
||||
[oo_]=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);
|
||||
else
|
||||
[oo_]=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,dataset_info,atT,innov,measurement_error,updated_variables,ys,trend_coeff);
|
||||
end
|
||||
if nargout>4
|
||||
Smoothed_variables_declaration_order_deviation_form=atT(oo_.dr.inv_order_var(bayestopt_.smoother_var_list),:);
|
||||
end
|
||||
|
|
|
@ -170,6 +170,22 @@ switch info(1)
|
|||
message = 'Particle Filter: Initial covariance of the states is not positive definite. Try a different nonlinear_filter_initialization';
|
||||
case 202
|
||||
message = 'Particle Filter: Initial covariance of the states based on simulation resulted in NaN/Inf. Use pruning or try a different nonlinear_filter_initialization';
|
||||
case 301
|
||||
message = 'IVF: The likelihood is Inf.';
|
||||
case 302
|
||||
message = 'IVF: The likelihood is NaN.';
|
||||
case 303
|
||||
message = 'IVF: The residuals are not 0.';
|
||||
case 304
|
||||
message = 'IVF: The solver returned with an error code.';
|
||||
case 305
|
||||
message = 'IVF: The returned shocks are bigger than 1e8.';
|
||||
case 310
|
||||
message = 'Occbin: Simulation terminated with periodic solution (no convergence).';
|
||||
case 311
|
||||
message = 'Occbin: Simulation did not converge, increase maxit or check_ahead_periods.';
|
||||
case 312
|
||||
message = 'Occbin: Constraint(s) are binding at the end of the sample.';
|
||||
otherwise
|
||||
message = 'This case shouldn''t happen. Contact the authors of Dynare';
|
||||
end
|
|
@ -76,6 +76,18 @@ if DynareOptions.order>1
|
|||
end
|
||||
end
|
||||
|
||||
if (DynareOptions.occbin.likelihood.status && DynareOptions.occbin.likelihood.inversion_filter) || (DynareOptions.occbin.smoother.status && DynareOptions.occbin.smoother.inversion_filter)
|
||||
err_index= find(diag(Model.Sigma_e)~=0);
|
||||
if length(err_index)~=length(DynareOptions.varobs)
|
||||
fprintf('initial_estimation_checks:: The IVF requires exactly as many shocks as observables.')
|
||||
end
|
||||
var_index=find(any(isnan(DynareDataset.data)));
|
||||
if ~isempty(var_index)
|
||||
fprintf('initial_estimation_checks:: The IVF requires exactly as many shocks as observables.\n')
|
||||
fprintf('initial_estimation_checks:: The data series %s contains NaN, I am therefore dropping shock %s for these time points.\n',...
|
||||
DynareOptions.varobs{var_index},Model.exo_names{DynareOptions.occbin.likelihood.IVF_shock_observable_mapping(var_index)})
|
||||
end
|
||||
end
|
||||
|
||||
if DynareOptions.order>1 || (DynareOptions.order==1 && ~ischar(DynareOptions.mode_compute) && DynareOptions.mode_compute==11)
|
||||
if DynareOptions.order==1 && DynareOptions.mode_compute==11
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function [LIK, lik, a, P] = missing_observations_kalman_filter(data_index,number_of_observations,no_more_missing_observations,Y,start,last,a,P,kalman_tol,riccati_tol,rescale_prediction_error_covariance,presample,T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods)
|
||||
function [LIK, lik, a, P] = missing_observations_kalman_filter(data_index,number_of_observations,no_more_missing_observations,Y,start,last,a,P,kalman_tol,riccati_tol,rescale_prediction_error_covariance,presample,T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods,occbin_)
|
||||
% Computes the likelihood of a state space model in the case with missing observations.
|
||||
%
|
||||
% INPUTS
|
||||
|
@ -91,8 +91,57 @@ notsteady = 1;
|
|||
F_singular = true;
|
||||
s = 0;
|
||||
rescale_prediction_error_covariance0=rescale_prediction_error_covariance;
|
||||
if occbin_.status
|
||||
Qt = repmat(Q,[1 1 3]);
|
||||
a0 = zeros(mm,last);
|
||||
a1 = zeros(mm,last);
|
||||
P0 = zeros(mm,mm,last);
|
||||
P1 = zeros(mm,mm,last);
|
||||
vv = zeros(pp,last);
|
||||
|
||||
options_=occbin_.info{1};
|
||||
oo_=occbin_.info{2};
|
||||
M_=occbin_.info{3};
|
||||
occbin_options=occbin_.info{4};
|
||||
opts_regime.regime_history = occbin_options.opts_simul.init_regime;
|
||||
opts_regime.binding_indicator = occbin_options.opts_simul.init_binding_indicator;
|
||||
first_period_occbin_update = max(t+1,options_.occbin.likelihood.first_period_occbin_update);
|
||||
if isempty(opts_regime.binding_indicator) && isempty(opts_regime.regime_history)
|
||||
opts_regime.binding_indicator=zeros(last+2,length(M_.occbin.constraint));
|
||||
end
|
||||
[~, ~, ~, regimes_] = occbin.check_regimes([], [], [], opts_regime, M_, oo_, options_);
|
||||
if length(occbin_.info)>4
|
||||
TT=occbin_.info{5};
|
||||
RR=occbin_.info{6};
|
||||
CC=occbin_.info{7};
|
||||
T0=occbin_.info{8};
|
||||
R0=occbin_.info{9};
|
||||
TT = cat(3,TT,T);
|
||||
RR = cat(3,RR,R);
|
||||
CC = cat(2,CC,zeros(mm,1));
|
||||
if size(TT,3)<(last+1)
|
||||
TT=repmat(T,1,1,last+1);
|
||||
RR=repmat(R,1,1,last+1);
|
||||
CC=repmat(zeros(mm,1),1,last+1);
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
first_period_occbin_update = inf;
|
||||
C=0;
|
||||
end
|
||||
|
||||
while notsteady && t<=last
|
||||
if occbin_.status
|
||||
a1(:,t) = a;
|
||||
P1(:,:,t) = P;
|
||||
C = CC(:,t+1);
|
||||
R = RR(:,:,t+1);
|
||||
T = TT(:,:,t+1);
|
||||
if ~(isqvec)
|
||||
QQ = R*Q*transpose(R); % Variance of R times the vector of structural innovations.
|
||||
end
|
||||
end
|
||||
s = t-start+1;
|
||||
d_index = data_index{t};
|
||||
if isqvec
|
||||
|
@ -129,39 +178,79 @@ while notsteady && t<=last
|
|||
% badly_conditioned_F = true;
|
||||
end
|
||||
end
|
||||
if badly_conditioned_F
|
||||
if ~all(abs(F(:))<kalman_tol)
|
||||
% Use univariate filter.
|
||||
return
|
||||
if ~occbin_.status || (occbin_.status && (options_.occbin.likelihood.use_updated_regime==0 || t<first_period_occbin_update))
|
||||
if badly_conditioned_F && (~occbin_.status || (occbin_.status && t<first_period_occbin_update))
|
||||
if ~all(abs(F(:))<kalman_tol)
|
||||
% Use univariate filter.
|
||||
return
|
||||
else
|
||||
% Pathological case, discard draw
|
||||
return
|
||||
end
|
||||
else
|
||||
% Pathological case, discard draw
|
||||
return
|
||||
end
|
||||
else
|
||||
F_singular = false;
|
||||
if rescale_prediction_error_covariance
|
||||
log_dF = log(det(F./(sig*sig')))+2*sum(log(sig));
|
||||
iF = inv(F./(sig*sig'))./(sig*sig');
|
||||
rescale_prediction_error_covariance=rescale_prediction_error_covariance0;
|
||||
else
|
||||
log_dF = log(det(F));
|
||||
iF = inv(F);
|
||||
end
|
||||
lik(s) = log_dF + transpose(v)*iF*v + length(d_index)*log(2*pi);
|
||||
if Zflag
|
||||
K = P*z'*iF;
|
||||
P = T*(P-K*z*P)*transpose(T)+QQ;
|
||||
else
|
||||
K = P(:,z)*iF;
|
||||
P = T*(P-K*P(z,:))*transpose(T)+QQ;
|
||||
end
|
||||
a = T*(a+K*v);
|
||||
if t>=no_more_missing_observations && ~isqvec
|
||||
notsteady = max(abs(K(:)-oldK))>riccati_tol;
|
||||
oldK = K(:);
|
||||
F_singular = false;
|
||||
if rescale_prediction_error_covariance
|
||||
log_dF = log(det(F./(sig*sig')))+2*sum(log(sig));
|
||||
iF = inv(F./(sig*sig'))./(sig*sig');
|
||||
rescale_prediction_error_covariance=rescale_prediction_error_covariance0;
|
||||
else
|
||||
log_dF = log(det(F));
|
||||
iF = inv(F);
|
||||
end
|
||||
lik(s) = log_dF + transpose(v)*iF*v + length(d_index)*log(2*pi);
|
||||
if t<first_period_occbin_update
|
||||
if Zflag
|
||||
K = P*z'*iF;
|
||||
if occbin_.status
|
||||
P0(:,:,t) = (P-K*z*P);
|
||||
end
|
||||
|
||||
P = T*(P-K*z*P)*transpose(T)+QQ;
|
||||
else
|
||||
K = P(:,z)*iF;
|
||||
if occbin_.status
|
||||
P0(:,:,t) = (P-K*P(z,:));
|
||||
end
|
||||
P = T*(P-K*P(z,:))*transpose(T)+QQ;
|
||||
end
|
||||
if occbin_.status
|
||||
a0(:,t) = (a+K*v);
|
||||
vv(d_index,t) = v;
|
||||
end
|
||||
a = T*(a+K*v)+C;
|
||||
if t>=no_more_missing_observations && ~isqvec && ~occbin_.status
|
||||
notsteady = max(abs(K(:)-oldK))>riccati_tol;
|
||||
oldK = K(:);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if occbin_.status && t>=first_period_occbin_update
|
||||
|
||||
if isqvec
|
||||
Qt = Qvec(:,:,t-1:t+1);
|
||||
end
|
||||
occbin_options.opts_simul.waitbar=0;
|
||||
[ax, a1x, Px, P1x, vx, Tx, Rx, Cx, regimes_(t:t+2), info, M_, likx, etax(t,:)] = occbin.kalman_update_algo_1(a0(:,t-1),a1(:,t-1:t),P0(:,:,t-1),P1(:,:,t-1:t),data_index(t-1:t),Z,vv(:,t-1:t),Y(:,t-1:t),H,Qt,T0,R0,TT(:,:,t-1:t),RR(:,:,t-1:t),CC(:,t-1:t),regimes_(t:t+1),M_,oo_,options_,occbin_options);
|
||||
if info
|
||||
return
|
||||
end
|
||||
if options_.occbin.likelihood.use_updated_regime
|
||||
lik(s) = likx;
|
||||
end
|
||||
a0(:,t) = ax(:,1);
|
||||
a1(:,t) = a1x(:,2);
|
||||
a = ax(:,2);
|
||||
vv(d_index,t) = vx(d_index,2);
|
||||
TT(:,:,t:t+1) = Tx;
|
||||
RR(:,:,t:t+1) = Rx;
|
||||
CC(:,t:t+1) = Cx;
|
||||
P0(:,:,t) = Px(:,:,1);
|
||||
P1(:,:,t) = P1x(:,:,2);
|
||||
P = Px(:,:,2);
|
||||
|
||||
end
|
||||
t = t+1;
|
||||
end
|
||||
|
||||
|
@ -182,4 +271,4 @@ if presample>=diffuse_periods
|
|||
LIK = sum(lik(1+presample-diffuse_periods:end));
|
||||
else
|
||||
LIK = sum(lik);
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
list_of_functions = {'discretionary_policy_1', 'dsge_var_likelihood', 'dyn_first_order_solver', 'dyn_waitbar', 'ep_residuals', 'evaluate_likelihood', 'prior_draw_gsa', 'identification_analysis', 'computeDLIK', 'univariate_computeDLIK', 'metropolis_draw', 'flag_implicit_skip_nan', 'moment_function', 'mr_hessian', 'masterParallel', 'auxiliary_initialization', 'auxiliary_particle_filter', 'conditional_filter_proposal', 'conditional_particle_filter', 'gaussian_filter', 'gaussian_filter_bank', 'gaussian_mixture_filter', 'gaussian_mixture_filter_bank', 'Kalman_filter', 'online_auxiliary_filter', 'pruned_state_space_system', 'sequential_importance_particle_filter', 'solve_model_for_online_filter', 'perfect_foresight_simulation', 'prior_draw', 'priordens'};
|
||||
list_of_functions = {'discretionary_policy_1', 'dsge_var_likelihood', 'dyn_first_order_solver', 'dyn_waitbar', 'ep_residuals', 'evaluate_likelihood', 'prior_draw_gsa', 'identification_analysis', 'computeDLIK', 'univariate_computeDLIK', 'metropolis_draw', 'flag_implicit_skip_nan', 'moment_function', 'mr_hessian', 'masterParallel', 'auxiliary_initialization', 'auxiliary_particle_filter', 'conditional_filter_proposal', 'conditional_particle_filter', 'gaussian_filter', 'gaussian_filter_bank', 'gaussian_mixture_filter', 'gaussian_mixture_filter_bank', 'Kalman_filter', 'online_auxiliary_filter', 'pruned_state_space_system', 'sequential_importance_particle_filter', 'solve_model_for_online_filter', 'perfect_foresight_simulation', 'prior_draw', 'priordens',...
|
||||
'+occbin/solver.m','+occbin/mkdatap_anticipated_dyn.m','+occbin/mkdatap_anticipated_2constraints_dyn.m','+occbin/match_function.m','+occbin/solve_one_constraint.m','+occbin/solve_two_constraint.m','+occbin/plot/shock_decomposition.m'};
|
|
@ -1,5 +1,5 @@
|
|||
function [alphahat,epsilonhat,etahat,a,P1,aK,PK,decomp,V, aalphahat,eetahat,d] = missing_DiffuseKalmanSmootherH3_Z(a_initial,T,Z,R,Q,H,Pinf1,Pstar1,Y,pp,mm,smpl,data_index,nk,kalman_tol,diffuse_kalman_tol,decomp_flag,state_uncertainty_flag, filter_covariance_flag, smoother_redux)
|
||||
% function [alphahat,epsilonhat,etahat,a,P1,aK,PK,decomp,V, aalphahat,eetahat,d] = missing_DiffuseKalmanSmootherH3_Z(a_initial,T,Z,R,Q,H,Pinf1,Pstar1,Y,pp,mm,smpl,data_index,nk,kalman_tol,diffuse_kalman_tol,decomp_flag,state_uncertainty_flag, filter_covariance_flag, smoother_redux)
|
||||
function [alphahat,epsilonhat,etahat,a,P1,aK,PK,decomp,V, aalphahat,eetahat,d,varargout] = missing_DiffuseKalmanSmootherH3_Z(a_initial,T,Z,R,Q,H,Pinf1,Pstar1,Y,pp,mm,smpl,data_index,nk,kalman_tol,diffuse_kalman_tol,decomp_flag,state_uncertainty_flag, filter_covariance_flag, smoother_redux, occbin_)
|
||||
% function [alphahat,epsilonhat,etahat,a,P1,aK,PK,decomp,V, aalphahat,eetahat,d] = missing_DiffuseKalmanSmootherH3_Z(a_initial,T,Z,R,Q,H,Pinf1,Pstar1,Y,pp,mm,smpl,data_index,nk,kalman_tol,diffuse_kalman_tol,decomp_flag,state_uncertainty_flag, filter_covariance_flag, smoother_redux, occbin_)
|
||||
% Computes the diffuse kalman smoother in the case of a singular var-cov matrix.
|
||||
% Univariate treatment of multivariate time series.
|
||||
%
|
||||
|
@ -150,6 +150,71 @@ else
|
|||
V=[];
|
||||
end
|
||||
|
||||
if ~occbin_.status
|
||||
isoccbin = 0;
|
||||
C=0;
|
||||
TT=[];
|
||||
RR=[];
|
||||
CC=[];
|
||||
else
|
||||
isoccbin = 1;
|
||||
Qt = repmat(Q,[1 1 3]);
|
||||
options_=occbin_.info{1};
|
||||
oo_=occbin_.info{2};
|
||||
M_=occbin_.info{3};
|
||||
occbin_options=occbin_.info{4};
|
||||
opts_regime = occbin_options.opts_regime;
|
||||
% first_period_occbin_update = inf;
|
||||
if isfield(opts_regime,'regime_history') && ~isempty(opts_regime.regime_history)
|
||||
opts_regime.regime_history=[opts_regime.regime_history(1) opts_regime.regime_history];
|
||||
else
|
||||
opts_regime.binding_indicator=zeros(smpl+2,length(M_.occbin.constraint));
|
||||
end
|
||||
occbin_options.opts_regime = opts_regime;
|
||||
[~, ~, ~, regimes_] = occbin.check_regimes([], [], [], opts_regime, M_, oo_, options_);
|
||||
if length(occbin_.info)>4
|
||||
if length(occbin_.info)==6 && options_.smoother_redux
|
||||
TT=repmat(T,1,1,smpl+1);
|
||||
RR=repmat(R,1,1,smpl+1);
|
||||
CC=repmat(zeros(mm,1),1,smpl+1);
|
||||
T0=occbin_.info{5};
|
||||
R0=occbin_.info{6};
|
||||
else
|
||||
|
||||
TT=occbin_.info{5};
|
||||
RR=occbin_.info{6};
|
||||
CC=occbin_.info{7};
|
||||
% TT = cat(3,TT,T);
|
||||
% RR = cat(3,RR,R);
|
||||
% CC = cat(2,CC,zeros(mm,1));
|
||||
if options_.smoother_redux
|
||||
my_order_var = oo_.dr.restrict_var_list;
|
||||
CC = CC(my_order_var,:);
|
||||
RR = RR(my_order_var,:,:);
|
||||
TT = TT(my_order_var,my_order_var,:);
|
||||
T0=occbin_.info{8};
|
||||
R0=occbin_.info{9};
|
||||
end
|
||||
if size(TT,3)<(smpl+1)
|
||||
TT=repmat(T,1,1,smpl+1);
|
||||
RR=repmat(R,1,1,smpl+1);
|
||||
CC=repmat(zeros(mm,1),1,smpl+1);
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
TT=repmat(T,1,1,smpl+1);
|
||||
RR=repmat(R,1,1,smpl+1);
|
||||
CC=repmat(zeros(mm,1),1,smpl+1);
|
||||
end
|
||||
if ~smoother_redux
|
||||
T0=T;
|
||||
R0=R;
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
t = 0;
|
||||
icc=0;
|
||||
if ~isempty(Pinf(:,:,1))
|
||||
|
@ -182,8 +247,8 @@ while newRank && t < smpl
|
|||
elseif Fstar(i,t) > kalman_tol
|
||||
a(:,t) = a(:,t) + Kstar(:,i,t)*v(i,t)/Fstar(i,t); % KD (2000), eq. (17)
|
||||
Pstar(:,:,t) = Pstar(:,:,t) - Kstar(:,i,t)*Kstar(:,i,t)'/Fstar(i,t); % KD (2000), eq. (17)
|
||||
% Pinf is passed through unaltered, see eq. (17) of
|
||||
% Koopman/Durbin (2000)
|
||||
% Pinf is passed through unaltered, see eq. (17) of
|
||||
% Koopman/Durbin (2000)
|
||||
else
|
||||
% do nothing as a_{t,i+1}=a_{t,i} and P_{t,i+1}=P_{t,i}, see
|
||||
% p. 157, DK (2012)
|
||||
|
@ -198,6 +263,10 @@ while newRank && t < smpl
|
|||
else
|
||||
oldRank = 0;
|
||||
end
|
||||
if isoccbin,
|
||||
TT(:,:,t+1)= T;
|
||||
RR(:,:,t+1)= R;
|
||||
end
|
||||
a1(:,t+1) = T*a(:,t);
|
||||
aK(1,:,t+1) = a1(:,t+1);
|
||||
for jnk=2:nk
|
||||
|
@ -221,7 +290,19 @@ while newRank && t < smpl
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
if isoccbin
|
||||
first_period_occbin_update = max(t+2,occbin_options.first_period_occbin_update);
|
||||
if occbin_options.opts_regime.waitbar
|
||||
hh = dyn_waitbar(0,'Occbin: Piecewise Kalman Filter');
|
||||
set(hh,'Name','Occbin: Piecewise Kalman Filter.');
|
||||
waitbar_indicator=1;
|
||||
else
|
||||
waitbar_indicator=0;
|
||||
end
|
||||
else
|
||||
first_period_occbin_update = inf;
|
||||
waitbar_indicator=0;
|
||||
end
|
||||
d = t;
|
||||
P(:,:,d+1) = Pstar(:,:,d+1);
|
||||
Fstar = Fstar(:,1:d);
|
||||
|
@ -237,63 +318,166 @@ while notsteady && t<smpl
|
|||
a(:,t) = a1(:,t);
|
||||
P1(:,:,t) = P(:,:,t);
|
||||
di = data_index{t}';
|
||||
for i=di
|
||||
Zi = Z(i,:);
|
||||
v(i,t) = Y(i,t) - Zi*a(:,t); % nu_{t,i} in 6.13 in DK (2012)
|
||||
Fi(i,t) = Zi*P(:,:,t)*Zi' + H(i); % F_{t,i} in 6.13 in DK (2012), relies on H being diagonal
|
||||
Ki(:,i,t) = P(:,:,t)*Zi'; % K_{t,i}*F_(i,t) in 6.13 in DK (2012)
|
||||
if Fi(i,t) > kalman_tol
|
||||
a(:,t) = a(:,t) + Ki(:,i,t)*v(i,t)/Fi(i,t); %filtering according to (6.13) in DK (2012)
|
||||
P(:,:,t) = P(:,:,t) - Ki(:,i,t)*Ki(:,i,t)'/Fi(i,t); %filtering according to (6.13) in DK (2012)
|
||||
if t>=first_period_occbin_update
|
||||
if waitbar_indicator
|
||||
dyn_waitbar(t/smpl, hh, sprintf('Period %u of %u', t,smpl));
|
||||
end
|
||||
if isqvec
|
||||
Qt = Qvec(:,:,t-1:t+1);
|
||||
end
|
||||
occbin_options.opts_regime.waitbar=0;
|
||||
[ax, a1x, Px, P1x, vx, Fix, Kix, Tx, Rx, Cx, tmp, error_flag, M_, aha, etaha,TTx,RRx,CCx] = occbin.kalman_update_algo_3(a(:,t-1),a1(:,t-1:t),P(:,:,t-1),P1(:,:,t-1:t),data_index(t-1:t),Z,v(:,t-1:t),Fi(:,t-1),Ki(:,:,t-1),Y(:,t-1:t),H,Qt,T0,R0,TT(:,:,t-1:t),RR(:,:,t-1:t),CC(:,t-1:t),regimes_(t:t+1),M_,oo_,options_,occbin_options,kalman_tol,nk);
|
||||
if ~error_flag
|
||||
regimes_(t:t+2)=tmp;
|
||||
else
|
||||
% do nothing as a_{t,i+1}=a_{t,i} and P_{t,i+1}=P_{t,i}, see
|
||||
% p. 157, DK (2012)
|
||||
varargout{1} = [];
|
||||
varargout{2} = [];
|
||||
varargout{3} = [];
|
||||
varargout{4} = [];
|
||||
return
|
||||
end
|
||||
end
|
||||
if smoother_redux
|
||||
ri=zeros(mm,1);
|
||||
for st=t:-1:max(d+1,t-1)
|
||||
di = flipud(data_index{st})';
|
||||
for i = di
|
||||
if Fi(i,st) > kalman_tol
|
||||
Li = eye(mm)-Ki(:,i,st)*Z(i,:)/Fi(i,st);
|
||||
ri = Z(i,:)'/Fi(i,st)*v(i,st)+Li'*ri; % DK (2012), 6.15, equation for r_{t,i-1}
|
||||
end
|
||||
end
|
||||
if st==t-1
|
||||
aalphahat(:,st) = a1(:,st) + P1(:,:,st)*ri;
|
||||
|
||||
if smoother_redux
|
||||
aalphahat(:,t-1) = aha(:,1);
|
||||
eetahat(:,t) = etaha(:,2);
|
||||
end
|
||||
a(:,t) = ax(:,1);
|
||||
a1(:,t) = a1x(:,2);
|
||||
a1(:,t+1) = ax(:,2);
|
||||
v(di,t) = vx(di,2);
|
||||
Fi(di,t) = Fix(di,2);
|
||||
Ki(:,di,t) = Kix(:,di,2);
|
||||
TT(:,:,t:t+1) = Tx(:,:,1:2);
|
||||
RR(:,:,t:t+1) = Rx(:,:,1:2);
|
||||
CC(:,t:t+1) = Cx(:,1:2);
|
||||
TTT(:,:,t)=TTx;
|
||||
RRR(:,:,t)=RRx;
|
||||
CCC(:,t)=CCx;
|
||||
P(:,:,t) = Px(:,:,1);
|
||||
P1(:,:,t) = P1x(:,:,2);
|
||||
P(:,:,t+1) = Px(:,:,2);
|
||||
for jnk=1:nk
|
||||
PK(jnk,:,:,t+jnk) = Px(:,:,1+jnk);
|
||||
aK(jnk,:,t+jnk) = ax(:,1+jnk);
|
||||
end
|
||||
else
|
||||
for i=di
|
||||
Zi = Z(i,:);
|
||||
v(i,t) = Y(i,t) - Zi*a(:,t); % nu_{t,i} in 6.13 in DK (2012)
|
||||
Fi(i,t) = Zi*P(:,:,t)*Zi' + H(i); % F_{t,i} in 6.13 in DK (2012), relies on H being diagonal
|
||||
Ki(:,i,t) = P(:,:,t)*Zi'; % K_{t,i}*F_(i,t) in 6.13 in DK (2012)
|
||||
if Fi(i,t) > kalman_tol
|
||||
a(:,t) = a(:,t) + Ki(:,i,t)*v(i,t)/Fi(i,t); %filtering according to (6.13) in DK (2012)
|
||||
P(:,:,t) = P(:,:,t) - Ki(:,i,t)*Ki(:,i,t)'/Fi(i,t); %filtering according to (6.13) in DK (2012)
|
||||
else
|
||||
eetahat(:,st) = QRt*ri;
|
||||
% do nothing as a_{t,i+1}=a_{t,i} and P_{t,i+1}=P_{t,i}, see
|
||||
% p. 157, DK (2012)
|
||||
end
|
||||
ri = T'*ri; % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
|
||||
end
|
||||
end
|
||||
if isqvec
|
||||
QQ = R*Qvec(:,:,t+1)*transpose(R);
|
||||
end
|
||||
a1(:,t+1) = T*a(:,t); %transition according to (6.14) in DK (2012)
|
||||
P(:,:,t+1) = T*P(:,:,t)*T' + QQ; %transition according to (6.14) in DK (2012)
|
||||
if filter_covariance_flag
|
||||
Pf = P(:,:,t+1);
|
||||
end
|
||||
aK(1,:,t+1) = a1(:,t+1);
|
||||
for jnk=1:nk
|
||||
if isqvec
|
||||
QQ = R*Qvec(:,:,t)*transpose(R);
|
||||
end
|
||||
if smoother_redux
|
||||
ri=zeros(mm,1);
|
||||
for st=t:-1:max(d+1,t-1)
|
||||
di = flipud(data_index{st})';
|
||||
for i = di
|
||||
if Fi(i,st) > kalman_tol
|
||||
Li = eye(mm)-Ki(:,i,st)*Z(i,:)/Fi(i,st);
|
||||
ri = Z(i,:)'/Fi(i,st)*v(i,st)+Li'*ri; % DK (2012), 6.15, equation for r_{t,i-1}
|
||||
end
|
||||
end
|
||||
if st==t-1
|
||||
aalphahat(:,st) = a1(:,st) + P1(:,:,st)*ri;
|
||||
else
|
||||
if isoccbin
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,st)*transpose(RR(:,:,st));
|
||||
else
|
||||
QRt = Q*transpose(RR(:,:,st));
|
||||
end
|
||||
T = TT(:,:,st);
|
||||
else
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,st)*transpose(R);
|
||||
end
|
||||
end
|
||||
eetahat(:,st) = QRt*ri;
|
||||
end
|
||||
ri = T'*ri; % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
|
||||
end
|
||||
end
|
||||
if isoccbin
|
||||
if isqvec
|
||||
QQ = RR(:,:,t+1)*Qvec(:,:,t+1)*transpose(RR(:,:,t+1));
|
||||
else
|
||||
QQ = RR(:,:,t+1)*Q*transpose(RR(:,:,t+1));
|
||||
end
|
||||
T = TT(:,:,t+1);
|
||||
C = CC(:,t+1);
|
||||
else
|
||||
if isqvec
|
||||
QQ = R*Qvec(:,:,t+1)*transpose(R);
|
||||
end
|
||||
end
|
||||
a1(:,t+1) = T*a(:,t)+C; %transition according to (6.14) in DK (2012)
|
||||
P(:,:,t+1) = T*P(:,:,t)*T' + QQ; %transition according to (6.14) in DK (2012)
|
||||
if filter_covariance_flag
|
||||
if jnk>1
|
||||
Pf = T*Pf*T' + QQ;
|
||||
end
|
||||
PK(jnk,:,:,t+jnk) = Pf;
|
||||
Pf = P(:,:,t+1);
|
||||
end
|
||||
if jnk>1
|
||||
aK(jnk,:,t+jnk) = T*dynare_squeeze(aK(jnk-1,:,t+jnk-1));
|
||||
aK(1,:,t+1) = a1(:,t+1);
|
||||
if ~isempty(nk) && nk>1 && isoccbin
|
||||
opts_simul = occbin_options.opts_regime;
|
||||
opts_simul.SHOCKS = zeros(nk,M_.exo_nbr);
|
||||
if smoother_redux
|
||||
tmp=zeros(M_.endo_nbr,1);
|
||||
tmp(oo_.dr.restrict_var_list)=a(:,t);
|
||||
opts_simul.endo_init = tmp(oo_.dr.inv_order_var);
|
||||
else
|
||||
opts_simul.endo_init = a(oo_.dr.inv_order_var,t);
|
||||
end
|
||||
opts_simul.init_regime = []; %regimes_(t);
|
||||
options_.occbin.simul=opts_simul;
|
||||
[~, out, ss] = occbin.solver(M_,oo_,options_);
|
||||
end
|
||||
for jnk=1:nk
|
||||
if filter_covariance_flag
|
||||
if jnk>1
|
||||
Pf = T*Pf*T' + QQ;
|
||||
end
|
||||
PK(jnk,:,:,t+jnk) = Pf;
|
||||
end
|
||||
if isoccbin
|
||||
if smoother_redux
|
||||
aK(jnk,:,t+jnk) = out.zpiece(jnk,oo_.dr.order_var(oo_.dr.restrict_var_list));
|
||||
else
|
||||
aK(jnk,oo_.dr.inv_order_var,t+jnk) = out.zpiece(jnk,:);
|
||||
end
|
||||
elseif jnk>1
|
||||
aK(jnk,:,t+jnk) = T*dynare_squeeze(aK(jnk-1,:,t+jnk-1));
|
||||
end
|
||||
end
|
||||
end
|
||||
% notsteady = ~(max(max(abs(P(:,:,t+1)-P(:,:,t))))<kalman_tol);
|
||||
end
|
||||
if waitbar_indicator
|
||||
dyn_waitbar_close(hh);
|
||||
end
|
||||
|
||||
P1(:,:,t+1) = P(:,:,t+1);
|
||||
|
||||
P1(:,:,t+1)=P(:,:,t+1);
|
||||
|
||||
if ~isinf(first_period_occbin_update) && isoccbin
|
||||
regimes_ = regimes_(2:smpl+1);
|
||||
else
|
||||
regimes_ = struct();
|
||||
TTT=TT;
|
||||
RRR=RR;
|
||||
CCC=CC;
|
||||
% return
|
||||
end
|
||||
varargout{1} = regimes_;
|
||||
varargout{2} = TTT;
|
||||
varargout{3} = RRR;
|
||||
varargout{4} = CCC;
|
||||
% $$$ P_s=tril(P(:,:,t))+tril(P(:,:,t),-1)';
|
||||
% $$$ P1_s=tril(P1(:,:,t))+tril(P1(:,:,t),-1)';
|
||||
% $$$ Fi_s = Fi(:,t);
|
||||
|
@ -346,8 +530,18 @@ while t > d+1
|
|||
end
|
||||
r(:,t) = ri; % DK (2012), below 6.15, r_{t-1}=r_{t,0}
|
||||
alphahat(:,t) = a1(:,t) + P1(:,:,t)*r(:,t);
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(R);
|
||||
if isoccbin
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(RR(:,:,t));
|
||||
else
|
||||
QRt = Q*transpose(RR(:,:,t));
|
||||
end
|
||||
R = RR(:,:,t);
|
||||
T = TT(:,:,t);
|
||||
else
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(R);
|
||||
end
|
||||
end
|
||||
etahat(:,t) = QRt*r(:,t);
|
||||
ri = T'*ri; % KD (2003), eq. (23), equation for r_{t-1,p_{t-1}}
|
||||
|
@ -383,8 +577,8 @@ if d
|
|||
Linf = eye(mm) - Kinf(:,i,t)*Z(i,:)/Finf(i,t);
|
||||
L0 = (Kinf(:,i,t)*(Fstar(i,t)/Finf(i,t))-Kstar(:,i,t))*Z(i,:)/Finf(i,t);
|
||||
r1(:,t) = Z(i,:)'*v(i,t)/Finf(i,t) + ...
|
||||
L0'*r0(:,t) + ...
|
||||
Linf'*r1(:,t); % KD (2000), eq. (25) for r_1
|
||||
L0'*r0(:,t) + ...
|
||||
Linf'*r1(:,t); % KD (2000), eq. (25) for r_1
|
||||
r0(:,t) = Linf'*r0(:,t); % KD (2000), eq. (25) for r_0
|
||||
if state_uncertainty_flag
|
||||
N_2(:,:,t)=Z(i,:)'/Finf(i,t)^2*Z(i,:)*Fstar(i,t) ...
|
||||
|
@ -406,8 +600,18 @@ if d
|
|||
end
|
||||
alphahat(:,t) = a1(:,t) + Pstar1(:,:,t)*r0(:,t) + Pinf1(:,:,t)*r1(:,t); % KD (2000), eq. (26)
|
||||
r(:,t) = r0(:,t);
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(R);
|
||||
if isoccbin
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(RR(:,:,t));
|
||||
else
|
||||
QRt = Q*transpose(RR(:,:,t));
|
||||
end
|
||||
R = RR(:,:,t);
|
||||
T = TT(:,:,t);
|
||||
else
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(R);
|
||||
end
|
||||
end
|
||||
etahat(:,t) = QRt*r(:,t); % KD (2000), eq. (27)
|
||||
if state_uncertainty_flag
|
||||
|
@ -439,6 +643,8 @@ if d
|
|||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
alphahat0 = 0*a1(:,1) + P1(:,:,1)*ri;
|
||||
end
|
||||
|
||||
if decomp_flag
|
||||
|
@ -452,10 +658,20 @@ if decomp_flag
|
|||
ri_d = Z(i,:)'/Fi(i,t)*v(i,t)+ri_d-Ki(:,i,t)'*ri_d/Fi(i,t)*Z(i,:)';
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% calculate eta_tm1t
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(R);
|
||||
if isoccbin
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(RR(:,:,t));
|
||||
else
|
||||
QRt = Q*transpose(RR(:,:,t));
|
||||
end
|
||||
R = RR(:,:,t);
|
||||
T = TT(:,:,t);
|
||||
else
|
||||
if isqvec
|
||||
QRt = Qvec(:,:,t)*transpose(R);
|
||||
end
|
||||
end
|
||||
eta_tm1t = QRt*ri_d;
|
||||
% calculate decomposition
|
||||
|
|
|
@ -223,8 +223,13 @@ for b=fpar:B
|
|||
fprintf('\nprior_posterior_statistics: One of the draws failed with the error:\n%s\n',message)
|
||||
fprintf('prior_posterior_statistics: This should not happen. Please contact the developers.\n',message)
|
||||
end
|
||||
[alphahat,etahat,epsilonhat,alphatilde,SteadyState,trend_coeff,aK,~,~,P,~,~,trend_addition,state_uncertainty,M_,oo_,bayestopt_] = ...
|
||||
DsgeSmoother(deep,gend,Y,data_index,missing_value,M_,oo_,opts_local,bayestopt_,estim_params_);
|
||||
if options_.occbin.smoother.status
|
||||
[alphahat,etahat,epsilonhat,alphatilde,SteadyState,trend_coeff,aK,~,~,P,~,~,trend_addition,state_uncertainty,M_,oo_,bayestopt_] = ...
|
||||
occbin.DSGE_smoother(deep,gend,Y,data_index,missing_value,M_,oo_,opts_local,bayestopt_,estim_params_);
|
||||
else
|
||||
[alphahat,etahat,epsilonhat,alphatilde,SteadyState,trend_coeff,aK,~,~,P,~,~,trend_addition,state_uncertainty,M_,oo_,bayestopt_] = ...
|
||||
DsgeSmoother(deep,gend,Y,data_index,missing_value,M_,oo_,opts_local,bayestopt_,estim_params_);
|
||||
end
|
||||
|
||||
stock_trend_coeff(options_.varobs_id,irun(9))=trend_coeff;
|
||||
stock_smoothed_trend(IdObs,:,irun(11))=trend_addition;
|
||||
|
|
|
@ -72,6 +72,20 @@ function [oo_, yf]=store_smoother_results(M_,oo_,options_,bayestopt_,dataset_,da
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
%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
|
||||
|
||||
gend=dataset_.nobs;
|
||||
if nargin<16
|
||||
Trend=zeros(options_.number_of_observed_variables,gend);
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
function [i_var, nvar, index_uniques] = varlist_indices(sublist, list)
|
||||
function [i_var, nvar, index_unique_present] = varlist_indices(sublist, list, nocheck_dummy)
|
||||
|
||||
% returns the indices of a list of endogenous variables
|
||||
% returns the indices of a list of variables
|
||||
%
|
||||
% INPUT
|
||||
% sublist [cell of char arrays] sublist of variables
|
||||
% list [cell of char arrays] list of variables
|
||||
%
|
||||
% OUTPUT
|
||||
% i_var variable indices in M_.endo_names
|
||||
% nvar number of variables in varlist
|
||||
% index_uniques indices of unique elements in varlist
|
||||
% i_var variable indices in list
|
||||
% nvar number of unique variables contained in list
|
||||
% index_uniques indices of unique and present elements in sublist
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2010-2018 Dynare Team
|
||||
% Copyright (C) 2010-2021 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -31,6 +31,9 @@ function [i_var, nvar, index_uniques] = varlist_indices(sublist, list)
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
if nargin<3
|
||||
nocheck_dummy=0;
|
||||
end
|
||||
if isempty(sublist)
|
||||
check = [];
|
||||
i_var = [];
|
||||
|
@ -38,27 +41,34 @@ else
|
|||
[check, i_var] = ismember(sublist, list);
|
||||
end
|
||||
|
||||
indices_not_present=[];
|
||||
if ~all(check)
|
||||
k = find(~check);
|
||||
str = 'The following symbols are not endogenous variables:';
|
||||
for ii = 1:length(k)
|
||||
str = sprintf('%s %s', str, sublist{k(ii)});
|
||||
k_not_present = find(~check);
|
||||
if ~nocheck_dummy
|
||||
str = 'The following symbols are not endogenous variables:';
|
||||
for ii = 1:length(k_not_present)
|
||||
str = sprintf('%s %s', str, sublist{k_not_present(ii)});
|
||||
end
|
||||
error(str)
|
||||
else
|
||||
indices_not_present=find(i_var==0);
|
||||
end
|
||||
error(str)
|
||||
end
|
||||
|
||||
nvar = length(i_var);
|
||||
[~, index_uniques, ~] = unique(i_var, 'first');
|
||||
index_uniques = sort(index_uniques);
|
||||
i_var_unique = i_var(index_uniques);
|
||||
nvar_present = length(i_var(check));
|
||||
[~, index_unique, ~] = unique(i_var, 'first');
|
||||
index_unique_present = index_unique(~ismember(index_unique,indices_not_present));
|
||||
index_unique_present = sort(index_unique_present);
|
||||
i_var_unique_present = i_var(index_unique_present);
|
||||
|
||||
if length(i_var_unique)~=nvar
|
||||
k = find(~ismember(1:nvar,index_uniques));
|
||||
if length(i_var_unique_present)~=nvar_present
|
||||
k = find(~ismember((1:length(i_var))',index_unique_present) & i_var~=0);
|
||||
str = 'The following symbols are specified twice in the variable list and are considered only once:';
|
||||
for ii = 1:length(k)
|
||||
str = sprintf('%s %s', str, sublist{k(ii)});
|
||||
str = sprintf('%s %s', str, sublist{i_var(k(ii))});
|
||||
end
|
||||
warning('%s\n', str)
|
||||
i_var = i_var_unique;
|
||||
nvar = length(i_var);
|
||||
end
|
||||
end
|
||||
|
||||
i_var = i_var_unique_present;
|
||||
nvar = length(i_var);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 6b9d94405c44fe2533a2d8bc377173a2a70f3a54
|
||||
Subproject commit 08ac455fcddd032058738669ed6a84fda9c76e05
|
|
@ -64,7 +64,8 @@
|
|||
"write_latex_steady_state_model" "steady" "check" "simul" "stoch_simul"
|
||||
"var_model" "trend_component_model" "var_expectation_model" "pac_model"
|
||||
"dsample" "Sigma_e" "planner_objective" "ramsey_model" "ramsey_policy"
|
||||
"evaluate_planner_objective"
|
||||
"evaluate_planner_objective" "occbin_setup" "occbin_solver"
|
||||
"occbin_write_regimes" "occbin_graph"
|
||||
"discretionary_policy" "identification" "bvar_density" "bvar_forecast"
|
||||
"dynare_sensitivity" "initval_file" "histval_file" "forecast"
|
||||
"shock_decomposition" "realtime_shock_decomposition"
|
||||
|
@ -84,7 +85,8 @@
|
|||
;; Keywords that may appear in blocks, and that begin a statement which will be
|
||||
;; closed by a semicolon
|
||||
(defvar dynare-statements-like
|
||||
'("stderr" "values" "scales" "restriction" "exclusion" "upper_cholesky" "lower_cholesky")
|
||||
'("stderr" "values" "scales" "restriction" "exclusion" "upper_cholesky" "lower_cholesky"
|
||||
"bind" "relax" "error_bind" "error_relax")
|
||||
"Dynare statements-like keywords.")
|
||||
|
||||
;; Those keywords that makes the lexer enter the DYNARE_BLOCK start condition
|
||||
|
@ -99,7 +101,7 @@
|
|||
"observation_trends" "deterministic_trends" "optim_weights" "homotopy_setup"
|
||||
"conditional_forecast_paths" "svar_identification" "moment_calibration"
|
||||
"irf_calibration" "ramsey_constraints" "generate_irfs"
|
||||
"matched_moments" "verbatim")
|
||||
"matched_moments" "occbin_constraints" "verbatim")
|
||||
"Dynare block keywords."))
|
||||
|
||||
;; Mathematical functions and operators used in model equations (see "hand_side" in Bison file)
|
||||
|
|
|
@ -120,6 +120,8 @@ wsOct
|
|||
!/ms-sbvar/data.m
|
||||
!/objectives/sgu_ex1.mat
|
||||
!/observation_trends_and_prefiltering/generate_trend_stationary_AR1.m
|
||||
!/occbin/filter/dataobsfile.mat
|
||||
!/occbin/filter/NKM_mh_mode_saved.mat
|
||||
!/optimal_policy/Ramsey/find_c.m
|
||||
!/optimal_policy/Ramsey/oo_ramsey_policy_initval.mat
|
||||
!/optimizers/optimizer_function_wrapper.m
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
MODFILES = \
|
||||
walsh.mod \
|
||||
occbin/model_irrcap_twoconstraints/dynrbc.mod \
|
||||
occbin/model_irrcap_twoconstraints/dynrbc_0_std_shocks.mod \
|
||||
occbin/model_borrcon/borrcon.mod \
|
||||
occbin/model_borrcon/borrcon_0_std_shocks.mod \
|
||||
occbin/filter/NKM.mod \
|
||||
occbin/filter/NKM_0_std_shocks.mod \
|
||||
optimizers/fs2000_6.mod \
|
||||
moments/example1_hp_test.mod \
|
||||
moments/fs2000_post_moments.mod \
|
||||
|
@ -594,6 +600,7 @@ XFAIL_MODFILES = ramst_xfail.mod \
|
|||
identification/LindeTrabandt/LindeTrabandt2019_xfail.mod \
|
||||
steady_state/Linear_steady_state_xfail.mod \
|
||||
optimal_policy/Ramsey/ramsey_histval_xfail.mod \
|
||||
occbin/model_irrcap_twoconstraints/dynrbc_token_xfail.mod \
|
||||
particle/first_spec_xfail_0.mod \
|
||||
particle/first_spec_xfail_1.mod \
|
||||
kalman_initial_state/fs2000_kalman_initial_xfail.mod \
|
||||
|
@ -617,6 +624,12 @@ optimal_policy/neo_growth_ramsey_foresight.o.trs: optimal_policy/neo_growth_fore
|
|||
optimal_policy/neo_growth_ramsey_k_order.m.trs: optimal_policy/neo_growth_k_order.m.trs
|
||||
optimal_policy/neo_growth_ramsey_k_order.o.trs: optimal_policy/neo_growth_k_order.o.trs
|
||||
|
||||
occbin/model_irrcap_twoconstraints/dynrbc_0_std_shocks.m.trs: occbin/model_irrcap_twoconstraints/dynrbc.m.trs
|
||||
occbin/model_irrcap_twoconstraints/dynrbc_0_std_shocks.o.trs: occbin/model_irrcap_twoconstraints/dynrbc.o.trs
|
||||
|
||||
occbin/model_borrcon/borrcon_0_std_shocks.m.trs: occbin/model_borrcon/borrcon.m.trs
|
||||
occbin/model_borrcon/borrcon_0_std_shocks.o.trs: occbin/model_borrcon/borrcon.o.trs
|
||||
|
||||
example1_use_dll.m.trs: example1.m.trs
|
||||
example1_use_dll.o.trs: example1.o.trs
|
||||
|
||||
|
@ -1245,6 +1258,10 @@ EXTRA_DIST = \
|
|||
observation_trends_and_prefiltering/Trend_model_calib_no_prefilter_common.inc \
|
||||
observation_trends_and_prefiltering/Trend_load_data_common.inc \
|
||||
observation_trends_and_prefiltering/Trend_no_prefilter_conditional_forecast.inc \
|
||||
occbin/model_borrcon/borrcon_common.inc \
|
||||
occbin/model_irrcap_twoconstraints/dynrbc_common.inc \
|
||||
occbin/filter/dataobsfile.mat \
|
||||
occbin/filter/NKM_mh_mode_saved.mat \
|
||||
optimal_policy/neo_growth_common.inc \
|
||||
optimal_policy/neo_growth_ramsey_common.inc \
|
||||
optimal_policy/Ramsey/oo_ramsey_policy_initval.mat \
|
||||
|
@ -1479,6 +1496,8 @@ clean-local:
|
|||
kalman/likelihood_from_dynare/fs_ns_dat_simul_uncorr_ME.m \
|
||||
kalman/likelihood_from_dynare/fs_ns_dat_simul_uncorr_ME_missing.m
|
||||
|
||||
rm -f occbin/filter/dataobsfile2.mat
|
||||
|
||||
find . -name "*.tex" -type f -delete
|
||||
find . -name "*.aux" -type f -delete
|
||||
find . -name "*.log" -type f -delete
|
||||
|
|
|
@ -0,0 +1,342 @@
|
|||
//Tests Occbin estimation with IVF and PKF with 1 constraints
|
||||
|
||||
// this file implements the model in:
|
||||
// Atkinson, T., A. W. Richter, and N. A. Throckmorton (2019).
|
||||
// The zero lower bound andestimation accuracy.Journal of Monetary Economics
|
||||
// original codes provided by Alexander Richter
|
||||
// adapted for dynare implementation
|
||||
// ------------------------- Settings -----------------------------------------//
|
||||
|
||||
@#ifndef small_model
|
||||
@#define small_model = 0
|
||||
@#endif
|
||||
|
||||
// if ~exist('run_ivf','var')
|
||||
run_ivf=0;
|
||||
// end
|
||||
|
||||
// ----------------- Defintions -----------------------------------------//
|
||||
var
|
||||
c //1 Consumption
|
||||
n //2 Labor
|
||||
y //5 Output
|
||||
yf //6 Final goods
|
||||
yg //11 Output growth gap
|
||||
w //12 Real wage rate
|
||||
wf //13 Flexible real wage
|
||||
pigap //15 Inflation rate -> pi(t)/pibar = pigap
|
||||
inom //16 Nominal interest rate
|
||||
inomnot //17 Notional interest rate
|
||||
mc //19 Real marginal cost
|
||||
lam //20 Inverse marginal utility of wealth
|
||||
g //21 Growth shock
|
||||
s //22 Risk premium shock
|
||||
mp //23 Monetary policy shock
|
||||
pi //24 Observed inflation
|
||||
@#if !(small_model)
|
||||
x //3 Investment
|
||||
k //4 Capital
|
||||
u //7 Utilization cost
|
||||
ups //8 Utilization choice
|
||||
wg //9 Real wage growth gap
|
||||
xg //10 Investment growth
|
||||
rk //14 Real rental rate
|
||||
q //18 Tobins q
|
||||
@#endif
|
||||
;
|
||||
varexo
|
||||
epsg // Productivity growth shock
|
||||
epsi // Notional interest rate shock
|
||||
epss // Risk premium shock
|
||||
;
|
||||
parameters
|
||||
// Calibrated Parameters
|
||||
beta // Discount factor
|
||||
chi // Labor disutility scale
|
||||
thetap // Elasticity of subs. between intermediate goods
|
||||
thetaw // Elasticity of subs. between labor types
|
||||
nbar // Steady state labor
|
||||
eta // Inverse frish elasticity of labor supply
|
||||
delta // Depreciation
|
||||
alpha // Capital share
|
||||
gbar // Mean growth rate
|
||||
pibar // Inflation target
|
||||
inombar // Steady gross nom interest rate
|
||||
inomlb // Effective lower bound on gross nominal interest rate
|
||||
sbar // Average risk premium
|
||||
// Parameters for DGP and Estimated parameters
|
||||
varphip // Rotemberg price adjustment cost
|
||||
varphiw // Rotemberg wage adjustment cost
|
||||
h // Habit persistence
|
||||
rhos // Persistence
|
||||
rhoi // Persistence
|
||||
sigz // Standard deviation technology
|
||||
sigs // Standard deviation risk premia
|
||||
sigi // Standard deviation mon pol
|
||||
phipi // Inflation responsiveness
|
||||
phiy // Output responsiveness
|
||||
nu // Investment adjustment cost
|
||||
sigups // Utilization
|
||||
|
||||
// Switching parameters
|
||||
zlb
|
||||
;
|
||||
|
||||
|
||||
// ---------------- Calibration -----------------------------------------//
|
||||
|
||||
beta = 0.9949; // Discount factor
|
||||
thetap = 6; // Elasticity of subs. between intermediate goods
|
||||
thetaw = 6; // Elasticity of subs. between labor types
|
||||
nbar = 1/3; // Steady state labor
|
||||
eta = 1/3; // Inverse frish elasticity of labor supply
|
||||
delta = 0.025; // Depreciation
|
||||
alpha = 0.35; // Capital share
|
||||
gbar = 1.0034; // Mean growth rate
|
||||
pibar = 1.0053; // Inflation target
|
||||
sbar = 1.0058; // Average risk premium
|
||||
rkbar = 1/beta;
|
||||
varphiw = 100; // Rotemberg wage adjustment cost
|
||||
nu = 4; // Investment adjustment cost
|
||||
sigups = 5; // Utilization
|
||||
varphip = 100; // Rotemberg price adjustment cost
|
||||
h = 0.80; // Habit persistence
|
||||
rhos = 0.80; // Persistence
|
||||
rhoi = 0.80; // Persistence
|
||||
sigz = 0.005; // Standard deviation
|
||||
sigs = 0.005; // Standard deviation
|
||||
sigi = 0.002; // Standard deviation
|
||||
phipi = 2.0; // Inflation responsiveness
|
||||
phiy = 0.5; // Output responsiveness
|
||||
zlb = 0 ; // ZLB dummy
|
||||
inomlb = 1 ; // Inom LB
|
||||
|
||||
// ---------------- Model -----------------------------------------------//
|
||||
model;
|
||||
|
||||
@#if !(small_model)
|
||||
[name = 'HH FOC utilization (1)']
|
||||
rk = steady_state(rk)*exp(sigups*(ups-1));
|
||||
|
||||
[name = 'Utilization definition (3)']
|
||||
u = steady_state(rk)*(exp(sigups*(ups-1))-1)/sigups;
|
||||
|
||||
[name = 'Firm FOC capital (4)']
|
||||
rk = mc*alpha*g*yf/(ups*k(-1));
|
||||
|
||||
[name = 'HH FOC capital (17)']
|
||||
q = beta*(lam/lam(+1))*(rk(+1)*ups(+1)-u(+1)+(1-delta)*q(+1))/g(+1);
|
||||
|
||||
[name = 'HH FOC investment (18)']
|
||||
1 = q*(1-nu*(xg-1)^2/2-nu*(xg-1)*xg)+beta*nu*gbar*q(+1)*(lam/lam(+1))*xg(+1)^2*(xg(+1)-1)/g(+1);
|
||||
|
||||
[name = 'Wage Phillips Curve (20)']
|
||||
varphiw*(wg-1)*wg = ((1-thetaw)*w+thetaw*wf)*n/yf + beta*varphiw*(lam/lam(+1))*(wg(+1)-1)*wg(+1)*(yf(+1)/yf) ;
|
||||
|
||||
[name = 'Real wage growth gap (6)']
|
||||
wg = pigap*g*w/(gbar*w(-1));
|
||||
|
||||
[name = 'Law of motion for capital (15)']
|
||||
k = (1-delta)*(k(-1)/g)+x*(1-nu*(xg-1)^2/2);
|
||||
|
||||
[name = 'Investment growth gap (14)']
|
||||
xg = g*x/(gbar*x(-1));
|
||||
@#endif
|
||||
|
||||
|
||||
@#if small_model
|
||||
[name = 'Production function (2)']
|
||||
yf = n;
|
||||
|
||||
[name = 'Firm FOC labor (5)']
|
||||
w = mc*yf/n;
|
||||
|
||||
[name = 'Output definition (7)']
|
||||
y = (1-varphip*(pigap-1)^2/2)*yf;
|
||||
|
||||
[name = 'ARC (13)']
|
||||
c = y;
|
||||
|
||||
[name = 'Household labpur supply equals flex wage']
|
||||
w = wf;
|
||||
@#else
|
||||
[name = 'Production function (2)']
|
||||
yf = (ups*k(-1)/g)^alpha*n^(1-alpha);
|
||||
|
||||
[name = 'Firm FOC labor (5)']
|
||||
w = (1-alpha)*mc*yf/n;
|
||||
|
||||
[name = 'Output definition (7)']
|
||||
y = (1-varphip*(pigap-1)^2/2-varphiw*(wg-1)^2/2)*yf - u*k(-1)/g;
|
||||
|
||||
[name = 'ARC (13)']
|
||||
x = y-c;
|
||||
@#endif
|
||||
|
||||
[name = 'Output growth gap (8)']
|
||||
yg = g*y/(gbar*y(-1));
|
||||
|
||||
[name = 'Notional Interest Rate (9)']
|
||||
inomnot = inomnot(-1)^rhoi*(inombar*pigap^phipi*yg^phiy)^(1-rhoi)*exp(mp);
|
||||
|
||||
[name = 'Nominal Interest Rate (10)']
|
||||
inom = (inomnot*(1-zlb)+zlb*inomlb);
|
||||
|
||||
[name = 'Inverse MUC (11)']
|
||||
lam = c-h*c(-1)/g;
|
||||
|
||||
[name = 'Flexible real wage definition (12)']
|
||||
wf = chi*n^eta*lam;
|
||||
|
||||
[name = 'HH FOC bond (16)']
|
||||
1 = beta*(lam/lam(+1))*s*inom/(g(+1)*pibar*pigap(+1));
|
||||
|
||||
[name = 'Price Phillips Curve (19)']
|
||||
varphip*(pigap-1)*pigap = 1-thetap+thetap*mc+beta*varphip*(lam/lam(+1))*(pigap(+1)-1)*pigap(+1)*(yf(+1)/yf);
|
||||
|
||||
[name = 'Stochastic productivity growth (21)']
|
||||
g = gbar+ sigz*epsg;
|
||||
|
||||
[name = 'Risk premium shock (22)']
|
||||
s = (1-rhos)*sbar + rhos*s(-1)+sigs*epss ;
|
||||
|
||||
[name = 'Notional interest rate shock (23)']
|
||||
mp = sigi*epsi;
|
||||
|
||||
[name = 'Observed inflation (24)']
|
||||
pi = pigap*pibar;
|
||||
|
||||
end;
|
||||
|
||||
occbin_constraints;
|
||||
name 'zlb'; bind inom+inombar <= inomlb; relax inom+inombar > inomlb;
|
||||
end;
|
||||
|
||||
// ---------------- Steady state -----------------------------------------//
|
||||
steady_state_model;
|
||||
mp = 0;
|
||||
xg = 1;
|
||||
s = sbar;
|
||||
n = nbar;
|
||||
ups =1;
|
||||
u =0;
|
||||
q =1;
|
||||
g = gbar;
|
||||
yg = 1;
|
||||
pigap = 1;
|
||||
wg =1;
|
||||
pi = pigap*pibar;
|
||||
// FOC bond
|
||||
inom = gbar*pibar/(beta*s);
|
||||
inomnot = inom;
|
||||
inombar = inom;
|
||||
// Firm pricing
|
||||
mc = (thetap-1)/thetap;
|
||||
// FOC capital
|
||||
rk = gbar/beta+delta-1;
|
||||
// Marginal cost definition
|
||||
@#if small_model
|
||||
alpha = 0;
|
||||
thetaw=1;
|
||||
@#endif
|
||||
w = (mc*(1-alpha)^(1-alpha)*alpha^alpha/rk^alpha)^(1/(1-alpha));
|
||||
@#if small_model
|
||||
wf = w;
|
||||
@#else
|
||||
wf = (thetaw-1)*w/thetaw;
|
||||
@#endif
|
||||
// Consolidated FOC firm
|
||||
k = w*n*gbar*alpha/(rk*(1-alpha));
|
||||
// Law of motion for capital
|
||||
x = (1-(1-delta)/gbar)*k;
|
||||
// Production function
|
||||
yf = (k/gbar)^alpha*n^(1-alpha);
|
||||
// Real GDP
|
||||
y = yf;
|
||||
// Aggregate resouce constraint
|
||||
c = y-x;
|
||||
// FOC labor
|
||||
lam = (1-h/gbar)*c;
|
||||
chi = wf/(n^eta*lam);
|
||||
|
||||
// try log observables
|
||||
end;
|
||||
|
||||
// ---------------- Checks -----------------------------------------//
|
||||
steady;
|
||||
check;
|
||||
|
||||
// ---------------- Simulation -----------------------------------------//
|
||||
shocks;
|
||||
var epsi = 1;
|
||||
var epss = 1;
|
||||
var epsg = 1;
|
||||
end;
|
||||
|
||||
steady;
|
||||
check;
|
||||
|
||||
// ---------------- Estimation -----------------------------------------//
|
||||
|
||||
varobs yg inom pi;
|
||||
estimated_params;
|
||||
// PARAM NAME, INITVAL, LB, UB, PRIOR_SHAPE, PRIOR_P1, PRIOR_P2, PRIOR_P3, PRIOR_P4, JSCALE
|
||||
// PRIOR_SHAPE: BETA_PDF, GAMMA_PDF, NORMAL_PDF, INV_GAMMA_PDF
|
||||
varphip,,0,inf,NORMAL_PDF,100,25;
|
||||
phipi,,,,NORMAL_PDF,2,0.25;
|
||||
phiy,,0,inf,NORMAL_PDF,0.5,0.25;
|
||||
h,,,,BETA_PDF,0.8,0.1;
|
||||
rhos,,,,BETA_PDF,0.8,0.1;
|
||||
rhoi,,,,BETA_PDF,0.8,0.1;
|
||||
sigz,,,,INV_GAMMA_PDF,0.005,0.005;
|
||||
sigs,,,,INV_GAMMA_PDF,0.005,0.005;
|
||||
sigi,,,,INV_GAMMA_PDF,0.002,0.002;
|
||||
end;
|
||||
|
||||
|
||||
// dataloading_jme_beta(1,'sims.txt',30);
|
||||
load('dataobsfile','inom')
|
||||
// check if inom is at lb and remove data + associated shock
|
||||
verbatim;
|
||||
inom(inom==1)=NaN;
|
||||
end;
|
||||
inx = strmatch('epsi',M_.exo_names);
|
||||
if any(isnan(inom))
|
||||
M_.heteroskedastic_shocks.Qscale_orig.periods=find(isnan(inom));
|
||||
M_.heteroskedastic_shocks.Qscale_orig.exo_id=inx;
|
||||
M_.heteroskedastic_shocks.Qscale_orig.scale=0;
|
||||
else
|
||||
options_.heteroskedastic_filter=false;
|
||||
end
|
||||
|
||||
copyfile dataobsfile.mat dataobsfile2.mat
|
||||
save dataobsfile2 inom -append
|
||||
// -----------------Occbin ----------------------------------------------//
|
||||
options_.occbin.smoother.debug=1;
|
||||
occbin_setup(filter_use_relaxation,likelihood_piecewise_kalman_filter);
|
||||
// use PKF
|
||||
estimation(
|
||||
datafile=dataobsfile2, mode_file=NKM_mh_mode_saved,
|
||||
mode_compute=0, nobs=120, first_obs=1,
|
||||
mh_replic=0, plot_priors=0, smoother,
|
||||
graph_format=(fig), nodisplay,consider_all_endogenous,heteroskedastic_filter);
|
||||
|
||||
oo0=oo_;
|
||||
// use inversion filter (note that IF provides smoother together with likelihood)
|
||||
occbin_setup(likelihood_inversion_filter,smoother_inversion_filter);
|
||||
|
||||
estimation(
|
||||
datafile=dataobsfile2, mode_file=NKM_mh_mode_saved,
|
||||
mode_compute=0, nobs=120, first_obs=1,
|
||||
mh_replic=0, plot_priors=0, smoother,
|
||||
graph_format=(fig), nodisplay, consider_all_endogenous,heteroskedastic_filter);
|
||||
|
||||
// show initial condition effect of IF
|
||||
figure,
|
||||
subplot(221)
|
||||
plot([oo0.SmoothedShocks.epsg oo_.SmoothedShocks.epsg]), title('epsg')
|
||||
subplot(222)
|
||||
plot([oo0.SmoothedShocks.epsi oo_.SmoothedShocks.epsi]), title('epsi')
|
||||
subplot(223)
|
||||
plot([oo0.SmoothedShocks.epss oo_.SmoothedShocks.epss]), title('epss')
|
||||
legend('PKF','IF')
|
|
@ -0,0 +1,345 @@
|
|||
//Tests Occbin estimation with IVF and PKF with 1 constraints and redundant shocks
|
||||
|
||||
// this file implements the model in:
|
||||
// Atkinson, T., A. W. Richter, and N. A. Throckmorton (2019).
|
||||
// The zero lower bound andestimation accuracy.Journal of Monetary Economics
|
||||
// original codes provided by Alexander Richter
|
||||
// adapted for dynare implementation
|
||||
// ------------------------- Settings -----------------------------------------//
|
||||
|
||||
@#ifndef small_model
|
||||
@#define small_model = 0
|
||||
@#endif
|
||||
|
||||
// if ~exist('run_ivf','var')
|
||||
run_ivf=0;
|
||||
// end
|
||||
|
||||
// ----------------- Defintions -----------------------------------------//
|
||||
var
|
||||
c //1 Consumption
|
||||
n //2 Labor
|
||||
y //5 Output
|
||||
yf //6 Final goods
|
||||
yg //11 Output growth gap
|
||||
w //12 Real wage rate
|
||||
wf //13 Flexible real wage
|
||||
pigap //15 Inflation rate -> pi(t)/pibar = pigap
|
||||
inom //16 Nominal interest rate
|
||||
inomnot //17 Notional interest rate
|
||||
mc //19 Real marginal cost
|
||||
lam //20 Inverse marginal utility of wealth
|
||||
g //21 Growth shock
|
||||
s //22 Risk premium shock
|
||||
mp //23 Monetary policy shock
|
||||
pi //24 Observed inflation
|
||||
@#if !(small_model)
|
||||
x //3 Investment
|
||||
k //4 Capital
|
||||
u //7 Utilization cost
|
||||
ups //8 Utilization choice
|
||||
wg //9 Real wage growth gap
|
||||
xg //10 Investment growth
|
||||
rk //14 Real rental rate
|
||||
q //18 Tobins q
|
||||
@#endif
|
||||
;
|
||||
varexo
|
||||
junk1
|
||||
epsg // Productivity growth shock
|
||||
epsi // Notional interest rate shock
|
||||
epss // Risk premium shock
|
||||
junk2
|
||||
;
|
||||
parameters
|
||||
// Calibrated Parameters
|
||||
beta // Discount factor
|
||||
chi // Labor disutility scale
|
||||
thetap // Elasticity of subs. between intermediate goods
|
||||
thetaw // Elasticity of subs. between labor types
|
||||
nbar // Steady state labor
|
||||
eta // Inverse frish elasticity of labor supply
|
||||
delta // Depreciation
|
||||
alpha // Capital share
|
||||
gbar // Mean growth rate
|
||||
pibar // Inflation target
|
||||
inombar // Steady gross nom interest rate
|
||||
inomlb // Effective lower bound on gross nominal interest rate
|
||||
sbar // Average risk premium
|
||||
// Parameters for DGP and Estimated parameters
|
||||
varphip // Rotemberg price adjustment cost
|
||||
varphiw // Rotemberg wage adjustment cost
|
||||
h // Habit persistence
|
||||
rhos // Persistence
|
||||
rhoi // Persistence
|
||||
sigz // Standard deviation technology
|
||||
sigs // Standard deviation risk premia
|
||||
sigi // Standard deviation mon pol
|
||||
phipi // Inflation responsiveness
|
||||
phiy // Output responsiveness
|
||||
nu // Investment adjustment cost
|
||||
sigups // Utilization
|
||||
|
||||
// Switching parameters
|
||||
zlb
|
||||
;
|
||||
|
||||
|
||||
// ---------------- Calibration -----------------------------------------//
|
||||
|
||||
beta = 0.9949; // Discount factor
|
||||
thetap = 6; // Elasticity of subs. between intermediate goods
|
||||
thetaw = 6; // Elasticity of subs. between labor types
|
||||
nbar = 1/3; // Steady state labor
|
||||
eta = 1/3; // Inverse frish elasticity of labor supply
|
||||
delta = 0.025; // Depreciation
|
||||
alpha = 0.35; // Capital share
|
||||
gbar = 1.0034; // Mean growth rate
|
||||
pibar = 1.0053; // Inflation target
|
||||
sbar = 1.0058; // Average risk premium
|
||||
rkbar = 1/beta;
|
||||
varphiw = 100; // Rotemberg wage adjustment cost
|
||||
nu = 4; // Investment adjustment cost
|
||||
sigups = 5; // Utilization
|
||||
varphip = 100; // Rotemberg price adjustment cost
|
||||
h = 0.80; // Habit persistence
|
||||
rhos = 0.80; // Persistence
|
||||
rhoi = 0.80; // Persistence
|
||||
sigz = 0.005; // Standard deviation
|
||||
sigs = 0.005; // Standard deviation
|
||||
sigi = 0.002; // Standard deviation
|
||||
phipi = 2.0; // Inflation responsiveness
|
||||
phiy = 0.5; // Output responsiveness
|
||||
zlb = 0 ; // ZLB dummy
|
||||
inomlb = 1 ; // Inom LB
|
||||
|
||||
// ---------------- Model -----------------------------------------------//
|
||||
model;
|
||||
|
||||
@#if !(small_model)
|
||||
[name = 'HH FOC utilization (1)']
|
||||
rk = steady_state(rk)*exp(sigups*(ups-1));
|
||||
|
||||
[name = 'Utilization definition (3)']
|
||||
u = steady_state(rk)*(exp(sigups*(ups-1))-1)/sigups;
|
||||
|
||||
[name = 'Firm FOC capital (4)']
|
||||
rk = mc*alpha*g*yf/(ups*k(-1));
|
||||
|
||||
[name = 'HH FOC capital (17)']
|
||||
q = beta*(lam/lam(+1))*(rk(+1)*ups(+1)-u(+1)+(1-delta)*q(+1))/g(+1);
|
||||
|
||||
[name = 'HH FOC investment (18)']
|
||||
1 = q*(1-nu*(xg-1)^2/2-nu*(xg-1)*xg)+beta*nu*gbar*q(+1)*(lam/lam(+1))*xg(+1)^2*(xg(+1)-1)/g(+1);
|
||||
|
||||
[name = 'Wage Phillips Curve (20)']
|
||||
varphiw*(wg-1)*wg = ((1-thetaw)*w+thetaw*wf)*n/yf + beta*varphiw*(lam/lam(+1))*(wg(+1)-1)*wg(+1)*(yf(+1)/yf) ;
|
||||
|
||||
[name = 'Real wage growth gap (6)']
|
||||
wg = pigap*g*w/(gbar*w(-1));
|
||||
|
||||
[name = 'Law of motion for capital (15)']
|
||||
k = (1-delta)*(k(-1)/g)+x*(1-nu*(xg-1)^2/2);
|
||||
|
||||
[name = 'Investment growth gap (14)']
|
||||
xg = g*x/(gbar*x(-1));
|
||||
@#endif
|
||||
|
||||
|
||||
@#if small_model
|
||||
[name = 'Production function (2)']
|
||||
yf = n;
|
||||
|
||||
[name = 'Firm FOC labor (5)']
|
||||
w = mc*yf/n;
|
||||
|
||||
[name = 'Output definition (7)']
|
||||
y = (1-varphip*(pigap-1)^2/2)*yf;
|
||||
|
||||
[name = 'ARC (13)']
|
||||
c = y;
|
||||
|
||||
[name = 'Household labpur supply equals flex wage']
|
||||
w = wf;
|
||||
@#else
|
||||
[name = 'Production function (2)']
|
||||
yf = (ups*k(-1)/g)^alpha*n^(1-alpha);
|
||||
|
||||
[name = 'Firm FOC labor (5)']
|
||||
w = (1-alpha)*mc*yf/n;
|
||||
|
||||
[name = 'Output definition (7)']
|
||||
y = (1-varphip*(pigap-1)^2/2-varphiw*(wg-1)^2/2)*yf - u*k(-1)/g;
|
||||
|
||||
[name = 'ARC (13)']
|
||||
x = y-c;
|
||||
@#endif
|
||||
|
||||
[name = 'Output growth gap (8)']
|
||||
yg = g*y/(gbar*y(-1)) + junk1 + junk2;
|
||||
|
||||
[name = 'Notional Interest Rate (9)']
|
||||
inomnot = inomnot(-1)^rhoi*(inombar*pigap^phipi*yg^phiy)^(1-rhoi)*exp(mp);
|
||||
|
||||
[name = 'Nominal Interest Rate (10)']
|
||||
inom = (inomnot*(1-zlb)+zlb*inomlb);
|
||||
|
||||
[name = 'Inverse MUC (11)']
|
||||
lam = c-h*c(-1)/g;
|
||||
|
||||
[name = 'Flexible real wage definition (12)']
|
||||
wf = chi*n^eta*lam;
|
||||
|
||||
[name = 'HH FOC bond (16)']
|
||||
1 = beta*(lam/lam(+1))*s*inom/(g(+1)*pibar*pigap(+1));
|
||||
|
||||
[name = 'Price Phillips Curve (19)']
|
||||
varphip*(pigap-1)*pigap = 1-thetap+thetap*mc+beta*varphip*(lam/lam(+1))*(pigap(+1)-1)*pigap(+1)*(yf(+1)/yf);
|
||||
|
||||
[name = 'Stochastic productivity growth (21)']
|
||||
g = gbar+ sigz*epsg;
|
||||
|
||||
[name = 'Risk premium shock (22)']
|
||||
s = (1-rhos)*sbar + rhos*s(-1)+sigs*epss ;
|
||||
|
||||
[name = 'Notional interest rate shock (23)']
|
||||
mp = sigi*epsi;
|
||||
|
||||
[name = 'Observed inflation (24)']
|
||||
pi = pigap*pibar;
|
||||
|
||||
end;
|
||||
|
||||
occbin_constraints;
|
||||
name 'zlb'; bind inom+inombar <= inomlb; relax inom+inombar > inomlb;
|
||||
end;
|
||||
|
||||
// ---------------- Steady state -----------------------------------------//
|
||||
steady_state_model;
|
||||
mp = 0;
|
||||
xg = 1;
|
||||
s = sbar;
|
||||
n = nbar;
|
||||
ups =1;
|
||||
u =0;
|
||||
q =1;
|
||||
g = gbar;
|
||||
yg = 1;
|
||||
pigap = 1;
|
||||
wg =1;
|
||||
pi = pigap*pibar;
|
||||
// FOC bond
|
||||
inom = gbar*pibar/(beta*s);
|
||||
inomnot = inom;
|
||||
inombar = inom;
|
||||
// Firm pricing
|
||||
mc = (thetap-1)/thetap;
|
||||
// FOC capital
|
||||
rk = gbar/beta+delta-1;
|
||||
// Marginal cost definition
|
||||
@#if small_model
|
||||
alpha = 0;
|
||||
thetaw=1;
|
||||
@#endif
|
||||
w = (mc*(1-alpha)^(1-alpha)*alpha^alpha/rk^alpha)^(1/(1-alpha));
|
||||
@#if small_model
|
||||
wf = w;
|
||||
@#else
|
||||
wf = (thetaw-1)*w/thetaw;
|
||||
@#endif
|
||||
// Consolidated FOC firm
|
||||
k = w*n*gbar*alpha/(rk*(1-alpha));
|
||||
// Law of motion for capital
|
||||
x = (1-(1-delta)/gbar)*k;
|
||||
// Production function
|
||||
yf = (k/gbar)^alpha*n^(1-alpha);
|
||||
// Real GDP
|
||||
y = yf;
|
||||
// Aggregate resouce constraint
|
||||
c = y-x;
|
||||
// FOC labor
|
||||
lam = (1-h/gbar)*c;
|
||||
chi = wf/(n^eta*lam);
|
||||
|
||||
// try log observables
|
||||
end;
|
||||
|
||||
// ---------------- Checks -----------------------------------------//
|
||||
steady;
|
||||
check;
|
||||
|
||||
// ---------------- Simulation -----------------------------------------//
|
||||
shocks;
|
||||
var epsi = 1;
|
||||
var epss = 1;
|
||||
var epsg = 1;
|
||||
end;
|
||||
|
||||
steady;
|
||||
check;
|
||||
|
||||
// ---------------- Estimation -----------------------------------------//
|
||||
|
||||
varobs yg inom pi;
|
||||
estimated_params;
|
||||
// PARAM NAME, INITVAL, LB, UB, PRIOR_SHAPE, PRIOR_P1, PRIOR_P2, PRIOR_P3, PRIOR_P4, JSCALE
|
||||
// PRIOR_SHAPE: BETA_PDF, GAMMA_PDF, NORMAL_PDF, INV_GAMMA_PDF
|
||||
varphip,,0,inf,NORMAL_PDF,100,25;
|
||||
phipi,,,,NORMAL_PDF,2,0.25;
|
||||
phiy,,0,inf,NORMAL_PDF,0.5,0.25;
|
||||
h,,,,BETA_PDF,0.8,0.1;
|
||||
rhos,,,,BETA_PDF,0.8,0.1;
|
||||
rhoi,,,,BETA_PDF,0.8,0.1;
|
||||
sigz,,,,INV_GAMMA_PDF,0.005,0.005;
|
||||
sigs,,,,INV_GAMMA_PDF,0.005,0.005;
|
||||
sigi,,,,INV_GAMMA_PDF,0.002,0.002;
|
||||
end;
|
||||
|
||||
|
||||
// dataloading_jme_beta(1,'sims.txt',30);
|
||||
load('dataobsfile','inom')
|
||||
// check if inom is at lb and remove data + associated shock
|
||||
verbatim;
|
||||
inom(inom==1)=NaN;
|
||||
end;
|
||||
inx = strmatch('epsi',M_.exo_names);
|
||||
if any(isnan(inom))
|
||||
M_.heteroskedastic_shocks.Qscale_orig.periods=find(isnan(inom));
|
||||
M_.heteroskedastic_shocks.Qscale_orig.exo_id=inx;
|
||||
M_.heteroskedastic_shocks.Qscale_orig.scale=0;
|
||||
else
|
||||
options_.heteroskedastic_filter=false;
|
||||
end
|
||||
|
||||
copyfile dataobsfile.mat dataobsfile2.mat
|
||||
save dataobsfile2 inom -append
|
||||
// -----------------Occbin ----------------------------------------------//
|
||||
options_.occbin.filter.use_relaxation=true;
|
||||
// use PKF
|
||||
estimation(
|
||||
datafile=dataobsfile2, mode_file=NKM_mh_mode_saved,
|
||||
mode_compute=0, nobs=120, first_obs=1,
|
||||
mh_replic=0, plot_priors=0, smoother,
|
||||
graph_format=(fig), nodisplay,consider_all_endogenous,heteroskedastic_filter);
|
||||
|
||||
oo0=oo_;
|
||||
|
||||
// use inversion filter (note that IF provides smoother together with likelihood)
|
||||
options_.occbin.likelihood.inversion_filter = 1;
|
||||
options_.occbin.smoother.inversion_filter = 1;
|
||||
|
||||
estimation(
|
||||
datafile=dataobsfile2, mode_file=NKM_mh_mode_saved,
|
||||
mode_compute=0, nobs=120, first_obs=1,
|
||||
mh_replic=0, plot_priors=0, smoother,
|
||||
graph_format=(fig), nodisplay, consider_all_endogenous,heteroskedastic_filter);
|
||||
|
||||
// show initial condition effect of IF
|
||||
figure,
|
||||
subplot(221)
|
||||
plot([oo0.SmoothedShocks.epsg oo_.SmoothedShocks.epsg]), title('epsg')
|
||||
subplot(222)
|
||||
plot([oo0.SmoothedShocks.epsi oo_.SmoothedShocks.epsi]), title('epsi')
|
||||
subplot(223)
|
||||
plot([oo0.SmoothedShocks.epss oo_.SmoothedShocks.epss]), title('epss')
|
||||
legend('PKF','IF')
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,53 @@
|
|||
// --+ options: nostrict +--
|
||||
//Test Occbin with 1 constraint and redundant shocks; also checks whether defaults for error_* are correct
|
||||
|
||||
var b ${b}$ (long_name='borrowing')
|
||||
c ${c}$ (long_name='vonsumption')
|
||||
ec ${E(c_t)}$ (long_name='expected consumption')
|
||||
lb ${\lambda}$ (long_name='Lagrange multiplier')
|
||||
y ${y}$ (long_name='Output')
|
||||
c_hat ${\hat c}$
|
||||
b_hat ${\hat c}$
|
||||
y_hat ${\hat y}$
|
||||
;
|
||||
varexo u $u$;
|
||||
|
||||
parameters RHO ${\rho}$, BETA ${\beta}$, M $M$, R $R$, SIGMA ${\sigma}$, GAMMAC $\gamma_c$, relax_borrcon ;
|
||||
|
||||
model;
|
||||
ec = c(1);
|
||||
c = y + b - R*b(-1) ;
|
||||
(1-relax_borrcon)*(b - M*y) + relax_borrcon*lb = 0;
|
||||
lb = 1/c^GAMMAC - BETA*R/c(+1)^GAMMAC ;
|
||||
log(y) = RHO*log(y(-1)) + u ;
|
||||
c_hat = log(c) - log(steady_state(c));
|
||||
b_hat = log(b) - log(steady_state(b));
|
||||
y_hat = log(y) - log(steady_state(y));
|
||||
end;
|
||||
|
||||
occbin_constraints;
|
||||
% name 'relax_borrcon'; bind lb<-lb_ss; relax b>M*y; error_bind abs(lb+lb_ss); error_relax abs(b-M*y);
|
||||
name 'relax_borrcon'; bind lb<-lb_ss; relax b>M*y;
|
||||
end;
|
||||
|
||||
steady_state_model;
|
||||
b=M;
|
||||
c=1+M-R*M;
|
||||
ec=c;
|
||||
lb=(1-BETA*R)/c^GAMMAC;
|
||||
y=1;
|
||||
end;
|
||||
|
||||
R = 1.05;
|
||||
BETA = 0.945;
|
||||
RHO = 0.9;
|
||||
SIGMA = 0.05;
|
||||
M = 1;
|
||||
GAMMAC = 1;
|
||||
relax_borrcon = 0;
|
||||
|
||||
shocks;
|
||||
var u; stderr SIGMA;
|
||||
end;
|
||||
|
||||
@#include "borrcon_common.inc"
|
|
@ -0,0 +1,58 @@
|
|||
// --+ options: nostrict +--
|
||||
//Test Occbin with 1 constraint and redundant shocks; also checks whether defaults for error_* are correct
|
||||
|
||||
var b ${b}$ (long_name='borrowing')
|
||||
c ${c}$ (long_name='vonsumption')
|
||||
ec ${E(c_t)}$ (long_name='expected consumption')
|
||||
lb ${\lambda}$ (long_name='Lagrange multiplier')
|
||||
y ${y}$ (long_name='Output')
|
||||
c_hat ${\hat c}$
|
||||
b_hat ${\hat c}$
|
||||
y_hat ${\hat y}$
|
||||
;
|
||||
|
||||
varexo junk1 u junk2 ;
|
||||
|
||||
parameters RHO ${\rho}$, BETA ${\beta}$, M $M$, R $R$, SIGMA ${\sigma}$, GAMMAC $\gamma_c$, relax_borrcon ;
|
||||
|
||||
model;
|
||||
ec = c(1);
|
||||
c = y + b - R*b(-1) ;
|
||||
(1-relax_borrcon)*(b - M*y) + relax_borrcon*lb = 0;
|
||||
lb = 1/c^GAMMAC - BETA*R/c(+1)^GAMMAC +junk1 + junk2;
|
||||
log(y) = RHO*log(y(-1)) + u ;
|
||||
c_hat = log(c) - log(steady_state(c));
|
||||
b_hat = log(b) - log(steady_state(b));
|
||||
y_hat = log(y) - log(steady_state(y));
|
||||
end;
|
||||
|
||||
occbin_constraints;
|
||||
name 'relax_borrcon'; bind lb<-lb_ss; relax b>M*y; error_bind abs(lb+lb_ss); error_relax abs(b-M*y);
|
||||
end;
|
||||
|
||||
steady_state_model;
|
||||
b=M;
|
||||
c=1+M-R*M;
|
||||
ec=c;
|
||||
lb=(1-BETA*R)/c^GAMMAC;
|
||||
y=1;
|
||||
end;
|
||||
|
||||
R = 1.05;
|
||||
BETA = 0.945;
|
||||
RHO = 0.9;
|
||||
SIGMA = 0.05;
|
||||
M = 1;
|
||||
GAMMAC = 1;
|
||||
relax_borrcon = 0;
|
||||
|
||||
shocks;
|
||||
var u; stderr SIGMA;
|
||||
end;
|
||||
|
||||
@#include "borrcon_common.inc"
|
||||
|
||||
orig_results=load('borrcon_results.mat');
|
||||
if max(max(abs(oo_.occbin.piecewise-orig_results.oo_.occbin.piecewise)))>1e-10
|
||||
error('Results do not match')
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
steady;
|
||||
check;
|
||||
|
||||
shocks(surprise,overwrite);
|
||||
var u;
|
||||
periods 10, 30;
|
||||
values 0.03, -0.03;
|
||||
end;
|
||||
|
||||
occbin_setup(simul_periods=80);
|
||||
occbin_solver(simul_maxit=11,simul_curb_retrench);
|
||||
%
|
||||
titlelist = char('c (consumption)','b (borrowing)','y (income)','lb (multiplier)');
|
||||
percent = 'Percent';
|
||||
level = 'Level';
|
||||
ylabels = char(percent,percent,percent,level);
|
||||
figtitle = 'Simulated variables';
|
||||
legendlist = cellstr(char('Piecewise Linear','Linear'));
|
||||
|
||||
options_.TeX=1;
|
||||
occbin_graph;
|
||||
occbin_graph c_hat b_hat y_hat;
|
||||
|
||||
write_latex_original_model(write_equation_tags);
|
||||
//collect_latex_files;
|
||||
|
||||
oo_= occbin.unpack_simulations(M_,oo_,options_);
|
||||
|
||||
line1=100*[(oo_.occbin.endo_piecewise.c-oo_.occbin.endo_ss.c)/oo_.occbin.endo_ss.c, ...
|
||||
(oo_.occbin.endo_piecewise.b-oo_.occbin.endo_ss.b)/oo_.occbin.endo_ss.b, ...
|
||||
(oo_.occbin.endo_piecewise.y-oo_.occbin.endo_ss.y)/oo_.occbin.endo_ss.y, ...
|
||||
oo_.occbin.endo_piecewise.lb/100];
|
||||
line2=100*[(oo_.occbin.endo_linear.c-oo_.occbin.endo_ss.c)/oo_.occbin.endo_ss.c, ...
|
||||
(oo_.occbin.endo_linear.b-oo_.occbin.endo_ss.b)/oo_.occbin.endo_ss.b, ...
|
||||
(oo_.occbin.endo_linear.y-oo_.occbin.endo_ss.y)/oo_.occbin.endo_ss.y, ...
|
||||
oo_.occbin.endo_linear.lb/100];
|
||||
|
||||
occbin.make_chart(titlelist,legendlist,figtitle,ylabels,cat(3,line1,line2));
|
|
@ -0,0 +1,47 @@
|
|||
//Tests Occbin with 2 constraints
|
||||
|
||||
// variables
|
||||
var a, c, i, k, lambdak;
|
||||
|
||||
// innovations to shock processes
|
||||
varexo erra;
|
||||
|
||||
|
||||
// parameters
|
||||
parameters ALPHA, DELTAK, BETA, GAMMAC, RHOA, PHI, PSI, PSINEG, INEG, IRR;
|
||||
|
||||
model;
|
||||
|
||||
# zkss = ((1/BETA-1+DELTAK)/ALPHA)^(1/(ALPHA-1));
|
||||
# zcss = -DELTAK*zkss + zkss^ALPHA;
|
||||
# ziss = DELTAK*zkss;
|
||||
# zuss = (zcss^(1-GAMMAC)-1)/(1-GAMMAC);
|
||||
# zvss = zuss/(1-BETA);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 1.
|
||||
-exp(c)^(-GAMMAC)*(1+2*INEG*PSI*(exp(k)/exp(k(-1))-1)/exp(k(-1)))
|
||||
+ BETA*exp(c(1))^(-GAMMAC)*((1-DELTAK)-2*INEG*PSI*(exp(k(1))/exp(k)-1)*
|
||||
(-exp(k(1))/exp(k)^2)+ALPHA*exp(a(1))*exp(k)^(ALPHA-1))=
|
||||
-lambdak+BETA*(1-DELTAK)*lambdak(1);
|
||||
|
||||
// 2.
|
||||
exp(c)+exp(k)-(1-DELTAK)*exp(k(-1))+
|
||||
INEG*PSI*(exp(k)/exp(k(-1))-1)^2=exp(a)*exp(k(-1))^(ALPHA);
|
||||
|
||||
// 3.
|
||||
exp(i) = exp(k)-(1-DELTAK)*exp(k(-1));
|
||||
|
||||
// 4.
|
||||
lambdak*(1-IRR) + IRR*(i - log(PHI*ziss)) = 0;
|
||||
|
||||
// 5.
|
||||
a = RHOA*a(-1)+erra;
|
||||
end;
|
||||
|
||||
occbin_constraints;
|
||||
name 'IRR'; bind i<PHI-1; relax lambdak<0;
|
||||
name 'INEG'; bind i<-0.000001;
|
||||
end;
|
||||
|
||||
@#include "dynrbc_common.inc"
|
|
@ -0,0 +1,64 @@
|
|||
//Tests Occbin with 2 constraints and redundant shocks
|
||||
|
||||
// variables
|
||||
var a, c, i, k, lambdak;
|
||||
|
||||
// innovations to shock processes
|
||||
varexo junk1 erra junk2;
|
||||
|
||||
|
||||
// parameters
|
||||
parameters ALPHA, DELTAK, BETA, GAMMAC, RHOA, PHI, PSI, PSINEG, INEG, IRR;
|
||||
|
||||
model;
|
||||
|
||||
# zkss = ((1/BETA-1+DELTAK)/ALPHA)^(1/(ALPHA-1));
|
||||
# zcss = -DELTAK*zkss + zkss^ALPHA;
|
||||
# ziss = DELTAK*zkss;
|
||||
# zuss = (zcss^(1-GAMMAC)-1)/(1-GAMMAC);
|
||||
# zvss = zuss/(1-BETA);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 1.
|
||||
-exp(c)^(-GAMMAC)*(1+2*INEG*PSI*(exp(k)/exp(k(-1))-1)/exp(k(-1)))
|
||||
+ BETA*exp(c(1))^(-GAMMAC)*((1-DELTAK)-2*INEG*PSI*(exp(k(1))/exp(k)-1)*
|
||||
(-exp(k(1))/exp(k)^2)+ALPHA*exp(a(1))*exp(k)^(ALPHA-1))=
|
||||
-lambdak+BETA*(1-DELTAK)*lambdak(1);
|
||||
|
||||
// 2.
|
||||
exp(c)+exp(k)-(1-DELTAK)*exp(k(-1))+
|
||||
INEG*PSI*(exp(k)/exp(k(-1))-1)^2=exp(a)*exp(k(-1))^(ALPHA) + junk1 + junk2;
|
||||
|
||||
// 3.
|
||||
exp(i) = exp(k)-(1-DELTAK)*exp(k(-1));
|
||||
|
||||
// 4.
|
||||
lambdak*(1-IRR) + IRR*(i - log(PHI*ziss)) = 0;
|
||||
|
||||
// 5.
|
||||
a = RHOA*a(-1)+erra;
|
||||
end;
|
||||
|
||||
occbin_constraints;
|
||||
name 'IRR'; bind i<PHI-1; relax lambdak<0; error_bind abs(i-(PHI-1)); error_relax abs(lambdak-0);
|
||||
name 'INEG'; bind i<-0.000001; relax i>-0.000001; error_bind abs(i-0.000001); error_relax abs(i-0.000001);
|
||||
end;
|
||||
|
||||
@#include "dynrbc_common.inc"
|
||||
|
||||
orig_results=load('dynrbc_results.mat');
|
||||
if max(max(abs(oo_.occbin.piecewise-orig_results.oo_.occbin.piecewise)))>1e-10
|
||||
error('Results do not match')
|
||||
end
|
||||
|
||||
if max(max(abs(oo_.SmoothedShocks.erra-orig_results.oo_.SmoothedShocks.erra)))>1e-10
|
||||
error('SmoothedShocks do not match')
|
||||
end
|
||||
|
||||
if max(max(abs(struct2array(oo_.SmoothedVariables)-struct2array(orig_results.oo_.SmoothedVariables))))>1e-10
|
||||
error('SmoothedShocks do not match')
|
||||
end
|
||||
|
||||
if max(max(abs(oo_.Smoother.SteadyState-orig_results.oo_.Smoother.SteadyState)))>1e-10
|
||||
error('SmoothedShocks do not match')
|
||||
end
|
|
@ -0,0 +1,116 @@
|
|||
steady_state_model;
|
||||
kss = ((1/BETA-1+DELTAK)/ALPHA)^(1/(ALPHA-1));
|
||||
css = -DELTAK*kss +kss^ALPHA;
|
||||
iss = DELTAK*kss;
|
||||
|
||||
|
||||
k = log(kss);
|
||||
c = log(css);
|
||||
i = log(iss);
|
||||
lambdak = 0;
|
||||
a=0;
|
||||
end;
|
||||
|
||||
BETA=0.96;
|
||||
ALPHA=0.33;
|
||||
DELTAK=0.10;
|
||||
GAMMAC=2;
|
||||
RHOA = 0.9;
|
||||
PHI = 0.975;
|
||||
PSI = 5; % adjustment cost for capital if investment is negative
|
||||
INEG = 0;
|
||||
IRR = 0;
|
||||
|
||||
shocks;
|
||||
var erra; stderr 0.015;
|
||||
end;
|
||||
|
||||
steady;
|
||||
|
||||
// run occbin simulations
|
||||
% Option=1: impulse responses
|
||||
% Option=2: random simulation
|
||||
|
||||
@#for option_val in [1, 2]
|
||||
|
||||
option=@{option_val};
|
||||
|
||||
%%%%%%%%%%%%%%%% Inputs stop here %%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
if option==1
|
||||
shocks(surprise,overwrite);
|
||||
var erra;
|
||||
periods 1:9, 10, 50, 90, 130, 131:169;
|
||||
values -0.0001, -0.01,-0.02, 0.01, 0.02, 0;
|
||||
end;
|
||||
|
||||
|
||||
elseif option==2
|
||||
nperiods = 100;
|
||||
randn('seed',1);
|
||||
shockssequence = 1*randn(nperiods,1)*0.02 ;
|
||||
|
||||
shocks(surprise,overwrite);
|
||||
var erra;
|
||||
periods 1:100;
|
||||
values (shockssequence);
|
||||
end;
|
||||
|
||||
end
|
||||
|
||||
% set inputs
|
||||
|
||||
occbin_setup;
|
||||
options_.occbin.smoother.debug=1;
|
||||
occbin_solver(simul_periods=200,simul_maxit=200,simul_curb_retrench,simul_check_ahead_periods=200);
|
||||
occbin_write_regimes(filename='test',periods=[1:100]);
|
||||
|
||||
%% Modify to plot IRFs
|
||||
titlelist = char('c','lambdak','k','i','a');
|
||||
percent = 'Percent';
|
||||
value = 'value';
|
||||
ylabels = char(percent,value,percent,percent,percent);
|
||||
figtitle = 'Simulated variables';
|
||||
legendlist = cellstr(char('Piecewise Linear','Linear'));
|
||||
|
||||
oo_= occbin.unpack_simulations(M_,oo_,options_);
|
||||
|
||||
line1=100*[oo_.occbin.endo_piecewise.c-oo_.occbin.endo_ss.c,oo_.occbin.endo_piecewise.lambdak/100,oo_.occbin.endo_piecewise.k-oo_.occbin.endo_ss.k,oo_.occbin.endo_piecewise.i-oo_.occbin.endo_ss.i,oo_.occbin.endo_piecewise.a-oo_.occbin.endo_ss.a];
|
||||
line2=100*[oo_.occbin.endo_linear.c-oo_.occbin.endo_ss.c,oo_.occbin.endo_linear.lambdak/100,oo_.occbin.endo_linear.k-oo_.occbin.endo_ss.k,oo_.occbin.endo_linear.i-oo_.occbin.endo_ss.i,oo_.occbin.endo_linear.a-oo_.occbin.endo_ss.a];
|
||||
|
||||
occbin.make_chart(titlelist,legendlist,figtitle,ylabels,cat(3,line1,line2));
|
||||
|
||||
occbin_graph(noconstant) c erra lambdak k i a k;
|
||||
|
||||
@#if option_val==1
|
||||
verbatim;
|
||||
c=oo_.occbin.endo_piecewise.c;
|
||||
end;
|
||||
save('datasim','c');
|
||||
varobs c;
|
||||
|
||||
occbin_solver(simul_periods=200,simul_maxit=200,simul_curb_retrench,simul_check_ahead_periods=200);
|
||||
occbin_setup(smoother_periods=200,smoother_maxit=200,smoother_curb_retrench,smoother_check_ahead_periods=200);
|
||||
calib_smoother(datafile=datasim);
|
||||
oo_= occbin.unpack_simulations(M_,oo_,options_);
|
||||
|
||||
titlelist = char('c','lambdak','k','i','a','erra');
|
||||
percent = 'Percent';
|
||||
value = 'value';
|
||||
ylabels = char(percent,value,percent,percent,percent, value);
|
||||
figtitle = 'Smoothed variables (piecewise)';
|
||||
legendlist = cellstr(char('Simulated','Piecewise smoother'));
|
||||
|
||||
shock_vector=[oo_.occbin.shocks_sequence./100; zeros(length(oo_.occbin.endo_piecewise.c)-size(oo_.occbin.shocks_sequence,1),size(oo_.occbin.shocks_sequence,2))];
|
||||
line1=100*[oo_.occbin.endo_piecewise.c-oo_.occbin.endo_ss.c,oo_.occbin.endo_piecewise.lambdak/100,oo_.occbin.endo_piecewise.k-oo_.occbin.endo_ss.k,oo_.occbin.endo_piecewise.i-oo_.occbin.endo_ss.i,oo_.occbin.endo_piecewise.a-oo_.occbin.endo_ss.a, shock_vector];
|
||||
line2=100*[oo_.occbin.smoother.SmoothedVariables.c-oo_.occbin.endo_ss.c,oo_.occbin.smoother.SmoothedVariables.lambdak/100,oo_.occbin.smoother.SmoothedVariables.k-oo_.occbin.endo_ss.k,oo_.occbin.smoother.SmoothedVariables.i-oo_.occbin.endo_ss.i,oo_.occbin.smoother.SmoothedVariables.a-oo_.occbin.endo_ss.a, oo_.occbin.smoother.SmoothedShocks.erra/100];
|
||||
occbin.make_chart(titlelist,legendlist,figtitle,ylabels,cat(3,line1,line2));
|
||||
|
||||
figtitle = 'Smoothed variables (linear)';
|
||||
legendlist = cellstr(char('Simulated','Linear smoother'));
|
||||
|
||||
line1=100*[oo_.occbin.endo_piecewise.c-oo_.occbin.endo_ss.c,oo_.occbin.endo_piecewise.lambdak/100,oo_.occbin.endo_piecewise.k-oo_.occbin.endo_ss.k,oo_.occbin.endo_piecewise.i-oo_.occbin.endo_ss.i,oo_.occbin.endo_piecewise.a-oo_.occbin.endo_ss.a, shock_vector];
|
||||
line2=100*[oo_.occbin.linear_smoother.SmoothedVariables.c-oo_.occbin.endo_ss.c,oo_.occbin.linear_smoother.SmoothedVariables.lambdak/100,oo_.occbin.linear_smoother.SmoothedVariables.k-oo_.occbin.endo_ss.k,oo_.occbin.linear_smoother.SmoothedVariables.i-oo_.occbin.endo_ss.i,oo_.occbin.linear_smoother.SmoothedVariables.a-oo_.occbin.endo_ss.a, oo_.occbin.linear_smoother.SmoothedShocks.erra/100];
|
||||
occbin.make_chart(titlelist,legendlist,figtitle,ylabels,cat(3,line1,line2));
|
||||
@#endif
|
||||
@#endfor
|
|
@ -0,0 +1,80 @@
|
|||
% check for correct error message if token cannot be interpreted
|
||||
// variables
|
||||
var a, c, i, k, lambdak;
|
||||
|
||||
// innovations to shock processes
|
||||
varexo erra;
|
||||
|
||||
|
||||
// parameters
|
||||
parameters ALPHA, DELTAK, BETA, GAMMAC, RHOA, PHI, PSI, PSINEG, INEG, IRR;
|
||||
|
||||
model(occbin);
|
||||
|
||||
# zkss = ((1/BETA-1+DELTAK)/ALPHA)^(1/(ALPHA-1));
|
||||
# zcss = -DELTAK*zkss + zkss^ALPHA;
|
||||
# ziss = DELTAK*zkss;
|
||||
# zuss = (zcss^(1-GAMMAC)-1)/(1-GAMMAC);
|
||||
# zvss = zuss/(1-BETA);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 1.
|
||||
-exp(c)^(-GAMMAC)*(1+2*INEG*PSI*(exp(k)/exp(k(-1))-1)/exp(k(-1)))
|
||||
+ BETA*exp(c(1))^(-GAMMAC)*((1-DELTAK)-2*INEG*PSI*(exp(k(1))/exp(k)-1)*
|
||||
(-exp(k(1))/exp(k)^2)+ALPHA*exp(a(1))*exp(k)^(ALPHA-1))=
|
||||
-lambdak+BETA*(1-DELTAK)*lambdak(1);
|
||||
|
||||
// 2.
|
||||
exp(c)+exp(k)-(1-DELTAK)*exp(k(-1))+
|
||||
INEG*PSI*(exp(k)/exp(k(-1))-1)^2=exp(a)*exp(k(-1))^(ALPHA);
|
||||
|
||||
// 3.
|
||||
[pswitch = 'INEG',
|
||||
// bind = 'exp(i+i_ss)<-0.000001',
|
||||
// relax = 'exp(i+i_ss)>-0.000001' ]
|
||||
bind = 'i<-b',
|
||||
relax = 'i>-0.000001' ]
|
||||
exp(i) = exp(k)-(1-DELTAK)*exp(k(-1));
|
||||
|
||||
// 4.
|
||||
[pswitch = 'IRR',
|
||||
bind = 'i<PHI-1',
|
||||
relax = 'lambdak<0' ]
|
||||
lambdak*(1-IRR) + IRR*(i - log(PHI*ziss)) = 0;
|
||||
|
||||
// 5.
|
||||
a = RHOA*a(-1)+erra;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
steady_state_model;
|
||||
kss = ((1/BETA-1+DELTAK)/ALPHA)^(1/(ALPHA-1));
|
||||
css = -DELTAK*kss +kss^ALPHA;
|
||||
iss = DELTAK*kss;
|
||||
|
||||
|
||||
k = log(kss);
|
||||
c = log(css);
|
||||
i = log(iss);
|
||||
lambdak = 0;
|
||||
a=0;
|
||||
end;
|
||||
|
||||
BETA=0.96;
|
||||
ALPHA=0.33;
|
||||
DELTAK=0.10;
|
||||
GAMMAC=2;
|
||||
RHOA = 0.9;
|
||||
PHI = 0.975;
|
||||
PSI = 5; % adjustment cost for capital if investment is negative
|
||||
INEG = 0;
|
||||
IRR = 0;
|
||||
|
||||
shocks;
|
||||
var erra; stderr 0.015;
|
||||
end;
|
||||
|
||||
steady;
|
||||
|
||||
stoch_simul(order=1,nocorr,nomoments,irf=0,noprint);
|
Loading…
Reference in New Issue