function [deviations, baseline, irfs] = backward_model_irf(initialcondition, innovationbaseline, listofshocks, listofvariables, varargin) % Returns impulse response functions. % % INPUTS % - initialcondition [dseries] Initial conditions for the endogenous variables, or period 0. % - innovationbaseline [dseries] Baseline for the future innovations. If empty the baseline scenario is zero for future shocks. % - listofshocks [cell of strings or dseries] The innovations for which the IRFs need to be computed. % - listofvariables [cell of strings] The endogenous variables which will be returned. % - periods [integer] scalar, the number of periods. % % OUTPUTS % - irfs [struct of dseries] % % REMARKS % - The names of the fields in the returned structure are given by the name % of the innovations listed in the second input argument. Each field gather % the associated paths for endogenous variables listed in the third input % argument. % - If second argument is not empty, periods must not be greater than innovationbaseline.nobs. % Copyright (C) 2017-2018 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 . 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!') end % Set default value for the fourth input argument. if nargin<5 periods = 40; else periods = varargin{1}; end % Set default value for the last input argument (no transformation). if nargin<6 notransform = true; else notransform = false; transform = varargin{2}; end % Check third argument. if ~iscell(listofshocks) error('Third input argument has to be a cell of string or dseries objects!') else if all(cellfun(@ischar, listofshocks)) deterministicshockflag = false; elseif all(cellfun(@isdseries, listofshocks)) deterministicshockflag = true; else error('Elements of third input argument must all be char arrays or dseries objects!') end if deterministicshockflag numberofexperiments = length(listofshocks); exonames = M_.exo_names; initialconditionperiod = initialcondition.dates(end); for i=1:numberofexperiments shock = listofshocks{i}; impulsenames = shock.name; listofunknownexo = setdiff(impulsenames, exonames); if ~isempty(listofunknownexo) disp(listofunknownexo) error('In experiment n°%s, some of the declared shocks are unknown!', int2str(i)) end if initialconditionperiod>=shock.dates(1) error('In experiment n°%s, the shock period must follow %s!', string(initialconditionperiod)) end end end end % Set default initial conditions for the innovations. for i=1:M_.exo_nbr if ~ismember(M_.exo_names{i}, initialcondition.name) initialcondition{M_.exo_names{i}} = dseries(zeros(initialcondition.nobs, 1), initialcondition.dates(1), M_.exo_names{i}); end end % Set default values for the baseline paths. % % TODO zero for all variables is probably a poor choice. It should be % zero for additive exogenous variables and 1 for multiplicative % exogenous variables. Innovations = zeros(periods, M_.exo_nbr); if ~isempty(innovationbaseline) if ~isdseries(innovationbaseline) error('If not empty, the second argument has to be a dseries object!') end if ~isequal(innovationbaseline.dates(1)-initialcondition.dates(end), 1) error('The first date of the second input argument must follow the last date of the first input argument!') end if innovationbaseline.nobs2 allirfs = dseries(transpose(endo_simul__1), initialcondition.init, endonames(1:M_.orig_endo_nbr), DynareModel.endo_names_tex(1:M_.orig_endo_nbr)); end % Extract a sub-dseries object if deterministicshockflag name = sprintf('experiment_%s', int2str(i)); else name = listofshocks{i}; end deviations.(name) = alldeviations{listofvariables{:}}; if nargout>2 irfs.(name) = allirfs{listofvariables{:}}; irfs.(name) = [irfs.(name) dseries(innovations, initialcondition.last+1, exonames)]; end end if nargout>1 baseline = dseries(transpose(endo_simul__0), initialcondition.init, endonames(1:M_.orig_endo_nbr), DynareModel.endo_names_tex(1:M_.orig_endo_nbr)); baseline = [baseline, innovationbaseline]; end