Questions on Ramsey welfare in Dynare 4.7

  1. The BK violation comes from differences in the computed steady states. They may not be unique.
  2. 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);

1 Like