Discounting under Optimal Monetary Policy

Dear Dynare Community,

I try to replicate the paper:
Optimal monetary policy in a New Keynesian model with heterogeneous expectations.
Journal of Economic Dynamics & Control. 73 (2016) pp. 373-387.
Di Bartolomeo et al.

I encounter the following problem:
If I solve the linear model under commitment or discretion, with the ramsey_policy or discretionary_policy command, and use the default discount factor (=1) I obtain the following warning message:

  1. For ramsey_policy:

     warning: division by zero
     warning: called from
         evaluate_planner_objective at line 64 column 6
         ramsey_policy at line 57 column 29
         Di_Bartolomeo_et_al at line 205 column 1
         dynare at line 223 column 1
     warning: division by zero
     warning: called from
         evaluate_planner_objective at line 74 column 5
         ramsey_policy at line 57 column 29
         Di_Bartolomeo_et_al at line 205 column 1
         dynare at line 223 column 1
    
     Approximated value of planner objective function
         - with initial Lagrange multipliers set to 0: NaN
         - with initial Lagrange multipliers set to steady state: NaN
    
  2. For discretionary_policy:

     warning: division by zero
     warning: called from
         evaluate_planner_objective at line 64 column 6
         discretionary_policy at line 38 column 29
         Di_Bartolomeo_et_al at line 172 column 1
         dynare at line 223 column 1
     warning: division by zero
     warning: called from
         evaluate_planner_objective at line 74 column 5
         discretionary_policy at line 38 column 29
         Di_Bartolomeo_et_al at line 172 column 1
         dynare at line 223 column 1
    
     Approximated value of planner objective function
     with discretionary policy:        NaN
    

If I use instead, e.g. ramsey_policy(planner_discount = b);, where b=0.99
I do not encounter any problems like the ones above.

Can someone tell me where the problem is?
The warning message tells me that somewhere a division by zero appears, most likely in the planner objective.
When defining the period loss function, line 63 in the code below, I can not find any possible reason for a division by zero if the discount factor changes.

I appreciate any comments.
Thanks in advance.
Di_Bartolomeo_et_al.mod (4.3 KB)

Best regards,
Max

By the way, I have three related questions.

1.) What happens internal to Dynare once I change the discount factor from \beta=0.99 to \beta=1
(if I change the command ramsey_policy(planner_discount = b) to ramsey_policy )?

Is Dynare switching from the intertemporal loss J_0 = E_0\sum_{t=0}^\infty \beta^tL_t to the scaled intertemporal loss \lim_{\beta\rightarrow1}(1-\beta)J_0=\lim_{\beta\rightarrow1} (1-\beta)E_0\sum_{t=0}^\infty\beta^tL_t=E(L_t), where E(\cdot) is the unconditional expectations operator and L_t is the period loss defined under the planner_objective command?

2.) Are the default objectives of ramsey_policy, discretionary_policy and osr identical or is there a way to make the objectives comparable?

3.) Do I have to programm my own routine in Matlab/Octave for optimal simple rules under the intertemporal loss J_0 = E_0\sum_{t=0}^\infty \beta^tL_t, where \beta=0.99?

I obatin the same warning message as above even for this very simple mod-file. nkm_omp.mod (2.1 KB)

To the best of my knowledge the mod-file should not contain any mistakes. Thus, I suspect that there is something at odds with Octave for the case planner_discount=1.

With Matlab, I cannot reproduce the issues in the simple model. If I change

b     = 1;     % beta:    Household discound factor

in the original model, I only get a different message about indeterminacy. Are you using the most recent stable version?
Regarding your questions:

  1. Dynare cannot take analytical limits, so the steady state of the objective with
Wbar =U/(1-beta); %steady state welfare

will not be well-defined. That is the reason you will not bet a meaninful value of the objective function
2. No, the objectives are not the same. See the manual. In particular, the first two are concerned with welfare, while osr is concerned with (co)-variances
3. Yes, that seems to be the case. But this is straightforward. A starting point would be https://github.com/JohannesPfeifer/DSGE_mod/tree/master/Born_Pfeifer_2018/Welfare where instead of the consumption equivalent you would optimize over the coefficients of the simple rules.

Dear Prof. Pfeifer,

thank you for your reply.

I am currently using Dynare 4.5.1 and Octave 4.2.1 under Windows 10.
This is because Octave 4.4.0 behaved instable under Windows 10, last time I tested it.
Now Dynare 4.5.7 runs on Octave 4.4.1. Maybe the later is stable under Windows 10. I will try.

For the simple model code I obtain the same warning as above (division by zero) and NaN values are stored in oo_.planner_objective_value if I set the parameter bet=1 or change from ramsey_policy(planner_discount = bet) to ramsey_policy.

For the Di Bartolomeon file (where I removed the indeterminacy issue Di_Bartolomeo_2.mod (4.3 KB) ) I obtain the same warning as above, namely

