Fixed routines for backward model simulation (with IRFs and forecasts).
parent
eae4bc91b8
commit
510eccd965
|
@ -31,7 +31,7 @@ global M_ options_ oo_
|
|||
|
||||
% Check that the model is actually backward
|
||||
if M_.maximum_lead
|
||||
error(['backward_model_irf:: The specified model is not backward looking!'])
|
||||
error(['backward_model_forecast:: The specified model is not backward looking!'])
|
||||
end
|
||||
|
||||
% Initialize returned argument.
|
||||
|
@ -53,14 +53,17 @@ if nargin<4
|
|||
withuncertainty = false;
|
||||
end
|
||||
|
||||
% Get full list of endogenous variables
|
||||
endo_names = cellstr(M_.endo_names);
|
||||
start = initialcondition.dates(end)+1;
|
||||
|
||||
% Set up initial conditions
|
||||
[initialcondition, periods, innovations, DynareOptions, DynareModel, DynareOutput, endonames, exonames, nx, ny1, iy1, jdx, model_dynamic, y] = ...
|
||||
simul_backward_model_init(initialcondition, periods, options_, M_, oo_, zeros(periods, M_.exo_nbr));
|
||||
|
||||
% Get vector of indices for the selected endogenous variables.
|
||||
n = length(listofvariables);
|
||||
idy = zeros(n,1);
|
||||
for i=1:n
|
||||
j = find(strcmp(listofvariables{i}, endo_names));
|
||||
j = find(strcmp(listofvariables{i}, endonames));
|
||||
if isempty(j)
|
||||
error('backward_model_forecast:: Variable %s is unknown!', listofvariables{i})
|
||||
else
|
||||
|
@ -79,37 +82,28 @@ if withuncertainty
|
|||
sigma = transpose(chol(Sigma));
|
||||
end
|
||||
|
||||
% Set initial condition.
|
||||
if isdates(initialcondition)
|
||||
if isempty(M_.endo_histval)
|
||||
error('backward_model_irf: histval block for setting initial condition is missing!')
|
||||
end
|
||||
initialcondition = dseries(transpose(M_.endo_histval), initialcondition, endo_names, cellstr(M_.endo_names_tex));
|
||||
% Compute forecast without shock
|
||||
if options_.linear
|
||||
ysim__0 = simul_backward_linear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, nx, ny1, iy1, jdx, model_dynamic);
|
||||
else
|
||||
ysim__0 = simul_backward_nonlinear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic);
|
||||
end
|
||||
forecasts.pointforecast = dseries(transpose(ysim__0(idy,:)), initialcondition.init, listofvariables);
|
||||
|
||||
% Put initial conditions in a vector of doubles
|
||||
initialconditions = transpose(initialcondition{endo_names{:}}.data);
|
||||
|
||||
% Compute forecast without shock
|
||||
innovations = zeros(periods+M_.maximum_exo_lag, M_.exo_nbr);
|
||||
if M_.maximum_exo_lag
|
||||
if isempty(M_.exo_histval)
|
||||
error('You need to set the past values for the exogenous variables!')
|
||||
else
|
||||
innovations(1:M_.maximum_exo_lag, :) = M_.exo_histval;
|
||||
end
|
||||
end
|
||||
|
||||
oo__0 = simul_backward_model(initialconditions, periods, options_, M_, oo_, innovations);
|
||||
forecasts.pointforecast = dseries(transpose(oo__0.endo_simul(idy,:)), initialcondition.init, listofvariables);
|
||||
% Set first period of forecast
|
||||
forecasts.start = start;
|
||||
|
||||
if withuncertainty
|
||||
% Preallocate an array gathering the simulations.
|
||||
ArrayOfForecasts = zeros(n, periods+size(initialconditions, 2), B);
|
||||
ArrayOfForecasts = zeros(n, periods+initialcondition.nobs, B);
|
||||
for i=1:B
|
||||
innovations(M_.maximum_exo_lag+1:end,:) = transpose(sigma*randn(M_.exo_nbr, periods));
|
||||
oo__ = simul_backward_model(initialconditions, periods, options_, M_, oo_, innovations);
|
||||
ArrayOfForecasts(:,:,i) = oo__.endo_simul(idy,:);
|
||||
innovations = transpose(sigma*randn(M_.exo_nbr, periods));
|
||||
if options_.linear
|
||||
[ysim__, xsim__] = simul_backward_linear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, nx, ny1, iy1, jdx, model_dynamic);
|
||||
else
|
||||
[ysim__, xsim__] = simul_backward_nonlinear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic);
|
||||
end
|
||||
ArrayOfForecasts(:,:,i) = ysim__(idy,:);
|
||||
end
|
||||
% Compute mean (over future uncertainty) forecast.
|
||||
forecasts.meanforecast = dseries(transpose(mean(ArrayOfForecasts, 3)), initialcondition.init, listofvariables);
|
||||
|
|
|
@ -58,63 +58,47 @@ else
|
|||
transform = varargin{2};
|
||||
end
|
||||
|
||||
% Get list of all exogenous variables in a cell of strings
|
||||
exo_names = cellstr(M_.exo_names);
|
||||
|
||||
% Get the list of all exogenous variables in a cell of strings
|
||||
endo_names = cellstr(M_.endo_names);
|
||||
|
||||
% Set initial condition.
|
||||
if isdates(initialcondition)
|
||||
if isempty(M_.endo_histval)
|
||||
error('backward_model_irf: histval block for setting initial condition is missing!')
|
||||
end
|
||||
initialcondition = dseries(transpose(M_.endo_histval), initialcondition, endo_names, cellstr(M_.endo_names_tex));
|
||||
end
|
||||
% Set up initial conditions
|
||||
[initialcondition, periods, innovations, DynareOptions, DynareModel, DynareOutput, endonames, exonames, nx, ny1, iy1, jdx, model_dynamic, y] = ...
|
||||
simul_backward_model_init(initialcondition, periods, options_, M_, oo_, zeros(periods, M_.exo_nbr));
|
||||
|
||||
% Get the covariance matrix of the shocks.
|
||||
Sigma = M_.Sigma_e + 1e-14*eye(M_.exo_nbr);
|
||||
sigma = transpose(chol(Sigma));
|
||||
|
||||
% Put initial conditions in a vector of doubles
|
||||
initialconditions = transpose(initialcondition{endo_names{:}}.data);
|
||||
|
||||
% Initialization of the returned argument. Each will be a dseries object containing the IRFS for the endogenous variables listed in the third input argument.
|
||||
irfs = struct();
|
||||
|
||||
% Get the covariance matrix of the shocks.
|
||||
Sigma = M_.Sigma_e + 1e-14*eye(M_.exo_nbr);
|
||||
sigma = transpose(chol(Sigma));
|
||||
|
||||
% Compute the IRFs (loop over innovations).
|
||||
for i=1:length(listofshocks)
|
||||
innovations = zeros(periods, DynareModel.exo_nbr);
|
||||
% Get transition paths induced by the initial condition.
|
||||
innovations = zeros(periods, M_.exo_nbr);
|
||||
if ~isempty(M_.exo_histval)
|
||||
innovations = [transpose(M_.exo_histval); innovations];
|
||||
shift = size(M_.exo_histval, 2);
|
||||
if options_.linear
|
||||
ysim__0 = simul_backward_linear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, nx, ny1, iy1, jdx, model_dynamic);
|
||||
else
|
||||
innovations = [zeros(1, M_.exo_nbr); innovations];
|
||||
shift = 1;
|
||||
ysim__0 = simul_backward_nonlinear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic);
|
||||
end
|
||||
oo__0 = simul_backward_model(initialconditions, periods, options_, M_, oo_, innovations);
|
||||
% Add the shock.
|
||||
j = find(strcmp(listofshocks{i}, exo_names));
|
||||
j = find(strcmp(listofshocks{i}, exonames));
|
||||
if isempty(j)
|
||||
error('backward_model_irf: Exogenous variable %s is unknown!', listofshocks{i})
|
||||
end
|
||||
innovations(shift+1,:) = transpose(sigma(:,j));
|
||||
oo__1 = simul_backward_model(initialconditions, periods, options_, M_, oo_, innovations);
|
||||
innovations(1,:) = transpose(sigma(:,j));
|
||||
if options_.linear
|
||||
ysim__1 = simul_backward_linear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, nx, ny1, iy1, jdx, model_dynamic);
|
||||
else
|
||||
ysim__1 = simul_backward_nonlinear_model_(initialcondition, periods, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic);
|
||||
end
|
||||
% Transform the endogenous variables
|
||||
if notransform
|
||||
endo_simul__0 = oo__0.endo_simul;
|
||||
endo_simul__1 = oo__1.endo_simul;
|
||||
endo_simul__0 = ysim__0;
|
||||
endo_simul__1 = ysim__1;
|
||||
else
|
||||
endo_simul__0 = feval(transform, oo__0.endo_simul);
|
||||
endo_simul__1 = feval(transform, oo__1.endo_simul);
|
||||
endo_simul__0 = feval(transform, ysim__0);
|
||||
endo_simul__1 = feval(transform, ysim__1);
|
||||
end
|
||||
% Instantiate a dseries object (with all the endogenous variables)
|
||||
allirfs = dseries(transpose(endo_simul__1-endo_simul__0), initialcondition.init, cellstr(M_.endo_names), cellstr(M_.endo_names_tex));
|
||||
allirfs = dseries(transpose(endo_simul__1-endo_simul__0), initialcondition.init, endonames, cellstr(DynareModel.endo_names_tex));
|
||||
% Extract a sub-dseries object
|
||||
irfs.(listofshocks{i}) = allirfs{listofvariables{:}};
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
function l = get_lags_on_endogenous_variables(DynareModel)
|
||||
|
||||
% Returns a vector with the max lag for each endogenous variable.
|
||||
|
||||
% Copyright (C) 2017 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/>.
|
||||
|
||||
l = zeros(DynareModel.orig_endo_nbr, 1);
|
||||
l(find(DynareModel.lead_lag_incidence(1,1:DynareModel.orig_endo_nbr))) = -1;
|
||||
|
||||
if ~isempty(DynareModel.aux_vars)
|
||||
aux_var_for_lagged_endogenous = find([DynareModel.aux_vars(:).type]==1);
|
||||
for i=1:length(aux_var_for_lagged_endogenous)
|
||||
l(DynareModel.aux_vars(aux_var_for_lagged_endogenous(i)).orig_index) = ...
|
||||
DynareModel.aux_vars(aux_var_for_lagged_endogenous(i)).orig_lead_lag;
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
function l = get_lags_on_exogenous_variables(DynareModel)
|
||||
|
||||
% Returns a vector with the max lag for each exogenous variable.
|
||||
|
||||
% Copyright (C) 2017 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/>.
|
||||
|
||||
l = zeros(DynareModel.exo_nbr, 1);
|
||||
|
||||
if ~isempty(DynareModel.aux_vars)
|
||||
aux_var_for_lagged_exogenous = find([DynareModel.aux_vars(:).type]==3);
|
||||
for i=1:length(aux_var_for_lagged_exogenous)
|
||||
l(DynareModel.aux_vars(aux_var_for_lagged_exogenous(i)).orig_index) = ...
|
||||
DynareModel.aux_vars(aux_var_for_lagged_exogenous(i)).orig_lead_lag-1;
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
function DynareOutput = simul_backward_linear_model(varargin)
|
||||
function simulations = simul_backward_linear_model(varargin)
|
||||
|
||||
% Simulates a stochastic linear backward looking model.
|
||||
%
|
||||
|
@ -38,40 +38,9 @@ function DynareOutput = simul_backward_linear_model(varargin)
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
[initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, nx, ny1, iy1, jdx, model_dynamic, y] = ...
|
||||
[initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, endonames, exonames, nx, ny1, iy1, jdx, model_dynamic, y] = ...
|
||||
simul_backward_model_init(varargin{:});
|
||||
|
||||
% initialization of the returned simulations.
|
||||
DynareOutput.endo_simul = NaN(DynareModel.endo_nbr,samplesize);
|
||||
if isempty(initialconditions)
|
||||
if isfield(DynareModel,'endo_histval') && ~isempty(DynareModel.endo_histval)
|
||||
DynareOutput.endo_simul = [DynareModel.endo_histval, DynareOutput.endo_simul];
|
||||
else
|
||||
DynareOutput.endo_simul = [zeros(DynareModel.endo_nbr, DynareModel.max_lag_orig), DynareOutput.endo_simul];
|
||||
end
|
||||
else
|
||||
if ~isequal(size(initialconditions, 2), DynareModel.max_lag_orig)
|
||||
error(['simul_backward_linear_model:: First argument should have %s columns!'], DynareModel.max_lag_orig)
|
||||
end
|
||||
DynareOutput.endo_simul = [initialconditions, DynareOutput.endo_simul];
|
||||
end
|
||||
Y = DynareOutput.endo_simul;
|
||||
[ysim, xsim] = simul_backward_linear_model_(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations, nx, ny1, iy1, jdx, model_dynamic);
|
||||
|
||||
DynareOutput.exo_simul = [ zeros(1, DynareModel.exo_nbr); DynareOutput.exo_simul];
|
||||
|
||||
% Get coefficients
|
||||
[cst, jacob] = model_dynamic(zeros(DynareModel.endo_nbr+ny1,1), ...
|
||||
zeros(DynareModel.max_lag_orig+1,DynareModel.exo_nbr), ...
|
||||
DynareModel.params, ...
|
||||
DynareOutput.steady_state, DynareModel.max_lag_orig+1);
|
||||
|
||||
A0inv = inv(jacob(:,jdx));
|
||||
A1 = jacob(:,nonzeros(DynareModel.lead_lag_incidence(1,:)));
|
||||
B = jacob(:,end-nx+1:end);
|
||||
|
||||
% Simulations
|
||||
for it = 1+(1:samplesize)
|
||||
Y(:,it) = -A0inv*(cst + A1*Y(iy1,it-1) + B*DynareOutput.exo_simul(it,:)');
|
||||
end
|
||||
|
||||
DynareOutput.endo_simul = Y;
|
||||
simulations = [dseries(ysim', initialconditions.init, endonames(1:DynareModel.orig_endo_nbr)), dseries(xsim, initialconditions.init, exonames)];
|
|
@ -0,0 +1,61 @@
|
|||
function [ysim, xsim] = simul_backward_linear_model_(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations, nx, ny1, iy1, jdx, model_dynamic)
|
||||
|
||||
% Simulates a stochastic linear backward looking model.
|
||||
%
|
||||
% INPUTS
|
||||
% - initialconditions [double] n*1 vector, initial conditions for the endogenous variables.
|
||||
% - samplesize [integer] scalar, number of periods for the simulation.
|
||||
% - DynareOptions [struct] Dynare's options_ global structure.
|
||||
% - DynareModel [struct] Dynare's M_ global structure.
|
||||
% - DynareOutput [struct] Dynare's oo_ global structure.
|
||||
% - innovations [double] T*q matrix, innovations to be used for the simulation.
|
||||
%
|
||||
% OUTPUTS
|
||||
% - DynareOutput [struct] Dynare's oo_ global structure.
|
||||
%
|
||||
% REMARKS
|
||||
% [1] The innovations used for the simulation are saved in DynareOutput.exo_simul, and the resulting paths for the endogenous
|
||||
% variables are saved in DynareOutput.endo_simul.
|
||||
% [2] The last input argument is not mandatory. If absent we use random draws and rescale them with the informations provided
|
||||
% through the shocks block.
|
||||
% [3] If the first input argument is empty, the endogenous variables are initialized with 0, or if available with the informations
|
||||
% provided thrtough the histval block.
|
||||
|
||||
% Copyright (C) 2017 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/>.
|
||||
|
||||
if ~isempty(innovations)
|
||||
DynareOutput.exo_simul(initialconditions.nobs+(1:samplesize),:) = innovations;
|
||||
end
|
||||
|
||||
% Get coefficients
|
||||
[cst, jacob] = model_dynamic(zeros(DynareModel.endo_nbr+ny1,1), ...
|
||||
zeros(DynareModel.max_lag_orig+1,DynareModel.exo_nbr), ...
|
||||
DynareModel.params, ...
|
||||
DynareOutput.steady_state, DynareModel.max_lag_orig+1);
|
||||
|
||||
A0inv = inv(jacob(:,jdx));
|
||||
A1 = jacob(:,nonzeros(DynareModel.lead_lag_incidence(1,:)));
|
||||
B = jacob(:,end-nx+1:end);
|
||||
|
||||
% Simulations
|
||||
for it = initialconditions.nobs+(1:samplesize)
|
||||
DynareOutput.endo_simul(:,it) = -A0inv*(cst + A1*DynareOutput.endo_simul(iy1,it-1) + B*DynareOutput.exo_simul(it,:)');
|
||||
end
|
||||
|
||||
ysim = DynareOutput.endo_simul(1:DynareModel.orig_endo_nbr,:);
|
||||
xsim = DynareOutput.exo_simul;
|
|
@ -1,4 +1,4 @@
|
|||
function DynareOutput = simul_backward_model(varargin)
|
||||
function simulation = simul_backward_model(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations)
|
||||
|
||||
% Simulates a stochastic backward looking model (with arbitrary precision).
|
||||
%
|
||||
|
@ -11,7 +11,7 @@ function DynareOutput = simul_backward_model(varargin)
|
|||
% - innovations [double] T*q matrix, innovations to be used for the simulation.
|
||||
%
|
||||
% OUTPUTS
|
||||
% - DynareOutput [struct] Dynare's oo_ global structure.
|
||||
% - simulation [dseries] Simulated endogenous and exogenous variables.
|
||||
%
|
||||
% REMARKS
|
||||
% [1] The innovations used for the simulation are saved in DynareOutput.exo_simul, and the resulting paths for the endogenous
|
||||
|
@ -38,10 +38,14 @@ function DynareOutput = simul_backward_model(varargin)
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
[initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput] = simul_backward_model_init(varargin{:});
|
||||
if nargin<6
|
||||
innovations =[];
|
||||
end
|
||||
|
||||
%[initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput] = simul_backward_model_init(varargin{:});
|
||||
|
||||
if DynareOptions.linear
|
||||
DynareOutput = simul_backward_linear_model(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations);
|
||||
simulation = simul_backward_linear_model(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations);
|
||||
else
|
||||
DynareOutput = simul_backward_nonlinear_model(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations);
|
||||
simulation = simul_backward_nonlinear_model(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations);
|
||||
end
|
|
@ -1,8 +1,8 @@
|
|||
function [initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, nx, ny1, iy1, jdx, model_dynamic, y] = simul_backward_model_init(varargin)
|
||||
function [initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, endonames, exonames, nx, ny1, iy1, jdx, model_dynamic, y] = simul_backward_model_init(varargin)
|
||||
|
||||
% Initialization of the routines simulating backward models.
|
||||
|
||||
% Copyright (C) 2012-2017 Dynare Team
|
||||
% Copyright (C) 2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
|
@ -20,17 +20,136 @@ function [initialconditions, samplesize, innovations, DynareOptions, DynareModel
|
|||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
initialconditions = varargin{1};
|
||||
samplesize = varargin{2};
|
||||
|
||||
if ~isdseries(initialconditions)
|
||||
error('First input argument must be a dseries object')
|
||||
end
|
||||
|
||||
samplesize = varargin{2};
|
||||
DynareOptions = varargin{3};
|
||||
DynareModel = varargin{4};
|
||||
DynareOutput = varargin{5};
|
||||
|
||||
% Test if the model is backward.
|
||||
if DynareModel.maximum_lead
|
||||
error('simul_backward_nonlinear_model:: The specified model is not backward looking!')
|
||||
end
|
||||
|
||||
if nargin<6
|
||||
% Test if the first argument is a dseries object.
|
||||
if ~isdseries(initialconditions)
|
||||
error('First input argument must be a dseries object!')
|
||||
end
|
||||
|
||||
% Test if the first argument contains all the lagged endogenous variables
|
||||
endonames = cellstr(DynareModel.endo_names);
|
||||
missingendogenousvariables = setdiff(endonames, initialconditions.name);
|
||||
endolags = get_lags_on_endogenous_variables(DynareModel);
|
||||
endolags_ = endolags(find(endolags));
|
||||
endowithlagnames = endonames(find(endolags));
|
||||
if ~isempty(missingendogenousvariables)
|
||||
missingendogenousvariables = setdiff(endowithlagnames, initialconditions.name);
|
||||
missingendogenouslaggedvariables = intersect(endowithlagnames, missingendogenousvariables);
|
||||
if ~isempty(missingendogenouslaggedvariables)
|
||||
disp('You have to initialize the following endogenous variables:')
|
||||
msg = sprintf('%s\n', missingendogenouslaggedvariables{1:end-1});
|
||||
msg = sprintf('%s%s', msg, missingendogenouslaggedvariables{end});
|
||||
disp(msg)
|
||||
skipline()
|
||||
error('Please fix the dseries object used for setting the initial conditions!')
|
||||
end
|
||||
end
|
||||
|
||||
% Test if we have enough periods in the database.
|
||||
maxlag = abs(min(endolags));
|
||||
if maxlag>initialconditions.nobs
|
||||
error('The dseries object provided as first input argument should at least have %s periods!', num2str(maxlag))
|
||||
end
|
||||
missinginitialcondition = false;
|
||||
for i = 1:length(endowithlagnames)
|
||||
lags = abs(endolags_(i));
|
||||
variable = initialconditions{endowithlagnames{i}};
|
||||
nanvalues = isnan(variable.data);
|
||||
if any(nanvalues(end-(lags-1):end))
|
||||
missinginitialcondition = true;
|
||||
for j=variable.nobs:-1:variable.nobs-(lags-1)
|
||||
if isnan(variable.data(j))
|
||||
disp(sprintf('Variable %s should not have a NaN value in period %s.', endowithlagnames{i}, date2string(variable.dates(j))))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if missinginitialcondition
|
||||
skipline()
|
||||
error('Please fix the dseries object used for setting the initial conditions!')
|
||||
end
|
||||
|
||||
% If the model has lags on the exogenous variables, test if we have corresponding initial conditions.
|
||||
exonames = cellstr(DynareModel.exo_names);
|
||||
missingexogenousvariables = setdiff(exonames, initialconditions.name);
|
||||
exolags = get_lags_on_exogenous_variables(DynareModel);
|
||||
exolags_ = exolags(find(exolags));
|
||||
exowithlagnames = exonames(find(exolags));
|
||||
if ~isempty(missingexogenousvariables)
|
||||
missingexogenousvariables = setdiff(exowithlagnames, initialconditions.name);
|
||||
missingexogenouslaggedvariables = intersect(exowithlagnames, missingexogenousvariables);
|
||||
if ~isempty(missingexogenouslaggedvariables)
|
||||
disp('You have to initialize the following exogenous variables:')
|
||||
msg = sprintf('%s\n', missingexogenouslaggedvariables{1:end-1});
|
||||
msg = sprintf('%s%s', msg, missingexogenouslaggedvariables{end});
|
||||
disp(msg)
|
||||
skipline()
|
||||
error('Please fix the dseries object used for setting the initial conditions!')
|
||||
end
|
||||
end
|
||||
|
||||
% Test if we have enough periods in the database.
|
||||
maxlag = abs(min(exolags));
|
||||
if maxlag>initialconditions.nobs
|
||||
error('The dseries object provided as first input argument should at least have %s periods!', num2str(maxlag))
|
||||
end
|
||||
missinginitialcondition = false;
|
||||
for i = 1:length(exowithlagnames)
|
||||
lags = abs(exolags_(i));
|
||||
variable = initialconditions{exowithlagnames{i}};
|
||||
nanvalues = isnan(variable.data);
|
||||
if any(nanvalues(end-(lags-1):end))
|
||||
missinginitialcondition = true;
|
||||
for j=variable.nobs:-1:variable.nobs-(lags-1)
|
||||
if isnan(variable.data(j))
|
||||
disp(sprintf('Variable %s should not have a NaN value in period %s.', exowithlagnames{i}, date2string(variable.dates(j))))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if missinginitialcondition
|
||||
skipline()
|
||||
error('Please fix the dseries object used for setting the initial conditions!')
|
||||
end
|
||||
|
||||
% Add auxiliary variables to the database.
|
||||
k = 0;
|
||||
for i = DynareModel.orig_endo_nbr+1:DynareModel.endo_nbr
|
||||
k = k+1;
|
||||
if DynareModel.aux_vars(k).type==1
|
||||
if ismember(deblank(DynareModel.endo_names(DynareModel.aux_vars(k).orig_index,:)), initialconditions.name)
|
||||
initialconditions{deblank(DynareModel.endo_names(DynareModel.aux_vars(k).endo_index, :))} = ...
|
||||
initialconditions{deblank(DynareModel.endo_names(DynareModel.aux_vars(k).orig_index, :))}.lag(abs(DynareModel.aux_vars(k).orig_lead_lag));
|
||||
else
|
||||
error('This is a bug. Please contact Dynare Team!');
|
||||
end
|
||||
elseif DynareModel.aux_vars(k).type==3
|
||||
if ismember(deblank(DynareModel.exo_names(DynareModel.aux_vars(k).orig_index, :)), initialconditions.name)
|
||||
initialconditions{deblank(DynareModel.endo_names(DynareModel.aux_vars(k).endo_index,:))} = ...
|
||||
initialconditions{deblank(DynareModel.exo_names(DynareModel.aux_vars(k).orig_index, :))}.lag(abs(DynareModel.aux_vars(k).orig_lead_lag));
|
||||
else
|
||||
error('This is a bug. Please contact Dynare Team!');
|
||||
end
|
||||
else
|
||||
error('Cannot simulate the model with this type of auxiliary variables!')
|
||||
end
|
||||
end
|
||||
|
||||
if nargin<6 || isempty(varargin{6})
|
||||
% Set the covariance matrix of the structural innovations.
|
||||
variances = diag(DynareModel.Sigma_e);
|
||||
number_of_shocks = length(DynareModel.Sigma_e);
|
||||
|
@ -52,18 +171,30 @@ if nargin<6
|
|||
% Put the simulated innovations in DynareOutput.exo_simul.
|
||||
DynareOutput.exo_simul = zeros(samplesize,number_of_shocks);
|
||||
DynareOutput.exo_simul(:,positive_var_indx) = DynareOutput.bnlms.shocks;
|
||||
if isfield(DynareModel,'exo_histval') && ~ isempty(DynareModel.exo_histval)
|
||||
DynareOutput.exo_simul = [transpose(DynareModel.exo_histval); DynareOutput.exo_simul];
|
||||
else
|
||||
DynareOutput.exo_simul = [zeros(1,number_of_shocks); DynareOutput.exo_simul];
|
||||
end
|
||||
innovations = DynareOutput.exo_simul;
|
||||
else
|
||||
innovations = varargin{6};
|
||||
DynareOutput.exo_simul = innovations; % innovations
|
||||
end
|
||||
|
||||
if nargout>6
|
||||
% Initialization of the returned simulations.
|
||||
DynareOutput.endo_simul = NaN(DynareModel.endo_nbr, samplesize+initialconditions.nobs);
|
||||
for i=1:length(endonames)
|
||||
if ismember(endonames{i}, initialconditions.name)
|
||||
DynareOutput.endo_simul(i,1:initialconditions.nobs) = transpose(initialconditions{endonames{i}}.data);
|
||||
end
|
||||
end
|
||||
|
||||
% Initialization of the array for the exogenous variables.
|
||||
DynareOutput.exo_simul = [NaN(initialconditions.nobs, DynareModel.exo_nbr); DynareOutput.exo_simul ];
|
||||
for i=1:length(exonames)
|
||||
if ismember(exonames{i}, initialconditions.name)
|
||||
DynareOutput.exo_simul(1:initialconditions.nobs, i) = initialconditions{exonames{i}}.data;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if nargout>8
|
||||
nx = size(DynareOutput.exo_simul,2);
|
||||
ny0 = nnz(DynareModel.lead_lag_incidence(2,:));
|
||||
ny1 = nnz(DynareModel.lead_lag_incidence(1,:));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function DynareOutput = simul_backward_nonlinear_model(varargin)
|
||||
function simulations = simul_backward_nonlinear_model(varargin)
|
||||
|
||||
% Simulates a stochastic non linear backward looking model with arbitrary precision (a deterministic solver is used).
|
||||
%
|
||||
|
@ -38,35 +38,9 @@ function DynareOutput = simul_backward_nonlinear_model(varargin)
|
|||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
[initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, nx, ny1, iy1, jdx, model_dynamic, y] = ...
|
||||
[initialconditions, samplesize, innovations, DynareOptions, DynareModel, DynareOutput, endonames, exonames, nx, ny1, iy1, jdx, model_dynamic, y] = ...
|
||||
simul_backward_model_init(varargin{:});
|
||||
|
||||
model_dynamic_s = str2func('dynamic_backward_model_for_simulation');
|
||||
[ysim, xsim] = simul_backward_nonlinear_model_(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic);
|
||||
|
||||
% initialization of the returned simulations.
|
||||
DynareOutput.endo_simul = NaN(DynareModel.endo_nbr, samplesize);
|
||||
if isempty(initialconditions)
|
||||
if isfield(DynareModel,'endo_histval') && ~isempty(DynareModel.endo_histval)
|
||||
DynareOutput.endo_simul = [DynareModel.endo_histval, DynareOutput.endo_simul];
|
||||
else
|
||||
warning('simul_backward_nonlinear_model:: Initial condition is zero for all variables! The model simulation may fail with the default initialization.')
|
||||
DynareOutput.endo_simul = [zeros(DynareModel.endo_nbr, DynareModel.max_lag_orig), DynareOutput.endo_simul];
|
||||
end
|
||||
else
|
||||
if ~isequal(size(initialconditions, 2), DynareModel.max_lag_orig)
|
||||
error(['simul_backward_nonlinear_model:: First argument should have %s columns!'], DynareModel.max_lag_orig)
|
||||
end
|
||||
DynareOutput.endo_simul = [initialconditions, DynareOutput.endo_simul];
|
||||
end
|
||||
Y = DynareOutput.endo_simul;
|
||||
|
||||
DynareOutput.exo_simul = [ zeros(1, DynareModel.exo_nbr); DynareOutput.exo_simul];
|
||||
|
||||
% Simulations (call a Newton-like algorithm for each period).
|
||||
for it = 1+(1:samplesize)
|
||||
ylag = Y(iy1,it-1); % Set lagged variables.
|
||||
y = Y(:,it-1); % A good guess for the initial conditions is the previous values for the endogenous variables.
|
||||
Y(:,it) = dynare_solve(model_dynamic_s, y, DynareOptions, model_dynamic, ylag, DynareOutput.exo_simul, DynareModel.params, DynareOutput.steady_state, it);
|
||||
end
|
||||
|
||||
DynareOutput.endo_simul = Y;
|
||||
simulations = [dseries(ysim', initialconditions.init, endonames(1:DynareModel.orig_endo_nbr)), dseries(xsim, initialconditions.init, exonames)];
|
|
@ -0,0 +1,55 @@
|
|||
function [ysim, xsim] = simul_backward_nonlinear_model_(initialconditions, samplesize, DynareOptions, DynareModel, DynareOutput, innovations, iy1, model_dynamic)
|
||||
|
||||
% Simulates a stochastic non linear backward looking model with arbitrary precision (a deterministic solver is used).
|
||||
%
|
||||
% INPUTS
|
||||
% - initial_conditions [double] n*1 vector, initial conditions for the endogenous variables.
|
||||
% - sample_size [integer] scalar, number of periods for the simulation.
|
||||
% - DynareOptions [struct] Dynare's options_ global structure.
|
||||
% - DynareModel [struct] Dynare's M_ global structure.
|
||||
% - DynareOutput [struct] Dynare's oo_ global structure.
|
||||
% - innovations [double] T*q matrix, innovations to be used for the simulation.
|
||||
%
|
||||
% OUTPUTS
|
||||
% - DynareOutput [struct] Dynare's oo_ global structure.
|
||||
%
|
||||
% REMARKS
|
||||
% [1] The innovations used for the simulation are saved in DynareOutput.exo_simul, and the resulting paths for the endogenous
|
||||
% variables are saved in DynareOutput.endo_simul.
|
||||
% [2] The last input argument is not mandatory. If absent we use random draws and rescale them with the informations provided
|
||||
% through the shocks block.
|
||||
% [3] If the first input argument is empty, the endogenous variables are initialized with 0, or if available with the informations
|
||||
% provided thrtough the histval block.
|
||||
|
||||
% Copyright (C) 2017 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/>.
|
||||
|
||||
model_dynamic_s = str2func('dynamic_backward_model_for_simulation');
|
||||
|
||||
if ~isempty(innovations)
|
||||
DynareOutput.exo_simul(initialconditions.nobs+(1:samplesize),:) = innovations;
|
||||
end
|
||||
|
||||
% Simulations (call a Newton-like algorithm for each period).
|
||||
for it = initialconditions.nobs+(1:samplesize)
|
||||
ylag = DynareOutput.endo_simul(iy1,it-1); % Set lagged variables.
|
||||
y = DynareOutput.endo_simul(:,it-1); % A good guess for the initial conditions is the previous values for the endogenous variables.
|
||||
DynareOutput.endo_simul(:,it) = dynare_solve(model_dynamic_s, y, DynareOptions, model_dynamic, ylag, DynareOutput.exo_simul, DynareModel.params, DynareOutput.steady_state, it);
|
||||
end
|
||||
|
||||
ysim = DynareOutput.endo_simul(1:DynareModel.orig_endo_nbr,:);
|
||||
xsim = DynareOutput.exo_simul;
|
Loading…
Reference in New Issue