Fixed routines for backward model simulation (with IRFs and forecasts).

time-shift
Stéphane Adjemian (Scylla) 2017-09-28 10:11:42 +02:00
parent eae4bc91b8
commit 510eccd965
10 changed files with 377 additions and 144 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)];

View File

@ -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;

View File

@ -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

View File

@ -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,:));

View File

@ -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)];

View File

@ -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;