Add specialized version of sim1 for static models.

Also add an integration test and fix homotopy error message.
time-shift
Stéphane Adjemian (Charybdis) 2021-05-28 12:09:02 +02:00
parent 9867203f25
commit 27ee801a67
Signed by: stepan
GPG Key ID: 295C1FE89E17EB3C
7 changed files with 127 additions and 22 deletions

View File

@ -0,0 +1,29 @@
function [r, J] = dynamic_static_model_for_simulation(z, dynamicmodel, x, params, steady_state, it_)
% Copyright © 2021 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/>.
% NOTE: It is assumed that all variables appear at time t in the model.
if nargout>1
% Compute residuals and jacobian of the full dynamic model.
[r, J] = feval(dynamicmodel, z, x, params, steady_state, it_);
J = J(:,1:rows(J)); % Remove derivatives with respect to shocks.
else
% Compute residuals.
r = feval(dynamicmodel, z, x, params, steady_state, it_);
end

View File

@ -70,14 +70,15 @@ if ~oo_.deterministic_simulation.status && ~options_.no_homotopy
fprintf('Switching to a homotopy method...\n')
end
if ~M_.maximum_lag
if ~M_.maximum_lag && M_.maximum_lead>0
disp('Homotopy not implemented for purely forward models!')
disp('Failed to solve the model!')
disp('Return with empty oo_.endo_simul.')
oo_.endo_simul = [];
return
end
if ~M_.maximum_lead
if ~M_.maximum_lead && M_.maximum_lag>0
disp('Homotopy not implemented for purely backward models!')
disp('Failed to solve the model!')
disp('Return with empty oo_.endo_simul.')
@ -85,6 +86,14 @@ if ~oo_.deterministic_simulation.status && ~options_.no_homotopy
return
end
if ~M_.maximum_lead && ~M_.maximum_lag
disp('Homotopy not implemented for purely static models!')
disp('Failed to solve the model!')
disp('Return with empty oo_.endo_simul.')
oo_.endo_simul = [];
return
end
% Disable warnings if homotopy
warning_old_state = warning;
warning off all

View File

@ -75,12 +75,15 @@ else
oo_.deterministic_simulation.status = false;
end
else
if M_.maximum_endo_lead == 0 && ~options_.lmmcp.status % Purely backward model
if M_.maximum_endo_lead == 0 && M_.maximum_endo_lag>0 && ~options_.lmmcp.status % Purely backward model
[oo_.endo_simul, oo_.deterministic_simulation] = ...
sim1_purely_backward(oo_.endo_simul, oo_.exo_simul, oo_.steady_state, M_, options_);
elseif M_.maximum_endo_lag == 0 && ~options_.lmmcp.status % Purely forward model
[oo_.endo_simul, oo_.deterministic_simulation] = ...
sim1_purely_forward(oo_.endo_simul, oo_.exo_simul, oo_.steady_state, M_, options_);
elseif M_.maximum_endo_lag == 0 && M_.maximum_endo_lead>0 && ~options_.lmmcp.status % Purely forward model
[oo_.endo_simul, oo_.deterministic_simulation] = ...
sim1_purely_forward(oo_.endo_simul, oo_.exo_simul, oo_.steady_state, M_, options_);
elseif M_.maximum_endo_lag == 0 && M_.maximum_endo_lead == 0 && ~options_.lmmcp.status % Purely static model
[oo_.endo_simul, oo_.deterministic_simulation] = ...
sim1_purely_static(oo_.endo_simul, oo_.exo_simul, oo_.steady_state, M_, options_);
else % General case
switch options_.stack_solve_algo
case 0

View File

@ -19,15 +19,8 @@ function [endogenousvariables, info] = sim1_purely_backward(endogenousvariables,
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
if size(M.lead_lag_incidence,1) > 1
ny0 = nnz(M.lead_lag_incidence(2,:)); % Number of variables at current period
nyb = nnz(M.lead_lag_incidence(1,:)); % Number of variables at previous period
iyb = find(M.lead_lag_incidence(1,:)>0); % Indices of variables at previous period
else
ny0 = nnz(M.lead_lag_incidence(1,:)); % Number of variables at current period
nyb = 0;
iyb = [];
end
ny0 = nnz(M.lead_lag_incidence(2,:)); % Number of variables at current period
iyb = M.lead_lag_incidence(1,:)>0; % Logical vector (for lagged variables)
if ny0 ~= M.endo_nbr
error('All endogenous variables must appear at the current period!')
@ -43,13 +36,8 @@ dynamicmodel_s = str2func('dynamic_backward_model_for_simulation');
info.status = true;
for it = M.maximum_lag + (1:options.periods)
if M.maximum_lag==0 && it==1
y = endogenousvariables(:,it); % Values at previous period, also used as guess value for current period
ylag = [];
else
y = endogenousvariables(:,it-1); % Values at previous period, also used as guess value for current period
ylag = y(iyb);
end
y = endogenousvariables(:,it-1); % Values at previous period, also used as guess value for current period
ylag = y(iyb);
if ismember(options.solve_algo, [12,14])
[tmp, check] = dynare_solve(dynamicmodel_s, y, options, M.isloggedlhs, M.isauxdiffloggedrhs, M.endo_names, M.lhs, ...
dynamicmodel, ylag, exogenousvariables, M.params, steadystate, it);

View File

@ -0,0 +1,50 @@
function [endogenousvariables, info] = sim1_purely_static(endogenousvariables, exogenousvariables, steadystate, M, options)
% Performs deterministic simulation of a purely static model
% Copyright © 2021 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 nnz(M.lead_lag_incidence(1,:)) ~= M.endo_nbr
error('All endogenous variables must appear at the current period!')
end
if ismember(options.solve_algo, [12,14]) && ~M.possible_to_use_solve_algo_12_14
error(M.message_solve_algo_12_14)
end
dynamicmodel = str2func([M.fname,'.dynamic']);
dynamicmodel_s = str2func('dynamic_static_model_for_simulation');
info.status = true;
y = endogenousvariables(:,1);
for it = 1:options.periods
if ismember(options.solve_algo, [12,14])
[tmp, check] = dynare_solve(dynamicmodel_s, y, options, M.isloggedlhs, M.isauxdiffloggedrhs, M.endo_names, M.lhs, ...
dynamicmodel, exogenousvariables, M.params, steadystate, it);
else
[tmp, check] = dynare_solve(dynamicmodel_s, y, options, ...
dynamicmodel, exogenousvariables, M.params, steadystate, it);
end
if check
info.status = false;
end
endogenousvariables(:,it) = tmp;
y = endogenousvariables(:,it);
end

View File

@ -332,6 +332,7 @@ MODFILES = \
deterministic_simulations/purely_forward/ar1.mod \
deterministic_simulations/purely_forward/nk.mod \
deterministic_simulations/purely_backward/ar1.mod \
deterministic_simulations/purely_static/toto.mod \
deterministic_simulations/rbc_det1.mod \
deterministic_simulations/rbc_det2.mod \
deterministic_simulations/rbc_det3.mod \

View File

@ -0,0 +1,25 @@
var x y;
varexo ex ey;
model;
y = x*x/2 + ey;
x = ex;
end;
initval;
y = 0;
x = 0;
ex = 0;
ey = 0;
end;
steady;
shocks;
var ex;
periods 1 2 3 4;
values 1 .5 .25 .125;
end;
simul(periods=4);