- The BK violation comes from differences in the computed steady states. They may not be unique.
- It turns out you cannot have additive parts of the welfare function in the model as they will introduce a singularity. The big number you encounter comes from Dynare replacing the resulting NaN with a large number. 4.7 should have a warning in that case. Now to the workaround. What you can do is have the components of utility as variables in the model:
% WelfareC
[name='UC']
UC = C^(1-SIGMA)/(1-SIGMA);
[name='UN']
UN = -CHI*N^(1+PHI)/(1+PHI);
and then manually compute the decomposition based on the codes in evaluate_planner_objective
after running the model. Here, it would be
%% housekeeping to have access to relevant info
if isempty(options_.qz_criterium)
options_.qz_criterium = 1+1e-6;
end
dr = oo_.dr;
ys=oo_.dr.ys;
exo_nbr = M_.exo_nbr;
nstatic = M_.nstatic;
nspred = M_.nspred;
beta = get_optimal_policy_discount_factor(M_.params, M_.param_names);
%% Original objective
[U,Uy,Uyy] = feval([M_.fname '.objective.static'],ys,zeros(1,exo_nbr), M_.params);
%% override original objective and instead read out UC (or UN if desired); needs to be defined in model-block
UC_pos=strmatch('UC',M_.endo_names,'exact');
U=ys(UC_pos); %get steady statee
Uy=zeros(size(Uy));
Uy(UC_pos)=1; %first derivative is 1 for defined variable, zero for all others
Uyy=sparse(zeros(size(Uyy))); %all second derivatives are zero
Gy = dr.ghx(nstatic+(1:nspred),:);
Gu = dr.ghu(nstatic+(1:nspred),:);
Gyy = dr.ghxx(nstatic+(1:nspred),:);
Gyu = dr.ghxu(nstatic+(1:nspred),:);
Guu = dr.ghuu(nstatic+(1:nspred),:);
Gss = dr.ghs2(nstatic+(1:nspred),:);
gy(dr.order_var,:) = dr.ghx;
gu(dr.order_var,:) = dr.ghu;
gyy(dr.order_var,:) = dr.ghxx;
gyu(dr.order_var,:) = dr.ghxu;
guu(dr.order_var,:) = dr.ghuu;
gss(dr.order_var,:) = dr.ghs2;
Uyy = full(Uyy);
Uyygygy = A_times_B_kronecker_C(Uyy,gy,gy);
Uyygugu = A_times_B_kronecker_C(Uyy,gu,gu);
Uyygugy = A_times_B_kronecker_C(Uyy,gu,gy);
%% Unconditional welfare
oo_=disp_th_moments(dr,M_.endo_names(dr.order_var(nstatic+(1:nspred))),M_,options_,oo_);
oo_.mean(isnan(oo_.mean)) = options_.huge_number;
oo_.var(isnan(oo_.var)) = options_.huge_number;
Ey = oo_.mean;
Eyhat = Ey - ys(dr.order_var(nstatic+(1:nspred)));
Eyhatyhat = oo_.var(:);
Euu = M_.Sigma_e(:);
EU = U + Uy*gy*Eyhat + 0.5*((Uyygygy + Uy*gyy)*Eyhatyhat + (Uyygugu + Uy*guu)*Euu + Uy*gss);
EW = EU/(1-beta);