disp_identification.m 13.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
function disp_identification(pdraws, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, name, options_ident)
% disp_identification(pdraws, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, name, options_ident)
% -------------------------------------------------------------------------
% This function displays all identification analysis to the command line
% =========================================================================
% INPUTS
%   pdraws:             [SampleSize by totparam_nbr] parameter draws
%   ide_reducedform:    [structure] Containing results from identification
%                       analysis based on the reduced-form solution (Ratto
%                       and Iskrev, 2011).
%   ide_moments:        [structure] Containing results from identification
%                       analysis based on moments (Iskrev, 2010).
%   ide_spectrum:       [structure] Containing results from identification
%                       analysis based on the spectrum (Qu and Tkachenko, 2012).
%   ide_minimal:        [structure] Containing results from identification
%                       analysis based on the minimal state space system
%                       (Komunjer and Ng, 2011).
%   name:               [totparam_nbr by 1] string cell of parameter names
%   options_ident:      [structure] identification options
% -------------------------------------------------------------------------
% OUTPUTS
%   * all output is printed on the command line
% -------------------------------------------------------------------------
24 25
% This function is called by
%   * dynare_identification.m
26 27
% =========================================================================
% Copyright (C) 2010-2019 Dynare Team
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
%
% 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/>.
43 44 45 46 47 48 49 50
% =========================================================================
[SampleSize, totparam_nbr] = size(pdraws);
no_identification_reducedform      = options_ident.no_identification_reducedform;
no_identification_moments          = options_ident.no_identification_moments;
no_identification_spectrum         = options_ident.no_identification_spectrum;
no_identification_minimal          = options_ident.no_identification_minimal;
tol_rank           = options_ident.tol_rank;
checks_via_subsets = options_ident.checks_via_subsets;
51

52
%% Display settings
53
disp(['  ']),
54 55 56 57
fprintf('Note that differences in the criteria could be due to numerical settings,\n')
fprintf('numerical errors or the method used to find problematic parameter sets.\n')
fprintf('Settings:\n')
if options_ident.analytic_derivation_mode == 0
58
    fprintf('    Derivation mode for Jacobians:                         Analytic using sylvester equations\n');
59
elseif options_ident.analytic_derivation_mode == 1
60
    fprintf('    Derivation mode for Jacobians:                         Analytic using kronecker products\n');
61
elseif options_ident.analytic_derivation_mode < 0
62
    fprintf('    Derivation mode for Jacobians:                         Numerical\n');
63 64
end
if checks_via_subsets
65
    fprintf('    Method to find problematic parameters:                 Rank condition on all possible subsets\n');
66
else
67
    fprintf('    Method to find problematic parameters:                 Nullspace and multicorrelation coefficients\n');
68 69
end
if options_ident.normalize_jacobians == 1
70
    fprintf('    Normalize Jacobians:                                   Yes\n');
71
else
72
    fprintf('    Normalize Jacobians:                                   No\n');
73
end
74
fprintf('    Tolerance level for rank computations:                 %s\n',num2str(options_ident.tol_rank));
75 76
fprintf('    Tolerance level for selecting nonzero columns:         %.0d\n',options_ident.tol_deriv);
fprintf('    Tolerance level for selecting nonzero singular values: %.0d\n',options_ident.tol_sv);
77

78

79 80 81 82 83
%% Display problematic parameter sets for different criteria in a loop
for jide = 1:4
    no_warning_message_display = 1;
    %% Set output strings depending on test
    if jide == 1
84
        strTest = 'REDUCED-FORM'; strJacobian = 'Tau'; strMeaning = 'Jacobian of steady state and reduced-form solution matrices';
85
        if ~no_identification_reducedform
86
            noidentification = 0; ide = ide_reducedform;
87
            if SampleSize == 1
88
                Jacob = ide.dREDUCEDFORM;
89
            end
90 91
        else %skip test
            noidentification = 1; no_warning_message_display = 0;
92
        end
93
    elseif jide == 2
94 95
        strTest = 'MINIMAL SYSTEM (Komunjer and Ng, 2011)'; strJacobian = 'Deltabar'; strMeaning = 'Jacobian of steady state and minimal system';
        if options_ident.order == 2