warning: division by zero
warning: called from
    evaluate_planner_objective at line 64 column 6
    ramsey_policy at line 57 column 29
    Di_Bartolomeo_2 at line 205 column 1
    dynare at line 223 column 1
warning: division by zero
warning: called from
    evaluate_planner_objective at line 74 column 5
    ramsey_policy at line 57 column 29
    Di_Bartolomeo_2 at line 205 column 1
    dynare at line 223 column 1

Approximated value of planner objective function
    - with initial Lagrange multipliers set to 0: NaN
    - with initial Lagrange multipliers set to steady state: NaN

Total computing time : 0h00m01s
Note: warning(s) encountered in MATLAB/Octave code

provided that I set b=1; in line 23 or use ramsey_policy(nograph); in line 77 of the file.

The variable Loss(it,iter) = oo_.planner_objective_value(1); contains only NaN values in both cases.

Regarding my questions:

1.) The manual suggests me that ramsey_policy and discretionary_policy are using both the objective J_0=E_0\sum_{t=0}^\infty \beta^tL_t. But by default with a unit discount factor (\beta=1). Due to reasons of convergence, I guessed that dynare might use the scaled intertemporal loss.
Is Dynare optimizing J_0=E_0\sum_{t=0}^\infty L_t by default?

3.) Sorry, I don’t understand. Should your Born_Pfeifer_2018_Welfare_.mod file offers me an idea how to implement an OSR in Dynare under the loss J_0=E_0\sum_{t=0}^\infty \beta^tL_t?
In other words, offers the link an opportunity to come around the limitation of the E(L_t) objective under osr?
Sorry, your code is distributed over too many lines and files. I don’t get it. :frowning:

  1. Again, the warning comes from the line of code I posted above. There is a clear division by 0. I also don’t know why the default for the planner_discount is 1 as this will always case the problem. Maybe @MichelJuillard knows why. AFAIK, Dynare does not automatically compute the limit.
  2. My code defines the welfare function in the mod-file and optimizes over the consumption equivalent to make it equal to the steady state. What you need to do is optimize over your parameters of choice instead to make that objective as big as positive.Depending on whether you are interested in conditional or unconditional welfare, you need to pick one of the two files and modify the call to
    lambda_unconditional_demand=csolve('get_consumption_equivalent_unconditional_welfare',0,[],1e-8,1000)
    to find a maximum instead of solving an equation.

Dear Prof. Pfeifer,

thank you very much.

W.r.t. my questions:

1.) Whenever one relies on beta=1 or on the commands ramsey_policy ,discretionary_policy one should expect to obtain a warning message and the variable oo_.planner_objective_value to assign NaN, right?

3.) I use the linear, two equations, Branch&McGough (2009) model.
AFAIK, I have to define my welfare measure J_0 = E_0\sum_{t=0}^\infty \beta^t \{\pi_t^2+\omega_y y_t^2\} in a way which is feasible for Octave.
E.g. J_0 = \mathrm{trace}(V) + \frac{\beta}{1-\beta}\mathrm{trace}(V\Sigma) and search over a parameter grid (e.g. for \phi_\pi and \phi_y) with some optim-routine to minimize J_0.
Why should I use Dynare for this job?
I think the steps are implemented into Octave with two m.files and some work by hand .
To be honest, I have no idea how to do this with Dynare.

  1. Yes, that is correct.
  2. Do you already have a mod file with the model and an policy rule with arbitrary parameters that works? I could then help with the optimizer.

Yes I have one, you can skip the looping stuff after line 59 in the code. osr_Branch_McGough.mod (4.4 KB)

Thank you very much

Could you please add a recursively defined loss function to the model block as well. From the above, you would have something like
J_0=E_0\sum_{t=0}^{\infty}\beta^t\{\pi_t^2+\omega_y y_t^2\}=\pi^2_0+\omega_yy_0^2+\beta E_0J_1

Yes, with \omega_y = 0.05 it is my loss function.

