diff --git a/matlab/backward/dynamic_static_model_for_simulation.m b/matlab/backward/dynamic_static_model_for_simulation.m new file mode 100644 index 000000000..8ce608333 --- /dev/null +++ b/matlab/backward/dynamic_static_model_for_simulation.m @@ -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 . + +% 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 \ No newline at end of file diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver.m b/matlab/perfect-foresight-models/perfect_foresight_solver.m index e675b7fec..37bf898f9 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_solver.m +++ b/matlab/perfect-foresight-models/perfect_foresight_solver.m @@ -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 diff --git a/matlab/perfect-foresight-models/perfect_foresight_solver_core.m b/matlab/perfect-foresight-models/perfect_foresight_solver_core.m index 3dac602f6..a1896890e 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_solver_core.m +++ b/matlab/perfect-foresight-models/perfect_foresight_solver_core.m @@ -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 diff --git a/matlab/perfect-foresight-models/sim1_purely_backward.m b/matlab/perfect-foresight-models/sim1_purely_backward.m index 3f155325f..06e5f005c 100644 --- a/matlab/perfect-foresight-models/sim1_purely_backward.m +++ b/matlab/perfect-foresight-models/sim1_purely_backward.m @@ -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 . -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); diff --git a/matlab/perfect-foresight-models/sim1_purely_static.m b/matlab/perfect-foresight-models/sim1_purely_static.m new file mode 100644 index 000000000..ec03a848a --- /dev/null +++ b/matlab/perfect-foresight-models/sim1_purely_static.m @@ -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 . + +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 \ No newline at end of file diff --git a/tests/Makefile.am b/tests/Makefile.am index 52052c2e2..7f66c697b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 \ diff --git a/tests/deterministic_simulations/purely_static/toto.mod b/tests/deterministic_simulations/purely_static/toto.mod new file mode 100644 index 000000000..21f76c702 --- /dev/null +++ b/tests/deterministic_simulations/purely_static/toto.mod @@ -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);