96
            strMeaning = 'Jacobian of first-order minimal system and second-order accurate mean';
97
        elseif options_ident.order == 3
98
            strMeaning = 'Jacobian of first-order minimal system and third-order accurate mean';
99 100 101
        end
        if ~no_identification_minimal
            noidentification = 0; ide = ide_minimal;
102
            if SampleSize == 1
103
                Jacob = ide.dMINIMAL;
104
            end
105 106
        else %skip test
            noidentification = 1; no_warning_message_display = 0;
107
        end
108
    elseif jide == 3
109 110 111 112 113
        strTest = 'SPECTRUM (Qu and Tkachenko, 2012)'; strJacobian = 'Gbar'; strMeaning = 'Jacobian of mean and spectrum';
        if options_ident.order > 1
            strTest = 'SPECTRUM (Mutschler, 2015)';
        end
        if ~no_identification_spectrum
114
            noidentification = 0; ide = ide_spectrum;
115
            if SampleSize == 1
116
                Jacob = ide.dSPECTRUM;
117
            end
118 119
        else %skip test
            noidentification = 1; no_warning_message_display = 0;
120
        end
121
    elseif jide == 4
122 123 124 125 126
        strTest = 'MOMENTS (Iskrev, 2010)'; strJacobian = 'J'; strMeaning = 'Jacobian of first two moments';
        if options_ident.order > 1
            strTest = 'MOMENTS (Mutschler, 2015)'; strJacobian = 'Mbar';
        end
        if ~no_identification_moments
127
            noidentification = 0; ide = ide_moments;
128
            if SampleSize == 1
129
                Jacob = ide.si_dMOMENTS;
130
            end
131 132
        else %skip test
            noidentification = 1; no_warning_message_display = 0;
133
        end
134
    end
135

136 137 138 139
    if ~noidentification
        %% display problematic parameters computed by identifcation_checks.m
        if ~checks_via_subsets
            if any(ide.ino) || any(any(ide.ind0==0)) || any(any(ide.jweak_pair))
140
                no_warning_message_display=0;
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
                skipline()
                disp([upper(strTest), ':'])
                disp('    !!!WARNING!!!');
                if SampleSize>1
                    disp(['    The rank of ', strJacobian, ' (', strMeaning, ') is deficient for ', num2str(length(find(ide.ino))),' out of ',int2str(SampleSize),' MC runs (with tol = ', num2str(tol_rank), ')!'  ]),
                else
                    disp(['    The rank of ', strJacobian, ' (', strMeaning, ') is deficient by ', num2str(size(Jacob,2)-ide.rank), ' (rank(', strJacobian, ') = ', num2str(ide.rank), ' < ', num2str(size(Jacob,2)), ' with tol = ', num2str(tol_rank), ')!']),
                end
                skipline()
                for j=1:totparam_nbr
                    if any(ide.ind0(:,j)==0)
                        pno = 100*length(find(ide.ind0(:,j)==0))/SampleSize;
                        if SampleSize>1
                            disp(['    ',name{j},' is not identified for ',num2str(pno),'% of MC runs!' ])
                        else
                            disp(['    ',name{j},' is not identified!' ])
                        end
                    end
                end
                npairs=size(ide.jweak_pair,2);
                jmap_pair=dyn_unvech(1:npairs);
                jstore=[];
                for j=1:npairs
                    iweak = length(find(ide.jweak_pair(:,j)));
                    if iweak
                        [jx,jy]=find(jmap_pair==j);
                        jstore=[jstore jx(1) jy(1)];
                        if SampleSize > 1
                            disp(['    [',name{jx(1)},',',name{jy(1)},'] are PAIRWISE collinear for ',num2str((iweak)/SampleSize*100),'% of MC runs!' ])
                        else
                            disp(['    [',name{jx(1)},',',name{jy(1)},'] are PAIRWISE collinear!' ])
                        end
                    end
                end
                for j=1:totparam_nbr
                    iweak = length(find(ide.jweak(:,j)));
                    if iweak && ~ismember(j,jstore)
                        if SampleSize>1
                            disp(['    ',name{j},' is collinear w.r.t. all other parameters for ',num2str(iweak/SampleSize*100),'% of MC runs!' ])
                        else
                            disp(['    ',name{j},' is collinear w.r.t. all other parameters!' ])
                        end
                    end
                end
