dynare/matlab/perfect-foresight-models/sim1.m

223 lines
6.8 KiB
Matlab

function oo = sim1(M, options, oo)
% function sim1
% Performs deterministic simulations with lead or lag on one period.
% Uses sparse matrices.
%
% INPUTS
% ...
% OUTPUTS
% ...
% ALGORITHM
% ...
%
% SPECIAL REQUIREMENTS
% None.
% Copyright (C) 1996-2015 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/>.
verbose = options.verbosity;
endogenous_terminal_period = options.endogenous_terminal_period;
vperiods = options.periods*ones(1,options.simul.maxit);
azero = options.dynatol.f/1e7;
lead_lag_incidence = M.lead_lag_incidence;
ny = M.endo_nbr;
maximum_lag = M.maximum_lag;
max_lag = M.maximum_endo_lag;
nyp = nnz(lead_lag_incidence(1,:)) ;
ny0 = nnz(lead_lag_incidence(2,:)) ;
nyf = nnz(lead_lag_incidence(3,:)) ;
nd = nyp+ny0+nyf;
stop = 0 ;
periods = options.periods;
steady_state = oo.steady_state;
params = M.params;
endo_simul = oo.endo_simul;
exo_simul = oo.exo_simul;
i_cols_1 = nonzeros(lead_lag_incidence(2:3,:)');
i_cols_A1 = find(lead_lag_incidence(2:3,:)');
i_cols_T = nonzeros(lead_lag_incidence(1:2,:)');
i_cols_0 = nonzeros(lead_lag_incidence(2,:)');
i_cols_A0 = find(lead_lag_incidence(2,:)');
i_cols_j = (1:nd)';
i_upd = maximum_lag*ny+(1:periods*ny);
Y = endo_simul(:);
if verbose
skipline()
printline(56)
disp('MODEL SIMULATION:')
skipline()
end
model_dynamic = str2func([M.fname,'_dynamic']);
z = Y(find(lead_lag_incidence'));
[d1,jacobian] = model_dynamic(z,oo.exo_simul, params, ...
steady_state,maximum_lag+1);
res = zeros(periods*ny,1);
o_periods = periods;
if endogenous_terminal_period
ZERO = zeros(length(i_upd),1);
end
h1 = clock ;
iA = zeros(periods*M.NNZDerivatives(1),3);
for iter = 1:options.simul.maxit
h2 = clock ;
i_rows = (1:ny)';
i_cols_A = find(lead_lag_incidence');
i_cols = i_cols_A+(maximum_lag-1)*ny;
m = 0;
for it = (maximum_lag+1):(maximum_lag+periods)
[d1,jacobian] = model_dynamic(Y(i_cols), exo_simul, params, ...
steady_state,it);
if it == maximum_lag+periods && it == maximum_lag+1
[r,c,v] = find(jacobian(:,i_cols_0));
iA((1:length(v))+m,:) = [i_rows(r),i_cols_A0(c),v];
elseif it == maximum_lag+periods
[r,c,v] = find(jacobian(:,i_cols_T));
iA((1:length(v))+m,:) = [i_rows(r),i_cols_A(i_cols_T(c)),v];
elseif it == maximum_lag+1
[r,c,v] = find(jacobian(:,i_cols_1));
iA((1:length(v))+m,:) = [i_rows(r),i_cols_A1(c),v];
else
[r,c,v] = find(jacobian(:,i_cols_j));
iA((1:length(v))+m,:) = [i_rows(r),i_cols_A(c),v];
end
m = m + length(v);
res(i_rows) = d1;
if endogenous_terminal_period && iter>1
dr = max(abs(d1));
if dr<azero
vperiods(iter) = it;
periods = it-maximum_lag+1;
break
end
end
i_rows = i_rows + ny;
i_cols = i_cols + ny;
if it > maximum_lag+1
i_cols_A = i_cols_A + ny;
end
end
err = max(abs(res));
if options.debug
fprintf('\nLargest absolute residual at iteration %d: %10.3f\n',iter,err);
if any(isnan(res)) || any(isinf(res)) || any(isnan(Y)) || any(isinf(Y))
fprintf('\nWARNING: NaN or Inf detected in the residuals or endogenous variables.\n');
end
if ~isreal(res) || ~isreal(Y)
fprintf('\nWARNING: Imaginary parts detected in the residuals or endogenous variables.\n');
end
skipline()
end
if verbose
str = sprintf('Iter: %s,\t err. = %s, \t time = %s',num2str(iter),num2str(err), num2str(etime(clock,h2)));
disp(str);
end
if err < options.dynatol.f
stop = 1 ;
break
end
iA = iA(1:m,:);
A = sparse(iA(:,1),iA(:,2),iA(:,3),periods*ny,periods*ny);
if endogenous_terminal_period && iter>1
dy = ZERO;
dy(1:i_rows(end)) = -A(1:i_rows(end),1:i_rows(end))\res(1:i_rows(end));
else
dy = -A\res;
end
Y(i_upd) = Y(i_upd) + dy;
end
if endogenous_terminal_period
err = evaluate_max_dynamic_residual(model_dynamic, Y, oo.exo_simul, params, steady_state, o_periods, ny, max_lag, lead_lag_incidence);
periods = o_periods;
end
if stop
if any(isnan(res)) || any(isinf(res)) || any(isnan(Y)) || any(isinf(Y)) || ~isreal(res) || ~isreal(Y)
oo.deterministic_simulation.status = false;% NaN or Inf occurred
oo.deterministic_simulation.error = err;
oo.deterministic_simulation.iterations = iter;
oo.deterministic_simulation.periods = vperiods(1:iter);
oo.endo_simul = reshape(Y,ny,periods+maximum_lag+M.maximum_lead);
if verbose
skipline()
disp(sprintf('Total time of simulation: %s.', num2str(etime(clock,h1))))
if ~isreal(res) || ~isreal(Y)
disp('Simulation terminated with imaginary parts in the residuals or endogenous variables.')
else
disp('Simulation terminated with NaN or Inf in the residuals or endogenous variables.')
end
disp('There is most likely something wrong with your model. Try model_diagnostics or another simulation method.')
printline(105)
end
else
if verbose
skipline();
disp(sprintf('Total time of simulation: %s', num2str(etime(clock,h1))))
printline(56)
end
oo.deterministic_simulation.status = true;% Convergency obtained.
oo.deterministic_simulation.error = err;
oo.deterministic_simulation.iterations = iter;
oo.deterministic_simulation.periods = vperiods(1:iter);
oo.endo_simul = reshape(Y,ny,periods+maximum_lag+M.maximum_lead);
end
elseif ~stop
if verbose
skipline();
disp(sprintf('Total time of simulation: %s.', num2str(etime(clock,h1))))
disp('Maximum number of iterations is reached (modify option maxit).')
printline(62)
end
oo.deterministic_simulation.status = false;% more iterations are needed.
oo.deterministic_simulation.error = err;
oo.deterministic_simulation.periods = vperiods(1:iter);
oo.deterministic_simulation.iterations = options.simul.maxit;
end
if verbose
skipline();
end