Commit ee7078e5 authored by MichelJuillard's avatar MichelJuillard
Browse files

factoring out steady-state computations; steady_state_model now

generates <fname>_steadystate2.m returning parameters as well in case
they have been modified by the user. Added several test cases.
parent 8f350dc7
......@@ -73,81 +73,6 @@ if M_.exo_nbr == 0
oo_.exo_steady_state = [] ;
end
% expanding system for Optimal Linear Regulator
if options_.ramsey_policy
if isfield(M_,'orig_model')
orig_model = M_.orig_model;
M_.endo_nbr = orig_model.endo_nbr;
M_.orig_endo_nbr = orig_model.orig_endo_nbr;
M_.aux_vars = orig_model.aux_vars;
M_.endo_names = orig_model.endo_names;
M_.lead_lag_incidence = orig_model.lead_lag_incidence;
M_.maximum_lead = orig_model.maximum_lead;
M_.maximum_endo_lead = orig_model.maximum_endo_lead;
M_.maximum_lag = orig_model.maximum_lag;
M_.maximum_endo_lag = orig_model.maximum_endo_lag;
oo_.steady_state = oo_.steady_state(1:M_.endo_nbr);
end
if options_.steadystate_flag
k_inst = [];
instruments = options_.instruments;
inst_nbr = size(options_.instruments);
for i = 1:inst_nbr
k_inst = [k_inst; strmatch(options_.instruments(i,:), ...
M_.endo_names,'exact')];
end
ys = oo_.steady_state;
if inst_nbr == 1
nl_func = @(x) dyn_ramsey_static_(x,M_,options_,oo_,it_);
% inst_val = fzero(nl_func,oo_.steady_state(k_inst));
inst_val = csolve(nl_func,oo_.steady_state(k_inst),'',options_.solve_tolf,100);
else
[inst_val,info1] = dynare_solve('dyn_ramsey_static_', ...
oo_.steady_state(k_inst),0, ...
M_,options_,oo_,it_);
end
M_.params = evalin('base','M_.params;');
ys(k_inst) = inst_val;
[x,check] = feval([M_.fname '_steadystate'],...
ys,[oo_.exo_steady_state; ...
oo_.exo_det_steady_state]);
M_.params = evalin('base','M_.params;');
if size(x,1) < M_.endo_nbr
if length(M_.aux_vars) > 0
x = add_auxiliary_variables_to_steadystate(x,M_.aux_vars,...
M_.fname,...
oo_.exo_steady_state,...
oo_.exo_det_steady_state,...
M_.params,...
options_.bytecode);
else
error([M_.fname '_steadystate.m doesn''t match the model']);
end
end
oo_.steady_state = x;
[junk,junk,multbar] = dyn_ramsey_static_(oo_.steady_state(k_inst),M_,options_,oo_,it_);
oo_.steady_state = [x(1:M_.orig_endo_nbr); multbar];
else
% xx = oo_.steady_state([1:M_.orig_endo_nbr (M_.orig_endo_nbr+M_.orig_eq_nbr+1):end]);
xx = oo_.steady_state(1:M_.orig_endo_nbr);
[xx,info1] = dynare_solve('dyn_ramsey_static_', ...
xx,0,M_,options_,oo_,it_);
[junk,junk,multbar] = dyn_ramsey_static_(xx,M_,options_,oo_,it_);
oo_.steady_state = [xx; multbar];
end
check1 = max(abs(feval([M_.fname '_static'],...
oo_.steady_state,...
[oo_.exo_steady_state; ...
oo_.exo_det_steady_state], M_.params))) > options_.dynatol ;
if check1
info(1) = 20;
info(2) = check1'*check1;
return
end
dr.ys = oo_.steady_state;
end
klen = M_.maximum_lag + M_.maximum_lead + 1;
iyv = M_.lead_lag_incidence';
iyv = iyv(:);
......@@ -163,24 +88,25 @@ z = repmat(dr.ys,1,klen);
if ~options_.bytecode
z = z(iyr0) ;
end;
exo_ss = [oo_.exo_steady_state' oo_.exo_det_steady_state'];
if options_.order == 1
if (options_.bytecode)
[chck, junk, loc_dr] = bytecode('dynamic','evaluate', z,[oo_.exo_simul ...
oo_.exo_det_simul], M_.params, dr.ys, 1);
[chck, junk, loc_dr] = bytecode('dynamic','evaluate', z,exo_ss, ...
M_.params, dr.ys, 1);
jacobia_ = [loc_dr.g1 loc_dr.g1_x loc_dr.g1_xd];
else
[junk,jacobia_] = feval([M_.fname '_dynamic'],z,[oo_.exo_simul ...
oo_.exo_det_simul], M_.params, dr.ys, it_);
[junk,jacobia_] = feval([M_.fname '_dynamic'],z,exo_ss, ...
M_.params, dr.ys, 1);
end;
elseif options_.order == 2
if (options_.bytecode)
[chck, junk, loc_dr] = bytecode('dynamic','evaluate', z,[oo_.exo_simul ...
oo_.exo_det_simul], M_.params, dr.ys, 1);
[chck, junk, loc_dr] = bytecode('dynamic','evaluate', z,exo_ss, ...
M_.params, dr.ys, 1);
jacobia_ = [loc_dr.g1 loc_dr.g1_x];
else
[junk,jacobia_,hessian1] = feval([M_.fname '_dynamic'],z,...
[oo_.exo_simul ...
oo_.exo_det_simul], M_.params, dr.ys, it_);
exo_ss, ...
M_.params, dr.ys, 1);
end;
if options_.use_dll
% In USE_DLL mode, the hessian is in the 3-column sparse representation
......
function [resids, rJ,mult] = dyn_ramsey_static_(x,M,options_,oo,it_)
function [steady_state,params,check] = dyn_ramsey_static(x,M,options_,oo)
% function [resids, rJ,mult] = dyn_ramsey_static_(x)
% function [steady_state,params,check] = dyn_ramsey_static_(x)
% Computes the static first order conditions for optimal policy
%
% INPUTS
% x: vector of endogenous variables
% x: vector of endogenous variables or instruments
%
% OUTPUTS
% resids: residuals of non linear equations
......@@ -30,13 +30,60 @@ function [resids, rJ,mult] = dyn_ramsey_static_(x,M,options_,oo,it_)
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
global oo_ M_
steady_state = [];
params = M.params;
check = 0;
nl_func = @(x) dyn_ramsey_static_1(x,M,options_,oo);
if options_.steadystate_flag
k_inst = [];
instruments = options_.instruments;
inst_nbr = size(options_.instruments);
for i = 1:inst_nbr
k_inst = [k_inst; strmatch(options_.instruments(i,:), ...
M.endo_names,'exact')];
end
ys = oo.steady_state;
if inst_nbr == 1
inst_val = csolve(nl_func,oo_.steady_state(k_inst),'',options_.solve_tolf,100);
else
[inst_val,info1] = dynare_solve(nl_func,ys(k_inst),0);
end
ys(k_inst) = inst_val;
[x,params,check] = evaluate_steadystate_file(ys,exo_ss,params,M.fname,options_.steadystate_flag);
if size(x,1) < M.endo_nbr
if length(M.aux_vars) > 0
x = feval([M.fname '_set_auxiliary_variables'],xx,...
[oo.exo_steady_state,...
oo.exo_det_steady_state],...
M.params);
else
error([M.fname '_steadystate.m doesn''t match the model']);
end
end
[junk,junk,multbar] = dyn_ramsey_static_1(x(k_inst),M,options_,oo_);
steady_state = [x(1:M.orig_endo_nbr); multbar];
else
xx = oo.steady_state(1:M.orig_endo_nbr);
[xx,info1] = dynare_solve(nl_func,xx,0);
[junk,junk,multbar] = nl_func(xx);
steady_state = [xx; multbar];
end
function [resids, rJ,mult] = dyn_ramsey_static_1(x,M,options_,oo)
resids = [];
rJ = [];
mult = [];
% recovering usefull fields
endo_nbr = M.endo_nbr;
exo_nbr = M.exo_nbr;
orig_endo_nbr = M_.orig_endo_nbr;
orig_eq_nbr = M_.orig_eq_nbr;
orig_endo_nbr = M.orig_endo_nbr;
orig_eq_nbr = M.orig_eq_nbr;
inst_nbr = orig_endo_nbr - orig_eq_nbr;
% indices of Lagrange multipliers
i_mult = [orig_endo_nbr+(1:orig_eq_nbr)]';
......@@ -63,41 +110,26 @@ if options_.steadystate_flag
oo.steady_state,...
[oo.exo_steady_state; ...
oo.exo_det_steady_state]);
if size(x,1) < M.endo_nbr
if length(M.aux_vars) > 0
x = add_auxiliary_variables_to_steadystate(x,M.aux_vars,...
M.fname,...
oo.exo_steady_state,...
oo.exo_det_steady_state,...
M_.params,...
options_.bytecode);
else
error([M.fname '_steadystate.m doesn''t match the model']);
end
end
else
xx = zeros(endo_nbr,1);
xx(1:orig_endo_nbr) = x;
end
xx = feval([M_.fname '_set_auxiliary_variables'],xx,...
[oo.exo_steady_state,...
oo.exo_det_steady_state],...
M_.params);
% setting steady state of auxiliary variables
xx = zeros(endo_nbr,1);
xx(1:orig_endo_nbr) = x(1:orig_endo_nbr);
% x = [x(1:orig_endo_nbr); zeros(orig_eq_nbr,1); x(orig_endo_nbr+1:end)];
end
x = feval([M.fname '_set_auxiliary_variables'],xx,...
[oo.exo_steady_state,...
oo.exo_det_steady_state],...
M.params);
% value and Jacobian of objective function
ex = zeros(1,M.exo_nbr);
[U,Uy,Uyy] = feval([fname '_objective_static'],xx,ex, M_.params);
[U,Uy,Uyy] = feval([fname '_objective_static'],x,ex, M.params);
Uy = Uy';
Uyy = reshape(Uyy,endo_nbr,endo_nbr);
% set multipliers to 0 to compute residuals
it_ = 1;
[f,fJ] = feval([fname '_static'],xx,[oo.exo_simul oo.exo_det_simul], ...
M_.params);
[f,fJ] = feval([fname '_static'],x,[oo.exo_simul oo.exo_det_simul], ...
M.params);
aux_eq = [1:orig_endo_nbr orig_endo_nbr+orig_eq_nbr+1:size(fJ,1)];
A = fJ(aux_eq,orig_endo_nbr+1:end);
......
......@@ -66,31 +66,10 @@ if ~isempty(options_.mode_file) && ~options_.mh_posterior_mode_estimation
load(options_.mode_file);
end
%% Compute the steady state:
if ~isempty(estim_params_)
set_parameters(xparam1);
end
if options_.steadystate_flag% if the *_steadystate.m file is provided.
[ys,tchek] = feval([M_.fname '_steadystate'],...
[zeros(M_.exo_nbr,1);...
oo_.exo_det_steady_state]);
if size(ys,1) < M_.endo_nbr
if length(M_.aux_vars) > 0
ys = add_auxiliary_variables_to_steadystate(ys,M_.aux_vars,...
M_.fname,...
zeros(M_.exo_nbr,1),...
oo_.exo_det_steady_state,...
M_.params,...
options_.bytecode);
else
error([M_.fname '_steadystate.m doesn''t match the model']);
end
end
oo_.steady_state = ys;
else% if the steady state file is not provided.
[dd,info,M_,options_,oo_] = resol(0,M_,options_,oo_);
oo_.steady_state = dd.ys; clear('dd');
end
if all(abs(oo_.steady_state(bayestopt_.mfys))<1e-9)
options_.noconstant = 1;
else
......
function [residuals,check1,jacob] = evaluate_static_model(ys,exo_ss,params,M,options)
% function [ys,info] = evaluate_steady_state(M,options,oo)
% Computes the steady state
%
% INPUTS
% ys vector initial values used to compute the steady
% state
% exo_ss vector exogenous steady state
% params vector parameters
% M struct model structure
% options struct options
%
% OUTPUTS
% residuals vector residuals when ys is not
% the steady state
% check1 scalar error flag
% jacob matrix Jacobian of static model
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2001-2011 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/>.
check1 = 0;
fh_static = str2func([M.fname '_static']);
if options.bytecode
[check1, residuals] = bytecode('evaluate','static',ys,...
exo_ss, params, ys, 1);
mexErrCheck('bytecode', check1);
elseif options.block
residuals = zeros(M.endo_nbr,1);
mfs = M.blocksMFS;
for b = 1:size(mfs,1)
mfsb = mfs{b};
% blocks that can be directly evaluated (mfsb is empty)
% have zero residuals by construction
if ~isempty(mfsb)
residuals(mfsb) = feval(fh_static,b,ys,exo_ss,params);
end
end
else
residuals = feval(fh_static,ys,exo_ss,params);
end
function [ys,params,info] = evaluate_steady_state(ys_init,M,options,oo,steadystate_check_flag)
% function [ys,info] = evaluate_steady_state(M,options,oo)
% Computes the steady state
%
% INPUTS
% ys_init vector initial values used to compute the steady
% state
% M struct model structure
% options struct options
% oo struct output results
% steadystate_check_flag boolean if true, check that the
% steadystate verifies the
% static model
%
% OUTPUTS
% ys vector steady state
% params vector model parameters possibly
% modified by user steadystate
% function
% info 2x1 vector error codes
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2001-2011 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/>.
info = 0;
check = 0;
steadystate_flag = options.steadystate_flag;
params = M.params;
exo_ss = [oo.exo_steady_state; oo.exo_det_steady_state];
updated_params_flag = 0;
fh_static = str2func([M.fname '_static']);
if length(M.aux_vars) > 0
h_set_auxiliary_variables = str2func([M.fname '_set_auxiliary_variables']);
ys_init = h_set_auxiliary_variables(ys_init,exo_ss,M.params);
end
if options.ramsey_policy
[ys,params] = dyn_ramsey_static(ys_init,M,options,oo);
elseif steadystate_flag
% explicit steady state file
[ys,params1,check] = evaluate_steady_state_file(ys_init,exo_ss,params,M.fname,steadystate_flag);
updated_params_flag = max(abs(params1-params)) > 1e-12;
if updated_params_flag
params = params1;
end
% adding values for auxiliary variables
if length(M.aux_vars) > 0
ys = h_set_auxiliary_variables(ys,exo_ss,M.params);
end
check1 = 0;
if steadystate_check_flag
% Check whether the steady state obtained from the _steadystate file is a steady state.
[residuals,check] = evaluate_static_model(ys,exo_ss,params,M,options);
if check
info(1) = 19;
info(2) = check; % to be improved
return;
end
if max(abs(residuals)) > options.dynatol
info(1) = 19;
info(2) = residuals'*residuals;
return
end
elseif ~isempty(options.steadystate_partial)
ssvar = options.steadystate_partial.ssvar;
nov = length(ssvar);
indv = zeros(nov,1);
for i = 1:nov
indv(i) = strmatch(ssvar(i),M.endo_names,'exact');
end
[ys,check] = dynare_solve('restricted_steadystate',...
ys(indv),...
options.jacobian_flag, ...
exo_ss,indv);
end
elseif (options.bytecode == 0 && options.block == 0)
if options.linear == 0
% non linear model
[ys,check] = dynare_solve(fh_static,...
ys_init,...
options.jacobian_flag, ...
exo_ss, params);
else
% linear model
[fvec,jacob] = feval(fh_static,ys_init,exo_ss, ...
params);
if max(abs(fvec)) > 1e-12
ys = ys_init-jacob\fvec;
else
ys = ys_init;
end
end
else
% block or bytecode
[ys,check] = dynare_solve_block_or_bytecode(ys_init,exo_ss, params);
end
if check
if options.steadystate_flag
info(1)= 19;
resid = check1 ;
else
info(1)= 20;
resid = evaluate_static_model(ys_init,exo_ss,params,M,options);
end
info(2) = resid'*resid ;
return
end
if ~isreal(ys)
info(1) = 21;
info(2) = sum(imag(ys).^2);
ys = real(ys);
return
end
if ~isempty(find(isnan(ys)))
info(1) = 22;
info(2) = NaN;
return
end
if options.steadystate_flag && updated_params_flag && ~isreal(M.params)
info(1) = 23;
info(2) = sum(imag(M.params).^2);
return
end
if options.steadystate_flag && updated_params_flag && ~isempty(find(isnan(M.params)))
info(1) = 24;
info(2) = NaN;
return
end
function [ys,params1,check] = evaluate_steady_state_file(ys_init,exo_ss,params,fname,steadystate_flag)
% function [ys,params1,check] = evaluate_steady_state_file(ys_init,exo_ss,params,steadystate_flag)
% Evaluates steady state files
%
% INPUTS
% ys_init vector initial values used to compute the steady
% state
% exo_ss vector exogenous steady state
% params vector parameters
% steadystate_check_flag boolean if true, check that the
% steadystate verifies the
% static model
%
% OUTPUTS
% ys vector steady state
% params1 vector model parameters possibly
% modified by user steadystate
% function
% check 2x1 vector error codes
%
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2001-2011 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 steadystate_flag == 1
% old format
h_steadystate = str2func([fname '_steadystate']);
[ys,check] = h_steadystate(ys_init, exo_ss);
params1 = evalin('base','M_.params');
else % steadystate_flag == 2
% new format
h_steadystate = str2func([fname '_steadystate2']);
[ys,params1,check] = h_steadystate(ys_init, exo_ss, params);
end
\ No newline at end of file
......@@ -60,12 +60,15 @@ options_.threads.kronecker.A_times_B_kronecker_C = 1;
options_.threads.kronecker.sparse_hessian_times_B_kronecker_C = 1;
% steady state file
if exist([M_.fname '_steadystate.m'],'file')
if exist([M_.fname '_steadystate2.m'],'file')
options_.steadystate_flag = 2;
elseif exist([M_.fname '_steadystate.m'],'file')
options_.steadystate_flag = 1;
else
options_.steadystate_flag = 0;
end
options_.steadystate_partial = [];
options_.steadystate.nocheck = 0;
% subset of the estimated deep parameters
options_.ParamSubSet = 'None';
......
......@@ -3,12 +3,12 @@ function DynareResults = initial_estimation_checks(xparam1,DynareDataset,Model,E
% Checks data (complex values, ML evaluation, initial values, BK conditions,..)
%
% INPUTS
% xparam1: vector of parameters to be estimated
% gend: scalar specifying the number of observations
% data: matrix of data
% xparam1: vector of parameters to be estimated
% gend: scalar specifying the number of observations
% data: matrix of data
%
% OUTPUTS
% none
% DynareResults structure of temporary results
%
% SPECIAL REQUIREMENTS
% none
......@@ -34,56 +34,16 @@ if DynareDataset.info.nvobs>Model.exo_nbr+EstimatedParameters.nvn
error(['initial_estimation_checks:: Estimation can''t take place because there are less shocks than observed variables!'])
end
% check if steady state solves static model (except if diffuse_filter == 1)
[DynareResults.steady_state] = ...
evaluate_steady_state(DynareResults.steady_state,Model,DynareOptions,DynareResults,DynareOptions.diffuse_filter==0);
if DynareOptions.dsge_var
[fval,cost_flag,info] = DsgeVarLikelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults);
else
[fval,cost_flag,ys,trend_coeff,info] = DsgeLikelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults);
end
% when their is an analytical steadystate, check that the values
% returned by *_steadystate match with the static model
if DynareOptions.steadystate_flag
[ys,check] = feval([Model.fname '_steadystate'],...