2015-03-02 10:45:12 +01:00
|
|
|
function [forecast,info] = dyn_forecast(var_list,M,options,oo,task,dataset_info)
|
|
|
|
% function dyn_forecast(var_list,M,options,oo,task,dataset_info)
|
2009-12-16 18:17:34 +01:00
|
|
|
% computes mean forecast for a given value of the parameters
|
2017-05-16 15:10:20 +02:00
|
|
|
% compues also confidence band for the forecast
|
2009-12-16 18:17:34 +01:00
|
|
|
%
|
|
|
|
% INPUTS
|
|
|
|
% var_list: list of variables (character matrix)
|
2016-03-11 16:01:21 +01:00
|
|
|
% M: Dynare model structure
|
|
|
|
% options: Dynare options structure
|
|
|
|
% oo: Dynare results structure
|
2009-12-16 18:17:34 +01:00
|
|
|
% task: indicates how to initialize the forecast
|
|
|
|
% either 'simul' or 'smoother'
|
2015-03-02 10:45:12 +01:00
|
|
|
% dataset_info: Various informations about the dataset (descriptive statistics and missing observations).
|
|
|
|
|
2009-12-16 18:17:34 +01:00
|
|
|
% OUTPUTS
|
|
|
|
% nothing is returned but the procedure saves output
|
|
|
|
% in oo_.forecast.Mean
|
|
|
|
% oo_.forecast.HPDinf
|
|
|
|
% oo_.forecast.HPDsup
|
|
|
|
%
|
|
|
|
% SPECIAL REQUIREMENTS
|
|
|
|
% none
|
|
|
|
|
2017-10-10 10:05:59 +02:00
|
|
|
% Copyright (C) 2003-2018 Dynare Team
|
2009-12-16 18:17:34 +01:00
|
|
|
%
|
|
|
|
% 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
|
2021-06-09 17:33:48 +02:00
|
|
|
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2009-12-16 18:17:34 +01:00
|
|
|
|
2016-03-23 13:59:10 +01:00
|
|
|
if nargin<6 && options.prefilter
|
2015-05-25 23:38:26 +02:00
|
|
|
error('The prefiltering option is not allowed without providing a dataset')
|
2016-03-23 13:59:10 +01:00
|
|
|
elseif nargin==6
|
2015-03-02 10:45:12 +01:00
|
|
|
mean_varobs=dataset_info.descriptive.mean';
|
|
|
|
end
|
2017-05-16 15:10:20 +02:00
|
|
|
|
2009-12-16 18:17:34 +01:00
|
|
|
info = 0;
|
|
|
|
|
2016-03-11 16:01:21 +01:00
|
|
|
oo=make_ex_(M,options,oo);
|
2015-02-15 17:49:01 +01:00
|
|
|
|
2015-11-24 20:55:33 +01:00
|
|
|
maximum_lag = M.maximum_lag;
|
2009-12-16 18:17:34 +01:00
|
|
|
|
2015-11-24 20:55:33 +01:00
|
|
|
endo_names = M.endo_names;
|
2009-12-16 18:17:34 +01:00
|
|
|
if isempty(var_list)
|
2017-10-10 10:05:59 +02:00
|
|
|
var_list = endo_names(1:M.orig_endo_nbr);
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
i_var = [];
|
2017-10-10 10:05:59 +02:00
|
|
|
for i = 1:length(var_list)
|
|
|
|
tmp = strmatch(var_list{i}, endo_names, 'exact');
|
2009-12-16 18:17:34 +01:00
|
|
|
if isempty(tmp)
|
2017-10-10 10:05:59 +02:00
|
|
|
error([var_list{i} ' isn''t an endogenous variable'])
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
i_var = [i_var; tmp];
|
|
|
|
end
|
|
|
|
|
|
|
|
n_var = length(i_var);
|
|
|
|
|
|
|
|
trend = 0;
|
|
|
|
switch task
|
|
|
|
case 'simul'
|
2015-11-24 20:55:33 +01:00
|
|
|
horizon = options.periods;
|
2009-12-16 18:17:34 +01:00
|
|
|
if horizon == 0
|
|
|
|
horizon = 5;
|
|
|
|
end
|
2015-11-24 20:55:33 +01:00
|
|
|
if isempty(M.endo_histval)
|
2017-02-14 12:54:22 +01:00
|
|
|
if options.loglinear && ~options.logged_steady_state
|
|
|
|
y0 = repmat(log(oo.dr.ys),1,maximum_lag);
|
|
|
|
else
|
|
|
|
y0 = repmat(oo.dr.ys,1,maximum_lag);
|
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
else
|
2017-02-14 12:54:22 +01:00
|
|
|
if options.loglinear
|
|
|
|
y0 = log_variable(1:M.endo_nbr,M.endo_histval,M);
|
|
|
|
else
|
|
|
|
y0 = M.endo_histval;
|
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
case 'smoother'
|
2015-11-24 20:55:33 +01:00
|
|
|
horizon = options.forecast;
|
2021-02-16 11:26:35 +01:00
|
|
|
if isnan(options.first_obs)
|
|
|
|
first_obs=1;
|
|
|
|
else
|
|
|
|
first_obs=options.first_obs;
|
|
|
|
end
|
|
|
|
if isfield(oo.SmoothedVariables,'Mean')
|
|
|
|
y_smoothed = oo.SmoothedVariables.Mean;
|
|
|
|
else
|
|
|
|
y_smoothed = oo.SmoothedVariables;
|
|
|
|
end
|
2015-11-24 20:55:33 +01:00
|
|
|
y0 = zeros(M.endo_nbr,maximum_lag);
|
|
|
|
for i = 1:M.endo_nbr
|
2017-10-10 10:05:59 +02:00
|
|
|
v_name = M.endo_names{i};
|
2015-03-07 12:44:48 +01:00
|
|
|
y0(i,:) = y_smoothed.(v_name)(end-maximum_lag+1:end); %includes steady state or mean, but simult_ will subtract only steady state
|
2017-05-16 15:10:20 +02:00
|
|
|
% 2. Subtract mean/steady state and add steady state; takes care of prefiltering
|
2015-03-07 12:44:48 +01:00
|
|
|
if isfield(oo.Smoother,'Constant') && isfield(oo.Smoother.Constant,v_name)
|
|
|
|
y0(i,:)=y0(i,:)-oo.Smoother.Constant.(v_name)(end-maximum_lag+1:end); %subtract mean or steady state
|
2016-03-23 12:24:19 +01:00
|
|
|
if options.loglinear
|
2016-05-02 13:51:51 +02:00
|
|
|
y0(i,:)=y0(i,:)+log_variable(i,oo.dr.ys,M);
|
2015-03-07 12:44:48 +01:00
|
|
|
else
|
2017-10-10 10:05:59 +02:00
|
|
|
y0(i,:)=y0(i,:)+oo.dr.ys(strmatch(v_name, M.endo_names, 'exact'));
|
2015-03-07 12:44:48 +01:00
|
|
|
end
|
2017-05-16 15:10:20 +02:00
|
|
|
end
|
2015-03-07 12:44:48 +01:00
|
|
|
% 2. Subtract trend
|
|
|
|
if isfield(oo.Smoother,'Trend') && isfield(oo.Smoother.Trend,v_name)
|
|
|
|
y0(i,:)=y0(i,:)-oo.Smoother.Trend.(v_name)(end-maximum_lag+1:end); %subtract trend, which is not subtracted by simult_
|
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
2015-11-24 20:55:33 +01:00
|
|
|
gend = options.nobs;
|
|
|
|
if isfield(oo.Smoother,'TrendCoeffs')
|
|
|
|
var_obs = options.varobs;
|
|
|
|
endo_names = M.endo_names;
|
2009-12-16 18:17:34 +01:00
|
|
|
i_var_obs = [];
|
|
|
|
trend_coeffs = [];
|
2013-05-21 16:38:17 +02:00
|
|
|
for i=1:length(var_obs)
|
2017-10-10 10:05:59 +02:00
|
|
|
tmp = strmatch(var_obs{i}, endo_names(i_var), 'exact');
|
|
|
|
trend_var_index = strmatch(var_obs{i}, M.endo_names, 'exact');
|
2009-12-16 18:17:34 +01:00
|
|
|
if ~isempty(tmp)
|
|
|
|
i_var_obs = [ i_var_obs; tmp];
|
2016-06-05 20:15:55 +02:00
|
|
|
trend_coeffs = [trend_coeffs; oo.Smoother.TrendCoeffs(trend_var_index)];
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
2013-03-19 19:04:03 +01:00
|
|
|
end
|
2017-05-16 15:10:20 +02:00
|
|
|
if ~isempty(trend_coeffs)
|
2021-02-16 11:26:35 +01:00
|
|
|
trend = trend_coeffs*(first_obs+gend-1+(1-M.maximum_lag:horizon));
|
2015-03-07 12:44:48 +01:00
|
|
|
if options.prefilter
|
2021-02-16 11:26:35 +01:00
|
|
|
trend = trend - repmat(mean(trend_coeffs*[first_obs:first_obs+gend-1],2),1,horizon+1); %subtract mean trend
|
2015-03-07 12:44:48 +01:00
|
|
|
end
|
2013-03-19 19:04:03 +01:00
|
|
|
end
|
2015-03-07 12:44:48 +01:00
|
|
|
else
|
2016-03-23 12:24:19 +01:00
|
|
|
trend_coeffs=zeros(length(options.varobs),1);
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
otherwise
|
|
|
|
error('Wrong flag value')
|
2017-05-16 15:10:20 +02:00
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
|
2015-11-24 20:55:33 +01:00
|
|
|
if M.exo_det_nbr == 0
|
2016-06-19 12:41:51 +02:00
|
|
|
if isequal(M.H,0)
|
|
|
|
[yf,int_width] = forcst(oo.dr,y0,horizon,var_list,M,oo,options);
|
|
|
|
else
|
2017-05-16 15:10:20 +02:00
|
|
|
[yf,int_width,int_width_ME] = forcst(oo.dr,y0,horizon,var_list,M,oo,options);
|
2016-06-19 12:41:51 +02:00
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
else
|
2015-11-24 20:55:33 +01:00
|
|
|
exo_det_length = size(oo.exo_det_simul,1)-M.maximum_lag;
|
2009-12-16 18:17:34 +01:00
|
|
|
if horizon > exo_det_length
|
2015-11-24 20:55:33 +01:00
|
|
|
ex = zeros(horizon,M.exo_nbr);
|
|
|
|
oo.exo_det_simul = [ oo.exo_det_simul;...
|
|
|
|
repmat(oo.exo_det_steady_state',...
|
2017-05-16 15:10:20 +02:00
|
|
|
horizon- ...
|
2009-12-16 18:17:34 +01:00
|
|
|
exo_det_length,1)];
|
2017-05-16 15:10:20 +02:00
|
|
|
elseif horizon <= exo_det_length
|
|
|
|
ex = zeros(exo_det_length,M.exo_nbr);
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
2018-08-02 14:13:03 +02:00
|
|
|
if options.linear
|
|
|
|
iorder = 1;
|
|
|
|
else
|
|
|
|
iorder = options.order;
|
|
|
|
end
|
2016-06-19 12:41:51 +02:00
|
|
|
if isequal(M.H,0)
|
|
|
|
[yf,int_width] = simultxdet(y0,ex,oo.exo_det_simul,...
|
2018-08-02 14:13:03 +02:00
|
|
|
iorder,var_list,M,oo,options);
|
2016-06-19 12:41:51 +02:00
|
|
|
else
|
|
|
|
[yf,int_width,int_width_ME] = simultxdet(y0,ex,oo.exo_det_simul,...
|
2018-08-02 14:13:03 +02:00
|
|
|
iorder,var_list,M,oo,options);
|
2016-06-19 12:41:51 +02:00
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
|
2015-03-07 12:44:48 +01:00
|
|
|
if ~isscalar(trend) %add trend back to forecast
|
2009-12-16 18:17:34 +01:00
|
|
|
yf(i_var_obs,:) = yf(i_var_obs,:) + trend;
|
|
|
|
end
|
|
|
|
|
2019-03-19 14:26:16 +01:00
|
|
|
if options.loglinear
|
2015-03-01 15:12:34 +01:00
|
|
|
if options.prefilter == 1 %subtract steady state and add mean for observables
|
2015-03-07 12:44:48 +01:00
|
|
|
yf(i_var_obs,:)=yf(i_var_obs,:)-repmat(log(oo.dr.ys(i_var_obs)),1,horizon+M.maximum_lag)+ repmat(mean_varobs,1,horizon+M.maximum_lag);
|
2015-03-01 15:12:34 +01:00
|
|
|
end
|
|
|
|
else
|
|
|
|
if options.prefilter == 1 %subtract steady state and add mean for observables
|
2016-03-23 13:59:10 +01:00
|
|
|
yf(i_var_obs,:)=yf(i_var_obs,:)-repmat(oo.dr.ys(i_var_obs),1,horizon+M.maximum_lag)+ repmat(mean_varobs,1,horizon+M.maximum_lag);
|
2017-05-16 15:10:20 +02:00
|
|
|
end
|
2015-03-01 14:25:28 +01:00
|
|
|
end
|
|
|
|
|
2009-12-16 18:17:34 +01:00
|
|
|
for i=1:n_var
|
2017-10-10 10:05:59 +02:00
|
|
|
vname = var_list{i};
|
2015-11-24 20:55:33 +01:00
|
|
|
forecast.Mean.(vname) = yf(i,maximum_lag+(1:horizon))';
|
|
|
|
forecast.HPDinf.(vname)= yf(i,maximum_lag+(1:horizon))' - int_width(1:horizon,i);
|
|
|
|
forecast.HPDsup.(vname) = yf(i,maximum_lag+(1:horizon))' + int_width(1:horizon,i);
|
2017-10-10 10:05:59 +02:00
|
|
|
if ~isequal(M.H,0) && ismember(var_list{i},options.varobs)
|
2016-06-19 12:41:51 +02:00
|
|
|
forecast.HPDinf_ME.(vname)= yf(i,maximum_lag+(1:horizon))' - int_width_ME(1:horizon,i);
|
|
|
|
forecast.HPDsup_ME.(vname) = yf(i,maximum_lag+(1:horizon))' + int_width_ME(1:horizon,i);
|
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
|
2015-11-24 20:55:33 +01:00
|
|
|
for i=1:M.exo_det_nbr
|
2017-10-10 10:05:59 +02:00
|
|
|
forecast.Exogenous.(M.exo_det_names{i}) = oo.exo_det_simul(maximum_lag+(1:horizon),i);
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
|
2019-03-19 14:26:16 +01:00
|
|
|
if ~options.nograph
|
2015-11-30 21:30:42 +01:00
|
|
|
oo.forecast = forecast;
|
2017-10-10 10:05:59 +02:00
|
|
|
forecast_graphs(var_list, M, oo, options)
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|