Sorry, I don`t know how to define it recursively :disappointed_relieved:
I have never done this. I am very sorry.

You do it as I did above. You write out the sum and recognize that after factoring out some terms (here the \beta) the remainder after the first term is simply the definition of J, but on period later.

But how to implement it into dynare. It looks like having initial conditions.

If J_1 = E_1\sum_{t=1}^\infty\beta^t \{ \pi_t^2+\omega_y y_t^2\} shouldn´t we have
J_0 = \pi_0^2+\omega_y y_0^2 + E_0 J_1 ?

Yes, you are right. I forgot to put it above (and have corrected it), because I was using Dynare’s implicit timing convention that every equation is contained in a conditional expectations. The implementation in Dynare is straightforward

J=pi^2+omega_y*y^2+betta*J(+1);

Cool!
now the problem remains how to tell dynare to optimize J_0?

Wait a second.
Where is the \beta in \beta E_0 J_1 coming from?

J is defined to have a sum starting with \beta^0, but when you write out the sum for J_0, the second term will have a \beta^1, so you need to factor it out to get the definition of J_1 with the sum starting again at 0.
The optimization part is the part I will try to assist you with.

1 Like

Thanks so much.

To summarize your argument. You mean
\begin{align} J_0 &= E_0\sum_{t=0}^\infty\beta^t \{ \pi_t^2+\omega_y y_t^2\} \\ &= \pi_0^2+\omega_y y_0^2 + E_0\sum_{t=1}^\infty\beta^t \{ \pi_t^2+\omega_y y_t^2 \} \\ &= \pi_0^2+\omega_y y_0^2 + E_0 E_1\sum_{t=0}^\infty\beta^{t+1} \{ \pi_{t+1}^2+\omega_y y_{t+1}^2 \} \\ &= \pi_0^2+\omega_y y_0^2 + \beta E_0 \underbrace{E_1\sum_{t=0}^\infty\beta^{t} \{ \pi_{t+1}^2+\omega_y y_{t+1}^2 \} }_{= J_1 } \end{align}

My feeling says you are right.
But I am to stupid to see that
J_1 = E_1\sum_{t=0}^\infty\beta^{t} \{ \pi_{t+1}^2+\omega_y y_{t+1}^2 \}
holds.
My head is looking for
J_1 = E_1\sum_{t=0}^\infty\beta^{t+1} \{ \pi_{t+1}^2+\omega_y y_{t+1}^2 \}

Do you still need any change in the model block from my side?

J_1 = E_1\sum_{t=0}^\infty\beta^{t+1} \{ \pi_{t+1}^2+\omega_y y_{t+1}^2\} would be wrong, because the first element now is
\beta\{\pi_1^2+\omega_y y_1^2\}
I still don’t know what \omega_y is in your mod-file.

I am adding a version that should run. The core parts are a call to on optimizer with bound provided:

target_name='J';
x_start=[rho_TR del_pi del_y]';
x_opt_name={'rho_TR',0,1
            'del_pi',1,Inf
            'del_y',0,Inf
            };

if length(x_start)~=length(x_opt_name)
    error('Name vector does not match')
end

stoch_simul(order=2,periods=0) J;
%make sure Dynare does not print out stuff during runs
options_.nomoments=0;
options_.nofunctions=1;
options_.nograph=1;
options_.verbosity=0;
%set noprint option to suppress error messages within optimizer
options_.noprint=1;
options_.TeX=0;

@#ifndef CMAES
    @#define CMAES=0
@#endif        

@#if CMAES==0
    % set csminwel options
    H0 = 1e-2*eye(length(x_start)); %Initial Hessian 
    crit = 1e-8; %Tolerance
    nit = 1000;  %Number of iterations

    [fhat,x_opt_hat] = csminwel(@get_minus_welfare_objective,x_start,H0,[],crit,nit,x_opt_name,target_name);
@#else
    %set CMAES options
    H0=0.2*ones(size(x_start,1),1)
    cmaesOptions = options_.cmaes;
    cmaesOptions.LBounds = cell2mat(x_opt_name(:,2));
    cmaesOptions.UBounds = cell2mat(x_opt_name(:,3));
    [x_opt_hat, fhat, COUNTEVAL, STOPFLAG, OUT, BESTEVER] = cmaes('get_minus_welfare_objective',x_start,H0,cmaesOptions,x_opt_name,target_name);
    x_opt_hat=BESTEVER.x;
@#endif

fprintf('Optimal parameter values are:\n')
for ii=1:length(x_opt_name)
    set_param_value(x_opt_name{ii},x_opt_hat(ii));
    fprintf('%-20s = %8.4f;\n',x_opt_name{ii},x_opt_hat(ii))
end

and the objective function that returns minus the unconditional welfare measure (if you want conditional welfare, this needs to be adjusted)

function fval=get_minus_welfare_objective(x_opt,x_opt_name,target_name)
% function outvalue=get_minus_welfare_objective(x_opt)
% computes minus the welfare objective given the parameters
% Inputs:
% - x_opt       [double]    vector of parameters over which to optimize
% - x_opt_name  [cell]      cell array with name in first column, lower and
%                           upper bounds in second and third
% - target_name [string]    name of the variable storing the welfare

% Copyright (C) 2018 Johannes Pfeifer
%
% This is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% It is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% For a copy of the GNU General Public License,
% see <http://www.gnu.org/licenses/>.

global oo_ options_ M_

for ii=1:size(x_opt_name,1)
    set_param_value(x_opt_name{ii,1},x_opt(ii));
end

if any(x_opt<=cell2mat(x_opt_name(:,2))) || any(x_opt>=cell2mat(x_opt_name(:,3))) %make sure parameters are within bounds
    fval=10e5+sum([x_opt].^2); %penalty function
    return
end

var_list_ = target_name;

info=stoch_simul(var_list_); %run stoch_simul to generate IRFs with the options specified in the mod-file

if info %solution was not successful
    fval=10e6+sum([x_opt].^2); %return with penalty 
else
    fval=-oo_.mean;
end

osr_Branch_McGough.mod (6.0 KB)
get_minus_welfare_objective.m (1.6 KB)

1 Like