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

221 lines
6.8 KiB
Matlab
Raw Normal View History

2015-02-15 16:49:33 +01:00
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/>.
2015-03-04 09:41:29 +01:00
verbose = options.verbosity;
2015-02-11 22:23:21 +01:00
endogenous_terminal_period = options.endogenous_terminal_period;
vperiods = options.periods*ones(1,options.simul.maxit);
azero = options.dynatol.f/1e7;
2015-02-11 22:23:21 +01:00
lead_lag_incidence = M.lead_lag_incidence;
2015-02-11 22:23:21 +01:00
ny = M.endo_nbr;
2015-02-11 22:23:21 +01:00
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 ;
2015-02-11 22:23:21 +01:00
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)';
2015-01-15 13:55:48 +01:00
i_upd = maximum_lag*ny+(1:periods*ny);
Y = endo_simul(:);
if verbose
skipline()
printline(56)
disp('MODEL SIMULATION:')
skipline()
end
2015-02-11 22:23:21 +01:00
model_dynamic = str2func([M.fname,'_dynamic']);
z = Y(find(lead_lag_incidence'));
2015-02-11 22:23:21 +01:00
[d1,jacobian] = model_dynamic(z,oo.exo_simul, params, ...
2015-01-15 13:55:48 +01:00
steady_state,maximum_lag+1);
res = zeros(periods*ny,1);
2013-12-30 15:41:06 +01:00
o_periods = periods;
ZERO = zeros(length(i_upd),1);
h1 = clock ;
2015-05-25 09:43:21 +02:00
iA = zeros(periods*M.NNZDerivatives(1),3);
for iter = 1:options.simul.maxit
h2 = clock ;
2015-07-07 15:26:49 +02:00
i_rows = (1:ny)';
i_cols_A = find(lead_lag_incidence');
2015-01-15 13:55:48 +01:00
i_cols = i_cols_A+(maximum_lag-1)*ny;
m = 0;
2015-01-15 13:55:48 +01:00
for it = (maximum_lag+1):(maximum_lag+periods)
[d1,jacobian] = model_dynamic(Y(i_cols), exo_simul, params, ...
steady_state,it);
2015-01-15 13:55:48 +01:00
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];
2015-01-15 13:55:48 +01:00
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];
2015-01-15 13:55:48 +01:00
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);
2015-07-07 15:26:49 +02:00
res(i_rows) = d1;
2015-07-07 15:26:49 +02:00
if endogenous_terminal_period && iter>1
dr = max(abs(d1));
2013-12-30 15:41:06 +01:00
if dr<azero
vperiods(iter) = it;
periods = it-maximum_lag+1;
break
end
end
2015-07-07 15:26:49 +02:00
i_rows = i_rows + ny;
i_cols = i_cols + ny;
2015-07-07 15:26:49 +02:00
2015-01-15 13:55:48 +01:00
if it > maximum_lag+1
i_cols_A = i_cols_A + ny;
end
end
2015-07-07 15:26:49 +02:00
err = max(abs(res));
2015-07-07 15:26:49 +02:00
if options_.debug
2015-07-07 15:26:49 +02:00
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))
2015-07-07 15:26:49 +02:00
fprintf('\nWARNING: NaN or Inf detected in the residuals or endogenous variables.\n');
end
if ~isreal(res) || ~isreal(Y)
2015-07-07 15:26:49 +02:00
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
2015-02-11 22:23:21 +01:00
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
2013-12-30 15:41:06 +01:00
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
2015-07-07 15:26:49 +02:00
Y(i_upd) = Y(i_upd) + dy;
end
if endogenous_terminal_period
2015-02-11 22:23:21 +01:00
err = evaluate_max_dynamic_residual(model_dynamic, Y, oo.exo_simul, params, steady_state, o_periods, ny, max_lag, lead_lag_incidence);
2013-12-30 15:41:06 +01:00
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