Commit 11e15154 authored by Ferhat Mihoubi's avatar Ferhat Mihoubi
Browse files

Adds conditional forecast using the extended path method

parent a4681b50
......@@ -2123,6 +2123,11 @@ values (xx);
end;
@end example
In case of conditional forecasts using an extended path method,
the shock command is extended in order to determine the nature of the expectation
on the endogenous variable paths. The command @code{expectation} has, in this case,
to be added after the @code{values} command (@pxref{Forecasting}).
@customhead{In stochastic context}
For stochastic simulations, the @code{shocks} block specifies the non
......@@ -4782,6 +4787,13 @@ DSGE model, by finding the structural shocks that are needed to match
the restricted paths. Use @code{conditional_forecast},
@code{conditional_forecast_paths} and @code{plot_conditional_forecast}
for that purpose.
If the model contains strong non-linearities, the conditional forecasts
can be computed using an extended path method with the @code{simulation}
option in @code{conditional_forecast} command set to @code{deterministic}.
Because in this case deterministic simulations are carried out,
the nature of the shocks (surprise or perfect foresight) has to be indicated
in the @code{conditional_forecast_paths} block, using the command @code{expectation}
for each endogenous path. The forecasts are plotted using the rplot command.
Finally, it is possible to do forecasting with a Bayesian VAR using
the @code{bvar_forecast} command.
......@@ -4941,7 +4953,10 @@ structural shocks that are needed to match the restricted paths. This
command has to be called after estimation.
Use @code{conditional_forecast_paths} block to give the list of
constrained endogenous, and their constrained future path. Option
constrained endogenous, and their constrained future path.
If an extended path method is applied on the original dsge model,
the nature of the expectation on the constrained endogenous has to be
specified using expectation command. Option
@code{controlled_varexo} is used to specify the structural shocks
which will be matched to generate the constrained path.
......@@ -4968,6 +4983,15 @@ Number of simulations. Default: @code{5000}.
@item conf_sig = @var{DOUBLE}
Level of significance for confidence interval. Default: @code{0.80}
@item simulation_type = @code{stochastic} | @code{deterministic}
Indicates the nature of simulations used to compute the conditional forecast.
The default value @code{stochastic} is used, when simulations are computed
using the reduced form representation of the DSGE model.
If the model has to be simulated using extended path method on the original
DSGE model, @code{simulation_type} has to be set equal to @code{deterministic}.
@end table
@examplehead
......@@ -4994,6 +5018,32 @@ conditional_forecast(parameter_set = calibration, controlled_varexo = (e, u), re
plot_conditional_forecast(periods = 10) a y;
@end example
@examplehead
@example
/* conditional forecast using extended path method
with perfect foresight on r path*/
var y r
varexo e u;
@dots{}
conditional_forecast_paths;
var y;
periods 1:3, 4:5;
values 2, 5;
var r
periods 1:5;
values 3;
expectation perfect_forsight;
end;
conditional_forecast(parameter_set = calibration, controlled_varexo = (e, u), simulation_type=deterministic);
rplot a;
rplot y;
@end example
@end deffn
@deffn Block conditional_forecast_paths ;
......@@ -5006,6 +5056,11 @@ example.
The syntax of the block is the same than the deterministic shocks in
the @code{shocks} blocks (@pxref{Shocks on exogenous variables}).
If the conditional forecast is carried out using the extended path method
on the original DSGE model, the nature of the expectation have to be specified
for each endogenous path, using the @code{expectation} = @code{surprise} | @code{perfect_foresight}.
By default, @code{expectation} is equal to @code{surprise}.
@end deffn
@deffn Command plot_conditional_forecast [@var{VARIABLE_NAME}@dots{}];
......
function det_cond_forecast(constrained_paths, constrained_vars, options_cond_fcst, constrained_perfect_foresight)
% Computes conditional forecasts for a deterministic model.
%
% INPUTS
% o constrained_paths [double] m*p array, where m is the number of constrained endogenous variables and p is the number of constrained periods.
% o constrained_vars [char] m*x array holding the names of the controlled endogenous variables.
% o options_cond_fcst [structure] containing the options. The fields are:
% + replic [integer] scalar, number of monte carlo simulations.
% + parameter_set [char] values of the estimated parameters:
% "posterior_mode",
% "posterior_mean",
% "posterior_median",
% "prior_mode" or
% "prior mean".
% [double] np*1 array, values of the estimated parameters.
% + controlled_varexo [char] m*x array, list of controlled exogenous variables.
% + conf_sig [double] scalar in [0,1], probability mass covered by the confidence bands.
% o constrained_perfect_foresight [double] m*1 array indicating if the endogenous variables path is perfectly foresight (1) or is a surprise (0)
%
%
% OUTPUTS
% None.
%
% SPECIAL REQUIREMENTS
% This routine has to be called after an estimation statement or an estimated_params block.
%
% REMARKS
% [1] Results are stored in a structure which is saved in a mat file called conditional_forecasts.mat.
% [2] Use the function plot_icforecast to plot the results.
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
global options_ oo_ M_
if ~isfield(options_cond_fcst,'periods') || isempty(options_cond_fcst.periods)
options_cond_fcst.periods = 60;
end
maximum_lag = M_.maximum_lag;
maximum_lead = M_.maximum_lead;
ys = oo_.steady_state;
ny = size(ys,1);
xs = [oo_.exo_steady_state ; oo_.exo_det_steady_state];
nx = size(xs,1);
constrained_periods = size(constrained_paths,2);
n_endo_constrained = size(constrained_vars,1);
if isfield(options_cond_fcst,'controlled_varexo')
n_control_exo = size(options_cond_fcst.controlled_varexo, 1);
if n_control_exo ~= n_endo_constrained
error(['det_cond_forecast:: the number of exogenous controlled variables (' int2str(n_control_exo) ') has to be equal to the number of constrained endogenous variabes (' int2str(n_endo_constrained) ')'])
end;
else
error('det_cond_forecast:: to run a deterministic conditional forecast you have to specified the exogenous variables controlled using the option controlled_varex in forecast command');
end;
exo_names = M_.exo_names;
controlled_varexo = zeros(1,n_control_exo);
for i = 1:nx
for j=1:n_control_exo
if strcmp(exo_names(i,:), options_cond_fcst.controlled_varexo(j,:))
controlled_varexo(j) = i;
end
end
end
save_options_initval_file = options_.initval_file;
options_.initval_file = '__';
[pos_constrained_pf, junk] = find(constrained_perfect_foresight);
indx_endo_solve_pf = constrained_vars(pos_constrained_pf);
if isempty(indx_endo_solve_pf)
pf = 0;
else
pf = length(indx_endo_solve_pf);
end;
indx_endo_solve_surprise = setdiff(constrained_vars, indx_endo_solve_pf);
if isempty(indx_endo_solve_surprise)
surprise = 0;
else
surprise = length(indx_endo_solve_surprise);
end;
eps = options_.solve_tolf;
maxit = options_.solve_maxit;
initial_conditions = oo_.steady_state;
past_val = 0;
save_options_periods = options_.periods;
options_.periods = options_cond_fcst.periods;
save_options_dynatol_f = options_.dynatol.f;
options_.dynatol.f = 1e-8;
eps1 = 1e-4;
exo = zeros(maximum_lag + options_cond_fcst.periods, nx);
endo = zeros(maximum_lag + options_cond_fcst.periods, ny);
endo(1,:) = oo_.steady_state';
% if all the endogenous paths are perfectly anticipated we do not need to
% implement extended path
if pf && ~surprise
time_index_constraint = maximum_lag + 1:maximum_lag + constrained_periods;
second_system_size = pf * constrained_periods;
J = zeros(second_system_size,second_system_size);
r = zeros(second_system_size,1);
indx_endo = zeros(second_system_size,1);
col_count = 1;
for j = 1:length(constrained_vars)
indx_endo(col_count : col_count + constrained_periods - 1) = constrained_vars(j) + (time_index_constraint - 1) * ny;
col_count = col_count + constrained_periods;
end;
make_ex_;
make_y_;
it = 1;
convg = 0;
while ~convg && it <= maxit
disp('---------------------------------------------------------------------------------------------');
disp(['iteration ' int2str(it)]);
not_achieved = 1;
alpha = 1;
while not_achieved
simul();
result = sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint)))) == ny * constrained_periods;
if (~oo_.deterministic_simulation.status || ~result) && it > 1
not_achieved = 1;
alpha = alpha / 2;
col_count = 1;
for j = controlled_varexo
oo_.exo_simul(time_index_constraint,j) = (old_exo(:,j) + alpha * D_exo(col_count: col_count + constrained_periods - 1));
col_count = col_count + constrained_periods;
end;
disp(['Divergence in Newton: reducing the path length alpha=' num2str(alpha)]);
oo_.endo_simul = repmat(oo_.steady_state, 1, options_cond_fcst.periods + 2);
else
not_achieved = 0;
end;
end;
y = oo_.endo_simul(constrained_vars(j), time_index_constraint);
ys = oo_.endo_simul(indx_endo);
col_count = 1;
for j = 1:length(constrained_vars)
y = oo_.endo_simul(constrained_vars(j), time_index_constraint);
r(col_count:col_count+constrained_periods - 1) = (y - constrained_paths(j,1:constrained_periods))';
col_count = col_count + constrained_periods;
end;
col_count = 1;
for j = controlled_varexo
for time = time_index_constraint
saved = oo_.exo_simul(time,j);
oo_.exo_simul(time,j) = oo_.exo_simul(time,j) + eps1;
simul();
J(:,col_count) = (oo_.endo_simul(indx_endo) - ys) / eps1;
oo_.exo_simul(time,j) = saved;
col_count = col_count + 1;
end;
end;
normr = norm(r, 1);
disp(['iteration ' int2str(it) ' error = ' num2str(normr)]);
if normr <= eps
convg = 1;
disp('convergence achieved');
else
% Newton update on exogenous shocks
old_exo = oo_.exo_simul(time_index_constraint,:);
D_exo = - J \ r;
col_count = 1;
for j = controlled_varexo
oo_.exo_simul(time_index_constraint,j) = (oo_.exo_simul(time_index_constraint,j) + D_exo(col_count: col_count + constrained_periods - 1));
col_count = col_count + constrained_periods;
end;
end;
it = it + 1;
end;
endo(maximum_lag + 1 :maximum_lag + options_cond_fcst.periods ,:) = oo_.endo_simul(:,maximum_lag + 1:maximum_lag + options_cond_fcst.periods )';
exo = oo_.exo_simul;
else
for t = 1:constrained_periods
disp('=============================================================================================');
disp(['t=' int2str(t) ' constrained_paths(:,t)=' num2str(constrained_paths(:,t)') ]);
disp('=============================================================================================');
if t == 1
make_ex_;
exo_init = oo_.exo_simul;
make_y_;
end;
oo_.exo_simul = exo_init;
oo_.endo_simul(:,1) = initial_conditions;
convg = 0;
it = 1;
time_index_constraint = maximum_lag + 1:maximum_lag + constrained_periods - t + 1;
second_system_size = surprise + pf * (constrained_periods - t + 1);
indx_endo = zeros(second_system_size,1);
col_count = 1;
for j = 1:length(constrained_vars)
if constrained_perfect_foresight(j)
indx_endo(col_count : col_count + constrained_periods - t) = constrained_vars(j) + (time_index_constraint - 1) * ny;
col_count = col_count + constrained_periods - t + 1;
else
indx_endo(col_count) = constrained_vars(j) + maximum_lag * ny;
col_count = col_count + 1;
end;
end;
J = zeros(second_system_size,second_system_size);
r = zeros(second_system_size,1);
while ~convg && it <= maxit
disp('---------------------------------------------------------------------------------------------');
disp(['iteration ' int2str(it) ' time ' int2str(t)]);
not_achieved = 1;
alpha = 1;
while not_achieved
simul();
result = sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint)))) == ny * length(time_index_constraint);
if (~oo_.deterministic_simulation.status || ~result) && it > 1
not_achieved = 1;
alpha = alpha / 2;
col_count = 1;
for j = controlled_varexo
if constrained_perfect_foresight(j)
oo_.exo_simul(time_index_constraint,j) = (old_exo(time_index_constraint,j) + alpha * D_exo(col_count: col_count + constrained_periods - t));
col_count = col_count + constrained_periods - t + 1;
else
oo_.exo_simul(maximum_lag + 1,j) = old_exo(maximum_lag + 1,j) + alpha * D_exo(col_count);
col_count = col_count + 1;
end;
end;
disp(['Divergence in Newton: reducing the path length alpha=' num2str(alpha) ' result=' num2str(result) ' sum(sum)=' num2str(sum(sum(isfinite(oo_.endo_simul(:,time_index_constraint))))) ' ny * length(time_index_constraint)=' num2str(ny * length(time_index_constraint)) ' oo_.deterministic_simulation.status=' num2str(oo_.deterministic_simulation.status)]);
oo_.endo_simul = [initial_conditions repmat(oo_.steady_state, 1, options_cond_fcst.periods + 1)];
else
not_achieved = 0;
end;
end;
if t==constrained_periods
ycc = oo_.endo_simul;
end;
yc = oo_.endo_simul(:,maximum_lag + 1);
ys = oo_.endo_simul(indx_endo);
col_count = 1;
for j = 1:length(constrained_vars)
if constrained_perfect_foresight(j)
y = oo_.endo_simul(constrained_vars(j), time_index_constraint);
r(col_count:col_count+constrained_periods - t) = (y - constrained_paths(j,t:constrained_periods))';
col_count = col_count + constrained_periods - t + 1;
else
y = yc(constrained_vars(j));
r(col_count) = y - constrained_paths(j,t);
col_count = col_count + 1;
end;
end
disp('computation of derivatives w.r. to exogenous shocks');
col_count = 1;
for j = controlled_varexo
if constrained_perfect_foresight(j)
for time = time_index_constraint
saved = oo_.exo_simul(time,j);
oo_.exo_simul(time,j) = oo_.exo_simul(time,j) + eps1;
simul();
J(:,col_count) = (oo_.endo_simul(indx_endo) - ys) / eps1;
oo_.exo_simul(time,j) = saved;
col_count = col_count + 1;
end;
else
saved = oo_.exo_simul(maximum_lag+1,j);
oo_.exo_simul(maximum_lag+1,j) = oo_.exo_simul(maximum_lag+1,j) + eps1;
simul();
J(:,col_count) = (oo_.endo_simul(indx_endo) - ys) / eps1;
oo_.exo_simul(maximum_lag+1,j) = saved;
col_count = col_count + 1;
end;
end;
normr = norm(r, 1);
disp(['iteration ' int2str(it) ' error = ' num2str(normr) ' at time ' int2str(t)]);
if normr <= eps
convg = 1;
disp('convergence achieved');
else
% Newton update on exogenous shocks
D_exo = - J \ r;
old_exo = oo_.exo_simul;
col_count = 1;
for j = controlled_varexo
if constrained_perfect_foresight(j)
oo_.exo_simul(time_index_constraint,j) = (oo_.exo_simul(time_index_constraint,j) + D_exo(col_count: col_count + constrained_periods - t));
col_count = col_count + constrained_periods - t + 1;
else
oo_.exo_simul(maximum_lag + 1,j) = oo_.exo_simul(maximum_lag + 1,j) + D_exo(col_count);
col_count = col_count + 1;
end;
end;
end;
it = it + 1;
end;
if ~convg
error(['convergence not achived at time ' int2str(t) ' after ' int2str(it) ' iterations']);
end;
for j = controlled_varexo
if constrained_perfect_foresight(j)
% in case of mixed surprise and perfect foresight
% endogenous path at each date all the exogenous paths have to be
% stored. The paths are stacked in exo.
for time = time_index_constraint;
exo(past_val + time,j) = oo_.exo_simul(time,j);
end
else
exo(maximum_lag + t,j) = oo_.exo_simul(maximum_lag + 1,j);
end;
end;
past_val = past_val + length(time_index_constraint);
if t < constrained_periods
endo(maximum_lag + t,:) = yc;
else
endo(maximum_lag + t :maximum_lag + options_cond_fcst.periods ,:) = ycc(:,maximum_lag + 1:maximum_lag + options_cond_fcst.periods - constrained_periods + 1)';
end;
initial_conditions = yc;
end;
end;
options_.periods = save_options_periods;
options_.dynatol.f = save_options_dynatol_f;
options_.initval_file = save_options_initval_file;
% disp('endo');
% disp(endo);
% disp('exo');
% disp(exo);
oo_.endo_simul = endo';
oo_.exo_simul = exo;
function det_cond_forecast(constrained_paths, constrained_vars, options_cond_fcst, constrained_perfect_foresight)
% Computes forecasts using the schocks retrieved from a condition forecast for a deterministic model.
%
% INPUTS
% o constrained_paths [double] m*p array, where m is the number of constrained endogenous variables and p is the number of constrained periods.
% o constrained_vars [char] m*x array holding the names of the controlled endogenous variables.
% o options_cond_fcst [structure] containing the options. The fields are:
% + replic [integer] scalar, number of monte carlo simulations.
% + parameter_set [char] values of the estimated parameters:
% "posterior_mode",
% "posterior_mean",
% "posterior_median",
% "prior_mode" or
% "prior mean".
% [double] np*1 array, values of the estimated parameters.
% + controlled_varexo [char] m*x array, list of controlled exogenous variables.
% + conf_sig [double] scalar in [0,1], probability mass covered by the confidence bands.
% o constrained_perfect_foresight [double] m*1 array indicating if the endogenous variables path is perfectly foresight (1) or is a surprise (0)
%
%
% OUTPUTS
% None.
%
% SPECIAL REQUIREMENTS
% This routine has to be called after an estimation statement or an estimated_params block.
%
% REMARKS
% [1] Results are stored in a structure which is saved in a mat file called conditional_forecasts.mat.
% [2] Use the function plot_icforecast to plot the results.
% Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
global options_ oo_ M_
if ~isfield(options_cond_fcst,'periods') || isempty(options_cond_fcst.periods)
options_cond_fcst.periods = 60;
end
maximum_lag = M_.maximum_lag;
maximum_lead = M_.maximum_lead;
ys = oo_.steady_state;
ny = size(ys,1);
xs = [oo_.exo_steady_state ; oo_.exo_det_steady_state];
nx = size(xs,1);
constrained_periods = size(constrained_paths,2);
n_endo_constrained = size(constrained_vars,1);
if isfield(options_cond_fcst,'controlled_varexo')
n_control_exo = size(options_cond_fcst.controlled_varexo, 1);
if n_control_exo ~= n_endo_constrained
error(['det_cond_forecast:: the number of exogenous controlled variables (' int2str(n_control_exo) ') has to be equal to the number of constrained endogenous variabes (' int2str(n_endo_constrained) ')'])
end;
else
error('det_cond_forecast:: to run a deterministic conditional forecast you have to specified the exogenous variables controlled using the option controlled_varex in forecast command');
end;
exo_names = M_.exo_names;
controlled_varexo = zeros(1,n_control_exo);
for i = 1:nx
for j=1:n_control_exo
if strcmp(exo_names(i,:), options_cond_fcst.controlled_varexo(j,:))
controlled_varexo(j) = i;
end
end
end
save_options_initval_file = options_.initval_file;
options_.initval_file = '__';
[pos_constrained_pf, junk] = find(constrained_perfect_foresight);
indx_endo_solve_pf = constrained_vars(pos_constrained_pf);
if isempty(indx_endo_solve_pf)
pf = 0;
else
pf = length(indx_endo_solve_pf);
end;
indx_endo_solve_surprise = setdiff(constrained_vars, indx_endo_solve_pf);
if isempty(indx_endo_solve_surprise)
surprise = 0;
else
surprise = length(indx_endo_solve_surprise);
end;
eps = options_.solve_tolf;
maxit = options_.solve_maxit;
% Check the solution using a unconditional forecast (soft tune)
initial_conditions = oo_.steady_state;
terminal_conditions = oo_.steady_state;
exo = oo_.exo_simul;
T = options_.periods + 2;
endo_simul = zeros(ny, T);
endo_simul(:,1) = initial_conditions;
endo_simul(:,T) = initial_conditions;
exo_simul = zeros(T, nx);
exo_simul(1,:) = [oo_.exo_steady_state' oo_.exo_det_steady_state'];
exo_simul(T,:) = [oo_.exo_steady_state' oo_.exo_det_steady_state'];
past_val = 0;
if pf && ~surprise
make_ex_;
make_y_;
oo_.endo_simul(:,1) = initial_conditions;
oo_.endo_simul(:,options_.periods + 2) = terminal_conditions;
%oo_.exo_simul = repmat(oo_.exo_steady_state, options_.periods + 2, 1);
oo_.exo_simul = exo;
simul();
endo_simul = oo_.endo_simul;
exo_simul = oo_.exo_simul;
else
for t=1:constrained_periods
make_ex_;
make_y_;
disp(['t=' int2str(t) ' constrained_periods=' int2str(constrained_periods)]);
oo_.endo_simul(:,1) = initial_conditions;
oo_.endo_simul(:,options_.periods + 2) = terminal_conditions;
time_index_constraint = maximum_lag + 1:maximum_lag + constrained_periods - t + 1;
if t <= constrained_periods
for j = controlled_varexo
if constrained_perfect_foresight(j)
for time = time_index_constraint;
oo_.exo_simul(time,j) = exo(past_val + time,j);
end;
oo_.exo_simul(time+1, j)= oo_.exo_steady_state(j);
else
oo_.exo_simul(maximum_lag + 1,j) = exo(maximum_lag + t,j);
end;
end;
else
tmp = size(oo_.exo_simul,1);
oo_.exo_simul = repmat(oo_.exo_steady_state',tmp,1);
end;
past_val = past_val + length(time_index_constraint);
simul();
initial_conditions = oo_.endo_simul(:,2);
if t < constrained_periods
endo_simul(:,t+1) = initial_conditions;
exo_simul(t+1,:) = oo_.exo_simul(2,:);
else
endo_simul(:,t + 1:t + options_cond_fcst.periods + maximum_lead) = oo_.endo_simul(:,maximum_lag + 1:maximum_lag + options_cond_fcst.periods + maximum_lead);