2022-04-10 15:51:55 +02:00
|
|
|
function [steady_state, params, check] = dyn_ramsey_static(ys_init, M, options_, oo)
|
2009-12-16 18:17:34 +01:00
|
|
|
|
2016-03-25 20:16:43 +01:00
|
|
|
% Computes the steady state for optimal policy
|
2009-12-16 18:17:34 +01:00
|
|
|
%
|
|
|
|
% INPUTS
|
2016-03-25 20:16:43 +01:00
|
|
|
% ys_init: vector of endogenous variables or instruments
|
|
|
|
% M: Dynare model structure
|
|
|
|
% options: Dynare options structure
|
|
|
|
% oo: Dynare results structure
|
2017-05-16 15:10:20 +02:00
|
|
|
%
|
2009-12-16 18:17:34 +01:00
|
|
|
% OUTPUTS
|
2016-03-25 20:16:43 +01:00
|
|
|
% steady_state: steady state value
|
|
|
|
% params: parameters at steady state, potentially updated by
|
|
|
|
% steady_state file
|
2016-08-02 15:31:13 +02:00
|
|
|
% check: error indicator, 0 if everything is OK
|
2009-12-16 18:17:34 +01:00
|
|
|
%
|
|
|
|
% SPECIAL REQUIREMENTS
|
|
|
|
% none
|
|
|
|
|
2022-04-10 15:51:55 +02:00
|
|
|
% Copyright © 2003-2022 Dynare Team
|
2009-12-16 18:17:34 +01:00
|
|
|
%
|
|
|
|
% 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
|
2021-06-09 17:33:48 +02:00
|
|
|
% along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2011-10-12 21:46:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
params = M.params;
|
|
|
|
check = 0;
|
2016-03-25 20:16:43 +01:00
|
|
|
options_.steadystate.nocheck = 1; %locally disable checking because Lagrange multipliers are not accounted for in evaluate_steady_state_file
|
2017-05-16 15:10:20 +02:00
|
|
|
% dyn_ramsey_static_1 is a subfunction
|
2011-10-12 21:46:50 +02:00
|
|
|
nl_func = @(x) dyn_ramsey_static_1(x,M,options_,oo);
|
|
|
|
|
2014-03-11 13:22:04 +01:00
|
|
|
% check_static_model is a subfunction
|
2021-11-05 12:39:06 +01:00
|
|
|
if ~options_.steadystate_flag && check_static_model(ys_init,M,options_,oo)
|
2014-10-30 11:45:08 +01:00
|
|
|
steady_state = ys_init;
|
2014-03-11 13:22:04 +01:00
|
|
|
return
|
|
|
|
elseif options_.steadystate_flag
|
2011-10-12 21:46:50 +02:00
|
|
|
k_inst = [];
|
2012-04-21 21:16:57 +02:00
|
|
|
inst_nbr = size(options_.instruments,1);
|
2011-10-12 21:46:50 +02:00
|
|
|
for i = 1:inst_nbr
|
2018-10-25 15:01:53 +02:00
|
|
|
k_inst = [k_inst; strmatch(options_.instruments{i}, M.endo_names, 'exact')];
|
2011-10-12 21:46:50 +02:00
|
|
|
end
|
|
|
|
if inst_nbr == 1
|
2015-05-25 10:06:13 +02:00
|
|
|
%solve for instrument, using univariate solver, starting at initial value for instrument
|
2016-08-02 17:09:18 +02:00
|
|
|
[inst_val, info1]= csolve(nl_func,ys_init(k_inst),'',options_.solve_tolf,options_.ramsey.maxit);
|
|
|
|
if info1==1 || info1==3
|
|
|
|
check=81;
|
|
|
|
end
|
|
|
|
if info1==4
|
|
|
|
check=87;
|
2017-05-16 15:10:20 +02:00
|
|
|
end
|
2011-10-12 21:46:50 +02:00
|
|
|
else
|
2015-05-26 15:50:55 +02:00
|
|
|
%solve for instrument, using multivariate solver, starting at
|
|
|
|
%initial value for instrument
|
2022-04-10 22:17:45 +02:00
|
|
|
o_jacobian_flag = options_.jacobian_flag;
|
|
|
|
options_.jacobian_flag = false;
|
|
|
|
[inst_val, errorflag] = dynare_solve(nl_func, ys_init(k_inst), options_.ramsey.maxit, options_.solve_tolf, options_.solve_tolx, options_);
|
|
|
|
options_.jacobian_flag = o_jacobian_flag;
|
2022-04-10 15:51:55 +02:00
|
|
|
if errorflag
|
2016-08-02 17:09:18 +02:00
|
|
|
check=81;
|
|
|
|
end
|
2011-10-12 21:46:50 +02:00
|
|
|
end
|
2014-10-30 11:45:08 +01:00
|
|
|
ys_init(k_inst) = inst_val;
|
2011-11-14 21:58:53 +01:00
|
|
|
exo_ss = [oo.exo_steady_state oo.exo_det_steady_state];
|
2016-08-02 17:09:18 +02:00
|
|
|
[xx,params] = evaluate_steady_state_file(ys_init,exo_ss,M,options_,~options_.steadystate.nocheck); %run steady state file again to update parameters
|
2018-11-13 17:58:42 +01:00
|
|
|
[~,~,steady_state] = nl_func(inst_val); %compute and return steady state
|
2011-10-12 21:46:50 +02:00
|
|
|
else
|
2012-02-02 12:04:15 +01:00
|
|
|
n_var = M.orig_endo_nbr;
|
2011-12-14 21:04:51 +01:00
|
|
|
xx = oo.steady_state(1:n_var);
|
2022-04-10 22:17:45 +02:00
|
|
|
o_jacobian_flag = options_.jacobian_flag;
|
|
|
|
options_.jacobian_flag = false;
|
|
|
|
[xx, errorflag] = dynare_solve(nl_func, xx, options_.ramsey.maxit, options_.solve_tolf, options_.solve_tolx, options_);
|
|
|
|
options_.jacobian_flag = o_jacobian_flag;
|
2022-04-10 15:51:55 +02:00
|
|
|
if errorflag
|
2017-05-02 13:48:25 +02:00
|
|
|
check=81;
|
|
|
|
end
|
2018-11-13 17:58:42 +01:00
|
|
|
[~,~,steady_state] = nl_func(xx);
|
2011-10-12 21:46:50 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-12-14 21:04:51 +01:00
|
|
|
function [resids,rJ,steady_state] = dyn_ramsey_static_1(x,M,options_,oo)
|
2011-10-12 21:46:50 +02:00
|
|
|
resids = [];
|
|
|
|
rJ = [];
|
|
|
|
mult = [];
|
2009-12-16 18:17:34 +01:00
|
|
|
|
|
|
|
% recovering usefull fields
|
2012-02-02 12:04:15 +01:00
|
|
|
params = M.params;
|
2010-05-29 07:48:00 +02:00
|
|
|
endo_nbr = M.endo_nbr;
|
2012-02-02 12:04:15 +01:00
|
|
|
endo_names = M.endo_names;
|
2011-10-12 21:46:50 +02:00
|
|
|
orig_endo_nbr = M.orig_endo_nbr;
|
2012-02-02 12:04:15 +01:00
|
|
|
aux_vars_type = [M.aux_vars.type];
|
2017-05-16 15:10:20 +02:00
|
|
|
orig_endo_aux_nbr = orig_endo_nbr + min(find(aux_vars_type == 6)) - 1;
|
2011-10-12 21:46:50 +02:00
|
|
|
orig_eq_nbr = M.orig_eq_nbr;
|
2012-02-02 12:04:15 +01:00
|
|
|
inst_nbr = orig_endo_aux_nbr - orig_eq_nbr;
|
2011-03-27 16:54:49 +02:00
|
|
|
% indices of Lagrange multipliers
|
2010-05-29 07:48:00 +02:00
|
|
|
fname = M.fname;
|
2009-12-16 18:17:34 +01:00
|
|
|
|
|
|
|
|
|
|
|
if options_.steadystate_flag
|
|
|
|
k_inst = [];
|
|
|
|
instruments = options_.instruments;
|
|
|
|
for i = 1:size(instruments,1)
|
2018-10-25 15:01:53 +02:00
|
|
|
k_inst = [k_inst; strmatch(instruments{i}, endo_names, 'exact')];
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
2014-10-30 11:45:08 +01:00
|
|
|
ys_init=zeros(size(oo.steady_state)); %create starting vector for steady state computation as only instrument value is handed over
|
|
|
|
ys_init(k_inst) = x; %set instrument, the only value required for steady state computation, to current value
|
2014-11-14 12:26:28 +01:00
|
|
|
[x,params,check] = evaluate_steady_state_file(ys_init,... %returned x now has size endo_nbr as opposed to input size of n_instruments
|
2011-11-14 21:58:53 +01:00
|
|
|
[oo.exo_steady_state; ...
|
2017-05-16 15:10:20 +02:00
|
|
|
oo.exo_det_steady_state], ...
|
2016-03-25 20:16:43 +01:00
|
|
|
M,options_,~options_.steadystate.nocheck);
|
2016-08-02 17:09:18 +02:00
|
|
|
if any(imag(x(1:M.orig_endo_nbr))) %return with penalty
|
2020-03-06 18:50:40 +01:00
|
|
|
resids=ones(inst_nbr,1)+sum(abs(imag(x(1:M.orig_endo_nbr)))); %return with penalty
|
2016-08-02 17:09:18 +02:00
|
|
|
steady_state=NaN(endo_nbr,1);
|
2017-05-16 12:42:01 +02:00
|
|
|
return
|
2016-08-02 17:09:18 +02:00
|
|
|
end
|
2021-11-05 08:59:47 +01:00
|
|
|
if check(1) %return
|
2020-03-06 18:55:01 +01:00
|
|
|
resids=ones(inst_nbr,1)+sum(abs(x(1:M.orig_endo_nbr))); %return with penalty
|
|
|
|
steady_state=NaN(endo_nbr,1);
|
|
|
|
return
|
|
|
|
end
|
2016-08-02 17:09:18 +02:00
|
|
|
|
2011-10-12 21:46:50 +02:00
|
|
|
end
|
2011-07-24 20:52:28 +02:00
|
|
|
|
2014-10-30 11:45:08 +01:00
|
|
|
xx = zeros(endo_nbr,1); %initialize steady state vector
|
|
|
|
xx(1:M.orig_endo_nbr) = x(1:M.orig_endo_nbr); %set values of original endogenous variables based on steady state file or initial value
|
|
|
|
|
|
|
|
% setting steady state of auxiliary variables that depends on original endogenous variables
|
|
|
|
if any([M.aux_vars.type] ~= 6) %auxiliary variables other than multipliers
|
2011-12-14 21:04:51 +01:00
|
|
|
needs_set_auxiliary_variables = 1;
|
2017-08-29 10:58:39 +02:00
|
|
|
if M.set_auxiliary_variables
|
2018-06-27 17:02:13 +02:00
|
|
|
fh = str2func([M.fname '.set_auxiliary_variables']);
|
2017-08-29 10:58:39 +02:00
|
|
|
s_a_v_func = @(z) fh(z,...
|
|
|
|
[oo.exo_steady_state,...
|
|
|
|
oo.exo_det_steady_state],...
|
|
|
|
params);
|
|
|
|
else
|
|
|
|
s_a_v_func = z;
|
|
|
|
end
|
2012-02-02 12:04:15 +01:00
|
|
|
xx = s_a_v_func(xx);
|
2011-12-14 21:04:51 +01:00
|
|
|
else
|
|
|
|
needs_set_auxiliary_variables = 0;
|
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
|
2011-12-14 21:04:51 +01:00
|
|
|
% set multipliers and auxiliary variables that
|
|
|
|
% depends on multipliers to 0 to compute residuals
|
2012-06-06 16:29:26 +02:00
|
|
|
if (options_.bytecode)
|
2020-01-10 17:55:57 +01:00
|
|
|
[res, junk] = bytecode('static',xx,[oo.exo_steady_state oo.exo_det_steady_state], ...
|
|
|
|
params, 'evaluate');
|
2017-05-16 15:10:20 +02:00
|
|
|
fJ = junk.g1;
|
2012-06-06 16:29:26 +02:00
|
|
|
else
|
2018-06-27 17:02:13 +02:00
|
|
|
[res,fJ] = feval([fname '.static'],xx,[oo.exo_steady_state oo.exo_det_steady_state], ...
|
2017-05-16 15:10:20 +02:00
|
|
|
params);
|
2012-06-06 16:29:26 +02:00
|
|
|
end
|
2011-12-14 21:04:51 +01:00
|
|
|
% index of multipliers and corresponding equations
|
|
|
|
% the auxiliary variables before the Lagrange multipliers are treated
|
|
|
|
% as ordinary endogenous variables
|
2016-04-04 17:11:03 +02:00
|
|
|
A = fJ(1:orig_endo_aux_nbr,orig_endo_nbr+find(aux_vars_type==6));
|
|
|
|
y = res(1:orig_endo_aux_nbr);
|
2014-03-11 13:22:04 +01:00
|
|
|
mult = -A\y;
|
2009-12-16 18:17:34 +01:00
|
|
|
|
2014-03-11 13:22:04 +01:00
|
|
|
resids1 = y+A*mult;
|
2011-06-22 11:31:35 +02:00
|
|
|
if inst_nbr == 1
|
|
|
|
r1 = sqrt(resids1'*resids1);
|
|
|
|
else
|
|
|
|
[q,r,e] = qr([A y]');
|
2012-02-02 12:04:15 +01:00
|
|
|
k = size(A,1)+(1-inst_nbr:0);
|
|
|
|
r1 = r(end,k)';
|
2011-06-22 11:31:35 +02:00
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
if options_.steadystate_flag
|
2011-06-22 11:31:35 +02:00
|
|
|
resids = r1;
|
2009-12-16 18:17:34 +01:00
|
|
|
else
|
2012-02-02 12:04:15 +01:00
|
|
|
resids = [res(orig_endo_nbr+(1:orig_endo_nbr-inst_nbr)); r1];
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
rJ = [];
|
2014-03-11 13:22:04 +01:00
|
|
|
if needs_set_auxiliary_variables
|
|
|
|
steady_state = s_a_v_func([xx(1:orig_endo_aux_nbr); mult]);
|
|
|
|
else
|
|
|
|
steady_state = [xx(1:orig_endo_aux_nbr); mult];
|
|
|
|
end
|
|
|
|
|
|
|
|
function result = check_static_model(ys,M,options_,oo)
|
|
|
|
result = false;
|
|
|
|
if (options_.bytecode)
|
2020-01-10 17:55:57 +01:00
|
|
|
[res, ~] = bytecode('static',ys,[oo.exo_steady_state oo.exo_det_steady_state], ...
|
|
|
|
M.params, 'evaluate');
|
2014-03-11 13:22:04 +01:00
|
|
|
else
|
2018-06-27 17:02:13 +02:00
|
|
|
res = feval([M.fname '.static'],ys,[oo.exo_steady_state oo.exo_det_steady_state], ...
|
2014-03-11 13:22:04 +01:00
|
|
|
M.params);
|
|
|
|
end
|
|
|
|
if norm(res) < options_.solve_tolf
|
|
|
|
result = true;
|
|
|
|
end
|