Use sparse representation for evaluating the static model

We also take advantage of the fact that the non-block version is always
available next to the block one, so when we are only interested in the residual
as a whole, we simplify by using the non-block version.
estimate-initial-state
Sébastien Villemot 2023-01-10 16:05:33 +01:00
parent b343f0231d
commit 3c55aa57e1
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
5 changed files with 37 additions and 72 deletions

View File

@ -17,7 +17,7 @@ function [steady_state, params, check] = dyn_ramsey_static(ys_init, M, options_,
% SPECIAL REQUIREMENTS
% none
% Copyright © 2003-2022 Dynare Team
% Copyright © 2003-2023 Dynare Team
%
% This file is part of Dynare.
%
@ -40,6 +40,7 @@ check = 0;
options_.steadystate.nocheck = 1; %locally disable checking because Lagrange multipliers are not accounted for in evaluate_steady_state_file
% dyn_ramsey_static_1 is a subfunction
nl_func = @(x) dyn_ramsey_static_1(x,M,options_,oo);
exo_ss = [oo.exo_steady_state oo.exo_det_steady_state];
% check_static_model is a subfunction
if ~options_.steadystate_flag && check_static_model(ys_init,M,options_,oo)
@ -72,7 +73,6 @@ elseif options_.steadystate_flag
end
end
ys_init(k_inst) = inst_val;
exo_ss = [oo.exo_steady_state oo.exo_det_steady_state];
[xx,params] = evaluate_steady_state_file(ys_init,exo_ss,M,options_,~options_.steadystate.nocheck); %run steady state file again to update parameters
[~,~,steady_state] = nl_func(inst_val); %compute and return steady state
else
@ -107,6 +107,7 @@ inst_nbr = orig_endo_aux_nbr - orig_eq_nbr;
% indices of Lagrange multipliers
fname = M.fname;
exo_ss = [oo.exo_steady_state oo.exo_det_steady_state];
if options_.steadystate_flag
k_inst = [];
@ -117,8 +118,7 @@ if options_.steadystate_flag
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
[x,params,check] = evaluate_steady_state_file(ys_init,... %returned x now has size endo_nbr as opposed to input size of n_instruments
[oo.exo_steady_state; ...
oo.exo_det_steady_state], ...
exo_ss, ...
M,options_,~options_.steadystate.nocheck);
if any(imag(x(1:M.orig_endo_nbr))) %return with penalty
resids=ones(inst_nbr,1)+sum(abs(imag(x(1:M.orig_endo_nbr)))); %return with penalty
@ -141,10 +141,7 @@ if any([M.aux_vars.type] ~= 6) %auxiliary variables other than multipliers
needs_set_auxiliary_variables = 1;
if M.set_auxiliary_variables
fh = str2func([M.fname '.set_auxiliary_variables']);
s_a_v_func = @(z) fh(z,...
[oo.exo_steady_state,...
oo.exo_det_steady_state],...
params);
s_a_v_func = @(z) fh(z, exo_ss, params);
else
s_a_v_func = z;
end
@ -156,12 +153,11 @@ end
% set multipliers and auxiliary variables that
% depends on multipliers to 0 to compute residuals
if (options_.bytecode)
[res, junk] = bytecode('static',xx,[oo.exo_steady_state oo.exo_det_steady_state], ...
params, 'evaluate');
[res, junk] = bytecode('static', xx, exo_ss, params, 'evaluate');
fJ = junk.g1;
else
[res,fJ] = feval([fname '.static'],xx,[oo.exo_steady_state oo.exo_det_steady_state], ...
params);
[res, T_order, T] = feval([fname '.sparse.static_resid'], xx, exo_ss, params);
fJ = feval([fname '.sparse.static_g1'], xx, exo_ss, params, M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr, T_order, T);
end
% index of multipliers and corresponding equations
% the auxiliary variables before the Lagrange multipliers are treated
@ -192,12 +188,11 @@ end
function result = check_static_model(ys,M,options_,oo)
result = false;
exo_ss = [oo.exo_steady_state oo.exo_det_steady_state];
if (options_.bytecode)
[res, ~] = bytecode('static',ys,[oo.exo_steady_state oo.exo_det_steady_state], ...
M.params, 'evaluate');
[res, ~] = bytecode('static', ys, exo_ss, M.params, 'evaluate');
else
res = feval([M.fname '.static'],ys,[oo.exo_steady_state oo.exo_det_steady_state], ...
M.params);
res = feval([M.fname '.sparse.static_resid'], ys, exo_ss, M.params);
end
if norm(res) < options_.solve_tolf
result = true;

View File

@ -20,7 +20,7 @@ function [residuals,check1,jacob] = evaluate_static_model(ys,exo_ss,params,M,opt
% SPECIAL REQUIREMENTS
% none
% Copyright © 2001-2021 Dynare Team
% Copyright © 2001-2023 Dynare Team
%
% This file is part of Dynare.
%
@ -48,27 +48,8 @@ if options.bytecode
jacob = junk.g1;
end
else
fh_static = str2func([M.fname '.static']);
if options.block
residuals = zeros(M.endo_nbr,1);
T = NaN(M.block_structure_stat.tmp_nbr, 1);
for b = 1:length(M.block_structure_stat.block)
[r, yy, T] = feval(fh_static,b,ys,exo_ss,params,T);
if M.block_structure_stat.block(b).Simulation_Type == 1 || ... % evaluateForward
M.block_structure_stat.block(b).Simulation_Type == 2 % evaluateBackward
vidx = M.block_structure_stat.block(b).variable;
r = yy(vidx) - ys(vidx);
end
residuals(M.block_structure_stat.block(b).equation) = r;
end
if nargout==3
jacob=NaN(length(ys));
end
else
if nargout<3
residuals = feval(fh_static,ys,exo_ss,params);
else
[residuals, jacob] = feval(fh_static,ys,exo_ss,params);
end
[residuals, T_order, T] = feval([M.fname '.sparse.static_resid'], ys, exo_ss, params);
if nargout >= 3
jacob = feval([M.fname '.sparse.static_g1'], ys, exo_ss, params, M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr, T_order, T);
end
end

View File

@ -22,7 +22,7 @@ function [ys,params,info] = evaluate_steady_state(ys_init,M,options,oo,steadysta
% SPECIAL REQUIREMENTS
% none
% Copyright © 2001-2022 Dynare Team
% Copyright © 2001-2023 Dynare Team
%
% This file is part of Dynare.
%
@ -279,8 +279,9 @@ elseif steadystate_flag
return
end
elseif ~options.bytecode && ~options.block
static_resid = str2func(sprintf('%s.sparse.static_resid', M.fname));
static_g1 = str2func(sprintf('%s.sparse.static_g1', M.fname));
if ~options.linear
static_model = str2func(sprintf('%s.static', M.fname));
% non linear model
if ismember(options.solve_algo,[10,11])
[lb,ub,eq_index] = get_complementarity_conditions(M,options.ramsey_policy);
@ -295,16 +296,18 @@ elseif ~options.bytecode && ~options.block
ys_init,...
options.steady.maxit, options.solve_tolf, options.solve_tolx, ...
options, exo_ss, params,...
M.endo_nbr,static_model,eq_index);
M.endo_nbr, static_resid, static_g1, ...
M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr, eq_index);
else
[ys, check] = dynare_solve(@static_problem, ys_init, ...
options.steady.maxit, options.solve_tolf, options.solve_tolx, ...
options, exo_ss, params, M.endo_nbr, static_model);
options, exo_ss, params, M.endo_nbr, static_resid, static_g1, ...
M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr);
end
if check && options.debug
[ys, check, fvec, fjac, errorcode] = dynare_solve(@static_problem, ys_init, ...
options.steady.maxit, options.solve_tolf, options.solve_tolx, ...
options, exo_ss, params, M.endo_nbr, static_model);
options, exo_ss, params, M.endo_nbr, static_resid, static_g1, M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr);
dprintf('Nonlinear solver routine returned errorcode=%i.', errorcode)
skipline()
[infrow,infcol]=find(isinf(fjac) | isnan(fjac));
@ -323,9 +326,8 @@ elseif ~options.bytecode && ~options.block
end
else
% linear model
fh_static = str2func([M.fname '.static']);
[fvec,jacob] = fh_static(ys_init,exo_ss, ...
params);
[fvec, T_order, T] = static_resid(ys_init, exo_ss, params);
jacob = static_g1(ys_init, exo_ss, params, M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr, T_order, T);
ii = find(~isfinite(fvec));
if ~isempty(ii)
@ -382,27 +384,12 @@ end
if M.static_and_dynamic_models_differ
% Evaluate residual of *dynamic* model using the steady state
% computed on the *static* one
z = repmat(ys,1,M.maximum_lead + M.maximum_lag + 1);
zx = repmat([exo_ss'], M.maximum_lead + M.maximum_lag + 1, 1);
if options.bytecode
z = repmat(ys,1,M.maximum_lead + M.maximum_lag + 1);
zx = repmat([exo_ss'], M.maximum_lead + M.maximum_lag + 1, 1);
[r, ~]= bytecode('dynamic','evaluate', z, zx, params, ys, 1);
elseif options.block
T=NaN(M.block_structure.dyn_tmp_nbr, 1);
for i = 1:length(M.block_structure.block)
[rr, yy, T, g] = feval([M.fname '.dynamic'], i, ...
dynvars_from_endo_simul(z, M.maximum_lag+1, M), ...
zx, params, ys, T, M.maximum_lag+1, false);
if M.block_structure.block(i).Simulation_Type == 1 || ... % evaluateForward
M.block_structure.block(i).Simulation_Type == 2 % evaluateBackward
vidx = M.block_structure.block(i).variable;
rr = yy(M.lead_lag_incidence(M.maximum_endo_lag+1, vidx)) - oo.steady_state(vidx);
end
idx = M.block_structure.block(i).equation;
r(idx) = rr;
end
else
r = feval([M.fname '.dynamic'], dynvars_from_endo_simul(z, M.maximum_lag+1, M), ...
zx, params, ys, M.maximum_lag + 1);
r = feval([M.fname '.sparse.dynamic_resid'], repmat(ys, 3, 1), exo_ss, params, ys);
end
% Fail if residual greater than tolerance
if max(abs(r)) > options.solve_tolf
@ -424,13 +411,14 @@ if ~isempty(find(isnan(ys)))
return
end
function [resids,jac] = static_problem(y,x,params,nvar,fh_static_model)
[r,j] = fh_static_model(y,x,params);
function [resids,jac] = static_problem(y, x, params, nvar, fh_static_resid, fh_static_g1, sparse_rowval, sparse_colval, sparse_colptr)
[r, T_order, T] = fh_static_resid(y, x, params);
j = fh_static_g1(y, x, params, sparse_rowval, sparse_colval, sparse_colptr, T_order, T);
resids = r(1:nvar);
jac = j(1:nvar,1:nvar);
function [resids,jac] = static_mcp_problem(y,x,params,nvar,fh_static_model,eq_index)
[r,j] = fh_static_model(y,x,params);
function [resids,jac] = static_mcp_problem(y, x, params, nvar, fh_static_resid, fh_static_g1, sparse_rowval, sparse_colval, sparse_colptr, eq_index)
[r, T_order, T] = fh_static_resid(y, x, params);
j = fh_static_g1(y, x, params, sparse_rowval, sparse_colval, sparse_colptr, T_order, T);
resids = r(eq_index);
jac = j(eq_index,1:nvar);

View File

@ -157,7 +157,8 @@ for b=1:nb
int2str(b)]);
end
else
[res,jacob]=feval([M.fname '.static'],dr.ys,exo,M.params);
[res, T_order, T] = feval([M.fname '.sparse.static_resid'], dr.ys, exo, M.params);
jacob = feval([M.fname '.sparse.static_g1'], dr.ys, exo, M.params, M.static_g1_sparse_rowval, M.static_g1_sparse_colval, M.static_g1_sparse_colptr, T_order, T);
end
if any(any(isinf(jacob) | isnan(jacob)))
problem_dummy=1;

@ -1 +1 @@
Subproject commit a4f299c0b781676afe3d9d073a7e2cd0551af997
Subproject commit 35ac73fad8645302c10d0cd0068710ad3847366a