function model_diagnostics(M_,options_,oo_) % function model_diagnostics(M_,options_,oo_) % computes various diagnostics on the model % INPUTS % M_ [matlab structure] Definition of the model. % options_ [matlab structure] Global options. % oo_ [matlab structure] Results % % OUTPUTS % none % % ALGORITHM % ... % % SPECIAL REQUIREMENTS % none. % % Copyright © 1996-2023 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 . endo_names = M_.endo_names; lead_lag_incidence = M_.lead_lag_incidence; maximum_endo_lag = M_.maximum_endo_lag; if options_.ramsey_policy %test whether specification matches inst_nbr = size(options_.instruments,1); if inst_nbr~=0 implied_inst_nbr = M_.ramsey_orig_endo_nbr - M_.ramsey_orig_eq_nbr; if inst_nbr>implied_inst_nbr warning('You have specified more steady state instruments than there are omitted equations. While there are use cases for this setup, it is rather unusual. Check whether this is desired.') elseif inst_nbr1e-15); fprintf('\nMODEL_DIAGNOSTICS: The Jacobian of the static model contains imaginary parts. The problem arises from: \n\n') display_problematic_vars_Jacobian(imagrow,imagcol,M_,dr.ys,'static','MODEL_DIAGNOSTICS: ') end try if (~isoctave && matlab_ver_less_than('9.12')) || isempty(options_.jacobian_tolerance) rank_jacob = rank(jacob); %can sometimes fail else rank_jacob = rank(jacob,options_.jacobian_tolerance); %can sometimes fail end catch rank_jacob=size(jacob,1); end if rank_jacob < size(jacob,1) problem_dummy=1; singularity_problem = 1; disp(['MODEL_DIAGNOSTICS: The Jacobian of the static model is ' ... 'singular']) disp(['MODEL_DIAGNOSTICS: there is ' num2str(n_vars_jacob-rank_jacob) ... ' collinear relationships between the variables and the equations']) if (~isoctave && matlab_ver_less_than('9.12')) || isempty(options_.jacobian_tolerance) ncol = null(jacob); else ncol = null(jacob,options_.jacobian_tolerance); %can sometimes fail end n_rel = size(ncol,2); for i = 1:n_rel if n_rel > 1 disp(['Relation ' int2str(i)]) end disp('Collinear variables:') for j=1:10 k = find(abs(ncol(:,i)) > 10^-j); if max(abs(jacob(:,k)*ncol(k,i))) < 1e-6 break end end if options_.block && ~options_.bytecode fprintf('%s\n',endo_names{M_.block_structure_stat.block(b).variable(k)}) else fprintf('%s\n',endo_names{k}) end end if (~isoctave && matlab_ver_less_than('9.12')) || isempty(options_.jacobian_tolerance) neq = null(jacob'); %can sometimes fail else neq = null(jacob',options_.jacobian_tolerance); %can sometimes fail end n_rel = size(neq,2); for i = 1:n_rel if n_rel > 1 disp(['Relation ' int2str(i)]) end disp('Collinear equations') for j=1:10 k = find(abs(neq(:,i)) > 10^-j); if max(abs(jacob(k,:)'*neq(k,i))) < 1e-6 break end end if options_.block && ~options_.bytecode disp(M_.block_structure_stat.block(b).equation(k)) else disp(k') end end end end if singularity_problem try options_check=options_; options_check.noprint=1; [eigenvalues_] = check(M_, options_check, oo_); if any(abs(abs(eigenvalues_)-1)<1e-6) fprintf('MODEL_DIAGNOSTICS: The singularity seems to be (partly) caused by the presence of a unit root\n') fprintf('MODEL_DIAGNOSTICS: as the absolute value of one eigenvalue is in the range of +-1e-6 to 1.\n') fprintf('MODEL_DIAGNOSTICS: If the model is actually supposed to feature unit root behavior, such a warning is expected,\n') fprintf('MODEL_DIAGNOSTICS: but you should nevertheless check whether there is an additional singularity problem.\n') end catch end fprintf('MODEL_DIAGNOSTICS: The presence of a singularity problem typically indicates that there is one\n') fprintf('MODEL_DIAGNOSTICS: redundant equation entered in the model block, while another non-redundant equation\n') fprintf('MODEL_DIAGNOSTICS: is missing. The problem often derives from Walras Law.\n') end %%check dynamic Jacobian klen = M_.maximum_lag + M_.maximum_lead + 1; exo_simul = [repmat(oo_.exo_steady_state',klen,1) repmat(oo_.exo_det_steady_state',klen,1)]; iyv = M_.lead_lag_incidence'; iyv = iyv(:); iyr0 = find(iyv) ; it_ = M_.maximum_lag + 1; z = repmat(dr.ys,1,klen); if options_.order == 1 if (options_.bytecode) [~, loc_dr] = bytecode('dynamic','evaluate', M_, options_, z, exo_simul, ... M_.params, dr.ys, 1); jacobia_ = [loc_dr.g1 loc_dr.g1_x loc_dr.g1_xd]; else [~,jacobia_] = feval([M_.fname '.dynamic'],z(iyr0),exo_simul, ... M_.params, dr.ys, it_); end elseif options_.order >= 2 if (options_.bytecode) [~, loc_dr] = bytecode('dynamic','evaluate', M_, options_, z, exo_simul, ... M_.params, dr.ys, 1); jacobia_ = [loc_dr.g1 loc_dr.g1_x]; else [~,jacobia_,hessian1] = feval([M_.fname '.dynamic'],z(iyr0),... exo_simul, ... M_.params, dr.ys, it_); end end if any(any(isinf(jacobia_) | isnan(jacobia_))) problem_dummy=1; [infrow,infcol]=find(isinf(jacobia_) | isnan(jacobia_)); fprintf('\nMODEL_DIAGNOSTICS: The Jacobian of the dynamic model contains Inf or NaN. The problem arises from: \n\n') display_problematic_vars_Jacobian(infrow,infcol,M_,dr.ys,'dynamic','MODEL_DIAGNOSTICS: ') end if any(any(~isreal(jacobia_))) [imagrow,imagcol]=find(abs(imag(jacobia_))>1e-15); if ~isempty(imagrow) problem_dummy=1; fprintf('\nMODEL_DIAGNOSTICS: The Jacobian of the dynamic model contains imaginary parts. The problem arises from: \n\n') display_problematic_vars_Jacobian(imagrow,imagcol,M_,dr.ys,'dynamic','MODEL_DIAGNOSTICS: ') end end if exist('hessian1','var') if any(any(isinf(hessian1) | isnan(hessian1))) problem_dummy=1; fprintf('\nMODEL_DIAGNOSTICS: The Hessian of the dynamic model contains Inf or NaN.\n') end end if problem_dummy==0 fprintf('MODEL_DIAGNOSTICS: No obvious problems with this mod-file were detected.\n') end