From 5ce20179bd96a6ab44455a901f098cd465d2ee39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Tue, 2 May 2017 23:04:07 +0200 Subject: [PATCH] Added specialized code for the inversion of backward models. --- matlab/backward_model_inversion.m | 121 +++++++++++++++++++++++++++ matlab/dynamic_model_for_inversion.m | 39 +++++++++ matlab/model_inversion.m | 26 +++--- 3 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 matlab/backward_model_inversion.m create mode 100644 matlab/dynamic_model_for_inversion.m diff --git a/matlab/backward_model_inversion.m b/matlab/backward_model_inversion.m new file mode 100644 index 000000000..ed144cbcf --- /dev/null +++ b/matlab/backward_model_inversion.m @@ -0,0 +1,121 @@ +function [endogenousvariables, exogenousvariables] = backward_model_inversion(constraints, exogenousvariables, initialconditions, endo_names, exo_names, freeinnovations, DynareModel, DynareOptions, DynareOutput) + +% INPUTS +% - constraints [dseries] with N constrained endogenous variables from t1 to t2. +% - exogenousvariables [dseries] with Q exogenous variables. +% - initialconditions [dseries] with M endogenous variables starting before t1 (M initialcond must contain at least the state variables). +% - endo_names [cell] list of endogenous variable names. +% - exo_names [cell] list of exogenous variable names. +% - freeinstruments [cell] list of exogenous variable names used to control the constrained endogenous variables. +% +% OUTPUTS +% - endogenous [dseries] +% - exogenous [dseries] +% +% REMARKS + +% 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 . + +% Get indices for the calibrated and free innovations. +freeinnovations_id = zeros(length(freeinnovations), 1); +if length(freeinnovations)0); + +% Get indices of variables appearing at time t. +iy0 = find(DynareModel.lead_lag_incidence(2,:)>0); + +% Set indices for trust_region algorithm. +idx = 1:DynareModel.endo_nbr; +jdx = 1:(nyfree+nxfree); + +% Build structure to be passed to the objective function. +ModelInversion.nyfree = nyfree; +ModelInversion.nyctrl = nyctrl; +ModelInversion.nxfree = nxfree; +ModelInversion.nxcalb = nxcalb; +ModelInversion.y_constrained_id = vec(DynareModel.lead_lag_incidence(2,controlledendogenousvariables_id)); +ModelInversion.y_free_id = vec(DynareModel.lead_lag_incidence(2,freeendogenousvariables_id)); +ModelInversion.x_free_id = freeinnovations_id; +ModelInversion.J_id = [ModelInversion.y_free_id ; sum(DynareModel.lead_lag_incidence(:)>0)+ModelInversion.x_free_id]; + +% Get the name of the dynamic model routines. +model_dynamic = str2func([DynareModel.fname,'_dynamic']); +model_dtransf = str2func('dynamic_model_for_inversion'); + +% Initialization of vector y (free endogenous variables and free innovations). +y = NaN(nyfree+nxfree); + +% Initialization of the returned simulations (endogenous variables). +Y = NaN(DynareModel.endo_nbr, nobs(constraints)+1); +initialconditions +constraints.dates(1) +Y(:,1) = initialconditions(constraints.dates(1)-1).data(1:DynareModel.endo_nbr); +for i=1:nyctrl + Y(controlledendogenousvariables_id(i),2:end) = transpose(constraints.data(:,i)); +end + +% Initialization of the returned simulations (exogenous variables). +X = exogenousvariables{exo_names{:}}.data; + +% Inversion of the model, solvers for the free endogenous and exogenous variables (call a Newton-like algorithm in each period). +for it = 2:nobs(constraints)+1 + % Set the lagged values of the endogenous variables. + ylag = Y(iy1,it-1); + % Set the current values of the constrained endogenous variables. + ycur = Y(controlledendogenousvariables_id,it); + % Vector z gather the free endogenous variables (initialized with lagged + % values) and the free exogenous variables (initialized with 0). + z = [Y(freeendogenousvariables_id,it-1); zeros(nxfree, 1)]; + % Solves for z. + z = dynare_solve(model_dtransf, z, DynareOptions, model_dynamic, ylag, ycur, X, DynareModel.params, DynareOutput.steady_state, it, ModelInversion); + % Update the matrix of exogenous variables. + X(it,freeinnovations_id) = z(nyfree+1:end); + % Update the matrix of endogenous variables. + Y(freeendogenousvariables_id,it) = z(1:nyfree); +end + +endogenousvariables = dseries(Y', constraints.dates(1)-1, endo_names); +exogenousvariables = dseries(X(2:end,:), constraints.dates(1), exo_names); \ No newline at end of file diff --git a/matlab/dynamic_model_for_inversion.m b/matlab/dynamic_model_for_inversion.m new file mode 100644 index 000000000..995f1b71f --- /dev/null +++ b/matlab/dynamic_model_for_inversion.m @@ -0,0 +1,39 @@ +function [r, J] = dynamic_model_for_inversion(z, dynamicmodel, ylag, ycur, x, params, steady_state, it_, ModelInversion) + +% 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 . + +% Set up y +y = zeros(length(ylag)+ModelInversion.nyfree+ModelInversion.nyctrl,1); +y(1:length(ylag)) = ylag; + +y(ModelInversion.y_constrained_id) = ycur; +if ModelInversion.nyfree + y(ModelInversion.y_free_id) = z(1:ModelInversion.nyfree); +end + +% Update x +x(it_, ModelInversion.x_free_id) = transpose(z(ModelInversion.nyfree+(1:ModelInversion.nxfree))); + +if nargout>1 + [r, Jacobian] = feval(dynamicmodel, y, x, params, steady_state, it_); +else + r = feval(dynamicmodel, y, x, params, steady_state, it_); + return +end + +J = Jacobian(:,ModelInversion.J_id); \ No newline at end of file diff --git a/matlab/model_inversion.m b/matlab/model_inversion.m index 311dc1ef2..6c873c655 100644 --- a/matlab/model_inversion.m +++ b/matlab/model_inversion.m @@ -1,12 +1,13 @@ -function [endogenousvariables, exogenousvariables] = model_inversion(constraints, exogenousvariables, initialconditions, DynareModel) - -global oo_ +function [endogenousvariables, exogenousvariables] = model_inversion(constraints, ... + exogenousvariables, ... + initialconditions, DynareModel, DynareOptions, DynareOutput) % INPUTS % - constraints [dseries] with N constrained endogenous variables from t1 to t2. % - exogenousvariables [dseries] with Q exogenous variables. % - initialconditions [dseries] with M endogenous variables starting before t1 (M initialcond must contain at least the state variables). % - DynareModel [struct] M_, Dynare global structure containing informations related to the model. +% - DynareOptions [struct] options_, Dynare global structure containing all the options. % % OUTPUTS % - endogenous [dseries] @@ -31,7 +32,7 @@ global oo_ % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -if ~isequal(nargin, 4) +if ~isequal(nargin, 6) error('model_inversion: This routine require six input arguments!') end @@ -71,6 +72,15 @@ end endo_names = cellstr(DynareModel.endo_names); exo_names = cellstr(DynareModel.exo_names); +% Use specidalized routine if the model is backward looking. +if ~DynareModel.maximum_lead + [endogenousvariables, exogenousvariables] = ... + backward_model_inversion(constraints, exogenousvariables, initialconditions, ... + endo_names, exo_names, freeinnovations, ... + DynareModel, DynareOptions, DynareOutput); + return +end + % Initialize fplan fplan = init_plan(crange); @@ -93,10 +103,4 @@ end f = det_cond_forecast(fplan, initialconditions, crange); endogenousvariables = f{endo_names{:}}; -exogenousvariables = f{exo_names{:}}; - -%if observed_exogenous_variables_flag -% for i=1:length(list_of_observed_exogenous_variables) -% exogenousvariables{list_of_observed_exogenous_variables{i}} = observed_exogenous_variables{list_of_observed_exogenous_variables{i}}; -% end -%end \ No newline at end of file +exogenousvariables = f{exo_names{:}}; \ No newline at end of file