From 45450651a2c4fcf8161909e461a3f81bd5d48245 Mon Sep 17 00:00:00 2001 From: Johannes Pfeifer Date: Wed, 21 Dec 2022 11:15:01 +0100 Subject: [PATCH] model_info.m: fix display of block decomposition --- doc/manual/source/the-model-file.rst | 58 +++++++------- matlab/model_info.m | 113 +++++++++++++++------------ preprocessor | 2 +- tests/Makefile.am | 2 + tests/model_info/NKM_3_back.mod | 41 ++++++++++ tests/model_info/NKM_3_forward.mod | 41 ++++++++++ 6 files changed, 179 insertions(+), 78 deletions(-) create mode 100644 tests/model_info/NKM_3_back.mod create mode 100644 tests/model_info/NKM_3_forward.mod diff --git a/doc/manual/source/the-model-file.rst b/doc/manual/source/the-model-file.rst index ac0f83733..c8ea90fe3 100644 --- a/doc/manual/source/the-model-file.rst +++ b/doc/manual/source/the-model-file.rst @@ -3428,20 +3428,18 @@ Getting information about the model .. command:: model_info ; model_info (OPTIONS...); - |br| This command provides information about the model. - - When used outside the context of the ``block`` option of the ``model`` block, + |br| This command provides information about the model. By default, it will provide a list of predetermined state variables, forward-looking variables, and purely static variables. - When used in conjunction with the ``block`` option of the ``model`` block, - it displays: + The command also allows to display information on the dynamic and static + versions of the block decomposition of the model: * The normalization of the model: an endogenous variable is - attributed to each equation of the model; + attributed to each equation of the model (the dependent variable); * The block structure of the model: for each block ``model_info`` - indicates its type, the equations number and endogenous - variables belonging to this block. + indicates its type, size as well as the equation number(s) or name tags and + endogenous variables belonging to this block. There are five different types of blocks depending on the @@ -3450,37 +3448,37 @@ Getting information about the model * ``EVALUATE FORWARD`` In this case the block contains only equations where the - endogenous variable attributed to the equation appears - at current period on the left hand side and where no forward looking + dependent variable :math:`j` attributed to the equation appears + contemporaneously on the left hand side and where no forward looking endogenous variables appear. The block has the form: :math:`y_{j,t} = f_j(y_t, y_{t-1}, \ldots, y_{t-k})`. * ``EVALUATE BACKWARD`` - The block contains only equations where the endogenous variable - attributed to the equation appears at current period on the left hand - side and where no backward looking endogenous variables + The block contains only equations where the dependent variable :math:`j` + attributed to the equation appears contemporaneously on the left hand side + and where no backward looking endogenous variables appear. The block has the form: :math:`y_{j,t} = f_j(y_t, y_{t+1}, \ldots, y_{t+k})`. * ``SOLVE BACKWARD x`` - The block contains only equations where the endogenous variable - attributed to the equation does not appear at current period on the + The block contains only equations where the dependent variable :math:`j` + attributed to the equation does not appear contemporaneously on the left hand side and where no forward looking endogenous variables appear. The block has the form: :math:`g_j(y_{j,t}, - y_t, y_{t-1}, \ldots, y_{t-k})=0`. ``x`` is equal to ``SIMPLE`` - if the block has only one equation. If several equations + y_t, y_{t-1}, \ldots, y_{t-k})=0`. Here, ``x`` denotes the subtype of the block. + ``x`` is equal to ``SIMPLE`` if the block has only one equation. If several equations appear in the block, ``x`` is equal to ``COMPLETE``. * ``SOLVE FORWARD x`` - The block contains only equations where the endogenous variable - attributed to the equation does not appear at current period on the + The block contains only equations where the dependent variable :math:`j` + attributed to the equation does not appear contemporaneously on the left hand side and where no backward looking endogenous variables appear. The block has the form: :math:`g_j(y_{j,t}, - y_t, y_{t+1}, \ldots, y_{t+k})=0`. ``x`` is equal to ``SIMPLE`` - if the block has only one equation. If several equations + y_t, y_{t+1}, \ldots, y_{t+k})=0`. Here, ``x`` denotes the subtype of the block. + ``x`` is equal to ``SIMPLE`` if the block has only one equation. If several equations appear in the block, ``x`` is equal to ``COMPLETE``. * ``SOLVE TWO BOUNDARIES x`` @@ -3488,22 +3486,24 @@ Getting information about the model The block contains equations depending on both forward and backward variables. The block looks like: :math:`g_j(y_{j,t}, y_t, y_{t-1}, \ldots, y_{t-k} ,y_t, y_{t+1}, \ldots, - y_{t+k})=0`. ``x`` is equal to ``SIMPLE`` if the block has only - one equation. If several equations appear in the block, ``x`` is - equal to ``COMPLETE``. + y_{t+k})=0`. Here, ``x`` denotes the subtype of the block. + ``x`` is equal to ``SIMPLE`` if the block has only one equation. If several equations + appear in the block, ``x`` is equal to ``COMPLETE``. *Options* - .. option:: static + .. option:: block_static - Prints out the block decomposition of the static - model. Without the ``static`` option, ``model_info`` displays the block - decomposition of the dynamic model. + Prints out the block decomposition of the static model. + + .. option:: block_dynamic + + Prints out the block decomposition of the dynamic model. .. option:: incidence Displays the gross incidence matrix and the reordered incidence - matrix of the block decomposed model. + matrix of the block decomposed model for the ``block_dynamic`` or ``block_static`` options. .. command:: print_bytecode_dynamic_model ; diff --git a/matlab/model_info.m b/matlab/model_info.m index 5744a45f9..054e53e9c 100644 --- a/matlab/model_info.m +++ b/matlab/model_info.m @@ -20,29 +20,42 @@ function model_info(options_model_info_) global M_; -static_ = isfield(options_model_info_, 'static') && options_model_info_.static; +dynamic_ = isfield(options_model_info_, 'block_dynamic') && options_model_info_.block_dynamic; +static_ = isfield(options_model_info_, 'block_static') && options_model_info_.block_static; incidence = isfield(options_model_info_, 'incidence') && options_model_info_.incidence; if static_ - fprintf(' Information about %s (static model)\n',M_.fname); - block_structre_str = 'block_structure_stat'; - nb_leadlag = 1; + temp_string=sprintf('\nInformation about %s (static model)\n',M_.fname); + fprintf(temp_string); + block_structure_str = 'block_structure_stat'; + if ~isfield(M_,'block_structure_stat') + fprintf('\nmodel_info: block information not present; skipping display.\n') + return; + else + nb_leadlag = 1; + end else - fprintf(' Information about %s (dynamic model)\n',M_.fname); - block_structre_str = 'block_structure'; - nb_leadlag = 3; + temp_string=sprintf('\nInformation about %s (dynamic model)\n',M_.fname); + fprintf(temp_string); + block_structure_str = 'block_structure'; + if dynamic_ && isfield(M_,'block_structure') + fprintf('\nmodel_info: block information not present; skipping display.\n') + return; + elseif dynamic_ + nb_leadlag = length([M_.(block_structure_str).incidence.lead_lag]); + end end -if isfield(M_,block_structre_str) +if dynamic_ || static_ || incidence %block information requested if static_ block_structure = M_.block_structure_stat; else block_structure = M_.block_structure; end - fprintf(strcat(' ===================',char(ones(1,length(M_.fname))*'='),'\n\n')); + fprintf([char(ones(1,length(temp_string))*'='),'\n']); nb_blocks=length(block_structure.block); - fprintf('The model has %d equations and is decomposed in %d blocks as follow:\n',M_.endo_nbr,nb_blocks); + fprintf('The model has %d equations and is decomposed into %d blocks as follows:\n',M_.endo_nbr,nb_blocks); fprintf('================================================================================================================================\n'); fprintf('| %10s | %10s | %30s | %31s | %31s |\n','Block no','Size','Block Type','Equation','Dependent variable'); fprintf('|============|============|================================|=================================|=================================|\n'); @@ -62,7 +75,7 @@ if isfield(M_,block_structre_str) fprintf('================================================================================================================================\n'); fprintf('\n'); if static_ - fprintf('%-30s %s','the variable','is used in the following equations contemporaneously'); + fprintf('%-30s %s','The variable','is used contemporaneously in the following equations:'); if(size(block_structure.incidence.sparse_IM,1)>0) IM=sortrows(block_structure.incidence.sparse_IM,2); else @@ -78,14 +91,14 @@ if isfield(M_,block_structre_str) last=IM(i,2); end fprintf('\n\n'); - else + else %dynamic model for k=1:M_.maximum_endo_lag+M_.maximum_endo_lead+1 if(k==M_.maximum_endo_lag+1) - fprintf('%-30s %s','the variable','is used in the following equations Contemporaneously'); + fprintf('%-30s %s','The variable','is used in the following equations contemporaneously'); elseif(k0) IM=sortrows(block_structure.incidence(k).sparse_IM,2); @@ -104,34 +117,36 @@ if isfield(M_,block_structre_str) fprintf('\n\n'); end end - - %printing the gross incidence matrix - IM_star = char([kron(ones(M_.endo_nbr, M_.endo_nbr-1), double(blanks(3))) double(blanks(M_.endo_nbr)')]); - for i = 1:nb_leadlag - n = size(block_structure.incidence(i).sparse_IM,1); - for j = 1:n - if ismember(block_structure.incidence(i).sparse_IM(j,2), M_.state_var) - IM_star(block_structure.incidence(i).sparse_IM(j,1), 3 * (block_structure.incidence(i).sparse_IM(j,2) - 1) + 1) = 'X'; - else - IM_star(block_structure.incidence(i).sparse_IM(j,1), 3 * (block_structure.incidence(i).sparse_IM(j,2) - 1) + 1) = '1'; + if incidence + + %printing the gross incidence matrix + IM_star = char([kron(ones(M_.endo_nbr, M_.endo_nbr-1), double(blanks(3))) double(blanks(M_.endo_nbr)')]); + for i = 1:nb_leadlag + n = size(block_structure.incidence(i).sparse_IM,1); + for j = 1:n + if ismember(block_structure.incidence(i).sparse_IM(j,2), M_.state_var) + IM_star(block_structure.incidence(i).sparse_IM(j,1), 3 * (block_structure.incidence(i).sparse_IM(j,2) - 1) + 1) = 'X'; + else + IM_star(block_structure.incidence(i).sparse_IM(j,1), 3 * (block_structure.incidence(i).sparse_IM(j,2) - 1) + 1) = '1'; + end end end - end - seq = 1: M_.endo_nbr; - blank = [ blanks(cellofchararraymaxlength(M_.endo_names)); blanks(cellofchararraymaxlength(M_.endo_names))]; - for i = 1:M_.endo_nbr - if i == 1 - var_names = char(blank, M_.endo_names{i}); - else - var_names = char(var_names, blank, M_.endo_names{i}); + seq = 1: M_.endo_nbr; + blank = [ blanks(cellofchararraymaxlength(M_.endo_names)); blanks(cellofchararraymaxlength(M_.endo_names))]; + for i = 1:M_.endo_nbr + if i == 1 + var_names = char(blank, M_.endo_names{i}); + else + var_names = char(var_names, blank, M_.endo_names{i}); + end end - end - if incidence topp = [char(kron(double(blanks(ceil(log10(M_.endo_nbr)))),ones(cellofchararraymaxlength(M_.endo_names),1))) var_names' ]; bott = [int2str(seq') blanks(M_.endo_nbr)' blanks(M_.endo_nbr)' IM_star]; - fprintf('\n Gross incidence matrix\n'); - fprintf(' =======================\n'); - disp([topp; bott]); + fprintf('\nGross incidence matrix\n'); + fprintf('=======================\n'); + disp(topp); + skipline; + disp(bott); %printing the reordered incidence matrix IM_star_reordered = char([kron(ones(M_.endo_nbr, M_.endo_nbr-1), double(blanks(3))) double(blanks(M_.endo_nbr)')]); @@ -145,12 +160,12 @@ if isfield(M_,block_structre_str) cur_block = cur_block + 1; end if i == 1 - var_names = [blank; M_.endo_names{block_structure.variable_reordered(i)}]; + var_names = char(blank, M_.endo_names{block_structure.variable_reordered(i)}); else if past_block ~= cur_block - var_names = [var_names; barre_blank; M_.endo_names{block_structure.variable_reordered(i)}]; + var_names = char(var_names, barre_blank, M_.endo_names{block_structure.variable_reordered(i)}); else - var_names = [var_names; blank; M_.endo_names{block_structure.variable_reordered(i)}]; + var_names = char(var_names, blank, M_.endo_names{block_structure.variable_reordered(i)}); end end end @@ -174,7 +189,7 @@ if isfield(M_,block_structre_str) end end end - fprintf('1: non nul element, X: non nul element related to a state variable\n'); + fprintf('\n1: non-null element, X: non-null element related to a state variable\n'); cur_block = 1; i_last = 0; @@ -203,12 +218,14 @@ if isfield(M_,block_structre_str) end bott = [int2str(block_structure.equation_reordered') blanks(M_.endo_nbr)' blanks(M_.endo_nbr)' IM_star_reordered]; - fprintf('\n Reordered incidence matrix\n'); - fprintf(' ==========================\n'); - disp([topp; bott]); - fprintf('1: non nul element, X: non nul element related to a state variable\n'); + fprintf('\nReordered incidence matrix\n'); + fprintf('==========================\n'); + disp(topp); + skipline; + disp(bott); + fprintf('\n1: non-null element, X: non-null element related to a state variable\n'); end -else +else %non-block information % print states if M_.maximum_endo_lag~=0 lag_index=find(M_.lead_lag_incidence(1,:)); @@ -263,7 +280,7 @@ function print_line(names,var_index,lead_lag,M_) else aux_index=find([M_.aux_vars(:).endo_index]==var_index); aux_type=M_.aux_vars(aux_index).type; - if isempty(M_.aux_vars(aux_index).orig_lead_lag) + if ~isfield(M_.aux_vars(aux_index),'orig_lead_lag') || isempty(M_.aux_vars(aux_index).orig_lead_lag) if ismember(aux_type,[1,3]) str = subst_auxvar(var_index, -1, M_); elseif ismember(aux_type,[0,2]) diff --git a/preprocessor b/preprocessor index 21fcfa775..2fd068115 160000 --- a/preprocessor +++ b/preprocessor @@ -1 +1 @@ -Subproject commit 21fcfa7758b83216fa5a823c3ed0eb6a66bdf0a0 +Subproject commit 2fd068115155fb33129178829e655f0e5a0f492c diff --git a/tests/Makefile.am b/tests/Makefile.am index e0f8aead5..08a7b3a69 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -86,6 +86,8 @@ MODFILES = \ estimation/univariate/nls/staticmodel.mod \ estimation/univariate/nls/dynamicmodel1.mod \ estimation/univariate/nls/dynamicmodel2.mod \ + model_info/NKM_3_back.mod \ + model_info/NKM_3_forward.mod \ moments/example1_var_decomp.mod \ moments/example1_bp_test.mod \ moments/test_AR1_spectral_density.mod \ diff --git a/tests/model_info/NKM_3_back.mod b/tests/model_info/NKM_3_back.mod new file mode 100644 index 000000000..35f7792b4 --- /dev/null +++ b/tests/model_info/NKM_3_back.mod @@ -0,0 +1,41 @@ +parameters betta sigma phipi phiy omega kappa r_ss; + +var c r ui; + +varexo pai; + +betta = 0.99; % discount rate patient +sigma = 1.5; % risk aversion param +omega = 0.75; % calvo param +phipi = 1.5; +phiy = 0.5; +r_ss = 0; +kappa = (1-omega)*(1-omega*betta)/omega; + +model(linear); +[name='Euler'] +c = c(+1) - (1/sigma)*(r - r_ss - pai(-2)); +[name='NKPC'] +pai = betta*pai(+2) + kappa*c; +[name='Taylor rule'] +r = phipi*pai + phiy*c + ui; + +end; + +initval; +ui = 0; +c = 0; +r = 0; +end; + +steady; + +shocks; +var pai; +periods 1,2,3,4,5,6,7,8,9,10; +values 0.006, 0.005854795, 0.00550196, 0.0052, 0.0048, 0.0043, 0.0037, 0.0028, 0.0022, 0.0015; +end; +model_info; +model_info(block_static,incidence); + +model_info(block_dynamic,incidence); diff --git a/tests/model_info/NKM_3_forward.mod b/tests/model_info/NKM_3_forward.mod new file mode 100644 index 000000000..3df40ccb3 --- /dev/null +++ b/tests/model_info/NKM_3_forward.mod @@ -0,0 +1,41 @@ +parameters betta sigma phipi phiy omega kappa r_ss; + +var c r ui; + +varexo pai; + +betta = 0.99; % discount rate patient +sigma = 1.5; % risk aversion param +omega = 0.75; % calvo param +phipi = 1.5; +phiy = 0.5; +r_ss = 0; +kappa = (1-omega)*(1-omega*betta)/omega; + +model(linear); +[name='Euler'] +c = c(+1) - (1/sigma)*(r - r_ss - pai(+1)); +[name='NKPC'] +pai = betta*pai(+1) + kappa*c; +[name='Taylor rule'] +r = phipi*pai + phiy*c + ui; + +end; + +initval; +ui = 0; +c = 0; +r = 0; +end; + +steady; + +shocks; +var pai; +periods 1,2,3,4,5,6,7,8,9,10; +values 0.006, 0.005854795, 0.00550196, 0.0052, 0.0048, 0.0043, 0.0037, 0.0028, 0.0022, 0.0015; +end; +model_info; +model_info(block_static,incidence); + +model_info(block_dynamic,incidence);