Finished identification order=1|2|3

Note that I still need to do a code clean up (provide some licenses for functions from other people) and to double check order=3. There is also much room for speed and memory improvement, but the code works fine for now. I will also provide more information to the merge request soon about the detailed changes for future reference.
time-shift
Willi Mutschler 2019-12-20 00:40:00 +01:00
parent d40b775260
commit 8b9b49f8d7
No known key found for this signature in database
GPG Key ID: 91E724BF17A73F6D
22 changed files with 2336 additions and 800 deletions

64
matlab/Q6_plication.m Normal file
View File

@ -0,0 +1,64 @@
% By Willi Mutschler, September 26, 2016. Email: willi@mutschler.eu
% Quadruplication Matrix as defined by
% Meijer (2005) - Matrix algebra for higher order moments. Linear Algebra and its Applications, 410,pp. 112134
%
% Inputs:
% p: size of vector
% Outputs:
% QP: quadruplication matrix
% QPinv: Moore-Penrose inverse of QP
%
function [DP6,DP6inv] = Q6_plication(p,progress)
if nargin <2
progress =0;
end
reverseStr = ''; counti=1;
np = p*(p+1)*(p+2)*(p+3)*(p+4)*(p+5)/(1*2*3*4*5*6);
DP6 = spalloc(p^6,p*(p+1)*(p+2)*(p+3)*(p+4)*(p+5)/(1*2*3*4*5*6),p^6);
for i1=1:p
for i2=i1:p
for i3=i2:p
for i4=i3:p
for i5=i4:p
for i6=i5:p
if progress && (rem(counti,100)== 0)
msg = sprintf(' Q6-plication Matrix Processed %d/%d', counti, np); fprintf([reverseStr, msg]); reverseStr = repmat(sprintf('\b'), 1, length(msg));
elseif progress && (counti==np)
msg = sprintf(' Q6-plication Matrix Processed %d/%d\n', counti, np); fprintf([reverseStr, msg]); reverseStr = repmat(sprintf('\b'), 1, length(msg));
end
idx = uperm([i6 i5 i4 i3 i2 i1]);
for r = 1:size(idx,1)
ii1 = idx(r,1); ii2= idx(r,2); ii3=idx(r,3); ii4=idx(r,4); ii5=idx(r,5); ii6=idx(r,6);
n = ii1 + (ii2-1)*p + (ii3-1)*p^2 + (ii4-1)*p^3 + (ii5-1)*p^4 + (ii6-1)*p^5;
m = mue(p,i6,i5,i4,i3,i2,i1);
DP6(n,m)=1;
end
counti = counti+1;
end
end
end
end
end
end
DP6inv = (transpose(DP6)*DP6)\transpose(DP6);
function m = mue(p,i1,i2,i3,i4,i5,i6)
m = binom_coef(p,6,1) - binom_coef(p,1,i1+1) - binom_coef(p,2,i2+1) - binom_coef(p,3,i3+1) - binom_coef(p,4,i4+1) - binom_coef(p,5,i5+1) - binom_coef(p,6,i6+1);
m = round(m);
end
function N = binom_coef(p,q,i)
t = q; r =p+q-i;
if t==0
N=1;
else
N=1;
for h = 0:(t-1)
N = N*(r-h);
end
N=N/factorial(t);
end
end
end

180
matlab/allVL1.m Normal file
View File

@ -0,0 +1,180 @@
function v = allVL1(n, L1, L1ops, MaxNbSol)
% All integer permutations with sum criteria
%
% function v=allVL1(n, L1); OR
% v=allVL1(n, L1, L1opt);
% v=allVL1(n, L1, L1opt, MaxNbSol);
%
% INPUT
% n: length of the vector
% L1: target L1 norm
% L1ops: optional string ('==' or '<=' or '<')
% default value is '=='
% MaxNbSol: integer, returns at most MaxNbSol permutations.
% When MaxNbSol is NaN, allVL1 returns the total number of all possible
% permutations, which is useful to check the feasibility before getting
% the permutations.
% OUTPUT:
% v: (m x n) array such as: sum(v,2) == L1,
% (or <= or < depending on L1ops)
% all elements of v is naturel numbers {0,1,...}
% v contains all (=m) possible combinations
% v is sorted by sum (L1 norm), then by dictionnary sorting criteria
% class(v) is same as class(L1)
% Algorithm:
% Recursive
% Remark:
% allVL1(n,L1-n)+1 for natural numbers defined as {1,2,...}
% Example:
% This function can be used to generate all orders of all
% multivariable polynomials of degree p in R^n:
% Order = allVL1(n, p)
% Author: Bruno Luong
% Original, 30/nov/2007
% Version 1.1, 30/apr/2008: Add H1 line as suggested by John D'Errico
% 1.2, 17/may/2009: Possibility to get the number of permutations
% alone (set fourth parameter MaxNbSol to NaN)
% 1.3, 16/Sep/2009: Correct bug for number of solution
% 1.4, 18/Dec/2010: + non-recursive engine
global MaxCounter;
if nargin<3 || isempty(L1ops)
L1ops = '==';
end
n = floor(n); % make sure n is integer
if n<1
v = [];
return
end
if nargin<4 || isempty(MaxNbSol)
MaxCounter = Inf;
else
MaxCounter = MaxNbSol;
end
Counter(0);
switch L1ops
case {'==' '='},
if isnan(MaxCounter)
% return the number of solutions
v = nchoosek(n+L1-1,L1); % nchoosek(n+L1-1,n-1)
else
v = allVL1eq(n, L1);
end
case '<=', % call allVL1eq for various sum targets
if isnan(MaxCounter)
% return the number of solutions
%v = nchoosek(n+L1,L1)*factorial(n-L1); BUG <- 16/Sep/2009:
v = 0;
for j=0:L1
v = v + nchoosek(n+j-1,j);
end
% See pascal's 11th identity, the sum doesn't seem to
% simplify to a fix formula
else
v = cell2mat(arrayfun(@(j) allVL1eq(n, j), (0:L1)', ...
'UniformOutput', false));
end
case '<',
v = allVL1(n, L1-1, '<=', MaxCounter);
otherwise
error('allVL1: unknown L1ops')
end
end % allVL1
%%
function v = allVL1eq(n, L1)
global MaxCounter;
n = feval(class(L1),n);
s = n+L1;
sd = double(n)+double(L1);
notoverflowed = double(s)==sd;
if isinf(MaxCounter) && notoverflowed
v = allVL1nonrecurs(n, L1);
else
v = allVL1recurs(n, L1);
end
end % allVL1eq
%% Recursive engine
function v = allVL1recurs(n, L1, head)
% function v=allVL1eq(n, L1);
% INPUT
% n: length of the vector
% L1: desired L1 norm
% head: optional parameter to by concatenate in the first column
% of the output
% OUTPUT:
% if head is not defined
% v: (m x n) array such as sum(v,2)==L1
% all elements of v is naturel numbers {0,1,...}
% v contains all (=m) possible combinations
% v is (dictionnary) sorted
% Algorithm:
% Recursive
global MaxCounter;
if n==1
if Counter < MaxCounter
v = L1;
else
v = zeros(0,1,class(L1));
end
else % recursive call
v = cell2mat(arrayfun(@(j) allVL1recurs(n-1, L1-j, j), (0:L1)', ...
'UniformOutput', false));
end
if nargin>=3 % add a head column
v = [head+zeros(size(v,1),1,class(head)) v];
end
end % allVL1recurs
%%
function res=Counter(newval)
persistent counter;
if nargin>=1
counter = newval;
res = counter;
else
res = counter;
counter = counter+1;
end
end % Counter
%% Non-recursive engine
function v = allVL1nonrecurs(n, L1)
% function v=allVL1eq(n, L1);
% INPUT
% n: length of the vector
% L1: desired L1 norm
% OUTPUT:
% if head is not defined
% v: (m x n) array such as sum(v,2)==L1
% all elements of v is naturel numbers {0,1,...}
% v contains all (=m) possible combinations
% v is (dictionnary) sorted
% Algorithm:
% NonRecursive
% Chose (n-1) the splitting points of the array [0:(n+L1)]
s = nchoosek(1:n+L1-1,n-1);
m = size(s,1);
s1 = zeros(m,1,class(L1));
s2 = (n+L1)+s1;
v = diff([s1 s s2],1,2); % m x n
v = v-1;
end % allVL1nonrecurs

53
matlab/bivmom.m Normal file
View File

@ -0,0 +1,53 @@
%
% bivmom.m Date: 1/11/2004
% This Matlab program computes the product moment of X_1^{p_1}X_2^{p_2},
% where X_1 and X_2 are standard bivariate normally distributed.
% n : dimension of X
% rho: correlation coefficient between X_1 and X_2
% Reference: Kotz, Balakrishnan, and Johnson (2000), Continuous Multivariate
% Distributions, Vol. 1, p.261
% Note that there is a typo in Eq.(46.25), there should be an extra rho in front
% of the equation.
% Usage: bivmom(p,rho)
%
function [y,dy] = bivmom(p,rho)
s1 = p(1);
s2 = p(2);
rho2 = rho^2;
if nargout > 1
drho2 = 2*rho;
end
if rem(s1+s2,2)==1
y = 0;
return
end
r = fix(s1/2);
s = fix(s2/2);
y = 1;
c = 1;
if nargout > 1
dy = 0;
dc = 0;
end
odd = 2*rem(s1,2);
for j=1:min(r,s)
if nargout > 1
dc = 2*dc*(r+1-j)*(s+1-j)*rho2/(j*(2*j-1+odd)) + 2*c*(r+1-j)*(s+1-j)*drho2/(j*(2*j-1+odd));
end
c = 2*c*(r+1-j)*(s+1-j)*rho2/(j*(2*j-1+odd));
y = y+c;
if nargout > 1
dy = dy + dc;
end
end
if odd
if nargout > 1
dy = y + dy*rho;
end
y = y*rho;
end
y = prod([1:2:s1])*prod([1:2:s2])*y;
if nargout > 1
dy = prod([1:2:s1])*prod([1:2:s2])*dy;
end

View File

@ -13,7 +13,7 @@ function k = commutation(n, m, sparseflag)
% k: [n by m] commutation matrix % k: [n by m] commutation matrix
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function is called by % This function is called by
% * get_first_order_solution_params_deriv.m (previously getH.m) % * get_perturbation_params_derivs.m (previously getH.m)
% * get_identification_jacobians.m (previously getJJ.m) % * get_identification_jacobians.m (previously getJJ.m)
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function calls % This function calls

View File

@ -23,9 +23,6 @@ function disp_identification(pdraws, ide_reducedform, ide_moments, ide_spectrum,
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function is called by % This function is called by
% * dynare_identification.m % * dynare_identification.m
% -------------------------------------------------------------------------
% This function calls
% * dynare_identification.m
% ========================================================================= % =========================================================================
% Copyright (C) 2010-2019 Dynare Team % Copyright (C) 2010-2019 Dynare Team
% %
@ -84,41 +81,52 @@ for jide = 1:4
no_warning_message_display = 1; no_warning_message_display = 1;
%% Set output strings depending on test %% Set output strings depending on test
if jide == 1 if jide == 1
strTest = 'REDUCED-FORM'; strJacobian = 'Tau'; strMeaning = 'reduced-form solution'; strTest = 'REDUCED-FORM'; strJacobian = 'Tau'; strMeaning = 'Jacobian of steady state and reduced-form solution matrices';
if ~no_identification_reducedform if ~no_identification_reducedform
noidentification = 0; ide = ide_reducedform; noidentification = 0; ide = ide_reducedform;
if SampleSize == 1 if SampleSize == 1
Jacob = ide.dTAU; Jacob = ide.dREDUCEDFORM;
end end
else %skip test else %skip test
noidentification = 1; no_warning_message_display = 0; noidentification = 1; no_warning_message_display = 0;
end end
elseif jide == 2 elseif jide == 2
strTest = 'Iskrev (2010)'; strJacobian = 'J'; strMeaning = 'moments'; strTest = 'MINIMAL SYSTEM (Komunjer and Ng, 2011)'; strJacobian = 'Deltabar'; strMeaning = 'Jacobian of steady state and minimal system';
if ~no_identification_moments if options_ident.order == 2
noidentification = 0; ide = ide_moments; strMeaning = 'Jacobian of second-order accurate mean and first-order minimal system';
elseif options_ident.order == 3
strMeaning = 'Jacobian of second-order accurate mean and first-order minimal system';
end
if ~no_identification_minimal
noidentification = 0; ide = ide_minimal;
if SampleSize == 1 if SampleSize == 1
Jacob = ide.si_J; Jacob = ide.dMINIMAL;
end end
else %skip test else %skip test
noidentification = 1; no_warning_message_display = 0; noidentification = 1; no_warning_message_display = 0;
end end
elseif jide == 3 elseif jide == 3
strTest = 'Komunjer and NG (2011)'; strJacobian = 'D'; strMeaning = 'minimal system'; strTest = 'SPECTRUM (Qu and Tkachenko, 2012)'; strJacobian = 'Gbar'; strMeaning = 'Jacobian of mean and spectrum';
if ~no_identification_minimal if options_ident.order > 1
noidentification = 0; ide = ide_minimal; strTest = 'SPECTRUM (Mutschler, 2015)';
end
if ~no_identification_spectrum
noidentification = 0; ide = ide_spectrum;
if SampleSize == 1 if SampleSize == 1
Jacob = ide.D; Jacob = ide.dSPECTRUM;
end end
else %skip test else %skip test
noidentification = 1; no_warning_message_display = 0; noidentification = 1; no_warning_message_display = 0;
end end
elseif jide == 4 elseif jide == 4
strTest = 'Qu and Tkachenko (2012)'; strJacobian = 'G'; strMeaning = 'spectrum'; strTest = 'MOMENTS (Iskrev, 2010)'; strJacobian = 'J'; strMeaning = 'Jacobian of first two moments';
if ~no_identification_spectrum if options_ident.order > 1
noidentification = 0; ide = ide_spectrum; strTest = 'MOMENTS (Mutschler, 2015)'; strJacobian = 'Mbar';
end
if ~no_identification_moments
noidentification = 0; ide = ide_moments;
if SampleSize == 1 if SampleSize == 1
Jacob = ide.G; Jacob = ide.si_dMOMENTS;
end end
else %skip test else %skip test
noidentification = 1; no_warning_message_display = 0; noidentification = 1; no_warning_message_display = 0;
@ -176,7 +184,7 @@ for jide = 1:4
end end
end end
%% display problematic parameters computed by identification_checks_via_subsets (only for debugging) %% display problematic parameters computed by identification_checks_via_subsets
elseif checks_via_subsets elseif checks_via_subsets
if ide.rank < size(Jacob,2) if ide.rank < size(Jacob,2)
no_warning_message_display = 0; no_warning_message_display = 0;
@ -236,7 +244,7 @@ end
%% Advanced identificaton patterns %% Advanced identificaton patterns
if SampleSize==1 && options_ident.advanced if SampleSize==1 && options_ident.advanced
skipline() skipline()
for j=1:size(ide_moments.cosnJ,2) for j=1:size(ide_moments.cosndMOMENTS,2)
pax=NaN(totparam_nbr,totparam_nbr); pax=NaN(totparam_nbr,totparam_nbr);
fprintf('\n') fprintf('\n')
disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)']) disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)'])
@ -249,10 +257,10 @@ if SampleSize==1 && options_ident.advanced
namx=[namx ' ' sprintf('%-15s','--')]; namx=[namx ' ' sprintf('%-15s','--')];
else else
namx=[namx ' ' sprintf('%-15s',name{dumpindx})]; namx=[namx ' ' sprintf('%-15s',name{dumpindx})];
pax(i,dumpindx)=ide_moments.cosnJ(i,j); pax(i,dumpindx)=ide_moments.cosndMOMENTS(i,j);
end end
end end
fprintf('%-15s [%s] %14.7f\n',name{i},namx,ide_moments.cosnJ(i,j)) fprintf('%-15s [%s] %14.7f\n',name{i},namx,ide_moments.cosndMOMENTS(i,j))
end end
end end
end end

View File

@ -104,6 +104,10 @@ end
if options_.order>2 && options_.particle.pruning if options_.order>2 && options_.particle.pruning
error('Higher order nonlinear filters are not compatible with pruning option.') error('Higher order nonlinear filters are not compatible with pruning option.')
end end
% Check the perturbation order (nonlinear filters with third order perturbation, or higher order, are not yet implemented).
if options_.order>2 && ~isfield(options_,'options_ident') %For identification at order=3 we skip this check.
error(['I cannot estimate a model with a ' int2str(options_.order) ' order approximation of the model!'])
end
% analytical derivation is not yet available for kalman_filter_fast % analytical derivation is not yet available for kalman_filter_fast
if options_.analytic_derivation && options_.fast_kalman_filter if options_.analytic_derivation && options_.fast_kalman_filter

View File

@ -1,32 +1,32 @@
function [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_si_dLRE, STO_si_dTAU, STO_si_J, STO_G, STO_D] = dynare_identification(options_ident, pdraws0) function [pdraws, STO_REDUCEDFORM, STO_MOMENTS, STO_DYNAMIC, STO_si_dDYNAMIC, STO_si_dREDUCEDFORM, STO_si_dMOMENTS, STO_dSPECTRUM, STO_dMINIMAL] = dynare_identification(options_ident, pdraws0)
%function [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_dLRE, STO_dTAU, STO_J, STO_G, STO_D] = dynare_identification(options_ident, pdraws0) %function [pdraws, STO_REDUCEDFORM, STO_MOMENTS, STO_DYNAMIC, STO_si_dDYNAMIC, STO_si_dREDUCEDFORM, STO_si_dMOMENTS, STO_dSPECTRUM, STO_dMINIMAL] = dynare_identification(options_ident, pdraws0)
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function is called, when the user specifies identification(...); in % This function is called, when the user specifies identification(...); in
% the mod file. It prepares all identification analysis, i.e. % the mod file. It prepares all identification analysis, i.e.
% (1) sets options, local/persistent/global variables for a new identification % (1) sets options, local and persistent variables for a new identification
% analysis either for a single point or MC Sample and displays and plots the results % analysis either for a single point or a MC Sample. It also displays
% or % and plots the results.
% (2) loads, displays and plots a previously saved identification analysis % or this function can be used to
% (2) load, display and plot a previously saved identification analysis
% Note: This function does not output the arguments to the workspace if only called by
% "identification" in the mod file, but saves results to the folder identification.
% If you want to use this function directly in the mod file and workspace, you still have
% to put identification once in the mod file, otherwise the preprocessor won't compute all necessary objects
% ========================================================================= % =========================================================================
% INPUTS % INPUTS
% * options_ident [structure] identification options % * options_ident [structure] identification options
% * pdraws0 [SampleSize by totparam_nbr] optional: matrix of MC sample of model parameters % * pdraws0 [SampleSize by totparam_nbr] optional: matrix of MC sample of model parameters
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% OUTPUTS % OUTPUTS
% Note: This function does not output the arguments to the workspace if only called by
% "identification" in the mod file, but saves results to the folder identification.
% One can, however, just use
% [pdraws, STO_TAU, STO_MOMENTS, STO_LRE, STO_dLRE, STO_dTAU, STO_J, STO_G, STO_D] = dynare_identification(options_ident, pdraws0)
% in the mod file to get the results directly in the workspace
% * pdraws [matrix] MC sample of model params used % * pdraws [matrix] MC sample of model params used
% * STO_TAU, [matrix] MC sample of entries in the model solution (stacked vertically) % * STO_REDUCEDFORM, [matrix] MC sample of entries in steady state and reduced form model solution (stacked vertically)
% * STO_MOMENTS, [matrix] MC sample of entries in the moments (stacked vertically) % * STO_MOMENTS, [matrix] MC sample of entries in theoretical first two moments (stacked vertically)
% * STO_LRE, [matrix] MC sample of entries in LRE model (stacked vertically) % * STO_DYNAMIC, [matrix] MC sample of entries in steady state and dynamic model derivatives (stacked vertically)
% * STO_dLRE, [matrix] MC sample of derivatives of the Jacobian (dLRE) % * STO_si_dDYNAMIC, [matrix] MC sample of derivatives of steady state and dynamic derivatives
% * STO_dTAU, [matrix] MC sample of derivatives of the model solution and steady state (dTAU) % * STO_si_dREDUCEDFORM, [matrix] MC sample of derivatives of steady state and reduced form model solution
% * STO_J [matrix] MC sample of Iskrev (2010)'s J matrix % * STO_si_dMOMENTS [matrix] MC sample of Iskrev (2010)'s J matrix
% * STO_G [matrix] MC sample of Qu and Tkachenko (2012)'s G matrix % * STO_dSPECTRUM [matrix] MC sample of Qu and Tkachenko (2012)'s \bar{G} matrix
% * STO_D [matrix] MC sample of Komunjer and Ng (2011)'s D matrix % * STO_dMINIMAL [matrix] MC sample of Komunjer and Ng (2011)'s \bar{\Delta} matrix
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function is called by % This function is called by
% * driver.m % * driver.m
@ -107,10 +107,10 @@ options_ident = set_default_option(options_ident,'parameter_set','prior_mean');
options_ident = set_default_option(options_ident,'load_ident_files',0); options_ident = set_default_option(options_ident,'load_ident_files',0);
% 1: load previously computed analysis from identification/fname_identif.mat % 1: load previously computed analysis from identification/fname_identif.mat
options_ident = set_default_option(options_ident,'useautocorr',0); options_ident = set_default_option(options_ident,'useautocorr',0);
% 1: use autocorrelations in Iskrev (2010)'s J criteria % 1: use autocorrelations in Iskrev (2010)'s criteria
% 0: use autocovariances in Iskrev (2010)'s J criteria % 0: use autocovariances in Iskrev (2010)'s criteria
options_ident = set_default_option(options_ident,'ar',1); options_ident = set_default_option(options_ident,'ar',1);
% number of lags to consider for autocovariances/autocorrelations in Iskrev (2010)'s J criteria % number of lags to consider for autocovariances/autocorrelations in Iskrev (2010)'s criteria
options_ident = set_default_option(options_ident,'prior_mc',1); options_ident = set_default_option(options_ident,'prior_mc',1);
% size of Monte-Carlo sample of parameter draws % size of Monte-Carlo sample of parameter draws
options_ident = set_default_option(options_ident,'prior_range',0); options_ident = set_default_option(options_ident,'prior_range',0);
@ -121,16 +121,17 @@ options_ident = set_default_option(options_ident,'periods',300);
options_ident = set_default_option(options_ident,'replic',100); options_ident = set_default_option(options_ident,'replic',100);
% number of replicas to compute simulated moment uncertainty, when analytic Hessian is not available % number of replicas to compute simulated moment uncertainty, when analytic Hessian is not available
options_ident = set_default_option(options_ident,'advanced',0); options_ident = set_default_option(options_ident,'advanced',0);
% 1: show a more detailed analysis based on reduced-form solution and Jacobian of dynamic model (LRE). Further, performs a brute force % 1: show a more detailed analysis based on reduced-form model solution and dynamic model derivatives. Further, performs a brute force
% search of the groups of parameters best reproducing the behavior of each single parameter of Iskrev (2010)'s J. % search of the groups of parameters best reproducing the behavior of each single parameter.
options_ident = set_default_option(options_ident,'normalize_jacobians',1); options_ident = set_default_option(options_ident,'normalize_jacobians',1);
% 1: normalize Jacobians by rescaling each row by its largest element in absolute value % 1: normalize Jacobians by either rescaling each row by its largest element in absolute value or for Gram (or Hessian-type) matrices by transforming into correlation-type matrices
options_ident = set_default_option(options_ident,'grid_nbr',5000); options_ident = set_default_option(options_ident,'grid_nbr',5000);
% number of grid points in [-pi;pi] to approximate the integral to compute Qu and Tkachenko (2012)'s G criteria % number of grid points in [-pi;pi] to approximate the integral to compute Qu and Tkachenko (2012)'s criteria
% note that grid_nbr needs to be even and actually we use (grid_nbr+1) points, as we add the 0 frequency and use symmetry, i.e. grid_nbr/2 % note that grid_nbr needs to be even and actually we use (grid_nbr+1) points, as we add the 0 frequency and use symmetry, i.e. grid_nbr/2
% negative as well as grid_nbr/2 positive values to speed up the compuations % negative as well as grid_nbr/2 positive values to speed up the compuations
if mod(options_ident.grid_nbr,2) ~= 0 if mod(options_ident.grid_nbr,2) ~= 0
options_ident.grid_nbr = options_ident.grid_nbr+1; options_ident.grid_nbr = options_ident.grid_nbr+1;
fprintf('IDENTIFICATION: ''grid_nbr'' needs to be even, hence it is reset to %d\n',options_ident.grid_nbr)
if mod(options_ident.grid_nbr,2) ~= 0 if mod(options_ident.grid_nbr,2) ~= 0
error('IDENTIFICATION: You need to set an even value for ''grid_nbr'''); error('IDENTIFICATION: You need to set an even value for ''grid_nbr''');
end end
@ -148,25 +149,25 @@ if ~isfield(options_ident,'no_identification_strength')
else else
options_ident.no_identification_strength = 1; options_ident.no_identification_strength = 1;
end end
%check whether to compute and display identification criteria based on steady state and reduced-form solution %check whether to compute and display identification criteria based on steady state and reduced-form model solution
if ~isfield(options_ident,'no_identification_reducedform') if ~isfield(options_ident,'no_identification_reducedform')
options_ident.no_identification_reducedform = 0; options_ident.no_identification_reducedform = 0;
else else
options_ident.no_identification_reducedform = 1; options_ident.no_identification_reducedform = 1;
end end
%check whether to compute and display identification criteria based on Iskrev (2010)'s J, i.e. derivative of first two moments %check whether to compute and display identification criteria based on Iskrev (2010), i.e. derivative of first two moments
if ~isfield(options_ident,'no_identification_moments') if ~isfield(options_ident,'no_identification_moments')
options_ident.no_identification_moments = 0; options_ident.no_identification_moments = 0;
else else
options_ident.no_identification_moments = 1; options_ident.no_identification_moments = 1;
end end
%check whether to compute and display identification criteria based on Komunjer and Ng (2011)'s D, i.e. derivative of first moment, minimal state space system and observational equivalent spectral density transformation %check whether to compute and display identification criteria based on Komunjer and Ng (2011), i.e. derivative of first moment, minimal state space system and observational equivalent spectral density transformation
if ~isfield(options_ident,'no_identification_minimal') if ~isfield(options_ident,'no_identification_minimal')
options_ident.no_identification_minimal = 0; options_ident.no_identification_minimal = 0;
else else
options_ident.no_identification_minimal = 1; options_ident.no_identification_minimal = 1;
end end
%Check whether to compute and display identification criteria based on Qu and Tkachenko (2012)'s G, i.e. Gram matrix of derivatives of first moment plus outer product of derivatives of spectral density %Check whether to compute and display identification criteria based on Qu and Tkachenko (2012), i.e. Gram matrix of derivatives of first moment plus outer product of derivatives of spectral density
if ~isfield(options_ident,'no_identification_spectrum') if ~isfield(options_ident,'no_identification_spectrum')
options_ident.no_identification_spectrum = 0; options_ident.no_identification_spectrum = 0;
else else
@ -211,6 +212,10 @@ options_ident = set_default_option(options_ident,'lik_init',1);
% ii) option 1 for the stationary elements % ii) option 1 for the stationary elements
options_ident = set_default_option(options_ident,'analytic_derivation',1); options_ident = set_default_option(options_ident,'analytic_derivation',1);
% 1: analytic derivation of gradient and hessian of likelihood in dsge_likelihood.m, only works for stationary models, i.e. kalman_algo<3 % 1: analytic derivation of gradient and hessian of likelihood in dsge_likelihood.m, only works for stationary models, i.e. kalman_algo<3
options_ident = set_default_option(options_ident,'order',1);
% 1: first-order perturbation approximation, identification is based on linear state space system
% 2: second-order perturbation approximation, identification is based on second-order pruned state space system
% 3: third-order perturbation approximation, identification is based on third-order pruned state space system
%overwrite values in options_, note that options_ is restored at the end of the function %overwrite values in options_, note that options_ is restored at the end of the function
if isfield(options_ident,'TeX') if isfield(options_ident,'TeX')
@ -273,7 +278,17 @@ else
end end
% overwrite settings in options_ and prepare to call dynare_estimation_init % overwrite settings in options_ and prepare to call dynare_estimation_init
options_.order = 1; % Identification does not support order>1 (yet) options_.order = options_ident.order;
if options_ident.order > 1
%order>1 is not compatible with analytic derivation in dsge_likelihood.m
options_ident.analytic_derivation=0;
options_.analytic_derivation=0;
%order>1 is based on pruned state space system
options_.pruning = true;
end
if options_ident.order == 3
options_.k_order_solver = 1;
end
options_.ar = options_ident.ar; options_.ar = options_ident.ar;
options_.prior_mc = options_ident.prior_mc; options_.prior_mc = options_ident.prior_mc;
options_.Schur_vec_tol = 1.e-8; options_.Schur_vec_tol = 1.e-8;
@ -284,15 +299,15 @@ options_ = set_default_option(options_,'datafile','');
options_.mode_compute = 0; options_.mode_compute = 0;
options_.plot_priors = 0; options_.plot_priors = 0;
options_.smoother = 1; options_.smoother = 1;
options_.options_ident = [];
[dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_, bayestopt_, bounds] = dynare_estimation_init(M_.endo_names, fname, 1, M_, options_, oo_, estim_params_, bayestopt_); [dataset_, dataset_info, xparam1, hh, M_, options_, oo_, estim_params_, bayestopt_, bounds] = dynare_estimation_init(M_.endo_names, fname, 1, M_, options_, oo_, estim_params_, bayestopt_);
%outputting dataset_ is needed for Octave %outputting dataset_ is needed for Octave
% set method to compute identification Jacobians (kronflag). Default:0 % set method to compute identification Jacobians (kronflag). Default:0
options_ident = set_default_option(options_ident,'analytic_derivation_mode', options_.analytic_derivation_mode); % if not set by user, inherit default global one options_ident = set_default_option(options_ident,'analytic_derivation_mode', options_.analytic_derivation_mode); % if not set by user, inherit default global one
% 0: efficient sylvester equation method to compute analytical derivatives as in Ratto & Iskrev (2011) % 0: efficient sylvester equation method to compute analytical derivatives as in Ratto & Iskrev (2012)
% 1: kronecker products method to compute analytical derivatives as in Iskrev (2010) % 1: kronecker products method to compute analytical derivatives as in Iskrev (2010) (only for order=1)
% -1: numerical two-sided finite difference method to compute numerical derivatives of all Jacobians using function identification_numerical_objective.m (previously thet2tau.m) % -1: numerical two-sided finite difference method to compute numerical derivatives of all identification Jacobians using function identification_numerical_objective.m (previously thet2tau.m)
% -2: numerical two-sided finite difference method to compute numerically dYss, dg1, d2Yss and d2g1, the Jacobians are then computed analytically as in options 0 % -2: numerical two-sided finite difference method to compute numerically dYss, dg1, dg2, dg3, d2Yss and d2g1, the identification Jacobians are then computed analytically as if option is set to 0
options_.analytic_derivation_mode = options_ident.analytic_derivation_mode; %overwrite setting options_.analytic_derivation_mode = options_ident.analytic_derivation_mode; %overwrite setting
% initialize persistent variables in prior_draw % initialize persistent variables in prior_draw
@ -365,7 +380,10 @@ end
options_ident.name_tex = name_tex; options_ident.name_tex = name_tex;
skipline() skipline()
disp('==== Identification analysis ====') fprintf('======== Identification Analysis ========\n')
if options_ident.order > 1
fprintf('Using Pruned State Space System (order=%d)\n',options_ident.order);
end
skipline() skipline()
if totparam_nbr < 2 if totparam_nbr < 2
options_ident.advanced = 0; options_ident.advanced = 0;
@ -378,20 +396,19 @@ options_ident = set_default_option(options_ident,'max_dim_cova_group',min([2,tot
options_ident.max_dim_cova_group = min([options_ident.max_dim_cova_group,totparam_nbr-1]); options_ident.max_dim_cova_group = min([options_ident.max_dim_cova_group,totparam_nbr-1]);
% In brute force search (ident_bruteforce.m) when advanced=1 this option sets the maximum dimension of groups of parameters that best reproduce the behavior of each single model parameter % In brute force search (ident_bruteforce.m) when advanced=1 this option sets the maximum dimension of groups of parameters that best reproduce the behavior of each single model parameter
options_ident = set_default_option(options_ident,'checks_via_subsets',0); %[ONLY FOR DEBUGGING] options_ident = set_default_option(options_ident,'checks_via_subsets',0);
% 1: uses identification_checks_via_subsets.m to compute problematic parameter combinations % 1: uses identification_checks_via_subsets.m to compute problematic parameter combinations
% 0: uses identification_checks.m to compute problematic parameter combinations [default] % 0: uses identification_checks.m to compute problematic parameter combinations [default]
options_ident = set_default_option(options_ident,'max_dim_subsets_groups',min([4,totparam_nbr-1])); %[ONLY FOR DEBUGGING] options_ident = set_default_option(options_ident,'max_dim_subsets_groups',min([4,totparam_nbr-1]));
% In identification_checks_via_subsets.m, when checks_via_subsets=1, this % In identification_checks_via_subsets.m, when checks_via_subsets=1, this option sets the maximum dimension of groups of parameters for which the corresponding rank criteria is checked
% option sets the maximum dimension of groups of parameters for which
% the corresponding rank criteria is checked
options_.options_ident = options_ident; %store identification options into global options options_.options_ident = options_ident; %store identification options into global options
MaxNumberOfBytes = options_.MaxNumberOfBytes; %threshold when to save from memory to files
store_options_ident = options_ident; store_options_ident = options_ident;
MaxNumberOfBytes = options_.MaxNumberOfBytes; %threshold when to save from memory to files
iload = options_ident.load_ident_files; iload = options_ident.load_ident_files;
SampleSize = options_ident.prior_mc; SampleSize = options_ident.prior_mc;
if iload <=0 if iload <=0
%% Perform new identification analysis, i.e. do not load previous analysis %% Perform new identification analysis, i.e. do not load previous analysis
if prior_exist if prior_exist
@ -442,14 +459,14 @@ if iload <=0
end end
else else
% no estimated_params block is available, all stderr and model parameters, but no corr parameters are chosen % no estimated_params block is available, all stderr and model parameters, but no corr parameters are chosen
params = [sqrt(diag(M_.Sigma_e))', M_.params']; % use current values params = [sqrt(diag(M_.Sigma_e))', M_.params'];
parameters = 'Current_params'; parameters = 'Current_params';
parameters_TeX = 'Current parameter values'; parameters_TeX = 'Current parameter values';
disp('Testing all current stderr and model parameter values') disp('Testing all current stderr and model parameter values')
end end
options_ident.tittxt = parameters; %title text for graphs and figures options_ident.tittxt = parameters; %title text for graphs and figures
% perform identification analysis for single point % perform identification analysis for single point
[ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_lre_point, derivatives_info_point, info, options_ident] = ... [ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, derivatives_info_point, info, options_ident] = ...
identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end implies initialization of persistent variables identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end implies initialization of persistent variables
if info(1)~=0 if info(1)~=0
% there are errors in the solution algorithm % there are errors in the solution algorithm
@ -496,7 +513,7 @@ if iload <=0
params = prior_draw(); params = prior_draw();
options_ident.tittxt = 'Random_prior_params'; %title text for graphs and figures options_ident.tittxt = 'Random_prior_params'; %title text for graphs and figures
% perform identification analysis % perform identification analysis
[ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_lre_point, derivatives_info, info, options_ident] = ... [ide_moments_point, ide_spectrum_point, ide_minimal_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, derivatives_info_point, info, options_ident] = ...
identification_analysis(params,indpmodel,indpstderr,indpcorr,options_ident,dataset_info, prior_exist, 1); identification_analysis(params,indpmodel,indpstderr,indpcorr,options_ident,dataset_info, prior_exist, 1);
end end
end end
@ -521,13 +538,13 @@ if iload <=0
end end
ide_hess_point.params = params; ide_hess_point.params = params;
% save all output into identification folder % save all output into identification folder
save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_lre_point','store_options_ident'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_dynamic_point','store_options_ident');
save([IdentifDirectoryName '/' fname '_' parameters '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_lre_point','store_options_ident'); save([IdentifDirectoryName '/' fname '_' parameters '_identif.mat'], 'ide_moments_point', 'ide_spectrum_point', 'ide_minimal_point', 'ide_hess_point', 'ide_reducedform_point', 'ide_dynamic_point','store_options_ident');
% display results of identification analysis % display results of identification analysis
disp_identification(params, ide_reducedform_point, ide_moments_point, ide_spectrum_point, ide_minimal_point, name, options_ident); disp_identification(params, ide_reducedform_point, ide_moments_point, ide_spectrum_point, ide_minimal_point, name, options_ident);
if ~options_ident.no_identification_strength && ~options_.nograph if ~options_ident.no_identification_strength && ~options_.nograph
% plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs
plot_identification(params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_lre_point, options_ident.advanced, parameters, name, IdentifDirectoryName, parameters_TeX, name_tex); plot_identification(params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, options_ident.advanced, parameters, name, IdentifDirectoryName, parameters_TeX, name_tex);
end end
if SampleSize > 1 if SampleSize > 1
@ -553,30 +570,30 @@ if iload <=0
end end
options_ident.tittxt = []; % clear title text for graphs and figures options_ident.tittxt = []; % clear title text for graphs and figures
% run identification analysis % run identification analysis
[ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_lre, ide_derivatives_info, info, options_MC] = ... [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, ide_derivatives_info, info, options_MC] = ...
identification_analysis(params, indpmodel, indpstderr, indpcorr, options_MC, dataset_info, prior_exist, 0); % the 0 implies that we do not initialize persistent variables anymore identification_analysis(params, indpmodel, indpstderr, indpcorr, options_MC, dataset_info, prior_exist, 0); % the 0 implies that we do not initialize persistent variables anymore
if iteration==0 && info(1)==0 % preallocate storage in the first admissable run if iteration==0 && info(1)==0 % preallocate storage in the first admissable run
delete([IdentifDirectoryName '/' fname '_identif_*.mat']) % delete previously saved results delete([IdentifDirectoryName '/' fname '_identif_*.mat']) % delete previously saved results
MAX_RUNS_BEFORE_SAVE_TO_FILE = min(SampleSize,ceil(MaxNumberOfBytes/(size(ide_reducedform.si_dTAU,1)*totparam_nbr)/8)); % set how many runs can be stored before we save to files MAX_RUNS_BEFORE_SAVE_TO_FILE = min(SampleSize,ceil(MaxNumberOfBytes/(size(ide_reducedform.si_dREDUCEDFORM,1)*totparam_nbr)/8)); % set how many runs can be stored before we save to files
pdraws = zeros(SampleSize,totparam_nbr); % preallocate storage for draws in each row pdraws = zeros(SampleSize,totparam_nbr); % preallocate storage for draws in each row
% preallocate storage for linear rational expectations model % preallocate storage for steady state and dynamic model derivatives
STO_si_dLRE = zeros([size(ide_lre.si_dLRE,1),modparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]); STO_si_dDYNAMIC = zeros([size(ide_dynamic.si_dDYNAMIC,1),modparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]);
STO_LRE = zeros(size(ide_lre.LRE,1),SampleSize); STO_DYNAMIC = zeros(size(ide_dynamic.DYNAMIC,1),SampleSize);
IDE_LRE.ind_dLRE = ide_lre.ind_dLRE; IDE_DYNAMIC.ind_dDYNAMIC = ide_dynamic.ind_dDYNAMIC;
IDE_LRE.in0 = zeros(SampleSize,modparam_nbr); IDE_DYNAMIC.in0 = zeros(SampleSize,modparam_nbr);
IDE_LRE.ind0 = zeros(SampleSize,modparam_nbr); IDE_DYNAMIC.ind0 = zeros(SampleSize,modparam_nbr);
IDE_LRE.jweak = zeros(SampleSize,modparam_nbr); IDE_DYNAMIC.jweak = zeros(SampleSize,modparam_nbr);
IDE_LRE.jweak_pair = zeros(SampleSize,modparam_nbr*(modparam_nbr+1)/2); IDE_DYNAMIC.jweak_pair = zeros(SampleSize,modparam_nbr*(modparam_nbr+1)/2);
IDE_LRE.cond = zeros(SampleSize,1); IDE_DYNAMIC.cond = zeros(SampleSize,1);
IDE_LRE.Mco = zeros(SampleSize,modparam_nbr); IDE_DYNAMIC.Mco = zeros(SampleSize,modparam_nbr);
% preallocate storage for reduced form % preallocate storage for reduced form
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
STO_si_dTAU = zeros([size(ide_reducedform.si_dTAU,1),totparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]); STO_si_dREDUCEDFORM = zeros([size(ide_reducedform.si_dREDUCEDFORM,1),totparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]);
STO_TAU = zeros(size(ide_reducedform.TAU,1),SampleSize); STO_REDUCEDFORM = zeros(size(ide_reducedform.REDUCEDFORM,1),SampleSize);
IDE_REDUCEDFORM.ind_dTAU = ide_reducedform.ind_dTAU; IDE_REDUCEDFORM.ind_dREDUCEDFORM = ide_reducedform.ind_dREDUCEDFORM;
IDE_REDUCEDFORM.in0 = zeros(SampleSize,1); IDE_REDUCEDFORM.in0 = zeros(SampleSize,1);
IDE_REDUCEDFORM.ind0 = zeros(SampleSize,totparam_nbr); IDE_REDUCEDFORM.ind0 = zeros(SampleSize,totparam_nbr);
IDE_REDUCEDFORM.jweak = zeros(SampleSize,totparam_nbr); IDE_REDUCEDFORM.jweak = zeros(SampleSize,totparam_nbr);
@ -589,9 +606,9 @@ if iload <=0
% preallocate storage for moments % preallocate storage for moments
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
STO_si_J = zeros([size(ide_moments.si_J,1),totparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]); STO_si_dMOMENTS = zeros([size(ide_moments.si_dMOMENTS,1),totparam_nbr,MAX_RUNS_BEFORE_SAVE_TO_FILE]);
STO_MOMENTS = zeros(size(ide_moments.MOMENTS,1),SampleSize); STO_MOMENTS = zeros(size(ide_moments.MOMENTS,1),SampleSize);
IDE_MOMENTS.ind_J = ide_moments.ind_J; IDE_MOMENTS.ind_dMOMENTS = ide_moments.ind_dMOMENTS;
IDE_MOMENTS.in0 = zeros(SampleSize,1); IDE_MOMENTS.in0 = zeros(SampleSize,1);
IDE_MOMENTS.ind0 = zeros(SampleSize,totparam_nbr); IDE_MOMENTS.ind0 = zeros(SampleSize,totparam_nbr);
IDE_MOMENTS.jweak = zeros(SampleSize,totparam_nbr); IDE_MOMENTS.jweak = zeros(SampleSize,totparam_nbr);
@ -606,8 +623,8 @@ if iload <=0
% preallocate storage for spectrum % preallocate storage for spectrum
if ~options_MC.no_identification_spectrum if ~options_MC.no_identification_spectrum
STO_G = zeros([size(ide_spectrum.G,1),size(ide_spectrum.G,2), MAX_RUNS_BEFORE_SAVE_TO_FILE]); STO_dSPECTRUM = zeros([size(ide_spectrum.dSPECTRUM,1),size(ide_spectrum.dSPECTRUM,2), MAX_RUNS_BEFORE_SAVE_TO_FILE]);
IDE_SPECTRUM.ind_G = ide_spectrum.ind_G; IDE_SPECTRUM.ind_dSPECTRUM = ide_spectrum.ind_dSPECTRUM;
IDE_SPECTRUM.in0 = zeros(SampleSize,1); IDE_SPECTRUM.in0 = zeros(SampleSize,1);
IDE_SPECTRUM.ind0 = zeros(SampleSize,totparam_nbr); IDE_SPECTRUM.ind0 = zeros(SampleSize,totparam_nbr);
IDE_SPECTRUM.jweak = zeros(SampleSize,totparam_nbr); IDE_SPECTRUM.jweak = zeros(SampleSize,totparam_nbr);
@ -620,8 +637,8 @@ if iload <=0
% preallocate storage for minimal system % preallocate storage for minimal system
if ~options_MC.no_identification_minimal if ~options_MC.no_identification_minimal
STO_D = zeros([size(ide_minimal.D,1),size(ide_minimal.D,2), MAX_RUNS_BEFORE_SAVE_TO_FILE]); STO_dMINIMAL = zeros([size(ide_minimal.dMINIMAL,1),size(ide_minimal.dMINIMAL,2), MAX_RUNS_BEFORE_SAVE_TO_FILE]);
IDE_MINIMAL.ind_D = ide_minimal.ind_D; IDE_MINIMAL.ind_dMINIMAL = ide_minimal.ind_dMINIMAL;
IDE_MINIMAL.in0 = zeros(SampleSize,1); IDE_MINIMAL.in0 = zeros(SampleSize,1);
IDE_MINIMAL.ind0 = zeros(SampleSize,totparam_nbr); IDE_MINIMAL.ind0 = zeros(SampleSize,totparam_nbr);
IDE_MINIMAL.jweak = zeros(SampleSize,totparam_nbr); IDE_MINIMAL.jweak = zeros(SampleSize,totparam_nbr);
@ -638,20 +655,20 @@ if iload <=0
run_index = run_index + 1; %increase index of admissable draws after saving to files run_index = run_index + 1; %increase index of admissable draws after saving to files
pdraws(iteration,:) = params; % store draw pdraws(iteration,:) = params; % store draw
% store results for linear rational expectations model % store results for steady state and dynamic model derivatives
STO_LRE(:,iteration) = ide_lre.LRE; STO_DYNAMIC(:,iteration) = ide_dynamic.DYNAMIC;
STO_si_dLRE(:,:,run_index) = ide_lre.si_dLRE; STO_si_dDYNAMIC(:,:,run_index) = ide_dynamic.si_dDYNAMIC;
IDE_LRE.cond(iteration,1) = ide_lre.cond; IDE_DYNAMIC.cond(iteration,1) = ide_dynamic.cond;
IDE_LRE.ino(iteration,1) = ide_lre.ino; IDE_DYNAMIC.ino(iteration,1) = ide_dynamic.ino;
IDE_LRE.ind0(iteration,:) = ide_lre.ind0; IDE_DYNAMIC.ind0(iteration,:) = ide_dynamic.ind0;
IDE_LRE.jweak(iteration,:) = ide_lre.jweak; IDE_DYNAMIC.jweak(iteration,:) = ide_dynamic.jweak;
IDE_LRE.jweak_pair(iteration,:) = ide_lre.jweak_pair; IDE_DYNAMIC.jweak_pair(iteration,:) = ide_dynamic.jweak_pair;
IDE_LRE.Mco(iteration,:) = ide_lre.Mco; IDE_DYNAMIC.Mco(iteration,:) = ide_dynamic.Mco;
% store results for reduced form solution % store results for reduced form model solution
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
STO_TAU(:,iteration) = ide_reducedform.TAU; STO_REDUCEDFORM(:,iteration) = ide_reducedform.REDUCEDFORM;
STO_si_dTAU(:,:,run_index) = ide_reducedform.si_dTAU; STO_si_dREDUCEDFORM(:,:,run_index) = ide_reducedform.si_dREDUCEDFORM;
IDE_REDUCEDFORM.cond(iteration,1) = ide_reducedform.cond; IDE_REDUCEDFORM.cond(iteration,1) = ide_reducedform.cond;
IDE_REDUCEDFORM.ino(iteration,1) = ide_reducedform.ino; IDE_REDUCEDFORM.ino(iteration,1) = ide_reducedform.ino;
IDE_REDUCEDFORM.ind0(iteration,:) = ide_reducedform.ind0; IDE_REDUCEDFORM.ind0(iteration,:) = ide_reducedform.ind0;
@ -663,7 +680,7 @@ if iload <=0
% store results for moments % store results for moments
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
STO_MOMENTS(:,iteration) = ide_moments.MOMENTS; STO_MOMENTS(:,iteration) = ide_moments.MOMENTS;
STO_si_J(:,:,run_index) = ide_moments.si_J; STO_si_dMOMENTS(:,:,run_index) = ide_moments.si_dMOMENTS;
IDE_MOMENTS.cond(iteration,1) = ide_moments.cond; IDE_MOMENTS.cond(iteration,1) = ide_moments.cond;
IDE_MOMENTS.ino(iteration,1) = ide_moments.ino; IDE_MOMENTS.ino(iteration,1) = ide_moments.ino;
IDE_MOMENTS.ind0(iteration,:) = ide_moments.ind0; IDE_MOMENTS.ind0(iteration,:) = ide_moments.ind0;
@ -676,7 +693,7 @@ if iload <=0
% store results for spectrum % store results for spectrum
if ~options_MC.no_identification_spectrum if ~options_MC.no_identification_spectrum
STO_G(:,:,run_index) = ide_spectrum.G; STO_dSPECTRUM(:,:,run_index) = ide_spectrum.dSPECTRUM;
IDE_SPECTRUM.cond(iteration,1) = ide_spectrum.cond; IDE_SPECTRUM.cond(iteration,1) = ide_spectrum.cond;
IDE_SPECTRUM.ino(iteration,1) = ide_spectrum.ino; IDE_SPECTRUM.ino(iteration,1) = ide_spectrum.ino;
IDE_SPECTRUM.ind0(iteration,:) = ide_spectrum.ind0; IDE_SPECTRUM.ind0(iteration,:) = ide_spectrum.ind0;
@ -687,7 +704,7 @@ if iload <=0
% store results for minimal system % store results for minimal system
if ~options_MC.no_identification_minimal if ~options_MC.no_identification_minimal
STO_D(:,:,run_index) = ide_minimal.D; STO_dMINIMAL(:,:,run_index) = ide_minimal.dMINIMAL;
IDE_MINIMAL.cond(iteration,1) = ide_minimal.cond; IDE_MINIMAL.cond(iteration,1) = ide_minimal.cond;
IDE_MINIMAL.ino(iteration,1) = ide_minimal.ino; IDE_MINIMAL.ino(iteration,1) = ide_minimal.ino;
IDE_MINIMAL.ind0(iteration,:) = ide_minimal.ind0; IDE_MINIMAL.ind0(iteration,:) = ide_minimal.ind0;
@ -701,37 +718,37 @@ if iload <=0
file_index = file_index + 1; file_index = file_index + 1;
if run_index<MAX_RUNS_BEFORE_SAVE_TO_FILE if run_index<MAX_RUNS_BEFORE_SAVE_TO_FILE
%we are finished (iteration == SampleSize), so get rid of additional storage %we are finished (iteration == SampleSize), so get rid of additional storage
STO_si_dLRE = STO_si_dLRE(:,:,1:run_index); STO_si_dDYNAMIC = STO_si_dDYNAMIC(:,:,1:run_index);
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
STO_si_dTAU = STO_si_dTAU(:,:,1:run_index); STO_si_dREDUCEDFORM = STO_si_dREDUCEDFORM(:,:,1:run_index);
end end
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
STO_si_J = STO_si_J(:,:,1:run_index); STO_si_dMOMENTS = STO_si_dMOMENTS(:,:,1:run_index);
end end
if ~options_MC.no_identification_spectrum if ~options_MC.no_identification_spectrum
STO_G = STO_G(:,:,1:run_index); STO_dSPECTRUM = STO_dSPECTRUM(:,:,1:run_index);
end end
if ~options_MC.no_identification_minimal if ~options_MC.no_identification_minimal
STO_D = STO_D(:,:,1:run_index); STO_dMINIMAL = STO_dMINIMAL(:,:,1:run_index);
end end
end end
save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_si_dLRE'); save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_si_dDYNAMIC');
STO_si_dLRE = zeros(size(STO_si_dLRE)); % reset storage STO_si_dDYNAMIC = zeros(size(STO_si_dDYNAMIC)); % reset storage
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_si_dTAU', '-append'); save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_si_dREDUCEDFORM', '-append');
STO_si_dTAU = zeros(size(STO_si_dTAU)); % reset storage STO_si_dREDUCEDFORM = zeros(size(STO_si_dREDUCEDFORM)); % reset storage
end end
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_si_J','-append'); save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_si_dMOMENTS','-append');
STO_si_J = zeros(size(STO_si_J)); % reset storage STO_si_dMOMENTS = zeros(size(STO_si_dMOMENTS)); % reset storage
end end
if ~options_MC.no_identification_spectrum if ~options_MC.no_identification_spectrum
save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_G','-append'); save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_dSPECTRUM','-append');
STO_G = zeros(size(STO_G)); % reset storage STO_dSPECTRUM = zeros(size(STO_dSPECTRUM)); % reset storage
end end
if ~options_MC.no_identification_minimal if ~options_MC.no_identification_minimal
save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_D','-append'); save([IdentifDirectoryName '/' fname '_identif_' int2str(file_index) '.mat'], 'STO_dMINIMAL','-append');
STO_D = zeros(size(STO_D)); % reset storage STO_dMINIMAL = zeros(size(STO_dMINIMAL)); % reset storage
end end
run_index = 0; % reset index run_index = 0; % reset index
end end
@ -743,9 +760,9 @@ if iload <=0
if SampleSize > 1 if SampleSize > 1
dyn_waitbar_close(h); dyn_waitbar_close(h);
normalize_STO_LRE = std(STO_LRE,0,2); normalize_STO_DYNAMIC = std(STO_DYNAMIC,0,2);
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
normalize_STO_TAU = std(STO_TAU,0,2); normalize_STO_REDUCEDFORM = std(STO_REDUCEDFORM,0,2);
end end
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
normalize_STO_MOMENTS = std(STO_MOMENTS,0,2); normalize_STO_MOMENTS = std(STO_MOMENTS,0,2);
@ -759,65 +776,65 @@ if iload <=0
normaliz1 = std(pdraws); normaliz1 = std(pdraws);
iter = 0; iter = 0;
for ifile_index = 1:file_index for ifile_index = 1:file_index
load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dLRE'); load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dDYNAMIC');
maxrun_dLRE = size(STO_si_dLRE,3); maxrun_dDYNAMIC = size(STO_si_dDYNAMIC,3);
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dTAU'); load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dREDUCEDFORM');
maxrun_dTAU = size(STO_si_dTAU,3); maxrun_dREDUCEDFORM = size(STO_si_dREDUCEDFORM,3);
else else
maxrun_dTAU = 0; maxrun_dREDUCEDFORM = 0;
end end
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_J'); load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_si_dMOMENTS');
maxrun_J = size(STO_si_J,3); maxrun_dMOMENTS = size(STO_si_dMOMENTS,3);
else else
maxrun_J = 0; maxrun_dMOMENTS = 0;
end end
if ~options_MC.no_identification_spectrum if ~options_MC.no_identification_spectrum
load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_G'); load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_dSPECTRUM');
maxrun_G = size(STO_G,3); maxrun_dSPECTRUM = size(STO_dSPECTRUM,3);
else else
maxrun_G = 0; maxrun_dSPECTRUM = 0;
end end
if ~options_MC.no_identification_minimal if ~options_MC.no_identification_minimal
load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_D'); load([IdentifDirectoryName '/' fname '_identif_' int2str(ifile_index) '.mat'], 'STO_dMINIMAL');
maxrun_D = size(STO_D,3); maxrun_dMINIMAL = size(STO_dMINIMAL,3);
else else
maxrun_D = 0; maxrun_dMINIMAL = 0;
end end
for irun=1:max([maxrun_dLRE, maxrun_dTAU, maxrun_J, maxrun_G, maxrun_D]) for irun=1:max([maxrun_dDYNAMIC, maxrun_dREDUCEDFORM, maxrun_dMOMENTS, maxrun_dSPECTRUM, maxrun_dMINIMAL])
iter=iter+1; iter=iter+1;
% note that this is not the same si_dLREnorm as computed in identification_analysis % note that this is not the same si_dDYNAMICnorm as computed in identification_analysis
% given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure % given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure
si_dLREnorm(iter,:) = vnorm(STO_si_dLRE(:,:,irun)./repmat(normalize_STO_LRE,1,totparam_nbr-(stderrparam_nbr+corrparam_nbr))).*normaliz1((stderrparam_nbr+corrparam_nbr)+1:end); si_dDYNAMICnorm(iter,:) = vnorm(STO_si_dDYNAMIC(:,:,irun)./repmat(normalize_STO_DYNAMIC,1,totparam_nbr-(stderrparam_nbr+corrparam_nbr))).*normaliz1((stderrparam_nbr+corrparam_nbr)+1:end);
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
% note that this is not the same si_dTAUnorm as computed in identification_analysis % note that this is not the same si_dREDUCEDFORMnorm as computed in identification_analysis
% given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure % given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure
si_dTAUnorm(iter,:) = vnorm(STO_si_dTAU(:,:,irun)./repmat(normalize_STO_TAU,1,totparam_nbr)).*normaliz1; si_dREDUCEDFORMnorm(iter,:) = vnorm(STO_si_dREDUCEDFORM(:,:,irun)./repmat(normalize_STO_REDUCEDFORM,1,totparam_nbr)).*normaliz1;
end end
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
% note that this is not the same si_Jnorm as computed in identification_analysis % note that this is not the same si_dMOMENTSnorm as computed in identification_analysis
% given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure % given that we have the MC sample of the Jacobians, we also normalize by the std of the sample of Jacobian entries, to get a fully standardized sensitivity measure
si_Jnorm(iter,:) = vnorm(STO_si_J(:,:,irun)./repmat(normalize_STO_MOMENTS,1,totparam_nbr)).*normaliz1; si_dMOMENTSnorm(iter,:) = vnorm(STO_si_dMOMENTS(:,:,irun)./repmat(normalize_STO_MOMENTS,1,totparam_nbr)).*normaliz1;
end end
if ~options_MC.no_identification_spectrum if ~options_MC.no_identification_spectrum
% note that this is not the same Gnorm as computed in identification_analysis % note that this is not the same dSPECTRUMnorm as computed in identification_analysis
Gnorm(iter,:) = vnorm(STO_G(:,:,irun)); %not yet used dSPECTRUMnorm(iter,:) = vnorm(STO_dSPECTRUM(:,:,irun)); %not yet used
end end
if ~options_MC.no_identification_minimal if ~options_MC.no_identification_minimal
% note that this is not the same Dnorm as computed in identification_analysis % note that this is not the same dMINIMALnorm as computed in identification_analysis
Dnorm(iter,:) = vnorm(STO_D(:,:,irun)); %not yet used dMINIMALnorm(iter,:) = vnorm(STO_dMINIMAL(:,:,irun)); %not yet used
end end
end end
end end
IDE_LRE.si_dLREnorm = si_dLREnorm; IDE_DYNAMIC.si_dDYNAMICnorm = si_dDYNAMICnorm;
save([IdentifDirectoryName '/' fname '_identif.mat'], 'pdraws', 'IDE_LRE','STO_LRE','-append'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'pdraws', 'IDE_DYNAMIC','STO_DYNAMIC','-append');
if ~options_MC.no_identification_reducedform if ~options_MC.no_identification_reducedform
IDE_REDUCEDFORM.si_dTAUnorm = si_dTAUnorm; IDE_REDUCEDFORM.si_dREDUCEDFORMnorm = si_dREDUCEDFORMnorm;
save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_REDUCEDFORM', 'STO_TAU','-append'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_REDUCEDFORM', 'STO_REDUCEDFORM','-append');
end end
if ~options_MC.no_identification_moments if ~options_MC.no_identification_moments
IDE_MOMENTS.si_Jnorm = si_Jnorm; IDE_MOMENTS.si_dMOMENTSnorm = si_dMOMENTSnorm;
save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_MOMENTS', 'STO_MOMENTS','-append'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'IDE_MOMENTS', 'STO_MOMENTS','-append');
end end
@ -836,25 +853,25 @@ end
%% if dynare_identification is called as it own function (not through identification command) and if we load files %% if dynare_identification is called as it own function (not through identification command) and if we load files
if nargout>3 && iload if nargout>3 && iload
filnam = dir([IdentifDirectoryName '/' fname '_identif_*.mat']); filnam = dir([IdentifDirectoryName '/' fname '_identif_*.mat']);
STO_si_dLRE = []; STO_si_dDYNAMIC = [];
STO_si_dTAU=[]; STO_si_dREDUCEDFORM=[];
STO_si_J = []; STO_si_dMOMENTS = [];
STO_G = []; STO_dSPECTRUM = [];
STO_D = []; STO_dMINIMAL = [];
for j=1:length(filnam) for j=1:length(filnam)
load([IdentifDirectoryName '/' fname '_identif_',int2str(j),'.mat']); load([IdentifDirectoryName '/' fname '_identif_',int2str(j),'.mat']);
STO_si_dLRE = cat(3,STO_si_dLRE, STO_si_dLRE(:,abs(iload),:)); STO_si_dDYNAMIC = cat(3,STO_si_dDYNAMIC, STO_si_dDYNAMIC(:,abs(iload),:));
if ~options_ident.no_identification_reducedform if ~options_ident.no_identification_reducedform
STO_si_dTAU = cat(3,STO_si_dTAU, STO_si_dTAU(:,abs(iload),:)); STO_si_dREDUCEDFORM = cat(3,STO_si_dREDUCEDFORM, STO_si_dREDUCEDFORM(:,abs(iload),:));
end end
if ~options_ident.no_identification_moments if ~options_ident.no_identification_moments
STO_si_J = cat(3,STO_si_J, STO_si_J(:,abs(iload),:)); STO_si_dMOMENTS = cat(3,STO_si_dMOMENTS, STO_si_dMOMENTS(:,abs(iload),:));
end end
if ~options_ident.no_identification_spectrum if ~options_ident.no_identification_spectrum
STO_G = cat(3,STO_G, STO_G(:,abs(iload),:)); STO_dSPECTRUM = cat(3,STO_dSPECTRUM, STO_dSPECTRUM(:,abs(iload),:));
end end
if ~options_ident.no_identification_minimal if ~options_ident.no_identification_minimal
STO_D = cat(3,STO_D, STO_D(:,abs(iload),:)); STO_dMINIMAL = cat(3,STO_dMINIMAL, STO_dMINIMAL(:,abs(iload),:));
end end
end end
end end
@ -865,7 +882,7 @@ if iload
disp_identification(ide_hess_point.params, ide_reducedform_point, ide_moments_point, ide_spectrum_point, ide_minimal_point, name, options_ident); disp_identification(ide_hess_point.params, ide_reducedform_point, ide_moments_point, ide_spectrum_point, ide_minimal_point, name, options_ident);
if ~options_.nograph if ~options_.nograph
% plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs
plot_identification(ide_hess_point.params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_lre_point, options_ident.advanced, parameters, name, IdentifDirectoryName, [],name_tex); plot_identification(ide_hess_point.params, ide_moments_point, ide_hess_point, ide_reducedform_point, ide_dynamic_point, options_ident.advanced, parameters, name, IdentifDirectoryName, [],name_tex);
end end
end end
@ -880,7 +897,7 @@ if SampleSize > 1
options_ident.advanced = advanced0; % reset advanced setting options_ident.advanced = advanced0; % reset advanced setting
if ~options_.nograph if ~options_.nograph
% plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs
plot_identification(pdraws, IDE_MOMENTS, ide_hess_point, IDE_REDUCEDFORM, IDE_LRE, options_ident.advanced, 'MC sample ', name, IdentifDirectoryName, [], name_tex); plot_identification(pdraws, IDE_MOMENTS, ide_hess_point, IDE_REDUCEDFORM, IDE_DYNAMIC, options_ident.advanced, 'MC sample ', name, IdentifDirectoryName, [], name_tex);
end end
%advanced display and plots for MC Sample, i.e. look at draws with highest/lowest condition number %advanced display and plots for MC Sample, i.e. look at draws with highest/lowest condition number
if options_ident.advanced if options_ident.advanced
@ -898,16 +915,16 @@ if SampleSize > 1
disp(['Testing ',tittxt, '.']), disp(['Testing ',tittxt, '.']),
if ~iload if ~iload
options_ident.tittxt = tittxt; %title text for graphs and figures options_ident.tittxt = tittxt; %title text for graphs and figures
[ide_moments_max, ide_spectrum_max, ide_minimal_max, ide_hess_max, ide_reducedform_max, ide_lre_max, derivatives_info_max, info_max, options_ident] = ... [ide_moments_max, ide_spectrum_max, ide_minimal_max, ide_hess_max, ide_reducedform_max, ide_dynamic_max, derivatives_info_max, info_max, options_ident] = ...
identification_analysis(pdraws(jmax,:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end initializes some persistent variables identification_analysis(pdraws(jmax,:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end initializes some persistent variables
save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_max', 'ide_moments_max', 'ide_spectrum_max', 'ide_minimal_max','ide_reducedform_max', 'ide_lre_max', 'jmax', '-append'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_max', 'ide_moments_max', 'ide_spectrum_max', 'ide_minimal_max','ide_reducedform_max', 'ide_dynamic_max', 'jmax', '-append');
end end
advanced0 = options_ident.advanced; options_ident.advanced = 1; % make sure advanced setting is on advanced0 = options_ident.advanced; options_ident.advanced = 1; % make sure advanced setting is on
disp_identification(pdraws(jmax,:), ide_reducedform_max, ide_moments_max, ide_spectrum_max, ide_minimal_max, name, options_ident); disp_identification(pdraws(jmax,:), ide_reducedform_max, ide_moments_max, ide_spectrum_max, ide_minimal_max, name, options_ident);
options_ident.advanced = advanced0; %reset advanced setting options_ident.advanced = advanced0; %reset advanced setting
if ~options_.nograph if ~options_.nograph
% plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs
plot_identification(pdraws(jmax,:), ide_moments_max, ide_hess_max, ide_reducedform_max, ide_lre_max, 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex); plot_identification(pdraws(jmax,:), ide_moments_max, ide_hess_max, ide_reducedform_max, ide_dynamic_max, 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex);
end end
% SMALLEST condition number % SMALLEST condition number
@ -918,16 +935,16 @@ if SampleSize > 1
disp(['Testing ',tittxt, '.']), disp(['Testing ',tittxt, '.']),
if ~iload if ~iload
options_ident.tittxt = tittxt; %title text for graphs and figures options_ident.tittxt = tittxt; %title text for graphs and figures
[ide_moments_min, ide_spectrum_min, ide_minimal_min, ide_hess_min, ide_reducedform_min, ide_lre_min, derivatives_info_min, info_min, options_ident] = ... [ide_moments_min, ide_spectrum_min, ide_minimal_min, ide_hess_min, ide_reducedform_min, ide_dynamic_min, derivatives_info_min, info_min, options_ident] = ...
identification_analysis(pdraws(jmin,:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end initializes persistent variables identification_analysis(pdraws(jmin,:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); %the 1 at the end initializes persistent variables
save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_min', 'ide_moments_min','ide_spectrum_min','ide_minimal_min','ide_reducedform_min', 'ide_lre_min', 'jmin', '-append'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_min', 'ide_moments_min','ide_spectrum_min','ide_minimal_min','ide_reducedform_min', 'ide_dynamic_min', 'jmin', '-append');
end end
advanced0 = options_ident.advanced; options_ident.advanced = 1; % make sure advanced setting is on advanced0 = options_ident.advanced; options_ident.advanced = 1; % make sure advanced setting is on
disp_identification(pdraws(jmin,:), ide_reducedform_min, ide_moments_min, ide_spectrum_min, ide_minimal_min, name, options_ident); disp_identification(pdraws(jmin,:), ide_reducedform_min, ide_moments_min, ide_spectrum_min, ide_minimal_min, name, options_ident);
options_ident.advanced = advanced0; %reset advanced setting options_ident.advanced = advanced0; %reset advanced setting
if ~options_.nograph if ~options_.nograph
% plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs
plot_identification(pdraws(jmin,:),ide_moments_min,ide_hess_min,ide_reducedform_min,ide_lre_min,1,tittxt,name,IdentifDirectoryName,tittxt,name_tex); plot_identification(pdraws(jmin,:),ide_moments_min,ide_hess_min,ide_reducedform_min,ide_dynamic_min,1,tittxt,name,IdentifDirectoryName,tittxt,name_tex);
end end
% reset nodisplay option % reset nodisplay option
options_.nodisplay = store_nodisplay; options_.nodisplay = store_nodisplay;
@ -941,7 +958,7 @@ if SampleSize > 1
disp(['Testing ',tittxt, '.']), disp(['Testing ',tittxt, '.']),
if ~iload if ~iload
options_ident.tittxt = tittxt; %title text for graphs and figures options_ident.tittxt = tittxt; %title text for graphs and figures
[ide_moments_(j), ide_spectrum_(j), ide_minimal_(j), ide_hess_(j), ide_reducedform_(j), ide_lre_(j), derivatives_info_(j), info_resolve, options_ident] = ... [ide_moments_(j), ide_spectrum_(j), ide_minimal_(j), ide_hess_(j), ide_reducedform_(j), ide_dynamic_(j), derivatives_info_(j), info_resolve, options_ident] = ...
identification_analysis(pdraws(jcrit(j),:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1); identification_analysis(pdraws(jcrit(j),:), indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, 1);
end end
advanced0 = options_ident.advanced; options_ident.advanced = 1; %make sure advanced setting is on advanced0 = options_ident.advanced; options_ident.advanced = 1; %make sure advanced setting is on
@ -949,11 +966,11 @@ if SampleSize > 1
options_ident.advanced = advanced0; % reset advanced options_ident.advanced = advanced0; % reset advanced
if ~options_.nograph if ~options_.nograph
% plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs % plot (i) identification strength and sensitivity measure based on the sample information matrix and (ii) advanced analysis graphs
plot_identification(pdraws(jcrit(j),:), ide_moments_(j), ide_hess_(j), ide_reducedform_(j), ide_lre_(j), 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex); plot_identification(pdraws(jcrit(j),:), ide_moments_(j), ide_hess_(j), ide_reducedform_(j), ide_dynamic_(j), 1, tittxt, name, IdentifDirectoryName, tittxt, name_tex);
end end
end end
if ~iload if ~iload
save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_', 'ide_moments_', 'ide_reducedform_', 'ide_lre_', 'ide_spectrum_', 'ide_minimal_', 'jcrit', '-append'); save([IdentifDirectoryName '/' fname '_identif.mat'], 'ide_hess_', 'ide_moments_', 'ide_reducedform_', 'ide_dynamic_', 'ide_spectrum_', 'ide_minimal_', 'jcrit', '-append');
end end
% reset nodisplay option % reset nodisplay option
options_.nodisplay = store_nodisplay; options_.nodisplay = store_nodisplay;

View File

@ -1,16 +1,9 @@
function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs) function [E_y, dE_y, REDUCEDFORM, dREDUCEDFORM, DYNAMIC, dDYNAMIC, MOMENTS, dMOMENTS, dSPECTRUM, dMINIMAL, derivatives_info] = get_identification_jacobians(estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs)
% [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs) % function [MEAN, dMEAN, REDUCEDFORM, dREDUCEDFORM, DYNAMIC, dDYNAMIC, MOMENTS, dMOMENTS, dSPECTRUM, dMINIMAL, derivatives_info] = get_identification_jacobians(estim_params, M, oo, options, options_ident, indpmodel, indpstderr, indpcorr, indvobs)
% previously getJJ.m % previously getJJ.m
% ------------------------------------------------------------------------- % % Sets up the Jacobians needed for identification analysis
% Sets up the Jacobians needed for identification analysis based on the
% Iskrev's J, Qu and Tkachenko's G and Komunjer and Ng's D matrices as well
% as on the reduced-form model (dTAU) and the dynamic model (dLRE)
% ========================================================================= % =========================================================================
% INPUTS % INPUTS
% A: [endo_nbr by endo_nbr] in DR order
% Transition matrix from Kalman filter for all endogenous declared variables,
% B: [endo_nbr by exo_nbr] in DR order
% Transition matrix from Kalman filter mapping shocks today to endogenous variables today
% estim_params: [structure] storing the estimation information % estim_params: [structure] storing the estimation information
% M: [structure] storing the model information % M: [structure] storing the model information
% oo: [structure] storing the reduced-form solution results % oo: [structure] storing the reduced-form solution results
@ -31,37 +24,50 @@ function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jaco
% indvobs: [obs_nbr by 1] index of observed (VAROBS) variables % indvobs: [obs_nbr by 1] index of observed (VAROBS) variables
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% OUTPUTS % OUTPUTS
% J: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by totparam_nbr] in DR Order %
% Jacobian of 1st and 2nd order moments of observables wrt, % MEAN [endo_nbr by 1], in DR order. Expectation of all model variables
% all parameters, i.e. dgam (see below for definition of gam). % * order==1: corresponds to steady state
% Corresponds to Iskrev (2010)'s J matrix. % * order==2: computed from pruned state space system (as in e.g. Andreasen, Fernandez-Villaverde, Rubio-Ramirez, 2018)
% G: [totparam_nbr by totparam_nbr] in DR Order % dMEAN [endo_nbr by totparam_nbr], in DR Order, Jacobian (wrt all params) of MEAN
% Sum of (1) Gram Matrix of Jacobian of spectral density %
% wrt to all parameters plus (2) Gram Matrix of Jacobian % REDUCEDFORM [rowredform_nbr by 1] in DR order. Steady state and reduced-form model solution matrices for all model variables
% of steady state wrt to all parameters. % * order==1: [Yss' vec(dghx)' vech(dghu*Sigma_e*dghu')']',
% Corresponds to Qu and Tkachenko (2012)'s G matrix. % where rowredform_nbr = endo_nbr+endo_nbr*nspred+endo_nbr*(endo_nbr+1)/2
% D: [obs_nbr+minstate_nbr^2+minstate_nbr*exo_nbr+obs_nbr*minstate_nbr+obs_nbr*exo_nbr+exo_nbr*(exo_nbr+1)/2 by totparam_nbr+minstate_nbr^2+exo_nbr^2] in DR order % * order==2: [Yss' vec(dghx)' vech(dghu*Sigma_e*dghu')' vec(dghxx)' vec(dghxu)' vec(dghuu)' vec(dghs2)']',
% Jacobian of minimal System Matrices and unique Transformation % where rowredform_nbr = endo_nbr+endo_nbr*nspred+endo_nbr*(endo_nbr+1)/2+endo_nbr*nspred^2*endo_nbr*nspred*exo_nr+endo_nbr*exo_nbr^2+endo_nbr
% of steady state and spectral density matrix. % dREDUCEDFORM: [rowrf_nbr by totparam_nbr] in DR order, Jacobian (wrt all params) of REDUCEDFORM
% Corresponds to Komunjer and Ng (2011)'s Delta matrix. % * order==1: corresponds to Iskrev (2010)'s J_2 matrix
% dTAU: [(endo_nbr+endo_nbr^2+endo_nbr*(endo_nbr+1)/2) by totparam_nbr] in DR order % * order==2: corresponds to Mutschler (2015)'s J matrix
% Jacobian of linearized reduced form state space model, given Yss [steady state], %
% A [transition matrix], B [matrix of shocks], Sigma [covariance of shocks] % DYNAMIC [rowdyn_nbr by 1] in declaration order. Steady state and dynamic model derivatives for all model variables
% tau = [ys; vec(A); dyn_vech(B*Sigma*B')] with respect to all parameters. % * order==1: [ys' vec(g1)']', rowdyn_nbr=endo_nbr+length(g1)
% dLRE: [endo_nbr+endo_nbr*(dynamicvar_nbr+exo_nbr) by modparam_nbr] in DR order % * order==2: [ys' vec(g1)' vec(g2)']', rowdyn_nbr=endo_nbr+length(g1)+length(g2)
% Jacobian of steady state and linear rational expectation matrices % dDYNAMIC [rowdyn_nbr by modparam_nbr] in declaration order. Jacobian (wrt model parameters) of DYNAMIC
% (i.e. Jacobian of dynamic model) with respect to estimated model parameters only (indpmodel) % * order==1: corresponds to Ratto and Iskrev (2011)'s J_\Gamma matrix (or LRE)
% dA: [endo_nbr by endo_nbr by totparam_nbr] in DR order % * order==2: additionally includes derivatives of dynamic hessian
% Jacobian (wrt to all parameters) of transition matrix A %
% dOm: [endo_nbr by endo_nbr by totparam_nbr] in DR order % MOMENTS: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by 1] in DR order. First two theoretical moments for VAROBS variables, i.e.
% Jacobian (wrt to all paramters) of Om = (B*Sigma_e*B') % [E[yobs]' vech(E[yobs*yobs'])' vec(E[yobs*yobs(-1)'])' ... vec(E[yobs*yobs(-nlag)'])']
% dYss [endo_nbr by modparam_nbr] in DR order % dMOMENTS: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by totparam_nbr] in DR order. Jacobian (wrt all params) of MOMENTS
% Jacobian (wrt model parameters only) of steady state % * order==1: corresponds to Iskrev (2010)'s J matrix
% MOMENTS: [obs_nbr+obs_nbr*(obs_nbr+1)/2+nlags*obs_nbr^2 by 1] % * order==2: corresponds to Mutschler (2015)'s \bar{M}_2 matrix, i.e. theoretical moments from the pruned state space system
% vector of theoretical moments of observed (VAROBS) %
% variables. Note that J is the Jacobian of MOMENTS. % dSPECTRUM: [totparam_nbr by totparam_nbr] in DR order. Gram matrix of Jacobian (wrt all params) of spectral density for VAROBS variables, where
% MOMENTS = [ys(indvobs); dyn_vech(GAM{1}); vec(GAM{j+1})]; for j=1:ar and where % spectral density at frequency w: f(w) = (2*pi)^(-1)*H(exp(-i*w))*E[xi*xi']*ctranspose(H(exp(-i*w)) with H being the Transfer function
% GAM is the first output of th_autocovariances % dSPECTRUM = int_{-\pi}^\pi transpose(df(w)/dp')*(df(w)/dp') dw
% * order==1: corresponds to Qu and Tkachenko (2012)'s G matrix, where xi and H are computed from linear state space system
% * order==2: corresponds to Mutschler (2015)'s G_2 matrix, where xi and H are computed from pruned state space system
%
% dMINIMAL: [obs_nbr+minx^2+minx*exo_nbr+obs_nbr*minx+obs_nbr*exo_nbr+exo_nbr*(exo_nbr+1)/2 by totparam_nbr+minx^2+exo_nbr^2]
% Jacobian (wrt all params, and similarity_transformation_matrices (T and U)) of observational equivalent minimal ABCD system,
% corresponds to Komunjer and Ng (2011)'s Deltabar matrix, where
% MINIMAL = [vec(E[yobs]' vec(minA)' vec(minB)' vec(minC)' vec(minD)' vech(Sigma_e)']'
% * order==1: E[yobs] is equal to steady state
% * order==2: E[yobs] is computed from the pruned state space system (second-order accurate), as noted in section 5 of Komunjer and Ng (2011)
%
% derivatives_info [structure] for use in dsge_likelihood to compute Hessian analytically.
% Contains dA, dB, and d(B*Sigma_e*B'), where A and B are from Kalman filter. Only used at order==1.
%
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function is called by % This function is called by
% * identification_analysis.m % * identification_analysis.m
@ -71,11 +77,10 @@ function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jaco
% * get_minimal_state_representation % * get_minimal_state_representation
% * duplication % * duplication
% * dyn_vech % * dyn_vech
% * get_perturbation_params_deriv (previously getH) % * get_perturbation_params_derivs (previously getH)
% * get_all_parameters % * get_all_parameters
% * fjaco % * fjaco
% * lyapunov_symm % * lyapunov_symm
% * th_autocovariances
% * identification_numerical_objective (previously thet2tau) % * identification_numerical_objective (previously thet2tau)
% * vec % * vec
% ========================================================================= % =========================================================================
@ -98,13 +103,17 @@ function [J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jaco
% ========================================================================= % =========================================================================
%get options %get options
no_identification_moments = options_ident.no_identification_moments;
no_identification_minimal = options_ident.no_identification_minimal;
no_identification_spectrum = options_ident.no_identification_spectrum;
order = options_ident.order;
nlags = options_ident.ar; nlags = options_ident.ar;
useautocorr = options_ident.useautocorr; useautocorr = options_ident.useautocorr;
grid_nbr = options_ident.grid_nbr; grid_nbr = options_ident.grid_nbr;
kronflag = options_ident.analytic_derivation_mode; kronflag = options_ident.analytic_derivation_mode;
no_identification_moments = options_ident.no_identification_moments;
no_identification_minimal = options_ident.no_identification_minimal; % set values
no_identification_spectrum = options_ident.no_identification_spectrum;
params0 = M.params; %values at which to evaluate dynamic, static and param_derivs files params0 = M.params; %values at which to evaluate dynamic, static and param_derivs files
Sigma_e0 = M.Sigma_e; %covariance matrix of exogenous shocks Sigma_e0 = M.Sigma_e; %covariance matrix of exogenous shocks
Corr_e0 = M.Correlation_matrix; %correlation matrix of exogenous shocks Corr_e0 = M.Correlation_matrix; %correlation matrix of exogenous shocks
@ -114,6 +123,7 @@ if isempty(para0)
%if there is no estimated_params block, consider all stderr and all model parameters, but no corr parameters %if there is no estimated_params block, consider all stderr and all model parameters, but no corr parameters
para0 = [stderr_e0', params0']; para0 = [stderr_e0', params0'];
end end
%get numbers/lengths of vectors %get numbers/lengths of vectors
modparam_nbr = length(indpmodel); modparam_nbr = length(indpmodel);
stderrparam_nbr = length(indpstderr); stderrparam_nbr = length(indpstderr);
@ -122,108 +132,189 @@ totparam_nbr = stderrparam_nbr + corrparam_nbr + modparam_nbr;
obs_nbr = length(indvobs); obs_nbr = length(indvobs);
exo_nbr = M.exo_nbr; exo_nbr = M.exo_nbr;
endo_nbr = M.endo_nbr; endo_nbr = M.endo_nbr;
nspred = M.nspred;
nstatic = M.nstatic;
indvall = (1:endo_nbr)'; %index for all endogenous variables
d2flag = 0; % do not compute second parameter derivatives
%% Construct dTAU, dLRE, dA, dOm, dYss % Get Jacobians (wrt selected params) of steady state, dynamic model derivatives and perturbation solution matrices for all endogenous variables
DERIVS = get_perturbation_params_derivs(M, options, estim_params, oo, indpmodel, indpstderr, indpcorr, 0);%d2flag=0 oo.dr.derivs = get_perturbation_params_derivs(M, options, estim_params, oo, indpmodel, indpstderr, indpcorr, d2flag);
dA = zeros(M.endo_nbr, M.endo_nbr, size(DERIVS.dghx,3));
dA(:,M.nstatic+(1:M.nspred),:) = DERIVS.dghx;
dB = DERIVS.dghu;
dSig = DERIVS.dSigma_e;
dOm = DERIVS.dOm;
dYss = DERIVS.dYss;
% Collect terms for derivative of tau=[Yss; vec(A); vech(Om)] [I,~] = find(M.lead_lag_incidence'); %I is used to select nonzero columns of the Jacobian of endogenous variables in dynamic model files
dTAU = zeros(endo_nbr*endo_nbr+endo_nbr*(endo_nbr+1)/2, totparam_nbr); yy0 = oo.dr.ys(I); %steady state of dynamic (endogenous and auxiliary variables) in lead_lag_incidence order
for j=1:totparam_nbr Yss = oo.dr.ys(oo.dr.order_var); % steady state in DR order
dTAU(:,j) = [vec(dA(:,:,j)); dyn_vech(dOm(:,:,j))]; if order == 1
[~, g1 ] = feval([M.fname,'.dynamic'], yy0, oo.exo_steady_state', params0, oo.dr.ys, 1);
%g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order
DYNAMIC = [Yss;
vec(g1(oo.dr.order_var,:))]; %add steady state and put rows of g1 in DR order
dDYNAMIC = [oo.dr.derivs.dYss;
reshape(oo.dr.derivs.dg1(oo.dr.order_var,:,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2),size(oo.dr.derivs.dg1,3)) ]; %reshape dg1 in DR order and add steady state
REDUCEDFORM = [Yss;
vec(oo.dr.ghx);
dyn_vech(oo.dr.ghu*Sigma_e0*transpose(oo.dr.ghu))]; %in DR order
dREDUCEDFORM = zeros(endo_nbr*nspred+endo_nbr*(endo_nbr+1)/2, totparam_nbr);
for j=1:totparam_nbr
dREDUCEDFORM(:,j) = [vec(oo.dr.derivs.dghx(:,:,j));
dyn_vech(oo.dr.derivs.dOm(:,:,j))];
end
dREDUCEDFORM = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) oo.dr.derivs.dYss]; dREDUCEDFORM ]; % add steady state
elseif order == 2
[~, g1, g2 ] = feval([M.fname,'.dynamic'], yy0, oo.exo_steady_state', params0, oo.dr.ys, 1);
%g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order
%g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order
DYNAMIC = [Yss;
vec(g1(oo.dr.order_var,:));
vec(g2(oo.dr.order_var,:))]; %add steady state and put rows of g1 and g2 in DR order
dDYNAMIC = [oo.dr.derivs.dYss;
reshape(oo.dr.derivs.dg1(oo.dr.order_var,:,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2),size(oo.dr.derivs.dg1,3)); %reshape dg1 in DR order
reshape(oo.dr.derivs.dg2(oo.dr.order_var,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2)^2,size(oo.dr.derivs.dg1,3))]; %reshape dg2 in DR order
REDUCEDFORM = [Yss;
vec(oo.dr.ghx);
dyn_vech(oo.dr.ghu*Sigma_e0*transpose(oo.dr.ghu));
vec(oo.dr.ghxx);
vec(oo.dr.ghxu);
vec(oo.dr.ghuu);
vec(oo.dr.ghs2)]; %in DR order
dREDUCEDFORM = zeros(endo_nbr*nspred+endo_nbr*(endo_nbr+1)/2+endo_nbr*nspred^2+endo_nbr*nspred*exo_nbr+endo_nbr*exo_nbr^2+endo_nbr, totparam_nbr);
for j=1:totparam_nbr
dREDUCEDFORM(:,j) = [vec(oo.dr.derivs.dghx(:,:,j));
dyn_vech(oo.dr.derivs.dOm(:,:,j));
vec(oo.dr.derivs.dghxx(:,:,j));
vec(oo.dr.derivs.dghxu(:,:,j));
vec(oo.dr.derivs.dghuu(:,:,j));
vec(oo.dr.derivs.dghs2(:,j))];
end
dREDUCEDFORM = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) oo.dr.derivs.dYss]; dREDUCEDFORM ]; % add steady state
elseif order == 3
[~, g1, g2, g3 ] = feval([M.fname,'.dynamic'], yy0, oo.exo_steady_state', params0, oo.dr.ys, 1);
%g1 is [endo_nbr by yy0ex0_nbr first derivative (wrt all dynamic variables) of dynamic model equations, i.e. df/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order
%g2 is [endo_nbr by yy0ex0_nbr^2] second derivative (wrt all dynamic variables) of dynamic model equations, i.e. d(df/dyy0ex0)/dyy0ex0, rows are in declaration order, columns in lead_lag_incidence order
DYNAMIC = [Yss;
vec(g1(oo.dr.order_var,:));
vec(g2(oo.dr.order_var,:));
vec(g3(oo.dr.order_var,:))]; %add steady state and put rows of g1 and g2 in DR order
dDYNAMIC = [oo.dr.derivs.dYss;
reshape(oo.dr.derivs.dg1(oo.dr.order_var,:,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2),size(oo.dr.derivs.dg1,3)); %reshape dg1 in DR order
reshape(oo.dr.derivs.dg2(oo.dr.order_var,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2)^2,size(oo.dr.derivs.dg1,3));
reshape(oo.dr.derivs.dg2(oo.dr.order_var,:),size(oo.dr.derivs.dg1,1)*size(oo.dr.derivs.dg1,2)^2,size(oo.dr.derivs.dg1,3))]; %reshape dg3 in DR order
REDUCEDFORM = [Yss;
vec(oo.dr.ghx);
dyn_vech(oo.dr.ghu*Sigma_e0*transpose(oo.dr.ghu));
vec(oo.dr.ghxx); vec(oo.dr.ghxu); vec(oo.dr.ghuu); vec(oo.dr.ghs2);
vec(oo.dr.ghxxx); vec(oo.dr.ghxxu); vec(oo.dr.ghxuu); vec(oo.dr.ghuuu); vec(oo.dr.ghxss); vec(oo.dr.ghuss)]; %in DR order
dREDUCEDFORM = zeros(size(REDUCEDFORM,1)-endo_nbr, totparam_nbr);
for j=1:totparam_nbr
dREDUCEDFORM(:,j) = [vec(oo.dr.derivs.dghx(:,:,j));
dyn_vech(oo.dr.derivs.dOm(:,:,j));
vec(oo.dr.derivs.dghxx(:,:,j)); vec(oo.dr.derivs.dghxu(:,:,j)); vec(oo.dr.derivs.dghuu(:,:,j)); vec(oo.dr.derivs.dghs2(:,j))
vec(oo.dr.derivs.dghxxx(:,:,j)); vec(oo.dr.derivs.dghxxu(:,:,j)); vec(oo.dr.derivs.dghxuu(:,:,j)); vec(oo.dr.derivs.dghuuu(:,:,j)); vec(oo.dr.derivs.dghxss(:,:,j)); vec(oo.dr.derivs.dghuss(:,:,j))];
end
dREDUCEDFORM = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) oo.dr.derivs.dYss]; dREDUCEDFORM ]; % add steady state
end end
dTAU = [ [zeros(endo_nbr, stderrparam_nbr+corrparam_nbr) dYss]; dTAU ]; % add steady state
dLRE = [dYss; reshape(DERIVS.dg1,size(DERIVS.dg1,1)*size(DERIVS.dg1,2),size(DERIVS.dg1,3)) ]; %reshape dg1 and add steady state
%State Space Matrices for VAROBS variables % Get (pruned) state space representation:
C = A(indvobs,:); options.options_ident.indvobs = indvobs;
dC = dA(indvobs,:,:); options.options_ident.indpmodel = indpmodel;
D = B(indvobs,:); options.options_ident.indpstderr = indpstderr;
dD = dB(indvobs,:,:); options.options_ident.indpcorr = indpcorr;
oo.dr = pruned_state_space_system(M, options, oo.dr);
E_y = oo.dr.pruned.E_y; dE_y = oo.dr.pruned.dE_y;
A = oo.dr.pruned.A; dA = oo.dr.pruned.dA;
B = oo.dr.pruned.B; dB = oo.dr.pruned.dB;
C = oo.dr.pruned.C; dC = oo.dr.pruned.dC;
D = oo.dr.pruned.D; dD = oo.dr.pruned.dD;
c = oo.dr.pruned.c; dc = oo.dr.pruned.dc;
d = oo.dr.pruned.d; dd = oo.dr.pruned.dd;
Varinov = oo.dr.pruned.Varinov; dVarinov = oo.dr.pruned.dVarinov;
Om_z = oo.dr.pruned.Om_z; dOm_z = oo.dr.pruned.dOm_z;
Om_y = oo.dr.pruned.Om_y; dOm_y = oo.dr.pruned.dOm_y;
%% Iskrev (2010) %storage for Jacobians used in dsge_likelihood.m for analytical Gradient and Hession of likelihood (only at order=1)
derivatives_info = struct();
if order == 1
dT = zeros(endo_nbr,endo_nbr,totparam_nbr);
dT(:,(nstatic+1):(nstatic+nspred),:) = oo.dr.derivs.dghx;
derivatives_info.DT = dT;
derivatives_info.DOm = oo.dr.derivs.dOm;
derivatives_info.DYss = oo.dr.derivs.dYss;
end
%% Compute dMOMENTS
%Note that our state space system for computing second moments is the following:
% zhat = A*zhat(-1) + B*xi, where zhat = z - E(z)
% yhat = C*zhat(-1) + D*xi, where yhat = y - E(y)
if ~no_identification_moments if ~no_identification_moments
MOMENTS = identification_numerical_objective(para0, 1, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); %[outputflag=1]
MOMENTS = [E_y; MOMENTS];
if kronflag == -1 if kronflag == -1
%numerical derivative of autocovariogram [outputflag=1] %numerical derivative of autocovariogram
J = fjaco(str2func('identification_numerical_objective'), para0, 1, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); dMOMENTS = fjaco(str2func('identification_numerical_objective'), para0, 1, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); %[outputflag=1]
M.params = params0; %make sure values are set back M.params = params0; %make sure values are set back
M.Sigma_e = Sigma_e0; %make sure values are set back M.Sigma_e = Sigma_e0; %make sure values are set back
M.Correlation_matrix = Corr_e0 ; %make sure values are set back M.Correlation_matrix = Corr_e0 ; %make sure values are set back
J = [[zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)]; J]; %add Jacobian of steady state of VAROBS variables dMOMENTS = [dE_y; dMOMENTS]; %add Jacobian of steady state of VAROBS variables
else else
J = zeros(obs_nbr + obs_nbr*(obs_nbr+1)/2 + nlags*obs_nbr^2 , totparam_nbr); dMOMENTS = zeros(obs_nbr + obs_nbr*(obs_nbr+1)/2 + nlags*obs_nbr^2 , totparam_nbr);
J(1:obs_nbr,stderrparam_nbr+corrparam_nbr+1 : totparam_nbr) = dYss(indvobs,:); %add Jacobian of steady state of VAROBS variables dMOMENTS(1:obs_nbr,:) = dE_y; %add Jacobian of first moments of VAROBS variables
% Denote Ezz0 = E_t(z_t * z_t'), then the following Lyapunov equation defines the autocovariagram: Ezz0 -A*Ezz*A' = B*Sig_e*B' = Om % Denote Ezz0 = E[zhat*zhat'], then the following Lyapunov equation defines the autocovariagram: Ezz0 -A*Ezz0*A' = B*Sig_xi*B' = Om_z
Gamma_y = lyapunov_symm(A, B*Sigma_e0*B', options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold, 1, options.debug); Ezz0 = lyapunov_symm(A, B*Varinov*B', options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold, 1, options.debug);
Eyy0 = C*Ezz0*C' + D*Varinov*D';
%here method=1 is used, whereas all other calls of lyapunov_symm use method=2. The reason is that T and U are persistent, and input matrix A is the same, so using option 2 for all the rest of iterations spares a lot of computing time while not repeating Schur every time %here method=1 is used, whereas all other calls of lyapunov_symm use method=2. The reason is that T and U are persistent, and input matrix A is the same, so using option 2 for all the rest of iterations spares a lot of computing time while not repeating Schur every time
indzeros = find(abs(Gamma_y) < 1e-12); %find values that are numerical zero indzeros = find(abs(Eyy0) < 1e-12); %find values that are numerical zero
Gamma_y(indzeros) = 0; Eyy0(indzeros) = 0;
% if useautocorr, if useautocorr
sdy = sqrt(diag(Gamma_y)); %theoretical standard deviation sdy = sqrt(diag(Eyy0)); %theoretical standard deviation
sy = sdy*sdy'; %cross products of standard deviations sy = sdy*sdy'; %cross products of standard deviations
% end end
for j = 1:(stderrparam_nbr+corrparam_nbr)
%Jacobian of Ezz0 wrt exogenous paramters: dEzz0(:,:,j)-A*dEzz0(:,:,j)*A'=dOm(:,:,j), because dA is zero by construction for stderr and corr parameters for jp = 1:totparam_nbr
dEzz0 = lyapunov_symm(A,dOm(:,:,j),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug); if jp <= (stderrparam_nbr+corrparam_nbr)
%here method=2 is used to spare a lot of computing time while not repeating Schur every time %Note that for stderr and corr parameters, the derivatives of the system matrices are zero, i.e. dA=dB=dC=dD=0
indzeros = find(abs(dEzz0) < 1e-12); dEzz0 = lyapunov_symm(A,dOm_z(:,:,jp),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug); %here method=2 is used to spare a lot of computing time while not repeating Schur every time
dEzz0(indzeros) = 0; dEyy0 = C*dEzz0*C' + dOm_y(:,:,jp);
else %model parameters
dEzz0 = lyapunov_symm(A,dOm_z(:,:,jp)+dA(:,:,jp)*Ezz0*A'+A*Ezz0*dA(:,:,jp)',options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug); %here method=2 is used to spare a lot of computing time while not repeating Schur every time
dEyy0 = dC(:,:,jp)*Ezz0*C' + C*dEzz0*C' + C*Ezz0*dC(:,:,jp)' + dOm_y(:,:,jp);
end
%indzeros = find(abs(dEyy0) < 1e-12);
%dEyy0(indzeros) = 0;
if useautocorr if useautocorr
dsy = 1/2./sdy.*diag(dEzz0); dsy = 1/2./sdy.*diag(dEyy0);
dsy = dsy*sdy'+sdy*dsy'; dsy = dsy*sdy'+sdy*dsy';
dEzz0corr = (dEzz0.*sy-dsy.*Gamma_y)./(sy.*sy); dEyy0corr = (dEyy0.*sy-dsy.*Eyy0)./(sy.*sy);
dEzz0corr = dEzz0corr-diag(diag(dEzz0corr))+diag(diag(dEzz0)); dEyy0corr = dEyy0corr-diag(diag(dEyy0corr))+diag(diag(dEyy0));
J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , j) = dyn_vech(dEzz0corr(indvobs,indvobs)); %focus only on VAROBS variables dMOMENTS(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , jp) = dyn_vech(dEyy0corr); %focus only on VAROBS variables
else else
J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , j) = dyn_vech(dEzz0(indvobs,indvobs)); %focus only on VAROBS variables dMOMENTS(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , jp) = dyn_vech(dEyy0); %focus only on VAROBS variables
end end
%Jacobian of Ezzi = E_t(z_t * z_{t-i}'): dEzzi(:,:,j) = A^i*dEzz0(:,:,j) wrt stderr and corr parameters, because dA is zero by construction for stderr and corr parameters tmpEyyi = A*Ezz0*C' + B*Varinov*D';
%we could distinguish between stderr and corr params, but this has no real speed effect as we multipliy with zeros
dtmpEyyi = dA(:,:,jp)*Ezz0*C' + A*dEzz0*C' + A*Ezz0*dC(:,:,jp)' + dB(:,:,jp)*Varinov*D' + B*dVarinov(:,:,jp)*D' + B*Varinov*dD(:,:,jp)';
Ai = eye(size(A,1)); %this is A^0
dAi = zeros(size(A,1),size(A,1)); %this is d(A^0)
for i = 1:nlags for i = 1:nlags
dEzzi = A^i*dEzz0; Eyyi = C*Ai*tmpEyyi;
dEyyi = dC(:,:,jp)*Ai*tmpEyyi + C*dAi*tmpEyyi + C*Ai*dtmpEyyi;
if useautocorr if useautocorr
dEzzi = (dEzzi.*sy-dsy.*(A^i*Gamma_y))./(sy.*sy); dEyyi = (dEyyi.*sy-dsy.*Eyyi)./(sy.*sy);
end end
J(obs_nbr + obs_nbr*(obs_nbr+1)/2 + (i-1)*obs_nbr^2 + 1 : obs_nbr + obs_nbr*(obs_nbr+1)/2 + i*obs_nbr^2, j) = vec(dEzzi(indvobs,indvobs)); %focus only on VAROBS variables dMOMENTS(obs_nbr + obs_nbr*(obs_nbr+1)/2 + (i-1)*obs_nbr^2 + 1 : obs_nbr + obs_nbr*(obs_nbr+1)/2 + i*obs_nbr^2, jp) = vec(dEyyi); %focus only on VAROBS variables
end dAi = dAi*A + Ai*dA(:,:,jp); %note that this is d(A^(i-1))
end Ai = Ai*A; %note that this is A^(i-1)
for j=1:modparam_nbr
%Jacobian of Ezz0 wrt model parameters: dEzz0(:,:,j) - A*dEzz0(:,:,j)*A' = dOm(:,:,j) + dA(:,:,j)*Ezz*A'+ A*Ezz*dA(:,:,j)'
dEzz0 = lyapunov_symm(A,dA(:,:,j+stderrparam_nbr+corrparam_nbr)*Gamma_y*A'+A*Gamma_y*dA(:,:,j+stderrparam_nbr+corrparam_nbr)'+dOm(:,:,j+stderrparam_nbr+corrparam_nbr),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug);
%here method=2 is used to spare a lot of computing time while not repeating Schur every time
indzeros = find(abs(dEzz0) < 1e-12);
dEzz0(indzeros) = 0;
if useautocorr
dsy = 1/2./sdy.*diag(dEzz0);
dsy = dsy*sdy'+sdy*dsy';
dEzz0corr = (dEzz0.*sy-dsy.*Gamma_y)./(sy.*sy);
dEzz0corr = dEzz0corr-diag(diag(dEzz0corr))+diag(diag(dEzz0));
J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , stderrparam_nbr+corrparam_nbr+j) = dyn_vech(dEzz0corr(indvobs,indvobs)); %focus only on VAROBS variables
else
J(obs_nbr+1 : obs_nbr+obs_nbr*(obs_nbr+1)/2 , stderrparam_nbr+corrparam_nbr+j) = dyn_vech(dEzz0(indvobs,indvobs)); %focus only on VAROBS variables
end
%Jacobian of Ezzi = E_t(z_t * z_{t-i}'): dEzzi(:,:,j) = A^i*dEzz0(:,:,j) + d(A^i)*dEzz0(:,:,j) wrt model parameters
for i = 1:nlags
dEzzi = A^i*dEzz0;
for ii=1:i
dEzzi = dEzzi + A^(ii-1)*dA(:,:,j+stderrparam_nbr+corrparam_nbr)*A^(i-ii)*Gamma_y;
end
if useautocorr
dEzzi = (dEzzi.*sy-dsy.*(A^i*Gamma_y))./(sy.*sy);
end
J(obs_nbr + obs_nbr*(obs_nbr+1)/2 + (i-1)*obs_nbr^2 + 1 : obs_nbr + obs_nbr*(obs_nbr+1)/2 + i*obs_nbr^2, j+stderrparam_nbr+corrparam_nbr) = vec(dEzzi(indvobs,indvobs)); %focus only on VAROBS variables
end end
end end
end end
else else
J = []; MOMENTS = [];
dMOMENTS = [];
end end
%% Qu and Tkachenko (2012) %% Compute dSPECTRUM
%Note that our state space system for computing the spectrum is the following:
% zhat = A*zhat(-1) + B*xi, where zhat = z - E(z)
% yhat = C*zhat(-1) + D*xi, where yhat = y - E(y)
if ~no_identification_spectrum if ~no_identification_spectrum
%Some info on the spectral density: Dynare's state space system is given for states (z_{t} = A*z_{t-1} + B*u_{t}) and observables (y_{t} = C*z_{t-1} + D*u_{t}) %Some info on the spectral density: Dynare's state space system is given for states (z_{t} = A*z_{t-1} + B*u_{t}) and observables (y_{t} = C*z_{t-1} + D*u_{t})
%The spectral density for y_{t} can be computed using different methods, which are numerically equivalent %The spectral density for y_{t} can be computed using different methods, which are numerically equivalent
@ -259,8 +350,8 @@ if ~no_identification_spectrum
tneg = exp(-sqrt(-1)*freqs); %negative Fourier frequencies tneg = exp(-sqrt(-1)*freqs); %negative Fourier frequencies
IA = eye(size(A,1)); IA = eye(size(A,1));
if kronflag == -1 if kronflag == -1
%numerical derivative of spectral density [outputflag=2] %numerical derivative of spectral density
dOmega_tmp = fjaco(str2func('identification_numerical_objective'), para0, 2, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); dOmega_tmp = fjaco(str2func('identification_numerical_objective'), para0, 2, estim_params, M, oo, options, indpmodel, indpstderr, indpcorr, indvobs, useautocorr, nlags, grid_nbr); %[outputflag=2]
M.params = params0; %make sure values are set back M.params = params0; %make sure values are set back
M.Sigma_e = Sigma_e0; %make sure values are set back M.Sigma_e = Sigma_e0; %make sure values are set back
M.Correlation_matrix = Corr_e0 ; %make sure values are set back M.Correlation_matrix = Corr_e0 ; %make sure values are set back
@ -269,9 +360,9 @@ if ~no_identification_spectrum
kk = kk+1; kk = kk+1;
dOmega = dOmega_tmp(1 + (kk-1)*obs_nbr^2 : kk*obs_nbr^2,:); dOmega = dOmega_tmp(1 + (kk-1)*obs_nbr^2 : kk*obs_nbr^2,:);
if ig == 1 % add zero frequency once if ig == 1 % add zero frequency once
G = dOmega'*dOmega; dSPECTRUM = dOmega'*dOmega;
else % due to symmetry to negative frequencies we can add positive frequencies twice else % due to symmetry to negative frequencies we can add positive frequencies twice
G = G + 2*(dOmega'*dOmega); dSPECTRUM = dSPECTRUM + 2*(dOmega'*dOmega);
end end
end end
elseif kronflag == 1 elseif kronflag == 1
@ -280,61 +371,61 @@ if ~no_identification_spectrum
dB = reshape(dB,size(dB,1)*size(dB,2),size(dB,3)); dB = reshape(dB,size(dB,1)*size(dB,2),size(dB,3));
dC = reshape(dC,size(dC,1)*size(dC,2),size(dC,3)); dC = reshape(dC,size(dC,1)*size(dC,2),size(dC,3));
dD = reshape(dD,size(dD,1)*size(dD,2),size(dD,3)); dD = reshape(dD,size(dD,1)*size(dD,2),size(dD,3));
dSig = reshape(dSig,size(dSig,1)*size(dSig,2),size(dSig,3)); dVarinov = reshape(dVarinov,size(dVarinov,1)*size(dVarinov,2),size(dVarinov,3));
K_obs_exo = commutation(obs_nbr,exo_nbr); K_obs_exo = commutation(obs_nbr,size(Varinov,1));
for ig=1:length(freqs) for ig=1:length(freqs)
z = tneg(ig); z = tneg(ig);
zIminusA = (z*IA - A); zIminusA = (z*IA - A);
zIminusAinv = zIminusA\IA; zIminusAinv = zIminusA\IA;
Transferfct = D + C*zIminusAinv*B; % Transfer function Transferfct = D + C*zIminusAinv*B; % Transfer function
dzIminusA = -dA; dzIminusA = -dA;
dzIminusAinv = kron(-(transpose(zIminusA)\IA),zIminusAinv)*dzIminusA; dzIminusAinv = kron(-(transpose(zIminusA)\IA),zIminusAinv)*dzIminusA; %this takes long
dTransferfct = dD + DerivABCD(C,dC,zIminusAinv,dzIminusAinv,B,dB); dTransferfct = dD + DerivABCD(C,dC,zIminusAinv,dzIminusAinv,B,dB); %also long
dTransferfct_conjt = K_obs_exo*conj(dTransferfct); dTransferfct_conjt = K_obs_exo*conj(dTransferfct);
dOmega = (1/(2*pi))*DerivABCD(Transferfct,dTransferfct,Sigma_e0,dSig,Transferfct',dTransferfct_conjt); dOmega = (1/(2*pi))*DerivABCD(Transferfct,dTransferfct,Varinov,dVarinov,Transferfct',dTransferfct_conjt); %also long
if ig == 1 % add zero frequency once if ig == 1 % add zero frequency once
G = dOmega'*dOmega; dSPECTRUM = dOmega'*dOmega;
else % due to symmetry to negative frequencies we can add positive frequencies twice else % due to symmetry to negative frequencies we can add positive frequencies twice
G = G + 2*(dOmega'*dOmega); dSPECTRUM = dSPECTRUM + 2*(dOmega'*dOmega);
end end
end end
%put back into tensor notation %put back into tensor notation
dA = reshape(dA,endo_nbr,endo_nbr,totparam_nbr); dA = reshape(dA,size(A,1),size(A,2),totparam_nbr);
dB = reshape(dB,endo_nbr,exo_nbr,totparam_nbr); dB = reshape(dB,size(B,1),size(B,2),totparam_nbr);
dC = reshape(dC,obs_nbr,endo_nbr,totparam_nbr); dC = reshape(dC,size(C,1),size(C,2),totparam_nbr);
dD = reshape(dD,obs_nbr,exo_nbr,totparam_nbr); dD = reshape(dD,size(D,1),size(D,2),totparam_nbr);
dSig = reshape(dSig,exo_nbr,exo_nbr,totparam_nbr); dVarinov = reshape(dVarinov,size(Varinov,1),size(Varinov,2),totparam_nbr);
elseif (kronflag==0) || (kronflag==-2) elseif (kronflag==0) || (kronflag==-2)
for ig = 1:length(freqs) for ig = 1:length(freqs)
IzminusA = tpos(ig)*IA - A; IzminusA = tpos(ig)*IA - A;
invIzminusA = IzminusA\eye(endo_nbr); invIzminusA = IzminusA\eye(size(A,1));
Transferfct = D + C*invIzminusA*B; Transferfct = D + C*invIzminusA*B;
dOmega = zeros(obs_nbr^2,totparam_nbr); dOmega = zeros(obs_nbr^2,totparam_nbr);
for j = 1:totparam_nbr for j = 1:totparam_nbr
if j <= stderrparam_nbr+corrparam_nbr %stderr and corr parameters: only dSig is nonzero if j <= stderrparam_nbr+corrparam_nbr %stderr and corr parameters: only dSig is nonzero
dOmega_tmp = Transferfct*dSig(:,:,j)*Transferfct'; dOmega_tmp = Transferfct*dVarinov(:,:,j)*Transferfct';
else %model parameters else %model parameters
dinvIzminusA = -invIzminusA*(-dA(:,:,j))*invIzminusA; dinvIzminusA = -invIzminusA*(-dA(:,:,j))*invIzminusA;
dTransferfct = dD(:,:,j) + dC(:,:,j)*invIzminusA*B + C*dinvIzminusA*B + C*invIzminusA*dB(:,:,j); dTransferfct = dD(:,:,j) + dC(:,:,j)*invIzminusA*B + C*dinvIzminusA*B + C*invIzminusA*dB(:,:,j);
dOmega_tmp = dTransferfct*M.Sigma_e*Transferfct' + Transferfct*dSig(:,:,j)*Transferfct' + Transferfct*M.Sigma_e*dTransferfct'; dOmega_tmp = dTransferfct*Varinov*Transferfct' + Transferfct*dVarinov(:,:,j)*Transferfct' + Transferfct*Varinov*dTransferfct';
end end
dOmega(:,j) = (1/(2*pi))*dOmega_tmp(:); dOmega(:,j) = (1/(2*pi))*dOmega_tmp(:);
end end
if ig == 1 % add zero frequency once if ig == 1 % add zero frequency once
G = dOmega'*dOmega; dSPECTRUM = dOmega'*dOmega;
else % due to symmetry to negative frequencies we can add positive frequencies twice else % due to symmetry to negative frequencies we can add positive frequencies twice
G = G + 2*(dOmega'*dOmega); dSPECTRUM = dSPECTRUM + 2*(dOmega'*dOmega);
end end
end end
end end
% Normalize Matrix and add steady state Jacobian, note that G is real and symmetric by construction % Normalize Matrix and add steady state Jacobian, note that G is real and symmetric by construction
G = 2*pi*G./(2*length(freqs)-1) + [zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)]'*[zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)]; dSPECTRUM = 2*pi*dSPECTRUM./(2*length(freqs)-1) + dE_y'*dE_y;
G = real(G); dSPECTRUM = real(dSPECTRUM);
else else
G = []; dSPECTRUM = [];
end end
%% Komunjer and Ng (2012) %% Compute dMINIMAL
if ~no_identification_minimal if ~no_identification_minimal
if obs_nbr < exo_nbr if obs_nbr < exo_nbr
% Check whether criteria can be used % Check whether criteria can be used
@ -342,36 +433,30 @@ if ~no_identification_minimal
warning_KomunjerNg = [warning_KomunjerNg ' There are more shocks and measurement errors than observables, this is not implemented (yet).\n']; warning_KomunjerNg = [warning_KomunjerNg ' There are more shocks and measurement errors than observables, this is not implemented (yet).\n'];
warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n']; warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n'];
fprintf(warning_KomunjerNg); fprintf(warning_KomunjerNg);
D = []; dMINIMAL = [];
else else
% Derive and check minimal state % Derive and check minimal state vector of first-order
if isfield(oo.dr,'state_var') [CheckCO,minnx,minA,minB,minC,minD,dminA,dminB,dminC,dminD] = get_minimal_state_representation(oo.dr.ghx(oo.dr.pruned.indx,:),... %A
state_var = oo.dr.state_var; %state variables in declaration order oo.dr.ghu(oo.dr.pruned.indx,:),... %B
else oo.dr.ghx(oo.dr.pruned.indy,:),... %C
% DR-order: static variables first, then purely backward variables, then mixed variables, finally purely forward variables. oo.dr.ghu(oo.dr.pruned.indy,:),... %D
% Inside each category, variables are arranged according to the declaration order. oo.dr.derivs.dghx(oo.dr.pruned.indx,:,:),... %dA
% state variables are the purely backward variables and the mixed variables oo.dr.derivs.dghu(oo.dr.pruned.indx,:,:),... %dB
state_var = transpose(oo.dr.order_var( (M.nstatic+1):(M.nstatic+M.npred+M.nboth) ) ); %state variables in declaration order oo.dr.derivs.dghx(oo.dr.pruned.indy,:,:),... %dC
end oo.dr.derivs.dghu(oo.dr.pruned.indy,:,:)); %dD
state_var_DR = oo.dr.inv_order_var(state_var); %state vector in DR order
minA = A(state_var_DR,state_var_DR); dminA = dA(state_var_DR,state_var_DR,:);
minB = B(state_var_DR,:); dminB = dB(state_var_DR,:,:);
minC = C(:,state_var_DR); dminC = dC(:,state_var_DR,:);
minD = D(:,:); dminD = dD(:,:,:);
[CheckCO,minnx,minA,minB,minC,minD,dminA,dminB,dminC,dminD] = get_minimal_state_representation(minA,minB,minC,minD,dminA,dminB,dminC,dminD);
if CheckCO == 0 if CheckCO == 0
warning_KomunjerNg = 'WARNING: Komunjer and Ng (2011) failed:\n'; warning_KomunjerNg = 'WARNING: Komunjer and Ng (2011) failed:\n';
warning_KomunjerNg = [warning_KomunjerNg ' Conditions for minimality are not fullfilled:\n']; warning_KomunjerNg = [warning_KomunjerNg ' Conditions for minimality are not fullfilled:\n'];
warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n']; warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n'];
fprintf(warning_KomunjerNg); %use sprintf to have line breaks fprintf(warning_KomunjerNg); %use sprintf to have line breaks
D = []; dMINIMAL = [];
else else
%reshape into Magnus-Neudecker Jacobians, i.e. dvec(X)/dp %reshape into Magnus-Neudecker Jacobians, i.e. dvec(X)/dp
dminA = reshape(dminA,size(dminA,1)*size(dminA,2),size(dminA,3)); dminA = reshape(dminA,size(dminA,1)*size(dminA,2),size(dminA,3));
dminB = reshape(dminB,size(dminB,1)*size(dminB,2),size(dminB,3)); dminB = reshape(dminB,size(dminB,1)*size(dminB,2),size(dminB,3));
dminC = reshape(dminC,size(dminC,1)*size(dminC,2),size(dminC,3)); dminC = reshape(dminC,size(dminC,1)*size(dminC,2),size(dminC,3));
dminD = reshape(dminD,size(dminD,1)*size(dminD,2),size(dminD,3)); dminD = reshape(dminD,size(dminD,1)*size(dminD,2),size(dminD,3));
dvechSig = reshape(dSig,size(dSig,1)*size(dSig,2),size(dSig,3)); dvechSig = reshape(oo.dr.derivs.dSigma_e,exo_nbr*exo_nbr,totparam_nbr);
indvechSig= find(tril(ones(exo_nbr,exo_nbr))); indvechSig= find(tril(ones(exo_nbr,exo_nbr)));
dvechSig = dvechSig(indvechSig,:); dvechSig = dvechSig(indvechSig,:);
Inx = eye(minnx); Inx = eye(minnx);
@ -387,64 +472,39 @@ if ~no_identification_minimal
kron(Inu,minB); kron(Inu,minB);
zeros(obs_nbr*minnx,exo_nbr^2); zeros(obs_nbr*minnx,exo_nbr^2);
kron(Inu,minD); kron(Inu,minD);
-2*Enu*kron(M.Sigma_e,Inu)]; -2*Enu*kron(Sigma_e0,Inu)];
D = full([KomunjerNg_DL KomunjerNg_DT KomunjerNg_DU]); dMINIMAL = full([KomunjerNg_DL KomunjerNg_DT KomunjerNg_DU]);
%add Jacobian of steady state %add Jacobian of steady state (here we also allow for higher-order perturbation, i.e. only the mean provides additional restrictions
D = [[zeros(obs_nbr,stderrparam_nbr+corrparam_nbr) dYss(indvobs,:)], zeros(obs_nbr,minnx^2+exo_nbr^2); D]; dMINIMAL = [dE_y zeros(obs_nbr,minnx^2+exo_nbr^2); dMINIMAL];
end end
end end
else else
D = []; dMINIMAL = [];
end
if nargout > 8
options.ar = nlags;
nodecomposition = 1;
[Gamma_y,~] = th_autocovariances(oo.dr,oo.dr.order_var(indvobs),M,options,nodecomposition); %focus only on observed variables
sdy=sqrt(diag(Gamma_y{1})); %theoretical standard deviation
sy=sdy*sdy'; %cross products of standard deviations
if useautocorr
sy=sy-diag(diag(sy))+eye(obs_nbr);
Gamma_y{1}=Gamma_y{1}./sy;
else
for j=1:nlags
Gamma_y{j+1}=Gamma_y{j+1}.*sy;
end
end
%Ezz is vector of theoretical moments of VAROBS variables
MOMENTS = dyn_vech(Gamma_y{1});
for j=1:nlags
MOMENTS = [MOMENTS; vec(Gamma_y{j+1})];
end
MOMENTS = [oo.dr.ys(oo.dr.order_var(indvobs)); MOMENTS];
end end
function [dX] = DerivABCD(A,dA,B,dB,C,dC,D,dD) function [dX] = DerivABCD(X1,dX1,X2,dX2,X3,dX3,X4,dX4)
% function [dX] = DerivABCD(A,dA,B,dB,C,dC,D,dD) % function [dX] = DerivABCD(X1,dX1,X2,dX2,X3,dX3,X4,dX4)
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% Derivative of X(p)=A(p)*B(p)*C(p)*D(p) w.r.t to p % Derivative of X(p)=X1(p)*X2(p)*X3(p)*X4(p) w.r.t to p
% See Magnus and Neudecker (1999), p. 175 % See Magnus and Neudecker (1999), p. 175
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% Inputs: Matrices A,B,C,D, and the corresponding derivatives w.r.t p. % Inputs: Matrices X1,X2,X3,X4, and the corresponding derivatives w.r.t p.
% Output: Derivative of product of A*B*C*D w.r.t. p % Output: Derivative of product of X1*X2*X3*X4 w.r.t. p
% ========================================================================= % =========================================================================
nparam = size(dA,2); nparam = size(dX1,2);
% If one or more matrices are left out, they are set to zero % If one or more matrices are left out, they are set to zero
if nargin == 4 if nargin == 4
C=speye(size(B,2)); dC=spalloc(numel(C),nparam,0); X3=speye(size(X2,2)); dX3=spalloc(numel(X3),nparam,0);
D=speye(size(C,2)); dD=spalloc(numel(D),nparam,0); X4=speye(size(X3,2)); dX4=spalloc(numel(X4),nparam,0);
elseif nargin == 6 elseif nargin == 6
D=speye(size(C,2)); dD=spalloc(numel(D),nparam,0); X4=speye(size(X3,2)); dX4=spalloc(numel(X4),nparam,0);
end end
dX1 = kron(transpose(D)*transpose(C)*transpose(B),speye(size(A,1)))*dA; dX = kron(transpose(X4)*transpose(X3)*transpose(X2),speye(size(X1,1)))*dX1...
dX2 = kron(transpose(D)*transpose(C),A)*dB; + kron(transpose(X4)*transpose(X3),X1)*dX2...
dX3 = kron(transpose(D),A*B)*dC; + kron(transpose(X4),X1*X2)*dX3...
dX4 = kron(speye(size(D,2)),A*B*C)*dD; + kron(speye(size(X4,2)),X1*X2*X3)*dX4;
dX= dX1+dX2+dX3+dX4;
end %DerivABCD end end %DerivABCD end
end%main function end end%main function end

View File

@ -260,8 +260,9 @@ if analytic_derivation_mode == -1
DERIVS.dghxss = reshape(dSig_gh(ind_ghxss,:), [M.endo_nbr M.nspred totparam_nbr]); %in tensor notation, wrt selected parameters DERIVS.dghxss = reshape(dSig_gh(ind_ghxss,:), [M.endo_nbr M.nspred totparam_nbr]); %in tensor notation, wrt selected parameters
DERIVS.dghuss = reshape(dSig_gh(ind_ghuss,:), [M.endo_nbr M.exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters DERIVS.dghuss = reshape(dSig_gh(ind_ghuss,:), [M.endo_nbr M.exo_nbr totparam_nbr]); %in tensor notation, wrt selected parameters
end end
% Parameter Jacobian of Om=ghu*Sigma_e*ghu' (wrt selected stderr, corr and model paramters) % Parameter Jacobian of Om=ghu*Sigma_e*ghu' and Correlation_matrix (wrt selected stderr, corr and model paramters)
DERIVS.dOm = zeros(M.endo_nbr,M.endo_nbr,totparam_nbr); %initialize in tensor notation DERIVS.dOm = zeros(M.endo_nbr,M.endo_nbr,totparam_nbr); %initialize in tensor notation
DERIVS.dCorrelation_matrix = zeros(M.exo_nbr,M.exo_nbr,totparam_nbr); %initialize
if ~isempty(indpstderr) %derivatives of ghu wrt stderr parameters are zero by construction if ~isempty(indpstderr) %derivatives of ghu wrt stderr parameters are zero by construction
for jp=1:stderrparam_nbr for jp=1:stderrparam_nbr
DERIVS.dOm(:,:,jp) = oo.dr.ghu*DERIVS.dSigma_e(:,:,jp)*oo.dr.ghu'; DERIVS.dOm(:,:,jp) = oo.dr.ghu*DERIVS.dSigma_e(:,:,jp)*oo.dr.ghu';
@ -270,6 +271,8 @@ if analytic_derivation_mode == -1
if ~isempty(indpcorr) %derivatives of ghu wrt corr parameters are zero by construction if ~isempty(indpcorr) %derivatives of ghu wrt corr parameters are zero by construction
for jp=1:corrparam_nbr for jp=1:corrparam_nbr
DERIVS.dOm(:,:,stderrparam_nbr+jp) = oo.dr.ghu*DERIVS.dSigma_e(:,:,stderrparam_nbr+jp)*oo.dr.ghu'; DERIVS.dOm(:,:,stderrparam_nbr+jp) = oo.dr.ghu*DERIVS.dSigma_e(:,:,stderrparam_nbr+jp)*oo.dr.ghu';
DERIVS.dCorrelation_matrix(indpcorr(jp,1),indpcorr(jp,2),stderrparam_nbr+jp) = 1;
DERIVS.dCorrelation_matrix(indpcorr(jp,2),indpcorr(jp,1),stderrparam_nbr+jp) = 1;%symmetry
end end
end end
if ~isempty(indpmodel) %derivatives of Sigma_e wrt model parameters are zero by construction if ~isempty(indpmodel) %derivatives of Sigma_e wrt model parameters are zero by construction
@ -1190,6 +1193,7 @@ end
%% Store into structure %% Store into structure
DERIVS.dg1 = dg1; DERIVS.dg1 = dg1;
DERIVS.dSigma_e = dSigma_e; DERIVS.dSigma_e = dSigma_e;
DERIVS.dCorrelation_matrix = dCorrelation_matrix;
DERIVS.dYss = dYss; DERIVS.dYss = dYss;
DERIVS.dghx = cat(3,zeros(M.endo_nbr,M.nspred,stderrparam_nbr+corrparam_nbr), dghx); DERIVS.dghx = cat(3,zeros(M.endo_nbr,M.nspred,stderrparam_nbr+corrparam_nbr), dghx);
DERIVS.dghu = cat(3,zeros(M.endo_nbr,M.exo_nbr,stderrparam_nbr+corrparam_nbr), dghu); DERIVS.dghu = cat(3,zeros(M.endo_nbr,M.exo_nbr,stderrparam_nbr+corrparam_nbr), dghu);

View File

@ -1,12 +1,15 @@
function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_lre, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init) function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init)
% [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_lre, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init) % [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide_dynamic, derivatives_info, info, options_ident] = identification_analysis(params, indpmodel, indpstderr, indpcorr, options_ident, dataset_info, prior_exist, init)
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% This function wraps all identification analysis, i.e. it % This function wraps all identification analysis, i.e. it
% (1) wraps functions for the theoretical identification analysis based on moments (Iskrev, 2010), % (1) wraps functions for the theoretical identification analysis based on moments (Iskrev, 2010),
% spectrum (Qu and Tkachenko, 2012), minimal system (Komunjer and Ng, 2011), information matrix, % spectrum (Qu and Tkachenko, 2012), minimal system (Komunjer and Ng, 2011), information matrix,
% reduced-form solution and linear rational expectation model (Ratto and Iskrev, 2011). % reduced-form solution and dynamic model derivatives (Ratto and Iskrev, 2011).
% (2) computes the identification strength based on moments (Ratto and Iskrev, 2011) % (2) computes the identification strength based on moments (Ratto and Iskrev, 2011)
% (3) checks which parameters are involved. % (3) checks which parameters are involved.
% If options_ident.order>1, then the identification analysis is based on
% Mutschler (2015), i.e. the pruned state space system and the corresponding
% moments, spectrum, reduced-form solution and dynamic model derivatives
% ========================================================================= % =========================================================================
% INPUTS % INPUTS
% * params [mc_sample_nbr by totparam_nbr] % * params [mc_sample_nbr by totparam_nbr]
@ -15,8 +18,8 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide
% index of model parameters for which identification is checked % index of model parameters for which identification is checked
% * indpstderr [stderrparam_nbr by 1] % * indpstderr [stderrparam_nbr by 1]
% index of stderr parameters for which identification is checked % index of stderr parameters for which identification is checked
% * indpcorr [corrparam_nbr by 1] % * indpcorr [corrparam_nbr by 2]
% index of corr parmeters for which identification is checked % matrix of corr parmeters for which identification is checked
% * options_ident [structure] % * options_ident [structure]
% identification options % identification options
% * dataset_info [structure] % * dataset_info [structure]
@ -25,23 +28,21 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide
% 1: prior exists. Identification is checked for stderr, corr and model parameters as declared in estimated_params block % 1: prior exists. Identification is checked for stderr, corr and model parameters as declared in estimated_params block
% 0: prior does not exist. Identification is checked for all stderr and model parameters, but no corr parameters % 0: prior does not exist. Identification is checked for all stderr and model parameters, but no corr parameters
% * init [integer] % * init [integer]
% flag for initialization of persistent vars. This is needed if one may want to re-initialize persistent % flag for initialization of persistent vars. This is needed if one may wants to make more calls to identification in the same dynare mod file
% variables even if they are not empty, e.g. by making more calls to identification in the same dynare mod file
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% OUTPUTS % OUTPUTS
% * ide_moments [structure] % * ide_moments [structure]
% identification results using theoretical moments (Iskrev, 2010) % identification results using theoretical moments (Iskrev, 2010; Mutschler, 2015)
% * ide_spectrum [structure] % * ide_spectrum [structure]
% identification results using spectrum (Qu and Tkachenko, 2012) % identification results using spectrum (Qu and Tkachenko, 2012; Mutschler, 2015)
% * ide_minimal [structure] % * ide_minimal [structure]
% identification results using minimal system (Komunjer and Ng, 2011) % identification results using minimal system (Komunjer and Ng, 2011)
% * ide_hess [structure] % * ide_hess [structure]
% identification results using asymptotic Hessian (Ratto and Iskrev, 2011) % identification results using asymptotic Hessian (Ratto and Iskrev, 2011)
% * ide_reducedform [structure] % * ide_reducedform [structure]
% identification results using reduced form solution (Ratto and Iskrev, 2011) % identification results using steady state and reduced form solution (Ratto and Iskrev, 2011)
% * ide_lre [structure] % * ide_dynamic [structure]
% identification results using linear rational expectations model, % identification results using steady state and dynamic model derivatives (Ratto and Iskrev, 2011)
% i.e. steady state and Jacobian of dynamic model, (Ratto and Iskrev, 2011)
% * derivatives_info [structure] % * derivatives_info [structure]
% info about derivatives, used in dsge_likelihood.m % info about derivatives, used in dsge_likelihood.m
% * info [integer] % * info [integer]
@ -57,7 +58,6 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide
% * dseries % * dseries
% * dsge_likelihood.m % * dsge_likelihood.m
% * dyn_vech % * dyn_vech
% * dynare_resolve
% * ident_bruteforce % * ident_bruteforce
% * identification_checks % * identification_checks
% * identification_checks_via_subsets % * identification_checks_via_subsets
@ -65,6 +65,7 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide
% * get_identification_jacobians (previously getJJ) % * get_identification_jacobians (previously getJJ)
% * matlab_ver_less_than % * matlab_ver_less_than
% * prior_bounds % * prior_bounds
% * resol
% * set_all_parameters % * set_all_parameters
% * simulated_moment_uncertainty % * simulated_moment_uncertainty
% * stoch_simul % * stoch_simul
@ -89,23 +90,23 @@ function [ide_moments, ide_spectrum, ide_minimal, ide_hess, ide_reducedform, ide
% ========================================================================= % =========================================================================
global oo_ M_ options_ bayestopt_ estim_params_ global oo_ M_ options_ bayestopt_ estim_params_
persistent ind_J ind_G ind_D ind_dTAU ind_dLRE persistent ind_dMOMENTS ind_dREDUCEDFORM ind_dDYNAMIC
% persistence is necessary, because in a MC loop the numerical threshold used may provide vectors of different length, leading to crashes in MC loops % persistence is necessary, because in a MC loop the numerical threshold used may provide vectors of different length, leading to crashes in MC loops
%initialize output structures %initialize output structures
ide_hess = struct(); %asymptotic/simulated information matrix ide_hess = struct(); %Jacobian of asymptotic/simulated information matrix
ide_reducedform = struct(); %reduced form solution ide_reducedform = struct(); %Jacobian of steady state and reduced form solution
ide_lre = struct(); %linear rational expectation model ide_dynamic = struct(); %Jacobian of steady state and dynamic model derivatives
ide_moments = struct(); %Iskrev (2010)'s J ide_moments = struct(); %Jacobian of first two moments (Iskrev, 2010; Mutschler, 2015)
ide_spectrum = struct(); %Qu and Tkachenko (2012)'s G ide_spectrum = struct(); %Gram matrix of Jacobian of spectral density plus Gram matrix of Jacobian of steady state (Qu and Tkachenko, 2012; Mutschler, 2015)
ide_minimal = struct(); %Komunjer and Ng (2011)'s D ide_minimal = struct(); %Jacobian of minimal system (Komunjer and Ng, 2011)
derivatives_info = struct(); %storage for Jacobians used in dsge_likelihood.m for (analytical or simulated) asymptotic Gradient and Hession of likelihood derivatives_info = struct(); %storage for Jacobians used in dsge_likelihood.m for (analytical or simulated) asymptotic Gradient and Hession of likelihood
totparam_nbr = length(params); %number of all parameters to be checked totparam_nbr = length(params); %number of all parameters to be checked
modparam_nbr = length(indpmodel); %number of model parameters to be checked modparam_nbr = length(indpmodel); %number of model parameters to be checked
stderrparam_nbr = length(indpstderr); %number of stderr parameters to be checked stderrparam_nbr = length(indpstderr); %number of stderr parameters to be checked
corrparam_nbr = size(indpcorr,1); %number of stderr parameters to be checked corrparam_nbr = size(indpcorr,1); %number of stderr parameters to be checked
indvobs = bayestopt_.mf2; % index of observable variables indvobs = bayestopt_.mf2; %index of observable variables
if ~isempty(estim_params_) if ~isempty(estim_params_)
%estimated_params block is available, so we are able to use set_all_parameters.m %estimated_params block is available, so we are able to use set_all_parameters.m
@ -113,163 +114,138 @@ if ~isempty(estim_params_)
end end
%get options (see dynare_identification.m for description of options) %get options (see dynare_identification.m for description of options)
no_identification_strength = options_ident.no_identification_strength;
no_identification_reducedform = options_ident.no_identification_reducedform;
no_identification_moments = options_ident.no_identification_moments;
no_identification_minimal = options_ident.no_identification_minimal;
no_identification_spectrum = options_ident.no_identification_spectrum;
order = options_ident.order;
nlags = options_ident.ar; nlags = options_ident.ar;
advanced = options_ident.advanced; advanced = options_ident.advanced;
replic = options_ident.replic; replic = options_ident.replic;
periods = options_ident.periods; periods = options_ident.periods;
max_dim_cova_group = options_ident.max_dim_cova_group; max_dim_cova_group = options_ident.max_dim_cova_group;
normalize_jacobians = options_ident.normalize_jacobians; normalize_jacobians = options_ident.normalize_jacobians;
checks_via_subsets = options_ident.checks_via_subsets;
tol_deriv = options_ident.tol_deriv; tol_deriv = options_ident.tol_deriv;
tol_rank = options_ident.tol_rank; tol_rank = options_ident.tol_rank;
tol_sv = options_ident.tol_sv; tol_sv = options_ident.tol_sv;
no_identification_strength = options_ident.no_identification_strength;
no_identification_reducedform = options_ident.no_identification_reducedform;
no_identification_moments = options_ident.no_identification_moments;
no_identification_minimal = options_ident.no_identification_minimal;
no_identification_spectrum = options_ident.no_identification_spectrum;
checks_via_subsets = options_ident.checks_via_subsets;
[I,~] = find(M_.lead_lag_incidence'); %I is used to select nonzero columns of the Jacobian of endogenous variables in dynamic model files %Compute linear approximation and fill dr structure
[oo_.dr,info,M_,options_,oo_] = resol(0,M_,options_,oo_);
%Compute linear approximation and matrices A and B of the transition equation for all endogenous variables in DR order
[A, B, ~, info, M_, options_, oo_] = dynare_resolve(M_,options_,oo_);
if info(1) == 0 %no errors in solution if info(1) == 0 %no errors in solution
oo0 = oo_; %store oo_ structure [MEAN, dMEAN, REDUCEDFORM, dREDUCEDFORM, DYNAMIC, dDYNAMIC, MOMENTS, dMOMENTS, dSPECTRUM, dMINIMAL, derivatives_info] = get_identification_jacobians(estim_params_, M_, oo_, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs);
y0 = oo_.dr.ys(oo_.dr.order_var); %steady state in DR order if isempty(dMINIMAL)
yy0 = oo_.dr.ys(I); %steady state of dynamic (endogenous and auxiliary variables) in DR order
ex0 = oo_.exo_steady_state'; %steady state of exogenous variables in declaration order
param0 = M_.params; %parameter values at which to evaluate dynamic, static and param_derivs files
Sigma_e0 = M_.Sigma_e; %store covariance matrix of exogenous shocks
%compute vectorized reduced-form solution in DR order
tau = [y0; vec(A); dyn_vech(B*Sigma_e0*B')];
%compute vectorized linear rational expectations model in DR order
[~, g1 ] = feval([M_.fname,'.dynamic'], yy0, repmat(ex0, M_.maximum_exo_lag+M_.maximum_exo_lead+1), param0, oo_.dr.ys, 1);
%g1 is [endo_nbr by (dynamicvar_nbr+exo_nbr)] first derivative (wrt all endogenous, exogenous and auxiliary variables) of dynamic model equations, i.e. df/d[yy0;ex0], in DR order
lre = [y0; vec(g1)]; %add steady state in DR order and vectorize
%Compute Jacobians for identification analysis either analytically or numerically dependent on analytic_derivation_mode in options_ident
[J, G, D, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params_, M_, oo0, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs);
if isempty(D)
% Komunjer and Ng is not computed if (1) minimality conditions are not fullfilled or (2) there are more shocks and measurement errors than observables, so we need to reset options % Komunjer and Ng is not computed if (1) minimality conditions are not fullfilled or (2) there are more shocks and measurement errors than observables, so we need to reset options
no_identification_minimal = 1; no_identification_minimal = 1;
options_ident.no_identification_minimal = 1; options_ident.no_identification_minimal = 1;
end end
%store derivatives for use in dsge_likelihood.m
derivatives_info.DT = dA;
derivatives_info.DOm = dOm;
derivatives_info.DYss = dYss;
if init if init
%check stationarity %check stationarity
if ~no_identification_moments if ~no_identification_moments
ind_J = (find(max(abs(J'),[],1) > tol_deriv)); %index for non-zero derivatives ind_dMOMENTS = (find(max(abs(dMOMENTS'),[],1) > tol_deriv)); %index for non-zero rows
if isempty(ind_J) && any(any(isnan(J))) if isempty(ind_dMOMENTS) && any(any(isnan(dMOMENTS)))
error('There are NaN in the JJ matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.' ) error('There are NaN in the dMOMENTS matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.' )
end end
if any(any(isnan(MOMENTS))) if any(any(isnan(MOMENTS)))
error('There are NaN''s in the theoretical moments: make sure that for non-stationary models stationary transformations of non-stationary observables are used for checking identification. [TIP: use first differences].') error('There are NaN''s in the theoretical moments: make sure that for non-stationary models stationary transformations of non-stationary observables are used for checking identification. [TIP: use first differences].')
end end
end end
if ~no_identification_spectrum if ~no_identification_spectrum
ind_G = (find(max(abs(G'),[],1) > tol_deriv)); %index for non-zero derivatives ind_dSPECTRUM = (find(max(abs(dSPECTRUM'),[],1) > tol_deriv)); %index for non-zero rows
if isempty(ind_G) && any(any(isnan(G))) if isempty(ind_dSPECTRUM) && any(any(isnan(dSPECTRUM)))
warning_QuTkachenko = 'WARNING: There are NaN in Qu and Tkachenko (2012)''s G matrix. Please check whether your model has units roots (diffuse_filter=1 does not work yet for the G matrix).\n'; warning_SPECTRUM = 'WARNING: There are NaN in the dSPECTRUM matrix. Please check whether your model has units roots and your forgot to set diffuse_filter=1.\n';
warning_QuTkachenko = [warning_QuTkachenko ' Skip identification analysis based on spectrum.\n']; warning_SPECTRUM = [warning_SPECTRUM ' Skip identification analysis based on spectrum.\n'];
fprintf(warning_QuTkachenko); fprintf(warning_SPECTRUM);
%reset options to neither display nor plot Qu and Tkachenko's G anymore %reset options to neither display nor plot dSPECTRUM anymore
no_identification_spectrum = 1; no_identification_spectrum = 1;
options_ident.no_identification_spectrum = 1; options_ident.no_identification_spectrum = 1;
end end
end end
if ~no_identification_minimal if ~no_identification_minimal
ind_D = (find(max(abs(D'),[],1) > tol_deriv)); %index for non-zero derivatives ind_dMINIMAL = (find(max(abs(dMINIMAL'),[],1) > tol_deriv)); %index for non-zero rows
if isempty(ind_D) && any(any(isnan(D))) if isempty(ind_dMINIMAL) && any(any(isnan(dMINIMAL)))
warning_KomunjerNg = 'WARNING: There are NaN in Komunjer and Ng (2011)''s D matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.\n'; warning_MINIMAL = 'WARNING: There are NaN in the dMINIMAL matrix. Please check whether your model has units roots and you forgot to set diffuse_filter=1.\n';
warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal system.\n']; warning_MINIMAL = [warning_MINIMAL ' Skip identification analysis based on minimal system.\n'];
fprintf(warning_KomunjerNg); fprintf(warning_MINIMAL);
%reset options to neither display nor plot Komunjer and Ng's D anymore %reset options to neither display nor plot dMINIMAL anymore
no_identification_minimal = 1; no_identification_minimal = 1;
options_ident.no_identification_minimal = 1; options_ident.no_identification_minimal = 1;
end end
end end
if no_identification_moments && no_identification_minimal && no_identification_spectrum if no_identification_moments && no_identification_minimal && no_identification_spectrum
%error if all three criteria fail %display error if all three criteria fail
error('identification_analyis: Stationarity condition(s) failed and/or diffuse_filter option missing'); error('identification_analyis: Stationarity condition(s) failed and/or diffuse_filter option missing');
end end
% Check order conditions % Check order conditions
if ~no_identification_moments if ~no_identification_moments
%check order condition of Iskrev (2010) %check order condition of Iskrev (2010)
while length(ind_J) < totparam_nbr && nlags < 10 while length(ind_dMOMENTS) < totparam_nbr && nlags < 10
%Try to add lags to autocovariogram if order condition fails %Try to add lags to autocovariogram if order condition fails
disp('The number of moments with non-zero derivative is smaller than the number of parameters') disp('The number of moments with non-zero derivative is smaller than the number of parameters')
disp(['Try increasing ar = ', int2str(nlags+1)]) disp(['Try increasing ar = ', int2str(nlags+1)])
nlags = nlags + 1; nlags = nlags + 1;
options_ident.no_identification_minimal = 1; %do not recompute D options_ident.no_identification_minimal = 1; %do not recompute dMINIMAL
options_ident.no_identification_spectrum = 1; %do not recompute G options_ident.no_identification_spectrum = 1; %do not recompute dSPECTRUM
options_ident.ar = nlags; %store new lag number options_ident.ar = nlags; %store new lag number
options_.ar = nlags; %store new lag number options_.ar = nlags; %store new lag number
[J, ~, ~, dTAU, dLRE, dA, dOm, dYss, MOMENTS] = get_identification_jacobians(A, B, estim_params_, M_, oo0, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs); [~, ~, ~, ~, ~, ~, MOMENTS, dMOMENTS, ~, ~, ~] = get_identification_jacobians(estim_params_, M_, oo_, options_, options_ident, indpmodel, indpstderr, indpcorr, indvobs);
ind_J = (find(max(abs(J'),[],1) > tol_deriv)); %new index with non-zero derivatives
%store derivatives for use in dsge_likelihood.m ind_dMOMENTS = (find(max(abs(dMOMENTS'),[],1) > tol_deriv)); %new index with non-zero rows
derivatives_info.DT = dA;
derivatives_info.DOm = dOm;
derivatives_info.DYss = dYss;
end end
options_ident.no_identification_minimal = no_identification_minimal; % reset option to original choice options_ident.no_identification_minimal = no_identification_minimal; % reset option to original setting
options_ident.no_identification_spectrum = no_identification_spectrum; % reset option to original choice options_ident.no_identification_spectrum = no_identification_spectrum; % reset option to original setting
if length(ind_J) < totparam_nbr if length(ind_dMOMENTS) < totparam_nbr
warning_Iskrev = 'WARNING: Order condition for Iskrev (2010) failed: There are not enough moments and too many parameters.\n'; warning_MOMENTS = 'WARNING: Order condition for dMOMENTS failed: There are not enough moments and too many parameters.\n';
warning_Iskrev = [warning_Iskrev ' The number of moments with non-zero derivative is smaller than the number of parameters up to 10 lags.\n']; warning_MOMENTS = [warning_MOMENTS ' The number of moments with non-zero derivative is smaller than the number of parameters up to 10 lags.\n'];
warning_Iskrev = [warning_Iskrev ' Either reduce the list of parameters, or further increase ar, or increase number of observables.\n']; warning_MOMENTS = [warning_MOMENTS ' Either reduce the list of parameters, or further increase ar, or increase number of observables.\n'];
warning_Iskrev = [warning_Iskrev ' Skip identification analysis based on moments.\n']; warning_MOMENTS = [warning_MOMENTS ' Skip identification analysis based on moments.\n'];
fprintf(warning_Iskrev); fprintf(warning_MOMENTS);
%reset options to neither display nor plot Iskrev's J anymore %reset options to neither display nor plot dMOMENTS anymore
no_identification_moments = 1; no_identification_moments = 1;
options_ident.no_identification_moments = 1; options_ident.no_identification_moments = 1;
end end
end end
if ~no_identification_minimal if ~no_identification_minimal
if length(ind_D) < size(D,2) if length(ind_dMINIMAL) < size(dMINIMAL,2)
warning_KomunjerNg = 'WARNING: Order condition for Komunjer and Ng (2011) failed: There are too many parameters or too few observable variables.\n'; warning_MINIMAL = 'WARNING: Order condition for dMINIMAL failed: There are too many parameters or too few observable variables.\n';
warning_KomunjerNg = [warning_KomunjerNg ' The number of minimal system elements with non-zero derivative is smaller than the number of parameters.\n']; warning_MINIMAL = [warning_MINIMAL ' The number of minimal system elements with non-zero derivative is smaller than the number of parameters.\n'];
warning_KomunjerNg = [warning_KomunjerNg ' Either reduce the list of parameters, or increase number of observables.\n']; warning_MINIMAL = [warning_MINIMAL ' Either reduce the list of parameters, or increase number of observables.\n'];
warning_KomunjerNg = [warning_KomunjerNg ' Skip identification analysis based on minimal state space system.\n']; warning_MINIMAL = [warning_MINIMAL ' Skip identification analysis based on minimal state space system.\n'];
fprintf(warning_KomunjerNg); fprintf(warning_MINIMAL);
%resest options to neither display nor plot Komunjer and Ng's D anymore %resest options to neither display nor plot dMINIMAL anymore
no_identification_minimal = 1; no_identification_minimal = 1;
options_ident.no_identification_minimal = 1; options_ident.no_identification_minimal = 1;
end end
end end
%There is no order condition for Qu and Tkachenko's G %Note that there is no order condition for dSPECTRUM, as the matrix is always of dimension totparam_nbr by totparam_nbr
if no_identification_moments && no_identification_minimal && no_identification_spectrum if no_identification_moments && no_identification_minimal && no_identification_spectrum
%error if all three criteria fail %error if all three criteria fail
error('identification_analyis: Order condition(s) failed'); error('identification_analyis: Order condition(s) failed');
end end
if ~no_identification_reducedform if ~no_identification_reducedform
ind_dTAU = (find(max(abs(dTAU'),[],1) > tol_deriv)); %index with non-zero derivatives ind_dREDUCEDFORM = (find(max(abs(dREDUCEDFORM'),[],1) > tol_deriv)); %index with non-zero rows
end end
ind_dLRE = (find(max(abs(dLRE'),[],1) > tol_deriv)); %index with non-zero derivatives ind_dDYNAMIC = (find(max(abs(dDYNAMIC'),[],1) > tol_deriv)); %index with non-zero rows
end end
LRE = lre(ind_dLRE); DYNAMIC = DYNAMIC(ind_dDYNAMIC); %focus only on non-zero entries
si_dLRE = (dLRE(ind_dLRE,:)); %focus only on non-zero derivatives si_dDYNAMIC = (dDYNAMIC(ind_dDYNAMIC,:)); %focus only on non-zero rows
if ~no_identification_reducedform if ~no_identification_reducedform
TAU = tau(ind_dTAU); REDUCEDFORM = REDUCEDFORM(ind_dREDUCEDFORM); %focus only on non-zero entries
si_dTAU = (dTAU(ind_dTAU,:)); %focus only on non-zero derivatives si_dREDUCEDFORM = (dREDUCEDFORM(ind_dREDUCEDFORM,:)); %focus only on non-zero rows
end end
if ~no_identification_moments if ~no_identification_moments
MOMENTS = MOMENTS(ind_J); MOMENTS = MOMENTS(ind_dMOMENTS); %focus only on non-zero entries
si_J = (J(ind_J,:)); %focus only on non-zero derivatives si_dMOMENTS = (dMOMENTS(ind_dMOMENTS,:)); %focus only on non-zero derivatives
%% compute identification strength based on moments %% MOMENTS IDENTIFICATION STRENGTH ANALYSIS
if ~no_identification_strength && init %only for initialization of persistent vars if ~no_identification_strength && init %only for initialization of persistent vars
ide_strength_J = NaN(1,totparam_nbr); %initialize ide_strength_dMOMENTS = NaN(1,totparam_nbr); %initialize
ide_strength_J_prior = NaN(1,totparam_nbr); %initialize ide_strength_dMOMENTS_prior = NaN(1,totparam_nbr); %initialize
ide_uncert_unnormaliz = NaN(1,totparam_nbr); %initialize ide_uncert_unnormaliz = NaN(1,totparam_nbr); %initialize
if prior_exist if prior_exist
offset_prior = 0; offset_prior = 0;
@ -295,7 +271,6 @@ if info(1) == 0 %no errors in solution
% reset some options for faster computations % reset some options for faster computations
options_.irf = 0; options_.irf = 0;
options_.noprint = 1; options_.noprint = 1;
options_.order = 1;
options_.SpectralDensity.trigger = 0; options_.SpectralDensity.trigger = 0;
options_.periods = periods+100; options_.periods = periods+100;
if options_.kalman_algo > 2 if options_.kalman_algo > 2
@ -307,16 +282,16 @@ if info(1) == 0 %no errors in solution
dataset_ = dseries(oo_.endo_simul(options_.varobs_id,100+1:end)',dates('1Q1'), options_.varobs); %get information on moments dataset_ = dseries(oo_.endo_simul(options_.varobs_id,100+1:end)',dates('1Q1'), options_.varobs); %get information on moments
derivatives_info.no_DLIK = 1; derivatives_info.no_DLIK = 1;
bounds = prior_bounds(bayestopt_, options_.prior_trunc); %reset bounds as lb and ub must only be operational during mode-finding bounds = prior_bounds(bayestopt_, options_.prior_trunc); %reset bounds as lb and ub must only be operational during mode-finding
if options_.order > 1
fprintf('IDENTIFICATION STRENGTH: Analytic computation of Hessian is not available for ''order>1''\n')
fprintf(' Identification strength is based on simulated moment uncertainty\n');
end
%note that for order>1 we do not provide any information on DT,DYss,DOM in derivatives_info, such that dsge_likelihood creates an error. Therefore the computation will be based on simulated_moment_uncertainty for order>1.
[fval, info, cost_flag, DLIK, AHess, ys, trend_coeff, M_, options_, bayestopt_, oo_] = dsge_likelihood(params', dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_, derivatives_info); %non-used output variables need to be set for octave for some reason [fval, info, cost_flag, DLIK, AHess, ys, trend_coeff, M_, options_, bayestopt_, oo_] = dsge_likelihood(params', dataset_, dataset_info, options_, M_, estim_params_, bayestopt_, bounds, oo_, derivatives_info); %non-used output variables need to be set for octave for some reason
%note that for the order of parameters in AHess we have: stderr parameters come first, corr parameters second, model parameters third. the order within these blocks corresponds to the order specified in the estimated_params block %note that for the order of parameters in AHess we have: stderr parameters come first, corr parameters second, model parameters third. the order within these blocks corresponds to the order specified in the estimated_params block
options_.analytic_derivation = analytic_derivation; %reset option options_.analytic_derivation = analytic_derivation; %reset option
AHess = -AHess; %take negative of hessian AHess = -AHess; %take negative of hessian
if ischar(tol_rank) %if tolerance is specified as 'robust' if min(eig(AHess))<-tol_rank
tol_rankAhess = max(size(AHess))*eps(norm(AHess));
else
tol_rankAhess = tol_rank;
end
if min(eig(AHess))<-tol_rankAhess
error('identification_analysis: Analytic Hessian is not positive semi-definite!') error('identification_analysis: Analytic Hessian is not positive semi-definite!')
end end
ide_hess.AHess = AHess; %store asymptotic Hessian ide_hess.AHess = AHess; %store asymptotic Hessian
@ -332,16 +307,16 @@ if info(1) == 0 %no errors in solution
indok = find(max(ide_hess.indno,[],1)==0); indok = find(max(ide_hess.indno,[],1)==0);
ide_uncert_unnormaliz(indok) = sqrt(diag(inv(AHess(indok,indok))))'; ide_uncert_unnormaliz(indok) = sqrt(diag(inv(AHess(indok,indok))))';
ind1 = find(ide_hess.ind0); ind1 = find(ide_hess.ind0);
cmm = si_J(:,ind1)*((AHess(ind1,ind1))\si_J(:,ind1)'); %covariance matrix of moments cmm = si_dMOMENTS(:,ind1)*((AHess(ind1,ind1))\si_dMOMENTS(:,ind1)'); %covariance matrix of moments
temp1 = ((AHess(ind1,ind1))\si_dTAU(:,ind1)'); temp1 = ((AHess(ind1,ind1))\si_dREDUCEDFORM(:,ind1)');
diag_chh = sum(si_dTAU(:,ind1)'.*temp1)'; diag_chh = sum(si_dREDUCEDFORM(:,ind1)'.*temp1)';
ind1 = ind1(ind1>stderrparam_nbr+corrparam_nbr); ind1 = ind1(ind1>stderrparam_nbr+corrparam_nbr);
clre = si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)*((AHess(ind1,ind1))\si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)'); cdynamic = si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)*((AHess(ind1,ind1))\si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)');
flag_score = 1; %this is only used for a title of a plot in plot_identification.m flag_score = 1; %this is used for the title in plot_identification.m
catch catch
%Asymptotic Hessian via simulation %Asymptotic Hessian via simulation
replic = max([replic, length(ind_J)*3]); replic = max([replic, length(ind_dMOMENTS)*3]);
cmm = simulated_moment_uncertainty(ind_J, periods, replic,options_,M_,oo_); %covariance matrix of moments cmm = simulated_moment_uncertainty(ind_dMOMENTS, periods, replic,options_,M_,oo_); %covariance matrix of moments
sd = sqrt(diag(cmm)); sd = sqrt(diag(cmm));
cc = cmm./(sd*sd'); cc = cmm./(sd*sd');
if isoctave || matlab_ver_less_than('8.3') if isoctave || matlab_ver_less_than('8.3')
@ -353,7 +328,7 @@ if info(1) == 0 %no errors in solution
[VV,DD,WW] = eig(cc); [VV,DD,WW] = eig(cc);
end end
id = find(diag(DD)>tol_deriv); id = find(diag(DD)>tol_deriv);
siTMP = si_J./repmat(sd,[1 totparam_nbr]); siTMP = si_dMOMENTS./repmat(sd,[1 totparam_nbr]);
MIM = (siTMP'*VV(:,id))*(DD(id,id)\(WW(:,id)'*siTMP)); MIM = (siTMP'*VV(:,id))*(DD(id,id)\(WW(:,id)'*siTMP));
clear siTMP; clear siTMP;
ide_hess.AHess = MIM; %store asymptotic hessian ide_hess.AHess = MIM; %store asymptotic hessian
@ -368,122 +343,123 @@ if info(1) == 0 %no errors in solution
end end
indok = find(max(ide_hess.indno,[],1)==0); indok = find(max(ide_hess.indno,[],1)==0);
ind1 = find(ide_hess.ind0); ind1 = find(ide_hess.ind0);
temp1 = ((MIM(ind1,ind1))\si_dTAU(:,ind1)'); temp1 = ((MIM(ind1,ind1))\si_dREDUCEDFORM(:,ind1)');
diag_chh = sum(si_dTAU(:,ind1)'.*temp1)'; diag_chh = sum(si_dREDUCEDFORM(:,ind1)'.*temp1)';
ind1 = ind1(ind1>stderrparam_nbr+corrparam_nbr); ind1 = ind1(ind1>stderrparam_nbr+corrparam_nbr);
clre = si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)*((MIM(ind1,ind1))\si_dLRE(:,ind1-stderrparam_nbr-corrparam_nbr)'); cdynamic = si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)*((MIM(ind1,ind1))\si_dDYNAMIC(:,ind1-stderrparam_nbr-corrparam_nbr)');
if ~isempty(indok) if ~isempty(indok)
ide_uncert_unnormaliz(indok) = (sqrt(diag(inv(tildaM(indok,indok))))./deltaM(indok))'; %sqrt(diag(inv(MIM(indok,indok))))'; ide_uncert_unnormaliz(indok) = (sqrt(diag(inv(tildaM(indok,indok))))./deltaM(indok))'; %sqrt(diag(inv(MIM(indok,indok))))';
end end
flag_score = 0; %this is only used for a title of a plot flag_score = 0; %this is used for the title in plot_identification.m
end % end of computing sample information matrix for identification strength measure end % end of computing sample information matrix for identification strength measure
ide_strength_J(indok) = (1./(ide_uncert_unnormaliz(indok)'./abs(params(indok)'))); %this is s_i in Ratto and Iskrev (2011, p.13) ide_strength_dMOMENTS(indok) = (1./(ide_uncert_unnormaliz(indok)'./abs(params(indok)'))); %this is s_i in Ratto and Iskrev (2011, p.13)
ide_strength_J_prior(indok) = (1./(ide_uncert_unnormaliz(indok)'./normaliz_prior_std(indok)')); %this is s_i^{prior} in Ratto and Iskrev (2011, p.14) ide_strength_dMOMENTS_prior(indok) = (1./(ide_uncert_unnormaliz(indok)'./normaliz_prior_std(indok)')); %this is s_i^{prior} in Ratto and Iskrev (2011, p.14)
sensitivity_zero_pos = find(isinf(deltaM)); sensitivity_zero_pos = find(isinf(deltaM));
deltaM_prior = deltaM.*abs(normaliz_prior_std'); %this is \Delta_i^{prior} in Ratto and Iskrev (2011, p.14) deltaM_prior = deltaM.*abs(normaliz_prior_std'); %this is \Delta_i^{prior} in Ratto and Iskrev (2011, p.14)
deltaM = deltaM.*abs(params'); %this is \Delta_i in Ratto and Iskrev (2011, p.14) deltaM = deltaM.*abs(params'); %this is \Delta_i in Ratto and Iskrev (2011, p.14)
quant = si_J./repmat(sqrt(diag(cmm)),1,totparam_nbr); quant = si_dMOMENTS./repmat(sqrt(diag(cmm)),1,totparam_nbr);
if size(quant,1)==1 if size(quant,1)==1
si_Jnorm = abs(quant).*normaliz_prior_std; si_dMOMENTSnorm = abs(quant).*normaliz_prior_std;
else else
si_Jnorm = vnorm(quant).*normaliz_prior_std; si_dMOMENTSnorm = vnorm(quant).*normaliz_prior_std;
end end
iy = find(diag_chh); iy = find(diag_chh);
ind_dTAU = ind_dTAU(iy); ind_dREDUCEDFORM = ind_dREDUCEDFORM(iy);
si_dTAU = si_dTAU(iy,:); si_dREDUCEDFORM = si_dREDUCEDFORM(iy,:);
if ~isempty(iy) if ~isempty(iy)
quant = si_dTAU./repmat(sqrt(diag_chh(iy)),1,totparam_nbr); quant = si_dREDUCEDFORM./repmat(sqrt(diag_chh(iy)),1,totparam_nbr);
if size(quant,1)==1 if size(quant,1)==1
si_dTAUnorm = abs(quant).*normaliz_prior_std; si_dREDUCEDFORMnorm = abs(quant).*normaliz_prior_std;
else else
si_dTAUnorm = vnorm(quant).*normaliz_prior_std; si_dREDUCEDFORMnorm = vnorm(quant).*normaliz_prior_std;
end end
else else
si_dTAUnorm = []; si_dREDUCEDFORMnorm = [];
end end
diag_clre = diag(clre); diag_cdynamic = diag(cdynamic);
iy = find(diag_clre); iy = find(diag_cdynamic);
ind_dLRE = ind_dLRE(iy); ind_dDYNAMIC = ind_dDYNAMIC(iy);
si_dLRE = si_dLRE(iy,:); si_dDYNAMIC = si_dDYNAMIC(iy,:);
if ~isempty(iy) if ~isempty(iy)
quant = si_dLRE./repmat(sqrt(diag_clre(iy)),1,modparam_nbr); quant = si_dDYNAMIC./repmat(sqrt(diag_cdynamic(iy)),1,modparam_nbr);
if size(quant,1)==1 if size(quant,1)==1
si_dLREnorm = abs(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end); si_dDYNAMICnorm = abs(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end);
else else
si_dLREnorm = vnorm(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end); si_dDYNAMICnorm = vnorm(quant).*normaliz_prior_std(stderrparam_nbr+corrparam_nbr+1:end);
end end
else else
si_dLREnorm=[]; si_dDYNAMICnorm=[];
end end
%store results of identification strength %store results of identification strength
ide_hess.ide_strength_J = ide_strength_J; ide_hess.ide_strength_dMOMENTS = ide_strength_dMOMENTS;
ide_hess.ide_strength_J_prior = ide_strength_J_prior; ide_hess.ide_strength_dMOMENTS_prior = ide_strength_dMOMENTS_prior;
ide_hess.deltaM = deltaM; ide_hess.deltaM = deltaM;
ide_hess.deltaM_prior = deltaM_prior; ide_hess.deltaM_prior = deltaM_prior;
ide_hess.sensitivity_zero_pos = sensitivity_zero_pos; ide_hess.sensitivity_zero_pos = sensitivity_zero_pos;
ide_hess.identified_parameter_indices = indok; ide_hess.identified_parameter_indices = indok;
ide_hess.flag_score = flag_score; ide_hess.flag_score = flag_score;
ide_lre.si_dLREnorm = si_dLREnorm; ide_dynamic.si_dDYNAMICnorm = si_dDYNAMICnorm;
ide_moments.si_Jnorm = si_Jnorm; ide_moments.si_dMOMENTSnorm = si_dMOMENTSnorm;
ide_reducedform.si_dTAUnorm = si_dTAUnorm; ide_reducedform.si_dREDUCEDFORMnorm = si_dREDUCEDFORMnorm;
end %end of identification strength analysis end %end of identification strength analysis
end end
%% Theoretical identification analysis based on linear rational expectations model, i.e. steady state and Jacobian of dynamic model equations %% Normalization of Jacobians
% For Dynamic, ReducedForm, Moment and Minimal Jacobian: rescale each row by its largest element in absolute value
% For Spectrum: transform into correlation-type matrices (as above with AHess)
if normalize_jacobians if normalize_jacobians
norm_dLRE = max(abs(si_dLRE),[],2); norm_dDYNAMIC = max(abs(si_dDYNAMIC),[],2);
norm_dLRE = norm_dLRE(:,ones(size(dLRE,2),1)); norm_dDYNAMIC = norm_dDYNAMIC(:,ones(size(dDYNAMIC,2),1));
else else
norm_dLRE = 1; norm_dDYNAMIC = 1;
end end
% store into structure (not everything is really needed) % store into structure (not everything is used later on)
ide_lre.ind_dLRE = ind_dLRE; ide_dynamic.ind_dDYNAMIC = ind_dDYNAMIC;
ide_lre.norm_dLRE = norm_dLRE; ide_dynamic.norm_dDYNAMIC = norm_dDYNAMIC;
ide_lre.si_dLRE = si_dLRE; ide_dynamic.si_dDYNAMIC = si_dDYNAMIC;
ide_lre.dLRE = dLRE; ide_dynamic.dDYNAMIC = dDYNAMIC;
ide_lre.LRE = LRE; ide_dynamic.DYNAMIC = DYNAMIC;
%% Theoretical identification analysis based on steady state and reduced-form-solution
if ~no_identification_reducedform if ~no_identification_reducedform
if normalize_jacobians if normalize_jacobians
norm_dTAU = max(abs(si_dTAU),[],2); norm_dREDUCEDFORM = max(abs(si_dREDUCEDFORM),[],2);
norm_dTAU = norm_dTAU(:,ones(totparam_nbr,1)); norm_dREDUCEDFORM = norm_dREDUCEDFORM(:,ones(totparam_nbr,1));
else else
norm_dTAU = 1; norm_dREDUCEDFORM = 1;
end end
% store into structure (not everything is really needed) % store into structure (not everything is used later on)
ide_reducedform.ind_dTAU = ind_dTAU; ide_reducedform.ind_dREDUCEDFORM = ind_dREDUCEDFORM;
ide_reducedform.norm_dTAU = norm_dTAU; ide_reducedform.norm_dREDUCEDFORM = norm_dREDUCEDFORM;
ide_reducedform.si_dTAU = si_dTAU; ide_reducedform.si_dREDUCEDFORM = si_dREDUCEDFORM;
ide_reducedform.dTAU = dTAU; ide_reducedform.dREDUCEDFORM = dREDUCEDFORM;
ide_reducedform.TAU = TAU; ide_reducedform.REDUCEDFORM = REDUCEDFORM;
end end
%% Theoretical identification analysis based on Iskrev (2010)'s method, i.e. first two moments
if ~no_identification_moments if ~no_identification_moments
if normalize_jacobians if normalize_jacobians
norm_J = max(abs(si_J),[],2); norm_dMOMENTS = max(abs(si_dMOMENTS),[],2);
norm_J = norm_J(:,ones(totparam_nbr,1)); norm_dMOMENTS = norm_dMOMENTS(:,ones(totparam_nbr,1));
else else
norm_J = 1; norm_dMOMENTS = 1;
end end
% store into structure (not everything is really needed) % store into structure (not everything is used later on)
ide_moments.ind_J = ind_J; ide_moments.ind_dMOMENTS = ind_dMOMENTS;
ide_moments.norm_J = norm_J; ide_moments.norm_dMOMENTS = norm_dMOMENTS;
ide_moments.si_J = si_J; ide_moments.si_dMOMENTS = si_dMOMENTS;
ide_moments.J = J; ide_moments.dMOMENTS = dMOMENTS;
ide_moments.MOMENTS = MOMENTS; ide_moments.MOMENTS = MOMENTS;
if advanced if advanced
% here we do not normalize (i.e. set normJ=1) as the OLS in ident_bruteforce is very sensitive to normJ % here we do not normalize (i.e. we set norm_dMOMENTS=1) as the OLS in ident_bruteforce is very sensitive to norm_dMOMENTS
[ide_moments.pars, ide_moments.cosnJ] = ident_bruteforce(J(ind_J,:), max_dim_cova_group, options_.TeX, options_ident.name_tex, options_ident.tittxt, options_ident.tol_deriv); [ide_moments.pars, ide_moments.cosndMOMENTS] = ident_bruteforce(dMOMENTS(ind_dMOMENTS,:), max_dim_cova_group, options_.TeX, options_ident.name_tex, options_ident.tittxt, options_ident.tol_deriv);
end end
%here idea is to have the unnormalized S and V, which is then used in plot_identification.m and for prior_mc > 1
[~, S, V] = svd(J(ind_J,:),0); %here we focus on the unnormalized S and V, which is then used in plot_identification.m and for prior_mc > 1
[~, S, V] = svd(dMOMENTS(ind_dMOMENTS,:),0);
S = diag(S); S = diag(S);
S = [S;zeros(size(J,2)-length(ind_J),1)]; S = [S;zeros(size(dMOMENTS,2)-length(ind_dMOMENTS),1)];
if totparam_nbr > 8 if totparam_nbr > 8
ide_moments.S = S([1:4, end-3:end]); ide_moments.S = S([1:4, end-3:end]);
ide_moments.V = V(:,[1:4, end-3:end]); ide_moments.V = V(:,[1:4, end-3:end]);
@ -493,62 +469,62 @@ if info(1) == 0 %no errors in solution
end end
end end
%% Theoretical identification analysis based on Komunjer and Ng (2011)'s method, i.e. steady state and observational equivalent spectral densities within a minimal system
if ~no_identification_minimal if ~no_identification_minimal
if normalize_jacobians if normalize_jacobians
norm_D = max(abs(D(ind_D,:)),[],2); ind_dMINIMAL = (find(max(abs(dMINIMAL'),[],1) > tol_deriv)); %index for non-zero rows
norm_D = norm_D(:,ones(size(D,2),1)); norm_dMINIMAL = max(abs(dMINIMAL(ind_dMINIMAL,:)),[],2);
norm_dMINIMAL = norm_dMINIMAL(:,ones(size(dMINIMAL,2),1));
else else
norm_D = 1; norm_dMINIMAL = 1;
end end
% store into structure % store into structure (not everything is used later on)
ide_minimal.ind_D = ind_D; ide_minimal.ind_dMINIMAL = ind_dMINIMAL;
ide_minimal.norm_D = norm_D; ide_minimal.norm_dMINIMAL = norm_dMINIMAL;
ide_minimal.D = D; ide_minimal.dMINIMAL = dMINIMAL;
end end
%% Theoretical identification analysis based on Qu and Tkachenko (2012)'s method, i.e. steady state and spectral density
if ~no_identification_spectrum if ~no_identification_spectrum
if normalize_jacobians if normalize_jacobians
tilda_G = zeros(size(G)); ind_dSPECTRUM = (find(max(abs(dSPECTRUM'),[],1) > tol_deriv)); %index for non-zero rows
delta_G = sqrt(diag(G(ind_G,ind_G))); tilda_dSPECTRUM = zeros(size(dSPECTRUM));
tilda_G(ind_G,ind_G) = G(ind_G,ind_G)./((delta_G)*(delta_G')); delta_dSPECTRUM = sqrt(diag(dSPECTRUM(ind_dSPECTRUM,ind_dSPECTRUM)));
norm_G = max(abs(G(ind_G,:)),[],2); tilda_dSPECTRUM(ind_dSPECTRUM,ind_dSPECTRUM) = dSPECTRUM(ind_dSPECTRUM,ind_dSPECTRUM)./((delta_dSPECTRUM)*(delta_dSPECTRUM'));
norm_G = norm_G(:,ones(size(G,2),1)); norm_dSPECTRUM = max(abs(dSPECTRUM(ind_dSPECTRUM,:)),[],2);
norm_dSPECTRUM = norm_dSPECTRUM(:,ones(size(dSPECTRUM,2),1));
else else
tilda_G = G; tilda_dSPECTRUM = dSPECTRUM;
norm_G = 1; norm_dSPECTRUM = 1;
end end
% store into structure % store into structure (not everything is used later on)
ide_spectrum.ind_G = ind_G; ide_spectrum.ind_dSPECTRUM = ind_dSPECTRUM;
ide_spectrum.tilda_G = tilda_G; ide_spectrum.norm_dSPECTRUM = norm_dSPECTRUM;
ide_spectrum.G = G; ide_spectrum.tilda_dSPECTRUM = tilda_dSPECTRUM;
ide_spectrum.norm_G = norm_G; ide_spectrum.dSPECTRUM = dSPECTRUM;
end end
%% Perform identification checks, i.e. find out which parameters are involved %% Perform identification checks, i.e. find out which parameters are involved
if checks_via_subsets if checks_via_subsets
% identification_checks_via_subsets is only for debugging % identification_checks_via_subsets is only for debugging
[ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = ... [ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = ...
identification_checks_via_subsets(ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident); identification_checks_via_subsets(ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident);
else else
[ide_lre.cond, ide_lre.rank, ide_lre.ind0, ide_lre.indno, ide_lre.ino, ide_lre.Mco, ide_lre.Pco, ide_lre.jweak, ide_lre.jweak_pair] = ... [ide_dynamic.cond, ide_dynamic.rank, ide_dynamic.ind0, ide_dynamic.indno, ide_dynamic.ino, ide_dynamic.Mco, ide_dynamic.Pco, ide_dynamic.jweak, ide_dynamic.jweak_pair] = ...
identification_checks(dLRE(ind_dLRE,:)./norm_dLRE, 1, tol_rank, tol_sv, modparam_nbr); identification_checks(dDYNAMIC(ind_dDYNAMIC,:)./norm_dDYNAMIC, 1, tol_rank, tol_sv, modparam_nbr);
if ~no_identification_reducedform if ~no_identification_reducedform
[ide_reducedform.cond, ide_reducedform.rank, ide_reducedform.ind0, ide_reducedform.indno, ide_reducedform.ino, ide_reducedform.Mco, ide_reducedform.Pco, ide_reducedform.jweak, ide_reducedform.jweak_pair] = ... [ide_reducedform.cond, ide_reducedform.rank, ide_reducedform.ind0, ide_reducedform.indno, ide_reducedform.ino, ide_reducedform.Mco, ide_reducedform.Pco, ide_reducedform.jweak, ide_reducedform.jweak_pair] = ...
identification_checks(dTAU(ind_dTAU,:)./norm_dTAU, 1, tol_rank, tol_sv, totparam_nbr); identification_checks(dREDUCEDFORM(ind_dREDUCEDFORM,:)./norm_dREDUCEDFORM, 1, tol_rank, tol_sv, totparam_nbr);
end end
if ~no_identification_moments if ~no_identification_moments
[ide_moments.cond, ide_moments.rank, ide_moments.ind0, ide_moments.indno, ide_moments.ino, ide_moments.Mco, ide_moments.Pco, ide_moments.jweak, ide_moments.jweak_pair] = ... [ide_moments.cond, ide_moments.rank, ide_moments.ind0, ide_moments.indno, ide_moments.ino, ide_moments.Mco, ide_moments.Pco, ide_moments.jweak, ide_moments.jweak_pair] = ...
identification_checks(J(ind_J,:)./norm_J, 1, tol_rank, tol_sv, totparam_nbr); identification_checks(dMOMENTS(ind_dMOMENTS,:)./norm_dMOMENTS, 1, tol_rank, tol_sv, totparam_nbr);
end end
if ~no_identification_minimal if ~no_identification_minimal
[ide_minimal.cond, ide_minimal.rank, ide_minimal.ind0, ide_minimal.indno, ide_minimal.ino, ide_minimal.Mco, ide_minimal.Pco, ide_minimal.jweak, ide_minimal.jweak_pair] = ... [ide_minimal.cond, ide_minimal.rank, ide_minimal.ind0, ide_minimal.indno, ide_minimal.ino, ide_minimal.Mco, ide_minimal.Pco, ide_minimal.jweak, ide_minimal.jweak_pair] = ...
identification_checks(D(ind_D,:)./norm_D, 2, tol_rank, tol_sv, totparam_nbr); identification_checks(dMINIMAL(ind_dMINIMAL,:)./norm_dMINIMAL, 2, tol_rank, tol_sv, totparam_nbr);
end end
if ~no_identification_spectrum if ~no_identification_spectrum
[ide_spectrum.cond, ide_spectrum.rank, ide_spectrum.ind0, ide_spectrum.indno, ide_spectrum.ino, ide_spectrum.Mco, ide_spectrum.Pco, ide_spectrum.jweak, ide_spectrum.jweak_pair] = ... [ide_spectrum.cond, ide_spectrum.rank, ide_spectrum.ind0, ide_spectrum.indno, ide_spectrum.ino, ide_spectrum.Mco, ide_spectrum.Pco, ide_spectrum.jweak, ide_spectrum.jweak_pair] = ...
identification_checks(tilda_G, 3, tol_rank, tol_sv, totparam_nbr); identification_checks(tilda_dSPECTRUM, 3, tol_rank, tol_sv, totparam_nbr);
end end
end end
end end

View File

@ -48,7 +48,9 @@ function [condX, rankX, ind0, indno, ixno, Mco, Pco, jweak, jweak_pair] = identi
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>. % along with Dynare. If not, see <http://www.gnu.org/licenses/>.
% ========================================================================= % =========================================================================
if issparse(X)
X = full(X);
end
if nargin < 3 || isempty(tol_rank) if nargin < 3 || isempty(tol_rank)
tol_rank = 1.e-10; %tolerance level used for rank computations tol_rank = 1.e-10; %tolerance level used for rank computations
end end

View File

@ -1,5 +1,5 @@
function [ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident) function [ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident)
%[ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident) %[ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = identification_checks_via_subsets(ide_dynamic, ide_reducedform, ide_moments, ide_spectrum, ide_minimal, totparam_nbr, modparam_nbr, options_ident)
% ------------------------------------------------------------------------- % -------------------------------------------------------------------------
% Finds problematic sets of paramters via checking the necessary rank condition % Finds problematic sets of paramters via checking the necessary rank condition
% of the Jacobians for all possible combinations of parameters. The rank is % of the Jacobians for all possible combinations of parameters. The rank is
@ -70,14 +70,14 @@ function [ide_lre, ide_reducedform, ide_moments, ide_spectrum, ide_minimal] = id
% ========================================================================= % =========================================================================
%% initialize output objects and get options %% initialize output objects and get options
no_identification_lre = 0; %always compute lre no_identification_dynamic = 0; %always compute dynamic
no_identification_reducedform = options_ident.no_identification_reducedform; no_identification_reducedform = options_ident.no_identification_reducedform;
no_identification_moments = options_ident.no_identification_moments; no_identification_moments = options_ident.no_identification_moments;
no_identification_spectrum = options_ident.no_identification_spectrum; no_identification_spectrum = options_ident.no_identification_spectrum;
no_identification_minimal = options_ident.no_identification_minimal; no_identification_minimal = options_ident.no_identification_minimal;
tol_rank = options_ident.tol_rank; tol_rank = options_ident.tol_rank;
max_dim_subsets_groups = options_ident.max_dim_subsets_groups; max_dim_subsets_groups = options_ident.max_dim_subsets_groups;
lre_problpars = cell(1,max_dim_subsets_groups); dynamic_problpars = cell(1,max_dim_subsets_groups);
reducedform_problpars = cell(1,max_dim_subsets_groups); reducedform_problpars = cell(1,max_dim_subsets_groups);
moments_problpars = cell(1,max_dim_subsets_groups); moments_problpars = cell(1,max_dim_subsets_groups);
spectrum_problpars = cell(1,max_dim_subsets_groups); spectrum_problpars = cell(1,max_dim_subsets_groups);
@ -87,298 +87,298 @@ indtotparam = 1:totparam_nbr; %initialize index of parameters
%% Prepare Jacobians and check rank %% Prepare Jacobians and check rank
% initialize linear rational expectations model % initialize linear rational expectations model
if ~no_identification_lre if ~no_identification_dynamic
dLRE = ide_lre.dLRE; dDYNAMIC = ide_dynamic.dDYNAMIC;
dLRE(ide_lre.ind_dLRE,:) = dLRE(ide_lre.ind_dLRE,:)./ide_lre.norm_dLRE; %normalize dDYNAMIC(ide_dynamic.ind_dDYNAMIC,:) = dDYNAMIC(ide_dynamic.ind_dDYNAMIC,:)./ide_dynamic.norm_dDYNAMIC; %normalize
if totparam_nbr > modparam_nbr if totparam_nbr > modparam_nbr
dLRE = [zeros(size(ide_lre.dLRE,1),totparam_nbr-modparam_nbr) dLRE]; %add derivatives wrt stderr and corr parameters dDYNAMIC = [zeros(size(ide_dynamic.dDYNAMIC,1),totparam_nbr-modparam_nbr) dDYNAMIC]; %add derivatives wrt stderr and corr parameters
end end
rank_dLRE = rank(dLRE,tol_rank); %compute rank with imposed tolerance level rank_dDYNAMIC = rank(full(dDYNAMIC),tol_rank); %compute rank with imposed tolerance level
ide_lre.rank = rank_dLRE; ide_dynamic.rank = rank_dDYNAMIC;
% check rank criteria for full Jacobian % check rank criteria for full Jacobian
if rank_dLRE == totparam_nbr if rank_dDYNAMIC == totparam_nbr
% all parameters are identifiable % all parameters are identifiable
no_identification_lre = 1; %skip in the following no_identification_dynamic = 1; %skip in the following
indparam_dLRE = []; indparam_dDYNAMIC = [];
else else
% there is lack of identification % there is lack of identification
indparam_dLRE = indtotparam; %initialize for nchoosek indparam_dDYNAMIC = indtotparam; %initialize for nchoosek
end end
else else
indparam_dLRE = []; %empty for nchoosek indparam_dDYNAMIC = []; %empty for nchoosek
end end
% initialize for reduced form solution criteria % initialize for reduced form solution criteria
if ~no_identification_reducedform if ~no_identification_reducedform
dTAU = ide_reducedform.dTAU; dREDUCEDFORM = ide_reducedform.dREDUCEDFORM;
dTAU(ide_reducedform.ind_dTAU,:) = dTAU(ide_reducedform.ind_dTAU,:)./ide_reducedform.norm_dTAU; %normalize dREDUCEDFORM(ide_reducedform.ind_dREDUCEDFORM,:) = dREDUCEDFORM(ide_reducedform.ind_dREDUCEDFORM,:)./ide_reducedform.norm_dREDUCEDFORM; %normalize
rank_dTAU = rank(dTAU,tol_rank); %compute rank with imposed tolerance level rank_dREDUCEDFORM = rank(full(dREDUCEDFORM),tol_rank); %compute rank with imposed tolerance level
ide_reducedform.rank = rank_dTAU; ide_reducedform.rank = rank_dREDUCEDFORM;
% check rank criteria for full Jacobian % check rank criteria for full Jacobian
if rank_dTAU == totparam_nbr if rank_dREDUCEDFORM == totparam_nbr
% all parameters are identifiable % all parameters are identifiable
no_identification_reducedform = 1; %skip in the following no_identification_reducedform = 1; %skip in the following
indparam_dTAU = []; indparam_dREDUCEDFORM = [];
else else
% there is lack of identification % there is lack of identification
indparam_dTAU = indtotparam; %initialize for nchoosek indparam_dREDUCEDFORM = indtotparam; %initialize for nchoosek
end end
else else
indparam_dTAU = []; %empty for nchoosek indparam_dREDUCEDFORM = []; %empty for nchoosek
end end
% initialize for moments criteria % initialize for moments criteria
if ~no_identification_moments if ~no_identification_moments
J = ide_moments.J; dMOMENTS = ide_moments.dMOMENTS;
J(ide_moments.ind_J,:) = J(ide_moments.ind_J,:)./ide_moments.norm_J; %normalize dMOMENTS(ide_moments.ind_dMOMENTS,:) = dMOMENTS(ide_moments.ind_dMOMENTS,:)./ide_moments.norm_dMOMENTS; %normalize
rank_J = rank(J,tol_rank); %compute rank with imposed tolerance level rank_dMOMENTS = rank(full(dMOMENTS),tol_rank); %compute rank with imposed tolerance level
ide_moments.rank = rank_J; ide_moments.rank = rank_dMOMENTS;
% check rank criteria for full Jacobian % check rank criteria for full Jacobian
if rank_J == totparam_nbr if rank_dMOMENTS == totparam_nbr
% all parameters are identifiable % all parameters are identifiable
no_identification_moments = 1; %skip in the following no_identification_moments = 1; %skip in the following
indparam_J = []; indparam_dMOMENTS = [];
else else
% there is lack of identification % there is lack of identification
indparam_J = indtotparam; %initialize for nchoosek indparam_dMOMENTS = indtotparam; %initialize for nchoosek
end end
else else
indparam_J = []; %empty for nchoosek indparam_dMOMENTS = []; %empty for nchoosek
end end
% initialize for spectrum criteria % initialize for spectrum criteria
if ~no_identification_spectrum if ~no_identification_spectrum
G = ide_spectrum.tilda_G; %tilda G is normalized G matrix in identification_analysis.m dSPECTRUM = ide_spectrum.tilda_dSPECTRUM; %tilda dSPECTRUM is normalized dSPECTRUM matrix in identification_analysis.m
%alternative normalization %alternative normalization
%G = ide_spectrum.G; %dSPECTRUM = ide_spectrum.dSPECTRUM;
%G(ide_spectrum.ind_G,:) = G(ide_spectrum.ind_G,:)./ide_spectrum.norm_G; %normalize %dSPECTRUM(ide_spectrum.ind_dSPECTRUM,:) = dSPECTRUM(ide_spectrum.ind_dSPECTRUM,:)./ide_spectrum.norm_dSPECTRUM; %normalize
rank_G = rank(G,tol_rank); %compute rank with imposed tolerance level rank_dSPECTRUM = rank(full(dSPECTRUM),tol_rank); %compute rank with imposed tolerance level
ide_spectrum.rank = rank_G; ide_spectrum.rank = rank_dSPECTRUM;
% check rank criteria for full Jacobian % check rank criteria for full Jacobian
if rank_G == totparam_nbr if rank_dSPECTRUM == totparam_nbr
% all parameters are identifiable % all parameters are identifiable
no_identification_spectrum = 1; %skip in the following no_identification_spectrum = 1; %skip in the following
indparam_G = []; indparam_dSPECTRUM = [];
else else
% lack of identification % lack of identification
indparam_G = indtotparam; %initialize for nchoosek indparam_dSPECTRUM = indtotparam; %initialize for nchoosek
end end
else else
indparam_G = []; %empty for nchoosek indparam_dSPECTRUM = []; %empty for nchoosek
end end
% initialize for minimal system criteria % initialize for minimal system criteria
if ~no_identification_minimal if ~no_identification_minimal
D = ide_minimal.D; dMINIMAL = ide_minimal.dMINIMAL;
D(ide_minimal.ind_D,:) = D(ide_minimal.ind_D,:)./ide_minimal.norm_D; %normalize dMINIMAL(ide_minimal.ind_dMINIMAL,:) = dMINIMAL(ide_minimal.ind_dMINIMAL,:)./ide_minimal.norm_dMINIMAL; %normalize
D_par = D(:,1:totparam_nbr); %part of D that is dependent on parameters dMINIMAL_par = dMINIMAL(:,1:totparam_nbr); %part of dMINIMAL that is dependent on parameters
D_rest = D(:,(totparam_nbr+1):end); %part of D that is independent of parameters dMINIMAL_rest = dMINIMAL(:,(totparam_nbr+1):end); %part of dMINIMAL that is independent of parameters
rank_D = rank(D,tol_rank); %compute rank via SVD see function below rank_dMINIMAL = rank(full(dMINIMAL),tol_rank); %compute rank via SVD see function below
ide_minimal.rank = rank_D; ide_minimal.rank = rank_dMINIMAL;
D_fixed_rank_nbr = size(D_rest,2); dMINIMAL_fixed_rank_nbr = size(dMINIMAL_rest,2);
% check rank criteria for full Jacobian % check rank criteria for full Jacobian
if rank_D == totparam_nbr + D_fixed_rank_nbr if rank_dMINIMAL == totparam_nbr + dMINIMAL_fixed_rank_nbr
% all parameters are identifiable % all parameters are identifiable
no_identification_minimal = 1; %skip in the following no_identification_minimal = 1; %skip in the following
indparam_D = []; indparam_dMINIMAL = [];
else else
% lack of identification % lack of identification
indparam_D = indtotparam; %initialize for nchoosek indparam_dMINIMAL = indtotparam; %initialize for nchoosek
end end
else else
indparam_D = []; %empty for nchoosek indparam_dMINIMAL = []; %empty for nchoosek
end end
%% Check single parameters %% Check single parameters
for j=1:totparam_nbr for j=1:totparam_nbr
if ~no_identification_lre if ~no_identification_dynamic
% Columns correspond to single parameters, i.e. full rank would be equal to 1 % Columns correspond to single parameters, i.e. full rank would be equal to 1
if rank(dLRE(:,j),tol_rank) == 0 if rank(full(dDYNAMIC(:,j)),tol_rank) == 0
lre_problpars{1} = [lre_problpars{1};j]; dynamic_problpars{1} = [dynamic_problpars{1};j];
end end
end end
if ~no_identification_reducedform if ~no_identification_reducedform
% Columns correspond to single parameters, i.e. full rank would be equal to 1 % Columns correspond to single parameters, i.e. full rank would be equal to 1
if rank(dTAU(:,j),tol_rank) == 0 if rank(full(dREDUCEDFORM(:,j)),tol_rank) == 0
reducedform_problpars{1} = [reducedform_problpars{1};j]; reducedform_problpars{1} = [reducedform_problpars{1};j];
end end
end end
if ~no_identification_moments if ~no_identification_moments
% Columns correspond to single parameters, i.e. full rank would be equal to 1 % Columns correspond to single parameters, i.e. full rank would be equal to 1
if rank(J(:,j),tol_rank) == 0 if rank(full(dMOMENTS(:,j)),tol_rank) == 0
moments_problpars{1} = [moments_problpars{1};j]; moments_problpars{1} = [moments_problpars{1};j];
end end
end end
if ~no_identification_spectrum if ~no_identification_spectrum
% Diagonal values correspond to single parameters, absolute value needs to be greater than tolerance level % Diagonal values correspond to single parameters, absolute value needs to be greater than tolerance level
if abs(G(j,j)) < tol_rank if abs(dSPECTRUM(j,j)) < tol_rank
spectrum_problpars{1} = [spectrum_problpars{1};j]; spectrum_problpars{1} = [spectrum_problpars{1};j];
end end
end end
if ~no_identification_minimal if ~no_identification_minimal
% Columns of D_par correspond to single parameters, needs to be augmented with D_rest (part that is independent of parameters), % Columns of dMINIMAL_par correspond to single parameters, needs to be augmented with dMINIMAL_rest (part that is independent of parameters),
% full rank would be equal to 1+D_fixed_rank_nbr % full rank would be equal to 1+dMINIMAL_fixed_rank_nbr
if rank([D_par(:,j) D_rest],tol_rank) == D_fixed_rank_nbr if rank(full([dMINIMAL_par(:,j) dMINIMAL_rest]),tol_rank) == dMINIMAL_fixed_rank_nbr
minimal_problpars{1} = [minimal_problpars{1};j]; minimal_problpars{1} = [minimal_problpars{1};j];
end end
end end
end end
% Check whether lack of identification is only due to single parameters % Check whether lack of identification is only due to single parameters
if ~no_identification_lre if ~no_identification_dynamic
if size(lre_problpars{1},1) == (totparam_nbr - rank_dLRE) if size(dynamic_problpars{1},1) == (totparam_nbr - rank_dDYNAMIC)
%found all nonidentified parameter sets %found all nonidentified parameter sets
no_identification_lre = 1; %skip in the following no_identification_dynamic = 1; %skip in the following
else else
%still parameter sets that are nonidentified %still parameter sets that are nonidentified
indparam_dLRE(lre_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam indparam_dDYNAMIC(dynamic_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam
end end
end end
if ~no_identification_reducedform if ~no_identification_reducedform
if size(reducedform_problpars{1},1) == (totparam_nbr - rank_dTAU) if size(reducedform_problpars{1},1) == (totparam_nbr - rank_dREDUCEDFORM)
%found all nonidentified parameter sets %found all nonidentified parameter sets
no_identification_reducedform = 1; %skip in the following no_identification_reducedform = 1; %skip in the following
else else
%still parameter sets that are nonidentified %still parameter sets that are nonidentified
indparam_dTAU(reducedform_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam indparam_dREDUCEDFORM(reducedform_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam
end end
end end
if ~no_identification_moments if ~no_identification_moments
if size(moments_problpars{1},1) == (totparam_nbr - rank_J) if size(moments_problpars{1},1) == (totparam_nbr - rank_dMOMENTS)
%found all nonidentified parameter sets %found all nonidentified parameter sets
no_identification_moments = 1; %skip in the following no_identification_moments = 1; %skip in the following
else else
%still parameter sets that are nonidentified %still parameter sets that are nonidentified
indparam_J(moments_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam indparam_dMOMENTS(moments_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam
end end
end end
if ~no_identification_spectrum if ~no_identification_spectrum
if size(spectrum_problpars{1},1) == (totparam_nbr - rank_G) if size(spectrum_problpars{1},1) == (totparam_nbr - rank_dSPECTRUM)
%found all nonidentified parameter sets %found all nonidentified parameter sets
no_identification_spectrum = 1; %skip in the following no_identification_spectrum = 1; %skip in the following
else else
%still parameter sets that are nonidentified %still parameter sets that are nonidentified
indparam_G(spectrum_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam indparam_dSPECTRUM(spectrum_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam
end end
end end
if ~no_identification_minimal if ~no_identification_minimal
if size(minimal_problpars{1},1) == (totparam_nbr + D_fixed_rank_nbr - rank_D) if size(minimal_problpars{1},1) == (totparam_nbr + dMINIMAL_fixed_rank_nbr - rank_dMINIMAL)
%found all nonidentified parameter sets %found all nonidentified parameter sets
no_identification_minimal = 1; %skip in the following no_identification_minimal = 1; %skip in the following
else else
%still parameter sets that are nonidentified %still parameter sets that are nonidentified
indparam_D(minimal_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam indparam_dMINIMAL(minimal_problpars{1}) = []; %remove single unidentified parameters from higher-order sets of indparam
end end
end end
%% check higher order (j>1) parameter sets %% check higher order (j>1) parameter sets
%get common parameter indices from which to sample higher-order sets using nchoosek (we do not want to run nchoosek three times), most of the times indparamJ, indparamG, and indparamD are equal anyways %get common parameter indices from which to sample higher-order sets using nchoosek (we do not want to run nchoosek three times), most of the times indparamdMOMENTS, indparamdSPECTRUM, and indparamdMINIMAL are equal anyways
indtotparam = unique([indparam_dLRE indparam_dTAU indparam_J indparam_G indparam_D]); indtotparam = unique([indparam_dDYNAMIC indparam_dREDUCEDFORM indparam_dMOMENTS indparam_dSPECTRUM indparam_dMINIMAL]);
for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subsets for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subsets
h = dyn_waitbar(0,['Brute force collinearity for ' int2str(j) ' parameters.']); h = dyn_waitbar(0,['Brute force collinearity for ' int2str(j) ' parameters.']);
%Step1: get all possible unique subsets of j elements %Step1: get all possible unique subsets of j elements
if ~no_identification_lre || ~no_identification_reducedform || ~no_identification_moments || ~no_identification_spectrum || ~no_identification_minimal if ~no_identification_dynamic || ~no_identification_reducedform || ~no_identification_moments || ~no_identification_spectrum || ~no_identification_minimal
indexj=nchoosek(int16(indtotparam),j); % int16 speeds up nchoosek indexj=nchoosek(int16(indtotparam),j); % int16 speeds up nchoosek
% One could also use a mex version of nchoosek to speed this up, e.g.VChooseK from https://de.mathworks.com/matlabcentral/fileexchange/26190-vchoosek % One could also use a mex version of nchoosek to speed this up, e.g.VChooseK from https://de.mathworks.com/matlabcentral/fileexchange/26190-vchoosek
end end
%Step 2: remove already problematic sets and initialize rank vector %Step 2: remove already problematic sets and initialize rank vector
if ~no_identification_lre if ~no_identification_dynamic
indexj_dLRE = RemoveProblematicParameterSets(indexj,lre_problpars); indexj_dDYNAMIC = RemoveProblematicParameterSets(indexj,dynamic_problpars);
rankj_dLRE = zeros(size(indexj_dLRE,1),1); rankj_dDYNAMIC = zeros(size(indexj_dDYNAMIC,1),1);
else else
indexj_dLRE = []; indexj_dDYNAMIC = [];
end end
if ~no_identification_reducedform if ~no_identification_reducedform
indexj_dTAU = RemoveProblematicParameterSets(indexj,reducedform_problpars); indexj_dREDUCEDFORM = RemoveProblematicParameterSets(indexj,reducedform_problpars);
rankj_dTAU = zeros(size(indexj_dTAU,1),1); rankj_dREDUCEDFORM = zeros(size(indexj_dREDUCEDFORM,1),1);
else else
indexj_dTAU = []; indexj_dREDUCEDFORM = [];
end end
if ~no_identification_moments if ~no_identification_moments
indexj_J = RemoveProblematicParameterSets(indexj,moments_problpars); indexj_dMOMENTS = RemoveProblematicParameterSets(indexj,moments_problpars);
rankj_J = zeros(size(indexj_J,1),1); rankj_dMOMENTS = zeros(size(indexj_dMOMENTS,1),1);
else else
indexj_J = []; indexj_dMOMENTS = [];
end end
if ~no_identification_spectrum if ~no_identification_spectrum
indexj_G = RemoveProblematicParameterSets(indexj,spectrum_problpars); indexj_dSPECTRUM = RemoveProblematicParameterSets(indexj,spectrum_problpars);
rankj_G = zeros(size(indexj_G,1),1); rankj_dSPECTRUM = zeros(size(indexj_dSPECTRUM,1),1);
else else
indexj_G = []; indexj_dSPECTRUM = [];
end end
if ~no_identification_minimal if ~no_identification_minimal
indexj_D = RemoveProblematicParameterSets(indexj,minimal_problpars); indexj_dMINIMAL = RemoveProblematicParameterSets(indexj,minimal_problpars);
rankj_D = zeros(size(indexj_D,1),1); rankj_dMINIMAL = zeros(size(indexj_dMINIMAL,1),1);
else else
indexj_D = []; indexj_dMINIMAL = [];
end end
%Step3: Check rank criteria on submatrices %Step3: Check rank criteria on submatrices
k_dLRE=0; k_dTAU=0; k_J=0; k_G=0; k_D=0; %initialize counters k_dDYNAMIC=0; k_dREDUCEDFORM=0; k_dMOMENTS=0; k_dSPECTRUM=0; k_dMINIMAL=0; %initialize counters
maxk = max([size(indexj_dLRE,1), size(indexj_dTAU,1), size(indexj_J,1), size(indexj_D,1), size(indexj_G,1)]); maxk = max([size(indexj_dDYNAMIC,1), size(indexj_dREDUCEDFORM,1), size(indexj_dMOMENTS,1), size(indexj_dMINIMAL,1), size(indexj_dSPECTRUM,1)]);
for k=1:maxk for k=1:maxk
if ~no_identification_lre if ~no_identification_dynamic
k_dLRE = k_dLRE+1; k_dDYNAMIC = k_dDYNAMIC+1;
if k_dLRE <= size(indexj_dLRE,1) if k_dDYNAMIC <= size(indexj_dDYNAMIC,1)
dLRE_j = dLRE(:,indexj_dLRE(k_dLRE,:)); % pick columns that correspond to parameter subset dDYNAMIC_j = dDYNAMIC(:,indexj_dDYNAMIC(k_dDYNAMIC,:)); % pick columns that correspond to parameter subset
rankj_dLRE(k_dLRE,1) = rank(dLRE_j,tol_rank); %compute rank with imposed tolerance rankj_dDYNAMIC(k_dDYNAMIC,1) = rank(full(dDYNAMIC_j),tol_rank); %compute rank with imposed tolerance
end end
end end
if ~no_identification_reducedform if ~no_identification_reducedform
k_dTAU = k_dTAU+1; k_dREDUCEDFORM = k_dREDUCEDFORM+1;
if k_dTAU <= size(indexj_dTAU,1) if k_dREDUCEDFORM <= size(indexj_dREDUCEDFORM,1)
dTAU_j = dTAU(:,indexj_dTAU(k_dTAU,:)); % pick columns that correspond to parameter subset dREDUCEDFORM_j = dREDUCEDFORM(:,indexj_dREDUCEDFORM(k_dREDUCEDFORM,:)); % pick columns that correspond to parameter subset
rankj_dTAU(k_dTAU,1) = rank(dTAU_j,tol_rank); %compute rank with imposed tolerance rankj_dREDUCEDFORM(k_dREDUCEDFORM,1) = rank(full(dREDUCEDFORM_j),tol_rank); %compute rank with imposed tolerance
end end
end end
if ~no_identification_moments if ~no_identification_moments
k_J = k_J+1; k_dMOMENTS = k_dMOMENTS+1;
if k_J <= size(indexj_J,1) if k_dMOMENTS <= size(indexj_dMOMENTS,1)
J_j = J(:,indexj_J(k_J,:)); % pick columns that correspond to parameter subset dMOMENTS_j = dMOMENTS(:,indexj_dMOMENTS(k_dMOMENTS,:)); % pick columns that correspond to parameter subset
rankj_J(k_J,1) = rank(J_j,tol_rank); %compute rank with imposed tolerance rankj_dMOMENTS(k_dMOMENTS,1) = rank(full(dMOMENTS_j),tol_rank); %compute rank with imposed tolerance
end end
end end
if ~no_identification_minimal if ~no_identification_minimal
k_D = k_D+1; k_dMINIMAL = k_dMINIMAL+1;
if k_D <= size(indexj_D,1) if k_dMINIMAL <= size(indexj_dMINIMAL,1)
D_j = [D_par(:,indexj_D(k_D,:)) D_rest]; % pick columns in D_par that correspond to parameter subset and augment with parameter-indepdendet part D_rest dMINIMAL_j = [dMINIMAL_par(:,indexj_dMINIMAL(k_dMINIMAL,:)) dMINIMAL_rest]; % pick columns in dMINIMAL_par that correspond to parameter subset and augment with parameter-indepdendet part dMINIMAL_rest
rankj_D(k_D,1) = rank(D_j,tol_rank); %compute rank with imposed tolerance rankj_dMINIMAL(k_dMINIMAL,1) = rank(full(dMINIMAL_j),tol_rank); %compute rank with imposed tolerance
end end
end end
if ~no_identification_spectrum if ~no_identification_spectrum
k_G = k_G+1; k_dSPECTRUM = k_dSPECTRUM+1;
if k_G <= size(indexj_G,1) if k_dSPECTRUM <= size(indexj_dSPECTRUM,1)
G_j = G(indexj_G(k_G,:),indexj_G(k_G,:)); % pick rows and columns that correspond to parameter subset dSPECTRUM_j = dSPECTRUM(indexj_dSPECTRUM(k_dSPECTRUM,:),indexj_dSPECTRUM(k_dSPECTRUM,:)); % pick rows and columns that correspond to parameter subset
rankj_G(k_G,1) = rank(G_j,tol_rank); % Compute rank with imposed tol rankj_dSPECTRUM(k_dSPECTRUM,1) = rank(full(dSPECTRUM_j),tol_rank); % Compute rank with imposed tol
end end
end end
dyn_waitbar(k/maxk,h) dyn_waitbar(k/maxk,h)
end end
%Step 4: Compare rank conditions for all possible subsets. If rank condition is violated, then the corresponding numbers of the parameters are stored %Step 4: Compare rank conditions for all possible subsets. If rank condition is violated, then the corresponding numbers of the parameters are stored
if ~no_identification_lre if ~no_identification_dynamic
lre_problpars{j} = indexj_dLRE(rankj_dLRE < j,:); dynamic_problpars{j} = indexj_dDYNAMIC(rankj_dDYNAMIC < j,:);
end end
if ~no_identification_reducedform if ~no_identification_reducedform
reducedform_problpars{j} = indexj_dTAU(rankj_dTAU < j,:); reducedform_problpars{j} = indexj_dREDUCEDFORM(rankj_dREDUCEDFORM < j,:);
end end
if ~no_identification_moments if ~no_identification_moments
moments_problpars{j} = indexj_J(rankj_J < j,:); moments_problpars{j} = indexj_dMOMENTS(rankj_dMOMENTS < j,:);
end end
if ~no_identification_minimal if ~no_identification_minimal
minimal_problpars{j} = indexj_D(rankj_D < (j+D_fixed_rank_nbr),:); minimal_problpars{j} = indexj_dMINIMAL(rankj_dMINIMAL < (j+dMINIMAL_fixed_rank_nbr),:);
end end
if ~no_identification_spectrum if ~no_identification_spectrum
spectrum_problpars{j} = indexj_G(rankj_G < j,:); spectrum_problpars{j} = indexj_dSPECTRUM(rankj_dSPECTRUM < j,:);
end end
% % Optional Step 5: % remove redundant 2-sets, eg. if the problematic sets are [(p1,p2);(p1,p3);(p2,p3)], then the unique problematic parameter sets are actually only [(p1,p2),(p1,p3)] % % Optional Step 5: % remove redundant 2-sets, eg. if the problematic sets are [(p1,p2);(p1,p3);(p2,p3)], then the unique problematic parameter sets are actually only [(p1,p2),(p1,p3)]
% if j == 2 % if j == 2
% for jj=1:max([size(lre_problpars{2},1), size(reducedform_problpars{2},1), size(moments_problpars{2},1), size(spectrum_problpars{2},1), size(minimal_problpars{2},1)]) % for jj=1:max([size(dynamic_problpars{2},1), size(reducedform_problpars{2},1), size(moments_problpars{2},1), size(spectrum_problpars{2},1), size(minimal_problpars{2},1)])
% if jj <= size(lre_problpars{2},1) % if jj <= size(dynamic_problpars{2},1)
% lre_problpars{2}(lre_problpars{2}(jj,2)==lre_problpars{2}(:,1)) = lre_problpars{2}(jj,1); % dynamic_problpars{2}(dynamic_problpars{2}(jj,2)==dynamic_problpars{2}(:,1)) = dynamic_problpars{2}(jj,1);
% end % end
% if jj <= size(reducedform_problpars{2},1) % if jj <= size(reducedform_problpars{2},1)
% reducedform_problpars{2}(reducedform_problpars{2}(jj,2)==reducedform_problpars{2}(:,1)) = reducedform_problpars{2}(jj,1); % reducedform_problpars{2}(reducedform_problpars{2}(jj,2)==reducedform_problpars{2}(:,1)) = reducedform_problpars{2}(jj,1);
@ -393,13 +393,13 @@ for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subset
% minimal_problpars{2}(minimal_problpars{2}(jj,2)==minimal_problpars{2}(:,1)) = minimal_problpars{2}(jj,1); % minimal_problpars{2}(minimal_problpars{2}(jj,2)==minimal_problpars{2}(:,1)) = minimal_problpars{2}(jj,1);
% end % end
% end % end
% lre_problpars{2} = unique(lre_problpars{2},'rows'); % dynamic_problpars{2} = unique(dynamic_problpars{2},'rows');
% reducedform_problpars{2} = unique(reducedform_problpars{2},'rows'); % reducedform_problpars{2} = unique(reducedform_problpars{2},'rows');
% moments_problpars{2} = unique(moments_problpars{2},'rows'); % moments_problpars{2} = unique(moments_problpars{2},'rows');
% spectrum_problpars{2} = unique(spectrum_problpars{2},'rows'); % spectrum_problpars{2} = unique(spectrum_problpars{2},'rows');
% minimal_problpars{2} = unique(minimal_problpars{2},'rows'); % minimal_problpars{2} = unique(minimal_problpars{2},'rows');
% % in indparam we replace the second parameter of problematic 2-sets by the observational equivalent first parameter to speed up nchoosek % % in indparam we replace the second parameter of problematic 2-sets by the observational equivalent first parameter to speed up nchoosek
% idx2 = unique([lre_problpars{2}; reducedform_problpars{2}; moments_problpars{2}; spectrum_problpars{2}; minimal_problpars{2}],'rows'); % idx2 = unique([dynamic_problpars{2}; reducedform_problpars{2}; moments_problpars{2}; spectrum_problpars{2}; minimal_problpars{2}],'rows');
% if ~isempty(idx2) % if ~isempty(idx2)
% indtotparam(ismember(indtotparam,idx2(:,2))) = []; % indtotparam(ismember(indtotparam,idx2(:,2))) = [];
% end % end
@ -408,10 +408,10 @@ for j=2:min(length(indtotparam),max_dim_subsets_groups) % Check j-element subset
end end
%% Save output variables %% Save output variables
if ~isempty(lre_problpars{1}) if ~isempty(dynamic_problpars{1})
lre_problpars{1}(ismember(lre_problpars{1},1:(totparam_nbr-modparam_nbr))) = []; % get rid of stderr and corr variables for lre dynamic_problpars{1}(ismember(dynamic_problpars{1},1:(totparam_nbr-modparam_nbr))) = []; % get rid of stderr and corr variables for dynamic
end end
ide_lre.problpars = lre_problpars; ide_dynamic.problpars = dynamic_problpars;
ide_reducedform.problpars = reducedform_problpars; ide_reducedform.problpars = reducedform_problpars;
ide_moments.problpars = moments_problpars; ide_moments.problpars = moments_problpars;
ide_spectrum.problpars = spectrum_problpars; ide_spectrum.problpars = spectrum_problpars;

View File

@ -47,43 +47,43 @@ if nargin <11
end end
[SampleSize, nparam]=size(params); [SampleSize, nparam]=size(params);
si_Jnorm = idemoments.si_Jnorm; si_dMOMENTSnorm = idemoments.si_dMOMENTSnorm;
si_dTAUnorm = idemodel.si_dTAUnorm; si_dTAUnorm = idemodel.si_dREDUCEDFORMnorm;
si_dLREnorm = idelre.si_dLREnorm; si_dLREnorm = idelre.si_dDYNAMICnorm;
tittxt1=regexprep(tittxt, ' ', '_'); tittxt1=regexprep(tittxt, ' ', '_');
tittxt1=strrep(tittxt1, '.', ''); tittxt1=strrep(tittxt1, '.', '');
if SampleSize == 1 if SampleSize == 1
si_J = idemoments.si_J; si_dMOMENTS = idemoments.si_dMOMENTS;
hh = dyn_figure(options_.nodisplay,'Name',[tittxt, ' - Identification using info from observables']); hh = dyn_figure(options_.nodisplay,'Name',[tittxt, ' - Identification using info from observables']);
subplot(211) subplot(211)
mmm = (idehess.ide_strength_J); mmm = (idehess.ide_strength_dMOMENTS);
[ss, is] = sort(mmm); [ss, is] = sort(mmm);
if ~all(isnan(idehess.ide_strength_J_prior)) if ~all(isnan(idehess.ide_strength_dMOMENTS_prior))
bar(log([idehess.ide_strength_J(:,is)' idehess.ide_strength_J_prior(:,is)'])) bar(log([idehess.ide_strength_dMOMENTS(:,is)' idehess.ide_strength_dMOMENTS_prior(:,is)']))
else else
bar(log([idehess.ide_strength_J(:,is)' ])) bar(log([idehess.ide_strength_dMOMENTS(:,is)' ]))
end end
hold on hold on
plot((1:length(idehess.ide_strength_J(:,is)))-0.15,log([idehess.ide_strength_J(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') plot((1:length(idehess.ide_strength_dMOMENTS(:,is)))-0.15,log([idehess.ide_strength_dMOMENTS(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none')
plot((1:length(idehess.ide_strength_J_prior(:,is)))+0.15,log([idehess.ide_strength_J_prior(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none') plot((1:length(idehess.ide_strength_dMOMENTS_prior(:,is)))+0.15,log([idehess.ide_strength_dMOMENTS_prior(:,is)']),'o','MarkerSize',7,'MarkerFaceColor',[0 0 0],'MarkerEdgeColor','none')
if any(isinf(log(idehess.ide_strength_J(idehess.identified_parameter_indices)))) if any(isinf(log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))))
%-Inf, i.e. 0 strength %-Inf, i.e. 0 strength
inf_indices=find(isinf(log(idehess.ide_strength_J(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J(idehess.identified_parameter_indices))<0); inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))<0);
inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices));
plot(find(inf_pos)-0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 0 0],'MarkerEdgeColor',[0 0 0]) plot(find(inf_pos)-0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 0 0],'MarkerEdgeColor',[0 0 0])
%+Inf, i.e. Inf strength %+Inf, i.e. Inf strength
inf_indices=find(isinf(log(idehess.ide_strength_J(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J(idehess.identified_parameter_indices))>0); inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS(idehess.identified_parameter_indices))>0);
inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices));
plot(find(inf_pos)-0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 1 1],'MarkerEdgeColor',[0 0 0]) plot(find(inf_pos)-0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 1 1],'MarkerEdgeColor',[0 0 0])
end end
if any(isinf(log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices)))) if any(isinf(log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))))
%-Inf, i.e. 0 strength %-Inf, i.e. 0 strength
inf_indices=find(isinf(log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))<0); inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))<0);
inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices));
plot(find(inf_pos)+0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 0 0],'MarkerEdgeColor',[0 0 0]) plot(find(inf_pos)+0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 0 0],'MarkerEdgeColor',[0 0 0])
%+Inf, i.e. 0 strength %+Inf, i.e. 0 strength
inf_indices=find(isinf(log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_J_prior(idehess.identified_parameter_indices))>0); inf_indices=find(isinf(log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))) & log(idehess.ide_strength_dMOMENTS_prior(idehess.identified_parameter_indices))>0);
inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices)); inf_pos=ismember(is,idehess.identified_parameter_indices(inf_indices));
plot(find(inf_pos)+0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 1 1],'MarkerEdgeColor',[0 0 0]) plot(find(inf_pos)+0.15,zeros(sum(inf_pos),1),'o','MarkerSize',7,'MarkerFaceColor',[1 1 1],'MarkerEdgeColor',[0 0 0])
end end
@ -93,7 +93,7 @@ if SampleSize == 1
for ip=1:nparam for ip=1:nparam
text(ip,dy(1),name{is(ip)},'rotation',90,'HorizontalAlignment','right','interpreter','none') text(ip,dy(1),name{is(ip)},'rotation',90,'HorizontalAlignment','right','interpreter','none')
end end
if ~all(isnan(idehess.ide_strength_J_prior)) if ~all(isnan(idehess.ide_strength_dMOMENTS_prior))
legend('relative to param value','relative to prior std','Location','Best') legend('relative to param value','relative to prior std','Location','Best')
else else
legend('relative to param value','Location','Best') legend('relative to param value','Location','Best')
@ -161,12 +161,12 @@ if SampleSize == 1
skipline() skipline()
disp('Plotting advanced diagnostics') disp('Plotting advanced diagnostics')
end end
if all(isnan([si_Jnorm';si_dTAUnorm';si_dLREnorm'])) if all(isnan([si_dMOMENTSnorm';si_dTAUnorm';si_dLREnorm']))
fprintf('\nIDENTIFICATION: Skipping sensitivity plot, because standard deviation of parameters is NaN, possibly due to the use of ML.\n') fprintf('\nIDENTIFICATION: Skipping sensitivity plot, because standard deviation of parameters is NaN, possibly due to the use of ML.\n')
else else
hh = dyn_figure(options_.nodisplay,'Name',[tittxt, ' - Sensitivity plot']); hh = dyn_figure(options_.nodisplay,'Name',[tittxt, ' - Sensitivity plot']);
subplot(211) subplot(211)
mmm = (si_Jnorm)'./max(si_Jnorm); mmm = (si_dMOMENTSnorm)'./max(si_dMOMENTSnorm);
mmm1 = (si_dTAUnorm)'./max(si_dTAUnorm); mmm1 = (si_dTAUnorm)'./max(si_dTAUnorm);
mmm=[mmm mmm1]; mmm=[mmm mmm1];
mmm1 = (si_dLREnorm)'./max(si_dLREnorm); mmm1 = (si_dLREnorm)'./max(si_dLREnorm);
@ -199,7 +199,7 @@ if SampleSize == 1
end end
end end
% identificaton patterns % identificaton patterns
for j=1:size(idemoments.cosnJ,2) for j=1:size(idemoments.cosndMOMENTS,2)
pax=NaN(nparam,nparam); pax=NaN(nparam,nparam);
% fprintf('\n') % fprintf('\n')
% disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)']) % disp(['Collinearity patterns with ', int2str(j) ,' parameter(s)'])
@ -212,10 +212,10 @@ if SampleSize == 1
namx=[namx ' ' sprintf('%-15s','--')]; namx=[namx ' ' sprintf('%-15s','--')];
else else
namx=[namx ' ' sprintf('%-15s',name{dumpindx})]; namx=[namx ' ' sprintf('%-15s',name{dumpindx})];
pax(i,dumpindx)=idemoments.cosnJ(i,j); pax(i,dumpindx)=idemoments.cosndMOMENTS(i,j);
end end
end end
% fprintf('%-15s [%s] %10.3f\n',name{i},namx,idemoments.cosnJ(i,j)) % fprintf('%-15s [%s] %10.3f\n',name{i},namx,idemoments.cosndMOMENTS(i,j))
end end
hh = dyn_figure(options_.nodisplay,'Name',[tittxt,' - Collinearity patterns with ', int2str(j) ,' parameter(s)']); hh = dyn_figure(options_.nodisplay,'Name',[tittxt,' - Collinearity patterns with ', int2str(j) ,' parameter(s)']);
imagesc(pax,[0 1]); imagesc(pax,[0 1]);
@ -337,9 +337,9 @@ if SampleSize == 1
else else
hh = dyn_figure(options_.nodisplay,'Name',['MC sensitivities']); hh = dyn_figure(options_.nodisplay,'Name',['MC sensitivities']);
subplot(211) subplot(211)
mmm = (idehess.ide_strength_J); mmm = (idehess.ide_strength_dMOMENTS);
[ss, is] = sort(mmm); [ss, is] = sort(mmm);
mmm = mean(si_Jnorm)'; mmm = mean(si_dMOMENTSnorm)';
mmm = mmm./max(mmm); mmm = mmm./max(mmm);
if advanced if advanced
mmm1 = mean(si_dTAUnorm)'; mmm1 = mean(si_dTAUnorm)';

80
matlab/prodmom.m Normal file
View File

@ -0,0 +1,80 @@
%
% prodmom.m Date: 4/29/2006
% This Matlab program computes the product moment of X_{i_1}^{nu_1}X_{i_2}^{nu_2}...X_{i_m}^{nu_m},
% where X_{i_j} are elements from X ~ N(0_n,V).
% V only needs to be positive semidefinite.
% V: variance-covariance matrix of X
% ii: vector of i_j
% nu: power of X_{i_j}
% Reference: Triantafyllopoulos (2003) On the Central Moments of the Multidimensional
% Gaussian Distribution, Mathematical Scientist
% Kotz, Balakrishnan, and Johnson (2000), Continuous Multivariate
% Distributions, Vol. 1, p.261
% Note that there is a typo in Eq.(46.25), there should be an extra rho in front
% of the equation.
% Usage: prodmom(V,[i1 i2 ... ir],[nu1 nu2 ... nur])
% Example: To get E[X_2X_4^3X_7^2], use prodmom(V,[2 4 7],[1 3 2])
%
function y = prodmom(V,ii,nu);
if nargin<3
nu = ones(size(ii));
end
s = sum(nu);
if s==0
y = 1;
return
end
if rem(s,2)==1
y = 0;
return
end
nuz = nu==0;
nu(nuz) = [];
ii(nuz) = [];
m = length(ii);
V = V(ii,ii);
s2 = s/2;
%
% Use univariate normal results
%
if m==1
y = V^s2*prod([1:2:s-1]);
return
end
%
% Use bivariate normal results when there are only two distinct indices
%
if m==2
rho = V(1,2)/sqrt(V(1,1)*V(2,2));
y = V(1,1)^(nu(1)/2)*V(2,2)^(nu(2)/2)*bivmom(nu,rho);
return
end
%
% Regular case
%
[nu,inu] = sort(nu,2,'descend');
V = V(inu,inu); % Extract only the relevant part of V
x = zeros(1,m);
V = V./2;
nu2 = nu./2;
p = 2;
q = nu2*V*nu2';
y = 0;
for i=1:fix(prod(nu+1)/2)
y = y+p*q^s2;
for j=1:m
if x(j)<nu(j)
x(j) = x(j)+1;
p = -round(p*(nu(j)+1-x(j))/x(j));
q = q-2*(nu2-x)*V(:,j)-V(j,j);
break
else
x(j) = 0;
if rem(nu(j),2)==1
p = -p;
end
q = q+2*nu(j)*(nu2-x)*V(:,j)-nu(j)^2*V(j,j);
end
end
end
y = y/prod([1:s2]);

105
matlab/prodmom_deriv.m Normal file
View File

@ -0,0 +1,105 @@
%
% prodmom.m Date: 4/29/2006
% This Matlab program computes the product moment of X_{i_1}^{nu_1}X_{i_2}^{nu_2}...X_{i_m}^{nu_m},
% where X_{i_j} are elements from X ~ N(0_n,V).
% V only needs to be positive semidefinite.
% V: variance-covariance matrix of X
% ii: vector of i_j
% nu: power of X_{i_j}
% Reference: Triantafyllopoulos (2003) On the Central Moments of the Multidimensional
% Gaussian Distribution, Mathematical Scientist
% Kotz, Balakrishnan, and Johnson (2000), Continuous Multivariate
% Distributions, Vol. 1, p.261
% Note that there is a typo in Eq.(46.25), there should be an extra rho in front
% of the equation.
% Usage: prodmom(V,[i1 i2 ... ir],[nu1 nu2 ... nur])
% Example: To get E[X_2X_4^3X_7^2], use prodmom(V,[2 4 7],[1 3 2])
%
function dy = prodmom_deriv(V,ii,nu,dV,dC);
if nargin<3
nu = ones(size(ii));
end
s = sum(nu);
if s==0
dy = zeros(1,1,size(dV,3));
return
end
if rem(s,2)==1
dy = zeros(1,1,size(dV,3));
return
end
nuz = nu==0;
nu(nuz) = [];
ii(nuz) = [];
m = length(ii);
V = V(ii,ii);
dV = dV(ii,ii,:);
s2 = s/2;
%
% Use univariate normal results
%
if m==1
dy = s2*V^(s2-1)*dV*prod([1:2:s-1]);
dy = reshape(dy,1,size(dV,3));
return
end
%
% Use bivariate normal results when there are only two distinct indices
%
if m==2
rho = V(1,2)/sqrt(V(1,1)*V(2,2));
drho = dC(ii(1),ii(2),:);
[tmp,dtmp] = bivmom(nu,rho);
dy = (nu(1)/2)*V(1,1)^(nu(1)/2-1)*dV(1,1,:) * V(2,2)^(nu(2)/2) * tmp...
+ V(1,1)^(nu(1)/2) * (nu(2)/2)*V(2,2)^(nu(2)/2-1)*dV(2,2,:) * tmp...
+ V(1,1)^(nu(1)/2) * V(2,2)^(nu(2)/2) * dtmp * drho;
dy = reshape(dy,1,size(dV,3));
return
end
%
% Regular case
%
[nu,inu] = sort(nu,2,'descend');
V = V(inu,inu); % Extract only the relevant part of V
dV = dV(inu,inu,:); % Extract only the relevant part of dV
x = zeros(1,m);
V = V./2;
dV = dV./2;
nu2 = nu./2;
p = 2;
q = nu2*V*nu2';
%dq = nu2*dV*nu2';
%dq = multiprod(multiprod(nu2,dV),nu2');
dq = NaN(size(q,1), size(q,2), size(dV,3));
for jp = 1:size(dV,3)
dq(:,:,jp) = nu2*dV(:,:,jp)*nu2';
end
dy = 0;
for i=1:fix(prod(nu+1)/2)
dy = dy+p*s2*q^(s2-1)*dq;
for j=1:m
if x(j)<nu(j)
x(j) = x(j)+1;
p = -round(p*(nu(j)+1-x(j))/x(j));
%dq = dq-2*(nu2-x)*dV(:,j,:)-dV(j,j,:);
%dq = dq-2*multiprod((nu2-x),dV(:,j,:))-dV(j,j,:);
for jp=1:size(dV,3)
dq(:,:,jp) = dq(:,:,jp)-2*(nu2-x)*dV(:,j,jp)-dV(j,j,jp);
end
q = q-2*(nu2-x)*V(:,j)-V(j,j);
break
else
x(j) = 0;
if rem(nu(j),2)==1
p = -p;
end
%dq = dq+2*nu(j)*multiprod((nu2-x),dV(:,j,:))-nu(j)^2*dV(j,j,:);
for jp=1:size(dV,3)
dq(:,:,jp) = dq(:,:,jp)+2*nu(j)*(nu2-x)*dV(:,j,jp)-nu(j)^2*dV(j,j,jp);
end
q = q+2*nu(j)*(nu2-x)*V(:,j)-nu(j)^2*V(j,j);
end
end
end
dy = dy/prod([1:s2]);
dy = reshape(dy,1,size(dV,3));

View File

@ -0,0 +1,763 @@
function dr = pruned_state_space_system(M, options, dr)
% This can be set up into the following ABCD representation:
% z = c + A*z(-1) + B*xi
% y = ybar + d + C*z(-1) + D*xi
% Denote
% hx = dr.ghx(indx,:); hu = dr.ghu(indx,:);
% hxx = dr.ghxx(indx,:); hxu = dr.ghxu(indx,:); huu = dr.ghuu(indx,:); hs2 = dr.ghs2(indx,:);
% gx = dr.ghx(indy,:); gu = dr.ghu(indy,:);
% gxx = dr.ghxx(indy,:); gxu = dr.ghxu(indy,:); guu = dr.ghuu(indy,:); gs2 = dr.ghs2(indy,:);
% hxss = dr.ghxss(indx,:); huss = dr.ghuss(indx,:); hxxx = dr.ghxxx(indx,:); huuu = dr.ghuuu(indx,:); hxxu = dr.ghxxu(indx,:); hxuu = dr.ghxxu(indx,:);
% gxss = dr.ghxss(indy,:); guss = dr.ghuss(indy,:); gxxx = dr.ghxxx(indy,:); guuu = dr.ghuuu(indy,:); gxxu = dr.ghxxu(indy,:); gxuu = dr.ghxxu(indy,:);
% Law of motion for first-order effects states xf and selected endogenous first-order effects variables yf:
% xf = hx*xf(-1) + hu*u
% yf = gx*xf(-1) + gu*u
% Law of motion for second-order effects states xs and selected endogenous second-order effects variables ys:
% xs = hx*xs(-1) + 1/2*hxx*kron(xf(-1),xf(-1)) + 1/2*huu*kron(u,u) + hxu*kron(xf(-1),u) + 1/2*hs2
% ys = gx*xs(-1) + 1/2*gxx*kron(xf(-1),xf(-1)) + 1/2*guu*kron(u,u) + gxu*kron(xf(-1),u) + 1/2*gs2
% Law of motion for third-order effects states xrd and selected endogenous second-order effects variables yrd:
% xrd = hx*xrd(-1) + hxx*kron(xf(-1),xs(-1)) + hxu*kron(xs(-1),u) + 3/6*hxss*xf(-1) + 3/6*huss*u + 1/6*hxxx*kron(xf(-1),kron(xf(-1),xf(-1))) + 1/6*huuu*kron(u,kron(u,u)) + 3/6*hxxu*kron(xf(-1),kron(xf(-1),u)) + 3/6*hxuu*kron(xf(-1),kron(u,u))
% yrd = gx*xrd(-1) + gxx*kron(xf(-1),xs(-1)) + gxu*kron(xs(-1),u) + 3/6*gxss*xf(-1) + 3/6*guss*u + 1/6*gxxx*kron(xf(-1),kron(xf(-1),xf(-1))) + 1/6*guuu*kron(u,kron(u,u)) + 3/6*gxxu*kron(xf(-1),kron(xf(-1),u)) + 3/6*gxuu*kron(xf(-1),kron(u,u))
% Selected variables: y = ybar + yf + ys
% Pruned state vector: z = [xf; xs; kron(xf,xf)]
% Pruned innovation vector: xi = [u; kron(u,u)-vec(Sigma_u); kron(xf(-1),u); kron(u,xf(-1))]
% Second moments of xi
% Sig_xi = E[u*u' , u*kron(u,u)' , zeros(u_nbr,x_nbr*u_nbr), zeros(u_nbr,u_nbr*x_nbr);
% kron(u,u)*u', kron(u,u)*kron(u,u)'-Sig_u(:)*Sig_u(:)', zeros(u_nbr^2,x_nbr*u_nbr), zeros(u_nbr^2,u_nbr*x_nbr);
% zeros(x_nbr*u_nbr,u_nbr), zeros(x_nbr*u_nbr,u_nbr^2), kron(xf(-1),u)*kron(xf(-1),u)', kron(xf(-1),u)*kron(u,xf(-1))';
% zeros(u_nbr*x_nbr,u_nbr), zeros(u_nbr*x_nbr,u_nbr^2), kron(u,xf(-1))*kron(xf(-1),u)', kron(u,xf(-1))*kron(u,xf(-1))';]
% That is, we only need to compute:
% - Sig_xi_11 = E[u*u']=Sig_u
% - Sig_xi_21 = E[kron(u,u)*u']=0 for symmetric distributions
% - Sig_xi_12 = transpose(Sig_xi_21)= 0 for symmetric distributions
% - Sig_xi_22 = E[kron(u,u)*kron(u,u)']-Sig_u(:)*Sig_u(:)' which requires the fourth-order product moments of u
% - Sig_xi_34 = E[kron(xf(-1),u)*kron(xf(-1),u)'] which requires the second-order moments of xf and second-order moments of u
% - Sig_xi_43 = transpose(Sig_xi_34)
% - Sig_xi_33 =
% - Sig_xi_44 =
%% Auxiliary indices, numbers and flags
order = options.order;
indx = [M.nstatic+(1:M.nspred) M.endo_nbr+(1:size(dr.ghx,2)-M.nspred)]';
indy = (1:M.endo_nbr)'; %by default select all variables
compute_derivs = false;
if isfield(options,'options_ident')
compute_derivs = true;
stderrparam_nbr = length(options.options_ident.indpstderr);
corrparam_nbr = size(options.options_ident.indpcorr,1);
modparam_nbr = length(options.options_ident.indpmodel);
totparam_nbr = stderrparam_nbr+corrparam_nbr+modparam_nbr;
indy = options.options_ident.indvobs;
end
Yss = dr.ys(dr.order_var); if compute_derivs; dYss = dr.derivs.dYss; end
E_uu = M.Sigma_e; if compute_derivs; dE_uu = dr.derivs.dSigma_e; end
Correlation_matrix = M.Correlation_matrix; if compute_derivs; dCorrelation_matrix = dr.derivs.dCorrelation_matrix; end
ghx = dr.ghx; if compute_derivs; dghx = dr.derivs.dghx; end
ghu = dr.ghu; if compute_derivs; dghu = dr.derivs.dghu; end
Om = ghu*E_uu*transpose(ghu); if compute_derivs; dOm = dr.derivs.dOm; end
y_nbr = length(indy);
x_nbr = length(indx);
u_nbr = M.exo_nbr;
% indices for extended state vector z and extended shock vector e
id_z1_xf = (1:x_nbr);
id_e1_u = (1:u_nbr);
if options.order > 1
id_z2_xs = id_z1_xf(end) + (1:x_nbr);
id_z3_xf_xf = id_z2_xs(end) + (1:x_nbr*x_nbr);
id_e2_u_u = id_e1_u(end) + (1:u_nbr*u_nbr);
id_e3_xf_u = id_e2_u_u(end) + (1:x_nbr*u_nbr);
id_e4_u_xf = id_e3_xf_u(end) + (1:u_nbr*x_nbr);
ghxx = dr.ghxx; if compute_derivs; dghxx = dr.derivs.dghxx; end
ghxu = dr.ghxu; if compute_derivs; dghxu = dr.derivs.dghxu; end
ghuu = dr.ghuu; if compute_derivs; dghuu = dr.derivs.dghuu; end
ghs2 = dr.ghs2; if compute_derivs; dghs2 = dr.derivs.dghs2; end
end
if options.order > 2
id_z4_xrd = id_z3_xf_xf(end) + (1:x_nbr);
id_z5_xf_xs = id_z4_xrd(end) + (1:x_nbr*x_nbr);
id_z6_xf_xf_xf = id_z5_xf_xs(end) + (1:x_nbr*x_nbr*x_nbr);
id_e5_xs_u = id_e4_u_xf(end) + (1:x_nbr*u_nbr);
id_e6_u_xs = id_e5_xs_u(end) + (1:u_nbr*x_nbr);
id_e7_xf_xf_u = id_e6_u_xs(end) + (1:x_nbr*x_nbr*u_nbr);
id_e8_xf_u_xf = id_e7_xf_xf_u(end) + (1:x_nbr*u_nbr*x_nbr);
id_e9_u_xf_xf = id_e8_xf_u_xf(end) + (1:u_nbr*x_nbr*x_nbr);
id_e10_xf_u_u = id_e9_u_xf_xf(end) + (1:x_nbr*u_nbr*u_nbr);
id_e11_u_xf_u = id_e10_xf_u_u(end) + (1:u_nbr*x_nbr*u_nbr);
id_e12_u_u_xf = id_e11_u_xf_u(end) + (1:u_nbr*u_nbr*x_nbr);
id_e13_u_u_u = id_e12_u_u_xf(end) + (1:u_nbr*u_nbr*u_nbr);
ghxxx = dr.ghxxx; if compute_derivs; dghxxx = dr.derivs.dghxxx; end
ghxxu = dr.ghxxu; if compute_derivs; dghxxu = dr.derivs.dghxxu; end
ghxuu = dr.ghxuu; if compute_derivs; dghxuu = dr.derivs.dghxuu; end
ghuuu = dr.ghuuu; if compute_derivs; dghuuu = dr.derivs.dghuuu; end
ghxss = dr.ghxss; if compute_derivs; dghxss = dr.derivs.dghxss; end
ghuss = dr.ghuss; if compute_derivs; dghuss = dr.derivs.dghuss; end
end
%% First-order
z_nbr = x_nbr;
e_nbr = M.exo_nbr;
A = ghx(indx,:);
B = ghu(indx,:);
C = ghx(indy,:);
D = ghu(indy,:);
c = zeros(x_nbr,1);
d = zeros(y_nbr,1);
Varinov = E_uu;
E_z = zeros(x_nbr,1); %this is E_xf
if compute_derivs == 1
dA = dghx(indx,:,:);
dB = dghu(indx,:,:);
dC = dghx(indy,:,:);
dD = dghu(indy,:,:);
dc = zeros(x_nbr,totparam_nbr);
dd = zeros(y_nbr,totparam_nbr);
dVarinov = dE_uu;
dE_z = zeros(x_nbr,totparam_nbr);
end
if order > 1
% Some common and useful objects for order > 1
% Compute E[xf*xf']
E_xfxf = lyapunov_symm(ghx(indx,:), Om(indx,indx), options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold, 1, options.debug); %use 1 to initialize persistent variables
K_ux = commutation(u_nbr,x_nbr); %commutation matrix
K_xu = commutation(x_nbr,u_nbr); %commutation matrix
QPu = quadruplication(u_nbr); %quadruplication matrix as in Meijer (2005), similar to Magnus-Neudecker definition of duplication matrix (i.e. dyn_vec) but for fourth-order product moments
%Compute unique product moments of E[kron(u*u',uu')] = E[kron(u,u)*kron(u,u)']
COMBOS4 = flipud(allVL1(u_nbr, 4)); %all possible combinations of powers that sum up to four for fourth-order product moments of u
E_u_u_u_u = zeros(u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4,1); %only unique entries of E[kron(u,kron(u,kron(u,u)))]
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
dE_u_u_u_u = zeros(u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4,stderrparam_nbr+corrparam_nbr);
end
for j = 1:size(COMBOS4,1)
E_u_u_u_u(j) = prodmom(E_uu, 1:u_nbr, COMBOS4(j,:));
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
dE_u_u_u_u(j,1:(stderrparam_nbr+corrparam_nbr)) = prodmom_deriv(E_uu, 1:u_nbr, COMBOS4(j,:), dE_uu(:,:,1:(stderrparam_nbr+corrparam_nbr)), dCorrelation_matrix(:,:,1:(stderrparam_nbr+corrparam_nbr)));
end
end
E_u_u_u_u = QPu*E_u_u_u_u; %add duplicate product moments, i.e. this is E[kron(u,kron(u,kron(u,u)))]
E_uu_uu = reshape(E_u_u_u_u,u_nbr^2,u_nbr^2); %E[kron(u*u',uu')] = E[kron(u,u)*kron(u,u)']
% E[kron((xf*xf'),(u*u'))]
E_xfxf_E_uu = kron(E_xfxf,E_uu);
if compute_derivs
dE_xfxf = zeros(size(E_xfxf,1),size(E_xfxf,2),totparam_nbr);
dE_xfxf_E_uu = zeros(size(E_xfxf_E_uu,1),size(E_xfxf_E_uu,2),totparam_nbr);
for jp = 1:totparam_nbr
if jp <= (stderrparam_nbr+corrparam_nbr)
%Jacobian of E_xfxf wrt exogenous paramters: dE_xfxf(:,:,jp)-hx*dE_xfxf(:,:,jp)*hx'=dOm(:,:,jp), because dhx is zero by construction for stderr and corr parameters
dE_xfxf(:,:,jp) = lyapunov_symm(ghx(indx,:), dOm(indx,indx,jp),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug);
else
%Jacobian of E_xfxf wrt model parameters: dE_xfxf(:,:,jp) - hx*dE_xfxf(:,:,jp)*hx' = d(hu*Sig_u*hu')(:,:,jp) + dhx(:,:,jp)*E_xfxf*hx'+ hx*E_xfxf*dhx(:,:,jp)'
dE_xfxf(:,:,jp) = lyapunov_symm(ghx(indx,:), dghx(indx,:,jp)*E_xfxf*ghx(indx,:)'+ghx(indx,:)*E_xfxf*dghx(indx,:,jp)'+dOm(indx,indx,jp),options.lyapunov_fixed_point_tol,options.qz_criterium,options.lyapunov_complex_threshold,2,options.debug);
%here method=2 is used to spare a lot of computing time while not repeating Schur every time
end
dE_xfxf_E_uu(:,:,jp) = kron(dE_xfxf(:,:,jp),E_uu) + kron(E_xfxf,dE_uu(:,:,jp));
end
end
% Second-order pruned state space system
z_nbr = x_nbr+x_nbr+x_nbr*x_nbr;
e_nbr = u_nbr+u_nbr*u_nbr+x_nbr*u_nbr+u_nbr*x_nbr;
A = zeros(z_nbr, z_nbr);
A(id_z1_xf , id_z1_xf ) = ghx(indx,:);
A(id_z2_xs , id_z2_xs ) = ghx(indx,:);
A(id_z2_xs , id_z3_xf_xf) = 0.5*ghxx(indx,:);
A(id_z3_xf_xf , id_z3_xf_xf) = kron(ghx(indx,:),ghx(indx,:));
B = zeros(z_nbr, e_nbr);
B(id_z1_xf , id_e1_u ) = ghu(indx,:);
B(id_z2_xs , id_e2_u_u ) = 0.5*ghuu(indx,:);
B(id_z2_xs , id_e3_xf_u) = ghxu(indx,:);
B(id_z3_xf_xf , id_e2_u_u ) = kron(ghu(indx,:),ghu(indx,:));
B(id_z3_xf_xf , id_e3_xf_u) = kron(ghx(indx,:),ghu(indx,:));
B(id_z3_xf_xf , id_e4_u_xf) = kron(ghu(indx,:),ghx(indx,:));
C = zeros(y_nbr, z_nbr);
C(1:y_nbr , id_z1_xf ) = ghx(indy,:);
C(1:y_nbr , id_z2_xs ) = ghx(indy,:);
C(1:y_nbr , id_z3_xf_xf) = 0.5*ghxx(indy,:);
D = zeros(y_nbr, e_nbr);
D(1:y_nbr , id_e1_u ) = ghu(indy,:);
D(1:y_nbr , id_e2_u_u ) = 0.5*ghuu(indy,:);
D(1:y_nbr , id_e3_xf_u) = ghxu(indy,:);
c = zeros(z_nbr, 1);
c(id_z2_xs , 1) = 0.5*ghs2(indx,:) + 0.5*ghuu(indx,:)*E_uu(:);
c(id_z3_xf_xf , 1) = kron(ghu(indx,:),ghu(indx,:))*E_uu(:);
d = zeros(y_nbr, 1);
d(1:y_nbr, 1) = 0.5*ghs2(indy,:) + 0.5*ghuu(indy,:)*E_uu(:);
Varinov = zeros(e_nbr,e_nbr);
Varinov(id_e1_u , id_e1_u) = E_uu;
Varinov(id_e2_u_u , id_e2_u_u) = E_uu_uu-E_uu(:)*transpose(E_uu(:));
Varinov(id_e3_xf_u , id_e3_xf_u) = E_xfxf_E_uu;
Varinov(id_e4_u_xf , id_e3_xf_u) = K_ux*E_xfxf_E_uu;
Varinov(id_e3_xf_u , id_e4_u_xf) = transpose(Varinov(id_e4_u_xf,id_e3_xf_u));
Varinov(id_e4_u_xf , id_e4_u_xf) = K_ux*E_xfxf_E_uu*transpose(K_ux);
I_hx = speye(x_nbr)-ghx(indx,:);
I_hxinv = I_hx\speye(x_nbr);
E_xs = I_hxinv*(0.5*ghxx(indx,:)*E_xfxf(:) + c(x_nbr+(1:x_nbr),1));
E_z = [zeros(x_nbr,1); E_xs; E_xfxf(:)];
if compute_derivs
dA = zeros(size(A,1),size(A,2),totparam_nbr);
dB = zeros(size(B,1),size(B,2),totparam_nbr);
dC = zeros(size(C,1),size(C,2),totparam_nbr);
dD = zeros(size(D,1),size(D,2),totparam_nbr);
dc = zeros(size(c,1),totparam_nbr);
dd = zeros(size(d,1),totparam_nbr);
dVarinov = zeros(size(Varinov,1),size(Varinov,2),totparam_nbr);
dE_xs = zeros(size(E_xs,1),size(E_xs,2),totparam_nbr);
dE_z = zeros(size(E_z,1),size(E_z,2),totparam_nbr);
for jp = 1:totparam_nbr
dA(id_z1_xf , id_z1_xf , jp) = dghx(indx,:,jp);
dA(id_z2_xs , id_z2_xs , jp) = dghx(indx,:,jp);
dA(id_z2_xs , id_z3_xf_xf , jp) = 0.5*dghxx(indx,:,jp);
dA(id_z3_xf_xf , id_z3_xf_xf , jp) = kron(dghx(indx,:,jp),ghx(indx,:)) + kron(ghx(indx,:),dghx(indx,:,jp));
dB(id_z1_xf , id_e1_u , jp) = dghu(indx,:,jp);
dB(id_z2_xs , id_e2_u_u , jp) = 0.5*dghuu(indx,:,jp);
dB(id_z2_xs , id_e3_xf_u , jp) = dghxu(indx,:,jp);
dB(id_z3_xf_xf , id_e2_u_u , jp) = kron(dghu(indx,:,jp),ghu(indx,:)) + kron(ghu(indx,:),dghu(indx,:,jp));
dB(id_z3_xf_xf , id_e3_xf_u , jp) = kron(dghx(indx,:,jp),ghu(indx,:)) + kron(ghx(indx,:),dghu(indx,:,jp));
dB(id_z3_xf_xf , id_e4_u_xf , jp) = kron(dghu(indx,:,jp),ghx(indx,:)) + kron(ghu(indx,:),dghx(indx,:,jp));
dC(1:y_nbr , id_z1_xf , jp) = dghx(indy,:,jp);
dC(1:y_nbr , id_z2_xs , jp) = dghx(indy,:,jp);
dC(1:y_nbr , id_z3_xf_xf , jp) = 0.5*dghxx(indy,:,jp);
dD(1:y_nbr , id_e1_u , jp) = dghu(indy,:,jp);
dD(1:y_nbr , id_e2_u_u , jp) = 0.5*dghuu(indy,:,jp);
dD(1:y_nbr , id_e3_xf_u , jp) = dghxu(indy,:,jp);
dc(id_z2_xs , jp) = 0.5*dghs2(indx,jp) + 0.5*(dghuu(indx,:,jp)*E_uu(:) + ghuu(indx,:)*vec(dE_uu(:,:,jp)));
dc(id_z3_xf_xf , jp) = (kron(dghu(indx,:,jp),ghu(indx,:)) + kron(ghu(indx,:),dghu(indx,:,jp)))*E_uu(:) + kron(ghu(indx,:),ghu(indx,:))*vec(dE_uu(:,:,jp));
dd(1:y_nbr , jp) = 0.5*dghs2(indy,jp) + 0.5*(dghuu(indy,:,jp)*E_uu(:) + ghuu(indy,:)*vec(dE_uu(:,:,jp)));
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e1_u , id_e1_u , jp) = dE_uu(:,:,jp);
dVarinov(id_e2_u_u , id_e2_u_u , jp) = reshape(QPu*dE_u_u_u_u(:,jp), u_nbr^2, u_nbr^2) - (reshape(dE_uu(:,:,jp),u_nbr^2,1)*transpose(E_uu(:)) + E_uu(:)*transpose(reshape(dE_uu(:,:,jp),u_nbr^2,1)));
end
dVarinov(id_e3_xf_u , id_e3_xf_u , jp) = dE_xfxf_E_uu(:,:,jp);
dVarinov(id_e4_u_xf , id_e3_xf_u , jp) = K_ux*dE_xfxf_E_uu(:,:,jp);
dVarinov(id_e3_xf_u , id_e4_u_xf , jp) = transpose(dVarinov(id_e4_u_xf,id_e3_xf_u,jp));
dVarinov(id_e4_u_xf , id_e4_u_xf , jp) = dVarinov(id_e4_u_xf , id_e3_xf_u , jp)*transpose(K_ux);
dE_xs(:,jp) = I_hxinv*( dghx(indx,:,jp)*E_xs + 1/2*(dghxx(indx,:,jp)*E_xfxf(:) + ghxx(indx,:)*vec(dE_xfxf(:,:,jp)) + dc(x_nbr+(1:x_nbr),jp)) );
dE_z(:,jp) = [zeros(x_nbr,1); dE_xs(:,jp); vec(dE_xfxf(:,:,jp))];
end
end
if order > 2
Q6Pu = Q6_plication(u_nbr); %quadruplication matrix as in Meijer (2005), similar to Magnus-Neudecker definition of duplication matrix (i.e. dyn_vec) but for fourth-order product moments
%Compute unique product moments of E[kron(u*u',uu')] = E[kron(u,u)*kron(u,u)']
COMBOS6 = flipud(allVL1(u_nbr, 6)); %all possible combinations of powers that sum up to four for fourth-order product moments of u
E_u_u_u_u_u_u = zeros(u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4*(u_nbr+4)/5*(u_nbr+5)/6,1); %only unique entries of E[kron(u,kron(u,kron(u,kron(u,kron(u,u)))))]
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
dE_u_u_u_u_u_u = zeros(size(E_u_u_u_u_u_u,1),stderrparam_nbr+corrparam_nbr);
end
for j = 1:size(COMBOS6,1)
E_u_u_u_u_u_u(j) = prodmom(E_uu, 1:u_nbr, COMBOS6(j,:));
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
dE_u_u_u_u_u_u(j,1:(stderrparam_nbr+corrparam_nbr)) = prodmom_deriv(E_uu, 1:u_nbr, COMBOS6(j,:), dE_uu(:,:,1:(stderrparam_nbr+corrparam_nbr)), dCorrelation_matrix(:,:,1:(stderrparam_nbr+corrparam_nbr)));
end
end
Var_z = lyapunov_symm(A, B*Varinov*transpose(B), options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold, 1, options.debug);
%E_xfxf = Var_z(id_z1_xf,id_z1_xf); %this is E_xfxf, as E_xf=0, we already have that
E_xfxs = Var_z(id_z1_xf,id_z2_xs); %as E_xf=0
E_xf_xf_xf = vec(Var_z(id_z1_xf,id_z3_xf_xf)); %as E_xf=0, this is vec(E[xf*kron(xf,xf)'])
E_xsxf = Var_z(id_z2_xs,id_z1_xf); %as E_xf=0
E_xsxs = Var_z(id_z2_xs,id_z2_xs) + E_xs*transpose(E_xs);
E_xs_xf_xf = vec(Var_z(id_z2_xs,id_z3_xf_xf)+E_xs*E_xfxf(:)'); %this is vec(E[xs*kron(xf,xf)'])
%E_xf_xf_xf = vec(Var_z(id_z3_xf_xf,id_z1_xf));
E_xf_xf_xs = vec(Var_z(id_z3_xf_xf,id_z2_xs) + E_xfxf(:)*E_xs');
E_xf_xf_xf_xf = vec(Var_z(id_z3_xf_xf,id_z3_xf_xf) + E_xfxf(:)*E_xfxf(:)');
%E_xs_E_uu = kron(E_xs,E_uu);
E_xfxs_E_uu = kron(E_xfxs,E_uu);
z_nbr = x_nbr+x_nbr+x_nbr^2+x_nbr+x_nbr*x_nbr+x_nbr^3;
e_nbr = u_nbr+u_nbr^2+x_nbr*u_nbr+u_nbr*x_nbr+x_nbr*u_nbr+u_nbr*x_nbr+x_nbr*x_nbr*u_nbr+x_nbr*u_nbr*x_nbr+u_nbr*x_nbr*x_nbr+u_nbr*u_nbr*x_nbr+u_nbr*x_nbr*u_nbr+x_nbr*u_nbr*u_nbr+u_nbr*u_nbr*u_nbr;
hx_hx = kron(ghx(indx,:),ghx(indx,:));
hu_hu = kron(ghu(indx,:),ghu(indx,:));
hx_hu = kron(ghx(indx,:),ghu(indx,:));
hu_hx = kron(ghu(indx,:),ghx(indx,:));
if compute_derivs
dVar_z = zeros(size(Var_z,1),size(Var_z,2),totparam_nbr);
dE_xfxs = zeros(size(E_xfxs,1),size(E_xfxs,2),totparam_nbr);
dE_xf_xf_xf = zeros(size(E_xf_xf_xf,1),totparam_nbr);
dE_xsxf = zeros(size(E_xsxf,1),size(E_xsxf,2),totparam_nbr);
dE_xsxs = zeros(size(E_xsxs,1),size(E_xsxs,2),totparam_nbr);
dE_xs_xf_xf = zeros(size(E_xs_xf_xf,1),totparam_nbr);
dE_xf_xf_xs = zeros(size(E_xf_xf_xs,1),totparam_nbr);
dE_xf_xf_xf_xf = zeros(size(E_xf_xf_xf_xf,1),totparam_nbr);
dE_xfxs_E_uu = zeros(size(E_xfxs_E_uu,1),size(E_xfxs_E_uu,2),totparam_nbr);
dhx_hx = zeros(size(hx_hx,1),size(hx_hx,2),totparam_nbr);
dhu_hu = zeros(size(hu_hu,1),size(hu_hu,2),totparam_nbr);
dhx_hu = zeros(size(hx_hu,1),size(hx_hu,2),totparam_nbr);
dhu_hx = zeros(size(hu_hx,1),size(hu_hx,2),totparam_nbr);
for jp=1:totparam_nbr
dVar_z(:,:,jp) = lyapunov_symm(A, dB(:,:,jp)*Varinov*transpose(B) + B*dVarinov(:,:,jp)*transpose(B) +B*Varinov*transpose(dB(:,:,jp)) + dA(:,:,jp)*Var_z*A' + A*Var_z*transpose(dA(:,:,jp)),... ,...
options.lyapunov_fixed_point_tol, options.qz_criterium, options.lyapunov_complex_threshold, 2, options.debug); %2 is used as we use 1 above
dE_xfxs(:,:,jp) = dVar_z(id_z1_xf,id_z2_xs,jp);
dE_xf_xf_xf(:,jp) = vec(dVar_z(id_z1_xf,id_z3_xf_xf,jp));
dE_xsxf(:,:,jp) = dVar_z(id_z2_xs,id_z1_xf,jp);
dE_xsxs(:,:,jp) = dVar_z(id_z2_xs,id_z2_xs,jp) + dE_xs(:,jp)*transpose(E_xs) + E_xs*transpose(dE_xs(:,jp));
dE_xs_xf_xf(:,jp) = vec(dVar_z(id_z2_xs,id_z3_xf_xf,jp) + dE_xs(:,jp)*E_xfxf(:)' + E_xs*vec(dE_xfxf(:,:,jp))');
dE_xf_xf_xs(:,jp) = vec(dVar_z(id_z3_xf_xf,id_z2_xs,jp) + vec(dE_xfxf(:,:,jp))*E_xs' + E_xfxf(:)*dE_xs(:,jp)');
dE_xf_xf_xf_xf(:,jp) = vec(dVar_z(id_z3_xf_xf,id_z3_xf_xf,jp) + vec(dE_xfxf(:,:,jp))*E_xfxf(:)' + E_xfxf(:)*vec(dE_xfxf(:,:,jp))');
dE_xfxs_E_uu(:,:,jp) = kron(dE_xfxs(:,:,jp),E_uu) + kron(E_xfxs,dE_uu(:,:,jp));
dhx_hx(:,:,jp) = kron(dghx(indx,:,jp),ghx(indx,:)) + kron(ghx(indx,:),dghx(indx,:,jp));
dhu_hu(:,:,jp) = kron(dghu(indx,:,jp),ghu(indx,:)) + kron(ghu(indx,:),dghu(indx,:,jp));
dhx_hu(:,:,jp) = kron(dghx(indx,:,jp),ghu(indx,:)) + kron(ghx(indx,:),dghu(indx,:,jp));
dhu_hx(:,:,jp) = kron(dghu(indx,:,jp),ghx(indx,:)) + kron(ghu(indx,:),dghx(indx,:,jp));
end
end
A = zeros(z_nbr,z_nbr);
A(id_z1_xf , id_z1_xf ) = ghx(indx,:);
A(id_z2_xs , id_z2_xs ) = ghx(indx,:);
A(id_z2_xs , id_z3_xf_xf ) = 1/2*ghxx(indx,:);
A(id_z3_xf_xf , id_z3_xf_xf ) = hx_hx;
A(id_z4_xrd , id_z1_xf ) = 3/6*ghxss(indx,:);
A(id_z4_xrd , id_z4_xrd ) = ghx(indx,:);
A(id_z4_xrd , id_z5_xf_xs ) = ghxx(indx,:);
A(id_z4_xrd , id_z6_xf_xf_xf) = 1/6*ghxxx(indx,:);
A(id_z5_xf_xs , id_z1_xf ) = kron(ghx(indx,:),1/2*ghs2(indx,:));
A(id_z5_xf_xs , id_z5_xf_xs ) = hx_hx;
A(id_z5_xf_xs , id_z6_xf_xf_xf) = kron(ghx(indx,:),1/2*ghxx(indx,:));
A(id_z6_xf_xf_xf , id_z6_xf_xf_xf) = kron(ghx(indx,:),hx_hx);
B = zeros(z_nbr,e_nbr);
B(id_z1_xf , id_e1_u ) = ghu(indx,:);
B(id_z2_xs , id_e2_u_u ) = 1/2*ghuu(indx,:);
B(id_z2_xs , id_e3_xf_u ) = ghxu(indx,:);
B(id_z3_xf_xf , id_e2_u_u ) = hu_hu;
B(id_z3_xf_xf , id_e3_xf_u ) = hx_hu;
B(id_z3_xf_xf , id_e4_u_xf ) = hu_hx;
B(id_z4_xrd , id_e1_u ) = 3/6*ghuss(indx,:);
B(id_z4_xrd , id_e5_xs_u ) = ghxu(indx,:);
B(id_z4_xrd , id_e7_xf_xf_u) = 3/6*ghxxu(indx,:);
B(id_z4_xrd , id_e10_xf_u_u) = 3/6*ghxuu(indx,:);
B(id_z4_xrd , id_e13_u_u_u ) = 1/6*ghuuu(indx,:);
B(id_z5_xf_xs , id_e1_u ) = kron(ghu(indx,:),1/2*ghs2(indx,:));
B(id_z5_xf_xs , id_e6_u_xs ) = hu_hx;
B(id_z5_xf_xs , id_e7_xf_xf_u) = kron(ghx(indx,:),ghxu(indx,:));
B(id_z5_xf_xs , id_e9_u_xf_xf) = kron(ghu(indx,:),1/2*ghxx(indx,:));
B(id_z5_xf_xs , id_e10_xf_u_u) = kron(ghx(indx,:),1/2*ghuu(indx,:));
B(id_z5_xf_xs , id_e11_u_xf_u) = kron(ghu(indx,:),ghxu(indx,:));
B(id_z5_xf_xs , id_e13_u_u_u ) = kron(ghu(indx,:),1/2*ghuu(indx,:));
B(id_z6_xf_xf_xf , id_e7_xf_xf_u) = kron(hx_hx,ghu(indx,:));
B(id_z6_xf_xf_xf , id_e8_xf_u_xf) = kron(ghx(indx,:),hu_hx);
B(id_z6_xf_xf_xf , id_e9_u_xf_xf) = kron(ghu(indx,:),hx_hx);
B(id_z6_xf_xf_xf , id_e10_xf_u_u) = kron(hx_hu,ghu(indx,:));
B(id_z6_xf_xf_xf , id_e11_u_xf_u) = kron(ghu(indx,:),hx_hu);
B(id_z6_xf_xf_xf , id_e12_u_u_xf) = kron(hu_hu,ghx(indx,:));
B(id_z6_xf_xf_xf , id_e13_u_u_u ) = kron(ghu(indx,:),hu_hu);
C = zeros(y_nbr,z_nbr);
C(1:y_nbr , id_z1_xf ) = ghx(indy,:) + 1/2*ghxss(indy,:);
C(1:y_nbr , id_z2_xs ) = ghx(indy,:);
C(1:y_nbr , id_z3_xf_xf ) = 1/2*ghxx(indy,:);
C(1:y_nbr , id_z4_xrd ) = ghx(indy,:);
C(1:y_nbr , id_z5_xf_xs ) = ghxx(indy,:);
C(1:y_nbr , id_z6_xf_xf_xf) = 1/6*ghxxx(indy,:);
D = zeros(y_nbr,e_nbr);
D(1:y_nbr , id_e1_u ) = ghu(indy,:) + 1/2*ghuss(indy,:);
D(1:y_nbr , id_e2_u_u ) = 1/2*ghuu(indy,:);
D(1:y_nbr , id_e3_xf_u ) = ghxu(indy,:);
D(1:y_nbr , id_e5_xs_u ) = ghxu(indy,:);
D(1:y_nbr , id_e7_xf_xf_u) = 1/2*ghxxu(indy,:);
D(1:y_nbr , id_e10_xf_u_u) = 1/2*ghxuu(indy,:);
D(1:y_nbr , id_e13_u_u_u ) = 1/6*ghuuu(indy,:);
c = zeros(z_nbr,1);
c(id_z2_xs , 1) = 1/2*ghs2(indx,:) + 1/2*ghuu(indx,:)*E_uu(:);
c(id_z3_xf_xf , 1) = hu_hu*E_uu(:);
d = zeros(y_nbr,1);
d(1:y_nbr , 1) = 0.5*ghs2(indy,:) + 0.5*ghuu(indy,:)*E_uu(:);
Varinov = zeros(e_nbr,e_nbr);
Varinov(id_e1_u , id_e1_u ) = E_uu;
Varinov(id_e1_u , id_e5_xs_u ) = kron(E_xs',E_uu);
Varinov(id_e1_u , id_e6_u_xs ) = kron(E_uu,E_xs');
Varinov(id_e1_u , id_e7_xf_xf_u) = kron(E_xfxf(:)',E_uu);
Varinov(id_e1_u , id_e8_xf_u_xf) = kron(E_uu,E_xfxf(:)')*kron(K_xu,speye(x_nbr));
Varinov(id_e1_u , id_e9_u_xf_xf) = kron(E_uu,E_xfxf(:)');
Varinov(id_e1_u , id_e13_u_u_u ) = reshape(E_u_u_u_u,u_nbr,u_nbr^3);
Varinov(id_e2_u_u , id_e2_u_u ) = E_uu_uu-E_uu(:)*transpose(E_uu(:));
Varinov(id_e3_xf_u , id_e3_xf_u ) = E_xfxf_E_uu;
Varinov(id_e3_xf_u , id_e4_u_xf ) = E_xfxf_E_uu*K_ux';
Varinov(id_e3_xf_u , id_e5_xs_u ) = E_xfxs_E_uu;
Varinov(id_e3_xf_u , id_e6_u_xs ) = E_xfxs_E_uu*K_ux';
Varinov(id_e3_xf_u , id_e7_xf_xf_u) = kron(reshape(E_xf_xf_xf,x_nbr,x_nbr^2), E_uu);
Varinov(id_e3_xf_u , id_e8_xf_u_xf) = kron(reshape(E_xf_xf_xf,x_nbr,x_nbr^2), E_uu)*kron(speye(x_nbr),K_ux)';
Varinov(id_e3_xf_u , id_e9_u_xf_xf) = K_xu*kron(E_uu, reshape(E_xf_xf_xf, x_nbr, x_nbr^2));
Varinov(id_e4_u_xf , id_e3_xf_u ) = K_ux*E_xfxf_E_uu;
Varinov(id_e4_u_xf , id_e4_u_xf ) = kron(E_uu,E_xfxf);
Varinov(id_e4_u_xf , id_e5_xs_u ) = K_ux*kron(E_xfxs,E_uu);
Varinov(id_e4_u_xf , id_e6_u_xs ) = kron(E_uu, E_xfxs);
Varinov(id_e4_u_xf , id_e7_xf_xf_u) = K_ux*kron(reshape(E_xf_xf_xf,x_nbr,x_nbr^2),E_uu);
Varinov(id_e4_u_xf , id_e8_xf_u_xf) = kron(E_uu,reshape(E_xf_xf_xf,x_nbr,x_nbr^2))*kron(K_xu,speye(x_nbr))';
Varinov(id_e4_u_xf , id_e9_u_xf_xf) = kron(E_uu,reshape(E_xf_xf_xf,x_nbr,x_nbr^2));
Varinov(id_e5_xs_u , id_e1_u ) = kron(E_xs, E_uu);
Varinov(id_e5_xs_u , id_e3_xf_u ) = kron(E_xsxf, E_uu);
Varinov(id_e5_xs_u , id_e4_u_xf ) = kron(E_xsxf, E_uu)*K_ux';
Varinov(id_e5_xs_u , id_e5_xs_u ) = kron(E_xsxs, E_uu);
Varinov(id_e5_xs_u , id_e6_u_xs ) = kron(E_xsxs, E_uu)*K_ux';
Varinov(id_e5_xs_u , id_e7_xf_xf_u) = kron(reshape(E_xs_xf_xf,x_nbr,x_nbr^2),E_uu);
Varinov(id_e5_xs_u , id_e8_xf_u_xf) = kron(reshape(E_xs_xf_xf,x_nbr,x_nbr^2),E_uu)*kron(speye(x_nbr),K_ux)';
Varinov(id_e5_xs_u , id_e9_u_xf_xf) = K_xu*kron(E_uu,reshape(E_xs_xf_xf,x_nbr,x_nbr^2));
Varinov(id_e5_xs_u , id_e13_u_u_u ) = kron(E_xs,reshape(E_u_u_u_u,u_nbr,u_nbr^3));
Varinov(id_e6_u_xs , id_e1_u ) = kron(E_uu,E_xs);
Varinov(id_e6_u_xs , id_e3_xf_u ) = K_ux*kron(E_xsxf, E_uu);
Varinov(id_e6_u_xs , id_e4_u_xf ) = kron(E_uu, E_xsxf);
Varinov(id_e6_u_xs , id_e5_xs_u ) = K_ux*kron(E_xsxs,E_uu);
Varinov(id_e6_u_xs , id_e6_u_xs ) = kron(E_uu, E_xsxs);
Varinov(id_e6_u_xs , id_e7_xf_xf_u) = K_ux*kron(reshape(E_xs_xf_xf,x_nbr,x_nbr^2), E_uu);
Varinov(id_e6_u_xs , id_e8_xf_u_xf) = kron(E_uu, reshape(E_xs_xf_xf,x_nbr,x_nbr^2))*kron(K_xu,speye(x_nbr))';
Varinov(id_e6_u_xs , id_e9_u_xf_xf) = kron(E_uu, reshape(E_xs_xf_xf,x_nbr,x_nbr^2));
Varinov(id_e6_u_xs , id_e13_u_u_u ) = K_ux*kron(E_xs,reshape(E_u_u_u_u,u_nbr,u_nbr^3));
Varinov(id_e7_xf_xf_u , id_e1_u ) = kron(E_xfxf(:),E_uu);
Varinov(id_e7_xf_xf_u , id_e3_xf_u ) = kron(reshape(E_xf_xf_xf,x_nbr^2,x_nbr),E_uu);
Varinov(id_e7_xf_xf_u , id_e4_u_xf ) = kron(reshape(E_xf_xf_xf,x_nbr^2,x_nbr),E_uu)*K_ux';
Varinov(id_e7_xf_xf_u , id_e5_xs_u ) = kron(reshape(E_xf_xf_xs,x_nbr^2,x_nbr),E_uu);
Varinov(id_e7_xf_xf_u , id_e6_u_xs ) = kron(reshape(E_xf_xf_xs,x_nbr^2,x_nbr),E_uu)*K_ux';
Varinov(id_e7_xf_xf_u , id_e7_xf_xf_u) = kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),E_uu);
Varinov(id_e7_xf_xf_u , id_e8_xf_u_xf) = kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),E_uu)*kron(speye(x_nbr),K_ux)';
Varinov(id_e7_xf_xf_u , id_e9_u_xf_xf) = kron(speye(x_nbr),K_ux)*kron(K_ux,speye(x_nbr))*kron(E_uu, reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2));
Varinov(id_e7_xf_xf_u , id_e13_u_u_u ) = kron(E_xfxf(:),reshape(E_u_u_u_u,u_nbr,u_nbr^3));
Varinov(id_e8_xf_u_xf , id_e1_u ) = kron(K_xu,speye(x_nbr))*kron(E_uu,E_xfxf(:));
Varinov(id_e8_xf_u_xf , id_e3_xf_u ) = kron(speye(x_nbr),K_xu)*kron(reshape(E_xf_xf_xf,x_nbr^2,x_nbr),E_uu);
Varinov(id_e8_xf_u_xf , id_e4_u_xf ) = kron(K_xu,speye(x_nbr))*kron(E_uu,reshape(E_xf_xf_xf,x_nbr^2,x_nbr));
Varinov(id_e8_xf_u_xf , id_e5_xs_u ) = kron(speye(x_nbr),K_ux)*kron(reshape(E_xf_xf_xs,x_nbr^2,x_nbr),E_uu);
Varinov(id_e8_xf_u_xf , id_e6_u_xs ) = kron(K_xu,speye(x_nbr))*kron(E_uu,reshape(E_xf_xf_xs,x_nbr^2,x_nbr));
Varinov(id_e8_xf_u_xf , id_e7_xf_xf_u) = kron(speye(x_nbr),K_ux)*kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),E_uu);
Varinov(id_e8_xf_u_xf , id_e8_xf_u_xf) = kron(K_xu,speye(x_nbr))*kron(E_uu,reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2))*kron(K_xu,speye(x_nbr))';
Varinov(id_e8_xf_u_xf , id_e9_u_xf_xf) = kron(K_xu,speye(x_nbr))*kron(E_uu,reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2));
Varinov(id_e8_xf_u_xf , id_e13_u_u_u ) = kron(K_xu,speye(x_nbr))*kron(reshape(E_u_u_u_u,u_nbr,u_nbr^3),E_xfxf(:));
Varinov(id_e9_u_xf_xf , id_e1_u ) = kron(E_uu, E_xfxf(:));
Varinov(id_e9_u_xf_xf , id_e3_xf_u ) = kron(E_uu, reshape(E_xf_xf_xf,x_nbr^2,x_nbr))*K_xu';
Varinov(id_e9_u_xf_xf , id_e4_u_xf ) = kron(E_uu, reshape(E_xf_xf_xf,x_nbr^2,x_nbr));
Varinov(id_e9_u_xf_xf , id_e5_xs_u ) = kron(E_uu, reshape(E_xf_xf_xs,x_nbr^2,x_nbr))*K_xu';
Varinov(id_e9_u_xf_xf , id_e6_u_xs ) = kron(E_uu, reshape(E_xf_xf_xs,x_nbr^2,x_nbr));
Varinov(id_e9_u_xf_xf , id_e7_xf_xf_u) = kron(speye(x_nbr),K_ux)*kron(K_ux,speye(x_nbr))*kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),E_uu);
Varinov(id_e9_u_xf_xf , id_e8_xf_u_xf) = kron(E_uu,reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2))*kron(speye(x_nbr),K_ux)';
Varinov(id_e9_u_xf_xf , id_e9_u_xf_xf) = kron(E_uu,reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2));
Varinov(id_e9_u_xf_xf , id_e13_u_u_u ) = kron(reshape(E_u_u_u_u,u_nbr,u_nbr^3),E_xfxf(:));
Varinov(id_e10_xf_u_u , id_e10_xf_u_u) = kron(E_xfxf,reshape(E_u_u_u_u,u_nbr^2,u_nbr^2));
Varinov(id_e10_xf_u_u , id_e11_u_xf_u) = kron(E_xfxf,reshape(E_u_u_u_u,u_nbr^2,u_nbr^2))*kron(K_ux,speye(u_nbr))';
Varinov(id_e10_xf_u_u , id_e12_u_u_xf) = kron(E_xfxf,reshape(E_u_u_u_u,u_nbr^2,u_nbr^2))*kron(K_ux,speye(u_nbr))'*kron(speye(u_nbr),K_ux)';
Varinov(id_e11_u_xf_u , id_e10_xf_u_u) = kron(K_ux,speye(u_nbr))*kron(E_xfxf,reshape(E_u_u_u_u,u_nbr^2,u_nbr^2));
Varinov(id_e11_u_xf_u , id_e11_u_xf_u) = kron(K_ux,speye(u_nbr))*kron(E_xfxf,reshape(E_u_u_u_u,u_nbr^2,u_nbr^2))*kron(K_ux,speye(u_nbr))';
Varinov(id_e11_u_xf_u , id_e12_u_u_xf) = kron(speye(u_nbr),K_ux)*kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),E_xfxf);
Varinov(id_e12_u_u_xf , id_e10_xf_u_u) = kron(K_ux,speye(u_nbr))*kron(speye(u_nbr),K_ux)*kron(E_xfxf,reshape(E_u_u_u_u,u_nbr^2,u_nbr^2));
Varinov(id_e12_u_u_xf , id_e11_u_xf_u) = kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),E_xfxf)*kron(speye(u_nbr),K_xu)';
Varinov(id_e12_u_u_xf , id_e12_u_u_xf) = kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),E_xfxf);
Varinov(id_e13_u_u_u , id_e1_u ) = reshape(E_u_u_u_u,u_nbr^3,u_nbr);
Varinov(id_e13_u_u_u , id_e5_xs_u ) = kron(E_xs', reshape(E_u_u_u_u,u_nbr^3,u_nbr));
Varinov(id_e13_u_u_u , id_e6_u_xs ) = kron(reshape(E_u_u_u_u,u_nbr^3,u_nbr),E_xs');
Varinov(id_e13_u_u_u , id_e7_xf_xf_u ) = kron(E_xfxf(:)',reshape(E_u_u_u_u,u_nbr^3,u_nbr));
Varinov(id_e13_u_u_u , id_e8_xf_u_xf ) = kron(E_xfxf(:)',reshape(E_u_u_u_u,u_nbr^3,u_nbr))*kron(speye(x_nbr),K_ux)';
Varinov(id_e13_u_u_u , id_e9_u_xf_xf ) = kron(reshape(E_u_u_u_u,u_nbr^3,u_nbr), E_xfxf(:)');
Varinov(id_e13_u_u_u , id_e13_u_u_u ) = reshape(Q6Pu*E_u_u_u_u_u_u,u_nbr^3,u_nbr^3);
E_z = (speye(z_nbr)-A)\c;
if compute_derivs
dA = zeros(z_nbr,z_nbr,totparam_nbr);
dB = zeros(z_nbr,e_nbr,totparam_nbr);
dC = zeros(y_nbr,z_nbr,totparam_nbr);
dD = zeros(y_nbr,e_nbr,totparam_nbr);
dc = zeros(z_nbr,totparam_nbr);
dd = zeros(y_nbr,totparam_nbr);
dVarinov = zeros(e_nbr,e_nbr,totparam_nbr);
dE_z =zeros(z_nbr,totparam_nbr);
for jp=1:totparam_nbr
dA(id_z1_xf , id_z1_xf ,jp) = dghx(indx,:,jp);
dA(id_z2_xs , id_z2_xs ,jp) = dghx(indx,:,jp);
dA(id_z2_xs , id_z3_xf_xf ,jp) = 1/2*dghxx(indx,:,jp);
dA(id_z3_xf_xf , id_z3_xf_xf ,jp) = dhx_hx(:,:,jp);
dA(id_z4_xrd , id_z1_xf ,jp) = 3/6*dghxss(indx,:,jp);
dA(id_z4_xrd , id_z4_xrd ,jp) = dghx(indx,:,jp);
dA(id_z4_xrd , id_z5_xf_xs ,jp) = dghxx(indx,:,jp);
dA(id_z4_xrd , id_z6_xf_xf_xf ,jp) = 1/6*dghxxx(indx,:,jp);
dA(id_z5_xf_xs , id_z1_xf ,jp) = kron(dghx(indx,:,jp),1/2*ghs2(indx,:)) + kron(ghx(indx,:),1/2*dghs2(indx,jp));
dA(id_z5_xf_xs , id_z5_xf_xs ,jp) = dhx_hx(:,:,jp);
dA(id_z5_xf_xs , id_z6_xf_xf_xf ,jp) = kron(dghx(indx,:,jp),1/2*ghxx(indx,:)) + kron(ghx(indx,:),1/2*dghxx(indx,:,jp));
dA(id_z6_xf_xf_xf , id_z6_xf_xf_xf ,jp) = kron(dghx(indx,:,jp),hx_hx) + kron(ghx(indx,:),dhx_hx(:,:,jp));
dB(id_z1_xf , id_e1_u , jp) = dghu(indx,:,jp);
dB(id_z2_xs , id_e2_u_u , jp) = 1/2*dghuu(indx,:,jp);
dB(id_z2_xs , id_e3_xf_u , jp) = dghxu(indx,:,jp);
dB(id_z3_xf_xf , id_e2_u_u , jp) = dhu_hu(:,:,jp);
dB(id_z3_xf_xf , id_e3_xf_u , jp) = dhx_hu(:,:,jp);
dB(id_z3_xf_xf , id_e4_u_xf , jp) = dhu_hx(:,:,jp);
dB(id_z4_xrd , id_e1_u , jp) = 3/6*dghuss(indx,:,jp);
dB(id_z4_xrd , id_e5_xs_u , jp) = dghxu(indx,:,jp);
dB(id_z4_xrd , id_e7_xf_xf_u , jp) = 3/6*dghxxu(indx,:,jp);
dB(id_z4_xrd , id_e10_xf_u_u , jp) = 3/6*dghxuu(indx,:,jp);
dB(id_z4_xrd , id_e13_u_u_u , jp) = 1/6*dghuuu(indx,:,jp);
dB(id_z5_xf_xs , id_e1_u , jp) = kron(dghu(indx,:,jp),1/2*ghs2(indx,:)) + kron(ghu(indx,:),1/2*dghs2(indx,jp));
dB(id_z5_xf_xs , id_e6_u_xs , jp) = dhu_hx(:,:,jp);
dB(id_z5_xf_xs , id_e7_xf_xf_u , jp) = kron(dghx(indx,:,jp),ghxu(indx,:)) + kron(ghx(indx,:),dghxu(indx,:,jp));
dB(id_z5_xf_xs , id_e9_u_xf_xf , jp) = kron(dghu(indx,:,jp),1/2*ghxx(indx,:)) + kron(ghu(indx,:),1/2*dghxx(indx,:,jp));
dB(id_z5_xf_xs , id_e10_xf_u_u , jp) = kron(dghx(indx,:,jp),1/2*ghuu(indx,:)) + kron(ghx(indx,:),1/2*dghuu(indx,:,jp));
dB(id_z5_xf_xs , id_e11_u_xf_u , jp) = kron(dghu(indx,:,jp),ghxu(indx,:)) + kron(ghu(indx,:),dghxu(indx,:,jp));
dB(id_z5_xf_xs , id_e13_u_u_u , jp) = kron(dghu(indx,:,jp),1/2*ghuu(indx,:)) + kron(ghu(indx,:),1/2*dghuu(indx,:,jp));
dB(id_z6_xf_xf_xf , id_e7_xf_xf_u , jp) = kron(dhx_hx(:,:,jp),ghu(indx,:)) + kron(hx_hx,dghu(indx,:,jp));
dB(id_z6_xf_xf_xf , id_e8_xf_u_xf , jp) = kron(dghx(indx,:,jp),hu_hx) + kron(ghx(indx,:),dhu_hx(:,:,jp));
dB(id_z6_xf_xf_xf , id_e9_u_xf_xf , jp) = kron(dghu(indx,:,jp),hx_hx) + kron(ghu(indx,:),dhx_hx(:,:,jp));
dB(id_z6_xf_xf_xf , id_e10_xf_u_u , jp) = kron(dhx_hu(:,:,jp),ghu(indx,:)) + kron(hx_hu,dghu(indx,:,jp));
dB(id_z6_xf_xf_xf , id_e11_u_xf_u , jp) = kron(dghu(indx,:,jp),hx_hu) + kron(ghu(indx,:),dhx_hu(:,:,jp));
dB(id_z6_xf_xf_xf , id_e12_u_u_xf , jp) = kron(dhu_hu(:,:,jp),ghx(indx,:)) + kron(hu_hu,dghx(indx,:,jp));
dB(id_z6_xf_xf_xf , id_e13_u_u_u , jp) = kron(dghu(indx,:,jp),hu_hu) + kron(ghu(indx,:),dhu_hu(:,:,jp));
dC(1:y_nbr , id_z1_xf , jp) = dghx(indy,:,jp) + 1/2*dghxss(indy,:,jp);
dC(1:y_nbr , id_z2_xs , jp) = dghx(indy,:,jp);
dC(1:y_nbr , id_z3_xf_xf , jp) = 1/2*dghxx(indy,:,jp);
dC(1:y_nbr , id_z4_xrd , jp) = dghx(indy,:,jp);
dC(1:y_nbr , id_z5_xf_xs , jp) = dghxx(indy,:,jp);
dC(1:y_nbr , id_z6_xf_xf_xf , jp) = 1/6*dghxxx(indy,:,jp);
dD(1:y_nbr , id_e1_u , jp) = dghu(indy,:,jp) + 1/2*dghuss(indy,:,jp);
dD(1:y_nbr , id_e2_u_u , jp) = 1/2*dghuu(indy,:,jp);
dD(1:y_nbr , id_e3_xf_u , jp) = dghxu(indy,:,jp);
dD(1:y_nbr , id_e5_xs_u , jp) = dghxu(indy,:,jp);
dD(1:y_nbr , id_e7_xf_xf_u , jp) = 1/2*dghxxu(indy,:,jp);
dD(1:y_nbr , id_e10_xf_u_u , jp) = 1/2*dghxuu(indy,:,jp);
dD(1:y_nbr , id_e13_u_u_u , jp) = 1/6*dghuuu(indy,:,jp);
dc(id_z2_xs , jp) = 1/2*dghs2(indx,jp) + 1/2*dghuu(indx,:,jp)*E_uu(:) + 1/2*ghuu(indx,:)*vec(dE_uu(:,:,jp));
dc(id_z3_xf_xf , jp) = dhu_hu(:,:,jp)*E_uu(:) + hu_hu*vec(dE_uu(:,:,jp));
dd(1:y_nbr , jp) = 0.5*dghs2(indy,jp) + 0.5*dghuu(indy,:,jp)*E_uu(:) + 0.5*ghuu(indy,:)*vec(dE_uu(:,:,jp));
dVarinov(id_e1_u , id_e1_u , jp) = dE_uu(:,:,jp);
dVarinov(id_e1_u , id_e5_xs_u , jp) = kron(dE_xs(:,jp)',E_uu) + kron(E_xs',dE_uu(:,:,jp));
dVarinov(id_e1_u , id_e6_u_xs , jp) = kron(dE_uu(:,:,jp),E_xs') + kron(E_uu,dE_xs(:,jp)');
dVarinov(id_e1_u , id_e7_xf_xf_u , jp) = kron(vec(dE_xfxf(:,:,jp))',E_uu) + kron(E_xfxf(:)',dE_uu(:,:,jp));
dVarinov(id_e1_u , id_e8_xf_u_xf , jp) = (kron(dE_uu(:,:,jp),E_xfxf(:)') + kron(E_uu,vec(dE_xfxf(:,:,jp))'))*kron(K_xu,speye(x_nbr));
dVarinov(id_e1_u , id_e9_u_xf_xf , jp) = kron(dE_uu(:,:,jp),E_xfxf(:)') + kron(E_uu,vec(dE_xfxf(:,:,jp))');
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e1_u , id_e13_u_u_u , jp) = reshape(QPu*dE_u_u_u_u(:,jp),u_nbr,u_nbr^3);
dVarinov(id_e2_u_u , id_e2_u_u , jp) = reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2) - vec(dE_uu(:,:,jp))*transpose(E_uu(:)) - E_uu(:)*transpose(vec(dE_uu(:,:,jp)));
end
dVarinov(id_e3_xf_u , id_e3_xf_u , jp) = dE_xfxf_E_uu(:,:,jp);
dVarinov(id_e3_xf_u , id_e4_u_xf , jp) = dE_xfxf_E_uu(:,:,jp)*K_ux';
dVarinov(id_e3_xf_u , id_e5_xs_u , jp) = dE_xfxs_E_uu(:,:,jp);
dVarinov(id_e3_xf_u , id_e6_u_xs , jp) = dE_xfxs_E_uu(:,:,jp)*K_ux';
dVarinov(id_e3_xf_u , id_e7_xf_xf_u , jp) = kron(reshape(dE_xf_xf_xf(:,jp),x_nbr,x_nbr^2), E_uu) + kron(reshape(E_xf_xf_xf,x_nbr,x_nbr^2), dE_uu(:,:,jp));
dVarinov(id_e3_xf_u , id_e8_xf_u_xf , jp) = (kron(reshape(dE_xf_xf_xf(:,jp),x_nbr,x_nbr^2), E_uu) + kron(reshape(E_xf_xf_xf,x_nbr,x_nbr^2), dE_uu(:,:,jp)))*kron(speye(x_nbr),K_ux)';
dVarinov(id_e3_xf_u , id_e9_u_xf_xf , jp) = K_xu*(kron(dE_uu(:,:,jp), reshape(E_xf_xf_xf, x_nbr, x_nbr^2)) + kron(E_uu, reshape(dE_xf_xf_xf(:,jp), x_nbr, x_nbr^2)));
dVarinov(id_e4_u_xf , id_e3_xf_u , jp) = K_ux*dE_xfxf_E_uu(:,:,jp);
dVarinov(id_e4_u_xf , id_e4_u_xf , jp) = kron(dE_uu(:,:,jp),E_xfxf) + kron(E_uu,dE_xfxf(:,:,jp));
dVarinov(id_e4_u_xf , id_e5_xs_u , jp) = K_ux*(kron(dE_xfxs(:,:,jp),E_uu) + kron(E_xfxs,dE_uu(:,:,jp)));
dVarinov(id_e4_u_xf , id_e6_u_xs , jp) = kron(dE_uu(:,:,jp), E_xfxs) + kron(E_uu, dE_xfxs(:,:,jp));
dVarinov(id_e4_u_xf , id_e7_xf_xf_u , jp) = K_ux*(kron(reshape(dE_xf_xf_xf(:,jp),x_nbr,x_nbr^2),E_uu) + kron(reshape(E_xf_xf_xf,x_nbr,x_nbr^2),dE_uu(:,:,jp)));
dVarinov(id_e4_u_xf , id_e8_xf_u_xf , jp) = (kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf,x_nbr,x_nbr^2)) + kron(E_uu,reshape(dE_xf_xf_xf(:,jp),x_nbr,x_nbr^2)))*kron(K_xu,speye(x_nbr))';
dVarinov(id_e4_u_xf , id_e9_u_xf_xf , jp) = kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf,x_nbr,x_nbr^2)) + kron(E_uu,reshape(dE_xf_xf_xf(:,jp),x_nbr,x_nbr^2));
dVarinov(id_e5_xs_u , id_e1_u , jp) = kron(dE_xs(:,jp), E_uu) + kron(E_xs, dE_uu(:,:,jp));
dVarinov(id_e5_xs_u , id_e3_xf_u , jp) = kron(dE_xsxf(:,:,jp), E_uu) + kron(E_xsxf, dE_uu(:,:,jp));
dVarinov(id_e5_xs_u , id_e4_u_xf , jp) = (kron(dE_xsxf(:,:,jp), E_uu) + kron(E_xsxf, dE_uu(:,:,jp)))*K_ux';
dVarinov(id_e5_xs_u , id_e5_xs_u , jp) = kron(dE_xsxs(:,:,jp), E_uu) + kron(E_xsxs, dE_uu(:,:,jp));
dVarinov(id_e5_xs_u , id_e6_u_xs , jp) = (kron(dE_xsxs(:,:,jp), E_uu) + kron(E_xsxs, dE_uu(:,:,jp)))*K_ux';
dVarinov(id_e5_xs_u , id_e7_xf_xf_u , jp) = kron(reshape(dE_xs_xf_xf(:,jp),x_nbr,x_nbr^2),E_uu) + kron(reshape(E_xs_xf_xf,x_nbr,x_nbr^2),dE_uu(:,:,jp));
dVarinov(id_e5_xs_u , id_e8_xf_u_xf , jp) = (kron(reshape(dE_xs_xf_xf(:,jp),x_nbr,x_nbr^2),E_uu) + kron(reshape(E_xs_xf_xf,x_nbr,x_nbr^2),dE_uu(:,:,jp)))*kron(speye(x_nbr),K_ux)';
dVarinov(id_e5_xs_u , id_e9_u_xf_xf , jp) = K_xu*(kron(dE_uu(:,:,jp),reshape(E_xs_xf_xf,x_nbr,x_nbr^2)) + kron(E_uu,reshape(dE_xs_xf_xf(:,jp),x_nbr,x_nbr^2)));
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e5_xs_u , id_e13_u_u_u , jp) = kron(dE_xs(:,jp),reshape(E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xs,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr,u_nbr^3));
else
dVarinov(id_e5_xs_u , id_e13_u_u_u , jp) = kron(dE_xs(:,jp),reshape(E_u_u_u_u,u_nbr,u_nbr^3));
end
dVarinov(id_e6_u_xs , id_e1_u , jp) = kron(dE_uu(:,:,jp),E_xs) + kron(E_uu,dE_xs(:,jp));
dVarinov(id_e6_u_xs , id_e3_xf_u , jp) = K_ux*(kron(dE_xsxf(:,:,jp), E_uu) + kron(E_xsxf, dE_uu(:,:,jp)));
dVarinov(id_e6_u_xs , id_e4_u_xf , jp) = kron(dE_uu(:,:,jp), E_xsxf) + kron(E_uu, dE_xsxf(:,:,jp));
dVarinov(id_e6_u_xs , id_e5_xs_u , jp) = K_ux*(kron(dE_xsxs(:,:,jp),E_uu) + kron(E_xsxs,dE_uu(:,:,jp)));
dVarinov(id_e6_u_xs , id_e6_u_xs , jp) = kron(dE_uu(:,:,jp), E_xsxs) + kron(E_uu, dE_xsxs(:,:,jp));
dVarinov(id_e6_u_xs , id_e7_xf_xf_u , jp) = K_ux*(kron(reshape(dE_xs_xf_xf(:,jp),x_nbr,x_nbr^2), E_uu) + kron(reshape(E_xs_xf_xf,x_nbr,x_nbr^2), dE_uu(:,:,jp)));
dVarinov(id_e6_u_xs , id_e8_xf_u_xf , jp) = (kron(dE_uu(:,:,jp), reshape(E_xs_xf_xf,x_nbr,x_nbr^2)) + kron(E_uu, reshape(dE_xs_xf_xf(:,jp),x_nbr,x_nbr^2)))*kron(K_xu,speye(x_nbr))';
dVarinov(id_e6_u_xs , id_e9_u_xf_xf , jp) = kron(dE_uu(:,:,jp), reshape(E_xs_xf_xf,x_nbr,x_nbr^2)) + kron(E_uu, reshape(dE_xs_xf_xf(:,jp),x_nbr,x_nbr^2));
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e6_u_xs , id_e13_u_u_u , jp) = K_ux*(kron(dE_xs(:,jp),reshape(E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xs,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr,u_nbr^3)));
else
dVarinov(id_e6_u_xs , id_e13_u_u_u , jp) = K_ux*kron(dE_xs(:,jp),reshape(E_u_u_u_u,u_nbr,u_nbr^3));
end
dVarinov(id_e7_xf_xf_u , id_e1_u , jp) = kron(vec(dE_xfxf(:,:,jp)),E_uu) + kron(E_xfxf(:),dE_uu(:,:,jp));
dVarinov(id_e7_xf_xf_u , id_e3_xf_u , jp) = kron(reshape(dE_xf_xf_xf(:,jp),x_nbr^2,x_nbr),E_uu) + kron(reshape(E_xf_xf_xf,x_nbr^2,x_nbr),dE_uu(:,:,jp));
dVarinov(id_e7_xf_xf_u , id_e4_u_xf , jp) = (kron(reshape(dE_xf_xf_xf(:,jp),x_nbr^2,x_nbr),E_uu) + kron(reshape(E_xf_xf_xf,x_nbr^2,x_nbr),dE_uu(:,:,jp)))*K_ux';
dVarinov(id_e7_xf_xf_u , id_e5_xs_u , jp) = kron(reshape(dE_xf_xf_xs(:,jp),x_nbr^2,x_nbr),E_uu) + kron(reshape(E_xf_xf_xs,x_nbr^2,x_nbr),dE_uu(:,:,jp));
dVarinov(id_e7_xf_xf_u , id_e6_u_xs , jp) = (kron(reshape(dE_xf_xf_xs(:,jp),x_nbr^2,x_nbr),E_uu) + kron(reshape(E_xf_xf_xs,x_nbr^2,x_nbr),dE_uu(:,:,jp)))*K_ux';
dVarinov(id_e7_xf_xf_u , id_e7_xf_xf_u , jp) = kron(reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2),E_uu) + kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),dE_uu(:,:,jp));
dVarinov(id_e7_xf_xf_u , id_e8_xf_u_xf , jp) = (kron(reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2),E_uu) + kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),dE_uu(:,:,jp)))*kron(speye(x_nbr),K_ux)';
dVarinov(id_e7_xf_xf_u , id_e9_u_xf_xf , jp) = kron(speye(x_nbr),K_ux)*kron(K_ux,speye(x_nbr))*(kron(dE_uu(:,:,jp), reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2)) + kron(E_uu, reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2)));
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e7_xf_xf_u , id_e13_u_u_u , jp) = kron(vec(dE_xfxf(:,:,jp)),reshape(E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xfxf(:),reshape(QPu*dE_u_u_u_u(:,jp),u_nbr,u_nbr^3));
else
dVarinov(id_e7_xf_xf_u , id_e13_u_u_u , jp) = kron(vec(dE_xfxf(:,:,jp)),reshape(E_u_u_u_u,u_nbr,u_nbr^3));
end
dVarinov(id_e8_xf_u_xf , id_e1_u , jp) = kron(K_xu,speye(x_nbr))*(kron(dE_uu(:,:,jp),E_xfxf(:)) + kron(E_uu,vec(dE_xfxf(:,:,jp))));
dVarinov(id_e8_xf_u_xf , id_e3_xf_u , jp) = kron(speye(x_nbr),K_xu)*(kron(reshape(dE_xf_xf_xf(:,jp),x_nbr^2,x_nbr),E_uu) + kron(reshape(E_xf_xf_xf,x_nbr^2,x_nbr),dE_uu(:,:,jp)));
dVarinov(id_e8_xf_u_xf , id_e4_u_xf , jp) = kron(K_xu,speye(x_nbr))*(kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf,x_nbr^2,x_nbr)) + kron(E_uu,reshape(dE_xf_xf_xf(:,jp),x_nbr^2,x_nbr)));
dVarinov(id_e8_xf_u_xf , id_e5_xs_u , jp) = kron(speye(x_nbr),K_ux)*(kron(reshape(dE_xf_xf_xs(:,jp),x_nbr^2,x_nbr),E_uu) + kron(reshape(E_xf_xf_xs,x_nbr^2,x_nbr),dE_uu(:,:,jp)));
dVarinov(id_e8_xf_u_xf , id_e6_u_xs , jp) = kron(K_xu,speye(x_nbr))*(kron(dE_uu(:,:,jp),reshape(E_xf_xf_xs,x_nbr^2,x_nbr)) + kron(E_uu,reshape(dE_xf_xf_xs(:,jp),x_nbr^2,x_nbr)));
dVarinov(id_e8_xf_u_xf , id_e7_xf_xf_u , jp) = kron(speye(x_nbr),K_ux)*(kron(reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2),E_uu) + kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),dE_uu(:,:,jp)));
dVarinov(id_e8_xf_u_xf , id_e8_xf_u_xf , jp) = kron(K_xu,speye(x_nbr))*(kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2)) + kron(E_uu,reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2)))*kron(K_xu,speye(x_nbr))';
dVarinov(id_e8_xf_u_xf , id_e9_u_xf_xf , jp) = kron(K_xu,speye(x_nbr))*(kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2)) + kron(E_uu,reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2)));
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e8_xf_u_xf , id_e13_u_u_u , jp) = kron(K_xu,speye(x_nbr))*(kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr,u_nbr^3),E_xfxf(:)) + kron(reshape(E_u_u_u_u,u_nbr,u_nbr^3),vec(dE_xfxf(:,:,jp))));
else
dVarinov(id_e8_xf_u_xf , id_e13_u_u_u , jp) = kron(K_xu,speye(x_nbr))*kron(reshape(E_u_u_u_u,u_nbr,u_nbr^3),vec(dE_xfxf(:,:,jp)));
end
dVarinov(id_e9_u_xf_xf , id_e1_u , jp) = kron(dE_uu(:,:,jp), E_xfxf(:)) + kron(E_uu, vec(dE_xfxf(:,:,jp)));
dVarinov(id_e9_u_xf_xf , id_e3_xf_u , jp) = (kron(dE_uu(:,:,jp), reshape(E_xf_xf_xf,x_nbr^2,x_nbr)) + kron(E_uu, reshape(dE_xf_xf_xf(:,jp),x_nbr^2,x_nbr)))*K_xu';
dVarinov(id_e9_u_xf_xf , id_e4_u_xf , jp) = kron(dE_uu(:,:,jp), reshape(E_xf_xf_xf,x_nbr^2,x_nbr)) + kron(E_uu, reshape(dE_xf_xf_xf(:,jp),x_nbr^2,x_nbr));
dVarinov(id_e9_u_xf_xf , id_e5_xs_u , jp) = (kron(dE_uu(:,:,jp), reshape(E_xf_xf_xs,x_nbr^2,x_nbr)) + kron(E_uu, reshape(dE_xf_xf_xs(:,jp),x_nbr^2,x_nbr)))*K_xu';
dVarinov(id_e9_u_xf_xf , id_e6_u_xs , jp) = kron(dE_uu(:,:,jp), reshape(E_xf_xf_xs,x_nbr^2,x_nbr)) + kron(E_uu, reshape(dE_xf_xf_xs(:,jp),x_nbr^2,x_nbr));
dVarinov(id_e9_u_xf_xf , id_e7_xf_xf_u , jp) = kron(speye(x_nbr),K_ux)*kron(K_ux,speye(x_nbr))*(kron(reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2),E_uu) + kron(reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2),dE_uu(:,:,jp)));
dVarinov(id_e9_u_xf_xf , id_e8_xf_u_xf , jp) = (kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2)) + kron(E_uu,reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2)))*kron(speye(x_nbr),K_ux)';
dVarinov(id_e9_u_xf_xf , id_e9_u_xf_xf , jp) = kron(dE_uu(:,:,jp),reshape(E_xf_xf_xf_xf,x_nbr^2,x_nbr^2)) + kron(E_uu,reshape(dE_xf_xf_xf_xf(:,jp),x_nbr^2,x_nbr^2));
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e9_u_xf_xf , id_e13_u_u_u , jp) = kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr,u_nbr^3),E_xfxf(:)) + kron(reshape(E_u_u_u_u,u_nbr,u_nbr^3),vec(dE_xfxf(:,:,jp)));
else
dVarinov(id_e9_u_xf_xf , id_e13_u_u_u , jp) = kron(reshape(E_u_u_u_u,u_nbr,u_nbr^3),vec(dE_xfxf(:,:,jp)));
end
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e10_xf_u_u , id_e10_xf_u_u , jp) = kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2));
dVarinov(id_e10_xf_u_u , id_e11_u_xf_u , jp) = (kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2)))*kron(K_ux,speye(u_nbr))';
dVarinov(id_e10_xf_u_u , id_e12_u_u_xf , jp) = (kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2)))*kron(K_ux,speye(u_nbr))'*kron(speye(u_nbr),K_ux)';
else
dVarinov(id_e10_xf_u_u , id_e10_xf_u_u , jp) = kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2));
dVarinov(id_e10_xf_u_u , id_e11_u_xf_u , jp) = kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2))*kron(K_ux,speye(u_nbr))';
dVarinov(id_e10_xf_u_u , id_e12_u_u_xf , jp) = kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2))*kron(K_ux,speye(u_nbr))'*kron(speye(u_nbr),K_ux)';
end
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e11_u_xf_u , id_e10_xf_u_u , jp) = kron(K_ux,speye(u_nbr))*(kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2)));
dVarinov(id_e11_u_xf_u , id_e11_u_xf_u , jp) = kron(K_ux,speye(u_nbr))*(kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2)))*kron(K_ux,speye(u_nbr))';
dVarinov(id_e11_u_xf_u , id_e12_u_u_xf , jp) = kron(speye(u_nbr),K_ux)*(kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2),E_xfxf) + kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),dE_xfxf(:,:,jp)));
else
dVarinov(id_e11_u_xf_u , id_e10_xf_u_u , jp) = kron(K_ux,speye(u_nbr))*kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2));
dVarinov(id_e11_u_xf_u , id_e11_u_xf_u , jp) = kron(K_ux,speye(u_nbr))*kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2))*kron(K_ux,speye(u_nbr))';
dVarinov(id_e11_u_xf_u , id_e12_u_u_xf , jp) = kron(speye(u_nbr),K_ux)*kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),dE_xfxf(:,:,jp));
end
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e12_u_u_xf , id_e10_xf_u_u , jp) = kron(K_ux,speye(u_nbr))*kron(speye(u_nbr),K_ux)*(kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2)));
dVarinov(id_e12_u_u_xf , id_e11_u_xf_u , jp) = (kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2),E_xfxf) + kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),dE_xfxf(:,:,jp)))*kron(speye(u_nbr),K_xu)';
dVarinov(id_e12_u_u_xf , id_e12_u_u_xf , jp) = kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^2,u_nbr^2),E_xfxf) + kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),dE_xfxf(:,:,jp));
else
dVarinov(id_e12_u_u_xf , id_e10_xf_u_u , jp) = kron(K_ux,speye(u_nbr))*kron(speye(u_nbr),K_ux)*kron(dE_xfxf(:,:,jp),reshape(E_u_u_u_u,u_nbr^2,u_nbr^2));
dVarinov(id_e12_u_u_xf , id_e11_u_xf_u , jp) = kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),dE_xfxf(:,:,jp))*kron(speye(u_nbr),K_xu)';
dVarinov(id_e12_u_u_xf , id_e12_u_u_xf , jp) = kron(reshape(E_u_u_u_u,u_nbr^2,u_nbr^2),dE_xfxf(:,:,jp));
end
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e13_u_u_u , id_e1_u , jp) = reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^3,u_nbr);
dVarinov(id_e13_u_u_u , id_e5_xs_u , jp) = kron(dE_xs(:,jp)', reshape(E_u_u_u_u,u_nbr^3,u_nbr)) + kron(E_xs', reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^3,u_nbr));
dVarinov(id_e13_u_u_u , id_e6_u_xs , jp) = kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^3,u_nbr),E_xs') + kron(reshape(E_u_u_u_u,u_nbr^3,u_nbr),dE_xs(:,jp)');
dVarinov(id_e13_u_u_u , id_e7_xf_xf_u , jp) = kron(vec(dE_xfxf(:,:,jp))',reshape(E_u_u_u_u,u_nbr^3,u_nbr)) + kron(E_xfxf(:)',reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^3,u_nbr));
dVarinov(id_e13_u_u_u , id_e8_xf_u_xf , jp) = (kron(vec(dE_xfxf(:,:,jp))',reshape(E_u_u_u_u,u_nbr^3,u_nbr)) + kron(E_xfxf(:)',reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^3,u_nbr)))*kron(speye(x_nbr),K_ux)';
dVarinov(id_e13_u_u_u , id_e9_u_xf_xf , jp) = kron(reshape(QPu*dE_u_u_u_u(:,jp),u_nbr^3,u_nbr), E_xfxf(:)') + kron(reshape(E_u_u_u_u,u_nbr^3,u_nbr), vec(dE_xfxf(:,:,jp))');
else
dVarinov(id_e13_u_u_u , id_e5_xs_u , jp) = kron(dE_xs(:,jp)', reshape(E_u_u_u_u,u_nbr^3,u_nbr));
dVarinov(id_e13_u_u_u , id_e6_u_xs , jp) = kron(reshape(E_u_u_u_u,u_nbr^3,u_nbr),dE_xs(:,jp)');
dVarinov(id_e13_u_u_u , id_e7_xf_xf_u , jp) = kron(vec(dE_xfxf(:,:,jp))',reshape(E_u_u_u_u,u_nbr^3,u_nbr));
dVarinov(id_e13_u_u_u , id_e8_xf_u_xf , jp) = kron(vec(dE_xfxf(:,:,jp))',reshape(E_u_u_u_u,u_nbr^3,u_nbr))*kron(speye(x_nbr),K_ux)';
dVarinov(id_e13_u_u_u , id_e9_u_xf_xf , jp) = kron(reshape(E_u_u_u_u,u_nbr^3,u_nbr), vec(dE_xfxf(:,:,jp))');
end
if jp <= (stderrparam_nbr+corrparam_nbr)
dVarinov(id_e13_u_u_u , id_e13_u_u_u , jp) = reshape(Q6Pu*dE_u_u_u_u_u_u(:,jp),u_nbr^3,u_nbr^3);
end
dE_z(:,jp) = (speye(z_nbr)-A)\(dc(:,jp) + dA(:,:,jp)*E_z);
end
end
end
end
E_y = Yss(indy,:) + C*E_z + d;
Om_z = B*Varinov*transpose(B);
Om_y = D*Varinov*transpose(D);
if compute_derivs
dE_y = zeros(y_nbr,totparam_nbr);
dOm_z = zeros(z_nbr,z_nbr,totparam_nbr);
dOm_y = zeros(y_nbr,y_nbr,totparam_nbr);
for jp = 1:totparam_nbr
dE_y(:,jp) = dC(:,:,jp)*E_z + C*dE_z(:,jp) + dd(:,jp);
dOm_z(:,:,jp) = dB(:,:,jp)*Varinov*B' + B*dVarinov(:,:,jp)*B' + B*Varinov*dB(:,:,jp)';
dOm_y(:,:,jp) = dD(:,:,jp)*Varinov*D' + D*dVarinov(:,:,jp)*D' + D*Varinov*dD(:,:,jp)';
if jp > (stderrparam_nbr+corrparam_nbr)
dE_y(:,jp) = dE_y(:,jp) + dYss(indy,jp-stderrparam_nbr-corrparam_nbr); %add steady state
end
end
end
%% Store into output structure
dr.pruned.indx = indx;
dr.pruned.indy = indy;
%dr.pruned.E_xfxf = E_xfxf;
dr.pruned.A = A;
dr.pruned.B = B;
dr.pruned.C = C;
dr.pruned.D = D;
dr.pruned.c = c;
dr.pruned.d = d;
dr.pruned.Om_z = Om_z;
dr.pruned.Om_y = Om_y;
dr.pruned.Varinov = Varinov;
dr.pruned.E_z = E_z;
dr.pruned.E_y = E_y;
if compute_derivs == 1
%dr.pruned.dE_xfxf = dE_xfxf;
dr.pruned.dA = dA;
dr.pruned.dB = dB;
dr.pruned.dC = dC;
dr.pruned.dD = dD;
dr.pruned.dc = dc;
dr.pruned.dd = dd;
dr.pruned.dOm_z = dOm_z;
dr.pruned.dOm_y = dOm_y;
dr.pruned.dVarinov = dVarinov;
dr.pruned.dE_z = dE_z;
dr.pruned.dE_y = dE_y;
end

83
matlab/quadruplication.m Normal file
View File

@ -0,0 +1,83 @@
% By Willi Mutschler, September 26, 2016. Email: willi@mutschler.eu
% Quadruplication Matrix as defined by
% Meijer (2005) - Matrix algebra for higher order moments. Linear Algebra and its Applications, 410,pp. 112134
%
% Inputs:
% p: size of vector
% Outputs:
% QP: quadruplication matrix
% QPinv: Moore-Penrose inverse of QP
%
function [QP,QPinv] = quadruplication(p,progress,sparseflag)
if nargin <2
progress =0;
end
if nargin < 3
sparseflag = 1;
end
reverseStr = ''; counti=1;
np = p*(p+1)*(p+2)*(p+3)/24;
if sparseflag
QP = spalloc(p^4,p*(p+1)*(p+2)*(p+3)/24,p^4);
else
QP = zeros(p^4,p*(p+1)*(p+2)*(p+3)/24);
end
if nargout > 1
if sparseflag
QPinv = spalloc(p*(p+1)*(p+2)*(p+3)/24,p*(p+1)*(p+2)*(p+3)/24,p^4);
else
QPinv = zeros(p*(p+1)*(p+2)*(p+3)/24,p*(p+1)*(p+2)*(p+3)/24);
end
end
for l=1:p
for k=l:p
for j=k:p
for i=j:p
if progress && (rem(counti,100)== 0)
msg = sprintf(' Quadruplication Matrix Processed %d/%d', counti, np); fprintf([reverseStr, msg]); reverseStr = repmat(sprintf('\b'), 1, length(msg));
elseif progress && (counti==np)
msg = sprintf(' Quadruplication Matrix Processed %d/%d\n', counti, np); fprintf([reverseStr, msg]); reverseStr = repmat(sprintf('\b'), 1, length(msg));
end
idx = uperm([i j k l]);
for r = 1:size(idx,1)
ii = idx(r,1); jj= idx(r,2); kk=idx(r,3); ll=idx(r,4);
n = ii + (jj-1)*p + (kk-1)*p^2 + (ll-1)*p^3;
m = mue(p,i,j,k,l);
QP(n,m)=1;
if nargout > 1
if i==j && j==k && k==l
QPinv(m,n)=1;
elseif i==j && j==k && k>l
QPinv(m,n)=1/4;
elseif i>j && j==k && k==l
QPinv(m,n)=1/4;
elseif i==j && j>k && k==l
QPinv(m,n) = 1/6;
elseif i>j && j>k && k==l
QPinv(m,n) = 1/12;
elseif i>j && j==k && k>l
QPinv(m,n) = 1/12;
elseif i==j && j>k && k>l
QPinv(m,n) = 1/12;
elseif i>j && j>k && k>l
QPinv(m,n) = 1/24;
end
end
end
counti = counti+1;
end
end
end
end
%QPinv = (transpose(QP)*QP)\transpose(QP);
function m = mue(p,i,j,k,l)
m = i + (j-1)*p + 1/2*(k-1)*p^2 + 1/6*(l-1)*p^3 - 1/2*j*(j-1) + 1/6*k*(k-1)*(k-2) - 1/24*l*(l-1)*(l-2)*(l-3) - 1/2*(k-1)^2*p + 1/6*(l-1)^3*p - 1/4*(l-1)*(l-2)*p^2 - 1/4*l*(l-1)*p + 1/6*(l-1)*p;
m = round(m);
end
end

27
matlab/uperm.m Normal file
View File

@ -0,0 +1,27 @@
% By Willi Mutschler, September 26, 2016. Email: willi@mutschler.eu
function p = uperm(a)
[u, ~, J] = unique(a);
p = u(up(J, length(a)));
function p = up(J, n)
ktab = histcounts(J,1:max(J));
l = n;
p = zeros(1, n);
s = 1;
for i=1:length(ktab)
k = ktab(i);
c = nchoosek(1:l, k);
m = size(c,1);
[t, ~] = find(~p.');
t = reshape(t, [], s);
c = t(c,:)';
s = s*m;
r = repmat((1:s)',[1 k]);
q = accumarray([r(:) c(:)], i, [s n]);
p = repmat(p, [m 1]) + q;
l = l - k;
end
end
end % uperm

View File

@ -190,6 +190,7 @@ MODFILES = \
identification/as2007/as2007_kronflags.mod \ identification/as2007/as2007_kronflags.mod \
identification/as2007/as2007_QT.mod \ identification/as2007/as2007_QT.mod \
identification/as2007/as2007_QT_equal_autocorr.mod \ identification/as2007/as2007_QT_equal_autocorr.mod \
identification/as2007/as2007_order_1_2_3.mod \
identification/BrockMirman/BrockMirman.mod \ identification/BrockMirman/BrockMirman.mod \
identification/cgg/cgg_criteria_differ.mod \ identification/cgg/cgg_criteria_differ.mod \
identification/ident_unit_root/ident_unit_root.mod \ identification/ident_unit_root/ident_unit_root.mod \

View File

@ -76,14 +76,14 @@ identification(parameter_set=calibration,
load('G_QT'); %note that this is computed using replication files of Qu and Tkachenko (2012) load('G_QT'); %note that this is computed using replication files of Qu and Tkachenko (2012)
temp = load([M_.dname filesep 'identification' filesep M_.fname '_identif']); temp = load([M_.dname filesep 'identification' filesep M_.fname '_identif']);
G_dynare = temp.ide_spectrum_point.G; G_dynare = temp.ide_spectrum_point.dSPECTRUM;
% Compare signs % Compare signs
if ~isequal(sign(G_dynare),sign(G_QT)) if ~isequal(sign(G_dynare),sign(G_QT))
error('signs of normalized G are note equal'); error('signs of normalized G are note equal');
end end
% Compare normalized versions % Compare normalized versions
tilda_G_dynare = temp.ide_spectrum_point.tilda_G; tilda_G_dynare = temp.ide_spectrum_point.tilda_dSPECTRUM;
ind_G_QT = (find(max(abs(G_QT'),[],1) > temp.store_options_ident.tol_deriv)); ind_G_QT = (find(max(abs(G_QT'),[],1) > temp.store_options_ident.tol_deriv));
tilda_G_QT = zeros(size(G_QT)); tilda_G_QT = zeros(size(G_QT));
delta_G_QT = sqrt(diag(G_QT(ind_G_QT,ind_G_QT))); delta_G_QT = sqrt(diag(G_QT(ind_G_QT,ind_G_QT)));

View File

@ -0,0 +1,109 @@
%this is the mod file used in replication files of An and Schorfheide (2007)
% modified to include some obvious and artificial identification failures
% and to check whether all kronflags are working
% created by Willi Mutschler (willi@mutschler.eu)
var y R g z c dy p YGR INFL INT;
varobs y R g z c dy p YGR INFL INT;
varexo e_r e_g e_z;
parameters sigr sigg sigz tau phi psi1 psi2 rhor rhog rhoz rrst pist gamst nu cyst dumpy dumpyrhog;
rrst = 1.0000;
pist = 3.2000;
gamst= 0.5500;
tau = 2.0000;
nu = 0.1000;
kap = 0.3300;
phi = tau*(1-nu)/nu/kap/exp(pist/400)^2;
cyst = 0.8500;
psi1 = 1.5000;
psi2 = 0.1250;
rhor = 0.7500;
rhog = 0.9500;
rhoz = 0.9000;
sigr = 0.2;
sigg = 0.6;
sigz = 0.3;
dumpy = 0;
dumpyrhog = 1;
model;
#pist2 = exp(pist/400);
#rrst2 = exp(rrst/400);
#bet = 1/rrst2;
#gst = 1/cyst;
#cst = (1-nu)^(1/tau);
#yst = cst*gst;
1 = exp(-tau*c(+1)+tau*c+R-z(+1)-p(+1));
(1-nu)/nu/phi/(pist2^2)*(exp(tau*c)-1) = (exp(p)-1)*((1-1/2/nu)*exp(p)+1/2/nu) - bet*(exp(p(+1))-1)*exp(-tau*c(+1)+tau*c+dy(+1)+p(+1));
exp(c-y) = exp(-g) - phi*pist2^2*gst/2*(exp(p)-1)^2;
R = rhor*R(-1) + (1-rhor)*psi1*p + (1-rhor)*psi2*(y-g) + sigr*e_r;
g = dumpyrhog*rhog*g(-1) + sigg*e_g;
z = rhoz*z(-1) + sigz*e_z;
YGR = gamst+100*(dy+z);
INFL = pist+400*p;
INT = pist+rrst+4*gamst+400*R;
dy = y - y(-1);
end;
shocks;
var e_r = 0.6^2;
var e_g = 0.5^2;
var e_z = 0.4^2;
corr e_r, e_g = 0.3;
corr e_r, e_z = 0.2;
corr e_z, e_g = 0.1;
end;
steady_state_model;
z=0; g=0; c=0; y=0; p=0; R=0; dy=0;
YGR=gamst; INFL=pist; INT=pist+rrst+4*gamst;
end;
estimated_params;
tau, 2, 1e-5, 10, gamma_pdf, 2, 0.5;
%these parameters do not enter the linearized solution
cyst, 0.85, 1e-5, 0.99999, beta_pdf, 0.85, 0.1;
sigg, 0.6, 1e-8, 5, inv_gamma_pdf, 0.4, 4;
rhoz, 0.9, 1e-5, 0.99999, beta_pdf, 0.66, 0.15;
corr e_r,e_g, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4;
corr e_z,e_g, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4;
corr e_z,e_r, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4;
%these parameters could only be identified from the steady state of YGR INFL and INT, however, we observer y pi R instead
rrst, 1, 1e-5, 10, gamma_pdf, 0.8, 0.5;
gamst, 0.55, -5, 5, normal_pdf, 0.4, 0.2;
dumpy, 0, -10, 10, normal_pdf, 0, 1;
%these parameters jointly determine the slope kappa of the linearized new keynesian phillips curve
pist, 3.2, 1e-5, 20, gamma_pdf, 4, 2;
nu, 0.1, 1e-5, 0.99999, beta_pdf, 0.1, .05;
phi, 50, 1e-5, 100, gamma_pdf, 50, 20;
%these parameters are pairwise collinear as one should not use both formulations for the standard error of a shock
sigz, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4;
stderr e_z, 0.3, 1e-8, 5, inv_gamma_pdf, 0.4, 4;
%these parameters are pairwise collinear as they are multiplicative
rhog, 0.95, 1e-5, 0.99999, beta_pdf, 0.8, 0.1;
dumpyrhog, 1, -10, 10, normal_pdf, 1, 1;
%these parameters are jointly not identified due to the specification of the Taylor rule
psi1, 1.5, 1e-5, 10, gamma_pdf, 1.5, 0.25;
psi2, 0.125, 1e-5, 10, gamma_pdf, 0.5, 0.25;
rhor, 0.75, 1e-5, 0.99999, beta_pdf, 0.5, 0.2;
stderr e_r, 0.2, 1e-8, 5, inv_gamma_pdf, 0.3, 4;
end;
steady;
check;
stoch_simul(order=3,irf=0,periods=0); %needed for identification(order=3)
@#for ORDER in [1, 2, 3]
@#for KRONFLAG in [-1, -2, 0]
fprintf('*** ORDER = @{ORDER} WITH ANALYTIC_DERIVATION_MODE=@{KRONFLAG} ***\n')
identification(order=@{ORDER}, parameter_set=calibration, grid_nbr=10,analytic_derivation_mode=@{KRONFLAG});
@#endfor
@#endfor

View File

@ -96,7 +96,7 @@ identification(advanced=1);
temp=load([M_.dname filesep 'identification' filesep M_.fname '_ML_Starting_value_identif']) temp=load([M_.dname filesep 'identification' filesep M_.fname '_ML_Starting_value_identif'])
temp_comparison=load(['rbc_ident_std_as_structural_par' filesep 'identification' filesep 'rbc_ident_std_as_structural_par' '_ML_Starting_value_identif']) temp_comparison=load(['rbc_ident_std_as_structural_par' filesep 'identification' filesep 'rbc_ident_std_as_structural_par' '_ML_Starting_value_identif'])
if max(abs(temp.ide_hess_point.ide_strength_J - temp_comparison.ide_hess_point.ide_strength_J))>1e-8 ||... if max(abs(temp.ide_hess_point.ide_strength_dMOMENTS - temp_comparison.ide_hess_point.ide_strength_dMOMENTS))>1e-8 ||...
max(abs(temp.ide_hess_point.deltaM - temp_comparison.ide_hess_point.deltaM))>1e-8 ||... max(abs(temp.ide_hess_point.deltaM - temp_comparison.ide_hess_point.deltaM))>1e-8 ||...
max(abs(temp.ide_moments_point.MOMENTS- temp_comparison.ide_moments_point.MOMENTS))>1e-8 ||... max(abs(temp.ide_moments_point.MOMENTS- temp_comparison.ide_moments_point.MOMENTS))>1e-8 ||...
max(abs(temp.ide_moments_point.MOMENTS- temp_comparison.ide_moments_point.MOMENTS))>1e-8 max(abs(temp.ide_moments_point.MOMENTS- temp_comparison.ide_moments_point.MOMENTS))>1e-8