From 3ddafb164b0e6510c3825384582aad1c9f23b0b0 Mon Sep 17 00:00:00 2001 From: Marco Ratto <marco.ratto@jrc.ec.europa.eu> Date: Mon, 13 Aug 2012 13:01:56 +0200 Subject: [PATCH] -) Added missing terms for analytic Hessian when steady state depends on estimated params; -) bug fixes; (cherry picked from commit c84f70f6630f4988716dcb4ea59315180bbb36e7) --- matlab/getH.m | 199 +++++++++++++++++++------------------------------- 1 file changed, 75 insertions(+), 124 deletions(-) diff --git a/matlab/getH.m b/matlab/getH.m index 825d251382..8f94e91a44 100644 --- a/matlab/getH.m +++ b/matlab/getH.m @@ -19,9 +19,9 @@ function [H, dA, dOm, Hss, gp, d2A, d2Om, H2ss] = getH(A, B, M_,oo_,options_,kro % You should have received a copy of the GNU General Public License % 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<6 || isempty(kronflag), kronflag = 0; end +if nargin<7 || isempty(indx), indx = [1:M_.param_nbr]; end, +if nargin<8 || isempty(indexo), indexo = []; end, [I,J]=find(M_.lead_lag_incidence'); yy0=oo_.dr.ys(I); @@ -58,28 +58,45 @@ else % end dyssdtheta=zeros(length(oo_.dr.ys),M_.param_nbr); d2yssdtheta=zeros(length(oo_.dr.ys),M_.param_nbr,M_.param_nbr); +[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, d2yssdtheta); +dyssdtheta = -gg1\df; if nargout>5, [residual, gg1, gg2] = feval([M_.fname,'_static'],oo_.dr.ys, oo_.exo_steady_state', M_.params); + [residual, g1, g2, g3] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... + M_.params, oo_.dr.ys, 1); + [nr, nc]=size(g2); + [df, gp, d2f] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... - M_.params, oo_.dr.ys, 1, dyssdtheta, d2yssdtheta); + M_.params, oo_.dr.ys, 1, dyssdtheta*0, d2yssdtheta); d2f = get_all_resid_2nd_derivs(d2f,length(oo_.dr.ys),M_.param_nbr); - d2f = d2f(:,indx,indx); + gpx = zeros(nr,nr,M_.param_nbr); + for j=1:nr, + for i=1:nr, + inx = I == i; + gpx(j,i,:)=sum(gp(j,inx,:),2); + end + end +% d2f = d2f(:,indx,indx); if isempty(find(gg2)), - for j=1:length(indx), - d2yssdtheta(:,indx,j) = -gg1\d2f(:,:,j); + for j=1:M_.param_nbr, + d2yssdtheta(:,:,j) = -gg1\d2f(:,:,j); end else gam = d2f*0; - for j=1:length(indx), - d2yssdtheta(:,indx,j) = -gg1\(d2f(:,:,j)+gam(:,:,j)); + for j=1:nr, + tmp1 = (squeeze(gpx(j,:,:))'*dyssdtheta); + gam(j,:,:)=transpose(reshape(gg2(j,:),[nr nr])*dyssdtheta)*dyssdtheta ... + + tmp1 + tmp1'; end + for j=1:M_.param_nbr, + d2yssdtheta(:,:,j) = -gg1\(d2f(:,:,j)+gam(:,:,j)); +% d2yssdtheta(:,:,j) = -gg1\(d2f(:,:,j)+gam(:,:,j)+ squeeze(gpx(:,:,j))*dyssdtheta); + end + clear tmp1 gpx gam, 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, d2yssdtheta); end -dyssdtheta = -gg1\df; if any(any(isnan(dyssdtheta))), [U,T] = schur(gg1); @@ -97,42 +114,60 @@ if any(any(isnan(dyssdtheta))), end end if nargout>5, - [df, gp, d2f, gpp] = feval([M_.fname,'_params_derivs'],yy0, oo_.exo_steady_state', ... + [df, gp, d2f, gpp, hp] = 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); + H2ss = d2yssdtheta(oo_.dr.order_var,indx,indx); 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,d2yssdtheta); [residual, g1, g2 ] = feval([M_.fname,'_dynamic'],yy0, oo_.exo_steady_state', ... M_.params, oo_.dr.ys, 1); + [nr, nc]=size(g2); end +nc = sqrt(nc); Hss = dyssdtheta(oo_.dr.order_var,indx); dyssdtheta = dyssdtheta(I,:); -[nr, nc]=size(g2); -nc = sqrt(nc); -ns = max(max(M_.lead_lag_incidence)); +ns = max(max(M_.lead_lag_incidence)); % retrieve the number of states excluding columns for shocks gp2 = gp*0; for j=1:nr, - [I J]=ind2sub([nc nc],find(g2(j,:))); + [II JJ]=ind2sub([nc nc],find(g2(j,:))); for i=1:nc, - is = find(I==i); - is = is(find(J(is)<=ns)); + is = find(II==i); + is = is(find(JJ(is)<=ns)); if ~isempty(is), g20=full(g2(j,find(g2(j,:)))); - gp2(j,i,:)=g20(is)*dyssdtheta(J(is),:); + gp2(j,i,:)=g20(is)*dyssdtheta(JJ(is),:); end end end - gp = gp+gp2; gp = gp(:,:,indx); + +if nargout>5, + h22 = get_all_hess_derivs(hp,nr,nc,M_.param_nbr); + gp22 = g22*0; + tmp1 = reshape(g3,[nr*nc*nc nc]); + tmp2=tmp1*[dyssdtheta; zeros(nc-ns,M_.param_nbr)]; + tmp1=reshape(tmp2,[nr nc nc M_.param_nbr]); + + for j=1:nr, + for i=1:nc, + gp22(j,i,:,:)=squeeze(tmp1(j,i,:,:))'*[dyssdtheta; zeros(nc-ns,M_.param_nbr)]; + tmpu = squeeze(h22(j,i,:,:))'*[dyssdtheta; zeros(nc-ns,M_.param_nbr)]; + gp22(j,i,:,:)=gp22(j,i,:,:)+reshape(tmpu+tmpu',[1 1 M_.param_nbr M_.param_nbr]); + end + tmp0=reshape(g2(j,:),[nc nc]); + gp22(j,:,:,:)=gp22(j,:,:,:)+reshape(tmp0(:,1:ns)*d2yssdtheta(I,:,:),[1 nc M_.param_nbr M_.param_nbr]); + end + + g22 = g22+gp22; + g22 = g22(:,:,indx,indx); + clear tmp0 tmp1 tmp2 tmpu, +end end @@ -148,8 +183,6 @@ kstate = oo_.dr.kstate; GAM1 = zeros(M_.endo_nbr,M_.endo_nbr); Dg1 = zeros(M_.endo_nbr,M_.endo_nbr,param_nbr); -% nf = find(M_.lead_lag_incidence(M_.maximum_endo_lag+2,:)); -% GAM1(:, nf) = -g1(:,M_.lead_lag_incidence(M_.maximum_endo_lag+2,nf)); k1 = find(kstate(:,2) == M_.maximum_endo_lag+2 & kstate(:,3)); GAM1(:, kstate(k1,1)) = -a(:,kstate(k1,3)); @@ -158,20 +191,6 @@ if nargout > 5, D2g1 = zeros(M_.endo_nbr,M_.endo_nbr,param_nbr,param_nbr); D2g1(:, kstate(k1,1), :, :) = -d2a(:,kstate(k1,3),:,:); end -% k = find(kstate(:,2) > M_.maximum_endo_lag+2 & kstate(:,3)); -% kk = find(kstate(:,2) > M_.maximum_endo_lag+2 & ~kstate(:,3)); -% nauxe = 0; -% if ~isempty(k), -% ax(:,k)= -a(:,kstate(k,3)); -% ax(:,kk)= 0; -% dax(:,k,:)= -da(:,kstate(k,3),:); -% dax(:,kk,:)= 0; -% nauxe=size(ax,2); -% GAM1 = [ax GAM1]; -% Dg1 = cat(2,dax,Dg1); -% clear ax -% end - [junk,cols_b,cols_j] = find(M_.lead_lag_incidence(M_.maximum_endo_lag+1, ... oo_.dr.order_var)); @@ -183,104 +202,25 @@ if nargout > 5, D2g0 = zeros(M_.endo_nbr,M_.endo_nbr,param_nbr,param_nbr); D2g0(:, cols_b, :, :) = g22(:,cols_j,:,:); end -% GAM0 = g1(:,M_.lead_lag_incidence(M_.maximum_endo_lag+1,:)); k2 = find(kstate(:,2) == M_.maximum_endo_lag+1 & kstate(:,4)); GAM2 = zeros(M_.endo_nbr,M_.endo_nbr); Dg2 = zeros(M_.endo_nbr,M_.endo_nbr,param_nbr); -% nb = find(M_.lead_lag_incidence(1,:)); -% GAM2(:, nb) = -g1(:,M_.lead_lag_incidence(1,nb)); GAM2(:, kstate(k2,1)) = -a(:,kstate(k2,4)); Dg2(:, kstate(k2,1), :) = -da(:,kstate(k2,4),:); if nargout > 5, D2g2 = zeros(M_.endo_nbr,M_.endo_nbr,param_nbr,param_nbr); D2g2(:, kstate(k2,1), :, :) = -d2a(:,kstate(k2,4),:,:); -end% naux = 0; -% k = find(kstate(:,2) < M_.maximum_endo_lag+1 & kstate(:,4)); -% kk = find(kstate(:,2) < M_.maximum_endo_lag+1 ); -% if ~isempty(k), -% ax(:,k)= -a(:,kstate(k,4)); -% ax = ax(:,kk); -% dax(:,k,:)= -da(:,kstate(k,4),:); -% dax = dax(:,kk,:); -% naux = size(ax,2); -% GAM2 = [GAM2 ax]; -% Dg2 = cat(2,Dg2,dax); -% end -% -% GAM0 = blkdiag(GAM0,eye(naux)); -% Dg0 = cat(1,Dg0,zeros(naux+nauxe,M_.endo_nbr,param_nbr)); -% Dg0 = cat(2,Dg0,zeros(m+nauxe,naux,param_nbr)); -% Dg0 = cat(2,zeros(m+nauxe,nauxe,param_nbr),Dg0); -% -% GAM2 = [GAM2 ; A(M_.endo_nbr+1:end,:)]; -% Dg2 = cat(1,Dg2,zeros(naux+nauxe,m,param_nbr)); -% Dg2 = cat(2,zeros(m+nauxe,nauxe,param_nbr),Dg2); -% GAM2 = [zeros(m+nauxe,nauxe) [GAM2; zeros(nauxe,m)]]; -% GAM0 = [[zeros(m,nauxe);(eye(nauxe))] [GAM0; zeros(nauxe,m)]]; +end GAM3 = -g1(:,length(yy0)+1:end); -% GAM3 = -g1(oo_.dr.order_var,length(yy0)+1:end); -% GAM3 = [GAM3; zeros(naux+nauxe,size(GAM3,2))]; -% Dg3 = -gp(oo_.dr.order_var,length(yy0)+1:end,:); Dg3 = -gp(:,length(yy0)+1:end,:); if nargout>5, D2g3 = -g22(:,length(yy0)+1:end,:,:); clear g22 d2a end -% Dg3 = cat(1,Dg3,zeros(naux+nauxe,size(GAM3,2),param_nbr)); - -% auxe = zeros(0,1); -% k0 = kstate(find(kstate(:,2) >= M_.maximum_endo_lag+2),:);; -% i0 = find(k0(:,2) == M_.maximum_endo_lag+2); -% for i=M_.maximum_endo_lag+3:M_.maximum_endo_lag+2+M_.maximum_endo_lead, -% i1 = find(k0(:,2) == i); -% n1 = size(i1,1); -% j = zeros(n1,1); -% for j1 = 1:n1 -% j(j1) = find(k0(i0,1)==k0(i1(j1),1)); -% end -% auxe = [auxe; i0(j)]; -% i0 = i1; -% end -% auxe = [(1:size(auxe,1))' auxe(end:-1:1)]; -% n_ir1 = size(auxe,1); -% nr = m + n_ir1; -% GAM1 = [[GAM1 zeros(size(GAM1,1),naux)]; zeros(naux+nauxe,m+nauxe)]; -% GAM1(m+1:end,:) = sparse(auxe(:,1),auxe(:,2),ones(n_ir1,1),n_ir1,nr); -% Dg1 = cat(2,Dg1,zeros(M_.endo_nbr,naux,param_nbr)); -% Dg1 = cat(1,Dg1,zeros(naux+nauxe,m+nauxe,param_nbr)); - -% Ax = A; -% A1 = A; -% Bx = B; -% B1 = B; -% for j=1:M_.maximum_endo_lead-1, -% A1 = A1*A; -% B1 = A*B1; -% k = find(kstate(:,2) == M_.maximum_endo_lag+2+j ); -% Ax = [A1(kstate(k,1),:); Ax]; -% Bx = [B1(kstate(k,1),:); Bx]; -% end -% Ax = [zeros(m+nauxe,nauxe) Ax]; -% A0 = A; -% A=Ax; clear Ax A1; -% B0=B; -% B = Bx; clear Bx B1; - -% m = size(A,1); -% n = size(B,2); -% Dg1 = zeros(m,m,param_nbr); -% Dg1(:, nf, :) = -gp(:,M_.lead_lag_incidence(3,nf),:); - -% Dg0 = gp(:,M_.lead_lag_incidence(2,:),:); - -% Dg2 = zeros(m,m,param_nbr); -% Dg2(:, nb, :) = -gp(:,M_.lead_lag_incidence(1,nb),:); - -% Dg3 = -gp(:,length(yy0)+1:end,:); if kronflag==1, % kronecker products Dg0=reshape(Dg0,m^2,param_nbr); @@ -554,4 +494,15 @@ for is=1:length(rpp), r22(rpp(is,1),rpp(is,3),rpp(is,2))=rpp(is,4); end -return \ No newline at end of file +return + +function h2 = get_all_hess_derivs(hp,r,m,npar), + +h2=zeros(r,m,m,npar); + +for is=1:length(hp), + h2(hp(is,1),hp(is,2),hp(is,3),hp(is,4))=hp(is,5); + h2(hp(is,1),hp(is,3),hp(is,2),hp(is,4))=hp(is,5); +end + +return -- GitLab