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 . 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 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