185
            end
186

187 188
            %% display problematic parameters computed by identification_checks_via_subsets
        elseif checks_via_subsets
189 190 191 192 193 194 195 196 197 198 199 200 201
            if ide.rank < size(Jacob,2)
                no_warning_message_display = 0;
                skipline()
                disp([upper(strTest), ':'])
                disp('    !!!WARNING!!!');
                if SampleSize>1
                    disp(['    The rank of ', strJacobian, ' (', strMeaning, ') is deficient for ', num2str(length(find(ide.ino))),' out of ',int2str(SampleSize),' MC runs (with tol = ', num2str(tol_rank), ')!'  ]),
                else
                    disp(['    The rank of ', strJacobian, ' (', strMeaning, ') is deficient by ', num2str(size(Jacob,2)-ide.rank), ' (rank(', strJacobian, ') = ', num2str(ide.rank), ' < ', num2str(size(Jacob,2)), ' with tol = ', num2str(tol_rank), ')!']),
                end
                if all(cellfun(@isempty,ide.problpars))
                    disp(['    No problematic parameter combinations with maximum dimension ', num2str(size(ide.problpars,2)), ' were found. Increase max_dim_subsets_groups.']);
                    skipline()
202
                else
203 204 205 206 207 208 209 210 211
                    disp(['    Displaying problematic parameter combinations (with maximum dimension ', num2str(size(ide.problpars,2)), '):']);
                    skipline()
                    probparamset_nbr = 0;
                    for jset = 1:size(ide.problpars,2)
                        if isempty(ide.problpars{jset}) == 0
                            for jrow = 1:size(ide.problpars{jset},1)
                                for j = transpose(ide.problpars{jset}(jrow,:))
                                    probparamset_nbr = probparamset_nbr + 1;
                                    %pno = 100*length(find(ide.ind0(:,j)==0))/SampleSize;
212
                                    problparnamestring = strjoin(eval(['[', sprintf('name(%d), ', j), ']']),',');
213 214 215 216 217 218 219 220 221 222 223
                                    if SampleSize > 1
                                        if length(j) == 1
                                            disp(['    ',problparnamestring,' is not identified for ',num2str(pno),'% of MC runs!' ])
                                        else
                                            disp(['    [',problparnamestring,'] are collinear (with tol = ', num2str(tol_rank), ') for ',num2str((iweak)/SampleSize*100),'% of MC runs!' ])
                                        end
                                    else
                                        if length(j) == 1
                                            disp(['    ',problparnamestring, ' is not identified!' ])
                                        else
                                            disp(['    [',problparnamestring, '] are collinear!' ])
224
                                        end
225 226 227
                                    end
                                end
                            end
228
                        end
229 230
                    end
                end
231
            end
232 233
        end
    end
234 235 236 237
    %% All parameters are identified
    if no_warning_message_display
        skipline()
        disp([upper(strTest), ':']);
238
        disp(['    All parameters are identified in the ', strMeaning, ' (rank(', strJacobian, ') is full with tol = ', num2str(tol_rank), ').' ]),
239
    end
240 241
end

242

243

244 245
%% Advanced identificaton patterns
if SampleSize==1 && options_ident.advanced
246
    skipline()
247
    for j=1:size(ide_moments.cosndMOMENTS,2)
248
        pax=NaN(totparam_nbr,totparam_nbr);
249 250 251
        fprintf('\n')
        disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)'])
        fprintf('%-15s [%-*s] %10s\n','Parameter',(15+1)*j,' Expl. params ','cosn')
252
        for i=1:totparam_nbr
253
            namx='';
254
            for in=1:j
255
                dumpindx = ide_moments.pars{i,j}(in);
256
                if isnan(dumpindx)
257 258 259
                    namx=[namx ' ' sprintf('%-15s','--')];
                else
                    namx=[namx ' ' sprintf('%-15s',name{dumpindx})];
260
                    pax(i,dumpindx)=ide_moments.cosndMOMENTS(i,j);
261 262
                end
            end
263
            fprintf('%-15s [%s] %14.7f\n',name{i},namx,ide_moments.cosndMOMENTS(i,j))
264 265 266
        end
    end
end