From e37c2532ee116d163064daa0e845e712b7ac5167 Mon Sep 17 00:00:00 2001 From: Marco Ratto <marco.ratto@jrc.ec.europa.eu> Date: Fri, 6 Jul 2012 12:19:25 +0200 Subject: [PATCH] * Fix problem with models where steadystate files change parameter values. 1) allow to compute derivatives starting from NUMERICAL derivatives of jacobian and steady state: this has a minor cost in accuracy and allow apply without errors identification and estimation with numerical derivatives; 2) added trap in dynare_estimation_init: if steadystate changes param values, automaticly shifts to numerical derivs of jacoban and steady state + analytic derivatives of all the rest; 3) bug fixes for 2nd order derivatives w.r.t. model parameters; **** (Manually cherry picked from ed4d37341c707ec80e8c3291a451e5e1388021f2) --- matlab/dsge_likelihood.m | 8 ++- matlab/dynare_estimation_init.m | 25 ++++++++-- matlab/dynare_identification.m | 2 + matlab/getH.m | 83 ++++++++++++++++++++------------ matlab/getJJ.m | 13 ++++- matlab/global_initialization.m | 1 + matlab/identification_analysis.m | 8 ++- matlab/thet2tau.m | 7 +++ 8 files changed, 107 insertions(+), 40 deletions(-) diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m index a646f82af4..da63a35cae 100644 --- a/matlab/dsge_likelihood.m +++ b/matlab/dsge_likelihood.m @@ -181,6 +181,10 @@ if nargout==1, analytic_derivation=0; end +if analytic_derivation, + kron_flag=DynareOptions.analytic_derivation_mode; +end + %------------------------------------------------------------------------------ % 1. Get the structural parameters & define penalties %------------------------------------------------------------------------------ @@ -498,9 +502,9 @@ if analytic_derivation, end if full_Hess, - [dum, DT, DOm, DYss, dum2, D2T, D2Om, D2Yss] = getH(A, B, Model,DynareResults,0,indparam,indexo); + [dum, DT, DOm, DYss, dum2, D2T, D2Om, D2Yss] = getH(A, B, Model,DynareResults,DynareOptions,kron_flag,indparam,indexo); else - [dum, DT, DOm, DYss] = getH(A, B, Model,DynareResults,0,indparam,indexo); + [dum, DT, DOm, DYss] = getH(A, B, Model,DynareResults,DynareOptions,kron_flag,indparam,indexo); end else DT = derivatives_info.DT; diff --git a/matlab/dynare_estimation_init.m b/matlab/dynare_estimation_init.m index a66ed7821f..e1d42f0c13 100644 --- a/matlab/dynare_estimation_init.m +++ b/matlab/dynare_estimation_init.m @@ -285,10 +285,29 @@ else end; if options_.analytic_derivation, - if ~(exist('sylvester3','file')==2), + if ~(exist('sylvester3','file')==2), dynareroot = strrep(which('dynare'),'dynare.m',''); addpath([dynareroot 'gensylv']) end + if estim_params_.np, + % check if steady state changes param values + M=M_; + M.params(estim_params_.param_vals(:,1)) = M.params(estim_params_.param_vals(:,1))*1.01; + if options_.diffuse_filter + steadystate_check_flag = 0; + else + steadystate_check_flag = 1; + end + [tmp1, params] = evaluate_steady_state(oo_.steady_state,M,options_,oo_,steadystate_check_flag); + change_flag=any(find(params-M.params)); + if change_flag, + disp('The steadystate file changed the values for the following parameters: '), + disp(M.param_names(find(params-M.params),:)) + disp('The derivatives of jacobian and steady-state will be computed numerically'), + disp('(re-set options_.analytic_derivation_mode= -2)'), + options_.analytic_derivation_mode= -2; + end + end end % Test if the data file is declared. @@ -335,10 +354,10 @@ nvx = estim_params_.nvx; ncx = estim_params_.ncx; nvn = estim_params_.nvn; ncn = estim_params_.ncn; -if estim_params_.np +if estim_params_.np, M.params(estim_params_.param_vals(:,1)) = xparam1(nvx+ncx+nvn+ncn+1:end); end; -oo_.steady_state = evaluate_steady_state(oo_.steady_state,M,options_,oo_,steadystate_check_flag); +[oo_.steady_state, params] = evaluate_steady_state(oo_.steady_state,M,options_,oo_,steadystate_check_flag); if all(abs(oo_.steady_state(bayestopt_.mfys))<1e-9) options_.noconstant = 1; else diff --git a/matlab/dynare_identification.m b/matlab/dynare_identification.m index fb8174a855..46d75d1b8c 100644 --- a/matlab/dynare_identification.m +++ b/matlab/dynare_identification.m @@ -60,6 +60,7 @@ options_ident = set_default_option(options_ident,'replic',100); options_ident = set_default_option(options_ident,'advanced',0); options_ident = set_default_option(options_ident,'normalize_jacobians',1); options_ident = set_default_option(options_ident,'lik_init',1); +options_ident = set_default_option(options_ident,'analytic_derivation',1); if options_ident.gsa_sample_file, GSAFolder = checkpath('gsa',M_.dname); if options_ident.gsa_sample_file==1, @@ -117,6 +118,7 @@ options_ = set_default_option(options_,'datafile',[]); options_.mode_compute = 0; options_.plot_priors = 0; [dataset_,xparam1, M_, options_, oo_, estim_params_,bayestopt_]=dynare_estimation_init(M_.endo_names,fname_,1, M_, options_, oo_, estim_params_, bayestopt_); +options_ident.analytic_derivation_mode = options_.analytic_derivation_mode; if isempty(dataset_), dataset_.info.ntobs = periods; dataset_.info.nvobs = rows(options_.varobs); diff --git a/matlab/getH.m b/matlab/getH.m index 34097cb58b..825d251382 100644 --- a/matlab/getH.m +++ b/matlab/getH.m @@ -1,4 +1,4 @@ -function [H, dA, dOm, Hss, gp, d2A, d2Om, H2ss] = getH(A, B, M_,oo_,kronflag,indx,indexo) +function [H, dA, dOm, Hss, gp, d2A, d2Om, H2ss] = getH(A, B, M_,oo_,options_,kronflag,indx,indexo) % computes derivative of reduced form linear model w.r.t. deep params % @@ -20,47 +20,73 @@ function [H, dA, dOm, Hss, gp, d2A, d2Om, H2ss] = getH(A, B, M_,oo_,kronflag,ind % along with Dynare. If not, see <http://www.gnu.org/licenses/>. if nargin<3 || isempty(kronflag), kronflag = 0; end -if nargin<4 || isempty(indx), indx = [1:M_.param_nbr];, end, -if nargin<5 || isempty(indexo), indexo = [];, end, - +if nargin<4 || isempty(indx), indx = [1:M_.param_nbr]; end, +if nargin<5 || isempty(indexo), indexo = []; end, [I,J]=find(M_.lead_lag_incidence'); yy0=oo_.dr.ys(I); +param_nbr = length(indx); +if nargout>5, + param_nbr_2 = param_nbr*(param_nbr+1)/2; +end + +m = size(A,1); +n = size(B,2); + +if kronflag==-2, + if nargout>5, + [residual, g1, g2 ] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1); + g22 = hessian('thet2tau',[M_.params(indx)],options_.gstep,M_, oo_, indx,[],-1); + H2ss=g22(1:M_.endo_nbr,:); + H2ss = reshape(H2ss,[M_.endo_nbr param_nbr param_nbr]); + g22=g22(M_.endo_nbr+1:end,:); + g22 = reshape(g22,[size(g1) param_nbr param_nbr]); + else + [residual, g1 ] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1); + end + gp = fjaco('thet2tau',[M_.params(indx)],M_, oo_, indx,[],-1); + Hss=gp(1:M_.endo_nbr,:); + gp=gp(M_.endo_nbr+1:end,:); + gp = reshape(gp,[size(g1) param_nbr]); +else + % yy0=[]; % for j=1:size(M_.lead_lag_incidence,1); % yy0 = [ yy0; oo_.dr.ys(find(M_.lead_lag_incidence(j,:)))]; % end dyssdtheta=zeros(length(oo_.dr.ys),M_.param_nbr); +d2yssdtheta=zeros(length(oo_.dr.ys),M_.param_nbr,M_.param_nbr); if nargout>5, [residual, gg1, gg2] = feval([M_.fname,'_static'],oo_.dr.ys, oo_.exo_steady_state', M_.params); [df, gp, d2f] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1, dyssdtheta); + M_.params, oo_.dr.ys, 1, dyssdtheta, d2yssdtheta); d2f = get_all_resid_2nd_derivs(d2f,length(oo_.dr.ys),M_.param_nbr); d2f = d2f(:,indx,indx); if isempty(find(gg2)), for j=1:length(indx), - d2yssdtheta(:,:,j) = -gg1\d2f(:,:,j); + d2yssdtheta(:,indx,j) = -gg1\d2f(:,:,j); end else gam = d2f*0; for j=1:length(indx), - d2yssdtheta(:,:,j) = -gg1\(d2f(:,:,j)+gam(:,:,j)); + d2yssdtheta(:,indx,j) = -gg1\(d2f(:,:,j)+gam(:,:,j)); end end else [residual, gg1] = feval([M_.fname,'_static'],oo_.dr.ys, oo_.exo_steady_state', M_.params); df = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1, dyssdtheta); + M_.params, oo_.dr.ys, 1, dyssdtheta, d2yssdtheta); end dyssdtheta = -gg1\df; if any(any(isnan(dyssdtheta))), [U,T] = schur(gg1); - global options_ qz_criterium=options_.qz_criterium; e1 = abs(ordeig(T)) < qz_criterium-1; k = sum(e1); % Number non stationary variables. - n = length(e1)-k; % Number of stationary variables. +% n = length(e1)-k; % Number of stationary variables. [U,T] = ordschur(U,T,e1); T = T(k+1:end,k+1:end); dyssdtheta = -U(:,k+1:end)*(T\U(:,k+1:end)')*df; @@ -71,22 +97,24 @@ if any(any(isnan(dyssdtheta))), end end if nargout>5, -[df, gp, d2f, gpp] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1, dyssdtheta); -H2ss = d2yssdtheta(oo_.dr.order_var,:,:); -[residual, g1, g2, g3] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1); + [df, gp, d2f, gpp] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1, dyssdtheta, d2yssdtheta); + H2ss = d2yssdtheta(oo_.dr.order_var,:,:); + [residual, g1, g2, g3] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1); + nelem=size(g1,2); + g22 = get_all_2nd_derivs(gpp,m,nelem,M_.param_nbr); + g22 = g22(:,:,indx,indx); else -[df, gp] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1, dyssdtheta); -[residual, g1, g2 ] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1); + [df, gp] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1, dyssdtheta,d2yssdtheta); + [residual, g1, g2 ] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1); end Hss = dyssdtheta(oo_.dr.order_var,indx); dyssdtheta = dyssdtheta(I,:); [nr, nc]=size(g2); -[m, nelem]=size(g1); nc = sqrt(nc); ns = max(max(M_.lead_lag_incidence)); gp2 = gp*0; @@ -105,14 +133,8 @@ end gp = gp+gp2; gp = gp(:,:,indx); -param_nbr = length(indx); -if nargout>5, - param_nbr_2 = param_nbr*(param_nbr+1)/2; end -m = size(A,1); -n = size(B,2); - klen = M_.maximum_endo_lag + M_.maximum_endo_lead + 1; @@ -120,9 +142,6 @@ k11 = M_.lead_lag_incidence(find([1:klen] ~= M_.maximum_endo_lag+1),:); a = g1(:,nonzeros(k11')); da = gp(:,nonzeros(k11'),:); if nargout > 5, - nelem = size(g1,2); - g22 = get_all_2nd_derivs(gpp,m,nelem,M_.param_nbr); - g22 = g22(:,:,indx,indx); d2a = g22(:,nonzeros(k11'),:,:); end kstate = oo_.dr.kstate; @@ -250,8 +269,8 @@ end % B0=B; % B = Bx; clear Bx B1; -m = size(A,1); -n = size(B,2); +% m = size(A,1); +% n = size(B,2); % Dg1 = zeros(m,m,param_nbr); % Dg1(:, nf, :) = -gp(:,M_.lead_lag_incidence(3,nf),:); @@ -499,7 +518,7 @@ is=find(gpp(:,3)==i); is=is(find(gpp(is,4)==j)); if ~isempty(is), - g22(gpp(is,1),gpp(is,2))=gpp(is,5); + g22(sub2ind([m,n],gpp(is,1),gpp(is,2)))=gpp(is,5)'; end return diff --git a/matlab/getJJ.m b/matlab/getJJ.m index 859edf0dab..b717858a59 100644 --- a/matlab/getJJ.m +++ b/matlab/getJJ.m @@ -33,10 +33,21 @@ if kronflag == -1, params0 = M_.params; H = fjaco(fun,[sqrt(diag(M_.Sigma_e(indexo,indexo))); M_.params(indx)],M_, oo_, indx,indexo,0,mf,nlags,useautocorr); M_.params = params0; + params0 = M_.params; + gp = fjaco(fun,[sqrt(diag(M_.Sigma_e(indexo,indexo))); M_.params(indx)],M_, oo_, indx,indexo,-1); + M_.params = params0; + offset = length(indexo); + gp = gp(1:M_.endo_nbr,offset+1:end); + dYss = H(1:M_.endo_nbr,offset+1:end); + dA = reshape(H(M_.orig_endo_nbr+[1:numel(A)],:),[size(A),size(H,2)]); + dOm = dA*0; + for j=1:size(H,2), + dOm(:,:,j) = dyn_unvech(H(M_.orig_endo_nbr+numel(A)+1:end,j)); + end assignin('base','M_', M_); assignin('base','oo_', oo_); else - [H, dA, dOm, dYss, gp] = getH(A, B, M_,oo_,kronflag,indx,indexo); + [H, dA, dOm, dYss, gp] = getH(A, B, M_,oo_,options_,kronflag,indx,indexo); gp = reshape(gp,size(gp,1)*size(gp,2),size(gp,3)); gp = [dYss; gp]; % if isempty(H), diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m index aa2f677039..4ab1d3bdc6 100644 --- a/matlab/global_initialization.m +++ b/matlab/global_initialization.m @@ -320,6 +320,7 @@ options_.MaxNumberOfBytes = 1e6; options_.MaximumNumberOfMegaBytes = 111; options_.PosteriorSampleSize = 1000; options_.analytic_derivation = 0; +options_.analytic_derivation_mode = 0; options_.bayesian_irf = 0; options_.bayesian_th_moments = 0; options_.diffuse_filter = 0; diff --git a/matlab/identification_analysis.m b/matlab/identification_analysis.m index 12862b7df2..2c0b701f68 100644 --- a/matlab/identification_analysis.m +++ b/matlab/identification_analysis.m @@ -57,6 +57,8 @@ replic = options_ident.replic; periods = options_ident.periods; max_dim_cova_group = options_ident.max_dim_cova_group; normalize_jacobians = options_ident.normalize_jacobians; +kron_flag = options_ident.analytic_derivation_mode; + [I,J]=find(M_.lead_lag_incidence'); ide_hess = struct(); @@ -75,7 +77,7 @@ if info(1)==0, oo_.dr.ys, 1); vg1 = [oo_.dr.ys(oo_.dr.order_var); vec(g1)]; - [JJ, H, gam, gp, dA, dOm, dYss] = getJJ(A, B, M_,oo0,options_,0,indx,indexo,bayestopt_.mf2,nlags,useautocorr); + [JJ, H, gam, gp, dA, dOm, dYss] = getJJ(A, B, M_,oo0,options_,kron_flag,indx,indexo,bayestopt_.mf2,nlags,useautocorr); derivatives_info.DT=dA; derivatives_info.DOm=dOm; derivatives_info.DYss=dYss; @@ -85,7 +87,7 @@ if info(1)==0, disp('The number of moments with non-zero derivative is smaller than the number of parameters') disp(['Try increasing ar = ', int2str(nlags+1)]) nlags=nlags+1; - [JJ, H, gam, gp, dA, dOm, dYss] = getJJ(A, B, M_,oo0,options_,0,indx,indexo,bayestopt_.mf2,nlags,useautocorr); + [JJ, H, gam, gp, dA, dOm, dYss] = getJJ(A, B, M_,oo0,options_,kron_flag,indx,indexo,bayestopt_.mf2,nlags,useautocorr); derivatives_info.DT=dA; derivatives_info.DOm=dOm; derivatives_info.DYss=dYss; @@ -133,6 +135,7 @@ if info(1)==0, if options_.kalman_algo > 2, options_.kalman_algo = 1; end + analytic_derivation = options_.analytic_derivation; options_.analytic_derivation = -2; info = stoch_simul(options_.varobs); data_info.data=oo_.endo_simul(options_.varobs_id,100+1:end); @@ -140,6 +143,7 @@ if info(1)==0, derivatives_info.no_DLIK=1; [fval,DLIK,AHess,cost_flag,ys,trend_coeff,info,M_,options_,bayestopt_,oo_] = dsge_likelihood(params',data_info,options_,M_,estim_params_,bayestopt_,oo_,derivatives_info); % fval = DsgeLikelihood(xparam1,data_info,options_,M_,estim_params_,bayestopt_,oo_); + options_.analytic_derivation = analytic_derivation; AHess=-AHess; if min(eig(AHess))<0, error('Analytic Hessian is not positive semi-definite!') diff --git a/matlab/thet2tau.m b/matlab/thet2tau.m index a59b374b8d..79c593fad8 100644 --- a/matlab/thet2tau.m +++ b/matlab/thet2tau.m @@ -39,6 +39,13 @@ end [A,B,tele,tubbies,M_,options_,oo_] = dynare_resolve(M_,options_,oo_); if flagmoments==0, tau = [oo_.dr.ys(oo_.dr.order_var); A(:); dyn_vech(B*M_.Sigma_e*B')]; +elseif flagmoments==-1 + [I,J]=find(M_.lead_lag_incidence'); + yy0=oo_.dr.ys(I); + [residual, g1] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1); + tau=[oo_.dr.ys(oo_.dr.order_var); g1(:)]; + else GAM = lyapunov_symm(A,B*M_.Sigma_e*B',options_.qz_criterium,options_.lyapunov_complex_threshold); k = find(abs(GAM) < 1e-12); -- GitLab